Skip to content

Commit

Permalink
Merge af057fe into b12c292
Browse files Browse the repository at this point in the history
  • Loading branch information
btaillon-coveo committed Oct 29, 2020
2 parents b12c292 + af057fe commit 62ceef2
Show file tree
Hide file tree
Showing 29 changed files with 421 additions and 202 deletions.
4 changes: 2 additions & 2 deletions deploy.beta.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ if (travisBranchName) {
}

console.log('executing deploy script beta');
setTimeout(function() {
exec(`npm publish --tag beta${branchToTag}`, function(error, stdout, stderr) {
setTimeout(function () {
exec(`npm publish --tag beta${branchToTag}`, function (error, stdout, stderr) {
if (error) {
console.log(error, stdout, stderr);
process.exit(1);
Expand Down
2 changes: 1 addition & 1 deletion karma.accessibility.test.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ const configuration = {
}
};

module.exports = function(config) {
module.exports = function (config) {
config.set(configuration);
};
2 changes: 1 addition & 1 deletion karma.unit.test.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@ const configuration = {
}
};

module.exports = function(config) {
module.exports = function (config) {
config.set(configuration);
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,4 @@
"@types/node": "~10.5.4"
},
"snyk": true
}
}
4 changes: 2 additions & 2 deletions src/rest/AnalyticsEndpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { IAPIAnalyticsVisitResponseRest } from './APIAnalyticsVisitResponse';
import { ICustomEvent } from './CustomEvent';
import { ITopQueries } from './TopQueries';
import { SearchEndpoint } from '../rest/SearchEndpoint';
import { AnalyticsInformation } from '../ui/Analytics/AnalyticsInformation';

export interface IAnalyticsEndpointOptions {
accessToken: AccessToken;
Expand Down Expand Up @@ -104,8 +105,7 @@ export class AnalyticsEndpoint {
}

public clearCookies() {
Cookie.erase('visitorId');
Cookie.erase('visitId');
new AnalyticsInformation().clearCookies();
}

private async sendToService(data: Record<string, any>, path: string, paramName: string): Promise<any> {
Expand Down
4 changes: 4 additions & 0 deletions src/rest/AnalyticsEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,8 @@ export interface IAnalyticsEvent {
* **Example:** `{ "currentResultsPerPage": 25, "userRole": "developer" }`
*/
customData?: { [key: string]: any };
/**
* A GUID representing the current user. This GUID is generated locally and stored in a non-expiring browser cookie.
*/
clientId: string;
}
1 change: 1 addition & 0 deletions src/rest/QuerySuggest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ export interface IQuerySuggestRequest {

/**
* A GUID representing the current user, who can be authenticated or anonymous. This GUID is normally generated by the usage analytics service and stored in a non-expiring browser cookie.
* @deprecated
*/
visitorId?: string;

Expand Down
139 changes: 52 additions & 87 deletions src/rest/SearchEndpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import { QueryError } from '../rest/QueryError';
import { Utils } from '../utils/Utils';
import * as _ from 'underscore';
import { buildHistoryStore } from '../utils/HistoryStore';
import { Cookie } from '../utils/CookieUtils';
import { TimeSpan } from '../utils/TimeSpanUtils';
import { UrlUtils } from '../utils/UrlUtils';
import { IGroupByResult } from './GroupByResult';
Expand All @@ -41,6 +40,8 @@ import { BackOffRequest, IBackOffRequest } from './BackOffRequest';
import { IFacetSearchRequest } from './Facet/FacetSearchRequest';
import { IFacetSearchResponse } from './Facet/FacetSearchResponse';
import { IPlanResponse, ExecutionPlan } from './Plan';
import { mapObject } from 'underscore';
import { AnalyticsInformation } from '../ui/Analytics/AnalyticsInformation';

export class DefaultSearchEndpointOptions implements ISearchEndpointOptions {
restUri: string;
Expand Down Expand Up @@ -332,6 +333,7 @@ export class SearchEndpoint implements ISearchEndpoint {

@includeActionsHistory()
@includeReferrer()
@includeAnalytics()
@includeVisitorId()
@includeIsGuestUser()
private buildCompleteCall(request: any, callOptions?: IEndpointCallOptions, callParams?: IEndpointCallParameters) {
Expand Down Expand Up @@ -876,10 +878,6 @@ export class SearchEndpoint implements ISearchEndpoint {
@method('POST')
@requestDataType('application/json')
@responseType('text')
@includeActionsHistory()
@includeReferrer()
@includeVisitorId()
@includeIsGuestUser()
public async facetSearch(
request: IFacetSearchRequest,
callOptions?: IEndpointCallOptions,
Expand Down Expand Up @@ -1081,7 +1079,7 @@ export class SearchEndpoint implements ISearchEndpoint {
this.isRedirecting = true;
}

private buildBaseUri(path: string): string {
public buildBaseUri(path: string): string {
Assert.isString(path);

return UrlUtils.normalizeAsString({
Expand Down Expand Up @@ -1275,18 +1273,19 @@ function defaultDecoratorEndpointCallParameters() {
return params;
}

function getEndpointCallParameters(nbParams: number, args: any[]) {
if (!args[nbParams - 1]) {
args[nbParams - 1] = defaultDecoratorEndpointCallParameters();
}
return args[nbParams - 1] as IEndpointCallParameters;
}

function path(path: string) {
return function (target: Object, key: string, descriptor: TypedPropertyDescriptor<any>) {
const { originalMethod, nbParams } = decoratorSetup(target, key, descriptor);

descriptor.value = function (...args: any[]) {
const url = this.buildBaseUri(path);
if (args[nbParams - 1]) {
args[nbParams - 1].url = url;
} else {
const endpointCallParams = _.extend(defaultDecoratorEndpointCallParameters(), { url: url });
args[nbParams - 1] = endpointCallParams;
}
descriptor.value = function (this: SearchEndpoint, ...args: any[]) {
getEndpointCallParameters(nbParams, args).url = this.buildBaseUri(path);
return originalMethod.apply(this, args);
};

Expand All @@ -1298,14 +1297,8 @@ function alertsPath(path: string) {
return function (target: Object, key: string, descriptor: TypedPropertyDescriptor<any>) {
const { originalMethod, nbParams } = decoratorSetup(target, key, descriptor);

descriptor.value = function (...args: any[]) {
const url = this.buildSearchAlertsUri(path);
if (args[nbParams - 1]) {
args[nbParams - 1].url = url;
} else {
const endpointCallParams = _.extend(defaultDecoratorEndpointCallParameters(), { url: url });
args[nbParams - 1] = endpointCallParams;
}
descriptor.value = function (this: SearchEndpoint, ...args: any[]) {
getEndpointCallParameters(nbParams, args).url = this.buildSearchAlertsUri(path);
return originalMethod.apply(this, args);
};

Expand All @@ -1317,13 +1310,8 @@ function requestDataType(type: string) {
return function (target: Object, key: string, descriptor: TypedPropertyDescriptor<any>) {
const { originalMethod, nbParams } = decoratorSetup(target, key, descriptor);

descriptor.value = function (...args: any[]) {
if (args[nbParams - 1]) {
args[nbParams - 1].requestDataType = type;
} else {
const endpointCallParams = _.extend(defaultDecoratorEndpointCallParameters(), { requestDataType: type });
args[nbParams - 1] = endpointCallParams;
}
descriptor.value = function (this: SearchEndpoint, ...args: any[]) {
getEndpointCallParameters(nbParams, args).requestDataType = type;
return originalMethod.apply(this, args);
};
return descriptor;
Expand All @@ -1334,13 +1322,8 @@ function method(met: string) {
return function (target: Object, key: string, descriptor: TypedPropertyDescriptor<any>) {
const { originalMethod, nbParams } = decoratorSetup(target, key, descriptor);

descriptor.value = function (...args: any[]) {
if (args[nbParams - 1]) {
args[nbParams - 1].method = met;
} else {
const endpointCallParams = _.extend(defaultDecoratorEndpointCallParameters(), { method: met });
args[nbParams - 1] = endpointCallParams;
}
descriptor.value = function (this: SearchEndpoint, ...args: any[]) {
getEndpointCallParameters(nbParams, args).method = met;
return originalMethod.apply(this, args);
};

Expand All @@ -1352,13 +1335,8 @@ function responseType(resp: string) {
return function (target: Object, key: string, descriptor: TypedPropertyDescriptor<any>) {
const { originalMethod, nbParams } = decoratorSetup(target, key, descriptor);

descriptor.value = function (...args: any[]) {
if (args[nbParams - 1]) {
args[nbParams - 1].responseType = resp;
} else {
const endpointCallParams = _.extend(defaultDecoratorEndpointCallParameters(), { responseType: resp });
args[nbParams - 1] = endpointCallParams;
}
descriptor.value = function (this: SearchEndpoint, ...args: any[]) {
getEndpointCallParameters(nbParams, args).responseType = resp;
return originalMethod.apply(this, args);
};

Expand All @@ -1379,14 +1357,10 @@ function accessTokenInUrl(tokenKey: string = 'access_token') {
return queryString;
};

descriptor.value = function (...args: any[]) {
descriptor.value = function (this: SearchEndpoint, ...args: any[]) {
const queryString = buildAccessToken(tokenKey, this);
if (args[nbParams - 1]) {
args[nbParams - 1].queryString = args[nbParams - 1].queryString.concat(queryString);
} else {
const endpointCallParams = _.extend(defaultDecoratorEndpointCallParameters(), { queryString: queryString });
args[nbParams - 1] = endpointCallParams;
}
const params = getEndpointCallParameters(nbParams, args);
params.queryString = [...(params.queryString || []), ...queryString];
return originalMethod.apply(this, args);
};

Expand All @@ -1398,20 +1372,13 @@ function includeActionsHistory(historyStore = buildHistoryStore()) {
return function (target: Object, key: string, descriptor: TypedPropertyDescriptor<any>) {
const { originalMethod, nbParams } = decoratorSetup(target, key, descriptor);

descriptor.value = function (...args: any[]) {
descriptor.value = function (this: SearchEndpoint, ...args: any[]) {
let historyFromStore = historyStore.getHistory();
if (historyFromStore == null) {
historyFromStore = [];
}

if (args[nbParams - 1]) {
args[nbParams - 1].requestData.actionsHistory = historyFromStore;
} else {
const endpointCallParams = _.extend(defaultDecoratorEndpointCallParameters(), {
requestData: { actionsHistory: historyFromStore }
});
args[nbParams - 1] = endpointCallParams;
}
getEndpointCallParameters(nbParams, args).requestData.actionsHistory = historyFromStore;
return originalMethod.apply(this, args);
};

Expand All @@ -1422,20 +1389,32 @@ function includeActionsHistory(historyStore = buildHistoryStore()) {
function includeReferrer() {
return function (target: Object, key: string, descriptor: TypedPropertyDescriptor<any>) {
const { originalMethod, nbParams } = decoratorSetup(target, key, descriptor);
descriptor.value = function (...args: any[]) {
descriptor.value = function (this: SearchEndpoint, ...args: any[]) {
let referrer = document.referrer;
if (referrer == null) {
referrer = '';
}

if (args[nbParams - 1]) {
args[nbParams - 1].requestData.referrer = referrer;
} else {
const endpointCallParams = _.extend(defaultDecoratorEndpointCallParameters(), {
requestData: { referrer: referrer }
});
args[nbParams - 1] = endpointCallParams;
}
getEndpointCallParameters(nbParams, args).requestData.referrer = referrer;
return originalMethod.apply(this, args);
};

return descriptor;
};
}

function includeAnalytics() {
return function (target: Object, key: string, descriptor: TypedPropertyDescriptor<any>) {
const { originalMethod, nbParams } = decoratorSetup(target, key, descriptor);
descriptor.value = function (this: SearchEndpoint, ...args: any[]) {
const analyticsInstance = new AnalyticsInformation();
const analytics = {
clientId: analyticsInstance.clientId,
documentLocation: analyticsInstance.location,
documentReferrer: analyticsInstance.referrer,
pageId: analyticsInstance.lastPageId
};
getEndpointCallParameters(nbParams, args).requestData.analytics = mapObject(analytics, value => value || '');
return originalMethod.apply(this, args);
};

Expand All @@ -1446,20 +1425,13 @@ function includeReferrer() {
function includeVisitorId() {
return function (target: Object, key: string, descriptor: TypedPropertyDescriptor<any>) {
const { originalMethod, nbParams } = decoratorSetup(target, key, descriptor);
descriptor.value = function (...args: any[]) {
let visitorId = Cookie.get('visitorId');
descriptor.value = function (this: SearchEndpoint, ...args: any[]) {
let visitorId = new AnalyticsInformation().visitorId;
if (visitorId == null) {
visitorId = '';
}

if (args[nbParams - 1]) {
args[nbParams - 1].requestData.visitorId = visitorId;
} else {
const endpointCallParams = _.extend(defaultDecoratorEndpointCallParameters(), {
requestData: { visitorId: visitorId }
});
args[nbParams - 1] = endpointCallParams;
}
getEndpointCallParameters(nbParams, args).requestData.visitorId = visitorId;
return originalMethod.apply(this, args);
};

Expand All @@ -1470,17 +1442,10 @@ function includeVisitorId() {
function includeIsGuestUser() {
return function (target: Object, key: string, descriptor: TypedPropertyDescriptor<any>) {
const { originalMethod, nbParams } = decoratorSetup(target, key, descriptor);
descriptor.value = function (...args: any[]) {
descriptor.value = function (this: SearchEndpoint, ...args: any[]) {
let isGuestUser = this.options.isGuestUser;

if (args[nbParams - 1]) {
args[nbParams - 1].requestData.isGuestUser = isGuestUser;
} else {
const endpointCallParams = _.extend(defaultDecoratorEndpointCallParameters(), {
requestData: { isGuestUser: isGuestUser }
});
args[nbParams - 1] = endpointCallParams;
}
getEndpointCallParameters(nbParams, args).requestData.isGuestUser = isGuestUser;
return originalMethod.apply(this, args);
};

Expand Down
13 changes: 12 additions & 1 deletion src/ui/Analytics/Analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ import { PendingSearchEvent } from './PendingSearchEvent';
import { PendingSearchAsYouTypeSearchEvent } from './PendingSearchAsYouTypeSearchEvent';
import { AccessToken } from '../../rest/AccessToken';
import { AnalyticsEvents, IAnalyticsEventArgs } from '../../events/AnalyticsEvents';
import { Cookie } from '../../utils/CookieUtils';
import { QueryUtils } from '../../utils/QueryUtils';
import { AnalyticsInformation } from './AnalyticsInformation';

export interface IAnalyticsOptions {
user?: string;
Expand Down Expand Up @@ -254,6 +257,8 @@ export class Analytics extends Component {
let event = this.componentOptionsModel.getEventName(Model.eventTypes.changeOne + ComponentOptionsModel.attributesEnum.searchHub);
this.bind.onRootElement(event, (args: IAttributeChangedEventArg) => this.handleSearchHubChanged(args));
}

this.createClientId();
}

/**
Expand Down Expand Up @@ -405,7 +410,7 @@ export class Analytics extends Component {
if (this.disabled || this.client instanceof NoopAnalyticsClient) {
return this.logger.warn('Could not clear local data while analytics are disabled.');
}
this.client.endpoint.clearCookies();
new AnalyticsInformation().clearCookies();
this.resolveQueryController().resetHistory();
}

Expand Down Expand Up @@ -455,6 +460,12 @@ export class Analytics extends Component {
});
}

private createClientId() {
if (!new AnalyticsInformation().clientId) {
Cookie.set('clientId', QueryUtils.createGuid());
}
}

private initializeAnalyticsClient() {
if (Utils.isNonEmptyString(this.options.endpoint)) {
let endpoint = this.initializeAnalyticsEndpoint();
Expand Down

0 comments on commit 62ceef2

Please sign in to comment.