@saasquatch/program-boilerplate 3.6.0-0 → 3.6.0-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,7 +5,7 @@
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.meetEventTriggerRules = exports.meetCustomFieldRules = exports.meetEdgeTriggerConditions = void 0;
7
7
  const assert = require("assert");
8
- const jsonata = require("jsonata");
8
+ const jsonata_1 = require("./jsonata");
9
9
  //functions
10
10
  /**
11
11
  * Turns a string scalar into a Number, Boolean or String
@@ -40,11 +40,20 @@ function meetEdgeTriggerConditions(fields, activeTrigger) {
40
40
  }
41
41
  for (const field of fields) {
42
42
  if (!field.startsWith("user.")) {
43
- // TODO: what to do here? this is probably some kind of error case
44
- continue;
43
+ // we consider a malformed edge field to be "not passing"
44
+ return false;
45
+ }
46
+ // a simple query to retrieve the value of a field from the user should
47
+ // not take more than a few milliseconds. if it takes longer than 500ms
48
+ // something is definitely wrong with the query
49
+ const jsonataTimeoutMs = 500;
50
+ const { success: prevSuccess, result: previousValue } = jsonata_1.safeJsonata2(field.replace("user.", "previous."), activeTrigger, jsonataTimeoutMs);
51
+ const { success: currentSuccess, result: currentValue } = jsonata_1.safeJsonata2(field, activeTrigger, jsonataTimeoutMs);
52
+ // one of the JSONata expressions failed to evaluate -- edge field is considered
53
+ // "not passing"
54
+ if (!prevSuccess || !currentSuccess) {
55
+ return false;
45
56
  }
46
- const previousValue = jsonata(field.replace("user.", "previous.")).evaluate(activeTrigger);
47
- const currentValue = jsonata(field).evaluate(activeTrigger);
48
57
  try {
49
58
  assert.deepStrictEqual(currentValue, previousValue);
50
59
  // assertion passed -- field did not change
package/dist/jsonata.d.ts CHANGED
@@ -7,5 +7,9 @@ import * as jsonata from "jsonata";
7
7
  * @param {Number} timeout - max time in ms
8
8
  * @param {Number} maxDepth - max stack depth
9
9
  */
10
- export declare function timeboxExpression(expr: jsonata.Expression): void;
10
+ export declare function timeboxExpression(expr: jsonata.Expression, timeout?: number, maxDepth?: number): void;
11
11
  export declare function safeJsonata(expression: string, inputData: any): any;
12
+ export declare function safeJsonata2(expression: string, inputData: any, timeout?: number, maxDepth?: number): {
13
+ success: boolean;
14
+ result: any;
15
+ };
package/dist/jsonata.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.safeJsonata = exports.timeboxExpression = void 0;
3
+ exports.safeJsonata2 = exports.safeJsonata = exports.timeboxExpression = void 0;
4
4
  const jsonata = require("jsonata");
5
5
  const logger_1 = require("./logger");
6
6
  const TIMEOUT = 5000;
@@ -14,19 +14,21 @@ const logger = logger_1.getLogger(process.env.PROGRAM_LOG_LEVEL || "debug");
14
14
  * @param {Number} timeout - max time in ms
15
15
  * @param {Number} maxDepth - max stack depth
16
16
  */
17
- function timeboxExpression(expr) {
18
- let depth = 0;
19
- const time = Date.now();
20
- let checkRunnaway = function () {
21
- if (depth > MAXDEPTH) {
17
+ function timeboxExpression(expr, timeout, maxDepth) {
18
+ const startTime = Date.now();
19
+ const actualTimeout = timeout !== null && timeout !== void 0 ? timeout : TIMEOUT;
20
+ const actualMaxDepth = maxDepth !== null && maxDepth !== void 0 ? maxDepth : MAXDEPTH;
21
+ let currentDepth = 0;
22
+ const checkRunnaway = function () {
23
+ if (currentDepth > actualMaxDepth) {
22
24
  // stack too deep
23
25
  throw {
24
26
  code: "U1001",
25
- message: "Stack overflow error: Check for non-terminating recursive function. Consider rewriting as tail-recursive.",
27
+ message: "Stack overflow error: Check for non-terminating recursive function. Consider rewriting as tail-recursive.",
26
28
  stack: new Error().stack,
27
29
  };
28
30
  }
29
- if (Date.now() - time > TIMEOUT) {
31
+ if (Date.now() - startTime > actualTimeout) {
30
32
  // expression has run for too long
31
33
  throw {
32
34
  code: "U1002",
@@ -36,12 +38,12 @@ function timeboxExpression(expr) {
36
38
  }
37
39
  };
38
40
  // register callbacks
39
- expr.assign("__evaluate_entry", function (expr, input, environment) {
40
- depth++;
41
+ expr.assign("__evaluate_entry", () => {
42
+ currentDepth++;
41
43
  checkRunnaway();
42
44
  });
43
- expr.assign("__evaluate_exit", function (expr, input, environment, result) {
44
- depth--;
45
+ expr.assign("__evaluate_exit", () => {
46
+ currentDepth--;
45
47
  checkRunnaway();
46
48
  });
47
49
  }
@@ -57,3 +59,18 @@ function safeJsonata(expression, inputData) {
57
59
  }
58
60
  }
59
61
  exports.safeJsonata = safeJsonata;
62
+ function safeJsonata2(expression, inputData, timeout, maxDepth) {
63
+ try {
64
+ const jsonataQuery = jsonata(expression);
65
+ timeboxExpression(jsonataQuery, timeout, maxDepth);
66
+ const result = jsonataQuery.evaluate(inputData);
67
+ return { success: true, result };
68
+ }
69
+ catch (e) {
70
+ if (e instanceof Error) {
71
+ logger.warn(`Failed to evaluate JSONata expression: ${e.message}`);
72
+ }
73
+ return { success: false, result: undefined };
74
+ }
75
+ }
76
+ exports.safeJsonata2 = safeJsonata2;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saasquatch/program-boilerplate",
3
- "version": "3.6.0-0",
3
+ "version": "3.6.0-1",
4
4
  "description": "Boilerplate for writing programs",
5
5
  "main": "dist/index.js",
6
6
  "files": [