@pallasoft/ps-core-components 2.32.0 → 2.34.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.
Files changed (85) hide show
  1. package/dist/analytics/index.d.ts +12 -0
  2. package/dist/analytics/index.js +28 -0
  3. package/dist/analytics/report-client-error.d.ts +1 -0
  4. package/dist/analytics/report-client-error.js +6 -0
  5. package/dist/components/ps-analytics-provider.d.ts +14 -0
  6. package/dist/components/ps-analytics-provider.js +72 -0
  7. package/dist/components/ps-client-error-reporter.d.ts +5 -0
  8. package/dist/components/ps-client-error-reporter.js +22 -0
  9. package/dist/components/ps-consent-banner.d.ts +11 -0
  10. package/dist/components/ps-consent-banner.js +21 -0
  11. package/dist/constants/ps-analytics-config.d.ts +19 -0
  12. package/dist/constants/ps-analytics-config.js +22 -0
  13. package/dist/constants/ps-client-error-config.d.ts +23 -0
  14. package/dist/constants/ps-client-error-config.js +17 -0
  15. package/dist/esm/analytics/index.js +12 -0
  16. package/dist/esm/analytics/report-client-error.js +2 -0
  17. package/dist/esm/components/ps-analytics-provider.js +68 -0
  18. package/dist/esm/components/ps-client-error-reporter.js +18 -0
  19. package/dist/esm/components/ps-consent-banner.js +17 -0
  20. package/dist/esm/constants/ps-analytics-config.js +19 -0
  21. package/dist/esm/constants/ps-client-error-config.js +14 -0
  22. package/dist/esm/hooks/use-consent.js +17 -0
  23. package/dist/esm/hooks/use-ps-debounced-revalidate.js +23 -0
  24. package/dist/esm/hooks/use-ps-live.js +34 -0
  25. package/dist/esm/index.js +5 -0
  26. package/dist/esm/interfaces/ps-live-handle.js +1 -0
  27. package/dist/esm/interfaces/ps-live-input.js +1 -0
  28. package/dist/esm/interfaces/ps-live-open-options.js +1 -0
  29. package/dist/esm/models/analytics-csp-input.js +1 -0
  30. package/dist/esm/models/analytics-csp-origins.js +1 -0
  31. package/dist/esm/models/ps-client-error-payload.js +1 -0
  32. package/dist/esm/models/ps-client-error-settings.js +1 -0
  33. package/dist/esm/models/ps-consent-api.js +1 -0
  34. package/dist/esm/models/ps-consent-choice.js +1 -0
  35. package/dist/esm/models/ps-consent-state.js +1 -0
  36. package/dist/esm/models/ps-gtag-window.js +1 -0
  37. package/dist/esm/services/analytics-csp-service.js +27 -0
  38. package/dist/esm/services/ps-analytics-key-service.js +8 -0
  39. package/dist/esm/services/ps-client-error-service.js +72 -0
  40. package/dist/esm/services/ps-consent-service.js +57 -0
  41. package/dist/esm/services/ps-google-analytics-service.js +41 -0
  42. package/dist/esm/services/ps-post-hog-service.js +18 -0
  43. package/dist/hooks/use-consent.d.ts +2 -0
  44. package/dist/hooks/use-consent.js +21 -0
  45. package/dist/hooks/use-ps-debounced-revalidate.d.ts +2 -0
  46. package/dist/hooks/use-ps-debounced-revalidate.js +27 -0
  47. package/dist/hooks/use-ps-live.d.ts +2 -0
  48. package/dist/hooks/use-ps-live.js +38 -0
  49. package/dist/index.d.ts +5 -0
  50. package/dist/index.js +5 -0
  51. package/dist/interfaces/ps-live-handle.d.ts +3 -0
  52. package/dist/interfaces/ps-live-handle.js +2 -0
  53. package/dist/interfaces/ps-live-input.d.ts +11 -0
  54. package/dist/interfaces/ps-live-input.js +2 -0
  55. package/dist/interfaces/ps-live-open-options.d.ts +7 -0
  56. package/dist/interfaces/ps-live-open-options.js +2 -0
  57. package/dist/models/analytics-csp-input.d.ts +7 -0
  58. package/dist/models/analytics-csp-input.js +2 -0
  59. package/dist/models/analytics-csp-origins.d.ts +5 -0
  60. package/dist/models/analytics-csp-origins.js +2 -0
  61. package/dist/models/ps-client-error-payload.d.ts +9 -0
  62. package/dist/models/ps-client-error-payload.js +2 -0
  63. package/dist/models/ps-client-error-settings.d.ts +4 -0
  64. package/dist/models/ps-client-error-settings.js +2 -0
  65. package/dist/models/ps-consent-api.d.ts +9 -0
  66. package/dist/models/ps-consent-api.js +2 -0
  67. package/dist/models/ps-consent-choice.d.ts +1 -0
  68. package/dist/models/ps-consent-choice.js +2 -0
  69. package/dist/models/ps-consent-state.d.ts +5 -0
  70. package/dist/models/ps-consent-state.js +2 -0
  71. package/dist/models/ps-gtag-window.d.ts +4 -0
  72. package/dist/models/ps-gtag-window.js +2 -0
  73. package/dist/services/analytics-csp-service.d.ts +7 -0
  74. package/dist/services/analytics-csp-service.js +31 -0
  75. package/dist/services/ps-analytics-key-service.d.ts +3 -0
  76. package/dist/services/ps-analytics-key-service.js +12 -0
  77. package/dist/services/ps-client-error-service.d.ts +14 -0
  78. package/dist/services/ps-client-error-service.js +76 -0
  79. package/dist/services/ps-consent-service.d.ts +15 -0
  80. package/dist/services/ps-consent-service.js +61 -0
  81. package/dist/services/ps-google-analytics-service.d.ts +6 -0
  82. package/dist/services/ps-google-analytics-service.js +45 -0
  83. package/dist/services/ps-post-hog-service.d.ts +4 -0
  84. package/dist/services/ps-post-hog-service.js +55 -0
  85. package/package.json +15 -1
@@ -0,0 +1,72 @@
1
+ import { PsClientErrorConfig } from '../constants/ps-client-error-config';
2
+ export class PsClientErrorService {
3
+ static configure(settings) {
4
+ this.settings = settings;
5
+ }
6
+ static clear() {
7
+ this.settings = null;
8
+ }
9
+ static reset() {
10
+ this.settings = null;
11
+ this.sentKeys.clear();
12
+ this.sentCount = 0;
13
+ }
14
+ static report(error, context = '', source = PsClientErrorConfig.sources.boundary) {
15
+ if (!this.settings || typeof window === 'undefined')
16
+ return;
17
+ if (this.sentCount >= PsClientErrorConfig.maxReportsPerPage)
18
+ return;
19
+ const payload = this.payload(error, context, source, this.settings);
20
+ const key = `${payload.message}|${payload.context}`;
21
+ if (this.sentKeys.has(key))
22
+ return;
23
+ this.sentKeys.add(key);
24
+ this.sentCount += 1;
25
+ this.send(this.settings.endpoint, JSON.stringify(payload));
26
+ }
27
+ static payload(error, context, source, settings) {
28
+ const isError = error instanceof Error;
29
+ const rawMessage = isError ? error.message : typeof error === 'string' ? error : '';
30
+ return {
31
+ message: this.clean(rawMessage ? rawMessage : PsClientErrorConfig.unknownMessage).slice(0, PsClientErrorConfig.maxMessageLength),
32
+ stack: isError && error.stack
33
+ ? this.clean(error.stack).slice(0, PsClientErrorConfig.maxStackLength)
34
+ : '',
35
+ pathname: window.location.pathname,
36
+ appVersion: settings.appVersion ? settings.appVersion : '',
37
+ userAgentClass: this.userAgentClass(),
38
+ source,
39
+ context: this.clean(context).slice(0, PsClientErrorConfig.maxContextLength),
40
+ };
41
+ }
42
+ static clean(value) {
43
+ return value.replace(PsClientErrorConfig.emailPattern, PsClientErrorConfig.redactedValue);
44
+ }
45
+ static userAgentClass() {
46
+ const agent = typeof navigator === 'undefined' ? '' : navigator.userAgent;
47
+ const classes = PsClientErrorConfig.userAgentClasses;
48
+ if (!agent)
49
+ return classes.unknown;
50
+ if (PsClientErrorConfig.botPattern.test(agent))
51
+ return classes.bot;
52
+ if (PsClientErrorConfig.mobilePattern.test(agent))
53
+ return classes.mobile;
54
+ return classes.desktop;
55
+ }
56
+ static send(endpoint, body) {
57
+ if (typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function') {
58
+ const blob = new Blob([body], { type: PsClientErrorConfig.jsonContentType });
59
+ if (navigator.sendBeacon(endpoint, blob))
60
+ return;
61
+ }
62
+ fetch(endpoint, {
63
+ method: 'POST',
64
+ headers: { 'Content-Type': PsClientErrorConfig.jsonContentType },
65
+ body,
66
+ keepalive: true,
67
+ }).catch(() => undefined);
68
+ }
69
+ }
70
+ PsClientErrorService.settings = null;
71
+ PsClientErrorService.sentKeys = new Set();
72
+ PsClientErrorService.sentCount = 0;
@@ -0,0 +1,57 @@
1
+ import { PsAnalyticsConfig } from '../constants/ps-analytics-config';
2
+ export class PsConsentService {
3
+ static snapshot(cookieName) {
4
+ const existing = this.states.get(cookieName);
5
+ if (existing)
6
+ return existing;
7
+ const state = { choice: this.readCookie(cookieName), isReopened: false };
8
+ this.states.set(cookieName, state);
9
+ return state;
10
+ }
11
+ static subscribe(listener) {
12
+ this.listeners.add(listener);
13
+ return () => {
14
+ this.listeners.delete(listener);
15
+ };
16
+ }
17
+ static choose(cookieName, choice) {
18
+ this.writeCookie(cookieName, choice);
19
+ this.states.set(cookieName, { choice, isReopened: false });
20
+ this.notify();
21
+ }
22
+ static reopen(cookieName) {
23
+ this.states.set(cookieName, { ...this.snapshot(cookieName), isReopened: true });
24
+ this.notify();
25
+ }
26
+ static reset() {
27
+ this.states.clear();
28
+ this.notify();
29
+ }
30
+ static notify() {
31
+ this.listeners.forEach((listener) => listener());
32
+ }
33
+ static readCookie(cookieName) {
34
+ if (typeof document === 'undefined')
35
+ return null;
36
+ const prefix = `${cookieName}=`;
37
+ const entry = document.cookie
38
+ .split(';')
39
+ .map((part) => part.trim())
40
+ .find((part) => part.startsWith(prefix));
41
+ const value = entry ? entry.slice(prefix.length) : '';
42
+ if (value === PsAnalyticsConfig.consentGranted)
43
+ return PsAnalyticsConfig.consentGranted;
44
+ if (value === PsAnalyticsConfig.consentDenied)
45
+ return PsAnalyticsConfig.consentDenied;
46
+ return null;
47
+ }
48
+ static writeCookie(cookieName, choice) {
49
+ if (typeof document === 'undefined')
50
+ return;
51
+ const secure = window.location.protocol === 'https:' ? '; Secure' : '';
52
+ document.cookie = `${cookieName}=${choice}; Path=/; Max-Age=${PsAnalyticsConfig.consentMaxAgeSeconds}; SameSite=Lax${secure}`;
53
+ }
54
+ }
55
+ PsConsentService.serverState = { choice: null, isReopened: false };
56
+ PsConsentService.states = new Map();
57
+ PsConsentService.listeners = new Set();
@@ -0,0 +1,41 @@
1
+ import { PsAnalyticsConfig } from '../constants/ps-analytics-config';
2
+ export class PsGoogleAnalyticsService {
3
+ static load(id, tagManagerUrl, nonce) {
4
+ const target = window;
5
+ Reflect.set(window, `ga-disable-${id}`, false);
6
+ if (typeof target.gtag !== 'function') {
7
+ target.dataLayer = target.dataLayer ? target.dataLayer : [];
8
+ target.gtag = function gtag() {
9
+ target.dataLayer?.push(arguments);
10
+ };
11
+ target.gtag('js', new Date());
12
+ }
13
+ if (document.querySelector(`script[${PsAnalyticsConfig.scriptAttribute}="${id}"]`))
14
+ return;
15
+ const script = document.createElement('script');
16
+ script.async = true;
17
+ script.src = `${tagManagerUrl.replace(/\/+$/, '')}${PsAnalyticsConfig.tagManagerScriptPath}${encodeURIComponent(id)}`;
18
+ script.setAttribute(PsAnalyticsConfig.scriptAttribute, id);
19
+ if (nonce)
20
+ script.setAttribute('nonce', nonce);
21
+ document.head.appendChild(script);
22
+ }
23
+ static configure(id, pathname, userId) {
24
+ const target = window;
25
+ if (typeof target.gtag !== 'function')
26
+ return;
27
+ target.gtag('config', id, {
28
+ send_page_view: false,
29
+ page_path: pathname,
30
+ ...(userId ? { user_id: userId } : {}),
31
+ });
32
+ }
33
+ static clearUser() {
34
+ const target = window;
35
+ if (typeof target.gtag === 'function')
36
+ target.gtag('set', { user_id: undefined });
37
+ }
38
+ static disable(id) {
39
+ Reflect.set(window, `ga-disable-${id}`, true);
40
+ }
41
+ }
@@ -0,0 +1,18 @@
1
+ import { PsAnalyticsConfig } from '../constants/ps-analytics-config';
2
+ export class PsPostHogService {
3
+ static async load(key, apiHost) {
4
+ const module = await import('posthog-js');
5
+ const client = module.default;
6
+ client.init(key, {
7
+ ...(apiHost ? { api_host: apiHost } : {}),
8
+ defaults: PsAnalyticsConfig.postHog.defaults,
9
+ autocapture: PsAnalyticsConfig.postHog.autocapture,
10
+ capture_pageview: false,
11
+ capture_pageleave: PsAnalyticsConfig.postHog.capturePageleave,
12
+ capture_exceptions: PsAnalyticsConfig.postHog.captureExceptions,
13
+ person_profiles: PsAnalyticsConfig.postHog.personProfiles,
14
+ });
15
+ client.opt_in_capturing();
16
+ return client;
17
+ }
18
+ }
@@ -0,0 +1,2 @@
1
+ import type { PsConsentApi } from '../models/ps-consent-api';
2
+ export declare const useConsent: (consentCookieName?: string) => PsConsentApi;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useConsent = void 0;
4
+ const react_1 = require("react");
5
+ const ps_analytics_config_1 = require("../constants/ps-analytics-config");
6
+ const ps_consent_service_1 = require("../services/ps-consent-service");
7
+ const useConsent = (consentCookieName = ps_analytics_config_1.PsAnalyticsConfig.defaultConsentCookieName) => {
8
+ const state = (0, react_1.useSyncExternalStore)((listener) => ps_consent_service_1.PsConsentService.subscribe(listener), () => ps_consent_service_1.PsConsentService.snapshot(consentCookieName), () => ps_consent_service_1.PsConsentService.serverState);
9
+ const accept = (0, react_1.useCallback)(() => ps_consent_service_1.PsConsentService.choose(consentCookieName, ps_analytics_config_1.PsAnalyticsConfig.consentGranted), [consentCookieName]);
10
+ const reject = (0, react_1.useCallback)(() => ps_consent_service_1.PsConsentService.choose(consentCookieName, ps_analytics_config_1.PsAnalyticsConfig.consentDenied), [consentCookieName]);
11
+ const reopen = (0, react_1.useCallback)(() => ps_consent_service_1.PsConsentService.reopen(consentCookieName), [consentCookieName]);
12
+ return {
13
+ choice: state.choice,
14
+ isGranted: state.choice === ps_analytics_config_1.PsAnalyticsConfig.consentGranted,
15
+ isBannerOpen: state === ps_consent_service_1.PsConsentService.serverState ? false : state.choice === null || state.isReopened,
16
+ accept,
17
+ reject,
18
+ reopen,
19
+ };
20
+ };
21
+ exports.useConsent = useConsent;
@@ -0,0 +1,2 @@
1
+ import type { PsRevalidatorLike } from '../interfaces/ps-revalidator-like';
2
+ export declare const usePsDebouncedRevalidate: (revalidator: PsRevalidatorLike, delayMilliseconds: number) => (() => void);
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.usePsDebouncedRevalidate = void 0;
4
+ const react_1 = require("react");
5
+ const usePsDebouncedRevalidate = (revalidator, delayMilliseconds) => {
6
+ const latest = (0, react_1.useRef)(revalidator);
7
+ const timer = (0, react_1.useRef)(null);
8
+ latest.current = revalidator;
9
+ const fire = (0, react_1.useCallback)(() => {
10
+ timer.current = null;
11
+ if (latest.current.state !== 'idle') {
12
+ timer.current = setTimeout(fire, delayMilliseconds);
13
+ return;
14
+ }
15
+ void latest.current.revalidate();
16
+ }, [delayMilliseconds]);
17
+ (0, react_1.useEffect)(() => () => {
18
+ if (timer.current !== null)
19
+ clearTimeout(timer.current);
20
+ }, []);
21
+ return (0, react_1.useCallback)(() => {
22
+ if (timer.current !== null)
23
+ clearTimeout(timer.current);
24
+ timer.current = setTimeout(fire, delayMilliseconds);
25
+ }, [delayMilliseconds, fire]);
26
+ };
27
+ exports.usePsDebouncedRevalidate = usePsDebouncedRevalidate;
@@ -0,0 +1,2 @@
1
+ import type { PsLiveInput } from '../interfaces/ps-live-input';
2
+ export declare const usePsLive: (input: PsLiveInput) => void;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.usePsLive = void 0;
4
+ const react_1 = require("react");
5
+ const usePsLive = (input) => {
6
+ const latest = (0, react_1.useRef)(input);
7
+ const { enabled, open, path } = input;
8
+ const eventKey = input.events.join(',');
9
+ latest.current = input;
10
+ (0, react_1.useEffect)(() => {
11
+ if (!enabled)
12
+ return;
13
+ let isActive = true;
14
+ let close = null;
15
+ void open({
16
+ events: latest.current.events,
17
+ fetchToken: () => latest.current.fetchToken(),
18
+ onEvent: (name, payload) => latest.current.onEvent(name, payload),
19
+ onResume: () => {
20
+ const { onResume } = latest.current;
21
+ if (onResume !== undefined)
22
+ onResume();
23
+ },
24
+ path,
25
+ }).then((handle) => {
26
+ if (isActive)
27
+ close = () => handle.close();
28
+ else
29
+ handle.close();
30
+ });
31
+ return () => {
32
+ isActive = false;
33
+ if (close !== null)
34
+ close();
35
+ };
36
+ }, [enabled, eventKey, open, path]);
37
+ };
38
+ exports.usePsLive = usePsLive;
package/dist/index.d.ts CHANGED
@@ -76,6 +76,8 @@ export * from './hooks/use-ps-debounced-value';
76
76
  export * from './hooks/use-ps-change-queue';
77
77
  export * from './interfaces/ps-change-queue-input';
78
78
  export * from './interfaces/ps-change-queue-result';
79
+ export * from './hooks/use-ps-live';
80
+ export * from './hooks/use-ps-debounced-revalidate';
79
81
  export * from './hooks/use-ps-optimistic-rows';
80
82
  export * from './hooks/use-ps-optimistic-fetcher';
81
83
  export * from './hooks/use-ps-optimistic-save';
@@ -88,6 +90,9 @@ export * from './services/ps-optimistic-save-service';
88
90
  export * from './services/ps-client-param-revalidation-service';
89
91
  export * from './interfaces/ps-fetcher-like';
90
92
  export * from './interfaces/ps-fetcher-submit-options';
93
+ export * from './interfaces/ps-live-handle';
94
+ export * from './interfaces/ps-live-input';
95
+ export * from './interfaces/ps-live-open-options';
91
96
  export * from './interfaces/ps-optimistic-fetcher-input';
92
97
  export * from './interfaces/ps-optimistic-fetcher-result';
93
98
  export * from './interfaces/ps-revalidator-like';
package/dist/index.js CHANGED
@@ -92,6 +92,8 @@ __exportStar(require("./hooks/use-ps-debounced-value"), exports);
92
92
  __exportStar(require("./hooks/use-ps-change-queue"), exports);
93
93
  __exportStar(require("./interfaces/ps-change-queue-input"), exports);
94
94
  __exportStar(require("./interfaces/ps-change-queue-result"), exports);
95
+ __exportStar(require("./hooks/use-ps-live"), exports);
96
+ __exportStar(require("./hooks/use-ps-debounced-revalidate"), exports);
95
97
  __exportStar(require("./hooks/use-ps-optimistic-rows"), exports);
96
98
  __exportStar(require("./hooks/use-ps-optimistic-fetcher"), exports);
97
99
  __exportStar(require("./hooks/use-ps-optimistic-save"), exports);
@@ -104,6 +106,9 @@ __exportStar(require("./services/ps-optimistic-save-service"), exports);
104
106
  __exportStar(require("./services/ps-client-param-revalidation-service"), exports);
105
107
  __exportStar(require("./interfaces/ps-fetcher-like"), exports);
106
108
  __exportStar(require("./interfaces/ps-fetcher-submit-options"), exports);
109
+ __exportStar(require("./interfaces/ps-live-handle"), exports);
110
+ __exportStar(require("./interfaces/ps-live-input"), exports);
111
+ __exportStar(require("./interfaces/ps-live-open-options"), exports);
107
112
  __exportStar(require("./interfaces/ps-optimistic-fetcher-input"), exports);
108
113
  __exportStar(require("./interfaces/ps-optimistic-fetcher-result"), exports);
109
114
  __exportStar(require("./interfaces/ps-revalidator-like"), exports);
@@ -0,0 +1,3 @@
1
+ export interface PsLiveHandle {
2
+ close: () => void;
3
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,11 @@
1
+ import type { PsLiveHandle } from './ps-live-handle';
2
+ import type { PsLiveOpenOptions } from './ps-live-open-options';
3
+ export interface PsLiveInput {
4
+ enabled: boolean;
5
+ events: string[];
6
+ fetchToken: () => Promise<string | null>;
7
+ onEvent: (name: string, payload: unknown) => void;
8
+ onResume?: () => void;
9
+ open: (options: PsLiveOpenOptions) => Promise<PsLiveHandle>;
10
+ path: string;
11
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,7 @@
1
+ export interface PsLiveOpenOptions {
2
+ events: string[];
3
+ fetchToken: () => Promise<string | null>;
4
+ onEvent: (name: string, payload: unknown) => void;
5
+ onResume: () => void;
6
+ path: string;
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,7 @@
1
+ export interface AnalyticsCspInput {
2
+ googleAnalyticsId?: string;
3
+ googleAnalyticsUrls?: string;
4
+ googleTagManagerUrls?: string;
5
+ postHogKey?: string;
6
+ postHogUrls?: string;
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
1
+ export interface AnalyticsCspOrigins {
2
+ scriptSrc: string[];
3
+ connectSrc: string[];
4
+ imgSrc: string[];
5
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,9 @@
1
+ export interface PsClientErrorPayload {
2
+ message: string;
3
+ stack: string;
4
+ pathname: string;
5
+ appVersion: string;
6
+ userAgentClass: string;
7
+ source: string;
8
+ context: string;
9
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ export interface PsClientErrorSettings {
2
+ endpoint: string;
3
+ appVersion?: string;
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,9 @@
1
+ import type { PsConsentChoice } from './ps-consent-choice';
2
+ export interface PsConsentApi {
3
+ choice: PsConsentChoice | null;
4
+ isGranted: boolean;
5
+ isBannerOpen: boolean;
6
+ accept: () => void;
7
+ reject: () => void;
8
+ reopen: () => void;
9
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export type PsConsentChoice = 'granted' | 'denied';
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
1
+ import type { PsConsentChoice } from './ps-consent-choice';
2
+ export interface PsConsentState {
3
+ choice: PsConsentChoice | null;
4
+ isReopened: boolean;
5
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ export interface PsGtagWindow extends Window {
2
+ dataLayer?: unknown[];
3
+ gtag?: (...args: unknown[]) => void;
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,7 @@
1
+ import type { AnalyticsCspInput } from '../models/analytics-csp-input';
2
+ import type { AnalyticsCspOrigins } from '../models/analytics-csp-origins';
3
+ export declare class AnalyticsCspService {
4
+ static origins(input: AnalyticsCspInput): AnalyticsCspOrigins;
5
+ private static parse;
6
+ private static unique;
7
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AnalyticsCspService = void 0;
4
+ const ps_analytics_config_1 = require("../constants/ps-analytics-config");
5
+ const ps_analytics_key_service_1 = require("./ps-analytics-key-service");
6
+ class AnalyticsCspService {
7
+ static origins(input) {
8
+ const isGoogleOn = ps_analytics_key_service_1.PsAnalyticsKeyService.isEnabled(input.googleAnalyticsId);
9
+ const isPostHogOn = ps_analytics_key_service_1.PsAnalyticsKeyService.isEnabled(input.postHogKey);
10
+ const googleUrls = isGoogleOn ? this.parse(input.googleAnalyticsUrls) : [];
11
+ const tagManagerUrls = isGoogleOn ? this.parse(input.googleTagManagerUrls) : [];
12
+ const postHogUrls = isPostHogOn ? this.parse(input.postHogUrls) : [];
13
+ return {
14
+ scriptSrc: this.unique([...tagManagerUrls, ...postHogUrls]),
15
+ connectSrc: this.unique([...googleUrls, ...tagManagerUrls, ...postHogUrls]),
16
+ imgSrc: this.unique([...googleUrls, ...tagManagerUrls]),
17
+ };
18
+ }
19
+ static parse(value) {
20
+ if (!value)
21
+ return [];
22
+ return value
23
+ .split(ps_analytics_config_1.PsAnalyticsConfig.listSeparator)
24
+ .map((item) => item.trim())
25
+ .filter((item) => ps_analytics_key_service_1.PsAnalyticsKeyService.isEnabled(item));
26
+ }
27
+ static unique(values) {
28
+ return Array.from(new Set(values));
29
+ }
30
+ }
31
+ exports.AnalyticsCspService = AnalyticsCspService;
@@ -0,0 +1,3 @@
1
+ export declare class PsAnalyticsKeyService {
2
+ static isEnabled(value: string | null | undefined): value is string;
3
+ }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PsAnalyticsKeyService = void 0;
4
+ const ps_analytics_config_1 = require("../constants/ps-analytics-config");
5
+ class PsAnalyticsKeyService {
6
+ static isEnabled(value) {
7
+ if (value === null || value === undefined)
8
+ return false;
9
+ return !ps_analytics_config_1.PsAnalyticsConfig.offValues.includes(value.trim());
10
+ }
11
+ }
12
+ exports.PsAnalyticsKeyService = PsAnalyticsKeyService;
@@ -0,0 +1,14 @@
1
+ import type { PsClientErrorSettings } from '../models/ps-client-error-settings';
2
+ export declare class PsClientErrorService {
3
+ private static settings;
4
+ private static sentKeys;
5
+ private static sentCount;
6
+ static configure(settings: PsClientErrorSettings): void;
7
+ static clear(): void;
8
+ static reset(): void;
9
+ static report(error: unknown, context?: string, source?: string): void;
10
+ private static payload;
11
+ private static clean;
12
+ private static userAgentClass;
13
+ private static send;
14
+ }
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PsClientErrorService = void 0;
4
+ const ps_client_error_config_1 = require("../constants/ps-client-error-config");
5
+ class PsClientErrorService {
6
+ static configure(settings) {
7
+ this.settings = settings;
8
+ }
9
+ static clear() {
10
+ this.settings = null;
11
+ }
12
+ static reset() {
13
+ this.settings = null;
14
+ this.sentKeys.clear();
15
+ this.sentCount = 0;
16
+ }
17
+ static report(error, context = '', source = ps_client_error_config_1.PsClientErrorConfig.sources.boundary) {
18
+ if (!this.settings || typeof window === 'undefined')
19
+ return;
20
+ if (this.sentCount >= ps_client_error_config_1.PsClientErrorConfig.maxReportsPerPage)
21
+ return;
22
+ const payload = this.payload(error, context, source, this.settings);
23
+ const key = `${payload.message}|${payload.context}`;
24
+ if (this.sentKeys.has(key))
25
+ return;
26
+ this.sentKeys.add(key);
27
+ this.sentCount += 1;
28
+ this.send(this.settings.endpoint, JSON.stringify(payload));
29
+ }
30
+ static payload(error, context, source, settings) {
31
+ const isError = error instanceof Error;
32
+ const rawMessage = isError ? error.message : typeof error === 'string' ? error : '';
33
+ return {
34
+ message: this.clean(rawMessage ? rawMessage : ps_client_error_config_1.PsClientErrorConfig.unknownMessage).slice(0, ps_client_error_config_1.PsClientErrorConfig.maxMessageLength),
35
+ stack: isError && error.stack
36
+ ? this.clean(error.stack).slice(0, ps_client_error_config_1.PsClientErrorConfig.maxStackLength)
37
+ : '',
38
+ pathname: window.location.pathname,
39
+ appVersion: settings.appVersion ? settings.appVersion : '',
40
+ userAgentClass: this.userAgentClass(),
41
+ source,
42
+ context: this.clean(context).slice(0, ps_client_error_config_1.PsClientErrorConfig.maxContextLength),
43
+ };
44
+ }
45
+ static clean(value) {
46
+ return value.replace(ps_client_error_config_1.PsClientErrorConfig.emailPattern, ps_client_error_config_1.PsClientErrorConfig.redactedValue);
47
+ }
48
+ static userAgentClass() {
49
+ const agent = typeof navigator === 'undefined' ? '' : navigator.userAgent;
50
+ const classes = ps_client_error_config_1.PsClientErrorConfig.userAgentClasses;
51
+ if (!agent)
52
+ return classes.unknown;
53
+ if (ps_client_error_config_1.PsClientErrorConfig.botPattern.test(agent))
54
+ return classes.bot;
55
+ if (ps_client_error_config_1.PsClientErrorConfig.mobilePattern.test(agent))
56
+ return classes.mobile;
57
+ return classes.desktop;
58
+ }
59
+ static send(endpoint, body) {
60
+ if (typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function') {
61
+ const blob = new Blob([body], { type: ps_client_error_config_1.PsClientErrorConfig.jsonContentType });
62
+ if (navigator.sendBeacon(endpoint, blob))
63
+ return;
64
+ }
65
+ fetch(endpoint, {
66
+ method: 'POST',
67
+ headers: { 'Content-Type': ps_client_error_config_1.PsClientErrorConfig.jsonContentType },
68
+ body,
69
+ keepalive: true,
70
+ }).catch(() => undefined);
71
+ }
72
+ }
73
+ exports.PsClientErrorService = PsClientErrorService;
74
+ PsClientErrorService.settings = null;
75
+ PsClientErrorService.sentKeys = new Set();
76
+ PsClientErrorService.sentCount = 0;
@@ -0,0 +1,15 @@
1
+ import type { PsConsentChoice } from '../models/ps-consent-choice';
2
+ import type { PsConsentState } from '../models/ps-consent-state';
3
+ export declare class PsConsentService {
4
+ static readonly serverState: PsConsentState;
5
+ private static states;
6
+ private static listeners;
7
+ static snapshot(cookieName: string): PsConsentState;
8
+ static subscribe(listener: () => void): () => void;
9
+ static choose(cookieName: string, choice: PsConsentChoice): void;
10
+ static reopen(cookieName: string): void;
11
+ static reset(): void;
12
+ private static notify;
13
+ private static readCookie;
14
+ private static writeCookie;
15
+ }