@shushed/helpers 0.0.202 → 0.0.203-bug-erp-770-20251208112219

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 (290) hide show
  1. package/dist/index.d.ts +34970 -0
  2. package/dist/index.js +113321 -0
  3. package/dist/package.json +3 -6
  4. package/package.json +4 -7
  5. package/dist/cjs/contracts/asset.schema.json +0 -78
  6. package/dist/cjs/contracts/category.schema.json +0 -86
  7. package/dist/cjs/contracts/country.schema.json +0 -258
  8. package/dist/cjs/contracts/currency.schema.json +0 -177
  9. package/dist/cjs/contracts/customer-segment.schema.json +0 -32
  10. package/dist/cjs/contracts/development-colour.schema.json +0 -97
  11. package/dist/cjs/contracts/index.js +0 -48
  12. package/dist/cjs/contracts/marketing-preferences.schema.json +0 -41
  13. package/dist/cjs/contracts/messages/ean-change.schema.json +0 -22
  14. package/dist/cjs/contracts/messages/index.js +0 -29
  15. package/dist/cjs/contracts/messages/order/delivered.schema.json +0 -26
  16. package/dist/cjs/contracts/messages/order/index.js +0 -18
  17. package/dist/cjs/contracts/messages/order/new.schema.json +0 -32
  18. package/dist/cjs/contracts/messages/order/processed.schema.json +0 -15
  19. package/dist/cjs/contracts/messages/order/return-initiated.schema.json +0 -26
  20. package/dist/cjs/contracts/messages/order/returned.schema.json +0 -25
  21. package/dist/cjs/contracts/messages/order/shipped.schema.json +0 -26
  22. package/dist/cjs/contracts/messages/product-category.schema.json +0 -21
  23. package/dist/cjs/contracts/messages/product-draft.schema.json +0 -66
  24. package/dist/cjs/contracts/messages/product.schema.json +0 -29
  25. package/dist/cjs/contracts/money.schema.json +0 -54
  26. package/dist/cjs/contracts/order/address.schema.json +0 -127
  27. package/dist/cjs/contracts/order/customer.schema.json +0 -149
  28. package/dist/cjs/contracts/order/index.js +0 -31
  29. package/dist/cjs/contracts/order/item.schema.json +0 -98
  30. package/dist/cjs/contracts/order/payment.schema.json +0 -115
  31. package/dist/cjs/contracts/order/shipment/index.js +0 -29
  32. package/dist/cjs/contracts/order/shipment/item/index.js +0 -8
  33. package/dist/cjs/contracts/order/shipment/item/returned.schema.json +0 -30
  34. package/dist/cjs/contracts/order/shipment/item.schema.json +0 -22
  35. package/dist/cjs/contracts/order/shipment/pos/index.js +0 -10
  36. package/dist/cjs/contracts/order/shipment/pos/outbound.schema.json +0 -37
  37. package/dist/cjs/contracts/order/shipment/pos/return.schema.json +0 -31
  38. package/dist/cjs/contracts/order/shipment/pos.schema.json +0 -48
  39. package/dist/cjs/contracts/order/shipment/shipped/index.js +0 -10
  40. package/dist/cjs/contracts/order/shipment/shipped/outbound.schema.json +0 -34
  41. package/dist/cjs/contracts/order/shipment/shipped/return.schema.json +0 -43
  42. package/dist/cjs/contracts/order/shipment/shipped.schema.json +0 -52
  43. package/dist/cjs/contracts/order/shipment.schema.json +0 -58
  44. package/dist/cjs/contracts/order.schema.json +0 -231
  45. package/dist/cjs/contracts/product-category.schema.json +0 -34
  46. package/dist/cjs/contracts/product-draft.schema.json +0 -782
  47. package/dist/cjs/contracts/product.schema.json +0 -816
  48. package/dist/cjs/contracts/total.schema.json +0 -41
  49. package/dist/cjs/dist-dereferenced/asset.js +0 -4
  50. package/dist/cjs/dist-dereferenced/category.js +0 -4
  51. package/dist/cjs/dist-dereferenced/country.js +0 -4
  52. package/dist/cjs/dist-dereferenced/currency.js +0 -4
  53. package/dist/cjs/dist-dereferenced/customer-segment.js +0 -4
  54. package/dist/cjs/dist-dereferenced/development-colour.js +0 -4
  55. package/dist/cjs/dist-dereferenced/index.js +0 -69
  56. package/dist/cjs/dist-dereferenced/marketing-preferences.js +0 -4
  57. package/dist/cjs/dist-dereferenced/messages/ean-change.js +0 -4
  58. package/dist/cjs/dist-dereferenced/messages/index.js +0 -50
  59. package/dist/cjs/dist-dereferenced/messages/order/delivered.js +0 -4
  60. package/dist/cjs/dist-dereferenced/messages/order/index.js +0 -18
  61. package/dist/cjs/dist-dereferenced/messages/order/new.js +0 -4
  62. package/dist/cjs/dist-dereferenced/messages/order/processed.js +0 -4
  63. package/dist/cjs/dist-dereferenced/messages/order/return-initiated.js +0 -4
  64. package/dist/cjs/dist-dereferenced/messages/order/returned.js +0 -4
  65. package/dist/cjs/dist-dereferenced/messages/order/shipped.js +0 -4
  66. package/dist/cjs/dist-dereferenced/messages/price-change.js +0 -4
  67. package/dist/cjs/dist-dereferenced/messages/product-category.js +0 -4
  68. package/dist/cjs/dist-dereferenced/messages/product-draft.js +0 -4
  69. package/dist/cjs/dist-dereferenced/messages/product.js +0 -4
  70. package/dist/cjs/dist-dereferenced/money.js +0 -4
  71. package/dist/cjs/dist-dereferenced/order/address.js +0 -4
  72. package/dist/cjs/dist-dereferenced/order/customer.js +0 -4
  73. package/dist/cjs/dist-dereferenced/order/index.js +0 -51
  74. package/dist/cjs/dist-dereferenced/order/item.js +0 -4
  75. package/dist/cjs/dist-dereferenced/order/orderMain.js +0 -4
  76. package/dist/cjs/dist-dereferenced/order/payment.js +0 -4
  77. package/dist/cjs/dist-dereferenced/order/shipment/index.js +0 -45
  78. package/dist/cjs/dist-dereferenced/order/shipment/item/index.js +0 -11
  79. package/dist/cjs/dist-dereferenced/order/shipment/item/itemMain.js +0 -4
  80. package/dist/cjs/dist-dereferenced/order/shipment/item/returned.js +0 -4
  81. package/dist/cjs/dist-dereferenced/order/shipment/pos/index.js +0 -13
  82. package/dist/cjs/dist-dereferenced/order/shipment/pos/outbound.js +0 -4
  83. package/dist/cjs/dist-dereferenced/order/shipment/pos/posMain.js +0 -4
  84. package/dist/cjs/dist-dereferenced/order/shipment/pos/return.js +0 -4
  85. package/dist/cjs/dist-dereferenced/order/shipment/shipmentMain.js +0 -4
  86. package/dist/cjs/dist-dereferenced/order/shipment/shipped/index.js +0 -13
  87. package/dist/cjs/dist-dereferenced/order/shipment/shipped/outbound.js +0 -4
  88. package/dist/cjs/dist-dereferenced/order/shipment/shipped/return.js +0 -4
  89. package/dist/cjs/dist-dereferenced/order/shipment/shipped/shippedMain.js +0 -4
  90. package/dist/cjs/dist-dereferenced/price.js +0 -4
  91. package/dist/cjs/dist-dereferenced/product-category.js +0 -4
  92. package/dist/cjs/dist-dereferenced/product-draft.js +0 -4
  93. package/dist/cjs/dist-dereferenced/product.js +0 -4
  94. package/dist/cjs/dist-dereferenced/stock.js +0 -4
  95. package/dist/cjs/dist-dereferenced/total.js +0 -4
  96. package/dist/cjs/dist-types/asset.js +0 -2
  97. package/dist/cjs/dist-types/category.js +0 -2
  98. package/dist/cjs/dist-types/country.js +0 -2
  99. package/dist/cjs/dist-types/currency.js +0 -2
  100. package/dist/cjs/dist-types/customer-segment.js +0 -2
  101. package/dist/cjs/dist-types/development-colour.js +0 -2
  102. package/dist/cjs/dist-types/index.js +0 -38
  103. package/dist/cjs/dist-types/marketing-preferences.js +0 -2
  104. package/dist/cjs/dist-types/messages/ean-change.js +0 -2
  105. package/dist/cjs/dist-types/messages/index.js +0 -37
  106. package/dist/cjs/dist-types/messages/order/delivered.js +0 -2
  107. package/dist/cjs/dist-types/messages/order/index.js +0 -2
  108. package/dist/cjs/dist-types/messages/order/new.js +0 -2
  109. package/dist/cjs/dist-types/messages/order/processed.js +0 -2
  110. package/dist/cjs/dist-types/messages/order/return-initiated.js +0 -2
  111. package/dist/cjs/dist-types/messages/order/returned.js +0 -2
  112. package/dist/cjs/dist-types/messages/order/shipped.js +0 -2
  113. package/dist/cjs/dist-types/messages/price-change.js +0 -2
  114. package/dist/cjs/dist-types/messages/product-category.js +0 -2
  115. package/dist/cjs/dist-types/messages/product-draft.js +0 -2
  116. package/dist/cjs/dist-types/messages/product.js +0 -2
  117. package/dist/cjs/dist-types/money.js +0 -2
  118. package/dist/cjs/dist-types/order/address.js +0 -2
  119. package/dist/cjs/dist-types/order/customer.js +0 -2
  120. package/dist/cjs/dist-types/order/index.js +0 -37
  121. package/dist/cjs/dist-types/order/item.js +0 -2
  122. package/dist/cjs/dist-types/order/orderMain.js +0 -2
  123. package/dist/cjs/dist-types/order/payment.js +0 -2
  124. package/dist/cjs/dist-types/order/shipment/index.js +0 -39
  125. package/dist/cjs/dist-types/order/shipment/item/index.js +0 -2
  126. package/dist/cjs/dist-types/order/shipment/item/itemMain.js +0 -2
  127. package/dist/cjs/dist-types/order/shipment/item/returned.js +0 -2
  128. package/dist/cjs/dist-types/order/shipment/pos/index.js +0 -2
  129. package/dist/cjs/dist-types/order/shipment/pos/outbound.js +0 -2
  130. package/dist/cjs/dist-types/order/shipment/pos/posMain.js +0 -2
  131. package/dist/cjs/dist-types/order/shipment/pos/return.js +0 -2
  132. package/dist/cjs/dist-types/order/shipment/shipmentMain.js +0 -2
  133. package/dist/cjs/dist-types/order/shipment/shipped/index.js +0 -2
  134. package/dist/cjs/dist-types/order/shipment/shipped/outbound.js +0 -2
  135. package/dist/cjs/dist-types/order/shipment/shipped/return.js +0 -2
  136. package/dist/cjs/dist-types/order/shipment/shipped/shippedMain.js +0 -2
  137. package/dist/cjs/dist-types/price.js +0 -2
  138. package/dist/cjs/dist-types/product-category.js +0 -2
  139. package/dist/cjs/dist-types/product-draft.js +0 -2
  140. package/dist/cjs/dist-types/product.js +0 -2
  141. package/dist/cjs/dist-types/stock.js +0 -2
  142. package/dist/cjs/dist-types/total.js +0 -2
  143. package/dist/cjs/index.js +0 -39
  144. package/dist/cjs/src-public/airtable.js +0 -625
  145. package/dist/cjs/src-public/bcOrder.js +0 -943
  146. package/dist/cjs/src-public/bigquery.js +0 -59
  147. package/dist/cjs/src-public/centra.js +0 -1053
  148. package/dist/cjs/src-public/cloudtasks.js +0 -207
  149. package/dist/cjs/src-public/dato.js +0 -403
  150. package/dist/cjs/src-public/env.js +0 -900
  151. package/dist/cjs/src-public/getEventTime.js +0 -28
  152. package/dist/cjs/src-public/index.js +0 -54
  153. package/dist/cjs/src-public/ipValidation.js +0 -167
  154. package/dist/cjs/src-public/jwks.js +0 -108
  155. package/dist/cjs/src-public/pubsub.js +0 -423
  156. package/dist/cjs/src-public/rateLimit.js +0 -140
  157. package/dist/cjs/src-public/redisClient.js +0 -44
  158. package/dist/cjs/src-public/runtime.js +0 -145
  159. package/dist/cjs/src-public/sanitize.js +0 -25
  160. package/dist/cjs/src-public/scheduler.js +0 -247
  161. package/dist/cjs/src-public/secret.js +0 -16
  162. package/dist/cjs/src-public/setHeaders.js +0 -16
  163. package/dist/cjs/src-public/types.js +0 -2
  164. package/dist/cjs/src-public/utils.js +0 -457
  165. package/dist/cjs/src-public/validate.js +0 -74
  166. package/dist/types/contracts/index.d.ts +0 -15
  167. package/dist/types/contracts/messages/index.d.ts +0 -5
  168. package/dist/types/contracts/messages/order/index.d.ts +0 -6
  169. package/dist/types/contracts/order/index.d.ts +0 -6
  170. package/dist/types/contracts/order/shipment/index.d.ts +0 -6
  171. package/dist/types/contracts/order/shipment/item/index.d.ts +0 -1
  172. package/dist/types/contracts/order/shipment/pos/index.d.ts +0 -2
  173. package/dist/types/contracts/order/shipment/shipped/index.d.ts +0 -2
  174. package/dist/types/dist-dereferenced/asset.d.ts +0 -51
  175. package/dist/types/dist-dereferenced/category.d.ts +0 -58
  176. package/dist/types/dist-dereferenced/country.d.ts +0 -8
  177. package/dist/types/dist-dereferenced/currency.d.ts +0 -8
  178. package/dist/types/dist-dereferenced/customer-segment.d.ts +0 -26
  179. package/dist/types/dist-dereferenced/development-colour.d.ts +0 -114
  180. package/dist/types/dist-dereferenced/index.d.ts +0 -16
  181. package/dist/types/dist-dereferenced/marketing-preferences.d.ts +0 -31
  182. package/dist/types/dist-dereferenced/messages/ean-change.d.ts +0 -17
  183. package/dist/types/dist-dereferenced/messages/index.d.ts +0 -6
  184. package/dist/types/dist-dereferenced/messages/order/delivered.d.ts +0 -3438
  185. package/dist/types/dist-dereferenced/messages/order/index.d.ts +0 -6
  186. package/dist/types/dist-dereferenced/messages/order/new.d.ts +0 -3438
  187. package/dist/types/dist-dereferenced/messages/order/processed.d.ts +0 -3432
  188. package/dist/types/dist-dereferenced/messages/order/return-initiated.d.ts +0 -3438
  189. package/dist/types/dist-dereferenced/messages/order/returned.d.ts +0 -3437
  190. package/dist/types/dist-dereferenced/messages/order/shipped.d.ts +0 -3436
  191. package/dist/types/dist-dereferenced/messages/price-change.d.ts +0 -67
  192. package/dist/types/dist-dereferenced/messages/product-category.d.ts +0 -33
  193. package/dist/types/dist-dereferenced/messages/product-draft.d.ts +0 -589
  194. package/dist/types/dist-dereferenced/messages/product.d.ts +0 -628
  195. package/dist/types/dist-dereferenced/money.d.ts +0 -41
  196. package/dist/types/dist-dereferenced/order/address.d.ts +0 -98
  197. package/dist/types/dist-dereferenced/order/customer.d.ts +0 -312
  198. package/dist/types/dist-dereferenced/order/index.d.ts +0 -3428
  199. package/dist/types/dist-dereferenced/order/item.d.ts +0 -339
  200. package/dist/types/dist-dereferenced/order/orderMain.d.ts +0 -3423
  201. package/dist/types/dist-dereferenced/order/payment.d.ts +0 -110
  202. package/dist/types/dist-dereferenced/order/shipment/index.d.ts +0 -253
  203. package/dist/types/dist-dereferenced/order/shipment/item/index.d.ts +0 -19
  204. package/dist/types/dist-dereferenced/order/shipment/item/itemMain.d.ts +0 -18
  205. package/dist/types/dist-dereferenced/order/shipment/item/returned.d.ts +0 -34
  206. package/dist/types/dist-dereferenced/order/shipment/pos/index.d.ts +0 -282
  207. package/dist/types/dist-dereferenced/order/shipment/pos/outbound.d.ts +0 -319
  208. package/dist/types/dist-dereferenced/order/shipment/pos/posMain.d.ts +0 -280
  209. package/dist/types/dist-dereferenced/order/shipment/pos/return.d.ts +0 -330
  210. package/dist/types/dist-dereferenced/order/shipment/shipmentMain.d.ts +0 -250
  211. package/dist/types/dist-dereferenced/order/shipment/shipped/index.d.ts +0 -288
  212. package/dist/types/dist-dereferenced/order/shipment/shipped/outbound.d.ts +0 -286
  213. package/dist/types/dist-dereferenced/order/shipment/shipped/return.d.ts +0 -287
  214. package/dist/types/dist-dereferenced/order/shipment/shipped/shippedMain.d.ts +0 -286
  215. package/dist/types/dist-dereferenced/price.d.ts +0 -58
  216. package/dist/types/dist-dereferenced/product-category.d.ts +0 -24
  217. package/dist/types/dist-dereferenced/product-draft.d.ts +0 -580
  218. package/dist/types/dist-dereferenced/product.d.ts +0 -619
  219. package/dist/types/dist-dereferenced/stock.d.ts +0 -74
  220. package/dist/types/dist-dereferenced/total.d.ts +0 -172
  221. package/dist/types/dist-types/asset.d.ts +0 -16
  222. package/dist/types/dist-types/category.d.ts +0 -20
  223. package/dist/types/dist-types/country.d.ts +0 -2
  224. package/dist/types/dist-types/currency.d.ts +0 -2
  225. package/dist/types/dist-types/customer-segment.d.ts +0 -6
  226. package/dist/types/dist-types/development-colour.d.ts +0 -31
  227. package/dist/types/dist-types/index.d.ts +0 -16
  228. package/dist/types/dist-types/marketing-preferences.d.ts +0 -9
  229. package/dist/types/dist-types/messages/ean-change.d.ts +0 -5
  230. package/dist/types/dist-types/messages/index.d.ts +0 -6
  231. package/dist/types/dist-types/messages/order/delivered.d.ts +0 -300
  232. package/dist/types/dist-types/messages/order/index.d.ts +0 -6
  233. package/dist/types/dist-types/messages/order/new.d.ts +0 -300
  234. package/dist/types/dist-types/messages/order/processed.d.ts +0 -300
  235. package/dist/types/dist-types/messages/order/return-initiated.d.ts +0 -300
  236. package/dist/types/dist-types/messages/order/returned.d.ts +0 -301
  237. package/dist/types/dist-types/messages/order/shipped.d.ts +0 -301
  238. package/dist/types/dist-types/messages/price-change.d.ts +0 -16
  239. package/dist/types/dist-types/messages/product-category.d.ts +0 -7
  240. package/dist/types/dist-types/messages/product-draft.d.ts +0 -136
  241. package/dist/types/dist-types/messages/product.d.ts +0 -144
  242. package/dist/types/dist-types/money.d.ts +0 -11
  243. package/dist/types/dist-types/order/address.d.ts +0 -27
  244. package/dist/types/dist-types/order/customer.d.ts +0 -82
  245. package/dist/types/dist-types/order/index.d.ts +0 -8
  246. package/dist/types/dist-types/order/item.d.ts +0 -86
  247. package/dist/types/dist-types/order/orderMain.d.ts +0 -297
  248. package/dist/types/dist-types/order/payment.d.ts +0 -30
  249. package/dist/types/dist-types/order/shipment/index.d.ts +0 -6
  250. package/dist/types/dist-types/order/shipment/item/index.d.ts +0 -4
  251. package/dist/types/dist-types/order/shipment/item/itemMain.d.ts +0 -6
  252. package/dist/types/dist-types/order/shipment/item/returned.d.ts +0 -11
  253. package/dist/types/dist-types/order/shipment/pos/index.d.ts +0 -5
  254. package/dist/types/dist-types/order/shipment/pos/outbound.d.ts +0 -76
  255. package/dist/types/dist-types/order/shipment/pos/posMain.d.ts +0 -71
  256. package/dist/types/dist-types/order/shipment/pos/return.d.ts +0 -75
  257. package/dist/types/dist-types/order/shipment/shipmentMain.d.ts +0 -62
  258. package/dist/types/dist-types/order/shipment/shipped/index.d.ts +0 -5
  259. package/dist/types/dist-types/order/shipment/shipped/outbound.d.ts +0 -68
  260. package/dist/types/dist-types/order/shipment/shipped/return.d.ts +0 -68
  261. package/dist/types/dist-types/order/shipment/shipped/shippedMain.d.ts +0 -69
  262. package/dist/types/dist-types/price.d.ts +0 -15
  263. package/dist/types/dist-types/product-category.d.ts +0 -6
  264. package/dist/types/dist-types/product-draft.d.ts +0 -135
  265. package/dist/types/dist-types/product.d.ts +0 -143
  266. package/dist/types/dist-types/stock.d.ts +0 -19
  267. package/dist/types/dist-types/total.d.ts +0 -44
  268. package/dist/types/index.d.ts +0 -3
  269. package/dist/types/src-public/airtable.d.ts +0 -227
  270. package/dist/types/src-public/bcOrder.d.ts +0 -84
  271. package/dist/types/src-public/bigquery.d.ts +0 -17
  272. package/dist/types/src-public/centra.d.ts +0 -176
  273. package/dist/types/src-public/cloudtasks.d.ts +0 -74
  274. package/dist/types/src-public/dato.d.ts +0 -62
  275. package/dist/types/src-public/env.d.ts +0 -144
  276. package/dist/types/src-public/getEventTime.d.ts +0 -1
  277. package/dist/types/src-public/index.d.ts +0 -19
  278. package/dist/types/src-public/ipValidation.d.ts +0 -15
  279. package/dist/types/src-public/jwks.d.ts +0 -15
  280. package/dist/types/src-public/pubsub.d.ts +0 -95
  281. package/dist/types/src-public/rateLimit.d.ts +0 -21
  282. package/dist/types/src-public/redisClient.d.ts +0 -6
  283. package/dist/types/src-public/runtime.d.ts +0 -58
  284. package/dist/types/src-public/sanitize.d.ts +0 -4
  285. package/dist/types/src-public/scheduler.d.ts +0 -71
  286. package/dist/types/src-public/secret.d.ts +0 -6
  287. package/dist/types/src-public/setHeaders.d.ts +0 -13
  288. package/dist/types/src-public/types.d.ts +0 -264
  289. package/dist/types/src-public/utils.d.ts +0 -101
  290. package/dist/types/src-public/validate.d.ts +0 -9
@@ -1,900 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
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);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
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
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- const crypto = __importStar(require("crypto"));
40
- const crypto_1 = require("crypto");
41
- const co_body_1 = __importDefault(require("co-body"));
42
- const jose_1 = require("jose");
43
- const lodash_omit_1 = __importDefault(require("lodash.omit"));
44
- const rate_limiter_flexible_1 = require("rate-limiter-flexible");
45
- const pubsub_1 = __importDefault(require("./pubsub"));
46
- const redisClient_1 = require("./redisClient");
47
- const runtime_1 = __importDefault(require("./runtime"));
48
- const utils_1 = require("./utils");
49
- const ENV_NAME_CONTAINING_SERVICE_ACCOUNTS = 'hush_trigger_allowed_service_accounts';
50
- const ENV_NAME_RN_WORFKLOW_TRIGGER_ID = 'hush_trigger_rn_workflow_trigger_id';
51
- const ENV_NAME_PUBSUB_PROJECT_ID = 'hush_pubsub_project_id';
52
- const ENV_NAME_PUBSUB_SERVICE_ACCOUNT = 'hush_pubsub_service_account';
53
- const ENV_NAME_SECRET_ENCRYPTION_KEY = 'SECRET_ENCRYPTION_KEY';
54
- global.IN_MEMORY_REF = global.IN_MEMORY_REF || {
55
- env: {},
56
- workflow: {},
57
- trigger: {},
58
- };
59
- class EnvEngine extends runtime_1.default {
60
- globalInMemoryRef;
61
- inMemoryRef;
62
- docRef = null;
63
- store;
64
- _envCache = {};
65
- _lockRateLimiter = null;
66
- constructor(opts, _) {
67
- super(opts);
68
- Object.assign(global.IN_MEMORY_REF || {}, {
69
- env: { [this.envName]: global.IN_MEMORY_REF?.env?.[this.envName] || {} },
70
- workflow: { [this.envName + this.workflowId]: global.IN_MEMORY_REF?.workflow?.[this.envName + this.workflowId] || {} },
71
- trigger: { [this.envName + this.workflowId + this.triggerId]: global.IN_MEMORY_REF?.trigger?.[this.envName + this.workflowId + this.triggerId] || {} },
72
- });
73
- this.globalInMemoryRef = {
74
- env: global.IN_MEMORY_REF?.env?.[this.envName] || {},
75
- workflow: global.IN_MEMORY_REF?.workflow?.[this.envName + this.workflowId] || {},
76
- trigger: global.IN_MEMORY_REF?.trigger?.[this.envName + this.workflowId + this.triggerId] || {},
77
- };
78
- this.inMemoryRef = {
79
- env: {},
80
- workflow: {},
81
- trigger: {},
82
- };
83
- this.store = {
84
- env: null,
85
- workflow: null,
86
- trigger: null,
87
- };
88
- }
89
- initializeDocRef() {
90
- if (this.docRef) {
91
- return;
92
- }
93
- const firestore = (0, utils_1.getFirestore)(this.systemEnvName);
94
- this.docRef = {
95
- env: firestore?.doc(`hush-${this.envName}/0-0`),
96
- workflow: firestore?.doc(`hush-${this.envName}/${this.workflowId}-0`),
97
- trigger: firestore?.doc(`hush-${this.envName}/${this.workflowId}-${this.triggerId}`),
98
- };
99
- }
100
- async set(envs, level = 'trigger', optionsOrEncryptWithValue) {
101
- const options = typeof optionsOrEncryptWithValue === 'object' ? optionsOrEncryptWithValue : {
102
- encrypted: !!optionsOrEncryptWithValue,
103
- encryptionKey: optionsOrEncryptWithValue,
104
- ephemeralMs: 0
105
- };
106
- let expirseAt = 0;
107
- if ((options.ephemeralMs || 0) > 3 * 60 * 60 * 1000) {
108
- throw new Error('Validation Error. The options.ephemeralMs cannot be set for the duration longer than 3 hours');
109
- }
110
- const now = Date.now();
111
- expirseAt = now + (options.ephemeralMs || 0);
112
- if (options.encrypted && !options.encryptionKey) {
113
- if (!options.ephemeralMs) {
114
- throw new Error(`Invariant while setting the value for ${this.systemEnvName}. If the options.encryptionKey is not set and the encryption with the default key is used, only the ephemeral storage can be used. Set the ephemeralMs`);
115
- }
116
- else {
117
- if (!this._envCache[this.systemEnvName]) {
118
- const jsonEnv = JSON.parse(process.env[`${this.systemEnvName}ProjectEnv`] || JSON.stringify({
119
- __mock_invalid: true
120
- }));
121
- this._envCache[this.systemEnvName] = jsonEnv;
122
- }
123
- let cachedEnv = this._envCache[this.systemEnvName];
124
- if (cachedEnv['__mock_invalid']) {
125
- cachedEnv = process.env;
126
- }
127
- options.encryptionKey = cachedEnv[ENV_NAME_SECRET_ENCRYPTION_KEY];
128
- if (!options.encryptionKey) {
129
- throw new Error(`Invariant while setting the value for ${this.systemEnvName}. If the options.encryptionKey is not set and the encryption with the default key is used, only the ephemeral storage can be used. Set the ephemeralMs. The default key is missing.`);
130
- }
131
- }
132
- }
133
- let aes = null;
134
- if (options.encryptionKey) {
135
- aes = new AES256GCM(Buffer.from(options.encryptionKey, 'utf8'));
136
- }
137
- const objPlain = envs
138
- .filter((env) => !!env.name)
139
- .reduce((prev, curr) => {
140
- const value = curr.value;
141
- return ({ ...prev, [curr.name]: value });
142
- }, {});
143
- const objEncrypted = envs
144
- .filter((env) => !!env.name)
145
- .reduce((prev, curr) => {
146
- let value = curr.value;
147
- if (aes) {
148
- value = aes.encrypt(curr.value);
149
- }
150
- return ({ ...prev, [curr.name]: value });
151
- }, {});
152
- Object.assign(this.inMemoryRef[level], Object.fromEntries(Object.entries(objPlain).map(([k, v]) => [k, `${expirseAt}/${now}/${v}`])));
153
- if (options.ephemeralMs) {
154
- if (!options.ignoreStores?.includes('global')) {
155
- Object.assign(this.globalInMemoryRef[level], Object.fromEntries(Object.entries(objEncrypted).map(([k, v]) => [k, `${expirseAt}/${now}/${v}`])));
156
- }
157
- if (!options.ignoreStores?.includes('redis')) {
158
- (async () => {
159
- const redisClient = await (0, redisClient_1.getConnectedRedisClient)(this.systemEnvName).catch(() => null);
160
- if (redisClient) {
161
- Promise.allSettled(Object.entries(objEncrypted).map(([k, v]) => redisClient.set(k, `${expirseAt}/${now}/${v}`, { PX: expirseAt - Date.now() })));
162
- }
163
- })().catch(() => this.logging.error(`Failed to set the ${envs.map(x => x.name).join(', ')} in Redis`));
164
- }
165
- }
166
- else {
167
- await this.initializeDocRef();
168
- if (this.docRef[level]) {
169
- try {
170
- await this.docRef[level].set(objEncrypted, { merge: true });
171
- }
172
- catch (err) {
173
- throw new Error(`Failed to set the ${envs.map(x => x.name).join(', ')}. Error: ${err.message}`);
174
- }
175
- }
176
- else { }
177
- }
178
- return undefined;
179
- }
180
- async getFirestoreStore(level = 'trigger') {
181
- await this.initializeDocRef();
182
- const store = await this.docRef[level].get();
183
- return store.data() || {};
184
- }
185
- async get(keys, level = 'trigger', decryptWithValueOrOptions) {
186
- const options = typeof decryptWithValueOrOptions === 'object' ? decryptWithValueOrOptions : {
187
- encrypted: !!decryptWithValueOrOptions,
188
- encryptionKey: decryptWithValueOrOptions,
189
- isEphemeral: false
190
- };
191
- const keysParsed = typeof keys === 'string' ? [keys] : keys;
192
- const result = await this._get(keysParsed, level, options);
193
- if (typeof keys === 'string') {
194
- return result[keys].valid ? result[keys].value : '';
195
- }
196
- return Object.fromEntries(Object.entries(result).map(([k, v]) => [k, v.valid ? v.value : '']));
197
- }
198
- async _get(keysParsed, level = 'trigger', options) {
199
- let aes = null;
200
- if (options.encrypted && !options.encryptionKey) {
201
- if (!options.isEphemeral) {
202
- throw new Error(`Invariant while getting the value for ${this.systemEnvName}. If the options.encryptionKey is not set and the encryption with the default key is used, only the ephemeral storage can be used. Set the ephemeralMs`);
203
- }
204
- else {
205
- if (!this._envCache[this.systemEnvName]) {
206
- let jsonEnv;
207
- if (process.env[`${this.systemEnvName}ProjectEnv`]) {
208
- try {
209
- jsonEnv = JSON.parse(process.env[`${this.systemEnvName}ProjectEnv`] || '');
210
- }
211
- catch (err) {
212
- this.logging.error(`Invariant: Cannot parse the ${this.systemEnvName}ProjectEnv as JSON. ${err?.message}`);
213
- }
214
- }
215
- this._envCache[this.systemEnvName] = jsonEnv || {
216
- __mock_invalid: true
217
- };
218
- }
219
- let cachedEnv = this._envCache[this.systemEnvName];
220
- if (cachedEnv['__mock_invalid']) {
221
- cachedEnv = process.env;
222
- }
223
- options.encryptionKey = cachedEnv[ENV_NAME_SECRET_ENCRYPTION_KEY];
224
- if (!options.encryptionKey) {
225
- throw new Error(`Invariant while getting the value for ${this.systemEnvName}. If the options.encryptionKey is not set and the encryption with the default key is used, only the ephemeral storage can be used. Set the ephemeralMs. The default key is missing.`);
226
- }
227
- }
228
- }
229
- if (options.encryptionKey) {
230
- aes = new AES256GCM(Buffer.from(options.encryptionKey, 'utf8'));
231
- }
232
- let store = {};
233
- if (options.isEphemeral && !options.store || options.store === 'inMemory') {
234
- store = this.inMemoryRef[level];
235
- }
236
- else if (options.store === 'global') {
237
- store = this.globalInMemoryRef[level];
238
- }
239
- else if (options.store === 'redis') {
240
- store = {};
241
- }
242
- else {
243
- store = await this.getFirestoreStore(level);
244
- }
245
- if (options.store === 'redis') {
246
- const redisClient = await (0, redisClient_1.getConnectedRedisClient)(this.systemEnvName).catch(() => null);
247
- if (redisClient) {
248
- const values = await Promise.race([
249
- redisClient.mGet(keysParsed),
250
- new Promise((resolve) => setTimeout(() => {
251
- resolve(keysParsed.map(() => null));
252
- }, 30))
253
- ]);
254
- for (let i = 0; i < keysParsed.length; i++) {
255
- store[keysParsed[i]] = values[i] || '';
256
- }
257
- }
258
- }
259
- const parseEphemeral = !!options.isEphemeral;
260
- const result = keysParsed.reduce((acc, k) => {
261
- let v = store?.[k] || '';
262
- let expiresAt = 0;
263
- let createdAt = 0;
264
- if (parseEphemeral && v.includes('/')) {
265
- const valueParts = v.split('/');
266
- v = valueParts.slice(2).join('/');
267
- createdAt = parseInt(valueParts[1]);
268
- expiresAt = parseInt(valueParts[0]);
269
- }
270
- let finalValue = '';
271
- if (aes && v && typeof v === 'string' && options.store !== 'inMemory') {
272
- try {
273
- finalValue = aes.decrypt(v);
274
- }
275
- catch (err) {
276
- finalValue = '';
277
- }
278
- }
279
- else {
280
- finalValue = typeof v !== 'string' ? `${(v === null || typeof v === 'undefined') ? '' : `${v}`}` : v;
281
- }
282
- acc[k] = {
283
- createdAt,
284
- expiresAt,
285
- value: finalValue,
286
- valid: parseEphemeral ? (expiresAt > Date.now() - (options.expirationMarginMs || 0) && finalValue !== '') : (finalValue !== '')
287
- };
288
- return acc;
289
- }, {});
290
- return result;
291
- }
292
- withGoogleAccessToken() {
293
- const serviceName = process.env.K_SERVICE || '<not-cloud-run>';
294
- return this.with(`google_access_token_${serviceName}`, 'env', { encrypted: true, ephemeralMs: 10 * 60 * 1000, fetch: () => (0, utils_1.getAccessToken)() });
295
- }
296
- withGoogleIdentityToken(audience) {
297
- const audienceNorm = {
298
- workflowId: audience ? (audience.workflowId || this.workflowId) : null,
299
- triggerId: audience ? (audience.triggerId || this.triggerId) : null
300
- };
301
- const serviceName = process.env.K_SERVICE || '<not-cloud-run>';
302
- console.log('JAKUB8', serviceName);
303
- const expectedAudience = [process.env.GCLOUD_PROJECT, audienceNorm.workflowId, audienceNorm.triggerId].filter(x => x !== null).join('-');
304
- return this.with(`google_identity_token_${serviceName}_${expectedAudience}`, 'env', { encrypted: true, ephemeralMs: 10 * 60 * 1000, fetch: () => (0, utils_1.getIdentityToken)(expectedAudience) });
305
- }
306
- resolveEnvName(envName) {
307
- if (envName.startsWith('process.env.')) {
308
- envName = envName.slice('process.env.'.length);
309
- }
310
- if (!this._envCache[this.systemEnvName]) {
311
- const jsonEnv = JSON.parse(process.env[`${this.systemEnvName}ProjectEnv`] || '{ "__mock_invalid": true }');
312
- this._envCache[this.systemEnvName] = jsonEnv;
313
- }
314
- const envObj = this._envCache[this.systemEnvName];
315
- return envObj[envName] || envName;
316
- }
317
- async checkGoogleIdentiyToken(accessToken, audience, allowedServiceAccounts = [`runtime@${process.env.GCLOUD_PROJECT}.iam.gserviceaccount.com`]) {
318
- if (!accessToken) {
319
- return false;
320
- }
321
- function equalToWildcard(stringWithWildcard, str) {
322
- const escaped = stringWithWildcard.replace(/[-/\\^$+?.()|[\]{}]/g, '\\$&');
323
- const pattern = '^' + escaped.replace(/\*/g, '.*') + '$';
324
- const regex = new RegExp(pattern);
325
- return regex.test(str);
326
- }
327
- const audienceNorm = {
328
- workflowId: audience ? (audience.workflowId || this.workflowId) : null,
329
- triggerId: audience ? (audience.triggerId || this.triggerId) : null
330
- };
331
- const expectedAudience = [process.env.GCLOUD_PROJECT, audienceNorm.triggerId, audienceNorm.workflowId].filter(x => x !== null).join('-');
332
- const splitted = accessToken.split(".");
333
- let keyMeta;
334
- let meta;
335
- try {
336
- keyMeta = JSON.parse(Buffer.from(splitted[0], "base64").toString('utf-8')) || {};
337
- meta = JSON.parse(Buffer.from(splitted[1], "base64").toString('utf-8')) || {};
338
- }
339
- catch (err) {
340
- this.logging.error(`Authorization header - Malformed Token. ${err.message}`);
341
- return false;
342
- }
343
- let tokenExpirationTime = meta.exp;
344
- if (!tokenExpirationTime) {
345
- this.logging.error(`Authorization header - Expiration time is missing`);
346
- return false;
347
- }
348
- tokenExpirationTime = tokenExpirationTime * 1000;
349
- if (tokenExpirationTime < Date.now()) {
350
- this.logging.error(`Authorization header - Token expired`);
351
- return false;
352
- }
353
- if (!meta.email_verified) {
354
- this.logging.error(`Authorization header - Email not verified`);
355
- return false;
356
- }
357
- if (!allowedServiceAccounts.some(x => equalToWildcard(x, meta.email))) {
358
- this.logging.error(`Authorization header - Wrong service account, got ${meta?.email}, expected one of ${allowedServiceAccounts.join(', ')}`);
359
- return false;
360
- }
361
- if (!keyMeta.kid || !keyMeta.alg) {
362
- this.logging.error(`Authorization header - Malformed Authorization Header. KID is missing`);
363
- return false;
364
- }
365
- if (meta.aud !== expectedAudience) {
366
- const receivedMoreSpecific = (expectedAudience + '-' + this.triggerId) === meta.aud || (expectedAudience + '-' + this.workflowId + '-' + this.triggerId) === meta.aud || (expectedAudience + '-' + this.workflowId) === meta.aud || (expectedAudience + '/' + this.workflowId + '/' + this.triggerId) === meta.aud || (expectedAudience + '/' + this.workflowId) === meta.aud || (expectedAudience + '/' + this.triggerId) === meta.aud;
367
- if (!receivedMoreSpecific) {
368
- this.logging.error(`Authorization header - Wrong audience, got ${meta?.aud}, expected ${expectedAudience}`);
369
- return false;
370
- }
371
- }
372
- const tokenSignature = (0, crypto_1.createHash)('sha256').update(accessToken).digest('hex');
373
- const tokensServiceAccount = await this.get('google_identity_token_signature_' + tokenSignature, 'env', { encrypted: false, isEphemeral: true, store: 'global' });
374
- if (tokensServiceAccount && allowedServiceAccounts.some(x => equalToWildcard(x, tokensServiceAccount))) {
375
- return tokensServiceAccount;
376
- }
377
- const publicKey = await this.with('google_public_keys', 'env', {
378
- encrypted: false,
379
- ephemeralMs: 20 * 60 * 1000,
380
- fetch: async () => {
381
- const res = await fetch('https://www.googleapis.com/oauth2/v3/certs');
382
- if (!res.ok) {
383
- throw new Error(`Failed to fetch public keys: ${await res.text().catch(() => 'Unknown error')}`);
384
- }
385
- return res.text();
386
- }
387
- })(async (publicKeys) => {
388
- const jwks = JSON.parse(publicKeys);
389
- const keyInStorage = jwks?.keys.find((x) => x.kid === keyMeta.kid);
390
- if (!keyInStorage) {
391
- throw new Error('Google JWKS - Key not found in the Google JWKS set');
392
- }
393
- return keyInStorage;
394
- });
395
- try {
396
- await (0, jose_1.jwtVerify)(accessToken, await (0, jose_1.importJWK)(publicKey, keyMeta.alg), {
397
- issuer: ['https://accounts.google.com', 'accounts.google.com'],
398
- clockTolerance: 0,
399
- audience: [expectedAudience, expectedAudience + '-' + this.workflowId, expectedAudience + '-' + this.workflowId + '-' + this.triggerId, expectedAudience + '/' + this.workflowId + '/' + this.triggerId, expectedAudience + '/' + this.workflowId, expectedAudience + '/' + this.triggerId, expectedAudience + '-' + this.triggerId],
400
- });
401
- }
402
- catch (err) {
403
- this.logging.log(`Authorization header - Signature verification failed: ${err.message}`);
404
- return false;
405
- }
406
- await this.set([{
407
- name: 'google_identity_token_signature_' + tokenSignature,
408
- value: meta.email
409
- }], 'env', { encrypted: false, ephemeralMs: Math.max(tokenExpirationTime - Date.now(), 5 * 60 * 1000), ignoreStores: ['redis'] });
410
- return meta.email;
411
- }
412
- withSecret(key) {
413
- if (key.startsWith('process.secret.')) {
414
- key = key.slice('process.secret.'.length);
415
- }
416
- return this.with('__secret_' + key, 'env', {
417
- encrypted: true,
418
- ephemeralMs: 5 * 60 * 1000,
419
- fetch: () => {
420
- return this.withGoogleAccessToken()(async (accessToken) => {
421
- const secret = await (0, utils_1.getSecret)(this, key, accessToken);
422
- return secret;
423
- });
424
- }
425
- });
426
- }
427
- with(key, level = 'trigger', options) {
428
- return async (fn) => {
429
- let lastError;
430
- let lastResult;
431
- let valueFoundAndWorking = false;
432
- const injectedFunction = async (value) => {
433
- let nextValueFoundAndWorking = true;
434
- const requestCacheRefresh = () => {
435
- nextValueFoundAndWorking = false;
436
- };
437
- try {
438
- const result = await fn(value, requestCacheRefresh);
439
- lastResult = result;
440
- lastError = undefined;
441
- }
442
- catch (err) {
443
- lastError = err;
444
- lastResult = undefined;
445
- requestCacheRefresh();
446
- }
447
- valueFoundAndWorking = nextValueFoundAndWorking;
448
- return valueFoundAndWorking;
449
- };
450
- let possibleValue = null;
451
- let stores;
452
- if (options?.ephemeralMs) {
453
- stores = ['inMemory', 'global', 'redis'];
454
- }
455
- else {
456
- stores = ['firestore'];
457
- }
458
- const checkedStores = [];
459
- for (let i = 0; i < stores.length; i++) {
460
- const store = stores[i];
461
- checkedStores.push(store);
462
- const value = await this._get([key], level, { ...options, store: store, isEphemeral: true });
463
- if (value[key].valid) {
464
- possibleValue = Object.assign({}, value[key], {
465
- checkedStores
466
- });
467
- if (await injectedFunction(value[key].value)) {
468
- if (store === 'redis') {
469
- this.set([{
470
- name: key,
471
- value: value[key].value
472
- }], level, { encrypted: options?.encrypted || false, ephemeralMs: value[key].expiresAt - Date.now(), ignoreStores: ['redis'] });
473
- }
474
- return lastResult;
475
- }
476
- possibleValue = null;
477
- }
478
- }
479
- if (!possibleValue && options?.fetch) {
480
- this.logging.log(`Value ${key} not found in the cache, fetching from the source`);
481
- const value = await options?.fetch?.();
482
- possibleValue = {
483
- value: value,
484
- valid: true,
485
- createdAt: Date.now(),
486
- expiresAt: Date.now() + (options?.ephemeralMs || 0),
487
- };
488
- await injectedFunction(value);
489
- this.set([{
490
- name: key,
491
- value: value
492
- }], level, { encrypted: options?.encrypted || false, ephemeralMs: options?.ephemeralMs || 0 });
493
- }
494
- if (lastError) {
495
- throw lastError;
496
- }
497
- return lastResult;
498
- };
499
- }
500
- pauseRespectfulNudge(subscriptionName, partialConfig) {
501
- const workflowTriggerId = this.resolveEnvName(ENV_NAME_RN_WORFKLOW_TRIGGER_ID);
502
- if (!workflowTriggerId) {
503
- throw new Error('RN Workflow Trigger ID is not set. Please set the ' + ENV_NAME_RN_WORFKLOW_TRIGGER_ID + ' environment variable.');
504
- }
505
- const pubSubProjectId = this.resolveEnvName(ENV_NAME_PUBSUB_PROJECT_ID);
506
- if (!pubSubProjectId) {
507
- throw new Error('PubSub Project ID is not set. Please set the ' + ENV_NAME_PUBSUB_PROJECT_ID + ' environment variable.');
508
- }
509
- const rnConfig = Object.assign({}, {
510
- workflowTriggerId: workflowTriggerId,
511
- pubSubProjectId: pubSubProjectId,
512
- }, partialConfig);
513
- const subscriptionQualifiedName = `projects/${rnConfig.pubSubProjectId}/subscriptions/${subscriptionName}`;
514
- return this.withGoogleIdentityToken({
515
- workflowId: rnConfig.workflowTriggerId.split('/')[0],
516
- triggerId: rnConfig.workflowTriggerId.split('/')[1],
517
- })(async (token) => {
518
- if (!(await fetch(this.runtimeUrl + `/executeWorkflow/${rnConfig.workflowTriggerId}`, {
519
- method: 'POST',
520
- headers: {
521
- 'X-Buildship-Trigger-Authorization': `Bearer ${token}`,
522
- Authorization: `Bearer ${token}`,
523
- 'Content-Type': 'application/json'
524
- },
525
- body: JSON.stringify({
526
- subscriptionName: subscriptionQualifiedName,
527
- operation: 'pause',
528
- })
529
- })).ok) {
530
- throw new Error('Failed to deactivate the main subscription with respectful nudge');
531
- }
532
- return true;
533
- });
534
- }
535
- getRespectfulNudgeConfig(subscriptionName, rnPartialConfig) {
536
- const workflowTriggerId = this.resolveEnvName(ENV_NAME_RN_WORFKLOW_TRIGGER_ID);
537
- if (!workflowTriggerId) {
538
- throw new Error('RN Workflow Trigger ID is not set. Please set the ' + ENV_NAME_RN_WORFKLOW_TRIGGER_ID + ' environment variable.');
539
- }
540
- const pubSubProjectId = this.resolveEnvName(ENV_NAME_PUBSUB_PROJECT_ID);
541
- if (!pubSubProjectId) {
542
- throw new Error('PubSub Project ID is not set. Please set the ' + ENV_NAME_PUBSUB_PROJECT_ID + ' environment variable.');
543
- }
544
- const rnConfig = Object.assign({}, {
545
- pubSubProjectId: pubSubProjectId,
546
- noAllowedWorkers: 1,
547
- workflowTriggerId: this.workflowId + '/' + this.triggerId,
548
- workerGroup: this.envName,
549
- errorThreshold: 0.80,
550
- error429Threshold: 0.30,
551
- pauseOnErrorThresholdExceededSeconds: 60 * 10,
552
- pauseOnError429ThresholdExceededSeconds: 60 * 10,
553
- pauseBeforeProcessingMessagesSeconds: 0,
554
- maxOutstandingMessages: 5,
555
- ackDeadline: 10,
556
- retryMinDelay: 60,
557
- retryMaxDelay: 60 * 10,
558
- retryLimit: 5,
559
- topicName: subscriptionName,
560
- tableName: '',
561
- tableAckDeadline: 60,
562
- tableRetryMinDelay: 60 * 5,
563
- tableRetryMaxDelay: 60 * 10,
564
- tableRetryLimit: 10,
565
- orderingIndexFields: [],
566
- orderingSortField: '',
567
- batchSize: 1,
568
- subscriptionFilter: null,
569
- batchWindowSeconds: 10,
570
- }, Object.fromEntries(Object.entries(rnPartialConfig).filter(x => !(x === null || x === undefined))));
571
- return rnConfig;
572
- }
573
- createOrUpdateRespectfulNudge(subscriptionName, rnPartialConfig) {
574
- const workflowTriggerId = this.resolveEnvName(ENV_NAME_RN_WORFKLOW_TRIGGER_ID);
575
- if (!workflowTriggerId) {
576
- throw new Error('RN Workflow Trigger ID is not set. Please set the ' + ENV_NAME_RN_WORFKLOW_TRIGGER_ID + ' environment variable.');
577
- }
578
- const pubSubProjectId = this.resolveEnvName(ENV_NAME_PUBSUB_PROJECT_ID);
579
- if (!pubSubProjectId) {
580
- throw new Error('PubSub Project ID is not set. Please set the ' + ENV_NAME_PUBSUB_PROJECT_ID + ' environment variable.');
581
- }
582
- const rnConfig = this.getRespectfulNudgeConfig(subscriptionName, rnPartialConfig);
583
- const subscriptionQualifiedName = `projects/${rnConfig.pubSubProjectId}/subscriptions/${subscriptionName}`;
584
- return this.withGoogleIdentityToken({
585
- workflowId: workflowTriggerId.split('/')[0],
586
- triggerId: workflowTriggerId.split('/')[1],
587
- })(async (token) => {
588
- const response = await fetch(this.runtimeUrl + `/executeWorkflow/${workflowTriggerId}`, {
589
- method: 'POST',
590
- headers: {
591
- 'X-Buildship-Trigger-Authorization': `Bearer ${token}`,
592
- Authorization: `Bearer ${token}`,
593
- 'Content-Type': 'application/json'
594
- },
595
- body: JSON.stringify({
596
- ...rnConfig,
597
- subscriptionName: subscriptionQualifiedName,
598
- operation: 'upsert',
599
- })
600
- });
601
- if (!response.ok) {
602
- throw new Error('Failed to register the main subscription with respectful nudge');
603
- }
604
- return true;
605
- });
606
- }
607
- getRequestSource(request) {
608
- const reqIsRespectfulNudge = (0, utils_1.isRespectfulNudge)(request.headers);
609
- if (reqIsRespectfulNudge) {
610
- return 'respectful-nudge';
611
- }
612
- const reqIsPubSub = (0, utils_1.isPubSubRequest)(request.headers);
613
- if (reqIsPubSub) {
614
- return 'pubsub';
615
- }
616
- const reqIsScheduler = (0, utils_1.isCronMessage)(request.headers);
617
- if (reqIsScheduler) {
618
- return 'scheduler';
619
- }
620
- const reqIsCloudTask = (0, utils_1.isCloudTask)(request.headers);
621
- if (reqIsCloudTask) {
622
- return 'cloud-task';
623
- }
624
- return 'direct';
625
- }
626
- async validateAuthorizationHeader(request) {
627
- const authHeader = request.headers.authorization;
628
- if (!authHeader || typeof authHeader !== 'string') {
629
- throw new Error('Missing Authorization Header');
630
- }
631
- const allowedServiceAccounts = this.resolveEnvName(ENV_NAME_CONTAINING_SERVICE_ACCOUNTS).split(";").map(x => {
632
- const [serviceAccount, ...flags] = x.trim().split(",").map(y => y.trim());
633
- return {
634
- flags,
635
- serviceAccount
636
- };
637
- });
638
- const serviceAccount = await this.checkGoogleIdentiyToken(authHeader.slice('Bearer '.length), undefined, allowedServiceAccounts.map(x => x.serviceAccount));
639
- if (!serviceAccount) {
640
- throw new Error('Invalid Authorization Header');
641
- }
642
- const flags = allowedServiceAccounts.find(x => x.serviceAccount === serviceAccount)?.flags || [];
643
- if (!flags.includes('env-' + this.envName)) {
644
- throw new Error('No permissions to access the environment ' + this.envName);
645
- }
646
- return {
647
- serviceAccount,
648
- flags: flags
649
- };
650
- }
651
- async decodeRequests(request, nodeReq) {
652
- const requestSource = this.getRequestSource(request);
653
- let requestBody = null;
654
- const rawRequestBody = null;
655
- if (requestSource === 'pubsub' || requestSource === 'respectful-nudge' || request.headers['content-type'] === 'application/json') {
656
- const rawRequestBody = co_body_1.default.text(nodeReq, {
657
- limit: '2mb'
658
- });
659
- requestBody = await (rawRequestBody.then(x => JSON.parse(x || 'null')).catch(err => {
660
- throw new Error('Could not parse the request of the body. Body provided: ' + requestBody + '. Error message: ' + err.message);
661
- }));
662
- }
663
- const receivedArrayOfRequests = Array.isArray(requestBody);
664
- const requestBodies = receivedArrayOfRequests ? requestBody : [requestBody];
665
- const messages = [];
666
- for (let i = 0; i < requestBodies.length; i++) {
667
- const requestBody = requestBodies[i];
668
- let messageBody;
669
- let messageBodyRaw = null;
670
- if (typeof requestBody?.message?.data === 'string' && Buffer.from(requestBody.message.data, "base64").toString('base64') === requestBody.message.data) {
671
- messageBodyRaw = Buffer.from(requestBody.message.data, "base64").toString('utf-8');
672
- messageBody = await (Promise.resolve(messageBodyRaw).then(x => JSON.parse(x)).catch((_) => ({
673
- error: 'Could not parse the message body. Original body: ' + messageBodyRaw + ' . Error: ' + _.message,
674
- })));
675
- }
676
- else if (typeof requestBody?.message?.data === 'object' && typeof requestBody.subscription === 'string') {
677
- messageBodyRaw = JSON.stringify(requestBody.message.data);
678
- messageBody = requestBody.message.data;
679
- }
680
- else {
681
- messageBody = requestBody;
682
- messageBodyRaw = receivedArrayOfRequests ? rawRequestBody : JSON.stringify(requestBody);
683
- }
684
- const message = {
685
- requestSource: requestSource,
686
- messageId: requestBody?.message?.messageId || undefined,
687
- sourceSystem: requestBody?.message?.attributes?.source_system || 'unknown',
688
- targetSystem: requestBody?.message?.attributes?.target_system || 'unknown',
689
- buildshipId: requestBody?.message?.attributes?.buildship_id || 'unknown',
690
- publishTime: (0, utils_1.parseDateOrDefault)(requestBody?.message?.publish_time),
691
- body: messageBody,
692
- bodyTxt: messageBodyRaw,
693
- exportableToBigQuery: !!requestBody?.message?.attributes?.bigquery,
694
- extraAttributes: Object.assign({}, request.query, (0, lodash_omit_1.default)(requestBody?.message?.attributes || {}, ['source_system', 'target_system', 'buildship_id', 'bigquery'])),
695
- subscriptionName: (requestBody?.subscription?.split('/')?.pop() || request.query.subscriptionName)?.replace(/^rn\./, ''),
696
- };
697
- messages.push(message);
698
- }
699
- return messages;
700
- }
701
- async decodeRequest(request, nodeReq) {
702
- const requests = await this.decodeRequests(request, nodeReq);
703
- if (requests.length > 0) {
704
- this.logging.error('Received multiple requests in the same batch. This is not supported. Picking the first message from the request');
705
- }
706
- return requests[0];
707
- }
708
- async fetchLogEntries(triggerId, retries = 3, delay = 1000, filterOverride = null) {
709
- const getAccessToken = async () => {
710
- const response = await fetch("http://metadata/computeMetadata/v1/instance/service-accounts/default/token", {
711
- headers: { "Metadata-Flavor": "Google" },
712
- });
713
- if (!response.ok) {
714
- throw new Error(`Failed to obtain access token: ${response.statusText}`);
715
- }
716
- const data = await response.json();
717
- return {
718
- accessToken: data.access_token,
719
- expiresAt: new Date(new Date().getTime() + ((data.expires_in * 1000)) - ((data.expires_in * 1000) * 9 / 10))
720
- };
721
- };
722
- const projectId = process.env.GCLOUD_PROJECT;
723
- const accessToken = (await getAccessToken()).accessToken;
724
- let filter = `logName="projects/${projectId}/logs/buildship-node-io" AND jsonPayload.nId="${triggerId}"`;
725
- if (filterOverride) {
726
- filter = filterOverride;
727
- }
728
- const requestBody = {
729
- resourceNames: [`projects/${projectId}`],
730
- filter: filter,
731
- pageSize: 1,
732
- orderBy: "timestamp desc",
733
- };
734
- for (let attempt = 1; attempt <= retries; attempt++) {
735
- try {
736
- const response = await fetch("https://logging.googleapis.com/v2/entries:list", {
737
- method: "POST",
738
- headers: {
739
- Authorization: `Bearer ${accessToken}`,
740
- "Content-Type": "application/json",
741
- },
742
- body: JSON.stringify(requestBody),
743
- });
744
- if (!response.ok) {
745
- const errorText = await response.text();
746
- throw new Error(`Error fetching log entries: ${response.statusText} - ${errorText}`);
747
- }
748
- const data = await response.json();
749
- const entries = data.entries || [];
750
- if (entries.length > 0) {
751
- return entries;
752
- }
753
- if (attempt < retries) {
754
- await new Promise((resolve) => setTimeout(resolve, delay));
755
- }
756
- }
757
- catch (error) {
758
- console.error(`Attempt ${attempt} failed due to an error:`, error);
759
- if (attempt < retries) {
760
- await new Promise((resolve) => setTimeout(resolve, delay));
761
- }
762
- else {
763
- throw new Error(`Failed to get data after ${retries} attempts.`);
764
- }
765
- }
766
- }
767
- throw new Error("No data found. Send a request to the API and try again.");
768
- }
769
- ;
770
- getPubSubHelper(PubSubClass) {
771
- const pubSubProjectId = this.resolveEnvName(ENV_NAME_PUBSUB_PROJECT_ID);
772
- if (!pubSubProjectId) {
773
- throw new Error('PubSub Project ID is not set. Please set the ' + ENV_NAME_PUBSUB_PROJECT_ID + ' environment variable.');
774
- }
775
- const serviceAccount = this.resolveEnvName(ENV_NAME_PUBSUB_SERVICE_ACCOUNT);
776
- if (!serviceAccount) {
777
- throw new Error('PubSub Service Account is not set. Please set the ' + ENV_NAME_PUBSUB_SERVICE_ACCOUNT + ' environment variable.');
778
- }
779
- const pubSub = global.HUSH_PUBSUB_INSTANCE || new PubSubClass({
780
- projectId: pubSubProjectId
781
- });
782
- global.HUSH_PUBSUB_INSTANCE = pubSub;
783
- this.logging.log('getPubSubHelper', {
784
- serviceAccountEmail: serviceAccount,
785
- });
786
- return new pubsub_1.default(this, {
787
- serviceAccountEmail: serviceAccount
788
- }, pubSub);
789
- }
790
- static LOCK_NOT_ACQUIRED_ERROR = Symbol('Lock not acquired');
791
- async withLock(key, maxWaitTimeMs = 200, fn) {
792
- let result = EnvEngine.LOCK_NOT_ACQUIRED_ERROR;
793
- if (await this.acquireLock(key, maxWaitTimeMs)) {
794
- try {
795
- result = await fn();
796
- }
797
- catch (err) {
798
- await this.releaseLock(key);
799
- throw err;
800
- }
801
- await this.releaseLock(key);
802
- }
803
- return result;
804
- }
805
- async acquireLock(key, maxWaitTimeMs = 200) {
806
- if (!this._lockRateLimiter) {
807
- return true;
808
- }
809
- try {
810
- await this._lockRateLimiter.consume(key);
811
- }
812
- catch (err) {
813
- if (err instanceof Error) {
814
- throw err;
815
- }
816
- if (maxWaitTimeMs > 0) {
817
- await new Promise((resolve) => setTimeout(resolve, maxWaitTimeMs));
818
- return this.acquireLock(key, 0);
819
- }
820
- else {
821
- return false;
822
- }
823
- }
824
- return true;
825
- }
826
- async releaseLock(key) {
827
- if (this._lockRateLimiter) {
828
- await this._lockRateLimiter.reward(key, 1);
829
- }
830
- return true;
831
- }
832
- async getLockRateLimiter() {
833
- const redisClient = await (0, redisClient_1.getConnectedRedisClient)(this.systemEnvName);
834
- if (!redisClient) {
835
- return null;
836
- }
837
- if (!this._lockRateLimiter) {
838
- const lockMemory = new rate_limiter_flexible_1.RateLimiterMemory({
839
- points: 1,
840
- duration: 60 * 3,
841
- });
842
- const lockRedis = new rate_limiter_flexible_1.RateLimiterRedis({
843
- storeClient: redisClient,
844
- points: 1,
845
- duration: 60 * 3,
846
- insuranceLimiter: lockMemory,
847
- });
848
- this._lockRateLimiter = lockRedis;
849
- }
850
- return this._lockRateLimiter;
851
- }
852
- }
853
- class AES256GCM {
854
- normalizedKey;
855
- constructor(key) {
856
- this.normalizedKey = crypto
857
- .createHash("sha256")
858
- .update(key)
859
- .digest()
860
- .slice(0, 32);
861
- }
862
- pad(payload) {
863
- const padLength = 8 - (payload.length % 8);
864
- return Buffer.concat([payload, Buffer.alloc(padLength, padLength)]);
865
- }
866
- getNormalizedKey() {
867
- return this.getNormalizedKey;
868
- }
869
- encrypt(payload) {
870
- const normalizedWrappingKey = this.normalizedKey;
871
- const paddedPayload = this.pad(Buffer.from(payload));
872
- const iv = crypto.randomBytes(12);
873
- const cipher = crypto.createCipheriv("aes-256-gcm", normalizedWrappingKey, iv);
874
- const encryptedPayload = Buffer.concat([
875
- cipher.update(paddedPayload),
876
- cipher.final(),
877
- ]);
878
- const authTag = cipher.getAuthTag();
879
- return (encryptedPayload.toString("base64") +
880
- "." +
881
- iv.toString("base64") +
882
- "." +
883
- authTag.toString("base64"));
884
- }
885
- decrypt(payload) {
886
- const [encryptedKey64, iv64, authTag64] = payload.split(".");
887
- const encryptedPayload = Buffer.from(encryptedKey64, "base64");
888
- const iv = Buffer.from(iv64, "base64");
889
- const authTag = Buffer.from(authTag64, "base64");
890
- const decipher = crypto.createDecipheriv("aes-256-gcm", this.normalizedKey, iv);
891
- decipher.setAuthTag(authTag);
892
- const paddedKey = Buffer.concat([
893
- decipher.update(encryptedPayload),
894
- decipher.final(),
895
- ]);
896
- const padLength = paddedKey[paddedKey.length - 1];
897
- return paddedKey.slice(0, -padLength).toString();
898
- }
899
- }
900
- exports.default = EnvEngine;