@mhubcloud/tms_core 2.0.0-beta.0 → 2.0.0-beta.2
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/dist/index.js +624 -0
- package/package.json +2 -2
- package/src/index.ts +2 -1
- package/src/utils/testUtils.ts +18 -0
- package/tests/AffiliatePort.js +1 -1
- package/tests/CJ.js +1 -1
- package/tests/Facebook.js +1 -1
- package/tests/GoogleAnalytics4.js +1 -1
- package/tests/Piano.js +1 -1
- package/tests/UniversalAnalytics.js +1 -1
- package/js/lib/defaultPublisher.js +0 -116
- package/js/lib/utils.js +0 -349
- package/js/publishers/AffiliatePort.js +0 -78
- package/js/publishers/CJ.js +0 -68
- package/js/publishers/Facebook.js +0 -64
- package/js/publishers/GoogleAnalytics4.js +0 -76
- package/js/publishers/HttpPublisher.js +0 -64
- package/js/publishers/Piano.js +0 -68
- package/js/publishers/UniversalAnalytics.js +0 -75
- package/tests/testUtils.js +0 -7
package/dist/index.js
ADDED
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
|
+
DefaultPublisher: () => defaultPublisher,
|
|
34
|
+
publisher: () => publisher,
|
|
35
|
+
testUtils: () => testUtils_exports,
|
|
36
|
+
utils: () => utils_exports
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(src_exports);
|
|
39
|
+
|
|
40
|
+
// src/utils/utils.ts
|
|
41
|
+
var utils_exports = {};
|
|
42
|
+
__export(utils_exports, {
|
|
43
|
+
EventPublisherBase: () => EventPublisherBase,
|
|
44
|
+
encodeEmail: () => encodeEmail,
|
|
45
|
+
extractAdCode: () => extractAdCode,
|
|
46
|
+
flatten: () => flatten,
|
|
47
|
+
handlePlatformRequest: () => handlePlatformRequest,
|
|
48
|
+
handleResponse: () => handleResponse,
|
|
49
|
+
log: () => log,
|
|
50
|
+
logException: () => logException,
|
|
51
|
+
prepareTestRequestHeaders: () => prepareTestRequestHeaders,
|
|
52
|
+
removeUndefined: () => removeUndefined
|
|
53
|
+
});
|
|
54
|
+
var crypto = __toESM(require("crypto"));
|
|
55
|
+
var appInsights = __toESM(require("applicationinsights"));
|
|
56
|
+
var import_node_fetch = __toESM(require("node-fetch"));
|
|
57
|
+
var aiClient = null;
|
|
58
|
+
if (process.env.APPINSIGHTS_INSTRUMENTATIONKEY) {
|
|
59
|
+
appInsights.setup().setAutoCollectDependencies(false).setAutoCollectConsole(true, true).setSendLiveMetrics(false).setAutoCollectRequests(false).setAutoCollectPerformance(false).setUseDiskRetryCaching(false).start();
|
|
60
|
+
aiClient = appInsights.defaultClient;
|
|
61
|
+
}
|
|
62
|
+
var EventPublisherBase = class {
|
|
63
|
+
config;
|
|
64
|
+
constructor(config) {
|
|
65
|
+
this.config = config;
|
|
66
|
+
}
|
|
67
|
+
/** @deprecated Please use a 'new Class(config)' notation. The .register() method will be deleted in future major version
|
|
68
|
+
* Registers a new instance of @see EventPublisherBase -derived class with array of publishers
|
|
69
|
+
* @param {EventPublisher[]} publishers Tha publishers array to register with
|
|
70
|
+
* @param {Object} config Configuration to pass to new instance
|
|
71
|
+
* Call this static method on @see EventPublisherBase -derived class.
|
|
72
|
+
* It will create its instance and pass @param config to its constructor.
|
|
73
|
+
* Than it will add resulting instance of @param publishers.
|
|
74
|
+
*/
|
|
75
|
+
static register(publishers, config) {
|
|
76
|
+
publishers.push(
|
|
77
|
+
new this(
|
|
78
|
+
config
|
|
79
|
+
)
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
function log(log3, level, message, properties) {
|
|
84
|
+
log3.warn(message);
|
|
85
|
+
aiClient?.trackTrace({
|
|
86
|
+
message,
|
|
87
|
+
severity: level,
|
|
88
|
+
properties
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
function logException(log3, exception) {
|
|
92
|
+
log3.warn(exception);
|
|
93
|
+
aiClient?.trackException({
|
|
94
|
+
exception
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function removeUndefined(originalValue) {
|
|
98
|
+
if (originalValue instanceof Array) {
|
|
99
|
+
return removeUndefinedFromArray(originalValue);
|
|
100
|
+
} else if (originalValue instanceof Object) {
|
|
101
|
+
return removeUndefinedFromObject(originalValue);
|
|
102
|
+
} else {
|
|
103
|
+
return originalValue;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function removeUndefinedFromObject(object) {
|
|
107
|
+
const resultObject = {};
|
|
108
|
+
for (const property in object) {
|
|
109
|
+
if (Object.prototype.hasOwnProperty.call(object, property) && object[property] !== void 0) {
|
|
110
|
+
resultObject[property] = removeUndefined(
|
|
111
|
+
object[property]
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return resultObject;
|
|
116
|
+
}
|
|
117
|
+
function removeUndefinedFromArray(array) {
|
|
118
|
+
const resultArray = [];
|
|
119
|
+
for (const item of array) {
|
|
120
|
+
if (item !== void 0) {
|
|
121
|
+
resultArray.push(removeUndefined(item));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return resultArray;
|
|
125
|
+
}
|
|
126
|
+
function encodeEmail(email) {
|
|
127
|
+
return computeSha256HashFromString(email);
|
|
128
|
+
}
|
|
129
|
+
function computeSha256HashFromString(stringToHash) {
|
|
130
|
+
if (typeof stringToHash !== "string") {
|
|
131
|
+
return void 0;
|
|
132
|
+
}
|
|
133
|
+
return crypto.createHash("sha256").update(stringToHash.toLowerCase(), "ascii").digest("hex").toLowerCase();
|
|
134
|
+
}
|
|
135
|
+
function extractAdCode(data, adPlatform, adCode, format = null) {
|
|
136
|
+
const ad = data.ads.filter((x) => {
|
|
137
|
+
return x.adPlatform === adPlatform;
|
|
138
|
+
}).sort((a, b) => b.visitAt - a.visitAt)[0];
|
|
139
|
+
if (!ad) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
const code = ad.adCodes ? ad.adCodes[adCode] : null;
|
|
143
|
+
if (code) {
|
|
144
|
+
const returnValue = { code, visitAt: ad.visitAt };
|
|
145
|
+
if (format) {
|
|
146
|
+
return format(returnValue, ad);
|
|
147
|
+
}
|
|
148
|
+
return returnValue;
|
|
149
|
+
}
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
function flatten(event, separator = "_") {
|
|
153
|
+
return Object.assign(
|
|
154
|
+
{},
|
|
155
|
+
...function _flatten(o, separator2, parent) {
|
|
156
|
+
return [].concat(
|
|
157
|
+
...Object.keys(o).map((key) => {
|
|
158
|
+
if (typeof o[key] === "object" && o[key] !== null) {
|
|
159
|
+
const newParent = parent ? parent + separator2 + key : key;
|
|
160
|
+
return _flatten(o[key], separator2, newParent);
|
|
161
|
+
} else {
|
|
162
|
+
const newKey = parent ? parent + separator2 + key : key;
|
|
163
|
+
return { [newKey]: o[key] };
|
|
164
|
+
}
|
|
165
|
+
})
|
|
166
|
+
);
|
|
167
|
+
}(event, separator)
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
function prepareTestRequestHeaders(headers, origUrl, origRequest, origResponse) {
|
|
171
|
+
headers["x-mhub-orig-url"] = origUrl;
|
|
172
|
+
headers["x-mhub-orig-method"] = origRequest.method;
|
|
173
|
+
headers["x-mhub-orig-response-status-code"] = origResponse.status;
|
|
174
|
+
headers["x-mhub-orig-response-status-message"] = origResponse.statusText;
|
|
175
|
+
}
|
|
176
|
+
async function handleResponse(response, event) {
|
|
177
|
+
if (!response.ok) {
|
|
178
|
+
throw new Error(
|
|
179
|
+
`HTTP Error code: ${response.status}, event: ${event}, body: ${await response.text()}`
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
const body = await response.text();
|
|
183
|
+
try {
|
|
184
|
+
return JSON.parse(body);
|
|
185
|
+
} catch (ex) {
|
|
186
|
+
return body;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
async function handlePlatformRequest({
|
|
190
|
+
source,
|
|
191
|
+
baseUrl,
|
|
192
|
+
requestOptions,
|
|
193
|
+
query = "",
|
|
194
|
+
event,
|
|
195
|
+
logger
|
|
196
|
+
}) {
|
|
197
|
+
if (!baseUrl || baseUrl.length < 3) {
|
|
198
|
+
throw new Error("URL for request was not provided or was not valid");
|
|
199
|
+
}
|
|
200
|
+
const fullUrl = baseUrl + query;
|
|
201
|
+
const fetchRequestOptions = {
|
|
202
|
+
method: requestOptions.method ?? "POST",
|
|
203
|
+
body: requestOptions.body ?? void 0,
|
|
204
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
205
|
+
headers: { ...requestOptions.headers }
|
|
206
|
+
};
|
|
207
|
+
const rawPlatformResponse = await (0, import_node_fetch.default)(fullUrl, fetchRequestOptions);
|
|
208
|
+
if (process.env.PUBLISHER_TESTURL) {
|
|
209
|
+
await handleTestRequest({
|
|
210
|
+
fetchRequestOptions,
|
|
211
|
+
fullUrl,
|
|
212
|
+
query,
|
|
213
|
+
rawPlatformResponse
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
const processedPlatfromResponse = await handleResponse(
|
|
217
|
+
rawPlatformResponse,
|
|
218
|
+
event
|
|
219
|
+
);
|
|
220
|
+
log(logger, 1, `${source} - ${event} - sent`);
|
|
221
|
+
return processedPlatfromResponse;
|
|
222
|
+
}
|
|
223
|
+
async function handleTestRequest(params) {
|
|
224
|
+
try {
|
|
225
|
+
params.fetchRequestOptions.headers = {
|
|
226
|
+
...params.fetchRequestOptions.headers,
|
|
227
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
228
|
+
"x-mhub-orig-url": params.fullUrl,
|
|
229
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
230
|
+
"x-mhub-orig-method": params.fetchRequestOptions.method ?? "",
|
|
231
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
232
|
+
"x-mhub-orig-response-status-code": `${params.rawPlatformResponse.status}`,
|
|
233
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
234
|
+
"x-mhub-orig-response-status-message": params.rawPlatformResponse.statusText
|
|
235
|
+
};
|
|
236
|
+
await (0, import_node_fetch.default)(
|
|
237
|
+
`${process.env.PUBLISHER_TESTURL ?? ""} + ${params.query ?? ""}`,
|
|
238
|
+
params.fetchRequestOptions
|
|
239
|
+
);
|
|
240
|
+
} catch {
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// src/defaultPublisher.ts
|
|
245
|
+
async function defaultPublisher(azureFunctionContext, eventHubMessages, source, platformPublisher, trigger) {
|
|
246
|
+
const processMessagePromises = [];
|
|
247
|
+
for (const message of eventHubMessages) {
|
|
248
|
+
processMessagePromises.push(
|
|
249
|
+
processMessage(
|
|
250
|
+
message,
|
|
251
|
+
azureFunctionContext.log,
|
|
252
|
+
platformPublisher,
|
|
253
|
+
trigger
|
|
254
|
+
)
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
const results = await Promise.allSettled(processMessagePromises);
|
|
258
|
+
for (const result of results) {
|
|
259
|
+
if (result.status === "rejected") {
|
|
260
|
+
logException(
|
|
261
|
+
azureFunctionContext.log,
|
|
262
|
+
new Error(result.reason)
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
async function processMessage(message, log3, platfromPublisher, trigger) {
|
|
268
|
+
const logProperties = {
|
|
269
|
+
source: platfromPublisher.source,
|
|
270
|
+
data: JSON.stringify(message)
|
|
271
|
+
};
|
|
272
|
+
const publishers = trigger(message);
|
|
273
|
+
if (!publishers.length) {
|
|
274
|
+
log(
|
|
275
|
+
log3,
|
|
276
|
+
1,
|
|
277
|
+
"Message excluded by filter (no publishers determined)",
|
|
278
|
+
logProperties
|
|
279
|
+
);
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
let publishedAny = false;
|
|
283
|
+
let failedToPublishAll = false;
|
|
284
|
+
for (const eventPublisher of publishers) {
|
|
285
|
+
const mapped = await eventPublisher.map(message);
|
|
286
|
+
const res = await publishMessage(
|
|
287
|
+
log3,
|
|
288
|
+
mapped,
|
|
289
|
+
eventPublisher.config,
|
|
290
|
+
platfromPublisher,
|
|
291
|
+
message.event.code + (message.event.name ? "/" + message.event.name : "")
|
|
292
|
+
);
|
|
293
|
+
if (res) {
|
|
294
|
+
publishedAny = true;
|
|
295
|
+
} else {
|
|
296
|
+
logException(
|
|
297
|
+
log3,
|
|
298
|
+
new Error(
|
|
299
|
+
`The message has not been published. Source: ${platfromPublisher.source}`
|
|
300
|
+
)
|
|
301
|
+
);
|
|
302
|
+
failedToPublishAll = true;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (!publishedAny) {
|
|
306
|
+
logException(
|
|
307
|
+
log3,
|
|
308
|
+
new Error(
|
|
309
|
+
"The message has not been published to any publisher configuration"
|
|
310
|
+
)
|
|
311
|
+
);
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
return !failedToPublishAll;
|
|
315
|
+
}
|
|
316
|
+
async function publishMessage(log3, mapped, config, platformPublisher, event) {
|
|
317
|
+
await platformPublisher.publish(log3, config, mapped, event);
|
|
318
|
+
return true;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// src/publishers/affiliatePort.ts
|
|
322
|
+
var affiliatePort = {
|
|
323
|
+
source: "AffiliatePort",
|
|
324
|
+
/**
|
|
325
|
+
* Publishes data to AffiliatePort
|
|
326
|
+
* @param log zure Function context.log
|
|
327
|
+
* @param config Publisher configuration
|
|
328
|
+
* @param data Data in publisher-friendly format to be published
|
|
329
|
+
* @param event Event for which the function is triggered
|
|
330
|
+
*/
|
|
331
|
+
async publish(log3, config, data, event) {
|
|
332
|
+
if (data.products instanceof Array && (typeof config.offerId === "string" || typeof config.offerId === "number")) {
|
|
333
|
+
const affiliatePortData = removeUndefined(
|
|
334
|
+
data
|
|
335
|
+
);
|
|
336
|
+
const requestOptions = {
|
|
337
|
+
method: "GET"
|
|
338
|
+
};
|
|
339
|
+
const baseUrl = "https://tracking.affiliateclub.cz/aff_lsr";
|
|
340
|
+
for (const product of affiliatePortData.products) {
|
|
341
|
+
const query = `?offer_id=${encodeURIComponent(
|
|
342
|
+
config.offerId
|
|
343
|
+
)}&adv_sub=TID_${affiliatePortData.orderId}&amount=${product.quantity * product.price}&transaction_id=${affiliatePortData.transactionID}&adv_sub2=${product.category}&adv_sub3=${product.masterType}`;
|
|
344
|
+
await handlePlatformRequest({
|
|
345
|
+
source: this.source,
|
|
346
|
+
baseUrl,
|
|
347
|
+
query,
|
|
348
|
+
requestOptions,
|
|
349
|
+
event,
|
|
350
|
+
logger: log3
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
} else {
|
|
354
|
+
throw new Error("Invalid config for platform " + this.source);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
// src/publishers/cj.ts
|
|
360
|
+
var cj = {
|
|
361
|
+
source: "CJAffiliate",
|
|
362
|
+
/**
|
|
363
|
+
* Publishes data to CJ
|
|
364
|
+
* @param log Azure Function context.log
|
|
365
|
+
* @param config Publisher configuration
|
|
366
|
+
* @param data Data in publisher-friendly format to be published
|
|
367
|
+
* @param event Event for which the function is triggered
|
|
368
|
+
*/
|
|
369
|
+
async publish(log3, config, data, event) {
|
|
370
|
+
if (!data.cjevent) {
|
|
371
|
+
log(log3, 1, `CJ - ${event} - skipped because CJEVENT is missing`);
|
|
372
|
+
} else {
|
|
373
|
+
if (typeof config.cid === "string" && typeof config.type === "string") {
|
|
374
|
+
const cjData = removeUndefined(data);
|
|
375
|
+
let query = "?cid=" + encodeURI(config.cid);
|
|
376
|
+
query += "&type=" + encodeURI(config.type);
|
|
377
|
+
for (const property in data) {
|
|
378
|
+
if (Object.prototype.hasOwnProperty.call(cjData, property) && cjData[property] !== void 0) {
|
|
379
|
+
query += "&" + encodeURI(property) + "=" + encodeURI(
|
|
380
|
+
cjData[property] === null ? "" : (
|
|
381
|
+
// eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style
|
|
382
|
+
cjData[property]?.toString()
|
|
383
|
+
)
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
const baseUrl = "https://www.kdukvh.com/u";
|
|
388
|
+
const requestOptions = {
|
|
389
|
+
method: "GET"
|
|
390
|
+
};
|
|
391
|
+
await handlePlatformRequest({
|
|
392
|
+
source: this.source,
|
|
393
|
+
baseUrl,
|
|
394
|
+
query,
|
|
395
|
+
requestOptions,
|
|
396
|
+
event,
|
|
397
|
+
logger: log3
|
|
398
|
+
});
|
|
399
|
+
} else {
|
|
400
|
+
throw new Error("Invalid config for platform " + this.source);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
// src/publishers/facebook.ts
|
|
407
|
+
var facebook = {
|
|
408
|
+
source: "Faceboook",
|
|
409
|
+
/**
|
|
410
|
+
*Publishes data to Facebook
|
|
411
|
+
* @param log Azure Function context.log
|
|
412
|
+
* @param config Publisher configuration
|
|
413
|
+
* @param data Data in publisher-friendly format to be published
|
|
414
|
+
* @param event Event for which the function is triggered
|
|
415
|
+
*/
|
|
416
|
+
async publish(log3, config, data, event) {
|
|
417
|
+
if (typeof config.id === "string" && typeof config.access_token === "string") {
|
|
418
|
+
const requestOptions = {
|
|
419
|
+
method: "POST",
|
|
420
|
+
body: JSON.stringify({ data: [removeUndefined(data)] }),
|
|
421
|
+
headers: {
|
|
422
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
423
|
+
"Content-Type": "application/json"
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
const baseUrl = `https://graph.facebook.com/v11.0/${encodeURIComponent(
|
|
427
|
+
config.id
|
|
428
|
+
)}/events`;
|
|
429
|
+
const query = `?access_token=${encodeURI(config.access_token)}`;
|
|
430
|
+
await handlePlatformRequest({
|
|
431
|
+
source: this.source,
|
|
432
|
+
baseUrl,
|
|
433
|
+
query,
|
|
434
|
+
requestOptions,
|
|
435
|
+
event,
|
|
436
|
+
logger: log3
|
|
437
|
+
});
|
|
438
|
+
} else {
|
|
439
|
+
throw new Error("Invalid config for platform " + this.source);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
// src/publishers/googleAnalytics4.ts
|
|
445
|
+
var googleAnalytics4 = {
|
|
446
|
+
source: "GoogleAnalytics4",
|
|
447
|
+
/**
|
|
448
|
+
* Publishes data to Google Analytics
|
|
449
|
+
* @param log zure Function context.log
|
|
450
|
+
* @param config Publisher configuration
|
|
451
|
+
* @param data Data in publisher-friendly format to be published
|
|
452
|
+
* @param event Event for which the function is triggered
|
|
453
|
+
*/
|
|
454
|
+
async publish(log3, config, data, event) {
|
|
455
|
+
if (config.trackingId) {
|
|
456
|
+
const ga4Data = removeUndefined(data);
|
|
457
|
+
ga4Data.v = 2;
|
|
458
|
+
ga4Data.seg = 1;
|
|
459
|
+
ga4Data.gcs = 111;
|
|
460
|
+
ga4Data.tid = config.trackingId;
|
|
461
|
+
let payload = "";
|
|
462
|
+
for (const property in ga4Data) {
|
|
463
|
+
if (Object.prototype.hasOwnProperty.call(ga4Data, property)) {
|
|
464
|
+
if (payload) {
|
|
465
|
+
payload += "&";
|
|
466
|
+
}
|
|
467
|
+
payload += encodeURI(property) + "=" + encodeURI(ga4Data[property]);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
const requestOptions = {
|
|
471
|
+
method: "POST",
|
|
472
|
+
headers: {
|
|
473
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
474
|
+
"User-Agent": "mHub Cloud"
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
const baseUrl = "https://www.google-analytics.com/g/collect";
|
|
478
|
+
const query = `?${payload}`;
|
|
479
|
+
await handlePlatformRequest({
|
|
480
|
+
source: this.source,
|
|
481
|
+
baseUrl,
|
|
482
|
+
query,
|
|
483
|
+
requestOptions,
|
|
484
|
+
event,
|
|
485
|
+
logger: log3
|
|
486
|
+
});
|
|
487
|
+
} else {
|
|
488
|
+
throw new Error("Invalid config for platform " + this.source);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
// src/publishers/piano.ts
|
|
494
|
+
var piano = {
|
|
495
|
+
source: "Piano",
|
|
496
|
+
/**
|
|
497
|
+
* Publishes data to Piano
|
|
498
|
+
* @param log zure Function context.log
|
|
499
|
+
* @param config Publisher configuration
|
|
500
|
+
* @param data Data in publisher-friendly format to be published
|
|
501
|
+
* @param event Event for which the function is triggered
|
|
502
|
+
*/
|
|
503
|
+
async publish(log3, config, data, event) {
|
|
504
|
+
if (typeof config.siteId === "string" && typeof config.collectionDomain === "string") {
|
|
505
|
+
const pianoData = removeUndefined(data);
|
|
506
|
+
let query = "";
|
|
507
|
+
query = "?s=" + encodeURI(config.siteId);
|
|
508
|
+
query += "&idclient=" + encodeURI(pianoData.aux.visitorId);
|
|
509
|
+
query += "&ref=" + encodeURI(pianoData.aux.ref);
|
|
510
|
+
const requestOptions = {
|
|
511
|
+
method: "POST"
|
|
512
|
+
};
|
|
513
|
+
requestOptions.headers = {};
|
|
514
|
+
if (pianoData.aux.userAgent) {
|
|
515
|
+
requestOptions.headers["User-Agent"] = pianoData.aux.userAgent;
|
|
516
|
+
}
|
|
517
|
+
if (pianoData.aux.referer) {
|
|
518
|
+
requestOptions.headers.Referer = pianoData.aux.referer;
|
|
519
|
+
}
|
|
520
|
+
if (pianoData.aux.forwardedFor) {
|
|
521
|
+
requestOptions.headers["X-Forwarded-For"] = pianoData.aux.forwardedFor;
|
|
522
|
+
}
|
|
523
|
+
const baseUrl = `https://${config.collectionDomain}/`;
|
|
524
|
+
await handlePlatformRequest({
|
|
525
|
+
source: this.source,
|
|
526
|
+
baseUrl,
|
|
527
|
+
query,
|
|
528
|
+
requestOptions,
|
|
529
|
+
event,
|
|
530
|
+
logger: log3
|
|
531
|
+
});
|
|
532
|
+
} else {
|
|
533
|
+
throw new Error("Invalid config for platform " + this.source);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
// src/publishers/universalAnalytics.ts
|
|
539
|
+
var universalAnalytics = {
|
|
540
|
+
source: "UniversalAnalytics",
|
|
541
|
+
/**
|
|
542
|
+
* Publishes data to UniversalAnalytics
|
|
543
|
+
* @param log zure Function context.log
|
|
544
|
+
* @param config Publisher configuration
|
|
545
|
+
* @param data Data in publisher-friendly format to be published
|
|
546
|
+
* @param event Event for which the function is triggered
|
|
547
|
+
*/
|
|
548
|
+
async publish(log3, config, data, event) {
|
|
549
|
+
if (config.trackingId) {
|
|
550
|
+
const uaData = removeUndefined(data);
|
|
551
|
+
uaData.v = 1;
|
|
552
|
+
uaData.tid = config.trackingId;
|
|
553
|
+
let payload = "";
|
|
554
|
+
for (const property in uaData) {
|
|
555
|
+
if (Object.prototype.hasOwnProperty.call(uaData, property)) {
|
|
556
|
+
if (payload) {
|
|
557
|
+
payload += "&";
|
|
558
|
+
}
|
|
559
|
+
if (uaData[property]) {
|
|
560
|
+
payload += encodeURI(property) + "=" + encodeURI(uaData[property] ?? "");
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
const requestOptions = {
|
|
565
|
+
method: "POST",
|
|
566
|
+
body: payload,
|
|
567
|
+
headers: {
|
|
568
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
569
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
570
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
571
|
+
"User-Agent": "mHub Cloud"
|
|
572
|
+
}
|
|
573
|
+
};
|
|
574
|
+
const baseUrl = "https://www.google-analytics.com/collect";
|
|
575
|
+
const query = `?${payload}`;
|
|
576
|
+
await handlePlatformRequest({
|
|
577
|
+
source: this.source,
|
|
578
|
+
baseUrl,
|
|
579
|
+
query,
|
|
580
|
+
requestOptions,
|
|
581
|
+
event,
|
|
582
|
+
logger: log3
|
|
583
|
+
});
|
|
584
|
+
} else {
|
|
585
|
+
throw new Error("Invalid config for platform " + this.source);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
};
|
|
589
|
+
|
|
590
|
+
// src/utils/testUtils.ts
|
|
591
|
+
var testUtils_exports = {};
|
|
592
|
+
__export(testUtils_exports, {
|
|
593
|
+
context: () => context
|
|
594
|
+
});
|
|
595
|
+
var context = {};
|
|
596
|
+
context.log = function log2(str) {
|
|
597
|
+
console.log(str);
|
|
598
|
+
};
|
|
599
|
+
context.log.warn = function warn(str) {
|
|
600
|
+
console.warn(str);
|
|
601
|
+
};
|
|
602
|
+
|
|
603
|
+
// src/index.ts
|
|
604
|
+
var publisher = {
|
|
605
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
606
|
+
Facebook: facebook,
|
|
607
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
608
|
+
CJ: cj,
|
|
609
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
610
|
+
GoogleAnalytics4: googleAnalytics4,
|
|
611
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
612
|
+
UniversalAnalytics: universalAnalytics,
|
|
613
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
614
|
+
Piano: piano,
|
|
615
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
616
|
+
AffiliatePort: affiliatePort
|
|
617
|
+
};
|
|
618
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
619
|
+
0 && (module.exports = {
|
|
620
|
+
DefaultPublisher,
|
|
621
|
+
publisher,
|
|
622
|
+
testUtils,
|
|
623
|
+
utils
|
|
624
|
+
});
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mhubcloud/tms_core",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.2",
|
|
4
4
|
"description": "Core function for mHub Cloud TMS publishers",
|
|
5
5
|
"homepage": "https://mhubcloud.com/",
|
|
6
6
|
"license": "Apache 2.0",
|
|
7
7
|
"email": "info@crossmasters.com",
|
|
8
8
|
"author": "Jan Brzobohatý",
|
|
9
|
-
"main": "index.js",
|
|
9
|
+
"main": "dist/index.js",
|
|
10
10
|
"keywords": [
|
|
11
11
|
"mHub Cloud",
|
|
12
12
|
"TMS",
|
package/src/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { facebook } from './publishers/facebook';
|
|
|
5
5
|
import { googleAnalytics4 } from './publishers/googleAnalytics4';
|
|
6
6
|
import { piano } from './publishers/piano';
|
|
7
7
|
import { universalAnalytics } from './publishers/universalAnalytics';
|
|
8
|
+
import * as testUtils from './utils/testUtils';
|
|
8
9
|
import * as utils from './utils/utils';
|
|
9
10
|
|
|
10
11
|
export const publisher = {
|
|
@@ -22,4 +23,4 @@ export const publisher = {
|
|
|
22
23
|
AffiliatePort: affiliatePort,
|
|
23
24
|
};
|
|
24
25
|
|
|
25
|
-
export { utils, defaultPublisher as DefaultPublisher };
|
|
26
|
+
export { utils, defaultPublisher as DefaultPublisher, testUtils };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface LogFunction {
|
|
2
|
+
(str: string): void;
|
|
3
|
+
warn: (str: string) => void;
|
|
4
|
+
}
|
|
5
|
+
// TODO tohle by se mělo dát spíš do nějakých obecných types asi
|
|
6
|
+
interface Context {
|
|
7
|
+
log: LogFunction;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const context: Context = {} as Context;
|
|
11
|
+
context.log = function log(str: string) {
|
|
12
|
+
console.log(str);
|
|
13
|
+
} as LogFunction;
|
|
14
|
+
context.log.warn = function warn(str: string) {
|
|
15
|
+
console.warn(str);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export { context };
|
package/tests/AffiliatePort.js
CHANGED
|
@@ -2,7 +2,7 @@ const publisher = require('../dist/index.js').publisher.AffiliatePort;
|
|
|
2
2
|
const defaultPublisher = require('../dist/index.js').DefaultPublisher;
|
|
3
3
|
const utils = require('../dist/index.js').utils;
|
|
4
4
|
var assert = require('assert');
|
|
5
|
-
const testUtils = require('
|
|
5
|
+
const testUtils = require('../dist/index.js').testUtils;
|
|
6
6
|
|
|
7
7
|
describe('test AffiliatePort publisher', function () {
|
|
8
8
|
it('purchase', async function () {
|
package/tests/CJ.js
CHANGED
|
@@ -2,7 +2,7 @@ const publisher = require('../dist/index.js').publisher.CJ;
|
|
|
2
2
|
const defaultPublisher = require('../dist/index.js').DefaultPublisher;
|
|
3
3
|
const utils = require('../dist/index.js').utils;
|
|
4
4
|
var assert = require('assert');
|
|
5
|
-
const testUtils = require('
|
|
5
|
+
const testUtils = require('../dist/index.js').testUtils;
|
|
6
6
|
|
|
7
7
|
describe('test CJ publisher', function () {
|
|
8
8
|
it('purchase', async function () {
|
package/tests/Facebook.js
CHANGED
|
@@ -2,7 +2,7 @@ const publisher = require('../dist/index.js').publisher.Facebook;
|
|
|
2
2
|
const defaultPublisher = require('../dist/index.js').DefaultPublisher;
|
|
3
3
|
const utils = require('../dist/index.js').utils;
|
|
4
4
|
var assert = require('assert');
|
|
5
|
-
const testUtils = require('
|
|
5
|
+
const testUtils = require('../dist/index.js').testUtils;
|
|
6
6
|
|
|
7
7
|
describe('test Facebook publisher', function () {
|
|
8
8
|
it('purchase', async function () {
|