@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.
- package/README.md +7 -0
- package/dist/analytics/Analytics.d.ts +11 -0
- package/dist/analytics/Analytics.js +48 -0
- package/dist/analytics/GoogleAnalytics.d.ts +16 -0
- package/dist/analytics/GoogleAnalytics.js +92 -0
- package/dist/analytics/index.d.ts +2 -0
- package/dist/analytics/index.js +18 -0
- package/dist/api/ApiClient.d.ts +18 -0
- package/dist/api/ApiClient.js +43 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +17 -0
- package/dist/captcha/MockHumanVerification.d.ts +4 -0
- package/dist/captcha/MockHumanVerification.js +11 -0
- package/dist/captcha/RecaptchaAdapter.d.ts +18 -0
- package/dist/captcha/RecaptchaAdapter.js +43 -0
- package/dist/captcha/errors/CaptchaError.d.ts +12 -0
- package/dist/captcha/errors/CaptchaError.js +19 -0
- package/dist/captcha/errors/CaptchaErrors.d.ts +8 -0
- package/dist/captcha/errors/CaptchaErrors.js +31 -0
- package/dist/captcha/errors/CaptchaVerificationError.d.ts +5 -0
- package/dist/captcha/errors/CaptchaVerificationError.js +11 -0
- package/dist/captcha/errors/index.d.ts +3 -0
- package/dist/captcha/errors/index.js +24 -0
- package/dist/captcha/index.d.ts +3 -0
- package/dist/captcha/index.js +19 -0
- package/dist/consent/ConsentActions.d.ts +5 -0
- package/dist/consent/ConsentActions.js +41 -0
- package/dist/consent/ConsentData.d.ts +13 -0
- package/dist/consent/ConsentData.js +35 -0
- package/dist/consent/CookieConsent.d.ts +19 -0
- package/dist/consent/CookieConsent.js +161 -0
- package/dist/consent/index.d.ts +2 -0
- package/dist/consent/index.js +18 -0
- package/dist/identity/actions.d.ts +4 -0
- package/dist/identity/actions.js +22 -0
- package/dist/identity/api/Identity.d.ts +11 -0
- package/dist/identity/api/Identity.js +2 -0
- package/dist/identity/api/IdentityService.d.ts +9 -0
- package/dist/identity/api/IdentityService.js +27 -0
- package/dist/identity/api/Profile.d.ts +10 -0
- package/dist/identity/api/Profile.js +2 -0
- package/dist/identity/api/ProfileService.d.ts +12 -0
- package/dist/identity/api/ProfileService.js +27 -0
- package/dist/identity/api/index.d.ts +4 -0
- package/dist/identity/api/index.js +20 -0
- package/dist/identity/auth0/Auth0IdentityService.d.ts +9 -0
- package/dist/identity/auth0/Auth0IdentityService.js +27 -0
- package/dist/identity/auth0/Auth0Profile.d.ts +30 -0
- package/dist/identity/auth0/Auth0Profile.js +57 -0
- package/dist/identity/auth0/Auth0ProfileService.d.ts +21 -0
- package/dist/identity/auth0/Auth0ProfileService.js +69 -0
- package/dist/identity/auth0/index.d.ts +2 -0
- package/dist/identity/auth0/index.js +18 -0
- package/dist/identity/client/ClientProfile.d.ts +27 -0
- package/dist/identity/client/ClientProfile.js +31 -0
- package/dist/identity/client/IdentityContainer.d.ts +12 -0
- package/dist/identity/client/IdentityContainer.js +23 -0
- package/dist/identity/client/IdentityContext.d.ts +8 -0
- package/dist/identity/client/IdentityContext.js +6 -0
- package/dist/identity/client/index.d.ts +3 -0
- package/dist/identity/client/index.js +19 -0
- package/dist/identity/client/useIdentity.d.ts +2 -0
- package/dist/identity/client/useIdentity.js +9 -0
- package/dist/identity/client/useProfile.d.ts +2 -0
- package/dist/identity/client/useProfile.js +9 -0
- package/dist/identity/index.d.ts +3 -0
- package/dist/identity/index.js +19 -0
- package/dist/identity/server/IdentityProvider.d.ts +5 -0
- package/dist/identity/server/IdentityProvider.js +29 -0
- package/dist/identity/server/index.d.ts +1 -0
- package/dist/identity/server/index.js +17 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +21 -0
- package/dist/ip/index.d.ts +1 -0
- package/dist/ip/index.js +17 -0
- package/dist/ip/useIpAddress.d.ts +1 -0
- package/dist/ip/useIpAddress.js +69 -0
- package/dist/leadgen/AbstractPipeDriveAdapter.d.ts +27 -0
- package/dist/leadgen/AbstractPipeDriveAdapter.js +43 -0
- package/dist/leadgen/ConfigPipeDriveAdapter.d.ts +18 -0
- package/dist/leadgen/ConfigPipeDriveAdapter.js +60 -0
- package/dist/leadgen/MockPipedrive.d.ts +16 -0
- package/dist/leadgen/MockPipedrive.js +32 -0
- package/dist/leadgen/PipedriveClient.d.ts +40 -0
- package/dist/leadgen/PipedriveClient.js +223 -0
- package/dist/leadgen/index.d.ts +4 -0
- package/dist/leadgen/index.js +20 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.js +20 -0
- package/package.json +52 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.IdentityContainer = IdentityContainer;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const IdentityContext_1 = require("./IdentityContext");
|
|
8
|
+
const ClientProfile_1 = require("./ClientProfile");
|
|
9
|
+
// component
|
|
10
|
+
function IdentityContainer({ brand, identity, profileData, onSetProfileData, children }) {
|
|
11
|
+
// bind context
|
|
12
|
+
const context = (0, react_1.useMemo)(() => {
|
|
13
|
+
// empty context if there is no identity
|
|
14
|
+
if (!identity) {
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
17
|
+
// create client profile
|
|
18
|
+
const profile = new ClientProfile_1.ClientProfile(Object.assign(Object.assign({}, identity), { brand, data: profileData, onSetProfileData }));
|
|
19
|
+
return { identity, profile };
|
|
20
|
+
}, [brand, identity, profileData, onSetProfileData]);
|
|
21
|
+
// render
|
|
22
|
+
return ((0, jsx_runtime_1.jsx)(IdentityContext_1.IdentityContext.Provider, { value: context, children: children }));
|
|
23
|
+
}
|
|
@@ -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("./IdentityContainer"), exports);
|
|
18
|
+
__exportStar(require("./useIdentity"), exports);
|
|
19
|
+
__exportStar(require("./useProfile"), exports);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useIdentity = useIdentity;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const IdentityContext_1 = require("./IdentityContext");
|
|
6
|
+
// hook
|
|
7
|
+
function useIdentity() {
|
|
8
|
+
return (0, react_1.useContext)(IdentityContext_1.IdentityContext).identity;
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useProfile = useProfile;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const IdentityContext_1 = require("./IdentityContext");
|
|
6
|
+
// hook
|
|
7
|
+
function useProfile() {
|
|
8
|
+
return (0, react_1.useContext)(IdentityContext_1.IdentityContext).profile;
|
|
9
|
+
}
|
|
@@ -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("./api"), exports);
|
|
18
|
+
__exportStar(require("./auth0"), exports);
|
|
19
|
+
__exportStar(require("./server"), exports);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { PropsWithChildren } from 'react';
|
|
2
|
+
export declare function IdentityProvider({ children }: IdentityProvider.Props): Promise<string | number | bigint | boolean | import("react/jsx-runtime").JSX.Element | Iterable<import("react").ReactNode> | null | undefined>;
|
|
3
|
+
export declare namespace IdentityProvider {
|
|
4
|
+
type Props = PropsWithChildren;
|
|
5
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IdentityProvider = IdentityProvider;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
6
|
+
const actions_1 = require("../actions");
|
|
7
|
+
const api_1 = require("../api");
|
|
8
|
+
const IdentityContainer_1 = require("../client/IdentityContainer");
|
|
9
|
+
// container
|
|
10
|
+
async function IdentityProvider({ children }) {
|
|
11
|
+
// get brand and services
|
|
12
|
+
const brand = funnel_core_1.AppConfig.brand();
|
|
13
|
+
const identityService = api_1.IdentityService.tryGet();
|
|
14
|
+
const profileService = api_1.ProfileService.tryGet();
|
|
15
|
+
// enable identity if set
|
|
16
|
+
if (identityService || profileService) {
|
|
17
|
+
// TODO: remove after testing
|
|
18
|
+
// await new Promise(resolve => setTimeout(resolve, 2000))
|
|
19
|
+
// try to get identity and profile
|
|
20
|
+
// const identity = await identityService?.current()
|
|
21
|
+
// const profile = await profileService?.current()
|
|
22
|
+
// render
|
|
23
|
+
return ((0, jsx_runtime_1.jsx)(IdentityContainer_1.IdentityContainer, { brand: brand, onSetProfileData: actions_1.IdentityActions.setProfileData, children: children }));
|
|
24
|
+
}
|
|
25
|
+
// or disable
|
|
26
|
+
else {
|
|
27
|
+
return children;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './IdentityProvider';
|
|
@@ -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("./IdentityProvider"), exports);
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
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("./captcha/RecaptchaAdapter"), exports);
|
|
19
|
+
__exportStar(require("./consent"), exports);
|
|
20
|
+
__exportStar(require("./identity/client"), exports);
|
|
21
|
+
__exportStar(require("./ip"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './useIpAddress';
|
package/dist/ip/index.js
ADDED
|
@@ -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("./useIpAddress"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useIpAddress(): string | null | undefined;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useIpAddress = useIpAddress;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
6
|
+
// hooks
|
|
7
|
+
function useIpAddress() {
|
|
8
|
+
// bind state
|
|
9
|
+
const ipResolver = SharedIpResolver.instance;
|
|
10
|
+
const [ip, setIp] = (0, react_1.useState)(ipResolver.ip);
|
|
11
|
+
// fetch address
|
|
12
|
+
(0, react_1.useEffect)(() => {
|
|
13
|
+
// bind ip
|
|
14
|
+
let cancelled = false;
|
|
15
|
+
ipResolver.getIp().then(ip => {
|
|
16
|
+
// update if not cancelled
|
|
17
|
+
if (!cancelled) {
|
|
18
|
+
setIp(ip);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
// cancel on unmount
|
|
22
|
+
return () => {
|
|
23
|
+
cancelled = true;
|
|
24
|
+
};
|
|
25
|
+
}, [ipResolver]);
|
|
26
|
+
// return ip
|
|
27
|
+
return ip;
|
|
28
|
+
}
|
|
29
|
+
// helper
|
|
30
|
+
class SharedIpResolver {
|
|
31
|
+
static get instance() {
|
|
32
|
+
// create if required
|
|
33
|
+
if (!SharedIpResolver._instance) {
|
|
34
|
+
SharedIpResolver._instance = new SharedIpResolver();
|
|
35
|
+
}
|
|
36
|
+
// throw if we don't have the instance
|
|
37
|
+
const instance = SharedIpResolver._instance;
|
|
38
|
+
if (!instance) {
|
|
39
|
+
throw new funnel_core_1.IllegalStateError('Unable to instantiate SharedIpResolver');
|
|
40
|
+
}
|
|
41
|
+
// return instance
|
|
42
|
+
return instance;
|
|
43
|
+
}
|
|
44
|
+
get ip() {
|
|
45
|
+
return this._ip;
|
|
46
|
+
}
|
|
47
|
+
getIp() {
|
|
48
|
+
// create promise if it isn't started
|
|
49
|
+
let ipPromise = this._ipPromise;
|
|
50
|
+
if (!ipPromise) {
|
|
51
|
+
ipPromise = this.fetchIp();
|
|
52
|
+
this._ipPromise = ipPromise;
|
|
53
|
+
}
|
|
54
|
+
// return promise
|
|
55
|
+
return ipPromise;
|
|
56
|
+
}
|
|
57
|
+
async fetchIp() {
|
|
58
|
+
// fetch ip
|
|
59
|
+
const response = await fetch('https://api.ipify.org');
|
|
60
|
+
// extract ip address
|
|
61
|
+
const ip = response.ok
|
|
62
|
+
? await response.text()
|
|
63
|
+
: null;
|
|
64
|
+
// update locally
|
|
65
|
+
this._ip = ip;
|
|
66
|
+
// and return it
|
|
67
|
+
return ip;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Contact, IHumanVerification, ILeadGen } from '@nascentdigital/funnel-core';
|
|
2
|
+
import { PipedriveClient } from './PipedriveClient';
|
|
3
|
+
export declare abstract class AbstractPipeDriveAdapter<TUserData extends Contact.UserData = Contact.UserData, TTags extends Contact.Tags = Contact.Tags, TResponse extends PipedriveClient.CaptureContactResponse = PipedriveClient.CaptureContactResponse> implements ILeadGen {
|
|
4
|
+
protected readonly pipeDrive: PipedriveClient;
|
|
5
|
+
private readonly _apiKey;
|
|
6
|
+
private readonly _humanVerification;
|
|
7
|
+
private readonly _ownerId;
|
|
8
|
+
protected constructor(args: AbstractPipeDriveAdapter.ConstructorArgs);
|
|
9
|
+
captureEmail(args: any): Promise<void>;
|
|
10
|
+
captureContact({ contact, verificationToken }: AbstractPipeDriveAdapter.CaptureContactArgs<TUserData, TTags>): Promise<PipedriveClient.CaptureContactResponse>;
|
|
11
|
+
captureLead(args: any): Promise<void>;
|
|
12
|
+
protected abstract getCustomFields(contact: Contact<TUserData, TTags>): AbstractPipeDriveAdapter.CustomFields;
|
|
13
|
+
protected abstract getLabelIds(contact: Contact<TUserData, TTags>): AbstractPipeDriveAdapter.LabelIds;
|
|
14
|
+
}
|
|
15
|
+
export declare namespace AbstractPipeDriveAdapter {
|
|
16
|
+
type ConstructorArgs = {
|
|
17
|
+
apiKey: string;
|
|
18
|
+
humanVerification: IHumanVerification;
|
|
19
|
+
ownerId?: number;
|
|
20
|
+
};
|
|
21
|
+
type CaptureContactArgs<TUserData extends Contact.UserData = Contact.UserData, TTags extends Contact.Tags = Contact.Tags> = {
|
|
22
|
+
contact: Contact<TUserData, TTags>;
|
|
23
|
+
verificationToken: string;
|
|
24
|
+
};
|
|
25
|
+
type CustomFields = Record<string, string>;
|
|
26
|
+
type LabelIds = number[];
|
|
27
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AbstractPipeDriveAdapter = void 0;
|
|
4
|
+
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
5
|
+
const PipedriveClient_1 = require("./PipedriveClient");
|
|
6
|
+
class AbstractPipeDriveAdapter {
|
|
7
|
+
constructor(args) {
|
|
8
|
+
// initialize instance variables
|
|
9
|
+
this._apiKey = args.apiKey;
|
|
10
|
+
this._humanVerification = args.humanVerification;
|
|
11
|
+
this._ownerId = args.ownerId;
|
|
12
|
+
this.pipeDrive = new PipedriveClient_1.PipedriveClient({ apiKey: this._apiKey });
|
|
13
|
+
}
|
|
14
|
+
async captureEmail(args) {
|
|
15
|
+
throw new Error('Method not implemented.');
|
|
16
|
+
}
|
|
17
|
+
async captureContact({ contact, verificationToken }) {
|
|
18
|
+
// verify will throw if users is not human
|
|
19
|
+
await this._humanVerification.verify({ verificationToken });
|
|
20
|
+
// map contact phones to person phones
|
|
21
|
+
const phones = [];
|
|
22
|
+
if (contact.phone) {
|
|
23
|
+
phones.push({
|
|
24
|
+
value: funnel_core_1.Contact.Phone.isSingle(contact.phone) ? contact.phone : contact.phone.primary,
|
|
25
|
+
primary: true
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
// capture basic data
|
|
29
|
+
const data = {
|
|
30
|
+
email: contact.email,
|
|
31
|
+
label_ids: this.getLabelIds(contact),
|
|
32
|
+
phones,
|
|
33
|
+
customData: this.getCustomFields(contact),
|
|
34
|
+
ownerId: this._ownerId
|
|
35
|
+
};
|
|
36
|
+
// submit data to Pipedrive
|
|
37
|
+
return this.pipeDrive.upsertPerson(data);
|
|
38
|
+
}
|
|
39
|
+
async captureLead(args) {
|
|
40
|
+
throw new Error('Method not implemented.');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.AbstractPipeDriveAdapter = AbstractPipeDriveAdapter;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Contact, IHumanVerification } from '@nascentdigital/funnel-core';
|
|
2
|
+
import { AbstractPipeDriveAdapter } from './AbstractPipeDriveAdapter';
|
|
3
|
+
export declare class ConfigPipeDriveAdapter<TCustomData extends Record<string, string> = Record<string, string>, TCustomTags extends Record<string, number> = Record<string, number>> extends AbstractPipeDriveAdapter<TCustomData> {
|
|
4
|
+
private readonly _customFields;
|
|
5
|
+
private readonly _labelIds;
|
|
6
|
+
constructor(args: ConfigPipeDriveAdapter.ConstructorArgs<TCustomData, TCustomTags>);
|
|
7
|
+
protected getCustomFields({ userData, name }: Contact): AbstractPipeDriveAdapter.CustomFields;
|
|
8
|
+
protected getLabelIds({ tags }: Contact): AbstractPipeDriveAdapter.LabelIds;
|
|
9
|
+
}
|
|
10
|
+
export declare namespace ConfigPipeDriveAdapter {
|
|
11
|
+
type ConstructorArgs<TCustomData extends Record<string, string> = Record<string, string>, TCustomTags extends Record<string, number> = Record<string, number>> = {
|
|
12
|
+
customFields: TCustomData;
|
|
13
|
+
labelIds: TCustomTags;
|
|
14
|
+
apiKey: string;
|
|
15
|
+
humanVerification: IHumanVerification;
|
|
16
|
+
ownerId?: number;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConfigPipeDriveAdapter = void 0;
|
|
4
|
+
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
5
|
+
const AbstractPipeDriveAdapter_1 = require("./AbstractPipeDriveAdapter");
|
|
6
|
+
class ConfigPipeDriveAdapter extends AbstractPipeDriveAdapter_1.AbstractPipeDriveAdapter {
|
|
7
|
+
constructor(args) {
|
|
8
|
+
// construct base
|
|
9
|
+
super(args);
|
|
10
|
+
// initialize instance variables
|
|
11
|
+
this._customFields = args.customFields;
|
|
12
|
+
this._labelIds = args.labelIds;
|
|
13
|
+
}
|
|
14
|
+
getCustomFields({ userData, name }) {
|
|
15
|
+
// bind custom fields based on config
|
|
16
|
+
const customFields = {};
|
|
17
|
+
const { _customFields } = this;
|
|
18
|
+
Object.entries(userData !== null && userData !== void 0 ? userData : {}).forEach(([fieldId, value]) => {
|
|
19
|
+
// skip if we don't have a mapping for this field
|
|
20
|
+
if (!(fieldId in _customFields)) {
|
|
21
|
+
console.warn(`[TestLeadGen] no mapping for custom field "${fieldId}"`);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
// map the field to the data
|
|
25
|
+
customFields[_customFields[fieldId]] = value;
|
|
26
|
+
});
|
|
27
|
+
// merge known fields with custom fields and return
|
|
28
|
+
if (funnel_core_1.Contact.Name.isSplit(name)) {
|
|
29
|
+
return {
|
|
30
|
+
'custom_fields': customFields,
|
|
31
|
+
'first_name': name.firstName,
|
|
32
|
+
'last_name': name.lastName,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
const [first, ...last] = name.split(' ');
|
|
37
|
+
return {
|
|
38
|
+
'custom_fields': customFields,
|
|
39
|
+
'first_name': first,
|
|
40
|
+
'last_name': last.join(' '),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
getLabelIds({ tags }) {
|
|
45
|
+
// for each contact tag get mapped label id
|
|
46
|
+
const labelIds = [];
|
|
47
|
+
tags === null || tags === void 0 ? void 0 : tags.forEach(tag => {
|
|
48
|
+
// skip if we don;t have mapping for tag
|
|
49
|
+
if (!this._labelIds[tag]) {
|
|
50
|
+
console.warn(`[TestLeadGen] no mapping for tag "${tag}"`);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
// added mapped label id
|
|
54
|
+
labelIds.push(this._labelIds[tag]);
|
|
55
|
+
});
|
|
56
|
+
// return valid label ids
|
|
57
|
+
return labelIds;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.ConfigPipeDriveAdapter = ConfigPipeDriveAdapter;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { IHumanVerification, ILeadGen } from '@nascentdigital/funnel-core';
|
|
2
|
+
export declare class MockPipedrive implements ILeadGen {
|
|
3
|
+
private readonly _apiKey;
|
|
4
|
+
private readonly _humanVerification;
|
|
5
|
+
constructor({ apiKey, humanVerification }: MockPipedrive.ConstructorArgs);
|
|
6
|
+
captureEmail(email: string): Promise<void>;
|
|
7
|
+
captureContact({ contact }: ILeadGen.CaptureContactArgs): Promise<{}>;
|
|
8
|
+
captureLead(args: any): Promise<void>;
|
|
9
|
+
private logArgs;
|
|
10
|
+
}
|
|
11
|
+
export declare namespace MockPipedrive {
|
|
12
|
+
type ConstructorArgs = {
|
|
13
|
+
apiKey: string;
|
|
14
|
+
humanVerification: IHumanVerification;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MockPipedrive = void 0;
|
|
4
|
+
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
5
|
+
// class
|
|
6
|
+
class MockPipedrive {
|
|
7
|
+
constructor({ apiKey, humanVerification }) {
|
|
8
|
+
// initialize instance variables
|
|
9
|
+
this._apiKey = apiKey;
|
|
10
|
+
this._humanVerification = humanVerification;
|
|
11
|
+
}
|
|
12
|
+
async captureEmail(email) {
|
|
13
|
+
this.logArgs('[MockPipedrive] capture email', email);
|
|
14
|
+
await this._humanVerification.verify({ verificationToken: '' });
|
|
15
|
+
return Promise.resolve();
|
|
16
|
+
}
|
|
17
|
+
captureContact({ contact }) {
|
|
18
|
+
this.logArgs('[MockPipedrive] capture contact', contact);
|
|
19
|
+
return Promise.resolve({});
|
|
20
|
+
}
|
|
21
|
+
captureLead(args) {
|
|
22
|
+
throw new funnel_core_1.NotImplementedError();
|
|
23
|
+
}
|
|
24
|
+
logArgs(message, args) {
|
|
25
|
+
let stringArgs = '';
|
|
26
|
+
if (args) {
|
|
27
|
+
stringArgs = JSON.stringify(args);
|
|
28
|
+
}
|
|
29
|
+
console.log(message, stringArgs);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.MockPipedrive = MockPipedrive;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { RequiredBy } from '@nascentdigital/funnel-core';
|
|
2
|
+
export declare class PipedriveClient {
|
|
3
|
+
private readonly _apiKey;
|
|
4
|
+
private readonly _marketingStatusEnabled;
|
|
5
|
+
constructor({ apiKey, marketingStatusEnabled }: PipedriveClient.ConstructorArgs);
|
|
6
|
+
upsertPerson(data: RequiredBy<Partial<PipedriveClient.Person>, 'email'>): Promise<PipedriveClient.CaptureContactResponse>;
|
|
7
|
+
captureNote(personId: number, content: string): Promise<void>;
|
|
8
|
+
captureOrganization(personId: number, organizationName: string): Promise<void>;
|
|
9
|
+
private send;
|
|
10
|
+
}
|
|
11
|
+
export declare namespace PipedriveClient {
|
|
12
|
+
type ConstructorArgs = {
|
|
13
|
+
apiKey: string;
|
|
14
|
+
marketingStatusEnabled?: boolean;
|
|
15
|
+
};
|
|
16
|
+
type Person = {
|
|
17
|
+
email: string;
|
|
18
|
+
phones: ReadonlyArray<Phone>;
|
|
19
|
+
marketingStatus?: MarketingStatus;
|
|
20
|
+
label_ids: number[];
|
|
21
|
+
customData: {
|
|
22
|
+
[key: string]: string;
|
|
23
|
+
};
|
|
24
|
+
ownerId?: number;
|
|
25
|
+
};
|
|
26
|
+
type MarketingStatus = 'no_consent' | 'subscribed' | 'unsubscribed' | 'archived';
|
|
27
|
+
type Phone = {
|
|
28
|
+
value: string;
|
|
29
|
+
primary: boolean;
|
|
30
|
+
};
|
|
31
|
+
type CaptureContactResponse = {
|
|
32
|
+
success: boolean;
|
|
33
|
+
data: {
|
|
34
|
+
id: number;
|
|
35
|
+
first_name: string;
|
|
36
|
+
last_name: string;
|
|
37
|
+
owner_id: string;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
}
|