From 3b96b9fb10e2bdef2e3a80daee208b141a60a490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Thu, 9 Dec 2021 10:53:15 +0100 Subject: [PATCH 1/9] feat(specs): add `analytics` spec and client --- .github/workflows/check.yml | 9 + .../client-analytics/.gitignore | 4 + .../.openapi-generator-ignore | 7 + .../client-analytics/api.ts | 3 + .../client-analytics/model/errorBase.ts | 6 + .../model/getAverageClickPositionResponse.ts | 16 + .../getAverageClickPositionResponseDates.ts | 14 + .../model/getClickPositionsResponse.ts | 8 + .../getClickPositionsResponsePositions.ts | 10 + .../model/getClickThroughRateResponse.ts | 20 ++ .../model/getClickThroughRateResponseDates.ts | 18 + .../model/getConversationRateResponse.ts | 20 ++ .../model/getConversationRateResponseDates.ts | 18 + .../model/getStatusResponse.ts | 6 + .../client-analytics/model/models.ts | 52 +++ .../client-analytics/package.json | 24 ++ .../client-analytics/src/analyticsApi.ts | 330 ++++++++++++++++++ .../client-analytics/src/apis.ts | 7 + .../client-analytics/tsconfig.json | 22 ++ .../client-analytics/utils/Response.ts | 23 ++ .../client-analytics/utils/StatefulHost.ts | 34 ++ .../client-analytics/utils/Transporter.ts | 243 +++++++++++++ .../client-analytics/utils/cache/Cache.ts | 27 ++ .../utils/cache/MemoryCache.ts | 39 +++ .../client-analytics/utils/errors.ts | 38 ++ .../client-analytics/utils/helpers.ts | 117 +++++++ .../utils/requester/EchoRequester.ts | 17 + .../utils/requester/HttpRequester.ts | 98 ++++++ .../utils/requester/Requester.ts | 8 + .../client-analytics/utils/stackTrace.ts | 30 ++ .../client-analytics/utils/types.ts | 65 ++++ .../utils/requester/HttpRequester.ts | 2 +- .../utils/requester/HttpRequester.ts | 2 +- .../utils/requester/HttpRequester.ts | 2 +- .../utils/requester/HttpRequester.ts | 2 +- openapitools.json | 32 +- package.json | 4 +- playground/.env.example | 4 + playground/javascript/analytics.ts | 29 ++ playground/javascript/package.json | 3 + playground/javascript/search.ts | 2 +- .../paths/click/getAverageClickPosition.yml | 57 +++ .../click/getAverageTopClickPosition.yml | 1 - .../paths/click/getClickPositions.yml | 53 +++ .../paths/click/getClickThroughRate.yml | 65 ++++ .../paths/click/getConversionRate.yml | 65 ++++ specs/analytics/paths/common/parameters.yml | 42 +++ specs/analytics/paths/status/getStatus.yml | 29 ++ specs/analytics/spec.yml | 16 +- specs/common/parameters.yml | 24 ++ templates/javascript/api-single.mustache | 25 +- yarn.lock | 10 + 52 files changed, 1778 insertions(+), 24 deletions(-) create mode 100644 clients/algoliasearch-client-javascript/client-analytics/.gitignore create mode 100644 clients/algoliasearch-client-javascript/client-analytics/.openapi-generator-ignore create mode 100644 clients/algoliasearch-client-javascript/client-analytics/api.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/errorBase.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getAverageClickPositionResponse.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getAverageClickPositionResponseDates.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getClickPositionsResponse.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getClickPositionsResponsePositions.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getClickThroughRateResponse.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getClickThroughRateResponseDates.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getConversationRateResponse.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getConversationRateResponseDates.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getStatusResponse.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/models.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/package.json create mode 100644 clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/src/apis.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/tsconfig.json create mode 100644 clients/algoliasearch-client-javascript/client-analytics/utils/Response.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/utils/StatefulHost.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/utils/Transporter.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/utils/cache/Cache.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/utils/cache/MemoryCache.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/utils/errors.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/utils/helpers.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/utils/requester/EchoRequester.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/utils/requester/HttpRequester.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/utils/requester/Requester.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/utils/stackTrace.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/utils/types.ts create mode 100644 playground/javascript/analytics.ts create mode 100644 specs/analytics/paths/click/getAverageClickPosition.yml delete mode 100644 specs/analytics/paths/click/getAverageTopClickPosition.yml create mode 100644 specs/analytics/paths/common/parameters.yml diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index edf70c449e..673d6ba469 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -29,6 +29,9 @@ jobs: - name: Checking personalization specs run: yarn specs personalization + - name: Checking analytics specs + run: yarn specs analytics + - name: Lint run: yamllint specs @@ -59,6 +62,12 @@ jobs: - name: Build personalization client run: yarn client:build-js:personalization + - name: Generate analytics client + run: yarn generate javascript analytics + + - name: Build analytics client + run: yarn client:build-js:analytics + - name: Lint run: yarn lint diff --git a/clients/algoliasearch-client-javascript/client-analytics/.gitignore b/clients/algoliasearch-client-javascript/client-analytics/.gitignore new file mode 100644 index 0000000000..8aafcdc3fd --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/.gitignore @@ -0,0 +1,4 @@ +node_modules +dist +.openapi-generator +.env diff --git a/clients/algoliasearch-client-javascript/client-analytics/.openapi-generator-ignore b/clients/algoliasearch-client-javascript/client-analytics/.openapi-generator-ignore new file mode 100644 index 0000000000..abfb5c9516 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/.openapi-generator-ignore @@ -0,0 +1,7 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +git_push.sh diff --git a/clients/algoliasearch-client-javascript/client-analytics/api.ts b/clients/algoliasearch-client-javascript/client-analytics/api.ts new file mode 100644 index 0000000000..59b02c4607 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/api.ts @@ -0,0 +1,3 @@ +// This is the entrypoint for the package +export * from './src/apis'; +export * from './model/models'; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/errorBase.ts b/clients/algoliasearch-client-javascript/client-analytics/model/errorBase.ts new file mode 100644 index 0000000000..a533aa7a15 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/errorBase.ts @@ -0,0 +1,6 @@ +/** + * Error. + */ +export type ErrorBase = { + message?: string; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getAverageClickPositionResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getAverageClickPositionResponse.ts new file mode 100644 index 0000000000..85016cee6f --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getAverageClickPositionResponse.ts @@ -0,0 +1,16 @@ +import type { GetAverageClickPositionResponseDates } from './getAverageClickPositionResponseDates'; + +export type GetAverageClickPositionResponse = { + /** + * The average of all the click count event. + */ + average: number; + /** + * The number of click event. + */ + clickCount: number; + /** + * A list of click events with their date. + */ + dates: GetAverageClickPositionResponseDates[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getAverageClickPositionResponseDates.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getAverageClickPositionResponseDates.ts new file mode 100644 index 0000000000..254d109ae3 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getAverageClickPositionResponseDates.ts @@ -0,0 +1,14 @@ +export type GetAverageClickPositionResponseDates = { + /** + * The average of all the click count event. + */ + average: number; + /** + * The number of click event. + */ + clickCount: number; + /** + * Date of the event. + */ + date: Date; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getClickPositionsResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getClickPositionsResponse.ts new file mode 100644 index 0000000000..4524b01f09 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getClickPositionsResponse.ts @@ -0,0 +1,8 @@ +import type { GetClickPositionsResponsePositions } from './getClickPositionsResponsePositions'; + +export type GetClickPositionsResponse = { + /** + * A list of the positions with their click count. + */ + positions: GetClickPositionsResponsePositions[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getClickPositionsResponsePositions.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getClickPositionsResponsePositions.ts new file mode 100644 index 0000000000..cdb591fa05 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getClickPositionsResponsePositions.ts @@ -0,0 +1,10 @@ +export type GetClickPositionsResponsePositions = { + /** + * Range of positions with the following pattern: Positions from 1 to 10 included are displayed in separated groups. Positions from 11 to 20 included are grouped together. Positions from 21 and up are grouped together. + */ + position?: number[]; + /** + * The number of click event. + */ + clickCount?: number; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getClickThroughRateResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getClickThroughRateResponse.ts new file mode 100644 index 0000000000..e22dcf9e92 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getClickThroughRateResponse.ts @@ -0,0 +1,20 @@ +import type { GetClickThroughRateResponseDates } from './getClickThroughRateResponseDates'; + +export type GetClickThroughRateResponse = { + /** + * The click-through rate. + */ + rate: number; + /** + * The number of click event. + */ + clickCount: number; + /** + * The number of tracked search click. + */ + trackedSearchCount: number; + /** + * A list of click-through rate events with their date. + */ + dates: GetClickThroughRateResponseDates[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getClickThroughRateResponseDates.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getClickThroughRateResponseDates.ts new file mode 100644 index 0000000000..583a46fda8 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getClickThroughRateResponseDates.ts @@ -0,0 +1,18 @@ +export type GetClickThroughRateResponseDates = { + /** + * The click-through rate. + */ + rate: number; + /** + * The number of click event. + */ + clickCount: number; + /** + * The number of tracked search click. + */ + trackedSearchCount: number; + /** + * Date of the event. + */ + date: Date; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getConversationRateResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getConversationRateResponse.ts new file mode 100644 index 0000000000..256a0d7096 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getConversationRateResponse.ts @@ -0,0 +1,20 @@ +import type { GetConversationRateResponseDates } from './getConversationRateResponseDates'; + +export type GetConversationRateResponse = { + /** + * The click-through rate. + */ + rate: number; + /** + * The number of tracked search click. + */ + trackedSearchCount: number; + /** + * The number of converted clicks. + */ + conversionCount: number; + /** + * A list of click-through rate events with their date. + */ + dates: GetConversationRateResponseDates[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getConversationRateResponseDates.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getConversationRateResponseDates.ts new file mode 100644 index 0000000000..6898f53d8e --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getConversationRateResponseDates.ts @@ -0,0 +1,18 @@ +export type GetConversationRateResponseDates = { + /** + * The click-through rate. + */ + rate: number; + /** + * The number of tracked search click. + */ + trackedSearchCount: number; + /** + * The number of converted clicks. + */ + conversionCount: number; + /** + * Date of the event. + */ + date: Date; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getStatusResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getStatusResponse.ts new file mode 100644 index 0000000000..8cae298049 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getStatusResponse.ts @@ -0,0 +1,6 @@ +export type GetStatusResponse = { + /** + * Date of last update (ISO-8601 format). + */ + updatedAt: Date; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/models.ts b/clients/algoliasearch-client-javascript/client-analytics/model/models.ts new file mode 100644 index 0000000000..10109659f4 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/models.ts @@ -0,0 +1,52 @@ +/* eslint-disable no-param-reassign */ +import type { RequestOptions } from '../utils/types'; + +export * from './errorBase'; +export * from './getAverageClickPositionResponse'; +export * from './getAverageClickPositionResponseDates'; +export * from './getClickPositionsResponse'; +export * from './getClickPositionsResponsePositions'; +export * from './getClickThroughRateResponse'; +export * from './getClickThroughRateResponseDates'; +export * from './getConversationRateResponse'; +export * from './getConversationRateResponseDates'; +export * from './getStatusResponse'; + +export interface Authentication { + /** + * Apply authentication settings to header and query params. + */ + applyToRequest: (requestOptions: RequestOptions) => Promise | void; +} + +export class ApiKeyAuth implements Authentication { + apiKey: string = ''; + + constructor(private location: string, private paramName: string) {} + + applyToRequest(requestOptions: RequestOptions): void { + if (this.location === 'query') { + requestOptions.queryParameters[this.paramName] = this.apiKey; + } else if ( + this.location === 'header' && + requestOptions && + requestOptions.headers + ) { + requestOptions.headers[this.paramName] = this.apiKey; + } else if ( + this.location === 'cookie' && + requestOptions && + requestOptions.headers + ) { + if (requestOptions.headers.Cookie) { + requestOptions.headers.Cookie += `; ${ + this.paramName + }=${encodeURIComponent(this.apiKey)}`; + } else { + requestOptions.headers.Cookie = `${this.paramName}=${encodeURIComponent( + this.apiKey + )}`; + } + } + } +} diff --git a/clients/algoliasearch-client-javascript/client-analytics/package.json b/clients/algoliasearch-client-javascript/client-analytics/package.json new file mode 100644 index 0000000000..ed650433d7 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/package.json @@ -0,0 +1,24 @@ +{ + "name": "@algolia/client-analytics", + "version": "5.0.0", + "description": "JavaScript client for @algolia/client-analytics", + "repository": "algolia/algoliasearch-client-javascript", + "author": "Algolia", + "private": true, + "license": "MIT", + "main": "dist/api.js", + "types": "dist/api.d.ts", + "scripts": { + "clean": "rm -Rf node_modules/ *.js", + "build": "tsc", + "test": "yarn build && node dist/client.js" + }, + "engines": { + "node": "^16.0.0", + "yarn": "^3.0.0" + }, + "devDependencies": { + "@types/node": "16.11.11", + "typescript": "4.5.2" + } +} diff --git a/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts b/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts new file mode 100644 index 0000000000..4b324e036c --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts @@ -0,0 +1,330 @@ +import type { GetAverageClickPositionResponse } from '../model/getAverageClickPositionResponse'; +import type { GetClickPositionsResponse } from '../model/getClickPositionsResponse'; +import type { GetClickThroughRateResponse } from '../model/getClickThroughRateResponse'; +import type { GetConversationRateResponse } from '../model/getConversationRateResponse'; +import type { GetStatusResponse } from '../model/getStatusResponse'; +import { ApiKeyAuth } from '../model/models'; +import { Transporter } from '../utils/Transporter'; +import type { Requester } from '../utils/requester/Requester'; +import type { Headers, Host, Request, RequestOptions } from '../utils/types'; + +export enum AnalyticsApiKeys { + apiKey, + appId, +} + +export class AnalyticsApi { + protected authentications = { + apiKey: new ApiKeyAuth('header', 'X-Algolia-API-Key'), + appId: new ApiKeyAuth('header', 'X-Algolia-Application-Id'), + }; + + private transporter: Transporter; + + private sendRequest( + request: Request, + requestOptions: RequestOptions + ): Promise { + if (this.authentications.apiKey.apiKey) { + this.authentications.apiKey.applyToRequest(requestOptions); + } + + if (this.authentications.appId.apiKey) { + this.authentications.appId.applyToRequest(requestOptions); + } + + return this.transporter.request(request, requestOptions); + } + + constructor( + appId: string, + apiKey: string, + region: 'de' | 'us', + options?: { requester?: Requester; hosts?: Host[] } + ) { + this.setApiKey(AnalyticsApiKeys.appId, appId); + this.setApiKey(AnalyticsApiKeys.apiKey, apiKey); + + this.transporter = new Transporter({ + hosts: options?.hosts ?? this.getDefaultHosts(region), + baseHeaders: { + 'content-type': 'application/x-www-form-urlencoded', + }, + userAgent: 'Algolia for Javascript', + timeouts: { + connect: 2, + read: 5, + write: 30, + }, + requester: options?.requester, + }); + } + + getDefaultHosts(region: 'de' | 'us'): Host[] { + return [ + { + url: `analytics.${region}.algolia.com`, + accept: 'readWrite', + protocol: 'https', + }, + ]; + } + + setRequest(requester: Requester): void { + this.transporter.setRequester(requester); + } + + setHosts(hosts: Host[]): void { + this.transporter.setHosts(hosts); + } + + setApiKey(key: AnalyticsApiKeys, value: string): void { + this.authentications[AnalyticsApiKeys[key]].apiKey = value; + } + + /** + * Returns the average click position. The endpoint returns a value for the complete given time range, as well as a value per day. An average of null means Algolia didn\'t receive any click events for the queries with the clickAnalytics search parameter set to true. The average is null until Algolia receives at least one click event. + * + * @summary Returns the average click position. + * @param index - The index name to target. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + */ + getAverageClickPosition( + index: string, + startDate?: Date, + endDate?: Date, + tags?: string + ): Promise { + const path = '/2/clicks/averageClickPosition'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getAverageClickPosition.' + ); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } + /** + * Returns the distribution of clicks per range of positions. If the groups all have a count of 0, it means Algolia didn\'t receive any click events for the queries with the clickAnalytics search parameter set to true. The count is 0 until Algolia receives at least one click event. + * + * @summary Returns the distribution of clicks per range of positions. + * @param index - The index name to target. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + */ + getClickPositions( + index: string, + startDate?: Date, + endDate?: Date, + tags?: string + ): Promise { + const path = '/2/clicks/positions'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getClickPositions.' + ); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } + /** + * Returns a click-through rate (CTR). The endpoint returns a value for the complete given time range, as well as a value per day. It also returns the count of clicks and searches used to compute the rates. Tracked searches are searches for which the engine returned a queryID, so searches where you\'ve set the clickAnalytics search parameter to true. This is different than the “count” attribute of the response, which includes tracked searches and searches where you didn\'t enable the clickAnalytics search parameter. If the CTR is null, it means that Algolia didn\'t receive any queries with the clickAnalytics search parameter set to true. If the CTR is 0, it means Algolia didn\'t receive any click events for the queries with the clickAnalytics search parameter set to true. + * + * @summary Returns a click-through rate (CTR). + * @param index - The index name to target. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + */ + getClickThroughRate( + index: string, + startDate?: Date, + endDate?: Date, + tags?: string + ): Promise { + const path = '/2/clicks/clickThroughRate'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getClickThroughRate.' + ); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } + /** + * Returns a conversion rate (CR). The endpoint returns a value for the complete given time range, as well as a value per day. It also returns the count of conversion and searches used to compute the rates. Tracked searches are searches for which the engine returned a queryID, so searches where you\'ve set the clickAnalytics search parameter to true. This is different than the “count” attribute of the response, which includes tracked searches and searches where you didn\'t enable the clickAnalytics search parameter. If the CR is null, it means that Algolia didn\'t receive any queries with the clickAnalytics search parameter set to true. If the CR is 0, it means Algolia didn\'t receive any conversion events for the queries with the clickAnalytics search parameter set to true. + * + * @summary Returns a conversion rate (CR). + * @param index - The index name to target. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + */ + getConversationRate( + index: string, + startDate?: Date, + endDate?: Date, + tags?: string + ): Promise { + const path = '/2/conversions/conversionRate'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getConversationRate.' + ); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } + /** + * Returns the latest update time of the analytics API for a given index. If the index has been recently created and/or no search has been performed yet the updated time will be null. + * + * @summary Get latest update time of the analytics API. + * @param index - The index name to target. + */ + getStatus(index: string): Promise { + const path = '/2/status'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getStatus.' + ); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } +} diff --git a/clients/algoliasearch-client-javascript/client-analytics/src/apis.ts b/clients/algoliasearch-client-javascript/client-analytics/src/apis.ts new file mode 100644 index 0000000000..d7b69922f7 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/src/apis.ts @@ -0,0 +1,7 @@ +import { AnalyticsApi } from './analyticsApi'; + +export * from './analyticsApi'; +export * from '../utils/errors'; +export { EchoRequester } from '../utils/requester/EchoRequester'; + +export const APIS = [AnalyticsApi]; diff --git a/clients/algoliasearch-client-javascript/client-analytics/tsconfig.json b/clients/algoliasearch-client-javascript/client-analytics/tsconfig.json new file mode 100644 index 0000000000..2f72c93ccb --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "commonjs", + "noImplicitAny": false, + "suppressImplicitAnyIndexErrors": true, + "target": "ES6", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "strict": true, + "moduleResolution": "node", + "removeComments": true, + "sourceMap": true, + "noLib": false, + "declaration": true, + "lib": ["dom", "es6", "es5", "dom.iterable", "scripthost"], + "outDir": "dist", + "typeRoots": ["node_modules/@types"], + "types": ["node"] + }, + "include": ["src", "model", "api.ts"], + "exclude": ["dist", "node_modules"] +} diff --git a/clients/algoliasearch-client-javascript/client-analytics/utils/Response.ts b/clients/algoliasearch-client-javascript/client-analytics/utils/Response.ts new file mode 100644 index 0000000000..bd22de7df9 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/utils/Response.ts @@ -0,0 +1,23 @@ +import type { Response } from './types'; + +export function isNetworkError({ + isTimedOut, + status, +}: Omit): boolean { + return !isTimedOut && ~~status === 0; +} + +export function isRetryable({ + isTimedOut, + status, +}: Omit): boolean { + return ( + isTimedOut || + isNetworkError({ isTimedOut, status }) || + (~~(status / 100) !== 2 && ~~(status / 100) !== 4) + ); +} + +export function isSuccess({ status }: Pick): boolean { + return ~~(status / 100) === 2; +} diff --git a/clients/algoliasearch-client-javascript/client-analytics/utils/StatefulHost.ts b/clients/algoliasearch-client-javascript/client-analytics/utils/StatefulHost.ts new file mode 100644 index 0000000000..162c4ed1c6 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/utils/StatefulHost.ts @@ -0,0 +1,34 @@ +import type { Host } from './types'; + +const EXPIRATION_DELAY = 2 * 60 * 1000; + +export class StatefulHost implements Host { + url: string; + accept: 'read' | 'readWrite' | 'write'; + protocol: 'http' | 'https'; + + private lastUpdate: number; + private status: 'down' | 'timedout' | 'up'; + + constructor(host: Host, status: StatefulHost['status'] = 'up') { + this.url = host.url; + this.accept = host.accept; + this.protocol = host.protocol; + + this.status = status; + this.lastUpdate = Date.now(); + } + + isUp(): boolean { + return ( + this.status === 'up' || Date.now() - this.lastUpdate > EXPIRATION_DELAY + ); + } + + isTimedout(): boolean { + return ( + this.status === 'timedout' && + Date.now() - this.lastUpdate <= EXPIRATION_DELAY + ); + } +} diff --git a/clients/algoliasearch-client-javascript/client-analytics/utils/Transporter.ts b/clients/algoliasearch-client-javascript/client-analytics/utils/Transporter.ts new file mode 100644 index 0000000000..48b4edebfd --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/utils/Transporter.ts @@ -0,0 +1,243 @@ +import { isRetryable, isSuccess } from './Response'; +import { StatefulHost } from './StatefulHost'; +import type { Cache } from './cache/Cache'; +import { MemoryCache } from './cache/MemoryCache'; +import { RetryError } from './errors'; +import { + deserializeFailure, + deserializeSuccess, + serializeData, + serializeHeaders, + serializeUrl, +} from './helpers'; +import { HttpRequester } from './requester/HttpRequester'; +import type { Requester } from './requester/Requester'; +import { + stackTraceWithoutCredentials, + stackFrameWithoutCredentials, +} from './stackTrace'; +import type { + Headers, + Host, + Request, + RequestOptions, + StackFrame, + Timeouts, + Response, + EndRequest, +} from './types'; + +export class Transporter { + private hosts: Host[]; + private baseHeaders: Headers; + private hostsCache: Cache; + private userAgent: string; + private timeouts: Timeouts; + private requester: Requester; + + constructor({ + hosts, + baseHeaders, + userAgent, + timeouts, + requester = new HttpRequester(), + }: { + hosts: Host[]; + baseHeaders: Headers; + userAgent: string; + timeouts: Timeouts; + requester?: Requester; + }) { + this.hosts = hosts; + this.hostsCache = new MemoryCache(); + this.baseHeaders = baseHeaders; + this.userAgent = userAgent; + this.timeouts = timeouts; + this.requester = requester; + } + + setHosts(hosts: Host[]): void { + this.hosts = hosts; + this.hostsCache.clear(); + } + + setRequester(requester: Requester): void { + this.requester = requester; + } + + async createRetryableOptions(compatibleHosts: Host[]): Promise<{ + hosts: Host[]; + getTimeout: (retryCount: number, timeout: number) => number; + }> { + const statefulHosts = await Promise.all( + compatibleHosts.map((statelessHost) => { + return this.hostsCache.get(statelessHost, () => { + return Promise.resolve(new StatefulHost(statelessHost)); + }); + }) + ); + const hostsUp = statefulHosts.filter((host) => host.isUp()); + const hostsTimeouted = statefulHosts.filter((host) => host.isTimedout()); + + /** + * Note, we put the hosts that previously timeouted on the end of the list. + */ + const hostsAvailable = [...hostsUp, ...hostsTimeouted]; + + const hosts = hostsAvailable.length > 0 ? hostsAvailable : compatibleHosts; + + return { + hosts, + getTimeout(timeoutsCount: number, baseTimeout: number): number { + /** + * Imagine that you have 4 hosts, if timeouts will increase + * on the following way: 1 (timeouted) > 4 (timeouted) > 5 (200). + * + * Note that, the very next request, we start from the previous timeout. + * + * 5 (timeouted) > 6 (timeouted) > 7 ... + * + * This strategy may need to be reviewed, but is the strategy on the our + * current v3 version. + */ + const timeoutMultiplier = + hostsTimeouted.length === 0 && timeoutsCount === 0 + ? 1 + : hostsTimeouted.length + 3 + timeoutsCount; + + return timeoutMultiplier * baseTimeout; + }, + }; + } + + async request( + request: Request, + requestOptions: RequestOptions + ): Promise { + const stackTrace: StackFrame[] = []; + + const isRead = request.method === 'GET'; + + /** + * First we prepare the payload that do not depend from hosts. + */ + const data = serializeData(request, requestOptions); + const headers = serializeHeaders(this.baseHeaders, requestOptions); + const method = request.method; + + // On `GET`, the data is proxied to query parameters. + const dataQueryParameters: Record = isRead + ? { + ...request.data, + ...requestOptions.data, + } + : {}; + + const queryParameters = { + 'x-algolia-agent': this.userAgent, + ...dataQueryParameters, + ...requestOptions.queryParameters, + }; + + let timeoutsCount = 0; + + const retry = async ( + hosts: Host[], + getTimeout: (timeoutsCount: number, timeout: number) => number + ): Promise => { + /** + * We iterate on each host, until there is no host left. + */ + const host = hosts.pop(); + if (host === undefined) { + throw new RetryError(stackTraceWithoutCredentials(stackTrace)); + } + + let responseTimeout = requestOptions.timeout; + if (responseTimeout === undefined) { + responseTimeout = isRead ? this.timeouts.read : this.timeouts.write; + } + + const payload: EndRequest = { + data, + headers, + method, + url: serializeUrl(host, request.path, queryParameters), + connectTimeout: getTimeout(timeoutsCount, this.timeouts.connect), + responseTimeout: getTimeout(timeoutsCount, responseTimeout), + }; + + /** + * The stackFrame is pushed to the stackTrace so we + * can have information about onRetry and onFailure + * decisions. + */ + const pushToStackTrace = (response: Response): StackFrame => { + const stackFrame: StackFrame = { + request: payload, + response, + host, + triesLeft: hosts.length, + }; + + stackTrace.push(stackFrame); + + return stackFrame; + }; + + const response = await this.requester.send(payload, request); + + if (isRetryable(response)) { + const stackFrame = pushToStackTrace(response); + + // If response is a timeout, we increase the number of timeouts so we can increase the timeout later. + if (response.isTimedOut) { + timeoutsCount++; + } + /** + * Failures are individually sent to the logger, allowing + * the end user to debug / store stack frames even + * when a retry error does not happen. + */ + // eslint-disable-next-line no-console -- this will be fixed with the new `Logger` + console.log( + 'Retryable failure', + stackFrameWithoutCredentials(stackFrame) + ); + + /** + * We also store the state of the host in failure cases. If the host, is + * down it will remain down for the next 2 minutes. In a timeout situation, + * this host will be added end of the list of hosts on the next request. + */ + await this.hostsCache.set( + host, + new StatefulHost(host, response.isTimedOut ? 'timedout' : 'down') + ); + return retry(hosts, getTimeout); + } + if (isSuccess(response)) { + return deserializeSuccess(response); + } + + pushToStackTrace(response); + throw deserializeFailure(response, stackTrace); + }; + + /** + * Finally, for each retryable host perform request until we got a non + * retryable response. Some notes here: + * + * 1. The reverse here is applied so we can apply a `pop` later on => more performant. + * 2. We also get from the retryable options a timeout multiplier that is tailored + * for the current context. + */ + const compatibleHosts = this.hosts.filter( + (host) => + host.accept === 'readWrite' || + (isRead ? host.accept === 'read' : host.accept === 'write') + ); + const options = await this.createRetryableOptions(compatibleHosts); + return retry([...options.hosts].reverse(), options.getTimeout); + } +} diff --git a/clients/algoliasearch-client-javascript/client-analytics/utils/cache/Cache.ts b/clients/algoliasearch-client-javascript/client-analytics/utils/cache/Cache.ts new file mode 100644 index 0000000000..625862660c --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/utils/cache/Cache.ts @@ -0,0 +1,27 @@ +export interface Cache { + /** + * Gets the value of the given `key`. + */ + get: ( + key: Record | string, + defaultValue: () => Promise + ) => Promise; + + /** + * Sets the given value with the given `key`. + */ + set: ( + key: Record | string, + value: TValue + ) => Promise; + + /** + * Deletes the given `key`. + */ + delete: (key: Record | string) => Promise; + + /** + * Clears the cache. + */ + clear: () => Promise; +} diff --git a/clients/algoliasearch-client-javascript/client-analytics/utils/cache/MemoryCache.ts b/clients/algoliasearch-client-javascript/client-analytics/utils/cache/MemoryCache.ts new file mode 100644 index 0000000000..f7853f39bc --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/utils/cache/MemoryCache.ts @@ -0,0 +1,39 @@ +import type { Cache } from './Cache'; + +export class MemoryCache implements Cache { + private cache: Record = {}; + + async get( + key: Record | string, + defaultValue: () => Promise + ): Promise { + const keyAsString = JSON.stringify(key); + + if (keyAsString in this.cache) { + return Promise.resolve(this.cache[keyAsString]); + } + + return await defaultValue(); + } + + set( + key: Record | string, + value: TValue + ): Promise { + this.cache[JSON.stringify(key)] = value; + + return Promise.resolve(value); + } + + delete(key: Record | string): Promise { + delete this.cache[JSON.stringify(key)]; + + return Promise.resolve(); + } + + clear(): Promise { + this.cache = {}; + + return Promise.resolve(); + } +} diff --git a/clients/algoliasearch-client-javascript/client-analytics/utils/errors.ts b/clients/algoliasearch-client-javascript/client-analytics/utils/errors.ts new file mode 100644 index 0000000000..a02f3004ad --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/utils/errors.ts @@ -0,0 +1,38 @@ +import type { Response, StackFrame } from './types'; + +class ErrorWithStackTrace extends Error { + stackTrace: StackFrame[]; + + constructor(message: string, stackTrace: StackFrame[]) { + super(message); + // the array and object should be frozen to reflect the stackTrace at the time of the error + this.stackTrace = stackTrace; + } +} + +export class RetryError extends ErrorWithStackTrace { + constructor(stackTrace: StackFrame[]) { + super( + 'Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.', + stackTrace + ); + } +} + +export class ApiError extends ErrorWithStackTrace { + status: number; + + constructor(message: string, status: number, stackTrace: StackFrame[]) { + super(message, stackTrace); + this.status = status; + } +} + +export class DeserializationError extends Error { + response: Response; + + constructor(message: string, response: Response) { + super(message); + this.response = response; + } +} diff --git a/clients/algoliasearch-client-javascript/client-analytics/utils/helpers.ts b/clients/algoliasearch-client-javascript/client-analytics/utils/helpers.ts new file mode 100644 index 0000000000..5d64ac8868 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/utils/helpers.ts @@ -0,0 +1,117 @@ +import { ApiError, DeserializationError } from './errors'; +import type { + Headers, + Host, + Request, + RequestOptions, + Response, + StackFrame, +} from './types'; + +export function shuffle(array: TData[]): TData[] { + const shuffledArray = array; + + for (let c = array.length - 1; c > 0; c--) { + const b = Math.floor(Math.random() * (c + 1)); + const a = array[c]; + + shuffledArray[c] = array[b]; + shuffledArray[b] = a; + } + + return shuffledArray; +} + +export function serializeUrl( + host: Host, + path: string, + queryParameters: Readonly> +): string { + const queryParametersAsString = serializeQueryParameters(queryParameters); + let url = `${host.protocol}://${host.url}/${ + path.charAt(0) === '/' ? path.substr(1) : path + }`; + + if (queryParametersAsString.length) { + url += `?${queryParametersAsString}`; + } + + return url; +} + +export function serializeQueryParameters( + parameters: Readonly> +): string { + const isObjectOrArray = (value: any): boolean => + Object.prototype.toString.call(value) === '[object Object]' || + Object.prototype.toString.call(value) === '[object Array]'; + + return Object.keys(parameters) + .map( + (key) => + `${key}=${ + isObjectOrArray(parameters[key]) + ? JSON.stringify(parameters[key]) + : parameters[key] + }` + ) + .join('&'); +} + +export function serializeData( + request: Request, + requestOptions: RequestOptions +): string | undefined { + if ( + request.method === 'GET' || + (request.data === undefined && requestOptions.data === undefined) + ) { + return undefined; + } + + const data = Array.isArray(request.data) + ? request.data + : { ...request.data, ...requestOptions.data }; + + return JSON.stringify(data); +} + +export function serializeHeaders( + baseHeaders: Headers, + requestOptions: RequestOptions +): Headers { + const headers: Headers = { + ...baseHeaders, + ...requestOptions.headers, + }; + const serializedHeaders: Headers = {}; + + Object.keys(headers).forEach((header) => { + const value = headers[header]; + serializedHeaders[header.toLowerCase()] = value; + }); + + return serializedHeaders; +} + +export function deserializeSuccess(response: Response): TObject { + try { + return JSON.parse(response.content); + } catch (e) { + throw new DeserializationError((e as Error).message, response); + } +} + +export function deserializeFailure( + { content, status }: Response, + stackFrame: StackFrame[] +): Error { + let message = content; + try { + message = JSON.parse(content).message; + } catch (e) { + // .. + } + + return new ApiError(message, status, stackFrame); +} diff --git a/clients/algoliasearch-client-javascript/client-analytics/utils/requester/EchoRequester.ts b/clients/algoliasearch-client-javascript/client-analytics/utils/requester/EchoRequester.ts new file mode 100644 index 0000000000..41a3dd9041 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/utils/requester/EchoRequester.ts @@ -0,0 +1,17 @@ +import type { EndRequest, Request, Response } from '../types'; + +import { Requester } from './Requester'; + +export class EchoRequester extends Requester { + constructor(private status = 200) { + super(); + } + + send(_request: EndRequest, originalRequest: Request): Promise { + return Promise.resolve({ + content: JSON.stringify(originalRequest), + isTimedOut: false, + status: this.status, + }); + } +} diff --git a/clients/algoliasearch-client-javascript/client-analytics/utils/requester/HttpRequester.ts b/clients/algoliasearch-client-javascript/client-analytics/utils/requester/HttpRequester.ts new file mode 100644 index 0000000000..1567d2a891 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/utils/requester/HttpRequester.ts @@ -0,0 +1,98 @@ +import http from 'http'; +import https from 'https'; + +import type { EndRequest, Response } from '../types'; + +import { Requester } from './Requester'; + +export class HttpRequester extends Requester { + private httpAgent: http.Agent; + private httpsAgent: https.Agent; + + constructor() { + super(); + this.httpAgent = new http.Agent({ keepAlive: true }); + this.httpsAgent = new https.Agent({ keepAlive: true }); + } + + send(request: EndRequest): Promise { + return new Promise((resolve) => { + let responseTimeout: NodeJS.Timeout | undefined; + // eslint-disable-next-line prefer-const -- linter thinks this is not reassigned + let connectTimeout: NodeJS.Timeout | undefined; + const url = new URL(request.url); + const path = + url.search === null ? url.pathname : `${url.pathname}${url.search}`; + const options: https.RequestOptions = { + agent: url.protocol === 'https:' ? this.httpsAgent : this.httpAgent, + hostname: url.hostname, + path, + method: request.method, + headers: request.headers, + ...(url.port !== undefined ? { port: url.port || '' } : {}), + }; + + const req = (url.protocol === 'https:' ? https : http).request( + options, + (response) => { + let contentBuffers: Buffer[] = []; + + response.on('data', (chunk) => { + contentBuffers = contentBuffers.concat(chunk); + }); + + response.on('end', () => { + clearTimeout(connectTimeout as NodeJS.Timeout); + clearTimeout(responseTimeout as NodeJS.Timeout); + + resolve({ + status: response.statusCode || 0, + content: Buffer.concat(contentBuffers).toString(), + isTimedOut: false, + }); + }); + } + ); + + const createTimeout = ( + timeout: number, + content: string + ): NodeJS.Timeout => { + return setTimeout(() => { + req.destroy(); + + resolve({ + status: 0, + content, + isTimedOut: true, + }); + }, timeout * 1000); + }; + + connectTimeout = createTimeout( + request.connectTimeout, + 'Connection timeout' + ); + + req.on('error', (error) => { + clearTimeout(connectTimeout as NodeJS.Timeout); + clearTimeout(responseTimeout!); + resolve({ status: 0, content: error.message, isTimedOut: false }); + }); + + req.once('response', () => { + clearTimeout(connectTimeout as NodeJS.Timeout); + responseTimeout = createTimeout( + request.responseTimeout, + 'Socket timeout' + ); + }); + + if (request.data !== undefined) { + req.write(request.data); + } + + req.end(); + }); + } +} diff --git a/clients/algoliasearch-client-javascript/client-analytics/utils/requester/Requester.ts b/clients/algoliasearch-client-javascript/client-analytics/utils/requester/Requester.ts new file mode 100644 index 0000000000..41c0606575 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/utils/requester/Requester.ts @@ -0,0 +1,8 @@ +import type { EndRequest, Request, Response } from '../types'; + +export abstract class Requester { + abstract send( + request: EndRequest, + originalRequest: Request + ): Promise; +} diff --git a/clients/algoliasearch-client-javascript/client-analytics/utils/stackTrace.ts b/clients/algoliasearch-client-javascript/client-analytics/utils/stackTrace.ts new file mode 100644 index 0000000000..14750a54f2 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/utils/stackTrace.ts @@ -0,0 +1,30 @@ +import type { StackFrame } from './types'; + +export function stackTraceWithoutCredentials( + stackTrace: StackFrame[] +): StackFrame[] { + return stackTrace.map((stackFrame) => + stackFrameWithoutCredentials(stackFrame) + ); +} + +export function stackFrameWithoutCredentials( + stackFrame: StackFrame +): StackFrame { + const modifiedHeaders: Record = stackFrame.request.headers[ + 'x-algolia-api-key' + ] + ? { 'x-algolia-api-key': '*****' } + : {}; + + return { + ...stackFrame, + request: { + ...stackFrame.request, + headers: { + ...stackFrame.request.headers, + ...modifiedHeaders, + }, + }, + }; +} diff --git a/clients/algoliasearch-client-javascript/client-analytics/utils/types.ts b/clients/algoliasearch-client-javascript/client-analytics/utils/types.ts new file mode 100644 index 0000000000..d2a478c1a0 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/utils/types.ts @@ -0,0 +1,65 @@ +export type Method = 'DELETE' | 'GET' | 'PATCH' | 'POST' | 'PUT'; + +export type Request = { + method: Method; + path: string; + data?: Record; +}; + +export type RequestOptions = { + /** + * Custom timeout for the request. Note that, in normal situacions + * the given timeout will be applied. But the transporter layer may + * increase this timeout if there is need for it. + */ + timeout?: number; + + /** + * Custom headers for the request. This headers are + * going to be merged the transporter headers. + */ + headers?: Record; + + /** + * Custom query parameters for the request. This query parameters are + * going to be merged the transporter query parameters. + */ + queryParameters: Record; + data?: Record; +}; + +export type EndRequest = { + method: Method; + url: string; + connectTimeout: number; + responseTimeout: number; + headers: Headers; + data?: string; +}; + +export type Response = { + content: string; + isTimedOut: boolean; + status: number; +}; + +export type Headers = Record; + +export type Host = { + url: string; + accept: 'read' | 'readWrite' | 'write'; + protocol: 'http' | 'https'; +}; + +export type StackFrame = { + request: EndRequest; + response: Response; + host: Host; + triesLeft: number; +}; + +export type Timeouts = { + readonly connect: number; + readonly read: number; + readonly write: number; +}; diff --git a/clients/algoliasearch-client-javascript/client-personalization/utils/requester/HttpRequester.ts b/clients/algoliasearch-client-javascript/client-personalization/utils/requester/HttpRequester.ts index cc4245f3b6..1567d2a891 100644 --- a/clients/algoliasearch-client-javascript/client-personalization/utils/requester/HttpRequester.ts +++ b/clients/algoliasearch-client-javascript/client-personalization/utils/requester/HttpRequester.ts @@ -22,7 +22,7 @@ export class HttpRequester extends Requester { let connectTimeout: NodeJS.Timeout | undefined; const url = new URL(request.url); const path = - url.search === null ? url.pathname : `${url.pathname}?${url.search}`; + url.search === null ? url.pathname : `${url.pathname}${url.search}`; const options: https.RequestOptions = { agent: url.protocol === 'https:' ? this.httpsAgent : this.httpAgent, hostname: url.hostname, diff --git a/clients/algoliasearch-client-javascript/client-search/utils/requester/HttpRequester.ts b/clients/algoliasearch-client-javascript/client-search/utils/requester/HttpRequester.ts index cc4245f3b6..1567d2a891 100644 --- a/clients/algoliasearch-client-javascript/client-search/utils/requester/HttpRequester.ts +++ b/clients/algoliasearch-client-javascript/client-search/utils/requester/HttpRequester.ts @@ -22,7 +22,7 @@ export class HttpRequester extends Requester { let connectTimeout: NodeJS.Timeout | undefined; const url = new URL(request.url); const path = - url.search === null ? url.pathname : `${url.pathname}?${url.search}`; + url.search === null ? url.pathname : `${url.pathname}${url.search}`; const options: https.RequestOptions = { agent: url.protocol === 'https:' ? this.httpsAgent : this.httpAgent, hostname: url.hostname, diff --git a/clients/algoliasearch-client-javascript/recommend/utils/requester/HttpRequester.ts b/clients/algoliasearch-client-javascript/recommend/utils/requester/HttpRequester.ts index cc4245f3b6..1567d2a891 100644 --- a/clients/algoliasearch-client-javascript/recommend/utils/requester/HttpRequester.ts +++ b/clients/algoliasearch-client-javascript/recommend/utils/requester/HttpRequester.ts @@ -22,7 +22,7 @@ export class HttpRequester extends Requester { let connectTimeout: NodeJS.Timeout | undefined; const url = new URL(request.url); const path = - url.search === null ? url.pathname : `${url.pathname}?${url.search}`; + url.search === null ? url.pathname : `${url.pathname}${url.search}`; const options: https.RequestOptions = { agent: url.protocol === 'https:' ? this.httpsAgent : this.httpAgent, hostname: url.hostname, diff --git a/clients/algoliasearch-client-javascript/utils/requester/HttpRequester.ts b/clients/algoliasearch-client-javascript/utils/requester/HttpRequester.ts index cc4245f3b6..1567d2a891 100644 --- a/clients/algoliasearch-client-javascript/utils/requester/HttpRequester.ts +++ b/clients/algoliasearch-client-javascript/utils/requester/HttpRequester.ts @@ -22,7 +22,7 @@ export class HttpRequester extends Requester { let connectTimeout: NodeJS.Timeout | undefined; const url = new URL(request.url); const path = - url.search === null ? url.pathname : `${url.pathname}?${url.search}`; + url.search === null ? url.pathname : `${url.pathname}${url.search}`; const options: https.RequestOptions = { agent: url.protocol === 'https:' ? this.httpsAgent : this.httpAgent, hostname: url.hostname, diff --git a/openapitools.json b/openapitools.json index 860cd53e01..4b0a194ca8 100644 --- a/openapitools.json +++ b/openapitools.json @@ -18,7 +18,9 @@ "supportsES6": true, "npmName": "@algolia/client-search", "packageName": "@algolia/client-search", - "npmVersion": "5.0.0" + "npmVersion": "5.0.0", + + "isSearchHost": true } }, "javascript-recommend": { @@ -37,7 +39,9 @@ "supportsES6": true, "npmName": "@algolia/recommend", "packageName": "@algolia/recommend", - "npmVersion": "5.0.0" + "npmVersion": "5.0.0", + + "isSearchHost": true } }, "javascript-personalization": { @@ -57,7 +61,29 @@ "packageName": "@algolia/client-personalization", "npmVersion": "5.0.0", - "isPersonalizationHost": false + "hasRegionalHost": true, + "isPersonalizationHost": true + } + }, + "javascript-analytics": { + "generatorName": "typescript-node", + "templateDir": "#{cwd}/templates/javascript/", + "config": "#{cwd}/openapitools.json", + "apiPackage": "src", + "output": "#{cwd}/clients/algoliasearch-client-javascript/client-analytics", + "glob": "specs/analytics/spec.yml", + "gitHost": "algolia", + "gitUserId": "algolia", + "gitRepoId": "algoliasearch-client-javascript", + "additionalProperties": { + "modelPropertyNaming": "original", + "supportsES6": true, + "npmName": "@algolia/client-analytics", + "packageName": "@algolia/client-analytics", + "npmVersion": "5.0.0", + + "hasRegionalHost": true, + "isAnalyticsHost": true } } } diff --git a/package.json b/package.json index 48f280b232..883f6694c0 100644 --- a/package.json +++ b/package.json @@ -8,16 +8,18 @@ ], "scripts": { "clean": "rm -rf **/dist **/build **/node_modules", + "client:build-js:analytics": "yarn workspace @algolia/client-analytics build", "client:build-js:personalization": "yarn workspace @algolia/client-personalization build", "client:build-js:recommend": "yarn workspace @algolia/recommend build", "client:build-js:search": "yarn workspace @algolia/client-search build", - "client:build-js": "yarn client:build-js:search && yarn client:build-js:recommend && yarn client:build-js:personalization", + "client:build-js": "yarn client:build-js:search && yarn client:build-js:recommend && yarn client:build-js:personalization && yarn client:build-js:analytics", "client:build": "yarn client:build-js", "cts:generate": "yarn workspace tests cts:generate", "cts:test": "yarn workspace tests test", "lint": "eslint --ext=ts .", "post:generate": "./scripts/post-gen/global.sh", "generate": "./scripts/multiplexer.sh ./scripts/generate.sh ${0:-all} ${1:-all} && yarn post:generate", + "playground:js:analytics": "yarn workspace javascript-playground start:analytics", "playground:js:personalization": "yarn workspace javascript-playground start:personalization", "playground:js:recommend": "yarn workspace javascript-playground start:recommend", "playground:js:search": "yarn workspace javascript-playground start:search", diff --git a/playground/.env.example b/playground/.env.example index 88ab91239e..952f5d218a 100644 --- a/playground/.env.example +++ b/playground/.env.example @@ -1,6 +1,10 @@ ALGOLIA_APPLICATION_ID="" ALGOLIA_ADMIN_KEY="" ALGOLIA_SEARCH_KEY="" +ALGOLIA_RECOMMENDATION_KEY="" +ALGOLIA_ANALYTICS_KEY="" SEARCH_INDEX="" SEARCH_QUERY="" + +ANALYTICS_INDEX="" diff --git a/playground/javascript/analytics.ts b/playground/javascript/analytics.ts new file mode 100644 index 0000000000..633aab5b92 --- /dev/null +++ b/playground/javascript/analytics.ts @@ -0,0 +1,29 @@ +import { AnalyticsApi, ApiError } from '@algolia/client-analytics'; +import dotenv from 'dotenv'; + +dotenv.config({ path: '../.env' }); + +const appId = process.env.ALGOLIA_APPLICATION_ID || '**** APP_ID *****'; +const apiKey = + process.env.ALGOLIA_ANALYTICS_KEY || '**** ANALYTICS_API_KEY *****'; + +const analyticsIndex = process.env.ANALYTICS_INDEX || 'test_index'; + +// Init client with appId and apiKey +const client = new AnalyticsApi(appId, apiKey, 'de'); + +async function testAnalytics() { + try { + const res = await client.getStatus(analyticsIndex); + + console.log(`[OK]`, res); + } catch (e) { + if (e instanceof ApiError) { + return console.log(`[${e.status}] ${e.message}`, e.stackTrace, e); + } + + console.log('[ERROR]', e); + } +} + +testAnalytics(); diff --git a/playground/javascript/package.json b/playground/javascript/package.json index 4d774abd34..9eae8bd127 100644 --- a/playground/javascript/package.json +++ b/playground/javascript/package.json @@ -3,14 +3,17 @@ "version": "0.0.0", "scripts": { "build": "tsc", + "start:analytics": "yarn install && yarn build && yarn test:analytics", "start:personalization": "yarn install && yarn build && yarn test:personalization", "start:recommend": "yarn install && yarn build && yarn test:recommend", "start:search": "yarn install && yarn build && yarn test:search", + "test:analytics": "node dist/analytics.js", "test:personalization": "node dist/personalization.js", "test:recommend": "node dist/recommend.js", "test:search": "node dist/search.js" }, "devDependencies": { + "@algolia/client-analytics": "5.0.0", "@algolia/client-personalization": "5.0.0", "@algolia/client-search": "5.0.0", "@algolia/recommend": "5.0.0", diff --git a/playground/javascript/search.ts b/playground/javascript/search.ts index 75686950cc..089b426e8b 100644 --- a/playground/javascript/search.ts +++ b/playground/javascript/search.ts @@ -14,7 +14,7 @@ const client = new SearchApi(appId, apiKey); async function testSearch() { try { - const res = await client.search(searchIndex, {}); + const res = await client.search(searchIndex, { query: searchQuery }); console.log(`[OK]`, res); } catch (e) { diff --git a/specs/analytics/paths/click/getAverageClickPosition.yml b/specs/analytics/paths/click/getAverageClickPosition.yml new file mode 100644 index 0000000000..7023b42acb --- /dev/null +++ b/specs/analytics/paths/click/getAverageClickPosition.yml @@ -0,0 +1,57 @@ +get: + tags: + - analytics + operationId: getAverageClickPosition + description: | + Returns the average click position. The endpoint returns a value for the complete given time range, as well as a value per day. + + An average of null means Algolia didn't receive any click events for the queries with the clickAnalytics search parameter set to true. The average is null until Algolia receives at least one click event. + summary: Returns the average click position. + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + title: getAverageClickPositionResponse + type: object + additionalProperties: false + required: + - average + - clickCount + - dates + properties: + average: + $ref: '../common/parameters.yml#/average' + clickCount: + $ref: '../common/parameters.yml#/clickCount' + dates: + type: array + description: A list of click events with their date. + items: + type: object + additionalProperties: false + required: + - average + - clickCount + - date + properties: + average: + $ref: '../common/parameters.yml#/average' + clickCount: + $ref: '../common/parameters.yml#/clickCount' + date: + $ref: '../common/parameters.yml#/date' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/click/getAverageTopClickPosition.yml b/specs/analytics/paths/click/getAverageTopClickPosition.yml deleted file mode 100644 index 3ddb9d7f54..0000000000 --- a/specs/analytics/paths/click/getAverageTopClickPosition.yml +++ /dev/null @@ -1 +0,0 @@ -get: diff --git a/specs/analytics/paths/click/getClickPositions.yml b/specs/analytics/paths/click/getClickPositions.yml index 3ddb9d7f54..f05ed824cd 100644 --- a/specs/analytics/paths/click/getClickPositions.yml +++ b/specs/analytics/paths/click/getClickPositions.yml @@ -1 +1,54 @@ get: + tags: + - analytics + operationId: getClickPositions + description: | + Returns the distribution of clicks per range of positions. + + If the groups all have a count of 0, it means Algolia didn't receive any click events for the queries with the clickAnalytics search parameter set to true. The count is 0 until Algolia receives at least one click event. + summary: Returns the distribution of clicks per range of positions. + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + title: getClickPositionsResponse + type: object + additionalProperties: false + required: + - positions + properties: + positions: + type: array + description: A list of the positions with their click count. + items: + type: object + additionalProperties: false + properties: + position: + description: | + Range of positions with the following pattern: + + Positions from 1 to 10 included are displayed in separated groups. + Positions from 11 to 20 included are grouped together. + Positions from 21 and up are grouped together. + type: array + items: + type: number + format: integer + clickCount: + $ref: '../common/parameters.yml#/clickCount' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/click/getClickThroughRate.yml b/specs/analytics/paths/click/getClickThroughRate.yml index 3ddb9d7f54..63e6dc4c5c 100644 --- a/specs/analytics/paths/click/getClickThroughRate.yml +++ b/specs/analytics/paths/click/getClickThroughRate.yml @@ -1 +1,66 @@ get: + tags: + - analytics + operationId: getClickThroughRate + description: | + Returns a click-through rate (CTR). The endpoint returns a value for the complete given time range, as well as a value per day. It also returns the count of clicks and searches used to compute the rates. + + Tracked searches are searches for which the engine returned a queryID, so searches where you've set the clickAnalytics search parameter to true. This is different than the “count” attribute of the response, which includes tracked searches and searches where you didn't enable the clickAnalytics search parameter. + + If the CTR is null, it means that Algolia didn't receive any queries with the clickAnalytics search parameter set to true. + If the CTR is 0, it means Algolia didn't receive any click events for the queries with the clickAnalytics search parameter set to true. + summary: Returns a click-through rate (CTR). + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + title: getClickThroughRateResponse + type: object + additionalProperties: false + required: + - dates + - clickCount + - trackedSearchCount + - rate + properties: + rate: + $ref: '../common/parameters.yml#/rate' + clickCount: + $ref: '../common/parameters.yml#/clickCount' + trackedSearchCount: + $ref: '../common/parameters.yml#/trackedSearchCount' + dates: + type: array + description: A list of click-through rate events with their date. + items: + type: object + additionalProperties: false + required: + - rate + - clickCount + - trackedSearchCount + - date + properties: + rate: + $ref: '../common/parameters.yml#/rate' + clickCount: + $ref: '../common/parameters.yml#/clickCount' + trackedSearchCount: + $ref: '../common/parameters.yml#/trackedSearchCount' + date: + $ref: '../common/parameters.yml#/date' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/click/getConversionRate.yml b/specs/analytics/paths/click/getConversionRate.yml index 3ddb9d7f54..b3331d9ad6 100644 --- a/specs/analytics/paths/click/getConversionRate.yml +++ b/specs/analytics/paths/click/getConversionRate.yml @@ -1 +1,66 @@ get: + tags: + - analytics + operationId: getConversationRate + description: | + Returns a conversion rate (CR). The endpoint returns a value for the complete given time range, as well as a value per day. It also returns the count of conversion and searches used to compute the rates. + + Tracked searches are searches for which the engine returned a queryID, so searches where you've set the clickAnalytics search parameter to true. This is different than the “count” attribute of the response, which includes tracked searches and searches where you didn't enable the clickAnalytics search parameter. + + If the CR is null, it means that Algolia didn't receive any queries with the clickAnalytics search parameter set to true. + If the CR is 0, it means Algolia didn't receive any conversion events for the queries with the clickAnalytics search parameter set to true. + summary: Returns a conversion rate (CR). + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + title: getConversationRateResponse + type: object + additionalProperties: false + required: + - dates + - trackedSearchCount + - conversionCount + - rate + properties: + rate: + $ref: '../common/parameters.yml#/rate' + trackedSearchCount: + $ref: '../common/parameters.yml#/trackedSearchCount' + conversionCount: + $ref: '../common/parameters.yml#/conversionCount' + dates: + type: array + description: A list of click-through rate events with their date. + items: + type: object + additionalProperties: false + required: + - rate + - trackedSearchCount + - conversionCount + - date + properties: + rate: + $ref: '../common/parameters.yml#/rate' + trackedSearchCount: + $ref: '../common/parameters.yml#/trackedSearchCount' + conversionCount: + $ref: '../common/parameters.yml#/conversionCount' + date: + $ref: '../common/parameters.yml#/date' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/common/parameters.yml b/specs/analytics/paths/common/parameters.yml new file mode 100644 index 0000000000..710e01ad4a --- /dev/null +++ b/specs/analytics/paths/common/parameters.yml @@ -0,0 +1,42 @@ +# query +Tags: + name: tags + in: query + description: | + Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + schema: + type: string + +# misc +average: + type: number + format: double + description: The average of all the click count event. + +clickCount: + type: number + format: integer + description: The number of click event. + +date: + type: string + format: date-time + description: Date of the event. + +rate: + type: number + format: double + description: The click-through rate. + +trackedSearchCount: + type: number + format: integer + description: The number of tracked search click. + +conversionCount: + type: number + format: integer + description: The number of converted clicks. + +updatedAt: + $ref: '../../../common/parameters.yml#/updatedAt' diff --git a/specs/analytics/paths/status/getStatus.yml b/specs/analytics/paths/status/getStatus.yml index 3ddb9d7f54..e14b9b34cf 100644 --- a/specs/analytics/paths/status/getStatus.yml +++ b/specs/analytics/paths/status/getStatus.yml @@ -1 +1,30 @@ get: + tags: + - analytics + operationId: getStatus + description: Returns the latest update time of the analytics API for a given index. If the index has been recently created and/or no search has been performed yet the updated time will be null. + summary: Get latest update time of the analytics API. + parameters: + - $ref: '../../../common/parameters.yml#/Index' + responses: + '200': + description: OK + content: + application/json: + schema: + title: getStatusResponse + type: object + additionalProperties: false + required: + - updatedAt + properties: + updatedAt: + $ref: '../common/parameters.yml#/updatedAt' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/spec.yml b/specs/analytics/spec.yml index fb71e428c5..498b4b4a63 100644 --- a/specs/analytics/spec.yml +++ b/specs/analytics/spec.yml @@ -46,14 +46,14 @@ paths: # ################################# # ### Click Analytics Endpoints ### # ################################# - # /2/clicks/averageClickPosition: - # $ref: './paths/click/getAverageTopClickPosition.yml' - # /2/clicks/positions: - # $ref: './paths/click/getClickPositions.yml' - # /2/clicks/clickThroughRate: - # $ref: './paths/click/getClickThroughRate.yml' - # /2/conversions/conversionRate: - # $ref: './paths/click/getConversionRate.yml' + /2/clicks/averageClickPosition: + $ref: './paths/click/getAverageClickPosition.yml' + /2/clicks/positions: + $ref: './paths/click/getClickPositions.yml' + /2/clicks/clickThroughRate: + $ref: './paths/click/getClickThroughRate.yml' + /2/conversions/conversionRate: + $ref: './paths/click/getConversionRate.yml' # ######################## # ### Status Endpoints ### diff --git a/specs/common/parameters.yml b/specs/common/parameters.yml index ac0faf7da6..8ec2d45f81 100644 --- a/specs/common/parameters.yml +++ b/specs/common/parameters.yml @@ -9,6 +9,30 @@ IndexName: example: 'myIndexName' # query +Index: + in: query + name: index + description: The index name to target. + required: true + schema: + type: string + +StartDate: + in: query + name: startDate + description: The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + schema: + type: string + format: date-time + +EndDate: + in: query + name: endDate + description: The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze + schema: + type: string + format: date-time + ForwardToReplicas: in: query name: forwardToReplicas diff --git a/templates/javascript/api-single.mustache b/templates/javascript/api-single.mustache index 05cf6a95e1..7e7df6b894 100644 --- a/templates/javascript/api-single.mustache +++ b/templates/javascript/api-single.mustache @@ -51,8 +51,15 @@ export class {{classname}} { constructor( appId: string, - apiKey: string,{{#isPersonalizationHost}} - region?: string, {{/isPersonalizationHost}} + apiKey: string, + {{#hasRegionalHost}} + {{#isPersonalizationHost}} + region?: string, + {{/isPersonalizationHost}} + {{#isAnalyticsHost}} + region: 'de' | 'us', + {{/isAnalyticsHost}} + {{/hasRegionalHost}} options?: {requester?: Requester, hosts?: Host[]} ) { this.setApiKey({{classname}}Keys.appId, appId); @@ -60,8 +67,8 @@ export class {{classname}} { this.transporter = new Transporter({ hosts: options?.hosts ?? this.getDefaultHosts( - {{^isPersonalizationHost}}appId{{/isPersonalizationHost}} - {{#isPersonalizationHost}}region{{/isPersonalizationHost}} + {{^hasRegionalHost}}appId{{/hasRegionalHost}} + {{#hasRegionalHost}}region{{/hasRegionalHost}} ), baseHeaders: { 'content-type': 'application/x-www-form-urlencoded' @@ -76,7 +83,7 @@ export class {{classname}} { }); } - {{^isPersonalizationHost}} + {{#isSearchHost}} public getDefaultHosts(appId: string): Host[] { return ( [ @@ -91,7 +98,7 @@ export class {{classname}} { ]) ); } - {{/isPersonalizationHost}} + {{/isSearchHost}} {{#isPersonalizationHost}} public getDefaultHosts(region: string = 'us'): Host[] { @@ -99,6 +106,12 @@ export class {{classname}} { } {{/isPersonalizationHost}} + {{#isAnalyticsHost}} + public getDefaultHosts(region: 'de' | 'us'): Host[] { + return [{ url: `analytics.${region}.algolia.com`, accept: 'readWrite', protocol: 'https' }]; + } + {{/isAnalyticsHost}} + public setRequest(requester: Requester): void { this.transporter.setRequester(requester); } diff --git a/yarn.lock b/yarn.lock index e14bbac32d..4529934394 100644 --- a/yarn.lock +++ b/yarn.lock @@ -29,6 +29,15 @@ __metadata: languageName: unknown linkType: soft +"@algolia/client-analytics@5.0.0, @algolia/client-analytics@workspace:clients/algoliasearch-client-javascript/client-analytics": + version: 0.0.0-use.local + resolution: "@algolia/client-analytics@workspace:clients/algoliasearch-client-javascript/client-analytics" + dependencies: + "@types/node": 16.11.11 + typescript: 4.5.2 + languageName: unknown + linkType: soft + "@algolia/client-personalization@5.0.0, @algolia/client-personalization@workspace:clients/algoliasearch-client-javascript/client-personalization": version: 0.0.0-use.local resolution: "@algolia/client-personalization@workspace:clients/algoliasearch-client-javascript/client-personalization" @@ -3640,6 +3649,7 @@ fsevents@^2.3.2: version: 0.0.0-use.local resolution: "javascript-playground@workspace:playground/javascript" dependencies: + "@algolia/client-analytics": 5.0.0 "@algolia/client-personalization": 5.0.0 "@algolia/client-search": 5.0.0 "@algolia/recommend": 5.0.0 From 2219e83a7245b86ff0e492f20c6a4abb9117e603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Mon, 13 Dec 2021 18:56:45 +0100 Subject: [PATCH 2/9] feat: some more endpoints --- .eslintrc.js | 1 + .../model/getAttributeTopFiltersResponse.ts | 8 + .../getAttributeTopFiltersResponseValues.ts | 18 ++ .../model/getNoClickRateResponse.ts | 20 ++ .../model/getNoClickRateResponseDates.ts | 18 ++ .../model/getNoResultTopFiltersResponse.ts | 8 + .../getNoResultTopFiltersResponseValues.ts | 14 + .../getNoResultTopFiltersResponseValues1.ts | 9 + .../model/getNoResultsRateResponse.ts | 8 + .../model/getNoResultsRateResponseSearches.ts | 14 + .../client-analytics/model/models.ts | 9 + .../client-analytics/src/analyticsApi.ts | 276 ++++++++++++++++++ .../paths/click/getClickPositions.yml | 3 +- specs/analytics/paths/common/parameters.yml | 56 +++- .../paths/search/getAttributeTopFilters.yml | 54 ++++ .../analytics/paths/search/getNoClickRate.yml | 59 ++++ .../paths/search/getNoResultTopFilters.yml | 62 ++++ .../paths/search/getNoResultsRate.yml | 52 ++++ specs/analytics/spec.yml | 30 +- 19 files changed, 694 insertions(+), 25 deletions(-) create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getAttributeTopFiltersResponse.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getAttributeTopFiltersResponseValues.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getNoClickRateResponse.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getNoClickRateResponseDates.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponse.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponseValues.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponseValues1.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getNoResultsRateResponse.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getNoResultsRateResponseSearches.ts diff --git a/.eslintrc.js b/.eslintrc.js index 9de5e25dd2..3642706073 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -36,6 +36,7 @@ module.exports = { 'no-redeclare': 0, '@typescript-eslint/no-redeclare': 0, + 'max-params': ['error', 7], '@typescript-eslint/no-unused-vars': 2, 'unused-imports/no-unused-imports-ts': 2, '@typescript-eslint/member-ordering': [ diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getAttributeTopFiltersResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getAttributeTopFiltersResponse.ts new file mode 100644 index 0000000000..9fcee89fa1 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getAttributeTopFiltersResponse.ts @@ -0,0 +1,8 @@ +import type { GetAttributeTopFiltersResponseValues } from './getAttributeTopFiltersResponseValues'; + +export type GetAttributeTopFiltersResponse = { + /** + * A list of filters for an attributes. + */ + values: GetAttributeTopFiltersResponseValues[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getAttributeTopFiltersResponseValues.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getAttributeTopFiltersResponseValues.ts new file mode 100644 index 0000000000..d717423333 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getAttributeTopFiltersResponseValues.ts @@ -0,0 +1,18 @@ +export type GetAttributeTopFiltersResponseValues = { + /** + * The attribute. + */ + attribute: string; + /** + * The operator. + */ + operator: string; + /** + * The value of the attribute. + */ + value: string; + /** + * The number of events for the attribute. + */ + count: number; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getNoClickRateResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getNoClickRateResponse.ts new file mode 100644 index 0000000000..0d2881331a --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getNoClickRateResponse.ts @@ -0,0 +1,20 @@ +import type { GetNoClickRateResponseDates } from './getNoClickRateResponseDates'; + +export type GetNoClickRateResponse = { + /** + * The click-through rate. + */ + rate: number; + /** + * The number of click event. + */ + count: number; + /** + * The number of click event. + */ + noClickCount: number; + /** + * A list of click-through rate events with their date. + */ + dates: GetNoClickRateResponseDates[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getNoClickRateResponseDates.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getNoClickRateResponseDates.ts new file mode 100644 index 0000000000..df727c85e7 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getNoClickRateResponseDates.ts @@ -0,0 +1,18 @@ +export type GetNoClickRateResponseDates = { + /** + * The click-through rate. + */ + rate: number; + /** + * The number of click event. + */ + count: number; + /** + * The number of click event. + */ + noClickCount: number; + /** + * Date of the event. + */ + date: Date; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponse.ts new file mode 100644 index 0000000000..a8108f8c77 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponse.ts @@ -0,0 +1,8 @@ +import type { GetNoResultTopFiltersResponseValues1 } from './getNoResultTopFiltersResponseValues1'; + +export type GetNoResultTopFiltersResponse = { + /** + * A list of filters without results. + */ + values: GetNoResultTopFiltersResponseValues1[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponseValues.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponseValues.ts new file mode 100644 index 0000000000..40a5425585 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponseValues.ts @@ -0,0 +1,14 @@ +export type GetNoResultTopFiltersResponseValues = { + /** + * The attribute. + */ + attribute: string; + /** + * The operator. + */ + operator: string; + /** + * The value of the attribute. + */ + value: string; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponseValues1.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponseValues1.ts new file mode 100644 index 0000000000..2335bfe403 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponseValues1.ts @@ -0,0 +1,9 @@ +import type { GetNoResultTopFiltersResponseValues } from './getNoResultTopFiltersResponseValues'; + +export type GetNoResultTopFiltersResponseValues1 = { + /** + * The number of occurrences. + */ + count: number; + values: GetNoResultTopFiltersResponseValues[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultsRateResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultsRateResponse.ts new file mode 100644 index 0000000000..481085a0e5 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultsRateResponse.ts @@ -0,0 +1,8 @@ +import type { GetNoResultsRateResponseSearches } from './getNoResultsRateResponseSearches'; + +export type GetNoResultsRateResponse = { + /** + * A list of top searches with their count. + */ + searches: GetNoResultsRateResponseSearches[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultsRateResponseSearches.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultsRateResponseSearches.ts new file mode 100644 index 0000000000..153a7dd2a0 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultsRateResponseSearches.ts @@ -0,0 +1,14 @@ +export type GetNoResultsRateResponseSearches = { + /** + * The search query. + */ + search: string; + /** + * The number of occurrences. + */ + count: number; + /** + * The number of occurrences with filter. + */ + withFilterCount: number; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/models.ts b/clients/algoliasearch-client-javascript/client-analytics/model/models.ts index 10109659f4..13706088df 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/models.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/models.ts @@ -2,6 +2,8 @@ import type { RequestOptions } from '../utils/types'; export * from './errorBase'; +export * from './getAttributeTopFiltersResponse'; +export * from './getAttributeTopFiltersResponseValues'; export * from './getAverageClickPositionResponse'; export * from './getAverageClickPositionResponseDates'; export * from './getClickPositionsResponse'; @@ -10,6 +12,13 @@ export * from './getClickThroughRateResponse'; export * from './getClickThroughRateResponseDates'; export * from './getConversationRateResponse'; export * from './getConversationRateResponseDates'; +export * from './getNoClickRateResponse'; +export * from './getNoClickRateResponseDates'; +export * from './getNoResultTopFiltersResponse'; +export * from './getNoResultTopFiltersResponseValues'; +export * from './getNoResultTopFiltersResponseValues1'; +export * from './getNoResultsRateResponse'; +export * from './getNoResultsRateResponseSearches'; export * from './getStatusResponse'; export interface Authentication { diff --git a/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts b/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts index 4b324e036c..e5e343abdc 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts @@ -1,7 +1,11 @@ +import type { GetAttributeTopFiltersResponse } from '../model/getAttributeTopFiltersResponse'; import type { GetAverageClickPositionResponse } from '../model/getAverageClickPositionResponse'; import type { GetClickPositionsResponse } from '../model/getClickPositionsResponse'; import type { GetClickThroughRateResponse } from '../model/getClickThroughRateResponse'; import type { GetConversationRateResponse } from '../model/getConversationRateResponse'; +import type { GetNoClickRateResponse } from '../model/getNoClickRateResponse'; +import type { GetNoResultTopFiltersResponse } from '../model/getNoResultTopFiltersResponse'; +import type { GetNoResultsRateResponse } from '../model/getNoResultsRateResponse'; import type { GetStatusResponse } from '../model/getStatusResponse'; import { ApiKeyAuth } from '../model/models'; import { Transporter } from '../utils/Transporter'; @@ -82,6 +86,83 @@ export class AnalyticsApi { this.authentications[AnalyticsApiKeys[key]].apiKey = value; } + /** + * Returns top filters for the given attribute. Limited to the 1000 most used filters. + * + * @summary Returns top filters for the given attribute. + * @param attribute - The exact name of the attribute. + * @param index - The index name to target. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param limit - How many items to fetch. + * @param offset - From which position to start retrieving results. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + */ + getAttributeTopFilters( + attribute: string, + index: string, + startDate?: Date, + endDate?: Date, + limit?: number, + offset?: number, + tags?: string + ): Promise { + const path = '/2/filters'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (attribute === null || attribute === undefined) { + throw new Error( + 'Required parameter attribute was null or undefined when calling getAttributeTopFilters.' + ); + } + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getAttributeTopFilters.' + ); + } + + if (attribute !== undefined) { + queryParameters.attribute = attribute.toString(); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (limit !== undefined) { + queryParameters.limit = limit.toString(); + } + + if (offset !== undefined) { + queryParameters.offset = offset.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } /** * Returns the average click position. The endpoint returns a value for the complete given time range, as well as a value per day. An average of null means Algolia didn\'t receive any click events for the queries with the clickAnalytics search parameter set to true. The average is null until Algolia receives at least one click event. * @@ -294,6 +375,201 @@ export class AnalyticsApi { return this.sendRequest(request, requestOptions); } + /** + * Returns the rate at which searches didn\'t lead to any clicks. The endpoint returns a value for the complete given time range, as well as a value per day. It also returns the count of searches and searches without clicks. + * + * @summary Returns the rate at which searches didn\'t lead to any clicks. + * @param index - The index name to target. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + */ + getNoClickRate( + index: string, + startDate?: Date, + endDate?: Date, + tags?: string + ): Promise { + const path = '/2/searches/noClickRate'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getNoClickRate.' + ); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } + /** + * Returns top filters for the given no result search. Limited to the 1000 most used filters. + * + * @summary Returns top filters for the given no result search. + * @param index - The index name to target. + * @param search - The query term. Must match the exact user input. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param limit - How many items to fetch. + * @param offset - From which position to start retrieving results. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + */ + getNoResultTopFilters( + index: string, + search: string, + startDate?: Date, + endDate?: Date, + limit?: number, + offset?: number, + tags?: string + ): Promise { + const path = '/2/filters/noResults'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getNoResultTopFilters.' + ); + } + + if (search === null || search === undefined) { + throw new Error( + 'Required parameter search was null or undefined when calling getNoResultTopFilters.' + ); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + if (search !== undefined) { + queryParameters.search = search.toString(); + } + + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (limit !== undefined) { + queryParameters.limit = limit.toString(); + } + + if (offset !== undefined) { + queryParameters.offset = offset.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } + /** + * Returns top searches that didn\'t return any results. Limited to the 1000 most frequent ones. + * + * @summary Returns top searches that didn\'t return any results. + * @param index - The index name to target. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param limit - How many items to fetch. + * @param offset - From which position to start retrieving results. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + */ + getNoResultsRate( + index: string, + startDate?: Date, + endDate?: Date, + limit?: number, + offset?: number, + tags?: string + ): Promise { + const path = '/2/searches/noResultRate'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getNoResultsRate.' + ); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (limit !== undefined) { + queryParameters.limit = limit.toString(); + } + + if (offset !== undefined) { + queryParameters.offset = offset.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } /** * Returns the latest update time of the analytics API for a given index. If the index has been recently created and/or no search has been performed yet the updated time will be null. * diff --git a/specs/analytics/paths/click/getClickPositions.yml b/specs/analytics/paths/click/getClickPositions.yml index f05ed824cd..518011771f 100644 --- a/specs/analytics/paths/click/getClickPositions.yml +++ b/specs/analytics/paths/click/getClickPositions.yml @@ -40,8 +40,7 @@ get: Positions from 21 and up are grouped together. type: array items: - type: number - format: integer + type: integer clickCount: $ref: '../common/parameters.yml#/clickCount' '400': diff --git a/specs/analytics/paths/common/parameters.yml b/specs/analytics/paths/common/parameters.yml index 710e01ad4a..4e0c3049d4 100644 --- a/specs/analytics/paths/common/parameters.yml +++ b/specs/analytics/paths/common/parameters.yml @@ -1,9 +1,40 @@ # query +Attribute: + in: query + name: attribute + description: The exact name of the attribute. + required: true + schema: + type: string + +Limit: + in: query + name: limit + description: How many items to fetch. + schema: + type: integer + default: 10 + +Search: + in: query + name: search + description: The query term. Must match the exact user input. + required: true + schema: + type: string + +Offset: + in: query + name: offset + description: From which position to start retrieving results. + schema: + type: integer + default: 0 + Tags: name: tags in: query - description: | - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + description: Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. schema: type: string @@ -14,8 +45,7 @@ average: description: The average of all the click count event. clickCount: - type: number - format: integer + type: integer description: The number of click event. date: @@ -29,14 +59,24 @@ rate: description: The click-through rate. trackedSearchCount: - type: number - format: integer + type: integer description: The number of tracked search click. conversionCount: - type: number - format: integer + type: integer description: The number of converted clicks. updatedAt: $ref: '../../../common/parameters.yml#/updatedAt' + +attribute: + description: The attribute. + type: string + +operator: + description: The operator. + type: string + +value: + description: The value of the attribute. + type: string diff --git a/specs/analytics/paths/search/getAttributeTopFilters.yml b/specs/analytics/paths/search/getAttributeTopFilters.yml index 3ddb9d7f54..005f99cc52 100644 --- a/specs/analytics/paths/search/getAttributeTopFilters.yml +++ b/specs/analytics/paths/search/getAttributeTopFilters.yml @@ -1 +1,55 @@ get: + tags: + - analytics + operationId: getAttributeTopFilters + description: Returns top filters for the given attribute. Limited to the 1000 most used filters. + summary: Returns top filters for the given attribute. + parameters: + - $ref: '../common/parameters.yml#/Attribute' + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Limit' + - $ref: '../common/parameters.yml#/Offset' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + title: getAttributeTopFiltersResponse + type: object + additionalProperties: false + required: + - values + properties: + values: + type: array + description: A list of filters for an attributes. + items: + type: object + additionalProperties: false + required: + - operator + - attribute + - value + - count + properties: + attribute: + $ref: '../common/parameters.yml#/attribute' + operator: + $ref: '../common/parameters.yml#/operator' + value: + $ref: '../common/parameters.yml#/value' + count: + description: The number of events for the attribute. + type: integer + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/search/getNoClickRate.yml b/specs/analytics/paths/search/getNoClickRate.yml index 3ddb9d7f54..3972db1501 100644 --- a/specs/analytics/paths/search/getNoClickRate.yml +++ b/specs/analytics/paths/search/getNoClickRate.yml @@ -1 +1,60 @@ get: + tags: + - analytics + operationId: getNoClickRate + description: Returns the rate at which searches didn't lead to any clicks. The endpoint returns a value for the complete given time range, as well as a value per day. It also returns the count of searches and searches without clicks. + summary: Returns the rate at which searches didn't lead to any clicks. + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + title: getNoClickRateResponse + type: object + additionalProperties: false + required: + - dates + - count + - noClickCount + - rate + properties: + rate: + $ref: '../common/parameters.yml#/rate' + count: + $ref: '../common/parameters.yml#/clickCount' + noClickCount: + $ref: '../common/parameters.yml#/clickCount' + dates: + type: array + description: A list of click-through rate events with their date. + items: + type: object + additionalProperties: false + required: + - rate + - count + - noClickCount + - date + properties: + rate: + $ref: '../common/parameters.yml#/rate' + count: + $ref: '../common/parameters.yml#/clickCount' + noClickCount: + $ref: '../common/parameters.yml#/clickCount' + date: + $ref: '../common/parameters.yml#/date' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/search/getNoResultTopFilters.yml b/specs/analytics/paths/search/getNoResultTopFilters.yml index 3ddb9d7f54..a036ab1edc 100644 --- a/specs/analytics/paths/search/getNoResultTopFilters.yml +++ b/specs/analytics/paths/search/getNoResultTopFilters.yml @@ -1 +1,63 @@ get: + tags: + - analytics + operationId: getNoResultTopFilters + description: Returns top filters for the given no result search. Limited to the 1000 most used filters. + summary: Returns top filters for the given no result search. + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../common/parameters.yml#/Search' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Limit' + - $ref: '../common/parameters.yml#/Offset' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + title: getNoResultTopFiltersResponse + type: object + additionalProperties: false + required: + - values + properties: + values: + type: array + description: A list of filters without results. + items: + type: object + additionalProperties: false + required: + - values + - count + properties: + count: + description: The number of occurrences. + type: integer + values: + type: array + items: + type: object + additionalProperties: false + required: + - attribute + - operator + - value + properties: + attribute: + $ref: '../common/parameters.yml#/attribute' + operator: + $ref: '../common/parameters.yml#/operator' + value: + $ref: '../common/parameters.yml#/value' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/search/getNoResultsRate.yml b/specs/analytics/paths/search/getNoResultsRate.yml index 3ddb9d7f54..9ae7f470f9 100644 --- a/specs/analytics/paths/search/getNoResultsRate.yml +++ b/specs/analytics/paths/search/getNoResultsRate.yml @@ -1 +1,53 @@ get: + tags: + - analytics + operationId: getNoResultsRate + description: Returns top searches that didn't return any results. Limited to the 1000 most frequent ones. + summary: Returns top searches that didn't return any results. + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Limit' + - $ref: '../common/parameters.yml#/Offset' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + title: getNoResultsRateResponse + type: object + additionalProperties: false + required: + - searches + properties: + searches: + type: array + description: A list of top searches with their count. + items: + type: object + additionalProperties: false + required: + - search + - count + - withFilterCount + properties: + search: + description: The search query. + type: string + count: + description: The number of occurrences. + type: integer + withFilterCount: + description: The number of occurrences with filter. + type: integer + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/spec.yml b/specs/analytics/spec.yml index 498b4b4a63..4ded0e711d 100644 --- a/specs/analytics/spec.yml +++ b/specs/analytics/spec.yml @@ -17,29 +17,29 @@ paths: # ### Search Analytics Endpoints ### # ################################## # /2/searches: - # $ref: './paths/search/getTopSearches.yml' + # $ref: './paths/search/getTopSearches.yml' # /2/searches/count: - # $ref: './paths/search/getSearchesCount.yml' + # $ref: './paths/search/getSearchesCount.yml' # /2/searches/noResults: - # $ref: './paths/search/getSearchesNoResults.yml' + # $ref: './paths/search/getSearchesNoResults.yml' # /2/searches/noClicks: - # $ref: './paths/search/getSearchesNoClicks.yml' - # /2/searches/noResultRate: - # $ref: './paths/search/getNoResultsRate.yml' - # /2/searches/noClickRate: - # $ref: './paths/search/getNoClickRate.yml' + # $ref: './paths/search/getSearchesNoClicks.yml' + /2/searches/noResultRate: + $ref: './paths/search/getNoResultsRate.yml' + /2/searches/noClickRate: + $ref: './paths/search/getNoClickRate.yml' # /2/hits: - # $ref: './paths/search/getTopHits.yml' + # $ref: './paths/search/getTopHits.yml' # /2/users/count: # $ref: './paths/search/getUsersCount.yml' # /2/filters: - # $ref: './paths/search/getTopFilterAttributes.yml' - # /2/filters/noResults?search=: - # $ref: './paths/search/getNoResultTopFilters.yml' + # $ref: './paths/search/getTopFilterAttributes.yml' + /2/filters/noResults: + $ref: './paths/search/getNoResultTopFilters.yml' # /2/filters/{attribute list}?search=: - # $ref: './paths/search/getSearchAttributesTopFilters.yml' - # /2/filters/{attribute}: - # $ref: './paths/search/getAttributeTopFilters.yml' + # $ref: './paths/search/getSearchAttributesTopFilters.yml' + /2/filters: + $ref: './paths/search/getAttributeTopFilters.yml' # /2/countries: # $ref: './paths/search/getTopCountries.yml' From 68438727e9c0ab25888921af8f450fcedf6ee5c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Tue, 14 Dec 2021 10:45:24 +0100 Subject: [PATCH 3/9] feat: even more endpoints --- .eslintrc.js | 2 +- .../model/getAttributeTopFiltersResponse.ts | 8 - .../model/getAverageClickPositionResponse.ts | 2 +- .../model/getClickPositionsResponse.ts | 2 +- .../model/getConversationRateResponse.ts | 2 +- .../model/getNoClickRateResponse.ts | 2 +- .../model/getNoResultTopFiltersResponse.ts | 8 - .../getNoResultTopFiltersResponseValues1.ts | 9 - .../model/getNoResultsRateResponse.ts | 18 +- .../model/getNoResultsRateResponseDates.ts | 18 + .../model/getSearchesCountResponse.ts | 12 + .../model/getSearchesCountResponseDates.ts | 10 + .../model/getSearchesNoClicksResponse.ts | 8 + ...=> getSearchesNoClicksResponseSearches.ts} | 4 +- .../model/getSearchesNoResultsResponse.ts | 8 + .../getSearchesNoResultsResponseSearches.ts | 14 + .../model/getTopCountriesResponse.ts | 8 + .../model/getTopCountriesResponseCountries.ts | 10 + .../model/getTopFilterAttributes.ts | 8 + .../model/getTopFilterAttributesAttributes.ts | 10 + .../model/getTopFilterForAttributeResponse.ts | 8 + ...getTopFilterForAttributeResponseValues.ts} | 4 +- .../model/getTopFiltersNoResults.ts | 8 + ...ues.ts => getTopFiltersNoResultsValues.ts} | 2 +- .../model/getTopFiltersNoResultsValues1.ts | 9 + .../model/getUsersCountResponse.ts | 12 + .../client-analytics/model/models.ts | 30 +- .../client-analytics/model/topHitsReponse.ts | 8 + .../model/topHitsReponseHits.ts | 10 + .../model/topHitsResponseWithAnalytics.ts | 8 + .../model/topHitsResponseWithAnalyticsHits.ts | 30 + .../model/topSearchesResponse.ts | 8 + .../model/topSearchesResponseWithAnalytics.ts | 8 + ...opSearchesResponseWithAnalyticsSearches.ts | 38 + .../client-analytics/src/analyticsApi.ts | 877 ++++++++++++++++-- .../paths/click/getAverageClickPosition.yml | 7 +- .../paths/click/getClickPositions.yml | 9 +- .../paths/click/getClickThroughRate.yml | 8 +- .../paths/click/getConversionRate.yml | 10 +- specs/analytics/paths/common/parameters.yml | 63 +- .../common/schemas/getTopFilterAttributes.yml | 20 + .../common/schemas/getTopFiltersNoResults.yml | 34 + .../paths/common/schemas/getTopHits.yml | 58 ++ .../paths/common/schemas/getTopSearches.yml | 67 ++ .../analytics/paths/search/getNoClickRate.yml | 2 +- .../paths/search/getNoResultTopFilters.yml | 63 -- .../paths/search/getNoResultsRate.yml | 41 +- .../search/getSearchAttributesTopFilters.yml | 62 ++ .../paths/search/getSearchesCount.yml | 47 + .../paths/search/getSearchesNoClicks.yml | 49 + .../paths/search/getSearchesNoResults.yml | 49 + .../paths/search/getTopCountries.yml | 47 + .../paths/search/getTopFilterAttributes.yml | 28 +- .../getTopFilterAttributesForSearch.yml | 29 + ...lters.yml => getTopFilterForAttribute.yml} | 9 +- .../paths/search/getTopFiltersNoResults.yml | 29 + .../getTopFiltersNoResultsForSearch.yml | 29 + specs/analytics/paths/search/getTopHits.yml | 31 +- .../paths/search/getTopHitsForSearch.yml | 32 + .../analytics/paths/search/getTopSearches.yml | 32 + .../analytics/paths/search/getUsersCount.yml | 47 + specs/analytics/spec.yml | 46 +- 62 files changed, 1922 insertions(+), 249 deletions(-) delete mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getAttributeTopFiltersResponse.ts delete mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponse.ts delete mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponseValues1.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getNoResultsRateResponseDates.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getSearchesCountResponse.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getSearchesCountResponseDates.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getSearchesNoClicksResponse.ts rename clients/algoliasearch-client-javascript/client-analytics/model/{getNoResultsRateResponseSearches.ts => getSearchesNoClicksResponseSearches.ts} (62%) create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getSearchesNoResultsResponse.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getSearchesNoResultsResponseSearches.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopCountriesResponse.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopCountriesResponseCountries.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributes.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributesAttributes.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterForAttributeResponse.ts rename clients/algoliasearch-client-javascript/client-analytics/model/{getAttributeTopFiltersResponseValues.ts => getTopFilterForAttributeResponseValues.ts} (66%) create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResults.ts rename clients/algoliasearch-client-javascript/client-analytics/model/{getNoResultTopFiltersResponseValues.ts => getTopFiltersNoResultsValues.ts} (76%) create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValues1.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getUsersCountResponse.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/topHitsReponse.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/topHitsReponseHits.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/topHitsResponseWithAnalytics.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/topHitsResponseWithAnalyticsHits.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponse.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponseWithAnalytics.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponseWithAnalyticsSearches.ts create mode 100644 specs/analytics/paths/common/schemas/getTopFilterAttributes.yml create mode 100644 specs/analytics/paths/common/schemas/getTopFiltersNoResults.yml create mode 100644 specs/analytics/paths/common/schemas/getTopHits.yml create mode 100644 specs/analytics/paths/common/schemas/getTopSearches.yml delete mode 100644 specs/analytics/paths/search/getNoResultTopFilters.yml create mode 100644 specs/analytics/paths/search/getTopFilterAttributesForSearch.yml rename specs/analytics/paths/search/{getAttributeTopFilters.yml => getTopFilterForAttribute.yml} (86%) create mode 100644 specs/analytics/paths/search/getTopFiltersNoResults.yml create mode 100644 specs/analytics/paths/search/getTopFiltersNoResultsForSearch.yml create mode 100644 specs/analytics/paths/search/getTopHitsForSearch.yml diff --git a/.eslintrc.js b/.eslintrc.js index 3642706073..9434aab522 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -36,7 +36,7 @@ module.exports = { 'no-redeclare': 0, '@typescript-eslint/no-redeclare': 0, - 'max-params': ['error', 7], + 'max-params': ['error', 9], '@typescript-eslint/no-unused-vars': 2, 'unused-imports/no-unused-imports-ts': 2, '@typescript-eslint/member-ordering': [ diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getAttributeTopFiltersResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getAttributeTopFiltersResponse.ts deleted file mode 100644 index 9fcee89fa1..0000000000 --- a/clients/algoliasearch-client-javascript/client-analytics/model/getAttributeTopFiltersResponse.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { GetAttributeTopFiltersResponseValues } from './getAttributeTopFiltersResponseValues'; - -export type GetAttributeTopFiltersResponse = { - /** - * A list of filters for an attributes. - */ - values: GetAttributeTopFiltersResponseValues[]; -}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getAverageClickPositionResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getAverageClickPositionResponse.ts index 85016cee6f..594148b405 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/getAverageClickPositionResponse.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getAverageClickPositionResponse.ts @@ -10,7 +10,7 @@ export type GetAverageClickPositionResponse = { */ clickCount: number; /** - * A list of click events with their date. + * A list of average click position with their date. */ dates: GetAverageClickPositionResponseDates[]; }; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getClickPositionsResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getClickPositionsResponse.ts index 4524b01f09..85ea2e7177 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/getClickPositionsResponse.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getClickPositionsResponse.ts @@ -2,7 +2,7 @@ import type { GetClickPositionsResponsePositions } from './getClickPositionsResp export type GetClickPositionsResponse = { /** - * A list of the positions with their click count. + * A list of the click positions with their click count. */ positions: GetClickPositionsResponsePositions[]; }; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getConversationRateResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getConversationRateResponse.ts index 256a0d7096..04ecd51de5 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/getConversationRateResponse.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getConversationRateResponse.ts @@ -14,7 +14,7 @@ export type GetConversationRateResponse = { */ conversionCount: number; /** - * A list of click-through rate events with their date. + * A list of conversion events with their date. */ dates: GetConversationRateResponseDates[]; }; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getNoClickRateResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getNoClickRateResponse.ts index 0d2881331a..e45f85d2f0 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/getNoClickRateResponse.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getNoClickRateResponse.ts @@ -14,7 +14,7 @@ export type GetNoClickRateResponse = { */ noClickCount: number; /** - * A list of click-through rate events with their date. + * A list of searches without clicks with their date, rate and counts. */ dates: GetNoClickRateResponseDates[]; }; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponse.ts deleted file mode 100644 index a8108f8c77..0000000000 --- a/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponse.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { GetNoResultTopFiltersResponseValues1 } from './getNoResultTopFiltersResponseValues1'; - -export type GetNoResultTopFiltersResponse = { - /** - * A list of filters without results. - */ - values: GetNoResultTopFiltersResponseValues1[]; -}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponseValues1.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponseValues1.ts deleted file mode 100644 index 2335bfe403..0000000000 --- a/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponseValues1.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { GetNoResultTopFiltersResponseValues } from './getNoResultTopFiltersResponseValues'; - -export type GetNoResultTopFiltersResponseValues1 = { - /** - * The number of occurrences. - */ - count: number; - values: GetNoResultTopFiltersResponseValues[]; -}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultsRateResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultsRateResponse.ts index 481085a0e5..bebc3527e7 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultsRateResponse.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultsRateResponse.ts @@ -1,8 +1,20 @@ -import type { GetNoResultsRateResponseSearches } from './getNoResultsRateResponseSearches'; +import type { GetNoResultsRateResponseDates } from './getNoResultsRateResponseDates'; export type GetNoResultsRateResponse = { /** - * A list of top searches with their count. + * The click-through rate. */ - searches: GetNoResultsRateResponseSearches[]; + rate: number; + /** + * The number of occurrences. + */ + count: number; + /** + * The number of occurrences. + */ + noResultCount: number; + /** + * A list of searches without results with their date, rate and counts. + */ + dates: GetNoResultsRateResponseDates[]; }; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultsRateResponseDates.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultsRateResponseDates.ts new file mode 100644 index 0000000000..63a4bfab3e --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultsRateResponseDates.ts @@ -0,0 +1,18 @@ +export type GetNoResultsRateResponseDates = { + /** + * Date of the event. + */ + date: Date; + /** + * The number of occurrences. + */ + noResultCount: number; + /** + * The number of occurrences. + */ + count: number; + /** + * The click-through rate. + */ + rate: number; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getSearchesCountResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getSearchesCountResponse.ts new file mode 100644 index 0000000000..4b67c49096 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getSearchesCountResponse.ts @@ -0,0 +1,12 @@ +import type { GetSearchesCountResponseDates } from './getSearchesCountResponseDates'; + +export type GetSearchesCountResponse = { + /** + * The number of occurrences. + */ + count: number; + /** + * A list of search events with their date and count. + */ + dates: GetSearchesCountResponseDates[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getSearchesCountResponseDates.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getSearchesCountResponseDates.ts new file mode 100644 index 0000000000..3be77438c1 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getSearchesCountResponseDates.ts @@ -0,0 +1,10 @@ +export type GetSearchesCountResponseDates = { + /** + * Date of the event. + */ + date: Date; + /** + * The number of occurrences. + */ + count: number; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getSearchesNoClicksResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getSearchesNoClicksResponse.ts new file mode 100644 index 0000000000..d4ab03d68d --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getSearchesNoClicksResponse.ts @@ -0,0 +1,8 @@ +import type { GetSearchesNoClicksResponseSearches } from './getSearchesNoClicksResponseSearches'; + +export type GetSearchesNoClicksResponse = { + /** + * A list of searches with no clicks and their count. + */ + searches: GetSearchesNoClicksResponseSearches[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultsRateResponseSearches.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getSearchesNoClicksResponseSearches.ts similarity index 62% rename from clients/algoliasearch-client-javascript/client-analytics/model/getNoResultsRateResponseSearches.ts rename to clients/algoliasearch-client-javascript/client-analytics/model/getSearchesNoClicksResponseSearches.ts index 153a7dd2a0..5fd59ec278 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultsRateResponseSearches.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getSearchesNoClicksResponseSearches.ts @@ -1,4 +1,4 @@ -export type GetNoResultsRateResponseSearches = { +export type GetSearchesNoClicksResponseSearches = { /** * The search query. */ @@ -8,7 +8,7 @@ export type GetNoResultsRateResponseSearches = { */ count: number; /** - * The number of occurrences with filter. + * The number of occurrences. */ withFilterCount: number; }; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getSearchesNoResultsResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getSearchesNoResultsResponse.ts new file mode 100644 index 0000000000..c44df94b77 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getSearchesNoResultsResponse.ts @@ -0,0 +1,8 @@ +import type { GetSearchesNoResultsResponseSearches } from './getSearchesNoResultsResponseSearches'; + +export type GetSearchesNoResultsResponse = { + /** + * A list of searches with no results and their count. + */ + searches: GetSearchesNoResultsResponseSearches[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getSearchesNoResultsResponseSearches.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getSearchesNoResultsResponseSearches.ts new file mode 100644 index 0000000000..592730c073 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getSearchesNoResultsResponseSearches.ts @@ -0,0 +1,14 @@ +export type GetSearchesNoResultsResponseSearches = { + /** + * The search query. + */ + search: string; + /** + * The number of occurrences. + */ + count: number; + /** + * Number of hits that the search query matched. + */ + nbHits: number; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopCountriesResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopCountriesResponse.ts new file mode 100644 index 0000000000..6093557d10 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopCountriesResponse.ts @@ -0,0 +1,8 @@ +import type { GetTopCountriesResponseCountries } from './getTopCountriesResponseCountries'; + +export type GetTopCountriesResponse = { + /** + * A list of countries with their count. + */ + countries: GetTopCountriesResponseCountries[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopCountriesResponseCountries.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopCountriesResponseCountries.ts new file mode 100644 index 0000000000..a5c121a487 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopCountriesResponseCountries.ts @@ -0,0 +1,10 @@ +export type GetTopCountriesResponseCountries = { + /** + * The country. + */ + country: string; + /** + * The number of occurrences. + */ + count: number; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributes.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributes.ts new file mode 100644 index 0000000000..13e53aae6b --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributes.ts @@ -0,0 +1,8 @@ +import type { GetTopFilterAttributesAttributes } from './getTopFilterAttributesAttributes'; + +export type GetTopFilterAttributes = { + /** + * A list of attributes with their count. + */ + attributes: GetTopFilterAttributesAttributes[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributesAttributes.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributesAttributes.ts new file mode 100644 index 0000000000..b9f8be5f11 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributesAttributes.ts @@ -0,0 +1,10 @@ +export type GetTopFilterAttributesAttributes = { + /** + * The attribute. + */ + attribute: string; + /** + * The number of occurrences. + */ + count: number; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterForAttributeResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterForAttributeResponse.ts new file mode 100644 index 0000000000..e85bb54c02 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterForAttributeResponse.ts @@ -0,0 +1,8 @@ +import type { GetTopFilterForAttributeResponseValues } from './getTopFilterForAttributeResponseValues'; + +export type GetTopFilterForAttributeResponse = { + /** + * A list of filters for the given attributes. + */ + values: GetTopFilterForAttributeResponseValues[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getAttributeTopFiltersResponseValues.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterForAttributeResponseValues.ts similarity index 66% rename from clients/algoliasearch-client-javascript/client-analytics/model/getAttributeTopFiltersResponseValues.ts rename to clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterForAttributeResponseValues.ts index d717423333..0933aa03e7 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/getAttributeTopFiltersResponseValues.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterForAttributeResponseValues.ts @@ -1,4 +1,4 @@ -export type GetAttributeTopFiltersResponseValues = { +export type GetTopFilterForAttributeResponseValues = { /** * The attribute. */ @@ -12,7 +12,7 @@ export type GetAttributeTopFiltersResponseValues = { */ value: string; /** - * The number of events for the attribute. + * The number of occurrences. */ count: number; }; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResults.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResults.ts new file mode 100644 index 0000000000..efad37959d --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResults.ts @@ -0,0 +1,8 @@ +import type { GetTopFiltersNoResultsValues1 } from './getTopFiltersNoResultsValues1'; + +export type GetTopFiltersNoResults = { + /** + * A list of filters without results. + */ + values: GetTopFiltersNoResultsValues1[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponseValues.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValues.ts similarity index 76% rename from clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponseValues.ts rename to clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValues.ts index 40a5425585..973427ec2e 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/getNoResultTopFiltersResponseValues.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValues.ts @@ -1,4 +1,4 @@ -export type GetNoResultTopFiltersResponseValues = { +export type GetTopFiltersNoResultsValues = { /** * The attribute. */ diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValues1.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValues1.ts new file mode 100644 index 0000000000..9e035b95a5 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValues1.ts @@ -0,0 +1,9 @@ +import type { GetTopFiltersNoResultsValues } from './getTopFiltersNoResultsValues'; + +export type GetTopFiltersNoResultsValues1 = { + /** + * The number of occurrences. + */ + count: number; + values: GetTopFiltersNoResultsValues[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getUsersCountResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getUsersCountResponse.ts new file mode 100644 index 0000000000..437bba9b00 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getUsersCountResponse.ts @@ -0,0 +1,12 @@ +import type { GetSearchesCountResponseDates } from './getSearchesCountResponseDates'; + +export type GetUsersCountResponse = { + /** + * The number of occurrences. + */ + count: number; + /** + * A list of users count with their date. + */ + dates: GetSearchesCountResponseDates[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/models.ts b/clients/algoliasearch-client-javascript/client-analytics/model/models.ts index 13706088df..15fc420665 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/models.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/models.ts @@ -2,8 +2,6 @@ import type { RequestOptions } from '../utils/types'; export * from './errorBase'; -export * from './getAttributeTopFiltersResponse'; -export * from './getAttributeTopFiltersResponseValues'; export * from './getAverageClickPositionResponse'; export * from './getAverageClickPositionResponseDates'; export * from './getClickPositionsResponse'; @@ -14,12 +12,32 @@ export * from './getConversationRateResponse'; export * from './getConversationRateResponseDates'; export * from './getNoClickRateResponse'; export * from './getNoClickRateResponseDates'; -export * from './getNoResultTopFiltersResponse'; -export * from './getNoResultTopFiltersResponseValues'; -export * from './getNoResultTopFiltersResponseValues1'; export * from './getNoResultsRateResponse'; -export * from './getNoResultsRateResponseSearches'; +export * from './getNoResultsRateResponseDates'; +export * from './getSearchesCountResponse'; +export * from './getSearchesCountResponseDates'; +export * from './getSearchesNoClicksResponse'; +export * from './getSearchesNoClicksResponseSearches'; +export * from './getSearchesNoResultsResponse'; +export * from './getSearchesNoResultsResponseSearches'; export * from './getStatusResponse'; +export * from './getTopCountriesResponse'; +export * from './getTopCountriesResponseCountries'; +export * from './getTopFilterAttributes'; +export * from './getTopFilterAttributesAttributes'; +export * from './getTopFilterForAttributeResponse'; +export * from './getTopFilterForAttributeResponseValues'; +export * from './getTopFiltersNoResults'; +export * from './getTopFiltersNoResultsValues'; +export * from './getTopFiltersNoResultsValues1'; +export * from './getUsersCountResponse'; +export * from './topHitsReponse'; +export * from './topHitsReponseHits'; +export * from './topHitsResponseWithAnalytics'; +export * from './topHitsResponseWithAnalyticsHits'; +export * from './topSearchesResponse'; +export * from './topSearchesResponseWithAnalytics'; +export * from './topSearchesResponseWithAnalyticsSearches'; export interface Authentication { /** diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/topHitsReponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/topHitsReponse.ts new file mode 100644 index 0000000000..4f441337cc --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/topHitsReponse.ts @@ -0,0 +1,8 @@ +import type { TopHitsReponseHits } from './topHitsReponseHits'; + +export type TopHitsReponse = { + /** + * A list of top hits with their count. + */ + hits: TopHitsReponseHits[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/topHitsReponseHits.ts b/clients/algoliasearch-client-javascript/client-analytics/model/topHitsReponseHits.ts new file mode 100644 index 0000000000..b7b376c1cc --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/topHitsReponseHits.ts @@ -0,0 +1,10 @@ +export type TopHitsReponseHits = { + /** + * The hit. + */ + hit: string; + /** + * The number of occurrences. + */ + count: number; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/topHitsResponseWithAnalytics.ts b/clients/algoliasearch-client-javascript/client-analytics/model/topHitsResponseWithAnalytics.ts new file mode 100644 index 0000000000..fb2b5d3db9 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/topHitsResponseWithAnalytics.ts @@ -0,0 +1,8 @@ +import type { TopHitsResponseWithAnalyticsHits } from './topHitsResponseWithAnalyticsHits'; + +export type TopHitsResponseWithAnalytics = { + /** + * A list of top hits with their count and analytics. + */ + hits: TopHitsResponseWithAnalyticsHits[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/topHitsResponseWithAnalyticsHits.ts b/clients/algoliasearch-client-javascript/client-analytics/model/topHitsResponseWithAnalyticsHits.ts new file mode 100644 index 0000000000..ce8afdbb2a --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/topHitsResponseWithAnalyticsHits.ts @@ -0,0 +1,30 @@ +export type TopHitsResponseWithAnalyticsHits = { + /** + * The hit. + */ + hit: string; + /** + * The number of occurrences. + */ + count: number; + /** + * The click-through rate. + */ + clickThroughRate: number; + /** + * The conversion rate. + */ + conversionRate: number; + /** + * The number of tracked search click. + */ + trackedSearchCount: number; + /** + * The number of click event. + */ + clickCount: number; + /** + * The number of converted clicks. + */ + conversionCount: number; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponse.ts new file mode 100644 index 0000000000..2dabac55c6 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponse.ts @@ -0,0 +1,8 @@ +import type { GetSearchesNoResultsResponseSearches } from './getSearchesNoResultsResponseSearches'; + +export type TopSearchesResponse = { + /** + * A list of top searches with their count. + */ + searches: GetSearchesNoResultsResponseSearches[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponseWithAnalytics.ts b/clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponseWithAnalytics.ts new file mode 100644 index 0000000000..1a58b7a9d8 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponseWithAnalytics.ts @@ -0,0 +1,8 @@ +import type { TopSearchesResponseWithAnalyticsSearches } from './topSearchesResponseWithAnalyticsSearches'; + +export type TopSearchesResponseWithAnalytics = { + /** + * A list of top searches with their count and analytics. + */ + searches: TopSearchesResponseWithAnalyticsSearches[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponseWithAnalyticsSearches.ts b/clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponseWithAnalyticsSearches.ts new file mode 100644 index 0000000000..af52de5a07 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponseWithAnalyticsSearches.ts @@ -0,0 +1,38 @@ +export type TopSearchesResponseWithAnalyticsSearches = { + /** + * The search query. + */ + search: string; + /** + * The number of occurrences. + */ + count: number; + /** + * The click-through rate. + */ + clickThroughRate: number; + /** + * The average position of all the click count event. + */ + averageClickPosition: number; + /** + * The conversion rate. + */ + conversionRate: number; + /** + * The number of tracked search click. + */ + trackedSearchCount: number; + /** + * The number of click event. + */ + clickCount: number; + /** + * The number of converted clicks. + */ + conversionCount: number; + /** + * Number of hits that the search query matched. + */ + nbHits: number; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts b/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts index e5e343abdc..b4afa3e6e2 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts @@ -1,13 +1,23 @@ -import type { GetAttributeTopFiltersResponse } from '../model/getAttributeTopFiltersResponse'; import type { GetAverageClickPositionResponse } from '../model/getAverageClickPositionResponse'; import type { GetClickPositionsResponse } from '../model/getClickPositionsResponse'; import type { GetClickThroughRateResponse } from '../model/getClickThroughRateResponse'; import type { GetConversationRateResponse } from '../model/getConversationRateResponse'; import type { GetNoClickRateResponse } from '../model/getNoClickRateResponse'; -import type { GetNoResultTopFiltersResponse } from '../model/getNoResultTopFiltersResponse'; import type { GetNoResultsRateResponse } from '../model/getNoResultsRateResponse'; +import type { GetSearchesCountResponse } from '../model/getSearchesCountResponse'; +import type { GetSearchesNoClicksResponse } from '../model/getSearchesNoClicksResponse'; +import type { GetSearchesNoResultsResponse } from '../model/getSearchesNoResultsResponse'; import type { GetStatusResponse } from '../model/getStatusResponse'; +import type { GetTopCountriesResponse } from '../model/getTopCountriesResponse'; +import type { GetTopFilterAttributes } from '../model/getTopFilterAttributes'; +import type { GetTopFilterForAttributeResponse } from '../model/getTopFilterForAttributeResponse'; +import type { GetTopFiltersNoResults } from '../model/getTopFiltersNoResults'; +import type { GetUsersCountResponse } from '../model/getUsersCountResponse'; import { ApiKeyAuth } from '../model/models'; +import type { TopHitsReponse } from '../model/topHitsReponse'; +import type { TopHitsResponseWithAnalytics } from '../model/topHitsResponseWithAnalytics'; +import type { TopSearchesResponse } from '../model/topSearchesResponse'; +import type { TopSearchesResponseWithAnalytics } from '../model/topSearchesResponseWithAnalytics'; import { Transporter } from '../utils/Transporter'; import type { Requester } from '../utils/requester/Requester'; import type { Headers, Host, Request, RequestOptions } from '../utils/types'; @@ -87,10 +97,543 @@ export class AnalyticsApi { } /** - * Returns top filters for the given attribute. Limited to the 1000 most used filters. + * Returns the average click position. The endpoint returns a value for the complete given time range, as well as a value per day. + * + * @summary Returns the average click position. + * @param index - The index name to target. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + */ + getAverageClickPosition( + index: string, + startDate?: Date, + endDate?: Date, + tags?: string + ): Promise { + const path = '/2/clicks/averageClickPosition'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getAverageClickPosition.' + ); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } + /** + * Returns the distribution of clicks per range of positions. + * + * @summary Returns the distribution of clicks per range of positions. + * @param index - The index name to target. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + */ + getClickPositions( + index: string, + startDate?: Date, + endDate?: Date, + tags?: string + ): Promise { + const path = '/2/clicks/positions'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getClickPositions.' + ); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } + /** + * Returns a click-through rate (CTR). The endpoint returns a value for the complete given time range, as well as a value per day. It also returns the count of clicks and searches used to compute the rates. + * + * @summary Returns a click-through rate (CTR). + * @param index - The index name to target. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + */ + getClickThroughRate( + index: string, + startDate?: Date, + endDate?: Date, + tags?: string + ): Promise { + const path = '/2/clicks/clickThroughRate'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getClickThroughRate.' + ); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } + /** + * Returns a conversion rate (CR). The endpoint returns a value for the complete given time range, as well as a value per day. It also returns the count of conversion and searches used to compute the rates. + * + * @summary Returns a conversion rate (CR). + * @param index - The index name to target. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + */ + getConversationRate( + index: string, + startDate?: Date, + endDate?: Date, + tags?: string + ): Promise { + const path = '/2/conversions/conversionRate'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getConversationRate.' + ); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } + /** + * Returns the rate at which searches didn\'t lead to any clicks. The endpoint returns a value for the complete given time range, as well as a value per day. It also returns the count of searches and searches without clicks. + * + * @summary Returns the rate at which searches didn\'t lead to any clicks. + * @param index - The index name to target. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + */ + getNoClickRate( + index: string, + startDate?: Date, + endDate?: Date, + tags?: string + ): Promise { + const path = '/2/searches/noClickRate'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getNoClickRate.' + ); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } + /** + * Returns the rate at which searches didn\'t return any results. The endpoint returns a value for the complete given time range, as well as a value per day. It also returns the count of searches and searches without results used to compute the rates. + * + * @summary Returns the rate at which searches didn\'t return any results. + * @param index - The index name to target. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + */ + getNoResultsRate( + index: string, + startDate?: Date, + endDate?: Date, + tags?: string + ): Promise { + const path = '/2/searches/noResultRate'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getNoResultsRate.' + ); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } + /** + * Returns the number of searches across the given time range. The endpoint returns a value for the complete given time range, as well as a value per day. + * + * @summary Returns the number of searches across the given time range. + * @param index - The index name to target. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + */ + getSearchesCount( + index: string, + startDate?: Date, + endDate?: Date, + tags?: string + ): Promise { + const path = '/2/searches/count'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getSearchesCount.' + ); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } + /** + * Returns top searches that didn\'t lead to any clicks. Limited to the 1000 most frequent ones. For each search, also returns the average number of found hits. + * + * @summary Returns top searches that didn\'t lead to any clicks. + * @param index - The index name to target. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param limit - How many items to fetch. + * @param offset - From which position to start retrieving results. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + */ + getSearchesNoClicks( + index: string, + startDate?: Date, + endDate?: Date, + limit?: number, + offset?: number, + tags?: string + ): Promise { + const path = '/2/searches/noClicks'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getSearchesNoClicks.' + ); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (limit !== undefined) { + queryParameters.limit = limit.toString(); + } + + if (offset !== undefined) { + queryParameters.offset = offset.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } + /** + * Returns top searches that didn\'t return any results. Limited to the 1000 most frequent ones. + * + * @summary Returns top searches that didn\'t return any results. + * @param index - The index name to target. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param limit - How many items to fetch. + * @param offset - From which position to start retrieving results. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + */ + getSearchesNoResults( + index: string, + startDate?: Date, + endDate?: Date, + limit?: number, + offset?: number, + tags?: string + ): Promise { + const path = '/2/searches/noResults'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getSearchesNoResults.' + ); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (limit !== undefined) { + queryParameters.limit = limit.toString(); + } + + if (offset !== undefined) { + queryParameters.offset = offset.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } + /** + * Returns the latest update time of the analytics API for a given index. If the index has been recently created and/or no search has been performed yet the updated time will be null. * - * @summary Returns top filters for the given attribute. - * @param attribute - The exact name of the attribute. + * @summary Get latest update time of the analytics API. + * @param index - The index name to target. + */ + getStatus(index: string): Promise { + const path = '/2/status'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getStatus.' + ); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } + /** + * Returns top countries. Limited to the 1000 most frequent ones. + * + * @summary Returns top countries. * @param index - The index name to target. * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. @@ -98,35 +641,89 @@ export class AnalyticsApi { * @param offset - From which position to start retrieving results. * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. */ - getAttributeTopFilters( - attribute: string, + getTopCountries( index: string, startDate?: Date, endDate?: Date, limit?: number, offset?: number, tags?: string - ): Promise { - const path = '/2/filters'; + ): Promise { + const path = '/2/countries'; const headers: Headers = { Accept: 'application/json' }; const queryParameters: Record = {}; - if (attribute === null || attribute === undefined) { + if (index === null || index === undefined) { throw new Error( - 'Required parameter attribute was null or undefined when calling getAttributeTopFilters.' + 'Required parameter index was null or undefined when calling getTopCountries.' ); } + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (limit !== undefined) { + queryParameters.limit = limit.toString(); + } + + if (offset !== undefined) { + queryParameters.offset = offset.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } + /** + * Returns top filter attributes. Limited to the 1000 most used filters. + * + * @summary Returns top filter attributes. + * @param index - The index name to target. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param limit - How many items to fetch. + * @param offset - From which position to start retrieving results. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + */ + getTopFilterAttributes( + index: string, + startDate?: Date, + endDate?: Date, + limit?: number, + offset?: number, + tags?: string + ): Promise { + const path = '/2/filters'; + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + if (index === null || index === undefined) { throw new Error( - 'Required parameter index was null or undefined when calling getAttributeTopFilters.' + 'Required parameter index was null or undefined when calling getTopFilterAttributes.' ); } - if (attribute !== undefined) { - queryParameters.attribute = attribute.toString(); - } - if (index !== undefined) { queryParameters.index = index.toString(); } @@ -164,27 +761,42 @@ export class AnalyticsApi { return this.sendRequest(request, requestOptions); } /** - * Returns the average click position. The endpoint returns a value for the complete given time range, as well as a value per day. An average of null means Algolia didn\'t receive any click events for the queries with the clickAnalytics search parameter set to true. The average is null until Algolia receives at least one click event. + * Returns top filter attributes for a given search. Limited to the 1000 most used filters. * - * @summary Returns the average click position. + * @summary Returns top filter attributes for a given search. * @param index - The index name to target. + * @param search - The query term. Must match the exact user input. * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param limit - How many items to fetch. + * @param offset - From which position to start retrieving results. * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. */ - getAverageClickPosition( + getTopFilterAttributes_1( index: string, + search: string, startDate?: Date, endDate?: Date, + limit?: number, + offset?: number, tags?: string - ): Promise { - const path = '/2/clicks/averageClickPosition'; + ): Promise { + const path = '/2/filters?search={search}'.replace( + '{search}', + encodeURIComponent(String(search)) + ); const headers: Headers = { Accept: 'application/json' }; const queryParameters: Record = {}; if (index === null || index === undefined) { throw new Error( - 'Required parameter index was null or undefined when calling getAverageClickPosition.' + 'Required parameter index was null or undefined when calling getTopFilterAttributes_1.' + ); + } + + if (search === null || search === undefined) { + throw new Error( + 'Required parameter search was null or undefined when calling getTopFilterAttributes_1.' ); } @@ -200,6 +812,14 @@ export class AnalyticsApi { queryParameters.endDate = endDate.toString(); } + if (limit !== undefined) { + queryParameters.limit = limit.toString(); + } + + if (offset !== undefined) { + queryParameters.offset = offset.toString(); + } + if (tags !== undefined) { queryParameters.tags = tags.toString(); } @@ -217,27 +837,42 @@ export class AnalyticsApi { return this.sendRequest(request, requestOptions); } /** - * Returns the distribution of clicks per range of positions. If the groups all have a count of 0, it means Algolia didn\'t receive any click events for the queries with the clickAnalytics search parameter set to true. The count is 0 until Algolia receives at least one click event. + * Returns top filters for the given attribute. Limited to the 1000 most used filters. * - * @summary Returns the distribution of clicks per range of positions. + * @summary Returns top filters for the given attribute. + * @param attribute - The exact name of the attribute. * @param index - The index name to target. * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param limit - How many items to fetch. + * @param offset - From which position to start retrieving results. * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. */ - getClickPositions( + getTopFilterForAttribute( + attribute: string, index: string, startDate?: Date, endDate?: Date, + limit?: number, + offset?: number, tags?: string - ): Promise { - const path = '/2/clicks/positions'; + ): Promise { + const path = '/2/filters/{attribute}'.replace( + '{attribute}', + encodeURIComponent(String(attribute)) + ); const headers: Headers = { Accept: 'application/json' }; const queryParameters: Record = {}; + if (attribute === null || attribute === undefined) { + throw new Error( + 'Required parameter attribute was null or undefined when calling getTopFilterForAttribute.' + ); + } + if (index === null || index === undefined) { throw new Error( - 'Required parameter index was null or undefined when calling getClickPositions.' + 'Required parameter index was null or undefined when calling getTopFilterForAttribute.' ); } @@ -253,6 +888,14 @@ export class AnalyticsApi { queryParameters.endDate = endDate.toString(); } + if (limit !== undefined) { + queryParameters.limit = limit.toString(); + } + + if (offset !== undefined) { + queryParameters.offset = offset.toString(); + } + if (tags !== undefined) { queryParameters.tags = tags.toString(); } @@ -270,27 +913,31 @@ export class AnalyticsApi { return this.sendRequest(request, requestOptions); } /** - * Returns a click-through rate (CTR). The endpoint returns a value for the complete given time range, as well as a value per day. It also returns the count of clicks and searches used to compute the rates. Tracked searches are searches for which the engine returned a queryID, so searches where you\'ve set the clickAnalytics search parameter to true. This is different than the “count” attribute of the response, which includes tracked searches and searches where you didn\'t enable the clickAnalytics search parameter. If the CTR is null, it means that Algolia didn\'t receive any queries with the clickAnalytics search parameter set to true. If the CTR is 0, it means Algolia didn\'t receive any click events for the queries with the clickAnalytics search parameter set to true. + * Returns top filters with no results. Limited to the 1000 most used filters. * - * @summary Returns a click-through rate (CTR). + * @summary Returns top filters with no results. * @param index - The index name to target. * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param limit - How many items to fetch. + * @param offset - From which position to start retrieving results. * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. */ - getClickThroughRate( + getTopFiltersNoResults( index: string, startDate?: Date, endDate?: Date, + limit?: number, + offset?: number, tags?: string - ): Promise { - const path = '/2/clicks/clickThroughRate'; + ): Promise { + const path = '/2/filters/noResults'; const headers: Headers = { Accept: 'application/json' }; const queryParameters: Record = {}; if (index === null || index === undefined) { throw new Error( - 'Required parameter index was null or undefined when calling getClickThroughRate.' + 'Required parameter index was null or undefined when calling getTopFiltersNoResults.' ); } @@ -306,6 +953,14 @@ export class AnalyticsApi { queryParameters.endDate = endDate.toString(); } + if (limit !== undefined) { + queryParameters.limit = limit.toString(); + } + + if (offset !== undefined) { + queryParameters.offset = offset.toString(); + } + if (tags !== undefined) { queryParameters.tags = tags.toString(); } @@ -323,27 +978,42 @@ export class AnalyticsApi { return this.sendRequest(request, requestOptions); } /** - * Returns a conversion rate (CR). The endpoint returns a value for the complete given time range, as well as a value per day. It also returns the count of conversion and searches used to compute the rates. Tracked searches are searches for which the engine returned a queryID, so searches where you\'ve set the clickAnalytics search parameter to true. This is different than the “count” attribute of the response, which includes tracked searches and searches where you didn\'t enable the clickAnalytics search parameter. If the CR is null, it means that Algolia didn\'t receive any queries with the clickAnalytics search parameter set to true. If the CR is 0, it means Algolia didn\'t receive any conversion events for the queries with the clickAnalytics search parameter set to true. + * Returns top filters for the given no result search. Limited to the 1000 most used filters. * - * @summary Returns a conversion rate (CR). + * @summary Returns top filters for the given no result search. * @param index - The index name to target. + * @param search - The query term. Must match the exact user input. * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param limit - How many items to fetch. + * @param offset - From which position to start retrieving results. * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. */ - getConversationRate( + getTopFiltersNoResultsForSearch( index: string, + search: string, startDate?: Date, endDate?: Date, + limit?: number, + offset?: number, tags?: string - ): Promise { - const path = '/2/conversions/conversionRate'; + ): Promise { + const path = '/2/filters/noResults?search={search}'.replace( + '{search}', + encodeURIComponent(String(search)) + ); const headers: Headers = { Accept: 'application/json' }; const queryParameters: Record = {}; if (index === null || index === undefined) { throw new Error( - 'Required parameter index was null or undefined when calling getConversationRate.' + 'Required parameter index was null or undefined when calling getTopFiltersNoResultsForSearch.' + ); + } + + if (search === null || search === undefined) { + throw new Error( + 'Required parameter search was null or undefined when calling getTopFiltersNoResultsForSearch.' ); } @@ -359,6 +1029,14 @@ export class AnalyticsApi { queryParameters.endDate = endDate.toString(); } + if (limit !== undefined) { + queryParameters.limit = limit.toString(); + } + + if (offset !== undefined) { + queryParameters.offset = offset.toString(); + } + if (tags !== undefined) { queryParameters.tags = tags.toString(); } @@ -376,27 +1054,33 @@ export class AnalyticsApi { return this.sendRequest(request, requestOptions); } /** - * Returns the rate at which searches didn\'t lead to any clicks. The endpoint returns a value for the complete given time range, as well as a value per day. It also returns the count of searches and searches without clicks. + * Returns top hits. Limited to the 1000 most frequent ones. * - * @summary Returns the rate at which searches didn\'t lead to any clicks. + * @summary Returns top hits. * @param index - The index name to target. + * @param clickAnalytics - Whether to include the click-through and conversion rates for a search. * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param limit - How many items to fetch. + * @param offset - From which position to start retrieving results. * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. */ - getNoClickRate( + getTopHits( index: string, + clickAnalytics?: boolean, startDate?: Date, endDate?: Date, + limit?: number, + offset?: number, tags?: string - ): Promise { - const path = '/2/searches/noClickRate'; + ): Promise { + const path = '/2/hits'; const headers: Headers = { Accept: 'application/json' }; const queryParameters: Record = {}; if (index === null || index === undefined) { throw new Error( - 'Required parameter index was null or undefined when calling getNoClickRate.' + 'Required parameter index was null or undefined when calling getTopHits.' ); } @@ -404,6 +1088,10 @@ export class AnalyticsApi { queryParameters.index = index.toString(); } + if (clickAnalytics !== undefined) { + queryParameters.clickAnalytics = clickAnalytics.toString(); + } + if (startDate !== undefined) { queryParameters.startDate = startDate.toString(); } @@ -412,6 +1100,14 @@ export class AnalyticsApi { queryParameters.endDate = endDate.toString(); } + if (limit !== undefined) { + queryParameters.limit = limit.toString(); + } + + if (offset !== undefined) { + queryParameters.offset = offset.toString(); + } + if (tags !== undefined) { queryParameters.tags = tags.toString(); } @@ -429,39 +1125,44 @@ export class AnalyticsApi { return this.sendRequest(request, requestOptions); } /** - * Returns top filters for the given no result search. Limited to the 1000 most used filters. + * Returns top hits for the given search. Limited to the 1000 most frequent ones. * - * @summary Returns top filters for the given no result search. + * @summary Returns top hits for the given search. * @param index - The index name to target. * @param search - The query term. Must match the exact user input. + * @param clickAnalytics - Whether to include the click-through and conversion rates for a search. * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. * @param limit - How many items to fetch. * @param offset - From which position to start retrieving results. - * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + * @param tags Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. */ - getNoResultTopFilters( + getTopHitsForSearch( index: string, search: string, + clickAnalytics?: boolean, startDate?: Date, endDate?: Date, limit?: number, offset?: number, tags?: string - ): Promise { - const path = '/2/filters/noResults'; + ): Promise { + const path = '/2/hits?search={search}'.replace( + '{search}', + encodeURIComponent(String(search)) + ); const headers: Headers = { Accept: 'application/json' }; const queryParameters: Record = {}; if (index === null || index === undefined) { throw new Error( - 'Required parameter index was null or undefined when calling getNoResultTopFilters.' + 'Required parameter index was null or undefined when calling getTopHitsForSearch.' ); } if (search === null || search === undefined) { throw new Error( - 'Required parameter search was null or undefined when calling getNoResultTopFilters.' + 'Required parameter search was null or undefined when calling getTopHitsForSearch.' ); } @@ -469,8 +1170,8 @@ export class AnalyticsApi { queryParameters.index = index.toString(); } - if (search !== undefined) { - queryParameters.search = search.toString(); + if (clickAnalytics !== undefined) { + queryParameters.clickAnalytics = clickAnalytics.toString(); } if (startDate !== undefined) { @@ -506,31 +1207,37 @@ export class AnalyticsApi { return this.sendRequest(request, requestOptions); } /** - * Returns top searches that didn\'t return any results. Limited to the 1000 most frequent ones. + * Returns top searches. Limited to the 1000 most frequent ones. For each search, also returns the average number of hits returned. * - * @summary Returns top searches that didn\'t return any results. + * @summary Returns top searches. * @param index - The index name to target. + * @param clickAnalytics - Whether to include the click-through and conversion rates for a search. * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param orderBy - Reorder the results. + * @param direction - The sorting of the result. * @param limit - How many items to fetch. - * @param offset - From which position to start retrieving results. - * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + * @param offset From which position to start retrieving results. + * @param tags Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. */ - getNoResultsRate( + getTopSearches( index: string, + clickAnalytics?: boolean, startDate?: Date, endDate?: Date, + orderBy?: Record, + direction?: Record, limit?: number, offset?: number, tags?: string - ): Promise { - const path = '/2/searches/noResultRate'; + ): Promise { + const path = '/2/searches'; const headers: Headers = { Accept: 'application/json' }; const queryParameters: Record = {}; if (index === null || index === undefined) { throw new Error( - 'Required parameter index was null or undefined when calling getNoResultsRate.' + 'Required parameter index was null or undefined when calling getTopSearches.' ); } @@ -538,6 +1245,10 @@ export class AnalyticsApi { queryParameters.index = index.toString(); } + if (clickAnalytics !== undefined) { + queryParameters.clickAnalytics = clickAnalytics.toString(); + } + if (startDate !== undefined) { queryParameters.startDate = startDate.toString(); } @@ -546,6 +1257,14 @@ export class AnalyticsApi { queryParameters.endDate = endDate.toString(); } + if (orderBy !== undefined) { + queryParameters.orderBy = orderBy.toString(); + } + + if (direction !== undefined) { + queryParameters.direction = direction.toString(); + } + if (limit !== undefined) { queryParameters.limit = limit.toString(); } @@ -571,19 +1290,27 @@ export class AnalyticsApi { return this.sendRequest(request, requestOptions); } /** - * Returns the latest update time of the analytics API for a given index. If the index has been recently created and/or no search has been performed yet the updated time will be null. + * Returns the distinct count of users across the given time range. The endpoint returns a value for the complete given time range, as well as a value per day. * - * @summary Get latest update time of the analytics API. + * @summary Returns the distinct count of users across the given time range. * @param index - The index name to target. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. */ - getStatus(index: string): Promise { - const path = '/2/status'; + getUsersCount( + index: string, + startDate?: Date, + endDate?: Date, + tags?: string + ): Promise { + const path = '/2/users/count'; const headers: Headers = { Accept: 'application/json' }; const queryParameters: Record = {}; if (index === null || index === undefined) { throw new Error( - 'Required parameter index was null or undefined when calling getStatus.' + 'Required parameter index was null or undefined when calling getUsersCount.' ); } @@ -591,6 +1318,18 @@ export class AnalyticsApi { queryParameters.index = index.toString(); } + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + const request: Request = { method: 'GET', path, diff --git a/specs/analytics/paths/click/getAverageClickPosition.yml b/specs/analytics/paths/click/getAverageClickPosition.yml index 7023b42acb..f30f554f45 100644 --- a/specs/analytics/paths/click/getAverageClickPosition.yml +++ b/specs/analytics/paths/click/getAverageClickPosition.yml @@ -2,10 +2,7 @@ get: tags: - analytics operationId: getAverageClickPosition - description: | - Returns the average click position. The endpoint returns a value for the complete given time range, as well as a value per day. - - An average of null means Algolia didn't receive any click events for the queries with the clickAnalytics search parameter set to true. The average is null until Algolia receives at least one click event. + description: Returns the average click position. The endpoint returns a value for the complete given time range, as well as a value per day. summary: Returns the average click position. parameters: - $ref: '../../../common/parameters.yml#/Index' @@ -32,7 +29,7 @@ get: $ref: '../common/parameters.yml#/clickCount' dates: type: array - description: A list of click events with their date. + description: A list of average click position with their date. items: type: object additionalProperties: false diff --git a/specs/analytics/paths/click/getClickPositions.yml b/specs/analytics/paths/click/getClickPositions.yml index 518011771f..854fef7804 100644 --- a/specs/analytics/paths/click/getClickPositions.yml +++ b/specs/analytics/paths/click/getClickPositions.yml @@ -2,10 +2,7 @@ get: tags: - analytics operationId: getClickPositions - description: | - Returns the distribution of clicks per range of positions. - - If the groups all have a count of 0, it means Algolia didn't receive any click events for the queries with the clickAnalytics search parameter set to true. The count is 0 until Algolia receives at least one click event. + description: Returns the distribution of clicks per range of positions. summary: Returns the distribution of clicks per range of positions. parameters: - $ref: '../../../common/parameters.yml#/Index' @@ -26,7 +23,9 @@ get: properties: positions: type: array - description: A list of the positions with their click count. + description: A list of the click positions with their click count. + minItems: 2 + maxItems: 2 items: type: object additionalProperties: false diff --git a/specs/analytics/paths/click/getClickThroughRate.yml b/specs/analytics/paths/click/getClickThroughRate.yml index 63e6dc4c5c..cbba6c80af 100644 --- a/specs/analytics/paths/click/getClickThroughRate.yml +++ b/specs/analytics/paths/click/getClickThroughRate.yml @@ -2,13 +2,7 @@ get: tags: - analytics operationId: getClickThroughRate - description: | - Returns a click-through rate (CTR). The endpoint returns a value for the complete given time range, as well as a value per day. It also returns the count of clicks and searches used to compute the rates. - - Tracked searches are searches for which the engine returned a queryID, so searches where you've set the clickAnalytics search parameter to true. This is different than the “count” attribute of the response, which includes tracked searches and searches where you didn't enable the clickAnalytics search parameter. - - If the CTR is null, it means that Algolia didn't receive any queries with the clickAnalytics search parameter set to true. - If the CTR is 0, it means Algolia didn't receive any click events for the queries with the clickAnalytics search parameter set to true. + description: Returns a click-through rate (CTR). The endpoint returns a value for the complete given time range, as well as a value per day. It also returns the count of clicks and searches used to compute the rates. summary: Returns a click-through rate (CTR). parameters: - $ref: '../../../common/parameters.yml#/Index' diff --git a/specs/analytics/paths/click/getConversionRate.yml b/specs/analytics/paths/click/getConversionRate.yml index b3331d9ad6..9ae6d3b69d 100644 --- a/specs/analytics/paths/click/getConversionRate.yml +++ b/specs/analytics/paths/click/getConversionRate.yml @@ -2,13 +2,7 @@ get: tags: - analytics operationId: getConversationRate - description: | - Returns a conversion rate (CR). The endpoint returns a value for the complete given time range, as well as a value per day. It also returns the count of conversion and searches used to compute the rates. - - Tracked searches are searches for which the engine returned a queryID, so searches where you've set the clickAnalytics search parameter to true. This is different than the “count” attribute of the response, which includes tracked searches and searches where you didn't enable the clickAnalytics search parameter. - - If the CR is null, it means that Algolia didn't receive any queries with the clickAnalytics search parameter set to true. - If the CR is 0, it means Algolia didn't receive any conversion events for the queries with the clickAnalytics search parameter set to true. + description: Returns a conversion rate (CR). The endpoint returns a value for the complete given time range, as well as a value per day. It also returns the count of conversion and searches used to compute the rates. summary: Returns a conversion rate (CR). parameters: - $ref: '../../../common/parameters.yml#/Index' @@ -38,7 +32,7 @@ get: $ref: '../common/parameters.yml#/conversionCount' dates: type: array - description: A list of click-through rate events with their date. + description: A list of conversion events with their date. items: type: object additionalProperties: false diff --git a/specs/analytics/paths/common/parameters.yml b/specs/analytics/paths/common/parameters.yml index 4e0c3049d4..ff640d8d79 100644 --- a/specs/analytics/paths/common/parameters.yml +++ b/specs/analytics/paths/common/parameters.yml @@ -1,12 +1,37 @@ -# query +# path Attribute: - in: query + in: path name: attribute description: The exact name of the attribute. required: true schema: type: string +# query +OrderBy: + in: query + name: orderBy + description: Reorder the results. + schema: + enum: [searchCount, clickThroughRate, conversionRate, averageClickPosition] + default: 'searchCount' + +Direction: + in: query + name: direction + description: The sorting of the result. + schema: + enum: [asc, desc] + default: 'asc' + +ClickAnalytics: + in: query + name: clickAnalytics + description: Whether to include the click-through and conversion rates for a search. + schema: + type: boolean + default: false + Limit: in: query name: limit @@ -16,7 +41,15 @@ Limit: default: 10 Search: - in: query + in: path + name: search + description: The query term. Must match the exact user input. + required: true + schema: + type: string + +SearchInPath: + in: path name: search description: The query term. Must match the exact user input. required: true @@ -44,6 +77,10 @@ average: format: double description: The average of all the click count event. +averageClickPosition: + type: integer + description: The average position of all the click count event. + clickCount: type: integer description: The number of click event. @@ -58,6 +95,11 @@ rate: format: double description: The click-through rate. +conversionRate: + type: number + format: double + description: The conversion rate. + trackedSearchCount: type: integer description: The number of tracked search click. @@ -80,3 +122,18 @@ operator: value: description: The value of the attribute. type: string + +search: + description: The search query. + type: string + +hit: + description: The hit. + type: string + +count: + description: The number of occurrences. + type: integer + +nbHits: + $ref: '../../../search/common/schemas/SearchResponse.yml#/baseSearchResponse/properties/nbHits' diff --git a/specs/analytics/paths/common/schemas/getTopFilterAttributes.yml b/specs/analytics/paths/common/schemas/getTopFilterAttributes.yml new file mode 100644 index 0000000000..4299859e3a --- /dev/null +++ b/specs/analytics/paths/common/schemas/getTopFilterAttributes.yml @@ -0,0 +1,20 @@ +title: getTopFilterAttributesResponse +type: object +additionalProperties: false +required: + - attributes +properties: + attributes: + type: array + description: A list of attributes with their count. + items: + type: object + additionalProperties: false + required: + - attribute + - count + properties: + attribute: + $ref: '../parameters.yml#/attribute' + count: + $ref: '../parameters.yml#/count' diff --git a/specs/analytics/paths/common/schemas/getTopFiltersNoResults.yml b/specs/analytics/paths/common/schemas/getTopFiltersNoResults.yml new file mode 100644 index 0000000000..9d0e077520 --- /dev/null +++ b/specs/analytics/paths/common/schemas/getTopFiltersNoResults.yml @@ -0,0 +1,34 @@ +title: getTopFiltersNoResultsResponse +type: object +additionalProperties: false +required: + - values +properties: + values: + type: array + description: A list of filters without results. + items: + type: object + additionalProperties: false + required: + - values + - count + properties: + count: + $ref: '../parameters.yml#/count' + values: + type: array + items: + type: object + additionalProperties: false + required: + - attribute + - operator + - value + properties: + attribute: + $ref: '../parameters.yml#/attribute' + operator: + $ref: '../parameters.yml#/operator' + value: + $ref: '../parameters.yml#/value' diff --git a/specs/analytics/paths/common/schemas/getTopHits.yml b/specs/analytics/paths/common/schemas/getTopHits.yml new file mode 100644 index 0000000000..550446e9a1 --- /dev/null +++ b/specs/analytics/paths/common/schemas/getTopHits.yml @@ -0,0 +1,58 @@ +topHitsReponse: + title: getTopHitsResponse + type: object + additionalProperties: false + required: + - hits + properties: + hits: + type: array + description: A list of top hits with their count. + items: + type: object + additionalProperties: false + required: + - hit + - count + properties: + hit: + $ref: '../parameters.yml#/hit' + count: + $ref: '../parameters.yml#/count' + +topHitsResponseWithAnalytics: + title: getTopHitsResponseWithAnalytics + type: object + additionalProperties: false + required: + - hits + properties: + hits: + type: array + description: A list of top hits with their count and analytics. + items: + type: object + additionalProperties: false + required: + - hit + - count + - clickThroughRate + - conversionRate + - trackedSearchCount + - clickCount + - conversionCount + properties: + hit: + $ref: '../parameters.yml#/hit' + count: + $ref: '../parameters.yml#/count' + clickThroughRate: + $ref: '../parameters.yml#/rate' + conversionRate: + $ref: '../parameters.yml#/conversionRate' + trackedSearchCount: + $ref: '../parameters.yml#/trackedSearchCount' + clickCount: + $ref: '../parameters.yml#/clickCount' + conversionCount: + $ref: '../parameters.yml#/conversionCount' diff --git a/specs/analytics/paths/common/schemas/getTopSearches.yml b/specs/analytics/paths/common/schemas/getTopSearches.yml new file mode 100644 index 0000000000..1e17932d9b --- /dev/null +++ b/specs/analytics/paths/common/schemas/getTopSearches.yml @@ -0,0 +1,67 @@ +topSearchesResponse: + title: getTopSearchesResponse + type: object + additionalProperties: false + required: + - searches + properties: + searches: + type: array + description: A list of top searches with their count. + items: + type: object + additionalProperties: false + required: + - search + - count + - nbHits + properties: + search: + $ref: '../parameters.yml#/search' + count: + $ref: '../parameters.yml#/count' + nbHits: + $ref: '../parameters.yml#/nbHits' + +topSearchesResponseWithAnalytics: + title: getTopSearchesResponseWithAnalytics + type: object + additionalProperties: false + required: + - searches + properties: + searches: + type: array + description: A list of top searches with their count and analytics. + items: + type: object + additionalProperties: false + required: + - search + - count + - nbHits + - clickThroughRate + - averageClickPosition + - conversionRate + - trackedSearchCount + - clickCount + - conversionCount + properties: + search: + $ref: '../parameters.yml#/search' + count: + $ref: '../parameters.yml#/count' + clickThroughRate: + $ref: '../parameters.yml#/rate' + averageClickPosition: + $ref: '../parameters.yml#/averageClickPosition' + conversionRate: + $ref: '../parameters.yml#/conversionRate' + trackedSearchCount: + $ref: '../parameters.yml#/trackedSearchCount' + clickCount: + $ref: '../parameters.yml#/clickCount' + conversionCount: + $ref: '../parameters.yml#/conversionCount' + nbHits: + $ref: '../parameters.yml#/nbHits' diff --git a/specs/analytics/paths/search/getNoClickRate.yml b/specs/analytics/paths/search/getNoClickRate.yml index 3972db1501..4f22268c30 100644 --- a/specs/analytics/paths/search/getNoClickRate.yml +++ b/specs/analytics/paths/search/getNoClickRate.yml @@ -32,7 +32,7 @@ get: $ref: '../common/parameters.yml#/clickCount' dates: type: array - description: A list of click-through rate events with their date. + description: A list of searches without clicks with their date, rate and counts. items: type: object additionalProperties: false diff --git a/specs/analytics/paths/search/getNoResultTopFilters.yml b/specs/analytics/paths/search/getNoResultTopFilters.yml deleted file mode 100644 index a036ab1edc..0000000000 --- a/specs/analytics/paths/search/getNoResultTopFilters.yml +++ /dev/null @@ -1,63 +0,0 @@ -get: - tags: - - analytics - operationId: getNoResultTopFilters - description: Returns top filters for the given no result search. Limited to the 1000 most used filters. - summary: Returns top filters for the given no result search. - parameters: - - $ref: '../../../common/parameters.yml#/Index' - - $ref: '../common/parameters.yml#/Search' - - $ref: '../../../common/parameters.yml#/StartDate' - - $ref: '../../../common/parameters.yml#/EndDate' - - $ref: '../common/parameters.yml#/Limit' - - $ref: '../common/parameters.yml#/Offset' - - $ref: '../common/parameters.yml#/Tags' - responses: - '200': - description: OK - content: - application/json: - schema: - title: getNoResultTopFiltersResponse - type: object - additionalProperties: false - required: - - values - properties: - values: - type: array - description: A list of filters without results. - items: - type: object - additionalProperties: false - required: - - values - - count - properties: - count: - description: The number of occurrences. - type: integer - values: - type: array - items: - type: object - additionalProperties: false - required: - - attribute - - operator - - value - properties: - attribute: - $ref: '../common/parameters.yml#/attribute' - operator: - $ref: '../common/parameters.yml#/operator' - value: - $ref: '../common/parameters.yml#/value' - '400': - $ref: '../../../common/responses/BadRequest.yml' - '402': - $ref: '../../../common/responses/FeatureNotEnabled.yml' - '403': - $ref: '../../../common/responses/MethodNotAllowed.yml' - '404': - $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/search/getNoResultsRate.yml b/specs/analytics/paths/search/getNoResultsRate.yml index 9ae7f470f9..8d296b5299 100644 --- a/specs/analytics/paths/search/getNoResultsRate.yml +++ b/specs/analytics/paths/search/getNoResultsRate.yml @@ -2,14 +2,12 @@ get: tags: - analytics operationId: getNoResultsRate - description: Returns top searches that didn't return any results. Limited to the 1000 most frequent ones. - summary: Returns top searches that didn't return any results. + description: Returns the rate at which searches didn't return any results. The endpoint returns a value for the complete given time range, as well as a value per day. It also returns the count of searches and searches without results used to compute the rates. + summary: Returns the rate at which searches didn't return any results. parameters: - $ref: '../../../common/parameters.yml#/Index' - $ref: '../../../common/parameters.yml#/StartDate' - $ref: '../../../common/parameters.yml#/EndDate' - - $ref: '../common/parameters.yml#/Limit' - - $ref: '../common/parameters.yml#/Offset' - $ref: '../common/parameters.yml#/Tags' responses: '200': @@ -21,28 +19,37 @@ get: type: object additionalProperties: false required: - - searches + - rate + - count + - noResultCount + - dates properties: - searches: + rate: + $ref: '../common/parameters.yml#/rate' + count: + $ref: '../common/parameters.yml#/count' + noResultCount: + $ref: '../common/parameters.yml#/count' + dates: type: array - description: A list of top searches with their count. + description: A list of searches without results with their date, rate and counts. items: type: object additionalProperties: false required: - - search + - date + - noResultCount - count - - withFilterCount + - rate properties: - search: - description: The search query. - type: string + date: + $ref: '../common/parameters.yml#/date' + noResultCount: + $ref: '../common/parameters.yml#/count' count: - description: The number of occurrences. - type: integer - withFilterCount: - description: The number of occurrences with filter. - type: integer + $ref: '../common/parameters.yml#/count' + rate: + $ref: '../common/parameters.yml#/rate' '400': $ref: '../../../common/responses/BadRequest.yml' '402': diff --git a/specs/analytics/paths/search/getSearchAttributesTopFilters.yml b/specs/analytics/paths/search/getSearchAttributesTopFilters.yml index 3ddb9d7f54..704196afee 100644 --- a/specs/analytics/paths/search/getSearchAttributesTopFilters.yml +++ b/specs/analytics/paths/search/getSearchAttributesTopFilters.yml @@ -1 +1,63 @@ get: + tags: + - analytics + operationId: getSearchAttributesTopFilters + description: Returns top filters for the given no result search. Limited to the 1000 most used filters. + summary: Returns top filters for the given no result search. + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../common/parameters.yml#/Search' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Limit' + - $ref: '../common/parameters.yml#/Offset' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + title: getSearchAttributesTopFiltersResponse + type: object + additionalProperties: false + required: + - values + properties: + values: + type: array + description: A list of filters without results. + items: + type: object + additionalProperties: false + required: + - values + - count + properties: + count: + description: The number of occurrences. + type: integer + values: + type: array + items: + type: object + additionalProperties: false + required: + - attribute + - operator + - value + properties: + attribute: + $ref: '../common/parameters.yml#/attribute' + operator: + $ref: '../common/parameters.yml#/operator' + value: + $ref: '../common/parameters.yml#/value' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/search/getSearchesCount.yml b/specs/analytics/paths/search/getSearchesCount.yml index 3ddb9d7f54..b32486050d 100644 --- a/specs/analytics/paths/search/getSearchesCount.yml +++ b/specs/analytics/paths/search/getSearchesCount.yml @@ -1 +1,48 @@ get: + tags: + - analytics + operationId: getSearchesCount + description: Returns the number of searches across the given time range. The endpoint returns a value for the complete given time range, as well as a value per day. + summary: Returns the number of searches across the given time range. + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + title: getSearchesCountResponse + type: object + additionalProperties: false + required: + - dates + - count + properties: + count: + $ref: '../common/parameters.yml#/count' + dates: + type: array + description: A list of search events with their date and count. + items: + type: object + additionalProperties: false + required: + - date + - count + properties: + date: + $ref: '../common/parameters.yml#/date' + count: + $ref: '../common/parameters.yml#/count' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/search/getSearchesNoClicks.yml b/specs/analytics/paths/search/getSearchesNoClicks.yml index 3ddb9d7f54..9d85431889 100644 --- a/specs/analytics/paths/search/getSearchesNoClicks.yml +++ b/specs/analytics/paths/search/getSearchesNoClicks.yml @@ -1 +1,50 @@ get: + tags: + - analytics + operationId: getSearchesNoClicks + description: Returns top searches that didn't lead to any clicks. Limited to the 1000 most frequent ones. For each search, also returns the average number of found hits. + summary: Returns top searches that didn't lead to any clicks. + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Limit' + - $ref: '../common/parameters.yml#/Offset' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + title: getSearchesNoClicksResponse + type: object + additionalProperties: false + required: + - searches + properties: + searches: + type: array + description: A list of searches with no clicks and their count. + items: + type: object + additionalProperties: false + required: + - search + - count + - withFilterCount + properties: + search: + $ref: '../common/parameters.yml#/search' + count: + $ref: '../common/parameters.yml#/count' + withFilterCount: + $ref: '../common/parameters.yml#/count' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/search/getSearchesNoResults.yml b/specs/analytics/paths/search/getSearchesNoResults.yml index 3ddb9d7f54..99a672a051 100644 --- a/specs/analytics/paths/search/getSearchesNoResults.yml +++ b/specs/analytics/paths/search/getSearchesNoResults.yml @@ -1 +1,50 @@ get: + tags: + - analytics + operationId: getSearchesNoResults + description: Returns top searches that didn't return any results. Limited to the 1000 most frequent ones. + summary: Returns top searches that didn't return any results. + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Limit' + - $ref: '../common/parameters.yml#/Offset' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + title: getSearchesNoResultsResponse + type: object + additionalProperties: false + required: + - searches + properties: + searches: + type: array + description: A list of searches with no results and their count. + items: + type: object + additionalProperties: false + required: + - search + - count + - nbHits + properties: + search: + $ref: '../common/parameters.yml#/search' + count: + $ref: '../common/parameters.yml#/count' + nbHits: + $ref: '../common/parameters.yml#/nbHits' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/search/getTopCountries.yml b/specs/analytics/paths/search/getTopCountries.yml index 3ddb9d7f54..a534cfd36d 100644 --- a/specs/analytics/paths/search/getTopCountries.yml +++ b/specs/analytics/paths/search/getTopCountries.yml @@ -1 +1,48 @@ get: + tags: + - analytics + operationId: getTopCountries + description: Returns top countries. Limited to the 1000 most frequent ones. + summary: Returns top countries. + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Limit' + - $ref: '../common/parameters.yml#/Offset' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + title: getTopCountriesResponse + type: object + additionalProperties: false + required: + - countries + properties: + countries: + type: array + description: A list of countries with their count. + items: + type: object + additionalProperties: false + required: + - country + - count + properties: + country: + description: The country. + type: string + count: + $ref: '../common/parameters.yml#/count' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/search/getTopFilterAttributes.yml b/specs/analytics/paths/search/getTopFilterAttributes.yml index 516f9e4a9c..908abc06a1 100644 --- a/specs/analytics/paths/search/getTopFilterAttributes.yml +++ b/specs/analytics/paths/search/getTopFilterAttributes.yml @@ -1,2 +1,28 @@ -# handle /2/filters?search= as well get: + tags: + - analytics + operationId: getTopFilterAttributes + description: Returns top filter attributes. Limited to the 1000 most used filters. + summary: Returns top filter attributes. + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Limit' + - $ref: '../common/parameters.yml#/Offset' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../common/schemas/getTopFilterAttributes.yml' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/search/getTopFilterAttributesForSearch.yml b/specs/analytics/paths/search/getTopFilterAttributesForSearch.yml new file mode 100644 index 0000000000..d43af5dcff --- /dev/null +++ b/specs/analytics/paths/search/getTopFilterAttributesForSearch.yml @@ -0,0 +1,29 @@ +get: + tags: + - analytics + operationId: getTopFilterAttributes + description: Returns top filter attributes for a given search. Limited to the 1000 most used filters. + summary: Returns top filter attributes for a given search. + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../common/parameters.yml#/SearchInPath' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Limit' + - $ref: '../common/parameters.yml#/Offset' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../common/schemas/getTopFilterAttributes.yml' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/search/getAttributeTopFilters.yml b/specs/analytics/paths/search/getTopFilterForAttribute.yml similarity index 86% rename from specs/analytics/paths/search/getAttributeTopFilters.yml rename to specs/analytics/paths/search/getTopFilterForAttribute.yml index 005f99cc52..76abf94c1f 100644 --- a/specs/analytics/paths/search/getAttributeTopFilters.yml +++ b/specs/analytics/paths/search/getTopFilterForAttribute.yml @@ -1,7 +1,7 @@ get: tags: - analytics - operationId: getAttributeTopFilters + operationId: getTopFilterForAttribute description: Returns top filters for the given attribute. Limited to the 1000 most used filters. summary: Returns top filters for the given attribute. parameters: @@ -18,7 +18,7 @@ get: content: application/json: schema: - title: getAttributeTopFiltersResponse + title: getTopFilterForAttributeResponse type: object additionalProperties: false required: @@ -26,7 +26,7 @@ get: properties: values: type: array - description: A list of filters for an attributes. + description: A list of filters for the given attributes. items: type: object additionalProperties: false @@ -43,8 +43,7 @@ get: value: $ref: '../common/parameters.yml#/value' count: - description: The number of events for the attribute. - type: integer + $ref: '../common/parameters.yml#/count' '400': $ref: '../../../common/responses/BadRequest.yml' '402': diff --git a/specs/analytics/paths/search/getTopFiltersNoResults.yml b/specs/analytics/paths/search/getTopFiltersNoResults.yml new file mode 100644 index 0000000000..fd1f7e0506 --- /dev/null +++ b/specs/analytics/paths/search/getTopFiltersNoResults.yml @@ -0,0 +1,29 @@ +get: + tags: + - analytics + operationId: getTopFiltersNoResults + description: Returns top filters with no results. Limited to the 1000 most used filters. + summary: Returns top filters with no results. + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Limit' + - $ref: '../common/parameters.yml#/Offset' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../common/schemas/getTopFiltersNoResults.yml' + + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/search/getTopFiltersNoResultsForSearch.yml b/specs/analytics/paths/search/getTopFiltersNoResultsForSearch.yml new file mode 100644 index 0000000000..a29373963c --- /dev/null +++ b/specs/analytics/paths/search/getTopFiltersNoResultsForSearch.yml @@ -0,0 +1,29 @@ +get: + tags: + - analytics + operationId: getTopFiltersNoResultsForSearch + description: Returns top filters for the given no result search. Limited to the 1000 most used filters. + summary: Returns top filters for the given no result search. + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../common/parameters.yml#/SearchInPath' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Limit' + - $ref: '../common/parameters.yml#/Offset' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../common/schemas/getTopFiltersNoResults.yml' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/search/getTopHits.yml b/specs/analytics/paths/search/getTopHits.yml index e92c2b1912..09631cf12b 100644 --- a/specs/analytics/paths/search/getTopHits.yml +++ b/specs/analytics/paths/search/getTopHits.yml @@ -1,2 +1,31 @@ get: -# handle /2/hits?search= as well + tags: + - analytics + operationId: getTopHits + description: Returns top hits. Limited to the 1000 most frequent ones. + summary: Returns top hits. + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../common/parameters.yml#/ClickAnalytics' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Limit' + - $ref: '../common/parameters.yml#/Offset' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + oneOf: + - $ref: '../common/schemas/getTopHits.yml#/topHitsReponse' + - $ref: '../common/schemas/getTopHits.yml#/topHitsResponseWithAnalytics' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/search/getTopHitsForSearch.yml b/specs/analytics/paths/search/getTopHitsForSearch.yml new file mode 100644 index 0000000000..7bfb0ff28d --- /dev/null +++ b/specs/analytics/paths/search/getTopHitsForSearch.yml @@ -0,0 +1,32 @@ +get: + tags: + - analytics + operationId: getTopHitsForSearch + description: Returns top hits for the given search. Limited to the 1000 most frequent ones. + summary: Returns top hits for the given search. + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../common/parameters.yml#/SearchInPath' + - $ref: '../common/parameters.yml#/ClickAnalytics' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Limit' + - $ref: '../common/parameters.yml#/Offset' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + oneOf: + - $ref: '../common/schemas/getTopHits.yml#/topHitsReponse' + - $ref: '../common/schemas/getTopHits.yml#/topHitsResponseWithAnalytics' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/search/getTopSearches.yml b/specs/analytics/paths/search/getTopSearches.yml index 3ddb9d7f54..c516eb234d 100644 --- a/specs/analytics/paths/search/getTopSearches.yml +++ b/specs/analytics/paths/search/getTopSearches.yml @@ -1 +1,33 @@ get: + tags: + - analytics + operationId: getTopSearches + description: Returns top searches. Limited to the 1000 most frequent ones. For each search, also returns the average number of hits returned. + summary: Returns top searches. + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../common/parameters.yml#/ClickAnalytics' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/OrderBy' + - $ref: '../common/parameters.yml#/Direction' + - $ref: '../common/parameters.yml#/Limit' + - $ref: '../common/parameters.yml#/Offset' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + oneOf: + - $ref: '../common/schemas/getTopSearches.yml#/topSearchesResponse' + - $ref: '../common/schemas/getTopSearches.yml#/topSearchesResponseWithAnalytics' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/paths/search/getUsersCount.yml b/specs/analytics/paths/search/getUsersCount.yml index 3ddb9d7f54..95872f055f 100644 --- a/specs/analytics/paths/search/getUsersCount.yml +++ b/specs/analytics/paths/search/getUsersCount.yml @@ -1 +1,48 @@ get: + tags: + - analytics + operationId: getUsersCount + description: Returns the distinct count of users across the given time range. The endpoint returns a value for the complete given time range, as well as a value per day. + summary: Returns the distinct count of users across the given time range. + parameters: + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + title: getUsersCountResponse + type: object + additionalProperties: false + required: + - dates + - count + properties: + count: + $ref: '../common/parameters.yml#/count' + dates: + type: array + description: A list of users count with their date. + items: + type: object + additionalProperties: false + required: + - date + - count + properties: + date: + $ref: '../common/parameters.yml#/date' + count: + $ref: '../common/parameters.yml#/count' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/spec.yml b/specs/analytics/spec.yml index 4ded0e711d..3557228992 100644 --- a/specs/analytics/spec.yml +++ b/specs/analytics/spec.yml @@ -16,32 +16,38 @@ paths: # ################################## # ### Search Analytics Endpoints ### # ################################## - # /2/searches: - # $ref: './paths/search/getTopSearches.yml' - # /2/searches/count: - # $ref: './paths/search/getSearchesCount.yml' - # /2/searches/noResults: - # $ref: './paths/search/getSearchesNoResults.yml' - # /2/searches/noClicks: - # $ref: './paths/search/getSearchesNoClicks.yml' + /2/searches: + $ref: './paths/search/getTopSearches.yml' + /2/searches/count: + $ref: './paths/search/getSearchesCount.yml' + /2/searches/noResults: + $ref: './paths/search/getSearchesNoResults.yml' + /2/searches/noClicks: + $ref: './paths/search/getSearchesNoClicks.yml' /2/searches/noResultRate: $ref: './paths/search/getNoResultsRate.yml' /2/searches/noClickRate: $ref: './paths/search/getNoClickRate.yml' - # /2/hits: - # $ref: './paths/search/getTopHits.yml' - # /2/users/count: - # $ref: './paths/search/getUsersCount.yml' - # /2/filters: - # $ref: './paths/search/getTopFilterAttributes.yml' + /2/hits: + $ref: './paths/search/getTopHits.yml' + /2/hits?search={search}: + $ref: './paths/search/getTopHitsForSearch.yml' + /2/users/count: + $ref: './paths/search/getUsersCount.yml' + /2/filters: + $ref: './paths/search/getTopFilterAttributes.yml' + /2/filters/{attribute}: + $ref: './paths/search/getTopFilterForAttribute.yml' + /2/filters?search={search}: + $ref: './paths/search/getTopFilterAttributesForSearch.yml' /2/filters/noResults: - $ref: './paths/search/getNoResultTopFilters.yml' + $ref: './paths/search/getTopFiltersNoResults.yml' + /2/filters/noResults?search={search}: + $ref: './paths/search/getTopFiltersNoResultsForSearch.yml' # /2/filters/{attribute list}?search=: - # $ref: './paths/search/getSearchAttributesTopFilters.yml' - /2/filters: - $ref: './paths/search/getAttributeTopFilters.yml' - # /2/countries: - # $ref: './paths/search/getTopCountries.yml' + # $ref: './paths/search/getSearchAttributesTolFilters.yml' + /2/countries: + $ref: './paths/search/getTopCountries.yml' # ################################# # ### Click Analytics Endpoints ### From 867dde12d442afdc66d1f4c9855ab5c1a8201885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Tue, 14 Dec 2021 11:37:00 +0100 Subject: [PATCH 4/9] fix: eslint issue --- .eslintrc.js | 3 ++- .../client-analytics/src/analyticsApi.ts | 6 ++--- scripts/post-gen/javascript.sh | 24 +++++++++++++++++-- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 9434aab522..ea2658cd25 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -35,8 +35,9 @@ module.exports = { // there's a conflict when declaring `type` and `namespaces`, even with `ignoreDeclarationMerge` 'no-redeclare': 0, '@typescript-eslint/no-redeclare': 0, + // Some endpoints have A LOT of parameters + 'max-params': 0, - 'max-params': ['error', 9], '@typescript-eslint/no-unused-vars': 2, 'unused-imports/no-unused-imports-ts': 2, '@typescript-eslint/member-ordering': [ diff --git a/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts b/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts index b4afa3e6e2..728454fe05 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts @@ -1135,7 +1135,7 @@ export class AnalyticsApi { * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. * @param limit - How many items to fetch. * @param offset - From which position to start retrieving results. - * @param tags Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. */ getTopHitsForSearch( index: string, @@ -1217,8 +1217,8 @@ export class AnalyticsApi { * @param orderBy - Reorder the results. * @param direction - The sorting of the result. * @param limit - How many items to fetch. - * @param offset From which position to start retrieving results. - * @param tags Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + * @param offset - From which position to start retrieving results. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. */ getTopSearches( index: string, diff --git a/scripts/post-gen/javascript.sh b/scripts/post-gen/javascript.sh index 18b1746d7e..e96e6d07b8 100755 --- a/scripts/post-gen/javascript.sh +++ b/scripts/post-gen/javascript.sh @@ -8,5 +8,25 @@ mkdir -p $CLIENT/utils cp -R clients/algoliasearch-client-javascript/utils/ $CLIENT/utils -echo "> Linting ${GENERATOR}..." -eslint --ext=ts ${CLIENT} --fix +lint_client() { + set +e + + echo "> Linting ${GENERATOR}..." + + log=$(eslint --ext=ts ${CLIENT} --fix) + + if [[ $? != 0 ]]; then + # jsdoc/require-hyphen-before-param-description fails to lint more than + # 6 parameters, we re-run the script if failed to lint the rest + eslint --ext=ts ${CLIENT} --fix + + if [[ $? != 0 ]]; then + exit 1 + fi + fi + + set -e + +} + +lint_client From dfe6a0796a6be678ccc311833f484e378da2756c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Tue, 14 Dec 2021 11:46:27 +0100 Subject: [PATCH 5/9] fix: incorrect types --- .../model/getTopFilterAttributes.ts | 8 --- .../model/getTopFilterAttributesAttributes.ts | 10 --- .../model/getTopFiltersNoResults.ts | 8 --- .../model/getTopFiltersNoResultsValues.ts | 14 ---- .../model/getTopFiltersNoResultsValues1.ts | 9 --- .../client-analytics/model/models.ts | 5 -- .../client-analytics/src/analyticsApi.ts | 10 ++- .../common/schemas/getTopFilterAttributes.yml | 44 ++++++------ .../common/schemas/getTopFiltersNoResults.yml | 72 ++++++++++--------- 9 files changed, 66 insertions(+), 114 deletions(-) delete mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributes.ts delete mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributesAttributes.ts delete mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResults.ts delete mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValues.ts delete mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValues1.ts diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributes.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributes.ts deleted file mode 100644 index 13e53aae6b..0000000000 --- a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributes.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { GetTopFilterAttributesAttributes } from './getTopFilterAttributesAttributes'; - -export type GetTopFilterAttributes = { - /** - * A list of attributes with their count. - */ - attributes: GetTopFilterAttributesAttributes[]; -}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributesAttributes.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributesAttributes.ts deleted file mode 100644 index b9f8be5f11..0000000000 --- a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributesAttributes.ts +++ /dev/null @@ -1,10 +0,0 @@ -export type GetTopFilterAttributesAttributes = { - /** - * The attribute. - */ - attribute: string; - /** - * The number of occurrences. - */ - count: number; -}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResults.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResults.ts deleted file mode 100644 index efad37959d..0000000000 --- a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResults.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { GetTopFiltersNoResultsValues1 } from './getTopFiltersNoResultsValues1'; - -export type GetTopFiltersNoResults = { - /** - * A list of filters without results. - */ - values: GetTopFiltersNoResultsValues1[]; -}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValues.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValues.ts deleted file mode 100644 index 973427ec2e..0000000000 --- a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValues.ts +++ /dev/null @@ -1,14 +0,0 @@ -export type GetTopFiltersNoResultsValues = { - /** - * The attribute. - */ - attribute: string; - /** - * The operator. - */ - operator: string; - /** - * The value of the attribute. - */ - value: string; -}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValues1.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValues1.ts deleted file mode 100644 index 9e035b95a5..0000000000 --- a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValues1.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { GetTopFiltersNoResultsValues } from './getTopFiltersNoResultsValues'; - -export type GetTopFiltersNoResultsValues1 = { - /** - * The number of occurrences. - */ - count: number; - values: GetTopFiltersNoResultsValues[]; -}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/models.ts b/clients/algoliasearch-client-javascript/client-analytics/model/models.ts index 15fc420665..4a51e53ca5 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/models.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/models.ts @@ -23,13 +23,8 @@ export * from './getSearchesNoResultsResponseSearches'; export * from './getStatusResponse'; export * from './getTopCountriesResponse'; export * from './getTopCountriesResponseCountries'; -export * from './getTopFilterAttributes'; -export * from './getTopFilterAttributesAttributes'; export * from './getTopFilterForAttributeResponse'; export * from './getTopFilterForAttributeResponseValues'; -export * from './getTopFiltersNoResults'; -export * from './getTopFiltersNoResultsValues'; -export * from './getTopFiltersNoResultsValues1'; export * from './getUsersCountResponse'; export * from './topHitsReponse'; export * from './topHitsReponseHits'; diff --git a/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts b/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts index 728454fe05..19aae773a7 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts @@ -9,9 +9,7 @@ import type { GetSearchesNoClicksResponse } from '../model/getSearchesNoClicksRe import type { GetSearchesNoResultsResponse } from '../model/getSearchesNoResultsResponse'; import type { GetStatusResponse } from '../model/getStatusResponse'; import type { GetTopCountriesResponse } from '../model/getTopCountriesResponse'; -import type { GetTopFilterAttributes } from '../model/getTopFilterAttributes'; import type { GetTopFilterForAttributeResponse } from '../model/getTopFilterForAttributeResponse'; -import type { GetTopFiltersNoResults } from '../model/getTopFiltersNoResults'; import type { GetUsersCountResponse } from '../model/getUsersCountResponse'; import { ApiKeyAuth } from '../model/models'; import type { TopHitsReponse } from '../model/topHitsReponse'; @@ -713,7 +711,7 @@ export class AnalyticsApi { limit?: number, offset?: number, tags?: string - ): Promise { + ): Promise> { const path = '/2/filters'; const headers: Headers = { Accept: 'application/json' }; const queryParameters: Record = {}; @@ -780,7 +778,7 @@ export class AnalyticsApi { limit?: number, offset?: number, tags?: string - ): Promise { + ): Promise> { const path = '/2/filters?search={search}'.replace( '{search}', encodeURIComponent(String(search)) @@ -930,7 +928,7 @@ export class AnalyticsApi { limit?: number, offset?: number, tags?: string - ): Promise { + ): Promise> { const path = '/2/filters/noResults'; const headers: Headers = { Accept: 'application/json' }; const queryParameters: Record = {}; @@ -997,7 +995,7 @@ export class AnalyticsApi { limit?: number, offset?: number, tags?: string - ): Promise { + ): Promise> { const path = '/2/filters/noResults?search={search}'.replace( '{search}', encodeURIComponent(String(search)) diff --git a/specs/analytics/paths/common/schemas/getTopFilterAttributes.yml b/specs/analytics/paths/common/schemas/getTopFilterAttributes.yml index 4299859e3a..80a6a9679d 100644 --- a/specs/analytics/paths/common/schemas/getTopFilterAttributes.yml +++ b/specs/analytics/paths/common/schemas/getTopFilterAttributes.yml @@ -1,20 +1,24 @@ -title: getTopFilterAttributesResponse -type: object -additionalProperties: false -required: - - attributes -properties: - attributes: - type: array - description: A list of attributes with their count. - items: - type: object - additionalProperties: false - required: - - attribute - - count - properties: - attribute: - $ref: '../parameters.yml#/attribute' - count: - $ref: '../parameters.yml#/count' +getTopFilterAttributesResponse: + title: getTopFilterAttributesResponse + type: object + additionalProperties: false + required: + - attributes + properties: + attributes: + type: array + description: A list of attributes with their count. + items: + $ref: '#/getTopFilterAttributes' + +getTopFilterAttributes: + type: object + additionalProperties: false + required: + - attribute + - count + properties: + attribute: + $ref: '../parameters.yml#/attribute' + count: + $ref: '../parameters.yml#/count' diff --git a/specs/analytics/paths/common/schemas/getTopFiltersNoResults.yml b/specs/analytics/paths/common/schemas/getTopFiltersNoResults.yml index 9d0e077520..48af278ab2 100644 --- a/specs/analytics/paths/common/schemas/getTopFiltersNoResults.yml +++ b/specs/analytics/paths/common/schemas/getTopFiltersNoResults.yml @@ -1,34 +1,38 @@ -title: getTopFiltersNoResultsResponse -type: object -additionalProperties: false -required: - - values -properties: - values: - type: array - description: A list of filters without results. - items: - type: object - additionalProperties: false - required: - - values - - count - properties: - count: - $ref: '../parameters.yml#/count' - values: - type: array - items: - type: object - additionalProperties: false - required: - - attribute - - operator - - value - properties: - attribute: - $ref: '../parameters.yml#/attribute' - operator: - $ref: '../parameters.yml#/operator' - value: - $ref: '../parameters.yml#/value' +getTopFiltersNoResultsResponse: + title: getTopFiltersNoResultsResponse + type: object + additionalProperties: false + required: + - values + properties: + values: + type: array + description: A list of filters without results. + items: + $ref: '#/getTopFiltersNoResultsValues' + +getTopFiltersNoResultsValues: + type: object + additionalProperties: false + required: + - values + - count + properties: + count: + $ref: '../parameters.yml#/count' + values: + type: array + items: + type: object + additionalProperties: false + required: + - attribute + - operator + - value + properties: + attribute: + $ref: '../parameters.yml#/attribute' + operator: + $ref: '../parameters.yml#/operator' + value: + $ref: '../parameters.yml#/value' From 0a052fb5935f799a8abe0ff36eda53c546ef7901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Tue, 14 Dec 2021 12:01:14 +0100 Subject: [PATCH 6/9] fix: specs and missing types --- .../model/getTopFilterAttribute.ts | 10 +++++++ .../model/getTopFilterAttributesResponse.ts | 8 +++++ .../model/getTopFiltersNoResultsResponse.ts | 8 +++++ .../model/getTopFiltersNoResultsValue.ts | 14 +++++++++ .../model/getTopFiltersNoResultsValues.ts | 12 ++++++++ .../client-analytics/model/models.ts | 5 ++++ .../client-analytics/src/analyticsApi.ts | 16 +++++----- .../common/schemas/getTopFilterAttributes.yml | 4 +-- .../common/schemas/getTopFiltersNoResults.yml | 30 +++++++++++-------- .../paths/search/getTopFilterAttributes.yml | 2 +- .../getTopFilterAttributesForSearch.yml | 4 +-- .../paths/search/getTopFiltersNoResults.yml | 2 +- .../getTopFiltersNoResultsForSearch.yml | 2 +- 13 files changed, 90 insertions(+), 27 deletions(-) create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttribute.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributesResponse.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsResponse.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValue.ts create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValues.ts diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttribute.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttribute.ts new file mode 100644 index 0000000000..85fe43b917 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttribute.ts @@ -0,0 +1,10 @@ +export type GetTopFilterAttribute = { + /** + * The attribute. + */ + attribute: string; + /** + * The number of occurrences. + */ + count: number; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributesResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributesResponse.ts new file mode 100644 index 0000000000..d54653be74 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterAttributesResponse.ts @@ -0,0 +1,8 @@ +import type { GetTopFilterAttribute } from './getTopFilterAttribute'; + +export type GetTopFilterAttributesResponse = { + /** + * A list of attributes with their count. + */ + attributes: GetTopFilterAttribute[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsResponse.ts new file mode 100644 index 0000000000..60d85c2abf --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsResponse.ts @@ -0,0 +1,8 @@ +import type { GetTopFiltersNoResultsValues } from './getTopFiltersNoResultsValues'; + +export type GetTopFiltersNoResultsResponse = { + /** + * A list of filters without results. + */ + values: GetTopFiltersNoResultsValues[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValue.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValue.ts new file mode 100644 index 0000000000..fb40a51d7b --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValue.ts @@ -0,0 +1,14 @@ +export type GetTopFiltersNoResultsValue = { + /** + * The attribute. + */ + attribute: string; + /** + * The operator. + */ + operator: string; + /** + * The value of the attribute. + */ + value: string; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValues.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValues.ts new file mode 100644 index 0000000000..fb8c39d7a9 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFiltersNoResultsValues.ts @@ -0,0 +1,12 @@ +import type { GetTopFiltersNoResultsValue } from './getTopFiltersNoResultsValue'; + +export type GetTopFiltersNoResultsValues = { + /** + * The number of occurrences. + */ + count: number; + /** + * A list of filters without results. + */ + values: GetTopFiltersNoResultsValue[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/models.ts b/clients/algoliasearch-client-javascript/client-analytics/model/models.ts index 4a51e53ca5..d6b059bd49 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/models.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/models.ts @@ -23,8 +23,13 @@ export * from './getSearchesNoResultsResponseSearches'; export * from './getStatusResponse'; export * from './getTopCountriesResponse'; export * from './getTopCountriesResponseCountries'; +export * from './getTopFilterAttribute'; +export * from './getTopFilterAttributesResponse'; export * from './getTopFilterForAttributeResponse'; export * from './getTopFilterForAttributeResponseValues'; +export * from './getTopFiltersNoResultsResponse'; +export * from './getTopFiltersNoResultsValue'; +export * from './getTopFiltersNoResultsValues'; export * from './getUsersCountResponse'; export * from './topHitsReponse'; export * from './topHitsReponseHits'; diff --git a/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts b/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts index 19aae773a7..56a65e2dcd 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts @@ -9,7 +9,9 @@ import type { GetSearchesNoClicksResponse } from '../model/getSearchesNoClicksRe import type { GetSearchesNoResultsResponse } from '../model/getSearchesNoResultsResponse'; import type { GetStatusResponse } from '../model/getStatusResponse'; import type { GetTopCountriesResponse } from '../model/getTopCountriesResponse'; +import type { GetTopFilterAttributesResponse } from '../model/getTopFilterAttributesResponse'; import type { GetTopFilterForAttributeResponse } from '../model/getTopFilterForAttributeResponse'; +import type { GetTopFiltersNoResultsResponse } from '../model/getTopFiltersNoResultsResponse'; import type { GetUsersCountResponse } from '../model/getUsersCountResponse'; import { ApiKeyAuth } from '../model/models'; import type { TopHitsReponse } from '../model/topHitsReponse'; @@ -711,7 +713,7 @@ export class AnalyticsApi { limit?: number, offset?: number, tags?: string - ): Promise> { + ): Promise { const path = '/2/filters'; const headers: Headers = { Accept: 'application/json' }; const queryParameters: Record = {}; @@ -770,7 +772,7 @@ export class AnalyticsApi { * @param offset - From which position to start retrieving results. * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. */ - getTopFilterAttributes_1( + getTopFilterAttributesForSearch( index: string, search: string, startDate?: Date, @@ -778,7 +780,7 @@ export class AnalyticsApi { limit?: number, offset?: number, tags?: string - ): Promise> { + ): Promise { const path = '/2/filters?search={search}'.replace( '{search}', encodeURIComponent(String(search)) @@ -788,13 +790,13 @@ export class AnalyticsApi { if (index === null || index === undefined) { throw new Error( - 'Required parameter index was null or undefined when calling getTopFilterAttributes_1.' + 'Required parameter index was null or undefined when calling getTopFilterAttributesForSearch.' ); } if (search === null || search === undefined) { throw new Error( - 'Required parameter search was null or undefined when calling getTopFilterAttributes_1.' + 'Required parameter search was null or undefined when calling getTopFilterAttributesForSearch.' ); } @@ -928,7 +930,7 @@ export class AnalyticsApi { limit?: number, offset?: number, tags?: string - ): Promise> { + ): Promise { const path = '/2/filters/noResults'; const headers: Headers = { Accept: 'application/json' }; const queryParameters: Record = {}; @@ -995,7 +997,7 @@ export class AnalyticsApi { limit?: number, offset?: number, tags?: string - ): Promise> { + ): Promise { const path = '/2/filters/noResults?search={search}'.replace( '{search}', encodeURIComponent(String(search)) diff --git a/specs/analytics/paths/common/schemas/getTopFilterAttributes.yml b/specs/analytics/paths/common/schemas/getTopFilterAttributes.yml index 80a6a9679d..bdd65a4e45 100644 --- a/specs/analytics/paths/common/schemas/getTopFilterAttributes.yml +++ b/specs/analytics/paths/common/schemas/getTopFilterAttributes.yml @@ -9,9 +9,9 @@ getTopFilterAttributesResponse: type: array description: A list of attributes with their count. items: - $ref: '#/getTopFilterAttributes' + $ref: '#/getTopFilterAttribute' -getTopFilterAttributes: +getTopFilterAttribute: type: object additionalProperties: false required: diff --git a/specs/analytics/paths/common/schemas/getTopFiltersNoResults.yml b/specs/analytics/paths/common/schemas/getTopFiltersNoResults.yml index 48af278ab2..80043b114e 100644 --- a/specs/analytics/paths/common/schemas/getTopFiltersNoResults.yml +++ b/specs/analytics/paths/common/schemas/getTopFiltersNoResults.yml @@ -22,17 +22,21 @@ getTopFiltersNoResultsValues: $ref: '../parameters.yml#/count' values: type: array + description: A list of filters without results. items: - type: object - additionalProperties: false - required: - - attribute - - operator - - value - properties: - attribute: - $ref: '../parameters.yml#/attribute' - operator: - $ref: '../parameters.yml#/operator' - value: - $ref: '../parameters.yml#/value' + $ref: '#/getTopFiltersNoResultsValue' + +getTopFiltersNoResultsValue: + type: object + additionalProperties: false + required: + - attribute + - operator + - value + properties: + attribute: + $ref: '../parameters.yml#/attribute' + operator: + $ref: '../parameters.yml#/operator' + value: + $ref: '../parameters.yml#/value' diff --git a/specs/analytics/paths/search/getTopFilterAttributes.yml b/specs/analytics/paths/search/getTopFilterAttributes.yml index 908abc06a1..340fc201de 100644 --- a/specs/analytics/paths/search/getTopFilterAttributes.yml +++ b/specs/analytics/paths/search/getTopFilterAttributes.yml @@ -17,7 +17,7 @@ get: content: application/json: schema: - $ref: '../common/schemas/getTopFilterAttributes.yml' + $ref: '../common/schemas/getTopFilterAttributes.yml#/getTopFilterAttributesResponse' '400': $ref: '../../../common/responses/BadRequest.yml' '402': diff --git a/specs/analytics/paths/search/getTopFilterAttributesForSearch.yml b/specs/analytics/paths/search/getTopFilterAttributesForSearch.yml index d43af5dcff..4e17faf84a 100644 --- a/specs/analytics/paths/search/getTopFilterAttributesForSearch.yml +++ b/specs/analytics/paths/search/getTopFilterAttributesForSearch.yml @@ -1,7 +1,7 @@ get: tags: - analytics - operationId: getTopFilterAttributes + operationId: getTopFilterAttributesForSearch description: Returns top filter attributes for a given search. Limited to the 1000 most used filters. summary: Returns top filter attributes for a given search. parameters: @@ -18,7 +18,7 @@ get: content: application/json: schema: - $ref: '../common/schemas/getTopFilterAttributes.yml' + $ref: '../common/schemas/getTopFilterAttributes.yml#/getTopFilterAttributesResponse' '400': $ref: '../../../common/responses/BadRequest.yml' '402': diff --git a/specs/analytics/paths/search/getTopFiltersNoResults.yml b/specs/analytics/paths/search/getTopFiltersNoResults.yml index fd1f7e0506..1c61c4e10f 100644 --- a/specs/analytics/paths/search/getTopFiltersNoResults.yml +++ b/specs/analytics/paths/search/getTopFiltersNoResults.yml @@ -17,7 +17,7 @@ get: content: application/json: schema: - $ref: '../common/schemas/getTopFiltersNoResults.yml' + $ref: '../common/schemas/getTopFiltersNoResults.yml#/getTopFiltersNoResultsResponse' '400': $ref: '../../../common/responses/BadRequest.yml' diff --git a/specs/analytics/paths/search/getTopFiltersNoResultsForSearch.yml b/specs/analytics/paths/search/getTopFiltersNoResultsForSearch.yml index a29373963c..adb433a211 100644 --- a/specs/analytics/paths/search/getTopFiltersNoResultsForSearch.yml +++ b/specs/analytics/paths/search/getTopFiltersNoResultsForSearch.yml @@ -18,7 +18,7 @@ get: content: application/json: schema: - $ref: '../common/schemas/getTopFiltersNoResults.yml' + $ref: '../common/schemas/getTopFiltersNoResults.yml#/getTopFiltersNoResultsResponse' '400': $ref: '../../../common/responses/BadRequest.yml' '402': From f9fa2671d292f703927ea299d3201e3df2d34cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Tue, 14 Dec 2021 12:17:50 +0100 Subject: [PATCH 7/9] feat: endpoint with attributes --- .../client-analytics/src/analyticsApi.ts | 83 +++++++++++++++++++ .../getTopFiltersForAttributesSearch.yml | 35 ++++++++ specs/analytics/spec.yml | 4 +- 3 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 specs/analytics/paths/search/getTopFiltersForAttributesSearch.yml diff --git a/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts b/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts index 56a65e2dcd..438c200f55 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts @@ -912,6 +912,89 @@ export class AnalyticsApi { return this.sendRequest(request, requestOptions); } + /** + * Returns top filters for the given attributes and search. Several attributes can be given by separating them with a comma. Several attributes can be given by separating them with a comma. + * + * @summary Returns top filters for the given attributes and search. + * @param attributes - The exact names of the attributes, separated by commas. + * @param index - The index name to target. + * @param search - The query term. Must match the exact user input. + * @param startDate - The lower bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param endDate - The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. + * @param limit - How many items to fetch. + * @param offset - From which position to start retrieving results. + * @param tags - Filter metrics on the provided tags. Each tag must correspond to an analyticsTags set at search time. Multiple tags can be combined with the operators OR and AND. If a tag contains characters like spaces or parentheses, it should be URL encoded. + */ + getTopFiltersForAttributesSearch( + attributes: string, + index: string, + search: string, + startDate?: Date, + endDate?: Date, + limit?: number, + offset?: number, + tags?: string + ): Promise { + const path = '/2/filters/{attributes}?search={search}' + .replace('{attributes}', encodeURIComponent(String(attributes))) + .replace('{search}', encodeURIComponent(String(search))); + const headers: Headers = { Accept: 'application/json' }; + const queryParameters: Record = {}; + + if (attributes === null || attributes === undefined) { + throw new Error( + 'Required parameter attributes was null or undefined when calling getTopFiltersForAttributesSearch.' + ); + } + + if (index === null || index === undefined) { + throw new Error( + 'Required parameter index was null or undefined when calling getTopFiltersForAttributesSearch.' + ); + } + + if (search === null || search === undefined) { + throw new Error( + 'Required parameter search was null or undefined when calling getTopFiltersForAttributesSearch.' + ); + } + + if (index !== undefined) { + queryParameters.index = index.toString(); + } + + if (startDate !== undefined) { + queryParameters.startDate = startDate.toString(); + } + + if (endDate !== undefined) { + queryParameters.endDate = endDate.toString(); + } + + if (limit !== undefined) { + queryParameters.limit = limit.toString(); + } + + if (offset !== undefined) { + queryParameters.offset = offset.toString(); + } + + if (tags !== undefined) { + queryParameters.tags = tags.toString(); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } /** * Returns top filters with no results. Limited to the 1000 most used filters. * diff --git a/specs/analytics/paths/search/getTopFiltersForAttributesSearch.yml b/specs/analytics/paths/search/getTopFiltersForAttributesSearch.yml new file mode 100644 index 0000000000..2d07338f6b --- /dev/null +++ b/specs/analytics/paths/search/getTopFiltersForAttributesSearch.yml @@ -0,0 +1,35 @@ +get: + tags: + - analytics + operationId: getTopFiltersForAttributesSearch + description: Returns top filters for the given attributes and search. Several attributes can be given by separating them with a comma. Several attributes can be given by separating them with a comma. + summary: Returns top filters for the given attributes and search. + parameters: + - in: path + name: attributes + required: true + description: The exact names of the attributes, separated by commas. + schema: + type: string + - $ref: '../../../common/parameters.yml#/Index' + - $ref: '../common/parameters.yml#/SearchInPath' + - $ref: '../../../common/parameters.yml#/StartDate' + - $ref: '../../../common/parameters.yml#/EndDate' + - $ref: '../common/parameters.yml#/Limit' + - $ref: '../common/parameters.yml#/Offset' + - $ref: '../common/parameters.yml#/Tags' + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../common/schemas/getTopFilterAttributes.yml#/getTopFilterAttributesResponse' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/analytics/spec.yml b/specs/analytics/spec.yml index 3557228992..84997696c3 100644 --- a/specs/analytics/spec.yml +++ b/specs/analytics/spec.yml @@ -44,8 +44,8 @@ paths: $ref: './paths/search/getTopFiltersNoResults.yml' /2/filters/noResults?search={search}: $ref: './paths/search/getTopFiltersNoResultsForSearch.yml' - # /2/filters/{attribute list}?search=: - # $ref: './paths/search/getSearchAttributesTolFilters.yml' + /2/filters/{attributes}?search={search}: + $ref: './paths/search/getTopFiltersForAttributesSearch.yml' /2/countries: $ref: './paths/search/getTopCountries.yml' From f0a74fb3a60527aceee2b9e9b52e365afd00382c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Tue, 14 Dec 2021 12:26:34 +0100 Subject: [PATCH 8/9] fix: make naming consistent --- ...eValues.ts => getTopFilterForAttribute.ts} | 2 +- .../model/getTopFilterForAttributeResponse.ts | 4 +-- .../model/getTopHitsResponse.ts | 8 +++++ ...ponseHits.ts => getTopHitsResponseHits.ts} | 2 +- .../model/getTopHitsResponseWithAnalytics.ts | 8 +++++ ...=> getTopHitsResponseWithAnalyticsHits.ts} | 2 +- ...sResponse.ts => getTopSearchesResponse.ts} | 2 +- .../getTopSearchesResponseWithAnalytics.ts | 8 +++++ ...pSearchesResponseWithAnalyticsSearches.ts} | 2 +- .../client-analytics/model/models.ts | 16 +++++----- .../client-analytics/model/topHitsReponse.ts | 8 ----- .../model/topHitsResponseWithAnalytics.ts | 8 ----- .../model/topSearchesResponseWithAnalytics.ts | 8 ----- .../client-analytics/src/analyticsApi.ts | 16 +++++----- .../common/schemas/getTopFilterAttributes.yml | 1 - .../schemas/getTopFilterForAttribute.yml | 29 +++++++++++++++++++ .../common/schemas/getTopFiltersNoResults.yml | 1 - .../paths/common/schemas/getTopHits.yml | 6 ++-- .../paths/common/schemas/getTopSearches.yml | 6 ++-- .../paths/search/getTopFilterForAttribute.yml | 27 +---------------- .../getTopFiltersForAttributesSearch.yml | 2 +- specs/analytics/paths/search/getTopHits.yml | 4 +-- .../paths/search/getTopHitsForSearch.yml | 4 +-- .../analytics/paths/search/getTopSearches.yml | 4 +-- 24 files changed, 88 insertions(+), 90 deletions(-) rename clients/algoliasearch-client-javascript/client-analytics/model/{getTopFilterForAttributeResponseValues.ts => getTopFilterForAttribute.ts} (80%) create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopHitsResponse.ts rename clients/algoliasearch-client-javascript/client-analytics/model/{topHitsReponseHits.ts => getTopHitsResponseHits.ts} (72%) create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopHitsResponseWithAnalytics.ts rename clients/algoliasearch-client-javascript/client-analytics/model/{topHitsResponseWithAnalyticsHits.ts => getTopHitsResponseWithAnalyticsHits.ts} (89%) rename clients/algoliasearch-client-javascript/client-analytics/model/{topSearchesResponse.ts => getTopSearchesResponse.ts} (84%) create mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/getTopSearchesResponseWithAnalytics.ts rename clients/algoliasearch-client-javascript/client-analytics/model/{topSearchesResponseWithAnalyticsSearches.ts => getTopSearchesResponseWithAnalyticsSearches.ts} (91%) delete mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/topHitsReponse.ts delete mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/topHitsResponseWithAnalytics.ts delete mode 100644 clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponseWithAnalytics.ts create mode 100644 specs/analytics/paths/common/schemas/getTopFilterForAttribute.yml diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterForAttributeResponseValues.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterForAttribute.ts similarity index 80% rename from clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterForAttributeResponseValues.ts rename to clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterForAttribute.ts index 0933aa03e7..501a4298a1 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterForAttributeResponseValues.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterForAttribute.ts @@ -1,4 +1,4 @@ -export type GetTopFilterForAttributeResponseValues = { +export type GetTopFilterForAttribute = { /** * The attribute. */ diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterForAttributeResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterForAttributeResponse.ts index e85bb54c02..982de7c3ce 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterForAttributeResponse.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopFilterForAttributeResponse.ts @@ -1,8 +1,8 @@ -import type { GetTopFilterForAttributeResponseValues } from './getTopFilterForAttributeResponseValues'; +import type { GetTopFilterForAttribute } from './getTopFilterForAttribute'; export type GetTopFilterForAttributeResponse = { /** * A list of filters for the given attributes. */ - values: GetTopFilterForAttributeResponseValues[]; + values: GetTopFilterForAttribute[]; }; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopHitsResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopHitsResponse.ts new file mode 100644 index 0000000000..454261b174 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopHitsResponse.ts @@ -0,0 +1,8 @@ +import type { GetTopHitsResponseHits } from './getTopHitsResponseHits'; + +export type GetTopHitsResponse = { + /** + * A list of top hits with their count. + */ + hits: GetTopHitsResponseHits[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/topHitsReponseHits.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopHitsResponseHits.ts similarity index 72% rename from clients/algoliasearch-client-javascript/client-analytics/model/topHitsReponseHits.ts rename to clients/algoliasearch-client-javascript/client-analytics/model/getTopHitsResponseHits.ts index b7b376c1cc..4a24c30a21 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/topHitsReponseHits.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopHitsResponseHits.ts @@ -1,4 +1,4 @@ -export type TopHitsReponseHits = { +export type GetTopHitsResponseHits = { /** * The hit. */ diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopHitsResponseWithAnalytics.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopHitsResponseWithAnalytics.ts new file mode 100644 index 0000000000..254e062bd1 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopHitsResponseWithAnalytics.ts @@ -0,0 +1,8 @@ +import type { GetTopHitsResponseWithAnalyticsHits } from './getTopHitsResponseWithAnalyticsHits'; + +export type GetTopHitsResponseWithAnalytics = { + /** + * A list of top hits with their count and analytics. + */ + hits: GetTopHitsResponseWithAnalyticsHits[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/topHitsResponseWithAnalyticsHits.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopHitsResponseWithAnalyticsHits.ts similarity index 89% rename from clients/algoliasearch-client-javascript/client-analytics/model/topHitsResponseWithAnalyticsHits.ts rename to clients/algoliasearch-client-javascript/client-analytics/model/getTopHitsResponseWithAnalyticsHits.ts index ce8afdbb2a..0a117f396f 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/topHitsResponseWithAnalyticsHits.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopHitsResponseWithAnalyticsHits.ts @@ -1,4 +1,4 @@ -export type TopHitsResponseWithAnalyticsHits = { +export type GetTopHitsResponseWithAnalyticsHits = { /** * The hit. */ diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopSearchesResponse.ts similarity index 84% rename from clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponse.ts rename to clients/algoliasearch-client-javascript/client-analytics/model/getTopSearchesResponse.ts index 2dabac55c6..cc805fa4e6 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponse.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopSearchesResponse.ts @@ -1,6 +1,6 @@ import type { GetSearchesNoResultsResponseSearches } from './getSearchesNoResultsResponseSearches'; -export type TopSearchesResponse = { +export type GetTopSearchesResponse = { /** * A list of top searches with their count. */ diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getTopSearchesResponseWithAnalytics.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopSearchesResponseWithAnalytics.ts new file mode 100644 index 0000000000..78fad12f8b --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopSearchesResponseWithAnalytics.ts @@ -0,0 +1,8 @@ +import type { GetTopSearchesResponseWithAnalyticsSearches } from './getTopSearchesResponseWithAnalyticsSearches'; + +export type GetTopSearchesResponseWithAnalytics = { + /** + * A list of top searches with their count and analytics. + */ + searches: GetTopSearchesResponseWithAnalyticsSearches[]; +}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponseWithAnalyticsSearches.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getTopSearchesResponseWithAnalyticsSearches.ts similarity index 91% rename from clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponseWithAnalyticsSearches.ts rename to clients/algoliasearch-client-javascript/client-analytics/model/getTopSearchesResponseWithAnalyticsSearches.ts index af52de5a07..dca7dd1d3a 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponseWithAnalyticsSearches.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getTopSearchesResponseWithAnalyticsSearches.ts @@ -1,4 +1,4 @@ -export type TopSearchesResponseWithAnalyticsSearches = { +export type GetTopSearchesResponseWithAnalyticsSearches = { /** * The search query. */ diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/models.ts b/clients/algoliasearch-client-javascript/client-analytics/model/models.ts index d6b059bd49..f651efbaeb 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/models.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/models.ts @@ -25,19 +25,19 @@ export * from './getTopCountriesResponse'; export * from './getTopCountriesResponseCountries'; export * from './getTopFilterAttribute'; export * from './getTopFilterAttributesResponse'; +export * from './getTopFilterForAttribute'; export * from './getTopFilterForAttributeResponse'; -export * from './getTopFilterForAttributeResponseValues'; export * from './getTopFiltersNoResultsResponse'; export * from './getTopFiltersNoResultsValue'; export * from './getTopFiltersNoResultsValues'; +export * from './getTopHitsResponse'; +export * from './getTopHitsResponseHits'; +export * from './getTopHitsResponseWithAnalytics'; +export * from './getTopHitsResponseWithAnalyticsHits'; +export * from './getTopSearchesResponse'; +export * from './getTopSearchesResponseWithAnalytics'; +export * from './getTopSearchesResponseWithAnalyticsSearches'; export * from './getUsersCountResponse'; -export * from './topHitsReponse'; -export * from './topHitsReponseHits'; -export * from './topHitsResponseWithAnalytics'; -export * from './topHitsResponseWithAnalyticsHits'; -export * from './topSearchesResponse'; -export * from './topSearchesResponseWithAnalytics'; -export * from './topSearchesResponseWithAnalyticsSearches'; export interface Authentication { /** diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/topHitsReponse.ts b/clients/algoliasearch-client-javascript/client-analytics/model/topHitsReponse.ts deleted file mode 100644 index 4f441337cc..0000000000 --- a/clients/algoliasearch-client-javascript/client-analytics/model/topHitsReponse.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { TopHitsReponseHits } from './topHitsReponseHits'; - -export type TopHitsReponse = { - /** - * A list of top hits with their count. - */ - hits: TopHitsReponseHits[]; -}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/topHitsResponseWithAnalytics.ts b/clients/algoliasearch-client-javascript/client-analytics/model/topHitsResponseWithAnalytics.ts deleted file mode 100644 index fb2b5d3db9..0000000000 --- a/clients/algoliasearch-client-javascript/client-analytics/model/topHitsResponseWithAnalytics.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { TopHitsResponseWithAnalyticsHits } from './topHitsResponseWithAnalyticsHits'; - -export type TopHitsResponseWithAnalytics = { - /** - * A list of top hits with their count and analytics. - */ - hits: TopHitsResponseWithAnalyticsHits[]; -}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponseWithAnalytics.ts b/clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponseWithAnalytics.ts deleted file mode 100644 index 1a58b7a9d8..0000000000 --- a/clients/algoliasearch-client-javascript/client-analytics/model/topSearchesResponseWithAnalytics.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { TopSearchesResponseWithAnalyticsSearches } from './topSearchesResponseWithAnalyticsSearches'; - -export type TopSearchesResponseWithAnalytics = { - /** - * A list of top searches with their count and analytics. - */ - searches: TopSearchesResponseWithAnalyticsSearches[]; -}; diff --git a/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts b/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts index 438c200f55..d9b94350a3 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/src/analyticsApi.ts @@ -12,12 +12,12 @@ import type { GetTopCountriesResponse } from '../model/getTopCountriesResponse'; import type { GetTopFilterAttributesResponse } from '../model/getTopFilterAttributesResponse'; import type { GetTopFilterForAttributeResponse } from '../model/getTopFilterForAttributeResponse'; import type { GetTopFiltersNoResultsResponse } from '../model/getTopFiltersNoResultsResponse'; +import type { GetTopHitsResponse } from '../model/getTopHitsResponse'; +import type { GetTopHitsResponseWithAnalytics } from '../model/getTopHitsResponseWithAnalytics'; +import type { GetTopSearchesResponse } from '../model/getTopSearchesResponse'; +import type { GetTopSearchesResponseWithAnalytics } from '../model/getTopSearchesResponseWithAnalytics'; import type { GetUsersCountResponse } from '../model/getUsersCountResponse'; import { ApiKeyAuth } from '../model/models'; -import type { TopHitsReponse } from '../model/topHitsReponse'; -import type { TopHitsResponseWithAnalytics } from '../model/topHitsResponseWithAnalytics'; -import type { TopSearchesResponse } from '../model/topSearchesResponse'; -import type { TopSearchesResponseWithAnalytics } from '../model/topSearchesResponseWithAnalytics'; import { Transporter } from '../utils/Transporter'; import type { Requester } from '../utils/requester/Requester'; import type { Headers, Host, Request, RequestOptions } from '../utils/types'; @@ -934,7 +934,7 @@ export class AnalyticsApi { limit?: number, offset?: number, tags?: string - ): Promise { + ): Promise { const path = '/2/filters/{attributes}?search={search}' .replace('{attributes}', encodeURIComponent(String(attributes))) .replace('{search}', encodeURIComponent(String(search))); @@ -1156,7 +1156,7 @@ export class AnalyticsApi { limit?: number, offset?: number, tags?: string - ): Promise { + ): Promise { const path = '/2/hits'; const headers: Headers = { Accept: 'application/json' }; const queryParameters: Record = {}; @@ -1229,7 +1229,7 @@ export class AnalyticsApi { limit?: number, offset?: number, tags?: string - ): Promise { + ): Promise { const path = '/2/hits?search={search}'.replace( '{search}', encodeURIComponent(String(search)) @@ -1313,7 +1313,7 @@ export class AnalyticsApi { limit?: number, offset?: number, tags?: string - ): Promise { + ): Promise { const path = '/2/searches'; const headers: Headers = { Accept: 'application/json' }; const queryParameters: Record = {}; diff --git a/specs/analytics/paths/common/schemas/getTopFilterAttributes.yml b/specs/analytics/paths/common/schemas/getTopFilterAttributes.yml index bdd65a4e45..f30b0af0be 100644 --- a/specs/analytics/paths/common/schemas/getTopFilterAttributes.yml +++ b/specs/analytics/paths/common/schemas/getTopFilterAttributes.yml @@ -1,5 +1,4 @@ getTopFilterAttributesResponse: - title: getTopFilterAttributesResponse type: object additionalProperties: false required: diff --git a/specs/analytics/paths/common/schemas/getTopFilterForAttribute.yml b/specs/analytics/paths/common/schemas/getTopFilterForAttribute.yml new file mode 100644 index 0000000000..bcc08813eb --- /dev/null +++ b/specs/analytics/paths/common/schemas/getTopFilterForAttribute.yml @@ -0,0 +1,29 @@ +getTopFilterForAttributeResponse: + type: object + additionalProperties: false + required: + - values + properties: + values: + type: array + description: A list of filters for the given attributes. + items: + $ref: '#/getTopFilterForAttribute' + +getTopFilterForAttribute: + type: object + additionalProperties: false + required: + - operator + - attribute + - value + - count + properties: + attribute: + $ref: '../parameters.yml#/attribute' + operator: + $ref: '../parameters.yml#/operator' + value: + $ref: '../parameters.yml#/value' + count: + $ref: '../parameters.yml#/count' diff --git a/specs/analytics/paths/common/schemas/getTopFiltersNoResults.yml b/specs/analytics/paths/common/schemas/getTopFiltersNoResults.yml index 80043b114e..610e63a061 100644 --- a/specs/analytics/paths/common/schemas/getTopFiltersNoResults.yml +++ b/specs/analytics/paths/common/schemas/getTopFiltersNoResults.yml @@ -1,5 +1,4 @@ getTopFiltersNoResultsResponse: - title: getTopFiltersNoResultsResponse type: object additionalProperties: false required: diff --git a/specs/analytics/paths/common/schemas/getTopHits.yml b/specs/analytics/paths/common/schemas/getTopHits.yml index 550446e9a1..6077ad0ad6 100644 --- a/specs/analytics/paths/common/schemas/getTopHits.yml +++ b/specs/analytics/paths/common/schemas/getTopHits.yml @@ -1,5 +1,4 @@ -topHitsReponse: - title: getTopHitsResponse +getTopHitsResponse: type: object additionalProperties: false required: @@ -20,8 +19,7 @@ topHitsReponse: count: $ref: '../parameters.yml#/count' -topHitsResponseWithAnalytics: - title: getTopHitsResponseWithAnalytics +getTopHitsResponseWithAnalytics: type: object additionalProperties: false required: diff --git a/specs/analytics/paths/common/schemas/getTopSearches.yml b/specs/analytics/paths/common/schemas/getTopSearches.yml index 1e17932d9b..4a5535cf7a 100644 --- a/specs/analytics/paths/common/schemas/getTopSearches.yml +++ b/specs/analytics/paths/common/schemas/getTopSearches.yml @@ -1,5 +1,4 @@ -topSearchesResponse: - title: getTopSearchesResponse +getTopSearchesResponse: type: object additionalProperties: false required: @@ -23,8 +22,7 @@ topSearchesResponse: nbHits: $ref: '../parameters.yml#/nbHits' -topSearchesResponseWithAnalytics: - title: getTopSearchesResponseWithAnalytics +getTopSearchesResponseWithAnalytics: type: object additionalProperties: false required: diff --git a/specs/analytics/paths/search/getTopFilterForAttribute.yml b/specs/analytics/paths/search/getTopFilterForAttribute.yml index 76abf94c1f..af79b7fef0 100644 --- a/specs/analytics/paths/search/getTopFilterForAttribute.yml +++ b/specs/analytics/paths/search/getTopFilterForAttribute.yml @@ -18,32 +18,7 @@ get: content: application/json: schema: - title: getTopFilterForAttributeResponse - type: object - additionalProperties: false - required: - - values - properties: - values: - type: array - description: A list of filters for the given attributes. - items: - type: object - additionalProperties: false - required: - - operator - - attribute - - value - - count - properties: - attribute: - $ref: '../common/parameters.yml#/attribute' - operator: - $ref: '../common/parameters.yml#/operator' - value: - $ref: '../common/parameters.yml#/value' - count: - $ref: '../common/parameters.yml#/count' + $ref: '../common/schemas/getTopFilterForAttribute.yml#/getTopFilterForAttributeResponse' '400': $ref: '../../../common/responses/BadRequest.yml' '402': diff --git a/specs/analytics/paths/search/getTopFiltersForAttributesSearch.yml b/specs/analytics/paths/search/getTopFiltersForAttributesSearch.yml index 2d07338f6b..06e3ad7b20 100644 --- a/specs/analytics/paths/search/getTopFiltersForAttributesSearch.yml +++ b/specs/analytics/paths/search/getTopFiltersForAttributesSearch.yml @@ -24,7 +24,7 @@ get: content: application/json: schema: - $ref: '../common/schemas/getTopFilterAttributes.yml#/getTopFilterAttributesResponse' + $ref: '../common/schemas/getTopFilterForAttribute.yml#/getTopFilterForAttributeResponse' '400': $ref: '../../../common/responses/BadRequest.yml' '402': diff --git a/specs/analytics/paths/search/getTopHits.yml b/specs/analytics/paths/search/getTopHits.yml index 09631cf12b..9772ac391c 100644 --- a/specs/analytics/paths/search/getTopHits.yml +++ b/specs/analytics/paths/search/getTopHits.yml @@ -19,8 +19,8 @@ get: application/json: schema: oneOf: - - $ref: '../common/schemas/getTopHits.yml#/topHitsReponse' - - $ref: '../common/schemas/getTopHits.yml#/topHitsResponseWithAnalytics' + - $ref: '../common/schemas/getTopHits.yml#/getTopHitsResponse' + - $ref: '../common/schemas/getTopHits.yml#/getTopHitsResponseWithAnalytics' '400': $ref: '../../../common/responses/BadRequest.yml' '402': diff --git a/specs/analytics/paths/search/getTopHitsForSearch.yml b/specs/analytics/paths/search/getTopHitsForSearch.yml index 7bfb0ff28d..393217b069 100644 --- a/specs/analytics/paths/search/getTopHitsForSearch.yml +++ b/specs/analytics/paths/search/getTopHitsForSearch.yml @@ -20,8 +20,8 @@ get: application/json: schema: oneOf: - - $ref: '../common/schemas/getTopHits.yml#/topHitsReponse' - - $ref: '../common/schemas/getTopHits.yml#/topHitsResponseWithAnalytics' + - $ref: '../common/schemas/getTopHits.yml#/getTopHitsResponse' + - $ref: '../common/schemas/getTopHits.yml#/getTopHitsResponseWithAnalytics' '400': $ref: '../../../common/responses/BadRequest.yml' '402': diff --git a/specs/analytics/paths/search/getTopSearches.yml b/specs/analytics/paths/search/getTopSearches.yml index c516eb234d..d22c1e7d55 100644 --- a/specs/analytics/paths/search/getTopSearches.yml +++ b/specs/analytics/paths/search/getTopSearches.yml @@ -21,8 +21,8 @@ get: application/json: schema: oneOf: - - $ref: '../common/schemas/getTopSearches.yml#/topSearchesResponse' - - $ref: '../common/schemas/getTopSearches.yml#/topSearchesResponseWithAnalytics' + - $ref: '../common/schemas/getTopSearches.yml#/getTopSearchesResponse' + - $ref: '../common/schemas/getTopSearches.yml#/getTopSearchesResponseWithAnalytics' '400': $ref: '../../../common/responses/BadRequest.yml' '402': From 38385de345fb02c9f304061b2492b35e4187969d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Wed, 15 Dec 2021 10:32:54 +0100 Subject: [PATCH 9/9] apply changes from suggestion --- .../model/getClickPositionsResponsePositions.ts | 4 ++-- specs/analytics/paths/click/getClickPositions.yml | 3 +++ specs/analytics/paths/search/getTopFiltersNoResults.yml | 1 - specs/common/parameters.yml | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/clients/algoliasearch-client-javascript/client-analytics/model/getClickPositionsResponsePositions.ts b/clients/algoliasearch-client-javascript/client-analytics/model/getClickPositionsResponsePositions.ts index cdb591fa05..639a2fafec 100644 --- a/clients/algoliasearch-client-javascript/client-analytics/model/getClickPositionsResponsePositions.ts +++ b/clients/algoliasearch-client-javascript/client-analytics/model/getClickPositionsResponsePositions.ts @@ -2,9 +2,9 @@ export type GetClickPositionsResponsePositions = { /** * Range of positions with the following pattern: Positions from 1 to 10 included are displayed in separated groups. Positions from 11 to 20 included are grouped together. Positions from 21 and up are grouped together. */ - position?: number[]; + position: number[]; /** * The number of click event. */ - clickCount?: number; + clickCount: number; }; diff --git a/specs/analytics/paths/click/getClickPositions.yml b/specs/analytics/paths/click/getClickPositions.yml index 854fef7804..f7d444120d 100644 --- a/specs/analytics/paths/click/getClickPositions.yml +++ b/specs/analytics/paths/click/getClickPositions.yml @@ -29,6 +29,9 @@ get: items: type: object additionalProperties: false + required: + - position + - clickCount properties: position: description: | diff --git a/specs/analytics/paths/search/getTopFiltersNoResults.yml b/specs/analytics/paths/search/getTopFiltersNoResults.yml index 1c61c4e10f..a33b70ff90 100644 --- a/specs/analytics/paths/search/getTopFiltersNoResults.yml +++ b/specs/analytics/paths/search/getTopFiltersNoResults.yml @@ -18,7 +18,6 @@ get: application/json: schema: $ref: '../common/schemas/getTopFiltersNoResults.yml#/getTopFiltersNoResultsResponse' - '400': $ref: '../../../common/responses/BadRequest.yml' '402': diff --git a/specs/common/parameters.yml b/specs/common/parameters.yml index bdab1de291..1cfcf33937 100644 --- a/specs/common/parameters.yml +++ b/specs/common/parameters.yml @@ -37,7 +37,7 @@ StartDate: EndDate: in: query name: endDate - description: The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze + description: The upper bound timestamp (a date, a string like “2006-01-02”) of the period to analyze. schema: type: string format: date-time