@blazedpath/commons 0.0.4

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.
Files changed (224) hide show
  1. package/README.md +3 -0
  2. package/blz-base/health/index.js +215 -0
  3. package/blz-base/index.js +1466 -0
  4. package/blz-cache/LruCache.js +44 -0
  5. package/blz-cache/index.js +29 -0
  6. package/blz-config/index.js +434 -0
  7. package/blz-core/index.js +364 -0
  8. package/blz-cryptography/index.js +54 -0
  9. package/blz-datetimes/index.js +356 -0
  10. package/blz-file/example.dat +2545 -0
  11. package/blz-file/fileService.js +205 -0
  12. package/blz-file/index.js +94 -0
  13. package/blz-file/index.test.js +31 -0
  14. package/blz-file/lab.js +33 -0
  15. package/blz-hazelcast/index.js +189 -0
  16. package/blz-hazelcast/lib/credentials.js +25 -0
  17. package/blz-hazelcast/lib/credentialsFactory.js +12 -0
  18. package/blz-hazelcast/lib/hazelcastCache.js +234 -0
  19. package/blz-iterable/index.js +446 -0
  20. package/blz-json-schema/index.js +11 -0
  21. package/blz-jwt/index.js +121 -0
  22. package/blz-kafka/index.js +522 -0
  23. package/blz-math/index.js +131 -0
  24. package/blz-mongodb/index.js +326 -0
  25. package/blz-rds/__test__/scape.test.js +58 -0
  26. package/blz-rds/blz-rds-executor.js +578 -0
  27. package/blz-rds/blz-rds-helper.js +310 -0
  28. package/blz-rds/commands/core/add.js +13 -0
  29. package/blz-rds/commands/core/and.js +18 -0
  30. package/blz-rds/commands/core/asc.js +10 -0
  31. package/blz-rds/commands/core/avg.js +10 -0
  32. package/blz-rds/commands/core/column-ref.js +8 -0
  33. package/blz-rds/commands/core/count-distinct.js +10 -0
  34. package/blz-rds/commands/core/count.js +10 -0
  35. package/blz-rds/commands/core/decimal.js +8 -0
  36. package/blz-rds/commands/core/desc.js +10 -0
  37. package/blz-rds/commands/core/distinct.js +10 -0
  38. package/blz-rds/commands/core/divide.js +11 -0
  39. package/blz-rds/commands/core/embedded-exists.js +17 -0
  40. package/blz-rds/commands/core/embedded-select.js +17 -0
  41. package/blz-rds/commands/core/equals.js +9 -0
  42. package/blz-rds/commands/core/false.js +8 -0
  43. package/blz-rds/commands/core/greater-or-equal.js +9 -0
  44. package/blz-rds/commands/core/greater.js +9 -0
  45. package/blz-rds/commands/core/in.js +9 -0
  46. package/blz-rds/commands/core/integer.js +8 -0
  47. package/blz-rds/commands/core/is-not-null.js +11 -0
  48. package/blz-rds/commands/core/is-null-or-value.js +10 -0
  49. package/blz-rds/commands/core/is-null.js +11 -0
  50. package/blz-rds/commands/core/less-or-equal.js +9 -0
  51. package/blz-rds/commands/core/less-unary.js +12 -0
  52. package/blz-rds/commands/core/less.js +9 -0
  53. package/blz-rds/commands/core/like.js +12 -0
  54. package/blz-rds/commands/core/max.js +10 -0
  55. package/blz-rds/commands/core/min.js +10 -0
  56. package/blz-rds/commands/core/multiply.js +13 -0
  57. package/blz-rds/commands/core/not-equals.js +9 -0
  58. package/blz-rds/commands/core/not-in.js +9 -0
  59. package/blz-rds/commands/core/not.js +13 -0
  60. package/blz-rds/commands/core/null.js +8 -0
  61. package/blz-rds/commands/core/nvl.js +11 -0
  62. package/blz-rds/commands/core/or.js +13 -0
  63. package/blz-rds/commands/core/parameter.js +34 -0
  64. package/blz-rds/commands/core/remainder.js +16 -0
  65. package/blz-rds/commands/core/string.js +8 -0
  66. package/blz-rds/commands/core/subtract.js +13 -0
  67. package/blz-rds/commands/core/sum.js +10 -0
  68. package/blz-rds/commands/core/true.js +8 -0
  69. package/blz-rds/commands/core/tuple.js +13 -0
  70. package/blz-rds/commands/datetimes/add-days.js +11 -0
  71. package/blz-rds/commands/datetimes/add-hours.js +11 -0
  72. package/blz-rds/commands/datetimes/add-milliseconds.js +11 -0
  73. package/blz-rds/commands/datetimes/add-minutes.js +11 -0
  74. package/blz-rds/commands/datetimes/add-months.js +11 -0
  75. package/blz-rds/commands/datetimes/add-seconds.js +11 -0
  76. package/blz-rds/commands/datetimes/add-years.js +11 -0
  77. package/blz-rds/commands/datetimes/date-diff.js +11 -0
  78. package/blz-rds/commands/datetimes/date.js +12 -0
  79. package/blz-rds/commands/datetimes/datetime-diff.js +11 -0
  80. package/blz-rds/commands/datetimes/datetime.js +15 -0
  81. package/blz-rds/commands/datetimes/day.js +10 -0
  82. package/blz-rds/commands/datetimes/hour.js +10 -0
  83. package/blz-rds/commands/datetimes/millisecond.js +10 -0
  84. package/blz-rds/commands/datetimes/minute.js +10 -0
  85. package/blz-rds/commands/datetimes/month-text.js +10 -0
  86. package/blz-rds/commands/datetimes/month.js +10 -0
  87. package/blz-rds/commands/datetimes/now.js +9 -0
  88. package/blz-rds/commands/datetimes/second.js +10 -0
  89. package/blz-rds/commands/datetimes/subtract-days.js +11 -0
  90. package/blz-rds/commands/datetimes/subtract-hours.js +11 -0
  91. package/blz-rds/commands/datetimes/subtract-milliseconds.js +11 -0
  92. package/blz-rds/commands/datetimes/subtract-minutes.js +11 -0
  93. package/blz-rds/commands/datetimes/subtract-seconds.js +11 -0
  94. package/blz-rds/commands/datetimes/time-diff.js +11 -0
  95. package/blz-rds/commands/datetimes/time.js +13 -0
  96. package/blz-rds/commands/datetimes/today.js +9 -0
  97. package/blz-rds/commands/datetimes/week-day-text.js +10 -0
  98. package/blz-rds/commands/datetimes/week-day.js +10 -0
  99. package/blz-rds/commands/datetimes/week.js +10 -0
  100. package/blz-rds/commands/datetimes/year.js +10 -0
  101. package/blz-rds/commands/math/abs.js +10 -0
  102. package/blz-rds/commands/math/acos.js +10 -0
  103. package/blz-rds/commands/math/asin.js +10 -0
  104. package/blz-rds/commands/math/atan.js +10 -0
  105. package/blz-rds/commands/math/atan2.js +11 -0
  106. package/blz-rds/commands/math/ceil.js +10 -0
  107. package/blz-rds/commands/math/cos.js +10 -0
  108. package/blz-rds/commands/math/cosh.js +10 -0
  109. package/blz-rds/commands/math/exp.js +10 -0
  110. package/blz-rds/commands/math/floor.js +10 -0
  111. package/blz-rds/commands/math/log.js +18 -0
  112. package/blz-rds/commands/math/log10.js +10 -0
  113. package/blz-rds/commands/math/pow.js +11 -0
  114. package/blz-rds/commands/math/random.js +9 -0
  115. package/blz-rds/commands/math/round.js +18 -0
  116. package/blz-rds/commands/math/sign.js +10 -0
  117. package/blz-rds/commands/math/sin.js +10 -0
  118. package/blz-rds/commands/math/sinh.js +10 -0
  119. package/blz-rds/commands/math/sqrt.js +10 -0
  120. package/blz-rds/commands/math/tan.js +10 -0
  121. package/blz-rds/commands/math/tanh.js +10 -0
  122. package/blz-rds/commands/math/trunc.js +18 -0
  123. package/blz-rds/commands/strings/concat.js +20 -0
  124. package/blz-rds/commands/strings/contains.js +12 -0
  125. package/blz-rds/commands/strings/ends-with.js +12 -0
  126. package/blz-rds/commands/strings/index-of.js +11 -0
  127. package/blz-rds/commands/strings/is-null-or-empty.js +11 -0
  128. package/blz-rds/commands/strings/is-null-or-white-space.js +11 -0
  129. package/blz-rds/commands/strings/join.js +22 -0
  130. package/blz-rds/commands/strings/last-index-of.js +11 -0
  131. package/blz-rds/commands/strings/length.js +10 -0
  132. package/blz-rds/commands/strings/pad-left.js +20 -0
  133. package/blz-rds/commands/strings/pad-right.js +20 -0
  134. package/blz-rds/commands/strings/replace.js +12 -0
  135. package/blz-rds/commands/strings/starts-with.js +12 -0
  136. package/blz-rds/commands/strings/substring.js +12 -0
  137. package/blz-rds/commands/strings/to-lower.js +10 -0
  138. package/blz-rds/commands/strings/to-upper.js +10 -0
  139. package/blz-rds/commands/strings/trim-end.js +10 -0
  140. package/blz-rds/commands/strings/trim-start.js +10 -0
  141. package/blz-rds/commands/strings/trim.js +10 -0
  142. package/blz-rds/index.js +744 -0
  143. package/blz-rds-mysql/base.js +857 -0
  144. package/blz-rds-mysql/connection-manager.js +129 -0
  145. package/blz-rds-mysql/execute-bulk-insert.js +35 -0
  146. package/blz-rds-mysql/execute-bulk-merge.js +45 -0
  147. package/blz-rds-mysql/execute-non-query.js +34 -0
  148. package/blz-rds-mysql/execute-query.js +50 -0
  149. package/blz-rds-mysql/index.js +41 -0
  150. package/blz-rds-mysql/stored-procedure.js +207 -0
  151. package/blz-rds-mysql/syntaxis.json +114 -0
  152. package/blz-rds-mysqlx/base.js +846 -0
  153. package/blz-rds-mysqlx/connection-manager.js +141 -0
  154. package/blz-rds-mysqlx/execute-bulk-insert.js +35 -0
  155. package/blz-rds-mysqlx/execute-bulk-merge.js +45 -0
  156. package/blz-rds-mysqlx/execute-non-query.js +29 -0
  157. package/blz-rds-mysqlx/execute-query.js +39 -0
  158. package/blz-rds-mysqlx/index.js +41 -0
  159. package/blz-rds-mysqlx/stored-procedure.js +179 -0
  160. package/blz-rds-mysqlx/syntaxis.json +105 -0
  161. package/blz-rds-oracle/index.js +540 -0
  162. package/blz-rds-oracle/syntaxis.json +112 -0
  163. package/blz-rds-postgres/base.js +861 -0
  164. package/blz-rds-postgres/connection-manager.js +225 -0
  165. package/blz-rds-postgres/execute-bulk-insert.js +81 -0
  166. package/blz-rds-postgres/execute-bulk-merge.js +93 -0
  167. package/blz-rds-postgres/execute-non-query.js +23 -0
  168. package/blz-rds-postgres/execute-query.js +37 -0
  169. package/blz-rds-postgres/index.js +41 -0
  170. package/blz-rds-postgres/result-set.js +51 -0
  171. package/blz-rds-postgres/stored-procedure.js +116 -0
  172. package/blz-rds-postgres/syntaxis.json +114 -0
  173. package/blz-redis/index.js +217 -0
  174. package/blz-redis/lib/redisCache.js +265 -0
  175. package/blz-regex/index.js +25 -0
  176. package/blz-security/.eslintrc.js +15 -0
  177. package/blz-security/__test__/AuthorizationKpn.yaml +1043 -0
  178. package/blz-security/__test__/FinancingSetting.yaml +177 -0
  179. package/blz-security/__test__/KpnConfigPortal.yaml +330 -0
  180. package/blz-security/__test__/OrderManagement.yaml +5190 -0
  181. package/blz-security/__test__/Security.yaml +128 -0
  182. package/blz-security/__test__/autorization.test.js +105 -0
  183. package/blz-security/__test__/orderManagement.test.js +26 -0
  184. package/blz-security/__test__/secureUrl.test.js +79 -0
  185. package/blz-security/__test__/solveMergeRule.test.js +109 -0
  186. package/blz-security/__test__/sqlInjectionGuard.test.js +203 -0
  187. package/blz-security/__test__/xssGuard.test.js +204 -0
  188. package/blz-security/authorizationService.js +536 -0
  189. package/blz-security/config/global.js +8 -0
  190. package/blz-security/config/welcome +8 -0
  191. package/blz-security/doc/README.md +75 -0
  192. package/blz-security/filescanner/index.js +46 -0
  193. package/blz-security/helpers/consts.js +229 -0
  194. package/blz-security/helpers/utils.js +267 -0
  195. package/blz-security/implementations/cache.js +90 -0
  196. package/blz-security/implementations/oidc.js +404 -0
  197. package/blz-security/implementations/pkceCacheStore.js +23 -0
  198. package/blz-security/implementations/saml.js +10 -0
  199. package/blz-security/implementations/uma.js +63 -0
  200. package/blz-security/implementations/webAuthn.js +9 -0
  201. package/blz-security/implementations/wstg.js +72 -0
  202. package/blz-security/index.js +77 -0
  203. package/blz-security/lab/index.js +27 -0
  204. package/blz-security/middleware/HapiServerAzureAd.js +641 -0
  205. package/blz-security/middleware/HapiServerKeycloak.js +840 -0
  206. package/blz-security/middleware/HapiServerSimToken.js +247 -0
  207. package/blz-security/middleware/hapi.js +515 -0
  208. package/blz-security/middleware/hapiServer.js +974 -0
  209. package/blz-security/navigationMemoryRepository.js +15 -0
  210. package/blz-security/navigationMongoDbRepository.js +73 -0
  211. package/blz-security/secureUrlService.js +47 -0
  212. package/blz-security/securityService.js +409 -0
  213. package/blz-security/sqlInjectionGuard.js +162 -0
  214. package/blz-security/templates/forbidden.html +0 -0
  215. package/blz-security/templates/session-iframe-azure-ad.html +7 -0
  216. package/blz-security/templates/session-iframe.html +73 -0
  217. package/blz-security/templates/unauthorized.html +1 -0
  218. package/blz-security/xssGuard.js +87 -0
  219. package/blz-strings/index.js +167 -0
  220. package/blz-uuid/index.js +7 -0
  221. package/blz-yaml/index.js +19 -0
  222. package/index.js +84 -0
  223. package/package.json +97 -0
  224. package/process-managers/index.js +422 -0
package/package.json ADDED
@@ -0,0 +1,97 @@
1
+ {
2
+ "name": "@blazedpath/commons",
3
+ "version": "0.0.4",
4
+ "description": "commos library for blazedpath applications",
5
+ "main": "index.js",
6
+ "types": "dist/index.d.ts",
7
+ "license": "UNLICENSED",
8
+ "publishConfig": { "access": "public" },
9
+ "dependencies": {
10
+ "@hapi/boom": "^10.0.1",
11
+ "@hapi/call": "^9.0.1",
12
+ "@hapi/cookie": "^12.0.1",
13
+ "@hapi/jwt": "^3.2.0",
14
+ "@hapi/yar": "^11.0.3",
15
+ "crypto": "^1.0.1",
16
+ "dompurify": "^3.2.6",
17
+ "fs-extra": "^11.3.0",
18
+ "got": "^11.8.6",
19
+ "handlebars": "^4.7.8",
20
+ "jsdom": "^26.1.0",
21
+ "jwk-to-pem": "^2.0.7",
22
+ "nearley": "^2.20.1",
23
+ "path": "^0.12.7",
24
+ "semver": "^7.6.0",
25
+ "underscore": "^1.13.7",
26
+ "agenda": "^5.0.0",
27
+ "async-retry": "^1.3.3",
28
+ "@azure/msal-node": "^3.4.1",
29
+ "axios": "^1.12.0",
30
+ "clamav.js": "^0.12.0",
31
+ "crypto-js": "^4.2.0",
32
+ "decode-uri-component": "^0.4.1",
33
+ "h3lp": "^1.12.1",
34
+ "ioredis": "^5.6.0",
35
+ "jest": "^29.7.0",
36
+ "js-yaml": "^4.1.0",
37
+ "jsonpath": "^1.1.1",
38
+ "jsonwebtoken": "^9.0.2",
39
+ "jwks-rsa": "^3.1.0",
40
+ "lru-cache": "^10.2.1",
41
+ "micromatch": "^4.0.8",
42
+ "mongodb": "^6.11.0",
43
+ "node-fetch": "^2.7.0",
44
+ "openid-client": "^5.6.4",
45
+ "pino": "^9.7.0",
46
+ "uuid": "^9.0.1",
47
+ "yargs": "^17.7.2",
48
+ "zod": "^3.25.56",
49
+ "dotenv": "^16.4.4",
50
+ "soap": "^0.45.0",
51
+ "generic-pool": "^3.9.0",
52
+ "dayjs": "^1.11.10",
53
+ "luxon": "^3.4.4",
54
+ "pg": "^8.11.3",
55
+ "pg-cursor": "^2.10.3",
56
+ "pgsql-ast-parser": "^12.0.1",
57
+ "sqlstring": "^2.3.3",
58
+ "electron-rebuild": "^3.2.9",
59
+ "nan": "2.18.0",
60
+ "oracledb": "^6.7.0",
61
+ "@mysql/xdevapi": "^8.0.35",
62
+ "mysql": "^2.18.1",
63
+ "named-placeholders": "^1.1.3",
64
+ "kafkajs": "^2.2.4",
65
+ "jsonschema": "^1.4.1",
66
+ "hazelcast-client": "^5.3.0"
67
+ },
68
+ "devDependencies": {
69
+ "@types/got": "9.6.12",
70
+ "@types/handlebars": "4.1.0",
71
+ "eslint": "7.32.0",
72
+ "eslint-config-standard": "16.0.3",
73
+ "eslint-plugin-import": "2.26.0",
74
+ "eslint-plugin-node": "11.1.0",
75
+ "eslint-plugin-promise": "5.2.0",
76
+ "@types/pg": "8.11.0",
77
+ "@types/underscore": "1.11.15",
78
+ "@types/mysql": "2.15.25",
79
+ "@types/node": "20.11.17",
80
+ "jest": "^29.7.0"
81
+ },
82
+ "bin": {
83
+ "blz-security": "."
84
+ },
85
+ "eslintConfig": {
86
+ "extends": "standard"
87
+ },
88
+ "scripts": {
89
+ "lint": "standard",
90
+ "test": "jest",
91
+ "postinstall": "npx electron-rebuild --version 7.1.10 -f -w oracledb"
92
+ },
93
+ "overrides": {
94
+ "shelljs": "0.9.2",
95
+ "cross-spawn": "7.0.6"
96
+ }
97
+ }
@@ -0,0 +1,422 @@
1
+ const { MongoClient, ObjectId } = require('mongodb');
2
+ let Agenda = require('agenda');
3
+ const AsyncRetry = require('async-retry');
4
+ const logger = require('pino')();
5
+
6
+ let removeTokenAndChilds = function (instanceData, tokenId, unset) {
7
+ delete instanceData.tokens[tokenId];
8
+ unset['tokens.' + tokenId] = '';
9
+ for (let otherTokenId in instanceData.tokens) {
10
+ let otherTokenData = instanceData.tokens[otherTokenId];
11
+ if (otherTokenData.parentTokenId === tokenId)
12
+ removeTokenAndChilds(instanceData, otherTokenId, unset);
13
+ }
14
+ };
15
+
16
+ let getInstance = function (instanceData) {
17
+ let instance = {
18
+ processName: instanceData.processName,
19
+ instanceId: instanceData._id,
20
+ model: instanceData.model,
21
+ tokens: []
22
+ };
23
+ for (let tokenId in instanceData.tokens) {
24
+ let tokenData = instanceData.tokens[tokenId];
25
+ let token = {
26
+ tokenId: tokenId,
27
+ nodeName: tokenData.nodeName,
28
+ hasError: tokenData.hasError ?? undefined
29
+ };
30
+ if (tokenData.parentTokenId)
31
+ token.parentTokenId = tokenData.parentTokenId;
32
+ instance.tokens.push(token);
33
+ }
34
+ return instance;
35
+ };
36
+
37
+ let writeMongo = async function (processName, instanceId, variableName, value) {
38
+ let set = {};
39
+ set[variableName] = value;
40
+ await _mongodbCollectionInstances.updateOne({ _id: { $eq: ObjectId(instanceId) } }, { $set: set });
41
+ return null;
42
+ };
43
+
44
+ let tokenProcessorFn = null;
45
+
46
+ module.exports = {
47
+ setConnection: async function (connection, tokenProcessor, config) {
48
+ tokenProcessorFn = tokenProcessor;
49
+ _processorConfig = config;
50
+ // seccion que hace el retry
51
+ let mongoClient = null;
52
+ if (connection.useRetries){
53
+ await AsyncRetry(async () => {
54
+ mongoClient = new MongoClient(connection.url, { useUnifiedTopology: true });
55
+ try {
56
+ await mongoClient.connect();
57
+ } catch (err) {
58
+ console.error('Error connecting to MongoDB:', err);
59
+ throw err; // This will trigger a retry
60
+ } finally {
61
+ }
62
+ }, {
63
+ retries: connection.retryCount,
64
+ minTimeout: connection.minRetryInterval * 1000,
65
+ maxTimeout: connection.maxRetryInterval * 1000,
66
+ });
67
+ } else {
68
+ mongoClient = new MongoClient(connection.url, { useUnifiedTopology: true });
69
+ await mongoClient.connect();
70
+ }
71
+
72
+ // termino la seccion del retry
73
+ let mongoDb = mongoClient.db(connection.databaseName);
74
+ _mongodbCollectionInstances = mongoDb.collection('blz-instances');
75
+ _agenda = new Agenda({ mongo: mongoDb, db: { collection: 'blz-jobs' }, name: `worker-${process.pid}` });
76
+ _agenda.define('start', async function (job) {
77
+ module.exports.start(job.attrs.data.processName, {}, job.attrs.data.startNodeName, tokenProcessor);
78
+ await job.remove();
79
+ });
80
+ // This is the job in charge of processing the token.
81
+ _agenda.define('process-token', { concurrency: 1, lockLimit: 1, lockLifetime: 120000 }, async function (job) {
82
+ // 🧱 Prevent double execution manually
83
+ if (job.attrs.data.status === 'done' || job.attrs.data.running) {
84
+ if (job.attrs.data.status === 'done') {
85
+ logger.info(`process-token skipped: already executed for token ${tokenId}`);
86
+ await job.remove(); // cleanup
87
+ }
88
+ return;
89
+ }
90
+ // 🏁 Mark it as running
91
+ job.attrs.data.running = true;
92
+ await job.save();
93
+
94
+ const { processName, instanceId, tokenId, nodeName, inboundTransaction } = job.attrs.data;
95
+ let instanceData = null;
96
+ try {
97
+ instanceData = await _mongodbCollectionInstances.findOne({ _id: new ObjectId(instanceId) });
98
+
99
+ if (instanceData && instanceData.tokens[tokenId]) {
100
+ await tokenProcessor(processName, instanceId, tokenId, nodeName, inboundTransaction);
101
+ }
102
+
103
+ // 🧩 3️⃣ Mark done.
104
+ job.attrs.data.status = 'done';
105
+ job.attrs.data.running = false;
106
+ await job.save();
107
+ await job.remove();
108
+ } catch (err) {
109
+ const safeError = (err instanceof Error)
110
+ ? { message: err.message ?? err.data, stack: err.stack }
111
+ : { ...err };
112
+
113
+ job.attrs.failCount = (job.attrs.failCount || 0) + 1;
114
+
115
+ if (job.attrs.failCount >= _processorConfig.retriesAfterError) {
116
+ logger.error({
117
+ msg: 'process-token failed maximum times, disabling job',
118
+ processName,
119
+ instanceId,
120
+ tokenId,
121
+ nodeName,
122
+ failCount: job.attrs.failCount,
123
+ error: safeError
124
+ });
125
+
126
+ job.attrs.disabled = true;
127
+ const newTokens = { ...instanceData.tokens };
128
+ if (newTokens[tokenId]) {
129
+ newTokens[tokenId] = { ...newTokens[tokenId], hasError: true };
130
+ }
131
+ await writeMongo(processName, instanceId, 'tokens', newTokens);
132
+ } else {
133
+ const retryInMs = 5000;
134
+ logger.warn({
135
+ msg: `process-token failed, scheduled new retry (attempt ${job.attrs.failCount}/${_processorConfig.retriesAfterError})`,
136
+ processName,
137
+ instanceId,
138
+ tokenId,
139
+ nodeName,
140
+ failCount: job.attrs.failCount,
141
+ nextRetryInMs: retryInMs,
142
+ error: safeError
143
+ });
144
+
145
+ job.attrs.nextRunAt = new Date(Date.now() + retryInMs);
146
+ }
147
+ job.attrs.data.running = false;
148
+ await job.save();
149
+ return;
150
+ }
151
+ });
152
+
153
+ await _agenda.start();
154
+ },
155
+ start: async function (processName, startModel, startNodeName) {
156
+ let mongodbInstanceId = new ObjectId();
157
+ let instanceId = mongodbInstanceId.toHexString();
158
+ let tokenId = (new ObjectId).toHexString();
159
+ let instanceData = {
160
+ _id: mongodbInstanceId,
161
+ processName: processName,
162
+ model: startModel,
163
+ tokens: {},
164
+ compensations: {}
165
+ };
166
+ instanceData.tokens[tokenId] = { nodeName: startNodeName };
167
+ await _mongodbCollectionInstances.insertOne(instanceData);
168
+ console.log('Creating job for tokenId:', tokenId);
169
+ // // Prevent duplicates and Do not update an existing job if it exists
170
+ await _agenda.now('process-token', { processName: processName, instanceId: instanceId, tokenId: tokenId, nodeName: startNodeName }, { unique: { 'data.tokenId': tokenId }, insertOnly: true });
171
+ return instanceId;
172
+ },
173
+ resume: async function (processName, instanceId) {
174
+ let mongoInstance = await module.exports.getInstance(processName, instanceId)
175
+ // get token/node that has the the error
176
+ let jobId = null;
177
+ for( let i = 0; i < mongoInstance.tokens.length; ++i ) {
178
+ const item = mongoInstance.tokens[ i ];
179
+ if( item.hasError )
180
+ jobId = mongoInstance.tokens[0].tokenId;
181
+ }
182
+ if (!jobId) {
183
+ logger.warn(`No bpm mongoInstance.token found with errors for mongoInstance ${instanceId}`);
184
+ return null;
185
+ }
186
+ const jobs = await _agenda.jobs({ 'data.tokenId': jobId });
187
+ const job = jobs[0];
188
+ if (!job) {
189
+ logger.warn(`No job found with id ${jobId}`);
190
+ return null;
191
+ }
192
+
193
+ // Re-enable the job
194
+ job.attrs.disabled = false;
195
+
196
+ // Clear any lock or failed timestamps to allow retry
197
+ job.attrs.lockedAt = null;
198
+ job.attrs.lastFinishedAt = null;
199
+ job.attrs.failedAt = null;
200
+ job.attrs.failReason = null;
201
+
202
+ // Save the updated job
203
+ await job.save();
204
+ // Reschedule or immediately run
205
+ await job.run();
206
+
207
+ logger.info(`BPM instance: ${instanceId} has been re-enabled, and is attempting to run again.`);
208
+ return null;
209
+ },
210
+ killAgendaJob: async function (agenda, jobId, options = {}) {
211
+
212
+ },
213
+ scheduleStart: async function (processName, startNodeName, datetime) {
214
+ let now = new Date(Date.now());
215
+ now = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds(), now.getUTCMilliseconds()));
216
+ await _agenda.schedule(datetime, 'start', { processName: processName, startNodeName: startNodeName });
217
+ },
218
+ killInstance: async function (processName, instanceId, instanceFinisher) {
219
+ await _mongodbCollectionInstances.deleteOne({ _id: { $eq: ObjectId(instanceId) } });
220
+ instanceFinisher(processName);
221
+ },
222
+ createToken: async function (processName, instanceId, nodeName, parentTokenId) {
223
+ let tokenId = (new ObjectId()).toHexString();
224
+ let tokenData = { nodeName: nodeName };
225
+ if (parentTokenId)
226
+ tokenData.parentTokenId = parentTokenId;
227
+ let set = {};
228
+ set['tokens.' + tokenId] = tokenData;
229
+ await _mongodbCollectionInstances.updateOne({ _id: { $eq: ObjectId(instanceId) } }, { $set: set });
230
+ await _agenda.now('process-token', { processName: processName, instanceId: instanceId, tokenId: tokenId, nodeName: nodeName });
231
+ },
232
+ moveToken: async function (processName, instanceId, tokenId, targets, newGatewayNumber, tokenProcessor) {
233
+ var instanceData = await _mongodbCollectionInstances.findOne({ _id: { $eq: ObjectId(instanceId) } });
234
+ let tokenData = instanceData.tokens[tokenId];
235
+ if (tokenData) {
236
+ let parentTokenId = tokenData.parentTokenId;
237
+ let gatewayNumbers = tokenData.gatewayNumbers;
238
+ let unset = {};
239
+ let set = {};
240
+ removeTokenAndChilds(instanceData, tokenId, unset);
241
+ await _mongodbCollectionInstances.updateOne({ _id: { $eq: ObjectId(instanceId) } }, { $unset: unset });
242
+ instanceData = await _mongodbCollectionInstances.findOne({ _id: { $eq: ObjectId(instanceId) } });
243
+ for (let i = 0; i < targets.length; i++) {
244
+ let target = targets[i];
245
+ let pass = true;
246
+ if (target.filterGatewayNumber) {
247
+ for (let otherTokenId in instanceData.tokens) {
248
+ let otherTokenData = instanceData.tokens[otherTokenId];
249
+ if (otherTokenData.gatewayNumbers && otherTokenData.gatewayNumbers.indexOf(target.filterGatewayNumber) !== -1)
250
+ pass = false;
251
+ }
252
+ }
253
+ if (pass) {
254
+ target.newTokenId = (new ObjectId()).toHexString();
255
+ target.newTokenData = {nodeName: target.nodeName};
256
+ if (parentTokenId)
257
+ target.newTokenData.parentTokenId = parentTokenId;
258
+ if (gatewayNumbers || newGatewayNumber) {
259
+ target.newTokenData.gatewayNumbers = [];
260
+ if (gatewayNumbers) {
261
+ for (let j = 0; j < gatewayNumbers.length; j++) {
262
+ let gatewayNumber = gatewayNumbers[j];
263
+ if (gatewayNumber !== target.filterGatewayNumber)
264
+ target.newTokenData.gatewayNumbers.push(gatewayNumber);
265
+ }
266
+ }
267
+ if (newGatewayNumber) {
268
+ target.newTokenData.gatewayNumbers.push(newGatewayNumber);
269
+ }
270
+ }
271
+ if (target.waitMessages)
272
+ target.newTokenData.waitMessages = target.waitMessages;
273
+ if (target.waitSignals)
274
+ target.newTokenData.waitSignals = target.waitSignals;
275
+ set['tokens.' + target.newTokenId] = target.newTokenData;
276
+ }
277
+ }
278
+ if (Object.keys(set).length === 0)
279
+ await _mongodbCollectionInstances.updateOne({_id: {$eq: ObjectId(instanceId)}}, { $unset: unset });
280
+ else
281
+ await _mongodbCollectionInstances.updateOne({_id: {$eq: ObjectId(instanceId)}}, { $unset: unset, $set: set });
282
+ for (let i = 0; i < targets.length; i++) {
283
+ let target = targets[i];
284
+ if (target.newTokenId) {
285
+ if (target.immediateNodeName) {
286
+ if (target.immediateSchedule) {
287
+ await _agenda.now('process-token', { processName: processName, instanceId: instanceId, tokenId: target.newTokenId, nodeName: target.immediateNodeName, inboundTransaction: target.inbound });
288
+ }
289
+ else {
290
+ await tokenProcessor(processName, instanceId, target.newTokenId, target.immediateNodeName, target.inbound);
291
+ }
292
+ }
293
+ if (target.waitTimers) {
294
+ for (let j = 0; j < target.waitTimers.length; j++) {
295
+ let waitTimer = target.waitTimers[j];
296
+ await _agenda.schedule(waitTimer.datetime, 'process-token', { processName: processName, instanceId: instanceId, tokenId: target.newTokenId, nodeName: waitTimer.nodeName, inboundTransaction: target.inbound });
297
+ }
298
+ }
299
+ }
300
+ }
301
+ }
302
+ },
303
+ killToken: async function (processName, instanceId, tokenId, subProcessFinisher, instanceFinisher, err) {
304
+ var instanceData = await _mongodbCollectionInstances.findOne({ _id: { $eq: ObjectId(instanceId) } });
305
+ let tokenData = instanceData.tokens[tokenId];
306
+ if (tokenData) {
307
+ let parentTokenId = tokenData.parentTokenId;
308
+ let unset = {};
309
+ removeTokenAndChilds(instanceData, tokenId, unset);
310
+ if (err) {
311
+ for (let otherTokenId in instanceData.tokens) {
312
+ let otherTokenData = instanceData.tokens[otherTokenId];
313
+ if (otherTokenData.parentTokenId === parentTokenId)
314
+ removeTokenAndChilds(instanceData, otherTokenId, unset);
315
+ }
316
+ }
317
+ if (Object.keys(instanceData.tokens).length === 0) {
318
+ await _mongodbCollectionInstances.deleteOne({ _id: { $eq: ObjectId(instanceId) } });
319
+ instanceFinisher(processName, err);
320
+ }
321
+ else {
322
+ await _mongodbCollectionInstances.updateOne({ _id: { $eq: ObjectId(instanceId) } }, { $unset: unset });
323
+ if (parentTokenId) {
324
+ let subProcessFinished = true;
325
+ for (let otherTokenId in instanceData.tokens) {
326
+ let otherTokenData = instanceData.tokens[otherTokenId];
327
+ if (otherTokenData.parentTokenId === parentTokenId)
328
+ subProcessFinished = false;
329
+ }
330
+ if (subProcessFinished)
331
+ subProcessFinisher(processName, instanceId, parentTokenId, err);
332
+ }
333
+ }
334
+ }
335
+ },
336
+ readModel: async function (processName, instanceId, variableName) {
337
+ var instanceData = await _mongodbCollectionInstances.findOne({ _id: { $eq: ObjectId(instanceId) } });
338
+ if (instanceData) {
339
+ if (variableName === null || variableName === undefined)
340
+ return instanceData.model;
341
+ else
342
+ return instanceData.model[variableName];
343
+ }
344
+ return null;
345
+ },
346
+ writeModel: async function (processName, instanceId, variableName, value) {
347
+ let set = {};
348
+ set['model.' + variableName] = value;
349
+ await _mongodbCollectionInstances.updateOne({ _id: { $eq: ObjectId(instanceId) } }, { $set: set });
350
+ return null;
351
+ },
352
+ getNodeName: async function (processName, instanceId, tokenId) {
353
+ var instanceData = await _mongodbCollectionInstances.findOne({ _id: { $eq: ObjectId(instanceId) } });
354
+ let nodeName = null;
355
+ if (instanceData) {
356
+ let tokenData = instanceData.tokens[tokenId];
357
+ if (tokenData)
358
+ nodeName = tokenData.nodeName;
359
+ }
360
+ return nodeName;
361
+ },
362
+ getReceivers: async function (processName, instanceId, messageKey, signalName) {
363
+ var instanceData = await _mongodbCollectionInstances.findOne({ _id: { $eq: ObjectId(instanceId) } });
364
+ let receivers = [];
365
+ if (instanceData) {
366
+ for (let tokenId in instanceData.tokens) {
367
+ let tokenData = instanceData.tokens[tokenId];
368
+ if (tokenData.waitMessages) {
369
+ for (let i = 0; i < tokenData.waitMessages.length; i++) {
370
+ let waitMessage = tokenData.waitMessages[i];
371
+ if (waitMessage.messageKey === messageKey)
372
+ receivers.push({ tokenId: tokenId, nodeName: waitMessage.nodeName });
373
+ }
374
+ }
375
+ if (tokenData.waitSignals) {
376
+ for (let i = 0; i < tokenData.waitSignals.length; i++) {
377
+ let waitSignal = tokenData.waitSignals[i];
378
+ if (waitSignal.signalName === signalName)
379
+ receivers.push({ tokenId: tokenId, nodeName: waitSignal.nodeName });
380
+ }
381
+ }
382
+ }
383
+ }
384
+ return receivers;
385
+ },
386
+ enqueueCompensation: async function (processName, instanceId, compensationKey, nodeName) {
387
+ var instanceData = await _mongodbCollectionInstances.findOne({ _id: { $eq: ObjectId(instanceId) } });
388
+ let compensations = instanceData.compensations[compensationKey];
389
+ if (compensations === null || compensations === undefined) {
390
+ compensations = [];
391
+ instanceData.compensations[compensationKey] = compensations;
392
+ }
393
+ compensations.push({ nodeName: nodeName, model: JSON.parse(JSON.stringify(instanceData.model)) });
394
+ let set = {};
395
+ set['compensations.' + compensationKey] = compensations;
396
+ await _mongodbCollectionInstances.updateOne({ _id: { $eq: ObjectId(instanceId) } }, { $set: set });
397
+ },
398
+ compensate: async function (processName, instanceId, compensationKey, instanceCompensator) {
399
+ var instanceData = await _mongodbCollectionInstances.findOne({ _id: { $eq: ObjectId(instanceId) } });
400
+ let compensations = instanceData.compensations[compensationKey];
401
+ if (compensations) {
402
+ while (compensations.length > 0) {
403
+ let compensation = compensations.pop();
404
+ instanceCompensator(processName, instanceId, compensationKey, compensation.nodeName, compensation.model);
405
+ }
406
+ }
407
+ let set = {};
408
+ set['compensations.' + compensationKey] = [];
409
+ await _mongodbCollectionInstances.updateOne({ _id: { $eq: ObjectId(instanceId) } }, { $set: set });
410
+ },
411
+ listInstances: async function (processName, offset, limit) {
412
+ var mongodbCursor = await _mongodbCollectionInstances.find({ processName: { $eq: processName } }, { skip: offset, limit: limit });
413
+ return await mongodbCursor.map(function (instanceData) { return getInstance(instanceData); }).toArray();
414
+ },
415
+ getInstance: async function (processName, instanceId) {
416
+ var instanceData = await _mongodbCollectionInstances.findOne({ _id: { $eq: ObjectId(instanceId) } });
417
+ let instance = null;
418
+ if (instanceData)
419
+ instance = getInstance(instanceData);
420
+ return instance;
421
+ }
422
+ };