@tracelog/lib 0.5.4 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +157 -180
- package/dist/browser/tracelog.esm.js +1007 -1357
- package/dist/browser/tracelog.js +2 -2
- package/dist/cjs/api.d.ts +12 -2
- package/dist/cjs/api.js +63 -27
- package/dist/cjs/app.d.ts +2 -2
- package/dist/cjs/app.js +26 -32
- package/dist/cjs/constants/config.constants.d.ts +4 -2
- package/dist/cjs/constants/config.constants.js +6 -18
- package/dist/cjs/constants/index.d.ts +0 -1
- package/dist/cjs/constants/index.js +0 -1
- package/dist/cjs/constants/storage.constants.d.ts +3 -2
- package/dist/cjs/constants/storage.constants.js +4 -4
- package/dist/cjs/handlers/click.handler.js +3 -6
- package/dist/cjs/handlers/error.handler.js +1 -11
- package/dist/cjs/handlers/page-view.handler.js +0 -4
- package/dist/cjs/handlers/performance.handler.js +14 -29
- package/dist/cjs/handlers/scroll.handler.js +7 -6
- package/dist/cjs/handlers/session.handler.js +7 -6
- package/dist/cjs/integrations/google-analytics.integration.js +2 -6
- package/dist/cjs/listeners/activity-listener-manager.js +3 -3
- package/dist/cjs/listeners/input-listener-managers.js +3 -3
- package/dist/cjs/listeners/touch-listener-manager.js +3 -3
- package/dist/cjs/listeners/unload-listener-manager.js +3 -3
- package/dist/cjs/listeners/visibility-listener-manager.js +3 -3
- package/dist/cjs/managers/event.manager.d.ts +2 -1
- package/dist/cjs/managers/event.manager.js +60 -38
- package/dist/cjs/managers/sender.manager.js +29 -36
- package/dist/cjs/managers/session.manager.js +5 -13
- package/dist/cjs/managers/state.manager.d.ts +0 -3
- package/dist/cjs/managers/state.manager.js +1 -43
- package/dist/cjs/managers/storage.manager.d.ts +16 -2
- package/dist/cjs/managers/storage.manager.js +73 -19
- package/dist/cjs/managers/user.manager.d.ts +1 -1
- package/dist/cjs/managers/user.manager.js +2 -2
- package/dist/cjs/public-api.d.ts +3 -3
- package/dist/cjs/public-api.js +1 -1
- package/dist/cjs/test-bridge.d.ts +1 -0
- package/dist/cjs/test-bridge.js +37 -2
- package/dist/cjs/types/config.types.d.ts +15 -18
- package/dist/cjs/types/config.types.js +6 -0
- package/dist/cjs/types/event.types.d.ts +1 -13
- package/dist/cjs/types/index.d.ts +0 -2
- package/dist/cjs/types/index.js +0 -2
- package/dist/cjs/types/mode.types.d.ts +1 -2
- package/dist/cjs/types/mode.types.js +0 -1
- package/dist/cjs/types/queue.types.d.ts +0 -6
- package/dist/cjs/types/state.types.d.ts +2 -0
- package/dist/cjs/types/test-bridge.types.d.ts +2 -2
- package/dist/cjs/types/validation-error.types.d.ts +0 -6
- package/dist/cjs/types/validation-error.types.js +1 -10
- package/dist/cjs/utils/browser/device-detector.utils.js +2 -24
- package/dist/cjs/utils/browser/index.d.ts +1 -0
- package/dist/cjs/utils/browser/index.js +1 -0
- package/dist/cjs/utils/browser/qa-mode.utils.d.ts +13 -0
- package/dist/cjs/utils/browser/qa-mode.utils.js +43 -0
- package/dist/cjs/utils/browser/utm-params.utils.js +0 -15
- package/dist/cjs/utils/data/uuid.utils.d.ts +13 -0
- package/dist/cjs/utils/data/uuid.utils.js +37 -1
- package/dist/cjs/utils/index.d.ts +1 -1
- package/dist/cjs/utils/index.js +1 -1
- package/dist/cjs/utils/logging.utils.d.ts +6 -0
- package/dist/cjs/utils/logging.utils.js +25 -0
- package/dist/cjs/utils/network/index.d.ts +0 -1
- package/dist/cjs/utils/network/index.js +0 -1
- package/dist/cjs/utils/network/url.utils.d.ts +2 -8
- package/dist/cjs/utils/network/url.utils.js +46 -90
- package/dist/cjs/utils/security/sanitize.utils.d.ts +1 -13
- package/dist/cjs/utils/security/sanitize.utils.js +15 -178
- package/dist/cjs/utils/validations/config-validations.utils.d.ts +3 -9
- package/dist/cjs/utils/validations/config-validations.utils.js +48 -94
- package/dist/cjs/utils/validations/event-validations.utils.js +11 -5
- package/dist/cjs/utils/validations/index.d.ts +0 -1
- package/dist/cjs/utils/validations/index.js +0 -1
- package/dist/cjs/utils/validations/metadata-validations.utils.js +0 -1
- package/dist/cjs/utils/validations/type-guards.utils.d.ts +2 -2
- package/dist/cjs/utils/validations/type-guards.utils.js +50 -4
- package/dist/esm/api.d.ts +12 -2
- package/dist/esm/api.js +62 -27
- package/dist/esm/app.d.ts +2 -2
- package/dist/esm/app.js +28 -34
- package/dist/esm/constants/config.constants.d.ts +4 -2
- package/dist/esm/constants/config.constants.js +4 -16
- package/dist/esm/constants/index.d.ts +0 -1
- package/dist/esm/constants/index.js +0 -1
- package/dist/esm/constants/storage.constants.d.ts +3 -2
- package/dist/esm/constants/storage.constants.js +3 -2
- package/dist/esm/handlers/click.handler.js +3 -6
- package/dist/esm/handlers/error.handler.js +1 -11
- package/dist/esm/handlers/page-view.handler.js +0 -4
- package/dist/esm/handlers/performance.handler.js +14 -29
- package/dist/esm/handlers/scroll.handler.js +7 -6
- package/dist/esm/handlers/session.handler.js +7 -6
- package/dist/esm/integrations/google-analytics.integration.js +3 -7
- package/dist/esm/listeners/activity-listener-manager.js +3 -3
- package/dist/esm/listeners/input-listener-managers.js +3 -3
- package/dist/esm/listeners/touch-listener-manager.js +3 -3
- package/dist/esm/listeners/unload-listener-manager.js +3 -3
- package/dist/esm/listeners/visibility-listener-manager.js +3 -3
- package/dist/esm/managers/event.manager.d.ts +2 -1
- package/dist/esm/managers/event.manager.js +62 -40
- package/dist/esm/managers/sender.manager.js +31 -38
- package/dist/esm/managers/session.manager.js +5 -13
- package/dist/esm/managers/state.manager.d.ts +0 -3
- package/dist/esm/managers/state.manager.js +1 -43
- package/dist/esm/managers/storage.manager.d.ts +16 -2
- package/dist/esm/managers/storage.manager.js +73 -19
- package/dist/esm/managers/user.manager.d.ts +1 -1
- package/dist/esm/managers/user.manager.js +2 -2
- package/dist/esm/public-api.d.ts +3 -3
- package/dist/esm/public-api.js +1 -1
- package/dist/esm/test-bridge.d.ts +1 -0
- package/dist/esm/test-bridge.js +37 -2
- package/dist/esm/types/config.types.d.ts +15 -18
- package/dist/esm/types/config.types.js +5 -1
- package/dist/esm/types/event.types.d.ts +1 -13
- package/dist/esm/types/index.d.ts +0 -2
- package/dist/esm/types/index.js +0 -2
- package/dist/esm/types/mode.types.d.ts +1 -2
- package/dist/esm/types/mode.types.js +0 -1
- package/dist/esm/types/queue.types.d.ts +0 -6
- package/dist/esm/types/state.types.d.ts +2 -0
- package/dist/esm/types/test-bridge.types.d.ts +2 -2
- package/dist/esm/types/validation-error.types.d.ts +0 -6
- package/dist/esm/types/validation-error.types.js +0 -8
- package/dist/esm/utils/browser/device-detector.utils.js +2 -24
- package/dist/esm/utils/browser/index.d.ts +1 -0
- package/dist/esm/utils/browser/index.js +1 -0
- package/dist/esm/utils/browser/qa-mode.utils.d.ts +13 -0
- package/dist/esm/utils/browser/qa-mode.utils.js +39 -0
- package/dist/esm/utils/browser/utm-params.utils.js +0 -15
- package/dist/esm/utils/data/uuid.utils.d.ts +13 -0
- package/dist/esm/utils/data/uuid.utils.js +35 -0
- package/dist/esm/utils/index.d.ts +1 -1
- package/dist/esm/utils/index.js +1 -1
- package/dist/esm/utils/logging.utils.d.ts +6 -0
- package/dist/esm/utils/logging.utils.js +20 -0
- package/dist/esm/utils/network/index.d.ts +0 -1
- package/dist/esm/utils/network/index.js +0 -1
- package/dist/esm/utils/network/url.utils.d.ts +2 -8
- package/dist/esm/utils/network/url.utils.js +45 -88
- package/dist/esm/utils/security/sanitize.utils.d.ts +1 -13
- package/dist/esm/utils/security/sanitize.utils.js +15 -176
- package/dist/esm/utils/validations/config-validations.utils.d.ts +3 -9
- package/dist/esm/utils/validations/config-validations.utils.js +49 -94
- package/dist/esm/utils/validations/event-validations.utils.js +11 -5
- package/dist/esm/utils/validations/index.d.ts +0 -1
- package/dist/esm/utils/validations/index.js +0 -1
- package/dist/esm/utils/validations/metadata-validations.utils.js +0 -1
- package/dist/esm/utils/validations/type-guards.utils.d.ts +2 -2
- package/dist/esm/utils/validations/type-guards.utils.js +50 -4
- package/package.json +1 -1
- package/dist/cjs/app.types.d.ts +0 -2
- package/dist/cjs/app.types.js +0 -12
- package/dist/cjs/constants/api.constants.d.ts +0 -6
- package/dist/cjs/constants/api.constants.js +0 -14
- package/dist/cjs/managers/api.manager.d.ts +0 -13
- package/dist/cjs/managers/api.manager.js +0 -44
- package/dist/cjs/managers/config.builder.d.ts +0 -33
- package/dist/cjs/managers/config.builder.js +0 -116
- package/dist/cjs/managers/config.manager.d.ts +0 -56
- package/dist/cjs/managers/config.manager.js +0 -157
- package/dist/cjs/managers/tags.manager.d.ts +0 -36
- package/dist/cjs/managers/tags.manager.js +0 -171
- package/dist/cjs/types/api.types.d.ts +0 -52
- package/dist/cjs/types/api.types.js +0 -56
- package/dist/cjs/types/tag.types.d.ts +0 -43
- package/dist/cjs/types/tag.types.js +0 -31
- package/dist/cjs/utils/logging/debug-logger.utils.d.ts +0 -14
- package/dist/cjs/utils/logging/debug-logger.utils.js +0 -47
- package/dist/cjs/utils/logging/index.d.ts +0 -1
- package/dist/cjs/utils/logging/index.js +0 -5
- package/dist/cjs/utils/network/fetch-with-timeout.utils.d.ts +0 -4
- package/dist/cjs/utils/network/fetch-with-timeout.utils.js +0 -25
- package/dist/cjs/utils/validations/url-validations.utils.d.ts +0 -15
- package/dist/cjs/utils/validations/url-validations.utils.js +0 -47
- package/dist/esm/app.types.d.ts +0 -2
- package/dist/esm/app.types.js +0 -1
- package/dist/esm/constants/api.constants.d.ts +0 -6
- package/dist/esm/constants/api.constants.js +0 -11
- package/dist/esm/managers/api.manager.d.ts +0 -13
- package/dist/esm/managers/api.manager.js +0 -41
- package/dist/esm/managers/config.builder.d.ts +0 -33
- package/dist/esm/managers/config.builder.js +0 -112
- package/dist/esm/managers/config.manager.d.ts +0 -56
- package/dist/esm/managers/config.manager.js +0 -153
- package/dist/esm/managers/tags.manager.d.ts +0 -36
- package/dist/esm/managers/tags.manager.js +0 -167
- package/dist/esm/types/api.types.d.ts +0 -52
- package/dist/esm/types/api.types.js +0 -53
- package/dist/esm/types/tag.types.d.ts +0 -43
- package/dist/esm/types/tag.types.js +0 -28
- package/dist/esm/utils/logging/debug-logger.utils.d.ts +0 -14
- package/dist/esm/utils/logging/debug-logger.utils.js +0 -44
- package/dist/esm/utils/logging/index.d.ts +0 -1
- package/dist/esm/utils/logging/index.js +0 -1
- package/dist/esm/utils/network/fetch-with-timeout.utils.d.ts +0 -4
- package/dist/esm/utils/network/fetch-with-timeout.utils.js +0 -22
- package/dist/esm/utils/validations/url-validations.utils.d.ts +0 -15
- package/dist/esm/utils/validations/url-validations.utils.js +0 -42
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.fetchWithTimeout = fetchWithTimeout;
|
|
4
|
-
async function fetchWithTimeout(url, options = {}) {
|
|
5
|
-
const { timeout = 10000, ...fetchOptions } = options;
|
|
6
|
-
const controller = new AbortController();
|
|
7
|
-
const timeoutId = setTimeout(() => {
|
|
8
|
-
controller.abort();
|
|
9
|
-
}, timeout);
|
|
10
|
-
try {
|
|
11
|
-
const response = await fetch(url, {
|
|
12
|
-
...fetchOptions,
|
|
13
|
-
signal: controller.signal,
|
|
14
|
-
});
|
|
15
|
-
clearTimeout(timeoutId);
|
|
16
|
-
return response;
|
|
17
|
-
}
|
|
18
|
-
catch (error) {
|
|
19
|
-
clearTimeout(timeoutId);
|
|
20
|
-
if (error instanceof Error && error.name === 'AbortError') {
|
|
21
|
-
throw new Error(`Request timeout after ${timeout}ms`);
|
|
22
|
-
}
|
|
23
|
-
throw error;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validates if a URL is valid and optionally allows HTTP URLs
|
|
3
|
-
* @param url - The URL to validate
|
|
4
|
-
* @param allowHttp - Whether to allow HTTP URLs (default: false)
|
|
5
|
-
* @returns True if the URL is valid, false otherwise
|
|
6
|
-
*/
|
|
7
|
-
export declare const isValidUrl: (url: string, allowHttp?: boolean) => boolean;
|
|
8
|
-
/**
|
|
9
|
-
* Validates a URL field in configuration
|
|
10
|
-
* @param url - The URL to validate
|
|
11
|
-
* @param allowHttp - Whether to allow HTTP URLs
|
|
12
|
-
* @param fieldName - The name of the field being validated
|
|
13
|
-
* @param errors - Array to push errors to
|
|
14
|
-
*/
|
|
15
|
-
export declare const validateUrl: (url: unknown, allowHttp: boolean | undefined, fieldName: string, errors: string[]) => void;
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.validateUrl = exports.isValidUrl = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Validates if a URL is valid and optionally allows HTTP URLs
|
|
6
|
-
* @param url - The URL to validate
|
|
7
|
-
* @param allowHttp - Whether to allow HTTP URLs (default: false)
|
|
8
|
-
* @returns True if the URL is valid, false otherwise
|
|
9
|
-
*/
|
|
10
|
-
const isValidUrl = (url, allowHttp = false) => {
|
|
11
|
-
try {
|
|
12
|
-
const parsed = new URL(url);
|
|
13
|
-
const isHttps = parsed.protocol === 'https:';
|
|
14
|
-
const isHttp = parsed.protocol === 'http:';
|
|
15
|
-
return isHttps || (allowHttp && isHttp);
|
|
16
|
-
}
|
|
17
|
-
catch {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
exports.isValidUrl = isValidUrl;
|
|
22
|
-
/**
|
|
23
|
-
* Validates a URL field in configuration
|
|
24
|
-
* @param url - The URL to validate
|
|
25
|
-
* @param allowHttp - Whether to allow HTTP URLs
|
|
26
|
-
* @param fieldName - The name of the field being validated
|
|
27
|
-
* @param errors - Array to push errors to
|
|
28
|
-
*/
|
|
29
|
-
const validateUrl = (url, allowHttp, fieldName, errors) => {
|
|
30
|
-
if (url !== undefined) {
|
|
31
|
-
if (typeof url === 'string') {
|
|
32
|
-
try {
|
|
33
|
-
const parsed = new URL(url);
|
|
34
|
-
if (parsed.protocol === 'http:' && !allowHttp) {
|
|
35
|
-
errors.push(`${fieldName} using http requires allowHttp=true`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
errors.push(`${fieldName} must be a valid URL`);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
errors.push(`${fieldName} must be a string`);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
exports.validateUrl = validateUrl;
|
package/dist/esm/app.types.d.ts
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
export { Mode, EventType, DeviceType, ScrollDirection, ErrorType, TagConditionOperator, TagLogicalOperator, TagConditionType, } from './types';
|
|
2
|
-
export type { ScrollData, ClickData, CustomEventData, MetadataType, WebVitalsData, ErrorData, PageViewData, UTM, EventLocation, EventData, AppConfig, ApiConfig, ExtendedEventsQueueDto, TagConfig, BaseEventsQueueDto, WebVitalType, SessionEndReason, } from './types';
|
package/dist/esm/app.types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { Mode, EventType, DeviceType, ScrollDirection, ErrorType, TagConditionOperator, TagLogicalOperator, TagConditionType, } from './types';
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_SAMPLING_RATE } from './config.constants';
|
|
2
|
-
/**
|
|
3
|
-
* Default API configuration values
|
|
4
|
-
* Used as fallback when API config is not available or incomplete
|
|
5
|
-
*/
|
|
6
|
-
export const DEFAULT_API_CONFIG = {
|
|
7
|
-
samplingRate: DEFAULT_SAMPLING_RATE,
|
|
8
|
-
excludedUrlPaths: [],
|
|
9
|
-
tags: [],
|
|
10
|
-
ipExcluded: false,
|
|
11
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generates API URL for TraceLog service based on project ID
|
|
3
|
-
*
|
|
4
|
-
* Handles two special cases:
|
|
5
|
-
* - 'localhost:8080' or 'localhost:9999' - for local development (generates http://localhost:PORT)
|
|
6
|
-
* - Regular project IDs - generates subdomain URLs via getApiUrl utility
|
|
7
|
-
*
|
|
8
|
-
* @param id Project ID or localhost address
|
|
9
|
-
* @param allowHttp Whether to allow HTTP protocol (default: false)
|
|
10
|
-
* @returns Generated API URL
|
|
11
|
-
* @throws Error if URL generation or validation fails
|
|
12
|
-
*/
|
|
13
|
-
export declare function getApiUrlForProject(id: string, allowHttp?: boolean): string;
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { getApiUrl, isValidUrl } from '../utils';
|
|
2
|
-
import { SpecialProjectId } from '../types';
|
|
3
|
-
import { debugLog } from '../utils/logging';
|
|
4
|
-
/**
|
|
5
|
-
* Generates API URL for TraceLog service based on project ID
|
|
6
|
-
*
|
|
7
|
-
* Handles two special cases:
|
|
8
|
-
* - 'localhost:8080' or 'localhost:9999' - for local development (generates http://localhost:PORT)
|
|
9
|
-
* - Regular project IDs - generates subdomain URLs via getApiUrl utility
|
|
10
|
-
*
|
|
11
|
-
* @param id Project ID or localhost address
|
|
12
|
-
* @param allowHttp Whether to allow HTTP protocol (default: false)
|
|
13
|
-
* @returns Generated API URL
|
|
14
|
-
* @throws Error if URL generation or validation fails
|
|
15
|
-
*/
|
|
16
|
-
export function getApiUrlForProject(id, allowHttp = false) {
|
|
17
|
-
try {
|
|
18
|
-
// Handle localhost development case (localhost:8080 or localhost:9999)
|
|
19
|
-
if (id === SpecialProjectId.Localhost || id === SpecialProjectId.Fail) {
|
|
20
|
-
const url = `http://${id}`;
|
|
21
|
-
if (!isValidUrl(url, true)) {
|
|
22
|
-
throw new Error(`Invalid localhost URL format: ${id}`);
|
|
23
|
-
}
|
|
24
|
-
return url;
|
|
25
|
-
}
|
|
26
|
-
// Handle regular project ID case
|
|
27
|
-
const url = getApiUrl(id, allowHttp);
|
|
28
|
-
if (!isValidUrl(url, allowHttp)) {
|
|
29
|
-
throw new Error(`Generated API URL failed validation: ${url}`);
|
|
30
|
-
}
|
|
31
|
-
return url;
|
|
32
|
-
}
|
|
33
|
-
catch (error) {
|
|
34
|
-
debugLog.error('ApiManager', 'API URL generation failed', {
|
|
35
|
-
projectId: id,
|
|
36
|
-
allowHttp,
|
|
37
|
-
error: error instanceof Error ? error.message : error,
|
|
38
|
-
});
|
|
39
|
-
throw error;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { AppConfig, ApiConfig, Config } from '../types';
|
|
2
|
-
/**
|
|
3
|
-
* Centralized configuration builder
|
|
4
|
-
* Single source of truth for merging and building final configuration
|
|
5
|
-
*/
|
|
6
|
-
export declare class ConfigBuilder {
|
|
7
|
-
/**
|
|
8
|
-
* Builds final configuration from app config and API config
|
|
9
|
-
* Applies clear precedence: API overrides client, with defaults as fallback
|
|
10
|
-
*/
|
|
11
|
-
static build(appConfig: AppConfig, apiConfig?: ApiConfig): Config;
|
|
12
|
-
/**
|
|
13
|
-
* Resolves session timeout with validation
|
|
14
|
-
* Returns default if undefined or out of valid range
|
|
15
|
-
*/
|
|
16
|
-
private static resolveSessionTimeout;
|
|
17
|
-
/**
|
|
18
|
-
* Resolves sampling rate with validation
|
|
19
|
-
* Priority: API config > app config > default
|
|
20
|
-
*/
|
|
21
|
-
private static resolveSamplingRate;
|
|
22
|
-
/**
|
|
23
|
-
* Resolves error sampling rate based on mode
|
|
24
|
-
* In debug/qa modes: uses provided value or defaults to full sampling (1.0)
|
|
25
|
-
* In production: uses provided value or defaults to 10% sampling (0.1)
|
|
26
|
-
*/
|
|
27
|
-
private static resolveErrorSampling;
|
|
28
|
-
/**
|
|
29
|
-
* Resolves mode with special project ID handling
|
|
30
|
-
* Priority: Special project ID > API mode > app mode
|
|
31
|
-
*/
|
|
32
|
-
private static resolveMode;
|
|
33
|
-
}
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_SESSION_TIMEOUT, DEFAULT_SAMPLING_RATE, MIN_SAMPLING_RATE, MAX_SAMPLING_RATE, MIN_SESSION_TIMEOUT_MS, MAX_SESSION_TIMEOUT_MS, } from '../constants/config.constants';
|
|
2
|
-
import { Mode, SpecialProjectId } from '../types';
|
|
3
|
-
import { debugLog } from '../utils/logging';
|
|
4
|
-
/**
|
|
5
|
-
* Centralized configuration builder
|
|
6
|
-
* Single source of truth for merging and building final configuration
|
|
7
|
-
*/
|
|
8
|
-
export class ConfigBuilder {
|
|
9
|
-
/**
|
|
10
|
-
* Builds final configuration from app config and API config
|
|
11
|
-
* Applies clear precedence: API overrides client, with defaults as fallback
|
|
12
|
-
*/
|
|
13
|
-
static build(appConfig, apiConfig = {}) {
|
|
14
|
-
// Resolve mode first as it affects other settings (like errorSampling)
|
|
15
|
-
const finalMode = this.resolveMode(appConfig, apiConfig.mode);
|
|
16
|
-
const config = {
|
|
17
|
-
// Core identifiers
|
|
18
|
-
id: appConfig.id,
|
|
19
|
-
// Session configuration
|
|
20
|
-
sessionTimeout: this.resolveSessionTimeout(appConfig.sessionTimeout),
|
|
21
|
-
// Mode configuration (resolved first)
|
|
22
|
-
mode: finalMode,
|
|
23
|
-
// Sampling configuration (depends on mode)
|
|
24
|
-
samplingRate: this.resolveSamplingRate(apiConfig.samplingRate, appConfig.samplingRate),
|
|
25
|
-
errorSampling: this.resolveErrorSampling(appConfig.errorSampling, finalMode),
|
|
26
|
-
// Filtering configuration
|
|
27
|
-
excludedUrlPaths: apiConfig.excludedUrlPaths ?? appConfig.excludedUrlPaths ?? [],
|
|
28
|
-
tags: apiConfig.tags ?? [],
|
|
29
|
-
ipExcluded: apiConfig.ipExcluded ?? false,
|
|
30
|
-
// Client-only configuration
|
|
31
|
-
globalMetadata: appConfig.globalMetadata ?? {},
|
|
32
|
-
scrollContainerSelectors: appConfig.scrollContainerSelectors,
|
|
33
|
-
sensitiveQueryParams: appConfig.sensitiveQueryParams ?? [],
|
|
34
|
-
integrations: appConfig.integrations,
|
|
35
|
-
// Security configuration
|
|
36
|
-
allowHttp: appConfig.allowHttp ?? false,
|
|
37
|
-
};
|
|
38
|
-
debugLog.debug('ConfigBuilder', 'Configuration built', {
|
|
39
|
-
projectId: config.id,
|
|
40
|
-
mode: config.mode,
|
|
41
|
-
samplingRate: config.samplingRate,
|
|
42
|
-
errorSampling: config.errorSampling,
|
|
43
|
-
hasTags: !!config.tags?.length,
|
|
44
|
-
hasExclusions: !!config.excludedUrlPaths?.length,
|
|
45
|
-
});
|
|
46
|
-
return config;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Resolves session timeout with validation
|
|
50
|
-
* Returns default if undefined or out of valid range
|
|
51
|
-
*/
|
|
52
|
-
static resolveSessionTimeout(timeout) {
|
|
53
|
-
if (timeout === undefined) {
|
|
54
|
-
return DEFAULT_SESSION_TIMEOUT;
|
|
55
|
-
}
|
|
56
|
-
if (timeout < MIN_SESSION_TIMEOUT_MS || timeout > MAX_SESSION_TIMEOUT_MS) {
|
|
57
|
-
debugLog.warn('ConfigBuilder', 'Invalid session timeout, using default', {
|
|
58
|
-
provided: timeout,
|
|
59
|
-
min: MIN_SESSION_TIMEOUT_MS,
|
|
60
|
-
max: MAX_SESSION_TIMEOUT_MS,
|
|
61
|
-
default: DEFAULT_SESSION_TIMEOUT,
|
|
62
|
-
});
|
|
63
|
-
return DEFAULT_SESSION_TIMEOUT;
|
|
64
|
-
}
|
|
65
|
-
return timeout;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Resolves sampling rate with validation
|
|
69
|
-
* Priority: API config > app config > default
|
|
70
|
-
*/
|
|
71
|
-
static resolveSamplingRate(apiRate, appRate) {
|
|
72
|
-
const rate = apiRate ?? appRate;
|
|
73
|
-
if (rate === undefined) {
|
|
74
|
-
return DEFAULT_SAMPLING_RATE;
|
|
75
|
-
}
|
|
76
|
-
if (rate < MIN_SAMPLING_RATE || rate > MAX_SAMPLING_RATE) {
|
|
77
|
-
debugLog.warn('ConfigBuilder', 'Invalid sampling rate, using default', {
|
|
78
|
-
provided: rate,
|
|
79
|
-
default: DEFAULT_SAMPLING_RATE,
|
|
80
|
-
});
|
|
81
|
-
return DEFAULT_SAMPLING_RATE;
|
|
82
|
-
}
|
|
83
|
-
return rate;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Resolves error sampling rate based on mode
|
|
87
|
-
* In debug/qa modes: uses provided value or defaults to full sampling (1.0)
|
|
88
|
-
* In production: uses provided value or defaults to 10% sampling (0.1)
|
|
89
|
-
*/
|
|
90
|
-
static resolveErrorSampling(appErrorSampling, apiMode) {
|
|
91
|
-
const isDebugMode = apiMode === Mode.DEBUG || apiMode === Mode.QA;
|
|
92
|
-
if (isDebugMode) {
|
|
93
|
-
// In debug mode, respect explicit value or default to full sampling
|
|
94
|
-
return appErrorSampling ?? 1;
|
|
95
|
-
}
|
|
96
|
-
return appErrorSampling ?? 0.1; // Default to 10% sampling in production
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Resolves mode with special project ID handling
|
|
100
|
-
* Priority: Special project ID > API mode > app mode
|
|
101
|
-
*/
|
|
102
|
-
static resolveMode(appConfig, apiMode) {
|
|
103
|
-
// Force DEBUG mode for special project IDs
|
|
104
|
-
if (appConfig.id === SpecialProjectId.Skip ||
|
|
105
|
-
appConfig.id === SpecialProjectId.Fail ||
|
|
106
|
-
appConfig.id.toLowerCase().startsWith('skip-')) {
|
|
107
|
-
return Mode.DEBUG;
|
|
108
|
-
}
|
|
109
|
-
// API mode takes precedence over app mode
|
|
110
|
-
return apiMode ?? appConfig.mode;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { AppConfig, Config } from '../types';
|
|
2
|
-
/**
|
|
3
|
-
* Configuration manager responsible for loading and merging application configuration.
|
|
4
|
-
*
|
|
5
|
-
* Handles configuration from two sources:
|
|
6
|
-
* 1. API configuration (server-side settings)
|
|
7
|
-
* 2. App configuration (client initialization settings)
|
|
8
|
-
*
|
|
9
|
-
* Uses ConfigBuilder for centralized merge logic.
|
|
10
|
-
*
|
|
11
|
-
* Supports special project IDs for development and testing:
|
|
12
|
-
* - 'skip': Bypasses all network calls, uses defaults
|
|
13
|
-
* - 'localhost:8080': Loads config from local development server
|
|
14
|
-
*/
|
|
15
|
-
export declare class ConfigManager {
|
|
16
|
-
private static readonly PRODUCTION_DOMAINS;
|
|
17
|
-
/**
|
|
18
|
-
* Gets complete configuration by loading API config and building final config.
|
|
19
|
-
*
|
|
20
|
-
* @param apiUrl - Base URL for the configuration API
|
|
21
|
-
* @param appConfig - Client-side configuration from init()
|
|
22
|
-
* @returns Promise<Config> - Merged configuration object
|
|
23
|
-
*/
|
|
24
|
-
get(apiUrl: string, appConfig: AppConfig): Promise<Config>;
|
|
25
|
-
/**
|
|
26
|
-
* Loads configuration from API and returns sanitized API config.
|
|
27
|
-
* Only returns values explicitly provided by the API.
|
|
28
|
-
*/
|
|
29
|
-
private loadFromApi;
|
|
30
|
-
/**
|
|
31
|
-
* Builds the configuration URL based on project type and QA mode.
|
|
32
|
-
*/
|
|
33
|
-
private buildConfigUrl;
|
|
34
|
-
/**
|
|
35
|
-
* Builds request headers based on project configuration.
|
|
36
|
-
* Always includes X-TraceLog-Project header for consistent identification.
|
|
37
|
-
*/
|
|
38
|
-
private buildHeaders;
|
|
39
|
-
/**
|
|
40
|
-
* Parses and validates JSON response from config API.
|
|
41
|
-
*/
|
|
42
|
-
private parseJsonResponse;
|
|
43
|
-
/**
|
|
44
|
-
* Checks if QA mode is enabled via URL parameter.
|
|
45
|
-
*/
|
|
46
|
-
private isQaModeEnabled;
|
|
47
|
-
/**
|
|
48
|
-
* Applies QA mode to API config if enabled via URL parameter.
|
|
49
|
-
*/
|
|
50
|
-
private applyQaModeIfEnabled;
|
|
51
|
-
/**
|
|
52
|
-
* Creates default configuration for skip mode and fallback scenarios.
|
|
53
|
-
* Only uses API defaults for fields not provided by the app config.
|
|
54
|
-
*/
|
|
55
|
-
private createDefaultConfig;
|
|
56
|
-
}
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_API_CONFIG, REQUEST_TIMEOUT_MS } from '../constants';
|
|
2
|
-
import { Mode, SpecialProjectId } from '../types';
|
|
3
|
-
import { sanitizeApiConfig, fetchWithTimeout } from '../utils';
|
|
4
|
-
import { debugLog } from '../utils/logging';
|
|
5
|
-
import { ConfigBuilder } from './config.builder';
|
|
6
|
-
/**
|
|
7
|
-
* Configuration manager responsible for loading and merging application configuration.
|
|
8
|
-
*
|
|
9
|
-
* Handles configuration from two sources:
|
|
10
|
-
* 1. API configuration (server-side settings)
|
|
11
|
-
* 2. App configuration (client initialization settings)
|
|
12
|
-
*
|
|
13
|
-
* Uses ConfigBuilder for centralized merge logic.
|
|
14
|
-
*
|
|
15
|
-
* Supports special project IDs for development and testing:
|
|
16
|
-
* - 'skip': Bypasses all network calls, uses defaults
|
|
17
|
-
* - 'localhost:8080': Loads config from local development server
|
|
18
|
-
*/
|
|
19
|
-
export class ConfigManager {
|
|
20
|
-
/**
|
|
21
|
-
* Gets complete configuration by loading API config and building final config.
|
|
22
|
-
*
|
|
23
|
-
* @param apiUrl - Base URL for the configuration API
|
|
24
|
-
* @param appConfig - Client-side configuration from init()
|
|
25
|
-
* @returns Promise<Config> - Merged configuration object
|
|
26
|
-
*/
|
|
27
|
-
async get(apiUrl, appConfig) {
|
|
28
|
-
// Handle skip mode - no network calls for config
|
|
29
|
-
// Support 'skip' or any ID starting with 'skip-' (e.g., 'skip-1', 'skip-2')
|
|
30
|
-
// Also handle 'fail' mode (SpecialProjectId.Fail) - skip config but fail event sends
|
|
31
|
-
if (appConfig.id === SpecialProjectId.Skip ||
|
|
32
|
-
appConfig.id === SpecialProjectId.Fail ||
|
|
33
|
-
appConfig.id.toLowerCase().startsWith('skip-')) {
|
|
34
|
-
return this.createDefaultConfig(appConfig);
|
|
35
|
-
}
|
|
36
|
-
const apiConfig = await this.loadFromApi(apiUrl, appConfig);
|
|
37
|
-
// Apply QA mode from URL parameter if set
|
|
38
|
-
const finalApiConfig = this.applyQaModeIfEnabled(apiConfig);
|
|
39
|
-
const config = ConfigBuilder.build(appConfig, finalApiConfig);
|
|
40
|
-
debugLog.info('ConfigManager', 'Configuration loaded', {
|
|
41
|
-
projectId: config.id,
|
|
42
|
-
mode: config.mode,
|
|
43
|
-
hasTags: !!config.tags?.length,
|
|
44
|
-
hasExclusions: !!config.excludedUrlPaths?.length,
|
|
45
|
-
});
|
|
46
|
-
return config;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Loads configuration from API and returns sanitized API config.
|
|
50
|
-
* Only returns values explicitly provided by the API.
|
|
51
|
-
*/
|
|
52
|
-
async loadFromApi(apiUrl, appConfig) {
|
|
53
|
-
try {
|
|
54
|
-
const configUrl = this.buildConfigUrl(apiUrl, appConfig);
|
|
55
|
-
const headers = this.buildHeaders(appConfig);
|
|
56
|
-
const response = await fetchWithTimeout(configUrl, {
|
|
57
|
-
method: 'GET',
|
|
58
|
-
headers,
|
|
59
|
-
timeout: REQUEST_TIMEOUT_MS,
|
|
60
|
-
});
|
|
61
|
-
if (!response.ok) {
|
|
62
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
63
|
-
}
|
|
64
|
-
const rawData = await this.parseJsonResponse(response);
|
|
65
|
-
const apiConfig = sanitizeApiConfig(rawData);
|
|
66
|
-
// Only merge defaults for fields that are arrays (to ensure they're never undefined)
|
|
67
|
-
return {
|
|
68
|
-
...apiConfig,
|
|
69
|
-
excludedUrlPaths: apiConfig.excludedUrlPaths ?? DEFAULT_API_CONFIG.excludedUrlPaths,
|
|
70
|
-
tags: apiConfig.tags ?? DEFAULT_API_CONFIG.tags,
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
catch (error) {
|
|
74
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
75
|
-
debugLog.error('ConfigManager', 'Failed to load configuration', {
|
|
76
|
-
error: errorMessage,
|
|
77
|
-
apiUrl,
|
|
78
|
-
projectId: appConfig.id,
|
|
79
|
-
});
|
|
80
|
-
throw new Error(`Configuration load failed: ${errorMessage}`);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Builds the configuration URL based on project type and QA mode.
|
|
85
|
-
*/
|
|
86
|
-
buildConfigUrl(apiUrl, appConfig) {
|
|
87
|
-
const isLocalhost = appConfig.id === SpecialProjectId.Localhost || appConfig.id === SpecialProjectId.Fail;
|
|
88
|
-
if (isLocalhost) {
|
|
89
|
-
return `http://${appConfig.id}/config`;
|
|
90
|
-
}
|
|
91
|
-
const baseUrl = `${apiUrl}/config`;
|
|
92
|
-
const isQaMode = this.isQaModeEnabled();
|
|
93
|
-
return isQaMode ? `${baseUrl}?qaMode=true` : baseUrl;
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Builds request headers based on project configuration.
|
|
97
|
-
* Always includes X-TraceLog-Project header for consistent identification.
|
|
98
|
-
*/
|
|
99
|
-
buildHeaders(appConfig) {
|
|
100
|
-
return {
|
|
101
|
-
'Content-Type': 'application/json',
|
|
102
|
-
'X-TraceLog-Project': appConfig.id,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Parses and validates JSON response from config API.
|
|
107
|
-
*/
|
|
108
|
-
async parseJsonResponse(response) {
|
|
109
|
-
const contentType = response.headers.get('content-type');
|
|
110
|
-
if (!contentType?.includes('application/json')) {
|
|
111
|
-
throw new Error('Invalid response content-type, expected JSON');
|
|
112
|
-
}
|
|
113
|
-
const rawData = await response.json();
|
|
114
|
-
if (!rawData || typeof rawData !== 'object' || Array.isArray(rawData)) {
|
|
115
|
-
throw new Error('Invalid response format, expected object');
|
|
116
|
-
}
|
|
117
|
-
return rawData;
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Checks if QA mode is enabled via URL parameter.
|
|
121
|
-
*/
|
|
122
|
-
isQaModeEnabled() {
|
|
123
|
-
const params = new URLSearchParams(window.location.search);
|
|
124
|
-
return params.get('qaMode') === 'true';
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Applies QA mode to API config if enabled via URL parameter.
|
|
128
|
-
*/
|
|
129
|
-
applyQaModeIfEnabled(apiConfig) {
|
|
130
|
-
if (this.isQaModeEnabled() && !apiConfig.mode) {
|
|
131
|
-
debugLog.info('ConfigManager', 'QA mode enabled via URL parameter');
|
|
132
|
-
return { ...apiConfig, mode: Mode.QA };
|
|
133
|
-
}
|
|
134
|
-
return apiConfig;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Creates default configuration for skip mode and fallback scenarios.
|
|
138
|
-
* Only uses API defaults for fields not provided by the app config.
|
|
139
|
-
*/
|
|
140
|
-
createDefaultConfig(appConfig) {
|
|
141
|
-
// Only use DEFAULT_API_CONFIG for fields not provided in appConfig
|
|
142
|
-
const apiConfig = {
|
|
143
|
-
// Only use defaults if app config doesn't provide these values
|
|
144
|
-
tags: DEFAULT_API_CONFIG.tags,
|
|
145
|
-
ipExcluded: DEFAULT_API_CONFIG.ipExcluded,
|
|
146
|
-
...(appConfig.samplingRate === undefined && { samplingRate: DEFAULT_API_CONFIG.samplingRate }),
|
|
147
|
-
// Don't override excludedUrlPaths if provided by app config
|
|
148
|
-
// ConfigBuilder will handle the fallback to [] if both are undefined
|
|
149
|
-
};
|
|
150
|
-
return ConfigBuilder.build(appConfig, apiConfig);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
ConfigManager.PRODUCTION_DOMAINS = [/^https:\/\/.*\.tracelog\.app$/, /^https:\/\/.*\.tracelog\.dev$/];
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { DeviceType, EventData } from '../types';
|
|
2
|
-
import { StateManager } from './state.manager';
|
|
3
|
-
export declare class TagsManager extends StateManager {
|
|
4
|
-
/**
|
|
5
|
-
* Gets matching tag IDs for an event based on configured tag conditions
|
|
6
|
-
*/
|
|
7
|
-
getEventTagsIds(event: EventData, deviceType: DeviceType): string[];
|
|
8
|
-
/**
|
|
9
|
-
* Evaluates all conditions for a tag using logical operators
|
|
10
|
-
*/
|
|
11
|
-
private evaluateTagConditions;
|
|
12
|
-
/**
|
|
13
|
-
* Evaluates a single tag condition
|
|
14
|
-
*/
|
|
15
|
-
private evaluateCondition;
|
|
16
|
-
/**
|
|
17
|
-
* Unified string matching logic for all string-based conditions
|
|
18
|
-
*/
|
|
19
|
-
private matchStringCondition;
|
|
20
|
-
/**
|
|
21
|
-
* Element-specific matching logic with optimized data extraction
|
|
22
|
-
*/
|
|
23
|
-
private matchElementCondition;
|
|
24
|
-
/**
|
|
25
|
-
* Exact field matching for element EQUALS operations
|
|
26
|
-
*/
|
|
27
|
-
private matchElementFieldExact;
|
|
28
|
-
/**
|
|
29
|
-
* Builds searchable element data string with null safety
|
|
30
|
-
*/
|
|
31
|
-
private buildElementDataString;
|
|
32
|
-
/**
|
|
33
|
-
* Safe regex testing with error handling
|
|
34
|
-
*/
|
|
35
|
-
private testRegex;
|
|
36
|
-
}
|