@walkeros/server-destination-datamanager 0.3.1 → 0.4.1
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 +186 -41
- package/dist/dev.d.mts +235 -0
- package/dist/dev.d.ts +235 -0
- package/dist/dev.js +1 -0
- package/dist/dev.js.map +1 -0
- package/dist/dev.mjs +1 -0
- package/dist/dev.mjs.map +1 -0
- package/dist/examples/index.d.mts +104 -35
- package/dist/examples/index.d.ts +104 -35
- package/dist/examples/index.js +182 -88
- package/dist/examples/index.mjs +181 -88
- package/dist/index.d.mts +147 -138
- package/dist/index.d.ts +147 -138
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/schemas.d.mts +1 -1
- package/dist/schemas.d.ts +1 -1
- package/dist/schemas.js +1 -1
- package/dist/schemas.js.map +1 -1
- package/dist/schemas.mjs +1 -1
- package/dist/schemas.mjs.map +1 -1
- package/package.json +8 -7
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,28 @@
|
|
|
1
|
-
import { Destination as Destination$1, Mapping as Mapping$1
|
|
1
|
+
import { Destination as Destination$1, Mapping as Mapping$1 } from '@walkeros/core';
|
|
2
2
|
import { DestinationServer } from '@walkeros/server-core';
|
|
3
|
+
import { OAuth2Client } from 'google-auth-library';
|
|
3
4
|
|
|
4
5
|
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';
|
|
5
6
|
|
|
6
7
|
interface Settings {
|
|
7
|
-
/**
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Service account credentials (client_email + private_key)
|
|
10
|
+
* Recommended for serverless environments (AWS Lambda, Docker, etc.)
|
|
11
|
+
*/
|
|
12
|
+
credentials?: {
|
|
13
|
+
client_email: string;
|
|
14
|
+
private_key: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Path to service account JSON file
|
|
18
|
+
* For local development or environments with filesystem access
|
|
19
|
+
*/
|
|
20
|
+
keyFilename?: string;
|
|
21
|
+
/**
|
|
22
|
+
* OAuth scopes for Data Manager API
|
|
23
|
+
* @default ['https://www.googleapis.com/auth/datamanager']
|
|
24
|
+
*/
|
|
25
|
+
scopes?: string[];
|
|
9
26
|
/** Array of destination accounts and conversion actions/user lists */
|
|
10
27
|
destinations: Destination[];
|
|
11
28
|
/** Default event source if not specified per event */
|
|
@@ -45,8 +62,10 @@ interface Mapping {
|
|
|
45
62
|
}
|
|
46
63
|
interface Env extends DestinationServer.Env {
|
|
47
64
|
fetch?: typeof fetch;
|
|
65
|
+
authClient?: OAuth2Client | null;
|
|
48
66
|
}
|
|
49
|
-
type
|
|
67
|
+
type InitSettings = Partial<Settings>;
|
|
68
|
+
type Types = Destination$1.Types<Settings, Mapping, Env, InitSettings>;
|
|
50
69
|
interface DestinationInterface extends DestinationServer.Destination<Types> {
|
|
51
70
|
init: DestinationServer.InitFn<Types>;
|
|
52
71
|
}
|
|
@@ -64,21 +83,27 @@ type Rules = Mapping$1.Rules<Rule>;
|
|
|
64
83
|
* https://developers.google.com/data-manager/api/reference/rest/v1/Destination
|
|
65
84
|
*/
|
|
66
85
|
interface Destination {
|
|
67
|
-
/**
|
|
68
|
-
|
|
86
|
+
/** Reference identifier for this destination */
|
|
87
|
+
reference?: string;
|
|
88
|
+
/** Login account (account initiating the request) */
|
|
89
|
+
loginAccount?: ProductAccount;
|
|
90
|
+
/** Linked account (child account linked to login account) */
|
|
91
|
+
linkedAccount?: ProductAccount;
|
|
92
|
+
/** Operating account (account where data is sent) */
|
|
93
|
+
operatingAccount?: ProductAccount;
|
|
69
94
|
/** Product-specific destination ID (conversion action or user list) */
|
|
70
|
-
productDestinationId
|
|
95
|
+
productDestinationId?: string;
|
|
71
96
|
}
|
|
72
97
|
/**
|
|
73
|
-
*
|
|
98
|
+
* Product account information
|
|
74
99
|
*/
|
|
75
|
-
interface
|
|
100
|
+
interface ProductAccount {
|
|
76
101
|
/** Account ID (e.g., "123-456-7890" for Google Ads) */
|
|
77
102
|
accountId: string;
|
|
78
103
|
/** Type of account */
|
|
79
104
|
accountType: AccountType;
|
|
80
105
|
}
|
|
81
|
-
type AccountType = 'GOOGLE_ADS' | 'DISPLAY_VIDEO_ADVERTISER' | 'DISPLAY_VIDEO_PARTNER' | 'GOOGLE_ANALYTICS_PROPERTY';
|
|
106
|
+
type AccountType = 'ACCOUNT_TYPE_UNSPECIFIED' | 'GOOGLE_ADS' | 'DISPLAY_VIDEO_ADVERTISER' | 'DISPLAY_VIDEO_PARTNER' | 'GOOGLE_ANALYTICS_PROPERTY' | 'DATA_PARTNER';
|
|
82
107
|
type EventSource = 'WEB' | 'APP' | 'IN_STORE' | 'PHONE' | 'OTHER';
|
|
83
108
|
/**
|
|
84
109
|
* Consent for Digital Markets Act (DMA) compliance
|
|
@@ -96,12 +121,10 @@ type ConsentStatus = 'CONSENT_GRANTED' | 'CONSENT_DENIED';
|
|
|
96
121
|
* https://developers.google.com/data-manager/api/reference/rest/v1/events/ingest
|
|
97
122
|
*/
|
|
98
123
|
interface IngestEventsRequest {
|
|
99
|
-
/** OAuth 2.0 access token */
|
|
100
|
-
access_token?: string;
|
|
101
|
-
/** Array of events to ingest (max 2000) */
|
|
102
|
-
events: Event[];
|
|
103
124
|
/** Array of destinations for these events (max 10) */
|
|
104
125
|
destinations: Destination[];
|
|
126
|
+
/** Array of events to ingest (max 2000) */
|
|
127
|
+
events: Event[];
|
|
105
128
|
/** Request-level consent (overridden by event-level) */
|
|
106
129
|
consent?: Consent;
|
|
107
130
|
/** If true, validate without ingestion */
|
|
@@ -114,30 +137,85 @@ interface IngestEventsRequest {
|
|
|
114
137
|
* https://developers.google.com/data-manager/api/reference/rest/v1/Event
|
|
115
138
|
*/
|
|
116
139
|
interface Event {
|
|
117
|
-
/**
|
|
118
|
-
|
|
140
|
+
/** Destination references for routing */
|
|
141
|
+
destinationReferences?: string[];
|
|
119
142
|
/** Transaction ID for deduplication (max 512 chars) */
|
|
120
143
|
transactionId?: string;
|
|
121
|
-
/**
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
|
|
144
|
+
/** Event timestamp in RFC 3339 format */
|
|
145
|
+
eventTimestamp?: string;
|
|
146
|
+
/** Last updated timestamp in RFC 3339 format */
|
|
147
|
+
lastUpdatedTimestamp?: string;
|
|
125
148
|
/** User data with identifiers (max 10 identifiers) */
|
|
126
149
|
userData?: UserData;
|
|
150
|
+
/** Event-level consent (overrides request-level) */
|
|
151
|
+
consent?: Consent;
|
|
127
152
|
/** Attribution identifiers */
|
|
128
153
|
adIdentifiers?: AdIdentifiers;
|
|
129
|
-
/** Conversion value */
|
|
130
|
-
conversionValue?: number;
|
|
131
154
|
/** Currency code (ISO 4217, 3 chars) */
|
|
132
155
|
currency?: string;
|
|
156
|
+
/** Conversion value */
|
|
157
|
+
conversionValue?: number;
|
|
158
|
+
/** Source of the event */
|
|
159
|
+
eventSource?: EventSource;
|
|
160
|
+
/** Device information for the event */
|
|
161
|
+
eventDeviceInfo?: DeviceInfo;
|
|
133
162
|
/** Shopping cart data */
|
|
134
163
|
cartData?: CartData;
|
|
164
|
+
/** Custom variables for the event */
|
|
165
|
+
customVariables?: CustomVariable[];
|
|
166
|
+
/** Experimental fields (subject to change) */
|
|
167
|
+
experimentalFields?: ExperimentalField[];
|
|
168
|
+
/** User properties */
|
|
169
|
+
userProperties?: UserProperties;
|
|
135
170
|
/** Event name for GA4 (max 40 chars, required for GA4) */
|
|
136
171
|
eventName?: string;
|
|
137
|
-
/**
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
|
|
172
|
+
/** Google Analytics client ID (max 255 chars) */
|
|
173
|
+
clientId?: string;
|
|
174
|
+
/** First-party user ID (max 256 chars) */
|
|
175
|
+
userId?: string;
|
|
176
|
+
/** Additional event parameters */
|
|
177
|
+
additionalEventParameters?: EventParameter[];
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Device information
|
|
181
|
+
*/
|
|
182
|
+
interface DeviceInfo {
|
|
183
|
+
/** User agent string */
|
|
184
|
+
userAgent?: string;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Custom variable
|
|
188
|
+
*/
|
|
189
|
+
interface CustomVariable {
|
|
190
|
+
/** Variable name */
|
|
191
|
+
name?: string;
|
|
192
|
+
/** Variable value */
|
|
193
|
+
value?: string;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Experimental field
|
|
197
|
+
*/
|
|
198
|
+
interface ExperimentalField {
|
|
199
|
+
/** Field name */
|
|
200
|
+
name?: string;
|
|
201
|
+
/** Field value */
|
|
202
|
+
value?: string;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* User properties
|
|
206
|
+
*/
|
|
207
|
+
interface UserProperties {
|
|
208
|
+
/** Property values */
|
|
209
|
+
[key: string]: string | number | boolean | undefined;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Event parameter
|
|
213
|
+
*/
|
|
214
|
+
interface EventParameter {
|
|
215
|
+
/** Parameter name */
|
|
216
|
+
name?: string;
|
|
217
|
+
/** Parameter value */
|
|
218
|
+
value?: string | number;
|
|
141
219
|
}
|
|
142
220
|
/**
|
|
143
221
|
* User data with identifiers
|
|
@@ -176,14 +254,16 @@ interface Address {
|
|
|
176
254
|
* https://developers.google.com/data-manager/api/reference/rest/v1/AdIdentifiers
|
|
177
255
|
*/
|
|
178
256
|
interface AdIdentifiers {
|
|
257
|
+
/** Session attributes (privacy-safe attribution) */
|
|
258
|
+
sessionAttributes?: string;
|
|
179
259
|
/** Google Click ID (primary attribution) */
|
|
180
260
|
gclid?: string;
|
|
181
261
|
/** iOS attribution identifier (post-ATT) */
|
|
182
262
|
gbraid?: string;
|
|
183
263
|
/** Web-to-app attribution identifier */
|
|
184
264
|
wbraid?: string;
|
|
185
|
-
/**
|
|
186
|
-
|
|
265
|
+
/** Device information for landing page */
|
|
266
|
+
landingPageDeviceInfo?: DeviceInfo;
|
|
187
267
|
}
|
|
188
268
|
/**
|
|
189
269
|
* Shopping cart data
|
|
@@ -255,118 +335,47 @@ interface RequestError {
|
|
|
255
335
|
eventCount?: number;
|
|
256
336
|
}
|
|
257
337
|
|
|
258
|
-
type
|
|
259
|
-
type
|
|
260
|
-
type
|
|
261
|
-
type
|
|
262
|
-
type
|
|
263
|
-
type
|
|
264
|
-
type
|
|
265
|
-
type
|
|
266
|
-
type
|
|
267
|
-
type
|
|
268
|
-
type
|
|
269
|
-
type
|
|
270
|
-
type
|
|
271
|
-
type
|
|
272
|
-
type
|
|
273
|
-
type
|
|
274
|
-
type
|
|
275
|
-
type
|
|
276
|
-
type
|
|
277
|
-
type
|
|
278
|
-
type
|
|
279
|
-
type
|
|
280
|
-
type
|
|
281
|
-
type
|
|
282
|
-
type
|
|
283
|
-
type
|
|
284
|
-
type
|
|
285
|
-
type
|
|
286
|
-
type
|
|
287
|
-
type
|
|
288
|
-
type
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
*/
|
|
296
|
-
declare const Purchase: Rule;
|
|
297
|
-
/**
|
|
298
|
-
* Lead event mapping
|
|
299
|
-
*/
|
|
300
|
-
declare const Lead: Rule;
|
|
301
|
-
/**
|
|
302
|
-
* Page view mapping for GA4
|
|
303
|
-
*/
|
|
304
|
-
declare const PageView: Rule;
|
|
305
|
-
/**
|
|
306
|
-
* Complete mapping configuration
|
|
307
|
-
*/
|
|
308
|
-
declare const mapping: {
|
|
309
|
-
order: {
|
|
310
|
-
complete: Rule;
|
|
311
|
-
};
|
|
312
|
-
lead: {
|
|
313
|
-
submit: Rule;
|
|
314
|
-
};
|
|
315
|
-
page: {
|
|
316
|
-
view: Rule;
|
|
317
|
-
};
|
|
318
|
-
};
|
|
319
|
-
/**
|
|
320
|
-
* User data mapping configuration
|
|
321
|
-
* Maps walkerOS user properties to Data Manager user identifiers
|
|
322
|
-
*/
|
|
323
|
-
declare const userDataMapping: Config;
|
|
324
|
-
|
|
325
|
-
declare const mapping$1_Lead: typeof Lead;
|
|
326
|
-
declare const mapping$1_PageView: typeof PageView;
|
|
327
|
-
declare const mapping$1_Purchase: typeof Purchase;
|
|
328
|
-
declare const mapping$1_mapping: typeof mapping;
|
|
329
|
-
declare const mapping$1_userDataMapping: typeof userDataMapping;
|
|
330
|
-
declare namespace mapping$1 {
|
|
331
|
-
export { mapping$1_Lead as Lead, mapping$1_PageView as PageView, mapping$1_Purchase as Purchase, mapping$1_mapping as mapping, mapping$1_userDataMapping as userDataMapping };
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
* Minimal configuration for Google Data Manager
|
|
336
|
-
*/
|
|
337
|
-
declare const minimal: Config;
|
|
338
|
-
/**
|
|
339
|
-
* Complete configuration with all options
|
|
340
|
-
*/
|
|
341
|
-
declare const complete: Config;
|
|
342
|
-
/**
|
|
343
|
-
* GA4-specific configuration
|
|
344
|
-
*/
|
|
345
|
-
declare const ga4: Config;
|
|
346
|
-
/**
|
|
347
|
-
* Debug configuration with logging enabled
|
|
348
|
-
*/
|
|
349
|
-
declare const debug: Config;
|
|
350
|
-
|
|
351
|
-
declare const basic_complete: typeof complete;
|
|
352
|
-
declare const basic_debug: typeof debug;
|
|
353
|
-
declare const basic_ga4: typeof ga4;
|
|
354
|
-
declare const basic_minimal: typeof minimal;
|
|
355
|
-
declare namespace basic {
|
|
356
|
-
export { basic_complete as complete, basic_debug as debug, basic_ga4 as ga4, basic_minimal as minimal };
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
declare const index_basic: typeof basic;
|
|
338
|
+
type index_AccountType = AccountType;
|
|
339
|
+
type index_AdIdentifiers = AdIdentifiers;
|
|
340
|
+
type index_Address = Address;
|
|
341
|
+
type index_CartData = CartData;
|
|
342
|
+
type index_CartItem = CartItem;
|
|
343
|
+
type index_Config = Config;
|
|
344
|
+
type index_Consent = Consent;
|
|
345
|
+
type index_ConsentStatus = ConsentStatus;
|
|
346
|
+
type index_CustomVariable = CustomVariable;
|
|
347
|
+
type index_Destination = Destination;
|
|
348
|
+
type index_DestinationInterface = DestinationInterface;
|
|
349
|
+
type index_DeviceInfo = DeviceInfo;
|
|
350
|
+
type index_Env = Env;
|
|
351
|
+
type index_Event = Event;
|
|
352
|
+
type index_EventParameter = EventParameter;
|
|
353
|
+
type index_EventSource = EventSource;
|
|
354
|
+
type index_ExperimentalField = ExperimentalField;
|
|
355
|
+
type index_IngestEventsRequest = IngestEventsRequest;
|
|
356
|
+
type index_IngestEventsResponse = IngestEventsResponse;
|
|
357
|
+
type index_InitFn = InitFn;
|
|
358
|
+
type index_InitSettings = InitSettings;
|
|
359
|
+
type index_Mapping = Mapping;
|
|
360
|
+
type index_PartialConfig = PartialConfig;
|
|
361
|
+
type index_ProductAccount = ProductAccount;
|
|
362
|
+
type index_PushEvents = PushEvents;
|
|
363
|
+
type index_PushFn = PushFn;
|
|
364
|
+
type index_RequestError = RequestError;
|
|
365
|
+
type index_RequestState = RequestState;
|
|
366
|
+
type index_RequestStatusResponse = RequestStatusResponse;
|
|
367
|
+
type index_Rule = Rule;
|
|
368
|
+
type index_Rules = Rules;
|
|
369
|
+
type index_Settings = Settings;
|
|
370
|
+
type index_Types = Types;
|
|
371
|
+
type index_UserData = UserData;
|
|
372
|
+
type index_UserIdentifier = UserIdentifier;
|
|
373
|
+
type index_UserProperties = UserProperties;
|
|
374
|
+
type index_ValidationError = ValidationError;
|
|
360
375
|
declare namespace index {
|
|
361
|
-
export {
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
declare const schemas$1: Record<string, JSONSchema>;
|
|
365
|
-
|
|
366
|
-
declare namespace schemas {
|
|
367
|
-
export { schemas$1 as schemas };
|
|
376
|
+
export type { index_AccountType as AccountType, index_AdIdentifiers as AdIdentifiers, index_Address as Address, index_CartData as CartData, index_CartItem as CartItem, index_Config as Config, index_Consent as Consent, index_ConsentStatus as ConsentStatus, index_CustomVariable as CustomVariable, index_Destination as Destination, index_DestinationInterface as DestinationInterface, index_DeviceInfo as DeviceInfo, index_Env as Env, index_Event as Event, index_EventParameter as EventParameter, index_EventSource as EventSource, index_ExperimentalField as ExperimentalField, index_IngestEventsRequest as IngestEventsRequest, index_IngestEventsResponse as IngestEventsResponse, index_InitFn as InitFn, index_InitSettings as InitSettings, index_Mapping as Mapping, index_PartialConfig as PartialConfig, index_ProductAccount as ProductAccount, index_PushEvents as PushEvents, index_PushFn as PushFn, index_RequestError as RequestError, index_RequestState as RequestState, index_RequestStatusResponse as RequestStatusResponse, index_Rule as Rule, index_Rules as Rules, index_Settings as Settings, index_Types as Types, index_UserData as UserData, index_UserIdentifier as UserIdentifier, index_UserProperties as UserProperties, index_ValidationError as ValidationError };
|
|
368
377
|
}
|
|
369
378
|
|
|
370
379
|
declare const destinationDataManager: DestinationInterface;
|
|
371
380
|
|
|
372
|
-
export { index
|
|
381
|
+
export { index as DestinationDataManager, destinationDataManager as default, destinationDataManager };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,a=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,o=(e,n)=>{for(var a in n)t(e,a,{get:n[a],enumerable:!0})},s={};o(s,{DestinationDataManager:()=>b,default:()=>U,destinationDataManager:()=>W,examples:()=>f,schemas:()=>k}),module.exports=(e=s,((e,o,s,r)=>{if(o&&"object"==typeof o||"function"==typeof o)for(let c of a(o))i.call(e,c)||c===s||t(e,c,{get:()=>o[c],enumerable:!(r=n(o,c))||r.enumerable});return e})(t({},"__esModule",{value:!0}),e));var r=require("@walkeros/core");var c=require("@walkeros/core"),d=require("@walkeros/core"),l=require("@walkeros/core"),u=require("@walkeros/server-core");async function g(e,t="given"){if(!(0,l.isString)(e)||!e)return"";let n=e.trim().toLowerCase();if("given"===t){const e=["mr.","mrs.","ms.","miss.","dr.","prof."];for(const t of e)if(n.startsWith(t)){n=n.substring(t.length).trim();break}}if("family"===t){const e=["jr.","sr.","iii","ii","iv","v"];for(const t of e){const e=` ${t}`;if(n.endsWith(e)){n=n.substring(0,n.length-e.length).trim();break}if(n.endsWith(t)){n=n.substring(0,n.length-t.length).trim();break}}}return(0,u.getHashServer)(n)}async function p(e){const t=[];if((0,d.isString)(e.email)&&e.email){const n=await async function(e){if(!(0,l.isString)(e)||!e)return"";let t=e.trim().toLowerCase();if(t.endsWith("@gmail.com")||t.endsWith("@googlemail.com")){const[e,n]=t.split("@");t=`${e.replace(/\./g,"")}@${n}`}return(0,u.getHashServer)(t)}(e.email);n&&t.push({emailAddress:n})}if((0,d.isString)(e.phone)&&e.phone){const n=await async function(e){if(!(0,l.isString)(e)||!e)return"";let t=e.trim();const n=t.startsWith("+");return t=t.replace(/\D/g,""),t=n||t.length>10?`+${t}`:`+1${t}`,(0,u.getHashServer)(t)}(e.phone);n&&t.push({phoneNumber:n})}if(e.firstName||e.lastName||e.regionCode||e.postalCode){const n={};(0,d.isString)(e.firstName)&&e.firstName&&(n.givenName=await g(e.firstName,"given")),(0,d.isString)(e.lastName)&&e.lastName&&(n.familyName=await g(e.lastName,"family")),(0,d.isString)(e.regionCode)&&e.regionCode&&(n.regionCode=e.regionCode.toUpperCase()),(0,d.isString)(e.postalCode)&&e.postalCode&&(n.postalCode=e.postalCode),Object.keys(n).length>0&&t.push({address:n})}if(0!==t.length)return{userIdentifiers:t.slice(0,10)}}async function m(e,t){const n={eventTimestamp:(a=e.timestamp,new Date(a).toISOString())};var a;const i=t||{};(0,d.isString)(i.transactionId)&&i.transactionId&&(n.transactionId=i.transactionId.substring(0,512)),(0,d.isString)(i.clientId)&&i.clientId&&(n.clientId=i.clientId.substring(0,255)),(0,d.isString)(i.userId)&&i.userId&&(n.userId=i.userId.substring(0,256));const o=await p(i);o&&(n.userData=o);const s=function(e){const t={};return(0,d.isString)(e.gclid)&&e.gclid&&(t.gclid=e.gclid),(0,d.isString)(e.gbraid)&&e.gbraid&&(t.gbraid=e.gbraid),(0,d.isString)(e.wbraid)&&e.wbraid&&(t.wbraid=e.wbraid),(0,d.isString)(e.sessionAttributes)&&e.sessionAttributes&&(t.sessionAttributes=e.sessionAttributes),Object.keys(t).length>0?t:void 0}(i);s&&(n.adIdentifiers=s),"number"==typeof i.conversionValue&&(n.conversionValue=i.conversionValue),(0,d.isString)(i.currency)&&i.currency&&(n.currency=i.currency.substring(0,3).toUpperCase()),i.cartData&&"object"==typeof i.cartData&&(n.cartData=i.cartData),(0,d.isString)(i.eventName)&&i.eventName&&(n.eventName=i.eventName.substring(0,40)),(0,d.isString)(i.eventSource)&&i.eventSource&&(n.eventSource=i.eventSource);const r={};if("boolean"==typeof i.adUserData&&(r.adUserData=i.adUserData?"CONSENT_GRANTED":"CONSENT_DENIED"),"boolean"==typeof i.adPersonalization&&(r.adPersonalization=i.adPersonalization?"CONSENT_GRANTED":"CONSENT_DENIED"),0===Object.keys(r).length){const t=function(e){if(!e)return;const t={};return(0,d.isDefined)(e.marketing)&&(t.adUserData=e.marketing?"CONSENT_GRANTED":"CONSENT_DENIED"),(0,d.isDefined)(e.personalization)&&(t.adPersonalization=e.personalization?"CONSENT_GRANTED":"CONSENT_DENIED"),Object.keys(t).length>0?t:void 0}(e.consent);t&&(n.consent=t)}else n.consent=r;return n}var v=async function(e,{config:t,mapping:n,data:a,collector:i,env:o}){const{accessToken:s,destinations:r,eventSource:d,validateOnly:l=!1,url:u="https://datamanager.googleapis.com/v1",consent:g,testEventCode:p,logLevel:v="none",userData:b,userId:f,clientId:N,sessionAttributes:y,consentAdUserData:I,consentAdPersonalization:D}=t.settings,S=function(e="none"){const t={debug:0,info:1,warn:2,error:3,none:4}[e];return{debug:(e,n)=>{t<=0&&console.log(`[DataManager] ${e}`,n||"")},info:(e,n)=>{t<=1&&console.log(`[DataManager] ${e}`,n||"")},warn:(e,n)=>{t<=2&&console.warn(`[DataManager] ${e}`,n||"")},error:(e,n)=>{t<=3&&console.error(`[DataManager] ${e}`,n||"")}}}(v),h=b?await(0,c.getMappingValue)(e,{map:b}):{},O=f?await(0,c.getMappingValue)(e,f):void 0,E=N?await(0,c.getMappingValue)(e,N):void 0,A=y?await(0,c.getMappingValue)(e,y):void 0,w="boolean"==typeof I?I:"string"==typeof I&&e.consent?e.consent[I]:void 0,T="boolean"==typeof D?D:"string"==typeof D&&e.consent?e.consent[D]:void 0,z={};(0,c.isObject)(h)&&Object.assign(z,h),void 0!==O&&(z.userId=O),void 0!==E&&(z.clientId=E),void 0!==A&&(z.sessionAttributes=A),void 0!==w&&(z.adUserData=w),void 0!==T&&(z.adPersonalization=T);const k=t.data?await(0,c.getMappingValue)(e,t.data):{},C=(0,c.isObject)(a)?a:{},P={...z,...(0,c.isObject)(k)?k:{},...C},_=await m(e,P);S.debug("Processing event",{name:e.name,id:e.id,timestamp:e.timestamp}),!_.eventSource&&d&&(_.eventSource=d),!_.consent&&g&&(_.consent=g);const x={events:[_],destinations:r};g&&(x.consent=g),l&&(x.validateOnly=!0),p&&(x.testEventCode=p);const G=(null==o?void 0:o.fetch)||fetch,R=`${u}/events:ingest`;S.debug("Sending to Data Manager API",{endpoint:R,eventCount:x.events.length,destinations:r.length,validateOnly:l});const j=await G(R,{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},body:JSON.stringify(x)});if(!j.ok){const e=await j.text();throw S.error("API request failed",{status:j.status,error:e}),new Error(`Data Manager API error (${j.status}): ${e}`)}const L=await j.json();if(S.debug("API response",{status:j.status,requestId:L.requestId}),L.validationErrors&&L.validationErrors.length>0)throw S.error("Validation errors",{errors:L.validationErrors}),new Error(`Validation errors: ${JSON.stringify(L.validationErrors)}`);S.info("Event processed successfully",{requestId:L.requestId})},b={},f={};o(f,{basic:()=>E,mapping:()=>N});var N={};o(N,{Lead:()=>D,PageView:()=>S,Purchase:()=>I,mapping:()=>h,userDataMapping:()=>O});var y=require("@walkeros/core"),I={name:"purchase",data:{map:{transactionId:"data.id",conversionValue:"data.total",currency:{key:"data.currency",value:"USD"},eventName:{value:"purchase"},userId:"user.id",email:"user.id",gclid:"context.gclid",gbraid:"context.gbraid",wbraid:"context.wbraid",cartData:{map:{items:{loop:["nested",{condition:e=>(0,y.isObject)(e)&&"product"===e.entity,map:{merchantProductId:"data.id",price:"data.price",quantity:{key:"data.quantity",value:1}}}]}}}}}},D={name:"generate_lead",data:{map:{eventName:{value:"generate_lead"},conversionValue:{value:10},currency:{value:"USD"}}}},S={name:"page_view",data:{map:{eventName:{value:"page_view"}}}},h={order:{complete:I},lead:{submit:D},page:{view:S}},O={settings:{accessToken:"ya29.c.xxx",destinations:[{operatingAccount:{accountId:"123-456-7890",accountType:"GOOGLE_ADS"},productDestinationId:"AW-CONVERSION-123"}]},data:{map:{email:"user.id",phone:"data.phone",firstName:"data.firstName",lastName:"data.lastName",regionCode:"data.country",postalCode:"data.zip"}},mapping:h},E={};o(E,{complete:()=>w,debug:()=>z,ga4:()=>T,minimal:()=>A});var A={settings:{accessToken:"ya29.c.xxx",destinations:[{operatingAccount:{accountId:"123-456-7890",accountType:"GOOGLE_ADS"},productDestinationId:"AW-CONVERSION-123"}]}},w={settings:{accessToken:"ya29.c.xxx",destinations:[{operatingAccount:{accountId:"123-456-7890",accountType:"GOOGLE_ADS"},productDestinationId:"AW-CONVERSION-123"},{operatingAccount:{accountId:"987654321",accountType:"GOOGLE_ANALYTICS_PROPERTY"},productDestinationId:"G-XXXXXXXXXX"}],eventSource:"WEB",batchSize:100,batchInterval:5e3,validateOnly:!1,consent:{adUserData:"CONSENT_GRANTED",adPersonalization:"CONSENT_GRANTED"},userData:{email:"user.id",phone:"data.phone",firstName:"data.firstName",lastName:"data.lastName"},userId:"user.id",clientId:"user.device",sessionAttributes:"context.sessionAttributes"},data:{map:{eventSource:{value:"WEB"}}}},T={settings:{accessToken:"ya29.c.xxx",destinations:[{operatingAccount:{accountId:"123456789",accountType:"GOOGLE_ANALYTICS_PROPERTY"},productDestinationId:"G-XXXXXXXXXX"}],eventSource:"WEB"}},z={settings:{accessToken:"ya29.c.xxx",destinations:[{operatingAccount:{accountId:"123-456-7890",accountType:"GOOGLE_ADS"},productDestinationId:"AW-CONVERSION-123"}],logLevel:"debug"}},k={};o(k,{schemas:()=>M});var C=require("@walkeros/core"),P=C.z.enum(["GOOGLE_ADS","DISPLAY_VIDEO_ADVERTISER","DISPLAY_VIDEO_PARTNER","GOOGLE_ANALYTICS_PROPERTY"]),_=C.z.enum(["WEB","APP","IN_STORE","PHONE","OTHER"]),x=C.z.enum(["CONSENT_GRANTED","CONSENT_DENIED"]),G=C.z.object({adUserData:x.describe("Consent for data collection and use").optional(),adPersonalization:x.describe("Consent for ad personalization").optional()}),R=C.z.object({accountId:C.z.string().min(1).describe('Account ID (e.g., "123-456-7890" for Google Ads)'),accountType:P.describe("Type of account")}),j=C.z.object({operatingAccount:R.describe("Operating account details"),productDestinationId:C.z.string().min(1).describe("Product-specific destination ID (conversion action or user list)")}),L=require("@walkeros/core"),V=L.z.object({accessToken:L.z.string().min(1).describe("OAuth 2.0 access token with datamanager scope (like ya29.c.xxx)"),destinations:L.z.array(j).min(1).max(10).describe("Array of destination accounts and conversion actions/user lists (max 10)"),eventSource:_.describe("Default event source if not specified per event (like WEB)").optional(),batchSize:L.z.number().int().min(1).max(2e3).describe("Maximum number of events to batch before sending (max 2000, like 100)").optional(),batchInterval:L.z.number().int().min(0).describe("Time in milliseconds to wait before auto-flushing batch (like 5000)").optional(),validateOnly:L.z.boolean().describe("If true, validate request without ingestion (testing mode)").optional(),url:L.z.string().url().describe("Override API endpoint for testing (like https://datamanager.googleapis.com/v1)").optional(),consent:G.describe("Request-level consent for all events").optional(),testEventCode:L.z.string().describe("Test event code for debugging (like TEST12345)").optional(),logLevel:L.z.enum(["debug","info","warn","error","none"]).describe("Log level for debugging (debug shows all API calls)").optional(),userData:L.z.record(L.z.string(),L.z.unknown()).describe("Guided helper: User data mapping for all events (like { email: 'user.id', phone: 'data.phone' })").optional(),userId:L.z.any().describe("Guided helper: First-party user ID for all events (like 'user.id')").optional(),clientId:L.z.any().describe("Guided helper: GA4 client ID for all events (like 'user.device')").optional(),sessionAttributes:L.z.any().describe("Guided helper: Privacy-safe attribution for all events (like 'context.sessionAttributes')").optional(),consentAdUserData:L.z.union([L.z.string(),L.z.boolean()]).describe("Consent mapping: Field name from event.consent (like 'marketing') or static boolean value").optional(),consentAdPersonalization:L.z.union([L.z.string(),L.z.boolean()]).describe("Consent mapping: Field name from event.consent (like 'targeting') or static boolean value").optional()}),X=require("@walkeros/core").z.object({}),q=require("@walkeros/core"),M={settings:(0,q.zodToSchema)(V),mapping:(0,q.zodToSchema)(X)},W={type:"datamanager",config:{},async init({config:e}){const t=function(e={}){const t=e.settings||{},{accessToken:n,destinations:a}=t;n||(0,r.throwError)("Config settings accessToken missing"),a&&0!==a.length||(0,r.throwError)("Config settings destinations missing or empty");const i={...t,accessToken:n,destinations:a};return{...e,settings:i}}(e);return t},push:async(e,{config:t,mapping:n,data:a,collector:i,env:o})=>await v(e,{config:t,mapping:n,data:a,collector:i,env:o})},U=W;//# sourceMappingURL=index.js.map
|
|
1
|
+
"use strict";var e,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,a={};((e,n)=>{for(var r in n)t(e,r,{get:n[r],enumerable:!0})})(a,{DestinationDataManager:()=>w,default:()=>y,destinationDataManager:()=>b}),module.exports=(e=a,((e,a,s,o)=>{if(a&&"object"==typeof a||"function"==typeof a)for(let c of r(a))i.call(e,c)||c===s||t(e,c,{get:()=>a[c],enumerable:!(o=n(a,c))||o.enumerable});return e})(t({},"__esModule",{value:!0}),e));var s=require("@walkeros/core");var o=require("@walkeros/core"),c=require("@walkeros/core"),l=require("@walkeros/core"),g=require("@walkeros/server-core");async function d(e,t="given"){if(!(0,l.isString)(e)||!e)return"";let n=e.trim().toLowerCase();if("given"===t){const e=["mr.","mrs.","ms.","miss.","dr.","prof."];for(const t of e)if(n.startsWith(t)){n=n.substring(t.length).trim();break}}if("family"===t){const e=["jr.","sr.","iii","ii","iv","v"];for(const t of e){const e=` ${t}`;if(n.endsWith(e)){n=n.substring(0,n.length-e.length).trim();break}if(n.endsWith(t)){n=n.substring(0,n.length-t.length).trim();break}}}return(0,g.getHashServer)(n)}async function u(e){const t=[];if((0,c.isString)(e.email)&&e.email){const n=await async function(e){if(!(0,l.isString)(e)||!e)return"";let t=e.trim().toLowerCase();if(t.endsWith("@gmail.com")||t.endsWith("@googlemail.com")){const[e,n]=t.split("@");t=`${e.replace(/\./g,"")}@${n}`}return(0,g.getHashServer)(t)}(e.email);n&&t.push({emailAddress:n})}if((0,c.isString)(e.phone)&&e.phone){const n=await async function(e){if(!(0,l.isString)(e)||!e)return"";let t=e.trim();const n=t.startsWith("+");return t=t.replace(/\D/g,""),t=n||t.length>10?`+${t}`:`+1${t}`,(0,g.getHashServer)(t)}(e.phone);n&&t.push({phoneNumber:n})}if(e.firstName||e.lastName||e.regionCode||e.postalCode){const n={};(0,c.isString)(e.firstName)&&e.firstName&&(n.givenName=await d(e.firstName,"given")),(0,c.isString)(e.lastName)&&e.lastName&&(n.familyName=await d(e.lastName,"family")),(0,c.isString)(e.regionCode)&&e.regionCode&&(n.regionCode=e.regionCode.toUpperCase()),(0,c.isString)(e.postalCode)&&e.postalCode&&(n.postalCode=e.postalCode),Object.keys(n).length>0&&t.push({address:n})}if(0!==t.length)return{userIdentifiers:t.slice(0,10)}}async function f(e,t){const n={eventTimestamp:(r=e.timestamp,new Date(r).toISOString())};var r;const i=t||{};(0,c.isString)(i.transactionId)&&i.transactionId&&(n.transactionId=i.transactionId.substring(0,512)),(0,c.isString)(i.clientId)&&i.clientId&&(n.clientId=i.clientId.substring(0,255)),(0,c.isString)(i.userId)&&i.userId&&(n.userId=i.userId.substring(0,256));const a=await u(i);a&&(n.userData=a);const s=function(e){const t={};return(0,c.isString)(e.gclid)&&e.gclid&&(t.gclid=e.gclid),(0,c.isString)(e.gbraid)&&e.gbraid&&(t.gbraid=e.gbraid),(0,c.isString)(e.wbraid)&&e.wbraid&&(t.wbraid=e.wbraid),(0,c.isString)(e.sessionAttributes)&&e.sessionAttributes&&(t.sessionAttributes=e.sessionAttributes),Object.keys(t).length>0?t:void 0}(i);s&&(n.adIdentifiers=s),"number"==typeof i.conversionValue&&(n.conversionValue=i.conversionValue),(0,c.isString)(i.currency)&&i.currency&&(n.currency=i.currency.substring(0,3).toUpperCase()),i.cartData&&"object"==typeof i.cartData&&(n.cartData=i.cartData),(0,c.isString)(i.eventName)&&i.eventName&&(n.eventName=i.eventName.substring(0,40)),(0,c.isString)(i.eventSource)&&i.eventSource&&(n.eventSource=i.eventSource);const o={};if("boolean"==typeof i.adUserData&&(o.adUserData=i.adUserData?"CONSENT_GRANTED":"CONSENT_DENIED"),"boolean"==typeof i.adPersonalization&&(o.adPersonalization=i.adPersonalization?"CONSENT_GRANTED":"CONSENT_DENIED"),0===Object.keys(o).length){const t=function(e){if(!e)return;const t={};return(0,c.isDefined)(e.marketing)&&(t.adUserData=e.marketing?"CONSENT_GRANTED":"CONSENT_DENIED"),(0,c.isDefined)(e.personalization)&&(t.adPersonalization=e.personalization?"CONSENT_GRANTED":"CONSENT_DENIED"),Object.keys(t).length>0?t:void 0}(e.consent);t&&(n.consent=t)}else n.consent=o;return n}var p=require("google-auth-library"),h=["https://www.googleapis.com/auth/datamanager"],m=class extends Error{constructor(e,t){super(e),this.cause=t,this.name="DataManagerAuthError"}};var v=async function(e,{config:t,mapping:n,data:r,collector:i,env:a}){const{destinations:s,eventSource:c,validateOnly:l=!1,url:g="https://datamanager.googleapis.com/v1",consent:d,testEventCode:u,logLevel:p="none",userData:h,userId:v,clientId:w,sessionAttributes:b,consentAdUserData:y,consentAdPersonalization:S}=t.settings,E=function(e="none"){const t={debug:0,info:1,warn:2,error:3,none:4}[e];return{debug:(e,n)=>{t<=0&&console.log(`[DataManager] ${e}`,n||"")},info:(e,n)=>{t<=1&&console.log(`[DataManager] ${e}`,n||"")},warn:(e,n)=>{t<=2&&console.warn(`[DataManager] ${e}`,n||"")},error:(e,n)=>{t<=3&&console.error(`[DataManager] ${e}`,n||"")}}}(p),N=h?await(0,o.getMappingValue)(e,{map:h}):{},D=v?await(0,o.getMappingValue)(e,v):void 0,C=w?await(0,o.getMappingValue)(e,w):void 0,I=b?await(0,o.getMappingValue)(e,b):void 0,O="boolean"==typeof y?y:"string"==typeof y&&e.consent?e.consent[y]:void 0,A="boolean"==typeof S?S:"string"==typeof S&&e.consent?e.consent[S]:void 0,k={};(0,o.isObject)(N)&&Object.assign(k,N),void 0!==D&&(k.userId=D),void 0!==C&&(k.clientId=C),void 0!==I&&(k.sessionAttributes=I),void 0!==O&&(k.adUserData=O),void 0!==A&&(k.adPersonalization=A);const P=t.data?await(0,o.getMappingValue)(e,t.data):{},T=(0,o.isObject)(r)?r:{},j={...k,...(0,o.isObject)(P)?P:{},...T},M=await f(e,j);if(E.debug("Processing event",{name:e.name,id:e.id,timestamp:e.timestamp}),!M.eventSource&&c&&(M.eventSource=c),!M.consent&&d&&(M.consent=d),!s||0===s.length)throw new Error("Destinations are required");const $={events:[M],destinations:s};d&&($.consent=d),l&&($.validateOnly=!0),u&&($.testEventCode=u);const q=null==a?void 0:a.authClient;if(!q)throw new Error("Auth client not initialized. Ensure init() was called successfully.");let _;try{_=await async function(e){try{const t=await e.getAccessToken();if(!t.token)throw new m("Auth client returned empty token");return t.token}catch(e){throw new m("Failed to obtain access token",e instanceof Error?e:void 0)}}(q)}catch(e){throw E.error("Authentication failed",{error:e}),e}const z=(null==a?void 0:a.fetch)||fetch,V=`${g}/events:ingest`;E.debug("Sending to Data Manager API",{endpoint:V,eventCount:$.events.length,destinations:s.length,validateOnly:l});const G=await z(V,{method:"POST",headers:{Authorization:`Bearer ${_}`,"Content-Type":"application/json"},body:JSON.stringify($)});if(!G.ok){const e=await G.text();throw E.error("API request failed",{status:G.status,error:e}),new Error(`Data Manager API error (${G.status}): ${e}`)}const U=await G.json();if(E.debug("API response",{status:G.status,requestId:U.requestId}),U.validationErrors&&U.validationErrors.length>0)throw E.error("Validation errors",{errors:U.validationErrors}),new Error(`Validation errors: ${JSON.stringify(U.validationErrors)}`);E.info("Event processed successfully",{requestId:U.requestId})},w={},b={type:"datamanager",config:{},async init({config:e,env:t}){const n=function(e={}){const t=e.settings||{},{destinations:n}=t;n&&0!==n.length||(0,s.throwError)("Config settings destinations missing or empty");const r={...t,destinations:n};return{...e,settings:r}}(e);if(!n.settings)throw new Error("Settings required for Data Manager destination");if(!n.settings.destinations||0===n.settings.destinations.length)throw new Error("At least one destination required in settings");try{const e=await async function(e){const{credentials:t,keyFilename:n,scopes:r=h}=e;try{if(t){const e=new p.GoogleAuth({credentials:t,scopes:r});return await e.getClient()}if(n){const e=new p.GoogleAuth({keyFilename:n,scopes:r});return await e.getClient()}const e=new p.GoogleAuth({scopes:r});return await e.getClient()}catch(e){throw new m("Failed to create auth client. Check credentials configuration or ensure GOOGLE_APPLICATION_CREDENTIALS is set.",e instanceof Error?e:void 0)}}(n.settings);return{...n,env:{...t,authClient:e}}}catch(e){throw new Error(`Data Manager authentication failed: ${e instanceof Error?e.message:"Unknown error"}`)}},push:async(e,{config:t,mapping:n,data:r,collector:i,env:a})=>await v(e,{config:t,mapping:n,data:r,collector:i,env:a})},y=b;//# sourceMappingURL=index.js.map
|