@nascentdigital/funnel-services 4.4.18

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 (90) hide show
  1. package/README.md +7 -0
  2. package/dist/analytics/Analytics.d.ts +11 -0
  3. package/dist/analytics/Analytics.js +48 -0
  4. package/dist/analytics/GoogleAnalytics.d.ts +16 -0
  5. package/dist/analytics/GoogleAnalytics.js +92 -0
  6. package/dist/analytics/index.d.ts +2 -0
  7. package/dist/analytics/index.js +18 -0
  8. package/dist/api/ApiClient.d.ts +18 -0
  9. package/dist/api/ApiClient.js +43 -0
  10. package/dist/api/index.d.ts +1 -0
  11. package/dist/api/index.js +17 -0
  12. package/dist/captcha/MockHumanVerification.d.ts +4 -0
  13. package/dist/captcha/MockHumanVerification.js +11 -0
  14. package/dist/captcha/RecaptchaAdapter.d.ts +18 -0
  15. package/dist/captcha/RecaptchaAdapter.js +43 -0
  16. package/dist/captcha/errors/CaptchaError.d.ts +12 -0
  17. package/dist/captcha/errors/CaptchaError.js +19 -0
  18. package/dist/captcha/errors/CaptchaErrors.d.ts +8 -0
  19. package/dist/captcha/errors/CaptchaErrors.js +31 -0
  20. package/dist/captcha/errors/CaptchaVerificationError.d.ts +5 -0
  21. package/dist/captcha/errors/CaptchaVerificationError.js +11 -0
  22. package/dist/captcha/errors/index.d.ts +3 -0
  23. package/dist/captcha/errors/index.js +24 -0
  24. package/dist/captcha/index.d.ts +3 -0
  25. package/dist/captcha/index.js +19 -0
  26. package/dist/consent/ConsentActions.d.ts +5 -0
  27. package/dist/consent/ConsentActions.js +41 -0
  28. package/dist/consent/ConsentData.d.ts +13 -0
  29. package/dist/consent/ConsentData.js +35 -0
  30. package/dist/consent/CookieConsent.d.ts +19 -0
  31. package/dist/consent/CookieConsent.js +161 -0
  32. package/dist/consent/index.d.ts +2 -0
  33. package/dist/consent/index.js +18 -0
  34. package/dist/identity/actions.d.ts +4 -0
  35. package/dist/identity/actions.js +22 -0
  36. package/dist/identity/api/Identity.d.ts +11 -0
  37. package/dist/identity/api/Identity.js +2 -0
  38. package/dist/identity/api/IdentityService.d.ts +9 -0
  39. package/dist/identity/api/IdentityService.js +27 -0
  40. package/dist/identity/api/Profile.d.ts +10 -0
  41. package/dist/identity/api/Profile.js +2 -0
  42. package/dist/identity/api/ProfileService.d.ts +12 -0
  43. package/dist/identity/api/ProfileService.js +27 -0
  44. package/dist/identity/api/index.d.ts +4 -0
  45. package/dist/identity/api/index.js +20 -0
  46. package/dist/identity/auth0/Auth0IdentityService.d.ts +9 -0
  47. package/dist/identity/auth0/Auth0IdentityService.js +27 -0
  48. package/dist/identity/auth0/Auth0Profile.d.ts +30 -0
  49. package/dist/identity/auth0/Auth0Profile.js +57 -0
  50. package/dist/identity/auth0/Auth0ProfileService.d.ts +21 -0
  51. package/dist/identity/auth0/Auth0ProfileService.js +69 -0
  52. package/dist/identity/auth0/index.d.ts +2 -0
  53. package/dist/identity/auth0/index.js +18 -0
  54. package/dist/identity/client/ClientProfile.d.ts +27 -0
  55. package/dist/identity/client/ClientProfile.js +31 -0
  56. package/dist/identity/client/IdentityContainer.d.ts +12 -0
  57. package/dist/identity/client/IdentityContainer.js +23 -0
  58. package/dist/identity/client/IdentityContext.d.ts +8 -0
  59. package/dist/identity/client/IdentityContext.js +6 -0
  60. package/dist/identity/client/index.d.ts +3 -0
  61. package/dist/identity/client/index.js +19 -0
  62. package/dist/identity/client/useIdentity.d.ts +2 -0
  63. package/dist/identity/client/useIdentity.js +9 -0
  64. package/dist/identity/client/useProfile.d.ts +2 -0
  65. package/dist/identity/client/useProfile.js +9 -0
  66. package/dist/identity/index.d.ts +3 -0
  67. package/dist/identity/index.js +19 -0
  68. package/dist/identity/server/IdentityProvider.d.ts +5 -0
  69. package/dist/identity/server/IdentityProvider.js +29 -0
  70. package/dist/identity/server/index.d.ts +1 -0
  71. package/dist/identity/server/index.js +17 -0
  72. package/dist/index.d.ts +5 -0
  73. package/dist/index.js +21 -0
  74. package/dist/ip/index.d.ts +1 -0
  75. package/dist/ip/index.js +17 -0
  76. package/dist/ip/useIpAddress.d.ts +1 -0
  77. package/dist/ip/useIpAddress.js +69 -0
  78. package/dist/leadgen/AbstractPipeDriveAdapter.d.ts +27 -0
  79. package/dist/leadgen/AbstractPipeDriveAdapter.js +43 -0
  80. package/dist/leadgen/ConfigPipeDriveAdapter.d.ts +18 -0
  81. package/dist/leadgen/ConfigPipeDriveAdapter.js +60 -0
  82. package/dist/leadgen/MockPipedrive.d.ts +16 -0
  83. package/dist/leadgen/MockPipedrive.js +32 -0
  84. package/dist/leadgen/PipedriveClient.d.ts +40 -0
  85. package/dist/leadgen/PipedriveClient.js +223 -0
  86. package/dist/leadgen/index.d.ts +4 -0
  87. package/dist/leadgen/index.js +20 -0
  88. package/dist/server.d.ts +4 -0
  89. package/dist/server.js +20 -0
  90. package/package.json +52 -0
package/README.md ADDED
@@ -0,0 +1,7 @@
1
+ # Services
2
+
3
+ ## API Testing
4
+
5
+ We use [Bruno](https://www.usebruno.com/) to share api collection to test and use. This allows us to share test endpoints and collaborate through git.
6
+
7
+ **Be Careful: Do not commit secret values through bruno configs! use [environment variables](https://docs.usebruno.com/get-started/variables/environment-variables) to mange secret variables, which bruno stores locally**
@@ -0,0 +1,11 @@
1
+ import { CookieConsent } from '../consent';
2
+ export declare namespace Analytics {
3
+ interface Provider {
4
+ trackPageView(): void;
5
+ trackEvent(): void;
6
+ onConsentChange(state: CookieConsent.State): void;
7
+ }
8
+ function bindProvider(provider: Provider): void;
9
+ function trackPageView(): void;
10
+ function trackEvent(): void;
11
+ }
@@ -0,0 +1,48 @@
1
+ 'use client';
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.Analytics = void 0;
5
+ const funnel_core_1 = require("@nascentdigital/funnel-core");
6
+ const consent_1 = require("../consent");
7
+ // namespace
8
+ var Analytics;
9
+ (function (Analytics) {
10
+ // helper
11
+ const getProvider = () => {
12
+ // throw if provider isn't initialized
13
+ const provider = _provider;
14
+ if (!provider) {
15
+ throw new funnel_core_1.InvalidOperationError('Attempt to access provider before being bound');
16
+ }
17
+ // return provider
18
+ return provider;
19
+ };
20
+ // methods
21
+ function bindProvider(provider) {
22
+ // skip if provider is the same
23
+ if (provider === _provider) {
24
+ console.warn('[Analytics] ignoring duplicate provider binding');
25
+ return;
26
+ }
27
+ // throw if there's already a provider
28
+ if (_provider) {
29
+ throw new funnel_core_1.InvalidOperationError('Provider is already bound');
30
+ }
31
+ // bind provider
32
+ _provider = provider;
33
+ // forward consent changes
34
+ consent_1.CookieConsent.state$()
35
+ .subscribe(state => provider.onConsentChange(state));
36
+ }
37
+ Analytics.bindProvider = bindProvider;
38
+ function trackPageView() {
39
+ return getProvider().trackPageView();
40
+ }
41
+ Analytics.trackPageView = trackPageView;
42
+ function trackEvent() {
43
+ return getProvider().trackEvent();
44
+ }
45
+ Analytics.trackEvent = trackEvent;
46
+ })(Analytics || (exports.Analytics = Analytics = {}));
47
+ // provider
48
+ let _provider = undefined;
@@ -0,0 +1,16 @@
1
+ import { ConsentService } from '@nascentdigital/funnel-core';
2
+ declare global {
3
+ interface Window {
4
+ dataLayer?: any[];
5
+ }
6
+ function gtag(...value: any[]): void;
7
+ }
8
+ export declare function GoogleAnalytics({ tagId, enableAds, debugMode }: GoogleAnalytics.Props): import("react/jsx-runtime").JSX.Element;
9
+ export declare namespace GoogleAnalytics {
10
+ type Props = {
11
+ tagId: string;
12
+ enableAds?: boolean;
13
+ debugMode?: boolean;
14
+ };
15
+ const services: ReadonlyArray<ConsentService>;
16
+ }
@@ -0,0 +1,92 @@
1
+ 'use client';
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.GoogleAnalytics = GoogleAnalytics;
8
+ const jsx_runtime_1 = require("react/jsx-runtime");
9
+ const script_1 = __importDefault(require("next/script"));
10
+ const react_1 = require("react");
11
+ const Analytics_1 = require("./Analytics");
12
+ // component
13
+ function GoogleAnalytics({ tagId, enableAds = false, debugMode = false }) {
14
+ // bind props + provider
15
+ const [consent, setConsent] = (0, react_1.useState)();
16
+ const provider = (0, react_1.useMemo)(() => new GoogleAnalyticsProvider(tagId, setConsent), [tagId]);
17
+ const allowed = (0, react_1.useMemo)(() => !!consent
18
+ && consent.services.some(c => c.service === 'analytics_storage' && c.accepted), [consent]);
19
+ // mount
20
+ (0, react_1.useEffect)(() => {
21
+ // bind provider
22
+ Analytics_1.Analytics.bindProvider(provider);
23
+ }, [provider]);
24
+ // update consent when changed
25
+ (0, react_1.useEffect)(() => {
26
+ // skip if consent isn't set
27
+ if (!consent) {
28
+ return;
29
+ }
30
+ // fail if datalayer isn't bound
31
+ else if (!window.dataLayer) {
32
+ console.warn('[GoogleAnalytics] attempt to update consent before dataLayer is bound');
33
+ return;
34
+ }
35
+ // bind defaults (deny all by default)
36
+ gtag('consent', 'update', consent.services.reduce((consent, { category, service, accepted }) => {
37
+ // set consent for service
38
+ consent[service] = accepted && (enableAds || category !== 'advertisement')
39
+ ? 'granted'
40
+ : 'denied';
41
+ // keep reducing
42
+ return consent;
43
+ }, {}));
44
+ }, [consent, enableAds]);
45
+ // render
46
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(script_1.default, { id: "_funnel-analytics-ga-init", dangerouslySetInnerHTML: {
47
+ __html: `
48
+ window.dataLayer = window.dataLayer || [];
49
+ function gtag(){dataLayer.push(arguments);}
50
+ gtag('consent', 'default', {
51
+ 'ad_user_data': 'denied',
52
+ 'ad_personalization': 'denied',
53
+ 'ad_storage': 'denied',
54
+ 'analytics_storage': 'denied',
55
+ 'security_storage': 'denied',
56
+ 'personalization_storage': 'denied',
57
+ 'functionality_storage': 'denied',
58
+ 'wait_for_update': 500
59
+ });
60
+ gtag('js', new Date());
61
+ gtag('config', '${tagId}' ${debugMode ? ",{ 'debug_mode': true }" : ''});`,
62
+ } }, "_funnel-analytics-ga-init"), allowed &&
63
+ (0, jsx_runtime_1.jsx)(script_1.default, { id: "_funnel-analytics-ga", src: `https://www.googletagmanager.com/gtag/js?id=${tagId}` }, "_funnel-analytics-ga")] }));
64
+ }
65
+ // extension
66
+ (function (GoogleAnalytics) {
67
+ // constants
68
+ GoogleAnalytics.services = [
69
+ 'functionality_storage', 'personalization_storage',
70
+ 'security_storage',
71
+ 'analytics_storage',
72
+ 'ad_storage', 'ad_user_data', 'ad_personalization'
73
+ ];
74
+ })(GoogleAnalytics || (exports.GoogleAnalytics = GoogleAnalytics = {}));
75
+ // provider
76
+ class GoogleAnalyticsProvider {
77
+ constructor(tagId, setConsent) {
78
+ this.tagId = tagId;
79
+ this.setConsent = setConsent;
80
+ }
81
+ trackPageView() {
82
+ throw new Error('Method not implemented.');
83
+ }
84
+ trackEvent() {
85
+ throw new Error('Method not implemented.');
86
+ }
87
+ onConsentChange(consent) {
88
+ console.debug('[GoogleAnalyticsProvider] handling consent change', consent);
89
+ // forward consent
90
+ this.setConsent(consent);
91
+ }
92
+ }
@@ -0,0 +1,2 @@
1
+ export * from './Analytics';
2
+ export * from './GoogleAnalytics';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./Analytics"), exports);
18
+ __exportStar(require("./GoogleAnalytics"), exports);
@@ -0,0 +1,18 @@
1
+ import 'server-only';
2
+ export declare class ApiClient {
3
+ private readonly _apiUrl?;
4
+ private readonly _apiToken?;
5
+ constructor();
6
+ get<TResponse = any>(args: Omit<ApiClient.SendArgs, 'method'>): Promise<TResponse>;
7
+ post<TResponse = any>(args: Omit<ApiClient.SendArgs, 'method'>): Promise<TResponse>;
8
+ send<TResponse>({ method, path, headers, body }: ApiClient.SendArgs): Promise<TResponse>;
9
+ }
10
+ export declare namespace ApiClient {
11
+ type SendArgs = {
12
+ method: 'GET' | 'POST';
13
+ path: string;
14
+ headers?: Record<string, string>;
15
+ body?: string;
16
+ };
17
+ }
18
+ export declare const apiClient: ApiClient;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.apiClient = exports.ApiClient = void 0;
4
+ require("server-only");
5
+ const funnel_core_1 = require("@nascentdigital/funnel-core");
6
+ // class
7
+ class ApiClient {
8
+ constructor() {
9
+ var _a, _b;
10
+ // initialize instance variables
11
+ this._apiUrl = (_a = process.env.API_URL) !== null && _a !== void 0 ? _a : undefined;
12
+ this._apiToken = (_b = process.env.API_TOKEN) !== null && _b !== void 0 ? _b : undefined;
13
+ }
14
+ get(args) {
15
+ return this.send(Object.assign(Object.assign({}, args), { method: 'GET' }));
16
+ }
17
+ post(args) {
18
+ return this.send(Object.assign(Object.assign({}, args), { method: 'POST' }));
19
+ }
20
+ async send({ method, path, headers = {}, body }) {
21
+ // fail if api url/token are missing
22
+ const { _apiUrl, _apiToken } = this;
23
+ if (!_apiUrl || !_apiToken) {
24
+ throw new funnel_core_1.IllegalStateError('ApiClient is missing API_URL/API_TOKEN configuration');
25
+ }
26
+ // send request
27
+ const url = new URL(path, _apiUrl);
28
+ const response = await fetch(url.href, {
29
+ method,
30
+ headers: Object.assign(Object.assign({}, headers), { Accept: 'application/json', 'Content-Type': 'application/json', Authorization: `Bearer ${_apiToken}` }),
31
+ body
32
+ });
33
+ // throw if there's an error
34
+ await funnel_core_1.IsometricErrorUtils.checkResponse(response, error => {
35
+ console.error('[ApiClient] request failed', error);
36
+ });
37
+ // or return response
38
+ return response.json();
39
+ }
40
+ }
41
+ exports.ApiClient = ApiClient;
42
+ // exports
43
+ exports.apiClient = new ApiClient();
@@ -0,0 +1 @@
1
+ export * from './ApiClient';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./ApiClient"), exports);
@@ -0,0 +1,4 @@
1
+ import { IHumanVerification } from '@nascentdigital/funnel-core';
2
+ export declare class MockHumanVerification implements IHumanVerification {
3
+ verify(args: IHumanVerification.VerifyUserIsHumanArgs): Promise<void>;
4
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MockHumanVerification = void 0;
4
+ // class
5
+ class MockHumanVerification {
6
+ verify(args) {
7
+ console.debug('[MockHumanVerification] verifying user is human');
8
+ return Promise.resolve(undefined);
9
+ }
10
+ }
11
+ exports.MockHumanVerification = MockHumanVerification;
@@ -0,0 +1,18 @@
1
+ import { IHumanVerification } from '@nascentdigital/funnel-core';
2
+ export declare class RecaptchaAdapter implements IHumanVerification {
3
+ private readonly _recaptchaSecretKey;
4
+ constructor({ recaptchaSecretKey }: RecaptchaAdapter.ConstructorArgs);
5
+ verify(args: IHumanVerification.VerifyUserIsHumanArgs): Promise<void>;
6
+ }
7
+ export declare namespace RecaptchaAdapter {
8
+ type RecaptchaResponse = {
9
+ success: boolean;
10
+ challenge_ts: unknown;
11
+ host: string;
12
+ 'error-codes'?: Array<string>;
13
+ };
14
+ type ConstructorArgs = {
15
+ recaptchaSecretKey: string;
16
+ };
17
+ function getVerificationToken(): Promise<string>;
18
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RecaptchaAdapter = void 0;
4
+ const errors_1 = require("./errors");
5
+ // class
6
+ class RecaptchaAdapter {
7
+ constructor({ recaptchaSecretKey }) {
8
+ // initialize instance variables
9
+ this._recaptchaSecretKey = recaptchaSecretKey;
10
+ }
11
+ async verify(args) {
12
+ var _a;
13
+ console.debug('[RecaptchaAdapter] verifying user is human');
14
+ // create verification URL
15
+ const verificationUrl = new URL('https://www.google.com/recaptcha/api/siteverify');
16
+ verificationUrl.searchParams.set('secret', this._recaptchaSecretKey);
17
+ verificationUrl.searchParams.set('response', args.verificationToken);
18
+ // get score from Google
19
+ const verifiedResponse = await fetch(verificationUrl.href, { method: 'POST' });
20
+ const response = await verifiedResponse.json();
21
+ // throw if there's an error
22
+ if (!response.success) {
23
+ const [code] = (_a = response['error-codes']) !== null && _a !== void 0 ? _a : [];
24
+ throw new errors_1.CaptchaVerificationError('User could not be verified', code);
25
+ }
26
+ console.debug('[RecaptchaAdapter] user is human');
27
+ return Promise.resolve(undefined);
28
+ }
29
+ }
30
+ exports.RecaptchaAdapter = RecaptchaAdapter;
31
+ // extension
32
+ (function (RecaptchaAdapter) {
33
+ // helpers
34
+ function getVerificationToken() {
35
+ return new Promise((resolve) => {
36
+ grecaptcha.ready(function () {
37
+ grecaptcha.execute(process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY || '', { action: 'submit' })
38
+ .then(resolve);
39
+ });
40
+ });
41
+ }
42
+ RecaptchaAdapter.getVerificationToken = getVerificationToken;
43
+ })(RecaptchaAdapter || (exports.RecaptchaAdapter = RecaptchaAdapter = {}));
@@ -0,0 +1,12 @@
1
+ import { IsometricError, SerializedIsometricError } from '@nascentdigital/funnel-core';
2
+ export declare class CaptchaError extends IsometricError {
3
+ readonly code?: string;
4
+ constructor(args: CaptchaError.ConstructorArgs);
5
+ serialize(): SerializedIsometricError;
6
+ }
7
+ export declare namespace CaptchaError {
8
+ type ConstructorArgs = IsometricError.ConstructorArgs.WithoutModuleId & {
9
+ code?: string;
10
+ };
11
+ type Options = Omit<ConstructorArgs, 'message'>;
12
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CaptchaError = void 0;
4
+ const funnel_core_1 = require("@nascentdigital/funnel-core");
5
+ const CaptchaErrors_1 = require("./CaptchaErrors");
6
+ // error
7
+ class CaptchaError extends funnel_core_1.IsometricError {
8
+ constructor(args) {
9
+ // construct base
10
+ super(Object.assign(Object.assign({}, args), { moduleId: CaptchaErrors_1.CaptchaErrors.moduleId }));
11
+ // initialize instance variables
12
+ this.code = args.code;
13
+ }
14
+ serialize() {
15
+ const { code = null } = this;
16
+ return Object.assign(Object.assign({}, super.serialize()), { code });
17
+ }
18
+ }
19
+ exports.CaptchaError = CaptchaError;
@@ -0,0 +1,8 @@
1
+ import { IsometricError, IsometricErrorModule, SerializedIsometricError } from '@nascentdigital/funnel-core';
2
+ export declare class CaptchaErrors implements IsometricErrorModule {
3
+ readonly id: IsometricErrorModule.Id;
4
+ deserialize(data: SerializedIsometricError): IsometricError | undefined;
5
+ }
6
+ export declare namespace CaptchaErrors {
7
+ const moduleId: IsometricErrorModule.Id;
8
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CaptchaErrors = void 0;
4
+ const funnel_core_1 = require("@nascentdigital/funnel-core");
5
+ const CaptchaVerificationError_1 = require("./CaptchaVerificationError");
6
+ // module
7
+ class CaptchaErrors {
8
+ constructor() {
9
+ this.id = CaptchaErrors.moduleId;
10
+ }
11
+ deserialize(data) {
12
+ // skip if module doesn't match
13
+ if (data.moduleId !== this.id) {
14
+ return undefined;
15
+ }
16
+ // convert
17
+ switch (data.name) {
18
+ // re-hydrate error
19
+ case CaptchaVerificationError_1.CaptchaVerificationError.name:
20
+ return new CaptchaVerificationError_1.CaptchaVerificationError(data.message, funnel_core_1.Value.parseString(data.code));
21
+ // or ignore if not matching
22
+ default:
23
+ return undefined;
24
+ }
25
+ }
26
+ }
27
+ exports.CaptchaErrors = CaptchaErrors;
28
+ // extensions
29
+ (function (CaptchaErrors) {
30
+ CaptchaErrors.moduleId = 'captcha';
31
+ })(CaptchaErrors || (exports.CaptchaErrors = CaptchaErrors = {}));
@@ -0,0 +1,5 @@
1
+ import { ApiError } from '@nascentdigital/funnel-core';
2
+ import { CaptchaError } from './CaptchaError';
3
+ export declare class CaptchaVerificationError extends CaptchaError {
4
+ constructor(message?: string, code?: string, options?: ApiError.Options);
5
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CaptchaVerificationError = void 0;
4
+ const CaptchaError_1 = require("./CaptchaError");
5
+ // class
6
+ class CaptchaVerificationError extends CaptchaError_1.CaptchaError {
7
+ constructor(message = 'Captcha verification failed', code, options = {}) {
8
+ super(Object.assign({ message, code }, options));
9
+ }
10
+ }
11
+ exports.CaptchaVerificationError = CaptchaVerificationError;
@@ -0,0 +1,3 @@
1
+ export * from './CaptchaError';
2
+ export * from './CaptchaErrors';
3
+ export * from './CaptchaVerificationError';
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ const funnel_core_1 = require("@nascentdigital/funnel-core");
18
+ const CaptchaErrors_1 = require("./CaptchaErrors");
19
+ // exports
20
+ __exportStar(require("./CaptchaError"), exports);
21
+ __exportStar(require("./CaptchaErrors"), exports);
22
+ __exportStar(require("./CaptchaVerificationError"), exports);
23
+ // bind module
24
+ funnel_core_1.IsometricErrorUtils.registerModule(CaptchaErrors_1.CaptchaErrors);
@@ -0,0 +1,3 @@
1
+ export * from './errors';
2
+ export * from './MockHumanVerification';
3
+ export * from './RecaptchaAdapter';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./errors"), exports);
18
+ __exportStar(require("./MockHumanVerification"), exports);
19
+ __exportStar(require("./RecaptchaAdapter"), exports);
@@ -0,0 +1,5 @@
1
+ import 'server-only';
2
+ import { ConsentData } from './ConsentData';
3
+ export declare namespace ConsentActions {
4
+ function captureConsent(data: ConsentData): Promise<void>;
5
+ }
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.ConsentActions = void 0;
15
+ require("server-only");
16
+ const headers_1 = require("next/headers");
17
+ const api_1 = require("../api");
18
+ // handler
19
+ var ConsentActions;
20
+ (function (ConsentActions) {
21
+ async function captureConsent(data) {
22
+ var _a;
23
+ // create dto
24
+ const { ip, url, userId } = data, consent = __rest(data, ["ip", "url", "userId"]);
25
+ const requestHeaders = await (0, headers_1.headers)();
26
+ const dto = {
27
+ userId,
28
+ userAgent: (_a = requestHeaders.get('user-agent')) !== null && _a !== void 0 ? _a : 'Unknown',
29
+ ip,
30
+ url,
31
+ consent
32
+ };
33
+ console.debug('[ConsentActions] submitting', dto);
34
+ // submit to funnel-api
35
+ await api_1.apiClient.post({
36
+ path: '/api/consent',
37
+ body: JSON.stringify(dto)
38
+ });
39
+ }
40
+ ConsentActions.captureConsent = captureConsent;
41
+ })(ConsentActions || (exports.ConsentActions = ConsentActions = {}));
@@ -0,0 +1,13 @@
1
+ import { ConsentCategory, ConsentService } from '@nascentdigital/funnel-core';
2
+ import * as Consent from 'vanilla-cookieconsent';
3
+ export type ConsentData = {
4
+ ip?: string;
5
+ url: string;
6
+ userId: string;
7
+ choice: Consent.AcceptType;
8
+ categories: ReadonlyArray<ConsentCategory.Choice>;
9
+ services: ReadonlyArray<ConsentService.Choice>;
10
+ };
11
+ export declare namespace ConsentData {
12
+ function parse(value: any): ConsentData;
13
+ }
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConsentData = void 0;
4
+ const funnel_core_1 = require("@nascentdigital/funnel-core");
5
+ // extension
6
+ var ConsentData;
7
+ (function (ConsentData) {
8
+ function parse(value) {
9
+ // throw if not an object
10
+ if (!value || typeof value !== 'object') {
11
+ throw new funnel_core_1.ArgumentError('ConsentData must be a valid object');
12
+ }
13
+ // throw if props are missing
14
+ else if (!('ip' in value) || typeof value.ip !== 'string' ||
15
+ !('url' in value) || typeof value.url !== 'string' ||
16
+ !('userId' in value) || typeof value.userId !== 'string' ||
17
+ !('choice' in value) || typeof value.choice !== 'string' ||
18
+ !('categories' in value) || !Array.isArray(value.categories) ||
19
+ !value.categories.every(funnel_core_1.ConsentCategory.Choice.filter) ||
20
+ !('services' in value) || !Array.isArray(value.services) ||
21
+ !value.services.every((v) => typeof v !== 'string')) {
22
+ throw new funnel_core_1.ArgumentError('ConsentData has invalid format');
23
+ }
24
+ // destructure
25
+ return {
26
+ ip: value.ip,
27
+ url: value.url,
28
+ userId: value.userId,
29
+ choice: value.choice,
30
+ categories: value.categories,
31
+ services: value.services
32
+ };
33
+ }
34
+ ConsentData.parse = parse;
35
+ })(ConsentData || (exports.ConsentData = ConsentData = {}));
@@ -0,0 +1,19 @@
1
+ import { ConsentCategory, ConsentService, Transform } from '@nascentdigital/funnel-core';
2
+ import { Jsonify } from 'type-fest';
3
+ import * as Consent from 'vanilla-cookieconsent';
4
+ import { ConsentData } from './ConsentData';
5
+ export declare function CookieConsent({ consentAction, copy }: CookieConsent.Props): import("react/jsx-runtime").JSX.Element;
6
+ export declare namespace CookieConsent {
7
+ type Props = {
8
+ consentAction: Transform.Async<ConsentData, void>;
9
+ copy: Copy;
10
+ };
11
+ type State = {
12
+ categories: ReadonlyArray<ConsentCategory.Choice>;
13
+ services: ReadonlyArray<ConsentService.Choice>;
14
+ };
15
+ type Copy = Jsonify<Consent.Translation> & {
16
+ cta: string;
17
+ };
18
+ function state$(): import("rxjs").Observable<State>;
19
+ }