@sygnl/mapper 1.0.0
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 +130 -0
- package/dist/index.cjs +299 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +280 -0
- package/dist/index.d.ts +280 -0
- package/dist/index.js +277 -0
- package/dist/index.js.map +1 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# @sygnl/mapper
|
|
2
|
+
|
|
3
|
+
Declarative event mapper for transforming events between different ad platform formats.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @sygnl/mapper
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { EventMapper, transforms } from '@sygnl/mapper';
|
|
15
|
+
|
|
16
|
+
const mapper = new EventMapper({
|
|
17
|
+
eventNames: [
|
|
18
|
+
{ from: 'purchase', to: 'Purchase' }
|
|
19
|
+
],
|
|
20
|
+
fields: [
|
|
21
|
+
{ from: 'user.email', to: 'userData.em' },
|
|
22
|
+
{ from: 'timestamp', to: 'event_time', transform: transforms.msToSeconds }
|
|
23
|
+
],
|
|
24
|
+
static: [
|
|
25
|
+
{ to: 'action_source', value: 'website' }
|
|
26
|
+
]
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const result = mapper.map(sourceEvent);
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Use Cases
|
|
33
|
+
|
|
34
|
+
- Map events to Meta CAPI format
|
|
35
|
+
- Transform for Google Enhanced Conversions
|
|
36
|
+
- Adapt to Snapchat/TikTok/Bing APIs
|
|
37
|
+
- Build platform-agnostic event pipelines
|
|
38
|
+
- Define mappings once, reuse everywhere
|
|
39
|
+
|
|
40
|
+
## API
|
|
41
|
+
|
|
42
|
+
### `EventMapper`
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
const mapper = new EventMapper({
|
|
46
|
+
eventNames?: EventNameMapping[],
|
|
47
|
+
fields?: FieldMapping[],
|
|
48
|
+
static?: StaticField[],
|
|
49
|
+
sourceRoot?: string,
|
|
50
|
+
targetRoot?: string
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const result = mapper.map(source);
|
|
54
|
+
const results = mapper.mapBatch(sources);
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Field Mapping
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
{
|
|
61
|
+
from: 'source.path' | ['path1', 'path2'], // Fallback sources
|
|
62
|
+
to: 'target.path',
|
|
63
|
+
transform?: (value, source) => any,
|
|
64
|
+
condition?: (source) => boolean,
|
|
65
|
+
default?: any,
|
|
66
|
+
skipFalsy?: boolean
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Transforms
|
|
71
|
+
|
|
72
|
+
Built-in transforms for common conversions:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { transforms } from '@sygnl/mapper';
|
|
76
|
+
|
|
77
|
+
transforms.msToSeconds(timestamp); // 1704067200000 → 1704067200
|
|
78
|
+
transforms.lowercase(str); // "EMAIL" → "email"
|
|
79
|
+
transforms.toArray(value); // "foo" → ["foo"]
|
|
80
|
+
transforms.pluck('id')(array); // [{id:1},{id:2}] → [1,2]
|
|
81
|
+
transforms.pipe(fn1, fn2, fn3); // Compose transforms
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Examples
|
|
85
|
+
|
|
86
|
+
### Meta CAPI Mapping
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
const metaMapper = new EventMapper({
|
|
90
|
+
eventNames: [
|
|
91
|
+
{ from: ['purchase', 'order_completed'], to: 'Purchase' }
|
|
92
|
+
],
|
|
93
|
+
fields: [
|
|
94
|
+
{ from: 'timestamp', to: 'event_time', transform: transforms.msToSeconds },
|
|
95
|
+
{ from: 'user.email', to: 'user_data.em' },
|
|
96
|
+
{ from: 'products', to: 'custom_data.content_ids', transform: transforms.pluck('id') },
|
|
97
|
+
{ from: 'value', to: 'custom_data.value' }
|
|
98
|
+
],
|
|
99
|
+
static: [
|
|
100
|
+
{ to: 'action_source', value: 'website' }
|
|
101
|
+
],
|
|
102
|
+
targetRoot: 'data.0'
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Conditional Mapping
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
{
|
|
110
|
+
from: 'revenue',
|
|
111
|
+
to: 'purchase_value',
|
|
112
|
+
condition: (source) => source.event_type === 'purchase',
|
|
113
|
+
transform: (value) => Math.round(value * 100) / 100
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Multiple Source Fallbacks
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
{
|
|
121
|
+
from: ['user.email', 'email', 'user_email'],
|
|
122
|
+
to: 'email'
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## License
|
|
127
|
+
|
|
128
|
+
Apache-2.0
|
|
129
|
+
|
|
130
|
+
Copyright 2026 Edge Foundry, Inc.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
EventMapper: () => EventMapper,
|
|
24
|
+
transforms: () => transforms_exports
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(index_exports);
|
|
27
|
+
|
|
28
|
+
// src/EventMapper.ts
|
|
29
|
+
var EventMapper = class {
|
|
30
|
+
constructor(config) {
|
|
31
|
+
this.config = config;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Map an event from source format to target format
|
|
35
|
+
*/
|
|
36
|
+
map(source) {
|
|
37
|
+
const result = {
|
|
38
|
+
data: {},
|
|
39
|
+
mappedFields: [],
|
|
40
|
+
skippedFields: [],
|
|
41
|
+
errors: []
|
|
42
|
+
};
|
|
43
|
+
try {
|
|
44
|
+
const sourceData = this.config.sourceRoot ? this.getValueAtPath(source, this.config.sourceRoot) : source;
|
|
45
|
+
if (this.config.eventNames) {
|
|
46
|
+
const eventName = this.mapEventName(sourceData);
|
|
47
|
+
if (eventName) {
|
|
48
|
+
this.setValueAtPath(result.data, "event_name", eventName);
|
|
49
|
+
result.mappedFields.push("event_name");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (this.config.fields) {
|
|
53
|
+
for (const fieldMapping of this.config.fields) {
|
|
54
|
+
this.mapField(sourceData, result.data, fieldMapping, result);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (this.config.static) {
|
|
58
|
+
for (const staticField of this.config.static) {
|
|
59
|
+
this.mapStaticField(sourceData, result.data, staticField, result);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (this.config.targetRoot) {
|
|
63
|
+
const wrapped = {};
|
|
64
|
+
this.setValueAtPath(wrapped, this.config.targetRoot, result.data);
|
|
65
|
+
result.data = wrapped;
|
|
66
|
+
}
|
|
67
|
+
} catch (error) {
|
|
68
|
+
result.errors.push({
|
|
69
|
+
field: "_root",
|
|
70
|
+
error: error instanceof Error ? error.message : String(error)
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Map event name using event name mappings
|
|
77
|
+
*/
|
|
78
|
+
mapEventName(source) {
|
|
79
|
+
if (!this.config.eventNames) return void 0;
|
|
80
|
+
const sourceEventName = source.event_type || source.eventType || source.event_name;
|
|
81
|
+
if (!sourceEventName) return void 0;
|
|
82
|
+
for (const mapping of this.config.eventNames) {
|
|
83
|
+
const fromNames = Array.isArray(mapping.from) ? mapping.from : [mapping.from];
|
|
84
|
+
if (fromNames.includes(sourceEventName)) {
|
|
85
|
+
return mapping.to;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return void 0;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Map a single field
|
|
92
|
+
*/
|
|
93
|
+
mapField(source, target, mapping, result) {
|
|
94
|
+
try {
|
|
95
|
+
if (mapping.condition && !mapping.condition(source)) {
|
|
96
|
+
result.skippedFields.push(mapping.to);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const fromPaths = Array.isArray(mapping.from) ? mapping.from : [mapping.from];
|
|
100
|
+
let value = void 0;
|
|
101
|
+
for (const fromPath of fromPaths) {
|
|
102
|
+
value = this.getValueAtPath(source, fromPath);
|
|
103
|
+
if (value !== void 0 && value !== null) break;
|
|
104
|
+
}
|
|
105
|
+
if (value === void 0 || value === null) {
|
|
106
|
+
if (mapping.default !== void 0) {
|
|
107
|
+
value = mapping.default;
|
|
108
|
+
} else {
|
|
109
|
+
result.skippedFields.push(mapping.to);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (mapping.skipFalsy && !value) {
|
|
114
|
+
result.skippedFields.push(mapping.to);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (mapping.transform) {
|
|
118
|
+
value = mapping.transform(value, source);
|
|
119
|
+
}
|
|
120
|
+
this.setValueAtPath(target, mapping.to, value);
|
|
121
|
+
result.mappedFields.push(mapping.to);
|
|
122
|
+
} catch (error) {
|
|
123
|
+
result.errors.push({
|
|
124
|
+
field: mapping.to,
|
|
125
|
+
error: error instanceof Error ? error.message : String(error)
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Map a static field
|
|
131
|
+
*/
|
|
132
|
+
mapStaticField(source, target, staticField, result) {
|
|
133
|
+
try {
|
|
134
|
+
const value = typeof staticField.value === "function" ? staticField.value(source) : staticField.value;
|
|
135
|
+
this.setValueAtPath(target, staticField.to, value);
|
|
136
|
+
result.mappedFields.push(staticField.to);
|
|
137
|
+
} catch (error) {
|
|
138
|
+
result.errors.push({
|
|
139
|
+
field: staticField.to,
|
|
140
|
+
error: error instanceof Error ? error.message : String(error)
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Get value at path using dot notation
|
|
146
|
+
* Supports array indexing (e.g., 'products.0.id')
|
|
147
|
+
*/
|
|
148
|
+
getValueAtPath(obj, path) {
|
|
149
|
+
const parts = path.split(".");
|
|
150
|
+
let value = obj;
|
|
151
|
+
for (const part of parts) {
|
|
152
|
+
if (value === void 0 || value === null) return void 0;
|
|
153
|
+
if (/^\d+$/.test(part)) {
|
|
154
|
+
value = value[parseInt(part, 10)];
|
|
155
|
+
} else {
|
|
156
|
+
value = value[part];
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return value;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Set value at path using dot notation
|
|
163
|
+
* Creates nested objects/arrays as needed
|
|
164
|
+
*/
|
|
165
|
+
setValueAtPath(obj, path, value) {
|
|
166
|
+
const parts = path.split(".");
|
|
167
|
+
let current = obj;
|
|
168
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
169
|
+
const part = parts[i];
|
|
170
|
+
const nextPart = parts[i + 1];
|
|
171
|
+
if (current[part] === void 0 || current[part] === null) {
|
|
172
|
+
if (/^\d+$/.test(nextPart)) {
|
|
173
|
+
current[part] = [];
|
|
174
|
+
} else {
|
|
175
|
+
current[part] = {};
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
current = current[part];
|
|
179
|
+
}
|
|
180
|
+
const lastPart = parts[parts.length - 1];
|
|
181
|
+
if (/^\d+$/.test(lastPart)) {
|
|
182
|
+
const index = parseInt(lastPart, 10);
|
|
183
|
+
if (!Array.isArray(current)) {
|
|
184
|
+
throw new Error(`Cannot set array index ${index} on non-array`);
|
|
185
|
+
}
|
|
186
|
+
current[index] = value;
|
|
187
|
+
} else {
|
|
188
|
+
current[lastPart] = value;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Batch map multiple events
|
|
193
|
+
*/
|
|
194
|
+
mapBatch(sources) {
|
|
195
|
+
return sources.map((source) => this.map(source));
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
// src/transforms.ts
|
|
200
|
+
var transforms_exports = {};
|
|
201
|
+
__export(transforms_exports, {
|
|
202
|
+
compose: () => compose,
|
|
203
|
+
first: () => first,
|
|
204
|
+
fromISO: () => fromISO,
|
|
205
|
+
identity: () => identity,
|
|
206
|
+
join: () => join,
|
|
207
|
+
lowercase: () => lowercase,
|
|
208
|
+
msToSeconds: () => msToSeconds,
|
|
209
|
+
omit: () => omit,
|
|
210
|
+
pick: () => pick,
|
|
211
|
+
pipe: () => pipe,
|
|
212
|
+
pluck: () => pluck,
|
|
213
|
+
renameKeys: () => renameKeys,
|
|
214
|
+
round: () => round,
|
|
215
|
+
secondsToMs: () => secondsToMs,
|
|
216
|
+
split: () => split,
|
|
217
|
+
toArray: () => toArray,
|
|
218
|
+
toBoolean: () => toBoolean,
|
|
219
|
+
toISO: () => toISO,
|
|
220
|
+
toNumber: () => toNumber,
|
|
221
|
+
toString: () => toString,
|
|
222
|
+
trim: () => trim,
|
|
223
|
+
uppercase: () => uppercase
|
|
224
|
+
});
|
|
225
|
+
var msToSeconds = (ms) => Math.floor(ms / 1e3);
|
|
226
|
+
var secondsToMs = (seconds) => seconds * 1e3;
|
|
227
|
+
var lowercase = (str) => str.toLowerCase();
|
|
228
|
+
var uppercase = (str) => str.toUpperCase();
|
|
229
|
+
var trim = (str) => str.trim();
|
|
230
|
+
var toString = (value) => String(value);
|
|
231
|
+
var toNumber = (value) => Number(value);
|
|
232
|
+
var toBoolean = (value) => Boolean(value);
|
|
233
|
+
var toArray = (value) => {
|
|
234
|
+
if (Array.isArray(value)) return value;
|
|
235
|
+
return [value];
|
|
236
|
+
};
|
|
237
|
+
var first = (value) => {
|
|
238
|
+
if (Array.isArray(value)) return value[0];
|
|
239
|
+
return value;
|
|
240
|
+
};
|
|
241
|
+
var pluck = (property) => (arr) => {
|
|
242
|
+
if (!Array.isArray(arr)) return [];
|
|
243
|
+
return arr.map((item) => item[property]);
|
|
244
|
+
};
|
|
245
|
+
var join = (separator = ",") => (arr) => {
|
|
246
|
+
if (!Array.isArray(arr)) return String(arr);
|
|
247
|
+
return arr.join(separator);
|
|
248
|
+
};
|
|
249
|
+
var split = (separator = ",") => (str) => {
|
|
250
|
+
return str.split(separator);
|
|
251
|
+
};
|
|
252
|
+
var toISO = (timestamp) => {
|
|
253
|
+
return new Date(timestamp).toISOString();
|
|
254
|
+
};
|
|
255
|
+
var fromISO = (iso) => {
|
|
256
|
+
return new Date(iso).getTime();
|
|
257
|
+
};
|
|
258
|
+
var round = (decimals = 0) => (num) => {
|
|
259
|
+
const factor = Math.pow(10, decimals);
|
|
260
|
+
return Math.round(num * factor) / factor;
|
|
261
|
+
};
|
|
262
|
+
var compose = (...fns) => {
|
|
263
|
+
return (value) => fns.reduceRight((acc, fn) => fn(acc), value);
|
|
264
|
+
};
|
|
265
|
+
var pipe = (...fns) => {
|
|
266
|
+
return (value) => fns.reduce((acc, fn) => fn(acc), value);
|
|
267
|
+
};
|
|
268
|
+
var identity = (value) => value;
|
|
269
|
+
var renameKeys = (keyMap) => (obj) => {
|
|
270
|
+
const result = {};
|
|
271
|
+
for (const [oldKey, newKey] of Object.entries(keyMap)) {
|
|
272
|
+
if (obj[oldKey] !== void 0) {
|
|
273
|
+
result[newKey] = obj[oldKey];
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return result;
|
|
277
|
+
};
|
|
278
|
+
var pick = (...keys) => (obj) => {
|
|
279
|
+
const result = {};
|
|
280
|
+
for (const key of keys) {
|
|
281
|
+
if (obj[key] !== void 0) {
|
|
282
|
+
result[key] = obj[key];
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return result;
|
|
286
|
+
};
|
|
287
|
+
var omit = (...keys) => (obj) => {
|
|
288
|
+
const result = { ...obj };
|
|
289
|
+
for (const key of keys) {
|
|
290
|
+
delete result[key];
|
|
291
|
+
}
|
|
292
|
+
return result;
|
|
293
|
+
};
|
|
294
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
295
|
+
0 && (module.exports = {
|
|
296
|
+
EventMapper,
|
|
297
|
+
transforms
|
|
298
|
+
});
|
|
299
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/EventMapper.ts","../src/transforms.ts"],"sourcesContent":["/**\n * @sygnl/mapper\n * \n * Declarative event mapper for transforming events between different ad platform formats.\n * \n * @example\n * ```typescript\n * import { EventMapper, msToSeconds } from '@sygnl/mapper';\n * \n * const mapper = new EventMapper({\n * eventNames: [\n * { from: 'purchase', to: 'Purchase' }\n * ],\n * fields: [\n * { from: 'user.email', to: 'userData.em' },\n * { from: 'timestamp', to: 'event_time', transform: msToSeconds }\n * ]\n * });\n * \n * const result = mapper.map(sourceEvent);\n * ```\n */\n\nexport { EventMapper } from './EventMapper';\nexport type {\n MapperConfig,\n FieldMapping,\n EventNameMapping,\n StaticField,\n MappingResult,\n TransformFn,\n ConditionFn,\n} from './types';\nexport * as transforms from './transforms';\n","/**\n * EventMapper - Declarative event transformation\n * \n * Map events from one format to another using simple configuration.\n * Perfect for ad platform integrations (Meta, Google, Snapchat, etc.)\n */\n\nimport type {\n MapperConfig,\n FieldMapping,\n EventNameMapping,\n StaticField,\n MappingResult,\n} from './types';\n\nexport class EventMapper {\n private config: MapperConfig;\n\n constructor(config: MapperConfig) {\n this.config = config;\n }\n\n /**\n * Map an event from source format to target format\n */\n map<T = any>(source: any): MappingResult<T> {\n const result: MappingResult<T> = {\n data: {} as T,\n mappedFields: [],\n skippedFields: [],\n errors: [],\n };\n\n try {\n // Start with source root if specified\n const sourceData = this.config.sourceRoot\n ? this.getValueAtPath(source, this.config.sourceRoot)\n : source;\n\n // Map event names\n if (this.config.eventNames) {\n const eventName = this.mapEventName(sourceData);\n if (eventName) {\n this.setValueAtPath(result.data, 'event_name', eventName);\n result.mappedFields.push('event_name');\n }\n }\n\n // Map fields\n if (this.config.fields) {\n for (const fieldMapping of this.config.fields) {\n this.mapField(sourceData, result.data, fieldMapping, result);\n }\n }\n\n // Add static fields\n if (this.config.static) {\n for (const staticField of this.config.static) {\n this.mapStaticField(sourceData, result.data, staticField, result);\n }\n }\n\n // Apply target root if specified\n if (this.config.targetRoot) {\n const wrapped: any = {};\n this.setValueAtPath(wrapped, this.config.targetRoot, result.data);\n result.data = wrapped as T;\n }\n } catch (error) {\n result.errors.push({\n field: '_root',\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n return result;\n }\n\n /**\n * Map event name using event name mappings\n */\n private mapEventName(source: any): string | undefined {\n if (!this.config.eventNames) return undefined;\n\n // Try to find event_type in source\n const sourceEventName = source.event_type || source.eventType || source.event_name;\n if (!sourceEventName) return undefined;\n\n // Find matching mapping\n for (const mapping of this.config.eventNames) {\n const fromNames = Array.isArray(mapping.from) ? mapping.from : [mapping.from];\n if (fromNames.includes(sourceEventName)) {\n return mapping.to;\n }\n }\n\n return undefined;\n }\n\n /**\n * Map a single field\n */\n private mapField(\n source: any,\n target: any,\n mapping: FieldMapping,\n result: MappingResult\n ): void {\n try {\n // Check condition\n if (mapping.condition && !mapping.condition(source)) {\n result.skippedFields.push(mapping.to);\n return;\n }\n\n // Get source value(s)\n const fromPaths = Array.isArray(mapping.from) ? mapping.from : [mapping.from];\n let value: any = undefined;\n\n // Try each source path until we find a value\n for (const fromPath of fromPaths) {\n value = this.getValueAtPath(source, fromPath);\n if (value !== undefined && value !== null) break;\n }\n\n // Use default if no value found\n if (value === undefined || value === null) {\n if (mapping.default !== undefined) {\n value = mapping.default;\n } else {\n result.skippedFields.push(mapping.to);\n return;\n }\n }\n\n // Skip falsy values if configured\n if (mapping.skipFalsy && !value) {\n result.skippedFields.push(mapping.to);\n return;\n }\n\n // Apply transform\n if (mapping.transform) {\n value = mapping.transform(value, source);\n }\n\n // Set target value\n this.setValueAtPath(target, mapping.to, value);\n result.mappedFields.push(mapping.to);\n } catch (error) {\n result.errors.push({\n field: mapping.to,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Map a static field\n */\n private mapStaticField(\n source: any,\n target: any,\n staticField: StaticField,\n result: MappingResult\n ): void {\n try {\n const value =\n typeof staticField.value === 'function'\n ? staticField.value(source)\n : staticField.value;\n\n this.setValueAtPath(target, staticField.to, value);\n result.mappedFields.push(staticField.to);\n } catch (error) {\n result.errors.push({\n field: staticField.to,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Get value at path using dot notation\n * Supports array indexing (e.g., 'products.0.id')\n */\n private getValueAtPath(obj: any, path: string): any {\n const parts = path.split('.');\n let value = obj;\n\n for (const part of parts) {\n if (value === undefined || value === null) return undefined;\n\n // Handle array index\n if (/^\\d+$/.test(part)) {\n value = value[parseInt(part, 10)];\n } else {\n value = value[part];\n }\n }\n\n return value;\n }\n\n /**\n * Set value at path using dot notation\n * Creates nested objects/arrays as needed\n */\n private setValueAtPath(obj: any, path: string, value: any): void {\n const parts = path.split('.');\n let current = obj;\n\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n const nextPart = parts[i + 1];\n\n // Create nested structure if needed\n if (current[part] === undefined || current[part] === null) {\n // Next part is array index\n if (/^\\d+$/.test(nextPart)) {\n current[part] = [];\n } else {\n current[part] = {};\n }\n }\n\n current = current[part];\n }\n\n const lastPart = parts[parts.length - 1];\n\n // Handle array index\n if (/^\\d+$/.test(lastPart)) {\n const index = parseInt(lastPart, 10);\n if (!Array.isArray(current)) {\n throw new Error(`Cannot set array index ${index} on non-array`);\n }\n current[index] = value;\n } else {\n current[lastPart] = value;\n }\n }\n\n /**\n * Batch map multiple events\n */\n mapBatch<T = any>(sources: any[]): MappingResult<T>[] {\n return sources.map((source) => this.map<T>(source));\n }\n}\n","/**\n * Common transform functions for event mapping\n */\n\n/**\n * Convert milliseconds to seconds\n */\nexport const msToSeconds = (ms: number): number => Math.floor(ms / 1000);\n\n/**\n * Convert seconds to milliseconds\n */\nexport const secondsToMs = (seconds: number): number => seconds * 1000;\n\n/**\n * Lowercase string\n */\nexport const lowercase = (str: string): string => str.toLowerCase();\n\n/**\n * Uppercase string\n */\nexport const uppercase = (str: string): string => str.toUpperCase();\n\n/**\n * Trim whitespace\n */\nexport const trim = (str: string): string => str.trim();\n\n/**\n * Convert to string\n */\nexport const toString = (value: any): string => String(value);\n\n/**\n * Convert to number\n */\nexport const toNumber = (value: any): number => Number(value);\n\n/**\n * Convert to boolean\n */\nexport const toBoolean = (value: any): boolean => Boolean(value);\n\n/**\n * Wrap value in array\n */\nexport const toArray = (value: any): any[] => {\n if (Array.isArray(value)) return value;\n return [value];\n};\n\n/**\n * Get first element of array, or value if not array\n */\nexport const first = (value: any): any => {\n if (Array.isArray(value)) return value[0];\n return value;\n};\n\n/**\n * Map array of objects to array of property values\n */\nexport const pluck = (property: string) => (arr: any[]): any[] => {\n if (!Array.isArray(arr)) return [];\n return arr.map((item) => item[property]);\n};\n\n/**\n * Join array into string\n */\nexport const join = (separator: string = ',') => (arr: any[]): string => {\n if (!Array.isArray(arr)) return String(arr);\n return arr.join(separator);\n};\n\n/**\n * Split string into array\n */\nexport const split = (separator: string = ',') => (str: string): string[] => {\n return str.split(separator);\n};\n\n/**\n * Format date as ISO 8601\n */\nexport const toISO = (timestamp: number): string => {\n return new Date(timestamp).toISOString();\n};\n\n/**\n * Parse ISO date to timestamp\n */\nexport const fromISO = (iso: string): number => {\n return new Date(iso).getTime();\n};\n\n/**\n * Round number to decimals\n */\nexport const round = (decimals: number = 0) => (num: number): number => {\n const factor = Math.pow(10, decimals);\n return Math.round(num * factor) / factor;\n};\n\n/**\n * Compose multiple transforms (right to left)\n */\nexport const compose = (...fns: ((value: any) => any)[]): ((value: any) => any) => {\n return (value: any) => fns.reduceRight((acc, fn) => fn(acc), value);\n};\n\n/**\n * Pipe multiple transforms (left to right)\n */\nexport const pipe = (...fns: ((value: any) => any)[]): ((value: any) => any) => {\n return (value: any) => fns.reduce((acc, fn) => fn(acc), value);\n};\n\n/**\n * Return value as-is (identity function)\n */\nexport const identity = (value: any): any => value;\n\n/**\n * Rename object keys\n */\nexport const renameKeys = (keyMap: Record<string, string>) => (obj: any): any => {\n const result: any = {};\n for (const [oldKey, newKey] of Object.entries(keyMap)) {\n if (obj[oldKey] !== undefined) {\n result[newKey] = obj[oldKey];\n }\n }\n return result;\n};\n\n/**\n * Pick specific keys from object\n */\nexport const pick = (...keys: string[]) => (obj: any): any => {\n const result: any = {};\n for (const key of keys) {\n if (obj[key] !== undefined) {\n result[key] = obj[key];\n }\n }\n return result;\n};\n\n/**\n * Omit specific keys from object\n */\nexport const omit = (...keys: string[]) => (obj: any): any => {\n const result = { ...obj };\n for (const key of keys) {\n delete result[key];\n }\n return result;\n};\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for event mapper
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Transform function to modify a value during mapping
|
|
6
|
+
*/
|
|
7
|
+
type TransformFn = (value: any, source: any) => any;
|
|
8
|
+
/**
|
|
9
|
+
* Condition function to determine if mapping should apply
|
|
10
|
+
*/
|
|
11
|
+
type ConditionFn = (source: any) => boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Field mapping configuration
|
|
14
|
+
*/
|
|
15
|
+
interface FieldMapping {
|
|
16
|
+
/**
|
|
17
|
+
* Source path in dot notation (e.g., 'user.email', 'products.0.id')
|
|
18
|
+
*/
|
|
19
|
+
from: string | string[];
|
|
20
|
+
/**
|
|
21
|
+
* Target path in dot notation (e.g., 'userData.em', 'items.0.id')
|
|
22
|
+
*/
|
|
23
|
+
to: string;
|
|
24
|
+
/**
|
|
25
|
+
* Optional transform function to modify value
|
|
26
|
+
*/
|
|
27
|
+
transform?: TransformFn;
|
|
28
|
+
/**
|
|
29
|
+
* Optional condition - only map if this returns true
|
|
30
|
+
*/
|
|
31
|
+
condition?: ConditionFn;
|
|
32
|
+
/**
|
|
33
|
+
* Default value if source is undefined/null
|
|
34
|
+
*/
|
|
35
|
+
default?: any;
|
|
36
|
+
/**
|
|
37
|
+
* Whether to skip if value is falsy
|
|
38
|
+
* @default false
|
|
39
|
+
*/
|
|
40
|
+
skipFalsy?: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Event name mapping configuration
|
|
44
|
+
*/
|
|
45
|
+
interface EventNameMapping {
|
|
46
|
+
/**
|
|
47
|
+
* Source event name or names
|
|
48
|
+
*/
|
|
49
|
+
from: string | string[];
|
|
50
|
+
/**
|
|
51
|
+
* Target event name
|
|
52
|
+
*/
|
|
53
|
+
to: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Static field to always add to output
|
|
57
|
+
*/
|
|
58
|
+
interface StaticField {
|
|
59
|
+
/**
|
|
60
|
+
* Target path
|
|
61
|
+
*/
|
|
62
|
+
to: string;
|
|
63
|
+
/**
|
|
64
|
+
* Static value or function to generate value
|
|
65
|
+
*/
|
|
66
|
+
value: any | ((source: any) => any);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Mapper configuration
|
|
70
|
+
*/
|
|
71
|
+
interface MapperConfig {
|
|
72
|
+
/**
|
|
73
|
+
* Event name mappings
|
|
74
|
+
*/
|
|
75
|
+
eventNames?: EventNameMapping[];
|
|
76
|
+
/**
|
|
77
|
+
* Field mappings
|
|
78
|
+
*/
|
|
79
|
+
fields?: FieldMapping[];
|
|
80
|
+
/**
|
|
81
|
+
* Static fields to always include
|
|
82
|
+
*/
|
|
83
|
+
static?: StaticField[];
|
|
84
|
+
/**
|
|
85
|
+
* Root path for source data
|
|
86
|
+
* @example 'data' to read from source.data.*
|
|
87
|
+
*/
|
|
88
|
+
sourceRoot?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Root path for target data
|
|
91
|
+
* @example 'data.0' to write to target.data[0].*
|
|
92
|
+
*/
|
|
93
|
+
targetRoot?: string;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Mapping result
|
|
97
|
+
*/
|
|
98
|
+
interface MappingResult<T = any> {
|
|
99
|
+
/**
|
|
100
|
+
* Mapped data
|
|
101
|
+
*/
|
|
102
|
+
data: T;
|
|
103
|
+
/**
|
|
104
|
+
* Fields that were mapped
|
|
105
|
+
*/
|
|
106
|
+
mappedFields: string[];
|
|
107
|
+
/**
|
|
108
|
+
* Fields that were skipped (condition/falsy)
|
|
109
|
+
*/
|
|
110
|
+
skippedFields: string[];
|
|
111
|
+
/**
|
|
112
|
+
* Errors encountered during mapping
|
|
113
|
+
*/
|
|
114
|
+
errors: Array<{
|
|
115
|
+
field: string;
|
|
116
|
+
error: string;
|
|
117
|
+
}>;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* EventMapper - Declarative event transformation
|
|
122
|
+
*
|
|
123
|
+
* Map events from one format to another using simple configuration.
|
|
124
|
+
* Perfect for ad platform integrations (Meta, Google, Snapchat, etc.)
|
|
125
|
+
*/
|
|
126
|
+
|
|
127
|
+
declare class EventMapper {
|
|
128
|
+
private config;
|
|
129
|
+
constructor(config: MapperConfig);
|
|
130
|
+
/**
|
|
131
|
+
* Map an event from source format to target format
|
|
132
|
+
*/
|
|
133
|
+
map<T = any>(source: any): MappingResult<T>;
|
|
134
|
+
/**
|
|
135
|
+
* Map event name using event name mappings
|
|
136
|
+
*/
|
|
137
|
+
private mapEventName;
|
|
138
|
+
/**
|
|
139
|
+
* Map a single field
|
|
140
|
+
*/
|
|
141
|
+
private mapField;
|
|
142
|
+
/**
|
|
143
|
+
* Map a static field
|
|
144
|
+
*/
|
|
145
|
+
private mapStaticField;
|
|
146
|
+
/**
|
|
147
|
+
* Get value at path using dot notation
|
|
148
|
+
* Supports array indexing (e.g., 'products.0.id')
|
|
149
|
+
*/
|
|
150
|
+
private getValueAtPath;
|
|
151
|
+
/**
|
|
152
|
+
* Set value at path using dot notation
|
|
153
|
+
* Creates nested objects/arrays as needed
|
|
154
|
+
*/
|
|
155
|
+
private setValueAtPath;
|
|
156
|
+
/**
|
|
157
|
+
* Batch map multiple events
|
|
158
|
+
*/
|
|
159
|
+
mapBatch<T = any>(sources: any[]): MappingResult<T>[];
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Common transform functions for event mapping
|
|
164
|
+
*/
|
|
165
|
+
/**
|
|
166
|
+
* Convert milliseconds to seconds
|
|
167
|
+
*/
|
|
168
|
+
declare const msToSeconds: (ms: number) => number;
|
|
169
|
+
/**
|
|
170
|
+
* Convert seconds to milliseconds
|
|
171
|
+
*/
|
|
172
|
+
declare const secondsToMs: (seconds: number) => number;
|
|
173
|
+
/**
|
|
174
|
+
* Lowercase string
|
|
175
|
+
*/
|
|
176
|
+
declare const lowercase: (str: string) => string;
|
|
177
|
+
/**
|
|
178
|
+
* Uppercase string
|
|
179
|
+
*/
|
|
180
|
+
declare const uppercase: (str: string) => string;
|
|
181
|
+
/**
|
|
182
|
+
* Trim whitespace
|
|
183
|
+
*/
|
|
184
|
+
declare const trim: (str: string) => string;
|
|
185
|
+
/**
|
|
186
|
+
* Convert to string
|
|
187
|
+
*/
|
|
188
|
+
declare const toString: (value: any) => string;
|
|
189
|
+
/**
|
|
190
|
+
* Convert to number
|
|
191
|
+
*/
|
|
192
|
+
declare const toNumber: (value: any) => number;
|
|
193
|
+
/**
|
|
194
|
+
* Convert to boolean
|
|
195
|
+
*/
|
|
196
|
+
declare const toBoolean: (value: any) => boolean;
|
|
197
|
+
/**
|
|
198
|
+
* Wrap value in array
|
|
199
|
+
*/
|
|
200
|
+
declare const toArray: (value: any) => any[];
|
|
201
|
+
/**
|
|
202
|
+
* Get first element of array, or value if not array
|
|
203
|
+
*/
|
|
204
|
+
declare const first: (value: any) => any;
|
|
205
|
+
/**
|
|
206
|
+
* Map array of objects to array of property values
|
|
207
|
+
*/
|
|
208
|
+
declare const pluck: (property: string) => (arr: any[]) => any[];
|
|
209
|
+
/**
|
|
210
|
+
* Join array into string
|
|
211
|
+
*/
|
|
212
|
+
declare const join: (separator?: string) => (arr: any[]) => string;
|
|
213
|
+
/**
|
|
214
|
+
* Split string into array
|
|
215
|
+
*/
|
|
216
|
+
declare const split: (separator?: string) => (str: string) => string[];
|
|
217
|
+
/**
|
|
218
|
+
* Format date as ISO 8601
|
|
219
|
+
*/
|
|
220
|
+
declare const toISO: (timestamp: number) => string;
|
|
221
|
+
/**
|
|
222
|
+
* Parse ISO date to timestamp
|
|
223
|
+
*/
|
|
224
|
+
declare const fromISO: (iso: string) => number;
|
|
225
|
+
/**
|
|
226
|
+
* Round number to decimals
|
|
227
|
+
*/
|
|
228
|
+
declare const round: (decimals?: number) => (num: number) => number;
|
|
229
|
+
/**
|
|
230
|
+
* Compose multiple transforms (right to left)
|
|
231
|
+
*/
|
|
232
|
+
declare const compose: (...fns: ((value: any) => any)[]) => ((value: any) => any);
|
|
233
|
+
/**
|
|
234
|
+
* Pipe multiple transforms (left to right)
|
|
235
|
+
*/
|
|
236
|
+
declare const pipe: (...fns: ((value: any) => any)[]) => ((value: any) => any);
|
|
237
|
+
/**
|
|
238
|
+
* Return value as-is (identity function)
|
|
239
|
+
*/
|
|
240
|
+
declare const identity: (value: any) => any;
|
|
241
|
+
/**
|
|
242
|
+
* Rename object keys
|
|
243
|
+
*/
|
|
244
|
+
declare const renameKeys: (keyMap: Record<string, string>) => (obj: any) => any;
|
|
245
|
+
/**
|
|
246
|
+
* Pick specific keys from object
|
|
247
|
+
*/
|
|
248
|
+
declare const pick: (...keys: string[]) => (obj: any) => any;
|
|
249
|
+
/**
|
|
250
|
+
* Omit specific keys from object
|
|
251
|
+
*/
|
|
252
|
+
declare const omit: (...keys: string[]) => (obj: any) => any;
|
|
253
|
+
|
|
254
|
+
declare const transforms_compose: typeof compose;
|
|
255
|
+
declare const transforms_first: typeof first;
|
|
256
|
+
declare const transforms_fromISO: typeof fromISO;
|
|
257
|
+
declare const transforms_identity: typeof identity;
|
|
258
|
+
declare const transforms_join: typeof join;
|
|
259
|
+
declare const transforms_lowercase: typeof lowercase;
|
|
260
|
+
declare const transforms_msToSeconds: typeof msToSeconds;
|
|
261
|
+
declare const transforms_omit: typeof omit;
|
|
262
|
+
declare const transforms_pick: typeof pick;
|
|
263
|
+
declare const transforms_pipe: typeof pipe;
|
|
264
|
+
declare const transforms_pluck: typeof pluck;
|
|
265
|
+
declare const transforms_renameKeys: typeof renameKeys;
|
|
266
|
+
declare const transforms_round: typeof round;
|
|
267
|
+
declare const transforms_secondsToMs: typeof secondsToMs;
|
|
268
|
+
declare const transforms_split: typeof split;
|
|
269
|
+
declare const transforms_toArray: typeof toArray;
|
|
270
|
+
declare const transforms_toBoolean: typeof toBoolean;
|
|
271
|
+
declare const transforms_toISO: typeof toISO;
|
|
272
|
+
declare const transforms_toNumber: typeof toNumber;
|
|
273
|
+
declare const transforms_toString: typeof toString;
|
|
274
|
+
declare const transforms_trim: typeof trim;
|
|
275
|
+
declare const transforms_uppercase: typeof uppercase;
|
|
276
|
+
declare namespace transforms {
|
|
277
|
+
export { transforms_compose as compose, transforms_first as first, transforms_fromISO as fromISO, transforms_identity as identity, transforms_join as join, transforms_lowercase as lowercase, transforms_msToSeconds as msToSeconds, transforms_omit as omit, transforms_pick as pick, transforms_pipe as pipe, transforms_pluck as pluck, transforms_renameKeys as renameKeys, transforms_round as round, transforms_secondsToMs as secondsToMs, transforms_split as split, transforms_toArray as toArray, transforms_toBoolean as toBoolean, transforms_toISO as toISO, transforms_toNumber as toNumber, transforms_toString as toString, transforms_trim as trim, transforms_uppercase as uppercase };
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export { type ConditionFn, EventMapper, type EventNameMapping, type FieldMapping, type MapperConfig, type MappingResult, type StaticField, type TransformFn, transforms };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for event mapper
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Transform function to modify a value during mapping
|
|
6
|
+
*/
|
|
7
|
+
type TransformFn = (value: any, source: any) => any;
|
|
8
|
+
/**
|
|
9
|
+
* Condition function to determine if mapping should apply
|
|
10
|
+
*/
|
|
11
|
+
type ConditionFn = (source: any) => boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Field mapping configuration
|
|
14
|
+
*/
|
|
15
|
+
interface FieldMapping {
|
|
16
|
+
/**
|
|
17
|
+
* Source path in dot notation (e.g., 'user.email', 'products.0.id')
|
|
18
|
+
*/
|
|
19
|
+
from: string | string[];
|
|
20
|
+
/**
|
|
21
|
+
* Target path in dot notation (e.g., 'userData.em', 'items.0.id')
|
|
22
|
+
*/
|
|
23
|
+
to: string;
|
|
24
|
+
/**
|
|
25
|
+
* Optional transform function to modify value
|
|
26
|
+
*/
|
|
27
|
+
transform?: TransformFn;
|
|
28
|
+
/**
|
|
29
|
+
* Optional condition - only map if this returns true
|
|
30
|
+
*/
|
|
31
|
+
condition?: ConditionFn;
|
|
32
|
+
/**
|
|
33
|
+
* Default value if source is undefined/null
|
|
34
|
+
*/
|
|
35
|
+
default?: any;
|
|
36
|
+
/**
|
|
37
|
+
* Whether to skip if value is falsy
|
|
38
|
+
* @default false
|
|
39
|
+
*/
|
|
40
|
+
skipFalsy?: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Event name mapping configuration
|
|
44
|
+
*/
|
|
45
|
+
interface EventNameMapping {
|
|
46
|
+
/**
|
|
47
|
+
* Source event name or names
|
|
48
|
+
*/
|
|
49
|
+
from: string | string[];
|
|
50
|
+
/**
|
|
51
|
+
* Target event name
|
|
52
|
+
*/
|
|
53
|
+
to: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Static field to always add to output
|
|
57
|
+
*/
|
|
58
|
+
interface StaticField {
|
|
59
|
+
/**
|
|
60
|
+
* Target path
|
|
61
|
+
*/
|
|
62
|
+
to: string;
|
|
63
|
+
/**
|
|
64
|
+
* Static value or function to generate value
|
|
65
|
+
*/
|
|
66
|
+
value: any | ((source: any) => any);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Mapper configuration
|
|
70
|
+
*/
|
|
71
|
+
interface MapperConfig {
|
|
72
|
+
/**
|
|
73
|
+
* Event name mappings
|
|
74
|
+
*/
|
|
75
|
+
eventNames?: EventNameMapping[];
|
|
76
|
+
/**
|
|
77
|
+
* Field mappings
|
|
78
|
+
*/
|
|
79
|
+
fields?: FieldMapping[];
|
|
80
|
+
/**
|
|
81
|
+
* Static fields to always include
|
|
82
|
+
*/
|
|
83
|
+
static?: StaticField[];
|
|
84
|
+
/**
|
|
85
|
+
* Root path for source data
|
|
86
|
+
* @example 'data' to read from source.data.*
|
|
87
|
+
*/
|
|
88
|
+
sourceRoot?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Root path for target data
|
|
91
|
+
* @example 'data.0' to write to target.data[0].*
|
|
92
|
+
*/
|
|
93
|
+
targetRoot?: string;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Mapping result
|
|
97
|
+
*/
|
|
98
|
+
interface MappingResult<T = any> {
|
|
99
|
+
/**
|
|
100
|
+
* Mapped data
|
|
101
|
+
*/
|
|
102
|
+
data: T;
|
|
103
|
+
/**
|
|
104
|
+
* Fields that were mapped
|
|
105
|
+
*/
|
|
106
|
+
mappedFields: string[];
|
|
107
|
+
/**
|
|
108
|
+
* Fields that were skipped (condition/falsy)
|
|
109
|
+
*/
|
|
110
|
+
skippedFields: string[];
|
|
111
|
+
/**
|
|
112
|
+
* Errors encountered during mapping
|
|
113
|
+
*/
|
|
114
|
+
errors: Array<{
|
|
115
|
+
field: string;
|
|
116
|
+
error: string;
|
|
117
|
+
}>;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* EventMapper - Declarative event transformation
|
|
122
|
+
*
|
|
123
|
+
* Map events from one format to another using simple configuration.
|
|
124
|
+
* Perfect for ad platform integrations (Meta, Google, Snapchat, etc.)
|
|
125
|
+
*/
|
|
126
|
+
|
|
127
|
+
declare class EventMapper {
|
|
128
|
+
private config;
|
|
129
|
+
constructor(config: MapperConfig);
|
|
130
|
+
/**
|
|
131
|
+
* Map an event from source format to target format
|
|
132
|
+
*/
|
|
133
|
+
map<T = any>(source: any): MappingResult<T>;
|
|
134
|
+
/**
|
|
135
|
+
* Map event name using event name mappings
|
|
136
|
+
*/
|
|
137
|
+
private mapEventName;
|
|
138
|
+
/**
|
|
139
|
+
* Map a single field
|
|
140
|
+
*/
|
|
141
|
+
private mapField;
|
|
142
|
+
/**
|
|
143
|
+
* Map a static field
|
|
144
|
+
*/
|
|
145
|
+
private mapStaticField;
|
|
146
|
+
/**
|
|
147
|
+
* Get value at path using dot notation
|
|
148
|
+
* Supports array indexing (e.g., 'products.0.id')
|
|
149
|
+
*/
|
|
150
|
+
private getValueAtPath;
|
|
151
|
+
/**
|
|
152
|
+
* Set value at path using dot notation
|
|
153
|
+
* Creates nested objects/arrays as needed
|
|
154
|
+
*/
|
|
155
|
+
private setValueAtPath;
|
|
156
|
+
/**
|
|
157
|
+
* Batch map multiple events
|
|
158
|
+
*/
|
|
159
|
+
mapBatch<T = any>(sources: any[]): MappingResult<T>[];
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Common transform functions for event mapping
|
|
164
|
+
*/
|
|
165
|
+
/**
|
|
166
|
+
* Convert milliseconds to seconds
|
|
167
|
+
*/
|
|
168
|
+
declare const msToSeconds: (ms: number) => number;
|
|
169
|
+
/**
|
|
170
|
+
* Convert seconds to milliseconds
|
|
171
|
+
*/
|
|
172
|
+
declare const secondsToMs: (seconds: number) => number;
|
|
173
|
+
/**
|
|
174
|
+
* Lowercase string
|
|
175
|
+
*/
|
|
176
|
+
declare const lowercase: (str: string) => string;
|
|
177
|
+
/**
|
|
178
|
+
* Uppercase string
|
|
179
|
+
*/
|
|
180
|
+
declare const uppercase: (str: string) => string;
|
|
181
|
+
/**
|
|
182
|
+
* Trim whitespace
|
|
183
|
+
*/
|
|
184
|
+
declare const trim: (str: string) => string;
|
|
185
|
+
/**
|
|
186
|
+
* Convert to string
|
|
187
|
+
*/
|
|
188
|
+
declare const toString: (value: any) => string;
|
|
189
|
+
/**
|
|
190
|
+
* Convert to number
|
|
191
|
+
*/
|
|
192
|
+
declare const toNumber: (value: any) => number;
|
|
193
|
+
/**
|
|
194
|
+
* Convert to boolean
|
|
195
|
+
*/
|
|
196
|
+
declare const toBoolean: (value: any) => boolean;
|
|
197
|
+
/**
|
|
198
|
+
* Wrap value in array
|
|
199
|
+
*/
|
|
200
|
+
declare const toArray: (value: any) => any[];
|
|
201
|
+
/**
|
|
202
|
+
* Get first element of array, or value if not array
|
|
203
|
+
*/
|
|
204
|
+
declare const first: (value: any) => any;
|
|
205
|
+
/**
|
|
206
|
+
* Map array of objects to array of property values
|
|
207
|
+
*/
|
|
208
|
+
declare const pluck: (property: string) => (arr: any[]) => any[];
|
|
209
|
+
/**
|
|
210
|
+
* Join array into string
|
|
211
|
+
*/
|
|
212
|
+
declare const join: (separator?: string) => (arr: any[]) => string;
|
|
213
|
+
/**
|
|
214
|
+
* Split string into array
|
|
215
|
+
*/
|
|
216
|
+
declare const split: (separator?: string) => (str: string) => string[];
|
|
217
|
+
/**
|
|
218
|
+
* Format date as ISO 8601
|
|
219
|
+
*/
|
|
220
|
+
declare const toISO: (timestamp: number) => string;
|
|
221
|
+
/**
|
|
222
|
+
* Parse ISO date to timestamp
|
|
223
|
+
*/
|
|
224
|
+
declare const fromISO: (iso: string) => number;
|
|
225
|
+
/**
|
|
226
|
+
* Round number to decimals
|
|
227
|
+
*/
|
|
228
|
+
declare const round: (decimals?: number) => (num: number) => number;
|
|
229
|
+
/**
|
|
230
|
+
* Compose multiple transforms (right to left)
|
|
231
|
+
*/
|
|
232
|
+
declare const compose: (...fns: ((value: any) => any)[]) => ((value: any) => any);
|
|
233
|
+
/**
|
|
234
|
+
* Pipe multiple transforms (left to right)
|
|
235
|
+
*/
|
|
236
|
+
declare const pipe: (...fns: ((value: any) => any)[]) => ((value: any) => any);
|
|
237
|
+
/**
|
|
238
|
+
* Return value as-is (identity function)
|
|
239
|
+
*/
|
|
240
|
+
declare const identity: (value: any) => any;
|
|
241
|
+
/**
|
|
242
|
+
* Rename object keys
|
|
243
|
+
*/
|
|
244
|
+
declare const renameKeys: (keyMap: Record<string, string>) => (obj: any) => any;
|
|
245
|
+
/**
|
|
246
|
+
* Pick specific keys from object
|
|
247
|
+
*/
|
|
248
|
+
declare const pick: (...keys: string[]) => (obj: any) => any;
|
|
249
|
+
/**
|
|
250
|
+
* Omit specific keys from object
|
|
251
|
+
*/
|
|
252
|
+
declare const omit: (...keys: string[]) => (obj: any) => any;
|
|
253
|
+
|
|
254
|
+
declare const transforms_compose: typeof compose;
|
|
255
|
+
declare const transforms_first: typeof first;
|
|
256
|
+
declare const transforms_fromISO: typeof fromISO;
|
|
257
|
+
declare const transforms_identity: typeof identity;
|
|
258
|
+
declare const transforms_join: typeof join;
|
|
259
|
+
declare const transforms_lowercase: typeof lowercase;
|
|
260
|
+
declare const transforms_msToSeconds: typeof msToSeconds;
|
|
261
|
+
declare const transforms_omit: typeof omit;
|
|
262
|
+
declare const transforms_pick: typeof pick;
|
|
263
|
+
declare const transforms_pipe: typeof pipe;
|
|
264
|
+
declare const transforms_pluck: typeof pluck;
|
|
265
|
+
declare const transforms_renameKeys: typeof renameKeys;
|
|
266
|
+
declare const transforms_round: typeof round;
|
|
267
|
+
declare const transforms_secondsToMs: typeof secondsToMs;
|
|
268
|
+
declare const transforms_split: typeof split;
|
|
269
|
+
declare const transforms_toArray: typeof toArray;
|
|
270
|
+
declare const transforms_toBoolean: typeof toBoolean;
|
|
271
|
+
declare const transforms_toISO: typeof toISO;
|
|
272
|
+
declare const transforms_toNumber: typeof toNumber;
|
|
273
|
+
declare const transforms_toString: typeof toString;
|
|
274
|
+
declare const transforms_trim: typeof trim;
|
|
275
|
+
declare const transforms_uppercase: typeof uppercase;
|
|
276
|
+
declare namespace transforms {
|
|
277
|
+
export { transforms_compose as compose, transforms_first as first, transforms_fromISO as fromISO, transforms_identity as identity, transforms_join as join, transforms_lowercase as lowercase, transforms_msToSeconds as msToSeconds, transforms_omit as omit, transforms_pick as pick, transforms_pipe as pipe, transforms_pluck as pluck, transforms_renameKeys as renameKeys, transforms_round as round, transforms_secondsToMs as secondsToMs, transforms_split as split, transforms_toArray as toArray, transforms_toBoolean as toBoolean, transforms_toISO as toISO, transforms_toNumber as toNumber, transforms_toString as toString, transforms_trim as trim, transforms_uppercase as uppercase };
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export { type ConditionFn, EventMapper, type EventNameMapping, type FieldMapping, type MapperConfig, type MappingResult, type StaticField, type TransformFn, transforms };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all) => {
|
|
3
|
+
for (var name in all)
|
|
4
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
// src/EventMapper.ts
|
|
8
|
+
var EventMapper = class {
|
|
9
|
+
constructor(config) {
|
|
10
|
+
this.config = config;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Map an event from source format to target format
|
|
14
|
+
*/
|
|
15
|
+
map(source) {
|
|
16
|
+
const result = {
|
|
17
|
+
data: {},
|
|
18
|
+
mappedFields: [],
|
|
19
|
+
skippedFields: [],
|
|
20
|
+
errors: []
|
|
21
|
+
};
|
|
22
|
+
try {
|
|
23
|
+
const sourceData = this.config.sourceRoot ? this.getValueAtPath(source, this.config.sourceRoot) : source;
|
|
24
|
+
if (this.config.eventNames) {
|
|
25
|
+
const eventName = this.mapEventName(sourceData);
|
|
26
|
+
if (eventName) {
|
|
27
|
+
this.setValueAtPath(result.data, "event_name", eventName);
|
|
28
|
+
result.mappedFields.push("event_name");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (this.config.fields) {
|
|
32
|
+
for (const fieldMapping of this.config.fields) {
|
|
33
|
+
this.mapField(sourceData, result.data, fieldMapping, result);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (this.config.static) {
|
|
37
|
+
for (const staticField of this.config.static) {
|
|
38
|
+
this.mapStaticField(sourceData, result.data, staticField, result);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (this.config.targetRoot) {
|
|
42
|
+
const wrapped = {};
|
|
43
|
+
this.setValueAtPath(wrapped, this.config.targetRoot, result.data);
|
|
44
|
+
result.data = wrapped;
|
|
45
|
+
}
|
|
46
|
+
} catch (error) {
|
|
47
|
+
result.errors.push({
|
|
48
|
+
field: "_root",
|
|
49
|
+
error: error instanceof Error ? error.message : String(error)
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Map event name using event name mappings
|
|
56
|
+
*/
|
|
57
|
+
mapEventName(source) {
|
|
58
|
+
if (!this.config.eventNames) return void 0;
|
|
59
|
+
const sourceEventName = source.event_type || source.eventType || source.event_name;
|
|
60
|
+
if (!sourceEventName) return void 0;
|
|
61
|
+
for (const mapping of this.config.eventNames) {
|
|
62
|
+
const fromNames = Array.isArray(mapping.from) ? mapping.from : [mapping.from];
|
|
63
|
+
if (fromNames.includes(sourceEventName)) {
|
|
64
|
+
return mapping.to;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return void 0;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Map a single field
|
|
71
|
+
*/
|
|
72
|
+
mapField(source, target, mapping, result) {
|
|
73
|
+
try {
|
|
74
|
+
if (mapping.condition && !mapping.condition(source)) {
|
|
75
|
+
result.skippedFields.push(mapping.to);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const fromPaths = Array.isArray(mapping.from) ? mapping.from : [mapping.from];
|
|
79
|
+
let value = void 0;
|
|
80
|
+
for (const fromPath of fromPaths) {
|
|
81
|
+
value = this.getValueAtPath(source, fromPath);
|
|
82
|
+
if (value !== void 0 && value !== null) break;
|
|
83
|
+
}
|
|
84
|
+
if (value === void 0 || value === null) {
|
|
85
|
+
if (mapping.default !== void 0) {
|
|
86
|
+
value = mapping.default;
|
|
87
|
+
} else {
|
|
88
|
+
result.skippedFields.push(mapping.to);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (mapping.skipFalsy && !value) {
|
|
93
|
+
result.skippedFields.push(mapping.to);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (mapping.transform) {
|
|
97
|
+
value = mapping.transform(value, source);
|
|
98
|
+
}
|
|
99
|
+
this.setValueAtPath(target, mapping.to, value);
|
|
100
|
+
result.mappedFields.push(mapping.to);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
result.errors.push({
|
|
103
|
+
field: mapping.to,
|
|
104
|
+
error: error instanceof Error ? error.message : String(error)
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Map a static field
|
|
110
|
+
*/
|
|
111
|
+
mapStaticField(source, target, staticField, result) {
|
|
112
|
+
try {
|
|
113
|
+
const value = typeof staticField.value === "function" ? staticField.value(source) : staticField.value;
|
|
114
|
+
this.setValueAtPath(target, staticField.to, value);
|
|
115
|
+
result.mappedFields.push(staticField.to);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
result.errors.push({
|
|
118
|
+
field: staticField.to,
|
|
119
|
+
error: error instanceof Error ? error.message : String(error)
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get value at path using dot notation
|
|
125
|
+
* Supports array indexing (e.g., 'products.0.id')
|
|
126
|
+
*/
|
|
127
|
+
getValueAtPath(obj, path) {
|
|
128
|
+
const parts = path.split(".");
|
|
129
|
+
let value = obj;
|
|
130
|
+
for (const part of parts) {
|
|
131
|
+
if (value === void 0 || value === null) return void 0;
|
|
132
|
+
if (/^\d+$/.test(part)) {
|
|
133
|
+
value = value[parseInt(part, 10)];
|
|
134
|
+
} else {
|
|
135
|
+
value = value[part];
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return value;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Set value at path using dot notation
|
|
142
|
+
* Creates nested objects/arrays as needed
|
|
143
|
+
*/
|
|
144
|
+
setValueAtPath(obj, path, value) {
|
|
145
|
+
const parts = path.split(".");
|
|
146
|
+
let current = obj;
|
|
147
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
148
|
+
const part = parts[i];
|
|
149
|
+
const nextPart = parts[i + 1];
|
|
150
|
+
if (current[part] === void 0 || current[part] === null) {
|
|
151
|
+
if (/^\d+$/.test(nextPart)) {
|
|
152
|
+
current[part] = [];
|
|
153
|
+
} else {
|
|
154
|
+
current[part] = {};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
current = current[part];
|
|
158
|
+
}
|
|
159
|
+
const lastPart = parts[parts.length - 1];
|
|
160
|
+
if (/^\d+$/.test(lastPart)) {
|
|
161
|
+
const index = parseInt(lastPart, 10);
|
|
162
|
+
if (!Array.isArray(current)) {
|
|
163
|
+
throw new Error(`Cannot set array index ${index} on non-array`);
|
|
164
|
+
}
|
|
165
|
+
current[index] = value;
|
|
166
|
+
} else {
|
|
167
|
+
current[lastPart] = value;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Batch map multiple events
|
|
172
|
+
*/
|
|
173
|
+
mapBatch(sources) {
|
|
174
|
+
return sources.map((source) => this.map(source));
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
// src/transforms.ts
|
|
179
|
+
var transforms_exports = {};
|
|
180
|
+
__export(transforms_exports, {
|
|
181
|
+
compose: () => compose,
|
|
182
|
+
first: () => first,
|
|
183
|
+
fromISO: () => fromISO,
|
|
184
|
+
identity: () => identity,
|
|
185
|
+
join: () => join,
|
|
186
|
+
lowercase: () => lowercase,
|
|
187
|
+
msToSeconds: () => msToSeconds,
|
|
188
|
+
omit: () => omit,
|
|
189
|
+
pick: () => pick,
|
|
190
|
+
pipe: () => pipe,
|
|
191
|
+
pluck: () => pluck,
|
|
192
|
+
renameKeys: () => renameKeys,
|
|
193
|
+
round: () => round,
|
|
194
|
+
secondsToMs: () => secondsToMs,
|
|
195
|
+
split: () => split,
|
|
196
|
+
toArray: () => toArray,
|
|
197
|
+
toBoolean: () => toBoolean,
|
|
198
|
+
toISO: () => toISO,
|
|
199
|
+
toNumber: () => toNumber,
|
|
200
|
+
toString: () => toString,
|
|
201
|
+
trim: () => trim,
|
|
202
|
+
uppercase: () => uppercase
|
|
203
|
+
});
|
|
204
|
+
var msToSeconds = (ms) => Math.floor(ms / 1e3);
|
|
205
|
+
var secondsToMs = (seconds) => seconds * 1e3;
|
|
206
|
+
var lowercase = (str) => str.toLowerCase();
|
|
207
|
+
var uppercase = (str) => str.toUpperCase();
|
|
208
|
+
var trim = (str) => str.trim();
|
|
209
|
+
var toString = (value) => String(value);
|
|
210
|
+
var toNumber = (value) => Number(value);
|
|
211
|
+
var toBoolean = (value) => Boolean(value);
|
|
212
|
+
var toArray = (value) => {
|
|
213
|
+
if (Array.isArray(value)) return value;
|
|
214
|
+
return [value];
|
|
215
|
+
};
|
|
216
|
+
var first = (value) => {
|
|
217
|
+
if (Array.isArray(value)) return value[0];
|
|
218
|
+
return value;
|
|
219
|
+
};
|
|
220
|
+
var pluck = (property) => (arr) => {
|
|
221
|
+
if (!Array.isArray(arr)) return [];
|
|
222
|
+
return arr.map((item) => item[property]);
|
|
223
|
+
};
|
|
224
|
+
var join = (separator = ",") => (arr) => {
|
|
225
|
+
if (!Array.isArray(arr)) return String(arr);
|
|
226
|
+
return arr.join(separator);
|
|
227
|
+
};
|
|
228
|
+
var split = (separator = ",") => (str) => {
|
|
229
|
+
return str.split(separator);
|
|
230
|
+
};
|
|
231
|
+
var toISO = (timestamp) => {
|
|
232
|
+
return new Date(timestamp).toISOString();
|
|
233
|
+
};
|
|
234
|
+
var fromISO = (iso) => {
|
|
235
|
+
return new Date(iso).getTime();
|
|
236
|
+
};
|
|
237
|
+
var round = (decimals = 0) => (num) => {
|
|
238
|
+
const factor = Math.pow(10, decimals);
|
|
239
|
+
return Math.round(num * factor) / factor;
|
|
240
|
+
};
|
|
241
|
+
var compose = (...fns) => {
|
|
242
|
+
return (value) => fns.reduceRight((acc, fn) => fn(acc), value);
|
|
243
|
+
};
|
|
244
|
+
var pipe = (...fns) => {
|
|
245
|
+
return (value) => fns.reduce((acc, fn) => fn(acc), value);
|
|
246
|
+
};
|
|
247
|
+
var identity = (value) => value;
|
|
248
|
+
var renameKeys = (keyMap) => (obj) => {
|
|
249
|
+
const result = {};
|
|
250
|
+
for (const [oldKey, newKey] of Object.entries(keyMap)) {
|
|
251
|
+
if (obj[oldKey] !== void 0) {
|
|
252
|
+
result[newKey] = obj[oldKey];
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return result;
|
|
256
|
+
};
|
|
257
|
+
var pick = (...keys) => (obj) => {
|
|
258
|
+
const result = {};
|
|
259
|
+
for (const key of keys) {
|
|
260
|
+
if (obj[key] !== void 0) {
|
|
261
|
+
result[key] = obj[key];
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return result;
|
|
265
|
+
};
|
|
266
|
+
var omit = (...keys) => (obj) => {
|
|
267
|
+
const result = { ...obj };
|
|
268
|
+
for (const key of keys) {
|
|
269
|
+
delete result[key];
|
|
270
|
+
}
|
|
271
|
+
return result;
|
|
272
|
+
};
|
|
273
|
+
export {
|
|
274
|
+
EventMapper,
|
|
275
|
+
transforms_exports as transforms
|
|
276
|
+
};
|
|
277
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/EventMapper.ts","../src/transforms.ts"],"sourcesContent":["/**\n * EventMapper - Declarative event transformation\n * \n * Map events from one format to another using simple configuration.\n * Perfect for ad platform integrations (Meta, Google, Snapchat, etc.)\n */\n\nimport type {\n MapperConfig,\n FieldMapping,\n EventNameMapping,\n StaticField,\n MappingResult,\n} from './types';\n\nexport class EventMapper {\n private config: MapperConfig;\n\n constructor(config: MapperConfig) {\n this.config = config;\n }\n\n /**\n * Map an event from source format to target format\n */\n map<T = any>(source: any): MappingResult<T> {\n const result: MappingResult<T> = {\n data: {} as T,\n mappedFields: [],\n skippedFields: [],\n errors: [],\n };\n\n try {\n // Start with source root if specified\n const sourceData = this.config.sourceRoot\n ? this.getValueAtPath(source, this.config.sourceRoot)\n : source;\n\n // Map event names\n if (this.config.eventNames) {\n const eventName = this.mapEventName(sourceData);\n if (eventName) {\n this.setValueAtPath(result.data, 'event_name', eventName);\n result.mappedFields.push('event_name');\n }\n }\n\n // Map fields\n if (this.config.fields) {\n for (const fieldMapping of this.config.fields) {\n this.mapField(sourceData, result.data, fieldMapping, result);\n }\n }\n\n // Add static fields\n if (this.config.static) {\n for (const staticField of this.config.static) {\n this.mapStaticField(sourceData, result.data, staticField, result);\n }\n }\n\n // Apply target root if specified\n if (this.config.targetRoot) {\n const wrapped: any = {};\n this.setValueAtPath(wrapped, this.config.targetRoot, result.data);\n result.data = wrapped as T;\n }\n } catch (error) {\n result.errors.push({\n field: '_root',\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n return result;\n }\n\n /**\n * Map event name using event name mappings\n */\n private mapEventName(source: any): string | undefined {\n if (!this.config.eventNames) return undefined;\n\n // Try to find event_type in source\n const sourceEventName = source.event_type || source.eventType || source.event_name;\n if (!sourceEventName) return undefined;\n\n // Find matching mapping\n for (const mapping of this.config.eventNames) {\n const fromNames = Array.isArray(mapping.from) ? mapping.from : [mapping.from];\n if (fromNames.includes(sourceEventName)) {\n return mapping.to;\n }\n }\n\n return undefined;\n }\n\n /**\n * Map a single field\n */\n private mapField(\n source: any,\n target: any,\n mapping: FieldMapping,\n result: MappingResult\n ): void {\n try {\n // Check condition\n if (mapping.condition && !mapping.condition(source)) {\n result.skippedFields.push(mapping.to);\n return;\n }\n\n // Get source value(s)\n const fromPaths = Array.isArray(mapping.from) ? mapping.from : [mapping.from];\n let value: any = undefined;\n\n // Try each source path until we find a value\n for (const fromPath of fromPaths) {\n value = this.getValueAtPath(source, fromPath);\n if (value !== undefined && value !== null) break;\n }\n\n // Use default if no value found\n if (value === undefined || value === null) {\n if (mapping.default !== undefined) {\n value = mapping.default;\n } else {\n result.skippedFields.push(mapping.to);\n return;\n }\n }\n\n // Skip falsy values if configured\n if (mapping.skipFalsy && !value) {\n result.skippedFields.push(mapping.to);\n return;\n }\n\n // Apply transform\n if (mapping.transform) {\n value = mapping.transform(value, source);\n }\n\n // Set target value\n this.setValueAtPath(target, mapping.to, value);\n result.mappedFields.push(mapping.to);\n } catch (error) {\n result.errors.push({\n field: mapping.to,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Map a static field\n */\n private mapStaticField(\n source: any,\n target: any,\n staticField: StaticField,\n result: MappingResult\n ): void {\n try {\n const value =\n typeof staticField.value === 'function'\n ? staticField.value(source)\n : staticField.value;\n\n this.setValueAtPath(target, staticField.to, value);\n result.mappedFields.push(staticField.to);\n } catch (error) {\n result.errors.push({\n field: staticField.to,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Get value at path using dot notation\n * Supports array indexing (e.g., 'products.0.id')\n */\n private getValueAtPath(obj: any, path: string): any {\n const parts = path.split('.');\n let value = obj;\n\n for (const part of parts) {\n if (value === undefined || value === null) return undefined;\n\n // Handle array index\n if (/^\\d+$/.test(part)) {\n value = value[parseInt(part, 10)];\n } else {\n value = value[part];\n }\n }\n\n return value;\n }\n\n /**\n * Set value at path using dot notation\n * Creates nested objects/arrays as needed\n */\n private setValueAtPath(obj: any, path: string, value: any): void {\n const parts = path.split('.');\n let current = obj;\n\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n const nextPart = parts[i + 1];\n\n // Create nested structure if needed\n if (current[part] === undefined || current[part] === null) {\n // Next part is array index\n if (/^\\d+$/.test(nextPart)) {\n current[part] = [];\n } else {\n current[part] = {};\n }\n }\n\n current = current[part];\n }\n\n const lastPart = parts[parts.length - 1];\n\n // Handle array index\n if (/^\\d+$/.test(lastPart)) {\n const index = parseInt(lastPart, 10);\n if (!Array.isArray(current)) {\n throw new Error(`Cannot set array index ${index} on non-array`);\n }\n current[index] = value;\n } else {\n current[lastPart] = value;\n }\n }\n\n /**\n * Batch map multiple events\n */\n mapBatch<T = any>(sources: any[]): MappingResult<T>[] {\n return sources.map((source) => this.map<T>(source));\n }\n}\n","/**\n * Common transform functions for event mapping\n */\n\n/**\n * Convert milliseconds to seconds\n */\nexport const msToSeconds = (ms: number): number => Math.floor(ms / 1000);\n\n/**\n * Convert seconds to milliseconds\n */\nexport const secondsToMs = (seconds: number): number => seconds * 1000;\n\n/**\n * Lowercase string\n */\nexport const lowercase = (str: string): string => str.toLowerCase();\n\n/**\n * Uppercase string\n */\nexport const uppercase = (str: string): string => str.toUpperCase();\n\n/**\n * Trim whitespace\n */\nexport const trim = (str: string): string => str.trim();\n\n/**\n * Convert to string\n */\nexport const toString = (value: any): string => String(value);\n\n/**\n * Convert to number\n */\nexport const toNumber = (value: any): number => Number(value);\n\n/**\n * Convert to boolean\n */\nexport const toBoolean = (value: any): boolean => Boolean(value);\n\n/**\n * Wrap value in array\n */\nexport const toArray = (value: any): any[] => {\n if (Array.isArray(value)) return value;\n return [value];\n};\n\n/**\n * Get first element of array, or value if not array\n */\nexport const first = (value: any): any => {\n if (Array.isArray(value)) return value[0];\n return value;\n};\n\n/**\n * Map array of objects to array of property values\n */\nexport const pluck = (property: string) => (arr: any[]): any[] => {\n if (!Array.isArray(arr)) return [];\n return arr.map((item) => item[property]);\n};\n\n/**\n * Join array into string\n */\nexport const join = (separator: string = ',') => (arr: any[]): string => {\n if (!Array.isArray(arr)) return String(arr);\n return arr.join(separator);\n};\n\n/**\n * Split string into array\n */\nexport const split = (separator: string = ',') => (str: string): string[] => {\n return str.split(separator);\n};\n\n/**\n * Format date as ISO 8601\n */\nexport const toISO = (timestamp: number): string => {\n return new Date(timestamp).toISOString();\n};\n\n/**\n * Parse ISO date to timestamp\n */\nexport const fromISO = (iso: string): number => {\n return new Date(iso).getTime();\n};\n\n/**\n * Round number to decimals\n */\nexport const round = (decimals: number = 0) => (num: number): number => {\n const factor = Math.pow(10, decimals);\n return Math.round(num * factor) / factor;\n};\n\n/**\n * Compose multiple transforms (right to left)\n */\nexport const compose = (...fns: ((value: any) => any)[]): ((value: any) => any) => {\n return (value: any) => fns.reduceRight((acc, fn) => fn(acc), value);\n};\n\n/**\n * Pipe multiple transforms (left to right)\n */\nexport const pipe = (...fns: ((value: any) => any)[]): ((value: any) => any) => {\n return (value: any) => fns.reduce((acc, fn) => fn(acc), value);\n};\n\n/**\n * Return value as-is (identity function)\n */\nexport const identity = (value: any): any => value;\n\n/**\n * Rename object keys\n */\nexport const renameKeys = (keyMap: Record<string, string>) => (obj: any): any => {\n const result: any = {};\n for (const [oldKey, newKey] of Object.entries(keyMap)) {\n if (obj[oldKey] !== undefined) {\n result[newKey] = obj[oldKey];\n }\n }\n return result;\n};\n\n/**\n * Pick specific keys from object\n */\nexport const pick = (...keys: string[]) => (obj: any): any => {\n const result: any = {};\n for (const key of keys) {\n if (obj[key] !== undefined) {\n result[key] = obj[key];\n }\n }\n return result;\n};\n\n/**\n * Omit specific keys from object\n */\nexport const omit = (...keys: string[]) => (obj: any): any => {\n const result = { ...obj };\n for (const key of keys) {\n delete result[key];\n }\n return result;\n};\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sygnl/mapper",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Declarative event mapper for transforming events between different ad platform formats",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mapper",
|
|
21
|
+
"event-mapping",
|
|
22
|
+
"transform",
|
|
23
|
+
"ad-platforms",
|
|
24
|
+
"meta",
|
|
25
|
+
"google",
|
|
26
|
+
"snapchat",
|
|
27
|
+
"tiktok",
|
|
28
|
+
"conversion-api"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsup",
|
|
32
|
+
"test": "vitest run",
|
|
33
|
+
"test:watch": "vitest",
|
|
34
|
+
"test:coverage": "vitest run --coverage",
|
|
35
|
+
"typecheck": "tsc --noEmit",
|
|
36
|
+
"prepublishOnly": "npm run build"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "^20.10.0",
|
|
40
|
+
"tsup": "^8.0.1",
|
|
41
|
+
"typescript": "^5.3.3",
|
|
42
|
+
"vitest": "^1.0.4",
|
|
43
|
+
"@vitest/coverage-v8": "^1.0.4"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=18"
|
|
47
|
+
},
|
|
48
|
+
"author": "Edge Foundry, Inc.",
|
|
49
|
+
"license": "Apache-2.0"
|
|
50
|
+
}
|