@walkeros/server-destination-hubspot 3.4.0-next-1776749829492

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.
@@ -0,0 +1,185 @@
1
+ import { Mapping, Flow } from '@walkeros/core';
2
+ import { DestinationServer } from '@walkeros/server-core';
3
+
4
+ /** Shape of a single custom event occurrence sent to HubSpot. */
5
+ interface HubSpotEventRequest {
6
+ eventName: string;
7
+ email?: string;
8
+ objectId?: string;
9
+ utk?: string;
10
+ uuid?: string;
11
+ occurredAt?: Date;
12
+ properties?: Record<string, string>;
13
+ }
14
+ /**
15
+ * Mock-friendly interface for the HubSpot Client methods the destination
16
+ * actually calls. Tests provide this via env.client instead of the real SDK.
17
+ */
18
+ interface HubSpotClientMock {
19
+ events: {
20
+ send: {
21
+ basicApi: {
22
+ send: (data: HubSpotEventRequest) => Promise<void>;
23
+ };
24
+ batchApi: {
25
+ send: (data: {
26
+ inputs: HubSpotEventRequest[];
27
+ }) => Promise<void>;
28
+ };
29
+ };
30
+ };
31
+ crm: {
32
+ contacts: {
33
+ basicApi: {
34
+ update: (id: string, data: {
35
+ properties: Record<string, string>;
36
+ }, idProperty?: string) => Promise<void>;
37
+ };
38
+ };
39
+ };
40
+ }
41
+ interface Settings {
42
+ /** HubSpot private app access token (required). */
43
+ accessToken: string;
44
+ /**
45
+ * Fully qualified event name prefix: pe{HubID}_
46
+ * Used to construct eventName from walkerOS event names.
47
+ * Example: 'pe12345678_'
48
+ */
49
+ eventNamePrefix: string;
50
+ /**
51
+ * walkerOS mapping value path to resolve contact email from events.
52
+ * Default: 'user.email'
53
+ */
54
+ email?: string;
55
+ /**
56
+ * walkerOS mapping value path to resolve HubSpot objectId from events.
57
+ * Default: undefined (use email for association)
58
+ */
59
+ objectId?: string;
60
+ /**
61
+ * Destination-level contact upsert mapping.
62
+ * Resolves to { email, properties } and upserts the contact on each push
63
+ * (with dedup via state hash).
64
+ */
65
+ identify?: Mapping.Value;
66
+ /**
67
+ * Static event properties added to every event occurrence.
68
+ * Useful for hs_touchpoint_source, hs_page_content_type, etc.
69
+ */
70
+ defaultProperties?: Record<string, string>;
71
+ /**
72
+ * Whether to use batch API for events (accumulate and flush).
73
+ * Default: false (single event sends).
74
+ */
75
+ batch?: boolean;
76
+ /**
77
+ * Batch size before auto-flush. Only used when batch: true.
78
+ * Default: 50. Max: 500.
79
+ */
80
+ batchSize?: number;
81
+ /** Runtime state -- not user-facing. Mutated by init/push. */
82
+ _client?: HubSpotClientMock;
83
+ _state?: RuntimeState;
84
+ _eventQueue?: HubSpotEventRequest[];
85
+ }
86
+ interface RuntimeState {
87
+ lastIdentity?: {
88
+ email?: string;
89
+ propertiesHash?: string;
90
+ };
91
+ }
92
+ /**
93
+ * Env -- optional SDK override. Production leaves this undefined and the
94
+ * destination creates a real Client instance. Tests provide a mock via
95
+ * env.client.
96
+ */
97
+ interface Env extends DestinationServer.Env {
98
+ client?: HubSpotClientMock;
99
+ }
100
+
101
+ declare const push: Env;
102
+ declare const simulation: string[];
103
+
104
+ declare const env_push: typeof push;
105
+ declare const env_simulation: typeof simulation;
106
+ declare namespace env {
107
+ export { env_push as push, env_simulation as simulation };
108
+ }
109
+
110
+ /**
111
+ * HubSpot SDK step examples.
112
+ *
113
+ * At push time, the destination invokes the `@hubspot/api-client` SDK. The
114
+ * public method paths users see on the client are:
115
+ *
116
+ * - `events.send.basicApi.send(eventRequest)` — fires an event
117
+ * - `events.send.batchApi.send({ inputs: [...] })` — flushes a batch
118
+ * - `crm.contacts.basicApi.update(id, data, idProperty)` — contact upsert
119
+ *
120
+ * Each `out` is therefore a list of tuples `[['method.path', ...args], ...]`
121
+ * matching the actual SDK call order. `identify` fires before the event.
122
+ * When the destination skips an event (`skip: true`, `ignore: true`, or
123
+ * missing identity), `out` is `[]`.
124
+ */
125
+ /**
126
+ * Extended step example that may carry destination-level settings overrides.
127
+ */
128
+ type HubSpotStepExample = Flow.StepExample & {
129
+ settings?: Partial<Settings>;
130
+ };
131
+ /**
132
+ * Default event forwarding -- events.send.basicApi.send() with auto-generated
133
+ * event name. Email resolved from default settings.email = 'user.email'.
134
+ */
135
+ declare const defaultEvent: HubSpotStepExample;
136
+ /**
137
+ * Mapped event name -- mapping.settings.eventName overrides the auto-generated
138
+ * name. The prefix is still prepended.
139
+ */
140
+ declare const mappedEventName: HubSpotStepExample;
141
+ /**
142
+ * Event with defaultProperties -- settings.defaultProperties are merged
143
+ * into every event. Per-event properties override defaults.
144
+ */
145
+ declare const defaultProperties: HubSpotStepExample;
146
+ /**
147
+ * Destination-level identify -- fires crm.contacts.basicApi.update() on
148
+ * first push when settings.identify mapping resolves. Then fires the event.
149
+ */
150
+ declare const destinationIdentify: HubSpotStepExample;
151
+ /**
152
+ * Per-event identify with skip -- user login fires contact upsert only,
153
+ * no custom event sent.
154
+ */
155
+ declare const userLoginIdentify: HubSpotStepExample;
156
+ /**
157
+ * objectId association -- use objectId instead of email for contact
158
+ * association on the event.
159
+ */
160
+ declare const objectIdAssociation: HubSpotStepExample;
161
+ /**
162
+ * No identity resolved -- event is skipped with a warning. Neither email
163
+ * nor objectId can be resolved from the event.
164
+ */
165
+ declare const noIdentity: HubSpotStepExample;
166
+ /**
167
+ * Wildcard ignore -- the event matches a mapping rule with ignore: true.
168
+ * The destination fires zero SDK calls.
169
+ */
170
+ declare const wildcardIgnored: HubSpotStepExample;
171
+
172
+ type step_HubSpotStepExample = HubSpotStepExample;
173
+ declare const step_defaultEvent: typeof defaultEvent;
174
+ declare const step_defaultProperties: typeof defaultProperties;
175
+ declare const step_destinationIdentify: typeof destinationIdentify;
176
+ declare const step_mappedEventName: typeof mappedEventName;
177
+ declare const step_noIdentity: typeof noIdentity;
178
+ declare const step_objectIdAssociation: typeof objectIdAssociation;
179
+ declare const step_userLoginIdentify: typeof userLoginIdentify;
180
+ declare const step_wildcardIgnored: typeof wildcardIgnored;
181
+ declare namespace step {
182
+ export { type step_HubSpotStepExample as HubSpotStepExample, step_defaultEvent as defaultEvent, step_defaultProperties as defaultProperties, step_destinationIdentify as destinationIdentify, step_mappedEventName as mappedEventName, step_noIdentity as noIdentity, step_objectIdAssociation as objectIdAssociation, step_userLoginIdentify as userLoginIdentify, step_wildcardIgnored as wildcardIgnored };
183
+ }
184
+
185
+ export { env, step };
@@ -0,0 +1,185 @@
1
+ import { Mapping, Flow } from '@walkeros/core';
2
+ import { DestinationServer } from '@walkeros/server-core';
3
+
4
+ /** Shape of a single custom event occurrence sent to HubSpot. */
5
+ interface HubSpotEventRequest {
6
+ eventName: string;
7
+ email?: string;
8
+ objectId?: string;
9
+ utk?: string;
10
+ uuid?: string;
11
+ occurredAt?: Date;
12
+ properties?: Record<string, string>;
13
+ }
14
+ /**
15
+ * Mock-friendly interface for the HubSpot Client methods the destination
16
+ * actually calls. Tests provide this via env.client instead of the real SDK.
17
+ */
18
+ interface HubSpotClientMock {
19
+ events: {
20
+ send: {
21
+ basicApi: {
22
+ send: (data: HubSpotEventRequest) => Promise<void>;
23
+ };
24
+ batchApi: {
25
+ send: (data: {
26
+ inputs: HubSpotEventRequest[];
27
+ }) => Promise<void>;
28
+ };
29
+ };
30
+ };
31
+ crm: {
32
+ contacts: {
33
+ basicApi: {
34
+ update: (id: string, data: {
35
+ properties: Record<string, string>;
36
+ }, idProperty?: string) => Promise<void>;
37
+ };
38
+ };
39
+ };
40
+ }
41
+ interface Settings {
42
+ /** HubSpot private app access token (required). */
43
+ accessToken: string;
44
+ /**
45
+ * Fully qualified event name prefix: pe{HubID}_
46
+ * Used to construct eventName from walkerOS event names.
47
+ * Example: 'pe12345678_'
48
+ */
49
+ eventNamePrefix: string;
50
+ /**
51
+ * walkerOS mapping value path to resolve contact email from events.
52
+ * Default: 'user.email'
53
+ */
54
+ email?: string;
55
+ /**
56
+ * walkerOS mapping value path to resolve HubSpot objectId from events.
57
+ * Default: undefined (use email for association)
58
+ */
59
+ objectId?: string;
60
+ /**
61
+ * Destination-level contact upsert mapping.
62
+ * Resolves to { email, properties } and upserts the contact on each push
63
+ * (with dedup via state hash).
64
+ */
65
+ identify?: Mapping.Value;
66
+ /**
67
+ * Static event properties added to every event occurrence.
68
+ * Useful for hs_touchpoint_source, hs_page_content_type, etc.
69
+ */
70
+ defaultProperties?: Record<string, string>;
71
+ /**
72
+ * Whether to use batch API for events (accumulate and flush).
73
+ * Default: false (single event sends).
74
+ */
75
+ batch?: boolean;
76
+ /**
77
+ * Batch size before auto-flush. Only used when batch: true.
78
+ * Default: 50. Max: 500.
79
+ */
80
+ batchSize?: number;
81
+ /** Runtime state -- not user-facing. Mutated by init/push. */
82
+ _client?: HubSpotClientMock;
83
+ _state?: RuntimeState;
84
+ _eventQueue?: HubSpotEventRequest[];
85
+ }
86
+ interface RuntimeState {
87
+ lastIdentity?: {
88
+ email?: string;
89
+ propertiesHash?: string;
90
+ };
91
+ }
92
+ /**
93
+ * Env -- optional SDK override. Production leaves this undefined and the
94
+ * destination creates a real Client instance. Tests provide a mock via
95
+ * env.client.
96
+ */
97
+ interface Env extends DestinationServer.Env {
98
+ client?: HubSpotClientMock;
99
+ }
100
+
101
+ declare const push: Env;
102
+ declare const simulation: string[];
103
+
104
+ declare const env_push: typeof push;
105
+ declare const env_simulation: typeof simulation;
106
+ declare namespace env {
107
+ export { env_push as push, env_simulation as simulation };
108
+ }
109
+
110
+ /**
111
+ * HubSpot SDK step examples.
112
+ *
113
+ * At push time, the destination invokes the `@hubspot/api-client` SDK. The
114
+ * public method paths users see on the client are:
115
+ *
116
+ * - `events.send.basicApi.send(eventRequest)` — fires an event
117
+ * - `events.send.batchApi.send({ inputs: [...] })` — flushes a batch
118
+ * - `crm.contacts.basicApi.update(id, data, idProperty)` — contact upsert
119
+ *
120
+ * Each `out` is therefore a list of tuples `[['method.path', ...args], ...]`
121
+ * matching the actual SDK call order. `identify` fires before the event.
122
+ * When the destination skips an event (`skip: true`, `ignore: true`, or
123
+ * missing identity), `out` is `[]`.
124
+ */
125
+ /**
126
+ * Extended step example that may carry destination-level settings overrides.
127
+ */
128
+ type HubSpotStepExample = Flow.StepExample & {
129
+ settings?: Partial<Settings>;
130
+ };
131
+ /**
132
+ * Default event forwarding -- events.send.basicApi.send() with auto-generated
133
+ * event name. Email resolved from default settings.email = 'user.email'.
134
+ */
135
+ declare const defaultEvent: HubSpotStepExample;
136
+ /**
137
+ * Mapped event name -- mapping.settings.eventName overrides the auto-generated
138
+ * name. The prefix is still prepended.
139
+ */
140
+ declare const mappedEventName: HubSpotStepExample;
141
+ /**
142
+ * Event with defaultProperties -- settings.defaultProperties are merged
143
+ * into every event. Per-event properties override defaults.
144
+ */
145
+ declare const defaultProperties: HubSpotStepExample;
146
+ /**
147
+ * Destination-level identify -- fires crm.contacts.basicApi.update() on
148
+ * first push when settings.identify mapping resolves. Then fires the event.
149
+ */
150
+ declare const destinationIdentify: HubSpotStepExample;
151
+ /**
152
+ * Per-event identify with skip -- user login fires contact upsert only,
153
+ * no custom event sent.
154
+ */
155
+ declare const userLoginIdentify: HubSpotStepExample;
156
+ /**
157
+ * objectId association -- use objectId instead of email for contact
158
+ * association on the event.
159
+ */
160
+ declare const objectIdAssociation: HubSpotStepExample;
161
+ /**
162
+ * No identity resolved -- event is skipped with a warning. Neither email
163
+ * nor objectId can be resolved from the event.
164
+ */
165
+ declare const noIdentity: HubSpotStepExample;
166
+ /**
167
+ * Wildcard ignore -- the event matches a mapping rule with ignore: true.
168
+ * The destination fires zero SDK calls.
169
+ */
170
+ declare const wildcardIgnored: HubSpotStepExample;
171
+
172
+ type step_HubSpotStepExample = HubSpotStepExample;
173
+ declare const step_defaultEvent: typeof defaultEvent;
174
+ declare const step_defaultProperties: typeof defaultProperties;
175
+ declare const step_destinationIdentify: typeof destinationIdentify;
176
+ declare const step_mappedEventName: typeof mappedEventName;
177
+ declare const step_noIdentity: typeof noIdentity;
178
+ declare const step_objectIdAssociation: typeof objectIdAssociation;
179
+ declare const step_userLoginIdentify: typeof userLoginIdentify;
180
+ declare const step_wildcardIgnored: typeof wildcardIgnored;
181
+ declare namespace step {
182
+ export { type step_HubSpotStepExample as HubSpotStepExample, step_defaultEvent as defaultEvent, step_defaultProperties as defaultProperties, step_destinationIdentify as destinationIdentify, step_mappedEventName as mappedEventName, step_noIdentity as noIdentity, step_objectIdAssociation as objectIdAssociation, step_userLoginIdentify as userLoginIdentify, step_wildcardIgnored as wildcardIgnored };
183
+ }
184
+
185
+ export { env, step };
@@ -0,0 +1,269 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/examples/index.ts
21
+ var examples_exports = {};
22
+ __export(examples_exports, {
23
+ env: () => env_exports,
24
+ step: () => step_exports
25
+ });
26
+ module.exports = __toCommonJS(examples_exports);
27
+
28
+ // src/examples/env.ts
29
+ var env_exports = {};
30
+ __export(env_exports, {
31
+ push: () => push,
32
+ simulation: () => simulation
33
+ });
34
+ var asyncNoop = () => Promise.resolve();
35
+ function createMockClient() {
36
+ return {
37
+ events: {
38
+ send: {
39
+ basicApi: { send: asyncNoop },
40
+ batchApi: { send: asyncNoop }
41
+ }
42
+ },
43
+ crm: {
44
+ contacts: {
45
+ basicApi: { update: asyncNoop }
46
+ }
47
+ }
48
+ };
49
+ }
50
+ var push = {
51
+ client: createMockClient()
52
+ };
53
+ var simulation = [
54
+ "call:events.send.basicApi.send",
55
+ "call:events.send.batchApi.send",
56
+ "call:crm.contacts.basicApi.update"
57
+ ];
58
+
59
+ // src/examples/step.ts
60
+ var step_exports = {};
61
+ __export(step_exports, {
62
+ defaultEvent: () => defaultEvent,
63
+ defaultProperties: () => defaultProperties,
64
+ destinationIdentify: () => destinationIdentify,
65
+ mappedEventName: () => mappedEventName,
66
+ noIdentity: () => noIdentity,
67
+ objectIdAssociation: () => objectIdAssociation,
68
+ userLoginIdentify: () => userLoginIdentify,
69
+ wildcardIgnored: () => wildcardIgnored
70
+ });
71
+ var import_core = require("@walkeros/core");
72
+ var defaultEvent = {
73
+ in: (0, import_core.getEvent)("product view", {
74
+ timestamp: 1700000100,
75
+ user: { email: "user@example.com" }
76
+ }),
77
+ out: [
78
+ [
79
+ "events.send.basicApi.send",
80
+ {
81
+ eventName: "pe12345678_product_view",
82
+ email: "user@example.com",
83
+ occurredAt: /* @__PURE__ */ new Date(1700000100),
84
+ properties: {}
85
+ }
86
+ ]
87
+ ]
88
+ };
89
+ var mappedEventName = {
90
+ in: (0, import_core.getEvent)("order complete", {
91
+ timestamp: 1700000101,
92
+ user: { email: "user@example.com" },
93
+ data: { total: 99.5, currency: "EUR", id: "ord-123" }
94
+ }),
95
+ mapping: {
96
+ name: "order complete",
97
+ settings: {
98
+ eventName: "purchase_completed",
99
+ properties: {
100
+ map: {
101
+ revenue: "data.total",
102
+ currency: "data.currency",
103
+ order_id: "data.id"
104
+ }
105
+ }
106
+ }
107
+ },
108
+ out: [
109
+ [
110
+ "events.send.basicApi.send",
111
+ {
112
+ eventName: "pe12345678_purchase_completed",
113
+ email: "user@example.com",
114
+ occurredAt: /* @__PURE__ */ new Date(1700000101),
115
+ properties: {
116
+ revenue: "99.5",
117
+ currency: "EUR",
118
+ order_id: "ord-123"
119
+ }
120
+ }
121
+ ]
122
+ ]
123
+ };
124
+ var defaultProperties = {
125
+ in: (0, import_core.getEvent)("page view", {
126
+ timestamp: 1700000102,
127
+ user: { email: "user@example.com" }
128
+ }),
129
+ settings: {
130
+ defaultProperties: {
131
+ hs_touchpoint_source: "walkerOS",
132
+ hs_page_content_type: "STANDARD_PAGE"
133
+ }
134
+ },
135
+ out: [
136
+ [
137
+ "events.send.basicApi.send",
138
+ {
139
+ eventName: "pe12345678_page_view",
140
+ email: "user@example.com",
141
+ occurredAt: /* @__PURE__ */ new Date(1700000102),
142
+ properties: {
143
+ hs_touchpoint_source: "walkerOS",
144
+ hs_page_content_type: "STANDARD_PAGE"
145
+ }
146
+ }
147
+ ]
148
+ ]
149
+ };
150
+ var destinationIdentify = {
151
+ in: (0, import_core.getEvent)("page view", {
152
+ timestamp: 1700000103,
153
+ user: { email: "user@example.com", firstName: "Jane", lastName: "Doe" }
154
+ }),
155
+ settings: {
156
+ identify: {
157
+ map: {
158
+ email: "user.email",
159
+ properties: {
160
+ map: {
161
+ firstname: "user.firstName",
162
+ lastname: "user.lastName"
163
+ }
164
+ }
165
+ }
166
+ }
167
+ },
168
+ out: [
169
+ [
170
+ "crm.contacts.basicApi.update",
171
+ "user@example.com",
172
+ { properties: { firstname: "Jane", lastname: "Doe" } },
173
+ "email"
174
+ ],
175
+ [
176
+ "events.send.basicApi.send",
177
+ {
178
+ eventName: "pe12345678_page_view",
179
+ email: "user@example.com",
180
+ occurredAt: /* @__PURE__ */ new Date(1700000103),
181
+ properties: {}
182
+ }
183
+ ]
184
+ ]
185
+ };
186
+ var userLoginIdentify = {
187
+ in: (0, import_core.getEvent)("user login", {
188
+ timestamp: 1700000104,
189
+ user: { email: "user@example.com" },
190
+ data: {
191
+ email: "login@acme.com",
192
+ first_name: "Jane",
193
+ last_name: "Doe",
194
+ lifecycle: "lead"
195
+ }
196
+ }),
197
+ mapping: {
198
+ skip: true,
199
+ settings: {
200
+ identify: {
201
+ map: {
202
+ email: "data.email",
203
+ properties: {
204
+ map: {
205
+ firstname: "data.first_name",
206
+ lastname: "data.last_name",
207
+ lifecyclestage: "data.lifecycle"
208
+ }
209
+ }
210
+ }
211
+ }
212
+ }
213
+ },
214
+ out: [
215
+ [
216
+ "crm.contacts.basicApi.update",
217
+ "login@acme.com",
218
+ {
219
+ properties: {
220
+ firstname: "Jane",
221
+ lastname: "Doe",
222
+ lifecyclestage: "lead"
223
+ }
224
+ },
225
+ "email"
226
+ ]
227
+ ]
228
+ };
229
+ var objectIdAssociation = {
230
+ in: (0, import_core.getEvent)("product view", {
231
+ timestamp: 1700000105,
232
+ user: { id: "hs-contact-789" }
233
+ }),
234
+ settings: {
235
+ email: void 0,
236
+ objectId: "user.id"
237
+ },
238
+ out: [
239
+ [
240
+ "events.send.basicApi.send",
241
+ {
242
+ eventName: "pe12345678_product_view",
243
+ objectId: "hs-contact-789",
244
+ occurredAt: /* @__PURE__ */ new Date(1700000105),
245
+ properties: {}
246
+ }
247
+ ]
248
+ ]
249
+ };
250
+ var noIdentity = {
251
+ in: (0, import_core.getEvent)("product view", {
252
+ timestamp: 1700000106,
253
+ user: {}
254
+ }),
255
+ out: []
256
+ };
257
+ var wildcardIgnored = {
258
+ in: (0, import_core.getEvent)("debug noise", {
259
+ timestamp: 1700000107,
260
+ user: { email: "user@example.com" }
261
+ }),
262
+ mapping: { ignore: true },
263
+ out: []
264
+ };
265
+ // Annotate the CommonJS export names for ESM import in node:
266
+ 0 && (module.exports = {
267
+ env,
268
+ step
269
+ });