@saasquatch/program-boilerplate 3.10.1-6 → 3.10.2-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/dist/conversion.d.ts +5 -5
- package/dist/conversion.js +27 -14
- package/dist/index.js +30 -16
- package/dist/jsonata.js +7 -8
- package/dist/logger.js +3 -4
- package/dist/queries.d.ts +2 -2
- package/dist/queries.js +24 -3
- package/dist/transaction.d.ts +7 -5
- package/dist/transaction.js +11 -3
- package/dist/trigger.d.ts +1 -1
- package/dist/trigger.js +25 -41
- package/dist/types/index.js +22 -8
- package/dist/types/rpc.d.ts +48 -24
- package/dist/types/saasquatch.d.ts +66 -9
- package/dist/utils.d.ts +3 -3
- package/dist/utils.js +12 -16
- package/package.json +11 -11
package/dist/conversion.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
/**
|
|
5
5
|
* A custom field based conversion rule
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
type CustomFieldConversionRule = {
|
|
8
8
|
operator: number | string;
|
|
9
9
|
fieldName: string;
|
|
10
10
|
value: RuleValue;
|
|
@@ -12,7 +12,7 @@ declare type CustomFieldConversionRule = {
|
|
|
12
12
|
/**
|
|
13
13
|
* An event-based conversion rule
|
|
14
14
|
*/
|
|
15
|
-
|
|
15
|
+
type EventTriggerRule = {
|
|
16
16
|
operator: string;
|
|
17
17
|
eventKey: string;
|
|
18
18
|
value: string;
|
|
@@ -20,7 +20,7 @@ declare type EventTriggerRule = {
|
|
|
20
20
|
/**
|
|
21
21
|
* A key-value pair
|
|
22
22
|
*/
|
|
23
|
-
|
|
23
|
+
type Event = {
|
|
24
24
|
key: string;
|
|
25
25
|
fields: {
|
|
26
26
|
[key: string]: any;
|
|
@@ -29,7 +29,7 @@ declare type Event = {
|
|
|
29
29
|
/**
|
|
30
30
|
* A user object returned from a GraphQL query
|
|
31
31
|
*/
|
|
32
|
-
|
|
32
|
+
type UserQueryResult = {
|
|
33
33
|
customFields: {
|
|
34
34
|
[key: string]: any;
|
|
35
35
|
};
|
|
@@ -37,7 +37,7 @@ declare type UserQueryResult = {
|
|
|
37
37
|
/**
|
|
38
38
|
* The value of a rule
|
|
39
39
|
*/
|
|
40
|
-
|
|
40
|
+
type RuleValue = string | boolean | number;
|
|
41
41
|
/**
|
|
42
42
|
* Checks whether any of the edge trigger conditions are met given
|
|
43
43
|
* a list of fields to check and the current context.
|
package/dist/conversion.js
CHANGED
|
@@ -4,7 +4,11 @@
|
|
|
4
4
|
*/
|
|
5
5
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
6
|
if (k2 === undefined) k2 = k;
|
|
7
|
-
Object.
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
8
12
|
}) : (function(o, m, k, k2) {
|
|
9
13
|
if (k2 === undefined) k2 = k;
|
|
10
14
|
o[k2] = m[k];
|
|
@@ -14,15 +18,27 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
14
18
|
}) : function(o, v) {
|
|
15
19
|
o["default"] = v;
|
|
16
20
|
});
|
|
17
|
-
var __importStar = (this && this.__importStar) || function (
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
};
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
24
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.
|
|
39
|
+
exports.meetEdgeTriggerConditions = meetEdgeTriggerConditions;
|
|
40
|
+
exports.meetCustomFieldRules = meetCustomFieldRules;
|
|
41
|
+
exports.meetEventTriggerRules = meetEventTriggerRules;
|
|
26
42
|
const assert = __importStar(require("assert"));
|
|
27
43
|
const jsonata_1 = require("./jsonata");
|
|
28
44
|
//functions
|
|
@@ -66,8 +82,8 @@ function meetEdgeTriggerConditions(fields, activeTrigger) {
|
|
|
66
82
|
// not take more than a few milliseconds. if it takes longer than 500ms
|
|
67
83
|
// something is definitely wrong with the query
|
|
68
84
|
const jsonataTimeoutMs = 500;
|
|
69
|
-
const { success: prevSuccess, result: previousValue } = jsonata_1.timeboxedJsonata(field.replace("user.", "previous."), activeTrigger, jsonataTimeoutMs);
|
|
70
|
-
const { success: currentSuccess, result: currentValue } = jsonata_1.timeboxedJsonata(field, activeTrigger, jsonataTimeoutMs);
|
|
85
|
+
const { success: prevSuccess, result: previousValue } = (0, jsonata_1.timeboxedJsonata)(field.replace("user.", "previous."), activeTrigger, jsonataTimeoutMs);
|
|
86
|
+
const { success: currentSuccess, result: currentValue } = (0, jsonata_1.timeboxedJsonata)(field, activeTrigger, jsonataTimeoutMs);
|
|
71
87
|
// one of the JSONata expressions failed to evaluate -- edge field is considered
|
|
72
88
|
// "not passing"
|
|
73
89
|
if (!prevSuccess || !currentSuccess) {
|
|
@@ -85,7 +101,6 @@ function meetEdgeTriggerConditions(fields, activeTrigger) {
|
|
|
85
101
|
}
|
|
86
102
|
return false;
|
|
87
103
|
}
|
|
88
|
-
exports.meetEdgeTriggerConditions = meetEdgeTriggerConditions;
|
|
89
104
|
/**
|
|
90
105
|
* Checks if the customFields of a user meet a certain customField-based conversion rule.
|
|
91
106
|
*
|
|
@@ -151,7 +166,6 @@ function meetCustomFieldRules(user, customConversionRules) {
|
|
|
151
166
|
}
|
|
152
167
|
return customConversionRules.every((rule) => meetCustomFieldCondition(user, rule));
|
|
153
168
|
}
|
|
154
|
-
exports.meetCustomFieldRules = meetCustomFieldRules;
|
|
155
169
|
/**
|
|
156
170
|
* @deprecated No longer in use, use JSONata expression and evaluation instead
|
|
157
171
|
* Checks if the events triggering the program meet every rule that defines event-based conversion
|
|
@@ -169,4 +183,3 @@ function meetEventTriggerRules(events, eventTriggerRules) {
|
|
|
169
183
|
}
|
|
170
184
|
return eventTriggerRules.every((rule) => meetEventCondition(events, rule));
|
|
171
185
|
}
|
|
172
|
-
exports.meetEventTriggerRules = meetEventTriggerRules;
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -11,18 +15,30 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
11
15
|
}) : function(o, v) {
|
|
12
16
|
o["default"] = v;
|
|
13
17
|
});
|
|
14
|
-
var __importStar = (this && this.__importStar) || function (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
21
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
37
|
};
|
|
24
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.
|
|
39
|
+
exports.loadStandardWebtaskConfig = exports.setLogLevel = exports.getLogger = exports.safeJsonata = exports.timeboxedJsonata = exports.timeboxExpression = exports.getRewardUnitsFromJsonata = exports.getUserCustomFieldsFromJsonata = exports.getTriggerSchema = exports.numToEquality = exports.inferType = exports.triggerProgram = exports.getGoalAnalyticTimestamp = exports.setRewardSchedule = exports.rewardEmailQuery = exports.meetEdgeTriggerConditions = exports.meetCustomFieldRules = exports.meetEventTriggerRules = exports.Transaction = exports.types = void 0;
|
|
40
|
+
exports.webtask = webtask;
|
|
41
|
+
exports.runWebtask = runWebtask;
|
|
26
42
|
const express_1 = __importDefault(require("express"));
|
|
27
43
|
const conversion_1 = require("./conversion");
|
|
28
44
|
Object.defineProperty(exports, "meetCustomFieldRules", { enumerable: true, get: function () { return conversion_1.meetCustomFieldRules; } });
|
|
@@ -64,11 +80,11 @@ const logger_3 = require("@saasquatch/logger");
|
|
|
64
80
|
*/
|
|
65
81
|
function webtask(program = {}) {
|
|
66
82
|
const compression = require("compression");
|
|
67
|
-
const app = express_1.default();
|
|
68
|
-
const logger = logger_2.getLogger("program-boilerplate");
|
|
83
|
+
const app = (0, express_1.default)();
|
|
84
|
+
const logger = (0, logger_2.getLogger)("program-boilerplate");
|
|
69
85
|
app.use(express_1.default.json({ limit: process.env.MAX_PAYLOAD_SIZE || "1mb" }));
|
|
70
86
|
app.use(compression());
|
|
71
|
-
app.use(logger_3.httpLogMiddleware(logger, { logNonErrorResponses: false }));
|
|
87
|
+
app.use((0, logger_3.httpLogMiddleware)(logger, { logNonErrorResponses: false }));
|
|
72
88
|
// Enforce HTTPS. The server does not redirect http -> https
|
|
73
89
|
// because OWASP advises not to
|
|
74
90
|
app.use((req, res, next) => {
|
|
@@ -92,14 +108,13 @@ function webtask(program = {}) {
|
|
|
92
108
|
app.get("/livez", healthCheck);
|
|
93
109
|
app.get("/readyz", healthCheck);
|
|
94
110
|
app.post("/*", (req, res) => {
|
|
95
|
-
const { json, code } = trigger_1.triggerProgram(req.body, program);
|
|
111
|
+
const { json, code } = (0, trigger_1.triggerProgram)(req.body, program);
|
|
96
112
|
return res.status(code).json(json);
|
|
97
113
|
});
|
|
98
114
|
return app;
|
|
99
115
|
}
|
|
100
|
-
exports.webtask = webtask;
|
|
101
116
|
function runWebtask(webtask, config) {
|
|
102
|
-
const logger = logger_2.getLogger("program-boilerplate");
|
|
117
|
+
const logger = (0, logger_2.getLogger)("program-boilerplate");
|
|
103
118
|
const server = webtask.listen(config.port, () => logger.notice(`${config.webtaskName} running on port ${config.port}`));
|
|
104
119
|
if (config.keepAliveTimeoutSeconds !== undefined) {
|
|
105
120
|
// https://cloud.google.com/load-balancing/docs/https/https-logging-monitoring#failure-messages
|
|
@@ -123,4 +138,3 @@ function runWebtask(webtask, config) {
|
|
|
123
138
|
process.on("SIGTERM", gracefulShutdown("SIGTERM"));
|
|
124
139
|
process.on("SIGINT", gracefulShutdown("SIGINT"));
|
|
125
140
|
}
|
|
126
|
-
exports.runWebtask = runWebtask;
|
package/dist/jsonata.js
CHANGED
|
@@ -3,7 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.timeboxExpression = timeboxExpression;
|
|
7
|
+
exports.safeJsonata = safeJsonata;
|
|
8
|
+
exports.timeboxedJsonata = timeboxedJsonata;
|
|
7
9
|
const jsonata_1 = __importDefault(require("jsonata"));
|
|
8
10
|
const logger_1 = require("@saasquatch/logger");
|
|
9
11
|
const TIMEOUT = 5000;
|
|
@@ -49,33 +51,30 @@ function timeboxExpression(expr, timeout, maxDepth) {
|
|
|
49
51
|
checkRunnaway();
|
|
50
52
|
});
|
|
51
53
|
}
|
|
52
|
-
exports.timeboxExpression = timeboxExpression;
|
|
53
54
|
/**
|
|
54
55
|
* @deprecated Use timeboxedJsonata instead
|
|
55
56
|
*/
|
|
56
57
|
function safeJsonata(expression, inputData) {
|
|
57
58
|
try {
|
|
58
|
-
const jsonataQuery = jsonata_1.default(expression);
|
|
59
|
+
const jsonataQuery = (0, jsonata_1.default)(expression);
|
|
59
60
|
timeboxExpression(jsonataQuery);
|
|
60
61
|
return jsonataQuery.evaluate(inputData);
|
|
61
62
|
}
|
|
62
63
|
catch (e) {
|
|
63
|
-
logger_1.getLogger("program-boilerplate").warn(`Failed to evaluate JSONata expression: ${e.message}`);
|
|
64
|
+
(0, logger_1.getLogger)("program-boilerplate").warn(`Failed to evaluate JSONata expression: ${e.message}`);
|
|
64
65
|
}
|
|
65
66
|
}
|
|
66
|
-
exports.safeJsonata = safeJsonata;
|
|
67
67
|
function timeboxedJsonata(expression, inputData, timeout, maxDepth) {
|
|
68
68
|
try {
|
|
69
|
-
const jsonataQuery = jsonata_1.default(expression);
|
|
69
|
+
const jsonataQuery = (0, jsonata_1.default)(expression);
|
|
70
70
|
timeboxExpression(jsonataQuery, timeout, maxDepth);
|
|
71
71
|
const result = jsonataQuery.evaluate(inputData);
|
|
72
72
|
return { success: true, result };
|
|
73
73
|
}
|
|
74
74
|
catch (e) {
|
|
75
75
|
if (e instanceof Error) {
|
|
76
|
-
logger_1.getLogger("program-boilerplate").warn(`Failed to evaluate JSONata expression: ${e.message}`);
|
|
76
|
+
(0, logger_1.getLogger)("program-boilerplate").warn(`Failed to evaluate JSONata expression: ${e.message}`);
|
|
77
77
|
}
|
|
78
78
|
return { success: false, result: undefined };
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
-
exports.timeboxedJsonata = timeboxedJsonata;
|
package/dist/logger.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getLogger = getLogger;
|
|
4
|
+
exports.setLogLevel = setLogLevel;
|
|
4
5
|
const logger_1 = require("@saasquatch/logger");
|
|
5
6
|
// Lazily initialized logger instance
|
|
6
7
|
let _logger;
|
|
@@ -19,12 +20,11 @@ function getLogger(logLevel) {
|
|
|
19
20
|
if (!logger_1.LOG_LEVELS.includes(logLevel)) {
|
|
20
21
|
logLevel = "info";
|
|
21
22
|
}
|
|
22
|
-
_logger = logger_1.initializeLogger({
|
|
23
|
+
_logger = (0, logger_1.initializeLogger)({
|
|
23
24
|
logLevel: logLevel,
|
|
24
25
|
});
|
|
25
26
|
return _logger;
|
|
26
27
|
}
|
|
27
|
-
exports.getLogger = getLogger;
|
|
28
28
|
/**
|
|
29
29
|
* Set the log level of the singleton logger.
|
|
30
30
|
*
|
|
@@ -35,4 +35,3 @@ function setLogLevel(logLevel) {
|
|
|
35
35
|
return;
|
|
36
36
|
_logger.level = logLevel;
|
|
37
37
|
}
|
|
38
|
-
exports.setLogLevel = setLogLevel;
|
package/dist/queries.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export declare const rewardEmailQuery = "\n query ($userId:String!, $accountId:String!, $rewardId:ID!, $programId:ID!, $referralId: ID!) {\n reward(id:$rewardId) {\n ...AllFlatRewardFields\n }\n user(id:$userId, accountId:$accountId) {\n firstName\n lastName\n customFields\n referralCode(programId:$programId)\n shareLink(programId:$programId,useCleanLink:true)\n facebook: messageLink(programId:$programId,shareMedium:FACEBOOK,engagementMedium:EMAIL)\n twitter: messageLink(programId:$programId,shareMedium:TWITTER,engagementMedium:EMAIL)\n email:messageLink(programId:$programId,shareMedium:EMAIL,engagementMedium:EMAIL)\n sms:messageLink(programId:$programId,shareMedium:SMS,engagementMedium:EMAIL)\n linkedin: messageLink(programId:$programId,shareMedium:LINKEDIN,engagementMedium:EMAIL)\n fbmessenger: messageLink(programId:$programId,shareMedium:FBMESSENGER,engagementMedium:EMAIL)\n }\n\n program(id: $programId) {\n sharing {\n redirectUrl {\n url\n }\n }\n }\n\n referral(id:$referralId) {\n referrerUser{\n firstName\n lastName\n email\n customFields\n }\n referredUser{\n firstName\n lastName\n email\n customFields\n }\n }\n\n tenant {\n emailAddress\n settings {\n companyName\n }\n }\n }\n\n fragment AllFlatRewardFields on FlatReward {\n type\n prettyValue\n value\n unit\n name\n dateGiven\n dateExpires\n dateCancelled\n rewardSource\n fuelTankCode\n fuelTankType\n currency\n programId\n programRewardKey\n }\n";
|
|
2
|
-
export declare const nonRewardEmailQueryForReferralPrograms = "query ($userId:String!, $accountId:String!,$programId:ID!, $referralId: ID!) {\n user(id:$userId, accountId:$accountId) {\n firstName\n lastName\n customFields\n referralCode(programId:$programId)\n shareLink(programId:$programId,useCleanLink:true)\n facebook: messageLink(programId:$programId,shareMedium:FACEBOOK)\n twitter: messageLink(programId:$programId,shareMedium:TWITTER)\n email:messageLink(programId:$programId,shareMedium:EMAIL)\n sms:messageLink(programId:$programId,shareMedium:SMS)\n linkedin: messageLink(programId:$programId,shareMedium:LINKEDIN)\n fbmessenger: messageLink(programId:$programId,shareMedium:FBMESSENGER)\n }\n\n referral(id:$referralId) {\n referrerUser{\n firstName\n lastName\n email\n customFields\n }\n referredUser{\n firstName\n lastName\n email\n customFields\n }\n }\n\n program(id: $programId) {\n sharing {\n redirectUrl {\n url\n }\n }\n }\n\n tenant {\n emailAddress\n settings {\n companyName\n }\n }\n}\n";
|
|
1
|
+
export declare const rewardEmailQuery = "\n query ($userId:String!, $accountId:String!, $rewardId:ID!, $programId:ID!, $referralId: ID!, $eventId: ID, $fetchEvent: Boolean!) {\n reward(id:$rewardId) {\n ...AllFlatRewardFields\n }\n user(id:$userId, accountId:$accountId) {\n firstName\n lastName\n customFields\n referralCode(programId:$programId)\n shareLink(programId:$programId,useCleanLink:true)\n facebook: messageLink(programId:$programId,shareMedium:FACEBOOK,engagementMedium:EMAIL)\n twitter: messageLink(programId:$programId,shareMedium:TWITTER,engagementMedium:EMAIL)\n email:messageLink(programId:$programId,shareMedium:EMAIL,engagementMedium:EMAIL)\n sms:messageLink(programId:$programId,shareMedium:SMS,engagementMedium:EMAIL)\n linkedin: messageLink(programId:$programId,shareMedium:LINKEDIN,engagementMedium:EMAIL)\n fbmessenger: messageLink(programId:$programId,shareMedium:FBMESSENGER,engagementMedium:EMAIL)\n }\n\n program(id: $programId) {\n sharing {\n redirectUrl {\n url\n }\n }\n }\n\n userEvents(filter: {id_eq: $eventId}) @include(if: $fetchEvent) {\n data {\n id\n dateReceived\n dateTriggered\n dateProcessed\n fields\n }\n }\n\n referral(id:$referralId) {\n referrerUser{\n firstName\n lastName\n email\n customFields\n }\n referredUser{\n firstName\n lastName\n email\n customFields\n }\n }\n\n tenant {\n emailAddress\n settings {\n companyName\n }\n }\n }\n\n fragment AllFlatRewardFields on FlatReward {\n type\n prettyValue\n value\n unit\n name\n dateGiven\n dateExpires\n dateCancelled\n rewardSource\n fuelTankCode\n fuelTankType\n currency\n programId\n programRewardKey\n }\n";
|
|
2
|
+
export declare const nonRewardEmailQueryForReferralPrograms = "query ($userId:String!, $accountId:String!,$programId:ID!, $referralId: ID!, $eventId: ID, $fetchEvent: Boolean!) {\n user(id:$userId, accountId:$accountId) {\n firstName\n lastName\n customFields\n referralCode(programId:$programId)\n shareLink(programId:$programId,useCleanLink:true)\n facebook: messageLink(programId:$programId,shareMedium:FACEBOOK)\n twitter: messageLink(programId:$programId,shareMedium:TWITTER)\n email:messageLink(programId:$programId,shareMedium:EMAIL)\n sms:messageLink(programId:$programId,shareMedium:SMS)\n linkedin: messageLink(programId:$programId,shareMedium:LINKEDIN)\n fbmessenger: messageLink(programId:$programId,shareMedium:FBMESSENGER)\n }\n\n userEvents(filter: {id_eq: $eventId}) @include(if: $fetchEvent) {\n data {\n id\n dateReceived\n dateTriggered\n dateProcessed\n fields\n }\n }\n\n referral(id:$referralId) {\n referrerUser{\n firstName\n lastName\n email\n customFields\n }\n referredUser{\n firstName\n lastName\n email\n customFields\n }\n }\n\n program(id: $programId) {\n sharing {\n redirectUrl {\n url\n }\n }\n }\n\n tenant {\n emailAddress\n settings {\n companyName\n }\n }\n}\n";
|
|
3
3
|
export declare const rewardEmailQueryForNonReferralPrograms = "\n query ($userId:String!, $accountId:String!, $rewardId:ID!, $programId:ID!) {\n reward(id:$rewardId) {\n ...AllFlatRewardFields\n }\n user(id:$userId, accountId:$accountId) {\n firstName\n lastName\n customFields\n email:messageLink(programId:$programId,shareMedium:EMAIL)\n }\n\n program(id: $programId) {\n sharing {\n redirectUrl {\n url\n }\n }\n }\n\n tenant {\n emailAddress\n settings {\n companyName\n }\n }\n }\n\n fragment AllFlatRewardFields on FlatReward {\n type\n prettyValue\n value\n unit\n name\n dateGiven\n dateExpires\n dateCancelled\n rewardSource\n fuelTankCode\n fuelTankType\n currency\n programId\n programRewardKey\n }\n";
|
|
4
4
|
export declare const nonRewardEmailQueryForNonReferralPrograms = "\n query ($userId:String!, $accountId:String!, $programId:ID!) {\n user(id:$userId, accountId:$accountId) {\n firstName\n lastName\n customFields\n email:messageLink(programId:$programId,shareMedium:EMAIL)\n }\n\n program(id: $programId) {\n sharing {\n redirectUrl {\n url\n }\n }\n }\n\n tenant {\n emailAddress\n settings {\n companyName\n }\n }\n }\n";
|
|
5
5
|
export declare const rewardScheduleQuery: (emailKey: string) => string;
|
package/dist/queries.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.rewardScheduleQuery = exports.nonRewardEmailQueryForNonReferralPrograms = exports.rewardEmailQueryForNonReferralPrograms = exports.nonRewardEmailQueryForReferralPrograms = exports.rewardEmailQuery = void 0;
|
|
4
4
|
exports.rewardEmailQuery = `
|
|
5
|
-
query ($userId:String!, $accountId:String!, $rewardId:ID!, $programId:ID!, $referralId: ID!) {
|
|
5
|
+
query ($userId:String!, $accountId:String!, $rewardId:ID!, $programId:ID!, $referralId: ID!, $eventId: ID, $fetchEvent: Boolean!) {
|
|
6
6
|
reward(id:$rewardId) {
|
|
7
7
|
...AllFlatRewardFields
|
|
8
8
|
}
|
|
@@ -28,6 +28,16 @@ exports.rewardEmailQuery = `
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
userEvents(filter: {id_eq: $eventId}) @include(if: $fetchEvent) {
|
|
32
|
+
data {
|
|
33
|
+
id
|
|
34
|
+
dateReceived
|
|
35
|
+
dateTriggered
|
|
36
|
+
dateProcessed
|
|
37
|
+
fields
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
31
41
|
referral(id:$referralId) {
|
|
32
42
|
referrerUser{
|
|
33
43
|
firstName
|
|
@@ -68,7 +78,7 @@ exports.rewardEmailQuery = `
|
|
|
68
78
|
programRewardKey
|
|
69
79
|
}
|
|
70
80
|
`;
|
|
71
|
-
exports.nonRewardEmailQueryForReferralPrograms = `query ($userId:String!, $accountId:String!,$programId:ID!, $referralId: ID!) {
|
|
81
|
+
exports.nonRewardEmailQueryForReferralPrograms = `query ($userId:String!, $accountId:String!,$programId:ID!, $referralId: ID!, $eventId: ID, $fetchEvent: Boolean!) {
|
|
72
82
|
user(id:$userId, accountId:$accountId) {
|
|
73
83
|
firstName
|
|
74
84
|
lastName
|
|
@@ -83,6 +93,16 @@ exports.nonRewardEmailQueryForReferralPrograms = `query ($userId:String!, $accou
|
|
|
83
93
|
fbmessenger: messageLink(programId:$programId,shareMedium:FBMESSENGER)
|
|
84
94
|
}
|
|
85
95
|
|
|
96
|
+
userEvents(filter: {id_eq: $eventId}) @include(if: $fetchEvent) {
|
|
97
|
+
data {
|
|
98
|
+
id
|
|
99
|
+
dateReceived
|
|
100
|
+
dateTriggered
|
|
101
|
+
dateProcessed
|
|
102
|
+
fields
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
86
106
|
referral(id:$referralId) {
|
|
87
107
|
referrerUser{
|
|
88
108
|
firstName
|
|
@@ -185,7 +205,7 @@ exports.nonRewardEmailQueryForNonReferralPrograms = `
|
|
|
185
205
|
}
|
|
186
206
|
`;
|
|
187
207
|
//context for reward schedule trigger
|
|
188
|
-
|
|
208
|
+
const rewardScheduleQuery = (emailKey) => {
|
|
189
209
|
const query = `query ProgramTrigger($programId: ID!) {
|
|
190
210
|
activeTrigger: activeProgramTrigger {
|
|
191
211
|
type
|
|
@@ -350,3 +370,4 @@ exports.rewardScheduleQuery = (emailKey) => {
|
|
|
350
370
|
}`;
|
|
351
371
|
return query;
|
|
352
372
|
};
|
|
373
|
+
exports.rewardScheduleQuery = rewardScheduleQuery;
|
package/dist/transaction.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ProgramTriggerBody } from "./types/rpc";
|
|
2
2
|
import { ProgramType, User } from "./types/saasquatch";
|
|
3
|
-
|
|
3
|
+
type TransactionContext = {
|
|
4
4
|
body: ProgramTriggerBody;
|
|
5
5
|
};
|
|
6
|
-
|
|
6
|
+
type ReferralRewardInput = {
|
|
7
7
|
rewardKey: string;
|
|
8
8
|
user: User;
|
|
9
9
|
referralId: string;
|
|
@@ -87,11 +87,12 @@ export default class Transaction {
|
|
|
87
87
|
user: User;
|
|
88
88
|
rewardId?: string;
|
|
89
89
|
}): void;
|
|
90
|
-
generateReferralEmail({ emailKey, user, referralId, rewardId, }: {
|
|
90
|
+
generateReferralEmail({ emailKey, user, referralId, rewardId, eventId, }: {
|
|
91
91
|
emailKey: string;
|
|
92
92
|
user: User;
|
|
93
93
|
referralId: string;
|
|
94
94
|
rewardId?: string;
|
|
95
|
+
eventId?: string;
|
|
95
96
|
}): void;
|
|
96
97
|
/**
|
|
97
98
|
* Generates both reward and email.
|
|
@@ -104,7 +105,7 @@ export default class Transaction {
|
|
|
104
105
|
/**
|
|
105
106
|
* Generates both reward and email for a referral.
|
|
106
107
|
*/
|
|
107
|
-
generateReferralRewardAndEmail({ emailKey, rewardKey, referralId, user, status, overrideProperties, dynamicProperties, }: {
|
|
108
|
+
generateReferralRewardAndEmail({ emailKey, rewardKey, referralId, user, status, overrideProperties, dynamicProperties, eventId, }: {
|
|
108
109
|
emailKey: string;
|
|
109
110
|
rewardKey: string;
|
|
110
111
|
referralId: string;
|
|
@@ -112,6 +113,7 @@ export default class Transaction {
|
|
|
112
113
|
status?: string;
|
|
113
114
|
overrideProperties?: any;
|
|
114
115
|
dynamicProperties?: any;
|
|
116
|
+
eventId?: string;
|
|
115
117
|
}): void;
|
|
116
118
|
generateRefunds(): void;
|
|
117
119
|
/**
|
|
@@ -119,7 +121,7 @@ export default class Transaction {
|
|
|
119
121
|
*/
|
|
120
122
|
toJson(): {
|
|
121
123
|
mutations: any[];
|
|
122
|
-
programId:
|
|
124
|
+
programId: string;
|
|
123
125
|
analytics: any[];
|
|
124
126
|
};
|
|
125
127
|
}
|
package/dist/transaction.js
CHANGED
|
@@ -160,12 +160,14 @@ class Transaction {
|
|
|
160
160
|
};
|
|
161
161
|
this.mutations = [...this.mutations, newMutation];
|
|
162
162
|
}
|
|
163
|
-
generateReferralEmail({ emailKey, user, referralId, rewardId, }) {
|
|
163
|
+
generateReferralEmail({ emailKey, user, referralId, rewardId, eventId, }) {
|
|
164
164
|
const variables = {
|
|
165
165
|
userId: user.id,
|
|
166
166
|
accountId: user.accountId,
|
|
167
167
|
programId: this.context.body.program.id,
|
|
168
168
|
referralId: referralId,
|
|
169
|
+
eventId: eventId,
|
|
170
|
+
fetchEvent: !!eventId,
|
|
169
171
|
};
|
|
170
172
|
const queryVariables = rewardId ? Object.assign(Object.assign({}, variables), { rewardId }) : variables;
|
|
171
173
|
const newMutation = {
|
|
@@ -198,7 +200,7 @@ class Transaction {
|
|
|
198
200
|
/**
|
|
199
201
|
* Generates both reward and email for a referral.
|
|
200
202
|
*/
|
|
201
|
-
generateReferralRewardAndEmail({ emailKey, rewardKey, referralId, user, status, overrideProperties, dynamicProperties, }) {
|
|
203
|
+
generateReferralRewardAndEmail({ emailKey, rewardKey, referralId, user, status, overrideProperties, dynamicProperties, eventId, }) {
|
|
202
204
|
const { rewardId } = this.generateReferralReward({
|
|
203
205
|
rewardKey,
|
|
204
206
|
referralId,
|
|
@@ -209,7 +211,13 @@ class Transaction {
|
|
|
209
211
|
overrideProperties,
|
|
210
212
|
dynamicProperties,
|
|
211
213
|
});
|
|
212
|
-
this.generateReferralEmail({
|
|
214
|
+
this.generateReferralEmail({
|
|
215
|
+
emailKey,
|
|
216
|
+
user,
|
|
217
|
+
referralId,
|
|
218
|
+
rewardId,
|
|
219
|
+
eventId,
|
|
220
|
+
});
|
|
213
221
|
}
|
|
214
222
|
generateRefunds() {
|
|
215
223
|
const refundEvents = (this.events || []).filter((e) => e.key === "refund" &&
|
package/dist/trigger.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Program, ProgramIntrospectionBody, ProgramTriggerBody, ProgramTriggerResult, ProgramValidationBody, ProgramVariableSchemaRequestBody } from "./types/rpc";
|
|
2
2
|
/**
|
|
3
3
|
* Triggers the program and returns the result (JSON + HTTP code)
|
|
4
4
|
*
|
package/dist/trigger.js
CHANGED
|
@@ -3,9 +3,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.triggerProgram =
|
|
7
|
-
const transaction_1 = __importDefault(require("./transaction"));
|
|
6
|
+
exports.triggerProgram = triggerProgram;
|
|
8
7
|
const logger_1 = require("@saasquatch/logger");
|
|
8
|
+
const transaction_1 = __importDefault(require("./transaction"));
|
|
9
|
+
function handleTriggerError(triggerType, e) {
|
|
10
|
+
const stack = typeof e === "object" && e !== null && "stack" in e ? e.stack : undefined;
|
|
11
|
+
const message = typeof e === "object" && e !== null && "message" in e
|
|
12
|
+
? e.message
|
|
13
|
+
: undefined;
|
|
14
|
+
const errorMes = {
|
|
15
|
+
error: `An error occurred in a webtask (${triggerType})`,
|
|
16
|
+
// consider not returning stack trace for security reasons
|
|
17
|
+
message: typeof e === "object" && e !== null && "stack" in e ? e.stack : undefined,
|
|
18
|
+
};
|
|
19
|
+
(0, logger_1.getLogger)("program-boilerplate").error({
|
|
20
|
+
message: errorMes.error,
|
|
21
|
+
["error.message"]: message,
|
|
22
|
+
["error.stack"]: stack,
|
|
23
|
+
});
|
|
24
|
+
return errorMes;
|
|
25
|
+
}
|
|
9
26
|
/**
|
|
10
27
|
* Triggers the program and returns the result (JSON + HTTP code)
|
|
11
28
|
*
|
|
@@ -40,14 +57,13 @@ function triggerProgram(body, program = {}) {
|
|
|
40
57
|
return handleProgramVariableSchemaRequest(body, program);
|
|
41
58
|
default:
|
|
42
59
|
const message = `Unrecognized messageType ${body.messageType}`;
|
|
43
|
-
logger_1.getLogger("program-boilerplate").warn(message);
|
|
60
|
+
(0, logger_1.getLogger)("program-boilerplate").warn(message);
|
|
44
61
|
return {
|
|
45
62
|
json: { message },
|
|
46
63
|
code: 501,
|
|
47
64
|
};
|
|
48
65
|
}
|
|
49
66
|
}
|
|
50
|
-
exports.triggerProgram = triggerProgram;
|
|
51
67
|
/**
|
|
52
68
|
* Trigger the program for the default cases
|
|
53
69
|
*
|
|
@@ -70,20 +86,8 @@ function handleProgramTrigger(body, program) {
|
|
|
70
86
|
};
|
|
71
87
|
}
|
|
72
88
|
catch (e) {
|
|
73
|
-
const errorMes =
|
|
74
|
-
|
|
75
|
-
// consider not returning stack trace for security reasons
|
|
76
|
-
message: e.stack,
|
|
77
|
-
};
|
|
78
|
-
logger_1.getLogger("program-boilerplate").error({
|
|
79
|
-
message: errorMes.error,
|
|
80
|
-
["error.message"]: e.message,
|
|
81
|
-
["error.stack"]: e.stack,
|
|
82
|
-
});
|
|
83
|
-
return {
|
|
84
|
-
json: errorMes,
|
|
85
|
-
code: 500,
|
|
86
|
-
};
|
|
89
|
+
const errorMes = handleTriggerError(triggerType, e);
|
|
90
|
+
return { json: errorMes, code: 500 };
|
|
87
91
|
}
|
|
88
92
|
}
|
|
89
93
|
/**
|
|
@@ -111,20 +115,8 @@ function handleProgramIntrospection(body, program) {
|
|
|
111
115
|
};
|
|
112
116
|
}
|
|
113
117
|
catch (e) {
|
|
114
|
-
const errorMes =
|
|
115
|
-
|
|
116
|
-
// consider not returning stack trace for security reasons
|
|
117
|
-
message: e.stack,
|
|
118
|
-
};
|
|
119
|
-
logger_1.getLogger("program-boilerplate").error({
|
|
120
|
-
message: "Error ocurred in a webtask",
|
|
121
|
-
["error.message"]: e.message,
|
|
122
|
-
["error.stack"]: e.stack,
|
|
123
|
-
});
|
|
124
|
-
return {
|
|
125
|
-
json: errorMes,
|
|
126
|
-
code: 500,
|
|
127
|
-
};
|
|
118
|
+
const errorMes = handleTriggerError(body.messageType, e);
|
|
119
|
+
return { json: errorMes, code: 500 };
|
|
128
120
|
}
|
|
129
121
|
}
|
|
130
122
|
/**
|
|
@@ -181,15 +173,7 @@ function handleProgramVariableSchemaRequest(body, program) {
|
|
|
181
173
|
newSchema = handleSchemaRequest(schema, triggerType, scheduleKey);
|
|
182
174
|
}
|
|
183
175
|
catch (e) {
|
|
184
|
-
|
|
185
|
-
error: "An error occurred in a webtask (PROGRAM_TRIGGER_VARIABLES_SCHEMA_REQUEST)",
|
|
186
|
-
message: e.stack,
|
|
187
|
-
};
|
|
188
|
-
logger_1.getLogger("program-boilerplate").error({
|
|
189
|
-
message: errorMes.error,
|
|
190
|
-
["error.message"]: e.message,
|
|
191
|
-
["error.stack"]: e.stack,
|
|
192
|
-
});
|
|
176
|
+
handleTriggerError(body.messageType, e);
|
|
193
177
|
}
|
|
194
178
|
if (!newSchema) {
|
|
195
179
|
return {
|
package/dist/types/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -11,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
11
15
|
}) : function(o, v) {
|
|
12
16
|
o["default"] = v;
|
|
13
17
|
});
|
|
14
|
-
var __importStar = (this && this.__importStar) || function (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
21
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
36
|
exports.saasquatch = exports.rpc = void 0;
|
|
23
37
|
const rpc = __importStar(require("./rpc"));
|
package/dist/types/rpc.d.ts
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import { ProgramTemplateBuilder } from "@saasquatch/schema/types/ProgramTemplate";
|
|
2
2
|
import Transaction from "../transaction";
|
|
3
|
+
import { Referral, RSJsonNode, User, UserEvent } from "./saasquatch";
|
|
3
4
|
/********************************************************/
|
|
4
5
|
/********************************************************/
|
|
5
6
|
/**
|
|
6
7
|
* The different trigger handlers the programs can export
|
|
7
8
|
*/
|
|
8
|
-
export
|
|
9
|
+
export type ActiveTriggerType = "AFTER_USER_CREATED_OR_UPDATED" | "SCHEDULED" | "REWARD_SCHEDULED" | "REFERRAL" | "AFTER_USER_EVENT_PROCESSED";
|
|
10
|
+
/**
|
|
11
|
+
* The different trigger handlers the programs can export
|
|
12
|
+
*/
|
|
13
|
+
export type TriggerType = ActiveTriggerType | ("PROGRAM_INTROSPECTION" | "PROGRAM_VALIDATION" | "PROGRAM_TRIGGER_VARIABLES_SCHEMA_REQUEST");
|
|
9
14
|
/**
|
|
10
15
|
* The Program type
|
|
11
16
|
*/
|
|
12
|
-
export
|
|
17
|
+
export type Program = {
|
|
13
18
|
AFTER_USER_CREATED_OR_UPDATED?: ProgramTriggerHandler;
|
|
14
19
|
AFTER_USER_EVENT_PROCESSED?: ProgramTriggerHandler;
|
|
15
20
|
REFERRAL?: ProgramTriggerHandler;
|
|
@@ -22,13 +27,24 @@ export declare type Program = {
|
|
|
22
27
|
/********************************************************/
|
|
23
28
|
/********************************************************/
|
|
24
29
|
/**
|
|
25
|
-
* A JSON request body for the PROGRAM_TRIGGER case.
|
|
26
|
-
* may not be complete.
|
|
30
|
+
* A JSON request body for the PROGRAM_TRIGGER case. Defined in core under ProgramTriggerQuery.graphql
|
|
27
31
|
*/
|
|
28
|
-
export
|
|
32
|
+
export type ProgramTriggerBody = {
|
|
29
33
|
messageType: "PROGRAM_TRIGGER";
|
|
30
|
-
activeTrigger:
|
|
31
|
-
|
|
34
|
+
activeTrigger: {
|
|
35
|
+
type: ActiveTriggerType;
|
|
36
|
+
time: number;
|
|
37
|
+
user: User;
|
|
38
|
+
previous?: User;
|
|
39
|
+
events?: UserEvent[];
|
|
40
|
+
referral?: Referral;
|
|
41
|
+
[key: string]: any;
|
|
42
|
+
};
|
|
43
|
+
program: {
|
|
44
|
+
id: string;
|
|
45
|
+
rules: RSJsonNode;
|
|
46
|
+
templateId: string;
|
|
47
|
+
};
|
|
32
48
|
tenant: {
|
|
33
49
|
impactBrandId: string | undefined | null;
|
|
34
50
|
settings: {
|
|
@@ -37,7 +53,7 @@ export declare type ProgramTriggerBody = {
|
|
|
37
53
|
};
|
|
38
54
|
ids: string[];
|
|
39
55
|
};
|
|
40
|
-
|
|
56
|
+
type TenantInfo = {
|
|
41
57
|
tenantAlias: string;
|
|
42
58
|
featureFlags?: string[] | null;
|
|
43
59
|
isLiveMode: boolean;
|
|
@@ -45,7 +61,7 @@ declare type TenantInfo = {
|
|
|
45
61
|
/**
|
|
46
62
|
* A JSON request body for the PROGRAM_INTROSPECTION case
|
|
47
63
|
*/
|
|
48
|
-
export
|
|
64
|
+
export type ProgramIntrospectionBody = {
|
|
49
65
|
messageType: "PROGRAM_INTROSPECTION";
|
|
50
66
|
template: any;
|
|
51
67
|
rules: any;
|
|
@@ -57,7 +73,7 @@ export declare type ProgramIntrospectionBody = {
|
|
|
57
73
|
* to be validated along with the result of the graphql query
|
|
58
74
|
* associated with the requirement
|
|
59
75
|
*/
|
|
60
|
-
export
|
|
76
|
+
export type ValidationRequest = {
|
|
61
77
|
key: string;
|
|
62
78
|
queryResult: any;
|
|
63
79
|
};
|
|
@@ -65,14 +81,14 @@ export declare type ValidationRequest = {
|
|
|
65
81
|
* The program information included by the backend for validation
|
|
66
82
|
* requests
|
|
67
83
|
*/
|
|
68
|
-
export
|
|
84
|
+
export type ValidationProgramField = {
|
|
69
85
|
id: string;
|
|
70
86
|
rules: any;
|
|
71
87
|
};
|
|
72
88
|
/**
|
|
73
89
|
* A JSON request body for the PROGRAM_VALIDATION case
|
|
74
90
|
*/
|
|
75
|
-
export
|
|
91
|
+
export type ProgramValidationBody = {
|
|
76
92
|
messageType: "PROGRAM_VALIDATION";
|
|
77
93
|
validationRequests: ValidationRequest[];
|
|
78
94
|
program: ValidationProgramField;
|
|
@@ -82,7 +98,7 @@ export declare type ProgramValidationBody = {
|
|
|
82
98
|
* The program information provided by the backend for
|
|
83
99
|
* requesting custom schema
|
|
84
100
|
*/
|
|
85
|
-
export
|
|
101
|
+
export type ProgramVariableSchemaRequestBody = {
|
|
86
102
|
messageType: "PROGRAM_TRIGGER_VARIABLES_SCHEMA_REQUEST";
|
|
87
103
|
schema: any;
|
|
88
104
|
triggerType: TriggerType;
|
|
@@ -93,11 +109,11 @@ export declare type ProgramVariableSchemaRequestBody = {
|
|
|
93
109
|
/**
|
|
94
110
|
* Handler for the default program trigger cases
|
|
95
111
|
*/
|
|
96
|
-
export
|
|
112
|
+
export type ProgramTriggerHandler = (transaction: Transaction) => void;
|
|
97
113
|
/**
|
|
98
114
|
* Output of program introspection
|
|
99
115
|
*/
|
|
100
|
-
export
|
|
116
|
+
export type ProgramIntrospectionResponse = ProgramTemplateBuilder | {
|
|
101
117
|
template: ProgramTemplateBuilder;
|
|
102
118
|
errors?: {
|
|
103
119
|
key: string;
|
|
@@ -108,7 +124,7 @@ export declare type ProgramIntrospectionResponse = ProgramTemplateBuilder | {
|
|
|
108
124
|
/**
|
|
109
125
|
* Introspection handler
|
|
110
126
|
*/
|
|
111
|
-
export
|
|
127
|
+
export type ProgramIntrospectionHandler = (template: ProgramTemplateBuilder, rules: any, program: any, tenant: TenantInfo) => ProgramIntrospectionResponse;
|
|
112
128
|
/**
|
|
113
129
|
* Handler for an individual program requirement validation.
|
|
114
130
|
* Handlers will be exported as key-value pairs in the
|
|
@@ -117,13 +133,13 @@ export declare type ProgramIntrospectionHandler = (template: ProgramTemplateBuil
|
|
|
117
133
|
* that will be used to compute the `queryResult` parameter for this
|
|
118
134
|
* function.
|
|
119
135
|
*/
|
|
120
|
-
export
|
|
121
|
-
export
|
|
136
|
+
export type RequirementValidationHandler = (queryResult: any, program: ValidationProgramField, time: number) => RequirementValidationResult[];
|
|
137
|
+
export type ProgramVariableSchemaHandler = (schema: any, triggerType: TriggerType, scheduleKey?: string) => ProgramVariableSchemaResult;
|
|
122
138
|
/**
|
|
123
139
|
* Key-value list of validation functions to be exported by
|
|
124
140
|
* the program
|
|
125
141
|
*/
|
|
126
|
-
|
|
142
|
+
type ProgramValidationFunctions = {
|
|
127
143
|
[key: string]: RequirementValidationHandler;
|
|
128
144
|
};
|
|
129
145
|
/********************************************************/
|
|
@@ -134,14 +150,14 @@ declare type ProgramValidationFunctions = {
|
|
|
134
150
|
* calculated by the boilerplate depending on the result
|
|
135
151
|
* of the trigger.
|
|
136
152
|
*/
|
|
137
|
-
export
|
|
153
|
+
export type ProgramTriggerResult = {
|
|
138
154
|
json: any;
|
|
139
155
|
code: number;
|
|
140
156
|
};
|
|
141
157
|
/**
|
|
142
158
|
* A result for an individual program requirement check
|
|
143
159
|
*/
|
|
144
|
-
export
|
|
160
|
+
export type RequirementValidationResult = {
|
|
145
161
|
message: string;
|
|
146
162
|
longDescription: string;
|
|
147
163
|
status: "ERROR" | "WARN" | "SUCCESS";
|
|
@@ -151,11 +167,11 @@ export declare type RequirementValidationResult = {
|
|
|
151
167
|
* The key provided here corresponds to a key from the
|
|
152
168
|
* `ProgramRequirement` type from below.
|
|
153
169
|
*/
|
|
154
|
-
export
|
|
170
|
+
export type ValidationResult = {
|
|
155
171
|
key: string;
|
|
156
172
|
results: RequirementValidationResult[];
|
|
157
173
|
};
|
|
158
|
-
export
|
|
174
|
+
export type ProgramVariableSchemaResult = {
|
|
159
175
|
schema: any;
|
|
160
176
|
};
|
|
161
177
|
/********************************************************/
|
|
@@ -163,7 +179,7 @@ export declare type ProgramVariableSchemaResult = {
|
|
|
163
179
|
/**
|
|
164
180
|
* A program requirement
|
|
165
181
|
*/
|
|
166
|
-
export
|
|
182
|
+
export type ProgramRequirement = {
|
|
167
183
|
key: string;
|
|
168
184
|
name: string;
|
|
169
185
|
description: string;
|
|
@@ -173,4 +189,12 @@ export declare type ProgramRequirement = {
|
|
|
173
189
|
[key: string]: any;
|
|
174
190
|
};
|
|
175
191
|
};
|
|
192
|
+
export type TriggerSchemaObject = {
|
|
193
|
+
type: ProgramTriggerBody["activeTrigger"]["type"];
|
|
194
|
+
time: ProgramTriggerBody["activeTrigger"]["time"];
|
|
195
|
+
user: ProgramTriggerBody["activeTrigger"]["user"];
|
|
196
|
+
previous?: User;
|
|
197
|
+
event?: UserEvent;
|
|
198
|
+
referral?: Referral;
|
|
199
|
+
};
|
|
176
200
|
export {};
|
|
@@ -1,20 +1,77 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* A program type
|
|
3
3
|
*/
|
|
4
|
-
export
|
|
4
|
+
export type ProgramType = "ACQUISITION" | "LOYALTY" | "RETENTION";
|
|
5
|
+
export type RSJsonNode = any;
|
|
6
|
+
export type ProgramGoal = {
|
|
7
|
+
goalId: string;
|
|
8
|
+
programId?: string;
|
|
9
|
+
count: number;
|
|
10
|
+
firstDate: number;
|
|
11
|
+
lastDate: number;
|
|
12
|
+
};
|
|
5
13
|
/**
|
|
6
|
-
*
|
|
7
|
-
* used internally by the programs.
|
|
14
|
+
* Defined in core under ProgramTriggerQuery.graphql
|
|
8
15
|
*/
|
|
9
|
-
export
|
|
16
|
+
export type User = {
|
|
10
17
|
id: string;
|
|
18
|
+
accountId: string;
|
|
19
|
+
firstName?: string;
|
|
20
|
+
lastName?: string;
|
|
21
|
+
referredByReferral?: Referral;
|
|
22
|
+
programGoals: ProgramGoal[];
|
|
23
|
+
[key: string]: any;
|
|
11
24
|
};
|
|
12
25
|
/**
|
|
13
|
-
*
|
|
14
|
-
* used internally by the programs.
|
|
26
|
+
* Defined in core under ProgramTriggerQuery.graphql
|
|
15
27
|
*/
|
|
16
|
-
export
|
|
28
|
+
export type UserEvent = {
|
|
29
|
+
key: string;
|
|
17
30
|
id: string;
|
|
18
|
-
|
|
19
|
-
|
|
31
|
+
fields: RSJsonNode;
|
|
32
|
+
isModification: boolean;
|
|
33
|
+
dateTriggered?: number;
|
|
34
|
+
dateReceived?: number;
|
|
35
|
+
dateProcessed?: number;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Defined in core under ProgramTriggerQuery.graphql
|
|
39
|
+
*/
|
|
40
|
+
export type UserReward = {
|
|
41
|
+
id: string;
|
|
42
|
+
dateGiven?: number;
|
|
43
|
+
dateExpires?: number;
|
|
44
|
+
dateCancelled?: number;
|
|
45
|
+
programId?: string;
|
|
46
|
+
programRewardKey?: string;
|
|
47
|
+
referralId?: string;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Defined in core under ProgramTriggerQuery.graphql
|
|
51
|
+
*/
|
|
52
|
+
export type FraudFlag = "IP" | "EMAIL" | "NAME" | "RATE" | "DAILY_REFERRAL_REWARD_LIMIT" | "TEMP_EMAIL" | "BLOCKED_USER" | "BLOCKED_IP";
|
|
53
|
+
/**
|
|
54
|
+
* Defined in core under ProgramTriggerQuery.graphql
|
|
55
|
+
*/
|
|
56
|
+
export type Referral = {
|
|
57
|
+
id: string;
|
|
58
|
+
moderationStatus?: "PENDING" | "ACTIONED";
|
|
59
|
+
referrerModerationStatus?: "PENDING" | "APPROVED" | "DENIED";
|
|
60
|
+
referredModerationStatus?: "PENDING" | "APPROVED" | "DENIED";
|
|
61
|
+
dateReferralStarted?: number;
|
|
62
|
+
dateFraudChecksCompleted?: number;
|
|
63
|
+
dateConverted?: number;
|
|
64
|
+
fraudSignals?: any;
|
|
65
|
+
fraudFlags: {
|
|
66
|
+
type: FraudFlag;
|
|
67
|
+
message: string;
|
|
68
|
+
}[];
|
|
69
|
+
isFraudExempt: boolean;
|
|
70
|
+
referrerUser: User & {
|
|
71
|
+
rewards: {
|
|
72
|
+
totalCount: number;
|
|
73
|
+
data: UserReward[];
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
rewards: UserReward[];
|
|
20
77
|
};
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ProgramTriggerBody } from "./types/rpc";
|
|
1
|
+
import { ProgramTriggerBody, TriggerSchemaObject } from "./types/rpc";
|
|
2
2
|
import jsonata from "jsonata";
|
|
3
|
-
export
|
|
3
|
+
export type WebtaskConfig = {
|
|
4
4
|
port: number;
|
|
5
5
|
webtaskName: string;
|
|
6
6
|
keepAliveTimeoutSeconds: number;
|
|
@@ -74,7 +74,7 @@ export declare function numToEquality(num: number): string;
|
|
|
74
74
|
* @param body the body of the trigger
|
|
75
75
|
* @return object[] The transformed data that is relevant for the trigger type
|
|
76
76
|
*/
|
|
77
|
-
export declare function getTriggerSchema(body: ProgramTriggerBody):
|
|
77
|
+
export declare function getTriggerSchema(body: ProgramTriggerBody): TriggerSchemaObject[];
|
|
78
78
|
/**
|
|
79
79
|
* Parses JSONata expressions and finds user custom fields used in the expression(s)
|
|
80
80
|
*
|
package/dist/utils.js
CHANGED
|
@@ -3,7 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.loadStandardWebtaskConfig = loadStandardWebtaskConfig;
|
|
7
|
+
exports.setRewardSchedule = setRewardSchedule;
|
|
8
|
+
exports.getGoalAnalyticTimestamp = getGoalAnalyticTimestamp;
|
|
9
|
+
exports.inferType = inferType;
|
|
10
|
+
exports.numToEquality = numToEquality;
|
|
11
|
+
exports.getTriggerSchema = getTriggerSchema;
|
|
12
|
+
exports.getUserCustomFieldsFromJsonata = getUserCustomFieldsFromJsonata;
|
|
13
|
+
exports.getRewardUnitsFromJsonata = getRewardUnitsFromJsonata;
|
|
7
14
|
const queries_1 = require("./queries");
|
|
8
15
|
const jsonata_paths_extractor_1 = __importDefault(require("@saasquatch/jsonata-paths-extractor"));
|
|
9
16
|
function loadStandardWebtaskConfig() {
|
|
@@ -29,7 +36,6 @@ function loadStandardWebtaskConfig() {
|
|
|
29
36
|
terminationDelaySeconds,
|
|
30
37
|
};
|
|
31
38
|
}
|
|
32
|
-
exports.loadStandardWebtaskConfig = loadStandardWebtaskConfig;
|
|
33
39
|
/**
|
|
34
40
|
* Append a reward schedule to the template and return the new template
|
|
35
41
|
*
|
|
@@ -48,7 +54,7 @@ function setRewardSchedule({ template, expiryWarningDays, key, emailKey, periodI
|
|
|
48
54
|
filter: {
|
|
49
55
|
dateExpires_timeframe,
|
|
50
56
|
},
|
|
51
|
-
query: queries_1.rewardScheduleQuery(emailKey),
|
|
57
|
+
query: (0, queries_1.rewardScheduleQuery)(emailKey),
|
|
52
58
|
periodInHours,
|
|
53
59
|
};
|
|
54
60
|
const currentSchedules = template.schedules;
|
|
@@ -62,7 +68,6 @@ function setRewardSchedule({ template, expiryWarningDays, key, emailKey, periodI
|
|
|
62
68
|
return template;
|
|
63
69
|
}
|
|
64
70
|
}
|
|
65
|
-
exports.setRewardSchedule = setRewardSchedule;
|
|
66
71
|
/**
|
|
67
72
|
* Returns the appropriate timestamp based on the trigger.
|
|
68
73
|
* If the trigger includes a purchase event, the timestamp
|
|
@@ -79,7 +84,6 @@ function getGoalAnalyticTimestamp(trigger) {
|
|
|
79
84
|
: undefined;
|
|
80
85
|
return purchaseEvent ? purchaseEvent.dateTriggered - 1 : trigger.time;
|
|
81
86
|
}
|
|
82
|
-
exports.getGoalAnalyticTimestamp = getGoalAnalyticTimestamp;
|
|
83
87
|
/**
|
|
84
88
|
* Translates a string type into its proper JavaScript type.
|
|
85
89
|
* Supports conversion to number, boolean, null and undefined values.
|
|
@@ -144,7 +148,6 @@ function inferType(val) {
|
|
|
144
148
|
return val;
|
|
145
149
|
}
|
|
146
150
|
}
|
|
147
|
-
exports.inferType = inferType;
|
|
148
151
|
/**
|
|
149
152
|
* Converts a number representation of a conversion operator set in program
|
|
150
153
|
* rules to a string that can be user in a GraphQL query
|
|
@@ -163,13 +166,13 @@ function numToEquality(num) {
|
|
|
163
166
|
return "eq";
|
|
164
167
|
}
|
|
165
168
|
}
|
|
166
|
-
exports.numToEquality = numToEquality;
|
|
167
169
|
/**
|
|
168
170
|
* Converts a trigger context into the relevant information for the specified trigger type.
|
|
169
171
|
* @param body the body of the trigger
|
|
170
172
|
* @return object[] The transformed data that is relevant for the trigger type
|
|
171
173
|
*/
|
|
172
174
|
function getTriggerSchema(body) {
|
|
175
|
+
var _a;
|
|
173
176
|
const activeTrigger = body.activeTrigger;
|
|
174
177
|
const triggerType = activeTrigger.type;
|
|
175
178
|
const standardData = {
|
|
@@ -187,11 +190,7 @@ function getTriggerSchema(body) {
|
|
|
187
190
|
Object.assign(Object.assign({}, standardData), { referral: activeTrigger.referral }),
|
|
188
191
|
];
|
|
189
192
|
case "AFTER_USER_EVENT_PROCESSED":
|
|
190
|
-
|
|
191
|
-
activeTrigger.events.forEach((event) => {
|
|
192
|
-
contexts.push(Object.assign(Object.assign({}, standardData), { event }));
|
|
193
|
-
});
|
|
194
|
-
return contexts;
|
|
193
|
+
return ((_a = activeTrigger.events) !== null && _a !== void 0 ? _a : []).map((event) => (Object.assign(Object.assign({}, standardData), { event })));
|
|
195
194
|
case "SCHEDULED":
|
|
196
195
|
return [
|
|
197
196
|
Object.assign({}, standardData),
|
|
@@ -204,7 +203,6 @@ function getTriggerSchema(body) {
|
|
|
204
203
|
throw new Error("Trigger type did not match expected options");
|
|
205
204
|
}
|
|
206
205
|
}
|
|
207
|
-
exports.getTriggerSchema = getTriggerSchema;
|
|
208
206
|
/**
|
|
209
207
|
* Parses JSONata expressions and finds user custom fields used in the expression(s)
|
|
210
208
|
*
|
|
@@ -218,7 +216,7 @@ function getUserCustomFieldsFromJsonata(jsonataExpressions) {
|
|
|
218
216
|
}
|
|
219
217
|
for (const expression of jsonataExpressions) {
|
|
220
218
|
try {
|
|
221
|
-
const allPaths = jsonata_paths_extractor_1.default(expression);
|
|
219
|
+
const allPaths = (0, jsonata_paths_extractor_1.default)(expression);
|
|
222
220
|
for (const path of allPaths) {
|
|
223
221
|
if (path.startsWith("/user/customFields/")) {
|
|
224
222
|
const key = path.split("/")[3];
|
|
@@ -244,7 +242,6 @@ function getUserCustomFieldsFromJsonata(jsonataExpressions) {
|
|
|
244
242
|
//dedup
|
|
245
243
|
return Array.from(new Set(userCustomFields));
|
|
246
244
|
}
|
|
247
|
-
exports.getUserCustomFieldsFromJsonata = getUserCustomFieldsFromJsonata;
|
|
248
245
|
function getRewardUnitsFromJsonata(expr) {
|
|
249
246
|
if (expr === undefined) {
|
|
250
247
|
return undefined;
|
|
@@ -264,4 +261,3 @@ function getRewardUnitsFromJsonata(expr) {
|
|
|
264
261
|
}
|
|
265
262
|
}
|
|
266
263
|
}
|
|
267
|
-
exports.getRewardUnitsFromJsonata = getRewardUnitsFromJsonata;
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saasquatch/program-boilerplate",
|
|
3
|
-
"version": "3.10.
|
|
3
|
+
"version": "3.10.2-0",
|
|
4
4
|
"description": "Boilerplate for writing programs",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist/"
|
|
8
8
|
],
|
|
9
9
|
"engines": {
|
|
10
|
-
"node": "^
|
|
10
|
+
"node": "^20 || ^22 || ^24"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
13
|
"build": "tsc --declaration",
|
|
@@ -28,27 +28,27 @@
|
|
|
28
28
|
"source-map": "^0.7.4"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@types/express": "^4.17.
|
|
32
|
-
"@types/node": "^
|
|
31
|
+
"@types/express": "^4.17.25",
|
|
32
|
+
"@types/node": "^24.10.0",
|
|
33
33
|
"@types/supertest": "^2.0.11",
|
|
34
|
-
"jest": "^
|
|
35
|
-
"jest-cucumber": "^
|
|
34
|
+
"jest": "^30.2.0",
|
|
35
|
+
"jest-cucumber": "^4.5.0",
|
|
36
36
|
"prettier": "^2.2.1",
|
|
37
37
|
"source-map": "^0.7.4",
|
|
38
38
|
"supertest": "^6.1.3",
|
|
39
|
-
"ts-jest": "^
|
|
40
|
-
"ts-node": "^9.
|
|
39
|
+
"ts-jest": "^29.4.5",
|
|
40
|
+
"ts-node": "^10.9.2",
|
|
41
41
|
"typedoc": "^0.17.8",
|
|
42
|
-
"typescript": "^
|
|
42
|
+
"typescript": "^5.9.3"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@saasquatch/jsonata-paths-extractor": "^1.0.1",
|
|
46
|
-
"@saasquatch/logger": "^
|
|
46
|
+
"@saasquatch/logger": "^2.0.0",
|
|
47
47
|
"@saasquatch/schema": "^2.0.0",
|
|
48
48
|
"bson-objectid": "^1.3.1",
|
|
49
49
|
"compression": "^1.7.4",
|
|
50
50
|
"express": "^4.17.1",
|
|
51
51
|
"jsonata": "^1.8.4",
|
|
52
|
-
"winston": "^3.
|
|
52
|
+
"winston": "^3.18.3"
|
|
53
53
|
}
|
|
54
54
|
}
|