@walkeros/server-destination-mparticle 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,240 @@
1
+ import { Mapping as Mapping$1, Destination as Destination$1 } from '@walkeros/core';
2
+ import { DestinationServer, sendServer } from '@walkeros/server-core';
3
+
4
+ /**
5
+ * mParticle data pod. Determines the regional endpoint used for the Events
6
+ * API. Defaults to `us1`. See {@link buildEndpoint} in `batch.ts`.
7
+ */
8
+ type Pod = 'us1' | 'us2' | 'eu1' | 'au1';
9
+ /**
10
+ * mParticle environment for the batch. `production` routes to production
11
+ * data streams; `development` sends to debug/verify streams.
12
+ */
13
+ type Environment = 'production' | 'development';
14
+ /**
15
+ * Event type used for the outgoing mParticle event. Defaults to
16
+ * `custom_event` when not explicitly mapped via rule settings.
17
+ */
18
+ type EventType = 'custom_event' | 'screen_view' | 'commerce_event';
19
+ /**
20
+ * mParticle custom event type (category) for `custom_event`s. Defaults to
21
+ * `other` when not specified.
22
+ */
23
+ type CustomEventType = 'navigation' | 'location' | 'search' | 'transaction' | 'user_content' | 'user_preference' | 'social' | 'media' | 'attribution' | 'other';
24
+ /**
25
+ * mParticle product action verbs for commerce events.
26
+ */
27
+ type ProductActionType = 'add_to_cart' | 'remove_from_cart' | 'checkout' | 'checkout_option' | 'click' | 'view_detail' | 'purchase' | 'refund' | 'add_to_wishlist' | 'remove_from_wishlist';
28
+ interface Settings {
29
+ /** mParticle input feed API key. */
30
+ apiKey: string;
31
+ /** mParticle input feed API secret. */
32
+ apiSecret: string;
33
+ /** Data pod selecting the regional endpoint. Default: `us1`. */
34
+ pod?: Pod;
35
+ /** Environment the batch targets. Default: `production`. */
36
+ environment?: Environment;
37
+ /**
38
+ * Mapping that resolves to `user_identities` per batch. Each entry value
39
+ * is a walkerOS mapping value; the resolved object is placed into the
40
+ * mParticle batch `user_identities` envelope.
41
+ */
42
+ userIdentities?: Mapping$1.Map;
43
+ /**
44
+ * Mapping that resolves to `user_attributes` per batch.
45
+ */
46
+ userAttributes?: Mapping$1.Value;
47
+ /**
48
+ * Optional static consent state passthrough — shape is forwarded verbatim
49
+ * to `consent_state` on the batch.
50
+ */
51
+ consent?: ConsentState;
52
+ /** walkerOS mapping value resolving to the client IP for the batch. */
53
+ ip?: Mapping$1.Value;
54
+ /**
55
+ * Optional request correlation id. When omitted, falls back to `event.id`.
56
+ */
57
+ sourceRequestId?: Mapping$1.Value;
58
+ }
59
+ type InitSettings = Partial<Settings>;
60
+ /**
61
+ * Per-rule mapping settings. Determines which mParticle event shape is
62
+ * produced for this walkerOS event and allows per-event identity overrides.
63
+ */
64
+ interface Mapping {
65
+ /** Event type. Default: `custom_event`. */
66
+ eventType?: EventType;
67
+ /** Custom event type category for `custom_event`. Default: `other`. */
68
+ customEventType?: CustomEventType;
69
+ /** Commerce mapping resolving to ProductAction and related fields. */
70
+ commerce?: Mapping$1.Value;
71
+ /** Per-event override for `user_identities`. Merged over settings. */
72
+ userIdentities?: Mapping$1.Map;
73
+ /** Per-event override for `user_attributes`. */
74
+ userAttributes?: Mapping$1.Value;
75
+ }
76
+ interface Env extends DestinationServer.Env {
77
+ sendServer?: typeof sendServer;
78
+ }
79
+ type Types = Destination$1.Types<Settings, Mapping, Env, InitSettings>;
80
+ interface Destination extends DestinationServer.Destination<Types> {
81
+ init: DestinationServer.InitFn<Types>;
82
+ }
83
+ type Config = {
84
+ settings: Settings;
85
+ } & DestinationServer.Config<Types>;
86
+ type InitFn = DestinationServer.InitFn<Types>;
87
+ type PushFn = DestinationServer.PushFn<Types>;
88
+ type PartialConfig = DestinationServer.PartialConfig<Types>;
89
+ type PushEvents = DestinationServer.PushEvents<Mapping>;
90
+ type Rule = Mapping$1.Rule<Mapping>;
91
+ type Rules = Mapping$1.Rules<Rule>;
92
+ /**
93
+ * Top-level mParticle batch payload posted to
94
+ * `https://s2s.{pod}.mparticle.com/v2/events`.
95
+ * https://docs.mparticle.com/developers/server/http/
96
+ */
97
+ interface MParticleBatch {
98
+ events: MParticleEvent[];
99
+ user_identities?: Record<string, string | number>;
100
+ user_attributes?: Record<string, unknown>;
101
+ environment: Environment;
102
+ schema_version?: number;
103
+ ip?: string;
104
+ source_request_id?: string;
105
+ consent_state?: ConsentState;
106
+ context?: Record<string, unknown>;
107
+ }
108
+ type MParticleEvent = {
109
+ event_type: 'custom_event';
110
+ data: CustomEventData;
111
+ } | {
112
+ event_type: 'screen_view';
113
+ data: ScreenViewEventData;
114
+ } | {
115
+ event_type: 'commerce_event';
116
+ data: CommerceEventData;
117
+ };
118
+ interface CommonEventData {
119
+ timestamp_unixtime_ms?: number;
120
+ source_message_id?: string;
121
+ session_uuid?: string;
122
+ custom_attributes?: Record<string, unknown>;
123
+ custom_flags?: Record<string, unknown>;
124
+ location?: Record<string, unknown>;
125
+ }
126
+ interface CustomEventData extends CommonEventData {
127
+ event_name: string;
128
+ custom_event_type: CustomEventType;
129
+ }
130
+ interface ScreenViewEventData extends CommonEventData {
131
+ screen_name?: string;
132
+ }
133
+ interface CommerceEventData extends CommonEventData {
134
+ product_action?: ProductAction;
135
+ promotion_action?: PromotionAction;
136
+ product_impressions?: ProductImpression[];
137
+ currency_code?: string;
138
+ is_non_interactive?: boolean;
139
+ }
140
+ interface ProductAction {
141
+ action: ProductActionType;
142
+ transaction_id?: string;
143
+ total_amount?: number;
144
+ tax_amount?: number;
145
+ shipping_amount?: number;
146
+ coupon_code?: string;
147
+ affiliation?: string;
148
+ checkout_step?: number;
149
+ checkout_options?: string;
150
+ products?: Product[];
151
+ }
152
+ interface Product {
153
+ id?: string;
154
+ name?: string;
155
+ brand?: string;
156
+ category?: string;
157
+ variant?: string;
158
+ position?: number;
159
+ price?: number;
160
+ quantity?: number;
161
+ coupon_code?: string;
162
+ total_product_amount?: number;
163
+ custom_attributes?: Record<string, unknown>;
164
+ }
165
+ interface PromotionAction {
166
+ action: 'view' | 'click';
167
+ promotions?: Array<{
168
+ id?: string;
169
+ name?: string;
170
+ creative?: string;
171
+ position?: string;
172
+ }>;
173
+ }
174
+ interface ProductImpression {
175
+ product_impression_list?: string;
176
+ products?: Product[];
177
+ }
178
+ /**
179
+ * mParticle consent state envelope forwarded verbatim on the batch.
180
+ * https://docs.mparticle.com/developers/server/http/#consent-state
181
+ */
182
+ interface ConsentState {
183
+ gdpr?: Record<string, GDPRConsentState>;
184
+ ccpa?: {
185
+ data_sale_opt_out?: CCPAConsentState;
186
+ };
187
+ }
188
+ interface GDPRConsentState {
189
+ consented: boolean;
190
+ document?: string;
191
+ timestamp_unixtime_ms?: number;
192
+ location?: string;
193
+ hardware_id?: string;
194
+ }
195
+ interface CCPAConsentState {
196
+ consented: boolean;
197
+ document?: string;
198
+ timestamp_unixtime_ms?: number;
199
+ location?: string;
200
+ hardware_id?: string;
201
+ }
202
+
203
+ type index_CCPAConsentState = CCPAConsentState;
204
+ type index_CommerceEventData = CommerceEventData;
205
+ type index_CommonEventData = CommonEventData;
206
+ type index_Config = Config;
207
+ type index_ConsentState = ConsentState;
208
+ type index_CustomEventData = CustomEventData;
209
+ type index_CustomEventType = CustomEventType;
210
+ type index_Destination = Destination;
211
+ type index_Env = Env;
212
+ type index_Environment = Environment;
213
+ type index_EventType = EventType;
214
+ type index_GDPRConsentState = GDPRConsentState;
215
+ type index_InitFn = InitFn;
216
+ type index_InitSettings = InitSettings;
217
+ type index_MParticleBatch = MParticleBatch;
218
+ type index_MParticleEvent = MParticleEvent;
219
+ type index_Mapping = Mapping;
220
+ type index_PartialConfig = PartialConfig;
221
+ type index_Pod = Pod;
222
+ type index_Product = Product;
223
+ type index_ProductAction = ProductAction;
224
+ type index_ProductActionType = ProductActionType;
225
+ type index_ProductImpression = ProductImpression;
226
+ type index_PromotionAction = PromotionAction;
227
+ type index_PushEvents = PushEvents;
228
+ type index_PushFn = PushFn;
229
+ type index_Rule = Rule;
230
+ type index_Rules = Rules;
231
+ type index_ScreenViewEventData = ScreenViewEventData;
232
+ type index_Settings = Settings;
233
+ type index_Types = Types;
234
+ declare namespace index {
235
+ export type { index_CCPAConsentState as CCPAConsentState, index_CommerceEventData as CommerceEventData, index_CommonEventData as CommonEventData, index_Config as Config, index_ConsentState as ConsentState, index_CustomEventData as CustomEventData, index_CustomEventType as CustomEventType, index_Destination as Destination, index_Env as Env, index_Environment as Environment, index_EventType as EventType, index_GDPRConsentState as GDPRConsentState, index_InitFn as InitFn, index_InitSettings as InitSettings, index_MParticleBatch as MParticleBatch, index_MParticleEvent as MParticleEvent, index_Mapping as Mapping, index_PartialConfig as PartialConfig, index_Pod as Pod, index_Product as Product, index_ProductAction as ProductAction, index_ProductActionType as ProductActionType, index_ProductImpression as ProductImpression, index_PromotionAction as PromotionAction, index_PushEvents as PushEvents, index_PushFn as PushFn, index_Rule as Rule, index_Rules as Rules, index_ScreenViewEventData as ScreenViewEventData, index_Settings as Settings, index_Types as Types };
236
+ }
237
+
238
+ declare const destinationMParticle: Destination;
239
+
240
+ export { index as DestinationMParticle, destinationMParticle as default, destinationMParticle };
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";var e,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,o={};((e,n)=>{for(var i in n)t(e,i,{get:n[i],enumerable:!0})})(o,{DestinationMParticle:()=>m,default:()=>l,destinationMParticle:()=>v}),module.exports=(e=o,((e,o,r,c)=>{if(o&&"object"==typeof o||"function"==typeof o)for(let a of i(o))s.call(e,a)||a===r||t(e,a,{get:()=>o[a],enumerable:!(c=n(o,a))||c.enumerable});return e})(t({},"__esModule",{value:!0}),e));var r=require("@walkeros/core"),c=require("@walkeros/server-core");var a=async function(e,{config:t,rule:n,data:i,env:s,logger:o}){var a;const m=t.settings,{apiKey:v,apiSecret:l,pod:d="us1",environment:g="production",userIdentities:f,userAttributes:y,consent:b,ip:_,sourceRequestId:O}=m,j=(null==n?void 0:n.settings)||{},w=(0,r.isObject)(i)?i:{},h=await async function(e,t,n){const i={...(0,r.isObject)(t)?t:{},...(0,r.isObject)(n)?n:{}},s=Object.keys(i);if(0===s.length)return;const o={};for(const t of s){const n=p(await(0,r.getMappingValue)(e,i[t]));void 0!==n&&(o[t]=n)}return Object.keys(o).length>0?o:void 0}(e,f,j.userIdentities),k=await async function(e,t,n){const i=t?await(0,r.getMappingValue)(e,t):void 0,s=n?await(0,r.getMappingValue)(e,n):void 0,o={...(0,r.isObject)(i)?i:{},...(0,r.isObject)(s)?s:{}};return Object.keys(o).length>0?o:void 0}(e,y,j.userAttributes),P=_?u(await(0,r.getMappingValue)(e,_)):void 0,S=null!=(a=u(O?await(0,r.getMappingValue)(e,O):void 0))?a:e.id||void 0,I=(null==n?void 0:n.name)||e.name,M=e.timestamp||Date.now(),q=e.id||void 0,x=j.eventType||"custom_event";let A;if("screen_view"===x)A=function(e,t,n,i){return{event_type:"screen_view",data:{...e?{screen_name:e}:{},...t&&Object.keys(t).length>0?{custom_attributes:t}:{},...void 0!==n?{timestamp_unixtime_ms:n}:{},...i?{source_message_id:i}:{}}}}(I,w,M,q);else if("commerce_event"===x){const t=j.commerce?await(0,r.getMappingValue)(e,j.commerce):void 0;A=function(e,t,n,i){return{event_type:"commerce_event",data:{...e||{},...t&&Object.keys(t).length>0?{custom_attributes:t}:{},...void 0!==n?{timestamp_unixtime_ms:n}:{},...i?{source_message_id:i}:{}}}}((0,r.isObject)(t)?t:void 0,w,M,q)}else{A=function(e,t,n,i,s){return{event_type:"custom_event",data:{event_name:e,custom_event_type:t,...n&&Object.keys(n).length>0?{custom_attributes:n}:{},...void 0!==i?{timestamp_unixtime_ms:i}:{},...s?{source_message_id:s}:{}}}}(I,j.customEventType||"other",w,M,q)}const V=function(e,t,n,i,s={}){const o={events:e,environment:i};return t&&Object.keys(t).length>0&&(o.user_identities=t),n&&Object.keys(n).length>0&&(o.user_attributes=n),s.ip&&(o.ip=s.ip),s.sourceRequestId&&(o.source_request_id=s.sourceRequestId),s.consent&&(o.consent_state=s.consent),s.context&&(o.context=s.context),o}([A],h,k,g,{ip:P,sourceRequestId:S,consent:b}),T=function(e="us1"){return"us1"===e?"https://s2s.mparticle.com/v2/events":`https://s2s.${e}.mparticle.com/v2/events`}(d),$=function(e,t){return`Basic ${Buffer.from(`${e}:${t}`).toString("base64")}`}(v,l);o.debug("Calling mParticle Events API",{endpoint:T,method:"POST",eventType:A.event_type,eventName:I,eventId:e.id});const C=(null==s?void 0:s.sendServer)||c.sendServer,K=await C(T,JSON.stringify(V),{headers:{Authorization:$,"Content-Type":"application/json"}});o.debug("mParticle API response",{ok:!(0,r.isObject)(K)||K.ok}),(0,r.isObject)(K)&&!1===K.ok&&o.throw(`mParticle API error: ${JSON.stringify(K)}`)};function u(e){if(null!=e)return"string"==typeof e?e||void 0:"number"==typeof e||"boolean"==typeof e?String(e):void 0}function p(e){if(null!=e)return"string"==typeof e?e||void 0:"number"==typeof e?e:"boolean"==typeof e?String(e):void 0}var m={},v={type:"mparticle",config:{},async init({config:e,logger:t}){const n=function(e={},t){const n=e.settings||{},{apiKey:i,apiSecret:s}=n;i||t.throw("Config settings apiKey missing"),s||t.throw("Config settings apiSecret missing");const o={pod:"us1",environment:"production",...n,apiKey:i,apiSecret:s};return{...e,settings:o}}(e,t);return n},push:async(e,t)=>await a(e,t)},l=v;//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/push.ts","../src/batch.ts","../src/types/index.ts"],"sourcesContent":["import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationMParticle from './types';\n\nexport const destinationMParticle: Destination = {\n type: 'mparticle',\n\n config: {},\n\n async init({ config: partialConfig, logger }) {\n const config = getConfig(partialConfig, logger);\n return config;\n },\n\n async push(event, context) {\n return await push(event, context);\n },\n};\n\nexport default destinationMParticle;\n","import type { Config, PartialConfig, Settings } from './types';\nimport type { Logger } from '@walkeros/core';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { apiKey, apiSecret } = settings;\n\n if (!apiKey) logger.throw('Config settings apiKey missing');\n if (!apiSecret) logger.throw('Config settings apiSecret missing');\n\n const settingsConfig: Settings = {\n pod: 'us1',\n environment: 'production',\n ...settings,\n apiKey: apiKey as string,\n apiSecret: apiSecret as string,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type { WalkerOS, Mapping as WalkerOSMapping } from '@walkeros/core';\nimport { getMappingValue, isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport type {\n CommerceEventData,\n ConsentState,\n CustomEventType,\n Mapping,\n MParticleEvent,\n PushFn,\n Settings,\n} from './types';\nimport {\n buildAuthHeader,\n buildBatch,\n buildCommerceEvent,\n buildCustomEvent,\n buildEndpoint,\n buildScreenViewEvent,\n} from './batch';\n\nexport const push: PushFn = async function (\n event,\n { config, rule, data, env, logger },\n) {\n const settings = config.settings as Settings;\n const {\n apiKey,\n apiSecret,\n pod = 'us1',\n environment = 'production',\n userIdentities: settingsIdentities,\n userAttributes: settingsUserAttributes,\n consent,\n ip: ipSetting,\n sourceRequestId: sourceRequestIdSetting,\n } = settings;\n\n const ruleSettings: Mapping = (rule?.settings || {}) as Mapping;\n\n const customAttributes = isObject(data)\n ? (data as Record<string, unknown>)\n : {};\n\n const userIdentities = await resolveIdentities(\n event,\n settingsIdentities,\n ruleSettings.userIdentities,\n );\n\n const userAttributes = await resolveUserAttributes(\n event,\n settingsUserAttributes,\n ruleSettings.userAttributes,\n );\n\n const ip = ipSetting\n ? toStringValue(await getMappingValue(event, ipSetting))\n : undefined;\n\n const sourceRequestIdRaw = sourceRequestIdSetting\n ? await getMappingValue(event, sourceRequestIdSetting)\n : undefined;\n const sourceRequestId =\n toStringValue(sourceRequestIdRaw) ?? (event.id || undefined);\n\n const eventName = rule?.name || event.name;\n const timestamp = event.timestamp || Date.now();\n const sourceMessageId = event.id || undefined;\n const eventType = ruleSettings.eventType || 'custom_event';\n\n let mpEvent: MParticleEvent;\n if (eventType === 'screen_view') {\n mpEvent = buildScreenViewEvent(\n eventName,\n customAttributes,\n timestamp,\n sourceMessageId,\n );\n } else if (eventType === 'commerce_event') {\n const commerceResolved = ruleSettings.commerce\n ? await getMappingValue(event, ruleSettings.commerce)\n : undefined;\n const commerceData = isObject(commerceResolved)\n ? (commerceResolved as Partial<CommerceEventData>)\n : undefined;\n mpEvent = buildCommerceEvent(\n commerceData,\n customAttributes,\n timestamp,\n sourceMessageId,\n );\n } else {\n const customEventType: CustomEventType =\n ruleSettings.customEventType || 'other';\n mpEvent = buildCustomEvent(\n eventName,\n customEventType,\n customAttributes,\n timestamp,\n sourceMessageId,\n );\n }\n\n const batch = buildBatch(\n [mpEvent],\n userIdentities,\n userAttributes,\n environment,\n {\n ip,\n sourceRequestId,\n consent: consent as ConsentState | undefined,\n },\n );\n\n const endpoint = buildEndpoint(pod);\n const authHeader = buildAuthHeader(apiKey, apiSecret);\n\n logger.debug('Calling mParticle Events API', {\n endpoint,\n method: 'POST',\n eventType: mpEvent.event_type,\n eventName,\n eventId: event.id,\n });\n\n const sendServerFn = env?.sendServer || sendServer;\n const result = await sendServerFn(endpoint, JSON.stringify(batch), {\n headers: {\n Authorization: authHeader,\n 'Content-Type': 'application/json',\n },\n });\n\n logger.debug('mParticle API response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`mParticle API error: ${JSON.stringify(result)}`);\n }\n};\n\nasync function resolveIdentities(\n event: WalkerOS.Event,\n settingsIdentities: WalkerOSMapping.Map | undefined,\n ruleIdentities: WalkerOSMapping.Map | undefined,\n): Promise<Record<string, string | number> | undefined> {\n const merged: WalkerOSMapping.Map = {\n ...(isObject(settingsIdentities) ? settingsIdentities : {}),\n ...(isObject(ruleIdentities) ? ruleIdentities : {}),\n };\n const keys = Object.keys(merged);\n if (keys.length === 0) return undefined;\n\n const out: Record<string, string | number> = {};\n for (const key of keys) {\n const raw = await getMappingValue(event, merged[key]);\n const coerced = toIdentityValue(raw);\n if (coerced !== undefined) out[key] = coerced;\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nasync function resolveUserAttributes(\n event: WalkerOS.Event,\n settingsAttributes: WalkerOSMapping.Value | undefined,\n ruleAttributes: WalkerOSMapping.Value | undefined,\n): Promise<Record<string, unknown> | undefined> {\n const settingsResolved = settingsAttributes\n ? await getMappingValue(event, settingsAttributes)\n : undefined;\n const ruleResolved = ruleAttributes\n ? await getMappingValue(event, ruleAttributes)\n : undefined;\n\n const merged: Record<string, unknown> = {\n ...(isObject(settingsResolved)\n ? (settingsResolved as Record<string, unknown>)\n : {}),\n ...(isObject(ruleResolved)\n ? (ruleResolved as Record<string, unknown>)\n : {}),\n };\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction toStringValue(value: unknown): string | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value === 'string') return value || undefined;\n if (typeof value === 'number' || typeof value === 'boolean')\n return String(value);\n return undefined;\n}\n\nfunction toIdentityValue(value: unknown): string | number | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value === 'string') return value || undefined;\n if (typeof value === 'number') return value;\n if (typeof value === 'boolean') return String(value);\n return undefined;\n}\n","import type {\n CommerceEventData,\n ConsentState,\n CustomEventType,\n Environment,\n MParticleBatch,\n MParticleEvent,\n Pod,\n ScreenViewEventData,\n} from './types';\n\n/**\n * Returns the mParticle Events API endpoint for the given pod.\n * us1 resolves to the legacy host (`s2s.mparticle.com`); other pods use the\n * pod-qualified host.\n * https://docs.mparticle.com/developers/server/http/#endpoint\n */\nexport function buildEndpoint(pod: Pod = 'us1'): string {\n if (pod === 'us1') return 'https://s2s.mparticle.com/v2/events';\n return `https://s2s.${pod}.mparticle.com/v2/events`;\n}\n\n/**\n * Builds the HTTP Basic auth header value from an API key/secret pair.\n * Uses Buffer (Node) for base64 encoding to keep server semantics.\n */\nexport function buildAuthHeader(apiKey: string, apiSecret: string): string {\n const token = Buffer.from(`${apiKey}:${apiSecret}`).toString('base64');\n return `Basic ${token}`;\n}\n\n/**\n * Builds a custom_event payload.\n */\nexport function buildCustomEvent(\n eventName: string,\n customEventType: CustomEventType,\n customAttributes: Record<string, unknown> | undefined,\n timestamp: number | undefined,\n sourceMessageId: string | undefined,\n): MParticleEvent {\n return {\n event_type: 'custom_event',\n data: {\n event_name: eventName,\n custom_event_type: customEventType,\n ...(customAttributes && Object.keys(customAttributes).length > 0\n ? { custom_attributes: customAttributes }\n : {}),\n ...(timestamp !== undefined ? { timestamp_unixtime_ms: timestamp } : {}),\n ...(sourceMessageId ? { source_message_id: sourceMessageId } : {}),\n },\n };\n}\n\n/**\n * Builds a screen_view event payload.\n */\nexport function buildScreenViewEvent(\n screenName: string | undefined,\n customAttributes: Record<string, unknown> | undefined,\n timestamp: number | undefined,\n sourceMessageId: string | undefined,\n): MParticleEvent {\n const data: ScreenViewEventData = {\n ...(screenName ? { screen_name: screenName } : {}),\n ...(customAttributes && Object.keys(customAttributes).length > 0\n ? { custom_attributes: customAttributes }\n : {}),\n ...(timestamp !== undefined ? { timestamp_unixtime_ms: timestamp } : {}),\n ...(sourceMessageId ? { source_message_id: sourceMessageId } : {}),\n };\n return { event_type: 'screen_view', data };\n}\n\n/**\n * Builds a commerce_event payload. Commerce data is a loosely-shaped subset\n * of {@link CommerceEventData} (product_action, currency_code, ...) resolved\n * from the per-rule commerce mapping.\n */\nexport function buildCommerceEvent(\n commerceData: Partial<CommerceEventData> | undefined,\n customAttributes: Record<string, unknown> | undefined,\n timestamp: number | undefined,\n sourceMessageId: string | undefined,\n): MParticleEvent {\n const data: CommerceEventData = {\n ...(commerceData || {}),\n ...(customAttributes && Object.keys(customAttributes).length > 0\n ? { custom_attributes: customAttributes }\n : {}),\n ...(timestamp !== undefined ? { timestamp_unixtime_ms: timestamp } : {}),\n ...(sourceMessageId ? { source_message_id: sourceMessageId } : {}),\n };\n return { event_type: 'commerce_event', data };\n}\n\nexport interface BuildBatchOptions {\n ip?: string;\n sourceRequestId?: string;\n consent?: ConsentState;\n context?: Record<string, unknown>;\n}\n\n/**\n * Assembles the batch envelope wrapping events + identity + environment.\n */\nexport function buildBatch(\n events: MParticleEvent[],\n userIdentities: Record<string, string | number> | undefined,\n userAttributes: Record<string, unknown> | undefined,\n environment: Environment,\n options: BuildBatchOptions = {},\n): MParticleBatch {\n const batch: MParticleBatch = {\n events,\n environment,\n };\n if (userIdentities && Object.keys(userIdentities).length > 0)\n batch.user_identities = userIdentities;\n if (userAttributes && Object.keys(userAttributes).length > 0)\n batch.user_attributes = userAttributes;\n if (options.ip) batch.ip = options.ip;\n if (options.sourceRequestId)\n batch.source_request_id = options.sourceRequestId;\n if (options.consent) batch.consent_state = options.consent;\n if (options.context) batch.context = options.context;\n return batch;\n}\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer, sendServer } from '@walkeros/server-core';\n\n/**\n * mParticle data pod. Determines the regional endpoint used for the Events\n * API. Defaults to `us1`. See {@link buildEndpoint} in `batch.ts`.\n */\nexport type Pod = 'us1' | 'us2' | 'eu1' | 'au1';\n\n/**\n * mParticle environment for the batch. `production` routes to production\n * data streams; `development` sends to debug/verify streams.\n */\nexport type Environment = 'production' | 'development';\n\n/**\n * Event type used for the outgoing mParticle event. Defaults to\n * `custom_event` when not explicitly mapped via rule settings.\n */\nexport type EventType = 'custom_event' | 'screen_view' | 'commerce_event';\n\n/**\n * mParticle custom event type (category) for `custom_event`s. Defaults to\n * `other` when not specified.\n */\nexport type CustomEventType =\n | 'navigation'\n | 'location'\n | 'search'\n | 'transaction'\n | 'user_content'\n | 'user_preference'\n | 'social'\n | 'media'\n | 'attribution'\n | 'other';\n\n/**\n * mParticle product action verbs for commerce events.\n */\nexport type ProductActionType =\n | 'add_to_cart'\n | 'remove_from_cart'\n | 'checkout'\n | 'checkout_option'\n | 'click'\n | 'view_detail'\n | 'purchase'\n | 'refund'\n | 'add_to_wishlist'\n | 'remove_from_wishlist';\n\nexport interface Settings {\n /** mParticle input feed API key. */\n apiKey: string;\n /** mParticle input feed API secret. */\n apiSecret: string;\n /** Data pod selecting the regional endpoint. Default: `us1`. */\n pod?: Pod;\n /** Environment the batch targets. Default: `production`. */\n environment?: Environment;\n /**\n * Mapping that resolves to `user_identities` per batch. Each entry value\n * is a walkerOS mapping value; the resolved object is placed into the\n * mParticle batch `user_identities` envelope.\n */\n userIdentities?: WalkerOSMapping.Map;\n /**\n * Mapping that resolves to `user_attributes` per batch.\n */\n userAttributes?: WalkerOSMapping.Value;\n /**\n * Optional static consent state passthrough — shape is forwarded verbatim\n * to `consent_state` on the batch.\n */\n consent?: ConsentState;\n /** walkerOS mapping value resolving to the client IP for the batch. */\n ip?: WalkerOSMapping.Value;\n /**\n * Optional request correlation id. When omitted, falls back to `event.id`.\n */\n sourceRequestId?: WalkerOSMapping.Value;\n}\n\nexport type InitSettings = Partial<Settings>;\n\n/**\n * Per-rule mapping settings. Determines which mParticle event shape is\n * produced for this walkerOS event and allows per-event identity overrides.\n */\nexport interface Mapping {\n /** Event type. Default: `custom_event`. */\n eventType?: EventType;\n /** Custom event type category for `custom_event`. Default: `other`. */\n customEventType?: CustomEventType;\n /** Commerce mapping resolving to ProductAction and related fields. */\n commerce?: WalkerOSMapping.Value;\n /** Per-event override for `user_identities`. Merged over settings. */\n userIdentities?: WalkerOSMapping.Map;\n /** Per-event override for `user_attributes`. */\n userAttributes?: WalkerOSMapping.Value;\n}\n\nexport interface Env extends DestinationServer.Env {\n sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n/**\n * Top-level mParticle batch payload posted to\n * `https://s2s.{pod}.mparticle.com/v2/events`.\n * https://docs.mparticle.com/developers/server/http/\n */\nexport interface MParticleBatch {\n events: MParticleEvent[];\n user_identities?: Record<string, string | number>;\n user_attributes?: Record<string, unknown>;\n environment: Environment;\n schema_version?: number;\n ip?: string;\n source_request_id?: string;\n consent_state?: ConsentState;\n context?: Record<string, unknown>;\n}\n\nexport type MParticleEvent =\n | { event_type: 'custom_event'; data: CustomEventData }\n | { event_type: 'screen_view'; data: ScreenViewEventData }\n | { event_type: 'commerce_event'; data: CommerceEventData };\n\nexport interface CommonEventData {\n timestamp_unixtime_ms?: number;\n source_message_id?: string;\n session_uuid?: string;\n custom_attributes?: Record<string, unknown>;\n custom_flags?: Record<string, unknown>;\n location?: Record<string, unknown>;\n}\n\nexport interface CustomEventData extends CommonEventData {\n event_name: string;\n custom_event_type: CustomEventType;\n}\n\nexport interface ScreenViewEventData extends CommonEventData {\n screen_name?: string;\n}\n\nexport interface CommerceEventData extends CommonEventData {\n product_action?: ProductAction;\n promotion_action?: PromotionAction;\n product_impressions?: ProductImpression[];\n currency_code?: string;\n is_non_interactive?: boolean;\n}\n\nexport interface ProductAction {\n action: ProductActionType;\n transaction_id?: string;\n total_amount?: number;\n tax_amount?: number;\n shipping_amount?: number;\n coupon_code?: string;\n affiliation?: string;\n checkout_step?: number;\n checkout_options?: string;\n products?: Product[];\n}\n\nexport interface Product {\n id?: string;\n name?: string;\n brand?: string;\n category?: string;\n variant?: string;\n position?: number;\n price?: number;\n quantity?: number;\n coupon_code?: string;\n total_product_amount?: number;\n custom_attributes?: Record<string, unknown>;\n}\n\nexport interface PromotionAction {\n action: 'view' | 'click';\n promotions?: Array<{\n id?: string;\n name?: string;\n creative?: string;\n position?: string;\n }>;\n}\n\nexport interface ProductImpression {\n product_impression_list?: string;\n products?: Product[];\n}\n\n/**\n * mParticle consent state envelope forwarded verbatim on the batch.\n * https://docs.mparticle.com/developers/server/http/#consent-state\n */\nexport interface ConsentState {\n gdpr?: Record<string, GDPRConsentState>;\n ccpa?: { data_sale_opt_out?: CCPAConsentState };\n}\n\nexport interface GDPRConsentState {\n consented: boolean;\n document?: string;\n timestamp_unixtime_ms?: number;\n location?: string;\n hardware_id?: string;\n}\n\nexport interface CCPAConsentState {\n consented: boolean;\n document?: string;\n timestamp_unixtime_ms?: number;\n location?: string;\n hardware_id?: string;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACGO,SAAS,UACd,gBAA+B,CAAC,GAChC,QACQ;AACR,QAAM,WAAY,cAAc,YAAY,CAAC;AAC7C,QAAM,EAAE,QAAQ,UAAU,IAAI;AAE9B,MAAI,CAAC,OAAQ,QAAO,MAAM,gCAAgC;AAC1D,MAAI,CAAC,UAAW,QAAO,MAAM,mCAAmC;AAEhE,QAAM,iBAA2B;AAAA,IAC/B,KAAK;AAAA,IACL,aAAa;AAAA,IACb,GAAG;AAAA,IACH;AAAA,IACA;AAAA,EACF;AAEA,SAAO,EAAE,GAAG,eAAe,UAAU,eAAe;AACtD;;;ACrBA,kBAA0C;AAC1C,yBAA2B;;;ACepB,SAAS,cAAc,MAAW,OAAe;AACtD,MAAI,QAAQ,MAAO,QAAO;AAC1B,SAAO,eAAe,GAAG;AAC3B;AAMO,SAAS,gBAAgB,QAAgB,WAA2B;AACzE,QAAM,QAAQ,OAAO,KAAK,GAAG,MAAM,IAAI,SAAS,EAAE,EAAE,SAAS,QAAQ;AACrE,SAAO,SAAS,KAAK;AACvB;AAKO,SAAS,iBACd,WACA,iBACA,kBACA,WACA,iBACgB;AAChB,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,MAAM;AAAA,MACJ,YAAY;AAAA,MACZ,mBAAmB;AAAA,MACnB,GAAI,oBAAoB,OAAO,KAAK,gBAAgB,EAAE,SAAS,IAC3D,EAAE,mBAAmB,iBAAiB,IACtC,CAAC;AAAA,MACL,GAAI,cAAc,SAAY,EAAE,uBAAuB,UAAU,IAAI,CAAC;AAAA,MACtE,GAAI,kBAAkB,EAAE,mBAAmB,gBAAgB,IAAI,CAAC;AAAA,IAClE;AAAA,EACF;AACF;AAKO,SAAS,qBACd,YACA,kBACA,WACA,iBACgB;AAChB,QAAM,OAA4B;AAAA,IAChC,GAAI,aAAa,EAAE,aAAa,WAAW,IAAI,CAAC;AAAA,IAChD,GAAI,oBAAoB,OAAO,KAAK,gBAAgB,EAAE,SAAS,IAC3D,EAAE,mBAAmB,iBAAiB,IACtC,CAAC;AAAA,IACL,GAAI,cAAc,SAAY,EAAE,uBAAuB,UAAU,IAAI,CAAC;AAAA,IACtE,GAAI,kBAAkB,EAAE,mBAAmB,gBAAgB,IAAI,CAAC;AAAA,EAClE;AACA,SAAO,EAAE,YAAY,eAAe,KAAK;AAC3C;AAOO,SAAS,mBACd,cACA,kBACA,WACA,iBACgB;AAChB,QAAM,OAA0B;AAAA,IAC9B,GAAI,gBAAgB,CAAC;AAAA,IACrB,GAAI,oBAAoB,OAAO,KAAK,gBAAgB,EAAE,SAAS,IAC3D,EAAE,mBAAmB,iBAAiB,IACtC,CAAC;AAAA,IACL,GAAI,cAAc,SAAY,EAAE,uBAAuB,UAAU,IAAI,CAAC;AAAA,IACtE,GAAI,kBAAkB,EAAE,mBAAmB,gBAAgB,IAAI,CAAC;AAAA,EAClE;AACA,SAAO,EAAE,YAAY,kBAAkB,KAAK;AAC9C;AAYO,SAAS,WACd,QACA,gBACA,gBACA,aACA,UAA6B,CAAC,GACd;AAChB,QAAM,QAAwB;AAAA,IAC5B;AAAA,IACA;AAAA,EACF;AACA,MAAI,kBAAkB,OAAO,KAAK,cAAc,EAAE,SAAS;AACzD,UAAM,kBAAkB;AAC1B,MAAI,kBAAkB,OAAO,KAAK,cAAc,EAAE,SAAS;AACzD,UAAM,kBAAkB;AAC1B,MAAI,QAAQ,GAAI,OAAM,KAAK,QAAQ;AACnC,MAAI,QAAQ;AACV,UAAM,oBAAoB,QAAQ;AACpC,MAAI,QAAQ,QAAS,OAAM,gBAAgB,QAAQ;AACnD,MAAI,QAAQ,QAAS,OAAM,UAAU,QAAQ;AAC7C,SAAO;AACT;;;AD3GO,IAAM,OAAe,eAC1B,OACA,EAAE,QAAQ,MAAM,MAAM,KAAK,OAAO,GAClC;AAxBF;AAyBE,QAAM,WAAW,OAAO;AACxB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB;AAAA,IACA,IAAI;AAAA,IACJ,iBAAiB;AAAA,EACnB,IAAI;AAEJ,QAAM,gBAAyB,6BAAM,aAAY,CAAC;AAElD,QAAM,uBAAmB,sBAAS,IAAI,IACjC,OACD,CAAC;AAEL,QAAM,iBAAiB,MAAM;AAAA,IAC3B;AAAA,IACA;AAAA,IACA,aAAa;AAAA,EACf;AAEA,QAAM,iBAAiB,MAAM;AAAA,IAC3B;AAAA,IACA;AAAA,IACA,aAAa;AAAA,EACf;AAEA,QAAM,KAAK,YACP,cAAc,UAAM,6BAAgB,OAAO,SAAS,CAAC,IACrD;AAEJ,QAAM,qBAAqB,yBACvB,UAAM,6BAAgB,OAAO,sBAAsB,IACnD;AACJ,QAAM,mBACJ,mBAAc,kBAAkB,MAAhC,YAAsC,MAAM,MAAM;AAEpD,QAAM,aAAY,6BAAM,SAAQ,MAAM;AACtC,QAAM,YAAY,MAAM,aAAa,KAAK,IAAI;AAC9C,QAAM,kBAAkB,MAAM,MAAM;AACpC,QAAM,YAAY,aAAa,aAAa;AAE5C,MAAI;AACJ,MAAI,cAAc,eAAe;AAC/B,cAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,WAAW,cAAc,kBAAkB;AACzC,UAAM,mBAAmB,aAAa,WAClC,UAAM,6BAAgB,OAAO,aAAa,QAAQ,IAClD;AACJ,UAAM,mBAAe,sBAAS,gBAAgB,IACzC,mBACD;AACJ,cAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,OAAO;AACL,UAAM,kBACJ,aAAa,mBAAmB;AAClC,cAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAQ;AAAA,IACZ,CAAC,OAAO;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,WAAW,cAAc,GAAG;AAClC,QAAM,aAAa,gBAAgB,QAAQ,SAAS;AAEpD,SAAO,MAAM,gCAAgC;AAAA,IAC3C;AAAA,IACA,QAAQ;AAAA,IACR,WAAW,QAAQ;AAAA,IACnB;AAAA,IACA,SAAS,MAAM;AAAA,EACjB,CAAC;AAED,QAAM,gBAAe,2BAAK,eAAc;AACxC,QAAM,SAAS,MAAM,aAAa,UAAU,KAAK,UAAU,KAAK,GAAG;AAAA,IACjE,SAAS;AAAA,MACP,eAAe;AAAA,MACf,gBAAgB;AAAA,IAClB;AAAA,EACF,CAAC;AAED,SAAO,MAAM,0BAA0B;AAAA,IACrC,QAAI,sBAAS,MAAM,IAAI,OAAO,KAAK;AAAA,EACrC,CAAC;AAED,UAAI,sBAAS,MAAM,KAAK,OAAO,OAAO,OAAO;AAC3C,WAAO,MAAM,wBAAwB,KAAK,UAAU,MAAM,CAAC,EAAE;AAAA,EAC/D;AACF;AAEA,eAAe,kBACb,OACA,oBACA,gBACsD;AACtD,QAAM,SAA8B;AAAA,IAClC,OAAI,sBAAS,kBAAkB,IAAI,qBAAqB,CAAC;AAAA,IACzD,OAAI,sBAAS,cAAc,IAAI,iBAAiB,CAAC;AAAA,EACnD;AACA,QAAM,OAAO,OAAO,KAAK,MAAM;AAC/B,MAAI,KAAK,WAAW,EAAG,QAAO;AAE9B,QAAM,MAAuC,CAAC;AAC9C,aAAW,OAAO,MAAM;AACtB,UAAM,MAAM,UAAM,6BAAgB,OAAO,OAAO,GAAG,CAAC;AACpD,UAAM,UAAU,gBAAgB,GAAG;AACnC,QAAI,YAAY,OAAW,KAAI,GAAG,IAAI;AAAA,EACxC;AACA,SAAO,OAAO,KAAK,GAAG,EAAE,SAAS,IAAI,MAAM;AAC7C;AAEA,eAAe,sBACb,OACA,oBACA,gBAC8C;AAC9C,QAAM,mBAAmB,qBACrB,UAAM,6BAAgB,OAAO,kBAAkB,IAC/C;AACJ,QAAM,eAAe,iBACjB,UAAM,6BAAgB,OAAO,cAAc,IAC3C;AAEJ,QAAM,SAAkC;AAAA,IACtC,OAAI,sBAAS,gBAAgB,IACxB,mBACD,CAAC;AAAA,IACL,OAAI,sBAAS,YAAY,IACpB,eACD,CAAC;AAAA,EACP;AACA,SAAO,OAAO,KAAK,MAAM,EAAE,SAAS,IAAI,SAAS;AACnD;AAEA,SAAS,cAAc,OAAoC;AACzD,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,MAAI,OAAO,UAAU,SAAU,QAAO,SAAS;AAC/C,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU;AAChD,WAAO,OAAO,KAAK;AACrB,SAAO;AACT;AAEA,SAAS,gBAAgB,OAA6C;AACpE,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,MAAI,OAAO,UAAU,SAAU,QAAO,SAAS;AAC/C,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,OAAO,UAAU,UAAW,QAAO,OAAO,KAAK;AACnD,SAAO;AACT;;;AE1MA;;;AJOO,IAAM,uBAAoC;AAAA,EAC/C,MAAM;AAAA,EAEN,QAAQ,CAAC;AAAA,EAET,MAAM,KAAK,EAAE,QAAQ,eAAe,OAAO,GAAG;AAC5C,UAAM,SAAS,UAAU,eAAe,MAAM;AAC9C,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAAK,OAAO,SAAS;AACzB,WAAO,MAAM,KAAK,OAAO,OAAO;AAAA,EAClC;AACF;AAEA,IAAO,gBAAQ;","names":[]}
package/dist/index.mjs ADDED
@@ -0,0 +1 @@
1
+ import{getMappingValue as e,isObject as t}from"@walkeros/core";import{sendServer as n}from"@walkeros/server-core";var i=async function(i,{config:r,rule:c,data:a,env:u,logger:m}){var v;const d=r.settings,{apiKey:p,apiSecret:l,pod:f="us1",environment:g="production",userIdentities:y,userAttributes:_,consent:b,ip:h,sourceRequestId:w}=d,k=(null==c?void 0:c.settings)||{},O=t(a)?a:{},S=await async function(n,i,s){const r={...t(i)?i:{},...t(s)?s:{}},c=Object.keys(r);if(0===c.length)return;const a={};for(const t of c){const i=o(await e(n,r[t]));void 0!==i&&(a[t]=i)}return Object.keys(a).length>0?a:void 0}(i,y,k.userIdentities),I=await async function(n,i,s){const o=i?await e(n,i):void 0,r=s?await e(n,s):void 0,c={...t(o)?o:{},...t(r)?r:{}};return Object.keys(c).length>0?c:void 0}(i,_,k.userAttributes),j=h?s(await e(i,h)):void 0,P=null!=(v=s(w?await e(i,w):void 0))?v:i.id||void 0,x=(null==c?void 0:c.name)||i.name,A=i.timestamp||Date.now(),q=i.id||void 0,T=k.eventType||"custom_event";let $;if("screen_view"===T)$=function(e,t,n,i){return{event_type:"screen_view",data:{...e?{screen_name:e}:{},...t&&Object.keys(t).length>0?{custom_attributes:t}:{},...void 0!==n?{timestamp_unixtime_ms:n}:{},...i?{source_message_id:i}:{}}}}(x,O,A,q);else if("commerce_event"===T){const n=k.commerce?await e(i,k.commerce):void 0;$=function(e,t,n,i){return{event_type:"commerce_event",data:{...e||{},...t&&Object.keys(t).length>0?{custom_attributes:t}:{},...void 0!==n?{timestamp_unixtime_ms:n}:{},...i?{source_message_id:i}:{}}}}(t(n)?n:void 0,O,A,q)}else{$=function(e,t,n,i,s){return{event_type:"custom_event",data:{event_name:e,custom_event_type:t,...n&&Object.keys(n).length>0?{custom_attributes:n}:{},...void 0!==i?{timestamp_unixtime_ms:i}:{},...s?{source_message_id:s}:{}}}}(x,k.customEventType||"other",O,A,q)}const C=function(e,t,n,i,s={}){const o={events:e,environment:i};return t&&Object.keys(t).length>0&&(o.user_identities=t),n&&Object.keys(n).length>0&&(o.user_attributes=n),s.ip&&(o.ip=s.ip),s.sourceRequestId&&(o.source_request_id=s.sourceRequestId),s.consent&&(o.consent_state=s.consent),s.context&&(o.context=s.context),o}([$],S,I,g,{ip:j,sourceRequestId:P,consent:b}),K=function(e="us1"){return"us1"===e?"https://s2s.mparticle.com/v2/events":`https://s2s.${e}.mparticle.com/v2/events`}(f),R=function(e,t){return`Basic ${Buffer.from(`${e}:${t}`).toString("base64")}`}(p,l);m.debug("Calling mParticle Events API",{endpoint:K,method:"POST",eventType:$.event_type,eventName:x,eventId:i.id});const N=(null==u?void 0:u.sendServer)||n,B=await N(K,JSON.stringify(C),{headers:{Authorization:R,"Content-Type":"application/json"}});m.debug("mParticle API response",{ok:!t(B)||B.ok}),t(B)&&!1===B.ok&&m.throw(`mParticle API error: ${JSON.stringify(B)}`)};function s(e){if(null!=e)return"string"==typeof e?e||void 0:"number"==typeof e||"boolean"==typeof e?String(e):void 0}function o(e){if(null!=e)return"string"==typeof e?e||void 0:"number"==typeof e?e:"boolean"==typeof e?String(e):void 0}var r={},c={type:"mparticle",config:{},async init({config:e,logger:t}){const n=function(e={},t){const n=e.settings||{},{apiKey:i,apiSecret:s}=n;i||t.throw("Config settings apiKey missing"),s||t.throw("Config settings apiSecret missing");const o={pod:"us1",environment:"production",...n,apiKey:i,apiSecret:s};return{...e,settings:o}}(e,t);return n},push:async(e,t)=>await i(e,t)},a=c;export{r as DestinationMParticle,a as default,c as destinationMParticle};//# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config.ts","../src/push.ts","../src/batch.ts","../src/types/index.ts","../src/index.ts"],"sourcesContent":["import type { Config, PartialConfig, Settings } from './types';\nimport type { Logger } from '@walkeros/core';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { apiKey, apiSecret } = settings;\n\n if (!apiKey) logger.throw('Config settings apiKey missing');\n if (!apiSecret) logger.throw('Config settings apiSecret missing');\n\n const settingsConfig: Settings = {\n pod: 'us1',\n environment: 'production',\n ...settings,\n apiKey: apiKey as string,\n apiSecret: apiSecret as string,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type { WalkerOS, Mapping as WalkerOSMapping } from '@walkeros/core';\nimport { getMappingValue, isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport type {\n CommerceEventData,\n ConsentState,\n CustomEventType,\n Mapping,\n MParticleEvent,\n PushFn,\n Settings,\n} from './types';\nimport {\n buildAuthHeader,\n buildBatch,\n buildCommerceEvent,\n buildCustomEvent,\n buildEndpoint,\n buildScreenViewEvent,\n} from './batch';\n\nexport const push: PushFn = async function (\n event,\n { config, rule, data, env, logger },\n) {\n const settings = config.settings as Settings;\n const {\n apiKey,\n apiSecret,\n pod = 'us1',\n environment = 'production',\n userIdentities: settingsIdentities,\n userAttributes: settingsUserAttributes,\n consent,\n ip: ipSetting,\n sourceRequestId: sourceRequestIdSetting,\n } = settings;\n\n const ruleSettings: Mapping = (rule?.settings || {}) as Mapping;\n\n const customAttributes = isObject(data)\n ? (data as Record<string, unknown>)\n : {};\n\n const userIdentities = await resolveIdentities(\n event,\n settingsIdentities,\n ruleSettings.userIdentities,\n );\n\n const userAttributes = await resolveUserAttributes(\n event,\n settingsUserAttributes,\n ruleSettings.userAttributes,\n );\n\n const ip = ipSetting\n ? toStringValue(await getMappingValue(event, ipSetting))\n : undefined;\n\n const sourceRequestIdRaw = sourceRequestIdSetting\n ? await getMappingValue(event, sourceRequestIdSetting)\n : undefined;\n const sourceRequestId =\n toStringValue(sourceRequestIdRaw) ?? (event.id || undefined);\n\n const eventName = rule?.name || event.name;\n const timestamp = event.timestamp || Date.now();\n const sourceMessageId = event.id || undefined;\n const eventType = ruleSettings.eventType || 'custom_event';\n\n let mpEvent: MParticleEvent;\n if (eventType === 'screen_view') {\n mpEvent = buildScreenViewEvent(\n eventName,\n customAttributes,\n timestamp,\n sourceMessageId,\n );\n } else if (eventType === 'commerce_event') {\n const commerceResolved = ruleSettings.commerce\n ? await getMappingValue(event, ruleSettings.commerce)\n : undefined;\n const commerceData = isObject(commerceResolved)\n ? (commerceResolved as Partial<CommerceEventData>)\n : undefined;\n mpEvent = buildCommerceEvent(\n commerceData,\n customAttributes,\n timestamp,\n sourceMessageId,\n );\n } else {\n const customEventType: CustomEventType =\n ruleSettings.customEventType || 'other';\n mpEvent = buildCustomEvent(\n eventName,\n customEventType,\n customAttributes,\n timestamp,\n sourceMessageId,\n );\n }\n\n const batch = buildBatch(\n [mpEvent],\n userIdentities,\n userAttributes,\n environment,\n {\n ip,\n sourceRequestId,\n consent: consent as ConsentState | undefined,\n },\n );\n\n const endpoint = buildEndpoint(pod);\n const authHeader = buildAuthHeader(apiKey, apiSecret);\n\n logger.debug('Calling mParticle Events API', {\n endpoint,\n method: 'POST',\n eventType: mpEvent.event_type,\n eventName,\n eventId: event.id,\n });\n\n const sendServerFn = env?.sendServer || sendServer;\n const result = await sendServerFn(endpoint, JSON.stringify(batch), {\n headers: {\n Authorization: authHeader,\n 'Content-Type': 'application/json',\n },\n });\n\n logger.debug('mParticle API response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`mParticle API error: ${JSON.stringify(result)}`);\n }\n};\n\nasync function resolveIdentities(\n event: WalkerOS.Event,\n settingsIdentities: WalkerOSMapping.Map | undefined,\n ruleIdentities: WalkerOSMapping.Map | undefined,\n): Promise<Record<string, string | number> | undefined> {\n const merged: WalkerOSMapping.Map = {\n ...(isObject(settingsIdentities) ? settingsIdentities : {}),\n ...(isObject(ruleIdentities) ? ruleIdentities : {}),\n };\n const keys = Object.keys(merged);\n if (keys.length === 0) return undefined;\n\n const out: Record<string, string | number> = {};\n for (const key of keys) {\n const raw = await getMappingValue(event, merged[key]);\n const coerced = toIdentityValue(raw);\n if (coerced !== undefined) out[key] = coerced;\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nasync function resolveUserAttributes(\n event: WalkerOS.Event,\n settingsAttributes: WalkerOSMapping.Value | undefined,\n ruleAttributes: WalkerOSMapping.Value | undefined,\n): Promise<Record<string, unknown> | undefined> {\n const settingsResolved = settingsAttributes\n ? await getMappingValue(event, settingsAttributes)\n : undefined;\n const ruleResolved = ruleAttributes\n ? await getMappingValue(event, ruleAttributes)\n : undefined;\n\n const merged: Record<string, unknown> = {\n ...(isObject(settingsResolved)\n ? (settingsResolved as Record<string, unknown>)\n : {}),\n ...(isObject(ruleResolved)\n ? (ruleResolved as Record<string, unknown>)\n : {}),\n };\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction toStringValue(value: unknown): string | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value === 'string') return value || undefined;\n if (typeof value === 'number' || typeof value === 'boolean')\n return String(value);\n return undefined;\n}\n\nfunction toIdentityValue(value: unknown): string | number | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value === 'string') return value || undefined;\n if (typeof value === 'number') return value;\n if (typeof value === 'boolean') return String(value);\n return undefined;\n}\n","import type {\n CommerceEventData,\n ConsentState,\n CustomEventType,\n Environment,\n MParticleBatch,\n MParticleEvent,\n Pod,\n ScreenViewEventData,\n} from './types';\n\n/**\n * Returns the mParticle Events API endpoint for the given pod.\n * us1 resolves to the legacy host (`s2s.mparticle.com`); other pods use the\n * pod-qualified host.\n * https://docs.mparticle.com/developers/server/http/#endpoint\n */\nexport function buildEndpoint(pod: Pod = 'us1'): string {\n if (pod === 'us1') return 'https://s2s.mparticle.com/v2/events';\n return `https://s2s.${pod}.mparticle.com/v2/events`;\n}\n\n/**\n * Builds the HTTP Basic auth header value from an API key/secret pair.\n * Uses Buffer (Node) for base64 encoding to keep server semantics.\n */\nexport function buildAuthHeader(apiKey: string, apiSecret: string): string {\n const token = Buffer.from(`${apiKey}:${apiSecret}`).toString('base64');\n return `Basic ${token}`;\n}\n\n/**\n * Builds a custom_event payload.\n */\nexport function buildCustomEvent(\n eventName: string,\n customEventType: CustomEventType,\n customAttributes: Record<string, unknown> | undefined,\n timestamp: number | undefined,\n sourceMessageId: string | undefined,\n): MParticleEvent {\n return {\n event_type: 'custom_event',\n data: {\n event_name: eventName,\n custom_event_type: customEventType,\n ...(customAttributes && Object.keys(customAttributes).length > 0\n ? { custom_attributes: customAttributes }\n : {}),\n ...(timestamp !== undefined ? { timestamp_unixtime_ms: timestamp } : {}),\n ...(sourceMessageId ? { source_message_id: sourceMessageId } : {}),\n },\n };\n}\n\n/**\n * Builds a screen_view event payload.\n */\nexport function buildScreenViewEvent(\n screenName: string | undefined,\n customAttributes: Record<string, unknown> | undefined,\n timestamp: number | undefined,\n sourceMessageId: string | undefined,\n): MParticleEvent {\n const data: ScreenViewEventData = {\n ...(screenName ? { screen_name: screenName } : {}),\n ...(customAttributes && Object.keys(customAttributes).length > 0\n ? { custom_attributes: customAttributes }\n : {}),\n ...(timestamp !== undefined ? { timestamp_unixtime_ms: timestamp } : {}),\n ...(sourceMessageId ? { source_message_id: sourceMessageId } : {}),\n };\n return { event_type: 'screen_view', data };\n}\n\n/**\n * Builds a commerce_event payload. Commerce data is a loosely-shaped subset\n * of {@link CommerceEventData} (product_action, currency_code, ...) resolved\n * from the per-rule commerce mapping.\n */\nexport function buildCommerceEvent(\n commerceData: Partial<CommerceEventData> | undefined,\n customAttributes: Record<string, unknown> | undefined,\n timestamp: number | undefined,\n sourceMessageId: string | undefined,\n): MParticleEvent {\n const data: CommerceEventData = {\n ...(commerceData || {}),\n ...(customAttributes && Object.keys(customAttributes).length > 0\n ? { custom_attributes: customAttributes }\n : {}),\n ...(timestamp !== undefined ? { timestamp_unixtime_ms: timestamp } : {}),\n ...(sourceMessageId ? { source_message_id: sourceMessageId } : {}),\n };\n return { event_type: 'commerce_event', data };\n}\n\nexport interface BuildBatchOptions {\n ip?: string;\n sourceRequestId?: string;\n consent?: ConsentState;\n context?: Record<string, unknown>;\n}\n\n/**\n * Assembles the batch envelope wrapping events + identity + environment.\n */\nexport function buildBatch(\n events: MParticleEvent[],\n userIdentities: Record<string, string | number> | undefined,\n userAttributes: Record<string, unknown> | undefined,\n environment: Environment,\n options: BuildBatchOptions = {},\n): MParticleBatch {\n const batch: MParticleBatch = {\n events,\n environment,\n };\n if (userIdentities && Object.keys(userIdentities).length > 0)\n batch.user_identities = userIdentities;\n if (userAttributes && Object.keys(userAttributes).length > 0)\n batch.user_attributes = userAttributes;\n if (options.ip) batch.ip = options.ip;\n if (options.sourceRequestId)\n batch.source_request_id = options.sourceRequestId;\n if (options.consent) batch.consent_state = options.consent;\n if (options.context) batch.context = options.context;\n return batch;\n}\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer, sendServer } from '@walkeros/server-core';\n\n/**\n * mParticle data pod. Determines the regional endpoint used for the Events\n * API. Defaults to `us1`. See {@link buildEndpoint} in `batch.ts`.\n */\nexport type Pod = 'us1' | 'us2' | 'eu1' | 'au1';\n\n/**\n * mParticle environment for the batch. `production` routes to production\n * data streams; `development` sends to debug/verify streams.\n */\nexport type Environment = 'production' | 'development';\n\n/**\n * Event type used for the outgoing mParticle event. Defaults to\n * `custom_event` when not explicitly mapped via rule settings.\n */\nexport type EventType = 'custom_event' | 'screen_view' | 'commerce_event';\n\n/**\n * mParticle custom event type (category) for `custom_event`s. Defaults to\n * `other` when not specified.\n */\nexport type CustomEventType =\n | 'navigation'\n | 'location'\n | 'search'\n | 'transaction'\n | 'user_content'\n | 'user_preference'\n | 'social'\n | 'media'\n | 'attribution'\n | 'other';\n\n/**\n * mParticle product action verbs for commerce events.\n */\nexport type ProductActionType =\n | 'add_to_cart'\n | 'remove_from_cart'\n | 'checkout'\n | 'checkout_option'\n | 'click'\n | 'view_detail'\n | 'purchase'\n | 'refund'\n | 'add_to_wishlist'\n | 'remove_from_wishlist';\n\nexport interface Settings {\n /** mParticle input feed API key. */\n apiKey: string;\n /** mParticle input feed API secret. */\n apiSecret: string;\n /** Data pod selecting the regional endpoint. Default: `us1`. */\n pod?: Pod;\n /** Environment the batch targets. Default: `production`. */\n environment?: Environment;\n /**\n * Mapping that resolves to `user_identities` per batch. Each entry value\n * is a walkerOS mapping value; the resolved object is placed into the\n * mParticle batch `user_identities` envelope.\n */\n userIdentities?: WalkerOSMapping.Map;\n /**\n * Mapping that resolves to `user_attributes` per batch.\n */\n userAttributes?: WalkerOSMapping.Value;\n /**\n * Optional static consent state passthrough — shape is forwarded verbatim\n * to `consent_state` on the batch.\n */\n consent?: ConsentState;\n /** walkerOS mapping value resolving to the client IP for the batch. */\n ip?: WalkerOSMapping.Value;\n /**\n * Optional request correlation id. When omitted, falls back to `event.id`.\n */\n sourceRequestId?: WalkerOSMapping.Value;\n}\n\nexport type InitSettings = Partial<Settings>;\n\n/**\n * Per-rule mapping settings. Determines which mParticle event shape is\n * produced for this walkerOS event and allows per-event identity overrides.\n */\nexport interface Mapping {\n /** Event type. Default: `custom_event`. */\n eventType?: EventType;\n /** Custom event type category for `custom_event`. Default: `other`. */\n customEventType?: CustomEventType;\n /** Commerce mapping resolving to ProductAction and related fields. */\n commerce?: WalkerOSMapping.Value;\n /** Per-event override for `user_identities`. Merged over settings. */\n userIdentities?: WalkerOSMapping.Map;\n /** Per-event override for `user_attributes`. */\n userAttributes?: WalkerOSMapping.Value;\n}\n\nexport interface Env extends DestinationServer.Env {\n sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n/**\n * Top-level mParticle batch payload posted to\n * `https://s2s.{pod}.mparticle.com/v2/events`.\n * https://docs.mparticle.com/developers/server/http/\n */\nexport interface MParticleBatch {\n events: MParticleEvent[];\n user_identities?: Record<string, string | number>;\n user_attributes?: Record<string, unknown>;\n environment: Environment;\n schema_version?: number;\n ip?: string;\n source_request_id?: string;\n consent_state?: ConsentState;\n context?: Record<string, unknown>;\n}\n\nexport type MParticleEvent =\n | { event_type: 'custom_event'; data: CustomEventData }\n | { event_type: 'screen_view'; data: ScreenViewEventData }\n | { event_type: 'commerce_event'; data: CommerceEventData };\n\nexport interface CommonEventData {\n timestamp_unixtime_ms?: number;\n source_message_id?: string;\n session_uuid?: string;\n custom_attributes?: Record<string, unknown>;\n custom_flags?: Record<string, unknown>;\n location?: Record<string, unknown>;\n}\n\nexport interface CustomEventData extends CommonEventData {\n event_name: string;\n custom_event_type: CustomEventType;\n}\n\nexport interface ScreenViewEventData extends CommonEventData {\n screen_name?: string;\n}\n\nexport interface CommerceEventData extends CommonEventData {\n product_action?: ProductAction;\n promotion_action?: PromotionAction;\n product_impressions?: ProductImpression[];\n currency_code?: string;\n is_non_interactive?: boolean;\n}\n\nexport interface ProductAction {\n action: ProductActionType;\n transaction_id?: string;\n total_amount?: number;\n tax_amount?: number;\n shipping_amount?: number;\n coupon_code?: string;\n affiliation?: string;\n checkout_step?: number;\n checkout_options?: string;\n products?: Product[];\n}\n\nexport interface Product {\n id?: string;\n name?: string;\n brand?: string;\n category?: string;\n variant?: string;\n position?: number;\n price?: number;\n quantity?: number;\n coupon_code?: string;\n total_product_amount?: number;\n custom_attributes?: Record<string, unknown>;\n}\n\nexport interface PromotionAction {\n action: 'view' | 'click';\n promotions?: Array<{\n id?: string;\n name?: string;\n creative?: string;\n position?: string;\n }>;\n}\n\nexport interface ProductImpression {\n product_impression_list?: string;\n products?: Product[];\n}\n\n/**\n * mParticle consent state envelope forwarded verbatim on the batch.\n * https://docs.mparticle.com/developers/server/http/#consent-state\n */\nexport interface ConsentState {\n gdpr?: Record<string, GDPRConsentState>;\n ccpa?: { data_sale_opt_out?: CCPAConsentState };\n}\n\nexport interface GDPRConsentState {\n consented: boolean;\n document?: string;\n timestamp_unixtime_ms?: number;\n location?: string;\n hardware_id?: string;\n}\n\nexport interface CCPAConsentState {\n consented: boolean;\n document?: string;\n timestamp_unixtime_ms?: number;\n location?: string;\n hardware_id?: string;\n}\n","import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationMParticle from './types';\n\nexport const destinationMParticle: Destination = {\n type: 'mparticle',\n\n config: {},\n\n async init({ config: partialConfig, logger }) {\n const config = getConfig(partialConfig, logger);\n return config;\n },\n\n async push(event, context) {\n return await push(event, context);\n },\n};\n\nexport default destinationMParticle;\n"],"mappings":"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","names":[]}