devstar插件

This commit is contained in:
2025-07-26 16:40:29 +08:00
commit 30033daafe
4387 changed files with 1041101 additions and 0 deletions

21
node_modules/search-insights/LICENSE.md generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015-present Algolia, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

88
node_modules/search-insights/README.md generated vendored Normal file
View File

@@ -0,0 +1,88 @@
# Search Insights
[![Build Status](https://circleci.com/gh/algolia/search-insights.js.svg?style=shield)](https://github.com/algolia/search-insights.js)
[![npm version](https://badge.fury.io/js/search-insights.svg)](https://badge.fury.io/js/search-insights)
Search Insights lets you report click, conversion and view metrics using the [Algolia Insights API](https://www.algolia.com/doc/rest-api/insights/#overview).
## Table of Contents
<!-- toc -->
- [Notices](#notices)
- [Cookie usage](#cookie-usage)
- [Payload validation](#payload-validation)
- [Getting started](#getting-started)
- [Browser](#browser)
- [Node.js](#nodejs)
- [Documentation](#documentation)
- [Contributing](#contributing)
- [Releasing](#releasing)
- [License](#license)
<!-- tocstop -->
> **NOTE:** You're looking at the documentation of `search-insights` v2. (_Click [here](https://github.com/algolia/search-insights.js/blob/v1/README.md) for v1.x documentation._)
## Notices
### Cookie usage
v2 introduces a breaking change which is `useCookie` being `false` by default.
### Payload validation
Since v2.0.4, search-insights no longer validates event payloads.
You can visit https://algolia.com/events/debugger instead.
---
## Getting started
> We have created dedicated integrations for Google Tag Manager and Segment. If you are using either of these platforms,
> it is recommended to use the dedicated integrations to manage sending events to the [Insights API][insights-api].
>
> - [Google Tag Manager](https://www.algolia.com/doc/guides/sending-events/connectors/google-tag-manager/)
> - [Segment](https://www.algolia.com/doc/guides/sending-events/connectors/segment/)
### Browser
For information on how to set up `search-insights.js` in a browser environment, see our documentation on [Installing and Initializing the Insights Client][insights-js-docs].
We also have documentation for using `search-insights.js` with [InstantSearch][instantsearch] and [Autocomplete][autocomplete].
- For information on using `search-insights.js` with [InstantSearch][instantsearch], see our documentation on [Sending click and conversion events with InstantSearch.js][instantsearch-guide].
- For information on using `search-insights.js` with [Autocomplete][autocomplete], see our documentation on [Sending Algolia Insights events with Autocomplete][autocomplete-guide].
> **NOTE:** If you are using [Require.js](https://requirejs.org/), see our [Note for Require.js users](./docs/requirejs.md).
### Node.js
For information on how to set up `search-insights.js` in a Node.js environment, see our guide on [Installing and Initializing the Insights Client for Node.js](./docs/nodejs.md).
[insights-api]: https://www.algolia.com/doc/rest-api/insights/
[insights-js-docs]: https://www.algolia.com/doc/api-client/methods/insights/#install-the-insights-client
[instantsearch]: https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/js/
[instantsearch-guide]: https://www.algolia.com/doc/guides/building-search-ui/events/js/
[autocomplete]: https://www.algolia.com/doc/ui-libraries/autocomplete/introduction/what-is-autocomplete/
[autocomplete-guide]: https://www.algolia.com/doc/ui-libraries/autocomplete/guides/sending-algolia-insights-events/
## Documentation
Documentation for `search-insights.js` can be found in our main [Algolia Docs](https://algolia.com/docs) website.
For API Client reference information, see the [Insights API Client Documentation](https://www.algolia.com/doc/api-client/methods/insights/).
## Contributing
To run the examples and the code, you need to run two separate commands:
- `yarn dev` runs webpack and the Node.js server
- `yarn build:dev` runs Rollup in watch mode
### Releasing
For information on releasing, see [RELEASE.md](./RELEASE.md).
## License
Search Insights is [MIT licensed](LICENSE.md).

3
node_modules/search-insights/dist/_addEventType.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import type { InsightsEvent, InsightsEventConversionSubType, InsightsEventType } from "./types";
export declare function addEventType(eventType: InsightsEventType, params: Array<Omit<InsightsEvent, "eventType">>): InsightsEvent[];
export declare function addEventTypeAndSubtype(eventType: InsightsEventType, eventSubtype: InsightsEventConversionSubType, params: Array<Omit<InsightsEvent, "eventSubtype" | "eventType">>): InsightsEvent[];

2
node_modules/search-insights/dist/_addQueryId.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
import type { InsightsEvent } from "./types";
export declare function addQueryId(events: InsightsEvent[]): InsightsEvent[];

3
node_modules/search-insights/dist/_algoliaAgent.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import type AlgoliaAnalytics from "./insights";
export declare const DEFAULT_ALGOLIA_AGENTS: string[];
export declare function addAlgoliaAgent(this: AlgoliaAnalytics, algoliaAgent: string): void;

View File

@@ -0,0 +1,3 @@
import type { InsightsClient } from "./types";
import type { RequestFnType } from "./utils/request";
export declare function createInsightsClient(requestFn: RequestFnType): InsightsClient;

View File

@@ -0,0 +1,3 @@
import type AlgoliaAnalytics from "./insights";
import type { InsightsClient } from "./types";
export declare function getFunctionalInterface(instance: AlgoliaAnalytics): InsightsClient;

2
node_modules/search-insights/dist/_getVersion.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
import type AlgoliaAnalytics from "./insights";
export declare function getVersion(this: AlgoliaAnalytics, callback?: (version: string) => void): string;

2
node_modules/search-insights/dist/_processQueue.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
import type AlgoliaAnalytics from "./insights";
export declare function processQueue(this: AlgoliaAnalytics, globalObject: any): void;

4
node_modules/search-insights/dist/_sendEvent.d.ts generated vendored Normal file
View File

@@ -0,0 +1,4 @@
import type AlgoliaAnalytics from "./insights";
import type { InsightsAdditionalEventParams, InsightsEvent } from "./types";
import type { RequestFnType } from "./utils/request";
export declare function makeSendEvents(requestFn: RequestFnType): (this: AlgoliaAnalytics, eventData: InsightsEvent[], additionalParams?: InsightsAdditionalEventParams) => Promise<boolean>;

16
node_modules/search-insights/dist/_tokenUtils.d.ts generated vendored Normal file
View File

@@ -0,0 +1,16 @@
import type AlgoliaAnalytics from "./insights";
export declare const MONTH: number;
export declare const getCookie: (name: string) => string;
export declare function checkIfAnonymousToken(token: number | string): boolean;
export declare function saveTokenAsCookie(this: AlgoliaAnalytics): void;
export declare function setAnonymousUserToken(this: AlgoliaAnalytics, inMemory?: boolean): void;
export declare function setUserToken(this: AlgoliaAnalytics, userToken: number | string): number | string;
export declare function getUserToken(this: AlgoliaAnalytics, options?: any, callback?: (err: any, userToken?: number | string) => void): number | string | undefined;
export declare function onUserTokenChange(this: AlgoliaAnalytics, callback?: (userToken?: number | string) => void, options?: {
immediate: boolean;
}): void;
export declare function setAuthenticatedUserToken(this: AlgoliaAnalytics, authenticatedUserToken: number | string | undefined): number | string | undefined;
export declare function getAuthenticatedUserToken(this: AlgoliaAnalytics, options?: any, callback?: (err: any, authenticatedUserToken?: number | string) => void): number | string | undefined;
export declare function onAuthenticatedUserTokenChange(this: AlgoliaAnalytics, callback?: (authenticatedUserToken?: number | string) => void, options?: {
immediate: boolean;
}): void;

31
node_modules/search-insights/dist/click.d.ts generated vendored Normal file
View File

@@ -0,0 +1,31 @@
import type AlgoliaAnalytics from "./insights";
import type { WithAdditionalParams } from "./utils";
export interface InsightsSearchClickEvent {
eventName: string;
userToken?: string;
authenticatedUserToken?: string;
timestamp?: number;
index: string;
queryID: string;
objectIDs: string[];
positions: number[];
}
export declare function clickedObjectIDsAfterSearch(this: AlgoliaAnalytics, ...params: Array<WithAdditionalParams<InsightsSearchClickEvent>>): ReturnType<AlgoliaAnalytics["sendEvents"]>;
export interface InsightsClickObjectIDsEvent {
eventName: string;
userToken?: string;
authenticatedUserToken?: string;
timestamp?: number;
index: string;
objectIDs: string[];
}
export declare function clickedObjectIDs(this: AlgoliaAnalytics, ...params: Array<WithAdditionalParams<InsightsClickObjectIDsEvent>>): ReturnType<AlgoliaAnalytics["sendEvents"]>;
export interface InsightsClickFiltersEvent {
eventName: string;
userToken?: string;
authenticatedUserToken?: string;
timestamp?: number;
index: string;
filters: string[];
}
export declare function clickedFilters(this: AlgoliaAnalytics, ...params: Array<WithAdditionalParams<InsightsClickFiltersEvent>>): ReturnType<AlgoliaAnalytics["sendEvents"]>;

45
node_modules/search-insights/dist/conversion.d.ts generated vendored Normal file
View File

@@ -0,0 +1,45 @@
import type AlgoliaAnalytics from "./insights";
import type { InsightsEvent } from "./types";
import type { WithAdditionalParams } from "./utils";
export interface InsightsSearchConversionEvent {
eventName: string;
userToken?: string;
authenticatedUserToken?: string;
timestamp?: number;
index: string;
queryID: string;
objectIDs: string[];
objectData?: InsightsEvent["objectData"];
value?: InsightsEvent["value"];
currency?: InsightsEvent["currency"];
}
export declare function convertedObjectIDsAfterSearch(this: AlgoliaAnalytics, ...params: Array<WithAdditionalParams<InsightsSearchConversionEvent>>): ReturnType<AlgoliaAnalytics["sendEvents"]>;
export declare function addedToCartObjectIDsAfterSearch(this: AlgoliaAnalytics, ...params: Array<WithAdditionalParams<InsightsSearchConversionEvent>>): ReturnType<AlgoliaAnalytics["sendEvents"]>;
export type InsightsSearchPurchaseEvent = Omit<InsightsSearchConversionEvent, "queryID"> & {
/** @deprecated Use objectData.queryID instead. */
queryID?: string;
};
export declare function purchasedObjectIDsAfterSearch(this: AlgoliaAnalytics, ...params: Array<WithAdditionalParams<InsightsSearchPurchaseEvent>>): ReturnType<AlgoliaAnalytics["sendEvents"]>;
export interface InsightsSearchConversionObjectIDsEvent {
eventName: string;
userToken?: string;
authenticatedUserToken?: string;
timestamp?: number;
index: string;
objectIDs: string[];
objectData?: InsightsEvent["objectData"];
value?: InsightsEvent["value"];
currency?: InsightsEvent["currency"];
}
export declare function convertedObjectIDs(this: AlgoliaAnalytics, ...params: Array<WithAdditionalParams<InsightsSearchConversionObjectIDsEvent>>): ReturnType<AlgoliaAnalytics["sendEvents"]>;
export declare function addedToCartObjectIDs(this: AlgoliaAnalytics, ...params: Array<WithAdditionalParams<InsightsSearchConversionObjectIDsEvent>>): ReturnType<AlgoliaAnalytics["sendEvents"]>;
export declare function purchasedObjectIDs(this: AlgoliaAnalytics, ...params: Array<WithAdditionalParams<InsightsSearchConversionObjectIDsEvent>>): ReturnType<AlgoliaAnalytics["sendEvents"]>;
export interface InsightsSearchConversionFiltersEvent {
eventName: string;
userToken?: string;
authenticatedUserToken?: string;
timestamp?: number;
index: string;
filters: string[];
}
export declare function convertedFilters(this: AlgoliaAnalytics, ...params: Array<WithAdditionalParams<InsightsSearchConversionFiltersEvent>>): ReturnType<AlgoliaAnalytics["sendEvents"]>;

10
node_modules/search-insights/dist/entry-browser.d.ts generated vendored Normal file
View File

@@ -0,0 +1,10 @@
import { createInsightsClient } from "./_createInsightsClient";
import { getFunctionalInterface } from "./_getFunctionalInterface";
import { processQueue } from "./_processQueue";
import AlgoliaAnalytics from "./insights";
import { getRequesterForBrowser } from "./utils/getRequesterForBrowser";
import { LocalStorage } from "./utils/localStorage";
export { createInsightsClient, getRequesterForBrowser, AlgoliaAnalytics, LocalStorage, getFunctionalInterface, processQueue };
export * from "./types";
declare const _default: import("./types").InsightsClient;
export default _default;

10
node_modules/search-insights/dist/entry-node.d.ts generated vendored Normal file
View File

@@ -0,0 +1,10 @@
import { createInsightsClient } from "./_createInsightsClient";
import { getFunctionalInterface } from "./_getFunctionalInterface";
import { processQueue } from "./_processQueue";
import AlgoliaAnalytics from "./insights";
import { getRequesterForNode } from "./utils/getRequesterForNode";
import { LocalStorage } from "./utils/localStorage";
export { createInsightsClient, getRequesterForNode, AlgoliaAnalytics, LocalStorage, getFunctionalInterface, processQueue };
export * from "./types";
declare const _default: import("./types").InsightsClient;
export default _default;

5
node_modules/search-insights/dist/entry-umd.d.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import AlgoliaAnalytics from "./insights";
import type { RequestFnType } from "./utils/request";
export declare function createInsightsClient(requestFn: RequestFnType): AlgoliaAnalytics;
declare const _default: AlgoliaAnalytics;
export default _default;

22
node_modules/search-insights/dist/init.d.ts generated vendored Normal file
View File

@@ -0,0 +1,22 @@
import type AlgoliaAnalytics from "./insights";
type InsightRegion = "de" | "us";
export interface InitParams {
apiKey?: string;
appId?: string;
userHasOptedOut?: boolean;
anonymousUserToken?: boolean;
useCookie?: boolean;
cookieDuration?: number;
region?: InsightRegion;
userToken?: string;
authenticatedUserToken?: string;
partial?: boolean;
host?: string;
}
/**
* Binds credentials and settings to class.
*
* @param options - InitParams.
*/
export declare function init(this: AlgoliaAnalytics, options?: InitParams): void;
export {};

69
node_modules/search-insights/dist/insights.d.ts generated vendored Normal file
View File

@@ -0,0 +1,69 @@
import { addAlgoliaAgent } from "./_algoliaAgent";
import { getVersion } from "./_getVersion";
import { makeSendEvents } from "./_sendEvent";
import { getUserToken, setUserToken, setAnonymousUserToken, onUserTokenChange, setAuthenticatedUserToken, onAuthenticatedUserTokenChange, getAuthenticatedUserToken, saveTokenAsCookie } from "./_tokenUtils";
import { clickedObjectIDsAfterSearch, clickedObjectIDs, clickedFilters } from "./click";
import { convertedObjectIDsAfterSearch, addedToCartObjectIDsAfterSearch, purchasedObjectIDsAfterSearch, convertedObjectIDs, addedToCartObjectIDs, purchasedObjectIDs, convertedFilters } from "./conversion";
import { init } from "./init";
import type { RequestFnType } from "./utils/request";
import { viewedObjectIDs, viewedFilters } from "./view";
type Queue = {
queue: string[][];
};
type AnalyticsFunction = {
[key: string]: (fnName: string, fnArgs: any[]) => void;
};
export type AlgoliaAnalyticsObject = AnalyticsFunction | Queue;
declare global {
interface Window {
AlgoliaAnalyticsObject?: string;
}
}
/**
* AlgoliaAnalytics class.
*/
declare class AlgoliaAnalytics {
_apiKey?: string;
_appId?: string;
_region?: string;
_host?: string;
_endpointOrigin: string;
_anonymousUserToken: boolean;
_userToken?: number | string;
_authenticatedUserToken?: number | string;
_userHasOptedOut: boolean;
_useCookie: boolean;
_cookieDuration: number;
_ua: string[];
_onUserTokenChangeCallback?: (userToken?: number | string) => void;
_onAuthenticatedUserTokenChangeCallback?: (authenticatedUserToken?: number | string) => void;
version: string;
init: typeof init;
getVersion: typeof getVersion;
addAlgoliaAgent: typeof addAlgoliaAgent;
saveTokenAsCookie: typeof saveTokenAsCookie;
setUserToken: typeof setUserToken;
setAnonymousUserToken: typeof setAnonymousUserToken;
getUserToken: typeof getUserToken;
onUserTokenChange: typeof onUserTokenChange;
setAuthenticatedUserToken: typeof setAuthenticatedUserToken;
getAuthenticatedUserToken: typeof getAuthenticatedUserToken;
onAuthenticatedUserTokenChange: typeof onAuthenticatedUserTokenChange;
sendEvents: ReturnType<typeof makeSendEvents>;
clickedObjectIDsAfterSearch: typeof clickedObjectIDsAfterSearch;
clickedObjectIDs: typeof clickedObjectIDs;
clickedFilters: typeof clickedFilters;
convertedObjectIDsAfterSearch: typeof convertedObjectIDsAfterSearch;
purchasedObjectIDsAfterSearch: typeof purchasedObjectIDsAfterSearch;
addedToCartObjectIDsAfterSearch: typeof addedToCartObjectIDsAfterSearch;
convertedObjectIDs: typeof convertedObjectIDs;
addedToCartObjectIDs: typeof addedToCartObjectIDs;
purchasedObjectIDs: typeof purchasedObjectIDs;
convertedFilters: typeof convertedFilters;
viewedObjectIDs: typeof viewedObjectIDs;
viewedFilters: typeof viewedFilters;
constructor({ requestFn }: {
requestFn: RequestFnType;
});
}
export default AlgoliaAnalytics;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,858 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var version="2.17.3";
function extractAdditionalParams(params) {
return params.reduce(function (ref, param) {
var events = ref.events;
var additionalParams = ref.additionalParams;
// Real events all have `index` as a mandatory parameter, which we
// can rely on to distinguish them from additional parameters
if ("index" in param) {
return { additionalParams: additionalParams, events: events.concat( [param]) };
}
return { events: events, additionalParams: param };
}, {
events: [],
additionalParams: undefined
});
}
var supportsCookies = function () {
try {
return Boolean(navigator.cookieEnabled);
}
catch (e) {
return false;
}
};
var supportsNodeHttpModule = function () {
try {
/* eslint-disable @typescript-eslint/no-var-requires */
var ref = require("http");
var nodeHttpRequest = ref.request;
var ref$1 = require("https");
var nodeHttpsRequest = ref$1.request;
/* eslint-enable */
return Boolean(nodeHttpRequest) && Boolean(nodeHttpsRequest);
}
catch (e) {
return false;
}
};
var supportsNativeFetch = function () {
try {
return fetch !== undefined;
}
catch (e) {
return false;
}
};
/**
* A utility class for safely interacting with localStorage.
*/
var LocalStorage = function LocalStorage () {};
LocalStorage.get = function get (key) {
var _a;
var val = (_a = this.store) === null || _a === void 0 ? void 0 : _a.getItem(key);
if (!val) {
return null;
}
try {
return JSON.parse(val);
}
catch (_b) {
return null;
}
};
/**
* Safely set a value in localStorage.
* If the storage is full, this method will catch the error and log a warning.
*
* @param key - String value of the key.
* @param value - Any value to store.
*/
LocalStorage.set = function set (key, value) {
var _a;
try {
(_a = this.store) === null || _a === void 0 ? void 0 : _a.setItem(key, JSON.stringify(value));
}
catch (_b) {
// eslint-disable-next-line no-console
console.error(("Unable to set " + key + " in localStorage, storage may be full."));
}
};
/**
* Remove a value from localStorage.
*
* @param key - String value of the key.
*/
LocalStorage.remove = function remove (key) {
var _a;
(_a = this.store) === null || _a === void 0 ? void 0 : _a.removeItem(key);
};
LocalStorage.store = ensureLocalStorage();
function ensureLocalStorage() {
try {
var testKey = "__test_localStorage__";
globalThis.localStorage.setItem(testKey, testKey);
globalThis.localStorage.removeItem(testKey);
return globalThis.localStorage;
}
catch (_a) {
return undefined;
}
}
var STORE = "AlgoliaObjectQueryCache";
var LIMIT = 5000; // 1 entry is typically no more than 100 bytes, so this is ~500kB worth of data - most browsers allow at least 5MB per origin
var FREE = 1000;
function getCache() {
var _a;
return (_a = LocalStorage.get(STORE)) !== null && _a !== void 0 ? _a : {};
}
function setCache(objectQueryMap) {
LocalStorage.set(STORE, limited(objectQueryMap));
}
function limited(objectQueryMap) {
return Object.keys(objectQueryMap).length > LIMIT
? purgeOldest(objectQueryMap)
: objectQueryMap;
}
function purgeOldest(objectQueryMap) {
var sorted = Object.entries(objectQueryMap).sort(function (ref, ref$1) {
var aTimestamp = ref[1][1];
var bTimestamp = ref$1[1][1];
return bTimestamp - aTimestamp;
});
var newObjectQueryMap = sorted
.slice(0, sorted.length - FREE - 1)
.reduce(function (acc, ref) {
var obj;
var key = ref[0];
var value = ref[1];
return (Object.assign(Object.assign({}, acc), ( obj = {}, obj[key] = value, obj )));
}, {});
return newObjectQueryMap;
}
function makeKey(index, objectID) {
return (index + "_" + objectID);
}
function storeQueryForObject(index, objectID, queryID) {
var objectQueryMap = getCache();
objectQueryMap[makeKey(index, objectID)] = [queryID, Date.now()];
setCache(objectQueryMap);
}
function getQueryForObject(index, objectID) {
return getCache()[makeKey(index, objectID)];
}
function removeQueryForObjects(index, objectIDs) {
var objectQueryMap = getCache();
objectIDs.forEach(function (objectID) {
delete objectQueryMap[makeKey(index, objectID)];
});
setCache(objectQueryMap);
}
// use theses type checking helpers to avoid mistyping "undefind", I mean "undfined"
var isUndefined = function (value) { return typeof value === "undefined"; };
var isNumber = function (value) { return typeof value === "number"; };
/* eslint-disable @typescript-eslint/ban-types */
var isFunction = function (value) { return typeof value === "function"; };
/* eslint-enable */
var isPromise = function (value) { return typeof (value === null || value === void 0 ? void 0 : value.then) === "function"; };
function getFunctionalInterface(instance) {
return function (functionName) {
var functionArguments = [], len = arguments.length - 1;
while ( len-- > 0 ) functionArguments[ len ] = arguments[ len + 1 ];
if (functionName && isFunction(instance[functionName])) {
// @ts-expect-error
return instance[functionName].apply(instance, functionArguments);
}
// eslint-disable-next-line no-console
console.warn(("The method `" + functionName + "` doesn't exist."));
return undefined;
};
}
var DEFAULT_ALGOLIA_AGENTS = [
("insights-js (" + version + ")"),
("insights-js-" + ("node-cjs") + " (" + version + ")")
];
function addAlgoliaAgent(algoliaAgent) {
if (this._ua.indexOf(algoliaAgent) === -1) {
this._ua.push(algoliaAgent);
}
}
function getVersion(callback) {
if (isFunction(callback)) {
callback(this.version);
}
return this.version;
}
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/* global Reflect, Promise */
function __rest(s, e) {
var t = {};
for (var p in s) { if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
{ t[p] = s[p]; } }
if (s != null && typeof Object.getOwnPropertySymbols === "function")
{ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
{ t[p[i]] = s[p[i]]; }
} }
return t;
}
function addQueryId(events) {
return events.map(function (event) {
var _a;
if (!isValidEventForQueryIdLookup(event)) {
return event;
}
var objectIDsWithInferredQueryID = [];
var updatedObjectData = (_a = event.objectIDs) === null || _a === void 0 ? void 0 : _a.map(function (objectID, i) {
var _a, _b;
var objectData = (_a = event.objectData) === null || _a === void 0 ? void 0 : _a[i];
if (objectData === null || objectData === void 0 ? void 0 : objectData.queryID) {
return objectData;
}
var ref = (_b = getQueryForObject(event.index, objectID)) !== null && _b !== void 0 ? _b : [];
var queryID = ref[0];
if (queryID) {
objectIDsWithInferredQueryID.push(objectID);
}
return Object.assign(Object.assign({}, objectData), { queryID: queryID });
});
if (objectIDsWithInferredQueryID.length === 0) {
return event;
}
return Object.assign(Object.assign({}, event), { objectData: updatedObjectData, objectIDsWithInferredQueryID: objectIDsWithInferredQueryID });
});
}
function isValidEventForQueryIdLookup(event) {
return !event.queryID && event.eventType === "conversion";
}
function makeSendEvents(requestFn) {
return function sendEvents(eventData, additionalParams) {
var this$1$1 = this;
var _a, _b;
if (this._userHasOptedOut) {
return Promise.resolve(false);
}
var hasCredentials = (!isUndefined(this._apiKey) && !isUndefined(this._appId)) ||
(((_a = additionalParams === null || additionalParams === void 0 ? void 0 : additionalParams.headers) === null || _a === void 0 ? void 0 : _a["X-Algolia-Application-Id"]) &&
((_b = additionalParams === null || additionalParams === void 0 ? void 0 : additionalParams.headers) === null || _b === void 0 ? void 0 : _b["X-Algolia-API-Key"]));
if (!hasCredentials) {
throw new Error("Before calling any methods on the analytics, you first need to call the 'init' function with appId and apiKey parameters or provide custom credentials in additional parameters.");
}
if (!this._userToken && this._anonymousUserToken) {
this.setAnonymousUserToken(true);
}
var events = ((additionalParams === null || additionalParams === void 0 ? void 0 : additionalParams.inferQueryID) ? addQueryId(eventData) : eventData).map(function (data) {
var _a, _b;
var filters = data.filters;
var rest = __rest(data, ["filters"]);
var payload = Object.assign(Object.assign({}, rest), { userToken: (_a = data === null || data === void 0 ? void 0 : data.userToken) !== null && _a !== void 0 ? _a : this$1$1._userToken, authenticatedUserToken: (_b = data === null || data === void 0 ? void 0 : data.authenticatedUserToken) !== null && _b !== void 0 ? _b : this$1$1._authenticatedUserToken });
if (!isUndefined(filters)) {
payload.filters = filters.map(encodeURIComponent);
}
return payload;
});
if (events.length === 0) {
return Promise.resolve(false);
}
var send = sendRequest(requestFn, this._ua, this._endpointOrigin, events, this._appId, this._apiKey, additionalParams === null || additionalParams === void 0 ? void 0 : additionalParams.headers);
return isPromise(send) ? send.then(purgePurchased(events)) : send;
};
}
function purgePurchased(events) {
return function (sent) {
if (sent) {
events
.filter(function (ref) {
var eventType = ref.eventType;
var eventSubtype = ref.eventSubtype;
var objectIDs = ref.objectIDs;
return eventType === "conversion" &&
eventSubtype === "purchase" &&
(objectIDs === null || objectIDs === void 0 ? void 0 : objectIDs.length);
})
.forEach(function (ref) {
var index = ref.index;
var objectIDs = ref.objectIDs;
return removeQueryForObjects(index, objectIDs);
});
}
return sent;
};
}
// eslint-disable-next-line max-params
function sendRequest(requestFn, userAgents, endpointOrigin, events, appId, apiKey, additionalHeaders) {
if ( additionalHeaders === void 0 ) additionalHeaders = {};
var providedAppId = additionalHeaders["X-Algolia-Application-Id"];
var providedApiKey = additionalHeaders["X-Algolia-API-Key"];
var restHeaders = __rest(additionalHeaders, ["X-Algolia-Application-Id", "X-Algolia-API-Key"]);
// Auth query
var headers = Object.assign({ "X-Algolia-Application-Id": providedAppId !== null && providedAppId !== void 0 ? providedAppId : appId, "X-Algolia-API-Key": providedApiKey !== null && providedApiKey !== void 0 ? providedApiKey : apiKey, "X-Algolia-Agent": encodeURIComponent(userAgents.join("; ")) }, restHeaders);
var queryParameters = Object.keys(headers)
.map(function (key) { return (key + "=" + (headers[key])); })
.join("&");
var reportingURL = endpointOrigin + "/1/events?" + queryParameters;
return requestFn(reportingURL, { events: events });
}
/**
* Create UUID according to
* https://www.ietf.org/rfc/rfc4122.txt.
*
* @returns Generated UUID.
*/
function createUUID() {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
/* eslint-disable no-bitwise */
var r = (Math.random() * 16) | 0;
var v = c === "x" ? r : (r & 0x3) | 0x8;
/* eslint-enable */
return v.toString(16);
});
}
var COOKIE_KEY = "_ALGOLIA";
var MONTH = 30 * 24 * 60 * 60 * 1000;
var setCookie = function (name, value, duration) {
var d = new Date();
d.setTime(d.getTime() + duration);
var expires = "expires=" + (d.toUTCString());
document.cookie = name + "=" + value + ";" + expires + ";path=/";
};
var getCookie = function (name) {
var prefix = name + "=";
var ca = document.cookie.split(";");
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) === " ") {
c = c.substring(1);
}
if (c.indexOf(prefix) === 0) {
return c.substring(prefix.length, c.length);
}
}
return "";
};
function checkIfAnonymousToken(token) {
if (typeof token === "number") {
return false;
}
return token.indexOf("anonymous-") === 0;
}
function saveTokenAsCookie() {
var foundToken = getCookie(COOKIE_KEY);
if (this._userToken &&
(!foundToken || foundToken === "" || foundToken.indexOf("anonymous-") !== 0)) {
setCookie(COOKIE_KEY, this._userToken, this._cookieDuration);
}
}
function setAnonymousUserToken(inMemory) {
if ( inMemory === void 0 ) inMemory = false;
if (inMemory) {
this.setUserToken(("anonymous-" + (createUUID())));
return;
}
if (!supportsCookies()) {
return;
}
var foundToken = getCookie(COOKIE_KEY);
if (!foundToken ||
foundToken === "" ||
foundToken.indexOf("anonymous-") !== 0) {
var savedUserToken = this.setUserToken(("anonymous-" + (createUUID())));
setCookie(COOKIE_KEY, savedUserToken, this._cookieDuration);
}
else {
this.setUserToken(foundToken);
}
}
function setUserToken(userToken) {
this._userToken = userToken;
if (isFunction(this._onUserTokenChangeCallback)) {
this._onUserTokenChangeCallback(this._userToken);
}
return this._userToken;
}
function getUserToken(options, callback) {
if (isFunction(callback)) {
callback(null, this._userToken);
}
return this._userToken;
}
function onUserTokenChange(callback, options) {
this._onUserTokenChangeCallback = callback;
if (options &&
options.immediate &&
isFunction(this._onUserTokenChangeCallback)) {
this._onUserTokenChangeCallback(this._userToken);
}
}
function setAuthenticatedUserToken(authenticatedUserToken) {
this._authenticatedUserToken = authenticatedUserToken;
if (isFunction(this._onAuthenticatedUserTokenChangeCallback)) {
this._onAuthenticatedUserTokenChangeCallback(this._authenticatedUserToken);
}
return this._authenticatedUserToken;
}
function getAuthenticatedUserToken(options, callback) {
if (isFunction(callback)) {
callback(null, this._authenticatedUserToken);
}
return this._authenticatedUserToken;
}
function onAuthenticatedUserTokenChange(callback, options) {
this._onAuthenticatedUserTokenChangeCallback = callback;
if (options &&
options.immediate &&
isFunction(this._onAuthenticatedUserTokenChangeCallback)) {
this._onAuthenticatedUserTokenChangeCallback(this._authenticatedUserToken);
}
}
function addEventType(eventType, params) {
return params.map(function (event) { return (Object.assign({ eventType: eventType }, event)); });
}
function addEventTypeAndSubtype(eventType, eventSubtype, params) {
return params.map(function (event) { return (Object.assign({ eventType: eventType,
eventSubtype: eventSubtype }, event)); });
}
function clickedObjectIDsAfterSearch() {
var this$1$1 = this;
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
events.forEach(function (ref) {
var index = ref.index;
var queryID = ref.queryID;
var objectIDs = ref.objectIDs;
return objectIDs.forEach(function (objectID) { return !this$1$1._userHasOptedOut && storeQueryForObject(index, objectID, queryID); });
});
return this.sendEvents(addEventType("click", events), additionalParams);
}
function clickedObjectIDs() {
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
return this.sendEvents(addEventType("click", events), additionalParams);
}
function clickedFilters() {
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
return this.sendEvents(addEventType("click", events), additionalParams);
}
function convertedObjectIDsAfterSearch() {
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
return this.sendEvents(addEventType("conversion", events), additionalParams);
}
function addedToCartObjectIDsAfterSearch() {
var this$1$1 = this;
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
events.forEach(function (ref) {
var index = ref.index;
var queryID = ref.queryID;
var objectIDs = ref.objectIDs;
var objectData = ref.objectData;
return objectIDs.forEach(function (objectID, i) {
var _a, _b;
var objQueryID = (_b = (_a = objectData === null || objectData === void 0 ? void 0 : objectData[i]) === null || _a === void 0 ? void 0 : _a.queryID) !== null && _b !== void 0 ? _b : queryID;
if (!this$1$1._userHasOptedOut && objQueryID)
{ storeQueryForObject(index, objectID, objQueryID); }
});
});
return this.sendEvents(addEventTypeAndSubtype("conversion", "addToCart", events), additionalParams);
}
function purchasedObjectIDsAfterSearch() {
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
return this.sendEvents(addEventTypeAndSubtype("conversion", "purchase", events), additionalParams);
}
function convertedObjectIDs() {
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
return this.sendEvents(addEventType("conversion", events), additionalParams);
}
function addedToCartObjectIDs() {
var this$1$1 = this;
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
events.forEach(function (ref) {
var index = ref.index;
var objectIDs = ref.objectIDs;
var objectData = ref.objectData;
return objectIDs.forEach(function (objectID, i) {
var _a;
var queryID = (_a = objectData === null || objectData === void 0 ? void 0 : objectData[i]) === null || _a === void 0 ? void 0 : _a.queryID;
if (!this$1$1._userHasOptedOut && queryID)
{ storeQueryForObject(index, objectID, queryID); }
});
});
return this.sendEvents(addEventTypeAndSubtype("conversion", "addToCart", events), additionalParams);
}
function purchasedObjectIDs() {
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
return this.sendEvents(addEventTypeAndSubtype("conversion", "purchase", events), additionalParams);
}
function convertedFilters() {
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
return this.sendEvents(addEventType("conversion", events), additionalParams);
}
var SUPPORTED_REGIONS = ["de", "us"];
/**
* Binds credentials and settings to class.
*
* @param options - InitParams.
*/
function init(options) {
if ( options === void 0 ) options = {};
var _a, _b;
if (!isUndefined(options.region) &&
SUPPORTED_REGIONS.indexOf(options.region) === -1) {
throw new Error(("optional region is incorrect, please provide either one of: " + (SUPPORTED_REGIONS.join(", ")) + "."));
}
if (!isUndefined(options.cookieDuration) &&
(!isNumber(options.cookieDuration) ||
!isFinite(options.cookieDuration) ||
Math.floor(options.cookieDuration) !== options.cookieDuration)) {
throw new Error("optional cookieDuration is incorrect, expected an integer.");
}
/* eslint-disable no-console */
if (process.env.NODE_ENV === "development") {
console.info("Since v2.0.4, search-insights no longer validates event payloads.\nYou can visit https://algolia.com/events/debugger instead.");
}
/* eslint-enable */
setOptions(this, options, {
_userHasOptedOut: Boolean(options.userHasOptedOut),
_region: options.region,
_host: options.host,
_anonymousUserToken: (_a = options.anonymousUserToken) !== null && _a !== void 0 ? _a : true,
_useCookie: (_b = options.useCookie) !== null && _b !== void 0 ? _b : false,
_cookieDuration: options.cookieDuration || 6 * MONTH
});
this._endpointOrigin =
this._host ||
(this._region
? ("https://insights." + (this._region) + ".algolia.io")
: "https://insights.algolia.io");
// user agent
this._ua = [].concat( DEFAULT_ALGOLIA_AGENTS );
if (options.authenticatedUserToken) {
this.setAuthenticatedUserToken(options.authenticatedUserToken);
}
if (options.userToken) {
this.setUserToken(options.userToken);
}
else if (!this._userToken && !this._userHasOptedOut && this._useCookie) {
this.setAnonymousUserToken();
}
else if (checkIfTokenNeedsToBeSaved(this)) {
this.saveTokenAsCookie();
}
}
function setOptions(target, _a, defaultValues) {
var partial = _a.partial;
var options = __rest(_a, ["partial"]);
if (!partial) {
Object.assign(target, defaultValues);
}
Object.assign(target, Object.keys(options).reduce(function (acc, key) {
var obj;
return (Object.assign(Object.assign({}, acc), ( obj = {}, obj[("_" + key)] = options[key], obj )));
}, {}));
}
function checkIfTokenNeedsToBeSaved(target) {
if (target._userToken === undefined) {
return false;
}
return (checkIfAnonymousToken(target._userToken) &&
target._useCookie &&
!target._userHasOptedOut);
}
function viewedObjectIDs() {
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
return this.sendEvents(addEventType("view", events), additionalParams);
}
function viewedFilters() {
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
return this.sendEvents(addEventType("view", events), additionalParams);
}
/**
* AlgoliaAnalytics class.
*/
var AlgoliaAnalytics = function AlgoliaAnalytics(ref) {
var requestFn = ref.requestFn;
this._endpointOrigin = "https://insights.algolia.io";
this._anonymousUserToken = true;
this._userHasOptedOut = false;
this._useCookie = false;
this._cookieDuration = 6 * MONTH;
// user agent
this._ua = [];
this.version = version;
this.sendEvents = makeSendEvents(requestFn).bind(this);
this.init = init.bind(this);
this.addAlgoliaAgent = addAlgoliaAgent.bind(this);
this.saveTokenAsCookie = saveTokenAsCookie.bind(this);
this.setUserToken = setUserToken.bind(this);
this.setAnonymousUserToken = setAnonymousUserToken.bind(this);
this.getUserToken = getUserToken.bind(this);
this.onUserTokenChange = onUserTokenChange.bind(this);
this.setAuthenticatedUserToken = setAuthenticatedUserToken.bind(this);
this.getAuthenticatedUserToken = getAuthenticatedUserToken.bind(this);
this.onAuthenticatedUserTokenChange =
onAuthenticatedUserTokenChange.bind(this);
this.clickedObjectIDsAfterSearch = clickedObjectIDsAfterSearch.bind(this);
this.clickedObjectIDs = clickedObjectIDs.bind(this);
this.clickedFilters = clickedFilters.bind(this);
this.convertedObjectIDsAfterSearch =
convertedObjectIDsAfterSearch.bind(this);
this.purchasedObjectIDsAfterSearch =
purchasedObjectIDsAfterSearch.bind(this);
this.addedToCartObjectIDsAfterSearch =
addedToCartObjectIDsAfterSearch.bind(this);
this.convertedObjectIDs = convertedObjectIDs.bind(this);
this.addedToCartObjectIDs = addedToCartObjectIDs.bind(this);
this.purchasedObjectIDs = purchasedObjectIDs.bind(this);
this.convertedFilters = convertedFilters.bind(this);
this.viewedObjectIDs = viewedObjectIDs.bind(this);
this.viewedFilters = viewedFilters.bind(this);
this.getVersion = getVersion.bind(this);
};
function createInsightsClient(requestFn) {
var aa = getFunctionalInterface(new AlgoliaAnalytics({ requestFn: requestFn }));
if (typeof window === "object") {
if (!window.AlgoliaAnalyticsObject) {
var pointer;
do {
pointer = createUUID();
} while (window[pointer] !== undefined);
window.AlgoliaAnalyticsObject = pointer;
window[window.AlgoliaAnalyticsObject] = aa;
}
}
aa.version = version;
return aa;
}
/**
* Processes queue that might have been set before
* the script was actually loaded and reassigns
* class over globalObject variable to execute commands
* instead of putting them to the queue.
*/
function processQueue(globalObject) {
// Set pointer which allows renaming of the script
var pointer = globalObject.AlgoliaAnalyticsObject;
if (pointer) {
var _aa = getFunctionalInterface(this);
// `aa` is the user facing function, which is defined in the install snippet.
// - before library is initialized `aa` fills a queue
// - after library is initialized `aa` calls `_aa`
var aa = globalObject[pointer];
aa.queue = aa.queue || [];
var queue = aa.queue;
// Loop queue and execute functions in the queue
queue.forEach(function (args) {
var ref = [].slice.call(args);
var functionName = ref[0];
var functionArguments = ref.slice(1);
_aa.apply(void 0, [ functionName ].concat( functionArguments ));
});
/* eslint-disable no-warning-comments */
// FIXME: Reassigning the pointer is a bad idea (cf: https://github.com/algolia/search-insights.js/issues/127)
// to remove this without any breaking change, we redefine the Array.prototype.push method on the queue array.
// for next major version, use a custom method instead of push.
/* eslint-enable */
// @ts-expect-error (otherwise typescript won't let you change the signature)
queue.push = function (args) {
var ref = [].slice.call(args);
var functionName = ref[0];
var functionArguments = ref.slice(1);
_aa.apply(void 0, [ functionName ].concat( functionArguments ));
};
}
}
var requestWithNodeHttpModule = function (url, data) {
return new Promise(function (resolve, reject) {
var serializedData = JSON.stringify(data);
/* eslint-disable @typescript-eslint/no-var-requires */
var ref = require("url").parse(url);
var protocol = ref.protocol;
var host = ref.host;
var path = ref.path;
/* eslint-enable */
var options = {
protocol: protocol,
host: host,
path: path,
method: "POST",
headers: {
"Content-Type": "application/json",
"Content-Length": serializedData.length
}
};
var ref$1 = url.startsWith("https://")
? require("https")
: require("http");
var request = ref$1.request;
var req = request(options, function (ref) {
var statusCode = ref.statusCode;
if (statusCode === 200) {
resolve(true);
}
else {
resolve(false);
}
});
req.on("error", function (error) {
/* eslint-disable no-console */
console.error(error);
/* eslint-enable */
reject(error);
});
req.on("timeout", function () { return resolve(false); });
req.write(serializedData);
req.end();
});
};
var requestWithNativeFetch = function (url, data) {
return new Promise(function (resolve, reject) {
fetch(url, {
method: "POST",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json"
}
})
.then(function (response) {
resolve(response.status === 200);
})
.catch(function (e) {
reject(e);
});
});
};
function getRequesterForNode() {
if (supportsNodeHttpModule()) {
return requestWithNodeHttpModule;
}
if (supportsNativeFetch()) {
return requestWithNativeFetch;
}
throw new Error("Could not find a supported HTTP request client in this environment.");
}
var entryNode = createInsightsClient(getRequesterForNode());
exports.AlgoliaAnalytics = AlgoliaAnalytics;
exports.LocalStorage = LocalStorage;
exports.createInsightsClient = createInsightsClient;
exports.default = entryNode;
exports.getFunctionalInterface = getFunctionalInterface;
exports.getRequesterForNode = getRequesterForNode;
exports.processQueue = processQueue;

View File

@@ -0,0 +1,844 @@
var version="2.17.3";
function extractAdditionalParams(params) {
return params.reduce(function (ref, param) {
var events = ref.events;
var additionalParams = ref.additionalParams;
// Real events all have `index` as a mandatory parameter, which we
// can rely on to distinguish them from additional parameters
if ("index" in param) {
return { additionalParams: additionalParams, events: events.concat( [param]) };
}
return { events: events, additionalParams: param };
}, {
events: [],
additionalParams: undefined
});
}
var supportsCookies = function () {
try {
return Boolean(navigator.cookieEnabled);
}
catch (e) {
return false;
}
};
var supportsNodeHttpModule = function () {
try {
/* eslint-disable @typescript-eslint/no-var-requires */
var ref = require("http");
var nodeHttpRequest = ref.request;
var ref$1 = require("https");
var nodeHttpsRequest = ref$1.request;
/* eslint-enable */
return Boolean(nodeHttpRequest) && Boolean(nodeHttpsRequest);
}
catch (e) {
return false;
}
};
var supportsNativeFetch = function () {
try {
return fetch !== undefined;
}
catch (e) {
return false;
}
};
/**
* A utility class for safely interacting with localStorage.
*/
var LocalStorage = function LocalStorage () {};
LocalStorage.get = function get (key) {
var _a;
var val = (_a = this.store) === null || _a === void 0 ? void 0 : _a.getItem(key);
if (!val) {
return null;
}
try {
return JSON.parse(val);
}
catch (_b) {
return null;
}
};
/**
* Safely set a value in localStorage.
* If the storage is full, this method will catch the error and log a warning.
*
* @param key - String value of the key.
* @param value - Any value to store.
*/
LocalStorage.set = function set (key, value) {
var _a;
try {
(_a = this.store) === null || _a === void 0 ? void 0 : _a.setItem(key, JSON.stringify(value));
}
catch (_b) {
// eslint-disable-next-line no-console
console.error(("Unable to set " + key + " in localStorage, storage may be full."));
}
};
/**
* Remove a value from localStorage.
*
* @param key - String value of the key.
*/
LocalStorage.remove = function remove (key) {
var _a;
(_a = this.store) === null || _a === void 0 ? void 0 : _a.removeItem(key);
};
LocalStorage.store = ensureLocalStorage();
function ensureLocalStorage() {
try {
var testKey = "__test_localStorage__";
globalThis.localStorage.setItem(testKey, testKey);
globalThis.localStorage.removeItem(testKey);
return globalThis.localStorage;
}
catch (_a) {
return undefined;
}
}
var STORE = "AlgoliaObjectQueryCache";
var LIMIT = 5000; // 1 entry is typically no more than 100 bytes, so this is ~500kB worth of data - most browsers allow at least 5MB per origin
var FREE = 1000;
function getCache() {
var _a;
return (_a = LocalStorage.get(STORE)) !== null && _a !== void 0 ? _a : {};
}
function setCache(objectQueryMap) {
LocalStorage.set(STORE, limited(objectQueryMap));
}
function limited(objectQueryMap) {
return Object.keys(objectQueryMap).length > LIMIT
? purgeOldest(objectQueryMap)
: objectQueryMap;
}
function purgeOldest(objectQueryMap) {
var sorted = Object.entries(objectQueryMap).sort(function (ref, ref$1) {
var aTimestamp = ref[1][1];
var bTimestamp = ref$1[1][1];
return bTimestamp - aTimestamp;
});
var newObjectQueryMap = sorted
.slice(0, sorted.length - FREE - 1)
.reduce(function (acc, ref) {
var obj;
var key = ref[0];
var value = ref[1];
return (Object.assign(Object.assign({}, acc), ( obj = {}, obj[key] = value, obj )));
}, {});
return newObjectQueryMap;
}
function makeKey(index, objectID) {
return (index + "_" + objectID);
}
function storeQueryForObject(index, objectID, queryID) {
var objectQueryMap = getCache();
objectQueryMap[makeKey(index, objectID)] = [queryID, Date.now()];
setCache(objectQueryMap);
}
function getQueryForObject(index, objectID) {
return getCache()[makeKey(index, objectID)];
}
function removeQueryForObjects(index, objectIDs) {
var objectQueryMap = getCache();
objectIDs.forEach(function (objectID) {
delete objectQueryMap[makeKey(index, objectID)];
});
setCache(objectQueryMap);
}
// use theses type checking helpers to avoid mistyping "undefind", I mean "undfined"
var isUndefined = function (value) { return typeof value === "undefined"; };
var isNumber = function (value) { return typeof value === "number"; };
/* eslint-disable @typescript-eslint/ban-types */
var isFunction = function (value) { return typeof value === "function"; };
/* eslint-enable */
var isPromise = function (value) { return typeof (value === null || value === void 0 ? void 0 : value.then) === "function"; };
function getFunctionalInterface(instance) {
return function (functionName) {
var functionArguments = [], len = arguments.length - 1;
while ( len-- > 0 ) functionArguments[ len ] = arguments[ len + 1 ];
if (functionName && isFunction(instance[functionName])) {
// @ts-expect-error
return instance[functionName].apply(instance, functionArguments);
}
// eslint-disable-next-line no-console
console.warn(("The method `" + functionName + "` doesn't exist."));
return undefined;
};
}
var DEFAULT_ALGOLIA_AGENTS = [
("insights-js (" + version + ")"),
("insights-js-" + ("node-esm") + " (" + version + ")")
];
function addAlgoliaAgent(algoliaAgent) {
if (this._ua.indexOf(algoliaAgent) === -1) {
this._ua.push(algoliaAgent);
}
}
function getVersion(callback) {
if (isFunction(callback)) {
callback(this.version);
}
return this.version;
}
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/* global Reflect, Promise */
function __rest(s, e) {
var t = {};
for (var p in s) { if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
{ t[p] = s[p]; } }
if (s != null && typeof Object.getOwnPropertySymbols === "function")
{ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
{ t[p[i]] = s[p[i]]; }
} }
return t;
}
function addQueryId(events) {
return events.map(function (event) {
var _a;
if (!isValidEventForQueryIdLookup(event)) {
return event;
}
var objectIDsWithInferredQueryID = [];
var updatedObjectData = (_a = event.objectIDs) === null || _a === void 0 ? void 0 : _a.map(function (objectID, i) {
var _a, _b;
var objectData = (_a = event.objectData) === null || _a === void 0 ? void 0 : _a[i];
if (objectData === null || objectData === void 0 ? void 0 : objectData.queryID) {
return objectData;
}
var ref = (_b = getQueryForObject(event.index, objectID)) !== null && _b !== void 0 ? _b : [];
var queryID = ref[0];
if (queryID) {
objectIDsWithInferredQueryID.push(objectID);
}
return Object.assign(Object.assign({}, objectData), { queryID: queryID });
});
if (objectIDsWithInferredQueryID.length === 0) {
return event;
}
return Object.assign(Object.assign({}, event), { objectData: updatedObjectData, objectIDsWithInferredQueryID: objectIDsWithInferredQueryID });
});
}
function isValidEventForQueryIdLookup(event) {
return !event.queryID && event.eventType === "conversion";
}
function makeSendEvents(requestFn) {
return function sendEvents(eventData, additionalParams) {
var this$1$1 = this;
var _a, _b;
if (this._userHasOptedOut) {
return Promise.resolve(false);
}
var hasCredentials = (!isUndefined(this._apiKey) && !isUndefined(this._appId)) ||
(((_a = additionalParams === null || additionalParams === void 0 ? void 0 : additionalParams.headers) === null || _a === void 0 ? void 0 : _a["X-Algolia-Application-Id"]) &&
((_b = additionalParams === null || additionalParams === void 0 ? void 0 : additionalParams.headers) === null || _b === void 0 ? void 0 : _b["X-Algolia-API-Key"]));
if (!hasCredentials) {
throw new Error("Before calling any methods on the analytics, you first need to call the 'init' function with appId and apiKey parameters or provide custom credentials in additional parameters.");
}
if (!this._userToken && this._anonymousUserToken) {
this.setAnonymousUserToken(true);
}
var events = ((additionalParams === null || additionalParams === void 0 ? void 0 : additionalParams.inferQueryID) ? addQueryId(eventData) : eventData).map(function (data) {
var _a, _b;
var filters = data.filters;
var rest = __rest(data, ["filters"]);
var payload = Object.assign(Object.assign({}, rest), { userToken: (_a = data === null || data === void 0 ? void 0 : data.userToken) !== null && _a !== void 0 ? _a : this$1$1._userToken, authenticatedUserToken: (_b = data === null || data === void 0 ? void 0 : data.authenticatedUserToken) !== null && _b !== void 0 ? _b : this$1$1._authenticatedUserToken });
if (!isUndefined(filters)) {
payload.filters = filters.map(encodeURIComponent);
}
return payload;
});
if (events.length === 0) {
return Promise.resolve(false);
}
var send = sendRequest(requestFn, this._ua, this._endpointOrigin, events, this._appId, this._apiKey, additionalParams === null || additionalParams === void 0 ? void 0 : additionalParams.headers);
return isPromise(send) ? send.then(purgePurchased(events)) : send;
};
}
function purgePurchased(events) {
return function (sent) {
if (sent) {
events
.filter(function (ref) {
var eventType = ref.eventType;
var eventSubtype = ref.eventSubtype;
var objectIDs = ref.objectIDs;
return eventType === "conversion" &&
eventSubtype === "purchase" &&
(objectIDs === null || objectIDs === void 0 ? void 0 : objectIDs.length);
})
.forEach(function (ref) {
var index = ref.index;
var objectIDs = ref.objectIDs;
return removeQueryForObjects(index, objectIDs);
});
}
return sent;
};
}
// eslint-disable-next-line max-params
function sendRequest(requestFn, userAgents, endpointOrigin, events, appId, apiKey, additionalHeaders) {
if ( additionalHeaders === void 0 ) additionalHeaders = {};
var providedAppId = additionalHeaders["X-Algolia-Application-Id"];
var providedApiKey = additionalHeaders["X-Algolia-API-Key"];
var restHeaders = __rest(additionalHeaders, ["X-Algolia-Application-Id", "X-Algolia-API-Key"]);
// Auth query
var headers = Object.assign({ "X-Algolia-Application-Id": providedAppId !== null && providedAppId !== void 0 ? providedAppId : appId, "X-Algolia-API-Key": providedApiKey !== null && providedApiKey !== void 0 ? providedApiKey : apiKey, "X-Algolia-Agent": encodeURIComponent(userAgents.join("; ")) }, restHeaders);
var queryParameters = Object.keys(headers)
.map(function (key) { return (key + "=" + (headers[key])); })
.join("&");
var reportingURL = endpointOrigin + "/1/events?" + queryParameters;
return requestFn(reportingURL, { events: events });
}
/**
* Create UUID according to
* https://www.ietf.org/rfc/rfc4122.txt.
*
* @returns Generated UUID.
*/
function createUUID() {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
/* eslint-disable no-bitwise */
var r = (Math.random() * 16) | 0;
var v = c === "x" ? r : (r & 0x3) | 0x8;
/* eslint-enable */
return v.toString(16);
});
}
var COOKIE_KEY = "_ALGOLIA";
var MONTH = 30 * 24 * 60 * 60 * 1000;
var setCookie = function (name, value, duration) {
var d = new Date();
d.setTime(d.getTime() + duration);
var expires = "expires=" + (d.toUTCString());
document.cookie = name + "=" + value + ";" + expires + ";path=/";
};
var getCookie = function (name) {
var prefix = name + "=";
var ca = document.cookie.split(";");
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) === " ") {
c = c.substring(1);
}
if (c.indexOf(prefix) === 0) {
return c.substring(prefix.length, c.length);
}
}
return "";
};
function checkIfAnonymousToken(token) {
if (typeof token === "number") {
return false;
}
return token.indexOf("anonymous-") === 0;
}
function saveTokenAsCookie() {
var foundToken = getCookie(COOKIE_KEY);
if (this._userToken &&
(!foundToken || foundToken === "" || foundToken.indexOf("anonymous-") !== 0)) {
setCookie(COOKIE_KEY, this._userToken, this._cookieDuration);
}
}
function setAnonymousUserToken(inMemory) {
if ( inMemory === void 0 ) inMemory = false;
if (inMemory) {
this.setUserToken(("anonymous-" + (createUUID())));
return;
}
if (!supportsCookies()) {
return;
}
var foundToken = getCookie(COOKIE_KEY);
if (!foundToken ||
foundToken === "" ||
foundToken.indexOf("anonymous-") !== 0) {
var savedUserToken = this.setUserToken(("anonymous-" + (createUUID())));
setCookie(COOKIE_KEY, savedUserToken, this._cookieDuration);
}
else {
this.setUserToken(foundToken);
}
}
function setUserToken(userToken) {
this._userToken = userToken;
if (isFunction(this._onUserTokenChangeCallback)) {
this._onUserTokenChangeCallback(this._userToken);
}
return this._userToken;
}
function getUserToken(options, callback) {
if (isFunction(callback)) {
callback(null, this._userToken);
}
return this._userToken;
}
function onUserTokenChange(callback, options) {
this._onUserTokenChangeCallback = callback;
if (options &&
options.immediate &&
isFunction(this._onUserTokenChangeCallback)) {
this._onUserTokenChangeCallback(this._userToken);
}
}
function setAuthenticatedUserToken(authenticatedUserToken) {
this._authenticatedUserToken = authenticatedUserToken;
if (isFunction(this._onAuthenticatedUserTokenChangeCallback)) {
this._onAuthenticatedUserTokenChangeCallback(this._authenticatedUserToken);
}
return this._authenticatedUserToken;
}
function getAuthenticatedUserToken(options, callback) {
if (isFunction(callback)) {
callback(null, this._authenticatedUserToken);
}
return this._authenticatedUserToken;
}
function onAuthenticatedUserTokenChange(callback, options) {
this._onAuthenticatedUserTokenChangeCallback = callback;
if (options &&
options.immediate &&
isFunction(this._onAuthenticatedUserTokenChangeCallback)) {
this._onAuthenticatedUserTokenChangeCallback(this._authenticatedUserToken);
}
}
function addEventType(eventType, params) {
return params.map(function (event) { return (Object.assign({ eventType: eventType }, event)); });
}
function addEventTypeAndSubtype(eventType, eventSubtype, params) {
return params.map(function (event) { return (Object.assign({ eventType: eventType,
eventSubtype: eventSubtype }, event)); });
}
function clickedObjectIDsAfterSearch() {
var this$1$1 = this;
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
events.forEach(function (ref) {
var index = ref.index;
var queryID = ref.queryID;
var objectIDs = ref.objectIDs;
return objectIDs.forEach(function (objectID) { return !this$1$1._userHasOptedOut && storeQueryForObject(index, objectID, queryID); });
});
return this.sendEvents(addEventType("click", events), additionalParams);
}
function clickedObjectIDs() {
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
return this.sendEvents(addEventType("click", events), additionalParams);
}
function clickedFilters() {
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
return this.sendEvents(addEventType("click", events), additionalParams);
}
function convertedObjectIDsAfterSearch() {
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
return this.sendEvents(addEventType("conversion", events), additionalParams);
}
function addedToCartObjectIDsAfterSearch() {
var this$1$1 = this;
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
events.forEach(function (ref) {
var index = ref.index;
var queryID = ref.queryID;
var objectIDs = ref.objectIDs;
var objectData = ref.objectData;
return objectIDs.forEach(function (objectID, i) {
var _a, _b;
var objQueryID = (_b = (_a = objectData === null || objectData === void 0 ? void 0 : objectData[i]) === null || _a === void 0 ? void 0 : _a.queryID) !== null && _b !== void 0 ? _b : queryID;
if (!this$1$1._userHasOptedOut && objQueryID)
{ storeQueryForObject(index, objectID, objQueryID); }
});
});
return this.sendEvents(addEventTypeAndSubtype("conversion", "addToCart", events), additionalParams);
}
function purchasedObjectIDsAfterSearch() {
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
return this.sendEvents(addEventTypeAndSubtype("conversion", "purchase", events), additionalParams);
}
function convertedObjectIDs() {
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
return this.sendEvents(addEventType("conversion", events), additionalParams);
}
function addedToCartObjectIDs() {
var this$1$1 = this;
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
events.forEach(function (ref) {
var index = ref.index;
var objectIDs = ref.objectIDs;
var objectData = ref.objectData;
return objectIDs.forEach(function (objectID, i) {
var _a;
var queryID = (_a = objectData === null || objectData === void 0 ? void 0 : objectData[i]) === null || _a === void 0 ? void 0 : _a.queryID;
if (!this$1$1._userHasOptedOut && queryID)
{ storeQueryForObject(index, objectID, queryID); }
});
});
return this.sendEvents(addEventTypeAndSubtype("conversion", "addToCart", events), additionalParams);
}
function purchasedObjectIDs() {
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
return this.sendEvents(addEventTypeAndSubtype("conversion", "purchase", events), additionalParams);
}
function convertedFilters() {
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
return this.sendEvents(addEventType("conversion", events), additionalParams);
}
var SUPPORTED_REGIONS = ["de", "us"];
/**
* Binds credentials and settings to class.
*
* @param options - InitParams.
*/
function init(options) {
if ( options === void 0 ) options = {};
var _a, _b;
if (!isUndefined(options.region) &&
SUPPORTED_REGIONS.indexOf(options.region) === -1) {
throw new Error(("optional region is incorrect, please provide either one of: " + (SUPPORTED_REGIONS.join(", ")) + "."));
}
if (!isUndefined(options.cookieDuration) &&
(!isNumber(options.cookieDuration) ||
!isFinite(options.cookieDuration) ||
Math.floor(options.cookieDuration) !== options.cookieDuration)) {
throw new Error("optional cookieDuration is incorrect, expected an integer.");
}
/* eslint-enable */
setOptions(this, options, {
_userHasOptedOut: Boolean(options.userHasOptedOut),
_region: options.region,
_host: options.host,
_anonymousUserToken: (_a = options.anonymousUserToken) !== null && _a !== void 0 ? _a : true,
_useCookie: (_b = options.useCookie) !== null && _b !== void 0 ? _b : false,
_cookieDuration: options.cookieDuration || 6 * MONTH
});
this._endpointOrigin =
this._host ||
(this._region
? ("https://insights." + (this._region) + ".algolia.io")
: "https://insights.algolia.io");
// user agent
this._ua = [].concat( DEFAULT_ALGOLIA_AGENTS );
if (options.authenticatedUserToken) {
this.setAuthenticatedUserToken(options.authenticatedUserToken);
}
if (options.userToken) {
this.setUserToken(options.userToken);
}
else if (!this._userToken && !this._userHasOptedOut && this._useCookie) {
this.setAnonymousUserToken();
}
else if (checkIfTokenNeedsToBeSaved(this)) {
this.saveTokenAsCookie();
}
}
function setOptions(target, _a, defaultValues) {
var partial = _a.partial;
var options = __rest(_a, ["partial"]);
if (!partial) {
Object.assign(target, defaultValues);
}
Object.assign(target, Object.keys(options).reduce(function (acc, key) {
var obj;
return (Object.assign(Object.assign({}, acc), ( obj = {}, obj[("_" + key)] = options[key], obj )));
}, {}));
}
function checkIfTokenNeedsToBeSaved(target) {
if (target._userToken === undefined) {
return false;
}
return (checkIfAnonymousToken(target._userToken) &&
target._useCookie &&
!target._userHasOptedOut);
}
function viewedObjectIDs() {
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
return this.sendEvents(addEventType("view", events), additionalParams);
}
function viewedFilters() {
var params = [], len = arguments.length;
while ( len-- ) params[ len ] = arguments[ len ];
var ref = extractAdditionalParams(params);
var events = ref.events;
var additionalParams = ref.additionalParams;
return this.sendEvents(addEventType("view", events), additionalParams);
}
/**
* AlgoliaAnalytics class.
*/
var AlgoliaAnalytics = function AlgoliaAnalytics(ref) {
var requestFn = ref.requestFn;
this._endpointOrigin = "https://insights.algolia.io";
this._anonymousUserToken = true;
this._userHasOptedOut = false;
this._useCookie = false;
this._cookieDuration = 6 * MONTH;
// user agent
this._ua = [];
this.version = version;
this.sendEvents = makeSendEvents(requestFn).bind(this);
this.init = init.bind(this);
this.addAlgoliaAgent = addAlgoliaAgent.bind(this);
this.saveTokenAsCookie = saveTokenAsCookie.bind(this);
this.setUserToken = setUserToken.bind(this);
this.setAnonymousUserToken = setAnonymousUserToken.bind(this);
this.getUserToken = getUserToken.bind(this);
this.onUserTokenChange = onUserTokenChange.bind(this);
this.setAuthenticatedUserToken = setAuthenticatedUserToken.bind(this);
this.getAuthenticatedUserToken = getAuthenticatedUserToken.bind(this);
this.onAuthenticatedUserTokenChange =
onAuthenticatedUserTokenChange.bind(this);
this.clickedObjectIDsAfterSearch = clickedObjectIDsAfterSearch.bind(this);
this.clickedObjectIDs = clickedObjectIDs.bind(this);
this.clickedFilters = clickedFilters.bind(this);
this.convertedObjectIDsAfterSearch =
convertedObjectIDsAfterSearch.bind(this);
this.purchasedObjectIDsAfterSearch =
purchasedObjectIDsAfterSearch.bind(this);
this.addedToCartObjectIDsAfterSearch =
addedToCartObjectIDsAfterSearch.bind(this);
this.convertedObjectIDs = convertedObjectIDs.bind(this);
this.addedToCartObjectIDs = addedToCartObjectIDs.bind(this);
this.purchasedObjectIDs = purchasedObjectIDs.bind(this);
this.convertedFilters = convertedFilters.bind(this);
this.viewedObjectIDs = viewedObjectIDs.bind(this);
this.viewedFilters = viewedFilters.bind(this);
this.getVersion = getVersion.bind(this);
};
function createInsightsClient(requestFn) {
var aa = getFunctionalInterface(new AlgoliaAnalytics({ requestFn: requestFn }));
if (typeof window === "object") {
if (!window.AlgoliaAnalyticsObject) {
var pointer;
do {
pointer = createUUID();
} while (window[pointer] !== undefined);
window.AlgoliaAnalyticsObject = pointer;
window[window.AlgoliaAnalyticsObject] = aa;
}
}
aa.version = version;
return aa;
}
/**
* Processes queue that might have been set before
* the script was actually loaded and reassigns
* class over globalObject variable to execute commands
* instead of putting them to the queue.
*/
function processQueue(globalObject) {
// Set pointer which allows renaming of the script
var pointer = globalObject.AlgoliaAnalyticsObject;
if (pointer) {
var _aa = getFunctionalInterface(this);
// `aa` is the user facing function, which is defined in the install snippet.
// - before library is initialized `aa` fills a queue
// - after library is initialized `aa` calls `_aa`
var aa = globalObject[pointer];
aa.queue = aa.queue || [];
var queue = aa.queue;
// Loop queue and execute functions in the queue
queue.forEach(function (args) {
var ref = [].slice.call(args);
var functionName = ref[0];
var functionArguments = ref.slice(1);
_aa.apply(void 0, [ functionName ].concat( functionArguments ));
});
/* eslint-disable no-warning-comments */
// FIXME: Reassigning the pointer is a bad idea (cf: https://github.com/algolia/search-insights.js/issues/127)
// to remove this without any breaking change, we redefine the Array.prototype.push method on the queue array.
// for next major version, use a custom method instead of push.
/* eslint-enable */
// @ts-expect-error (otherwise typescript won't let you change the signature)
queue.push = function (args) {
var ref = [].slice.call(args);
var functionName = ref[0];
var functionArguments = ref.slice(1);
_aa.apply(void 0, [ functionName ].concat( functionArguments ));
};
}
}
var requestWithNodeHttpModule = function (url, data) {
return new Promise(function (resolve, reject) {
var serializedData = JSON.stringify(data);
/* eslint-disable @typescript-eslint/no-var-requires */
var ref = require("url").parse(url);
var protocol = ref.protocol;
var host = ref.host;
var path = ref.path;
/* eslint-enable */
var options = {
protocol: protocol,
host: host,
path: path,
method: "POST",
headers: {
"Content-Type": "application/json",
"Content-Length": serializedData.length
}
};
var ref$1 = url.startsWith("https://")
? require("https")
: require("http");
var request = ref$1.request;
var req = request(options, function (ref) {
var statusCode = ref.statusCode;
if (statusCode === 200) {
resolve(true);
}
else {
resolve(false);
}
});
req.on("error", function (error) {
/* eslint-disable no-console */
console.error(error);
/* eslint-enable */
reject(error);
});
req.on("timeout", function () { return resolve(false); });
req.write(serializedData);
req.end();
});
};
var requestWithNativeFetch = function (url, data) {
return new Promise(function (resolve, reject) {
fetch(url, {
method: "POST",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json"
}
})
.then(function (response) {
resolve(response.status === 200);
})
.catch(function (e) {
reject(e);
});
});
};
function getRequesterForNode() {
if (supportsNodeHttpModule()) {
return requestWithNodeHttpModule;
}
if (supportsNativeFetch()) {
return requestWithNativeFetch;
}
throw new Error("Could not find a supported HTTP request client in this environment.");
}
var entryNode = createInsightsClient(getRequesterForNode());
export { AlgoliaAnalytics, LocalStorage, createInsightsClient, entryNode as default, getFunctionalInterface, getRequesterForNode, processQueue };

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

85
node_modules/search-insights/dist/types.d.ts generated vendored Normal file
View File

@@ -0,0 +1,85 @@
import type { addAlgoliaAgent } from "./_algoliaAgent";
import type { getVersion } from "./_getVersion";
import type { makeSendEvents } from "./_sendEvent";
import type { getUserToken, setUserToken, onUserTokenChange, onAuthenticatedUserTokenChange, setAuthenticatedUserToken, getAuthenticatedUserToken } from "./_tokenUtils";
import type { clickedObjectIDsAfterSearch, clickedObjectIDs, clickedFilters } from "./click";
import type { convertedObjectIDsAfterSearch, convertedObjectIDs, convertedFilters, purchasedObjectIDs, purchasedObjectIDsAfterSearch, addedToCartObjectIDsAfterSearch, addedToCartObjectIDs } from "./conversion";
import type { init } from "./init";
import type { viewedObjectIDs, viewedFilters } from "./view";
type ParamReturnTypeTuple<T extends (...args: any) => any> = [
Parameters<T>,
ReturnType<T>
];
export type InsightsMethodMap = {
init: ParamReturnTypeTuple<typeof init>;
getVersion: ParamReturnTypeTuple<typeof getVersion>;
addAlgoliaAgent: ParamReturnTypeTuple<typeof addAlgoliaAgent>;
setUserToken: ParamReturnTypeTuple<typeof setUserToken>;
getUserToken: ParamReturnTypeTuple<typeof getUserToken>;
onUserTokenChange: ParamReturnTypeTuple<typeof onUserTokenChange>;
setAuthenticatedUserToken: ParamReturnTypeTuple<typeof setAuthenticatedUserToken>;
getAuthenticatedUserToken: ParamReturnTypeTuple<typeof getAuthenticatedUserToken>;
onAuthenticatedUserTokenChange: ParamReturnTypeTuple<typeof onAuthenticatedUserTokenChange>;
clickedObjectIDsAfterSearch: ParamReturnTypeTuple<typeof clickedObjectIDsAfterSearch>;
clickedObjectIDs: ParamReturnTypeTuple<typeof clickedObjectIDs>;
clickedFilters: ParamReturnTypeTuple<typeof clickedFilters>;
convertedObjectIDsAfterSearch: ParamReturnTypeTuple<typeof convertedObjectIDsAfterSearch>;
convertedObjectIDs: ParamReturnTypeTuple<typeof convertedObjectIDs>;
convertedFilters: ParamReturnTypeTuple<typeof convertedFilters>;
viewedObjectIDs: ParamReturnTypeTuple<typeof viewedObjectIDs>;
viewedFilters: ParamReturnTypeTuple<typeof viewedFilters>;
purchasedObjectIDs: ParamReturnTypeTuple<typeof purchasedObjectIDs>;
purchasedObjectIDsAfterSearch: ParamReturnTypeTuple<typeof purchasedObjectIDsAfterSearch>;
addedToCartObjectIDs: ParamReturnTypeTuple<typeof addedToCartObjectIDs>;
addedToCartObjectIDsAfterSearch: ParamReturnTypeTuple<typeof addedToCartObjectIDsAfterSearch>;
sendEvents: ParamReturnTypeTuple<ReturnType<typeof makeSendEvents>>;
};
type MethodType<MethodName extends keyof InsightsMethodMap> = (method: MethodName, ...args: InsightsMethodMap[MethodName][0]) => InsightsMethodMap[MethodName][1];
export type Init = MethodType<"init">;
export type GetVersion = MethodType<"getVersion">;
export type AddAlgoliaAgent = MethodType<"addAlgoliaAgent">;
export type SetUserToken = MethodType<"setUserToken">;
export type GetUserToken = MethodType<"getUserToken">;
export type OnUserTokenChange = MethodType<"onUserTokenChange">;
export type ClickedObjectIDsAfterSearch = MethodType<"clickedObjectIDsAfterSearch">;
export type ClickedObjectIDs = MethodType<"clickedObjectIDs">;
export type ClickedFilters = MethodType<"clickedFilters">;
export type ConvertedObjectIDsAfterSearch = MethodType<"convertedObjectIDsAfterSearch">;
export type ConvertedObjectIDs = MethodType<"convertedObjectIDs">;
export type ConvertedFilters = MethodType<"convertedFilters">;
export type ViewedObjectIDs = MethodType<"viewedObjectIDs">;
export type ViewedFilters = MethodType<"viewedFilters">;
export type SendEvents = MethodType<"sendEvents">;
export type InsightsClient = (<MethodName extends keyof InsightsMethodMap>(method: MethodName, ...args: InsightsMethodMap[MethodName][0]) => InsightsMethodMap[MethodName][1]) & {
version?: string;
};
export type InsightsEventType = "click" | "conversion" | "view";
export type InsightsEventConversionSubType = "addToCart" | "purchase";
export type InsightsEventObjectData = {
queryID?: string;
price?: number | string;
discount?: number | string;
quantity?: number;
};
export type InsightsEvent = {
eventType: InsightsEventType;
eventSubtype?: InsightsEventConversionSubType;
eventName: string;
userToken?: number | string;
authenticatedUserToken?: number | string;
timestamp?: number;
index: string;
queryID?: string;
objectIDs?: string[];
positions?: number[];
objectData?: InsightsEventObjectData[];
objectIDsWithInferredQueryID?: string[];
filters?: string[];
value?: number | string;
currency?: string;
};
export type InsightsAdditionalEventParams = {
headers?: Record<string, string>;
inferQueryID?: boolean;
};
export {};

View File

@@ -0,0 +1,8 @@
import type { InsightsAdditionalEventParams } from "../types";
export type WithAdditionalParams<TEventType> = InsightsAdditionalEventParams | TEventType;
export declare function extractAdditionalParams<TEventType extends {
index: string;
}>(params: Array<InsightsAdditionalEventParams | TEventType>): {
events: TEventType[];
additionalParams?: InsightsAdditionalEventParams;
};

View File

@@ -0,0 +1,5 @@
export declare const supportsCookies: () => boolean;
export declare const supportsSendBeacon: () => boolean;
export declare const supportsXMLHttpRequest: () => boolean;
export declare const supportsNodeHttpModule: () => boolean;
export declare const supportsNativeFetch: () => boolean;

View File

@@ -0,0 +1,2 @@
import type { RequestFnType } from "./request";
export declare function getRequesterForBrowser(): RequestFnType;

View File

@@ -0,0 +1,2 @@
import type { RequestFnType } from "./request";
export declare function getRequesterForNode(): RequestFnType;

8
node_modules/search-insights/dist/utils/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,8 @@
export declare const isUndefined: (value: any) => value is undefined;
export declare const isString: (value: any) => value is string;
export declare const isNumber: (value: any) => value is number;
export declare const isFunction: (value: any) => value is Function;
export declare const isPromise: <T>(value: T | Promise<T>) => value is Promise<T>;
export * from "./extractAdditionalParams";
export * from "./featureDetection";
export * from "./objectQueryTracker";

View File

@@ -0,0 +1,28 @@
/**
* A utility class for safely interacting with localStorage.
*/
export declare class LocalStorage {
static store: Storage | undefined;
/**
* Safely get a value from localStorage.
* If the value is not able to be parsed as JSON, this method will return null.
*
* @param key - String value of the key.
* @returns Null if the key is not found or unable to be parsed, the value otherwise.
*/
static get<T>(key: string): T | null;
/**
* Safely set a value in localStorage.
* If the storage is full, this method will catch the error and log a warning.
*
* @param key - String value of the key.
* @param value - Any value to store.
*/
static set(key: string, value: any): void;
/**
* Remove a value from localStorage.
*
* @param key - String value of the key.
*/
static remove(key: string): void;
}

View File

@@ -0,0 +1,3 @@
export declare function storeQueryForObject(index: string, objectID: string, queryID: string): void;
export declare function getQueryForObject(index: string, objectID: string): [queryId: string, timestamp: number] | undefined;
export declare function removeQueryForObjects(index: string, objectIDs: string[]): void;

5
node_modules/search-insights/dist/utils/request.d.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
export type RequestFnType = (url: string, data: Record<string, unknown>) => Promise<boolean>;
export declare const requestWithXMLHttpRequest: RequestFnType;
export declare const requestWithSendBeacon: RequestFnType;
export declare const requestWithNodeHttpModule: RequestFnType;
export declare const requestWithNativeFetch: RequestFnType;

7
node_modules/search-insights/dist/utils/uuid.d.ts generated vendored Normal file
View File

@@ -0,0 +1,7 @@
/**
* Create UUID according to
* https://www.ietf.org/rfc/rfc4122.txt.
*
* @returns Generated UUID.
*/
export declare function createUUID(): string;

20
node_modules/search-insights/dist/view.d.ts generated vendored Normal file
View File

@@ -0,0 +1,20 @@
import type AlgoliaAnalytics from "./insights";
import type { WithAdditionalParams } from "./utils";
export interface InsightsSearchViewObjectIDsEvent {
eventName: string;
userToken?: string;
authenticatedUserToken?: string;
timestamp?: number;
index: string;
objectIDs: string[];
}
export declare function viewedObjectIDs(this: AlgoliaAnalytics, ...params: Array<WithAdditionalParams<InsightsSearchViewObjectIDsEvent>>): ReturnType<AlgoliaAnalytics["sendEvents"]>;
export interface InsightsSearchViewFiltersEvent {
eventName: string;
userToken?: string;
authenticatedUserToken?: string;
timestamp?: number;
index: string;
filters: string[];
}
export declare function viewedFilters(this: AlgoliaAnalytics, ...params: Array<WithAdditionalParams<InsightsSearchViewFiltersEvent>>): ReturnType<AlgoliaAnalytics["sendEvents"]>;

3
node_modules/search-insights/empty-module.cjs generated vendored Normal file
View File

@@ -0,0 +1,3 @@
// shim for node modules in React Native
// see https://github.com/facebook/react-native/issues/5079
module.exports = {};

4
node_modules/search-insights/empty-module.cjs.d.ts generated vendored Normal file
View File

@@ -0,0 +1,4 @@
// shim for node modules in React Native
// see https://github.com/facebook/react-native/issues/5079
type empty = {};
export default empty;

8
node_modules/search-insights/index-browser.cjs generated vendored Normal file
View File

@@ -0,0 +1,8 @@
const aa = require("./dist/search-insights-browser.min.cjs");
module.exports = aa.default;
Object.keys(aa).forEach((key) => {
if (key !== "default") {
module.exports[key] = aa[key];
}
});

3
node_modules/search-insights/index-browser.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
export * from "./dist/entry-browser";
import aa from "./dist/entry-browser";
export default aa;

3
node_modules/search-insights/index-browser.mjs generated vendored Normal file
View File

@@ -0,0 +1,3 @@
export * from "./dist/search-insights-browser.mjs";
import aa from "./dist/search-insights-browser.mjs";
export default aa;

9
node_modules/search-insights/index-node.cjs generated vendored Normal file
View File

@@ -0,0 +1,9 @@
const aa = require("./dist/search-insights-node.cjs");
module.exports = aa.default;
module.exports.createInsightsClient = aa.createInsightsClient;
module.exports.getRequesterForNode = aa.getRequesterForNode;
module.exports.AlgoliaAnalytics = aa.AlgoliaAnalytics;
module.exports.LocalStorage = aa.LocalStorage;
module.exports.getFunctionalInterface = aa.getFunctionalInterface;
module.exports.processQueue = aa.processQueue;

3
node_modules/search-insights/index-node.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
export * from "./dist/entry-node";
import aa from "./dist/entry-node";
export default aa;

3
node_modules/search-insights/index-node.mjs generated vendored Normal file
View File

@@ -0,0 +1,3 @@
export * from "./dist/search-insights-node.mjs";
import aa from "./dist/search-insights-node.mjs";
export default aa;

27
node_modules/search-insights/lib/_addEventType.ts generated vendored Normal file
View File

@@ -0,0 +1,27 @@
import type {
InsightsEvent,
InsightsEventConversionSubType,
InsightsEventType
} from "./types";
export function addEventType(
eventType: InsightsEventType,
params: Array<Omit<InsightsEvent, "eventType">>
): InsightsEvent[] {
return params.map((event) => ({
eventType,
...event
}));
}
export function addEventTypeAndSubtype(
eventType: InsightsEventType,
eventSubtype: InsightsEventConversionSubType,
params: Array<Omit<InsightsEvent, "eventSubtype" | "eventType">>
): InsightsEvent[] {
return params.map((event) => ({
eventType,
eventSubtype,
...event
}));
}

38
node_modules/search-insights/lib/_addQueryId.ts generated vendored Normal file
View File

@@ -0,0 +1,38 @@
import type { InsightsEvent } from "./types";
import { getQueryForObject } from "./utils";
export function addQueryId(events: InsightsEvent[]): InsightsEvent[] {
return events.map((event) => {
if (!isValidEventForQueryIdLookup(event)) {
return event;
}
const objectIDsWithInferredQueryID: string[] = [];
const updatedObjectData = event.objectIDs?.map((objectID, i) => {
const objectData = event.objectData?.[i];
if (objectData?.queryID) {
return objectData;
}
const [queryID] = getQueryForObject(event.index, objectID) ?? [];
if (queryID) {
objectIDsWithInferredQueryID.push(objectID);
}
return {
...objectData,
queryID
};
});
if (objectIDsWithInferredQueryID.length === 0) {
return event;
}
return {
...event,
objectData: updatedObjectData,
objectIDsWithInferredQueryID
};
});
}
function isValidEventForQueryIdLookup(event: InsightsEvent): boolean {
return !event.queryID && event.eventType === "conversion";
}

17
node_modules/search-insights/lib/_algoliaAgent.ts generated vendored Normal file
View File

@@ -0,0 +1,17 @@
import { version } from "../package.json";
import type AlgoliaAnalytics from "./insights";
export const DEFAULT_ALGOLIA_AGENTS = [
`insights-js (${version})`,
`insights-js-${__FLAVOR__} (${version})`
];
export function addAlgoliaAgent(
this: AlgoliaAnalytics,
algoliaAgent: string
): void {
if (this._ua.indexOf(algoliaAgent) === -1) {
this._ua.push(algoliaAgent);
}
}

View File

@@ -0,0 +1,26 @@
import { version } from "../package.json";
import { getFunctionalInterface } from "./_getFunctionalInterface";
import AlgoliaAnalytics from "./insights";
import type { InsightsClient } from "./types";
import type { RequestFnType } from "./utils/request";
import { createUUID } from "./utils/uuid";
export function createInsightsClient(requestFn: RequestFnType): InsightsClient {
const aa = getFunctionalInterface(new AlgoliaAnalytics({ requestFn }));
if (typeof window === "object") {
if (!window.AlgoliaAnalyticsObject) {
let pointer: string;
do {
pointer = createUUID();
} while (window[pointer as any] !== undefined);
window.AlgoliaAnalyticsObject = pointer;
(window as any)[window.AlgoliaAnalyticsObject] = aa;
}
}
aa.version = version;
return aa;
}

View File

@@ -0,0 +1,17 @@
import type AlgoliaAnalytics from "./insights";
import type { InsightsClient } from "./types";
import { isFunction } from "./utils";
export function getFunctionalInterface(
instance: AlgoliaAnalytics
): InsightsClient {
return (functionName, ...functionArguments) => {
if (functionName && isFunction(instance[functionName])) {
// @ts-expect-error
return instance[functionName](...functionArguments);
}
// eslint-disable-next-line no-console
console.warn(`The method \`${functionName}\` doesn't exist.`);
return undefined;
};
}

12
node_modules/search-insights/lib/_getVersion.ts generated vendored Normal file
View File

@@ -0,0 +1,12 @@
import type AlgoliaAnalytics from "./insights";
import { isFunction } from "./utils";
export function getVersion(
this: AlgoliaAnalytics,
callback?: (version: string) => void
): string {
if (isFunction(callback)) {
callback(this.version);
}
return this.version;
}

42
node_modules/search-insights/lib/_processQueue.ts generated vendored Normal file
View File

@@ -0,0 +1,42 @@
/**
* Processes queue that might have been set before
* the script was actually loaded and reassigns
* class over globalObject variable to execute commands
* instead of putting them to the queue.
*/
import { getFunctionalInterface } from "./_getFunctionalInterface";
import type AlgoliaAnalytics from "./insights";
export function processQueue(this: AlgoliaAnalytics, globalObject: any): void {
// Set pointer which allows renaming of the script
const pointer = globalObject.AlgoliaAnalyticsObject as string;
if (pointer) {
const _aa = getFunctionalInterface(this);
// `aa` is the user facing function, which is defined in the install snippet.
// - before library is initialized `aa` fills a queue
// - after library is initialized `aa` calls `_aa`
const aa = globalObject[pointer];
aa.queue = aa.queue || [];
const queue: IArguments[] = aa.queue;
// Loop queue and execute functions in the queue
queue.forEach((args: IArguments) => {
const [functionName, ...functionArguments] = [].slice.call(args);
_aa(functionName as any, ...(functionArguments as any));
});
/* eslint-disable no-warning-comments */
// FIXME: Reassigning the pointer is a bad idea (cf: https://github.com/algolia/search-insights.js/issues/127)
// to remove this without any breaking change, we redefine the Array.prototype.push method on the queue array.
// for next major version, use a custom method instead of push.
/* eslint-enable */
// @ts-expect-error (otherwise typescript won't let you change the signature)
queue.push = (args: IArguments): number => {
const [functionName, ...functionArguments] = [].slice.call(args);
_aa(functionName as any, ...(functionArguments as any));
};
}
}

111
node_modules/search-insights/lib/_sendEvent.ts generated vendored Normal file
View File

@@ -0,0 +1,111 @@
import { addQueryId } from "./_addQueryId";
import type AlgoliaAnalytics from "./insights";
import type { InsightsAdditionalEventParams, InsightsEvent } from "./types";
import { isPromise, isUndefined, removeQueryForObjects } from "./utils";
import type { RequestFnType } from "./utils/request";
export function makeSendEvents(requestFn: RequestFnType) {
return function sendEvents(
this: AlgoliaAnalytics,
eventData: InsightsEvent[],
additionalParams?: InsightsAdditionalEventParams
): Promise<boolean> {
if (this._userHasOptedOut) {
return Promise.resolve(false);
}
const hasCredentials =
(!isUndefined(this._apiKey) && !isUndefined(this._appId)) ||
(additionalParams?.headers?.["X-Algolia-Application-Id"] &&
additionalParams?.headers?.["X-Algolia-API-Key"]);
if (!hasCredentials) {
throw new Error(
"Before calling any methods on the analytics, you first need to call the 'init' function with appId and apiKey parameters or provide custom credentials in additional parameters."
);
}
if (!this._userToken && this._anonymousUserToken) {
this.setAnonymousUserToken(true);
}
const events: InsightsEvent[] = (
additionalParams?.inferQueryID ? addQueryId(eventData) : eventData
).map((data) => {
const { filters, ...rest } = data;
const payload: InsightsEvent = {
...rest,
userToken: data?.userToken ?? this._userToken,
authenticatedUserToken:
data?.authenticatedUserToken ?? this._authenticatedUserToken
};
if (!isUndefined(filters)) {
payload.filters = filters.map(encodeURIComponent);
}
return payload;
});
if (events.length === 0) {
return Promise.resolve(false);
}
const send = sendRequest(
requestFn,
this._ua,
this._endpointOrigin,
events,
this._appId,
this._apiKey,
additionalParams?.headers
);
return isPromise(send) ? send.then(purgePurchased(events)) : send;
};
}
function purgePurchased(events: InsightsEvent[]): (value: boolean) => boolean {
return (sent) => {
if (sent) {
events
.filter(
({ eventType, eventSubtype, objectIDs }) =>
eventType === "conversion" &&
eventSubtype === "purchase" &&
objectIDs?.length
)
.forEach(({ index, objectIDs }) =>
removeQueryForObjects(index, objectIDs!)
);
}
return sent;
};
}
// eslint-disable-next-line max-params
function sendRequest(
requestFn: RequestFnType,
userAgents: string[],
endpointOrigin: string,
events: InsightsEvent[],
appId?: string,
apiKey?: string,
additionalHeaders: InsightsAdditionalEventParams["headers"] = {}
): Promise<boolean> {
const {
"X-Algolia-Application-Id": providedAppId,
"X-Algolia-API-Key": providedApiKey,
...restHeaders
} = additionalHeaders;
// Auth query
const headers: Record<string, string> = {
"X-Algolia-Application-Id": providedAppId ?? appId,
"X-Algolia-API-Key": providedApiKey ?? apiKey,
"X-Algolia-Agent": encodeURIComponent(userAgents.join("; ")),
...restHeaders
};
const queryParameters = Object.keys(headers)
.map((key) => `${key}=${headers[key]}`)
.join("&");
const reportingURL = `${endpointOrigin}/1/events?${queryParameters}`;
return requestFn(reportingURL, { events });
}

150
node_modules/search-insights/lib/_tokenUtils.ts generated vendored Normal file
View File

@@ -0,0 +1,150 @@
import type AlgoliaAnalytics from "./insights";
import { isFunction, supportsCookies } from "./utils";
import { createUUID } from "./utils/uuid";
const COOKIE_KEY = "_ALGOLIA";
export const MONTH = 30 * 24 * 60 * 60 * 1000;
const setCookie = (
name: string,
value: number | string,
duration: number
): void => {
const d = new Date();
d.setTime(d.getTime() + duration);
const expires = `expires=${d.toUTCString()}`;
document.cookie = `${name}=${value};${expires};path=/`;
};
export const getCookie = (name: string): string => {
const prefix = `${name}=`;
const ca = document.cookie.split(";");
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) === " ") {
c = c.substring(1);
}
if (c.indexOf(prefix) === 0) {
return c.substring(prefix.length, c.length);
}
}
return "";
};
export function checkIfAnonymousToken(token: number | string): boolean {
if (typeof token === "number") {
return false;
}
return token.indexOf("anonymous-") === 0;
}
export function saveTokenAsCookie(this: AlgoliaAnalytics): void {
const foundToken = getCookie(COOKIE_KEY);
if (
this._userToken &&
(!foundToken || foundToken === "" || foundToken.indexOf("anonymous-") !== 0)
) {
setCookie(COOKIE_KEY, this._userToken, this._cookieDuration);
}
}
export function setAnonymousUserToken(
this: AlgoliaAnalytics,
inMemory = false
): void {
if (inMemory) {
this.setUserToken(`anonymous-${createUUID()}`);
return;
}
if (!supportsCookies()) {
return;
}
const foundToken = getCookie(COOKIE_KEY);
if (
!foundToken ||
foundToken === "" ||
foundToken.indexOf("anonymous-") !== 0
) {
const savedUserToken = this.setUserToken(`anonymous-${createUUID()}`);
setCookie(COOKIE_KEY, savedUserToken, this._cookieDuration);
} else {
this.setUserToken(foundToken);
}
}
export function setUserToken(
this: AlgoliaAnalytics,
userToken: number | string
): number | string {
this._userToken = userToken;
if (isFunction(this._onUserTokenChangeCallback)) {
this._onUserTokenChangeCallback(this._userToken);
}
return this._userToken;
}
export function getUserToken(
this: AlgoliaAnalytics,
options?: any,
callback?: (err: any, userToken?: number | string) => void
): number | string | undefined {
if (isFunction(callback)) {
callback(null, this._userToken);
}
return this._userToken;
}
export function onUserTokenChange(
this: AlgoliaAnalytics,
callback?: (userToken?: number | string) => void,
options?: { immediate: boolean }
): void {
this._onUserTokenChangeCallback = callback;
if (
options &&
options.immediate &&
isFunction(this._onUserTokenChangeCallback)
) {
this._onUserTokenChangeCallback(this._userToken);
}
}
export function setAuthenticatedUserToken(
this: AlgoliaAnalytics,
authenticatedUserToken: number | string | undefined
): number | string | undefined {
this._authenticatedUserToken = authenticatedUserToken;
if (isFunction(this._onAuthenticatedUserTokenChangeCallback)) {
this._onAuthenticatedUserTokenChangeCallback(this._authenticatedUserToken);
}
return this._authenticatedUserToken;
}
export function getAuthenticatedUserToken(
this: AlgoliaAnalytics,
options?: any,
callback?: (err: any, authenticatedUserToken?: number | string) => void
): number | string | undefined {
if (isFunction(callback)) {
callback(null, this._authenticatedUserToken);
}
return this._authenticatedUserToken;
}
export function onAuthenticatedUserTokenChange(
this: AlgoliaAnalytics,
callback?: (authenticatedUserToken?: number | string) => void,
options?: { immediate: boolean }
): void {
this._onAuthenticatedUserTokenChangeCallback = callback;
if (
options &&
options.immediate &&
isFunction(this._onAuthenticatedUserTokenChangeCallback)
) {
this._onAuthenticatedUserTokenChangeCallback(this._authenticatedUserToken);
}
}

73
node_modules/search-insights/lib/click.ts generated vendored Normal file
View File

@@ -0,0 +1,73 @@
import { addEventType } from "./_addEventType";
import type AlgoliaAnalytics from "./insights";
import type { WithAdditionalParams } from "./utils";
import { extractAdditionalParams, storeQueryForObject } from "./utils";
export interface InsightsSearchClickEvent {
eventName: string;
userToken?: string;
authenticatedUserToken?: string;
timestamp?: number;
index: string;
queryID: string;
objectIDs: string[];
positions: number[];
}
export function clickedObjectIDsAfterSearch(
this: AlgoliaAnalytics,
...params: Array<WithAdditionalParams<InsightsSearchClickEvent>>
): ReturnType<AlgoliaAnalytics["sendEvents"]> {
const { events, additionalParams } =
extractAdditionalParams<InsightsSearchClickEvent>(params);
events.forEach(({ index, queryID, objectIDs }) =>
objectIDs.forEach(
(objectID) =>
!this._userHasOptedOut && storeQueryForObject(index, objectID, queryID)
)
);
return this.sendEvents(addEventType("click", events), additionalParams);
}
export interface InsightsClickObjectIDsEvent {
eventName: string;
userToken?: string;
authenticatedUserToken?: string;
timestamp?: number;
index: string;
objectIDs: string[];
}
export function clickedObjectIDs(
this: AlgoliaAnalytics,
...params: Array<WithAdditionalParams<InsightsClickObjectIDsEvent>>
): ReturnType<AlgoliaAnalytics["sendEvents"]> {
const { events, additionalParams } =
extractAdditionalParams<InsightsClickObjectIDsEvent>(params);
return this.sendEvents(addEventType("click", events), additionalParams);
}
export interface InsightsClickFiltersEvent {
eventName: string;
userToken?: string;
authenticatedUserToken?: string;
timestamp?: number;
index: string;
filters: string[];
}
export function clickedFilters(
this: AlgoliaAnalytics,
...params: Array<WithAdditionalParams<InsightsClickFiltersEvent>>
): ReturnType<AlgoliaAnalytics["sendEvents"]> {
const { events, additionalParams } =
extractAdditionalParams<InsightsClickFiltersEvent>(params);
return this.sendEvents(addEventType("click", events), additionalParams);
}

148
node_modules/search-insights/lib/conversion.ts generated vendored Normal file
View File

@@ -0,0 +1,148 @@
import { addEventType, addEventTypeAndSubtype } from "./_addEventType";
import type AlgoliaAnalytics from "./insights";
import type { InsightsEvent } from "./types";
import type { WithAdditionalParams } from "./utils";
import { extractAdditionalParams, storeQueryForObject } from "./utils";
export interface InsightsSearchConversionEvent {
eventName: string;
userToken?: string;
authenticatedUserToken?: string;
timestamp?: number;
index: string;
queryID: string;
objectIDs: string[];
objectData?: InsightsEvent["objectData"];
value?: InsightsEvent["value"];
currency?: InsightsEvent["currency"];
}
export function convertedObjectIDsAfterSearch(
this: AlgoliaAnalytics,
...params: Array<WithAdditionalParams<InsightsSearchConversionEvent>>
): ReturnType<AlgoliaAnalytics["sendEvents"]> {
const { events, additionalParams } =
extractAdditionalParams<InsightsSearchConversionEvent>(params);
return this.sendEvents(addEventType("conversion", events), additionalParams);
}
export function addedToCartObjectIDsAfterSearch(
this: AlgoliaAnalytics,
...params: Array<WithAdditionalParams<InsightsSearchConversionEvent>>
): ReturnType<AlgoliaAnalytics["sendEvents"]> {
const { events, additionalParams } =
extractAdditionalParams<InsightsSearchConversionEvent>(params);
events.forEach(({ index, queryID, objectIDs, objectData }) =>
objectIDs.forEach((objectID, i) => {
const objQueryID = objectData?.[i]?.queryID ?? queryID;
if (!this._userHasOptedOut && objQueryID)
storeQueryForObject(index, objectID, objQueryID);
})
);
return this.sendEvents(
addEventTypeAndSubtype("conversion", "addToCart", events),
additionalParams
);
}
export type InsightsSearchPurchaseEvent = Omit<
InsightsSearchConversionEvent,
"queryID"
> & {
/** @deprecated Use objectData.queryID instead. */
queryID?: string;
};
export function purchasedObjectIDsAfterSearch(
this: AlgoliaAnalytics,
...params: Array<WithAdditionalParams<InsightsSearchPurchaseEvent>>
): ReturnType<AlgoliaAnalytics["sendEvents"]> {
const { events, additionalParams } =
extractAdditionalParams<InsightsSearchPurchaseEvent>(params);
return this.sendEvents(
addEventTypeAndSubtype("conversion", "purchase", events),
additionalParams
);
}
export interface InsightsSearchConversionObjectIDsEvent {
eventName: string;
userToken?: string;
authenticatedUserToken?: string;
timestamp?: number;
index: string;
objectIDs: string[];
objectData?: InsightsEvent["objectData"];
value?: InsightsEvent["value"];
currency?: InsightsEvent["currency"];
}
export function convertedObjectIDs(
this: AlgoliaAnalytics,
...params: Array<WithAdditionalParams<InsightsSearchConversionObjectIDsEvent>>
): ReturnType<AlgoliaAnalytics["sendEvents"]> {
const { events, additionalParams } =
extractAdditionalParams<InsightsSearchConversionObjectIDsEvent>(params);
return this.sendEvents(addEventType("conversion", events), additionalParams);
}
export function addedToCartObjectIDs(
this: AlgoliaAnalytics,
...params: Array<WithAdditionalParams<InsightsSearchConversionObjectIDsEvent>>
): ReturnType<AlgoliaAnalytics["sendEvents"]> {
const { events, additionalParams } =
extractAdditionalParams<InsightsSearchConversionObjectIDsEvent>(params);
events.forEach(({ index, objectIDs, objectData }) =>
objectIDs.forEach((objectID, i) => {
const queryID = objectData?.[i]?.queryID;
if (!this._userHasOptedOut && queryID)
storeQueryForObject(index, objectID, queryID);
})
);
return this.sendEvents(
addEventTypeAndSubtype("conversion", "addToCart", events),
additionalParams
);
}
export function purchasedObjectIDs(
this: AlgoliaAnalytics,
...params: Array<WithAdditionalParams<InsightsSearchConversionObjectIDsEvent>>
): ReturnType<AlgoliaAnalytics["sendEvents"]> {
const { events, additionalParams } =
extractAdditionalParams<InsightsSearchConversionObjectIDsEvent>(params);
return this.sendEvents(
addEventTypeAndSubtype("conversion", "purchase", events),
additionalParams
);
}
export interface InsightsSearchConversionFiltersEvent {
eventName: string;
userToken?: string;
authenticatedUserToken?: string;
timestamp?: number;
index: string;
filters: string[];
}
export function convertedFilters(
this: AlgoliaAnalytics,
...params: Array<WithAdditionalParams<InsightsSearchConversionFiltersEvent>>
): ReturnType<AlgoliaAnalytics["sendEvents"]> {
const { events, additionalParams } =
extractAdditionalParams<InsightsSearchConversionFiltersEvent>(params);
return this.sendEvents(addEventType("conversion", events), additionalParams);
}

18
node_modules/search-insights/lib/entry-browser.ts generated vendored Normal file
View File

@@ -0,0 +1,18 @@
import { createInsightsClient } from "./_createInsightsClient";
import { getFunctionalInterface } from "./_getFunctionalInterface";
import { processQueue } from "./_processQueue";
import AlgoliaAnalytics from "./insights";
import { getRequesterForBrowser } from "./utils/getRequesterForBrowser";
import { LocalStorage } from "./utils/localStorage";
export {
createInsightsClient,
getRequesterForBrowser,
AlgoliaAnalytics,
LocalStorage,
getFunctionalInterface,
processQueue
};
export * from "./types";
export default createInsightsClient(getRequesterForBrowser());

18
node_modules/search-insights/lib/entry-node.ts generated vendored Normal file
View File

@@ -0,0 +1,18 @@
import { createInsightsClient } from "./_createInsightsClient";
import { getFunctionalInterface } from "./_getFunctionalInterface";
import { processQueue } from "./_processQueue";
import AlgoliaAnalytics from "./insights";
import { getRequesterForNode } from "./utils/getRequesterForNode";
import { LocalStorage } from "./utils/localStorage";
export {
createInsightsClient,
getRequesterForNode,
AlgoliaAnalytics,
LocalStorage,
getFunctionalInterface,
processQueue
};
export * from "./types";
export default createInsightsClient(getRequesterForNode());

21
node_modules/search-insights/lib/entry-umd.ts generated vendored Normal file
View File

@@ -0,0 +1,21 @@
import { version } from "../package.json";
import { processQueue } from "./_processQueue";
import AlgoliaAnalytics from "./insights";
import { getRequesterForBrowser } from "./utils/getRequesterForBrowser";
import type { RequestFnType } from "./utils/request";
export function createInsightsClient(
requestFn: RequestFnType
): AlgoliaAnalytics {
const instance = new AlgoliaAnalytics({ requestFn });
if (typeof window === "object") {
// Process queue upon script execution
processQueue.call(instance, window);
}
instance.version = version;
return instance;
}
export default createInsightsClient(getRequesterForBrowser());

126
node_modules/search-insights/lib/init.ts generated vendored Normal file
View File

@@ -0,0 +1,126 @@
import { DEFAULT_ALGOLIA_AGENTS } from "./_algoliaAgent";
import { checkIfAnonymousToken, MONTH } from "./_tokenUtils";
import type AlgoliaAnalytics from "./insights";
import { isUndefined, isNumber } from "./utils";
type InsightRegion = "de" | "us";
const SUPPORTED_REGIONS: InsightRegion[] = ["de", "us"];
export interface InitParams {
apiKey?: string;
appId?: string;
userHasOptedOut?: boolean;
anonymousUserToken?: boolean;
useCookie?: boolean;
cookieDuration?: number;
region?: InsightRegion;
userToken?: string;
authenticatedUserToken?: string;
partial?: boolean;
host?: string;
}
/**
* Binds credentials and settings to class.
*
* @param options - InitParams.
*/
export function init(this: AlgoliaAnalytics, options: InitParams = {}): void {
if (
!isUndefined(options.region) &&
SUPPORTED_REGIONS.indexOf(options.region) === -1
) {
throw new Error(
`optional region is incorrect, please provide either one of: ${SUPPORTED_REGIONS.join(
", "
)}.`
);
}
if (
!isUndefined(options.cookieDuration) &&
(!isNumber(options.cookieDuration) ||
!isFinite(options.cookieDuration) ||
Math.floor(options.cookieDuration) !== options.cookieDuration)
) {
throw new Error(
`optional cookieDuration is incorrect, expected an integer.`
);
}
/* eslint-disable no-console */
if (__DEV__) {
console.info(`Since v2.0.4, search-insights no longer validates event payloads.
You can visit https://algolia.com/events/debugger instead.`);
}
/* eslint-enable */
setOptions(this, options, {
_userHasOptedOut: Boolean(options.userHasOptedOut),
_region: options.region,
_host: options.host,
_anonymousUserToken: options.anonymousUserToken ?? true,
_useCookie: options.useCookie ?? false,
_cookieDuration: options.cookieDuration || 6 * MONTH
});
this._endpointOrigin =
this._host ||
(this._region
? `https://insights.${this._region}.algolia.io`
: "https://insights.algolia.io");
// user agent
this._ua = [...DEFAULT_ALGOLIA_AGENTS];
if (options.authenticatedUserToken) {
this.setAuthenticatedUserToken(options.authenticatedUserToken);
}
if (options.userToken) {
this.setUserToken(options.userToken);
} else if (!this._userToken && !this._userHasOptedOut && this._useCookie) {
this.setAnonymousUserToken();
} else if (checkIfTokenNeedsToBeSaved(this)) {
this.saveTokenAsCookie();
}
}
type ThisParams = Pick<
AlgoliaAnalytics,
| "_anonymousUserToken"
| "_cookieDuration"
| "_host"
| "_region"
| "_useCookie"
| "_userHasOptedOut"
>;
function setOptions(
target: AlgoliaAnalytics,
{ partial, ...options }: InitParams,
defaultValues: ThisParams
): void {
if (!partial) {
Object.assign(target, defaultValues);
}
Object.assign(
target,
(Object.keys(options) as Array<keyof typeof options>).reduce(
(acc, key) => ({ ...acc, [`_${key}`]: options[key] }),
{}
)
);
}
function checkIfTokenNeedsToBeSaved(target: AlgoliaAnalytics): boolean {
if (target._userToken === undefined) {
return false;
}
return (
checkIfAnonymousToken(target._userToken) &&
target._useCookie &&
!target._userHasOptedOut
);
}

147
node_modules/search-insights/lib/insights.ts generated vendored Normal file
View File

@@ -0,0 +1,147 @@
import { version } from "../package.json";
import { addAlgoliaAgent } from "./_algoliaAgent";
import { getVersion } from "./_getVersion";
import { makeSendEvents } from "./_sendEvent";
import {
getUserToken,
setUserToken,
setAnonymousUserToken,
onUserTokenChange,
MONTH,
setAuthenticatedUserToken,
onAuthenticatedUserTokenChange,
getAuthenticatedUserToken,
saveTokenAsCookie
} from "./_tokenUtils";
import {
clickedObjectIDsAfterSearch,
clickedObjectIDs,
clickedFilters
} from "./click";
import {
convertedObjectIDsAfterSearch,
addedToCartObjectIDsAfterSearch,
purchasedObjectIDsAfterSearch,
convertedObjectIDs,
addedToCartObjectIDs,
purchasedObjectIDs,
convertedFilters
} from "./conversion";
import { init } from "./init";
import type { RequestFnType } from "./utils/request";
import { viewedObjectIDs, viewedFilters } from "./view";
type Queue = {
queue: string[][];
};
type AnalyticsFunction = {
[key: string]: (fnName: string, fnArgs: any[]) => void;
};
export type AlgoliaAnalyticsObject = AnalyticsFunction | Queue;
declare global {
interface Window {
AlgoliaAnalyticsObject?: string;
}
}
/**
* AlgoliaAnalytics class.
*/
class AlgoliaAnalytics {
_apiKey?: string;
_appId?: string;
_region?: string;
_host?: string;
_endpointOrigin = "https://insights.algolia.io";
_anonymousUserToken = true;
_userToken?: number | string;
_authenticatedUserToken?: number | string;
_userHasOptedOut = false;
_useCookie = false;
_cookieDuration = 6 * MONTH;
// user agent
_ua: string[] = [];
_onUserTokenChangeCallback?: (userToken?: number | string) => void;
_onAuthenticatedUserTokenChangeCallback?: (
authenticatedUserToken?: number | string
) => void;
version: string = version;
// Public methods
init: typeof init;
getVersion: typeof getVersion;
addAlgoliaAgent: typeof addAlgoliaAgent;
saveTokenAsCookie: typeof saveTokenAsCookie;
setUserToken: typeof setUserToken;
setAnonymousUserToken: typeof setAnonymousUserToken;
getUserToken: typeof getUserToken;
onUserTokenChange: typeof onUserTokenChange;
setAuthenticatedUserToken: typeof setAuthenticatedUserToken;
getAuthenticatedUserToken: typeof getAuthenticatedUserToken;
onAuthenticatedUserTokenChange: typeof onAuthenticatedUserTokenChange;
sendEvents: ReturnType<typeof makeSendEvents>;
clickedObjectIDsAfterSearch: typeof clickedObjectIDsAfterSearch;
clickedObjectIDs: typeof clickedObjectIDs;
clickedFilters: typeof clickedFilters;
convertedObjectIDsAfterSearch: typeof convertedObjectIDsAfterSearch;
purchasedObjectIDsAfterSearch: typeof purchasedObjectIDsAfterSearch;
addedToCartObjectIDsAfterSearch: typeof addedToCartObjectIDsAfterSearch;
convertedObjectIDs: typeof convertedObjectIDs;
addedToCartObjectIDs: typeof addedToCartObjectIDs;
purchasedObjectIDs: typeof purchasedObjectIDs;
convertedFilters: typeof convertedFilters;
viewedObjectIDs: typeof viewedObjectIDs;
viewedFilters: typeof viewedFilters;
constructor({ requestFn }: { requestFn: RequestFnType }) {
this.sendEvents = makeSendEvents(requestFn).bind(this);
this.init = init.bind(this);
this.addAlgoliaAgent = addAlgoliaAgent.bind(this);
this.saveTokenAsCookie = saveTokenAsCookie.bind(this);
this.setUserToken = setUserToken.bind(this);
this.setAnonymousUserToken = setAnonymousUserToken.bind(this);
this.getUserToken = getUserToken.bind(this);
this.onUserTokenChange = onUserTokenChange.bind(this);
this.setAuthenticatedUserToken = setAuthenticatedUserToken.bind(this);
this.getAuthenticatedUserToken = getAuthenticatedUserToken.bind(this);
this.onAuthenticatedUserTokenChange =
onAuthenticatedUserTokenChange.bind(this);
this.clickedObjectIDsAfterSearch = clickedObjectIDsAfterSearch.bind(this);
this.clickedObjectIDs = clickedObjectIDs.bind(this);
this.clickedFilters = clickedFilters.bind(this);
this.convertedObjectIDsAfterSearch =
convertedObjectIDsAfterSearch.bind(this);
this.purchasedObjectIDsAfterSearch =
purchasedObjectIDsAfterSearch.bind(this);
this.addedToCartObjectIDsAfterSearch =
addedToCartObjectIDsAfterSearch.bind(this);
this.convertedObjectIDs = convertedObjectIDs.bind(this);
this.addedToCartObjectIDs = addedToCartObjectIDs.bind(this);
this.purchasedObjectIDs = purchasedObjectIDs.bind(this);
this.convertedFilters = convertedFilters.bind(this);
this.viewedObjectIDs = viewedObjectIDs.bind(this);
this.viewedFilters = viewedFilters.bind(this);
this.getVersion = getVersion.bind(this);
}
}
export default AlgoliaAnalytics;

150
node_modules/search-insights/lib/types.ts generated vendored Normal file
View File

@@ -0,0 +1,150 @@
import type { addAlgoliaAgent } from "./_algoliaAgent";
import type { getVersion } from "./_getVersion";
import type { makeSendEvents } from "./_sendEvent";
import type {
getUserToken,
setUserToken,
onUserTokenChange,
onAuthenticatedUserTokenChange,
setAuthenticatedUserToken,
getAuthenticatedUserToken
} from "./_tokenUtils";
import type {
clickedObjectIDsAfterSearch,
clickedObjectIDs,
clickedFilters
} from "./click";
import type {
convertedObjectIDsAfterSearch,
convertedObjectIDs,
convertedFilters,
purchasedObjectIDs,
purchasedObjectIDsAfterSearch,
addedToCartObjectIDsAfterSearch,
addedToCartObjectIDs
} from "./conversion";
import type { init } from "./init";
import type { viewedObjectIDs, viewedFilters } from "./view";
type ParamReturnTypeTuple<T extends (...args: any) => any> = [
Parameters<T>,
ReturnType<T>
];
export type InsightsMethodMap = {
init: ParamReturnTypeTuple<typeof init>;
getVersion: ParamReturnTypeTuple<typeof getVersion>;
addAlgoliaAgent: ParamReturnTypeTuple<typeof addAlgoliaAgent>;
setUserToken: ParamReturnTypeTuple<typeof setUserToken>;
getUserToken: ParamReturnTypeTuple<typeof getUserToken>;
onUserTokenChange: ParamReturnTypeTuple<typeof onUserTokenChange>;
setAuthenticatedUserToken: ParamReturnTypeTuple<
typeof setAuthenticatedUserToken
>;
getAuthenticatedUserToken: ParamReturnTypeTuple<
typeof getAuthenticatedUserToken
>;
onAuthenticatedUserTokenChange: ParamReturnTypeTuple<
typeof onAuthenticatedUserTokenChange
>;
clickedObjectIDsAfterSearch: ParamReturnTypeTuple<
typeof clickedObjectIDsAfterSearch
>;
clickedObjectIDs: ParamReturnTypeTuple<typeof clickedObjectIDs>;
clickedFilters: ParamReturnTypeTuple<typeof clickedFilters>;
convertedObjectIDsAfterSearch: ParamReturnTypeTuple<
typeof convertedObjectIDsAfterSearch
>;
convertedObjectIDs: ParamReturnTypeTuple<typeof convertedObjectIDs>;
convertedFilters: ParamReturnTypeTuple<typeof convertedFilters>;
viewedObjectIDs: ParamReturnTypeTuple<typeof viewedObjectIDs>;
viewedFilters: ParamReturnTypeTuple<typeof viewedFilters>;
purchasedObjectIDs: ParamReturnTypeTuple<typeof purchasedObjectIDs>;
purchasedObjectIDsAfterSearch: ParamReturnTypeTuple<
typeof purchasedObjectIDsAfterSearch
>;
addedToCartObjectIDs: ParamReturnTypeTuple<typeof addedToCartObjectIDs>;
addedToCartObjectIDsAfterSearch: ParamReturnTypeTuple<
typeof addedToCartObjectIDsAfterSearch
>;
sendEvents: ParamReturnTypeTuple<ReturnType<typeof makeSendEvents>>;
};
type MethodType<MethodName extends keyof InsightsMethodMap> = (
method: MethodName,
...args: InsightsMethodMap[MethodName][0]
) => InsightsMethodMap[MethodName][1];
export type Init = MethodType<"init">;
export type GetVersion = MethodType<"getVersion">;
export type AddAlgoliaAgent = MethodType<"addAlgoliaAgent">;
export type SetUserToken = MethodType<"setUserToken">;
export type GetUserToken = MethodType<"getUserToken">;
export type OnUserTokenChange = MethodType<"onUserTokenChange">;
export type ClickedObjectIDsAfterSearch =
MethodType<"clickedObjectIDsAfterSearch">;
export type ClickedObjectIDs = MethodType<"clickedObjectIDs">;
export type ClickedFilters = MethodType<"clickedFilters">;
export type ConvertedObjectIDsAfterSearch =
MethodType<"convertedObjectIDsAfterSearch">;
export type ConvertedObjectIDs = MethodType<"convertedObjectIDs">;
export type ConvertedFilters = MethodType<"convertedFilters">;
export type ViewedObjectIDs = MethodType<"viewedObjectIDs">;
export type ViewedFilters = MethodType<"viewedFilters">;
export type SendEvents = MethodType<"sendEvents">;
export type InsightsClient = (<MethodName extends keyof InsightsMethodMap>(
method: MethodName,
...args: InsightsMethodMap[MethodName][0]
) => InsightsMethodMap[MethodName][1]) & { version?: string };
export type InsightsEventType = "click" | "conversion" | "view";
export type InsightsEventConversionSubType = "addToCart" | "purchase";
export type InsightsEventObjectData = {
queryID?: string;
price?: number | string;
discount?: number | string;
quantity?: number;
};
export type InsightsEvent = {
eventType: InsightsEventType;
eventSubtype?: InsightsEventConversionSubType;
eventName: string;
userToken?: number | string;
authenticatedUserToken?: number | string;
timestamp?: number;
index: string;
queryID?: string;
objectIDs?: string[];
positions?: number[];
objectData?: InsightsEventObjectData[];
objectIDsWithInferredQueryID?: string[];
filters?: string[];
value?: number | string;
currency?: string;
};
export type InsightsAdditionalEventParams = {
headers?: Record<string, string>;
inferQueryID?: boolean;
};

4
node_modules/search-insights/lib/typings.d.ts generated vendored Normal file
View File

@@ -0,0 +1,4 @@
declare module "*/package.json";
declare const __DEV__: boolean;
declare const __FLAVOR__: string;

View File

@@ -0,0 +1,25 @@
import type { InsightsAdditionalEventParams } from "../types";
export type WithAdditionalParams<TEventType> =
| InsightsAdditionalEventParams
| TEventType;
export function extractAdditionalParams<TEventType extends { index: string }>(
params: Array<InsightsAdditionalEventParams | TEventType>
): { events: TEventType[]; additionalParams?: InsightsAdditionalEventParams } {
return params.reduce(
({ events, additionalParams }, param) => {
// Real events all have `index` as a mandatory parameter, which we
// can rely on to distinguish them from additional parameters
if ("index" in param) {
return { additionalParams, events: [...events, param] };
}
return { events, additionalParams: param };
},
{
events: [] as TEventType[],
additionalParams: undefined as InsightsAdditionalEventParams | undefined
}
);
}

View File

@@ -0,0 +1,43 @@
export const supportsCookies = (): boolean => {
try {
return Boolean(navigator.cookieEnabled);
} catch (e) {
return false;
}
};
export const supportsSendBeacon = (): boolean => {
try {
return Boolean(navigator.sendBeacon);
} catch (e) {
return false;
}
};
export const supportsXMLHttpRequest = (): boolean => {
try {
return Boolean(XMLHttpRequest);
} catch (e) {
return false;
}
};
export const supportsNodeHttpModule = (): boolean => {
try {
/* eslint-disable @typescript-eslint/no-var-requires */
const { request: nodeHttpRequest } = require("http");
const { request: nodeHttpsRequest } = require("https");
/* eslint-enable */
return Boolean(nodeHttpRequest) && Boolean(nodeHttpsRequest);
} catch (e) {
return false;
}
};
export const supportsNativeFetch = (): boolean => {
try {
return fetch !== undefined;
} catch (e) {
return false;
}
};

View File

@@ -0,0 +1,29 @@
import {
supportsNativeFetch,
supportsSendBeacon,
supportsXMLHttpRequest
} from "./featureDetection";
import type { RequestFnType } from "./request";
import {
requestWithNativeFetch,
requestWithSendBeacon,
requestWithXMLHttpRequest
} from "./request";
export function getRequesterForBrowser(): RequestFnType {
if (supportsSendBeacon()) {
return requestWithSendBeacon;
}
if (supportsXMLHttpRequest()) {
return requestWithXMLHttpRequest;
}
if (supportsNativeFetch()) {
return requestWithNativeFetch;
}
throw new Error(
"Could not find a supported HTTP request client in this environment."
);
}

View File

@@ -0,0 +1,20 @@
import {
supportsNodeHttpModule,
supportsNativeFetch
} from "./featureDetection";
import type { RequestFnType } from "./request";
import { requestWithNodeHttpModule, requestWithNativeFetch } from "./request";
export function getRequesterForNode(): RequestFnType {
if (supportsNodeHttpModule()) {
return requestWithNodeHttpModule;
}
if (supportsNativeFetch()) {
return requestWithNativeFetch;
}
throw new Error(
"Could not find a supported HTTP request client in this environment."
);
}

19
node_modules/search-insights/lib/utils/index.ts generated vendored Normal file
View File

@@ -0,0 +1,19 @@
// use theses type checking helpers to avoid mistyping "undefind", I mean "undfined"
export const isUndefined = (value: any): value is undefined =>
typeof value === "undefined";
export const isString = (value: any): value is string =>
typeof value === "string";
export const isNumber = (value: any): value is number =>
typeof value === "number";
/* eslint-disable @typescript-eslint/ban-types */
export const isFunction = (value: any): value is Function =>
typeof value === "function";
/* eslint-enable */
export const isPromise = <T>(value: Promise<T> | T): value is Promise<T> =>
typeof (value as Promise<T> | undefined)?.then === "function";
export * from "./extractAdditionalParams";
export * from "./featureDetection";
export * from "./objectQueryTracker";

64
node_modules/search-insights/lib/utils/localStorage.ts generated vendored Normal file
View File

@@ -0,0 +1,64 @@
/**
* A utility class for safely interacting with localStorage.
*/
export class LocalStorage {
static store: Storage | undefined = ensureLocalStorage();
/**
* Safely get a value from localStorage.
* If the value is not able to be parsed as JSON, this method will return null.
*
* @param key - String value of the key.
* @returns Null if the key is not found or unable to be parsed, the value otherwise.
*/
static get<T>(key: string): T | null {
const val = this.store?.getItem(key);
if (!val) {
return null;
}
try {
return JSON.parse(val) as T;
} catch {
return null;
}
}
/**
* Safely set a value in localStorage.
* If the storage is full, this method will catch the error and log a warning.
*
* @param key - String value of the key.
* @param value - Any value to store.
*/
static set(key: string, value: any): void {
try {
this.store?.setItem(key, JSON.stringify(value));
} catch {
// eslint-disable-next-line no-console
console.error(
`Unable to set ${key} in localStorage, storage may be full.`
);
}
}
/**
* Remove a value from localStorage.
*
* @param key - String value of the key.
*/
static remove(key: string): void {
this.store?.removeItem(key);
}
}
function ensureLocalStorage(): Storage | undefined {
try {
const testKey = "__test_localStorage__";
globalThis.localStorage.setItem(testKey, testKey);
globalThis.localStorage.removeItem(testKey);
return globalThis.localStorage;
} catch {
return undefined;
}
}

View File

@@ -0,0 +1,74 @@
import { LocalStorage } from "./localStorage";
interface ObjectQueryMap {
[indexAndObjectId: string]: [queryId: string, timestamp: number];
}
const STORE = "AlgoliaObjectQueryCache";
const LIMIT = 5000; // 1 entry is typically no more than 100 bytes, so this is ~500kB worth of data - most browsers allow at least 5MB per origin
const FREE = 1000;
function getCache(): ObjectQueryMap {
return LocalStorage.get(STORE) ?? {};
}
function setCache(objectQueryMap: ObjectQueryMap): void {
LocalStorage.set(STORE, limited(objectQueryMap));
}
function limited(objectQueryMap: ObjectQueryMap): ObjectQueryMap {
return Object.keys(objectQueryMap).length > LIMIT
? purgeOldest(objectQueryMap)
: objectQueryMap;
}
function purgeOldest(objectQueryMap: ObjectQueryMap): ObjectQueryMap {
const sorted = Object.entries(objectQueryMap).sort(
([, [, aTimestamp]], [, [, bTimestamp]]) => bTimestamp - aTimestamp
);
const newObjectQueryMap = sorted
.slice(0, sorted.length - FREE - 1)
.reduce<ObjectQueryMap>(
(acc, [key, value]) => ({
...acc,
[key]: value
}),
{}
);
return newObjectQueryMap;
}
function makeKey(index: string, objectID: string): string {
return `${index}_${objectID}`;
}
export function storeQueryForObject(
index: string,
objectID: string,
queryID: string
): void {
const objectQueryMap = getCache();
objectQueryMap[makeKey(index, objectID)] = [queryID, Date.now()];
setCache(objectQueryMap);
}
export function getQueryForObject(
index: string,
objectID: string
): [queryId: string, timestamp: number] | undefined {
return getCache()[makeKey(index, objectID)];
}
export function removeQueryForObjects(
index: string,
objectIDs: string[]
): void {
const objectQueryMap = getCache();
objectIDs.forEach((objectID) => {
delete objectQueryMap[makeKey(index, objectID)];
});
setCache(objectQueryMap);
}

97
node_modules/search-insights/lib/utils/request.ts generated vendored Normal file
View File

@@ -0,0 +1,97 @@
import type { request as nodeRequest } from "http";
import type { UrlWithStringQuery } from "url";
export type RequestFnType = (
url: string,
data: Record<string, unknown>
) => Promise<boolean>;
export const requestWithXMLHttpRequest: RequestFnType = (url, data) => {
return new Promise((resolve, reject) => {
const serializedData = JSON.stringify(data);
const req = new XMLHttpRequest();
req.addEventListener("readystatechange", () => {
if (req.readyState === 4 && req.status === 200) {
resolve(true);
} else if (req.readyState === 4) {
resolve(false);
}
});
/* eslint-disable prefer-promise-reject-errors */
req.addEventListener("error", () => reject());
/* eslint-enable */
req.addEventListener("timeout", () => resolve(false));
req.open("POST", url);
req.setRequestHeader("Content-Type", "application/json");
req.send(serializedData);
});
};
export const requestWithSendBeacon: RequestFnType = (url, data) => {
const serializedData = JSON.stringify(data);
const beacon = navigator.sendBeacon(url, serializedData);
return Promise.resolve(beacon ? true : requestWithXMLHttpRequest(url, data));
};
export const requestWithNodeHttpModule: RequestFnType = (url, data) => {
return new Promise((resolve, reject) => {
const serializedData = JSON.stringify(data);
/* eslint-disable @typescript-eslint/no-var-requires */
const { protocol, host, path }: UrlWithStringQuery =
require("url").parse(url);
/* eslint-enable */
const options = {
protocol,
host,
path,
method: "POST",
headers: {
"Content-Type": "application/json",
"Content-Length": serializedData.length
}
};
const { request }: { request: typeof nodeRequest } = url.startsWith(
"https://"
)
? require("https")
: require("http");
const req = request(options, ({ statusCode }) => {
if (statusCode === 200) {
resolve(true);
} else {
resolve(false);
}
});
req.on("error", (error) => {
/* eslint-disable no-console */
console.error(error);
/* eslint-enable */
reject(error);
});
req.on("timeout", () => resolve(false));
req.write(serializedData);
req.end();
});
};
export const requestWithNativeFetch: RequestFnType = (url, data) => {
return new Promise((resolve, reject) => {
fetch(url, {
method: "POST",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json"
}
})
.then((response) => {
resolve(response.status === 200);
})
.catch((e: Error) => {
reject(e);
});
});
};

15
node_modules/search-insights/lib/utils/uuid.ts generated vendored Normal file
View File

@@ -0,0 +1,15 @@
/**
* Create UUID according to
* https://www.ietf.org/rfc/rfc4122.txt.
*
* @returns Generated UUID.
*/
export function createUUID(): string {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
/* eslint-disable no-bitwise */
const r = (Math.random() * 16) | 0;
const v = c === "x" ? r : (r & 0x3) | 0x8;
/* eslint-enable */
return v.toString(16);
});
}

44
node_modules/search-insights/lib/view.ts generated vendored Normal file
View File

@@ -0,0 +1,44 @@
import { addEventType } from "./_addEventType";
import type AlgoliaAnalytics from "./insights";
import type { WithAdditionalParams } from "./utils";
import { extractAdditionalParams } from "./utils";
export interface InsightsSearchViewObjectIDsEvent {
eventName: string;
userToken?: string;
authenticatedUserToken?: string;
timestamp?: number;
index: string;
objectIDs: string[];
}
export function viewedObjectIDs(
this: AlgoliaAnalytics,
...params: Array<WithAdditionalParams<InsightsSearchViewObjectIDsEvent>>
): ReturnType<AlgoliaAnalytics["sendEvents"]> {
const { events, additionalParams } =
extractAdditionalParams<InsightsSearchViewObjectIDsEvent>(params);
return this.sendEvents(addEventType("view", events), additionalParams);
}
export interface InsightsSearchViewFiltersEvent {
eventName: string;
userToken?: string;
authenticatedUserToken?: string;
timestamp?: number;
index: string;
filters: string[];
}
export function viewedFilters(
this: AlgoliaAnalytics,
...params: Array<WithAdditionalParams<InsightsSearchViewFiltersEvent>>
): ReturnType<AlgoliaAnalytics["sendEvents"]> {
const { events, additionalParams } =
extractAdditionalParams<InsightsSearchViewFiltersEvent>(params);
return this.sendEvents(addEventType("view", events), additionalParams);
}

102
node_modules/search-insights/package.json generated vendored Normal file
View File

@@ -0,0 +1,102 @@
{
"name": "search-insights",
"description": "Library for reporting click, conversion and view metrics using the Algolia Insights API",
"version": "2.17.3",
"jsdelivr": "dist/search-insights.min.js",
"main": "index-node.cjs",
"types": "index-node.d.ts",
"browser": "index-browser.mjs",
"module": "index-node.mjs",
"exports": {
"types": "./index-browser.d.ts",
"node": {
"types": "./index-node.d.ts",
"import": "./index-node.mjs",
"require": "./index-node.cjs"
},
"browser": {
"import": "./index-browser.mjs",
"require": "./index-browser.cjs"
},
"default": "./index-browser.mjs"
},
"react-native": {
"http": "./empty-module.cjs",
"https": "./empty-module.cjs"
},
"files": [
"dist",
"lib",
"!**/__tests__/**",
"empty-module.*",
"index-browser.*",
"index-node.*"
],
"scripts": {
"build": "rollup --environment NODE_ENV:'production' -c rollup.config.mjs && tsc --build tsconfig.declaration.json",
"build:dev": "rollup --watch --environment NODE_ENV:'development' -c rollup.config.mjs",
"lint": "eslint --ext .js,.ts,.tsx lib",
"lint:fix": "npm run lint -- --fix",
"prettier": "prettier 'lib/**/*.ts' 'docs/**/*.md' --write",
"test": "jest --runInBand",
"test:watch": "yarn test --watch",
"test:size": "bundlesize",
"toc": "markdown-toc -i --maxdepth=3 --bullets=\"-\" README.md",
"type-check": "tsc",
"type-check:watch": "yarn type-check --watch",
"release": "shipjs prepare"
},
"repository": {
"type": "git",
"url": "git+https://github.com/algolia/search-insights.js.git"
},
"author": {
"name": "Algolia",
"url": "https://www.algolia.com"
},
"license": "MIT",
"devDependencies": {
"@babel/core": "^7.22.11",
"@babel/eslint-parser": "^7.22.11",
"@rollup/plugin-buble": "^1.0.2",
"@rollup/plugin-commonjs": "^25.0.4",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.2.1",
"@rollup/plugin-replace": "^5.0.2",
"@rollup/plugin-typescript": "^11.1.3",
"@types/istanbul-reports": "^1.1.1",
"@types/jest": "^29.5.4",
"@types/jsdom": "^21.1.2",
"@types/node": "^20.5.7",
"@typescript-eslint/eslint-plugin": "^6.5.0",
"@typescript-eslint/parser": "^6.5.0",
"bundlesize2": "^0.0.31",
"eslint": "^8.48.0",
"eslint-config-algolia": "^22.0.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-import": "^2.28.1",
"eslint-plugin-jsdoc": "^46.5.1",
"eslint-plugin-prettier": "^5.0.0",
"jest": "^29.6.4",
"jest-environment-jsdom": "^29.6.4",
"jest-fetch-mock": "^3.0.3",
"jest-localstorage-mock": "^2.4.26",
"jest-watch-typeahead": "^2.2.2",
"markdown-toc": "^1.2.0",
"prettier": "^3.0.3",
"rollup": "^3.28.1",
"rollup-plugin-filesize": "^10.0.0",
"rollup-plugin-uglify": "^6.0.4",
"shipjs": "^0.26.3",
"ts-jest": "^29.1.1",
"typescript": "^5.2.2"
},
"bundlesize": [
{
"path": "./dist/search-insights.min.js",
"maxSize": "3.70 kB"
}
],
"packageManager": "yarn@1.22.19"
}