@budibase/server 2.6.19-alpha.4 → 2.6.19-alpha.40

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 (405) hide show
  1. package/.dockerignore +7 -6
  2. package/Dockerfile +16 -8
  3. package/builder/assets/index.49c9e712.css +6 -0
  4. package/builder/assets/index.e3ce193c.js +1870 -0
  5. package/builder/index.html +2 -2
  6. package/client/manifest.json +5229 -0
  7. package/dist/automation.js +32476 -0
  8. package/dist/automation.js.map +7 -0
  9. package/dist/index.js +44907 -13
  10. package/dist/index.js.map +7 -0
  11. package/dist/query.js +24400 -0
  12. package/dist/query.js.map +7 -0
  13. package/jest.config.ts +3 -0
  14. package/nodemon.json +1 -1
  15. package/package.json +32 -13
  16. package/pm2.config.js +1 -1
  17. package/scripts/build.js +48 -0
  18. package/src/api/controllers/application.ts +21 -22
  19. package/src/api/controllers/automation.ts +37 -9
  20. package/src/api/controllers/datasource.ts +4 -0
  21. package/src/api/controllers/deploy/index.ts +1 -0
  22. package/src/api/controllers/row/index.ts +15 -22
  23. package/src/api/controllers/row/internal.ts +1 -1
  24. package/src/api/controllers/row/utils.ts +12 -0
  25. package/src/api/controllers/static/index.ts +3 -3
  26. package/src/api/controllers/table/index.ts +3 -0
  27. package/src/api/controllers/table/internal.ts +2 -6
  28. package/src/api/controllers/table/utils.ts +32 -1
  29. package/src/api/controllers/view/index.ts +5 -5
  30. package/src/api/controllers/webhook.ts +33 -9
  31. package/src/api/routes/application.ts +5 -0
  32. package/src/api/routes/automation.ts +0 -1
  33. package/src/api/routes/static.ts +3 -1
  34. package/src/api/routes/tests/{automation.spec.js → automation.spec.ts} +106 -31
  35. package/src/api/routes/tests/{webhook.spec.js → webhook.spec.ts} +33 -11
  36. package/src/app.ts +0 -1
  37. package/src/automations/actions.ts +8 -0
  38. package/src/automations/logging/index.ts +21 -0
  39. package/src/automations/steps/bash.ts +4 -0
  40. package/src/automations/steps/collect.ts +58 -0
  41. package/src/automations/steps/createRow.ts +4 -0
  42. package/src/automations/steps/delay.ts +1 -0
  43. package/src/automations/steps/deleteRow.ts +4 -0
  44. package/src/automations/steps/discord.ts +4 -0
  45. package/src/automations/steps/executeQuery.ts +4 -0
  46. package/src/automations/steps/executeScript.ts +4 -0
  47. package/src/automations/steps/filter.ts +1 -0
  48. package/src/automations/steps/loop.ts +1 -0
  49. package/src/automations/steps/make.ts +4 -0
  50. package/src/automations/steps/openai.ts +106 -0
  51. package/src/automations/steps/outgoingWebhook.ts +4 -0
  52. package/src/automations/steps/queryRows.ts +4 -0
  53. package/src/automations/steps/sendSmtpEmail.ts +4 -0
  54. package/src/automations/steps/serverLog.ts +4 -0
  55. package/src/automations/steps/slack.ts +4 -0
  56. package/src/automations/steps/updateRow.ts +4 -0
  57. package/src/automations/steps/zapier.ts +4 -0
  58. package/src/automations/tests/openai.spec.ts +86 -0
  59. package/src/automations/triggers.ts +3 -2
  60. package/src/constants/index.ts +17 -16
  61. package/src/db/inMemoryView.ts +1 -0
  62. package/src/environment.ts +3 -0
  63. package/src/integrations/airtable.ts +3 -1
  64. package/src/integrations/arangodb.ts +3 -1
  65. package/src/integrations/base/sqlTable.ts +0 -1
  66. package/src/integrations/couchdb.ts +3 -1
  67. package/src/integrations/dynamodb.ts +3 -1
  68. package/src/integrations/elasticsearch.ts +3 -1
  69. package/src/integrations/firebase.ts +3 -1
  70. package/src/integrations/googlesheets.ts +4 -4
  71. package/src/integrations/microsoftSqlServer.ts +4 -4
  72. package/src/integrations/mongodb.ts +3 -1
  73. package/src/integrations/mysql.ts +4 -4
  74. package/src/integrations/oracle.ts +4 -4
  75. package/src/integrations/postgres.ts +4 -4
  76. package/src/integrations/redis.ts +3 -1
  77. package/src/integrations/s3.ts +3 -1
  78. package/src/integrations/snowflake.ts +3 -1
  79. package/src/middleware/builder.ts +26 -18
  80. package/src/sdk/app/automations/index.ts +2 -0
  81. package/src/sdk/app/automations/utils.ts +7 -0
  82. package/src/startup.ts +2 -0
  83. package/src/tests/utilities/TestConfiguration.ts +4 -2
  84. package/src/tests/utilities/structures.ts +42 -0
  85. package/src/threads/automation.ts +82 -22
  86. package/src/threads/index.ts +9 -3
  87. package/src/threads/utils.ts +2 -0
  88. package/src/utilities/fileSystem/app.ts +14 -4
  89. package/src/utilities/fileSystem/clientLibrary.ts +8 -3
  90. package/src/utilities/fileSystem/filesystem.ts +3 -1
  91. package/src/utilities/redis.ts +18 -1
  92. package/src/utilities/rowProcessor/map.ts +1 -1
  93. package/src/websockets/builder.ts +74 -0
  94. package/src/websockets/client.ts +2 -2
  95. package/src/websockets/grid.ts +40 -44
  96. package/src/websockets/index.ts +5 -2
  97. package/src/websockets/websocket.ts +198 -7
  98. package/tsconfig.build.json +9 -1
  99. package/tsconfig.json +1 -14
  100. package/builder/assets/index.07382a47.css +0 -6
  101. package/builder/assets/index.3d5c50fb.js +0 -1786
  102. package/dist/api/controllers/analytics.js +0 -46
  103. package/dist/api/controllers/apikeys.js +0 -72
  104. package/dist/api/controllers/application.js +0 -574
  105. package/dist/api/controllers/auth.js +0 -80
  106. package/dist/api/controllers/automation.js +0 -303
  107. package/dist/api/controllers/backup.js +0 -37
  108. package/dist/api/controllers/component.js +0 -59
  109. package/dist/api/controllers/datasource.js +0 -352
  110. package/dist/api/controllers/deploy/Deployment.js +0 -53
  111. package/dist/api/controllers/deploy/index.js +0 -198
  112. package/dist/api/controllers/dev.js +0 -146
  113. package/dist/api/controllers/integration.js +0 -28
  114. package/dist/api/controllers/layout.js +0 -49
  115. package/dist/api/controllers/metadata.js +0 -63
  116. package/dist/api/controllers/migrations.js +0 -29
  117. package/dist/api/controllers/ops.js +0 -40
  118. package/dist/api/controllers/permission.js +0 -162
  119. package/dist/api/controllers/plugin/file.js +0 -24
  120. package/dist/api/controllers/plugin/github.js +0 -69
  121. package/dist/api/controllers/plugin/index.js +0 -112
  122. package/dist/api/controllers/plugin/npm.js +0 -58
  123. package/dist/api/controllers/plugin/uploaders.js +0 -11
  124. package/dist/api/controllers/plugin/url.js +0 -24
  125. package/dist/api/controllers/plugin/utils.js +0 -27
  126. package/dist/api/controllers/public/applications.js +0 -146
  127. package/dist/api/controllers/public/mapping/applications.js +0 -29
  128. package/dist/api/controllers/public/mapping/index.js +0 -11
  129. package/dist/api/controllers/public/mapping/queries.js +0 -36
  130. package/dist/api/controllers/public/mapping/rows.js +0 -24
  131. package/dist/api/controllers/public/mapping/tables.js +0 -23
  132. package/dist/api/controllers/public/mapping/types.js +0 -2
  133. package/dist/api/controllers/public/mapping/users.js +0 -29
  134. package/dist/api/controllers/public/metrics.js +0 -113
  135. package/dist/api/controllers/public/queries.js +0 -58
  136. package/dist/api/controllers/public/rows.js +0 -120
  137. package/dist/api/controllers/public/tables.js +0 -95
  138. package/dist/api/controllers/public/users.js +0 -93
  139. package/dist/api/controllers/public/utils.js +0 -56
  140. package/dist/api/controllers/query/import/index.js +0 -87
  141. package/dist/api/controllers/query/import/sources/base/index.js +0 -75
  142. package/dist/api/controllers/query/import/sources/base/openapi.js +0 -42
  143. package/dist/api/controllers/query/import/sources/curl.js +0 -99
  144. package/dist/api/controllers/query/import/sources/openapi2.js +0 -145
  145. package/dist/api/controllers/query/import/sources/openapi3.js +0 -177
  146. package/dist/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json +0 -253
  147. package/dist/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json +0 -1054
  148. package/dist/api/controllers/query/import/sources/tests/openapi3/data/crud/crud.json +0 -253
  149. package/dist/api/controllers/query/import/sources/tests/openapi3/data/petstore/petstore.json +0 -1225
  150. package/dist/api/controllers/query/index.js +0 -299
  151. package/dist/api/controllers/query/validation.js +0 -53
  152. package/dist/api/controllers/role.js +0 -109
  153. package/dist/api/controllers/routing.js +0 -105
  154. package/dist/api/controllers/row/ExternalRequest.js +0 -683
  155. package/dist/api/controllers/row/external.js +0 -339
  156. package/dist/api/controllers/row/index.js +0 -203
  157. package/dist/api/controllers/row/internal.js +0 -509
  158. package/dist/api/controllers/row/internalSearch.js +0 -28
  159. package/dist/api/controllers/row/staticFormula.js +0 -165
  160. package/dist/api/controllers/row/utils.js +0 -183
  161. package/dist/api/controllers/screen.js +0 -110
  162. package/dist/api/controllers/script.js +0 -30
  163. package/dist/api/controllers/static/index.js +0 -268
  164. package/dist/api/controllers/table/bulkFormula.js +0 -173
  165. package/dist/api/controllers/table/external.js +0 -279
  166. package/dist/api/controllers/table/index.js +0 -179
  167. package/dist/api/controllers/table/internal.js +0 -197
  168. package/dist/api/controllers/table/utils.js +0 -379
  169. package/dist/api/controllers/templates.js +0 -56
  170. package/dist/api/controllers/user.js +0 -124
  171. package/dist/api/controllers/view/exporters.js +0 -46
  172. package/dist/api/controllers/view/index.js +0 -193
  173. package/dist/api/controllers/view/utils.js +0 -177
  174. package/dist/api/controllers/view/viewBuilder.js +0 -158
  175. package/dist/api/controllers/webhook.js +0 -134
  176. package/dist/api/index.js +0 -55
  177. package/dist/api/routes/analytics.js +0 -34
  178. package/dist/api/routes/apikeys.js +0 -37
  179. package/dist/api/routes/application.js +0 -48
  180. package/dist/api/routes/auth.js +0 -33
  181. package/dist/api/routes/automation.js +0 -50
  182. package/dist/api/routes/backup.js +0 -35
  183. package/dist/api/routes/component.js +0 -35
  184. package/dist/api/routes/datasource.js +0 -45
  185. package/dist/api/routes/deploy.js +0 -37
  186. package/dist/api/routes/dev.js +0 -49
  187. package/dist/api/routes/index.js +0 -75
  188. package/dist/api/routes/integration.js +0 -37
  189. package/dist/api/routes/layout.js +0 -37
  190. package/dist/api/routes/metadata.js +0 -40
  191. package/dist/api/routes/migrations.js +0 -36
  192. package/dist/api/routes/ops.js +0 -52
  193. package/dist/api/routes/permission.js +0 -44
  194. package/dist/api/routes/plugin.js +0 -39
  195. package/dist/api/routes/public/applications.js +0 -174
  196. package/dist/api/routes/public/index.js +0 -140
  197. package/dist/api/routes/public/metrics.js +0 -30
  198. package/dist/api/routes/public/middleware/mapper.js +0 -97
  199. package/dist/api/routes/public/queries.js +0 -72
  200. package/dist/api/routes/public/rows.js +0 -158
  201. package/dist/api/routes/public/tables.js +0 -152
  202. package/dist/api/routes/public/users.js +0 -135
  203. package/dist/api/routes/public/utils/Endpoint.js +0 -36
  204. package/dist/api/routes/query.js +0 -47
  205. package/dist/api/routes/role.js +0 -40
  206. package/dist/api/routes/routing.js +0 -39
  207. package/dist/api/routes/row.js +0 -239
  208. package/dist/api/routes/screen.js +0 -39
  209. package/dist/api/routes/script.js +0 -35
  210. package/dist/api/routes/static.js +0 -80
  211. package/dist/api/routes/table.js +0 -163
  212. package/dist/api/routes/templates.js +0 -37
  213. package/dist/api/routes/user.js +0 -43
  214. package/dist/api/routes/utils/validators.js +0 -238
  215. package/dist/api/routes/view.js +0 -42
  216. package/dist/api/routes/webhook.js +0 -43
  217. package/dist/app.js +0 -132
  218. package/dist/automations/actions.js +0 -137
  219. package/dist/automations/automationUtils.js +0 -173
  220. package/dist/automations/bullboard.js +0 -71
  221. package/dist/automations/index.js +0 -43
  222. package/dist/automations/logging/index.js +0 -53
  223. package/dist/automations/steps/bash.js +0 -111
  224. package/dist/automations/steps/createRow.js +0 -108
  225. package/dist/automations/steps/delay.js +0 -53
  226. package/dist/automations/steps/deleteRow.js +0 -96
  227. package/dist/automations/steps/discord.js +0 -116
  228. package/dist/automations/steps/executeQuery.js +0 -134
  229. package/dist/automations/steps/executeScript.js +0 -106
  230. package/dist/automations/steps/filter.js +0 -112
  231. package/dist/automations/steps/loop.js +0 -54
  232. package/dist/automations/steps/make.js +0 -134
  233. package/dist/automations/steps/outgoingWebhook.js +0 -166
  234. package/dist/automations/steps/queryRows.js +0 -216
  235. package/dist/automations/steps/sendSmtpEmail.js +0 -115
  236. package/dist/automations/steps/serverLog.js +0 -65
  237. package/dist/automations/steps/slack.js +0 -98
  238. package/dist/automations/steps/updateRow.js +0 -144
  239. package/dist/automations/steps/utils.js +0 -56
  240. package/dist/automations/steps/zapier.js +0 -130
  241. package/dist/automations/triggerInfo/app.js +0 -36
  242. package/dist/automations/triggerInfo/cron.js +0 -35
  243. package/dist/automations/triggerInfo/index.js +0 -40
  244. package/dist/automations/triggerInfo/rowDeleted.js +0 -36
  245. package/dist/automations/triggerInfo/rowSaved.js +0 -44
  246. package/dist/automations/triggerInfo/rowUpdated.js +0 -44
  247. package/dist/automations/triggerInfo/webhook.js +0 -40
  248. package/dist/automations/triggers.js +0 -181
  249. package/dist/automations/utils.js +0 -275
  250. package/dist/constants/definitions.js +0 -2
  251. package/dist/constants/index.js +0 -181
  252. package/dist/constants/layouts.js +0 -148
  253. package/dist/constants/screens.js +0 -51
  254. package/dist/db/defaultData/datasource_bb_default.js +0 -574
  255. package/dist/db/defaultData/employeeImport.js +0 -155
  256. package/dist/db/defaultData/expensesImport.js +0 -117
  257. package/dist/db/defaultData/inventoryImport.js +0 -109
  258. package/dist/db/defaultData/jobsImport.js +0 -152
  259. package/dist/db/dynamoClient.js +0 -124
  260. package/dist/db/inMemoryView.js +0 -62
  261. package/dist/db/index.js +0 -43
  262. package/dist/db/linkedRows/LinkController.js +0 -392
  263. package/dist/db/linkedRows/LinkDocument.js +0 -33
  264. package/dist/db/linkedRows/index.js +0 -206
  265. package/dist/db/linkedRows/linkUtils.js +0 -131
  266. package/dist/db/newid.js +0 -7
  267. package/dist/db/utils.js +0 -248
  268. package/dist/db/views/staticViews.js +0 -144
  269. package/dist/ddApm.js +0 -11
  270. package/dist/definitions/automations.js +0 -8
  271. package/dist/definitions/common.js +0 -2
  272. package/dist/definitions/datasource.js +0 -7
  273. package/dist/definitions/openapi.js +0 -6
  274. package/dist/environment.js +0 -109
  275. package/dist/events/AutomationEmitter.js +0 -53
  276. package/dist/events/BudibaseEmitter.js +0 -25
  277. package/dist/events/docUpdates/index.js +0 -17
  278. package/dist/events/docUpdates/processors.js +0 -18
  279. package/dist/events/docUpdates/syncUsers.js +0 -49
  280. package/dist/events/index.js +0 -11
  281. package/dist/events/utils.js +0 -43
  282. package/dist/integrations/airtable.js +0 -173
  283. package/dist/integrations/arangodb.js +0 -119
  284. package/dist/integrations/base/query.js +0 -32
  285. package/dist/integrations/base/sql.js +0 -600
  286. package/dist/integrations/base/sqlTable.js +0 -167
  287. package/dist/integrations/base/types.js +0 -2
  288. package/dist/integrations/couchdb.js +0 -140
  289. package/dist/integrations/dynamodb.js +0 -210
  290. package/dist/integrations/elasticsearch.js +0 -201
  291. package/dist/integrations/firebase.js +0 -189
  292. package/dist/integrations/googlesheets.js +0 -493
  293. package/dist/integrations/index.js +0 -138
  294. package/dist/integrations/microsoftSqlServer.js +0 -308
  295. package/dist/integrations/mongodb.js +0 -630
  296. package/dist/integrations/mysql.js +0 -291
  297. package/dist/integrations/oracle.js +0 -415
  298. package/dist/integrations/postgres.js +0 -335
  299. package/dist/integrations/queries/sql.js +0 -84
  300. package/dist/integrations/redis.js +0 -187
  301. package/dist/integrations/rest.js +0 -400
  302. package/dist/integrations/s3.js +0 -256
  303. package/dist/integrations/snowflake.js +0 -114
  304. package/dist/integrations/utils.js +0 -295
  305. package/dist/middleware/appInfo.js +0 -22
  306. package/dist/middleware/authorized.js +0 -112
  307. package/dist/middleware/builder.js +0 -93
  308. package/dist/middleware/currentapp.js +0 -103
  309. package/dist/middleware/joi-validator.js +0 -43
  310. package/dist/middleware/publicApi.js +0 -25
  311. package/dist/middleware/resourceId.js +0 -59
  312. package/dist/middleware/selfhost.js +0 -24
  313. package/dist/middleware/utils.js +0 -8
  314. package/dist/migrations/functions/appUrls.js +0 -42
  315. package/dist/migrations/functions/backfill/app/automations.js +0 -31
  316. package/dist/migrations/functions/backfill/app/datasources.js +0 -28
  317. package/dist/migrations/functions/backfill/app/layouts.js +0 -33
  318. package/dist/migrations/functions/backfill/app/queries.js +0 -49
  319. package/dist/migrations/functions/backfill/app/roles.js +0 -28
  320. package/dist/migrations/functions/backfill/app/screens.js +0 -28
  321. package/dist/migrations/functions/backfill/app/tables.js +0 -37
  322. package/dist/migrations/functions/backfill/app.js +0 -176
  323. package/dist/migrations/functions/backfill/global/configs.js +0 -67
  324. package/dist/migrations/functions/backfill/global/quotas.js +0 -60
  325. package/dist/migrations/functions/backfill/global/users.js +0 -50
  326. package/dist/migrations/functions/backfill/global.js +0 -205
  327. package/dist/migrations/functions/backfill/index.js +0 -32
  328. package/dist/migrations/functions/backfill/installation.js +0 -80
  329. package/dist/migrations/functions/syncQuotas.js +0 -52
  330. package/dist/migrations/functions/tableSettings.js +0 -130
  331. package/dist/migrations/functions/usageQuotas/index.js +0 -16
  332. package/dist/migrations/functions/usageQuotas/syncApps.js +0 -24
  333. package/dist/migrations/functions/usageQuotas/syncPlugins.js +0 -23
  334. package/dist/migrations/functions/usageQuotas/syncRows.js +0 -33
  335. package/dist/migrations/functions/usageQuotas/syncUsers.js +0 -21
  336. package/dist/migrations/functions/userEmailViewCasing.js +0 -24
  337. package/dist/migrations/index.js +0 -111
  338. package/dist/migrations/tests/helpers.js +0 -72
  339. package/dist/migrations/tests/structures.js +0 -37
  340. package/dist/sdk/app/applications/index.js +0 -28
  341. package/dist/sdk/app/applications/sync.js +0 -164
  342. package/dist/sdk/app/applications/utils.js +0 -21
  343. package/dist/sdk/app/automations/index.js +0 -29
  344. package/dist/sdk/app/automations/webhook.js +0 -54
  345. package/dist/sdk/app/backups/constants.js +0 -6
  346. package/dist/sdk/app/backups/exports.js +0 -160
  347. package/dist/sdk/app/backups/imports.js +0 -170
  348. package/dist/sdk/app/backups/index.js +0 -29
  349. package/dist/sdk/app/backups/statistics.js +0 -73
  350. package/dist/sdk/app/datasources/datasources.js +0 -173
  351. package/dist/sdk/app/datasources/index.js +0 -27
  352. package/dist/sdk/app/queries/index.js +0 -27
  353. package/dist/sdk/app/queries/queries.js +0 -60
  354. package/dist/sdk/app/rows/attachments.js +0 -61
  355. package/dist/sdk/app/rows/index.js +0 -28
  356. package/dist/sdk/app/rows/rows.js +0 -30
  357. package/dist/sdk/app/tables/index.js +0 -65
  358. package/dist/sdk/index.js +0 -27
  359. package/dist/sdk/plugins/index.js +0 -27
  360. package/dist/sdk/plugins/plugins.js +0 -53
  361. package/dist/sdk/users/index.js +0 -27
  362. package/dist/sdk/users/utils.js +0 -87
  363. package/dist/sdk/utils/index.js +0 -29
  364. package/dist/startup.js +0 -158
  365. package/dist/threads/automation.js +0 -450
  366. package/dist/threads/definitions.js +0 -2
  367. package/dist/threads/index.js +0 -140
  368. package/dist/threads/query.js +0 -265
  369. package/dist/threads/utils.js +0 -120
  370. package/dist/tsconfig.build.tsbuildinfo +0 -1
  371. package/dist/utilities/appDirectoryTemplate/package.json +0 -10
  372. package/dist/utilities/budibaseDir.js +0 -5
  373. package/dist/utilities/centralPath.js +0 -27
  374. package/dist/utilities/csv.js +0 -33
  375. package/dist/utilities/fileSystem/app.js +0 -88
  376. package/dist/utilities/fileSystem/clientLibrary.js +0 -138
  377. package/dist/utilities/fileSystem/filesystem.js +0 -180
  378. package/dist/utilities/fileSystem/index.js +0 -21
  379. package/dist/utilities/fileSystem/plugin.js +0 -76
  380. package/dist/utilities/fileSystem/processor.js +0 -34
  381. package/dist/utilities/fileSystem/template.js +0 -47
  382. package/dist/utilities/global.js +0 -149
  383. package/dist/utilities/index.js +0 -143
  384. package/dist/utilities/redis.js +0 -117
  385. package/dist/utilities/retry.js +0 -30
  386. package/dist/utilities/routing/index.js +0 -39
  387. package/dist/utilities/rowProcessor/index.js +0 -282
  388. package/dist/utilities/rowProcessor/map.js +0 -116
  389. package/dist/utilities/rowProcessor/utils.js +0 -87
  390. package/dist/utilities/schema.js +0 -112
  391. package/dist/utilities/scriptRunner.js +0 -26
  392. package/dist/utilities/security.js +0 -57
  393. package/dist/utilities/statusCodes.js +0 -9
  394. package/dist/utilities/usageQuota/rows.js +0 -88
  395. package/dist/utilities/usageQuota/usageQuoteReset.js +0 -16
  396. package/dist/utilities/users.js +0 -57
  397. package/dist/utilities/workerRequests.js +0 -171
  398. package/dist/watch.js +0 -53
  399. package/dist/websockets/client.js +0 -14
  400. package/dist/websockets/grid.js +0 -60
  401. package/dist/websockets/index.js +0 -17
  402. package/dist/websockets/websocket.js +0 -78
  403. /package/dist/{api/controllers/static/templates/BudibaseApp.svelte → BudibaseApp-Y5NZEDTC.svelte} +0 -0
  404. /package/dist/{api/controllers/static/templates/app.hbs → app.hbs} +0 -0
  405. /package/dist/{api/controllers/static/templates/preview.hbs → preview.hbs} +0 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../types/src/sdk/automations/index.ts", "../../types/src/sdk/hosting.ts", "../../types/src/sdk/context.ts", "../../types/src/sdk/events/app.ts", "../../types/src/sdk/events/auth.ts", "../../types/src/sdk/events/automation.ts", "../../types/src/sdk/events/email.ts", "../../types/src/sdk/events/datasource.ts", "../../types/src/sdk/events/event.ts", "../../types/src/sdk/events/layout.ts", "../../types/src/sdk/events/license.ts", "../../types/src/sdk/events/version.ts", "../../types/src/sdk/events/query.ts", "../../types/src/sdk/events/role.ts", "../../types/src/sdk/events/rows.ts", "../../types/src/sdk/events/screen.ts", "../../types/src/sdk/events/serve.ts", "../../types/src/sdk/events/table.ts", "../../types/src/sdk/events/user.ts", "../../types/src/sdk/events/view.ts", "../../types/src/sdk/events/account.ts", "../../types/src/sdk/events/backfill.ts", "../../types/src/sdk/events/identification.ts", "../../types/src/sdk/events/userGroup.ts", "../../types/src/sdk/events/plugin.ts", "../../types/src/sdk/events/backup.ts", "../../types/src/sdk/events/environmentVariable.ts", "../../types/src/sdk/events/auditLog.ts", "../../types/src/sdk/events/index.ts", "../../types/src/sdk/licensing/license.ts", "../../types/src/sdk/licensing/plan.ts", "../../types/src/sdk/licensing/quota.ts", "../../types/src/sdk/licensing/feature.ts", "../../types/src/sdk/licensing/billing.ts", "../../types/src/sdk/licensing/index.ts", "../../types/src/sdk/migrations.ts", "../../types/src/sdk/datasources.ts", "../../types/src/sdk/search.ts", "../../types/src/sdk/koa.ts", "../../types/src/sdk/auth.ts", "../../types/src/sdk/locks.ts", "../../types/src/sdk/db.ts", "../../types/src/sdk/middleware/matchers.ts", "../../types/src/sdk/middleware/tenancy.ts", "../../types/src/sdk/middleware/index.ts", "../../types/src/sdk/featureFlag.ts", "../../types/src/sdk/environmentVariables.ts", "../../types/src/sdk/auditLogs.ts", "../../types/src/sdk/sso.ts", "../../types/src/sdk/user.ts", "../../types/src/sdk/cli/constants.ts", "../../types/src/sdk/cli/index.ts", "../../types/src/sdk/websocket.ts", "../../types/src/sdk/index.ts", "../../types/src/documents/account/account.ts", "../../types/src/documents/account/user.ts", "../../types/src/documents/account/index.ts", "../../types/src/documents/app/app.ts", "../../types/src/documents/app/automation.ts", "../../types/src/documents/app/datasource.ts", "../../types/src/documents/app/layout.ts", "../../types/src/documents/app/query.ts", "../../types/src/documents/app/role.ts", "../../types/src/documents/app/table.ts", "../../types/src/documents/app/screen.ts", "../../types/src/documents/app/view.ts", "../../types/src/documents/document.ts", "../../types/src/documents/app/row.ts", "../../types/src/documents/app/user.ts", "../../types/src/documents/app/backup.ts", "../../types/src/documents/app/webhook.ts", "../../types/src/documents/app/links.ts", "../../types/src/documents/app/component.ts", "../../types/src/documents/app/index.ts", "../../types/src/documents/global/config.ts", "../../types/src/documents/global/user.ts", "../../types/src/documents/global/userGroup.ts", "../../types/src/documents/global/plugin.ts", "../../types/src/documents/global/quotas.ts", "../../types/src/documents/global/schedule.ts", "../../types/src/documents/global/templates.ts", "../../types/src/documents/global/environmentVariables.ts", "../../types/src/documents/global/auditLogs.ts", "../../types/src/documents/global/index.ts", "../../types/src/documents/platform/info.ts", "../../types/src/documents/platform/users.ts", "../../types/src/documents/platform/accounts.ts", "../../types/src/documents/platform/tenants.ts", "../../types/src/documents/platform/index.ts", "../../types/src/documents/pouch.ts", "../../types/src/documents/index.ts", "../../types/src/api/account/accounts.ts", "../../types/src/api/account/user.ts", "../../types/src/api/account/license.ts", "../../types/src/api/account/status.ts", "../../types/src/api/account/index.ts", "../../types/src/api/web/analytics.ts", "../../types/src/api/web/auth.ts", "../../types/src/api/web/user.ts", "../../types/src/api/web/errors.ts", "../../types/src/api/web/schedule.ts", "../../types/src/api/web/system/environment.ts", "../../types/src/api/web/system/index.ts", "../../types/src/api/web/app/backup.ts", "../../types/src/api/web/app/datasource.ts", "../../types/src/api/web/app/index.ts", "../../types/src/api/web/global/environmentVariables.ts", "../../types/src/api/web/global/auditLogs.ts", "../../types/src/api/web/global/events.ts", "../../types/src/api/web/global/configs.ts", "../../types/src/api/web/global/scim/users.ts", "../../types/src/api/web/global/scim/groups.ts", "../../types/src/api/web/global/scim/shared.ts", "../../types/src/api/web/global/scim/index.ts", "../../types/src/api/web/global/index.ts", "../../types/src/api/web/pagination.ts", "../../types/src/api/web/index.ts", "../../types/src/api/index.ts", "../../types/src/index.ts", "../../backend-core/src/constants/db.ts", "../../backend-core/src/constants/misc.ts", "../../backend-core/src/constants/index.ts", "../../backend-core/src/context/identity.ts", "../../backend-core/src/environment.ts", "../../backend-core/src/context/Context.ts", "../../backend-core/src/docIds/conversions.ts", "../../backend-core/src/db/couch/connections.ts", "../../backend-core/src/helpers.ts", "../../backend-core/src/db/couch/utils.ts", "../../backend-core/src/db/couch/pouchDB.ts", "../../backend-core/src/docIds/newid.ts", "../../backend-core/src/db/couch/DatabaseImpl.ts", "../../backend-core/src/db/couch/index.ts", "../../backend-core/src/db/db.ts", "../../backend-core/src/context/mainContext.ts", "../../backend-core/src/context/index.ts", "../../backend-core/src/redis/utils.ts", "../../backend-core/src/timers/timers.ts", "../../backend-core/src/timers/index.ts", "../../backend-core/src/redis/redis.ts", "../../backend-core/src/redis/init.ts", "../../backend-core/src/cache/base/index.ts", "../../backend-core/src/logging/correlation/correlation.ts", "../../backend-core/src/logging/correlation/index.ts", "../../backend-core/src/logging/pino/logger.ts", "../../backend-core/src/logging/alerts.ts", "../../backend-core/src/logging/index.ts", "../../string-templates/src/helpers/Helper.js", "../../string-templates/src/helpers/date.js", "../../string-templates/src/helpers/constants.js", "../../string-templates/src/helpers/external.js", "../../string-templates/src/utilities.js", "../../string-templates/src/helpers/list.js", "../../string-templates/src/helpers/javascript.js", "../../string-templates/src/helpers/index.js", "../../string-templates/src/processors/preprocessor.js", "../../string-templates/src/processors/postprocessor.js", "../../string-templates/src/processors/index.js", "../../string-templates/manifest.json", "../../string-templates/src/conversion/index.js", "../../string-templates/src/index.js", "../../string-templates/src/index.cjs", "../src/threads/query.ts", "../src/environment.ts", "../../backend-core/src/configs/index.ts", "../../backend-core/src/configs/configs.ts", "../../backend-core/src/cache/index.ts", "../../backend-core/src/cache/generic.ts", "../../backend-core/src/cache/user.ts", "../../backend-core/src/tenancy/index.ts", "../../backend-core/src/tenancy/db.ts", "../../backend-core/src/tenancy/tenancy.ts", "../../backend-core/src/platform/users.ts", "../../backend-core/src/platform/platformDb.ts", "../../backend-core/src/platform/tenants.ts", "../../backend-core/src/redis/redlockImpl.ts", "../../backend-core/src/accounts/api.ts", "../../backend-core/src/accounts/accounts.ts", "../../backend-core/src/cache/appMetadata.ts", "../../backend-core/src/db/index.ts", "../../backend-core/src/db/utils.ts", "../../backend-core/src/docIds/ids.ts", "../../backend-core/src/docIds/params.ts", "../../backend-core/src/db/views.ts", "../../backend-core/src/db/Replication.ts", "../../backend-core/src/db/lucene.ts", "../../backend-core/src/db/searchIndexes/index.ts", "../../backend-core/src/db/searchIndexes/searchIndexes.ts", "../../backend-core/src/cache/writethrough.ts", "../../backend-core/src/events/index.ts", "../../backend-core/src/events/processors/index.ts", "../../backend-core/src/events/processors/AnalyticsProcessor.ts", "../../backend-core/src/events/analytics.ts", "../../backend-core/src/events/processors/posthog/PosthogProcessor.ts", "../../backend-core/src/events/processors/posthog/rateLimiting.ts", "../../backend-core/src/events/processors/posthog/index.ts", "../../backend-core/src/events/processors/LoggingProcessor.ts", "../../backend-core/src/events/processors/AuditLogsProcessor.ts", "../../backend-core/src/queue/index.ts", "../../backend-core/src/queue/queue.ts", "../../backend-core/src/queue/inMemoryQueue.ts", "../../backend-core/src/utils/index.ts", "../../backend-core/src/utils/hashing.ts", "../../backend-core/src/utils/utils.ts", "../../backend-core/src/utils/stringUtils.ts", "../../backend-core/src/queue/constants.ts", "../../backend-core/src/queue/listeners.ts", "../../backend-core/src/events/processors/Processors.ts", "../../backend-core/src/events/identification.ts", "../../backend-core/src/installation.ts", "../../backend-core/src/events/backfill.ts", "../../backend-core/src/events/asyncEvents/queue.ts", "../../backend-core/src/events/asyncEvents/publisher.ts", "../../backend-core/src/events/events.ts", "../../backend-core/src/events/publishers/account.ts", "../../backend-core/src/events/publishers/app.ts", "../../backend-core/src/events/publishers/auth.ts", "../../backend-core/src/events/publishers/automation.ts", "../../backend-core/src/events/publishers/datasource.ts", "../../backend-core/src/events/publishers/email.ts", "../../backend-core/src/events/publishers/license.ts", "../../backend-core/src/events/publishers/layout.ts", "../../backend-core/src/events/publishers/org.ts", "../../backend-core/src/events/publishers/query.ts", "../../backend-core/src/events/publishers/role.ts", "../../backend-core/src/events/publishers/screen.ts", "../../backend-core/src/events/publishers/rows.ts", "../../backend-core/src/events/publishers/table.ts", "../../backend-core/src/events/publishers/serve.ts", "../../backend-core/src/events/publishers/user.ts", "../../backend-core/src/events/publishers/view.ts", "../../backend-core/src/events/publishers/installation.ts", "../../backend-core/src/events/publishers/backfill.ts", "../../backend-core/src/events/publishers/group.ts", "../../backend-core/src/events/publishers/plugin.ts", "../../backend-core/src/events/publishers/backup.ts", "../../backend-core/src/events/publishers/environmentVariable.ts", "../../backend-core/src/events/publishers/auditLog.ts", "../../backend-core/src/migrations/migrations.ts", "../../backend-core/src/migrations/definitions.ts", "../../backend-core/src/users.ts", "../../backend-core/src/security/roles.ts", "../../backend-core/src/security/permissions.ts", "../../backend-core/src/featureFlags/index.ts", "../../backend-core/src/security/sessions.ts", "../../backend-core/src/auth/index.ts", "../../backend-core/src/auth/auth.ts", "../../backend-core/src/middleware/index.ts", "../../backend-core/src/middleware/passport/local.ts", "../../backend-core/src/middleware/passport/utils.ts", "../../backend-core/src/middleware/passport/sso/google.ts", "../../backend-core/src/middleware/passport/sso/sso.ts", "../../backend-core/src/middleware/passport/sso/oidc.ts", "../../backend-core/src/middleware/passport/datasource/google.ts", "../../backend-core/src/middleware/authenticated.ts", "../../backend-core/src/middleware/matchers.ts", "../../backend-core/src/security/encryption.ts", "../../backend-core/src/errors/errors.ts", "../../backend-core/src/middleware/auditLog.ts", "../../backend-core/src/middleware/tenancy.ts", "../../backend-core/src/middleware/internalApi.ts", "../../backend-core/src/middleware/csrf.ts", "../../backend-core/src/middleware/adminOnly.ts", "../../backend-core/src/middleware/builderOrAdmin.ts", "../../backend-core/src/middleware/builderOnly.ts", "../../backend-core/src/logging/pino/middleware.ts", "../../backend-core/src/logging/correlation/middleware.ts", "../../backend-core/src/middleware/errorHandling.ts", "../../backend-core/src/middleware/querystringToBody.ts", "../../backend-core/src/middleware/joi-validator.ts", "../../backend-core/src/index.ts", "../../backend-core/src/plugin/index.ts", "../../backend-core/src/plugin/utils.ts", "../../backend-core/src/objectStore/index.ts", "../../backend-core/src/objectStore/objectStore.ts", "../../backend-core/src/objectStore/utils.ts", "../../backend-core/src/objectStore/buckets/app.ts", "../../backend-core/src/objectStore/cloudfront.ts", "../../backend-core/src/objectStore/buckets/global.ts", "../../backend-core/src/objectStore/buckets/plugins.ts", "../../backend-core/src/redis/index.ts", "../../backend-core/src/blacklist/index.ts", "../../backend-core/src/blacklist/blacklist.ts", "../../backend-core/src/events/processors/async/DocumentUpdateProcessor.ts", "../../backend-core/src/events/documentId.ts", "../src/db/index.ts", "../src/threads/utils.ts", "../src/utilities/scriptRunner.ts", "../src/integrations/postgres.ts", "../src/integrations/utils.ts", "../src/db/newid.ts", "../src/db/utils.ts", "../src/constants/index.ts", "../src/integrations/base/sql.ts", "../src/integrations/base/sqlTable.ts", "../src/utilities/index.ts", "../src/integrations/dynamodb.ts", "../src/db/dynamoClient.ts", "../src/integrations/mongodb.ts", "../src/integrations/elasticsearch.ts", "../src/integrations/couchdb.ts", "../src/integrations/microsoftSqlServer.ts", "../src/integrations/s3.ts", "../src/integrations/airtable.ts", "../src/integrations/mysql.ts", "../src/integrations/arangodb.ts", "../src/integrations/rest.ts", "../src/integrations/googlesheets.ts", "../../shared-core/src/constants.ts", "../../shared-core/src/filters.ts", "../../shared-core/src/helpers/helpers.ts", "../../shared-core/src/helpers/integrations.ts", "../../shared-core/src/utils.ts", "../src/integrations/firebase.ts", "../src/integrations/redis.ts", "../src/integrations/snowflake.ts", "../src/integrations/oracle.ts", "../src/integrations/index.ts", "../src/utilities/budibaseDir.ts", "../src/utilities/fileSystem/app.ts", "../src/utilities/fileSystem/filesystem.ts", "../src/utilities/fileSystem/plugin.ts", "../src/utilities/fileSystem/template.ts", "../src/sdk/app/backups/exports.ts", "../src/sdk/app/backups/constants.ts", "../src/sdk/app/backups/imports.ts", "../src/sdk/app/backups/statistics.ts", "../src/sdk/app/backups/index.ts", "../src/sdk/app/datasources/datasources.ts", "../../pro/packages/pro/src/sdk/index.ts", "../../pro/packages/pro/src/sdk/branding/index.ts", "../../pro/packages/pro/src/sdk/features/index.ts", "../../pro/packages/pro/src/sdk/features/features.ts", "../../pro/packages/pro/src/sdk/licensing/index.ts", "../../pro/packages/pro/src/sdk/licensing/cache/index.ts", "../../pro/packages/pro/src/sdk/licensing/cache/redis.ts", "../../pro/packages/pro/src/sdk/licensing/licenses/client.ts", "../../pro/packages/pro/src/utilities/api.ts", "../../pro/packages/pro/src/db/quotas/index.ts", "../../pro/packages/pro/src/db/quotas/quotas.ts", "../../pro/packages/pro/src/db/quotas/utils.ts", "../../pro/packages/pro/src/db/licenseInfo.ts", "../../pro/packages/pro/src/db/groups.ts", "../../pro/packages/pro/src/db/views/staticViews.ts", "../../pro/packages/pro/src/db/views/groups.ts", "../../pro/packages/pro/src/db/backups.ts", "../../pro/packages/pro/src/db/utils/pagination.ts", "../../pro/packages/pro/src/db/utils/views.ts", "../../pro/packages/pro/src/db/utils/retention.ts", "../../pro/packages/pro/src/constants/licenses.ts", "../../pro/packages/pro/src/constants/quotas.ts", "../../pro/packages/pro/src/constants/version.ts", "../../pro/packages/pro/src/constants/misc.ts", "../../pro/packages/pro/src/db/environmentVariables.ts", "../../pro/packages/pro/src/sdk/licensing/licenses/offline.ts", "../../pro/packages/pro/src/sdk/licensing/licenses/licenses.ts", "../../pro/packages/pro/src/sdk/licensing/cache/cache.ts", "../../pro/packages/pro/src/sdk/branding/branding.ts", "../../pro/packages/pro/src/sdk/quotas/index.ts", "../../pro/packages/pro/src/sdk/quotas/quotas.ts", "../../pro/packages/pro/src/sdk/quotas/helpers/apps.ts", "../../pro/packages/pro/src/sdk/quotas/helpers/queries.ts", "../../pro/packages/pro/src/sdk/quotas/helpers/rows.ts", "../../pro/packages/pro/src/sdk/quotas/helpers/automations.ts", "../../pro/packages/pro/src/sdk/quotas/helpers/dayPasses.ts", "../../pro/packages/pro/src/sdk/quotas/helpers/groups.ts", "../../pro/packages/pro/src/sdk/quotas/helpers/plugins.ts", "../../pro/packages/pro/src/sdk/quotas/helpers/users.ts", "../../pro/packages/pro/src/sdk/users/index.ts", "../../pro/packages/pro/src/sdk/api/api.ts", "../../pro/packages/pro/src/sdk/users/users.ts", "../../pro/packages/pro/src/sdk/automations/index.ts", "../../pro/packages/pro/src/sdk/automations/logging/index.ts", "../../pro/packages/pro/src/db/automations.ts", "../../pro/packages/pro/src/utilities/delay.ts", "../../pro/packages/pro/src/sdk/groups/index.ts", "../../pro/packages/pro/src/api/errors.ts", "../../pro/packages/pro/src/sdk/groups/groups.ts", "../../pro/packages/pro/src/sdk/plugins/index.ts", "../../pro/packages/pro/src/utilities/fileSystem.ts", "../../pro/packages/pro/src/sdk/environmentVariables/index.ts", "../../pro/packages/pro/src/sdk/environmentVariables/environmentVariables.ts", "../../pro/packages/pro/src/sdk/auditLogs/index.ts", "../../pro/packages/pro/src/sdk/auditLogs/auditLogs.ts", "../../pro/packages/pro/src/db/auditLogs.ts", "../../pro/packages/pro/src/sdk/auditLogs/utils.ts", "../../pro/packages/pro/src/sdk/backups/backup.ts", "../../pro/packages/pro/src/sdk/backups/queue.ts", "../../pro/packages/pro/src/sdk/backups/processing.ts", "../../pro/packages/pro/src/sdk/backups/index.ts", "../../pro/packages/pro/src/sdk/utils/index.ts", "../../pro/packages/pro/src/sdk/utils/apps.ts", "../../pro/packages/pro/src/sdk/scim/users.ts", "../../pro/packages/pro/src/sdk/init.ts", "../../pro/packages/pro/src/middleware/licensing.ts", "../../pro/packages/pro/src/middleware/feature.ts", "../../pro/packages/pro/src/middleware/doInScimContext.ts", "../../pro/packages/pro/src/middleware/requireSCIM.ts", "../../pro/packages/pro/src/api/controllers/global/groups.ts", "../../pro/packages/pro/src/api/controllers/global/environmentVariables.ts", "../../pro/packages/pro/src/api/routes/global/groups.ts", "../../pro/packages/pro/src/api/routes/global/environmentVariables.ts", "../../pro/packages/pro/src/api/controllers/global/auditLogs.ts", "../../pro/packages/pro/src/api/routes/global/auditLogs.ts", "../../pro/packages/pro/src/api/controllers/apps/backups.ts", "../../pro/packages/pro/src/api/routes/apps/backups.ts", "../../pro/packages/pro/src/api/controllers/schedules/index.ts", "../../pro/packages/pro/src/api/routes/schedules/index.ts", "../../pro/packages/pro/src/api/routes/global/scim.ts", "../../pro/packages/pro/src/api/controllers/global/scim/users.ts", "../../pro/packages/pro/src/api/controllers/global/scim/groups.ts", "../../pro/packages/pro/src/mappers/index.ts", "../../pro/packages/pro/src/mappers/users.ts", "../../pro/packages/pro/src/mappers/groups.ts", "../src/sdk/utils/index.ts", "../src/sdk/app/datasources/index.ts", "../src/sdk/app/tables/index.ts", "../src/sdk/app/automations/webhook.ts", "../src/sdk/app/automations/utils.ts", "../src/sdk/app/automations/index.ts", "../src/sdk/app/applications/sync.ts", "../src/utilities/global.ts", "../src/sdk/app/applications/utils.ts", "../src/sdk/app/applications/index.ts", "../src/sdk/app/queries/queries.ts", "../src/sdk/app/queries/index.ts", "../src/sdk/app/rows/attachments.ts", "../src/sdk/app/rows/rows.ts", "../src/sdk/app/rows/index.ts", "../src/sdk/users/utils.ts", "../src/sdk/users/index.ts", "../src/sdk/plugins/plugins.ts", "../src/api/controllers/plugin/file.ts", "../src/websockets/websocket.ts", "../src/middleware/utils.ts", "../src/middleware/authorized.ts", "../src/api/controllers/row/utils.ts", "../src/websockets/index.ts", "../src/sdk/plugins/index.ts", "../src/sdk/index.ts", "../src/integrations/queries/sql.ts"],
4
+ "sourcesContent": ["import { Automation, AutomationMetadata } from \"../../documents\"\nimport { Job } from \"bull\"\n\nexport interface AutomationDataEvent {\n appId?: string\n metadata?: AutomationMetadata\n automation?: Automation\n timeout?: number\n}\n\nexport interface AutomationData {\n event: AutomationDataEvent\n automation: Automation\n}\n\nexport type AutomationJob = Job<AutomationData>\n", "export enum Hosting {\n CLOUD = \"cloud\",\n SELF = \"self\",\n}\n", "import { User, Account } from \"../documents\"\nimport { IdentityType, HostInfo } from \"./events\"\n\nexport interface BaseContext {\n _id: string\n type: IdentityType\n tenantId?: string\n}\n\nexport interface AccountUserContext extends BaseContext {\n tenantId: string\n account: Account\n}\n\nexport interface UserContext extends BaseContext, User {\n _id: string\n tenantId: string\n account?: Account\n hostInfo: HostInfo\n}\n\nexport type IdentityContext = BaseContext | AccountUserContext | UserContext\n", "import { BaseEvent } from \"./event\"\n\nexport interface AppCreatedEvent extends BaseEvent {\n appId: string\n version: string\n audited: {\n name: string\n }\n}\n\nexport interface AppUpdatedEvent extends BaseEvent {\n appId: string\n version: string\n audited: {\n name: string\n }\n}\n\nexport interface AppDeletedEvent extends BaseEvent {\n appId: string\n audited: {\n name: string\n }\n}\n\nexport interface AppPublishedEvent extends BaseEvent {\n appId: string\n audited: {\n name: string\n }\n}\n\nexport interface AppUnpublishedEvent extends BaseEvent {\n appId: string\n audited: {\n name: string\n }\n}\n\nexport interface AppFileImportedEvent extends BaseEvent {\n appId: string\n audited: {\n name: string\n }\n}\n\nexport interface AppTemplateImportedEvent extends BaseEvent {\n appId: string\n templateKey: string\n audited: {\n name: string\n }\n}\n\nexport interface AppVersionUpdatedEvent extends BaseEvent {\n appId: string\n currentVersion: string\n updatedToVersion: string\n audited: {\n name: string\n }\n}\n\nexport interface AppVersionRevertedEvent extends BaseEvent {\n appId: string\n currentVersion: string\n revertedToVersion: string\n audited: {\n name: string\n }\n}\n\nexport interface AppRevertedEvent extends BaseEvent {\n appId: string\n audited: {\n name: string\n }\n}\n\nexport interface AppExportedEvent extends BaseEvent {\n appId: string\n audited: {\n name: string\n }\n}\n", "import { BaseEvent } from \"./event\"\nimport { ConfigType } from \"../../documents\"\n\nexport type LoginSource = \"local\" | \"google\" | \"oidc\" | \"google-internal\"\nexport type SSOType = ConfigType.OIDC | ConfigType.GOOGLE\n\nexport interface LoginEvent extends BaseEvent {\n userId: string\n source: LoginSource\n audited: {\n email: string\n }\n}\n\nexport interface LogoutEvent extends BaseEvent {\n userId: string\n audited: {\n email?: string\n }\n}\n\nexport interface SSOCreatedEvent extends BaseEvent {\n type: SSOType\n}\n\nexport interface SSOUpdatedEvent extends BaseEvent {\n type: SSOType\n}\n\nexport interface SSOActivatedEvent extends BaseEvent {\n type: SSOType\n}\n\nexport interface SSODeactivatedEvent extends BaseEvent {\n type: SSOType\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface AutomationCreatedEvent extends BaseEvent {\n appId: string\n automationId: string\n triggerId: string\n triggerType: string\n audited: {\n name: string\n }\n}\n\nexport interface AutomationTriggerUpdatedEvent extends BaseEvent {\n appId: string\n automationId: string\n triggerId: string\n triggerType: string\n}\n\nexport interface AutomationDeletedEvent extends BaseEvent {\n appId: string\n automationId: string\n triggerId: string\n triggerType: string\n audited: {\n name: string\n }\n}\n\nexport interface AutomationTestedEvent extends BaseEvent {\n appId: string\n automationId: string\n triggerId: string\n triggerType: string\n}\n\nexport interface AutomationStepCreatedEvent extends BaseEvent {\n appId: string\n automationId: string\n triggerId: string\n triggerType: string\n stepId: string\n stepType: string\n audited: {\n name: string\n }\n}\n\nexport interface AutomationStepDeletedEvent extends BaseEvent {\n appId: string\n automationId: string\n triggerId: string\n triggerType: string\n stepId: string\n stepType: string\n audited: {\n name: string\n }\n}\n\nexport interface AutomationsRunEvent extends BaseEvent {\n count: number\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface SMTPCreatedEvent extends BaseEvent {}\n\nexport interface SMTPUpdatedEvent extends BaseEvent {}\n", "import { BaseEvent } from \"./event\"\n\nexport interface DatasourceCreatedEvent extends BaseEvent {\n datasourceId: string\n source: string\n custom: boolean\n}\n\nexport interface DatasourceUpdatedEvent extends BaseEvent {\n datasourceId: string\n source: string\n custom: boolean\n}\n\nexport interface DatasourceDeletedEvent extends BaseEvent {\n datasourceId: string\n source: string\n custom: boolean\n}\n", "import { Hosting } from \"../hosting\"\nimport { Group, Identity } from \"./identification\"\n\nexport enum Event {\n // USER\n USER_CREATED = \"user:created\",\n USER_UPDATED = \"user:updated\",\n USER_DELETED = \"user:deleted\",\n\n // USER / ONBOARDING\n USER_ONBOARDING_COMPLETE = \"user:onboarding:complete\",\n\n // USER / PERMISSIONS\n USER_PERMISSION_ADMIN_ASSIGNED = \"user:admin:assigned\",\n USER_PERMISSION_ADMIN_REMOVED = \"user:admin:removed\",\n USER_PERMISSION_BUILDER_ASSIGNED = \"user:builder:assigned\",\n USER_PERMISSION_BUILDER_REMOVED = \"user:builder:removed\",\n\n // USER / INVITE\n USER_INVITED = \"user:invited\",\n USER_INVITED_ACCEPTED = \"user:invite:accepted\",\n\n // USER / PASSWORD\n USER_PASSWORD_FORCE_RESET = \"user:password:force:reset\",\n USER_PASSWORD_UPDATED = \"user:password:updated\",\n USER_PASSWORD_RESET_REQUESTED = \"user:password:reset:requested\",\n USER_PASSWORD_RESET = \"user:password:reset\",\n\n // EMAIL\n EMAIL_SMTP_CREATED = \"email:smtp:created\",\n EMAIL_SMTP_UPDATED = \"email:smtp:updated\",\n\n // AUTH\n AUTH_SSO_CREATED = \"auth:sso:created\",\n AUTH_SSO_UPDATED = \"auth:sso:updated\",\n AUTH_SSO_ACTIVATED = \"auth:sso:activated\",\n AUTH_SSO_DEACTIVATED = \"auth:sso:deactivated\",\n AUTH_LOGIN = \"auth:login\",\n AUTH_LOGOUT = \"auth:logout\",\n\n // ORG\n ORG_NAME_UPDATED = \"org:info:name:updated\",\n ORG_LOGO_UPDATED = \"org:info:logo:updated\",\n ORG_PLATFORM_URL_UPDATED = \"org:platformurl:updated\",\n\n // INSTALLATION\n INSTALLATION_VERSION_CHECKED = \"installation:version:checked\",\n INSTALLATION_VERSION_UPGRADED = \"installation:version:upgraded\",\n INSTALLATION_VERSION_DOWNGRADED = \"installation:version:downgraded\",\n INSTALLATION_FIRST_STARTUP = \"installation:firstStartup\",\n\n // ORG / ANALYTICS\n ANALYTICS_OPT_OUT = \"analytics:opt:out\",\n ANALYTICS_OPT_IN = \"analytics:opt:in\",\n\n // APP\n APP_CREATED = \"app:created\",\n APP_UPDATED = \"app:updated\",\n APP_DELETED = \"app:deleted\",\n APP_PUBLISHED = \"app:published\",\n APP_UNPUBLISHED = \"app:unpublished\",\n APP_TEMPLATE_IMPORTED = \"app:template:imported\",\n APP_FILE_IMPORTED = \"app:file:imported\",\n APP_VERSION_UPDATED = \"app:version:updated\",\n APP_VERSION_REVERTED = \"app:version:reverted\",\n APP_REVERTED = \"app:reverted\",\n APP_EXPORTED = \"app:exported\",\n\n // ROLE\n ROLE_CREATED = \"role:created\",\n ROLE_UPDATED = \"role:updated\",\n ROLE_DELETED = \"role:deleted\",\n ROLE_ASSIGNED = \"role:assigned\",\n ROLE_UNASSIGNED = \"role:unassigned\",\n\n // SERVE\n SERVED_BUILDER = \"served:builder\",\n SERVED_APP = \"served:app\",\n SERVED_APP_PREVIEW = \"served:app:preview\",\n\n // DATASOURCE\n DATASOURCE_CREATED = \"datasource:created\",\n DATASOURCE_UPDATED = \"datasource:updated\",\n DATASOURCE_DELETED = \"datasource:deleted\",\n\n // QUERY\n QUERY_CREATED = \"query:created\",\n QUERY_UPDATED = \"query:updated\",\n QUERY_DELETED = \"query:deleted\",\n QUERY_IMPORT = \"query:import\",\n QUERIES_RUN = \"queries:run\",\n QUERY_PREVIEWED = \"query:previewed\",\n\n // TABLE\n TABLE_CREATED = \"table:created\",\n TABLE_UPDATED = \"table:updated\",\n TABLE_DELETED = \"table:deleted\",\n TABLE_EXPORTED = \"table:exported\",\n TABLE_IMPORTED = \"table:imported\",\n TABLE_DATA_IMPORTED = \"table:data:imported\",\n\n // VIEW\n VIEW_CREATED = \"view:created\",\n VIEW_UPDATED = \"view:updated\",\n VIEW_DELETED = \"view:deleted\",\n VIEW_EXPORTED = \"view:exported\",\n VIEW_FILTER_CREATED = \"view:filter:created\",\n VIEW_FILTER_UPDATED = \"view:filter:updated\",\n VIEW_FILTER_DELETED = \"view:filter:deleted\",\n VIEW_CALCULATION_CREATED = \"view:calculation:created\",\n VIEW_CALCULATION_UPDATED = \"view:calculation:updated\",\n VIEW_CALCULATION_DELETED = \"view:calculation:deleted\",\n\n // ROWS\n ROWS_CREATED = \"rows:created\",\n ROWS_IMPORTED = \"rows:imported\",\n\n // COMPONENT\n COMPONENT_CREATED = \"component:created\",\n COMPONENT_DELETED = \"component:deleted\",\n\n // SCREEN\n SCREEN_CREATED = \"screen:created\",\n SCREEN_DELETED = \"screen:deleted\",\n\n // LAYOUT\n LAYOUT_CREATED = \"layout:created\",\n LAYOUT_DELETED = \"layout:deleted\",\n\n // AUTOMATION\n AUTOMATION_CREATED = \"automation:created\",\n AUTOMATION_DELETED = \"automation:deleted\",\n AUTOMATION_TESTED = \"automation:tested\",\n AUTOMATIONS_RUN = \"automations:run\",\n AUTOMATION_STEP_CREATED = \"automation:step:created\",\n AUTOMATION_STEP_DELETED = \"automation:step:deleted\",\n AUTOMATION_TRIGGER_UPDATED = \"automation:trigger:updated\",\n\n // LICENSE\n LICENSE_PLAN_CHANGED = \"license:plan:changed\",\n LICENSE_ACTIVATED = \"license:activated\",\n LICENSE_PAYMENT_FAILED = \"license:payment:failed\",\n LICENSE_PAYMENT_RECOVERED = \"license:payment:recovered\",\n LICENSE_CHECKOUT_OPENED = \"license:checkout:opened\",\n LICENSE_CHECKOUT_SUCCESS = \"license:checkout:success\",\n LICENSE_PORTAL_OPENED = \"license:portal:opened\",\n\n // ACCOUNT\n ACCOUNT_CREATED = \"account:created\",\n ACCOUNT_DELETED = \"account:deleted\",\n ACCOUNT_VERIFIED = \"account:verified\",\n\n // BACKFILL\n APP_BACKFILL_SUCCEEDED = \"app:backfill:succeeded\",\n APP_BACKFILL_FAILED = \"app:backfill:failed\",\n TENANT_BACKFILL_SUCCEEDED = \"tenant:backfill:succeeded\",\n TENANT_BACKFILL_FAILED = \"tenant:backfill:failed\",\n INSTALLATION_BACKFILL_SUCCEEDED = \"installation:backfill:succeeded\",\n INSTALLATION_BACKFILL_FAILED = \"installation:backfill:failed\",\n\n // USER\n USER_GROUP_CREATED = \"user_group:created\",\n USER_GROUP_UPDATED = \"user_group:updated\",\n USER_GROUP_DELETED = \"user_group:deleted\",\n USER_GROUP_USERS_ADDED = \"user_group:user_added\",\n USER_GROUP_USERS_REMOVED = \"user_group:users_deleted\",\n USER_GROUP_PERMISSIONS_EDITED = \"user_group:permissions_edited\",\n USER_GROUP_ONBOARDING = \"user_group:onboarding_added\",\n\n // PLUGIN\n PLUGIN_INIT = \"plugin:init\",\n PLUGIN_IMPORTED = \"plugin:imported\",\n PLUGIN_DELETED = \"plugin:deleted\",\n\n // BACKUP\n APP_BACKUP_RESTORED = \"app:backup:restored\",\n APP_BACKUP_TRIGGERED = \"app:backup:triggered\",\n\n // ENVIRONMENT VARIABLE\n ENVIRONMENT_VARIABLE_CREATED = \"environment_variable:created\",\n ENVIRONMENT_VARIABLE_DELETED = \"environment_variable:deleted\",\n ENVIRONMENT_VARIABLE_UPGRADE_PANEL_OPENED = \"environment_variable:upgrade_panel_opened\",\n\n // AUDIT LOG\n AUDIT_LOGS_FILTERED = \"audit_log:filtered\",\n AUDIT_LOGS_DOWNLOADED = \"audit_log:downloaded\",\n}\n\nexport const UserGroupSyncEvents: Event[] = [\n Event.USER_CREATED,\n Event.USER_UPDATED,\n Event.USER_DELETED,\n Event.USER_PERMISSION_ADMIN_ASSIGNED,\n Event.USER_PERMISSION_ADMIN_REMOVED,\n Event.USER_PERMISSION_BUILDER_ASSIGNED,\n Event.USER_PERMISSION_BUILDER_REMOVED,\n Event.USER_GROUP_CREATED,\n Event.USER_GROUP_UPDATED,\n Event.USER_GROUP_DELETED,\n Event.USER_GROUP_USERS_ADDED,\n Event.USER_GROUP_USERS_REMOVED,\n Event.USER_GROUP_PERMISSIONS_EDITED,\n]\n\nexport const AsyncEvents: Event[] = [...UserGroupSyncEvents]\n\n// all events that are not audited have been added to this record as undefined, this means\n// that Typescript can protect us against new events being added and auditing of those\n// events not being considered. This might be a little ugly, but provides a level of\n// Typescript build protection for the audit log feature, any new event also needs to be\n// added to this map, during which the developer will need to consider if it should be\n// a user facing event or not.\nexport const AuditedEventFriendlyName: Record<Event, string | undefined> = {\n // USER\n [Event.USER_CREATED]: `User \"{{ email }}\" created{{#if viaScim}} via SCIM{{/if}}`,\n [Event.USER_UPDATED]: `User \"{{ email }}\" updated{{#if viaScim}} via SCIM{{/if}}`,\n [Event.USER_DELETED]: `User \"{{ email }}\" deleted{{#if viaScim}} via SCIM{{/if}}`,\n [Event.USER_PERMISSION_ADMIN_ASSIGNED]: `User \"{{ email }}\" admin role assigned`,\n [Event.USER_PERMISSION_ADMIN_REMOVED]: `User \"{{ email }}\" admin role removed`,\n [Event.USER_PERMISSION_BUILDER_ASSIGNED]: `User \"{{ email }}\" builder role assigned`,\n [Event.USER_PERMISSION_BUILDER_REMOVED]: `User \"{{ email }}\" builder role removed`,\n [Event.USER_INVITED]: `User \"{{ email }}\" invited`,\n [Event.USER_INVITED_ACCEPTED]: `User \"{{ email }}\" accepted invite`,\n [Event.USER_PASSWORD_UPDATED]: `User \"{{ email }}\" password updated`,\n [Event.USER_PASSWORD_RESET_REQUESTED]: `User \"{{ email }}\" password reset requested`,\n [Event.USER_PASSWORD_RESET]: `User \"{{ email }}\" password reset`,\n [Event.USER_GROUP_CREATED]: `User group \"{{ name }}\" created{{#if viaScim}} via SCIM{{/if}}`,\n [Event.USER_GROUP_UPDATED]: `User group \"{{ name }}\" updated{{#if viaScim}} via SCIM{{/if}}`,\n [Event.USER_GROUP_DELETED]: `User group \"{{ name }}\" deleted{{#if viaScim}} via SCIM{{/if}}`,\n [Event.USER_GROUP_USERS_ADDED]: `User group \"{{ name }}\" {{ count }} users added{{#if viaScim}} via SCIM{{/if}}`,\n [Event.USER_GROUP_USERS_REMOVED]: `User group \"{{ name }}\" {{ count }} users removed{{#if viaScim}} via SCIM{{/if}}`,\n [Event.USER_GROUP_PERMISSIONS_EDITED]: `User group \"{{ name }}\" permissions edited`,\n [Event.USER_PASSWORD_FORCE_RESET]: undefined,\n [Event.USER_GROUP_ONBOARDING]: undefined,\n [Event.USER_ONBOARDING_COMPLETE]: undefined,\n\n // EMAIL\n [Event.EMAIL_SMTP_CREATED]: `Email configuration created`,\n [Event.EMAIL_SMTP_UPDATED]: `Email configuration updated`,\n\n // AUTH\n [Event.AUTH_SSO_CREATED]: `SSO configuration created`,\n [Event.AUTH_SSO_UPDATED]: `SSO configuration updated`,\n [Event.AUTH_SSO_ACTIVATED]: `SSO configuration activated`,\n [Event.AUTH_SSO_DEACTIVATED]: `SSO configuration deactivated`,\n [Event.AUTH_LOGIN]: `User \"{{ email }}\" logged in`,\n [Event.AUTH_LOGOUT]: `User \"{{ email }}\" logged out`,\n\n // ORG\n [Event.ORG_NAME_UPDATED]: `Organisation name updated`,\n [Event.ORG_LOGO_UPDATED]: `Organisation logo updated`,\n [Event.ORG_PLATFORM_URL_UPDATED]: `Organisation platform URL updated`,\n\n // APP\n [Event.APP_CREATED]: `App \"{{ name }}\" created`,\n [Event.APP_UPDATED]: `App \"{{ name }}\" updated`,\n [Event.APP_DELETED]: `App \"{{ name }}\" deleted`,\n [Event.APP_PUBLISHED]: `App \"{{ name }}\" published`,\n [Event.APP_UNPUBLISHED]: `App \"{{ name }}\" unpublished`,\n [Event.APP_TEMPLATE_IMPORTED]: `App \"{{ name }}\" template imported`,\n [Event.APP_FILE_IMPORTED]: `App \"{{ name }}\" file imported`,\n [Event.APP_VERSION_UPDATED]: `App \"{{ name }}\" version updated`,\n [Event.APP_VERSION_REVERTED]: `App \"{{ name }}\" version reverted`,\n [Event.APP_REVERTED]: `App \"{{ name }}\" reverted`,\n [Event.APP_EXPORTED]: `App \"{{ name }}\" exported`,\n [Event.APP_BACKUP_RESTORED]: `App backup \"{{ name }}\" restored`,\n [Event.APP_BACKUP_TRIGGERED]: `App backup \"{{ name }}\" triggered`,\n\n // DATASOURCE\n [Event.DATASOURCE_CREATED]: `Datasource created`,\n [Event.DATASOURCE_UPDATED]: `Datasource updated`,\n [Event.DATASOURCE_DELETED]: `Datasource deleted`,\n\n // QUERY\n [Event.QUERY_CREATED]: `Query created`,\n [Event.QUERY_UPDATED]: `Query updated`,\n [Event.QUERY_DELETED]: `Query deleted`,\n [Event.QUERY_IMPORT]: `Query import`,\n [Event.QUERIES_RUN]: undefined,\n [Event.QUERY_PREVIEWED]: undefined,\n\n // TABLE\n [Event.TABLE_CREATED]: `Table \"{{ name }}\" created`,\n [Event.TABLE_UPDATED]: `Table \"{{ name }}\" updated`,\n [Event.TABLE_DELETED]: `Table \"{{ name }}\" deleted`,\n [Event.TABLE_EXPORTED]: `Table \"{{ name }}\" exported`,\n [Event.TABLE_IMPORTED]: `Table \"{{ name }}\" imported`,\n [Event.TABLE_DATA_IMPORTED]: `Data imported to table`,\n\n // ROWS\n [Event.ROWS_CREATED]: `Rows created`,\n [Event.ROWS_IMPORTED]: `Rows imported`,\n\n // AUTOMATION\n [Event.AUTOMATION_CREATED]: `Automation \"{{ name }}\" created`,\n [Event.AUTOMATION_DELETED]: `Automation \"{{ name }}\" deleted`,\n [Event.AUTOMATION_STEP_CREATED]: `Automation \"{{ name }}\" step added`,\n [Event.AUTOMATION_STEP_DELETED]: `Automation \"{{ name }}\" step removed`,\n [Event.AUTOMATION_TESTED]: undefined,\n [Event.AUTOMATIONS_RUN]: undefined,\n [Event.AUTOMATION_TRIGGER_UPDATED]: undefined,\n\n // SCREEN\n [Event.SCREEN_CREATED]: `Screen \"{{ name }}\" created`,\n [Event.SCREEN_DELETED]: `Screen \"{{ name }}\" deleted`,\n\n // COMPONENT\n [Event.COMPONENT_CREATED]: `Component created`,\n [Event.COMPONENT_DELETED]: `Component deleted`,\n\n // ENVIRONMENT VARIABLE\n [Event.ENVIRONMENT_VARIABLE_CREATED]: `Environment variable created`,\n [Event.ENVIRONMENT_VARIABLE_DELETED]: `Environment variable deleted`,\n [Event.ENVIRONMENT_VARIABLE_UPGRADE_PANEL_OPENED]: undefined,\n\n // PLUGIN\n [Event.PLUGIN_IMPORTED]: `Plugin imported`,\n [Event.PLUGIN_DELETED]: `Plugin deleted`,\n [Event.PLUGIN_INIT]: undefined,\n\n // ROLE - NOT AUDITED\n [Event.ROLE_CREATED]: undefined,\n [Event.ROLE_UPDATED]: undefined,\n [Event.ROLE_DELETED]: undefined,\n [Event.ROLE_ASSIGNED]: undefined,\n [Event.ROLE_UNASSIGNED]: undefined,\n\n // LICENSE - NOT AUDITED\n [Event.LICENSE_PLAN_CHANGED]: undefined,\n [Event.LICENSE_ACTIVATED]: undefined,\n [Event.LICENSE_PAYMENT_FAILED]: undefined,\n [Event.LICENSE_PAYMENT_RECOVERED]: undefined,\n [Event.LICENSE_CHECKOUT_OPENED]: undefined,\n [Event.LICENSE_CHECKOUT_SUCCESS]: undefined,\n [Event.LICENSE_PORTAL_OPENED]: undefined,\n\n // ACCOUNT - NOT AUDITED\n [Event.ACCOUNT_CREATED]: undefined,\n [Event.ACCOUNT_DELETED]: undefined,\n [Event.ACCOUNT_VERIFIED]: undefined,\n\n // BACKFILL - NOT AUDITED\n [Event.APP_BACKFILL_SUCCEEDED]: undefined,\n [Event.APP_BACKFILL_FAILED]: undefined,\n [Event.TENANT_BACKFILL_SUCCEEDED]: undefined,\n [Event.TENANT_BACKFILL_FAILED]: undefined,\n [Event.INSTALLATION_BACKFILL_SUCCEEDED]: undefined,\n [Event.INSTALLATION_BACKFILL_FAILED]: undefined,\n\n // LAYOUT - NOT AUDITED\n [Event.LAYOUT_CREATED]: undefined,\n [Event.LAYOUT_DELETED]: undefined,\n\n // VIEW - NOT AUDITED\n [Event.VIEW_CREATED]: undefined,\n [Event.VIEW_UPDATED]: undefined,\n [Event.VIEW_DELETED]: undefined,\n [Event.VIEW_EXPORTED]: undefined,\n [Event.VIEW_FILTER_CREATED]: undefined,\n [Event.VIEW_FILTER_UPDATED]: undefined,\n [Event.VIEW_FILTER_DELETED]: undefined,\n [Event.VIEW_CALCULATION_CREATED]: undefined,\n [Event.VIEW_CALCULATION_UPDATED]: undefined,\n [Event.VIEW_CALCULATION_DELETED]: undefined,\n\n // SERVED - NOT AUDITED\n [Event.SERVED_BUILDER]: undefined,\n [Event.SERVED_APP]: undefined,\n [Event.SERVED_APP_PREVIEW]: undefined,\n\n // ANALYTICS - NOT AUDITED\n [Event.ANALYTICS_OPT_OUT]: undefined,\n [Event.ANALYTICS_OPT_IN]: undefined,\n\n // INSTALLATION - NOT AUDITED\n [Event.INSTALLATION_VERSION_CHECKED]: undefined,\n [Event.INSTALLATION_VERSION_UPGRADED]: undefined,\n [Event.INSTALLATION_VERSION_DOWNGRADED]: undefined,\n [Event.INSTALLATION_FIRST_STARTUP]: undefined,\n\n // AUDIT LOG - NOT AUDITED\n [Event.AUDIT_LOGS_FILTERED]: undefined,\n [Event.AUDIT_LOGS_DOWNLOADED]: undefined,\n}\n\n// properties added at the final stage of the event pipeline\nexport interface BaseEvent {\n version?: string\n service?: string\n environment?: string\n appId?: string\n installationId?: string\n tenantId?: string\n hosting?: Hosting\n // any props in the audited section will be removed before passing events\n // up out of system (purely for use with auditing)\n audited?: {\n [key: string]: any\n }\n}\n\nexport type TableExportFormat = \"json\" | \"csv\"\n\nexport type DocUpdateEvent = {\n id: string\n tenantId: string\n appId?: string\n}\n\nexport interface EventProcessor {\n processEvent(\n event: Event,\n identity: Identity,\n properties: any,\n timestamp?: string | number\n ): Promise<void>\n identify?(identity: Identity, timestamp?: string | number): Promise<void>\n identifyGroup?(group: Group, timestamp?: string | number): Promise<void>\n shutdown?(): void\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface LayoutCreatedEvent extends BaseEvent {\n layoutId: string\n}\n\nexport interface LayoutDeletedEvent extends BaseEvent {\n layoutId: string\n}\n", "import { PlanType, PriceDuration } from \"../licensing\"\n\nexport interface LicensePlanChangedEvent {\n accountId: string\n from: PlanType\n to: PlanType\n // may not be on historical events\n fromDuration: PriceDuration | undefined\n toDuration: PriceDuration | undefined\n fromQuantity: number | undefined\n toQuantity: number | undefined\n}\n\nexport interface LicenseActivatedEvent {\n accountId: string\n}\n\nexport interface LicenseCheckoutOpenedEvent {\n accountId: string\n}\n\nexport interface LicenseCheckoutSuccessEvent {\n accountId: string\n}\n\nexport interface LicensePortalOpenedEvent {\n accountId: string\n}\n\nexport interface LicensePaymentFailedEvent {\n accountId: string\n}\n\nexport interface LicensePaymentRecoveredEvent {\n accountId: string\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface VersionCheckedEvent extends BaseEvent {\n currentVersion: string\n}\n\nexport interface VersionChangeEvent extends BaseEvent {\n from: string\n to: string\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface QueryCreatedEvent extends BaseEvent {\n queryId: string\n datasourceId: string\n source: string\n queryVerb: string\n}\n\nexport interface QueryUpdatedEvent extends BaseEvent {\n queryId: string\n datasourceId: string\n source: string\n queryVerb: string\n}\n\nexport interface QueryDeletedEvent extends BaseEvent {\n queryId: string\n datasourceId: string\n source: string\n queryVerb: string\n}\n\nexport interface QueryImportedEvent extends BaseEvent {\n datasourceId: string\n source: string\n count: number\n importSource: string\n}\n\nexport interface QueryPreviewedEvent extends BaseEvent {\n queryId?: string\n datasourceId: string\n source: string\n queryVerb: string\n}\n\nexport interface QueriesRunEvent extends BaseEvent {\n count: number\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface RoleCreatedEvent extends BaseEvent {\n roleId: string\n permissionId: string\n inherits?: string\n}\n\nexport interface RoleUpdatedEvent extends BaseEvent {\n roleId: string\n permissionId: string\n inherits?: string\n}\n\nexport interface RoleDeletedEvent extends BaseEvent {\n roleId: string\n permissionId: string\n inherits?: string\n}\n\nexport interface RoleAssignedEvent extends BaseEvent {\n userId: string\n roleId: string\n}\n\nexport interface RoleUnassignedEvent extends BaseEvent {\n userId: string\n roleId: string\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface RowsImportedEvent extends BaseEvent {\n tableId: string\n count: number\n}\n\nexport interface RowsCreatedEvent extends BaseEvent {\n count: number\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface ScreenCreatedEvent extends BaseEvent {\n screenId: string\n layoutId?: string\n roleId: string\n audited: {\n name: string\n }\n}\n\nexport interface ScreenDeletedEvent extends BaseEvent {\n screenId: string\n layoutId?: string\n roleId: string\n audited: {\n name: string\n }\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface BuilderServedEvent extends BaseEvent {\n timezone: string\n}\n\nexport interface AppServedEvent extends BaseEvent {\n appVersion: string\n timezone: string\n}\n\nexport interface AppPreviewServedEvent extends BaseEvent {\n appVersion: string\n timezone: string\n}\n", "import { BaseEvent, TableExportFormat } from \"./event\"\n\nexport interface TableCreatedEvent extends BaseEvent {\n tableId: string\n audited: {\n name: string\n }\n}\n\nexport interface TableUpdatedEvent extends BaseEvent {\n tableId: string\n audited: {\n name: string\n }\n}\n\nexport interface TableDeletedEvent extends BaseEvent {\n tableId: string\n audited: {\n name: string\n }\n}\n\nexport interface TableExportedEvent extends BaseEvent {\n tableId: string\n format: TableExportFormat\n audited: {\n name: string\n }\n}\n\nexport interface TableImportedEvent extends BaseEvent {\n tableId: string\n audited: {\n name: string\n }\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface UserCreatedEvent extends BaseEvent {\n userId: string\n viaScim?: boolean\n audited: {\n email: string\n }\n}\n\nexport interface UserUpdatedEvent extends BaseEvent {\n userId: string\n viaScim?: boolean\n audited: {\n email: string\n }\n}\n\nexport interface UserDeletedEvent extends BaseEvent {\n userId: string\n viaScim?: boolean\n audited: {\n email: string\n }\n}\n\nexport interface UserOnboardingEvent extends BaseEvent {\n userId: string\n step?: string\n audited: {\n email: string\n }\n}\n\nexport interface UserPermissionAssignedEvent extends BaseEvent {\n userId: string\n audited: {\n email: string\n }\n}\n\nexport interface UserPermissionRemovedEvent extends BaseEvent {\n userId: string\n audited: {\n email: string\n }\n}\n\nexport interface UserInvitedEvent extends BaseEvent {\n audited: {\n email: string\n }\n}\n\nexport interface UserInviteAcceptedEvent extends BaseEvent {\n userId: string\n audited: {\n email: string\n }\n}\n\nexport interface UserPasswordForceResetEvent extends BaseEvent {\n userId: string\n audited: {\n email: string\n }\n}\n\nexport interface UserPasswordUpdatedEvent extends BaseEvent {\n userId: string\n audited: {\n email: string\n }\n}\n\nexport interface UserPasswordResetRequestedEvent extends BaseEvent {\n userId: string\n audited: {\n email: string\n }\n}\n\nexport interface UserPasswordResetEvent extends BaseEvent {\n userId: string\n audited: {\n email: string\n }\n}\n", "import { ViewCalculation } from \"../../documents\"\nimport { BaseEvent, TableExportFormat } from \"./event\"\n\nexport interface ViewCreatedEvent extends BaseEvent {\n tableId: string\n}\n\nexport interface ViewUpdatedEvent extends BaseEvent {\n tableId: string\n}\n\nexport interface ViewDeletedEvent extends BaseEvent {\n tableId: string\n}\n\nexport interface ViewExportedEvent extends BaseEvent {\n tableId: string\n format: TableExportFormat\n}\n\nexport interface ViewFilterCreatedEvent extends BaseEvent {\n tableId: string\n}\n\nexport interface ViewFilterUpdatedEvent extends BaseEvent {\n tableId: string\n}\n\nexport interface ViewFilterDeletedEvent extends BaseEvent {\n tableId: string\n}\n\nexport interface ViewCalculationCreatedEvent extends BaseEvent {\n tableId: string\n calculation: ViewCalculation\n}\n\nexport interface ViewCalculationUpdatedEvent extends BaseEvent {\n tableId: string\n calculation: ViewCalculation\n}\n\nexport interface ViewCalculationDeletedEvent extends BaseEvent {\n tableId: string\n calculation: ViewCalculation\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface AccountCreatedEvent extends BaseEvent {\n tenantId: string\n registrationStep?: string\n}\n\nexport interface AccountDeletedEvent extends BaseEvent {\n tenantId: string\n registrationStep?: string\n}\n\nexport interface AccountVerifiedEvent extends BaseEvent {\n tenantId: string\n}\n", "import { BaseEvent, Event } from \"./event\"\n\nexport interface AppBackfillSucceededEvent extends BaseEvent {\n appId: string\n automations: number\n datasources: number\n layouts: number\n queries: number\n roles: number\n tables: number\n screens: number\n errors?: string[]\n errorCount?: number\n}\n\nexport interface AppBackfillFailedEvent extends BaseEvent {\n error: string\n}\n\nexport interface TenantBackfillSucceededEvent extends BaseEvent {\n apps: number\n users: number\n\n usage: any\n errors?: [string]\n errorCount?: number\n}\n\nexport interface TenantBackfillFailedEvent extends BaseEvent {\n error: string\n}\n\nexport interface InstallationBackfillSucceededEvent extends BaseEvent {}\n\nexport interface InstallationBackfillFailedEvent extends BaseEvent {\n error: string\n}\n\nexport interface BackfillMetadata extends BaseEvent {\n eventWhitelist: Event[]\n}\n\nexport interface CachedEvent extends BaseEvent {\n event: Event\n properties: any\n}\n", "import { Hosting } from \"..\"\n\n// GROUPS\n\nexport enum GroupType {\n TENANT = \"tenant\",\n INSTALLATION = \"installation\",\n}\n\nexport interface Group {\n id: string\n type: IdentityType\n environment: string\n hosting: Hosting\n}\n\nexport interface TenantGroup extends Group {\n // account level information is associated with the tenant group\n // as we don't have this at the user level\n profession?: string // only available in cloud\n companySize?: string // only available in cloud\n installationId: string\n}\n\nexport interface InstallationGroup extends Group {\n version: string\n}\n\n// IDENTITIES\n\nexport enum IdentityType {\n USER = \"user\",\n TENANT = \"tenant\",\n INSTALLATION = \"installation\",\n}\n\nexport interface HostInfo {\n ipAddress?: string\n userAgent?: string\n}\n\nexport interface Identity {\n id: string\n type: IdentityType\n hosting: Hosting\n environment: string\n installationId?: string\n tenantId?: string\n // usable - no unique format\n realTenantId?: string\n hostInfo?: HostInfo\n}\n\nexport interface UserIdentity extends Identity {\n verified: boolean\n accountHolder: boolean\n providerType?: string\n builder?: boolean\n admin?: boolean\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface GroupCreatedEvent extends BaseEvent {\n groupId: string\n viaScim?: boolean\n audited: {\n name: string\n }\n}\n\nexport interface GroupUpdatedEvent extends BaseEvent {\n groupId: string\n viaScim?: boolean\n audited: {\n name: string\n }\n}\n\nexport interface GroupDeletedEvent extends BaseEvent {\n groupId: string\n viaScim?: boolean\n audited: {\n name: string\n }\n}\n\nexport interface GroupUsersAddedEvent extends BaseEvent {\n count: number\n groupId: string\n viaScim?: boolean\n audited: {\n name: string\n }\n}\n\nexport interface GroupUsersDeletedEvent extends BaseEvent {\n count: number\n groupId: string\n viaScim?: boolean\n audited: {\n name: string\n }\n}\n\nexport interface GroupAddedOnboardingEvent extends BaseEvent {\n groupId: string\n onboarding: boolean\n}\n\nexport interface GroupPermissionsEditedEvent extends BaseEvent {\n permissions: Record<string, string>\n groupId: string\n audited: {\n name: string\n }\n}\n", "import { BaseEvent } from \"./event\"\nimport { PluginSource, PluginType } from \"../../\"\n\nexport interface PluginInitEvent extends BaseEvent {\n type: PluginType\n name: string\n version: string\n description: string\n}\n\nexport interface PluginImportedEvent extends BaseEvent {\n pluginId: string\n type: PluginType\n source: PluginSource\n name: string\n version: string\n description: string\n}\n\nexport interface PluginDeletedEvent extends BaseEvent {\n pluginId: string\n type: PluginType\n name: string\n version: string\n description: string\n}\n", "import { BaseEvent } from \"./event\"\nimport { AppBackupTrigger, AppBackupType } from \"../../documents\"\n\nexport interface AppBackupRestoreEvent extends BaseEvent {\n appId: string\n restoreId: string\n backupCreatedAt: string\n name: string\n}\n\nexport interface AppBackupTriggeredEvent extends BaseEvent {\n backupId: string\n appId: string\n trigger: AppBackupTrigger\n type: AppBackupType\n name: string\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface EnvironmentVariableCreatedEvent extends BaseEvent {\n name: string\n environments: string[]\n}\n\nexport interface EnvironmentVariableDeletedEvent extends BaseEvent {\n name: string\n}\n\nexport interface EnvironmentVariableUpgradePanelOpenedEvent extends BaseEvent {\n userId: string\n}\n", "import { BaseEvent } from \"./event\"\nimport { AuditLogSearchParams } from \"../../api\"\n\nexport interface AuditLogFilteredEvent extends BaseEvent {\n filters: AuditLogSearchParams\n}\n\nexport interface AuditLogDownloadedEvent extends BaseEvent {\n filters: AuditLogSearchParams\n}\n", "export * from \"./app\"\nexport * from \"./auth\"\nexport * from \"./automation\"\nexport * from \"./email\"\nexport * from \"./datasource\"\nexport * from \"./event\"\nexport * from \"./layout\"\nexport * from \"./license\"\nexport * from \"./version\"\nexport * from \"./query\"\nexport * from \"./role\"\nexport * from \"./rows\"\nexport * from \"./screen\"\nexport * from \"./serve\"\nexport * from \"./table\"\nexport * from \"./user\"\nexport * from \"./view\"\nexport * from \"./account\"\nexport * from \"./backfill\"\nexport * from \"./identification\"\nexport * from \"./userGroup\"\nexport * from \"./plugin\"\nexport * from \"./backup\"\nexport * from \"./environmentVariable\"\nexport * from \"./auditLog\"\n", "import { PurchasedPlan, Quotas, Feature, Billing } from \".\"\n\nexport interface License {\n features: Feature[]\n quotas: Quotas\n plan: PurchasedPlan\n billing?: Billing\n testClockId?: string\n}\n", "export enum PlanType {\n FREE = \"free\",\n /** @deprecated */\n PRO = \"pro\",\n /** @deprecated */\n TEAM = \"team\",\n PREMIUM = \"premium\",\n BUSINESS = \"business\",\n ENTERPRISE = \"enterprise\",\n}\n\nexport enum PriceDuration {\n MONTHLY = \"monthly\",\n YEARLY = \"yearly\",\n}\n\nexport interface AvailablePlan {\n type: PlanType\n maxUsers: number\n prices: AvailablePrice[]\n}\n\nexport interface AvailablePrice {\n amount: number\n amountMonthly: number\n currency: string\n duration: PriceDuration\n priceId: string\n}\n\nexport enum PlanModel {\n PER_USER = \"perUser\",\n DAY_PASS = \"dayPass\",\n}\n\nexport interface PurchasedPlan {\n type: PlanType\n model: PlanModel\n usesInvoicing: boolean\n price?: PurchasedPrice\n}\n\nexport interface PurchasedPrice extends AvailablePrice {\n dayPasses: number | undefined\n /** @deprecated - now at the plan level via model */\n isPerUser: boolean\n}\n", "import { PlanType } from \".\"\n\nexport enum QuotaUsageType {\n STATIC = \"static\",\n MONTHLY = \"monthly\",\n}\n\nexport enum QuotaType {\n USAGE = \"usage\",\n CONSTANT = \"constant\",\n}\n\nexport enum StaticQuotaName {\n ROWS = \"rows\",\n APPS = \"apps\",\n USERS = \"users\",\n USER_GROUPS = \"userGroups\",\n PLUGINS = \"plugins\",\n}\n\nexport enum MonthlyQuotaName {\n QUERIES = \"queries\",\n AUTOMATIONS = \"automations\",\n DAY_PASSES = \"dayPasses\",\n}\n\nexport enum ConstantQuotaName {\n AUTOMATION_LOG_RETENTION_DAYS = \"automationLogRetentionDays\",\n APP_BACKUPS_RETENTION_DAYS = \"appBackupRetentionDays\",\n}\n\nexport type MeteredQuotaName = StaticQuotaName | MonthlyQuotaName\nexport type QuotaName = StaticQuotaName | MonthlyQuotaName | ConstantQuotaName\n\nexport const isStaticQuota = (\n quotaType: QuotaType,\n usageType: QuotaUsageType,\n name: QuotaName\n): name is StaticQuotaName => {\n return quotaType === QuotaType.USAGE && usageType === QuotaUsageType.STATIC\n}\n\nexport const isMonthlyQuota = (\n quotaType: QuotaType,\n usageType: QuotaUsageType,\n name: QuotaName\n): name is MonthlyQuotaName => {\n return quotaType === QuotaType.USAGE && usageType === QuotaUsageType.MONTHLY\n}\n\nexport const isConstantQuota = (\n quotaType: QuotaType,\n name: QuotaName\n): name is ConstantQuotaName => {\n return quotaType === QuotaType.CONSTANT\n}\n\nexport type PlanQuotas = { [key in PlanType]: Quotas | undefined }\n\nexport type MonthlyQuotas = {\n [MonthlyQuotaName.QUERIES]: Quota\n [MonthlyQuotaName.AUTOMATIONS]: Quota\n [MonthlyQuotaName.DAY_PASSES]: Quota\n}\n\nexport type StaticQuotas = {\n [StaticQuotaName.ROWS]: Quota\n [StaticQuotaName.APPS]: Quota\n [StaticQuotaName.USERS]: Quota\n [StaticQuotaName.USER_GROUPS]: Quota\n [StaticQuotaName.PLUGINS]: Quota\n}\n\nexport type ConstantQuotas = {\n [ConstantQuotaName.AUTOMATION_LOG_RETENTION_DAYS]: Quota\n [ConstantQuotaName.APP_BACKUPS_RETENTION_DAYS]: Quota\n}\n\nexport type Quotas = {\n [QuotaType.USAGE]: {\n [QuotaUsageType.MONTHLY]: MonthlyQuotas\n [QuotaUsageType.STATIC]: StaticQuotas\n }\n [QuotaType.CONSTANT]: ConstantQuotas\n}\n\nexport interface Quota {\n name: string\n value: number\n /**\n * Array of whole numbers (1-100) that dictate the percentage that this quota should trigger\n * at in relation to the corresponding usage inside budibase.\n *\n * Triggering results in a budibase installation sending a request to account-portal,\n * which can have subsequent effects such as sending emails to users.\n */\n triggers: number[]\n startDate?: number\n}\n", "import { PlanType } from \"./plan\"\n\nexport enum Feature {\n USER_GROUPS = \"userGroups\",\n APP_BACKUPS = \"appBackups\",\n ENVIRONMENT_VARIABLES = \"environmentVariables\",\n AUDIT_LOGS = \"auditLogs\",\n ENFORCEABLE_SSO = \"enforceableSSO\",\n BRANDING = \"branding\",\n SCIM = \"scim\",\n SYNC_AUTOMATIONS = \"syncAutomations\",\n}\n\nexport type PlanFeatures = { [key in PlanType]: Feature[] | undefined }\n", "import { PriceDuration } from \"./plan\"\n\nexport interface Customer {\n balance: number | null | undefined\n currency: string | null | undefined\n}\n\nexport interface Subscription {\n amount: number\n currency: string\n quantity: number\n duration: PriceDuration\n cancelAt: number | null | undefined\n currentPeriodStart: number\n currentPeriodEnd: number\n status: string\n pastDueAt?: number | null\n downgradeAt?: number\n}\n\nexport interface Billing {\n customer: Customer\n subscription?: Subscription\n}\n", "export * from \"./license\"\nexport * from \"./plan\"\nexport * from \"./quota\"\nexport * from \"./feature\"\nexport * from \"./billing\"\n", "export interface Migration extends MigrationDefinition {\n appOpts?: object\n fn: Function\n silent?: boolean\n preventRetry?: boolean\n}\n\nexport enum MigrationType {\n // run once per tenant, recorded in global db, global db is provided as an argument\n GLOBAL = \"global\",\n // run per app, recorded in each app db, app db is provided as an argument\n APP = \"app\",\n // run once, recorded in global info db, global info db is provided as an argument\n INSTALLATION = \"installation\",\n}\n\nexport interface MigrationNoOpOptions {\n type: MigrationType\n tenantId: string\n appId?: string\n}\n\n/**\n * e.g.\n * {\n * tenantIds: ['bb'],\n * force: {\n * global: ['quota_1']\n * }\n * }\n */\nexport interface MigrationOptions {\n tenantIds?: string[]\n force?: {\n [type: string]: string[]\n }\n noOp?: MigrationNoOpOptions\n}\n\nexport enum MigrationName {\n USER_EMAIL_VIEW_CASING = \"user_email_view_casing\",\n APP_URLS = \"app_urls\",\n EVENT_APP_BACKFILL = \"event_app_backfill\",\n EVENT_GLOBAL_BACKFILL = \"event_global_backfill\",\n EVENT_INSTALLATION_BACKFILL = \"event_installation_backfill\",\n GLOBAL_INFO_SYNC_USERS = \"global_info_sync_users\",\n TABLE_SETTINGS_LINKS_TO_ACTIONS = \"table_settings_links_to_actions\",\n // increment this number to re-activate this migration\n SYNC_QUOTAS = \"sync_quotas_1\",\n}\n\nexport interface MigrationDefinition {\n type: MigrationType\n name: MigrationName\n}\n", "import { Table } from \"../documents\"\n\nexport const PASSWORD_REPLACEMENT = \"--secret-value--\"\n\nexport enum Operation {\n CREATE = \"CREATE\",\n READ = \"READ\",\n UPDATE = \"UPDATE\",\n DELETE = \"DELETE\",\n BULK_CREATE = \"BULK_CREATE\",\n CREATE_TABLE = \"CREATE_TABLE\",\n UPDATE_TABLE = \"UPDATE_TABLE\",\n DELETE_TABLE = \"DELETE_TABLE\",\n}\n\nexport enum SortDirection {\n ASCENDING = \"ASCENDING\",\n DESCENDING = \"DESCENDING\",\n}\n\nexport enum QueryType {\n SQL = \"sql\",\n JSON = \"json\",\n FIELDS = \"fields\",\n}\n\nexport enum DatasourceFieldType {\n STRING = \"string\",\n CODE = \"code\",\n LONGFORM = \"longForm\",\n BOOLEAN = \"boolean\",\n NUMBER = \"number\",\n PASSWORD = \"password\",\n LIST = \"list\",\n OBJECT = \"object\",\n JSON = \"json\",\n FILE = \"file\",\n FIELD_GROUP = \"fieldGroup\",\n}\n\nexport enum SourceName {\n POSTGRES = \"POSTGRES\",\n DYNAMODB = \"DYNAMODB\",\n MONGODB = \"MONGODB\",\n ELASTICSEARCH = \"ELASTICSEARCH\",\n COUCHDB = \"COUCHDB\",\n SQL_SERVER = \"SQL_SERVER\",\n S3 = \"S3\",\n AIRTABLE = \"AIRTABLE\",\n MYSQL = \"MYSQL\",\n ARANGODB = \"ARANGODB\",\n REST = \"REST\",\n ORACLE = \"ORACLE\",\n GOOGLE_SHEETS = \"GOOGLE_SHEETS\",\n FIRESTORE = \"FIRESTORE\",\n REDIS = \"REDIS\",\n SNOWFLAKE = \"SNOWFLAKE\",\n}\n\nexport enum IncludeRelationship {\n INCLUDE = 1,\n EXCLUDE = 0,\n}\n\nexport enum FilterType {\n STRING = \"string\",\n FUZZY = \"fuzzy\",\n RANGE = \"range\",\n EQUAL = \"equal\",\n NOT_EQUAL = \"notEqual\",\n EMPTY = \"empty\",\n NOT_EMPTY = \"notEmpty\",\n ONE_OF = \"oneOf\",\n}\n\nexport enum DatasourceFeature {\n CONNECTION_CHECKING = \"connection\",\n FETCH_TABLE_NAMES = \"fetch_table_names\",\n}\n\nexport interface StepDefinition {\n key: string\n template: string\n}\n\nexport interface QueryDefinition {\n type: QueryType\n displayName?: string\n readable?: boolean\n customisable?: boolean\n fields?: object\n urlDisplay?: boolean\n steps?: Array<StepDefinition>\n}\n\nexport interface ExtraQueryConfig {\n [key: string]: {\n displayName: string\n type: string\n required: boolean\n data?: object\n }\n}\n\nexport interface DatasourceConfig {\n [key: string]: {\n type: string\n display?: string\n required?: boolean\n default?: any\n deprecated?: boolean\n }\n}\n\nexport interface Integration {\n docs: string\n plus?: boolean\n auth?: { type: string }\n features?: Partial<Record<DatasourceFeature, boolean>>\n relationships?: boolean\n description: string\n friendlyName: string\n type?: string\n iconUrl?: string\n datasource: DatasourceConfig\n query: {\n [key: string]: QueryDefinition\n }\n extra?: ExtraQueryConfig\n}\n\nexport type ConnectionInfo = {\n connected: boolean\n error?: string\n}\n\nexport interface IntegrationBase {\n create?(query: any): Promise<any[] | any>\n read?(query: any): Promise<any[] | any>\n update?(query: any): Promise<any[] | any>\n delete?(query: any): Promise<any[] | any>\n testConnection?(): Promise<ConnectionInfo>\n}\n\nexport interface DatasourcePlus extends IntegrationBase {\n tables: Record<string, Table>\n schemaErrors: Record<string, string>\n\n // if the datasource supports the use of bindings directly (to protect against SQL injection)\n // this returns the format of the identifier\n getBindingIdentifier(): string\n getStringConcat(parts: string[]): string\n buildSchema(datasourceId: string, entities: Record<string, Table>): any\n getTableNames(): Promise<string[]>\n}\n", "import { Operation, SortDirection } from \"./datasources\"\nimport { Row, Table } from \"../documents\"\nimport { SortType } from \"../api\"\n\nexport interface SearchFilters {\n allOr?: boolean\n string?: {\n [key: string]: string\n }\n fuzzy?: {\n [key: string]: string\n }\n range?: {\n [key: string]: {\n high: number | string\n low: number | string\n }\n }\n equal?: {\n [key: string]: any\n }\n notEqual?: {\n [key: string]: any\n }\n empty?: {\n [key: string]: any\n }\n notEmpty?: {\n [key: string]: any\n }\n oneOf?: {\n [key: string]: any[]\n }\n contains?: {\n [key: string]: any[]\n }\n notContains?: {\n [key: string]: any[]\n }\n containsAny?: {\n [key: string]: any[]\n }\n}\n\nexport interface SortJson {\n [key: string]: {\n direction: SortDirection\n type?: SortType\n }\n}\n\nexport interface PaginationJson {\n limit: number\n page?: string | number\n}\n\nexport interface RenameColumn {\n old: string\n updated: string\n}\n\nexport interface RelationshipsJson {\n through?: string\n from?: string\n to?: string\n fromPrimary?: string\n toPrimary?: string\n tableName: string\n column: string\n}\n\nexport interface QueryJson {\n endpoint: {\n datasourceId: string\n entityId: string\n operation: Operation\n schema?: string\n }\n resource?: {\n fields: string[]\n }\n filters?: SearchFilters\n sort?: SortJson\n paginate?: PaginationJson\n body?: Row | Row[]\n table?: Table\n meta?: {\n table?: Table\n tables?: Record<string, Table>\n renamed?: RenameColumn\n }\n extra?: {\n idFilter?: SearchFilters\n }\n relationships?: RelationshipsJson[]\n}\n\nexport interface SqlQuery {\n sql: string\n bindings?: string[]\n}\n", "import { Context, Request } from \"koa\"\nimport { User, Role, UserRoles, Account } from \"../documents\"\nimport { FeatureFlag, License } from \"../sdk\"\nimport { Files } from \"formidable\"\n\nexport interface ContextUser extends Omit<User, \"roles\"> {\n globalId?: string\n license?: License\n userId?: string\n roleId?: string | null\n role?: Role\n roles?: UserRoles\n csrfToken?: string\n featureFlags?: FeatureFlag[]\n accountPortalAccess?: boolean\n account?: Account\n}\n\n/**\n * Add support for koa-body in context.\n */\nexport interface BBRequest<RequestBody> extends Request {\n body: RequestBody\n files?: Files\n}\n\n/**\n * Basic context with no user.\n */\nexport interface Ctx<RequestBody = any, ResponseBody = any> extends Context {\n request: BBRequest<RequestBody>\n body: ResponseBody\n}\n\n/**\n * Authenticated context.\n */\nexport interface UserCtx<RequestBody = any, ResponseBody = any>\n extends Ctx<RequestBody, ResponseBody> {\n user: ContextUser\n}\n\n/**\n * @deprecated: Use UserCtx / Ctx appropriately\n * Authenticated context.\n */\nexport interface BBContext extends Ctx {\n user?: ContextUser\n}\n", "import { BBContext } from \"./koa\"\nimport { Hosting } from \"./hosting\"\n\nexport interface AuthToken {\n userId: string\n tenantId: string\n sessionId: string\n}\n\nexport interface CreateSession {\n sessionId: string\n tenantId: string\n csrfToken?: string\n hosting?: Hosting\n}\n\nexport interface Session extends CreateSession {\n userId: string\n lastAccessedAt: string\n createdAt: string\n // make optional attributes required\n csrfToken: string\n}\n\nexport interface SessionKey {\n key: string\n}\n\nexport interface ScannedSession {\n value: Session\n}\n\nexport interface PlatformLogoutOpts {\n ctx: BBContext\n userId: string\n keepActiveSession?: boolean\n}\n", "import Redlock from \"redlock\"\n\nexport enum LockType {\n /**\n * If this lock is already held the attempted operation will not be performed.\n * No retries will take place and no error will be thrown.\n */\n TRY_ONCE = \"try_once\",\n TRY_TWICE = \"try_twice\",\n DEFAULT = \"default\",\n DELAY_500 = \"delay_500\",\n CUSTOM = \"custom\",\n}\n\nexport enum LockName {\n MIGRATIONS = \"migrations\",\n TRIGGER_QUOTA = \"trigger_quota\",\n SYNC_ACCOUNT_LICENSE = \"sync_account_license\",\n UPDATE_TENANTS_DOC = \"update_tenants_doc\",\n PERSIST_WRITETHROUGH = \"persist_writethrough\",\n QUOTA_USAGE_EVENT = \"quota_usage_event\",\n}\n\nexport interface LockOptions {\n /**\n * The lock type determines which client to use\n */\n type: LockType\n /**\n * The custom options to use when creating the redlock instance\n * type must be set to custom for the options to be applied\n */\n customOptions?: Redlock.Options\n /**\n * The name for the lock\n */\n name: LockName\n /**\n * The ttl to auto-expire the lock if not unlocked manually\n */\n ttl: number\n /**\n * The individual resource to lock. This is useful for locking around very specific identifiers, e.g. a document that is prone to conflicts\n */\n resource?: string\n /**\n * This is a system-wide lock - don't use tenancy in lock key\n */\n systemLock?: boolean\n}\n", "import Nano from \"@budibase/nano\"\nimport { AllDocsResponse, AnyDocument, Document } from \"../\"\nimport { Writable } from \"stream\"\nimport PouchDB from \"pouchdb\"\n\nexport enum SearchIndex {\n ROWS = \"rows\",\n AUDIT = \"audit\",\n USER = \"user\",\n}\n\nexport type PouchOptions = {\n inMemory?: boolean\n replication?: boolean\n onDisk?: boolean\n find?: boolean\n}\n\nexport enum SortOption {\n ASCENDING = \"asc\",\n DESCENDING = \"desc\",\n}\n\nexport type CouchFindOptions = {\n selector: PouchDB.Find.Selector\n fields?: string[]\n sort?: {\n [key: string]: SortOption\n }[]\n limit?: number\n skip?: number\n bookmark?: string\n}\n\nexport type DatabaseOpts = {\n skip_setup?: boolean\n}\n\nexport type DatabasePutOpts = {\n force?: boolean\n}\n\nexport type DatabaseCreateIndexOpts = {\n index: {\n fields: string[]\n name?: string | undefined\n ddoc?: string | undefined\n type?: string | undefined\n }\n}\n\nexport type DatabaseDeleteIndexOpts = {\n name: string\n ddoc: string\n type?: string | undefined\n}\n\nexport type DatabaseQueryOpts = {\n include_docs?: boolean\n startkey?: string\n endkey?: string\n limit?: number\n skip?: number\n descending?: boolean\n key?: string\n keys?: string[]\n group?: boolean\n startkey_docid?: string\n}\n\nexport const isDocument = (doc: any): doc is Document => {\n return typeof doc === \"object\" && doc._id && doc._rev\n}\n\nexport interface DatabaseDumpOpts {\n filter?: (doc: AnyDocument) => boolean\n batch_size?: number\n batch_limit?: number\n style?: \"main_only\" | \"all_docs\"\n timeout?: number\n doc_ids?: string[]\n query_params?: any\n view?: string\n selector?: any\n}\n\nexport interface Database {\n name: string\n\n exists(): Promise<boolean>\n checkSetup(): Promise<Nano.DocumentScope<any>>\n get<T>(id?: string): Promise<T | any>\n remove(\n id: string | Document,\n rev?: string\n ): Promise<Nano.DocumentDestroyResponse>\n put(\n document: AnyDocument,\n opts?: DatabasePutOpts\n ): Promise<Nano.DocumentInsertResponse>\n bulkDocs(documents: AnyDocument[]): Promise<Nano.DocumentBulkResponse[]>\n allDocs<T>(params: DatabaseQueryOpts): Promise<AllDocsResponse<T>>\n query<T>(\n viewName: string,\n params: DatabaseQueryOpts\n ): Promise<AllDocsResponse<T>>\n destroy(): Promise<Nano.OkResponse | void>\n compact(): Promise<Nano.OkResponse | void>\n // these are all PouchDB related functions that are rarely used - in future\n // should be replaced by better typed/non-pouch implemented methods\n dump(stream: Writable, opts?: DatabaseDumpOpts): Promise<any>\n load(...args: any[]): Promise<any>\n createIndex(...args: any[]): Promise<any>\n deleteIndex(...args: any[]): Promise<any>\n getIndexes(...args: any[]): Promise<any>\n}\n", "export interface EndpointMatcher {\n /**\n * The HTTP Path. e.g. /api/things/:thingId\n */\n route: string\n /**\n * The HTTP Verb. e.g. GET, POST, etc.\n * ALL is also accepted to cover all verbs.\n */\n method: string\n /**\n * The route must match exactly - not just begins with\n */\n strict?: boolean\n}\n\nexport interface RegexMatcher {\n regex: RegExp\n method: string\n strict: boolean\n route: string\n}\n", "export interface GetTenantIdOptions {\n allowNoTenant?: boolean\n excludeStrategies?: TenantResolutionStrategy[]\n includeStrategies?: TenantResolutionStrategy[]\n}\n\nexport enum TenantResolutionStrategy {\n USER = \"user\",\n HEADER = \"header\",\n QUERY = \"query\",\n SUBDOMAIN = \"subdomain\",\n PATH = \"path\",\n}\n", "export * from \"./matchers\"\nexport * from \"./tenancy\"\n", "export enum FeatureFlag {\n LICENSING = \"LICENSING\",\n}\n\nexport interface TenantFeatureFlags {\n [key: string]: FeatureFlag[]\n}\n", "export enum AppEnvironment {\n PRODUCTION = \"production\",\n DEVELOPMENT = \"development\",\n}\n", "import { Event, HostInfo } from \"./events\"\nimport { AuditLogDoc } from \"../documents\"\n\nexport type AuditWriteOpts = {\n appId?: string\n timestamp?: string | number\n userId?: string\n hostInfo?: HostInfo\n}\n\nexport type AuditLogFn = (\n event: Event,\n metadata: any,\n opts: AuditWriteOpts\n) => Promise<AuditLogDoc | undefined>\n\nexport type AuditLogQueueEvent = {\n event: Event\n properties: any\n opts: AuditWriteOpts\n tenantId: string\n}\n", "import {\n OAuth2,\n SSOProfileJson,\n SSOProviderType,\n SSOUser,\n User,\n} from \"../documents\"\nimport { SaveUserOpts } from \"./user\"\n\nexport interface JwtClaims {\n preferred_username?: string\n email?: string\n}\n\nexport interface SSOAuthDetails {\n oauth2: OAuth2\n provider: string\n providerType: SSOProviderType\n userId: string\n email?: string\n profile?: SSOProfile\n}\n\nexport interface SSOProfile {\n id: string\n name?: {\n givenName?: string\n familyName?: string\n }\n _json: SSOProfileJson\n provider?: string\n}\n\nexport type SaveSSOUserFunction = (\n user: SSOUser,\n opts: SaveUserOpts\n) => Promise<User>\n", "export interface SaveUserOpts {\n hashPassword?: boolean\n requirePassword?: boolean\n currentUserId?: string\n}\n", "import { Event } from \"../events\"\n\nexport enum CommandWord {\n BACKUPS = \"backups\",\n HOSTING = \"hosting\",\n ANALYTICS = \"analytics\",\n HELP = \"help\",\n PLUGIN = \"plugins\",\n}\n\nexport enum InitType {\n QUICK = \"quick\",\n DIGITAL_OCEAN = \"do\",\n}\n\nexport const AnalyticsEvent = {\n OptOut: \"analytics:opt:out\",\n OptIn: \"analytics:opt:in\",\n SelfHostInit: \"hosting:init\",\n PluginInit: Event.PLUGIN_INIT,\n}\n", "export * from \"./constants\"\n", "export interface SocketSession {\n _id: string\n email: string\n firstName?: string\n lastName?: string\n sessionId: string\n room?: string\n}\n", "export * from \"./automations\"\nexport * from \"./hosting\"\nexport * from \"./context\"\nexport * from \"./events\"\nexport * from \"./licensing\"\nexport * from \"./migrations\"\nexport * from \"./datasources\"\nexport * from \"./search\"\nexport * from \"./koa\"\nexport * from \"./auth\"\nexport * from \"./locks\"\nexport * from \"./db\"\nexport * from \"./middleware\"\nexport * from \"./featureFlag\"\nexport * from \"./environmentVariables\"\nexport * from \"./auditLogs\"\nexport * from \"./sso\"\nexport * from \"./user\"\nexport * from \"./cli\"\nexport * from \"./websocket\"\n", "import { Feature, Hosting, License, PlanType, Quotas } from \"../../sdk\"\nimport { DeepPartial } from \"../../shared\"\nimport { QuotaUsage } from \"../global\"\n\nexport interface CreateAccount {\n email: string\n tenantId: string\n hosting: Hosting\n authType: AuthType\n // optional fields - for sso based sign ups\n registrationStep?: string\n // profile\n tenantName?: string\n name?: string\n size?: string\n profession?: string\n}\n\nexport interface CreatePassswordAccount extends CreateAccount {\n password: string\n}\n\nexport const isCreatePasswordAccount = (\n account: CreateAccount\n): account is CreatePassswordAccount => account.authType === AuthType.PASSWORD\n\nexport interface LicenseOverrides {\n features?: Feature[]\n quotas?: DeepPartial<Quotas>\n}\n\nexport interface Account extends CreateAccount {\n // generated\n accountId: string\n createdAt: number\n // registration\n verified: boolean\n verificationSent: boolean\n // licensing\n tier: string // deprecated\n planType?: PlanType\n /** @deprecated */\n planTier?: number\n license?: License\n installId?: string\n installTenantId?: string\n installVersion?: string\n stripeCustomerId?: string\n licenseKey?: string\n licenseKeyActivatedAt?: number\n licenseRequestedAt?: number\n licenseOverrides?: LicenseOverrides\n quotaUsage?: QuotaUsage\n}\n\nexport interface PasswordAccount extends Account {\n password: string\n}\n\nexport const isPasswordAccount = (\n account: Account\n): account is PasswordAccount =>\n account.authType === AuthType.PASSWORD && account.hosting === Hosting.SELF\n\nexport interface CloudAccount extends Account {\n password?: string\n budibaseUserId: string\n}\n\nexport const isCloudAccount = (account: Account): account is CloudAccount =>\n account.hosting === Hosting.CLOUD\n\nexport const isSelfHostAccount = (account: Account) =>\n account.hosting === Hosting.SELF\n\nexport const isSSOAccount = (account: Account): account is SSOAccount =>\n account.authType === AuthType.SSO\n\nexport enum AccountSSOProviderType {\n GOOGLE = \"google\",\n MICROSOFT = \"microsoft\",\n}\n\nexport enum AccountSSOProvider {\n GOOGLE = \"google\",\n MICROSOFT = \"microsoft\",\n}\n\nexport interface AccountSSO {\n provider: AccountSSOProvider\n providerType: AccountSSOProviderType\n oauth2?: OAuthTokens\n pictureUrl?: string\n thirdPartyProfile: any // TODO: define what the google profile looks like\n}\n\nexport type SSOAccount = (Account | CloudAccount) & AccountSSO\n\nexport enum AuthType {\n SSO = \"sso\",\n PASSWORD = \"password\",\n}\n\nexport interface OAuthTokens {\n accessToken: string\n refreshToken: string\n}\n", "export interface CreateAccountUserActivity {\n accountId: string\n userId: string\n timestamp: number\n}\n\nexport interface AccountUserActivity extends CreateAccountUserActivity {\n PK: string\n SK: string\n}\n", "export * from \"./account\"\nexport * from \"./user\"\n", "import { User, Document } from \"../\"\n\nexport type AppMetadataErrors = { [key: string]: string[] }\n\nexport interface App extends Document {\n appId: string\n type: string\n version: string\n componentLibraries: string[]\n name: string\n url: string | undefined\n template: string | undefined\n instance: AppInstance\n tenantId: string\n status: string\n theme?: string\n customTheme?: AppCustomTheme\n revertableVersion?: string\n lockedBy?: User\n navigation?: AppNavigation\n automationErrors?: AppMetadataErrors\n icon?: AppIcon\n}\n\nexport interface AppInstance {\n _id: string\n}\n\nexport interface AppNavigation {\n navigation: string\n title: string\n navWidth: string\n sticky?: boolean\n hideLogo?: boolean\n logoUrl?: string\n hideTitle?: boolean\n navBackground?: string\n navTextColor?: string\n links?: AppNavigationLink[]\n}\n\nexport interface AppNavigationLink {\n text: string\n url: string\n id?: string\n roleId?: string\n}\n\nexport interface AppCustomTheme {\n buttonBorderRadius?: string\n primaryColor?: string\n primaryColorHover?: string\n\n // Used to exist before new design UI\n navTextColor?: string\n navBackground?: string\n}\n\nexport interface AppIcon {\n name: string\n color: string\n}\n", "import { Document } from \"../document\"\nimport { EventEmitter } from \"events\"\n\nexport enum AutomationIOType {\n OBJECT = \"object\",\n STRING = \"string\",\n BOOLEAN = \"boolean\",\n NUMBER = \"number\",\n ARRAY = \"array\",\n JSON = \"json\",\n}\n\nexport enum AutomationCustomIOType {\n TABLE = \"table\",\n ROW = \"row\",\n ROWS = \"rows\",\n WIDE = \"wide\",\n QUERY = \"query\",\n QUERY_PARAMS = \"queryParams\",\n QUERY_LIMIT = \"queryLimit\",\n LOOP_OPTION = \"loopOption\",\n ITEM = \"item\",\n CODE = \"code\",\n FILTERS = \"filters\",\n COLUMN = \"column\",\n TRIGGER_SCHEMA = \"triggerSchema\",\n CRON = \"cron\",\n WEBHOOK_URL = \"webhookUrl\",\n}\n\nexport enum AutomationTriggerStepId {\n ROW_SAVED = \"ROW_SAVED\",\n ROW_UPDATED = \"ROW_UPDATED\",\n ROW_DELETED = \"ROW_DELETED\",\n WEBHOOK = \"WEBHOOK\",\n APP = \"APP\",\n CRON = \"CRON\",\n}\n\nexport enum AutomationStepType {\n LOGIC = \"LOGIC\",\n ACTION = \"ACTION\",\n TRIGGER = \"TRIGGER\",\n}\n\nexport enum AutomationActionStepId {\n SEND_EMAIL_SMTP = \"SEND_EMAIL_SMTP\",\n CREATE_ROW = \"CREATE_ROW\",\n UPDATE_ROW = \"UPDATE_ROW\",\n DELETE_ROW = \"DELETE_ROW\",\n EXECUTE_BASH = \"EXECUTE_BASH\",\n OUTGOING_WEBHOOK = \"OUTGOING_WEBHOOK\",\n EXECUTE_SCRIPT = \"EXECUTE_SCRIPT\",\n EXECUTE_QUERY = \"EXECUTE_QUERY\",\n SERVER_LOG = \"SERVER_LOG\",\n DELAY = \"DELAY\",\n FILTER = \"FILTER\",\n QUERY_ROWS = \"QUERY_ROWS\",\n LOOP = \"LOOP\",\n COLLECT = \"COLLECT\",\n OPENAI = \"OPENAI\",\n // these used to be lowercase step IDs, maintain for backwards compat\n discord = \"discord\",\n slack = \"slack\",\n zapier = \"zapier\",\n integromat = \"integromat\",\n}\n\nexport const AutomationStepIdArray = [\n ...Object.values(AutomationActionStepId),\n ...Object.values(AutomationTriggerStepId),\n]\n\nexport interface Automation extends Document {\n definition: {\n steps: AutomationStep[]\n trigger: AutomationTrigger\n }\n screenId?: string\n uiTree?: any\n appId: string\n live?: boolean\n name: string\n internal?: boolean\n type?: string\n}\n\ninterface BaseIOStructure {\n type?: AutomationIOType\n customType?: AutomationCustomIOType\n title?: string\n description?: string\n enum?: string[]\n pretty?: string[]\n properties?: {\n [key: string]: BaseIOStructure\n }\n required?: string[]\n}\n\ninterface InputOutputBlock {\n properties: {\n [key: string]: BaseIOStructure\n }\n required?: string[]\n}\n\nexport interface AutomationStepSchema {\n name: string\n stepTitle?: string\n tagline: string\n icon: string\n description: string\n type: AutomationStepType\n internal?: boolean\n deprecated?: boolean\n stepId: AutomationTriggerStepId | AutomationActionStepId\n blockToLoop?: string\n inputs: {\n [key: string]: any\n }\n schema: {\n inputs: InputOutputBlock\n outputs: InputOutputBlock\n }\n custom?: boolean\n features?: Partial<Record<AutomationFeature, boolean>>\n}\n\nexport enum AutomationFeature {\n LOOPING = \"LOOPING\",\n}\n\nexport interface AutomationStep extends AutomationStepSchema {\n id: string\n}\n\nexport interface AutomationTriggerSchema extends AutomationStepSchema {\n event?: string\n cronJobId?: string\n}\n\nexport interface AutomationTrigger extends AutomationTriggerSchema {\n id: string\n}\n\nexport enum AutomationStatus {\n SUCCESS = \"success\",\n ERROR = \"error\",\n STOPPED = \"stopped\",\n STOPPED_ERROR = \"stopped_error\",\n NO_ITERATIONS = \"no_iterations\",\n}\n\nexport interface AutomationResults {\n automationId?: string\n status?: AutomationStatus\n trigger?: any\n steps: {\n stepId: AutomationTriggerStepId | AutomationActionStepId\n inputs: {\n [key: string]: any\n }\n outputs: {\n [key: string]: any\n }\n }[]\n}\n\nexport interface AutomationLog extends AutomationResults, Document {\n automationName: string\n _rev?: string\n}\n\nexport interface AutomationLogPage {\n data: AutomationLog[]\n hasNextPage: boolean\n nextPage?: string\n}\n\nexport type AutomationStepInput = {\n inputs: Record<string, any>\n context: Record<string, any>\n emitter: EventEmitter\n appId: string\n apiKey?: string\n}\n\nexport interface AutomationMetadata extends Document {\n errorCount?: number\n automationChainCount?: number\n}\n", "import { Document } from \"../document\"\nimport { SourceName } from \"../../sdk\"\nimport { Table } from \"./table\"\n\nexport interface Datasource extends Document {\n type: string\n name?: string\n source: SourceName\n // the config is defined by the schema\n config?: {\n [key: string]: string | number | boolean | any[]\n }\n plus?: boolean\n entities?: {\n [key: string]: Table\n }\n}\n\nexport enum RestAuthType {\n BASIC = \"basic\",\n BEARER = \"bearer\",\n}\n\nexport interface RestBasicAuthConfig {\n username: string\n password: string\n}\n\nexport interface RestBearerAuthConfig {\n token: string\n}\n\nexport interface RestAuthConfig {\n _id: string\n name: string\n type: RestAuthType\n config: RestBasicAuthConfig | RestBearerAuthConfig\n}\n\nexport interface RestConfig {\n url: string\n rejectUnauthorized: boolean\n defaultHeaders: {\n [key: string]: any\n }\n legacyHttpParser: boolean\n authConfigs: RestAuthConfig[]\n staticVariables: {\n [key: string]: string\n }\n dynamicVariables: [\n {\n name: string\n queryId: string\n value: string\n }\n ]\n}\n", "import { Document } from \"../document\"\n\nexport interface Layout extends Document {\n props: any\n}\n", "import { Document } from \"../document\"\n\nexport interface Query extends Document {\n datasourceId: string\n name: string\n parameters: QueryParameter[]\n fields: RestQueryFields | any\n transformer: string | null\n schema: any\n readable: boolean\n queryVerb: string\n}\n\nexport interface QueryParameter {\n name: string\n default: string\n}\n\nexport interface RestQueryFields {\n path: string\n queryString?: string\n headers: { [key: string]: any }\n disabledHeaders: { [key: string]: any }\n requestBody: any\n bodyType: string\n json: object\n method: string\n authConfigId: string\n pagination: PaginationConfig | null\n paginationValues: PaginationValues | null\n}\n\nexport interface PaginationConfig {\n type: string\n location: string\n pageParam: string\n sizeParam: string | null\n responseParam: string | null\n}\n\nexport interface PaginationValues {\n page: string | number | null\n limit: number | null\n}\n\nexport interface PreviewQueryRequest extends Omit<Query, \"parameters\"> {\n parameters: {}\n flags?: {\n urlName?: boolean\n }\n}\n", "import { Document } from \"../document\"\n\nexport interface Role extends Document {\n permissionId: string\n inherits?: string\n permissions: { [key: string]: string[] }\n}\n", "import { Document } from \"../document\"\nimport { View } from \"./view\"\nimport { RenameColumn } from \"../../sdk\"\nimport { FieldType } from \"./row\"\n\nexport enum RelationshipTypes {\n ONE_TO_MANY = \"one-to-many\",\n MANY_TO_ONE = \"many-to-one\",\n MANY_TO_MANY = \"many-to-many\",\n}\n\nexport interface FieldSchema {\n type: FieldType\n externalType?: string\n fieldName?: string\n name: string\n sortable?: boolean\n tableId?: string\n relationshipType?: RelationshipTypes\n through?: string\n foreignKey?: string\n icon?: string\n autocolumn?: boolean\n subtype?: string\n throughFrom?: string\n throughTo?: string\n formula?: string\n formulaType?: string\n main?: boolean\n ignoreTimezones?: boolean\n timeOnly?: boolean\n lastID?: number\n useRichText?: boolean | null\n order?: number\n width?: number\n meta?: {\n toTable: string\n toKey: string\n }\n constraints?: {\n type?: string\n email?: boolean\n inclusion?: string[]\n length?: {\n minimum?: string | number | null\n maximum?: string | number | null\n }\n numericality?: {\n greaterThanOrEqualTo: string | null\n lessThanOrEqualTo: string | null\n }\n presence?:\n | boolean\n | {\n allowEmpty?: boolean\n }\n datetime?: {\n latest: string\n earliest: string\n }\n }\n}\n\nexport interface TableSchema {\n [key: string]: FieldSchema\n}\n\nexport interface Table extends Document {\n type?: string\n views?: { [key: string]: View }\n name: string\n primary?: string[]\n schema: TableSchema\n primaryDisplay?: string\n sourceId?: string\n relatedFormula?: string[]\n constrained?: string[]\n sql?: boolean\n indexes?: { [key: string]: any }\n rows?: { [key: string]: any }\n created?: boolean\n rowHeight?: number\n}\n\nexport interface TableRequest extends Table {\n _rename?: RenameColumn\n created?: boolean\n}\n", "import { Document } from \"../document\"\nimport { Component } from \"./component\"\n\nexport interface ScreenProps extends Component {\n size?: string\n gap?: string\n direction?: string\n vAlign?: string\n hAlign?: string\n}\n\nexport interface ScreenRouting {\n route: string\n roleId: string\n homeScreen?: boolean\n}\n\nexport interface Screen extends Document {\n layoutId?: string\n showNavigation?: boolean\n width?: string\n routing: ScreenRouting\n props: ScreenProps\n name?: string\n}\n", "export interface View {\n name: string\n tableId: string\n field?: string\n filters: ViewFilter[]\n schema: ViewSchema\n calculation?: ViewCalculation\n map?: string\n reduce?: any\n meta?: Record<string, any>\n}\n\nexport type ViewSchema = ViewCountOrSumSchema | ViewStatisticsSchema\n\nexport interface ViewCountOrSumSchema {\n field: string\n value: string\n}\n\n/**\n e.g:\n \"min\": {\n \"type\": \"number\"\n },\n \"max\": {\n \"type\": \"number\"\n }\n */\nexport interface ViewStatisticsSchema {\n [key: string]: {\n type: string\n }\n}\n\nexport interface ViewFilter {\n value?: any\n condition: string\n key: string\n conjunction?: string\n}\n\nexport enum ViewCalculation {\n SUM = \"sum\",\n COUNT = \"count\",\n STATISTICS = \"stats\",\n}\n", "export interface Document {\n _id?: string\n _rev?: string\n createdAt?: string | number\n updatedAt?: string\n}\n\nexport interface AnyDocument extends Document {\n [key: string]: any\n}\n", "import { Document } from \"../document\"\n\nexport enum FieldType {\n STRING = \"string\",\n LONGFORM = \"longform\",\n OPTIONS = \"options\",\n NUMBER = \"number\",\n BOOLEAN = \"boolean\",\n ARRAY = \"array\",\n DATETIME = \"datetime\",\n ATTACHMENT = \"attachment\",\n LINK = \"link\",\n FORMULA = \"formula\",\n AUTO = \"auto\",\n JSON = \"json\",\n INTERNAL = \"internal\",\n BARCODEQR = \"barcodeqr\",\n}\n\nexport interface RowAttachment {\n size: number\n name: string\n extension: string\n key: string\n // Populated on read\n url?: string\n}\n\nexport interface Row extends Document {\n type?: string\n tableId?: string\n [key: string]: any\n}\n", "import { Document } from \"../document\"\n\nexport interface UserMetadata extends Document {\n roleId: string\n email?: string\n}\n", "import { Document } from \"../document\"\nimport { User } from \"../../\"\n\nexport enum AppBackupType {\n BACKUP = \"backup\",\n RESTORE = \"restore\",\n}\n\nexport enum AppBackupStatus {\n STARTED = \"started\",\n PENDING = \"pending\",\n COMPLETE = \"complete\",\n FAILED = \"failed\",\n}\n\nexport enum AppBackupTrigger {\n PUBLISH = \"publish\",\n MANUAL = \"manual\",\n SCHEDULED = \"scheduled\",\n RESTORING = \"restoring\",\n}\n\nexport interface AppBackupContents {\n datasources: string[]\n screens: string[]\n automations: string[]\n}\n\nexport interface AppBackupMetadata {\n appId: string\n trigger?: AppBackupTrigger\n type: AppBackupType\n status: AppBackupStatus\n name?: string\n createdBy?: string | User\n timestamp: string\n finishedAt?: string\n startedAt?: string\n contents?: AppBackupContents\n}\n\nexport interface AppBackup extends Document, AppBackupMetadata {\n _id: string\n filename?: string\n}\n\nexport type AppBackupFetchOpts = {\n trigger?: AppBackupTrigger\n type?: AppBackupType\n limit?: number\n page?: string\n paginate?: boolean\n startDate?: string\n endDate?: string\n}\n\nexport interface AppBackupQueueData {\n appId: string\n docId: string\n docRev: string\n export?: {\n trigger: AppBackupTrigger\n name?: string\n createdBy?: string\n }\n import?: {\n backupId: string\n nameForBackup: string\n createdBy?: string\n }\n}\n", "import { Document } from \"../document\"\n\nexport enum WebhookActionType {\n AUTOMATION = \"automation\",\n}\n\nexport interface Webhook extends Document {\n live: boolean\n name: string\n action: {\n type: WebhookActionType\n target: string\n }\n bodySchema?: any\n}\n", "import { Document } from \"../document\"\n\nexport interface LinkDocument extends Document {\n type: string\n doc1: {\n rowId: string\n fieldName: string\n tableId: string\n }\n doc2: {\n rowId: string\n fieldName: string\n tableId: string\n }\n}\n\nexport interface LinkDocumentValue {\n id: string\n thisId: string\n fieldName: string\n}\n", "import { Document } from \"../document\"\n\nexport interface Component extends Document {\n _instanceName: string\n _styles: { [key: string]: any }\n _component: string\n _children?: Component[]\n [key: string]: any\n}\n", "export * from \"./app\"\nexport * from \"./automation\"\nexport * from \"./datasource\"\nexport * from \"./layout\"\nexport * from \"./query\"\nexport * from \"./role\"\nexport * from \"./table\"\nexport * from \"./screen\"\nexport * from \"./view\"\nexport * from \"../document\"\nexport * from \"./row\"\nexport * from \"./user\"\nexport * from \"./backup\"\nexport * from \"./webhook\"\nexport * from \"./links\"\nexport * from \"./component\"\n", "import { Document } from \"../document\"\n\nexport interface Config<T = any> extends Document {\n type: ConfigType\n config: T\n}\n\nexport interface SMTPInnerConfig {\n port: number\n host: string\n from: string\n subject?: string\n secure: boolean\n auth?: {\n user: string\n pass: string\n }\n connectionTimeout?: any\n}\n\nexport interface SMTPConfig extends Config<SMTPInnerConfig> {}\n\n/**\n * Accessible only via pro.\n */\nexport interface SettingsBrandingConfig {\n faviconUrl?: string\n faviconUrlEtag?: string\n\n emailBrandingEnabled?: boolean\n testimonialsEnabled?: boolean\n platformTitle?: string\n loginHeading?: string\n loginButton?: string\n\n metaDescription?: string\n metaImageUrl?: string\n metaTitle?: string\n}\n\nexport interface SettingsInnerConfig {\n platformUrl?: string\n company?: string\n logoUrl?: string // Populated on read\n logoUrlEtag?: string\n uniqueTenantId?: string\n analyticsEnabled?: boolean\n isSSOEnforced?: boolean\n}\n\nexport interface SettingsConfig extends Config<SettingsInnerConfig> {}\n\nexport type SSOConfigType = ConfigType.GOOGLE | ConfigType.OIDC\nexport type SSOConfig = GoogleInnerConfig | OIDCInnerConfig\n\nexport interface GoogleInnerConfig {\n clientID: string\n clientSecret: string\n activated: boolean\n /**\n * @deprecated read only\n */\n callbackURL?: string\n}\n\nexport interface GoogleConfig extends Config<GoogleInnerConfig> {}\n\nexport interface OIDCStrategyConfiguration {\n issuer: string\n authorizationURL: string\n tokenURL: string\n userInfoURL: string\n clientID: string\n clientSecret: string\n callbackURL: string\n}\n\nexport interface OIDCConfigs {\n configs: OIDCInnerConfig[]\n}\n\nexport interface OIDCInnerConfig {\n configUrl: string\n clientID: string\n clientSecret: string\n logo: string\n name: string\n uuid: string\n activated: boolean\n scopes: string[]\n}\n\nexport interface OIDCConfig extends Config<OIDCConfigs> {}\n\nexport interface OIDCWellKnownConfig {\n issuer: string\n authorization_endpoint: string\n token_endpoint: string\n userinfo_endpoint: string\n}\n\nexport interface SCIMInnerConfig {\n enabled: boolean\n}\n\nexport interface SCIMConfig extends Config<SCIMInnerConfig> {}\n\nexport const isSettingsConfig = (config: Config): config is SettingsConfig =>\n config.type === ConfigType.SETTINGS\n\nexport const isSMTPConfig = (config: Config): config is SMTPConfig =>\n config.type === ConfigType.SMTP\n\nexport const isGoogleConfig = (config: Config): config is GoogleConfig =>\n config.type === ConfigType.GOOGLE\n\nexport const isOIDCConfig = (config: Config): config is OIDCConfig =>\n config.type === ConfigType.OIDC\n\nexport const isSCIMConfig = (config: Config): config is SCIMConfig =>\n config.type === ConfigType.SCIM\n\nexport enum ConfigType {\n SETTINGS = \"settings\",\n ACCOUNT = \"account\",\n SMTP = \"smtp\",\n GOOGLE = \"google\",\n OIDC = \"oidc\",\n OIDC_LOGOS = \"logos_oidc\",\n SCIM = \"scim\",\n}\n", "import { Document } from \"../document\"\n\n// SSO\n\nexport interface SSOProfileJson {\n email?: string\n picture?: string\n}\n\nexport interface OAuth2 {\n accessToken: string\n refreshToken?: string\n}\n\nexport enum SSOProviderType {\n OIDC = \"oidc\",\n GOOGLE = \"google\",\n}\n\nexport interface UserSSO {\n provider: string // the individual provider e.g. Okta, Auth0, Google\n providerType: SSOProviderType\n oauth2?: OAuth2\n thirdPartyProfile?: SSOProfileJson\n}\n\nexport type SSOUser = User & UserSSO\n\nexport function isSSOUser(user: User): user is SSOUser {\n return !!(user as SSOUser).providerType\n}\n\n// USER\n\nexport interface User extends Document {\n tenantId: string\n email: string\n userId?: string\n firstName?: string\n lastName?: string\n pictureUrl?: string\n forceResetPassword?: boolean\n roles: UserRoles\n builder?: {\n global: boolean\n }\n admin?: {\n global: boolean\n }\n password?: string\n status?: UserStatus\n createdAt?: number // override the default createdAt behaviour - users sdk historically set this to Date.now()\n dayPassRecordedAt?: string\n userGroups?: string[]\n onboardedAt?: string\n scimInfo?: { isSync: true } & Record<string, any>\n}\n\nexport enum UserStatus {\n ACTIVE = \"active\",\n INACTIVE = \"inactive\",\n}\n\nexport interface UserRoles {\n [key: string]: string\n}\n\n// UTILITY TYPES\n\nexport interface BuilderUser extends User {\n builder: {\n global: boolean\n }\n}\n\nexport interface AdminUser extends User {\n admin: {\n global: boolean\n }\n builder: {\n global: boolean\n }\n}\n\nexport function isUser(user: object): user is User {\n return !!(user as User).roles\n}\n", "import { PaginationResponse } from \"../../api\"\nimport { Document } from \"../document\"\n\nexport interface UserGroup extends Document {\n name: string\n icon: string\n color: string\n users?: GroupUser[]\n roles?: UserGroupRoles\n createdAt?: number\n scimInfo?: {\n externalId: string\n isSync: boolean\n }\n}\n\nexport interface GroupUser {\n _id: string\n email: string\n}\n\nexport interface UserGroupRoles {\n [key: string]: string\n}\n\nexport interface SearchGroupRequest {}\nexport interface SearchGroupResponse {\n data: UserGroup[]\n}\n\nexport interface SearchUserGroupResponse extends PaginationResponse {\n users: {\n _id: any\n email: any\n }[]\n}\n", "import { Document } from \"../document\"\n\nexport enum PluginType {\n DATASOURCE = \"datasource\",\n COMPONENT = \"component\",\n AUTOMATION = \"automation\",\n}\n\nexport enum PluginSource {\n NPM = \"NPM\",\n GITHUB = \"Github\",\n URL = \"URL\",\n FILE = \"File Upload\",\n}\nexport interface FileType {\n path: string\n name: string\n}\n\nexport interface Plugin extends Document {\n description: string\n name: string\n version: string\n source: PluginSource\n package: { [key: string]: any }\n hash: string\n schema: {\n type: PluginType\n [key: string]: any\n }\n iconFileName?: string\n // Populated on read\n jsUrl?: string\n // Populated on read\n iconUrl?: string\n}\n\nexport const PLUGIN_TYPE_ARR = Object.values(PluginType)\n", "import { MonthlyQuotaName, StaticQuotaName } from \"../../sdk\"\n\nexport enum BreakdownQuotaName {\n ROW_QUERIES = \"rowQueries\",\n DATASOURCE_QUERIES = \"datasourceQueries\",\n AUTOMATIONS = \"automations\",\n}\n\nexport const APP_QUOTA_NAMES = [\n StaticQuotaName.ROWS,\n MonthlyQuotaName.QUERIES,\n MonthlyQuotaName.AUTOMATIONS,\n]\n\nexport const BREAKDOWN_QUOTA_NAMES = [\n MonthlyQuotaName.QUERIES,\n MonthlyQuotaName.AUTOMATIONS,\n]\n\nexport interface UsageBreakdown {\n parent: MonthlyQuotaName\n values: {\n [key: string]: number\n }\n}\n\nexport type QuotaTriggers = {\n [key: string]: string | undefined\n}\n\nexport interface StaticUsage {\n [StaticQuotaName.APPS]: number\n [StaticQuotaName.PLUGINS]: number\n [StaticQuotaName.USERS]: number\n [StaticQuotaName.USER_GROUPS]: number\n [StaticQuotaName.ROWS]: number\n triggers: {\n [key in StaticQuotaName]?: QuotaTriggers\n }\n}\n\nexport interface MonthlyUsage {\n [MonthlyQuotaName.QUERIES]: number\n [MonthlyQuotaName.AUTOMATIONS]: number\n [MonthlyQuotaName.DAY_PASSES]: number\n triggers: {\n [key in MonthlyQuotaName]?: QuotaTriggers\n }\n breakdown?: {\n [key in BreakdownQuotaName]?: UsageBreakdown\n }\n}\n\nexport interface BaseQuotaUsage {\n usageQuota: StaticUsage\n monthly: {\n [key: string]: MonthlyUsage\n }\n}\n\nexport interface QuotaUsage extends BaseQuotaUsage {\n _id: string\n _rev?: string\n quotaReset: string\n apps?: {\n [key: string]: BaseQuotaUsage\n }\n}\n\nexport type SetUsageValues = {\n total: number\n app?: number\n breakdown?: number\n triggers?: QuotaTriggers\n}\n\nexport type UsageValues = {\n total: number\n app?: number\n breakdown?: number\n}\n", "import { Document } from \"../document\"\n\nexport enum ScheduleType {\n APP_BACKUP = \"app_backup\",\n}\n\nexport enum ScheduleRepeatPeriod {\n DAILY = \"daily\",\n WEEKLY = \"weekly\",\n MONTHLY = \"monthly\",\n}\n\nexport interface Schedule extends Document {\n type: ScheduleType\n name: string\n startDate: string\n repeat: ScheduleRepeatPeriod\n metadata: ScheduleMetadata\n}\n\nexport type ScheduleMetadata = AppBackupScheduleMetadata\n\nexport const isAppBackupMetadata = (\n type: ScheduleType,\n metadata: ScheduleMetadata\n): metadata is AppBackupScheduleMetadata => {\n return type === ScheduleType.APP_BACKUP\n}\n\nexport interface AppBackupScheduleMetadata {\n apps: string[]\n}\n", "import { Document } from \"../document\"\n\nexport interface Template extends Document {\n ownerId?: string\n name?: string\n contents: string\n purpose: string\n type?: string\n}\n", "import { Document } from \"../document\"\n\nexport interface EnvironmentVariablesDoc extends Document {\n variables: string\n}\n\nexport type EnvironmentVariableValue = {\n production: string\n development: string\n}\n\n// what comes out of the \"variables\" when it is decrypted\nexport type EnvironmentVariablesDecrypted = Record<\n string,\n EnvironmentVariableValue\n>\n\nexport interface EnvironmentVariablesDocDecrypted extends Document {\n variables: EnvironmentVariablesDecrypted\n}\n", "import { Document } from \"../document\"\nimport { Event } from \"../../sdk\"\n\nexport const AuditLogSystemUser = \"SYSTEM\"\n\nexport type FallbackInfo = {\n appName?: string\n email?: string\n}\n\nexport interface AuditLogDoc extends Document {\n appId?: string\n event: Event\n userId: string\n timestamp: string\n metadata: any\n name: string\n fallback?: FallbackInfo\n}\n", "export * from \"./config\"\nexport * from \"./user\"\nexport * from \"./userGroup\"\nexport * from \"./plugin\"\nexport * from \"./quotas\"\nexport * from \"./schedule\"\nexport * from \"./templates\"\nexport * from \"./environmentVariables\"\nexport * from \"./auditLogs\"\n", "import { Document } from \"../document\"\n\nexport interface GlobalInfo {}\n\nexport interface Installation extends Document {\n _id: string\n installId: string\n version: string\n}\n", "import { Document } from \"../document\"\n\n/**\n * doc id is user email\n */\nexport interface PlatformUserByEmail extends Document {\n tenantId: string\n userId: string\n}\n\n/**\n * doc id is userId\n */\nexport interface PlatformUserById extends Document {\n tenantId: string\n}\n\nexport type PlatformUser = PlatformUserByEmail | PlatformUserById\n", "import { Document } from \"../document\"\n\nexport interface AccountMetadata extends Document {\n email: string\n}\n", "import { Document } from \"../document\"\n\nexport interface Tenants extends Document {\n tenantIds: string[]\n}\n", "export * from \"./info\"\nexport * from \"./users\"\nexport * from \"./accounts\"\nexport * from \"./tenants\"\n", "export interface RowValue {\n rev: string\n deleted: boolean\n}\n\nexport interface RowResponse<T> {\n id: string\n key: string\n error: string\n value: T | RowValue\n doc?: T | any\n}\n\nexport interface AllDocsResponse<T> {\n offset: number\n total_rows: number\n rows: RowResponse<T>[]\n}\n\nexport type BulkDocsResponse = BulkDocResponse[]\n\ninterface BulkDocResponse {\n ok: boolean\n id: string\n rev: string\n}\n\nexport interface PutResponse {\n ok: boolean\n id: string\n rev: string\n}\n", "export * from \"./account\"\nexport * from \"./app\"\nexport * from \"./global\"\nexport * from \"./platform\"\nexport * from \"./document\"\nexport * from \"./pouch\"\n", "import { Hosting } from \"../../sdk\"\n\nexport interface CreateAccountRequest {\n email: string\n tenantId: string\n hosting: Hosting\n size: string\n profession: string\n // optional fields\n tenantName?: string\n name?: string\n password: string\n}\n", "export interface PostAccountUserActivity {\n timestamp: number\n}\n\nexport interface PostAccountUserActivityResponse {\n userId: string\n timestamp: number\n}\n", "import { LicenseOverrides, QuotaUsage } from \"../../documents\"\nimport { PlanType } from \"../../sdk\"\n\nexport interface GetLicenseRequest {\n // All fields should be optional to cater for\n // historical versions of budibase\n quotaUsage?: QuotaUsage\n install: {\n id: string\n tenantId: string\n version: string\n }\n}\n\nexport interface QuotaTriggeredRequest {\n percentage: number\n name: string\n resetDate?: string\n}\n\nexport interface LicenseActivateRequest {\n installVersion?: string\n}\n\nexport interface UpdateLicenseRequest {\n planType?: PlanType\n overrides?: LicenseOverrides\n}\n", "export interface HealthStatusResponse {\n passing: boolean\n checks: {\n login: boolean\n search: boolean\n }\n}\n", "export * from \"./accounts\"\nexport * from \"./user\"\nexport * from \"./license\"\nexport * from \"./status\"\n", "export enum PingSource {\n BUILDER = \"builder\",\n APP = \"app\",\n}\n\nexport interface AnalyticsPingRequest {\n source: PingSource\n timezone: string\n}\n", "export interface LoginRequest {\n username: string\n password: string\n}\n\nexport interface PasswordResetRequest {\n email: string\n}\n\nexport interface PasswordResetUpdateRequest {\n resetCode: string\n password: string\n}\n\nexport interface UpdateSelfRequest {\n firstName?: string\n lastName?: string\n password?: string\n forceResetPassword?: boolean\n onboardedAt?: string\n}\n\nexport interface UpdateSelfResponse {\n _id: string\n _rev: string\n}\n", "import { User } from \"../../documents\"\n\nexport interface SaveUserResponse {\n _id: string\n _rev: string\n email: string\n}\n\nexport interface UserDetails {\n _id: string\n email: string\n}\n\nexport interface BulkUserRequest {\n delete?: {\n userIds: string[]\n }\n create?: {\n roles?: any[]\n users: User[]\n groups: any[]\n }\n}\n\nexport interface BulkUserCreated {\n successful: UserDetails[]\n unsuccessful: { email: string; reason: string }[]\n}\n\nexport interface BulkUserDeleted {\n successful: UserDetails[]\n unsuccessful: { _id: string; email: string; reason: string }[]\n}\n\nexport interface BulkUserResponse {\n created?: BulkUserCreated\n deleted?: BulkUserDeleted\n message?: string\n}\n\nexport interface InviteUserRequest {\n email: string\n userInfo: any\n}\n\nexport type InviteUsersRequest = InviteUserRequest[]\n\nexport interface InviteUsersResponse {\n successful: { email: string }[]\n unsuccessful: { email: string; reason: string }[]\n}\n\nexport interface SearchUsersRequest {\n page?: string\n email?: string\n appId?: string\n paginated?: boolean\n}\n\nexport interface CreateAdminUserRequest {\n email: string\n password: string\n tenantId: string\n}\n\nexport interface CreateAdminUserResponse {\n _id: string\n _rev: string\n email: string\n}\n\nexport interface AcceptUserInviteRequest {\n inviteCode: string\n password: string\n firstName: string\n lastName: string\n}\n\nexport interface AcceptUserInviteResponse {\n _id: string\n _rev: string\n email: string\n}\n\nexport interface SyncUserRequest {\n previousUser?: User\n}\n", "export interface APIError {\n message: string\n status: number\n error?: any\n validationErrors?: any\n}\n", "import {\n ScheduleMetadata,\n ScheduleRepeatPeriod,\n ScheduleType,\n} from \"../../documents\"\n\nexport interface CreateScheduleRequest {\n type: ScheduleType\n name: string\n startDate: string\n repeat: ScheduleRepeatPeriod\n metadata: ScheduleMetadata\n}\n\nexport interface UpdateScheduleRequest extends CreateScheduleRequest {}\n", "export interface GetEnvironmentResponse {\n multiTenancy: boolean\n cloud: boolean\n accountPortalUrl: string\n baseUrl: string\n disableAccountPortal: boolean\n isDev: boolean\n}\n", "export * from \"./environment\"\n", "import { AppBackupTrigger, AppBackupType } from \"../../../documents\"\n\nexport interface SearchAppBackupsRequest {\n trigger: AppBackupTrigger\n type: AppBackupType\n startDate: string\n endDate: string\n page?: string\n}\n\nexport interface CreateAppBackupRequest {\n name: string\n}\n\nexport interface CreateAppBackupResponse {\n backupId: string\n message: string\n}\n\nexport interface UpdateAppBackupRequest {\n name: string\n}\n", "import { Datasource } from \"../../../documents\"\n\nexport interface CreateDatasourceResponse {\n datasource: Datasource\n error?: any\n}\n\nexport interface UpdateDatasourceResponse {\n datasource: Datasource\n}\n\nexport interface CreateDatasourceRequest {\n datasource: Datasource\n fetchSchema?: boolean\n}\n\nexport interface VerifyDatasourceRequest {\n datasource: Datasource\n}\n\nexport interface VerifyDatasourceResponse {\n connected: boolean\n error?: string\n}\n\nexport interface FetchDatasourceInfoResponse {\n tableNames: string[]\n}\n\nexport interface UpdateDatasourceRequest extends Datasource {\n datasource: Datasource\n}\n", "export * from \"./backup\"\nexport * from \"./datasource\"\n", "export interface StatusEnvironmentVariableResponse {\n encryptionKeyAvailable: boolean\n}\n\nexport interface CreateEnvironmentVariableRequest {\n name: string\n production: string\n development: string\n}\n\nexport interface UpdateEnvironmentVariableRequest {\n production: string\n development: string\n}\n\nexport interface GetEnvironmentVariablesResponse {\n variables: string[]\n}\n", "import { Event, AuditedEventFriendlyName } from \"../../../sdk\"\nimport {\n PaginationResponse,\n PaginationRequest,\n BasicPaginationRequest,\n} from \"../\"\nimport { User, App } from \"../../../\"\n\nexport interface AuditLogSearchParams {\n userIds?: string[]\n appIds?: string[]\n events?: Event[]\n startDate?: string\n endDate?: string\n fullSearch?: string\n bookmark?: string\n}\n\nexport interface DownloadAuditLogsRequest extends AuditLogSearchParams {}\n\nexport interface SearchAuditLogsRequest\n extends BasicPaginationRequest,\n AuditLogSearchParams {}\n\nexport enum AuditLogResourceStatus {\n DELETED = \"deleted\",\n}\n\nexport type DeletedResourceInfo = {\n _id: string\n status: AuditLogResourceStatus\n email?: string\n name?: string\n}\n\nexport interface AuditLogEnriched {\n app?: App | DeletedResourceInfo\n user: User | DeletedResourceInfo\n event: Event\n timestamp: string\n name: string\n metadata: any\n}\n\nexport interface SearchAuditLogsResponse extends PaginationResponse {\n data: AuditLogEnriched[]\n}\n\nexport interface DefinitionsAuditLogsResponse {\n events: Record<string, string>\n}\n", "export enum EventPublishType {\n ENVIRONMENT_VARIABLE_UPGRADE_PANEL_OPENED = \"environment_variable_upgrade_panel_opened\",\n}\n\nexport interface PostEventPublishRequest {\n type: EventPublishType\n}\n", "import { SettingsConfig, SettingsInnerConfig } from \"../../../documents\"\n\n/**\n * Settings that aren't stored in the database - enriched at runtime.\n */\nexport interface PublicSettingsInnerConfig extends SettingsInnerConfig {\n google: boolean\n googleDatasourceConfigured: boolean\n oidc: boolean\n oidcCallbackUrl: string\n googleCallbackUrl: string\n}\n\nexport interface GetPublicSettingsResponse extends SettingsConfig {\n config: PublicSettingsInnerConfig\n}\n\nexport interface PublicOIDCConfig {\n logo?: string\n name?: string\n uuid?: string\n}\n\nexport type GetPublicOIDCConfigResponse = PublicOIDCConfig[]\n", "import { ScimResource, ScimMeta } from \"scim-patch\"\nimport { ScimListResponse } from \"./shared\"\n\ntype BooleanString = boolean | \"True\" | \"true\" | \"False\" | \"false\"\n\ntype Emails =\n | {\n value: string\n type: \"work\"\n primary: boolean\n }[]\n\nexport interface ScimUserResponse extends ScimResource {\n schemas: [\"urn:ietf:params:scim:schemas:core:2.0:User\"]\n id: string\n externalId: string\n meta: ScimMeta & {\n resourceType: \"User\"\n }\n userName: string\n displayName?: string\n name?: {\n formatted?: string\n familyName?: string\n givenName?: string\n }\n active: BooleanString\n emails?: Emails\n}\n\nexport interface ScimCreateUserRequest {\n schemas: [\n \"urn:ietf:params:scim:schemas:core:2.0:User\",\n \"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User\"\n ]\n externalId: string\n userName: string\n active: BooleanString\n emails?: Emails\n meta: {\n resourceType: \"User\"\n }\n displayName?: string\n name?: {\n formatted: string\n familyName: string\n givenName: string\n }\n roles: []\n}\n\nexport interface ScimUserListResponse\n extends ScimListResponse<ScimUserResponse> {}\n", "import { ScimResource, ScimMeta } from \"scim-patch\"\nimport { ScimListResponse } from \"./shared\"\n\nexport interface ScimGroupResponse extends ScimResource {\n schemas: [\"urn:ietf:params:scim:schemas:core:2.0:Group\"]\n id: string\n externalId: string\n displayName: string\n meta: ScimMeta & {\n resourceType: \"Group\"\n }\n members?: {\n value: string\n }[]\n}\n\nexport interface ScimCreateGroupRequest {\n schemas: [\n \"urn:ietf:params:scim:schemas:core:2.0:Group\",\n \"http://schemas.microsoft.com/2006/11/ResourceManagement/ADSCIM/2.0/Group\"\n ]\n externalId: string\n displayName: string\n meta: ScimMeta & {\n resourceType: \"Group\"\n }\n}\n\nexport interface ScimGroupListResponse\n extends ScimListResponse<ScimGroupResponse> {}\n", "import { ScimPatchOperation } from \"scim-patch\"\n\nexport interface ScimListResponse<T> {\n schemas: [\"urn:ietf:params:scim:api:messages:2.0:ListResponse\"]\n totalResults: number\n Resources: T[]\n startIndex: number\n itemsPerPage: number\n}\n\nexport interface ScimUpdateRequest {\n schemas: [\"urn:ietf:params:scim:api:messages:2.0:PatchOp\"]\n Operations: ScimPatchOperation[]\n}\n", "export * from \"./users\"\nexport * from \"./groups\"\nexport * from \"./shared\"\n", "export * from \"./environmentVariables\"\nexport * from \"./auditLogs\"\nexport * from \"./events\"\nexport * from \"./configs\"\nexport * from \"./scim\"\n", "export enum SortOrder {\n ASCENDING = \"ascending\",\n DESCENDING = \"descending\",\n}\n\nexport enum SortType {\n STRING = \"string\",\n number = \"number\",\n}\n\nexport interface BasicPaginationRequest {\n bookmark?: string\n}\n\nexport interface PaginationRequest extends BasicPaginationRequest {\n limit?: number\n sort?: {\n order: SortOrder\n column: string\n type: SortType\n }\n}\n\nexport interface PaginationResponse {\n bookmark: string | undefined\n hasNextPage: boolean\n}\n", "export * from \"./analytics\"\nexport * from \"./auth\"\nexport * from \"./user\"\nexport * from \"./errors\"\nexport * from \"./schedule\"\nexport * from \"./system\"\nexport * from \"./app\"\nexport * from \"./global\"\nexport * from \"./pagination\"\n", "export * from \"./account\"\nexport * from \"./web\"\n", "export * from \"./documents\"\nexport * from \"./sdk\"\nexport * from \"./api\"\n", "export const SEPARATOR = \"_\"\nexport const UNICODE_MAX = \"\\ufff0\"\n\n/**\n * Can be used to create a few different forms of querying a view.\n */\nexport enum AutomationViewMode {\n ALL = \"all\",\n AUTOMATION = \"automation\",\n STATUS = \"status\",\n}\n\nexport enum ViewName {\n USER_BY_APP = \"by_app\",\n USER_BY_EMAIL = \"by_email2\",\n BY_API_KEY = \"by_api_key\",\n /** @deprecated - could be deleted */\n USER_BY_BUILDERS = \"by_builders\",\n LINK = \"by_link\",\n ROUTING = \"screen_routes\",\n AUTOMATION_LOGS = \"automation_logs\",\n ACCOUNT_BY_EMAIL = \"account_by_email\",\n PLATFORM_USERS_LOWERCASE = \"platform_users_lowercase\",\n USER_BY_GROUP = \"user_by_group\",\n APP_BACKUP_BY_TRIGGER = \"by_trigger\",\n}\n\nexport const DeprecatedViews = {\n [ViewName.USER_BY_EMAIL]: [\n // removed due to inaccuracy in view doc filter logic\n \"by_email\",\n ],\n}\n\nexport enum InternalTable {\n USER_METADATA = \"ta_users\",\n}\n\nexport enum DocumentType {\n USER = \"us\",\n GROUP = \"gr\",\n WORKSPACE = \"workspace\",\n CONFIG = \"config\",\n TEMPLATE = \"template\",\n APP = \"app\",\n DEV = \"dev\",\n APP_DEV = \"app_dev\",\n APP_METADATA = \"app_metadata\",\n ROLE = \"role\",\n MIGRATIONS = \"migrations\",\n DEV_INFO = \"devinfo\",\n AUTOMATION_LOG = \"log_au\",\n ACCOUNT_METADATA = \"acc_metadata\",\n PLUGIN = \"plg\",\n DATASOURCE = \"datasource\",\n DATASOURCE_PLUS = \"datasource_plus\",\n APP_BACKUP = \"backup\",\n TABLE = \"ta\",\n ROW = \"ro\",\n AUTOMATION = \"au\",\n LINK = \"li\",\n WEBHOOK = \"wh\",\n INSTANCE = \"inst\",\n LAYOUT = \"layout\",\n SCREEN = \"screen\",\n QUERY = \"query\",\n DEPLOYMENTS = \"deployments\",\n METADATA = \"metadata\",\n MEM_VIEW = \"view\",\n USER_FLAG = \"flag\",\n AUTOMATION_METADATA = \"meta_au\",\n AUDIT_LOG = \"al\",\n}\n\nexport const StaticDatabases = {\n GLOBAL: {\n name: \"global-db\",\n docs: {\n apiKeys: \"apikeys\",\n usageQuota: \"usage_quota\",\n licenseInfo: \"license_info\",\n environmentVariables: \"environmentvariables\",\n },\n },\n // contains information about tenancy and so on\n PLATFORM_INFO: {\n name: \"global-info\",\n docs: {\n tenants: \"tenants\",\n install: \"install\",\n },\n },\n AUDIT_LOGS: {\n name: \"audit-logs\",\n },\n}\n\nexport const APP_PREFIX = DocumentType.APP + SEPARATOR\nexport const APP_DEV = DocumentType.APP_DEV + SEPARATOR\nexport const APP_DEV_PREFIX = APP_DEV\nexport const BUDIBASE_DATASOURCE_TYPE = \"budibase\"\n", "export enum UserStatus {\n ACTIVE = \"active\",\n INACTIVE = \"inactive\",\n}\n\nexport enum Cookie {\n Auth = \"budibase:auth\",\n Init = \"budibase:init\",\n ACCOUNT_RETURN_URL = \"budibase:account:returnurl\",\n DatasourceAuth = \"budibase:datasourceauth\",\n OIDC_CONFIG = \"budibase:oidc:config\",\n}\n\nexport enum Header {\n API_KEY = \"x-budibase-api-key\",\n LICENSE_KEY = \"x-budibase-license-key\",\n API_VER = \"x-budibase-api-version\",\n APP_ID = \"x-budibase-app-id\",\n TYPE = \"x-budibase-type\",\n PREVIEW_ROLE = \"x-budibase-role\",\n TENANT_ID = \"x-budibase-tenant-id\",\n TOKEN = \"x-budibase-token\",\n CSRF_TOKEN = \"x-csrf-token\",\n CORRELATION_ID = \"x-budibase-correlation-id\",\n AUTHORIZATION = \"authorization\",\n}\n\nexport enum GlobalRole {\n OWNER = \"owner\",\n ADMIN = \"admin\",\n BUILDER = \"builder\",\n WORKSPACE_MANAGER = \"workspace_manager\",\n}\n\nexport enum Config {\n SETTINGS = \"settings\",\n ACCOUNT = \"account\",\n SMTP = \"smtp\",\n GOOGLE = \"google\",\n OIDC = \"oidc\",\n OIDC_LOGOS = \"logos_oidc\",\n SCIM = \"scim\",\n}\n\nexport const MIN_VALID_DATE = new Date(-2147483647000)\nexport const MAX_VALID_DATE = new Date(2147483647000)\nexport const DEFAULT_TENANT_ID = \"default\"\n", "export * from \"./db\"\nexport * from \"./misc\"\n", "import {\n IdentityContext,\n IdentityType,\n User,\n isCloudAccount,\n Account,\n AccountUserContext,\n UserContext,\n Ctx,\n} from \"@budibase/types\"\nimport * as context from \".\"\n\nexport function getIdentity(): IdentityContext | undefined {\n return context.getIdentity()\n}\n\nexport function doInIdentityContext(identity: IdentityContext, task: any) {\n return context.doInIdentityContext(identity, task)\n}\n\n// used in server/worker\nexport function doInUserContext(user: User, ctx: Ctx, task: any) {\n const userContext: UserContext = {\n ...user,\n _id: user._id as string,\n type: IdentityType.USER,\n hostInfo: {\n ipAddress: ctx.request.ip,\n // filled in by koa-useragent package\n userAgent: ctx.userAgent._agent.source,\n },\n }\n return doInIdentityContext(userContext, task)\n}\n\n// used in account portal\nexport function doInAccountContext(account: Account, task: any) {\n const _id = getAccountUserId(account)\n const tenantId = account.tenantId\n const accountContext: AccountUserContext = {\n _id,\n type: IdentityType.USER,\n tenantId,\n account,\n }\n return doInIdentityContext(accountContext, task)\n}\n\nexport function getAccountUserId(account: Account) {\n let userId: string\n if (isCloudAccount(account)) {\n userId = account.budibaseUserId\n } else {\n // use account id as user id for self-hosting\n userId = account.accountId\n }\n return userId\n}\n", "import { existsSync, readFileSync } from \"fs\"\n\nfunction isTest() {\n return isCypress() || isJest()\n}\n\nfunction isJest() {\n return !!(process.env.NODE_ENV === \"jest\" || process.env.JEST_WORKER_ID)\n}\n\nfunction isCypress() {\n return process.env.NODE_ENV === \"cypress\"\n}\n\nfunction isDev() {\n return process.env.NODE_ENV !== \"production\"\n}\n\nlet LOADED = false\nif (!LOADED && isDev() && !isTest()) {\n require(\"dotenv\").config()\n LOADED = true\n}\n\nconst DefaultBucketName = {\n BACKUPS: \"backups\",\n APPS: \"prod-budi-app-assets\",\n TEMPLATES: \"templates\",\n GLOBAL: \"global\",\n PLUGINS: \"plugins\",\n}\n\nconst selfHosted = !!parseInt(process.env.SELF_HOSTED || \"\")\n\nfunction getAPIEncryptionKey() {\n return process.env.API_ENCRYPTION_KEY\n ? process.env.API_ENCRYPTION_KEY\n : process.env.JWT_SECRET // fallback to the JWT_SECRET used historically\n}\n\nfunction httpLogging() {\n if (process.env.HTTP_LOGGING === undefined) {\n // on by default unless otherwise specified\n return true\n }\n\n return process.env.HTTP_LOGGING\n}\n\nfunction findVersion() {\n function findFileInAncestors(\n fileName: string,\n currentDir: string\n ): string | null {\n const filePath = `${currentDir}/${fileName}`\n if (existsSync(filePath)) {\n return filePath\n }\n\n const parentDir = `${currentDir}/..`\n if (parentDir === currentDir) {\n // reached root directory\n return null\n }\n\n return findFileInAncestors(fileName, parentDir)\n }\n\n try {\n const packageJsonFile = findFileInAncestors(\"package.json\", process.cwd())\n const content = readFileSync(packageJsonFile!, \"utf-8\")\n return JSON.parse(content).version\n } catch {\n // throwing an error here is confusing/causes backend-core to be hard to import\n return undefined\n }\n}\n\nconst environment = {\n isTest,\n isJest,\n isDev,\n isProd: () => {\n return !isDev()\n },\n JS_BCRYPT: process.env.JS_BCRYPT,\n JWT_SECRET: process.env.JWT_SECRET,\n JWT_SECRET_FALLBACK: process.env.JWT_SECRET_FALLBACK,\n ENCRYPTION_KEY: process.env.ENCRYPTION_KEY,\n API_ENCRYPTION_KEY: getAPIEncryptionKey(),\n COUCH_DB_URL: process.env.COUCH_DB_URL || \"http://localhost:4005\",\n COUCH_DB_USERNAME: process.env.COUCH_DB_USER,\n COUCH_DB_PASSWORD: process.env.COUCH_DB_PASSWORD,\n GOOGLE_CLIENT_ID: process.env.GOOGLE_CLIENT_ID,\n GOOGLE_CLIENT_SECRET: process.env.GOOGLE_CLIENT_SECRET,\n SALT_ROUNDS: process.env.SALT_ROUNDS,\n REDIS_URL: process.env.REDIS_URL || \"localhost:6379\",\n REDIS_PASSWORD: process.env.REDIS_PASSWORD,\n REDIS_CLUSTERED: process.env.REDIS_CLUSTERED,\n MOCK_REDIS: process.env.MOCK_REDIS,\n MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY,\n MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY,\n AWS_REGION: process.env.AWS_REGION,\n MINIO_URL: process.env.MINIO_URL,\n MINIO_ENABLED: process.env.MINIO_ENABLED || 1,\n INTERNAL_API_KEY: process.env.INTERNAL_API_KEY,\n INTERNAL_API_KEY_FALLBACK: process.env.INTERNAL_API_KEY_FALLBACK,\n MULTI_TENANCY: process.env.MULTI_TENANCY,\n ACCOUNT_PORTAL_URL:\n process.env.ACCOUNT_PORTAL_URL || \"https://account.budibase.app\",\n ACCOUNT_PORTAL_API_KEY: process.env.ACCOUNT_PORTAL_API_KEY || \"\",\n DISABLE_ACCOUNT_PORTAL: process.env.DISABLE_ACCOUNT_PORTAL,\n SELF_HOSTED: selfHosted,\n COOKIE_DOMAIN: process.env.COOKIE_DOMAIN,\n PLATFORM_URL: process.env.PLATFORM_URL || \"\",\n POSTHOG_TOKEN: process.env.POSTHOG_TOKEN,\n ENABLE_ANALYTICS: process.env.ENABLE_ANALYTICS,\n TENANT_FEATURE_FLAGS: process.env.TENANT_FEATURE_FLAGS,\n CLOUDFRONT_CDN: process.env.CLOUDFRONT_CDN,\n CLOUDFRONT_PRIVATE_KEY_64: process.env.CLOUDFRONT_PRIVATE_KEY_64,\n CLOUDFRONT_PUBLIC_KEY_ID: process.env.CLOUDFRONT_PUBLIC_KEY_ID,\n BACKUPS_BUCKET_NAME:\n process.env.BACKUPS_BUCKET_NAME || DefaultBucketName.BACKUPS,\n APPS_BUCKET_NAME: process.env.APPS_BUCKET_NAME || DefaultBucketName.APPS,\n TEMPLATES_BUCKET_NAME:\n process.env.TEMPLATES_BUCKET_NAME || DefaultBucketName.TEMPLATES,\n GLOBAL_BUCKET_NAME:\n process.env.GLOBAL_BUCKET_NAME || DefaultBucketName.GLOBAL,\n PLUGIN_BUCKET_NAME:\n process.env.PLUGIN_BUCKET_NAME || DefaultBucketName.PLUGINS,\n USE_COUCH: process.env.USE_COUCH || true,\n DEFAULT_LICENSE: process.env.DEFAULT_LICENSE,\n SERVICE: process.env.SERVICE || \"budibase\",\n LOG_LEVEL: process.env.LOG_LEVEL || \"info\",\n SESSION_UPDATE_PERIOD: process.env.SESSION_UPDATE_PERIOD,\n DEPLOYMENT_ENVIRONMENT:\n process.env.DEPLOYMENT_ENVIRONMENT || \"docker-compose\",\n HTTP_LOGGING: httpLogging(),\n ENABLE_AUDIT_LOG_IP_ADDR: process.env.ENABLE_AUDIT_LOG_IP_ADDR,\n // smtp\n SMTP_FALLBACK_ENABLED: process.env.SMTP_FALLBACK_ENABLED,\n SMTP_USER: process.env.SMTP_USER,\n SMTP_PASSWORD: process.env.SMTP_PASSWORD,\n SMTP_HOST: process.env.SMTP_HOST,\n SMTP_PORT: parseInt(process.env.SMTP_PORT || \"\"),\n SMTP_FROM_ADDRESS: process.env.SMTP_FROM_ADDRESS,\n DISABLE_JWT_WARNING: process.env.DISABLE_JWT_WARNING,\n BLACKLIST_IPS: process.env.BLACKLIST_IPS,\n /**\n * Enable to allow an admin user to login using a password.\n * This can be useful to prevent lockout when configuring SSO.\n * However, this should be turned OFF by default for security purposes.\n */\n ENABLE_SSO_MAINTENANCE_MODE: selfHosted\n ? process.env.ENABLE_SSO_MAINTENANCE_MODE\n : false,\n VERSION: findVersion(),\n DISABLE_PINO_LOGGER: process.env.DISABLE_PINO_LOGGER,\n _set(key: any, value: any) {\n process.env[key] = value\n // @ts-ignore\n environment[key] = value\n },\n}\n\n// clean up any environment variable edge cases\nfor (let [key, value] of Object.entries(environment)) {\n // handle the edge case of \"0\" to disable an environment variable\n if (value === \"0\") {\n // @ts-ignore\n environment[key] = 0\n }\n // handle the edge case of \"false\" to disable an environment variable\n if (value === \"false\") {\n // @ts-ignore\n environment[key] = 0\n }\n}\n\nexport default environment\n", "import { AsyncLocalStorage } from \"async_hooks\"\nimport { ContextMap } from \"./types\"\n\nexport default class Context {\n static storage = new AsyncLocalStorage<ContextMap>()\n\n static run(context: ContextMap, func: any) {\n return Context.storage.run(context, () => func())\n }\n\n static get(): ContextMap {\n return Context.storage.getStore() as ContextMap\n }\n}\n", "import { APP_DEV_PREFIX, APP_PREFIX } from \"../constants\"\nimport { App } from \"@budibase/types\"\nconst NO_APP_ERROR = \"No app provided\"\n\nexport function isDevAppID(appId?: string) {\n if (!appId) {\n throw NO_APP_ERROR\n }\n return appId.startsWith(APP_DEV_PREFIX)\n}\n\nexport function isProdAppID(appId?: string) {\n if (!appId) {\n throw NO_APP_ERROR\n }\n return appId.startsWith(APP_PREFIX) && !isDevAppID(appId)\n}\n\nexport function isDevApp(app: App) {\n if (!app) {\n throw NO_APP_ERROR\n }\n return isDevAppID(app.appId)\n}\n\n/**\n * Generates a development app ID from a real app ID.\n * @returns {string} the dev app ID which can be used for dev database.\n */\nexport function getDevelopmentAppID(appId: string) {\n if (!appId || appId.startsWith(APP_DEV_PREFIX)) {\n return appId\n }\n // split to take off the app_ element, then join it together incase any other app_ exist\n const split = appId.split(APP_PREFIX)\n split.shift()\n const rest = split.join(APP_PREFIX)\n return `${APP_DEV_PREFIX}${rest}`\n}\nexport const getDevAppID = getDevelopmentAppID\n\n/**\n * Convert a development app ID to a deployed app ID.\n */\nexport function getProdAppID(appId: string) {\n if (!appId || !appId.startsWith(APP_DEV_PREFIX)) {\n return appId\n }\n // split to take off the app_dev element, then join it together incase any other app_ exist\n const split = appId.split(APP_DEV_PREFIX)\n split.shift()\n const rest = split.join(APP_DEV_PREFIX)\n return `${APP_PREFIX}${rest}`\n}\n\nexport function extractAppUUID(id: string) {\n const split = id?.split(\"_\") || []\n return split.length ? split[split.length - 1] : null\n}\n", "import env from \"../../environment\"\n\nexport const getCouchInfo = (connection?: string) => {\n const urlInfo = getUrlInfo(connection)\n let username\n let password\n if (urlInfo.auth?.username) {\n // set from url\n username = urlInfo.auth.username\n } else if (env.COUCH_DB_USERNAME) {\n // set from env\n username = env.COUCH_DB_USERNAME\n } else if (!env.isTest()) {\n throw new Error(\"CouchDB username not set\")\n }\n if (urlInfo.auth?.password) {\n // set from url\n password = urlInfo.auth.password\n } else if (env.COUCH_DB_PASSWORD) {\n // set from env\n password = env.COUCH_DB_PASSWORD\n } else if (!env.isTest()) {\n throw new Error(\"CouchDB password not set\")\n }\n const authCookie = Buffer.from(`${username}:${password}`).toString(\"base64\")\n return {\n url: urlInfo.url!,\n auth: {\n username: username,\n password: password,\n },\n cookie: `Basic ${authCookie}`,\n }\n}\n\nexport const getUrlInfo = (url = env.COUCH_DB_URL) => {\n let cleanUrl, username, password, host\n if (url) {\n // Ensure the URL starts with a protocol\n const protoRegex = /^https?:\\/\\//i\n if (!protoRegex.test(url)) {\n url = `http://${url}`\n }\n\n // Split into protocol and remainder\n const split = url.split(\"://\")\n const protocol = split[0]\n const rest = split.slice(1).join(\"://\")\n\n // Extract auth if specified\n if (url.includes(\"@\")) {\n // Split into host and remainder\n let parts = rest.split(\"@\")\n host = parts[parts.length - 1]\n let auth = parts.slice(0, -1).join(\"@\")\n\n // Split auth into username and password\n if (auth.includes(\":\")) {\n const authParts = auth.split(\":\")\n username = authParts[0]\n password = authParts.slice(1).join(\":\")\n } else {\n username = auth\n }\n } else {\n host = rest\n }\n cleanUrl = `${protocol}://${host}`\n }\n return {\n url: cleanUrl,\n auth: {\n username,\n password,\n },\n }\n}\n", "/**\n * Makes sure that a URL has the correct number of slashes, while maintaining the\n * http(s):// double slashes.\n * @param {string} url The URL to test and remove any extra double slashes.\n * @return {string} The updated url.\n */\nexport function checkSlashesInUrl(url: string) {\n return url.replace(/(https?:\\/\\/)|(\\/)+/g, \"$1$2\")\n}\n", "import { getCouchInfo } from \"./connections\"\nimport fetch from \"node-fetch\"\nimport { checkSlashesInUrl } from \"../../helpers\"\n\nexport async function directCouchCall(\n path: string,\n method: string = \"GET\",\n body?: any\n) {\n let { url, cookie } = getCouchInfo()\n const couchUrl = `${url}/${path}`\n return await directCouchUrlCall({ url: couchUrl, cookie, method, body })\n}\n\nexport async function directCouchUrlCall({\n url,\n cookie,\n method,\n body,\n}: {\n url: string\n cookie: string\n method: string\n body?: any\n}) {\n const params: any = {\n method: method,\n headers: {\n Authorization: cookie,\n },\n }\n if (body && method !== \"GET\") {\n params.body = JSON.stringify(body)\n params.headers[\"Content-Type\"] = \"application/json\"\n }\n return await fetch(checkSlashesInUrl(encodeURI(url)), params)\n}\n\nexport async function directCouchQuery(\n path: string,\n method: string = \"GET\",\n body?: any\n) {\n const response = await directCouchCall(path, method, body)\n if (response.status < 300) {\n return await response.json()\n } else {\n throw \"Cannot connect to CouchDB instance\"\n }\n}\n", "import PouchDB from \"pouchdb\"\nimport env from \"../../environment\"\nimport { PouchOptions } from \"@budibase/types\"\nimport { getCouchInfo } from \"./connections\"\n\nlet Pouch: any\nlet initialised = false\n\n/**\n * Return a constructor for PouchDB.\n * This should be rarely used outside of the main application config.\n * Exposed for exceptional cases such as in-memory views.\n */\nexport const getPouch = (opts: PouchOptions = {}) => {\n let { url, cookie } = getCouchInfo()\n let POUCH_DB_DEFAULTS = {\n prefix: url,\n fetch: (url: string, opts: any) => {\n // use a specific authorization cookie - be very explicit about how we authenticate\n opts.headers.set(\"Authorization\", cookie)\n return PouchDB.fetch(url, opts)\n },\n }\n\n if (opts.inMemory) {\n const inMemory = require(\"pouchdb-adapter-memory\")\n PouchDB.plugin(inMemory)\n POUCH_DB_DEFAULTS = {\n // @ts-ignore\n adapter: \"memory\",\n }\n }\n\n if (opts.onDisk) {\n POUCH_DB_DEFAULTS = {\n // @ts-ignore\n adapter: \"leveldb\",\n }\n }\n\n if (opts.replication) {\n const replicationStream = require(\"@budibase/pouchdb-replication-stream\")\n PouchDB.plugin(replicationStream.plugin)\n // @ts-ignore\n PouchDB.adapter(\"writableStream\", replicationStream.adapters.writableStream)\n }\n\n if (opts.find) {\n const find = require(\"pouchdb-find\")\n PouchDB.plugin(find)\n }\n\n return PouchDB.defaults(POUCH_DB_DEFAULTS)\n}\n\nexport function init(opts?: PouchOptions) {\n Pouch = getPouch(opts)\n initialised = true\n}\n\nconst checkInitialised = () => {\n if (!initialised) {\n throw new Error(\"init has not been called\")\n }\n}\n\nexport function getPouchDB(dbName: string, opts?: any): PouchDB.Database {\n checkInitialised()\n const db = new Pouch(dbName, opts)\n const dbPut = db.put\n db.put = async (doc: any, options = {}) => {\n if (!doc.createdAt) {\n doc.createdAt = new Date().toISOString()\n }\n doc.updatedAt = new Date().toISOString()\n return dbPut(doc, options)\n }\n db.exists = async () => {\n const info = await db.info()\n return !info.error\n }\n return db\n}\n\n// use this function if you have called getPouchDB - close\n// the databases you've opened once finished\nexport async function closePouchDB(db: PouchDB.Database) {\n if (!db || env.isTest()) {\n return\n }\n try {\n // specifically await so that if there is an error, it can be ignored\n return await db.close()\n } catch (err) {\n // ignore error, already closed\n }\n}\n", "import { v4 } from \"uuid\"\n\nexport function newid() {\n return v4().replace(/-/g, \"\")\n}\n", "import Nano from \"@budibase/nano\"\nimport {\n AllDocsResponse,\n AnyDocument,\n Database,\n DatabaseOpts,\n DatabaseQueryOpts,\n DatabasePutOpts,\n DatabaseCreateIndexOpts,\n DatabaseDeleteIndexOpts,\n Document,\n isDocument,\n} from \"@budibase/types\"\nimport { getCouchInfo } from \"./connections\"\nimport { directCouchUrlCall } from \"./utils\"\nimport { getPouchDB } from \"./pouchDB\"\nimport { WriteStream, ReadStream } from \"fs\"\nimport { newid } from \"../../docIds/newid\"\n\nfunction buildNano(couchInfo: { url: string; cookie: string }) {\n return Nano({\n url: couchInfo.url,\n requestDefaults: {\n headers: {\n Authorization: couchInfo.cookie,\n },\n },\n parseUrl: false,\n })\n}\n\nexport function DatabaseWithConnection(\n dbName: string,\n connection: string,\n opts?: DatabaseOpts\n) {\n if (!connection) {\n throw new Error(\"Must provide connection details\")\n }\n return new DatabaseImpl(dbName, opts, connection)\n}\n\nexport class DatabaseImpl implements Database {\n public readonly name: string\n private static nano: Nano.ServerScope\n private readonly instanceNano?: Nano.ServerScope\n private readonly pouchOpts: DatabaseOpts\n\n private readonly couchInfo = getCouchInfo()\n\n constructor(dbName?: string, opts?: DatabaseOpts, connection?: string) {\n if (dbName == null) {\n throw new Error(\"Database name cannot be undefined.\")\n }\n this.name = dbName\n this.pouchOpts = opts || {}\n if (connection) {\n this.couchInfo = getCouchInfo(connection)\n this.instanceNano = buildNano(this.couchInfo)\n }\n if (!DatabaseImpl.nano) {\n DatabaseImpl.init()\n }\n }\n\n static init() {\n const couchInfo = getCouchInfo()\n DatabaseImpl.nano = buildNano(couchInfo)\n }\n\n async exists() {\n const response = await directCouchUrlCall({\n url: `${this.couchInfo.url}/${this.name}`,\n method: \"HEAD\",\n cookie: this.couchInfo.cookie,\n })\n return response.status === 200\n }\n\n private nano() {\n return this.instanceNano || DatabaseImpl.nano\n }\n\n async checkSetup() {\n let shouldCreate = !this.pouchOpts?.skip_setup\n // check exists in a lightweight fashion\n let exists = await this.exists()\n if (!shouldCreate && !exists) {\n throw new Error(\"DB does not exist\")\n }\n if (!exists) {\n try {\n await this.nano().db.create(this.name)\n } catch (err: any) {\n // Handling race conditions\n if (err.statusCode !== 412) {\n throw err\n }\n }\n }\n return this.nano().db.use(this.name)\n }\n\n private async updateOutput(fnc: any) {\n try {\n return await fnc()\n } catch (err: any) {\n if (err.statusCode) {\n err.status = err.statusCode\n }\n throw err\n }\n }\n\n async get<T>(id?: string): Promise<T | any> {\n const db = await this.checkSetup()\n if (!id) {\n throw new Error(\"Unable to get doc without a valid _id.\")\n }\n return this.updateOutput(() => db.get(id))\n }\n\n async remove(idOrDoc: string | Document, rev?: string) {\n const db = await this.checkSetup()\n let _id: string\n let _rev: string\n\n if (isDocument(idOrDoc)) {\n _id = idOrDoc._id!\n _rev = idOrDoc._rev!\n } else {\n _id = idOrDoc\n _rev = rev!\n }\n\n if (!_id || !_rev) {\n throw new Error(\"Unable to remove doc without a valid _id and _rev.\")\n }\n return this.updateOutput(() => db.destroy(_id, _rev))\n }\n\n async post(document: AnyDocument, opts?: DatabasePutOpts) {\n if (!document._id) {\n document._id = newid()\n }\n return this.put(document, opts)\n }\n\n async put(document: AnyDocument, opts?: DatabasePutOpts) {\n if (!document._id) {\n throw new Error(\"Cannot store document without _id field.\")\n }\n const db = await this.checkSetup()\n if (!document.createdAt) {\n document.createdAt = new Date().toISOString()\n }\n document.updatedAt = new Date().toISOString()\n if (opts?.force && document._id) {\n try {\n const existing = await this.get(document._id)\n if (existing) {\n document._rev = existing._rev\n }\n } catch (err: any) {\n if (err.status !== 404) {\n throw err\n }\n }\n }\n return this.updateOutput(() => db.insert(document))\n }\n\n async bulkDocs(documents: AnyDocument[]) {\n const db = await this.checkSetup()\n return this.updateOutput(() => db.bulk({ docs: documents }))\n }\n\n async allDocs<T>(params: DatabaseQueryOpts): Promise<AllDocsResponse<T>> {\n const db = await this.checkSetup()\n return this.updateOutput(() => db.list(params))\n }\n\n async query<T>(\n viewName: string,\n params: DatabaseQueryOpts\n ): Promise<AllDocsResponse<T>> {\n const db = await this.checkSetup()\n const [database, view] = viewName.split(\"/\")\n return this.updateOutput(() => db.view(database, view, params))\n }\n\n async destroy() {\n try {\n return await this.nano().db.destroy(this.name)\n } catch (err: any) {\n // didn't exist, don't worry\n if (err.statusCode === 404) {\n return\n } else {\n throw { ...err, status: err.statusCode }\n }\n }\n }\n\n async compact() {\n const db = await this.checkSetup()\n return this.updateOutput(() => db.compact())\n }\n\n // All below functions are in-frequently called, just utilise PouchDB\n // for them as it implements them better than we can\n async dump(stream: WriteStream, opts?: { filter?: any }) {\n const pouch = getPouchDB(this.name)\n // @ts-ignore\n return pouch.dump(stream, opts)\n }\n\n async load(stream: ReadStream) {\n const pouch = getPouchDB(this.name)\n // @ts-ignore\n return pouch.load(stream)\n }\n\n async createIndex(opts: DatabaseCreateIndexOpts) {\n const pouch = getPouchDB(this.name)\n return pouch.createIndex(opts)\n }\n\n async deleteIndex(opts: DatabaseDeleteIndexOpts) {\n const pouch = getPouchDB(this.name)\n return pouch.deleteIndex(opts)\n }\n\n async getIndexes() {\n const pouch = getPouchDB(this.name)\n return pouch.getIndexes()\n }\n}\n", "export * from \"./connections\"\nexport * from \"./DatabaseImpl\"\nexport * from \"./utils\"\nexport { init, getPouch, getPouchDB, closePouchDB } from \"./pouchDB\"\n", "import env from \"../environment\"\nimport { directCouchQuery, DatabaseImpl } from \"./couch\"\nimport { CouchFindOptions, Database } from \"@budibase/types\"\n\nconst dbList = new Set()\n\nexport function getDB(dbName?: string, opts?: any): Database {\n return new DatabaseImpl(dbName, opts)\n}\n\n// we have to use a callback for this so that we can close\n// the DB when we're done, without this manual requests would\n// need to close the database when done with it to avoid memory leaks\nexport async function doWithDB(dbName: string, cb: any, opts = {}) {\n const db = getDB(dbName, opts)\n // need this to be async so that we can correctly close DB after all\n // async operations have been completed\n return await cb(db)\n}\n\nexport function allDbs() {\n if (!env.isTest()) {\n throw new Error(\"Cannot be used outside test environment.\")\n }\n return [...dbList]\n}\n\nexport async function directCouchAllDbs(queryString?: string) {\n let couchPath = \"/_all_dbs\"\n if (queryString) {\n couchPath += `?${queryString}`\n }\n return await directCouchQuery(couchPath)\n}\n\nexport async function directCouchFind(dbName: string, opts: CouchFindOptions) {\n const json = await directCouchQuery(`${dbName}/_find`, \"POST\", opts)\n return { rows: json.docs, bookmark: json.bookmark }\n}\n", "// some test cases call functions directly, need to\n// store an app ID to pretend there is a context\nimport env from \"../environment\"\nimport Context from \"./Context\"\nimport * as conversions from \"../docIds/conversions\"\nimport { getDB } from \"../db/db\"\nimport {\n DocumentType,\n SEPARATOR,\n StaticDatabases,\n DEFAULT_TENANT_ID,\n} from \"../constants\"\nimport { Database, IdentityContext } from \"@budibase/types\"\nimport { ContextMap } from \"./types\"\n\nlet TEST_APP_ID: string | null = null\n\nexport function getGlobalDBName(tenantId?: string) {\n // tenant ID can be set externally, for example user API where\n // new tenants are being created, this may be the case\n if (!tenantId) {\n tenantId = getTenantId()\n }\n return baseGlobalDBName(tenantId)\n}\n\nexport function getAuditLogDBName(tenantId?: string) {\n if (!tenantId) {\n tenantId = getTenantId()\n }\n if (tenantId === DEFAULT_TENANT_ID) {\n return StaticDatabases.AUDIT_LOGS.name\n } else {\n return `${tenantId}${SEPARATOR}${StaticDatabases.AUDIT_LOGS.name}`\n }\n}\n\nexport function baseGlobalDBName(tenantId: string | undefined | null) {\n if (!tenantId || tenantId === DEFAULT_TENANT_ID) {\n return StaticDatabases.GLOBAL.name\n } else {\n return `${tenantId}${SEPARATOR}${StaticDatabases.GLOBAL.name}`\n }\n}\n\nexport function getPlatformURL() {\n return env.PLATFORM_URL\n}\n\nexport function isMultiTenant() {\n return !!env.MULTI_TENANCY\n}\n\nexport function isTenantIdSet() {\n const context = Context.get()\n return !!context?.tenantId\n}\n\nexport function isTenancyEnabled() {\n return env.MULTI_TENANCY\n}\n\n/**\n * Given an app ID this will attempt to retrieve the tenant ID from it.\n * @return {null|string} The tenant ID found within the app ID.\n */\nexport function getTenantIDFromAppID(appId: string) {\n if (!appId) {\n return undefined\n }\n if (!isMultiTenant()) {\n return DEFAULT_TENANT_ID\n }\n const split = appId.split(SEPARATOR)\n const hasDev = split[1] === DocumentType.DEV\n if ((hasDev && split.length === 3) || (!hasDev && split.length === 2)) {\n return undefined\n }\n if (hasDev) {\n return split[2]\n } else {\n return split[1]\n }\n}\n\nfunction updateContext(updates: ContextMap): ContextMap {\n let context: ContextMap\n try {\n context = Context.get()\n } catch (err) {\n // no context, start empty\n context = {}\n }\n context = {\n ...context,\n ...updates,\n }\n return context\n}\n\nasync function newContext(updates: ContextMap, task: any) {\n // see if there already is a context setup\n let context: ContextMap = updateContext(updates)\n return Context.run(context, task)\n}\n\nexport async function doInAutomationContext(params: {\n appId: string\n automationId: string\n task: any\n}): Promise<any> {\n const tenantId = getTenantIDFromAppID(params.appId)\n return newContext(\n {\n tenantId,\n appId: params.appId,\n automationId: params.automationId,\n },\n params.task\n )\n}\n\nexport async function doInContext(appId: string, task: any): Promise<any> {\n const tenantId = getTenantIDFromAppID(appId)\n return newContext(\n {\n tenantId,\n appId,\n },\n task\n )\n}\n\nexport async function doInTenant<T>(\n tenantId: string | null,\n task: () => T\n): Promise<T> {\n // make sure default always selected in single tenancy\n if (!env.MULTI_TENANCY) {\n tenantId = tenantId || DEFAULT_TENANT_ID\n }\n\n const updates = tenantId ? { tenantId } : {}\n return newContext(updates, task)\n}\n\nexport async function doInAppContext(\n appId: string | null,\n task: any\n): Promise<any> {\n if (!appId && !env.isTest()) {\n throw new Error(\"appId is required\")\n }\n\n let updates: ContextMap\n if (!appId) {\n updates = { appId: \"\" }\n } else {\n const tenantId = getTenantIDFromAppID(appId)\n updates = { appId }\n if (tenantId) {\n updates.tenantId = tenantId\n }\n }\n return newContext(updates, task)\n}\n\nexport async function doInIdentityContext(\n identity: IdentityContext,\n task: any\n): Promise<any> {\n if (!identity) {\n throw new Error(\"identity is required\")\n }\n\n const context: ContextMap = {\n identity,\n }\n if (identity.tenantId) {\n context.tenantId = identity.tenantId\n }\n return newContext(context, task)\n}\n\nexport function getIdentity(): IdentityContext | undefined {\n try {\n const context = Context.get()\n return context?.identity\n } catch (e) {\n // do nothing - identity is not in context\n }\n}\n\nexport function getTenantId(): string {\n if (!isMultiTenant()) {\n return DEFAULT_TENANT_ID\n }\n const context = Context.get()\n const tenantId = context?.tenantId\n if (!tenantId) {\n throw new Error(\"Tenant id not found\")\n }\n return tenantId\n}\n\nexport function getAutomationId(): string | undefined {\n const context = Context.get()\n return context?.automationId\n}\n\nexport function getAppId(): string | undefined {\n const context = Context.get()\n const foundId = context?.appId\n if (!foundId && env.isTest() && TEST_APP_ID) {\n return TEST_APP_ID\n } else {\n return foundId\n }\n}\n\nexport const getProdAppId = () => {\n const appId = getAppId()\n if (!appId) {\n throw new Error(\"Could not get appId\")\n }\n return conversions.getProdAppID(appId)\n}\n\nexport function doInEnvironmentContext(\n values: Record<string, string>,\n task: any\n) {\n if (!values) {\n throw new Error(\"Must supply environment variables.\")\n }\n const updates = {\n environmentVariables: values,\n }\n return newContext(updates, task)\n}\n\nexport function doInScimContext(task: any) {\n const updates: ContextMap = {\n isScim: true,\n }\n return newContext(updates, task)\n}\n\nexport function getEnvironmentVariables() {\n const context = Context.get()\n if (!context.environmentVariables) {\n return null\n } else {\n return context.environmentVariables\n }\n}\n\nexport function getGlobalDB(): Database {\n const context = Context.get()\n if (!context || (env.MULTI_TENANCY && !context.tenantId)) {\n throw new Error(\"Global DB not found\")\n }\n return getDB(baseGlobalDBName(context?.tenantId))\n}\n\nexport function getAuditLogsDB(): Database {\n if (!getTenantId()) {\n throw new Error(\"No tenant ID found - cannot open audit log DB\")\n }\n return getDB(getAuditLogDBName())\n}\n\n/**\n * Gets the app database based on whatever the request\n * contained, dev or prod.\n */\nexport function getAppDB(opts?: any): Database {\n const appId = getAppId()\n return getDB(appId, opts)\n}\n\n/**\n * This specifically gets the prod app ID, if the request\n * contained a development app ID, this will get the prod one.\n */\nexport function getProdAppDB(opts?: any): Database {\n const appId = getAppId()\n if (!appId) {\n throw new Error(\"Unable to retrieve prod DB - no app ID.\")\n }\n return getDB(conversions.getProdAppID(appId), opts)\n}\n\n/**\n * This specifically gets the dev app ID, if the request\n * contained a prod app ID, this will get the dev one.\n */\nexport function getDevAppDB(opts?: any): Database {\n const appId = getAppId()\n if (!appId) {\n throw new Error(\"Unable to retrieve dev DB - no app ID.\")\n }\n return getDB(conversions.getDevelopmentAppID(appId), opts)\n}\n\nexport function isScim(): boolean {\n const context = Context.get()\n const scimCall = context?.isScim\n return !!scimCall\n}\n", "export { DEFAULT_TENANT_ID } from \"../constants\"\nexport * as identity from \"./identity\"\nexport * from \"./mainContext\"\n", "import env from \"../environment\"\n\nconst SLOT_REFRESH_MS = 2000\nconst CONNECT_TIMEOUT_MS = 10000\nexport const SEPARATOR = \"-\"\n\n/**\n * These Redis databases help us to segment up a Redis keyspace by prepending the\n * specified database name onto the cache key. This means that a single real Redis database\n * can be split up a bit; allowing us to use scans on small databases to find some particular\n * keys within.\n * If writing a very large volume of keys is expected (say 10K+) then it is better to keep these out\n * of the default keyspace and use a separate one - the SelectableDatabase can be used for this.\n */\nexport enum Databases {\n PW_RESETS = \"pwReset\",\n VERIFICATIONS = \"verification\",\n INVITATIONS = \"invitation\",\n DEV_LOCKS = \"devLocks\",\n DEBOUNCE = \"debounce\",\n SESSIONS = \"session\",\n USER_CACHE = \"users\",\n FLAGS = \"flags\",\n APP_METADATA = \"appMetadata\",\n QUERY_VARS = \"queryVars\",\n LICENSES = \"license\",\n GENERIC_CACHE = \"data_cache\",\n WRITE_THROUGH = \"writeThrough\",\n LOCKS = \"locks\",\n SOCKET_IO = \"socket_io\",\n}\n\n/**\n * These define the numeric Redis databases that can be access with the SELECT command -\n * (https://redis.io/commands/select/). By default a Redis server/cluster will have 16 selectable\n * databases, increasing this count increases the amount of CPU/memory required to run the server.\n * Ideally new Redis keyspaces should be used sparingly, only when absolutely necessary for performance\n * to be maintained. Generally a keyspace can grow to be very large is scans are not needed or desired,\n * but if you need to walk through all values in a database periodically then a separate selectable\n * keyspace should be used.\n */\nexport enum SelectableDatabase {\n DEFAULT = 0,\n SOCKET_IO = 1,\n UNUSED_1 = 2,\n UNUSED_2 = 3,\n UNUSED_3 = 4,\n UNUSED_4 = 5,\n UNUSED_5 = 6,\n UNUSED_6 = 7,\n UNUSED_7 = 8,\n UNUSED_8 = 9,\n UNUSED_9 = 10,\n UNUSED_10 = 11,\n UNUSED_11 = 12,\n UNUSED_12 = 13,\n UNUSED_13 = 14,\n UNUSED_14 = 15,\n}\n\nexport function getRedisOptions() {\n let password = env.REDIS_PASSWORD\n let url: string[] | string = env.REDIS_URL.split(\"//\")\n // get rid of the protocol\n url = url.length > 1 ? url[1] : url[0]\n // check for a password etc\n url = url.split(\"@\")\n if (url.length > 1) {\n // get the password\n password = url[0].split(\":\")[1]\n url = url[1]\n } else {\n url = url[0]\n }\n const [host, port] = url.split(\":\")\n\n let redisProtocolUrl\n\n // fully qualified redis URL\n if (/rediss?:\\/\\//.test(env.REDIS_URL)) {\n redisProtocolUrl = env.REDIS_URL\n }\n\n const opts: any = {\n connectTimeout: CONNECT_TIMEOUT_MS,\n }\n if (env.REDIS_CLUSTERED) {\n opts.redisOptions = {}\n opts.redisOptions.tls = {}\n opts.redisOptions.password = password\n opts.slotsRefreshTimeout = SLOT_REFRESH_MS\n opts.dnsLookup = (address: string, callback: any) => callback(null, address)\n } else {\n opts.host = host\n opts.port = port\n opts.password = password\n }\n return { opts, host, port, redisProtocolUrl }\n}\n\nexport function addDbPrefix(db: string, key: string) {\n if (key.includes(db)) {\n return key\n }\n return `${db}${SEPARATOR}${key}`\n}\n\nexport function removeDbPrefix(key: string) {\n let parts = key.split(SEPARATOR)\n if (parts.length >= 2) {\n parts.shift()\n return parts.join(SEPARATOR)\n } else {\n // return the only part\n return parts[0]\n }\n}\n", "let intervals: NodeJS.Timeout[] = []\n\nexport function set(callback: () => any, period: number) {\n const interval = setInterval(callback, period)\n intervals.push(interval)\n return interval\n}\n\nexport function clear(interval: NodeJS.Timeout) {\n const idx = intervals.indexOf(interval)\n if (idx !== -1) {\n intervals.splice(idx, 1)\n }\n clearInterval(interval)\n}\n\nexport function cleanup() {\n for (let interval of intervals) {\n clearInterval(interval)\n }\n intervals = []\n}\n", "export * from \"./timers\"\n", "import env from \"../environment\"\n// ioredis mock is all in memory\nconst Redis = env.MOCK_REDIS ? require(\"ioredis-mock\") : require(\"ioredis\")\nimport {\n addDbPrefix,\n removeDbPrefix,\n getRedisOptions,\n SEPARATOR,\n SelectableDatabase,\n} from \"./utils\"\nimport * as timers from \"../timers\"\n\nconst RETRY_PERIOD_MS = 2000\nconst STARTUP_TIMEOUT_MS = 5000\nconst CLUSTERED = env.REDIS_CLUSTERED\nconst DEFAULT_SELECT_DB = SelectableDatabase.DEFAULT\n\n// for testing just generate the client once\nlet CLOSED = false\nlet CLIENTS: { [key: number]: any } = {}\n\nlet CONNECTED = false\n\n// mock redis always connected\nif (env.MOCK_REDIS) {\n CONNECTED = true\n}\n\nfunction pickClient(selectDb: number): any {\n return CLIENTS[selectDb]\n}\n\nfunction connectionError(\n selectDb: number,\n timeout: NodeJS.Timeout,\n err: Error | string\n) {\n // manually shut down, ignore errors\n if (CLOSED) {\n return\n }\n pickClient(selectDb).disconnect()\n CLOSED = true\n // always clear this on error\n clearTimeout(timeout)\n CONNECTED = false\n console.error(\"Redis connection failed - \" + err)\n setTimeout(() => {\n init()\n }, RETRY_PERIOD_MS)\n}\n\n/**\n * Inits the system, will error if unable to connect to redis cluster (may take up to 10 seconds) otherwise\n * will return the ioredis client which will be ready to use.\n */\nfunction init(selectDb = DEFAULT_SELECT_DB) {\n let timeout: NodeJS.Timeout\n CLOSED = false\n let client = pickClient(selectDb)\n // already connected, ignore\n if (client && CONNECTED) {\n return\n }\n // testing uses a single in memory client\n if (env.MOCK_REDIS) {\n CLIENTS[selectDb] = new Redis(getRedisOptions())\n }\n // start the timer - only allowed 5 seconds to connect\n timeout = setTimeout(() => {\n if (!CONNECTED) {\n connectionError(\n selectDb,\n timeout,\n \"Did not successfully connect in timeout\"\n )\n }\n }, STARTUP_TIMEOUT_MS)\n\n // disconnect any lingering client\n if (client) {\n client.disconnect()\n }\n const { redisProtocolUrl, opts, host, port } = getRedisOptions()\n\n if (CLUSTERED) {\n client = new Redis.Cluster([{ host, port }], opts)\n } else if (redisProtocolUrl) {\n client = new Redis(redisProtocolUrl)\n } else {\n client = new Redis(opts)\n }\n // attach handlers\n client.on(\"end\", (err: Error) => {\n if (env.isTest()) {\n // don't try to re-connect in test env\n // allow the process to exit\n return\n }\n connectionError(selectDb, timeout, err)\n })\n client.on(\"error\", (err: Error) => {\n connectionError(selectDb, timeout, err)\n })\n client.on(\"connect\", () => {\n clearTimeout(timeout)\n CONNECTED = true\n })\n CLIENTS[selectDb] = client\n}\n\nfunction waitForConnection(selectDb: number = DEFAULT_SELECT_DB) {\n return new Promise(resolve => {\n if (pickClient(selectDb) == null) {\n init()\n } else if (CONNECTED) {\n resolve(\"\")\n return\n }\n // check if the connection is ready\n const interval = timers.set(() => {\n if (CONNECTED) {\n timers.clear(interval)\n resolve(\"\")\n }\n }, 500)\n })\n}\n\n/**\n * Utility function, takes a redis stream and converts it to a promisified response -\n * this can only be done with redis streams because they will have an end.\n * @param stream A redis stream, specifically as this type of stream will have an end.\n * @param client The client to use for further lookups.\n * @return {Promise<object>} The final output of the stream\n */\nfunction promisifyStream(stream: any, client: RedisWrapper) {\n return new Promise((resolve, reject) => {\n const outputKeys = new Set()\n stream.on(\"data\", (keys: string[]) => {\n keys.forEach(key => {\n outputKeys.add(key)\n })\n })\n stream.on(\"error\", (err: Error) => {\n reject(err)\n })\n stream.on(\"end\", async () => {\n const keysArray: string[] = Array.from(outputKeys) as string[]\n try {\n let getPromises = []\n for (let key of keysArray) {\n getPromises.push(client.get(key))\n }\n const jsonArray = await Promise.all(getPromises)\n resolve(\n keysArray.map(key => ({\n key: removeDbPrefix(key),\n value: JSON.parse(jsonArray.shift()),\n }))\n )\n } catch (err) {\n reject(err)\n }\n })\n })\n}\n\nclass RedisWrapper {\n _db: string\n _select: number\n\n constructor(db: string, selectDb: number | null = null) {\n this._db = db\n this._select = selectDb || DEFAULT_SELECT_DB\n }\n\n getClient() {\n return pickClient(this._select)\n }\n\n async init() {\n CLOSED = false\n init(this._select)\n await waitForConnection(this._select)\n if (this._select && !env.isTest()) {\n this.getClient().select(this._select)\n }\n return this\n }\n\n async finish() {\n CLOSED = true\n this.getClient().disconnect()\n }\n\n async scan(key = \"\"): Promise<any> {\n const db = this._db\n key = `${db}${SEPARATOR}${key}`\n let stream\n if (CLUSTERED) {\n let node = this.getClient().nodes(\"master\")\n stream = node[0].scanStream({ match: key + \"*\", count: 100 })\n } else {\n stream = this.getClient().scanStream({ match: key + \"*\", count: 100 })\n }\n return promisifyStream(stream, this.getClient())\n }\n\n async keys(pattern: string) {\n const db = this._db\n return this.getClient().keys(addDbPrefix(db, pattern))\n }\n\n async exists(key: string) {\n const db = this._db\n return await this.getClient().exists(addDbPrefix(db, key))\n }\n\n async get(key: string) {\n const db = this._db\n let response = await this.getClient().get(addDbPrefix(db, key))\n // overwrite the prefixed key\n if (response != null && response.key) {\n response.key = key\n }\n // if its not an object just return the response\n try {\n return JSON.parse(response)\n } catch (err) {\n return response\n }\n }\n\n async bulkGet(keys: string[]) {\n const db = this._db\n if (keys.length === 0) {\n return {}\n }\n const prefixedKeys = keys.map(key => addDbPrefix(db, key))\n let response = await this.getClient().mget(prefixedKeys)\n if (Array.isArray(response)) {\n let final: any = {}\n let count = 0\n for (let result of response) {\n if (result) {\n let parsed\n try {\n parsed = JSON.parse(result)\n } catch (err) {\n parsed = result\n }\n final[keys[count]] = parsed\n }\n count++\n }\n return final\n } else {\n throw new Error(`Invalid response: ${response}`)\n }\n }\n\n async store(key: string, value: any, expirySeconds: number | null = null) {\n const db = this._db\n if (typeof value === \"object\") {\n value = JSON.stringify(value)\n }\n const prefixedKey = addDbPrefix(db, key)\n await this.getClient().set(prefixedKey, value)\n if (expirySeconds) {\n await this.getClient().expire(prefixedKey, expirySeconds)\n }\n }\n\n async getTTL(key: string) {\n const db = this._db\n const prefixedKey = addDbPrefix(db, key)\n return this.getClient().ttl(prefixedKey)\n }\n\n async setExpiry(key: string, expirySeconds: number | null) {\n const db = this._db\n const prefixedKey = addDbPrefix(db, key)\n await this.getClient().expire(prefixedKey, expirySeconds)\n }\n\n async delete(key: string) {\n const db = this._db\n await this.getClient().del(addDbPrefix(db, key))\n }\n\n async clear() {\n let items = await this.scan()\n await Promise.all(items.map((obj: any) => this.delete(obj.key)))\n }\n}\n\nexport default RedisWrapper\n", "import Client from \"./redis\"\nimport * as utils from \"./utils\"\n\nlet userClient: Client,\n sessionClient: Client,\n appClient: Client,\n cacheClient: Client,\n writethroughClient: Client,\n lockClient: Client,\n socketClient: Client\n\nasync function init() {\n userClient = await new Client(utils.Databases.USER_CACHE).init()\n sessionClient = await new Client(utils.Databases.SESSIONS).init()\n appClient = await new Client(utils.Databases.APP_METADATA).init()\n cacheClient = await new Client(utils.Databases.GENERIC_CACHE).init()\n lockClient = await new Client(utils.Databases.LOCKS).init()\n writethroughClient = await new Client(utils.Databases.WRITE_THROUGH).init()\n socketClient = await new Client(\n utils.Databases.SOCKET_IO,\n utils.SelectableDatabase.SOCKET_IO\n ).init()\n}\n\nexport async function shutdown() {\n if (userClient) await userClient.finish()\n if (sessionClient) await sessionClient.finish()\n if (appClient) await appClient.finish()\n if (cacheClient) await cacheClient.finish()\n if (writethroughClient) await writethroughClient.finish()\n if (lockClient) await lockClient.finish()\n if (socketClient) await socketClient.finish()\n}\n\nprocess.on(\"exit\", async () => {\n await shutdown()\n})\n\nexport async function getUserClient() {\n if (!userClient) {\n await init()\n }\n return userClient\n}\n\nexport async function getSessionClient() {\n if (!sessionClient) {\n await init()\n }\n return sessionClient\n}\n\nexport async function getAppClient() {\n if (!appClient) {\n await init()\n }\n return appClient\n}\n\nexport async function getCacheClient() {\n if (!cacheClient) {\n await init()\n }\n return cacheClient\n}\n\nexport async function getWritethroughClient() {\n if (!writethroughClient) {\n await init()\n }\n return writethroughClient\n}\n\nexport async function getLockClient() {\n if (!lockClient) {\n await init()\n }\n return lockClient\n}\n\nexport async function getSocketClient() {\n if (!socketClient) {\n await init()\n }\n return socketClient\n}\n", "import { getTenantId } from \"../../context\"\nimport * as redis from \"../../redis/init\"\nimport { Client } from \"../../redis\"\n\nfunction generateTenantKey(key: string) {\n const tenantId = getTenantId()\n return `${key}:${tenantId}`\n}\n\nexport default class BaseCache {\n client: Client | undefined\n\n constructor(client: Client | undefined = undefined) {\n this.client = client\n }\n\n async getClient() {\n return !this.client ? await redis.getCacheClient() : this.client\n }\n\n async keys(pattern: string) {\n const client = await this.getClient()\n return client.keys(pattern)\n }\n\n /**\n * Read only from the cache.\n */\n async get(key: string, opts = { useTenancy: true }) {\n key = opts.useTenancy ? generateTenantKey(key) : key\n const client = await this.getClient()\n return client.get(key)\n }\n\n /**\n * Write to the cache.\n */\n async store(\n key: string,\n value: any,\n ttl: number | null = null,\n opts = { useTenancy: true }\n ) {\n key = opts.useTenancy ? generateTenantKey(key) : key\n const client = await this.getClient()\n await client.store(key, value, ttl)\n }\n\n /**\n * Remove from cache.\n */\n async delete(key: string, opts = { useTenancy: true }) {\n key = opts.useTenancy ? generateTenantKey(key) : key\n const client = await this.getClient()\n return client.delete(key)\n }\n\n /**\n * Read from the cache. Write to the cache if not exists.\n */\n async withCache(\n key: string,\n ttl: number,\n fetchFn: any,\n opts = { useTenancy: true }\n ) {\n const cachedValue = await this.get(key, opts)\n if (cachedValue) {\n return cachedValue\n }\n\n try {\n const fetchedValue = await fetchFn()\n\n await this.store(key, fetchedValue, ttl, opts)\n return fetchedValue\n } catch (err) {\n console.error(\"Error fetching before cache - \", err)\n throw err\n }\n }\n\n async bustCache(key: string, opts = { client: null }) {\n const client = await this.getClient()\n try {\n await client.delete(generateTenantKey(key))\n } catch (err) {\n console.error(\"Error busting cache - \", err)\n throw err\n }\n }\n}\n", "import { Header } from \"../../constants\"\nconst correlator = require(\"correlation-id\")\n\nexport const setHeader = (headers: any) => {\n const correlationId = correlator.getId()\n if (correlationId) {\n headers[Header.CORRELATION_ID] = correlationId\n }\n}\n\nexport function getId() {\n return correlator.getId()\n}\n", "export * from \"./correlation\"\n", "import env from \"../../environment\"\nimport pino, { LoggerOptions } from \"pino\"\nimport * as context from \"../../context\"\nimport * as correlation from \"../correlation\"\nimport { IdentityType } from \"@budibase/types\"\nimport { LOG_CONTEXT } from \"../index\"\n\n// LOGGER\n\nlet pinoInstance: pino.Logger | undefined\nif (!env.DISABLE_PINO_LOGGER) {\n const pinoOptions: LoggerOptions = {\n level: env.LOG_LEVEL,\n formatters: {\n level: label => {\n return { level: label.toUpperCase() }\n },\n bindings: () => {\n return {}\n },\n },\n timestamp: () => `,\"timestamp\":\"${new Date(Date.now()).toISOString()}\"`,\n }\n\n if (env.isDev()) {\n pinoOptions.transport = {\n target: \"pino-pretty\",\n options: {\n singleLine: true,\n },\n }\n }\n\n pinoInstance = pino(pinoOptions)\n\n // CONSOLE OVERRIDES\n\n interface MergingObject {\n objects?: any[]\n tenantId?: string\n appId?: string\n automationId?: string\n identityId?: string\n identityType?: IdentityType\n correlationId?: string\n err?: Error\n }\n\n function isPlainObject(obj: any) {\n return typeof obj === \"object\" && obj !== null && !(obj instanceof Error)\n }\n\n function isError(obj: any) {\n return obj instanceof Error\n }\n\n function isMessage(obj: any) {\n return typeof obj === \"string\"\n }\n\n /**\n * Backwards compatibility between console logging statements\n * and pino logging requirements.\n */\n function getLogParams(args: any[]): [MergingObject, string] {\n let error = undefined\n let objects: any[] = []\n let message = \"\"\n\n args.forEach(arg => {\n if (isMessage(arg)) {\n message = `${message} ${arg}`.trimStart()\n }\n if (isPlainObject(arg)) {\n objects.push(arg)\n }\n if (isError(arg)) {\n error = arg\n }\n })\n\n const identity = getIdentity()\n\n let contextObject = {}\n\n if (LOG_CONTEXT) {\n contextObject = {\n tenantId: getTenantId(),\n appId: getAppId(),\n automationId: getAutomationId(),\n identityId: identity?._id,\n identityType: identity?.type,\n correlationId: correlation.getId(),\n }\n }\n\n const mergingObject: any = {\n err: error,\n pid: process.pid,\n ...contextObject,\n }\n\n if (objects.length) {\n // init generic data object for params supplied that don't have a\n // '_logKey' field. This prints an object using argument index as the key\n // e.g. { 0: {}, 1: {} }\n const data: any = {}\n let dataIndex = 0\n\n for (let i = 0; i < objects.length; i++) {\n const object = objects[i]\n // the object has specified a log key\n // use this instead of generic key\n const logKey = object._logKey\n if (logKey) {\n delete object._logKey\n mergingObject[logKey] = object\n } else {\n data[dataIndex] = object\n dataIndex++\n }\n }\n\n if (Object.keys(data).length) {\n mergingObject.data = data\n }\n }\n\n return [mergingObject, message]\n }\n\n console.log = (...arg: any[]) => {\n const [obj, msg] = getLogParams(arg)\n pinoInstance?.info(obj, msg)\n }\n console.info = (...arg: any[]) => {\n const [obj, msg] = getLogParams(arg)\n pinoInstance?.info(obj, msg)\n }\n console.warn = (...arg: any[]) => {\n const [obj, msg] = getLogParams(arg)\n pinoInstance?.warn(obj, msg)\n }\n console.error = (...arg: any[]) => {\n const [obj, msg] = getLogParams(arg)\n pinoInstance?.error(obj, msg)\n }\n\n /**\n * custom trace impl - this resembles the node trace behaviour rather\n * than traditional trace logging\n * @param arg\n */\n console.trace = (...arg: any[]) => {\n const [obj, msg] = getLogParams(arg)\n if (!obj.err) {\n // to get stack trace\n obj.err = new Error()\n }\n pinoInstance?.trace(obj, msg)\n }\n\n console.debug = (...arg: any) => {\n const [obj, msg] = getLogParams(arg)\n pinoInstance?.debug(obj, msg)\n }\n\n // CONTEXT\n\n const getTenantId = () => {\n let tenantId\n try {\n tenantId = context.getTenantId()\n } catch (e: any) {\n // do nothing\n }\n return tenantId\n }\n\n const getAppId = () => {\n let appId\n try {\n appId = context.getAppId()\n } catch (e) {\n // do nothing\n }\n return appId\n }\n\n const getAutomationId = () => {\n let appId\n try {\n appId = context.getAutomationId()\n } catch (e) {\n // do nothing\n }\n return appId\n }\n\n const getIdentity = () => {\n let identity\n try {\n identity = context.getIdentity()\n } catch (e) {\n // do nothing\n }\n return identity\n }\n}\n\nexport const logger = pinoInstance\n", "const NonErrors = [\"AccountError\"]\n\nfunction isSuppressed(e?: any) {\n return e && e[\"suppressAlert\"]\n}\n\nexport function logAlert(message: string, e?: any) {\n if (e && NonErrors.includes(e.name) && isSuppressed(e)) {\n return\n }\n console.error(`bb-alert: ${message}`, e)\n}\n\nexport function logAlertWithInfo(\n message: string,\n db: string,\n id: string,\n error: any\n) {\n message = `${message} - db: ${db} - doc: ${id} - error: `\n logAlert(message, error)\n}\n\nexport function logWarn(message: string) {\n console.warn(`bb-warn: ${message}`)\n}\n", "export * as correlation from \"./correlation/correlation\"\nexport { logger } from \"./pino/logger\"\nexport * from \"./alerts\"\n\n// turn off or on context logging i.e. tenantId, appId etc\nexport let LOG_CONTEXT = true\n", "class Helper {\n constructor(name, fn, useValueFallback = true) {\n this.name = name\n this.fn = fn\n this.useValueFallback = useValueFallback\n }\n\n register(handlebars) {\n // wrap the function so that no helper can cause handlebars to break\n handlebars.registerHelper(this.name, (value, info) => {\n let context = {}\n if (info && info.data && info.data.root) {\n context = info.data.root\n }\n const result = this.fn(value, context)\n if (result == null) {\n return this.useValueFallback ? value : null\n } else {\n return result\n }\n })\n }\n\n unregister(handlebars) {\n handlebars.unregisterHelper(this.name)\n }\n}\n\nmodule.exports = Helper\n", "const dayjs = require(\"dayjs\")\ndayjs.extend(require(\"dayjs/plugin/duration\"))\ndayjs.extend(require(\"dayjs/plugin/advancedFormat\"))\ndayjs.extend(require(\"dayjs/plugin/isoWeek\"))\ndayjs.extend(require(\"dayjs/plugin/weekYear\"))\ndayjs.extend(require(\"dayjs/plugin/weekOfYear\"))\ndayjs.extend(require(\"dayjs/plugin/relativeTime\"))\ndayjs.extend(require(\"dayjs/plugin/utc\"))\ndayjs.extend(require(\"dayjs/plugin/timezone\"))\n\n/**\n * This file was largely taken from the helper-date package - we did this for two reasons:\n * 1. It made use of both moment of date.js - this caused some weird bugs with some relatively simple\n * syntax and didn't offer much in return.\n * 2. Replacing moment with dayjs helps massively reduce bundle size.\n * The original package can be found here:\n * https://github.com/helpers/helper-date\n */\n\nfunction isOptions(val) {\n return typeof val === \"object\" && typeof val.hash === \"object\"\n}\n\nfunction isApp(thisArg) {\n return (\n typeof thisArg === \"object\" &&\n typeof thisArg.options === \"object\" &&\n typeof thisArg.app === \"object\"\n )\n}\n\nfunction getContext(thisArg, locals, options) {\n if (isOptions(thisArg)) {\n return getContext({}, locals, thisArg)\n }\n // ensure args are in the correct order\n if (isOptions(locals)) {\n return getContext(thisArg, options, locals)\n }\n const appContext = isApp(thisArg) ? thisArg.context : {}\n options = options || {}\n\n // if \"options\" is not handlebars options, merge it onto locals\n if (!isOptions(options)) {\n locals = Object.assign({}, locals, options)\n }\n // merge handlebars root data onto locals if specified on the hash\n if (isOptions(options) && options.hash.root === true) {\n locals = Object.assign({}, options.data.root, locals)\n }\n let context = Object.assign({}, appContext, locals, options.hash)\n if (!isApp(thisArg)) {\n context = Object.assign({}, thisArg, context)\n }\n if (isApp(thisArg) && thisArg.view && thisArg.view.data) {\n context = Object.assign({}, context, thisArg.view.data)\n }\n return context\n}\n\nfunction initialConfig(str, pattern, options) {\n if (isOptions(pattern)) {\n options = pattern\n pattern = null\n }\n\n if (isOptions(str)) {\n options = str\n pattern = null\n str = null\n }\n return { str, pattern, options }\n}\n\nfunction setLocale(str, pattern, options) {\n // if options is null then it'll get updated here\n const config = initialConfig(str, pattern, options)\n const defaults = { lang: \"en\", date: new Date(config.str) }\n // for now don't allow this to be configurable, don't pass in options\n const opts = getContext(this, defaults, {})\n\n // set the language to use\n dayjs.locale(opts.lang || opts.language)\n}\n\nmodule.exports.date = (str, pattern, options) => {\n const config = initialConfig(str, pattern, options)\n\n // if no args are passed, return a formatted date\n if (config.str == null && config.pattern == null) {\n dayjs.locale(\"en\")\n return dayjs().format(\"MMMM DD, YYYY\")\n }\n\n setLocale(config.str, config.pattern, config.options)\n\n let date = dayjs(new Date(config.str))\n if (typeof config.options === \"string\") {\n date =\n config.options.toLowerCase() === \"utc\"\n ? date.utc()\n : date.tz(config.options)\n } else {\n date = date.tz(dayjs.tz.guess())\n }\n if (config.pattern === \"\") {\n return date.toISOString()\n }\n return date.format(config.pattern)\n}\n\nmodule.exports.duration = (str, pattern, format) => {\n const config = initialConfig(str, pattern)\n\n setLocale(config.str, config.pattern)\n\n const duration = dayjs.duration(config.str, config.pattern)\n if (!isOptions(format)) {\n return duration.format(format)\n } else {\n return duration.humanize()\n }\n}\n", "module.exports.HelperFunctionBuiltin = [\n \"#if\",\n \"#unless\",\n \"#each\",\n \"#with\",\n \"lookup\",\n \"log\",\n \"blockHelperMissing\",\n \"each\",\n \"helperMissing\",\n \"if\",\n \"unless\",\n \"log\",\n \"lookup\",\n \"with\",\n]\n\nmodule.exports.HelperFunctionNames = {\n OBJECT: \"object\",\n ALL: \"all\",\n LITERAL: \"literal\",\n JS: \"js\",\n}\n\nmodule.exports.LITERAL_MARKER = \"%LITERAL%\"\n", "const helpers = require(\"@budibase/handlebars-helpers\")\nconst { date, duration } = require(\"./date\")\nconst { HelperFunctionBuiltin } = require(\"./constants\")\n\n/**\n * full list of supported helpers can be found here:\n * https://github.com/Budibase/handlebars-helpers\n */\n\nconst EXTERNAL_FUNCTION_COLLECTIONS = [\n \"math\",\n \"array\",\n \"number\",\n \"url\",\n \"string\",\n \"comparison\",\n \"object\",\n \"regex\",\n]\n\nconst ADDED_HELPERS = {\n date: date,\n duration: duration,\n}\n\nexports.externalCollections = EXTERNAL_FUNCTION_COLLECTIONS\nexports.addedHelpers = ADDED_HELPERS\n\nexports.registerAll = handlebars => {\n for (let [name, helper] of Object.entries(ADDED_HELPERS)) {\n handlebars.registerHelper(name, helper)\n }\n let externalNames = []\n for (let collection of EXTERNAL_FUNCTION_COLLECTIONS) {\n // collect information about helper\n let hbsHelperInfo = helpers[collection]()\n for (let entry of Object.entries(hbsHelperInfo)) {\n const name = entry[0]\n // skip built in functions and ones seen already\n if (\n HelperFunctionBuiltin.indexOf(name) !== -1 ||\n externalNames.indexOf(name) !== -1\n ) {\n continue\n }\n externalNames.push(name)\n }\n // attach it to our handlebars instance\n helpers[collection]({\n handlebars,\n })\n }\n // add date external functionality\n exports.externalHelperNames = externalNames.concat(Object.keys(ADDED_HELPERS))\n}\n\nexports.unregisterAll = handlebars => {\n for (let name of Object.keys(ADDED_HELPERS)) {\n handlebars.unregisterHelper(name)\n }\n for (let name of module.exports.externalHelperNames) {\n handlebars.unregisterHelper(name)\n }\n exports.externalHelperNames = []\n}\n\nexports.externalHelperNames = []\n", "const ALPHA_NUMERIC_REGEX = /^[A-Za-z0-9]+$/g\n\nmodule.exports.FIND_HBS_REGEX = /{{([^{].*?)}}/g\nmodule.exports.FIND_ANY_HBS_REGEX = /{?{{([^{].*?)}}}?/g\nmodule.exports.FIND_TRIPLE_HBS_REGEX = /{{{([^{].*?)}}}/g\n\n// originally this could be done with a single regex using look behinds\n// but safari does not support this feature\n// original regex: /(?<!{){{[^{}]+}}(?!})/g\nmodule.exports.findDoubleHbsInstances = string => {\n let copied = string\n const doubleRegex = new RegExp(exports.FIND_HBS_REGEX)\n const regex = new RegExp(exports.FIND_TRIPLE_HBS_REGEX)\n const tripleMatches = copied.match(regex)\n // remove triple braces\n if (tripleMatches) {\n tripleMatches.forEach(match => {\n copied = copied.replace(match, \"\")\n })\n }\n const doubleMatches = copied.match(doubleRegex)\n return doubleMatches ? doubleMatches : []\n}\n\nmodule.exports.isAlphaNumeric = char => {\n return char.match(ALPHA_NUMERIC_REGEX)\n}\n\nmodule.exports.swapStrings = (string, start, length, swap) => {\n return string.slice(0, start) + swap + string.slice(start + length)\n}\n\nmodule.exports.removeHandlebarsStatements = (\n string,\n replacement = \"Invalid binding\"\n) => {\n let regexp = new RegExp(exports.FIND_HBS_REGEX)\n let matches = string.match(regexp)\n if (matches == null) {\n return string\n }\n for (let match of matches) {\n const idx = string.indexOf(match)\n string = exports.swapStrings(string, idx, match.length, replacement)\n }\n return string\n}\n\nmodule.exports.btoa = plainText => {\n return Buffer.from(plainText, \"utf-8\").toString(\"base64\")\n}\n\nmodule.exports.atob = base64 => {\n return Buffer.from(base64, \"base64\").toString(\"utf-8\")\n}\n", "const externalHandlebars = require(\"./external\")\nconst helperList = require(\"@budibase/handlebars-helpers\")\n\nmodule.exports.getHelperList = () => {\n let constructed = []\n for (let collection of externalHandlebars.externalCollections) {\n constructed.push(helperList[collection]())\n }\n const fullMap = {}\n for (let collection of constructed) {\n for (let [key, func] of Object.entries(collection)) {\n fullMap[key] = func\n }\n }\n for (let key of Object.keys(externalHandlebars.addedHelpers)) {\n fullMap[key] = externalHandlebars.addedHelpers[key]\n }\n return fullMap\n}\n", "const { atob } = require(\"../utilities\")\nconst { cloneDeep } = require(\"lodash/fp\")\nconst { LITERAL_MARKER } = require(\"../helpers/constants\")\nconst { getHelperList } = require(\"./list\")\n\n// The method of executing JS scripts depends on the bundle being built.\n// This setter is used in the entrypoint (either index.cjs or index.mjs).\nlet runJS\nmodule.exports.setJSRunner = runner => (runJS = runner)\n\n// Helper utility to strip square brackets from a value\nconst removeSquareBrackets = value => {\n if (!value || typeof value !== \"string\") {\n return value\n }\n const regex = /\\[+(.+)]+/\n const matches = value.match(regex)\n if (matches && matches[1]) {\n return matches[1]\n }\n return value\n}\n\n// Our context getter function provided to JS code as $.\n// Extracts a value from context.\nconst getContextValue = (path, context) => {\n let data = context\n path.split(\".\").forEach(key => {\n if (data == null || typeof data !== \"object\") {\n return null\n }\n data = data[removeSquareBrackets(key)]\n })\n return data\n}\n\n// Evaluates JS code against a certain context\nmodule.exports.processJS = (handlebars, context) => {\n if (process && process.env.NO_JS) {\n throw new Error(\"JS disabled in environment.\")\n }\n try {\n // Wrap JS in a function and immediately invoke it.\n // This is required to allow the final `return` statement to be valid.\n const js = `function run(){${atob(handlebars)}};run();`\n\n // Our $ context function gets a value from context.\n // We clone the context to avoid mutation in the binding affecting real\n // app context.\n const sandboxContext = {\n $: path => getContextValue(path, cloneDeep(context)),\n helpers: getHelperList(),\n }\n\n // Create a sandbox with our context and run the JS\n const res = { data: runJS(js, sandboxContext) }\n return `{{${LITERAL_MARKER} js_result-${JSON.stringify(res)}}}`\n } catch (error) {\n return \"Error while executing JS\"\n }\n}\n", "const Helper = require(\"./Helper\")\nconst { SafeString } = require(\"handlebars\")\nconst externalHandlebars = require(\"./external\")\nconst { processJS } = require(\"./javascript\")\nconst {\n HelperFunctionNames,\n HelperFunctionBuiltin,\n LITERAL_MARKER,\n} = require(\"./constants\")\nconst { getHelperList } = require(\"./list\")\n\nconst HTML_SWAPS = {\n \"<\": \"&lt;\",\n \">\": \"&gt;\",\n}\n\nfunction isObject(value) {\n if (value == null || typeof value !== \"object\") {\n return false\n }\n return (\n value.toString() === \"[object Object]\" ||\n (value.length > 0 && typeof value[0] === \"object\")\n )\n}\n\nconst HELPERS = [\n // external helpers\n new Helper(HelperFunctionNames.OBJECT, value => {\n return new SafeString(JSON.stringify(value))\n }),\n // javascript helper\n new Helper(HelperFunctionNames.JS, processJS, false),\n // this help is applied to all statements\n new Helper(HelperFunctionNames.ALL, (value, inputs) => {\n const { __opts } = inputs\n if (isObject(value)) {\n return new SafeString(JSON.stringify(value))\n }\n // null/undefined values produce bad results\n if (__opts && __opts.onlyFound && value == null) {\n return __opts.input\n }\n if (value == null || typeof value !== \"string\") {\n return value == null ? \"\" : value\n }\n if (value && value.string) {\n value = value.string\n }\n let text = value\n if (__opts && __opts.escapeNewlines) {\n text = value.replace(/\\n/g, \"\\\\n\")\n }\n text = new SafeString(text.replace(/&amp;/g, \"&\"))\n if (text == null || typeof text !== \"string\") {\n return text\n }\n return text.replace(/[<>]/g, tag => {\n return HTML_SWAPS[tag] || tag\n })\n }),\n // adds a note for post-processor\n new Helper(HelperFunctionNames.LITERAL, value => {\n if (value === undefined) {\n return \"\"\n }\n const type = typeof value\n const outputVal = type === \"object\" ? JSON.stringify(value) : value\n return `{{${LITERAL_MARKER} ${type}-${outputVal}}}`\n }),\n]\n\nmodule.exports.HelperNames = () => {\n return Object.values(HelperFunctionNames).concat(\n HelperFunctionBuiltin,\n externalHandlebars.externalHelperNames\n )\n}\n\nmodule.exports.registerMinimum = handlebars => {\n for (let helper of HELPERS) {\n helper.register(handlebars)\n }\n}\n\nmodule.exports.registerAll = handlebars => {\n module.exports.registerMinimum(handlebars)\n // register imported helpers\n externalHandlebars.registerAll(handlebars)\n}\n\nmodule.exports.unregisterAll = handlebars => {\n for (let helper of HELPERS) {\n helper.unregister(handlebars)\n }\n // unregister all imported helpers\n externalHandlebars.unregisterAll(handlebars)\n}\n\nmodule.exports.getHelperList = getHelperList\n", "const { HelperNames } = require(\"../helpers\")\nconst { swapStrings, isAlphaNumeric } = require(\"../utilities\")\n\nconst FUNCTION_CASES = [\"#\", \"else\", \"/\"]\n\nconst PreprocessorNames = {\n SWAP_TO_DOT: \"swap-to-dot-notation\",\n FIX_FUNCTIONS: \"fix-functions\",\n FINALISE: \"finalise\",\n}\n\n/* eslint-disable no-unused-vars */\nclass Preprocessor {\n constructor(name, fn) {\n this.name = name\n this.fn = fn\n }\n\n process(fullString, statement, opts) {\n const output = this.fn(statement, opts)\n const idx = fullString.indexOf(statement)\n return swapStrings(fullString, idx, statement.length, output)\n }\n}\n\nmodule.exports.processors = [\n new Preprocessor(PreprocessorNames.SWAP_TO_DOT, statement => {\n let startBraceIdx = statement.indexOf(\"[\")\n let lastIdx = 0\n while (startBraceIdx !== -1) {\n // if the character previous to the literal specifier is alphanumeric this should happen\n if (isAlphaNumeric(statement.charAt(startBraceIdx - 1))) {\n statement = swapStrings(statement, startBraceIdx + lastIdx, 1, \".[\")\n }\n lastIdx = startBraceIdx + 1\n const nextBraceIdx = statement.substring(lastIdx + 1).indexOf(\"[\")\n startBraceIdx = nextBraceIdx > 0 ? lastIdx + 1 + nextBraceIdx : -1\n }\n return statement\n }),\n\n new Preprocessor(PreprocessorNames.FIX_FUNCTIONS, statement => {\n for (let specialCase of FUNCTION_CASES) {\n const toFind = `{ ${specialCase}`,\n replacement = `{${specialCase}`\n statement = statement.replace(new RegExp(toFind, \"g\"), replacement)\n }\n return statement\n }),\n\n new Preprocessor(PreprocessorNames.FINALISE, (statement, opts) => {\n const noHelpers = opts && opts.noHelpers\n let insideStatement = statement.slice(2, statement.length - 2)\n if (insideStatement.charAt(0) === \" \") {\n insideStatement = insideStatement.slice(1)\n }\n if (insideStatement.charAt(insideStatement.length - 1) === \" \") {\n insideStatement = insideStatement.slice(0, insideStatement.length - 1)\n }\n const possibleHelper = insideStatement.split(\" \")[0]\n // function helpers can't be wrapped\n for (let specialCase of FUNCTION_CASES) {\n if (possibleHelper.includes(specialCase)) {\n return statement\n }\n }\n const testHelper = possibleHelper.trim().toLowerCase()\n if (\n !noHelpers &&\n HelperNames().some(option => testHelper === option.toLowerCase())\n ) {\n insideStatement = `(${insideStatement})`\n }\n return `{{ all ${insideStatement} }}`\n }),\n]\n\nmodule.exports.PreprocessorNames = PreprocessorNames\n", "const { LITERAL_MARKER } = require(\"../helpers/constants\")\n\nconst PostProcessorNames = {\n CONVERT_LITERALS: \"convert-literals\",\n}\n\n/* eslint-disable no-unused-vars */\nclass Postprocessor {\n constructor(name, fn) {\n this.name = name\n this.fn = fn\n }\n\n process(statement) {\n return this.fn(statement)\n }\n}\n\nmodule.exports.PostProcessorNames = PostProcessorNames\n\nmodule.exports.processors = [\n new Postprocessor(PostProcessorNames.CONVERT_LITERALS, statement => {\n if (typeof statement !== \"string\" || !statement.includes(LITERAL_MARKER)) {\n return statement\n }\n const splitMarkerIndex = statement.indexOf(\"-\")\n const type = statement.substring(12, splitMarkerIndex)\n const value = statement.substring(\n splitMarkerIndex + 1,\n statement.length - 2\n )\n switch (type) {\n case \"string\":\n return value\n case \"number\":\n return parseFloat(value)\n case \"boolean\":\n return value === \"true\"\n case \"object\":\n return JSON.parse(value)\n case \"js_result\":\n // We use the literal helper to process the result of JS expressions\n // as we want to be able to return any types.\n // We wrap the value in an abject to be able to use undefined properly.\n return JSON.parse(value).data\n }\n return value\n }),\n]\n", "const { FIND_HBS_REGEX } = require(\"../utilities\")\nconst preprocessor = require(\"./preprocessor\")\nconst postprocessor = require(\"./postprocessor\")\n\nfunction process(output, processors, opts) {\n for (let processor of processors) {\n // if a literal statement has occurred stop\n if (typeof output !== \"string\") {\n break\n }\n // re-run search each time incase previous processor updated/removed a match\n let regexp = new RegExp(FIND_HBS_REGEX)\n let matches = output.match(regexp)\n if (matches == null) {\n continue\n }\n for (let match of matches) {\n output = processor.process(output, match, opts)\n }\n }\n return output\n}\n\nmodule.exports.preprocess = (string, opts) => {\n let processors = preprocessor.processors\n if (opts.noFinalise) {\n processors = processors.filter(\n processor => processor.name !== preprocessor.PreprocessorNames.FINALISE\n )\n }\n return process(string, processors, opts)\n}\nmodule.exports.postprocess = string => {\n let processors = postprocessor.processors\n return process(string, processors)\n}\n", "{\n \"math\": {\n \"abs\": {\n \"args\": [\n \"a\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ abs 12012.1000 }} -> 12012.1\",\n \"description\": \"<p>Return the magnitude of <code>a</code>.</p>\\n\"\n },\n \"add\": {\n \"args\": [\n \"a\",\n \"b\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ add 1 2 }} -> 3\",\n \"description\": \"<p>Return the sum of <code>a</code> plus <code>b</code>.</p>\\n\"\n },\n \"avg\": {\n \"args\": [\n \"array\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ avg 1 2 3 4 5 }} -> 3\",\n \"description\": \"<p>Returns the average of all numbers in the given array.</p>\\n\"\n },\n \"ceil\": {\n \"args\": [\n \"value\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ ceil 1.2 }} -> 2\",\n \"description\": \"<p>Get the <code>Math.ceil()</code> of the given value.</p>\\n\"\n },\n \"divide\": {\n \"args\": [\n \"a\",\n \"b\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ divide 10 5 }} -> 2\",\n \"description\": \"<p>Divide <code>a</code> by <code>b</code></p>\\n\"\n },\n \"floor\": {\n \"args\": [\n \"value\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ floor 1.2 }} -> 1\",\n \"description\": \"<p>Get the <code>Math.floor()</code> of the given value.</p>\\n\"\n },\n \"minus\": {\n \"args\": [\n \"a\",\n \"b\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ subtract 10 5 }} -> 5\",\n \"description\": \"<p>Return the product of <code>a</code> minus <code>b</code>.</p>\\n\"\n },\n \"modulo\": {\n \"args\": [\n \"a\",\n \"b\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ modulo 10 5 }} -> 0\",\n \"description\": \"<p>Get the remainder of a division operation.</p>\\n\"\n },\n \"multiply\": {\n \"args\": [\n \"a\",\n \"b\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ multiply 10 5 }} -> 50\",\n \"description\": \"<p>Return the product of <code>a</code> times <code>b</code>.</p>\\n\"\n },\n \"plus\": {\n \"args\": [\n \"a\",\n \"b\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ plus 10 5 }} -> 15\",\n \"description\": \"<p>Add <code>a</code> by <code>b</code>.</p>\\n\"\n },\n \"random\": {\n \"args\": [\n \"min\",\n \"max\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ random 0 20 }} -> 10\",\n \"description\": \"<p>Generate a random number between two values</p>\\n\"\n },\n \"remainder\": {\n \"args\": [\n \"a\",\n \"b\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ remainder 10 6 }} -> 4\",\n \"description\": \"<p>Get the remainder when <code>a</code> is divided by <code>b</code>.</p>\\n\"\n },\n \"round\": {\n \"args\": [\n \"number\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ round 10.3 }} -> 10\",\n \"description\": \"<p>Round the given number.</p>\\n\"\n },\n \"subtract\": {\n \"args\": [\n \"a\",\n \"b\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ subtract 10 5 }} -> 5\",\n \"description\": \"<p>Return the product of <code>a</code> minus <code>b</code>.</p>\\n\"\n },\n \"sum\": {\n \"args\": [\n \"array\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ sum [1, 2, 3] }} -> 6\",\n \"description\": \"<p>Returns the sum of all numbers in the given array.</p>\\n\"\n },\n \"times\": {\n \"args\": [\n \"a\",\n \"b\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ times 10 5 }} -> 50\",\n \"description\": \"<p>Multiply number <code>a</code> by number <code>b</code>.</p>\\n\"\n }\n },\n \"array\": {\n \"after\": {\n \"args\": [\n \"array\",\n \"n\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ after [1, 2, 3] 1}} -> [3]\",\n \"description\": \"<p>Returns all of the items in an array after the specified index. Opposite of <a href=\\\"#before\\\">before</a>.</p>\\n\"\n },\n \"arrayify\": {\n \"args\": [\n \"value\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ arrayify 'foo' }} -> ['foo']\",\n \"description\": \"<p>Cast the given <code>value</code> to an array.</p>\\n\"\n },\n \"before\": {\n \"args\": [\n \"array\",\n \"n\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ before [1, 2, 3] 2}} -> [1, 2]\",\n \"description\": \"<p>Return all of the items in the collection before the specified count. Opposite of <a href=\\\"#after\\\">after</a>.</p>\\n\"\n },\n \"eachIndex\": {\n \"args\": [\n \"array\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{#eachIndex [1, 2, 3]}} {{item}} is {{index}} {{/eachIndex}}\",\n \"description\": \"<p>Iterates the array, listing an item and the index of it.</p>\\n\"\n },\n \"filter\": {\n \"args\": [\n \"array\",\n \"value\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#filter [1, 2, 3] 2}}2 Found{{else}}2 not found{{/filter}}\",\n \"description\": \"<p>Block helper that filters the given array and renders the block for values that evaluate to <code>true</code>, otherwise the inverse block is returned.</p>\\n\"\n },\n \"first\": {\n \"args\": [\n \"array\",\n \"n\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{first [1, 2, 3, 4] 2}} -> [1, 2]\",\n \"description\": \"<p>Returns the first item, or first <code>n</code> items of an array.</p>\\n\"\n },\n \"forEach\": {\n \"args\": [\n \"array\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{#forEach [{ 'name': 'John' }] }} {{ name }} {{/forEach}}\",\n \"description\": \"<p>Iterates over each item in an array and exposes the current item in the array as context to the inner block. In addition to the current array item, the helper exposes the following variables to the inner block: - <code>index</code> - <code>total</code> - <code>isFirst</code> - <code>isLast</code> Also, <code>@index</code> is exposed as a private variable, and additional private variables may be defined as hash arguments.</p>\\n\"\n },\n \"inArray\": {\n \"args\": [\n \"array\",\n \"value\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#inArray [1, 2, 3] 2}} 2 exists {{else}} 2 does not exist {{/inArray}} -> 2 exists\",\n \"description\": \"<p>Block helper that renders the block if an array has the given <code>value</code>. Optionally specify an inverse block to render when the array does not have the given value.</p>\\n\"\n },\n \"isArray\": {\n \"args\": [\n \"value\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{isArray [1, 2]}} -> true\",\n \"description\": \"<p>Returns true if <code>value</code> is an es5 array.</p>\\n\"\n },\n \"itemAt\": {\n \"args\": [\n \"array\",\n \"idx\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{itemAt [1, 2, 3] 1}} -> 2\",\n \"description\": \"<p>Returns the item from <code>array</code> at index <code>idx</code>.</p>\\n\"\n },\n \"join\": {\n \"args\": [\n \"array\",\n \"separator\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{join [1, 2, 3]}} -> '1, 2, 3'\",\n \"description\": \"<p>Join all elements of array into a string, optionally using a given separator.</p>\\n\"\n },\n \"equalsLength\": {\n \"args\": [\n \"value\",\n \"length\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{equalsLength '[1,2,3]' 3}} -> true\",\n \"description\": \"<p>Returns true if the the length of the given <code>value</code> is equal to the given <code>length</code>. Can be used as a block or inline helper.</p>\\n\"\n },\n \"last\": {\n \"args\": [\n \"value\",\n \"n\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{last [1, 2, 3]}} -> 3\",\n \"description\": \"<p>Returns the last item, or last <code>n</code> items of an array or string. Opposite of <a href=\\\"#first\\\">first</a>.</p>\\n\"\n },\n \"length\": {\n \"args\": [\n \"value\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{length '[1, 2, 3]'}} -> 3\",\n \"description\": \"<p>Returns the length of the given string or array.</p>\\n\"\n },\n \"lengthEqual\": {\n \"args\": [\n \"value\",\n \"length\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{equalsLength '[1,2,3]' 3}} -> true\",\n \"description\": \"<p>Returns true if the the length of the given <code>value</code> is equal to the given <code>length</code>. Can be used as a block or inline helper.</p>\\n\"\n },\n \"map\": {\n \"args\": [\n \"array\",\n \"fn\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{map [1, 2, 3] double}} -> [2, 4, 6]\",\n \"description\": \"<p>Returns a new array, created by calling <code>function</code> on each element of the given <code>array</code>. For example,</p>\\n\"\n },\n \"pluck\": {\n \"args\": [\n \"collection\",\n \"prop\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{pluck [{ 'name': 'Bob' }] 'name' }} -> ['Bob']\",\n \"description\": \"<p>Map over the given object or array or objects and create an array of values from the given <code>prop</code>. Dot-notation may be used (as a string) to get nested properties.</p>\\n\"\n },\n \"reverse\": {\n \"args\": [\n \"value\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{reverse [1, 2, 3]}} -> [3, 2, 1]\",\n \"description\": \"<p>Reverse the elements in an array, or the characters in a string.</p>\\n\"\n },\n \"some\": {\n \"args\": [\n \"array\",\n \"iter\",\n \"provided\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#some [1, 'b', 3] isString}} string found {{else}} No string found {{/some}} -> string found\",\n \"description\": \"<p>Block helper that returns the block if the callback returns true for some value in the given array.</p>\\n\"\n },\n \"sort\": {\n \"args\": [\n \"array\",\n \"key\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ sort ['b', 'a', 'c'] }} -> ['a', 'b', 'c']\",\n \"description\": \"<p>Sort the given <code>array</code>. If an array of objects is passed, you may optionally pass a <code>key</code> to sort on as the second argument. You may alternatively pass a sorting function as the second argument.</p>\\n\"\n },\n \"sortBy\": {\n \"args\": [\n \"array\",\n \"props\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ sortBy [{a: 'zzz'}, {a: 'aaa'}] 'a' }} -> [{'a':'aaa'}, {'a':'zzz'}]\",\n \"description\": \"<p>Sort an <code>array</code>. If an array of objects is passed, you may optionally pass a <code>key</code> to sort on as the second argument. You may alternatively pass a sorting function as the second argument.</p>\\n\"\n },\n \"withAfter\": {\n \"args\": [\n \"array\",\n \"idx\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{ withAfter [1, 2, 3] 1 }} {{this}} {{/withAfter}}\",\n \"description\": \"<p>Use the items in the array <em>after</em> the specified index as context inside a block. Opposite of <a href=\\\"#withBefore\\\">withBefore</a>.</p>\\n\"\n },\n \"withBefore\": {\n \"args\": [\n \"array\",\n \"idx\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{ withBefore [1, 2, 3] 2 }} {{this}} {{/withBefore}}\",\n \"description\": \"<p>Use the items in the array <em>before</em> the specified index as context inside a block. Opposite of <a href=\\\"#withAfter\\\">withAfter</a>.</p>\\n\"\n },\n \"withFirst\": {\n \"args\": [\n \"array\",\n \"idx\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{ withFirst [1, 2, 3] }} {{this}} {{/withFirst}}\",\n \"description\": \"<p>Use the first item in a collection inside a handlebars block expression. Opposite of <a href=\\\"#withLast\\\">withLast</a>.</p>\\n\"\n },\n \"withGroup\": {\n \"args\": [\n \"array\",\n \"size\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#withGroup [1, 2, 3, 4] 2}} {{#each this}} {{.}} {{each}} <br> {{/withGroup}} -> 1,2<br> 3,4<br>\",\n \"description\": \"<p>Block helper that groups array elements by given group <code>size</code>.</p>\\n\"\n },\n \"withLast\": {\n \"args\": [\n \"array\",\n \"idx\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#withLast [1, 2, 3, 4]}} {{this}} {{/withLast}} -> 4\",\n \"description\": \"<p>Use the last item or <code>n</code> items in an array as context inside a block. Opposite of <a href=\\\"#withFirst\\\">withFirst</a>.</p>\\n\"\n },\n \"withSort\": {\n \"args\": [\n \"array\",\n \"prop\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#withSort ['b', 'a', 'c']}} {{this}} {{/withSort}} -> abc\",\n \"description\": \"<p>Block helper that sorts a collection and exposes the sorted collection as context inside the block.</p>\\n\"\n },\n \"unique\": {\n \"args\": [\n \"array\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{#each (unique ['a', 'a', 'c', 'b', 'e', 'e']) }} {{.}} {{/each}} -> acbe\",\n \"description\": \"<p>Block helper that return an array with all duplicate values removed. Best used along with a <a href=\\\"#each\\\">each</a> helper.</p>\\n\"\n }\n },\n \"number\": {\n \"bytes\": {\n \"args\": [\n \"number\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ bytes 1386 }} -> 1.4Kb\",\n \"description\": \"<p>Format a number to it&#39;s equivalent in bytes. If a string is passed, it&#39;s length will be formatted and returned. <strong>Examples:</strong> - <code>&#39;foo&#39; =&gt; 3 B</code> - <code>13661855 =&gt; 13.66 MB</code> - <code>825399 =&gt; 825.39 kB</code> - <code>1396 =&gt; 1.4 kB</code></p>\\n\"\n },\n \"addCommas\": {\n \"args\": [\n \"num\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ addCommas 1000000 }} -> 1,000,000\",\n \"description\": \"<p>Add commas to numbers</p>\\n\"\n },\n \"phoneNumber\": {\n \"args\": [\n \"num\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ phoneNumber 8005551212 }} -> (800) 555-1212\",\n \"description\": \"<p>Convert a string or number to a formatted phone number.</p>\\n\"\n },\n \"toAbbr\": {\n \"args\": [\n \"number\",\n \"precision\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ toAbbr 10123 2 }} -> 10.12k\",\n \"description\": \"<p>Abbreviate numbers to the given number of <code>precision</code>. This for general numbers, not size in bytes.</p>\\n\"\n },\n \"toExponential\": {\n \"args\": [\n \"number\",\n \"fractionDigits\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ toExponential 10123 2 }} -> 101e+4\",\n \"description\": \"<p>Returns a string representing the given number in exponential notation.</p>\\n\"\n },\n \"toFixed\": {\n \"args\": [\n \"number\",\n \"digits\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ toFixed 1.1234 2 }} -> 1.12\",\n \"description\": \"<p>Formats the given number using fixed-point notation.</p>\\n\"\n },\n \"toFloat\": {\n \"args\": [\n \"number\"\n ],\n \"numArgs\": 1,\n \"description\": \"<p>Convert input to a float.</p>\\n\"\n },\n \"toInt\": {\n \"args\": [\n \"number\"\n ],\n \"numArgs\": 1,\n \"description\": \"<p>Convert input to an integer.</p>\\n\"\n },\n \"toPrecision\": {\n \"args\": [\n \"number\",\n \"precision\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{toPrecision '1.1234' 2}}\",\n \"description\": \"<p>Returns a string representing the <code>Number</code> object to the specified precision.</p>\\n\"\n }\n },\n \"url\": {\n \"encodeURI\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ encodeURI 'https://myurl?Hello There' }} -> https://myurl?Hello%20There\",\n \"description\": \"<p>Encodes a Uniform Resource Identifier (URI) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character.</p>\\n\"\n },\n \"escape\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ escape 'https://myurl?Hello+There' }} -> https://myurl?Hello%20There\",\n \"description\": \"<p>Escape the given string by replacing characters with escape sequences. Useful for allowing the string to be used in a URL, etc.</p>\\n\"\n },\n \"decodeURI\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ escape 'https://myurl?Hello%20There' }} -> https://myurl?Hello+There\",\n \"description\": \"<p>Decode a Uniform Resource Identifier (URI) component.</p>\\n\"\n },\n \"url_encode\": {\n \"args\": [],\n \"numArgs\": 0,\n \"description\": \"<p>Alias for <a href=\\\"#encodeuri\\\">encodeURI</a>.</p>\\n\"\n },\n \"url_decode\": {\n \"args\": [],\n \"numArgs\": 0,\n \"description\": \"<p>Alias for <a href=\\\"#decodeuri\\\">decodeURI</a>.</p>\\n\"\n },\n \"urlResolve\": {\n \"args\": [\n \"base\",\n \"href\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ urlResolve 'https://myurl' '/api/test' }} -> https://myurl/api/test\",\n \"description\": \"<p>Take a base URL, and a href URL, and resolve them as a browser would for an anchor tag.</p>\\n\"\n },\n \"urlParse\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ urlParse 'https://myurl/api/test' }}\",\n \"description\": \"<p>Parses a <code>url</code> string into an object.</p>\\n\"\n },\n \"stripQuerystring\": {\n \"args\": [\n \"url\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ stripQueryString 'https://myurl/api/test?foo=bar' }} -> 'https://myurl/api/test'\",\n \"description\": \"<p>Strip the query string from the given <code>url</code>.</p>\\n\"\n },\n \"stripProtocol\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ stripProtocol 'https://myurl/api/test' }} -> 'myurl/api/test'\",\n \"description\": \"<p>Strip protocol from a <code>url</code>. Useful for displaying media that may have an &#39;http&#39; protocol on secure connections.</p>\\n\"\n }\n },\n \"string\": {\n \"append\": {\n \"args\": [\n \"str\",\n \"suffix\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{append 'index' '.html'}} -> index.html\",\n \"description\": \"<p>Append the specified <code>suffix</code> to the given string.</p>\\n\"\n },\n \"camelcase\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{camelcase 'foo bar baz'}} -> fooBarBaz\",\n \"description\": \"<p>camelCase the characters in the given <code>string</code>.</p>\\n\"\n },\n \"capitalize\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{capitalize 'foo bar baz'}} -> Foo bar baz\",\n \"description\": \"<p>Capitalize the first word in a sentence.</p>\\n\"\n },\n \"capitalizeAll\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ capitalizeAll 'foo bar baz'}} -> Foo Bar Baz\",\n \"description\": \"<p>Capitalize all words in a string.</p>\\n\"\n },\n \"center\": {\n \"args\": [\n \"str\",\n \"spaces\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ center 'test' 1}} -> ' test '\",\n \"description\": \"<p>Center a string using non-breaking spaces</p>\\n\"\n },\n \"chop\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ chop ' ABC '}} -> 'ABC'\",\n \"description\": \"<p>Like trim, but removes both extraneous whitespace <strong>and non-word characters</strong> from the beginning and end of a string.</p>\\n\"\n },\n \"dashcase\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{dashcase 'a-b-c d_e'}} -> a-b-c-d-e\",\n \"description\": \"<p>dash-case the characters in <code>string</code>. Replaces non-word characters and periods with hyphens.</p>\\n\"\n },\n \"dotcase\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{dotcase 'a-b-c d_e'}} -> a.b.c.d.e\",\n \"description\": \"<p>dot.case the characters in <code>string</code>.</p>\\n\"\n },\n \"downcase\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{downcase 'aBcDeF'}} -> abcdef\",\n \"description\": \"<p>Lowercase all of the characters in the given string. Alias for <a href=\\\"#lowercase\\\">lowercase</a>.</p>\\n\"\n },\n \"ellipsis\": {\n \"args\": [\n \"str\",\n \"length\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ellipsis 'foo bar baz' 7}} -> foo bar\u2026\",\n \"description\": \"<p>Truncates a string to the specified <code>length</code>, and appends it with an elipsis, <code>\u2026</code>.</p>\\n\"\n },\n \"hyphenate\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{hyphenate 'foo bar baz qux'}} -> foo-bar-baz-qux\",\n \"description\": \"<p>Replace spaces in a string with hyphens.</p>\\n\"\n },\n \"isString\": {\n \"args\": [\n \"value\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{isString 'foo'}} -> true\",\n \"description\": \"<p>Return true if <code>value</code> is a string.</p>\\n\"\n },\n \"lowercase\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{lowercase 'Foo BAR baZ'}} -> foo bar baz\",\n \"description\": \"<p>Lowercase all characters in the given string.</p>\\n\"\n },\n \"occurrences\": {\n \"args\": [\n \"str\",\n \"substring\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{occurrences 'foo bar foo bar baz' 'foo'}} -> 2\",\n \"description\": \"<p>Return the number of occurrences of <code>substring</code> within the given <code>string</code>.</p>\\n\"\n },\n \"pascalcase\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{pascalcase 'foo bar baz'}} -> FooBarBaz\",\n \"description\": \"<p>PascalCase the characters in <code>string</code>.</p>\\n\"\n },\n \"pathcase\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{pathcase 'a-b-c d_e'}} -> a/b/c/d/e\",\n \"description\": \"<p>path/case the characters in <code>string</code>.</p>\\n\"\n },\n \"plusify\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{plusify 'foo bar baz'}} -> foo+bar+baz\",\n \"description\": \"<p>Replace spaces in the given string with pluses.</p>\\n\"\n },\n \"prepend\": {\n \"args\": [\n \"str\",\n \"prefix\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{prepend 'bar' 'foo-'}} -> foo-bar\",\n \"description\": \"<p>Prepends the given <code>string</code> with the specified <code>prefix</code>.</p>\\n\"\n },\n \"raw\": {\n \"args\": [\n \"options\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{{{#raw}}}} {{foo}} {{{{/raw}}}} -> {{foo}}\",\n \"description\": \"<p>Render a block without processing mustache templates inside the block.</p>\\n\"\n },\n \"remove\": {\n \"args\": [\n \"str\",\n \"substring\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{remove 'a b a b a b' 'a '}} -> b b b\",\n \"description\": \"<p>Remove all occurrences of <code>substring</code> from the given <code>str</code>.</p>\\n\"\n },\n \"removeFirst\": {\n \"args\": [\n \"str\",\n \"substring\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{remove 'a b a b a b' 'a'}} -> b a b a b\",\n \"description\": \"<p>Remove the first occurrence of <code>substring</code> from the given <code>str</code>.</p>\\n\"\n },\n \"replace\": {\n \"args\": [\n \"str\",\n \"a\",\n \"b\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{replace 'a b a b a b' 'a' 'z'}} -> z b z b z b\",\n \"description\": \"<p>Replace all occurrences of substring <code>a</code> with substring <code>b</code>.</p>\\n\"\n },\n \"replaceFirst\": {\n \"args\": [\n \"str\",\n \"a\",\n \"b\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{replace 'a b a b a b' 'a' 'z'}} -> z b a b a b\",\n \"description\": \"<p>Replace the first occurrence of substring <code>a</code> with substring <code>b</code>.</p>\\n\"\n },\n \"sentence\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{sentence 'hello world. goodbye world.'}} -> Hello world. Goodbye world.\",\n \"description\": \"<p>Sentence case the given string</p>\\n\"\n },\n \"snakecase\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{snakecase 'a-b-c d_e'}} -> a_b_c_d_e\",\n \"description\": \"<p>snake_case the characters in the given <code>string</code>.</p>\\n\"\n },\n \"split\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{split 'a,b,c'}} -> ['a', 'b', 'c']\",\n \"description\": \"<p>Split <code>string</code> by the given <code>character</code>.</p>\\n\"\n },\n \"startsWith\": {\n \"args\": [\n \"prefix\",\n \"testString\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#startsWith 'Goodbye' 'Hello, world!'}} Yep {{else}} Nope {{/startsWith}} -> Nope\",\n \"description\": \"<p>Tests whether a string begins with the given prefix.</p>\\n\"\n },\n \"titleize\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{#titleize 'this is title case' }} -> This Is Title Case\",\n \"description\": \"<p>Title case the given string.</p>\\n\"\n },\n \"trim\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{trim ' ABC ' }} -> ABC\",\n \"description\": \"<p>Removes extraneous whitespace from the beginning and end of a string.</p>\\n\"\n },\n \"trimLeft\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{trimLeft ' ABC ' }} -> 'ABC '\",\n \"description\": \"<p>Removes extraneous whitespace from the beginning of a string.</p>\\n\"\n },\n \"trimRight\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{trimRight ' ABC ' }} -> ' ABC '\",\n \"description\": \"<p>Removes extraneous whitespace from the end of a string.</p>\\n\"\n },\n \"truncate\": {\n \"args\": [\n \"str\",\n \"limit\",\n \"suffix\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{truncate 'foo bar baz' 7 }} -> foo bar\",\n \"description\": \"<p>Truncate a string to the specified <code>length</code>. Also see <a href=\\\"#ellipsis\\\">ellipsis</a>.</p>\\n\"\n },\n \"truncateWords\": {\n \"args\": [\n \"str\",\n \"limit\",\n \"suffix\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{truncateWords 'foo bar baz' 1 }} -> foo\",\n \"description\": \"<p>Truncate a string to have the specified number of words. Also see <a href=\\\"#truncate\\\">truncate</a>.</p>\\n\"\n },\n \"upcase\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{upcase 'aBcDef'}} -> ABCDEF\",\n \"description\": \"<p>Uppercase all of the characters in the given string. Alias for <a href=\\\"#uppercase\\\">uppercase</a>.</p>\\n\"\n },\n \"uppercase\": {\n \"args\": [\n \"str\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{uppercase 'aBcDef'}} -> ABCDEF\",\n \"description\": \"<p>Uppercase all of the characters in the given string. If used as a block helper it will uppercase the entire block. This helper does not support inverse blocks.</p>\\n\"\n }\n },\n \"comparison\": {\n \"and\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#and great magnificent}}both{{else}}no{{/and}}\",\n \"description\": \"<p>Helper that renders the block if <strong>both</strong> of the given values are truthy. If an inverse block is specified it will be rendered when falsy. Works as a block helper, inline helper or subexpression.</p>\\n\"\n },\n \"compare\": {\n \"args\": [\n \"a\",\n \"operator\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 4,\n \"example\": \"{{compare 10 '<' 5 }} -> true\",\n \"description\": \"<p>Render a block when a comparison of the first and third arguments returns true. The second argument is the [arithemetic operator][operators] to use. You may also optionally specify an inverse block to render when falsy.</p>\\n\"\n },\n \"contains\": {\n \"args\": [\n \"collection\",\n \"value\",\n \"[startIndex=0]\",\n \"options\"\n ],\n \"numArgs\": 4,\n \"example\": \"{{#contains ['a', 'b', 'c'] 'd'}} This will not be rendered. {{else}} This will be rendered. {{/contains}}\",\n \"description\": \"<p>Block helper that renders the block if <code>collection</code> has the given <code>value</code>, using strict equality (<code>===</code>) for comparison, otherwise the inverse block is rendered (if specified). If a <code>startIndex</code> is specified and is negative, it is used as the offset from the end of the collection.</p>\\n\"\n },\n \"default\": {\n \"args\": [\n \"value\",\n \"defaultValue\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{default null null 'default'}} -> default\",\n \"description\": \"<p>Returns the first value that is not undefined, otherwise the &#39;default&#39; value is returned.</p>\\n\"\n },\n \"eq\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#eq 3 3}} equal{{else}} not equal{{/eq}} -> equal\",\n \"description\": \"<p>Block helper that renders a block if <code>a</code> is <strong>equal to</strong> <code>b</code>. If an inverse block is specified it will be rendered when falsy. You may optionally use the <code>compare=&#39;&#39;</code> hash argument for the second value.</p>\\n\"\n },\n \"gt\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#gt 4 3}} greater than{{else}} not greater than{{/gt}} -> greater than\",\n \"description\": \"<p>Block helper that renders a block if <code>a</code> is <strong>greater than</strong> <code>b</code>. If an inverse block is specified it will be rendered when falsy. You may optionally use the <code>compare=&#39;&#39;</code> hash argument for the second value.</p>\\n\"\n },\n \"gte\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#gte 4 3}} greater than or equal{{else}} not greater than{{/gte}} -> greater than or equal\",\n \"description\": \"<p>Block helper that renders a block if <code>a</code> is <strong>greater than or equal to</strong> <code>b</code>. If an inverse block is specified it will be rendered when falsy. You may optionally use the <code>compare=&#39;&#39;</code> hash argument for the second value.</p>\\n\"\n },\n \"has\": {\n \"args\": [\n \"val\",\n \"pattern\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#has 'foobar' 'foo'}} has it{{else}} doesn't{{/has}} -> has it\",\n \"description\": \"<p>Block helper that renders a block if <code>value</code> has <code>pattern</code>. If an inverse block is specified it will be rendered when falsy.</p>\\n\"\n },\n \"isFalsey\": {\n \"args\": [\n \"val\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{isFalsey '' }} -> true\",\n \"description\": \"<p>Returns true if the given <code>value</code> is falsey. Uses the [falsey][] library for comparisons. Please see that library for more information or to report bugs with this helper.</p>\\n\"\n },\n \"isTruthy\": {\n \"args\": [\n \"val\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{isTruthy '12' }} -> true\",\n \"description\": \"<p>Returns true if the given <code>value</code> is truthy. Uses the [falsey][] library for comparisons. Please see that library for more information or to report bugs with this helper.</p>\\n\"\n },\n \"ifEven\": {\n \"args\": [\n \"number\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{#ifEven 2}} even {{else}} odd {{/ifEven}} -> even\",\n \"description\": \"<p>Return true if the given value is an even number.</p>\\n\"\n },\n \"ifNth\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#ifNth 10 2}} remainder {{else}} no remainder {{/ifNth}} -> remainder\",\n \"description\": \"<p>Conditionally renders a block if the remainder is zero when <code>a</code> operand is divided by <code>b</code>. If an inverse block is specified it will be rendered when the remainder is <strong>not zero</strong>.</p>\\n\"\n },\n \"ifOdd\": {\n \"args\": [\n \"value\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{#ifOdd 3}} odd {{else}} even {{/ifOdd}} -> odd\",\n \"description\": \"<p>Block helper that renders a block if <code>value</code> is <strong>an odd number</strong>. If an inverse block is specified it will be rendered when falsy.</p>\\n\"\n },\n \"is\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#is 3 3}} is {{else}} is not {{/is}} -> is\",\n \"description\": \"<p>Block helper that renders a block if <code>a</code> is <strong>equal to</strong> <code>b</code>. If an inverse block is specified it will be rendered when falsy. Similar to <a href=\\\"#eq\\\">eq</a> but does not do strict equality.</p>\\n\"\n },\n \"isnt\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#isnt 3 3}} isnt {{else}} is {{/isnt}} -> is\",\n \"description\": \"<p>Block helper that renders a block if <code>a</code> is <strong>not equal to</strong> <code>b</code>. If an inverse block is specified it will be rendered when falsy. Similar to <a href=\\\"#unlesseq\\\">unlessEq</a> but does not use strict equality for comparisons.</p>\\n\"\n },\n \"lt\": {\n \"args\": [\n \"context\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{#lt 2 3}} less than {{else}} more than or equal {{/lt}} -> less than\",\n \"description\": \"<p>Block helper that renders a block if <code>a</code> is <strong>less than</strong> <code>b</code>. If an inverse block is specified it will be rendered when falsy. You may optionally use the <code>compare=&#39;&#39;</code> hash argument for the second value.</p>\\n\"\n },\n \"lte\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#lte 2 3}} less than or equal {{else}} more than {{/lte}} -> less than or equal\",\n \"description\": \"<p>Block helper that renders a block if <code>a</code> is <strong>less than or equal to</strong> <code>b</code>. If an inverse block is specified it will be rendered when falsy. You may optionally use the <code>compare=&#39;&#39;</code> hash argument for the second value.</p>\\n\"\n },\n \"neither\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#neither null null}} both falsey {{else}} both not falsey {{/neither}} -> both falsey\",\n \"description\": \"<p>Block helper that renders a block if <strong>neither of</strong> the given values are truthy. If an inverse block is specified it will be rendered when falsy.</p>\\n\"\n },\n \"not\": {\n \"args\": [\n \"val\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{#not undefined }} falsey {{else}} not falsey {{/not}} -> falsey\",\n \"description\": \"<p>Returns true if <code>val</code> is falsey. Works as a block or inline helper.</p>\\n\"\n },\n \"or\": {\n \"args\": [\n \"arguments\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{#or 1 2 undefined }} at least one truthy {{else}} all falsey {{/or}} -> at least one truthy\",\n \"description\": \"<p>Block helper that renders a block if <strong>any of</strong> the given values is truthy. If an inverse block is specified it will be rendered when falsy.</p>\\n\"\n },\n \"unlessEq\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#unlessEq 2 1 }} not equal {{else}} equal {{/unlessEq}} -> not equal\",\n \"description\": \"<p>Block helper that always renders the inverse block <strong>unless <code>a</code> is equal to <code>b</code></strong>.</p>\\n\"\n },\n \"unlessGt\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#unlessGt 20 1 }} not greater than {{else}} greater than {{/unlessGt}} -> greater than\",\n \"description\": \"<p>Block helper that always renders the inverse block <strong>unless <code>a</code> is greater than <code>b</code></strong>.</p>\\n\"\n },\n \"unlessLt\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#unlessLt 20 1 }} greater than or equal {{else}} less than {{/unlessLt}} -> greater than or equal\",\n \"description\": \"<p>Block helper that always renders the inverse block <strong>unless <code>a</code> is less than <code>b</code></strong>.</p>\\n\"\n },\n \"unlessGteq\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#unlessGteq 20 1 }} less than {{else}} greater than or equal to {{/unlessGteq}} -> greater than or equal to\",\n \"description\": \"<p>Block helper that always renders the inverse block <strong>unless <code>a</code> is greater than or equal to <code>b</code></strong>.</p>\\n\"\n },\n \"unlessLteq\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#unlessLteq 20 1 }} greater than {{else}} less than or equal to {{/unlessLteq}} -> greater than\",\n \"description\": \"<p>Block helper that always renders the inverse block <strong>unless <code>a</code> is less than or equal to <code>b</code></strong>.</p>\\n\"\n }\n },\n \"object\": {\n \"extend\": {\n \"args\": [\n \"objects\"\n ],\n \"numArgs\": 1,\n \"description\": \"<p>Extend the context with the properties of other objects. A shallow merge is performed to avoid mutating the context.</p>\\n\"\n },\n \"forIn\": {\n \"args\": [\n \"context\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"description\": \"<p>Block helper that iterates over the properties of an object, exposing each key and value on the context.</p>\\n\"\n },\n \"forOwn\": {\n \"args\": [\n \"obj\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"description\": \"<p>Block helper that iterates over the <strong>own</strong> properties of an object, exposing each key and value on the context.</p>\\n\"\n },\n \"toPath\": {\n \"args\": [\n \"prop\"\n ],\n \"numArgs\": 1,\n \"description\": \"<p>Take arguments and, if they are string or number, convert them to a dot-delineated object property path.</p>\\n\"\n },\n \"get\": {\n \"args\": [\n \"prop\",\n \"context\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"description\": \"<p>Use property paths (<code>a.b.c</code>) to get a value or nested value from the context. Works as a regular helper or block helper.</p>\\n\"\n },\n \"getObject\": {\n \"args\": [\n \"prop\",\n \"context\"\n ],\n \"numArgs\": 2,\n \"description\": \"<p>Use property paths (<code>a.b.c</code>) to get an object from the context. Differs from the <code>get</code> helper in that this helper will return the actual object, including the given property key. Also, this helper does not work as a block helper.</p>\\n\"\n },\n \"hasOwn\": {\n \"args\": [\n \"key\",\n \"context\"\n ],\n \"numArgs\": 2,\n \"description\": \"<p>Return true if <code>key</code> is an own, enumerable property of the given <code>context</code> object.</p>\\n\"\n },\n \"isObject\": {\n \"args\": [\n \"value\"\n ],\n \"numArgs\": 1,\n \"description\": \"<p>Return true if <code>value</code> is an object.</p>\\n\"\n },\n \"JSONparse\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"description\": \"<p>Parses the given string using <code>JSON.parse</code>.</p>\\n\"\n },\n \"JSONstringify\": {\n \"args\": [\n \"obj\"\n ],\n \"numArgs\": 1,\n \"description\": \"<p>Stringify an object using <code>JSON.stringify</code>.</p>\\n\"\n },\n \"merge\": {\n \"args\": [\n \"object\",\n \"objects\"\n ],\n \"numArgs\": 2,\n \"description\": \"<p>Deeply merge the properties of the given <code>objects</code> with the context object.</p>\\n\"\n },\n \"parseJSON\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"description\": \"<p>Parses the given string using <code>JSON.parse</code>.</p>\\n\"\n },\n \"pick\": {\n \"args\": [\n \"properties\",\n \"context\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"description\": \"<p>Pick properties from the context object.</p>\\n\"\n },\n \"stringify\": {\n \"args\": [\n \"obj\"\n ],\n \"numArgs\": 1,\n \"description\": \"<p>Stringify an object using <code>JSON.stringify</code>.</p>\\n\"\n }\n },\n \"date\": {\n \"date\": {\n \"args\": [\n \"datetime\",\n \"format\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{date now \\\"DD-MM-YYYY\\\" \\\"America/New_York\\\" }} -> 21-01-2021\",\n \"description\": \"<p>Format a date using moment.js date formatting - the timezone is optional and uses the tz database.</p>\\n\"\n },\n \"duration\": {\n \"args\": [\n \"time\",\n \"durationType\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{duration timeLeft \\\"seconds\\\"}} -> a few seconds\",\n \"description\": \"<p>Produce a humanized duration left/until given an amount of time and the type of time measurement.</p>\\n\"\n }\n }\n}\n", "const { getHelperList } = require(\"../helpers\")\n\nfunction getLayers(fullBlock) {\n let layers = []\n while (fullBlock.length) {\n const start = fullBlock.lastIndexOf(\"(\"),\n end = fullBlock.indexOf(\")\")\n let layer\n if (start === -1 || end === -1) {\n layer = fullBlock.trim()\n fullBlock = \"\"\n } else {\n const untrimmed = fullBlock.substring(start, end + 1)\n layer = untrimmed.substring(1, untrimmed.length - 1).trim()\n fullBlock =\n fullBlock.slice(0, start) +\n fullBlock.slice(start + untrimmed.length + 1, fullBlock.length)\n }\n layers.push(layer)\n }\n return layers\n}\n\nfunction getVariable(variableName) {\n if (!variableName || typeof variableName !== \"string\") {\n return variableName\n }\n // it is an array\n const arrayOrObject = [\",\", \"{\", \":\"]\n let contains = false\n arrayOrObject.forEach(char => {\n if (variableName.includes(char)) {\n contains = true\n }\n })\n if (variableName.startsWith(\"[\") && contains) {\n return variableName\n }\n // it is just a number\n if (!isNaN(parseFloat(variableName))) {\n return variableName\n }\n if (variableName.startsWith(\"'\") || variableName.startsWith('\"')) {\n return variableName\n }\n // extract variable\n return `$(\"${variableName}\")`\n}\n\nfunction buildList(parts, value) {\n function build() {\n return parts\n .map(part => (part.startsWith(\"helper\") ? part : getVariable(part)))\n .join(\", \")\n }\n if (!value) {\n return parts.length > 1 ? `${build()}` : build()\n } else {\n return parts.length === 0 ? value : `${value}, ${build()}`\n }\n}\n\nfunction splitBySpace(layer) {\n const parts = []\n let started = null,\n endChar = null,\n last = 0\n function add(str) {\n const startsWith = [\"]\"]\n while (startsWith.indexOf(str.substring(0, 1)) !== -1) {\n str = str.substring(1, str.length)\n }\n if (str.length > 0) {\n parts.push(str.trim())\n }\n }\n const continuationChars = [\"[\", \"'\", '\"']\n for (let index = 0; index < layer.length; index++) {\n const char = layer[index]\n if (continuationChars.indexOf(char) !== -1 && started == null) {\n started = index\n endChar = char === \"[\" ? \"]\" : char\n } else if (\n char === endChar &&\n started != null &&\n layer[index + 1] !== \".\"\n ) {\n add(layer.substring(started, index + 1))\n started = null\n endChar = null\n last = index + 1\n } else if (started == null && char === \" \") {\n add(layer.substring(last, index))\n last = index\n }\n }\n if (\n (!layer.startsWith(\"[\") || parts.length === 0) &&\n last !== layer.length - 1\n ) {\n add(layer.substring(last, layer.length))\n }\n return parts\n}\n\nmodule.exports.convertHBSBlock = (block, blockNumber) => {\n const braceLength = block[2] === \"{\" ? 3 : 2\n block = block.substring(braceLength, block.length - braceLength).trim()\n const layers = getLayers(block)\n\n let value = null\n const list = getHelperList()\n for (let layer of layers) {\n const parts = splitBySpace(layer)\n if (value || parts.length > 1) {\n // first of layer should always be the helper\n const helper = parts.splice(0, 1)\n if (list[helper]) {\n value = `helpers.${helper}(${buildList(parts, value)})`\n }\n }\n // no helpers\n else {\n value = getVariable(parts[0])\n }\n }\n // split by space will remove square brackets\n return { variable: `var${blockNumber}`, value }\n}\n", "const handlebars = require(\"handlebars\")\nconst { registerAll, registerMinimum } = require(\"./helpers/index\")\nconst processors = require(\"./processors\")\nconst { atob, btoa } = require(\"./utilities\")\nconst manifest = require(\"../manifest.json\")\nconst {\n FIND_HBS_REGEX,\n FIND_ANY_HBS_REGEX,\n findDoubleHbsInstances,\n} = require(\"./utilities\")\nconst { convertHBSBlock } = require(\"./conversion\")\n\nconst hbsInstance = handlebars.create()\nregisterAll(hbsInstance)\nconst hbsInstanceNoHelpers = handlebars.create()\nregisterMinimum(hbsInstanceNoHelpers)\nconst defaultOpts = {\n noHelpers: false,\n cacheTemplates: false,\n noEscaping: false,\n escapeNewlines: false,\n noFinalise: false,\n}\n\n/**\n * Utility function to check if the object is valid.\n */\nfunction testObject(object) {\n // JSON stringify will fail if there are any cycles, stops infinite recursion\n try {\n JSON.stringify(object)\n } catch (err) {\n throw \"Unable to process inputs to JSON, cannot recurse\"\n }\n}\n\n/**\n * Creates a HBS template function for a given string, and optionally caches it.\n */\nlet templateCache = {}\nfunction createTemplate(string, opts) {\n opts = { ...defaultOpts, ...opts }\n\n // Finalising adds a helper, can't do this with no helpers\n const key = `${string}-${JSON.stringify(opts)}`\n\n // Reuse the cached template is possible\n if (opts.cacheTemplates && templateCache[key]) {\n return templateCache[key]\n }\n\n string = processors.preprocess(string, opts)\n\n // Optionally disable built in HBS escaping\n if (opts.noEscaping) {\n string = exports.disableEscaping(string)\n }\n\n // This does not throw an error when template can't be fulfilled,\n // have to try correct beforehand\n const instance = opts.noHelpers ? hbsInstanceNoHelpers : hbsInstance\n const template = instance.compile(string, {\n strict: false,\n })\n templateCache[key] = template\n return template\n}\n\n/**\n * Given an input object this will recurse through all props to try and update any handlebars statements within.\n * @param {object|array} object The input structure which is to be recursed, it is important to note that\n * if the structure contains any cycles then this will fail.\n * @param {object} context The context that handlebars should fill data from.\n * @param {object|undefined} [opts] optional - specify some options for processing.\n * @returns {Promise<object|array>} The structure input, as fully updated as possible.\n */\nmodule.exports.processObject = async (object, context, opts) => {\n testObject(object)\n for (let key of Object.keys(object || {})) {\n if (object[key] != null) {\n let val = object[key]\n if (typeof val === \"string\") {\n object[key] = await module.exports.processString(\n object[key],\n context,\n opts\n )\n } else if (typeof val === \"object\") {\n object[key] = await module.exports.processObject(\n object[key],\n context,\n opts\n )\n }\n }\n }\n return object\n}\n\n/**\n * This will process a single handlebars containing string. If the string passed in has no valid handlebars statements\n * then nothing will occur.\n * @param {string} string The template string which is the filled from the context object.\n * @param {object} context An object of information which will be used to enrich the string.\n * @param {object|undefined} [opts] optional - specify some options for processing.\n * @returns {Promise<string>} The enriched string, all templates should have been replaced if they can be.\n */\nmodule.exports.processString = async (string, context, opts) => {\n // TODO: carry out any async calls before carrying out async call\n return module.exports.processStringSync(string, context, opts)\n}\n\n/**\n * Given an input object this will recurse through all props to try and update any handlebars statements within. This is\n * a pure sync call and therefore does not have the full functionality of the async call.\n * @param {object|array} object The input structure which is to be recursed, it is important to note that\n * if the structure contains any cycles then this will fail.\n * @param {object} context The context that handlebars should fill data from.\n * @param {object|undefined} [opts] optional - specify some options for processing.\n * @returns {object|array} The structure input, as fully updated as possible.\n */\nmodule.exports.processObjectSync = (object, context, opts) => {\n testObject(object)\n for (let key of Object.keys(object || {})) {\n let val = object[key]\n if (typeof val === \"string\") {\n object[key] = module.exports.processStringSync(object[key], context, opts)\n } else if (typeof val === \"object\") {\n object[key] = module.exports.processObjectSync(object[key], context, opts)\n }\n }\n return object\n}\n\n/**\n * This will process a single handlebars containing string. If the string passed in has no valid handlebars statements\n * then nothing will occur. This is a pure sync call and therefore does not have the full functionality of the async call.\n * @param {string} string The template string which is the filled from the context object.\n * @param {object} context An object of information which will be used to enrich the string.\n * @param {object|undefined} [opts] optional - specify some options for processing.\n * @returns {string} The enriched string, all templates should have been replaced if they can be.\n */\nmodule.exports.processStringSync = (string, context, opts) => {\n // Take a copy of input in case of error\n const input = string\n if (typeof string !== \"string\") {\n throw \"Cannot process non-string types.\"\n }\n function process(stringPart) {\n const template = createTemplate(stringPart, opts)\n const now = Math.floor(Date.now() / 1000) * 1000\n return processors.postprocess(\n template({\n now: new Date(now).toISOString(),\n __opts: {\n ...opts,\n input: stringPart,\n },\n ...context,\n })\n )\n }\n try {\n if (opts && opts.onlyFound) {\n const blocks = exports.findHBSBlocks(string)\n for (let block of blocks) {\n const outcome = process(block)\n string = string.replace(block, outcome)\n }\n return string\n } else {\n return process(string)\n }\n } catch (err) {\n return input\n }\n}\n\n/**\n * By default with expressions like {{ name }} handlebars will escape various\n * characters, which can be problematic. To fix this we use the syntax {{{ name }}},\n * this function will find any double braces and switch to triple.\n * @param string the string to have double HBS statements converted to triple.\n */\nmodule.exports.disableEscaping = string => {\n const matches = findDoubleHbsInstances(string)\n if (matches == null) {\n return string\n }\n\n // find the unique set\n const unique = [...new Set(matches)]\n for (let match of unique) {\n // add a negative lookahead to exclude any already\n const regex = new RegExp(`${match}(?!})`, \"g\")\n string = string.replace(regex, `{${match}}`)\n }\n return string\n}\n\n/**\n * Simple utility function which makes sure that a templating property has been wrapped in literal specifiers correctly.\n * @param {string} property The property which is to be wrapped.\n * @returns {string} The wrapped property ready to be added to a templating string.\n */\nmodule.exports.makePropSafe = property => {\n return `[${property}]`.replace(\"[[\", \"[\").replace(\"]]\", \"]\")\n}\n\n/**\n * Checks whether or not a template string contains totally valid syntax (simply tries running it)\n * @param string The string to test for valid syntax - this may contain no templates and will be considered valid.\n * @param [opts] optional - specify some options for processing.\n * @returns {boolean} Whether or not the input string is valid.\n */\nmodule.exports.isValid = (string, opts) => {\n const validCases = [\n \"string\",\n \"number\",\n \"object\",\n \"array\",\n \"cannot read property\",\n \"undefined\",\n \"json at position 0\",\n ]\n // this is a portion of a specific string always output by handlebars in the case of a syntax error\n const invalidCases = [`expecting '`]\n // don't really need a real context to check if its valid\n const context = {}\n try {\n const template = createTemplate(string, {\n ...opts,\n noFinalise: true,\n })\n template(context)\n return true\n } catch (err) {\n const msg = err && err.message ? err.message : err\n if (!msg) {\n return false\n }\n const invalidCase = invalidCases.some(invalidCase =>\n msg.toLowerCase().includes(invalidCase)\n )\n const validCase = validCases.some(validCase =>\n msg.toLowerCase().includes(validCase)\n )\n // special case for maths functions - don't have inputs yet\n return validCase && !invalidCase\n }\n}\n\n/**\n * We have generated a static manifest file from the helpers that this string templating package makes use of.\n * This manifest provides information about each of the helpers and how it can be used.\n * @returns The manifest JSON which has been generated from the helpers.\n */\nmodule.exports.getManifest = () => {\n return manifest\n}\n\n/**\n * Checks if a HBS expression is a valid JS HBS expression\n * @param handlebars the HBS expression to check\n * @returns {boolean} whether the expression is JS or not\n */\nmodule.exports.isJSBinding = handlebars => {\n return module.exports.decodeJSBinding(handlebars) != null\n}\n\n/**\n * Encodes a raw JS string as a JS HBS expression\n * @param javascript the JS code to encode\n * @returns {string} the JS HBS expression\n */\nmodule.exports.encodeJSBinding = javascript => {\n return `{{ js \"${btoa(javascript)}\" }}`\n}\n\n/**\n * Decodes a JS HBS expression to the raw JS code\n * @param handlebars the JS HBS expression\n * @returns {string|null} the raw JS code\n */\nmodule.exports.decodeJSBinding = handlebars => {\n if (!handlebars || typeof handlebars !== \"string\") {\n return null\n }\n\n // JS is only valid if it is the only HBS expression\n if (!handlebars.trim().startsWith(\"{{ js \")) {\n return null\n }\n\n const captureJSRegex = new RegExp(/{{ js \"(.*)\" }}/)\n const match = handlebars.match(captureJSRegex)\n if (!match || match.length < 2) {\n return null\n }\n return atob(match[1])\n}\n\n/**\n * Same as the doesContainString function, but will check for all the strings\n * before confirming it contains.\n * @param {string} template The template string to search.\n * @param {string[]} strings The strings to look for.\n * @returns {boolean} Will return true if all strings found in HBS statement.\n */\nmodule.exports.doesContainStrings = (template, strings) => {\n let regexp = new RegExp(FIND_HBS_REGEX)\n let matches = template.match(regexp)\n if (matches == null) {\n return false\n }\n for (let match of matches) {\n let hbs = match\n if (exports.isJSBinding(match)) {\n hbs = exports.decodeJSBinding(match)\n }\n let allFound = true\n for (let string of strings) {\n if (!hbs.includes(string)) {\n allFound = false\n }\n }\n if (allFound) {\n return true\n }\n }\n return false\n}\n\n/**\n * Given a string, this will return any {{ binding }} or {{{ binding }}} type\n * statements.\n * @param {string} string The string to search within.\n * @return {string[]} The found HBS blocks.\n */\nmodule.exports.findHBSBlocks = string => {\n if (!string || typeof string !== \"string\") {\n return []\n }\n let regexp = new RegExp(FIND_ANY_HBS_REGEX)\n let matches = string.match(regexp)\n if (matches == null) {\n return []\n }\n return matches\n}\n\n/**\n * This function looks in the supplied template for handlebars instances, if they contain\n * JS the JS will be decoded and then the supplied string will be looked for. For example\n * if the template \"Hello, your name is {{ related }}\" this function would return that true\n * for the string \"related\" but not for \"name\" as it is not within the handlebars statement.\n * @param {string} template A template string to search for handlebars instances.\n * @param {string} string The word or sentence to search for.\n * @returns {boolean} The this return true if the string is found, false if not.\n */\nmodule.exports.doesContainString = (template, string) => {\n return exports.doesContainStrings(template, [string])\n}\n\nmodule.exports.convertToJS = hbs => {\n const blocks = exports.findHBSBlocks(hbs)\n let js = \"return `\",\n prevBlock = null\n const variables = {}\n if (blocks.length === 0) {\n js += hbs\n }\n let count = 1\n for (let block of blocks) {\n let stringPart = hbs\n if (prevBlock) {\n stringPart = stringPart.split(prevBlock)[1]\n }\n stringPart = stringPart.split(block)[0]\n prevBlock = block\n const { variable, value } = convertHBSBlock(block, count++)\n variables[variable] = value\n js += `${stringPart.split()}\\${${variable}}`\n }\n let varBlock = \"\"\n for (let [variable, value] of Object.entries(variables)) {\n varBlock += `const ${variable} = ${value};\\n`\n }\n js += \"`;\"\n return `${varBlock}${js}`\n}\n", "const templates = require(\"./index.js\")\n\n/**\n * CJS entrypoint for rollup\n */\nmodule.exports.isValid = templates.isValid\nmodule.exports.makePropSafe = templates.makePropSafe\nmodule.exports.getManifest = templates.getManifest\nmodule.exports.isJSBinding = templates.isJSBinding\nmodule.exports.encodeJSBinding = templates.encodeJSBinding\nmodule.exports.decodeJSBinding = templates.decodeJSBinding\nmodule.exports.processStringSync = templates.processStringSync\nmodule.exports.processObjectSync = templates.processObjectSync\nmodule.exports.processString = templates.processString\nmodule.exports.processObject = templates.processObject\nmodule.exports.doesContainStrings = templates.doesContainStrings\nmodule.exports.doesContainString = templates.doesContainString\nmodule.exports.disableEscaping = templates.disableEscaping\nmodule.exports.findHBSBlocks = templates.findHBSBlocks\nmodule.exports.convertToJS = templates.convertToJS\n\nif (!process.env.NO_JS) {\n const { VM } = require(\"vm2\")\n const { setJSRunner } = require(\"./helpers/javascript\")\n /**\n * Use vm2 to run JS scripts in a node env\n */\n setJSRunner((js, context) => {\n const vm = new VM({\n sandbox: context,\n timeout: 1000\n })\n return vm.run(js)\n })\n}\n", "import { default as threadUtils } from \"./utils\"\nthreadUtils.threadSetup()\nimport { WorkerCallback, QueryEvent, QueryVariable } from \"./definitions\"\nimport ScriptRunner from \"../utilities/scriptRunner\"\nimport { getIntegration } from \"../integrations\"\nimport { processStringSync } from \"@budibase/string-templates\"\nimport { context, cache, auth } from \"@budibase/backend-core\"\nimport { getGlobalIDFromUserMetadataID } from \"../db/utils\"\nimport sdk from \"../sdk\"\nimport { cloneDeep } from \"lodash/fp\"\n\nimport { isSQL } from \"../integrations/utils\"\nimport { interpolateSQL } from \"../integrations/queries/sql\"\n\nclass QueryRunner {\n datasource: any\n queryVerb: string\n queryId: string\n fields: any\n parameters: any\n pagination: any\n transformer: any\n cachedVariables: any[]\n ctx: any\n queryResponse: any\n noRecursiveQuery: boolean\n hasRerun: boolean\n hasRefreshedOAuth: boolean\n hasDynamicVariables: boolean\n\n constructor(input: QueryEvent, flags = { noRecursiveQuery: false }) {\n this.datasource = input.datasource\n this.queryVerb = input.queryVerb\n this.fields = input.fields\n this.parameters = input.parameters\n this.pagination = input.pagination\n this.transformer = input.transformer\n this.queryId = input.queryId\n this.noRecursiveQuery = flags.noRecursiveQuery\n this.cachedVariables = []\n // Additional context items for enrichment\n this.ctx = input.ctx\n // allows the response from a query to be stored throughout this\n // execution so that if it needs to be re-used for another variable\n // it can be\n this.queryResponse = {}\n this.hasRerun = false\n this.hasRefreshedOAuth = false\n this.hasDynamicVariables = false\n }\n\n async execute(): Promise<any> {\n let { datasource, fields, queryVerb, transformer } = this\n let datasourceClone = cloneDeep(datasource)\n let fieldsClone = cloneDeep(fields)\n\n const Integration = await getIntegration(datasourceClone.source)\n if (!Integration) {\n throw \"Integration type does not exist.\"\n }\n\n if (datasourceClone.config.authConfigs) {\n const updatedConfigs = []\n for (let config of datasourceClone.config.authConfigs) {\n updatedConfigs.push(await sdk.queries.enrichContext(config, this.ctx))\n }\n datasourceClone.config.authConfigs = updatedConfigs\n }\n\n const integration = new Integration(datasourceClone.config)\n\n // pre-query, make sure datasource variables are added to parameters\n const parameters = await this.addDatasourceVariables()\n\n // Enrich the parameters with the addition context items.\n // 'user' is now a reserved variable key in mapping parameters\n const enrichedParameters = await sdk.queries.enrichContext(\n parameters,\n this.ctx\n )\n const enrichedContext = { ...enrichedParameters, ...this.ctx }\n\n // Parse global headers\n if (datasourceClone.config.defaultHeaders) {\n datasourceClone.config.defaultHeaders = await sdk.queries.enrichContext(\n datasourceClone.config.defaultHeaders,\n enrichedContext\n )\n }\n\n let query\n // handle SQL injections by interpolating the variables\n if (isSQL(datasourceClone)) {\n query = await interpolateSQL(fieldsClone, enrichedContext, integration)\n } else {\n query = await sdk.queries.enrichContext(fieldsClone, enrichedContext)\n }\n\n // Add pagination values for REST queries\n if (this.pagination) {\n query.paginationValues = this.pagination\n }\n\n let output = threadUtils.formatResponse(await integration[queryVerb](query))\n let rows = output,\n info = undefined,\n extra = undefined,\n pagination = undefined\n if (threadUtils.hasExtraData(output)) {\n rows = output.data\n info = output.info\n extra = output.extra\n pagination = output.pagination\n }\n\n // transform as required\n if (transformer) {\n const runner = new ScriptRunner(transformer, {\n data: rows,\n params: enrichedParameters,\n })\n rows = runner.execute()\n }\n\n // if the request fails we retry once, invalidating the cached value\n if (info && info.code >= 400 && !this.hasRerun) {\n if (\n this.ctx.user?.provider &&\n info.code === 401 &&\n !this.hasRefreshedOAuth\n ) {\n await this.refreshOAuth2(this.ctx)\n // Attempt to refresh the access token from the provider\n this.hasRefreshedOAuth = true\n } else {\n this.hasRerun = true\n }\n\n await threadUtils.invalidateDynamicVariables(this.cachedVariables)\n return this.execute()\n }\n\n // check for undefined response\n if (!rows) {\n rows = []\n }\n\n // needs to an array for next step\n if (!Array.isArray(rows)) {\n rows = [rows]\n }\n\n // map into JSON if just raw primitive here\n if (rows.find((row: any) => typeof row !== \"object\")) {\n rows = rows.map((value: any) => ({ value }))\n }\n\n // get all the potential fields in the schema\n let keys = rows.flatMap(Object.keys)\n\n if (integration.end) {\n integration.end()\n }\n\n return { rows, keys, info, extra, pagination }\n }\n\n async runAnotherQuery(queryId: string, parameters: any) {\n const db = context.getAppDB()\n const query = await db.get(queryId)\n const datasource = await sdk.datasources.get(query.datasourceId, {\n enriched: true,\n })\n return new QueryRunner(\n {\n datasource,\n queryVerb: query.queryVerb,\n fields: query.fields,\n parameters,\n transformer: query.transformer,\n queryId,\n ctx: this.ctx,\n },\n { noRecursiveQuery: true }\n ).execute()\n }\n\n async refreshOAuth2(ctx: any) {\n const { oauth2, providerType, _id } = ctx.user\n const { configId } = ctx.auth\n\n if (!providerType || !oauth2?.refreshToken) {\n throw new Error(\"No refresh token found for authenticated user\")\n }\n\n const resp: any = await auth.refreshOAuthToken(\n oauth2.refreshToken,\n providerType,\n configId\n )\n\n // Refresh session flow. Should be in same location as refreshOAuthToken\n // There are several other properties available in 'resp'\n if (!resp.err) {\n const globalUserId = getGlobalIDFromUserMetadataID(_id)\n await auth.updateUserOAuth(globalUserId, resp)\n this.ctx.user = await cache.user.getUser(globalUserId)\n } else {\n // In this event the user may have oAuth issues that\n // could require re-authenticating with their provider.\n let errorMessage = resp.err.data ? resp.err.data : resp.err.toString()\n throw new Error(\n \"OAuth2 access token could not be refreshed: \" + errorMessage\n )\n }\n\n return resp\n }\n\n async getDynamicVariable(variable: QueryVariable) {\n let { parameters } = this\n const queryId = variable.queryId,\n name = variable.name\n let value = await threadUtils.checkCacheForDynamicVariable(queryId, name)\n if (!value) {\n value = this.queryResponse[queryId]\n ? this.queryResponse[queryId]\n : await this.runAnotherQuery(queryId, parameters)\n // store incase this query is to be called again\n this.queryResponse[queryId] = value\n await threadUtils.storeDynamicVariable(queryId, name, value)\n } else {\n this.cachedVariables.push({ queryId, name })\n }\n return value\n }\n\n async addDatasourceVariables() {\n let { datasource, parameters, fields } = this\n if (!datasource || !datasource.config) {\n return parameters\n }\n const staticVars = datasource.config.staticVariables || {}\n const dynamicVars = datasource.config.dynamicVariables || []\n for (let [key, value] of Object.entries(staticVars)) {\n if (!parameters[key]) {\n parameters[key] = value\n }\n }\n if (!this.noRecursiveQuery) {\n // need to see if this uses any variables\n const stringFields = JSON.stringify(fields)\n const foundVars = dynamicVars.filter((variable: QueryVariable) => {\n // don't allow a query to use its own dynamic variable (loop)\n if (variable.queryId === this.queryId) {\n return false\n }\n // look for {{ variable }} but allow spaces between handlebars\n const regex = new RegExp(`{{[ ]*${variable.name}[ ]*}}`)\n return regex.test(stringFields)\n })\n const dynamics = foundVars.map((dynVar: QueryVariable) =>\n this.getDynamicVariable(dynVar)\n )\n const responses = await Promise.all(dynamics)\n for (let i = 0; i < foundVars.length; i++) {\n const variable = foundVars[i]\n parameters[variable.name] = processStringSync(\n variable.value,\n {\n data: responses[i].rows,\n info: responses[i].extra,\n },\n {\n escapeNewlines: true,\n }\n )\n // make sure its known that this uses dynamic variables in case it fails\n this.hasDynamicVariables = true\n }\n }\n return parameters\n }\n}\n\nexport function execute(input: QueryEvent, callback: WorkerCallback) {\n const run = async () => {\n const Runner = new QueryRunner(input)\n try {\n const response = await Runner.execute()\n callback(null, response)\n } catch (err) {\n callback(err)\n }\n }\n context.doInAppContext(input.appId!, async () => {\n if (input.environmentVariables) {\n return context.doInEnvironmentContext(input.environmentVariables, () => {\n return run()\n })\n } else {\n return run()\n }\n })\n}\n", "import { join } from \"path\"\n\nfunction isTest() {\n return isCypress() || isJest()\n}\n\nfunction isJest() {\n return (\n process.env.NODE_ENV === \"jest\" ||\n (process.env.JEST_WORKER_ID != null &&\n process.env.JEST_WORKER_ID !== \"null\")\n )\n}\n\nfunction isDev() {\n return process.env.NODE_ENV !== \"production\"\n}\n\nfunction isCypress() {\n return process.env.NODE_ENV === \"cypress\"\n}\n\nlet LOADED = false\nif (!LOADED && isDev() && !isTest()) {\n require(\"dotenv\").config({\n path: join(__dirname, \"..\", \".env\"),\n })\n LOADED = true\n}\n\nfunction parseIntSafe(number?: string) {\n if (number) {\n return parseInt(number)\n }\n}\n\nconst environment = {\n // important - prefer app port to generic port\n PORT: process.env.APP_PORT || process.env.PORT,\n COUCH_DB_URL: process.env.COUCH_DB_URL,\n MINIO_URL: process.env.MINIO_URL,\n WORKER_URL: process.env.WORKER_URL,\n AWS_REGION: process.env.AWS_REGION,\n MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY,\n MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY,\n REDIS_URL: process.env.REDIS_URL,\n REDIS_PASSWORD: process.env.REDIS_PASSWORD,\n REDIS_CLUSTERED: process.env.REDIS_CLUSTERED,\n HTTP_MIGRATIONS: process.env.HTTP_MIGRATIONS,\n API_REQ_LIMIT_PER_SEC: process.env.API_REQ_LIMIT_PER_SEC,\n GOOGLE_CLIENT_ID: process.env.GOOGLE_CLIENT_ID,\n GOOGLE_CLIENT_SECRET: process.env.GOOGLE_CLIENT_SECRET,\n // environment\n NODE_ENV: process.env.NODE_ENV,\n JEST_WORKER_ID: process.env.JEST_WORKER_ID,\n BUDIBASE_ENVIRONMENT: process.env.BUDIBASE_ENVIRONMENT,\n DISABLE_ACCOUNT_PORTAL: process.env.DISABLE_ACCOUNT_PORTAL,\n TEMPLATE_REPOSITORY: process.env.TEMPLATE_REPOSITORY || \"app\",\n DISABLE_AUTO_PROD_APP_SYNC: process.env.DISABLE_AUTO_PROD_APP_SYNC,\n SESSION_UPDATE_PERIOD: process.env.SESSION_UPDATE_PERIOD,\n // minor\n SALT_ROUNDS: process.env.SALT_ROUNDS,\n LOGGER: process.env.LOGGER,\n ACCOUNT_PORTAL_URL: process.env.ACCOUNT_PORTAL_URL,\n AUTOMATION_MAX_ITERATIONS:\n parseIntSafe(process.env.AUTOMATION_MAX_ITERATIONS) || 200,\n SENDGRID_API_KEY: process.env.SENDGRID_API_KEY,\n DYNAMO_ENDPOINT: process.env.DYNAMO_ENDPOINT,\n QUERY_THREAD_TIMEOUT: parseIntSafe(process.env.QUERY_THREAD_TIMEOUT),\n SQL_MAX_ROWS: process.env.SQL_MAX_ROWS,\n BB_ADMIN_USER_EMAIL: process.env.BB_ADMIN_USER_EMAIL,\n BB_ADMIN_USER_PASSWORD: process.env.BB_ADMIN_USER_PASSWORD,\n PLUGINS_DIR: process.env.PLUGINS_DIR || \"/plugins\",\n OPENAI_API_KEY: process.env.OPENAI_API_KEY,\n // flags\n ALLOW_DEV_AUTOMATIONS: process.env.ALLOW_DEV_AUTOMATIONS,\n DISABLE_THREADING: process.env.DISABLE_THREADING,\n DISABLE_AUTOMATION_LOGS: process.env.DISABLE_AUTOMATION_LOGS,\n MULTI_TENANCY: process.env.MULTI_TENANCY,\n ENABLE_ANALYTICS: process.env.ENABLE_ANALYTICS,\n SELF_HOSTED: process.env.SELF_HOSTED,\n HTTP_MB_LIMIT: process.env.HTTP_MB_LIMIT,\n FORKED_PROCESS_NAME: process.env.FORKED_PROCESS_NAME || \"main\",\n // old\n CLIENT_ID: process.env.CLIENT_ID,\n _set(key: string, value: any) {\n process.env[key] = value\n // @ts-ignore\n environment[key] = value\n },\n isTest,\n isJest,\n isCypress,\n isDev,\n isProd: () => {\n return !isDev()\n },\n isInThread: () => {\n return process.env.FORKED_PROCESS\n },\n TOP_LEVEL_PATH: process.env.TOP_LEVEL_PATH,\n}\n\n// threading can cause memory issues with node-ts in development\nif (isDev() && environment.DISABLE_THREADING == null) {\n environment._set(\"DISABLE_THREADING\", \"1\")\n}\n\n// clean up any environment variable edge cases\nfor (let [key, value] of Object.entries(environment)) {\n // handle the edge case of \"0\" to disable an environment variable\n if (value === \"0\") {\n // @ts-ignore\n environment[key] = 0\n }\n // handle the edge case of \"false\" to disable an environment variable\n if (value === \"false\") {\n // @ts-ignore\n environment[key] = 0\n }\n}\n\nexport default environment\n", "export * from \"./configs\"\n", "import {\n Config,\n ConfigType,\n GoogleConfig,\n GoogleInnerConfig,\n OIDCConfig,\n OIDCInnerConfig,\n SCIMConfig,\n SCIMInnerConfig,\n SettingsConfig,\n SettingsInnerConfig,\n SMTPConfig,\n SMTPInnerConfig,\n} from \"@budibase/types\"\nimport { DocumentType, SEPARATOR } from \"../constants\"\nimport { CacheKey, TTL, withCache } from \"../cache\"\nimport * as context from \"../context\"\nimport env from \"../environment\"\nimport environment from \"../environment\"\n\n// UTILS\n\n/**\n * Generates a new configuration ID.\n * @returns {string} The new configuration ID which the config doc can be stored under.\n */\nexport function generateConfigID(type: ConfigType) {\n return `${DocumentType.CONFIG}${SEPARATOR}${type}`\n}\n\nexport async function getConfig<T extends Config>(\n type: ConfigType\n): Promise<T | undefined> {\n const db = context.getGlobalDB()\n try {\n // await to catch error\n return (await db.get(generateConfigID(type))) as T\n } catch (e: any) {\n if (e.status === 404) {\n return\n }\n throw e\n }\n}\n\nexport async function save(\n config: Config\n): Promise<{ id: string; rev: string }> {\n const db = context.getGlobalDB()\n return db.put(config)\n}\n\n// SETTINGS\n\nexport async function getSettingsConfigDoc(): Promise<SettingsConfig> {\n let config = await getConfig<SettingsConfig>(ConfigType.SETTINGS)\n\n if (!config) {\n config = {\n _id: generateConfigID(ConfigType.SETTINGS),\n type: ConfigType.SETTINGS,\n config: {},\n }\n }\n\n // overridden fields\n config.config.platformUrl = await getPlatformUrl({\n tenantAware: true,\n config: config.config,\n })\n config.config.analyticsEnabled = await analyticsEnabled({\n config: config.config,\n })\n\n return config\n}\n\nexport async function getSettingsConfig(): Promise<SettingsInnerConfig> {\n return (await getSettingsConfigDoc()).config\n}\n\nexport async function getPlatformUrl(\n opts: { tenantAware: boolean; config?: SettingsInnerConfig } = {\n tenantAware: true,\n }\n) {\n let platformUrl = env.PLATFORM_URL || \"http://localhost:10000\"\n\n if (!env.SELF_HOSTED && env.MULTI_TENANCY && opts.tenantAware) {\n // cloud and multi tenant - add the tenant to the default platform url\n const tenantId = context.getTenantId()\n if (!platformUrl.includes(\"localhost:\")) {\n platformUrl = platformUrl.replace(\"://\", `://${tenantId}.`)\n }\n } else if (env.SELF_HOSTED) {\n const config = opts?.config\n ? opts.config\n : // direct to db to prevent infinite loop\n (await getConfig<SettingsConfig>(ConfigType.SETTINGS))?.config\n if (config?.platformUrl) {\n platformUrl = config.platformUrl\n }\n }\n\n return platformUrl\n}\n\nexport const analyticsEnabled = async (opts?: {\n config?: SettingsInnerConfig\n}) => {\n // cloud - always use the environment variable\n if (!env.SELF_HOSTED) {\n return !!env.ENABLE_ANALYTICS\n }\n\n // self host - prefer the settings doc\n // use cache as events have high throughput\n const enabledInDB = await withCache(\n CacheKey.ANALYTICS_ENABLED,\n TTL.ONE_DAY,\n async () => {\n const config = opts?.config\n ? opts.config\n : // direct to db to prevent infinite loop\n (await getConfig<SettingsConfig>(ConfigType.SETTINGS))?.config\n\n // need to do explicit checks in case the field is not set\n if (config?.analyticsEnabled === false) {\n return false\n } else if (config?.analyticsEnabled === true) {\n return true\n }\n }\n )\n\n if (enabledInDB !== undefined) {\n return enabledInDB\n }\n\n // fallback to the environment variable\n // explicitly check for 0 or false here, undefined or otherwise is treated as true\n const envEnabled: any = env.ENABLE_ANALYTICS\n if (envEnabled === 0 || envEnabled === false) {\n return false\n } else {\n return true\n }\n}\n\n// GOOGLE\n\nasync function getGoogleConfigDoc(): Promise<GoogleConfig | undefined> {\n return await getConfig<GoogleConfig>(ConfigType.GOOGLE)\n}\n\nexport async function getGoogleConfig(): Promise<\n GoogleInnerConfig | undefined\n> {\n const config = await getGoogleConfigDoc()\n return config?.config\n}\n\nexport async function getGoogleDatasourceConfig(): Promise<\n GoogleInnerConfig | undefined\n> {\n if (!env.SELF_HOSTED) {\n // always use the env vars in cloud\n return getDefaultGoogleConfig()\n }\n\n // prefer the config in self-host\n let config = await getGoogleConfig()\n\n // fallback to env vars\n if (!config || !config.activated) {\n config = getDefaultGoogleConfig()\n }\n\n return config\n}\n\nexport function getDefaultGoogleConfig(): GoogleInnerConfig | undefined {\n if (environment.GOOGLE_CLIENT_ID && environment.GOOGLE_CLIENT_SECRET) {\n return {\n clientID: environment.GOOGLE_CLIENT_ID!,\n clientSecret: environment.GOOGLE_CLIENT_SECRET!,\n activated: true,\n }\n }\n}\n\n// OIDC\n\nasync function getOIDCConfigDoc(): Promise<OIDCConfig | undefined> {\n return getConfig<OIDCConfig>(ConfigType.OIDC)\n}\n\nexport async function getOIDCConfig(): Promise<OIDCInnerConfig | undefined> {\n const config = (await getOIDCConfigDoc())?.config\n // default to the 0th config\n return config?.configs && config.configs[0]\n}\n\n/**\n * @param configId The config id of the inner config to retrieve\n */\nexport async function getOIDCConfigById(\n configId: string\n): Promise<OIDCInnerConfig | undefined> {\n const config = (await getConfig<OIDCConfig>(ConfigType.OIDC))?.config\n return config && config.configs.filter((c: any) => c.uuid === configId)[0]\n}\n\n// SMTP\n\nexport async function getSMTPConfigDoc(): Promise<SMTPConfig | undefined> {\n return getConfig<SMTPConfig>(ConfigType.SMTP)\n}\n\nexport async function getSMTPConfig(\n isAutomation?: boolean\n): Promise<SMTPInnerConfig | undefined> {\n const config = await getSMTPConfigDoc()\n if (config) {\n return config.config\n }\n\n // always allow fallback in self host\n // in cloud don't allow for automations\n const allowFallback = env.SELF_HOSTED || !isAutomation\n\n // Use an SMTP fallback configuration from env variables\n if (env.SMTP_FALLBACK_ENABLED && allowFallback) {\n return {\n port: env.SMTP_PORT,\n host: env.SMTP_HOST!,\n secure: false,\n from: env.SMTP_FROM_ADDRESS!,\n auth: {\n user: env.SMTP_USER!,\n pass: env.SMTP_PASSWORD!,\n },\n }\n }\n}\n\n// SCIM\n\nexport async function getSCIMConfig(): Promise<SCIMInnerConfig | undefined> {\n const config = await getConfig<SCIMConfig>(ConfigType.SCIM)\n return config?.config\n}\n", "export * as generic from \"./generic\"\nexport * as user from \"./user\"\nexport * as app from \"./appMetadata\"\nexport * as writethrough from \"./writethrough\"\nexport * from \"./generic\"\n", "const BaseCache = require(\"./base\")\n\nconst GENERIC = new BaseCache.default()\n\nexport enum CacheKey {\n CHECKLIST = \"checklist\",\n INSTALLATION = \"installation\",\n ANALYTICS_ENABLED = \"analyticsEnabled\",\n UNIQUE_TENANT_ID = \"uniqueTenantId\",\n EVENTS = \"events\",\n BACKFILL_METADATA = \"backfillMetadata\",\n EVENTS_RATE_LIMIT = \"eventsRateLimit\",\n}\n\nexport enum TTL {\n ONE_MINUTE = 600,\n ONE_HOUR = 3600,\n ONE_DAY = 86400,\n}\n\nfunction performExport(funcName: string) {\n return (...args: any) => GENERIC[funcName](...args)\n}\n\nexport const keys = performExport(\"keys\")\nexport const get = performExport(\"get\")\nexport const store = performExport(\"store\")\nexport const destroy = performExport(\"delete\")\nexport const withCache = performExport(\"withCache\")\nexport const bustCache = performExport(\"bustCache\")\n", "import * as redis from \"../redis/init\"\nimport * as tenancy from \"../tenancy\"\nimport * as context from \"../context\"\nimport * as platform from \"../platform\"\nimport env from \"../environment\"\nimport * as accounts from \"../accounts\"\n\nconst EXPIRY_SECONDS = 3600\n\n/**\n * The default populate user function\n */\nasync function populateFromDB(userId: string, tenantId: string) {\n const db = tenancy.getTenantDB(tenantId)\n const user = await db.get(userId)\n user.budibaseAccess = true\n if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {\n const account = await accounts.getAccount(user.email)\n if (account) {\n user.account = account\n user.accountPortalAccess = true\n }\n }\n\n return user\n}\n\n/**\n * Get the requested user by id.\n * Use redis cache to first read the user.\n * If not present fallback to loading the user directly and re-caching.\n * @param {*} userId the id of the user to get\n * @param {*} tenantId the tenant of the user to get\n * @param {*} populateUser function to provide the user for re-caching. default to couch db\n * @returns\n */\nexport async function getUser(\n userId: string,\n tenantId?: string,\n populateUser?: any\n) {\n if (!populateUser) {\n populateUser = populateFromDB\n }\n if (!tenantId) {\n try {\n tenantId = context.getTenantId()\n } catch (err) {\n tenantId = await platform.users.lookupTenantId(userId)\n }\n }\n const client = await redis.getUserClient()\n // try cache\n let user = await client.get(userId)\n if (!user) {\n user = await populateUser(userId, tenantId)\n await client.store(userId, user, EXPIRY_SECONDS)\n }\n if (user && !user.tenantId && tenantId) {\n // make sure the tenant ID is always correct/set\n user.tenantId = tenantId\n }\n return user\n}\n\nexport async function invalidateUser(userId: string) {\n const client = await redis.getUserClient()\n await client.delete(userId)\n}\n", "export * from \"./db\"\nexport * from \"./tenancy\"\n", "import { getDB } from \"../db/db\"\nimport { getGlobalDBName } from \"../context\"\n\nexport function getTenantDB(tenantId: string) {\n return getDB(getGlobalDBName(tenantId))\n}\n", "import {\n DEFAULT_TENANT_ID,\n getTenantId,\n getTenantIDFromAppID,\n isMultiTenant,\n getPlatformURL,\n} from \"../context\"\nimport {\n BBContext,\n TenantResolutionStrategy,\n GetTenantIdOptions,\n} from \"@budibase/types\"\nimport { Header } from \"../constants\"\n\nexport function addTenantToUrl(url: string) {\n const tenantId = getTenantId()\n\n if (isMultiTenant()) {\n const char = url.indexOf(\"?\") === -1 ? \"?\" : \"&\"\n url += `${char}tenantId=${tenantId}`\n }\n\n return url\n}\n\nexport const isUserInAppTenant = (appId: string, user?: any) => {\n let userTenantId\n if (user) {\n userTenantId = user.tenantId || DEFAULT_TENANT_ID\n } else {\n userTenantId = getTenantId()\n }\n const tenantId = getTenantIDFromAppID(appId) || DEFAULT_TENANT_ID\n return tenantId === userTenantId\n}\n\nconst ALL_STRATEGIES = Object.values(TenantResolutionStrategy)\n\nexport const getTenantIDFromCtx = (\n ctx: BBContext,\n opts: GetTenantIdOptions\n): string | null => {\n // exit early if not multi-tenant\n if (!isMultiTenant()) {\n return DEFAULT_TENANT_ID\n }\n\n // opt defaults\n if (opts.allowNoTenant === undefined) {\n opts.allowNoTenant = false\n }\n if (!opts.includeStrategies) {\n opts.includeStrategies = ALL_STRATEGIES\n }\n if (!opts.excludeStrategies) {\n opts.excludeStrategies = []\n }\n\n const isAllowed = (strategy: TenantResolutionStrategy) => {\n // excluded takes precedence\n if (opts.excludeStrategies?.includes(strategy)) {\n return false\n }\n if (opts.includeStrategies?.includes(strategy)) {\n return true\n }\n }\n\n // always use user first\n if (isAllowed(TenantResolutionStrategy.USER)) {\n const userTenantId = ctx.user?.tenantId\n if (userTenantId) {\n return userTenantId\n }\n }\n\n // header\n if (isAllowed(TenantResolutionStrategy.HEADER)) {\n const headerTenantId = ctx.request.headers[Header.TENANT_ID]\n if (headerTenantId) {\n return headerTenantId as string\n }\n }\n\n // query param\n if (isAllowed(TenantResolutionStrategy.QUERY)) {\n const queryTenantId = ctx.request.query.tenantId\n if (queryTenantId) {\n return queryTenantId as string\n }\n }\n\n // subdomain\n if (isAllowed(TenantResolutionStrategy.SUBDOMAIN)) {\n // e.g. budibase.app or local.com:10000\n const platformHost = new URL(getPlatformURL()).host.split(\":\")[0]\n // e.g. tenant.budibase.app or tenant.local.com\n const requestHost = ctx.host\n // parse the tenant id from the difference\n if (requestHost.includes(platformHost)) {\n const tenantId = requestHost.substring(\n 0,\n requestHost.indexOf(`.${platformHost}`)\n )\n if (tenantId) {\n return tenantId\n }\n }\n }\n\n // path\n if (isAllowed(TenantResolutionStrategy.PATH)) {\n // params - have to parse manually due to koa-router not run yet\n const match = ctx.matched.find(\n (m: any) => !!m.paramNames.find((p: any) => p.name === \"tenantId\")\n )\n\n // get the raw path url - without any query params\n const ctxUrl = ctx.originalUrl\n let url\n if (ctxUrl.includes(\"?\")) {\n url = ctxUrl.split(\"?\")[0]\n } else {\n url = ctxUrl\n }\n\n if (match) {\n const params = match.params(url, match.captures(url), {})\n if (params.tenantId) {\n return params.tenantId\n }\n }\n }\n\n if (!opts.allowNoTenant) {\n ctx.throw(403, \"Tenant id not set\")\n }\n\n return null\n}\n", "import { getPlatformDB } from \"./platformDb\"\nimport { DEFAULT_TENANT_ID } from \"../constants\"\nimport env from \"../environment\"\nimport {\n PlatformUser,\n PlatformUserByEmail,\n PlatformUserById,\n User,\n} from \"@budibase/types\"\n\n// READ\n\nexport async function lookupTenantId(userId: string) {\n if (!env.MULTI_TENANCY) {\n return DEFAULT_TENANT_ID\n }\n\n const user = await getUserDoc(userId)\n return user.tenantId\n}\n\nasync function getUserDoc(emailOrId: string): Promise<PlatformUser> {\n const db = getPlatformDB()\n return db.get(emailOrId)\n}\n\n// CREATE\n\nfunction newUserIdDoc(id: string, tenantId: string): PlatformUserById {\n return {\n _id: id,\n tenantId,\n }\n}\n\nfunction newUserEmailDoc(\n userId: string,\n email: string,\n tenantId: string\n): PlatformUserByEmail {\n return {\n _id: email,\n userId,\n tenantId,\n }\n}\n\n/**\n * Add a new user id or email doc if it doesn't exist.\n */\nasync function addUserDoc(emailOrId: string, newDocFn: () => PlatformUser) {\n const db = getPlatformDB()\n let user: PlatformUser\n\n try {\n await db.get(emailOrId)\n } catch (e: any) {\n if (e.status === 404) {\n user = newDocFn()\n await db.put(user)\n } else {\n throw e\n }\n }\n}\n\nexport async function addUser(tenantId: string, userId: string, email: string) {\n await Promise.all([\n addUserDoc(userId, () => newUserIdDoc(userId, tenantId)),\n addUserDoc(email, () => newUserEmailDoc(userId, email, tenantId)),\n ])\n}\n\n// DELETE\n\nexport async function removeUser(user: User) {\n const db = getPlatformDB()\n const keys = [user._id!, user.email]\n const userDocs = await db.allDocs({\n keys,\n include_docs: true,\n })\n const toDelete = userDocs.rows.map((row: any) => {\n return {\n ...row.doc,\n _deleted: true,\n }\n })\n await db.bulkDocs(toDelete)\n}\n", "import { StaticDatabases } from \"../constants\"\nimport { getDB } from \"../db/db\"\n\nexport function getPlatformDB() {\n return getDB(StaticDatabases.PLATFORM_INFO.name)\n}\n", "import { StaticDatabases } from \"../constants\"\nimport { getPlatformDB } from \"./platformDb\"\nimport { LockName, LockOptions, LockType, Tenants } from \"@budibase/types\"\nimport * as locks from \"../redis/redlockImpl\"\n\nconst TENANT_DOC = StaticDatabases.PLATFORM_INFO.docs.tenants\n\nexport const tenacyLockOptions: LockOptions = {\n type: LockType.DEFAULT,\n name: LockName.UPDATE_TENANTS_DOC,\n ttl: 10 * 1000, // auto expire after 10 seconds\n systemLock: true,\n}\n\n// READ\n\nexport async function getTenantIds(): Promise<string[]> {\n const tenants = await getTenants()\n return tenants.tenantIds\n}\n\nasync function getTenants(): Promise<Tenants> {\n const db = getPlatformDB()\n let tenants: Tenants\n\n try {\n tenants = await db.get(TENANT_DOC)\n } catch (e: any) {\n // doesn't exist yet - create\n if (e.status === 404) {\n tenants = await createTenantsDoc()\n } else {\n throw e\n }\n }\n\n return tenants\n}\n\nexport async function exists(tenantId: string) {\n const tenants = await getTenants()\n return tenants.tenantIds.indexOf(tenantId) !== -1\n}\n\n// CREATE / UPDATE\n\nfunction newTenantsDoc(): Tenants {\n return {\n _id: TENANT_DOC,\n tenantIds: [],\n }\n}\n\nasync function createTenantsDoc(): Promise<Tenants> {\n const db = getPlatformDB()\n let tenants = newTenantsDoc()\n\n try {\n const response = await db.put(tenants)\n tenants._rev = response.rev\n } catch (e: any) {\n // don't throw 409 is doc has already been created\n if (e.status === 409) {\n return db.get(TENANT_DOC)\n }\n throw e\n }\n\n return tenants\n}\n\nexport async function addTenant(tenantId: string) {\n const db = getPlatformDB()\n\n // use a lock as tenant creation is conflict prone\n await locks.doWithLock(tenacyLockOptions, async () => {\n const tenants = await getTenants()\n\n // write the new tenant if it doesn't already exist\n if (tenants.tenantIds.indexOf(tenantId) === -1) {\n tenants.tenantIds.push(tenantId)\n await db.put(tenants)\n }\n })\n}\n\n// DELETE\n\nexport async function removeTenant(tenantId: string) {\n try {\n await locks.doWithLock(tenacyLockOptions, async () => {\n const db = getPlatformDB()\n const tenants = await getTenants()\n tenants.tenantIds = tenants.tenantIds.filter(id => id !== tenantId)\n await db.put(tenants)\n })\n } catch (err) {\n console.error(`Error removing tenant ${tenantId} from info db`, err)\n throw err\n }\n}\n", "import Redlock from \"redlock\"\nimport { getLockClient } from \"./init\"\nimport { LockOptions, LockType } from \"@budibase/types\"\nimport * as context from \"../context\"\nimport env from \"../environment\"\n\nasync function getClient(\n type: LockType,\n opts?: Redlock.Options\n): Promise<Redlock> {\n if (type === LockType.CUSTOM) {\n return newRedlock(opts)\n }\n if (env.isTest() && type !== LockType.TRY_ONCE) {\n return newRedlock(OPTIONS.TEST)\n }\n switch (type) {\n case LockType.TRY_ONCE: {\n return newRedlock(OPTIONS.TRY_ONCE)\n }\n case LockType.TRY_TWICE: {\n return newRedlock(OPTIONS.TRY_TWICE)\n }\n case LockType.DEFAULT: {\n return newRedlock(OPTIONS.DEFAULT)\n }\n case LockType.DELAY_500: {\n return newRedlock(OPTIONS.DELAY_500)\n }\n default: {\n throw new Error(`Could not get redlock client: ${type}`)\n }\n }\n}\n\nconst OPTIONS = {\n TRY_ONCE: {\n // immediately throws an error if the lock is already held\n retryCount: 0,\n },\n TRY_TWICE: {\n retryCount: 1,\n },\n TEST: {\n // higher retry count in unit tests\n // due to high contention.\n retryCount: 100,\n },\n DEFAULT: {\n // the expected clock drift; for more details\n // see http://redis.io/topics/distlock\n driftFactor: 0.01, // multiplied by lock ttl to determine drift time\n\n // the max number of times Redlock will attempt\n // to lock a resource before erroring\n retryCount: 10,\n\n // the time in ms between attempts\n retryDelay: 200, // time in ms\n\n // the max time in ms randomly added to retries\n // to improve performance under high contention\n // see https://www.awsarchitectureblog.com/2015/03/backoff.html\n retryJitter: 100, // time in ms\n },\n DELAY_500: {\n retryDelay: 500,\n },\n}\n\nexport async function newRedlock(opts: Redlock.Options = {}) {\n let options = { ...OPTIONS.DEFAULT, ...opts }\n const redisWrapper = await getLockClient()\n const client = redisWrapper.getClient()\n return new Redlock([client], options)\n}\n\ntype SuccessfulRedlockExecution<T> = {\n executed: true\n result: T\n}\ntype UnsuccessfulRedlockExecution = {\n executed: false\n}\n\ntype RedlockExecution<T> =\n | SuccessfulRedlockExecution<T>\n | UnsuccessfulRedlockExecution\n\nfunction getLockName(opts: LockOptions) {\n // determine lock name\n // by default use the tenantId for uniqueness, unless using a system lock\n const prefix = opts.systemLock ? \"system\" : context.getTenantId()\n let name: string = `lock:${prefix}_${opts.name}`\n // add additional unique name if required\n if (opts.resource) {\n name = name + `_${opts.resource}`\n }\n return name\n}\n\nexport async function doWithLock<T>(\n opts: LockOptions,\n task: () => Promise<T>\n): Promise<RedlockExecution<T>> {\n const redlock = await getClient(opts.type, opts.customOptions)\n let lock\n try {\n const name = getLockName(opts)\n\n // create the lock\n lock = await redlock.lock(name, opts.ttl)\n\n // perform locked task\n // need to await to ensure completion before unlocking\n const result = await task()\n return { executed: true, result }\n } catch (e: any) {\n console.warn(\"lock error\")\n // lock limit exceeded\n if (e.name === \"LockError\") {\n if (opts.type === LockType.TRY_ONCE) {\n // don't throw for try-once locks, they will always error\n // due to retry count (0) exceeded\n return { executed: false }\n } else {\n console.error(e)\n throw e\n }\n } else {\n console.error(e)\n throw e\n }\n } finally {\n if (lock) {\n await lock.unlock()\n }\n }\n}\n", "import fetch from \"node-fetch\"\nimport * as logging from \"../logging\"\n\nexport default class API {\n host: string\n\n constructor(host: string) {\n this.host = host\n }\n\n async apiCall(method: string, url: string, options?: any) {\n if (!options.headers) {\n options.headers = {}\n }\n\n if (!options.headers[\"Content-Type\"]) {\n options.headers = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...options.headers,\n }\n }\n\n let json = options.headers[\"Content-Type\"] === \"application/json\"\n\n // add x-budibase-correlation-id header\n logging.correlation.setHeader(options.headers)\n\n const requestOptions = {\n method: method,\n body: json ? JSON.stringify(options.body) : options.body,\n headers: options.headers,\n // TODO: See if this is necessary\n credentials: \"include\",\n }\n\n return await fetch(`${this.host}${url}`, requestOptions)\n }\n\n async post(url: string, options?: any) {\n return this.apiCall(\"POST\", url, options)\n }\n\n async get(url: string, options?: any) {\n return this.apiCall(\"GET\", url, options)\n }\n\n async patch(url: string, options?: any) {\n return this.apiCall(\"PATCH\", url, options)\n }\n\n async del(url: string, options?: any) {\n return this.apiCall(\"DELETE\", url, options)\n }\n\n async put(url: string, options?: any) {\n return this.apiCall(\"PUT\", url, options)\n }\n}\n", "import API from \"./api\"\nimport env from \"../environment\"\nimport { Header } from \"../constants\"\nimport { CloudAccount, HealthStatusResponse } from \"@budibase/types\"\n\nconst api = new API(env.ACCOUNT_PORTAL_URL)\n\n/**\n * This client is intended to be used in a cloud hosted deploy only.\n * Rather than relying on each consumer to perform the necessary environmental checks\n * we use the following check to exit early with a undefined response which should be\n * handled by the caller.\n */\nconst EXIT_EARLY = env.SELF_HOSTED || env.DISABLE_ACCOUNT_PORTAL\n\nexport const getAccount = async (\n email: string\n): Promise<CloudAccount | undefined> => {\n if (EXIT_EARLY) {\n return\n }\n const payload = {\n email,\n }\n const response = await api.post(`/api/accounts/search`, {\n body: payload,\n headers: {\n [Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,\n },\n })\n\n if (response.status !== 200) {\n throw new Error(`Error getting account by email ${email}`)\n }\n\n const json: CloudAccount[] = await response.json()\n return json[0]\n}\n\nexport const getAccountByTenantId = async (\n tenantId: string\n): Promise<CloudAccount | undefined> => {\n if (EXIT_EARLY) {\n return\n }\n const payload = {\n tenantId,\n }\n const response = await api.post(`/api/accounts/search`, {\n body: payload,\n headers: {\n [Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,\n },\n })\n\n if (response.status !== 200) {\n throw new Error(`Error getting account by tenantId ${tenantId}`)\n }\n\n const json: CloudAccount[] = await response.json()\n return json[0]\n}\n\nexport const getStatus = async (): Promise<\n HealthStatusResponse | undefined\n> => {\n if (EXIT_EARLY) {\n return\n }\n const response = await api.get(`/api/status`, {\n headers: {\n [Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,\n },\n })\n const json = await response.json()\n\n if (response.status !== 200) {\n throw new Error(`Error getting status`)\n }\n\n return json\n}\n", "import { getAppClient } from \"../redis/init\"\nimport { doWithDB, DocumentType } from \"../db\"\nimport { Database, App } from \"@budibase/types\"\n\nconst AppState = {\n INVALID: \"invalid\",\n}\nconst EXPIRY_SECONDS = 3600\n\n/**\n * The default populate app metadata function\n */\nasync function populateFromDB(appId: string) {\n return doWithDB(\n appId,\n (db: Database) => {\n return db.get(DocumentType.APP_METADATA)\n },\n { skip_setup: true }\n )\n}\n\nfunction isInvalid(metadata?: { state: string }) {\n return !metadata || metadata.state === AppState.INVALID\n}\n\n/**\n * Get the requested app metadata by id.\n * Use redis cache to first read the app metadata.\n * If not present fallback to loading the app metadata directly and re-caching.\n * @param {string} appId the id of the app to get metadata from.\n * @returns {object} the app metadata.\n */\nexport async function getAppMetadata(appId: string) {\n const client = await getAppClient()\n // try cache\n let metadata = await client.get(appId)\n if (!metadata) {\n let expiry: number | undefined = EXPIRY_SECONDS\n try {\n metadata = await populateFromDB(appId)\n } catch (err: any) {\n // app DB left around, but no metadata, it is invalid\n if (err && err.status === 404) {\n metadata = { state: AppState.INVALID }\n // don't expire the reference to an invalid app, it'll only be\n // updated if a metadata doc actually gets stored (app is remade/reverted)\n expiry = undefined\n } else {\n throw err\n }\n }\n // needed for cypress/some scenarios where the caching happens\n // so quickly the requests can get slightly out of sync\n // might store its invalid just before it stores its valid\n if (isInvalid(metadata)) {\n const temp = await client.get(appId)\n if (temp) {\n metadata = temp\n }\n }\n await client.store(appId, metadata, expiry)\n }\n // we've stored in the cache an object to tell us that it is currently invalid\n if (isInvalid(metadata)) {\n throw { status: 404, message: \"No app metadata found\" }\n }\n return metadata as App\n}\n\n/**\n * Invalidate/reset the cached metadata when a change occurs in the db.\n * @param appId {string} the cache key to bust/update.\n * @param newMetadata {object|undefined} optional - can simply provide the new metadata to update with.\n * @return {Promise<void>} will respond with success when cache is updated.\n */\nexport async function invalidateAppMetadata(appId: string, newMetadata?: any) {\n if (!appId) {\n throw \"Cannot invalidate if no app ID provided.\"\n }\n const client = await getAppClient()\n await client.delete(appId)\n if (newMetadata) {\n await client.store(appId, newMetadata, EXPIRY_SECONDS)\n }\n}\n", "export * from \"./couch\"\nexport * from \"./db\"\nexport * from \"./utils\"\nexport * from \"./views\"\nexport * from \"../docIds/conversions\"\nexport { default as Replication } from \"./Replication\"\n// exports to support old export structure\nexport * from \"../constants/db\"\nexport { getGlobalDBName, baseGlobalDBName } from \"../context\"\nexport * from \"./lucene\"\nexport * as searchIndexes from \"./searchIndexes\"\n", "import env from \"../environment\"\nimport { DEFAULT_TENANT_ID, SEPARATOR, DocumentType } from \"../constants\"\nimport { getTenantId, getGlobalDBName } from \"../context\"\nimport { doWithDB, directCouchAllDbs } from \"./db\"\nimport { getAppMetadata } from \"../cache/appMetadata\"\nimport { isDevApp, isDevAppID, getProdAppID } from \"../docIds/conversions\"\nimport { App, Database } from \"@budibase/types\"\nimport { getStartEndKeyURL } from \"../docIds\"\nexport * from \"../docIds\"\n\n/**\n * if in production this will use the CouchDB _all_dbs call to retrieve a list of databases. If testing\n * when using Pouch it will use the pouchdb-all-dbs package.\n * opts.efficient can be provided to make sure this call is always quick in a multi-tenant environment,\n * but it may not be 100% accurate in full efficiency mode (some tenantless apps may be missed).\n */\nexport async function getAllDbs(opts = { efficient: false }) {\n const efficient = opts && opts.efficient\n\n let dbs: any[] = []\n async function addDbs(queryString?: string) {\n const json = await directCouchAllDbs(queryString)\n dbs = dbs.concat(json)\n }\n let tenantId = getTenantId()\n if (!env.MULTI_TENANCY || (!efficient && tenantId === DEFAULT_TENANT_ID)) {\n // just get all DBs when:\n // - single tenancy\n // - default tenant\n // - apps dbs don't contain tenant id\n // - non-default tenant dbs are filtered out application side in getAllApps\n await addDbs()\n } else {\n // get prod apps\n await addDbs(getStartEndKeyURL(DocumentType.APP, tenantId))\n // get dev apps\n await addDbs(getStartEndKeyURL(DocumentType.APP_DEV, tenantId))\n // add global db name\n dbs.push(getGlobalDBName(tenantId))\n }\n return dbs\n}\n\n/**\n * Lots of different points in the system need to find the full list of apps, this will\n * enumerate the entire CouchDB cluster and get the list of databases (every app).\n *\n * @return {Promise<object[]>} returns the app information document stored in each app database.\n */\nexport async function getAllApps({\n dev,\n all,\n idsOnly,\n efficient,\n}: any = {}): Promise<App[] | string[]> {\n let tenantId = getTenantId()\n if (!env.MULTI_TENANCY && !tenantId) {\n tenantId = DEFAULT_TENANT_ID\n }\n let dbs = await getAllDbs({ efficient })\n const appDbNames = dbs.filter((dbName: any) => {\n if (env.isTest() && !dbName) {\n return false\n }\n\n const split = dbName.split(SEPARATOR)\n // it is an app, check the tenantId\n if (split[0] === DocumentType.APP) {\n // tenantId is always right before the UUID\n const possibleTenantId = split[split.length - 2]\n\n const noTenantId =\n split.length === 2 || possibleTenantId === DocumentType.DEV\n\n return (\n (tenantId === DEFAULT_TENANT_ID && noTenantId) ||\n possibleTenantId === tenantId\n )\n }\n return false\n })\n if (idsOnly) {\n const devAppIds = appDbNames.filter(appId => isDevAppID(appId))\n const prodAppIds = appDbNames.filter(appId => !isDevAppID(appId))\n switch (dev) {\n case true:\n return devAppIds\n case false:\n return prodAppIds\n default:\n return appDbNames\n }\n }\n const appPromises = appDbNames.map((app: any) =>\n // skip setup otherwise databases could be re-created\n getAppMetadata(app)\n )\n if (appPromises.length === 0) {\n return []\n } else {\n const response = await Promise.allSettled(appPromises)\n const apps = response\n .filter(\n (result: any) => result.status === \"fulfilled\" && result.value != null\n )\n .map(({ value }: any) => value)\n if (!all) {\n return apps.filter((app: any) => {\n if (dev) {\n return isDevApp(app)\n }\n return !isDevApp(app)\n })\n } else {\n return apps.map((app: any) => ({\n ...app,\n status: isDevApp(app) ? \"development\" : \"published\",\n }))\n }\n }\n}\n\nexport async function getAppsByIDs(appIds: string[]) {\n const settled = await Promise.allSettled(\n appIds.map(appId => getAppMetadata(appId))\n )\n // have to list the apps which exist, some may have been deleted\n return settled\n .filter(promise => promise.status === \"fulfilled\")\n .map(promise => (promise as PromiseFulfilledResult<App>).value)\n}\n\n/**\n * Utility function for getAllApps but filters to production apps only.\n */\nexport async function getProdAppIDs() {\n const apps = (await getAllApps({ idsOnly: true })) as string[]\n return apps.filter((id: any) => !isDevAppID(id))\n}\n\n/**\n * Utility function for the inverse of above.\n */\nexport async function getDevAppIDs() {\n const apps = (await getAllApps({ idsOnly: true })) as string[]\n return apps.filter((id: any) => isDevAppID(id))\n}\n\nexport function isSameAppID(\n appId1: string | undefined,\n appId2: string | undefined\n) {\n if (appId1 == undefined || appId2 == undefined) {\n return false\n }\n return getProdAppID(appId1) === getProdAppID(appId2)\n}\n\nexport async function dbExists(dbName: any) {\n return doWithDB(\n dbName,\n async (db: Database) => {\n return await db.exists()\n },\n { skip_setup: true }\n )\n}\n\nexport function pagination<T>(\n data: T[],\n pageSize: number,\n {\n paginate,\n property,\n getKey,\n }: {\n paginate: boolean\n property: string\n getKey?: (doc: T) => string | undefined\n } = {\n paginate: true,\n property: \"_id\",\n }\n) {\n if (!paginate) {\n return { data, hasNextPage: false }\n }\n const hasNextPage = data.length > pageSize\n let nextPage = undefined\n if (!getKey) {\n getKey = (doc: any) => (property ? doc?.[property] : doc?._id)\n }\n if (hasNextPage) {\n nextPage = getKey(data[pageSize])\n }\n return {\n data: data.slice(0, pageSize),\n hasNextPage,\n nextPage,\n }\n}\n", "import {\n APP_PREFIX,\n DocumentType,\n InternalTable,\n SEPARATOR,\n} from \"../constants\"\nimport { newid } from \"./newid\"\n\n/**\n * Generates a new app ID.\n * @returns {string} The new app ID which the app doc can be stored under.\n */\nexport const generateAppID = (tenantId?: string | null) => {\n let id = APP_PREFIX\n if (tenantId) {\n id += `${tenantId}${SEPARATOR}`\n }\n return `${id}${newid()}`\n}\n\n/**\n * Gets a new row ID for the specified table.\n * @param {string} tableId The table which the row is being created for.\n * @param {string|null} id If an ID is to be used then the UUID can be substituted for this.\n * @returns {string} The new ID which a row doc can be stored under.\n */\nexport function generateRowID(tableId: string, id?: string) {\n id = id || newid()\n return `${DocumentType.ROW}${SEPARATOR}${tableId}${SEPARATOR}${id}`\n}\n\n/**\n * Generates a new workspace ID.\n * @returns {string} The new workspace ID which the workspace doc can be stored under.\n */\nexport function generateWorkspaceID() {\n return `${DocumentType.WORKSPACE}${SEPARATOR}${newid()}`\n}\n\n/**\n * Generates a new global user ID.\n * @returns {string} The new user ID which the user doc can be stored under.\n */\nexport function generateGlobalUserID(id?: any) {\n return `${DocumentType.USER}${SEPARATOR}${id || newid()}`\n}\n\n/**\n * Generates a new user ID based on the passed in global ID.\n * @param {string} globalId The ID of the global user.\n * @returns {string} The new user ID which the user doc can be stored under.\n */\nexport function generateUserMetadataID(globalId: string) {\n return generateRowID(InternalTable.USER_METADATA, globalId)\n}\n\n/**\n * Breaks up the ID to get the global ID.\n */\nexport function getGlobalIDFromUserMetadataID(id: string) {\n const prefix = `${DocumentType.ROW}${SEPARATOR}${InternalTable.USER_METADATA}${SEPARATOR}`\n if (!id || !id.includes(prefix)) {\n return id\n }\n return id.split(prefix)[1]\n}\n\n/**\n * Generates a template ID.\n * @param ownerId The owner/user of the template, this could be global or a workspace level.\n */\nexport function generateTemplateID(ownerId: any) {\n return `${DocumentType.TEMPLATE}${SEPARATOR}${ownerId}${SEPARATOR}${newid()}`\n}\n\nexport function generateAppUserID(prodAppId: string, userId: string) {\n return `${prodAppId}${SEPARATOR}${userId}`\n}\n\n/**\n * Generates a new role ID.\n * @returns {string} The new role ID which the role doc can be stored under.\n */\nexport function generateRoleID(id?: any) {\n return `${DocumentType.ROLE}${SEPARATOR}${id || newid()}`\n}\n\n/**\n * Generates a new dev info document ID - this is scoped to a user.\n * @returns {string} The new dev info ID which info for dev (like api key) can be stored under.\n */\nexport const generateDevInfoID = (userId: any) => {\n return `${DocumentType.DEV_INFO}${SEPARATOR}${userId}`\n}\n\n/**\n * Generates a new plugin ID - to be used in the global DB.\n * @returns {string} The new plugin ID which a plugin metadata document can be stored under.\n */\nexport const generatePluginID = (name: string) => {\n return `${DocumentType.PLUGIN}${SEPARATOR}${name}`\n}\n", "import {\n DocumentType,\n InternalTable,\n SEPARATOR,\n UNICODE_MAX,\n ViewName,\n} from \"../constants\"\nimport { getProdAppID } from \"./conversions\"\n\n/**\n * If creating DB allDocs/query params with only a single top level ID this can be used, this\n * is usually the case as most of our docs are top level e.g. tables, automations, users and so on.\n * More complex cases such as link docs and rows which have multiple levels of IDs that their\n * ID consists of need their own functions to build the allDocs parameters.\n * @param {string} docType The type of document which input params are being built for, e.g. user,\n * link, app, table and so on.\n * @param {string|null} docId The ID of the document minus its type - this is only needed if looking\n * for a singular document.\n * @param {object} otherProps Add any other properties onto the request, e.g. include_docs.\n * @returns {object} Parameters which can then be used with an allDocs request.\n */\nexport function getDocParams(\n docType: string,\n docId?: string | null,\n otherProps: any = {}\n) {\n if (docId == null) {\n docId = \"\"\n }\n return {\n ...otherProps,\n startkey: `${docType}${SEPARATOR}${docId}`,\n endkey: `${docType}${SEPARATOR}${docId}${UNICODE_MAX}`,\n }\n}\n\n/**\n * Gets the DB allDocs/query params for retrieving a row.\n * @param {string|null} tableId The table in which the rows have been stored.\n * @param {string|null} rowId The ID of the row which is being specifically queried for. This can be\n * left null to get all the rows in the table.\n * @param {object} otherProps Any other properties to add to the request.\n * @returns {object} Parameters which can then be used with an allDocs request.\n */\nexport function getRowParams(\n tableId?: string | null,\n rowId?: string | null,\n otherProps = {}\n) {\n if (tableId == null) {\n return getDocParams(DocumentType.ROW, null, otherProps)\n }\n\n const endOfKey = rowId == null ? `${tableId}${SEPARATOR}` : rowId\n\n return getDocParams(DocumentType.ROW, endOfKey, otherProps)\n}\n\n/**\n * Retrieve the correct index for a view based on default design DB.\n */\nexport function getQueryIndex(viewName: ViewName) {\n return `database/${viewName}`\n}\n\n/**\n * Check if a given ID is that of a table.\n * @returns {boolean}\n */\nexport const isTableId = (id: string) => {\n // this includes datasource plus tables\n return (\n id &&\n (id.startsWith(`${DocumentType.TABLE}${SEPARATOR}`) ||\n id.startsWith(`${DocumentType.DATASOURCE_PLUS}${SEPARATOR}`))\n )\n}\n\n/**\n * Check if a given ID is that of a datasource or datasource plus.\n * @returns {boolean}\n */\nexport const isDatasourceId = (id: string) => {\n // this covers both datasources and datasource plus\n return id && id.startsWith(`${DocumentType.DATASOURCE}${SEPARATOR}`)\n}\n\n/**\n * Gets parameters for retrieving workspaces.\n */\nexport function getWorkspaceParams(id = \"\", otherProps = {}) {\n return {\n ...otherProps,\n startkey: `${DocumentType.WORKSPACE}${SEPARATOR}${id}`,\n endkey: `${DocumentType.WORKSPACE}${SEPARATOR}${id}${UNICODE_MAX}`,\n }\n}\n\n/**\n * Gets parameters for retrieving users.\n */\nexport function getGlobalUserParams(globalId: any, otherProps: any = {}) {\n if (!globalId) {\n globalId = \"\"\n }\n const startkey = otherProps?.startkey\n return {\n ...otherProps,\n // need to include this incase pagination\n startkey: startkey\n ? startkey\n : `${DocumentType.USER}${SEPARATOR}${globalId}`,\n endkey: `${DocumentType.USER}${SEPARATOR}${globalId}${UNICODE_MAX}`,\n }\n}\n\n/**\n * Gets parameters for retrieving users, this is a utility function for the getDocParams function.\n */\nexport function getUserMetadataParams(userId?: string | null, otherProps = {}) {\n return getRowParams(InternalTable.USER_METADATA, userId, otherProps)\n}\n\nexport function getUsersByAppParams(appId: any, otherProps: any = {}) {\n const prodAppId = getProdAppID(appId)\n return {\n ...otherProps,\n startkey: prodAppId,\n endkey: `${prodAppId}${UNICODE_MAX}`,\n }\n}\n\n/**\n * Gets parameters for retrieving templates. Owner ID must be specified, either global or a workspace level.\n */\nexport function getTemplateParams(\n ownerId: any,\n templateId: any,\n otherProps = {}\n) {\n if (!templateId) {\n templateId = \"\"\n }\n let final\n if (templateId) {\n final = templateId\n } else {\n final = `${DocumentType.TEMPLATE}${SEPARATOR}${ownerId}${SEPARATOR}`\n }\n return {\n ...otherProps,\n startkey: final,\n endkey: `${final}${UNICODE_MAX}`,\n }\n}\n\n/**\n * Gets parameters for retrieving a role, this is a utility function for the getDocParams function.\n */\nexport function getRoleParams(roleId?: string | null, otherProps = {}) {\n return getDocParams(DocumentType.ROLE, roleId, otherProps)\n}\n\nexport function getStartEndKeyURL(baseKey: any, tenantId?: string) {\n const tenancy = tenantId ? `${SEPARATOR}${tenantId}` : \"\"\n return `startkey=\"${baseKey}${tenancy}\"&endkey=\"${baseKey}${tenancy}${UNICODE_MAX}\"`\n}\n\n/**\n * Gets parameters for retrieving automations, this is a utility function for the getDocParams function.\n */\nexport const getPluginParams = (pluginId?: string | null, otherProps = {}) => {\n return getDocParams(DocumentType.PLUGIN, pluginId, otherProps)\n}\n", "import {\n DeprecatedViews,\n DocumentType,\n SEPARATOR,\n StaticDatabases,\n ViewName,\n} from \"../constants\"\nimport { getGlobalDB } from \"../context\"\nimport { doWithDB } from \"./\"\nimport { AllDocsResponse, Database, DatabaseQueryOpts } from \"@budibase/types\"\nimport env from \"../environment\"\n\nconst DESIGN_DB = \"_design/database\"\n\nfunction DesignDoc() {\n return {\n _id: DESIGN_DB,\n // view collation information, read before writing any complex views:\n // https://docs.couchdb.org/en/master/ddocs/views/collation.html#collation-specification\n views: {},\n }\n}\n\ninterface DesignDocument {\n views: any\n}\n\nasync function removeDeprecated(db: Database, viewName: ViewName) {\n // @ts-ignore\n if (!DeprecatedViews[viewName]) {\n return\n }\n try {\n const designDoc = await db.get<DesignDocument>(DESIGN_DB)\n // @ts-ignore\n for (let deprecatedNames of DeprecatedViews[viewName]) {\n delete designDoc.views[deprecatedNames]\n }\n await db.put(designDoc)\n } catch (err) {\n // doesn't exist, ignore\n }\n}\n\nexport async function createView(\n db: any,\n viewJs: string,\n viewName: string\n): Promise<void> {\n let designDoc\n try {\n designDoc = (await db.get(DESIGN_DB)) as DesignDocument\n } catch (err) {\n // no design doc, make one\n designDoc = DesignDoc()\n }\n const view = {\n map: viewJs,\n }\n designDoc.views = {\n ...designDoc.views,\n [viewName]: view,\n }\n try {\n await db.put(designDoc)\n } catch (err: any) {\n if (err.status === 409) {\n return await createView(db, viewJs, viewName)\n } else {\n throw err\n }\n }\n}\n\nexport const createNewUserEmailView = async () => {\n const db = getGlobalDB()\n const viewJs = `function(doc) {\n if (doc._id.startsWith(\"${DocumentType.USER}${SEPARATOR}\")) {\n emit(doc.email.toLowerCase(), doc._id)\n }\n }`\n await createView(db, viewJs, ViewName.USER_BY_EMAIL)\n}\n\nexport const createUserAppView = async () => {\n const db = getGlobalDB()\n const viewJs = `function(doc) {\n if (doc._id.startsWith(\"${DocumentType.USER}${SEPARATOR}\") && doc.roles) {\n for (let prodAppId of Object.keys(doc.roles)) {\n let emitted = prodAppId + \"${SEPARATOR}\" + doc._id\n emit(emitted, null)\n }\n }\n }`\n await createView(db, viewJs, ViewName.USER_BY_APP)\n}\n\nexport const createApiKeyView = async () => {\n const db = getGlobalDB()\n const viewJs = `function(doc) {\n if (doc._id.startsWith(\"${DocumentType.DEV_INFO}\") && doc.apiKey) {\n emit(doc.apiKey, doc.userId)\n }\n }`\n await createView(db, viewJs, ViewName.BY_API_KEY)\n}\n\nexport const createUserBuildersView = async () => {\n const db = getGlobalDB()\n const viewJs = `function(doc) {\n if (doc.builder && doc.builder.global === true) {\n emit(doc._id, doc._id)\n }\n }`\n await createView(db, viewJs, ViewName.USER_BY_BUILDERS)\n}\n\nexport interface QueryViewOptions {\n arrayResponse?: boolean\n}\n\nexport async function queryViewRaw<T>(\n viewName: ViewName,\n params: DatabaseQueryOpts,\n db: Database,\n createFunc: any,\n opts?: QueryViewOptions\n): Promise<AllDocsResponse<T>> {\n try {\n const response = await db.query<T>(`database/${viewName}`, params)\n // await to catch error\n return response\n } catch (err: any) {\n const pouchNotFound = err && err.name === \"not_found\"\n const couchNotFound = err && err.status === 404\n if (pouchNotFound || couchNotFound) {\n await removeDeprecated(db, viewName)\n await createFunc()\n return queryViewRaw(viewName, params, db, createFunc, opts)\n } else if (err.status === 409) {\n // can happen when multiple queries occur at once, view couldn't be created\n // other design docs being updated, re-run\n return queryViewRaw(viewName, params, db, createFunc, opts)\n } else {\n throw err\n }\n }\n}\n\nexport const queryView = async <T>(\n viewName: ViewName,\n params: DatabaseQueryOpts,\n db: Database,\n createFunc: any,\n opts?: QueryViewOptions\n): Promise<T[] | T | undefined> => {\n const response = await queryViewRaw<T>(viewName, params, db, createFunc, opts)\n const rows = response.rows\n const docs = rows.map((row: any) =>\n params.include_docs ? row.doc : row.value\n )\n\n // if arrayResponse has been requested, always return array regardless of length\n if (opts?.arrayResponse) {\n return docs as T[]\n } else {\n // return the single document if there is only one\n return docs.length <= 1 ? (docs[0] as T) : (docs as T[])\n }\n}\n\n// PLATFORM\n\nasync function createPlatformView(viewJs: string, viewName: ViewName) {\n try {\n await doWithDB(StaticDatabases.PLATFORM_INFO.name, async (db: Database) => {\n await createView(db, viewJs, viewName)\n })\n } catch (e: any) {\n if (e.status === 409 && env.isTest()) {\n // multiple tests can try to initialise platforms views\n // at once - safe to exit on conflict\n return\n }\n throw e\n }\n}\n\nexport const createPlatformAccountEmailView = async () => {\n const viewJs = `function(doc) {\n if (doc._id.startsWith(\"${DocumentType.ACCOUNT_METADATA}${SEPARATOR}\")) {\n emit(doc.email.toLowerCase(), doc._id)\n }\n }`\n await createPlatformView(viewJs, ViewName.ACCOUNT_BY_EMAIL)\n}\n\nexport const createPlatformUserView = async () => {\n const viewJs = `function(doc) {\n if (doc.tenantId) {\n emit(doc._id.toLowerCase(), doc._id)\n }\n }`\n await createPlatformView(viewJs, ViewName.PLATFORM_USERS_LOWERCASE)\n}\n\nexport const queryPlatformView = async <T>(\n viewName: ViewName,\n params: DatabaseQueryOpts,\n opts?: QueryViewOptions\n): Promise<T[] | T | undefined> => {\n const CreateFuncByName: any = {\n [ViewName.ACCOUNT_BY_EMAIL]: createPlatformAccountEmailView,\n [ViewName.PLATFORM_USERS_LOWERCASE]: createPlatformUserView,\n }\n\n return doWithDB(StaticDatabases.PLATFORM_INFO.name, async (db: Database) => {\n const createFn = CreateFuncByName[viewName]\n return queryView(viewName, params, db, createFn, opts)\n })\n}\n\nconst CreateFuncByName: any = {\n [ViewName.USER_BY_EMAIL]: createNewUserEmailView,\n [ViewName.BY_API_KEY]: createApiKeyView,\n [ViewName.USER_BY_BUILDERS]: createUserBuildersView,\n [ViewName.USER_BY_APP]: createUserAppView,\n}\n\nexport const queryGlobalView = async <T>(\n viewName: ViewName,\n params: DatabaseQueryOpts,\n db?: Database,\n opts?: QueryViewOptions\n): Promise<T[] | T | undefined> => {\n // can pass DB in if working with something specific\n if (!db) {\n db = getGlobalDB()\n }\n const createFn = CreateFuncByName[viewName]\n return queryView(viewName, params, db!, createFn, opts)\n}\n\nexport async function queryGlobalViewRaw<T>(\n viewName: ViewName,\n params: DatabaseQueryOpts,\n opts?: QueryViewOptions\n) {\n const db = getGlobalDB()\n const createFn = CreateFuncByName[viewName]\n return queryViewRaw<T>(viewName, params, db, createFn, opts)\n}\n", "import { getPouchDB, closePouchDB } from \"./couch\"\nimport { DocumentType } from \"../constants\"\n\nclass Replication {\n source: any\n target: any\n replication: any\n\n /**\n *\n * @param {String} source - the DB you want to replicate or rollback to\n * @param {String} target - the DB you want to replicate to, or rollback from\n */\n constructor({ source, target }: any) {\n this.source = getPouchDB(source)\n this.target = getPouchDB(target)\n }\n\n close() {\n return Promise.all([closePouchDB(this.source), closePouchDB(this.target)])\n }\n\n promisify(operation: any, opts = {}) {\n return new Promise(resolve => {\n operation(this.target, opts)\n .on(\"denied\", function (err: any) {\n // a document failed to replicate (e.g. due to permissions)\n throw new Error(`Denied: Document failed to replicate ${err}`)\n })\n .on(\"complete\", function (info: any) {\n return resolve(info)\n })\n .on(\"error\", function (err: any) {\n throw new Error(`Replication Error: ${err}`)\n })\n })\n }\n\n /**\n * Two way replication operation, intended to be promise based.\n * @param {Object} opts - PouchDB replication options\n */\n sync(opts = {}) {\n this.replication = this.promisify(this.source.sync, opts)\n return this.replication\n }\n\n /**\n * One way replication operation, intended to be promise based.\n * @param {Object} opts - PouchDB replication options\n */\n replicate(opts = {}) {\n this.replication = this.promisify(this.source.replicate.to, opts)\n return this.replication\n }\n\n appReplicateOpts() {\n return {\n filter: (doc: any) => {\n return doc._id !== DocumentType.APP_METADATA\n },\n }\n }\n\n /**\n * Rollback the target DB back to the state of the source DB\n */\n async rollback() {\n await this.target.destroy()\n // Recreate the DB again\n this.target = getPouchDB(this.target.name)\n // take the opportunity to remove deleted tombstones\n await this.replicate()\n }\n\n cancel() {\n this.replication.cancel()\n }\n}\n\nexport default Replication\n", "import fetch from \"node-fetch\"\nimport { getCouchInfo } from \"./couch\"\nimport { SearchFilters, Row } from \"@budibase/types\"\nimport { createUserIndex } from \"./searchIndexes/searchIndexes\"\n\nconst QUERY_START_REGEX = /\\d[0-9]*:/g\n\ninterface SearchResponse<T> {\n rows: T[] | any[]\n bookmark?: string\n totalRows: number\n}\n\ninterface PaginatedSearchResponse<T> extends SearchResponse<T> {\n hasNextPage: boolean\n}\n\nexport type SearchParams<T> = {\n tableId?: string\n sort?: string\n sortOrder?: string\n sortType?: string\n limit?: number\n bookmark?: string\n version?: string\n indexer?: () => Promise<any>\n disableEscaping?: boolean\n rows?: T | Row[]\n}\n\nexport function removeKeyNumbering(key: any): string {\n if (typeof key === \"string\" && key.match(QUERY_START_REGEX) != null) {\n const parts = key.split(\":\")\n // remove the number\n parts.shift()\n return parts.join(\":\")\n } else {\n return key\n }\n}\n\n/**\n * Class to build lucene query URLs.\n * Optionally takes a base lucene query object.\n */\nexport class QueryBuilder<T> {\n #dbName: string\n #index: string\n #query: SearchFilters\n #limit: number\n #sort?: string\n #bookmark?: string\n #sortOrder: string\n #sortType: string\n #includeDocs: boolean\n #version?: string\n #indexBuilder?: () => Promise<any>\n #noEscaping = false\n #skip?: number\n\n static readonly maxLimit = 200\n\n constructor(dbName: string, index: string, base?: SearchFilters) {\n this.#dbName = dbName\n this.#index = index\n this.#query = {\n allOr: false,\n string: {},\n fuzzy: {},\n range: {},\n equal: {},\n notEqual: {},\n empty: {},\n notEmpty: {},\n oneOf: {},\n contains: {},\n notContains: {},\n containsAny: {},\n ...base,\n }\n this.#limit = 50\n this.#sortOrder = \"ascending\"\n this.#sortType = \"string\"\n this.#includeDocs = true\n }\n\n disableEscaping() {\n this.#noEscaping = true\n return this\n }\n\n setIndexBuilder(builderFn: () => Promise<any>) {\n this.#indexBuilder = builderFn\n return this\n }\n\n setVersion(version?: string) {\n if (version != null) {\n this.#version = version\n }\n return this\n }\n\n setTable(tableId: string) {\n this.#query.equal!.tableId = tableId\n return this\n }\n\n setLimit(limit?: number) {\n if (limit != null) {\n this.#limit = limit\n }\n return this\n }\n\n setSort(sort?: string) {\n if (sort != null) {\n this.#sort = sort\n }\n return this\n }\n\n setSortOrder(sortOrder?: string) {\n if (sortOrder != null) {\n this.#sortOrder = sortOrder\n }\n return this\n }\n\n setSortType(sortType?: string) {\n if (sortType != null) {\n this.#sortType = sortType\n }\n return this\n }\n\n setBookmark(bookmark?: string) {\n if (bookmark != null) {\n this.#bookmark = bookmark\n }\n return this\n }\n\n setSkip(skip: number | undefined) {\n this.#skip = skip\n return this\n }\n\n excludeDocs() {\n this.#includeDocs = false\n return this\n }\n\n includeDocs() {\n this.#includeDocs = true\n return this\n }\n\n addString(key: string, partial: string) {\n this.#query.string![key] = partial\n return this\n }\n\n addFuzzy(key: string, fuzzy: string) {\n this.#query.fuzzy![key] = fuzzy\n return this\n }\n\n addRange(key: string, low: string | number, high: string | number) {\n this.#query.range![key] = {\n low,\n high,\n }\n return this\n }\n\n addEqual(key: string, value: any) {\n this.#query.equal![key] = value\n return this\n }\n\n addNotEqual(key: string, value: any) {\n this.#query.notEqual![key] = value\n return this\n }\n\n addEmpty(key: string, value: any) {\n this.#query.empty![key] = value\n return this\n }\n\n addNotEmpty(key: string, value: any) {\n this.#query.notEmpty![key] = value\n return this\n }\n\n addOneOf(key: string, value: any) {\n this.#query.oneOf![key] = value\n return this\n }\n\n addContains(key: string, value: any) {\n this.#query.contains![key] = value\n return this\n }\n\n addNotContains(key: string, value: any) {\n this.#query.notContains![key] = value\n return this\n }\n\n addContainsAny(key: string, value: any) {\n this.#query.containsAny![key] = value\n return this\n }\n\n setAllOr() {\n this.#query.allOr = true\n }\n\n handleSpaces(input: string) {\n if (this.#noEscaping) {\n return input\n } else {\n return input.replace(/ /g, \"_\")\n }\n }\n\n /**\n * Preprocesses a value before going into a lucene search.\n * Transforms strings to lowercase and wraps strings and bools in quotes.\n * @param value The value to process\n * @param options The preprocess options\n * @returns {string|*}\n */\n preprocess(value: any, { escape, lowercase, wrap, type }: any = {}) {\n const hasVersion = !!this.#version\n // Determine if type needs wrapped\n const originalType = typeof value\n // Convert to lowercase\n if (value && lowercase) {\n value = value.toLowerCase ? value.toLowerCase() : value\n }\n // Escape characters\n if (!this.#noEscaping && escape && originalType === \"string\") {\n value = `${value}`.replace(/[ \\/#+\\-&|!(){}\\]^\"~*?:\\\\]/g, \"\\\\$&\")\n }\n\n // Wrap in quotes\n if (originalType === \"string\" && !isNaN(value) && !type) {\n value = `\"${value}\"`\n } else if (hasVersion && wrap) {\n value = originalType === \"number\" ? value : `\"${value}\"`\n }\n return value\n }\n\n isMultiCondition() {\n let count = 0\n for (let filters of Object.values(this.#query)) {\n // not contains is one massive filter in allOr mode\n if (typeof filters === \"object\") {\n count += Object.keys(filters).length\n }\n }\n return count > 1\n }\n\n compressFilters(filters: Record<string, string[]>) {\n const compressed: typeof filters = {}\n for (let key of Object.keys(filters)) {\n const finalKey = removeKeyNumbering(key)\n if (compressed[finalKey]) {\n compressed[finalKey] = compressed[finalKey].concat(filters[key])\n } else {\n compressed[finalKey] = filters[key]\n }\n }\n // add prefixes back\n const final: typeof filters = {}\n let count = 1\n for (let [key, value] of Object.entries(compressed)) {\n final[`${count++}:${key}`] = value\n }\n return final\n }\n\n buildSearchQuery() {\n const builder = this\n let allOr = this.#query && this.#query.allOr\n let query = allOr ? \"\" : \"*:*\"\n const allPreProcessingOpts = { escape: true, lowercase: true, wrap: true }\n let tableId\n if (this.#query.equal!.tableId) {\n tableId = this.#query.equal!.tableId\n delete this.#query.equal!.tableId\n }\n\n const equal = (key: string, value: any) => {\n // 0 evaluates to false, which means we would return all rows if we don't check it\n if (!value && value !== 0) {\n return null\n }\n return `${key}:${builder.preprocess(value, allPreProcessingOpts)}`\n }\n\n const contains = (key: string, value: any, mode = \"AND\") => {\n if (Array.isArray(value) && value.length === 0) {\n return null\n }\n if (!Array.isArray(value)) {\n return `${key}:${value}`\n }\n let statement = `${builder.preprocess(value[0], { escape: true })}`\n for (let i = 1; i < value.length; i++) {\n statement += ` ${mode} ${builder.preprocess(value[i], {\n escape: true,\n })}`\n }\n return `${key}:(${statement})`\n }\n\n const fuzzy = (key: string, value: any) => {\n if (!value) {\n return null\n }\n value = builder.preprocess(value, {\n escape: true,\n lowercase: true,\n type: \"fuzzy\",\n })\n return `${key}:/.*${value}.*/`\n }\n\n const notContains = (key: string, value: any) => {\n const allPrefix = allOr ? \"*:* AND \" : \"\"\n const mode = allOr ? \"AND\" : undefined\n return allPrefix + \"NOT \" + contains(key, value, mode)\n }\n\n const containsAny = (key: string, value: any) => {\n return contains(key, value, \"OR\")\n }\n\n const oneOf = (key: string, value: any) => {\n if (!Array.isArray(value)) {\n if (typeof value === \"string\") {\n value = value.split(\",\")\n } else {\n return \"\"\n }\n }\n let orStatement = `${builder.preprocess(value[0], allPreProcessingOpts)}`\n for (let i = 1; i < value.length; i++) {\n orStatement += ` OR ${builder.preprocess(\n value[i],\n allPreProcessingOpts\n )}`\n }\n return `${key}:(${orStatement})`\n }\n\n function build(\n structure: any,\n queryFn: (key: string, value: any) => string | null,\n opts?: { returnBuilt?: boolean; mode?: string }\n ) {\n let built = \"\"\n for (let [key, value] of Object.entries(structure)) {\n // check for new format - remove numbering if needed\n key = removeKeyNumbering(key)\n key = builder.preprocess(builder.handleSpaces(key), {\n escape: true,\n })\n let expression = queryFn(key, value)\n if (expression == null) {\n continue\n }\n if (built.length > 0 || query.length > 0) {\n const mode = opts?.mode ? opts.mode : allOr ? \"OR\" : \"AND\"\n built += ` ${mode} `\n }\n built += expression\n }\n if (opts?.returnBuilt) {\n return built\n } else {\n query += built\n }\n }\n\n // Construct the actual lucene search query string from JSON structure\n if (this.#query.string) {\n build(this.#query.string, (key: string, value: any) => {\n if (!value) {\n return null\n }\n value = builder.preprocess(value, {\n escape: true,\n lowercase: true,\n type: \"string\",\n })\n return `${key}:${value}*`\n })\n }\n if (this.#query.range) {\n build(this.#query.range, (key: string, value: any) => {\n if (!value) {\n return null\n }\n if (value.low == null || value.low === \"\") {\n return null\n }\n if (value.high == null || value.high === \"\") {\n return null\n }\n const low = builder.preprocess(value.low, allPreProcessingOpts)\n const high = builder.preprocess(value.high, allPreProcessingOpts)\n return `${key}:[${low} TO ${high}]`\n })\n }\n if (this.#query.fuzzy) {\n build(this.#query.fuzzy, fuzzy)\n }\n if (this.#query.equal) {\n build(this.#query.equal, equal)\n }\n if (this.#query.notEqual) {\n build(this.#query.notEqual, (key: string, value: any) => {\n if (!value) {\n return null\n }\n return `!${key}:${builder.preprocess(value, allPreProcessingOpts)}`\n })\n }\n if (this.#query.empty) {\n build(this.#query.empty, (key: string) => `(*:* -${key}:[\"\" TO *])`)\n }\n if (this.#query.notEmpty) {\n build(this.#query.notEmpty, (key: string) => `${key}:[\"\" TO *]`)\n }\n if (this.#query.oneOf) {\n build(this.#query.oneOf, oneOf)\n }\n if (this.#query.contains) {\n build(this.#query.contains, contains)\n }\n if (this.#query.notContains) {\n build(this.compressFilters(this.#query.notContains), notContains)\n }\n if (this.#query.containsAny) {\n build(this.#query.containsAny, containsAny)\n }\n // make sure table ID is always added as an AND\n if (tableId) {\n query = this.isMultiCondition() ? `(${query})` : query\n allOr = false\n build({ tableId }, equal)\n }\n return query\n }\n\n buildSearchBody() {\n let body: any = {\n q: this.buildSearchQuery(),\n limit: Math.min(this.#limit, QueryBuilder.maxLimit),\n include_docs: this.#includeDocs,\n }\n if (this.#bookmark) {\n body.bookmark = this.#bookmark\n }\n if (this.#sort) {\n const order = this.#sortOrder === \"descending\" ? \"-\" : \"\"\n const type = `<${this.#sortType}>`\n body.sort = `${order}${this.handleSpaces(this.#sort)}${type}`\n }\n return body\n }\n\n async run() {\n if (this.#skip) {\n await this.#skipItems(this.#skip)\n }\n return await this.#execute()\n }\n\n /**\n * Lucene queries do not support pagination and use bookmarks instead.\n * For the given builder, walk through pages using bookmarks until the desired\n * page has been met.\n */\n async #skipItems(skip: number) {\n // Lucene does not support pagination.\n // Handle pagination by finding the right bookmark\n const prevIncludeDocs = this.#includeDocs\n const prevLimit = this.#limit\n\n this.excludeDocs()\n let skipRemaining = skip\n let iterationFetched = 0\n do {\n const toSkip = Math.min(QueryBuilder.maxLimit, skipRemaining)\n this.setLimit(toSkip)\n const { bookmark, rows } = await this.#execute()\n this.setBookmark(bookmark)\n iterationFetched = rows.length\n skipRemaining -= rows.length\n } while (skipRemaining > 0 && iterationFetched > 0)\n\n this.#includeDocs = prevIncludeDocs\n this.#limit = prevLimit\n }\n\n async #execute() {\n const { url, cookie } = getCouchInfo()\n const fullPath = `${url}/${this.#dbName}/_design/database/_search/${\n this.#index\n }`\n const body = this.buildSearchBody()\n try {\n return await runQuery<T>(fullPath, body, cookie)\n } catch (err: any) {\n if (err.status === 404 && this.#indexBuilder) {\n await this.#indexBuilder()\n return await runQuery<T>(fullPath, body, cookie)\n } else {\n throw err\n }\n }\n }\n}\n\n/**\n * Executes a lucene search query.\n * @param url The query URL\n * @param body The request body defining search criteria\n * @param cookie The auth cookie for CouchDB\n * @returns {Promise<{rows: []}>}\n */\nasync function runQuery<T>(\n url: string,\n body: any,\n cookie: string\n): Promise<SearchResponse<T>> {\n const response = await fetch(url, {\n body: JSON.stringify(body),\n method: \"POST\",\n headers: {\n Authorization: cookie,\n },\n })\n\n if (response.status === 404) {\n throw response\n }\n const json = await response.json()\n\n let output: SearchResponse<T> = {\n rows: [],\n totalRows: 0,\n }\n if (json.rows != null && json.rows.length > 0) {\n output.rows = json.rows.map((row: any) => row.doc)\n }\n if (json.bookmark) {\n output.bookmark = json.bookmark\n }\n if (json.total_rows) {\n output.totalRows = json.total_rows\n }\n return output\n}\n\n/**\n * Gets round the fixed limit of 200 results from a query by fetching as many\n * pages as required and concatenating the results. This recursively operates\n * until enough results have been found.\n * @param dbName {string} Which database to run a lucene query on\n * @param index {string} Which search index to utilise\n * @param query {object} The JSON query structure\n * @param params {object} The search params including:\n * tableId {string} The table ID to search\n * sort {string} The sort column\n * sortOrder {string} The sort order (\"ascending\" or \"descending\")\n * sortType {string} Whether to treat sortable values as strings or\n * numbers. (\"string\" or \"number\")\n * limit {number} The number of results to fetch\n * bookmark {string|null} Current bookmark in the recursive search\n * rows {array|null} Current results in the recursive search\n * @returns {Promise<*[]|*>}\n */\nasync function recursiveSearch<T>(\n dbName: string,\n index: string,\n query: any,\n params: any\n): Promise<any> {\n const bookmark = params.bookmark\n const rows = params.rows || []\n if (rows.length >= params.limit) {\n return rows\n }\n let pageSize = QueryBuilder.maxLimit\n if (rows.length > params.limit - QueryBuilder.maxLimit) {\n pageSize = params.limit - rows.length\n }\n const page = await new QueryBuilder<T>(dbName, index, query)\n .setVersion(params.version)\n .setTable(params.tableId)\n .setBookmark(bookmark)\n .setLimit(pageSize)\n .setSort(params.sort)\n .setSortOrder(params.sortOrder)\n .setSortType(params.sortType)\n .run()\n if (!page.rows.length) {\n return rows\n }\n if (page.rows.length < QueryBuilder.maxLimit) {\n return [...rows, ...page.rows]\n }\n const newParams = {\n ...params,\n bookmark: page.bookmark,\n rows: [...rows, ...page.rows],\n }\n return await recursiveSearch(dbName, index, query, newParams)\n}\n\n/**\n * Performs a paginated search. A bookmark will be returned to allow the next\n * page to be fetched. There is a max limit off 200 results per page in a\n * paginated search.\n * @param dbName {string} Which database to run a lucene query on\n * @param index {string} Which search index to utilise\n * @param query {object} The JSON query structure\n * @param params {object} The search params including:\n * tableId {string} The table ID to search\n * sort {string} The sort column\n * sortOrder {string} The sort order (\"ascending\" or \"descending\")\n * sortType {string} Whether to treat sortable values as strings or\n * numbers. (\"string\" or \"number\")\n * limit {number} The desired page size\n * bookmark {string} The bookmark to resume from\n * @returns {Promise<{hasNextPage: boolean, rows: *[]}>}\n */\nexport async function paginatedSearch<T>(\n dbName: string,\n index: string,\n query: SearchFilters,\n params: SearchParams<T>\n) {\n let limit = params.limit\n if (limit == null || isNaN(limit) || limit < 0) {\n limit = 50\n }\n limit = Math.min(limit, QueryBuilder.maxLimit)\n const search = new QueryBuilder<T>(dbName, index, query)\n if (params.version) {\n search.setVersion(params.version)\n }\n if (params.tableId) {\n search.setTable(params.tableId)\n }\n if (params.sort) {\n search\n .setSort(params.sort)\n .setSortOrder(params.sortOrder)\n .setSortType(params.sortType)\n }\n if (params.indexer) {\n search.setIndexBuilder(params.indexer)\n }\n if (params.disableEscaping) {\n search.disableEscaping()\n }\n const searchResults = await search\n .setBookmark(params.bookmark)\n .setLimit(limit)\n .run()\n\n // Try fetching 1 row in the next page to see if another page of results\n // exists or not\n search.setBookmark(searchResults.bookmark).setLimit(1)\n if (params.tableId) {\n search.setTable(params.tableId)\n }\n const nextResults = await search.run()\n\n return {\n ...searchResults,\n hasNextPage: nextResults.rows && nextResults.rows.length > 0,\n }\n}\n\n/**\n * Performs a full search, fetching multiple pages if required to return the\n * desired amount of results. There is a limit of 1000 results to avoid\n * heavy performance hits, and to avoid client components breaking from\n * handling too much data.\n * @param dbName {string} Which database to run a lucene query on\n * @param index {string} Which search index to utilise\n * @param query {object} The JSON query structure\n * @param params {object} The search params including:\n * tableId {string} The table ID to search\n * sort {string} The sort column\n * sortOrder {string} The sort order (\"ascending\" or \"descending\")\n * sortType {string} Whether to treat sortable values as strings or\n * numbers. (\"string\" or \"number\")\n * limit {number} The desired number of results\n * @returns {Promise<{rows: *}>}\n */\nexport async function fullSearch<T>(\n dbName: string,\n index: string,\n query: SearchFilters,\n params: SearchParams<T>\n) {\n let limit = params.limit\n if (limit == null || isNaN(limit) || limit < 0) {\n limit = 1000\n }\n params.limit = Math.min(limit, 1000)\n const rows = await recursiveSearch<T>(dbName, index, query, params)\n return { rows }\n}\n", "export * from \"./searchIndexes\"\n", "import { User, SearchIndex } from \"@budibase/types\"\nimport { getGlobalDB } from \"../../context\"\n\nexport async function createUserIndex() {\n const db = getGlobalDB()\n let designDoc\n try {\n designDoc = await db.get(\"_design/database\")\n } catch (err: any) {\n if (err.status === 404) {\n designDoc = { _id: \"_design/database\" }\n }\n }\n\n const fn = function (user: User) {\n if (user._id && !user._id.startsWith(\"us_\")) {\n return\n }\n const ignoredFields = [\n \"_id\",\n \"_rev\",\n \"password\",\n \"account\",\n \"license\",\n \"budibaseAccess\",\n \"accountPortalAccess\",\n \"csrfToken\",\n ]\n\n function idx(input: Record<string, any>, prev?: string) {\n for (let key of Object.keys(input)) {\n if (ignoredFields.includes(key)) {\n continue\n }\n let idxKey = prev != null ? `${prev}.${key}` : key\n if (typeof input[key] === \"string\") {\n // eslint-disable-next-line no-undef\n // @ts-ignore\n index(idxKey, input[key].toLowerCase(), { facet: true })\n } else if (typeof input[key] !== \"object\") {\n // eslint-disable-next-line no-undef\n // @ts-ignore\n index(idxKey, input[key], { facet: true })\n } else {\n idx(input[key], idxKey)\n }\n }\n }\n idx(user)\n }\n\n designDoc.indexes = {\n [SearchIndex.USER]: {\n index: fn.toString(),\n analyzer: {\n default: \"keyword\",\n name: \"perfield\",\n },\n },\n }\n await db.put(designDoc)\n}\n", "import BaseCache from \"./base\"\nimport { getWritethroughClient } from \"../redis/init\"\nimport { logWarn } from \"../logging\"\nimport { Database, Document, LockName, LockType } from \"@budibase/types\"\nimport * as locks from \"../redis/redlockImpl\"\n\nconst DEFAULT_WRITE_RATE_MS = 10000\nlet CACHE: BaseCache | null = null\n\ninterface CacheItem {\n doc: any\n lastWrite: number\n}\n\nasync function getCache() {\n if (!CACHE) {\n const client = await getWritethroughClient()\n CACHE = new BaseCache(client)\n }\n return CACHE\n}\n\nfunction makeCacheKey(db: Database, key: string) {\n return db.name + key\n}\n\nfunction makeCacheItem(doc: any, lastWrite: number | null = null): CacheItem {\n return { doc, lastWrite: lastWrite || Date.now() }\n}\n\nasync function put(\n db: Database,\n doc: Document,\n writeRateMs: number = DEFAULT_WRITE_RATE_MS\n) {\n const cache = await getCache()\n const key = doc._id\n let cacheItem: CacheItem | undefined\n if (key) {\n cacheItem = await cache.get(makeCacheKey(db, key))\n }\n const updateDb = !cacheItem || cacheItem.lastWrite < Date.now() - writeRateMs\n let output = doc\n if (updateDb) {\n const lockResponse = await locks.doWithLock(\n {\n type: LockType.TRY_ONCE,\n name: LockName.PERSIST_WRITETHROUGH,\n resource: key,\n ttl: 15000,\n },\n async () => {\n const writeDb = async (toWrite: any) => {\n // doc should contain the _id and _rev\n const response = await db.put(toWrite, { force: true })\n output = {\n ...doc,\n _id: response.id,\n _rev: response.rev,\n }\n }\n try {\n await writeDb(doc)\n } catch (err: any) {\n if (err.status !== 409) {\n throw err\n } else {\n // Swallow 409s but log them\n logWarn(`Ignoring conflict in write-through cache`)\n }\n }\n }\n )\n\n if (!lockResponse.executed) {\n logWarn(`Ignoring redlock conflict in write-through cache`)\n }\n }\n // if we are updating the DB then need to set the lastWrite to now\n cacheItem = makeCacheItem(output, updateDb ? null : cacheItem?.lastWrite)\n if (output._id) {\n await cache.store(makeCacheKey(db, output._id), cacheItem)\n }\n return { ok: true, id: output._id, rev: output._rev }\n}\n\nasync function get(db: Database, id: string): Promise<any> {\n const cache = await getCache()\n const cacheKey = makeCacheKey(db, id)\n let cacheItem: CacheItem = await cache.get(cacheKey)\n if (!cacheItem) {\n const doc = await db.get(id)\n cacheItem = makeCacheItem(doc)\n await cache.store(cacheKey, cacheItem)\n }\n return cacheItem.doc\n}\n\nasync function remove(db: Database, docOrId: any, rev?: any): Promise<void> {\n const cache = await getCache()\n if (!docOrId) {\n throw new Error(\"No ID/Rev provided.\")\n }\n const id = typeof docOrId === \"string\" ? docOrId : docOrId._id\n rev = typeof docOrId === \"string\" ? rev : docOrId._rev\n try {\n await cache.delete(makeCacheKey(db, id))\n } finally {\n await db.remove(id, rev)\n }\n}\n\nexport class Writethrough {\n db: Database\n writeRateMs: number\n\n constructor(db: Database, writeRateMs: number = DEFAULT_WRITE_RATE_MS) {\n this.db = db\n this.writeRateMs = writeRateMs\n }\n\n async put(doc: any) {\n return put(this.db, doc, this.writeRateMs)\n }\n\n async get(id: string) {\n return get(this.db, id)\n }\n\n async remove(docOrId: any, rev?: any) {\n return remove(this.db, docOrId, rev)\n }\n}\n", "export * from \"./publishers\"\nexport * as processors from \"./processors\"\nexport * as analytics from \"./analytics\"\nexport { default as identification } from \"./identification\"\nexport * as backfillCache from \"./backfill\"\n\nimport { processors } from \"./processors\"\n\nexport function initAsyncEvents() {}\n\nexport const shutdown = () => {\n processors.shutdown()\n console.log(\"Events shutdown\")\n}\n", "import AnalyticsProcessor from \"./AnalyticsProcessor\"\nimport LoggingProcessor from \"./LoggingProcessor\"\nimport AuditLogsProcessor from \"./AuditLogsProcessor\"\nimport Processors from \"./Processors\"\nimport { AuditLogFn } from \"@budibase/types\"\n\nexport const analyticsProcessor = new AnalyticsProcessor()\nconst loggingProcessor = new LoggingProcessor()\nconst auditLogsProcessor = new AuditLogsProcessor()\n\nexport function init(auditingFn: AuditLogFn) {\n return AuditLogsProcessor.init(auditingFn)\n}\n\nexport const processors = new Processors([\n analyticsProcessor,\n loggingProcessor,\n auditLogsProcessor,\n])\n", "import { Event, Identity, Group, IdentityType } from \"@budibase/types\"\nimport { EventProcessor } from \"./types\"\nimport env from \"../../environment\"\nimport * as analytics from \"../analytics\"\nimport PosthogProcessor from \"./posthog\"\n\n/**\n * Events that are always captured.\n */\nconst EVENT_WHITELIST = [\n Event.INSTALLATION_VERSION_UPGRADED,\n Event.INSTALLATION_VERSION_DOWNGRADED,\n]\nconst IDENTITY_WHITELIST = [IdentityType.INSTALLATION, IdentityType.TENANT]\n\nexport default class AnalyticsProcessor implements EventProcessor {\n posthog: PosthogProcessor | undefined\n\n constructor() {\n if (env.POSTHOG_TOKEN && !env.isTest()) {\n this.posthog = new PosthogProcessor(env.POSTHOG_TOKEN)\n }\n }\n\n async processEvent(\n event: Event,\n identity: Identity,\n properties: any,\n timestamp?: string | number\n ): Promise<void> {\n if (!EVENT_WHITELIST.includes(event) && !(await analytics.enabled())) {\n return\n }\n if (this.posthog) {\n await this.posthog.processEvent(event, identity, properties, timestamp)\n }\n }\n\n async identify(identity: Identity, timestamp?: string | number) {\n // Group indentifications (tenant and installation) always on\n if (\n !IDENTITY_WHITELIST.includes(identity.type) &&\n !(await analytics.enabled())\n ) {\n return\n }\n if (this.posthog) {\n await this.posthog.identify(identity, timestamp)\n }\n }\n\n async identifyGroup(group: Group, timestamp?: string | number) {\n // Group indentifications (tenant and installation) always on\n if (this.posthog) {\n await this.posthog.identifyGroup(group, timestamp)\n }\n }\n\n shutdown() {\n if (this.posthog) {\n this.posthog.shutdown()\n }\n }\n}\n", "import * as configs from \"../configs\"\n\n// wrapper utility function\nexport const enabled = async () => {\n return configs.analyticsEnabled()\n}\n", "import PostHog from \"posthog-node\"\nimport { Event, Identity, Group, BaseEvent } from \"@budibase/types\"\nimport { EventProcessor } from \"../types\"\nimport env from \"../../../environment\"\nimport * as context from \"../../../context\"\nimport * as rateLimiting from \"./rateLimiting\"\n\nconst EXCLUDED_EVENTS: Event[] = [\n Event.USER_UPDATED,\n Event.EMAIL_SMTP_UPDATED,\n Event.AUTH_SSO_UPDATED,\n Event.APP_UPDATED,\n Event.ROLE_UPDATED,\n Event.DATASOURCE_UPDATED,\n Event.QUERY_UPDATED,\n Event.TABLE_UPDATED,\n Event.VIEW_UPDATED,\n Event.VIEW_FILTER_UPDATED,\n Event.VIEW_CALCULATION_UPDATED,\n Event.AUTOMATION_TRIGGER_UPDATED,\n Event.USER_GROUP_UPDATED,\n]\n\nexport default class PosthogProcessor implements EventProcessor {\n posthog: PostHog\n\n constructor(token: string | undefined) {\n if (!token) {\n throw new Error(\"Posthog token is not defined\")\n }\n this.posthog = new PostHog(token)\n }\n\n async processEvent(\n event: Event,\n identity: Identity,\n properties: BaseEvent,\n timestamp?: string | number\n ): Promise<void> {\n // don't send excluded events\n if (EXCLUDED_EVENTS.includes(event)) {\n return\n }\n\n if (await rateLimiting.limited(event)) {\n return\n }\n\n properties = this.clearPIIProperties(properties)\n\n properties.version = env.VERSION\n properties.service = env.SERVICE\n properties.environment = identity.environment\n properties.hosting = identity.hosting\n\n const appId = context.getAppId()\n if (appId) {\n properties.appId = appId\n }\n\n const payload: any = { distinctId: identity.id, event, properties }\n\n if (timestamp) {\n payload.timestamp = new Date(timestamp)\n }\n\n // add groups to the event\n if (identity.installationId || identity.tenantId) {\n payload.groups = {}\n if (identity.installationId) {\n payload.groups.installation = identity.installationId\n payload.properties.installationId = identity.installationId\n }\n if (identity.tenantId) {\n payload.groups.tenant = identity.tenantId\n payload.properties.tenantId = identity.tenantId\n }\n }\n\n this.posthog.capture(payload)\n }\n\n clearPIIProperties(properties: any) {\n if (properties.email) {\n delete properties.email\n }\n if (properties.audited) {\n delete properties.audited\n }\n return properties\n }\n\n async identify(identity: Identity, timestamp?: string | number) {\n const payload: any = { distinctId: identity.id, properties: identity }\n if (timestamp) {\n payload.timestamp = new Date(timestamp)\n }\n this.posthog.identify(payload)\n }\n\n async identifyGroup(group: Group, timestamp?: string | number) {\n const payload: any = {\n distinctId: group.id,\n groupType: group.type,\n groupKey: group.id,\n properties: group,\n }\n\n if (timestamp) {\n payload.timestamp = new Date(timestamp)\n }\n this.posthog.groupIdentify(payload)\n }\n\n shutdown() {\n this.posthog.shutdown()\n }\n}\n", "import { Event } from \"@budibase/types\"\nimport { CacheKey, TTL } from \"../../../cache/generic\"\nimport * as cache from \"../../../cache/generic\"\nimport * as context from \"../../../context\"\n\ntype RateLimitedEvent =\n | Event.SERVED_BUILDER\n | Event.SERVED_APP_PREVIEW\n | Event.SERVED_APP\n\nconst isRateLimited = (event: Event): event is RateLimitedEvent => {\n return (\n event === Event.SERVED_BUILDER ||\n event === Event.SERVED_APP_PREVIEW ||\n event === Event.SERVED_APP\n )\n}\n\nconst isPerApp = (event: RateLimitedEvent) => {\n return event === Event.SERVED_APP_PREVIEW || event === Event.SERVED_APP\n}\n\ninterface EventProperties {\n timestamp: number\n}\n\nenum RateLimit {\n CALENDAR_DAY = \"calendarDay\",\n}\n\nconst RATE_LIMITS = {\n [Event.SERVED_APP]: RateLimit.CALENDAR_DAY,\n [Event.SERVED_APP_PREVIEW]: RateLimit.CALENDAR_DAY,\n [Event.SERVED_BUILDER]: RateLimit.CALENDAR_DAY,\n}\n\n/**\n * Check if this event should be sent right now\n * Return false to signal the event SHOULD be sent\n * Return true to signal the event should NOT be sent\n */\nexport const limited = async (event: Event): Promise<boolean> => {\n // not a rate limited event -- send\n if (!isRateLimited(event)) {\n return false\n }\n\n const cachedEvent = await readEvent(event)\n if (cachedEvent) {\n const timestamp = new Date(cachedEvent.timestamp)\n const limit = RATE_LIMITS[event]\n switch (limit) {\n case RateLimit.CALENDAR_DAY: {\n // get midnight at the start of the next day for the timestamp\n timestamp.setDate(timestamp.getDate() + 1)\n timestamp.setHours(0, 0, 0, 0)\n\n // if we have passed the threshold into the next day\n if (Date.now() > timestamp.getTime()) {\n // update the timestamp in the event -- send\n await recordEvent(event, { timestamp: Date.now() })\n return false\n } else {\n // still within the limited period -- don't send\n return true\n }\n }\n }\n } else {\n // no event present i.e. expired -- send\n await recordEvent(event, { timestamp: Date.now() })\n return false\n }\n}\n\nconst eventKey = (event: RateLimitedEvent) => {\n let key = `${CacheKey.EVENTS_RATE_LIMIT}:${event}`\n if (isPerApp(event)) {\n key = key + \":\" + context.getAppId()\n }\n return key\n}\n\nconst readEvent = async (\n event: RateLimitedEvent\n): Promise<EventProperties | undefined> => {\n const key = eventKey(event)\n const result = await cache.get(key)\n return result as EventProperties\n}\n\nconst recordEvent = async (\n event: RateLimitedEvent,\n properties: EventProperties\n) => {\n const key = eventKey(event)\n const limit = RATE_LIMITS[event]\n let ttl\n switch (limit) {\n case RateLimit.CALENDAR_DAY: {\n ttl = TTL.ONE_DAY\n }\n }\n\n await cache.store(key, properties, ttl)\n}\n", "import PosthogProcessor from \"./PosthogProcessor\"\nexport default PosthogProcessor\n", "import { Event, Identity, Group } from \"@budibase/types\"\nimport { EventProcessor } from \"./types\"\nimport env from \"../../environment\"\n\nconst skipLogging = env.SELF_HOSTED && !env.isDev()\n\nexport default class LoggingProcessor implements EventProcessor {\n async processEvent(\n event: Event,\n identity: Identity,\n properties: any,\n timestamp?: string\n ): Promise<void> {\n if (skipLogging) {\n return\n }\n console.log(`[audit] [identityType=${identity.type}] ${event}`, properties)\n }\n\n async identify(identity: Identity, timestamp?: string | number) {\n if (skipLogging) {\n return\n }\n console.log(`[audit] identified`, identity)\n }\n\n async identifyGroup(group: Group, timestamp?: string | number) {\n if (skipLogging) {\n return\n }\n console.log(`[audit] group identified`, group)\n }\n\n shutdown(): void {\n // no-op\n }\n}\n", "import {\n Event,\n Identity,\n Group,\n IdentityType,\n AuditLogQueueEvent,\n AuditLogFn,\n HostInfo,\n} from \"@budibase/types\"\nimport { EventProcessor } from \"./types\"\nimport { getAppId, doInTenant, getTenantId } from \"../../context\"\nimport BullQueue from \"bull\"\nimport { createQueue, JobQueue } from \"../../queue\"\nimport { isAudited } from \"../../utils\"\nimport env from \"../../environment\"\n\nexport default class AuditLogsProcessor implements EventProcessor {\n static auditLogsEnabled = false\n static auditLogQueue: BullQueue.Queue<AuditLogQueueEvent>\n\n // can't use constructor as need to return promise\n static init(fn: AuditLogFn) {\n AuditLogsProcessor.auditLogsEnabled = true\n const writeAuditLogs = fn\n AuditLogsProcessor.auditLogQueue = createQueue<AuditLogQueueEvent>(\n JobQueue.AUDIT_LOG\n )\n return AuditLogsProcessor.auditLogQueue.process(async job => {\n return doInTenant(job.data.tenantId, async () => {\n let properties = job.data.properties\n if (properties.audited) {\n properties = {\n ...properties,\n ...properties.audited,\n }\n delete properties.audited\n }\n\n // this feature is disabled by default due to privacy requirements\n // in some countries - available as env var in-case it is desired\n // in self host deployments\n let hostInfo: HostInfo | undefined = {}\n if (env.ENABLE_AUDIT_LOG_IP_ADDR) {\n hostInfo = job.data.opts.hostInfo\n }\n\n await writeAuditLogs(job.data.event, properties, {\n userId: job.data.opts.userId,\n timestamp: job.data.opts.timestamp,\n appId: job.data.opts.appId,\n hostInfo,\n })\n })\n })\n }\n\n async processEvent(\n event: Event,\n identity: Identity,\n properties: any,\n timestamp?: string\n ): Promise<void> {\n if (AuditLogsProcessor.auditLogsEnabled && isAudited(event)) {\n // only audit log actual events, don't include backfills\n const userId =\n identity.type === IdentityType.USER ? identity.id : undefined\n // add to the event queue, rather than just writing immediately\n await AuditLogsProcessor.auditLogQueue.add({\n event,\n properties,\n opts: {\n userId,\n timestamp,\n appId: getAppId(),\n hostInfo: identity.hostInfo,\n },\n tenantId: getTenantId(),\n })\n }\n }\n\n async identify(identity: Identity, timestamp?: string | number) {\n // no-op\n }\n\n async identifyGroup(group: Group, timestamp?: string | number) {\n // no-op\n }\n\n shutdown(): void {\n AuditLogsProcessor.auditLogQueue?.close()\n }\n}\n", "export * from \"./queue\"\nexport * from \"./constants\"\n", "import env from \"../environment\"\nimport { getRedisOptions } from \"../redis/utils\"\nimport { JobQueue } from \"./constants\"\nimport InMemoryQueue from \"./inMemoryQueue\"\nimport BullQueue from \"bull\"\nimport { addListeners, StalledFn } from \"./listeners\"\nimport * as timers from \"../timers\"\n\nconst CLEANUP_PERIOD_MS = 60 * 1000\nlet QUEUES: BullQueue.Queue[] | InMemoryQueue[] = []\nlet cleanupInterval: NodeJS.Timeout\n\nasync function cleanup() {\n for (let queue of QUEUES) {\n await queue.clean(CLEANUP_PERIOD_MS, \"completed\")\n }\n}\n\nexport function createQueue<T>(\n jobQueue: JobQueue,\n opts: { removeStalledCb?: StalledFn } = {}\n): BullQueue.Queue<T> {\n const { opts: redisOpts, redisProtocolUrl } = getRedisOptions()\n const queueConfig: any = redisProtocolUrl || { redis: redisOpts }\n let queue: any\n if (!env.isTest()) {\n queue = new BullQueue(jobQueue, queueConfig)\n } else {\n queue = new InMemoryQueue(jobQueue, queueConfig)\n }\n addListeners(queue, jobQueue, opts?.removeStalledCb)\n QUEUES.push(queue)\n if (!cleanupInterval && !env.isTest()) {\n cleanupInterval = timers.set(cleanup, CLEANUP_PERIOD_MS)\n // fire off an initial cleanup\n cleanup().catch(err => {\n console.error(`Unable to cleanup automation queue initially - ${err}`)\n })\n }\n return queue\n}\n\nexport async function shutdown() {\n if (cleanupInterval) {\n timers.clear(cleanupInterval)\n }\n if (QUEUES.length) {\n for (let queue of QUEUES) {\n await queue.close()\n }\n QUEUES = []\n }\n console.log(\"Queues shutdown\")\n}\n", "import events from \"events\"\nimport { timeout } from \"../utils\"\n\n/**\n * Bull works with a Job wrapper around all messages that contains a lot more information about\n * the state of the message, this object constructor implements the same schema of Bull jobs\n * for the sake of maintaining API consistency.\n * @param {string} queue The name of the queue which the message will be carried on.\n * @param {object} message The JSON message which will be passed back to the consumer.\n * @returns {Object} A new job which can now be put onto the queue, this is mostly an\n * internal structure so that an in memory queue can be easily swapped for a Bull queue.\n */\nfunction newJob(queue: string, message: any) {\n return {\n timestamp: Date.now(),\n queue: queue,\n data: message,\n }\n}\n\n/**\n * This is designed to replicate Bull (https://github.com/OptimalBits/bull) in memory as a sort of mock.\n * It is relatively simple, using an event emitter internally to register when messages are available\n * to the consumers - in can support many inputs and many consumers.\n */\nclass InMemoryQueue {\n _name: string\n _opts?: any\n _messages: any[]\n _emitter: EventEmitter\n _runCount: number\n _addCount: number\n /**\n * The constructor the queue, exactly the same as that of Bulls.\n * @param {string} name The name of the queue which is being configured.\n * @param {object|null} opts This is not used by the in memory queue as there is no real use\n * case when in memory, but is the same API as Bull\n */\n constructor(name: string, opts = null) {\n this._name = name\n this._opts = opts\n this._messages = []\n this._emitter = new events.EventEmitter()\n this._runCount = 0\n this._addCount = 0\n }\n\n /**\n * Same callback API as Bull, each callback passed to this will consume messages as they are\n * available. Please note this is a queue service, not a notification service, so each\n * consumer will receive different messages.\n * @param {function<object>} func The callback function which will return a \"Job\", the same\n * as the Bull API, within this job the property \"data\" contains the JSON message. Please\n * note this is incredibly limited compared to Bull as in reality the Job would contain\n * a lot more information about the queue and current status of Bull cluster.\n */\n process(func: any) {\n this._emitter.on(\"message\", async () => {\n if (this._messages.length <= 0) {\n return\n }\n let msg = this._messages.shift()\n let resp = func(msg)\n if (resp.then != null) {\n await resp\n }\n this._runCount++\n })\n }\n\n // simply puts a message to the queue and emits to the queue for processing\n /**\n * Simple function to replicate the add message functionality of Bull, putting\n * a new message on the queue. This then emits an event which will be used to\n * return the message to a consumer (if one is attached).\n * @param {object} msg A message to be transported over the queue, this should be\n * a JSON message as this is required by Bull.\n * @param {boolean} repeat serves no purpose for the import queue.\n */\n // eslint-disable-next-line no-unused-vars\n add(msg: any, repeat: boolean) {\n if (typeof msg !== \"object\") {\n throw \"Queue only supports carrying JSON.\"\n }\n this._messages.push(newJob(this._name, msg))\n this._addCount++\n this._emitter.emit(\"message\")\n }\n\n /**\n * replicating the close function from bull, which waits for jobs to finish.\n */\n async close() {\n return []\n }\n\n /**\n * This removes a cron which has been implemented, this is part of Bull API.\n * @param {string} cronJobId The cron which is to be removed.\n */\n removeRepeatableByKey(cronJobId: string) {\n // TODO: implement for testing\n console.log(cronJobId)\n }\n\n /**\n * Implemented for tests\n */\n getRepeatableJobs() {\n return []\n }\n\n // eslint-disable-next-line no-unused-vars\n removeJobs(pattern: string) {\n // no-op\n }\n\n /**\n * Implemented for tests\n */\n async clean() {\n return []\n }\n\n async getJob() {\n return {}\n }\n\n on() {\n // do nothing\n return this\n }\n\n async waitForCompletion() {\n do {\n await timeout(50)\n } while (this._addCount < this._runCount)\n }\n}\n\nexport default InMemoryQueue\n", "export * from \"./hashing\"\nexport * from \"./utils\"\nexport * from \"./stringUtils\"\n", "import env from \"../environment\"\nexport * from \"../docIds/newid\"\nconst bcrypt = env.JS_BCRYPT ? require(\"bcryptjs\") : require(\"bcrypt\")\n\nconst SALT_ROUNDS = env.SALT_ROUNDS || 10\n\nexport async function hash(data: string) {\n const salt = await bcrypt.genSalt(SALT_ROUNDS)\n return bcrypt.hash(data, salt)\n}\n\nexport async function compare(data: string, encrypted: string) {\n return bcrypt.compare(data, encrypted)\n}\n", "import { getAllApps } from \"../db\"\nimport { Header, MAX_VALID_DATE, DocumentType, SEPARATOR } from \"../constants\"\nimport env from \"../environment\"\nimport * as tenancy from \"../tenancy\"\nimport * as context from \"../context\"\nimport {\n App,\n AuditedEventFriendlyName,\n Ctx,\n Event,\n TenantResolutionStrategy,\n} from \"@budibase/types\"\nimport { SetOption } from \"cookies\"\nconst jwt = require(\"jsonwebtoken\")\n\nconst APP_PREFIX = DocumentType.APP + SEPARATOR\nconst PROD_APP_PREFIX = \"/app/\"\n\nconst BUILDER_PREVIEW_PATH = \"/app/preview\"\nconst BUILDER_PREFIX = \"/builder\"\nconst BUILDER_APP_PREFIX = `${BUILDER_PREFIX}/app/`\nconst PUBLIC_API_PREFIX = \"/api/public/v\"\n\nfunction confirmAppId(possibleAppId: string | undefined) {\n return possibleAppId && possibleAppId.startsWith(APP_PREFIX)\n ? possibleAppId\n : undefined\n}\n\nexport async function resolveAppUrl(ctx: Ctx) {\n const appUrl = ctx.path.split(\"/\")[2]\n let possibleAppUrl = `/${appUrl.toLowerCase()}`\n\n let tenantId: string | null = context.getTenantId()\n if (env.MULTI_TENANCY) {\n // always use the tenant id from the subdomain in multi tenancy\n // this ensures the logged-in user tenant id doesn't overwrite\n // e.g. in the case of viewing a public app while already logged-in to another tenant\n tenantId = tenancy.getTenantIDFromCtx(ctx, {\n includeStrategies: [TenantResolutionStrategy.SUBDOMAIN],\n })\n }\n\n // search prod apps for a url that matches\n const apps: App[] = await context.doInTenant(\n tenantId,\n () => getAllApps({ dev: false }) as Promise<App[]>\n )\n const app = apps.filter(\n a => a.url && a.url.toLowerCase() === possibleAppUrl\n )[0]\n\n return app && app.appId ? app.appId : undefined\n}\n\nexport function isServingApp(ctx: Ctx) {\n // dev app\n if (ctx.path.startsWith(`/${APP_PREFIX}`)) {\n return true\n }\n // prod app\n if (ctx.path.startsWith(PROD_APP_PREFIX)) {\n return true\n }\n return false\n}\n\nexport function isServingBuilder(ctx: Ctx): boolean {\n return ctx.path.startsWith(BUILDER_APP_PREFIX)\n}\n\nexport function isServingBuilderPreview(ctx: Ctx): boolean {\n return ctx.path.startsWith(BUILDER_PREVIEW_PATH)\n}\n\nexport function isPublicApiRequest(ctx: Ctx): boolean {\n return ctx.path.startsWith(PUBLIC_API_PREFIX)\n}\n\n/**\n * Given a request tries to find the appId, which can be located in various places\n * @param {object} ctx The main request body to look through.\n * @returns {string|undefined} If an appId was found it will be returned.\n */\nexport async function getAppIdFromCtx(ctx: Ctx) {\n // look in headers\n const options = [ctx.request.headers[Header.APP_ID]]\n let appId\n for (let option of options) {\n appId = confirmAppId(option as string)\n if (appId) {\n break\n }\n }\n\n // look in body\n if (!appId && ctx.request.body && ctx.request.body.appId) {\n appId = confirmAppId(ctx.request.body.appId)\n }\n\n // look in the path\n const pathId = parseAppIdFromUrl(ctx.path)\n if (!appId && pathId) {\n appId = confirmAppId(pathId)\n }\n\n // lookup using custom url - prod apps only\n // filter out the builder preview path which collides with the prod app path\n // to ensure we don't load all apps excessively\n const isBuilderPreview = ctx.path.startsWith(BUILDER_PREVIEW_PATH)\n const isViewingProdApp =\n ctx.path.startsWith(PROD_APP_PREFIX) && !isBuilderPreview\n if (!appId && isViewingProdApp) {\n appId = confirmAppId(await resolveAppUrl(ctx))\n }\n\n // look in the referer - builder only\n // make sure this is performed after prod app url resolution, in case the\n // referer header is present from a builder redirect\n const referer = ctx.request.headers.referer\n if (!appId && referer?.includes(BUILDER_APP_PREFIX)) {\n const refererId = parseAppIdFromUrl(ctx.request.headers.referer)\n appId = confirmAppId(refererId)\n }\n\n return appId\n}\n\nfunction parseAppIdFromUrl(url?: string) {\n if (!url) {\n return\n }\n return url.split(\"/\").find(subPath => subPath.startsWith(APP_PREFIX))\n}\n\n/**\n * opens the contents of the specified encrypted JWT.\n * @return {object} the contents of the token.\n */\nexport function openJwt(token: string) {\n if (!token) {\n return token\n }\n try {\n return jwt.verify(token, env.JWT_SECRET)\n } catch (e) {\n if (env.JWT_SECRET_FALLBACK) {\n // fallback to enable rotation\n return jwt.verify(token, env.JWT_SECRET_FALLBACK)\n } else {\n throw e\n }\n }\n}\n\nexport function isValidInternalAPIKey(apiKey: string) {\n if (env.INTERNAL_API_KEY && env.INTERNAL_API_KEY === apiKey) {\n return true\n }\n // fallback to enable rotation\n if (\n env.INTERNAL_API_KEY_FALLBACK &&\n env.INTERNAL_API_KEY_FALLBACK === apiKey\n ) {\n return true\n }\n return false\n}\n\n/**\n * Get a cookie from context, and decrypt if necessary.\n * @param {object} ctx The request which is to be manipulated.\n * @param {string} name The name of the cookie to get.\n */\nexport function getCookie(ctx: Ctx, name: string) {\n const cookie = ctx.cookies.get(name)\n\n if (!cookie) {\n return cookie\n }\n\n return openJwt(cookie)\n}\n\n/**\n * Store a cookie for the request - it will not expire.\n * @param {object} ctx The request which is to be manipulated.\n * @param {string} name The name of the cookie to set.\n * @param {string|object} value The value of cookie which will be set.\n * @param {object} opts options like whether to sign.\n */\nexport function setCookie(\n ctx: Ctx,\n value: any,\n name = \"builder\",\n opts = { sign: true }\n) {\n if (value && opts && opts.sign) {\n value = jwt.sign(value, env.JWT_SECRET)\n }\n\n const config: SetOption = {\n expires: MAX_VALID_DATE,\n path: \"/\",\n httpOnly: false,\n overwrite: true,\n }\n\n if (env.COOKIE_DOMAIN) {\n config.domain = env.COOKIE_DOMAIN\n }\n\n ctx.cookies.set(name, value, config)\n}\n\n/**\n * Utility function, simply calls setCookie with an empty string for value\n */\nexport function clearCookie(ctx: Ctx, name: string) {\n setCookie(ctx, null, name)\n}\n\n/**\n * Checks if the API call being made (based on the provided ctx object) is from the client. If\n * the call is not from a client app then it is from the builder.\n * @param {object} ctx The koa context object to be tested.\n * @return {boolean} returns true if the call is from the client lib (a built app rather than the builder).\n */\nexport function isClient(ctx: Ctx) {\n return ctx.headers[Header.TYPE] === \"client\"\n}\n\nexport function timeout(timeMs: number) {\n return new Promise(resolve => setTimeout(resolve, timeMs))\n}\n\nexport function isAudited(event: Event) {\n return !!AuditedEventFriendlyName[event]\n}\n", "export function validEmail(value: string) {\n return (\n value &&\n !!value.match(\n /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/\n )\n )\n}\n", "export enum JobQueue {\n AUTOMATION = \"automationQueue\",\n APP_BACKUP = \"appBackupQueue\",\n AUDIT_LOG = \"auditLogQueue\",\n SYSTEM_EVENT_QUEUE = \"systemEventQueue\",\n}\n", "import { Job, JobId, Queue } from \"bull\"\nimport { JobQueue } from \"./constants\"\nimport * as context from \"../context\"\n\nexport type StalledFn = (job: Job) => Promise<void>\n\nexport function addListeners(\n queue: Queue,\n jobQueue: JobQueue,\n removeStalledCb?: StalledFn\n) {\n logging(queue, jobQueue)\n if (removeStalledCb) {\n handleStalled(queue, removeStalledCb)\n }\n}\n\nfunction handleStalled(queue: Queue, removeStalledCb?: StalledFn) {\n queue.on(\"stalled\", async (job: Job) => {\n if (removeStalledCb) {\n await removeStalledCb(job)\n } else if (job.opts.repeat) {\n const jobId = job.id\n const repeatJobs = await queue.getRepeatableJobs()\n for (let repeatJob of repeatJobs) {\n if (repeatJob.id === jobId) {\n await queue.removeRepeatableByKey(repeatJob.key)\n }\n }\n console.log(`jobId=${jobId} disabled`)\n }\n })\n}\n\nfunction getLogParams(\n eventType: QueueEventType,\n event: BullEvent,\n opts: {\n job?: Job\n jobId?: JobId\n error?: Error\n } = {},\n extra: any = {}\n) {\n const message = `[BULL] ${eventType}=${event}`\n const err = opts.error\n\n const bullLog = {\n _logKey: \"bull\",\n eventType,\n event,\n job: opts.job,\n jobId: opts.jobId || opts.job?.id,\n ...extra,\n }\n\n let automationLog\n if (opts.job?.data?.automation) {\n automationLog = {\n _logKey: \"automation\",\n trigger: opts.job\n ? opts.job.data.automation.definition.trigger.event\n : undefined,\n }\n }\n\n return [message, err, bullLog, automationLog]\n}\n\nenum BullEvent {\n ERROR = \"error\",\n WAITING = \"waiting\",\n ACTIVE = \"active\",\n STALLED = \"stalled\",\n PROGRESS = \"progress\",\n COMPLETED = \"completed\",\n FAILED = \"failed\",\n PAUSED = \"paused\",\n RESUMED = \"resumed\",\n CLEANED = \"cleaned\",\n DRAINED = \"drained\",\n REMOVED = \"removed\",\n}\n\nenum QueueEventType {\n AUTOMATION_EVENT = \"automation-event\",\n APP_BACKUP_EVENT = \"app-backup-event\",\n AUDIT_LOG_EVENT = \"audit-log-event\",\n SYSTEM_EVENT = \"system-event\",\n}\n\nconst EventTypeMap: { [key in JobQueue]: QueueEventType } = {\n [JobQueue.AUTOMATION]: QueueEventType.AUTOMATION_EVENT,\n [JobQueue.APP_BACKUP]: QueueEventType.APP_BACKUP_EVENT,\n [JobQueue.AUDIT_LOG]: QueueEventType.AUDIT_LOG_EVENT,\n [JobQueue.SYSTEM_EVENT_QUEUE]: QueueEventType.SYSTEM_EVENT,\n}\n\nfunction logging(queue: Queue, jobQueue: JobQueue) {\n const eventType = EventTypeMap[jobQueue]\n\n function doInJobContext(job: Job, task: any) {\n // if this is an automation job try to get the app id\n const appId = job.data.event?.appId\n if (appId) {\n return context.doInContext(appId, task)\n } else {\n task()\n }\n }\n\n queue\n .on(BullEvent.STALLED, async (job: Job) => {\n // A job has been marked as stalled. This is useful for debugging job\n // workers that crash or pause the event loop.\n await doInJobContext(job, () => {\n console.error(...getLogParams(eventType, BullEvent.STALLED, { job }))\n })\n })\n .on(BullEvent.ERROR, (error: any) => {\n // An error occurred.\n console.error(...getLogParams(eventType, BullEvent.ERROR, { error }))\n })\n\n if (process.env.NODE_DEBUG?.includes(\"bull\")) {\n queue\n .on(BullEvent.WAITING, (jobId: JobId) => {\n // A Job is waiting to be processed as soon as a worker is idling.\n console.info(...getLogParams(eventType, BullEvent.WAITING, { jobId }))\n })\n .on(BullEvent.ACTIVE, async (job: Job, jobPromise: any) => {\n // A job has started. You can use `jobPromise.cancel()`` to abort it.\n await doInJobContext(job, () => {\n console.info(...getLogParams(eventType, BullEvent.ACTIVE, { job }))\n })\n })\n .on(BullEvent.PROGRESS, async (job: Job, progress: any) => {\n // A job's progress was updated\n await doInJobContext(job, () => {\n console.info(\n ...getLogParams(\n eventType,\n BullEvent.PROGRESS,\n { job },\n { progress }\n )\n )\n })\n })\n .on(BullEvent.COMPLETED, async (job: Job, result) => {\n // A job successfully completed with a `result`.\n await doInJobContext(job, () => {\n console.info(\n ...getLogParams(eventType, BullEvent.COMPLETED, { job }, { result })\n )\n })\n })\n .on(BullEvent.FAILED, async (job: Job, error: any) => {\n // A job failed with reason `err`!\n await doInJobContext(job, () => {\n console.error(\n ...getLogParams(eventType, BullEvent.FAILED, { job, error })\n )\n })\n })\n .on(BullEvent.PAUSED, () => {\n // The queue has been paused.\n console.info(...getLogParams(eventType, BullEvent.PAUSED))\n })\n .on(BullEvent.RESUMED, () => {\n // The queue has been resumed.\n console.info(...getLogParams(eventType, BullEvent.RESUMED))\n })\n .on(BullEvent.CLEANED, (jobs: Job[], type: string) => {\n // Old jobs have been cleaned from the queue. `jobs` is an array of cleaned\n // jobs, and `type` is the type of jobs cleaned.\n console.info(\n ...getLogParams(\n eventType,\n BullEvent.CLEANED,\n {},\n { length: jobs.length, type }\n )\n )\n })\n .on(BullEvent.DRAINED, () => {\n // Emitted every time the queue has processed all the waiting jobs (even if there can be some delayed jobs not yet processed)\n console.info(...getLogParams(eventType, BullEvent.DRAINED))\n })\n .on(BullEvent.REMOVED, (job: Job) => {\n // A job successfully removed.\n console.info(...getLogParams(eventType, BullEvent.REMOVED, { job }))\n })\n }\n}\n", "import { Event, Identity, Group } from \"@budibase/types\"\nimport { EventProcessor } from \"./types\"\n\nexport default class Processor implements EventProcessor {\n initialised: boolean = false\n processors: EventProcessor[] = []\n\n constructor(processors: EventProcessor[]) {\n this.processors = processors\n }\n\n async processEvent(\n event: Event,\n identity: Identity,\n properties: any,\n timestamp?: string | number\n ): Promise<void> {\n for (const eventProcessor of this.processors) {\n await eventProcessor.processEvent(event, identity, properties, timestamp)\n }\n }\n\n async identify(\n identity: Identity,\n timestamp?: string | number\n ): Promise<void> {\n for (const eventProcessor of this.processors) {\n if (eventProcessor.identify) {\n await eventProcessor.identify(identity, timestamp)\n }\n }\n }\n\n async identifyGroup(\n identity: Group,\n timestamp?: string | number\n ): Promise<void> {\n for (const eventProcessor of this.processors) {\n if (eventProcessor.identifyGroup) {\n await eventProcessor.identifyGroup(identity, timestamp)\n }\n }\n }\n\n shutdown() {\n for (const eventProcessor of this.processors) {\n if (eventProcessor.shutdown) {\n eventProcessor.shutdown()\n }\n }\n }\n}\n", "import * as context from \"../context\"\nimport * as identityCtx from \"../context/identity\"\nimport env from \"../environment\"\nimport {\n Hosting,\n User,\n Identity,\n IdentityType,\n Account,\n isCloudAccount,\n isSSOAccount,\n TenantGroup,\n CloudAccount,\n UserIdentity,\n InstallationGroup,\n UserContext,\n Group,\n isSSOUser,\n} from \"@budibase/types\"\nimport { processors } from \"./processors\"\nimport { newid } from \"../utils\"\nimport * as installation from \"../installation\"\nimport * as configs from \"../configs\"\nimport { withCache, TTL, CacheKey } from \"../cache/generic\"\n\n/**\n * An identity can be:\n * - account user (Self host)\n * - budibase user\n * - tenant\n * - installation\n */\nconst getCurrentIdentity = async (): Promise<Identity> => {\n let identityContext = identityCtx.getIdentity()\n const environment = getDeploymentEnvironment()\n\n let identityType\n\n if (!identityContext) {\n identityType = IdentityType.TENANT\n } else {\n identityType = identityContext.type\n }\n\n if (identityType === IdentityType.INSTALLATION) {\n const installationId = await getInstallationId()\n const hosting = getHostingFromEnv()\n return {\n id: formatDistinctId(installationId, identityType),\n hosting,\n type: identityType,\n installationId,\n environment,\n }\n } else if (identityType === IdentityType.TENANT) {\n const installationId = await getInstallationId()\n const tenantId = await getEventTenantId(context.getTenantId())\n const hosting = getHostingFromEnv()\n\n return {\n id: formatDistinctId(tenantId, identityType),\n type: identityType,\n hosting,\n installationId,\n tenantId,\n realTenantId: context.getTenantId(),\n environment,\n }\n } else if (identityType === IdentityType.USER) {\n const userContext = identityContext as UserContext\n const tenantId = await getEventTenantId(context.getTenantId())\n const installationId = await getInstallationId()\n\n const account = userContext.account\n let hosting\n if (account) {\n hosting = account.hosting\n } else {\n hosting = getHostingFromEnv()\n }\n\n return {\n id: userContext._id,\n type: identityType,\n hosting,\n installationId,\n tenantId,\n environment,\n hostInfo: userContext.hostInfo,\n }\n } else {\n throw new Error(\"Unknown identity type\")\n }\n}\n\nconst identifyInstallationGroup = async (\n installId: string,\n timestamp?: string | number\n): Promise<void> => {\n const id = installId\n const type = IdentityType.INSTALLATION\n const hosting = getHostingFromEnv()\n const version = env.VERSION\n const environment = getDeploymentEnvironment()\n\n const group: InstallationGroup = {\n id,\n type,\n hosting,\n version,\n environment,\n }\n\n await identifyGroup(group, timestamp)\n // need to create a normal identity for the group to be able to query it globally\n // match the posthog syntax to link this identity to the empty auto generated one\n await identify({ ...group, id: `$${type}_${id}` }, timestamp)\n}\n\nconst identifyTenantGroup = async (\n tenantId: string,\n account: Account | undefined,\n timestamp?: string | number\n): Promise<void> => {\n const id = await getEventTenantId(tenantId)\n const type = IdentityType.TENANT\n const installationId = await getInstallationId()\n const environment = getDeploymentEnvironment()\n\n let hosting: Hosting\n let profession: string | undefined\n let companySize: string | undefined\n\n if (account) {\n profession = account.profession\n companySize = account.size\n hosting = account.hosting\n } else {\n hosting = getHostingFromEnv()\n }\n\n const group: TenantGroup = {\n id,\n type,\n hosting,\n environment,\n installationId,\n profession,\n companySize,\n }\n\n await identifyGroup(group, timestamp)\n // need to create a normal identity for the group to be able to query it globally\n // match the posthog syntax to link this identity to the auto generated one\n await identify({ ...group, id: `$${type}_${id}` }, timestamp)\n}\n\nconst identifyUser = async (\n user: User,\n account: CloudAccount | undefined,\n timestamp?: string | number\n) => {\n const id = user._id as string\n const tenantId = await getEventTenantId(user.tenantId)\n const type = IdentityType.USER\n let builder = user.builder?.global || false\n let admin = user.admin?.global || false\n let providerType\n if (isSSOUser(user)) {\n providerType = user.providerType\n }\n const accountHolder = account?.budibaseUserId === user._id || false\n const verified =\n account && account?.budibaseUserId === user._id ? account.verified : false\n const installationId = await getInstallationId()\n const hosting = account ? account.hosting : getHostingFromEnv()\n const environment = getDeploymentEnvironment()\n\n const identity: UserIdentity = {\n id,\n type,\n hosting,\n installationId,\n tenantId,\n verified,\n accountHolder,\n providerType,\n builder,\n admin,\n environment,\n }\n\n await identify(identity, timestamp)\n}\n\nconst identifyAccount = async (account: Account) => {\n let id = account.accountId\n const tenantId = account.tenantId\n let type = IdentityType.USER\n let providerType = isSSOAccount(account) ? account.providerType : undefined\n const verified = account.verified\n const accountHolder = true\n const hosting = account.hosting\n const installationId = await getInstallationId()\n const environment = getDeploymentEnvironment()\n\n if (isCloudAccount(account)) {\n if (account.budibaseUserId) {\n // use the budibase user as the id if set\n id = account.budibaseUserId\n }\n }\n\n const identity: UserIdentity = {\n id,\n type,\n hosting,\n installationId,\n tenantId,\n providerType,\n verified,\n accountHolder,\n environment,\n }\n\n await identify(identity)\n}\n\nconst identify = async (identity: Identity, timestamp?: string | number) => {\n await processors.identify(identity, timestamp)\n}\n\nconst identifyGroup = async (group: Group, timestamp?: string | number) => {\n await processors.identifyGroup(group, timestamp)\n}\n\nconst getDeploymentEnvironment = () => {\n if (env.isDev()) {\n return \"development\"\n } else {\n return env.DEPLOYMENT_ENVIRONMENT\n }\n}\n\nconst getHostingFromEnv = () => {\n return env.SELF_HOSTED ? Hosting.SELF : Hosting.CLOUD\n}\n\nconst getInstallationId = async () => {\n if (isAccountPortal()) {\n return \"account-portal\"\n }\n const install = await installation.getInstall()\n return install.installId\n}\n\nconst getEventTenantId = async (tenantId: string): Promise<string> => {\n if (env.SELF_HOSTED) {\n return getUniqueTenantId(tenantId)\n } else {\n // tenant id's in the cloud are already unique\n return tenantId\n }\n}\n\nconst getUniqueTenantId = async (tenantId: string): Promise<string> => {\n // make sure this tenantId always matches the tenantId in context\n return context.doInTenant(tenantId, () => {\n return withCache(CacheKey.UNIQUE_TENANT_ID, TTL.ONE_DAY, async () => {\n const db = context.getGlobalDB()\n const config = await configs.getSettingsConfigDoc()\n\n let uniqueTenantId: string\n if (config.config.uniqueTenantId) {\n return config.config.uniqueTenantId\n } else {\n uniqueTenantId = `${newid()}_${tenantId}`\n config.config.uniqueTenantId = uniqueTenantId\n await db.put(config)\n return uniqueTenantId\n }\n })\n })\n}\n\nconst isAccountPortal = () => {\n return env.SERVICE === \"account-portal\"\n}\n\nconst formatDistinctId = (id: string, type: IdentityType) => {\n if (type === IdentityType.INSTALLATION || type === IdentityType.TENANT) {\n return `$${type}_${id}`\n } else {\n return id\n }\n}\n\nexport default {\n getCurrentIdentity,\n identifyInstallationGroup,\n identifyTenantGroup,\n identifyUser,\n identifyAccount,\n identify,\n identifyGroup,\n getInstallationId,\n getUniqueTenantId,\n}\n", "import { newid } from \"./utils\"\nimport * as events from \"./events\"\nimport { StaticDatabases } from \"./db\"\nimport { doWithDB } from \"./db\"\nimport { Installation, IdentityType, Database } from \"@budibase/types\"\nimport * as context from \"./context\"\nimport semver from \"semver\"\nimport { bustCache, withCache, TTL, CacheKey } from \"./cache/generic\"\nimport environment from \"./environment\"\n\nexport const getInstall = async (): Promise<Installation> => {\n return withCache(CacheKey.INSTALLATION, TTL.ONE_DAY, getInstallFromDB, {\n useTenancy: false,\n })\n}\nasync function createInstallDoc(platformDb: Database) {\n const install: Installation = {\n _id: StaticDatabases.PLATFORM_INFO.docs.install,\n installId: newid(),\n version: environment.VERSION,\n }\n try {\n const resp = await platformDb.put(install)\n install._rev = resp.rev\n return install\n } catch (err: any) {\n if (err.status === 409) {\n return getInstallFromDB()\n } else {\n throw err\n }\n }\n}\n\nexport const getInstallFromDB = async (): Promise<Installation> => {\n return doWithDB(\n StaticDatabases.PLATFORM_INFO.name,\n async (platformDb: any) => {\n let install: Installation\n try {\n install = await platformDb.get(\n StaticDatabases.PLATFORM_INFO.docs.install\n )\n } catch (e: any) {\n if (e.status === 404) {\n install = await createInstallDoc(platformDb)\n } else {\n throw e\n }\n }\n return install\n }\n )\n}\n\nconst updateVersion = async (version: string): Promise<boolean> => {\n try {\n await doWithDB(\n StaticDatabases.PLATFORM_INFO.name,\n async (platformDb: any) => {\n const install = await getInstall()\n install.version = version\n await platformDb.put(install)\n await bustCache(CacheKey.INSTALLATION)\n }\n )\n } catch (e: any) {\n if (e.status === 409) {\n // do nothing - version has already been updated\n // likely in clustered environment\n return false\n }\n throw e\n }\n return true\n}\n\nexport const checkInstallVersion = async (): Promise<void> => {\n const install = await getInstall()\n\n const currentVersion = install.version\n const newVersion = environment.VERSION\n\n if (currentVersion !== newVersion) {\n const isUpgrade = semver.gt(newVersion, currentVersion)\n const isDowngrade = semver.lt(newVersion, currentVersion)\n\n const success = await updateVersion(newVersion)\n\n if (success) {\n await context.doInIdentityContext(\n {\n _id: install.installId,\n type: IdentityType.INSTALLATION,\n },\n async () => {\n if (isUpgrade) {\n await events.installation.upgraded(currentVersion, newVersion)\n } else if (isDowngrade) {\n await events.installation.downgraded(currentVersion, newVersion)\n }\n }\n )\n await events.identification.identifyInstallationGroup(install.installId)\n }\n }\n}\n", "import {\n Event,\n BackfillMetadata,\n CachedEvent,\n SSOCreatedEvent,\n AutomationCreatedEvent,\n AutomationStepCreatedEvent,\n DatasourceCreatedEvent,\n LayoutCreatedEvent,\n QueryCreatedEvent,\n RoleCreatedEvent,\n ScreenCreatedEvent,\n TableCreatedEvent,\n ViewCreatedEvent,\n ViewCalculationCreatedEvent,\n ViewFilterCreatedEvent,\n AppPublishedEvent,\n UserCreatedEvent,\n RoleAssignedEvent,\n UserPermissionAssignedEvent,\n AppCreatedEvent,\n} from \"@budibase/types\"\nimport * as context from \"../context\"\nimport { CacheKey } from \"../cache/generic\"\nimport * as cache from \"../cache/generic\"\n\n// LIFECYCLE\n\nexport const start = async (events: Event[]) => {\n const metadata: BackfillMetadata = {\n eventWhitelist: events,\n }\n return saveBackfillMetadata(metadata)\n}\n\nexport const recordEvent = async (event: Event, properties: any) => {\n const eventKey = getEventKey(event, properties)\n // don't use a ttl - cleaned up by migration\n // don't use tenancy - already in the key\n await cache.store(eventKey, properties, undefined, { useTenancy: false })\n}\n\nexport const end = async () => {\n await deleteBackfillMetadata()\n await clearEvents()\n}\n\n// CRUD\n\nconst getBackfillMetadata = async (): Promise<BackfillMetadata | null> => {\n return cache.get(CacheKey.BACKFILL_METADATA)\n}\n\nconst saveBackfillMetadata = async (\n backfill: BackfillMetadata\n): Promise<void> => {\n // no TTL - deleted by backfill\n return cache.store(CacheKey.BACKFILL_METADATA, backfill)\n}\n\nconst deleteBackfillMetadata = async (): Promise<void> => {\n await cache.destroy(CacheKey.BACKFILL_METADATA)\n}\n\nconst clearEvents = async () => {\n // wildcard\n const pattern = getEventKey()\n const keys = await cache.keys(pattern)\n\n for (const key of keys) {\n // delete each key\n // don't use tenancy, already in the key\n await cache.destroy(key, { useTenancy: false })\n }\n}\n\n// HELPERS\n\nexport const isBackfillingEvent = async (event: Event) => {\n const backfill = await getBackfillMetadata()\n const events = backfill?.eventWhitelist\n if (events && events.includes(event)) {\n return true\n } else {\n return false\n }\n}\n\nexport const isAlreadySent = async (event: Event, properties: any) => {\n const eventKey = getEventKey(event, properties)\n const cachedEvent: CachedEvent = await cache.get(eventKey, {\n useTenancy: false,\n })\n return !!cachedEvent\n}\n\nconst CUSTOM_PROPERTY_SUFFIX: any = {\n // APP EVENTS\n [Event.AUTOMATION_CREATED]: (properties: AutomationCreatedEvent) => {\n return properties.automationId\n },\n [Event.AUTOMATION_STEP_CREATED]: (properties: AutomationStepCreatedEvent) => {\n return properties.stepId\n },\n [Event.DATASOURCE_CREATED]: (properties: DatasourceCreatedEvent) => {\n return properties.datasourceId\n },\n [Event.LAYOUT_CREATED]: (properties: LayoutCreatedEvent) => {\n return properties.layoutId\n },\n [Event.QUERY_CREATED]: (properties: QueryCreatedEvent) => {\n return properties.queryId\n },\n [Event.ROLE_CREATED]: (properties: RoleCreatedEvent) => {\n return properties.roleId\n },\n [Event.SCREEN_CREATED]: (properties: ScreenCreatedEvent) => {\n return properties.screenId\n },\n [Event.TABLE_CREATED]: (properties: TableCreatedEvent) => {\n return properties.tableId\n },\n [Event.VIEW_CREATED]: (properties: ViewCreatedEvent) => {\n return properties.tableId // best uniqueness\n },\n [Event.VIEW_CALCULATION_CREATED]: (\n properties: ViewCalculationCreatedEvent\n ) => {\n return properties.tableId // best uniqueness\n },\n [Event.VIEW_FILTER_CREATED]: (properties: ViewFilterCreatedEvent) => {\n return properties.tableId // best uniqueness\n },\n [Event.APP_CREATED]: (properties: AppCreatedEvent) => {\n return properties.appId // best uniqueness\n },\n [Event.APP_PUBLISHED]: (properties: AppPublishedEvent) => {\n return properties.appId // best uniqueness\n },\n // GLOBAL EVENTS\n [Event.AUTH_SSO_CREATED]: (properties: SSOCreatedEvent) => {\n return properties.type\n },\n [Event.AUTH_SSO_ACTIVATED]: (properties: SSOCreatedEvent) => {\n return properties.type\n },\n [Event.USER_CREATED]: (properties: UserCreatedEvent) => {\n return properties.userId\n },\n [Event.USER_PERMISSION_ADMIN_ASSIGNED]: (\n properties: UserPermissionAssignedEvent\n ) => {\n return properties.userId\n },\n [Event.USER_PERMISSION_BUILDER_ASSIGNED]: (\n properties: UserPermissionAssignedEvent\n ) => {\n return properties.userId\n },\n [Event.ROLE_ASSIGNED]: (properties: RoleAssignedEvent) => {\n return `${properties.roleId}-${properties.userId}`\n },\n}\n\nconst getEventKey = (event?: Event, properties?: any) => {\n let eventKey: string\n\n const tenantId = context.getTenantId()\n if (event) {\n eventKey = `${CacheKey.EVENTS}:${tenantId}:${event}`\n\n // use some properties to make the key more unique\n const custom = CUSTOM_PROPERTY_SUFFIX[event]\n const suffix = custom ? custom(properties) : undefined\n if (suffix) {\n eventKey = `${eventKey}:${suffix}`\n }\n } else {\n eventKey = `${CacheKey.EVENTS}:${tenantId}:*`\n }\n\n return eventKey\n}\n", "import BullQueue from \"bull\"\nimport { createQueue, JobQueue } from \"../../queue\"\nimport { Event, Identity } from \"@budibase/types\"\n\nexport interface EventPayload {\n event: Event\n identity: Identity\n properties: any\n timestamp?: string | number\n}\n\nexport let asyncEventQueue: BullQueue.Queue\n\nexport function init() {\n asyncEventQueue = createQueue<EventPayload>(JobQueue.SYSTEM_EVENT_QUEUE)\n}\n\nexport async function shutdown() {\n if (asyncEventQueue) {\n await asyncEventQueue.close()\n }\n}\n", "import { AsyncEvents } from \"@budibase/types\"\nimport { EventPayload, asyncEventQueue, init } from \"./queue\"\n\nexport async function publishAsyncEvent(payload: EventPayload) {\n if (!asyncEventQueue) {\n init()\n }\n const { event, identity } = payload\n if (AsyncEvents.indexOf(event) !== -1 && identity.tenantId) {\n await asyncEventQueue.add(payload)\n }\n}\n", "import { Event } from \"@budibase/types\"\nimport { processors } from \"./processors\"\nimport identification from \"./identification\"\nimport * as backfill from \"./backfill\"\nimport { publishAsyncEvent } from \"./asyncEvents\"\n\nexport const publishEvent = async (\n event: Event,\n properties: any,\n timestamp?: string | number\n) => {\n // in future this should use async events via a distributed queue.\n const identity = await identification.getCurrentIdentity()\n\n const backfilling = await backfill.isBackfillingEvent(event)\n // no backfill - send the event and exit\n if (!backfilling) {\n // send off async events if required\n await publishAsyncEvent({\n event,\n identity,\n properties,\n timestamp,\n })\n // now handle the main sync event processing pipeline\n await processors.processEvent(event, identity, properties, timestamp)\n return\n }\n\n // backfill active - check if the event has been sent already\n const alreadySent = await backfill.isAlreadySent(event, properties)\n if (alreadySent) {\n // do nothing\n return\n } else {\n // send and record the event\n await processors.processEvent(event, identity, properties, timestamp)\n await backfill.recordEvent(event, properties)\n }\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n Account,\n AccountCreatedEvent,\n AccountDeletedEvent,\n AccountVerifiedEvent,\n} from \"@budibase/types\"\n\nasync function created(account: Account) {\n const properties: AccountCreatedEvent = {\n tenantId: account.tenantId,\n }\n await publishEvent(Event.ACCOUNT_CREATED, properties)\n}\n\nasync function deleted(account: Account) {\n const properties: AccountDeletedEvent = {\n tenantId: account.tenantId,\n }\n await publishEvent(Event.ACCOUNT_DELETED, properties)\n}\n\nasync function verified(account: Account) {\n const properties: AccountVerifiedEvent = {\n tenantId: account.tenantId,\n }\n await publishEvent(Event.ACCOUNT_VERIFIED, properties)\n}\n\nexport default {\n created,\n deleted,\n verified,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n App,\n AppCreatedEvent,\n AppUpdatedEvent,\n AppDeletedEvent,\n AppPublishedEvent,\n AppUnpublishedEvent,\n AppFileImportedEvent,\n AppTemplateImportedEvent,\n AppVersionUpdatedEvent,\n AppVersionRevertedEvent,\n AppRevertedEvent,\n AppExportedEvent,\n} from \"@budibase/types\"\n\nconst created = async (app: App, timestamp?: string | number) => {\n const properties: AppCreatedEvent = {\n appId: app.appId,\n version: app.version,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_CREATED, properties, timestamp)\n}\n\nasync function updated(app: App) {\n const properties: AppUpdatedEvent = {\n appId: app.appId,\n version: app.version,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_UPDATED, properties)\n}\n\nasync function deleted(app: App) {\n const properties: AppDeletedEvent = {\n appId: app.appId,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_DELETED, properties)\n}\n\nasync function published(app: App, timestamp?: string | number) {\n const properties: AppPublishedEvent = {\n appId: app.appId,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_PUBLISHED, properties, timestamp)\n}\n\nasync function unpublished(app: App) {\n const properties: AppUnpublishedEvent = {\n appId: app.appId,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_UNPUBLISHED, properties)\n}\n\nasync function fileImported(app: App) {\n const properties: AppFileImportedEvent = {\n appId: app.appId,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_FILE_IMPORTED, properties)\n}\n\nasync function templateImported(app: App, templateKey: string) {\n const properties: AppTemplateImportedEvent = {\n appId: app.appId,\n templateKey,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_TEMPLATE_IMPORTED, properties)\n}\n\nasync function versionUpdated(\n app: App,\n currentVersion: string,\n updatedToVersion: string\n) {\n const properties: AppVersionUpdatedEvent = {\n appId: app.appId,\n currentVersion,\n updatedToVersion,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_VERSION_UPDATED, properties)\n}\n\nasync function versionReverted(\n app: App,\n currentVersion: string,\n revertedToVersion: string\n) {\n const properties: AppVersionRevertedEvent = {\n appId: app.appId,\n currentVersion,\n revertedToVersion,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_VERSION_REVERTED, properties)\n}\n\nasync function reverted(app: App) {\n const properties: AppRevertedEvent = {\n appId: app.appId,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_REVERTED, properties)\n}\n\nasync function exported(app: App) {\n const properties: AppExportedEvent = {\n appId: app.appId,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_EXPORTED, properties)\n}\n\nexport default {\n created,\n updated,\n deleted,\n published,\n unpublished,\n fileImported,\n templateImported,\n versionUpdated,\n versionReverted,\n reverted,\n exported,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n LoginEvent,\n LoginSource,\n LogoutEvent,\n SSOActivatedEvent,\n SSOCreatedEvent,\n SSODeactivatedEvent,\n SSOType,\n SSOUpdatedEvent,\n} from \"@budibase/types\"\nimport { identification } from \"..\"\n\nasync function login(source: LoginSource, email: string) {\n const identity = await identification.getCurrentIdentity()\n const properties: LoginEvent = {\n userId: identity.id,\n source,\n audited: {\n email,\n },\n }\n await publishEvent(Event.AUTH_LOGIN, properties)\n}\n\nasync function logout(email?: string) {\n const identity = await identification.getCurrentIdentity()\n const properties: LogoutEvent = {\n userId: identity.id,\n audited: {\n email,\n },\n }\n await publishEvent(Event.AUTH_LOGOUT, properties)\n}\n\nasync function SSOCreated(type: SSOType, timestamp?: string | number) {\n const properties: SSOCreatedEvent = {\n type,\n }\n await publishEvent(Event.AUTH_SSO_CREATED, properties, timestamp)\n}\n\nasync function SSOUpdated(type: SSOType) {\n const properties: SSOUpdatedEvent = {\n type,\n }\n await publishEvent(Event.AUTH_SSO_UPDATED, properties)\n}\n\nasync function SSOActivated(type: SSOType, timestamp?: string | number) {\n const properties: SSOActivatedEvent = {\n type,\n }\n await publishEvent(Event.AUTH_SSO_ACTIVATED, properties, timestamp)\n}\n\nasync function SSODeactivated(type: SSOType) {\n const properties: SSODeactivatedEvent = {\n type,\n }\n await publishEvent(Event.AUTH_SSO_DEACTIVATED, properties)\n}\n\nexport default {\n login,\n logout,\n SSOCreated,\n SSOUpdated,\n SSOActivated,\n SSODeactivated,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Automation,\n Event,\n AutomationStep,\n AutomationCreatedEvent,\n AutomationDeletedEvent,\n AutomationTestedEvent,\n AutomationStepCreatedEvent,\n AutomationStepDeletedEvent,\n AutomationTriggerUpdatedEvent,\n AutomationsRunEvent,\n} from \"@budibase/types\"\n\nasync function created(automation: Automation, timestamp?: string | number) {\n const properties: AutomationCreatedEvent = {\n appId: automation.appId,\n automationId: automation._id as string,\n triggerId: automation.definition?.trigger?.id,\n triggerType: automation.definition?.trigger?.stepId,\n audited: {\n name: automation.name,\n },\n }\n await publishEvent(Event.AUTOMATION_CREATED, properties, timestamp)\n}\n\nasync function triggerUpdated(automation: Automation) {\n const properties: AutomationTriggerUpdatedEvent = {\n appId: automation.appId,\n automationId: automation._id as string,\n triggerId: automation.definition?.trigger?.id,\n triggerType: automation.definition?.trigger?.stepId,\n }\n await publishEvent(Event.AUTOMATION_TRIGGER_UPDATED, properties)\n}\n\nasync function deleted(automation: Automation) {\n const properties: AutomationDeletedEvent = {\n appId: automation.appId,\n automationId: automation._id as string,\n triggerId: automation.definition?.trigger?.id,\n triggerType: automation.definition?.trigger?.stepId,\n audited: {\n name: automation.name,\n },\n }\n await publishEvent(Event.AUTOMATION_DELETED, properties)\n}\n\nasync function tested(automation: Automation) {\n const properties: AutomationTestedEvent = {\n appId: automation.appId,\n automationId: automation._id as string,\n triggerId: automation.definition?.trigger?.id,\n triggerType: automation.definition?.trigger?.stepId,\n }\n await publishEvent(Event.AUTOMATION_TESTED, properties)\n}\n\nconst run = async (count: number, timestamp?: string | number) => {\n const properties: AutomationsRunEvent = {\n count,\n }\n await publishEvent(Event.AUTOMATIONS_RUN, properties, timestamp)\n}\n\nasync function stepCreated(\n automation: Automation,\n step: AutomationStep,\n timestamp?: string | number\n) {\n const properties: AutomationStepCreatedEvent = {\n appId: automation.appId,\n automationId: automation._id as string,\n triggerId: automation.definition?.trigger?.id,\n triggerType: automation.definition?.trigger?.stepId,\n stepId: step.id!,\n stepType: step.stepId,\n audited: {\n name: automation.name,\n },\n }\n await publishEvent(Event.AUTOMATION_STEP_CREATED, properties, timestamp)\n}\n\nasync function stepDeleted(automation: Automation, step: AutomationStep) {\n const properties: AutomationStepDeletedEvent = {\n appId: automation.appId,\n automationId: automation._id as string,\n triggerId: automation.definition?.trigger?.id,\n triggerType: automation.definition?.trigger?.stepId,\n stepId: step.id!,\n stepType: step.stepId,\n audited: {\n name: automation.name,\n },\n }\n await publishEvent(Event.AUTOMATION_STEP_DELETED, properties)\n}\n\nexport default {\n created,\n triggerUpdated,\n deleted,\n tested,\n run,\n stepCreated,\n stepDeleted,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n Datasource,\n DatasourceCreatedEvent,\n DatasourceUpdatedEvent,\n DatasourceDeletedEvent,\n SourceName,\n} from \"@budibase/types\"\n\nfunction isCustom(datasource: Datasource) {\n const sources = Object.values(SourceName)\n // if not in the base source list, then it must be custom\n return !sources.includes(datasource.source)\n}\n\nasync function created(datasource: Datasource, timestamp?: string | number) {\n const properties: DatasourceCreatedEvent = {\n datasourceId: datasource._id as string,\n source: datasource.source,\n custom: isCustom(datasource),\n }\n await publishEvent(Event.DATASOURCE_CREATED, properties, timestamp)\n}\n\nasync function updated(datasource: Datasource) {\n const properties: DatasourceUpdatedEvent = {\n datasourceId: datasource._id as string,\n source: datasource.source,\n custom: isCustom(datasource),\n }\n await publishEvent(Event.DATASOURCE_UPDATED, properties)\n}\n\nasync function deleted(datasource: Datasource) {\n const properties: DatasourceDeletedEvent = {\n datasourceId: datasource._id as string,\n source: datasource.source,\n custom: isCustom(datasource),\n }\n await publishEvent(Event.DATASOURCE_DELETED, properties)\n}\n\nexport default {\n created,\n updated,\n deleted,\n}\n", "import { publishEvent } from \"../events\"\nimport { Event, SMTPCreatedEvent, SMTPUpdatedEvent } from \"@budibase/types\"\n\nasync function SMTPCreated(timestamp?: string | number) {\n const properties: SMTPCreatedEvent = {}\n await publishEvent(Event.EMAIL_SMTP_CREATED, properties, timestamp)\n}\n\nasync function SMTPUpdated() {\n const properties: SMTPUpdatedEvent = {}\n await publishEvent(Event.EMAIL_SMTP_UPDATED, properties)\n}\n\nexport default {\n SMTPCreated,\n SMTPUpdated,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n LicenseActivatedEvent,\n LicensePlanChangedEvent,\n PlanType,\n Account,\n LicensePortalOpenedEvent,\n LicenseCheckoutSuccessEvent,\n LicenseCheckoutOpenedEvent,\n LicensePaymentFailedEvent,\n LicensePaymentRecoveredEvent,\n PriceDuration,\n} from \"@budibase/types\"\n\nasync function planChanged(\n account: Account,\n opts: {\n from: PlanType\n to: PlanType\n fromQuantity: number | undefined\n toQuantity: number | undefined\n fromDuration: PriceDuration | undefined\n toDuration: PriceDuration | undefined\n }\n) {\n const properties: LicensePlanChangedEvent = {\n accountId: account.accountId,\n ...opts,\n }\n await publishEvent(Event.LICENSE_PLAN_CHANGED, properties)\n}\n\nasync function activated(account: Account) {\n const properties: LicenseActivatedEvent = {\n accountId: account.accountId,\n }\n await publishEvent(Event.LICENSE_ACTIVATED, properties)\n}\n\nasync function checkoutOpened(account: Account) {\n const properties: LicenseCheckoutOpenedEvent = {\n accountId: account.accountId,\n }\n await publishEvent(Event.LICENSE_CHECKOUT_OPENED, properties)\n}\n\nasync function checkoutSuccess(account: Account) {\n const properties: LicenseCheckoutSuccessEvent = {\n accountId: account.accountId,\n }\n await publishEvent(Event.LICENSE_CHECKOUT_SUCCESS, properties)\n}\n\nasync function portalOpened(account: Account) {\n const properties: LicensePortalOpenedEvent = {\n accountId: account.accountId,\n }\n await publishEvent(Event.LICENSE_PORTAL_OPENED, properties)\n}\n\nasync function paymentFailed(account: Account) {\n const properties: LicensePaymentFailedEvent = {\n accountId: account.accountId,\n }\n await publishEvent(Event.LICENSE_PAYMENT_FAILED, properties)\n}\n\nasync function paymentRecovered(account: Account) {\n const properties: LicensePaymentRecoveredEvent = {\n accountId: account.accountId,\n }\n await publishEvent(Event.LICENSE_PAYMENT_RECOVERED, properties)\n}\n\nexport default {\n planChanged,\n activated,\n checkoutOpened,\n checkoutSuccess,\n portalOpened,\n paymentFailed,\n paymentRecovered,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n Layout,\n LayoutCreatedEvent,\n LayoutDeletedEvent,\n} from \"@budibase/types\"\n\nasync function created(layout: Layout, timestamp?: string | number) {\n const properties: LayoutCreatedEvent = {\n layoutId: layout._id as string,\n }\n await publishEvent(Event.LAYOUT_CREATED, properties, timestamp)\n}\n\nasync function deleted(layoutId: string) {\n const properties: LayoutDeletedEvent = {\n layoutId,\n }\n await publishEvent(Event.LAYOUT_DELETED, properties)\n}\n\nexport default {\n created,\n deleted,\n}\n", "import { publishEvent } from \"../events\"\nimport { Event } from \"@budibase/types\"\n\nasync function nameUpdated(timestamp?: string | number) {\n const properties = {}\n await publishEvent(Event.ORG_NAME_UPDATED, properties, timestamp)\n}\n\nasync function logoUpdated(timestamp?: string | number) {\n const properties = {}\n await publishEvent(Event.ORG_LOGO_UPDATED, properties, timestamp)\n}\n\nasync function platformURLUpdated(timestamp?: string | number) {\n const properties = {}\n await publishEvent(Event.ORG_PLATFORM_URL_UPDATED, properties, timestamp)\n}\n\n// TODO\n\nasync function analyticsOptOut() {\n const properties = {}\n await publishEvent(Event.ANALYTICS_OPT_OUT, properties)\n}\n\nasync function analyticsOptIn() {\n const properties = {}\n await publishEvent(Event.ANALYTICS_OPT_OUT, properties)\n}\n\nexport default {\n nameUpdated,\n logoUpdated,\n platformURLUpdated,\n analyticsOptOut,\n analyticsOptIn,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n Datasource,\n Query,\n QueryCreatedEvent,\n QueryUpdatedEvent,\n QueryDeletedEvent,\n QueryImportedEvent,\n QueryPreviewedEvent,\n QueriesRunEvent,\n} from \"@budibase/types\"\n\n/* eslint-disable */\n\nconst created = async (\n datasource: Datasource,\n query: Query,\n timestamp?: string | number\n) => {\n const properties: QueryCreatedEvent = {\n queryId: query._id as string,\n datasourceId: datasource._id as string,\n source: datasource.source,\n queryVerb: query.queryVerb,\n }\n await publishEvent(Event.QUERY_CREATED, properties, timestamp)\n}\n\nconst updated = async (datasource: Datasource, query: Query) => {\n const properties: QueryUpdatedEvent = {\n queryId: query._id as string,\n datasourceId: datasource._id as string,\n source: datasource.source,\n queryVerb: query.queryVerb,\n }\n await publishEvent(Event.QUERY_UPDATED, properties)\n}\n\nconst deleted = async (datasource: Datasource, query: Query) => {\n const properties: QueryDeletedEvent = {\n queryId: query._id as string,\n datasourceId: datasource._id as string,\n source: datasource.source,\n queryVerb: query.queryVerb,\n }\n await publishEvent(Event.QUERY_DELETED, properties)\n}\n\nconst imported = async (\n datasource: Datasource,\n importSource: any,\n count: any\n) => {\n const properties: QueryImportedEvent = {\n datasourceId: datasource._id as string,\n source: datasource.source,\n count,\n importSource,\n }\n await publishEvent(Event.QUERY_IMPORT, properties)\n}\n\nconst run = async (count: number, timestamp?: string | number) => {\n const properties: QueriesRunEvent = {\n count,\n }\n await publishEvent(Event.QUERIES_RUN, properties, timestamp)\n}\n\nconst previewed = async (datasource: Datasource, query: Query) => {\n const properties: QueryPreviewedEvent = {\n queryId: query._id,\n datasourceId: datasource._id as string,\n source: datasource.source,\n queryVerb: query.queryVerb,\n }\n await publishEvent(Event.QUERY_PREVIEWED, properties)\n}\n\nexport default {\n created,\n updated,\n deleted,\n imported,\n run,\n previewed,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n Role,\n RoleAssignedEvent,\n RoleCreatedEvent,\n RoleDeletedEvent,\n RoleUnassignedEvent,\n RoleUpdatedEvent,\n User,\n} from \"@budibase/types\"\n\nasync function created(role: Role, timestamp?: string | number) {\n const properties: RoleCreatedEvent = {\n roleId: role._id as string,\n permissionId: role.permissionId,\n inherits: role.inherits,\n }\n await publishEvent(Event.ROLE_CREATED, properties, timestamp)\n}\n\nasync function updated(role: Role) {\n const properties: RoleUpdatedEvent = {\n roleId: role._id as string,\n permissionId: role.permissionId,\n inherits: role.inherits,\n }\n await publishEvent(Event.ROLE_UPDATED, properties)\n}\n\nasync function deleted(role: Role) {\n const properties: RoleDeletedEvent = {\n roleId: role._id as string,\n permissionId: role.permissionId,\n inherits: role.inherits,\n }\n await publishEvent(Event.ROLE_DELETED, properties)\n}\n\nasync function assigned(user: User, roleId: string, timestamp?: number) {\n const properties: RoleAssignedEvent = {\n userId: user._id as string,\n roleId,\n }\n await publishEvent(Event.ROLE_ASSIGNED, properties, timestamp)\n}\n\nasync function unassigned(user: User, roleId: string) {\n const properties: RoleUnassignedEvent = {\n userId: user._id as string,\n roleId,\n }\n await publishEvent(Event.ROLE_UNASSIGNED, properties)\n}\n\nexport default {\n created,\n updated,\n deleted,\n assigned,\n unassigned,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n Screen,\n ScreenCreatedEvent,\n ScreenDeletedEvent,\n} from \"@budibase/types\"\n\nasync function created(screen: Screen, timestamp?: string | number) {\n const properties: ScreenCreatedEvent = {\n layoutId: screen.layoutId,\n screenId: screen._id as string,\n roleId: screen.routing.roleId,\n audited: {\n name: screen.routing?.route,\n },\n }\n await publishEvent(Event.SCREEN_CREATED, properties, timestamp)\n}\n\nasync function deleted(screen: Screen) {\n const properties: ScreenDeletedEvent = {\n layoutId: screen.layoutId,\n screenId: screen._id as string,\n roleId: screen.routing.roleId,\n audited: {\n name: screen.routing?.route,\n },\n }\n await publishEvent(Event.SCREEN_DELETED, properties)\n}\n\nexport default {\n created,\n deleted,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n RowsImportedEvent,\n RowsCreatedEvent,\n Table,\n} from \"@budibase/types\"\n\n/* eslint-disable */\n\nconst created = async (count: number, timestamp?: string | number) => {\n const properties: RowsCreatedEvent = {\n count,\n }\n await publishEvent(Event.ROWS_CREATED, properties, timestamp)\n}\n\nconst imported = async (table: Table, count: number) => {\n const properties: RowsImportedEvent = {\n tableId: table._id as string,\n count,\n }\n await publishEvent(Event.ROWS_IMPORTED, properties)\n}\n\nexport default {\n created,\n imported,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n TableExportFormat,\n Table,\n TableCreatedEvent,\n TableUpdatedEvent,\n TableDeletedEvent,\n TableExportedEvent,\n TableImportedEvent,\n} from \"@budibase/types\"\n\nasync function created(table: Table, timestamp?: string | number) {\n const properties: TableCreatedEvent = {\n tableId: table._id as string,\n audited: {\n name: table.name,\n },\n }\n await publishEvent(Event.TABLE_CREATED, properties, timestamp)\n}\n\nasync function updated(table: Table) {\n const properties: TableUpdatedEvent = {\n tableId: table._id as string,\n audited: {\n name: table.name,\n },\n }\n await publishEvent(Event.TABLE_UPDATED, properties)\n}\n\nasync function deleted(table: Table) {\n const properties: TableDeletedEvent = {\n tableId: table._id as string,\n audited: {\n name: table.name,\n },\n }\n await publishEvent(Event.TABLE_DELETED, properties)\n}\n\nasync function exported(table: Table, format: TableExportFormat) {\n const properties: TableExportedEvent = {\n tableId: table._id as string,\n format,\n audited: {\n name: table.name,\n },\n }\n await publishEvent(Event.TABLE_EXPORTED, properties)\n}\n\nasync function imported(table: Table) {\n const properties: TableImportedEvent = {\n tableId: table._id as string,\n audited: {\n name: table.name,\n },\n }\n await publishEvent(Event.TABLE_IMPORTED, properties)\n}\n\nexport default {\n created,\n updated,\n deleted,\n exported,\n imported,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n App,\n BuilderServedEvent,\n Event,\n AppPreviewServedEvent,\n AppServedEvent,\n} from \"@budibase/types\"\n\nasync function servedBuilder(timezone: string) {\n const properties: BuilderServedEvent = {\n timezone,\n }\n await publishEvent(Event.SERVED_BUILDER, properties)\n}\n\nasync function servedApp(app: App, timezone: string) {\n const properties: AppServedEvent = {\n appVersion: app.version,\n timezone,\n }\n await publishEvent(Event.SERVED_APP, properties)\n}\n\nasync function servedAppPreview(app: App, timezone: string) {\n const properties: AppPreviewServedEvent = {\n appId: app.appId,\n appVersion: app.version,\n timezone,\n }\n await publishEvent(Event.SERVED_APP_PREVIEW, properties)\n}\n\nexport default {\n servedBuilder,\n servedApp,\n servedAppPreview,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n User,\n UserCreatedEvent,\n UserDeletedEvent,\n UserInviteAcceptedEvent,\n UserInvitedEvent,\n UserPasswordForceResetEvent,\n UserPasswordResetEvent,\n UserPasswordResetRequestedEvent,\n UserPasswordUpdatedEvent,\n UserPermissionAssignedEvent,\n UserPermissionRemovedEvent,\n UserUpdatedEvent,\n UserOnboardingEvent,\n} from \"@budibase/types\"\nimport { isScim } from \"../../context\"\n\nasync function created(user: User, timestamp?: number) {\n const properties: UserCreatedEvent = {\n userId: user._id as string,\n viaScim: isScim(),\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_CREATED, properties, timestamp)\n}\n\nasync function updated(user: User) {\n const properties: UserUpdatedEvent = {\n userId: user._id as string,\n viaScim: isScim(),\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_UPDATED, properties)\n}\n\nasync function deleted(user: User) {\n const properties: UserDeletedEvent = {\n userId: user._id as string,\n viaScim: isScim(),\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_DELETED, properties)\n}\n\nexport async function onboardingComplete(user: User) {\n const properties: UserOnboardingEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_ONBOARDING_COMPLETE, properties)\n}\n\n// PERMISSIONS\n\nasync function permissionAdminAssigned(user: User, timestamp?: number) {\n const properties: UserPermissionAssignedEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(\n Event.USER_PERMISSION_ADMIN_ASSIGNED,\n properties,\n timestamp\n )\n}\n\nasync function permissionAdminRemoved(user: User) {\n const properties: UserPermissionRemovedEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_PERMISSION_ADMIN_REMOVED, properties)\n}\n\nasync function permissionBuilderAssigned(user: User, timestamp?: number) {\n const properties: UserPermissionAssignedEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(\n Event.USER_PERMISSION_BUILDER_ASSIGNED,\n properties,\n timestamp\n )\n}\n\nasync function permissionBuilderRemoved(user: User) {\n const properties: UserPermissionRemovedEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_PERMISSION_BUILDER_REMOVED, properties)\n}\n\n// INVITE\n\nasync function invited(email: string) {\n const properties: UserInvitedEvent = {\n audited: {\n email,\n },\n }\n await publishEvent(Event.USER_INVITED, properties)\n}\n\nasync function inviteAccepted(user: User) {\n const properties: UserInviteAcceptedEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_INVITED_ACCEPTED, properties)\n}\n\n// PASSWORD\n\nasync function passwordForceReset(user: User) {\n const properties: UserPasswordForceResetEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_PASSWORD_FORCE_RESET, properties)\n}\n\nasync function passwordUpdated(user: User) {\n const properties: UserPasswordUpdatedEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_PASSWORD_UPDATED, properties)\n}\n\nasync function passwordResetRequested(user: User) {\n const properties: UserPasswordResetRequestedEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_PASSWORD_RESET_REQUESTED, properties)\n}\n\nasync function passwordReset(user: User) {\n const properties: UserPasswordResetEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_PASSWORD_RESET, properties)\n}\n\nexport default {\n created,\n updated,\n deleted,\n permissionAdminAssigned,\n permissionAdminRemoved,\n permissionBuilderAssigned,\n permissionBuilderRemoved,\n onboardingComplete,\n invited,\n inviteAccepted,\n passwordForceReset,\n passwordUpdated,\n passwordResetRequested,\n passwordReset,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n ViewCalculationCreatedEvent,\n ViewCalculationDeletedEvent,\n ViewCalculationUpdatedEvent,\n ViewCreatedEvent,\n ViewDeletedEvent,\n ViewExportedEvent,\n ViewFilterCreatedEvent,\n ViewFilterDeletedEvent,\n ViewFilterUpdatedEvent,\n ViewUpdatedEvent,\n View,\n ViewCalculation,\n Table,\n TableExportFormat,\n} from \"@budibase/types\"\n\n/* eslint-disable */\n\nasync function created(view: View, timestamp?: string | number) {\n const properties: ViewCreatedEvent = {\n tableId: view.tableId,\n }\n await publishEvent(Event.VIEW_CREATED, properties, timestamp)\n}\n\nasync function updated(view: View) {\n const properties: ViewUpdatedEvent = {\n tableId: view.tableId,\n }\n await publishEvent(Event.VIEW_UPDATED, properties)\n}\n\nasync function deleted(view: View) {\n const properties: ViewDeletedEvent = {\n tableId: view.tableId,\n }\n await publishEvent(Event.VIEW_DELETED, properties)\n}\n\nasync function exported(table: Table, format: TableExportFormat) {\n const properties: ViewExportedEvent = {\n tableId: table._id as string,\n format,\n }\n await publishEvent(Event.VIEW_EXPORTED, properties)\n}\n\nasync function filterCreated(view: View, timestamp?: string | number) {\n const properties: ViewFilterCreatedEvent = {\n tableId: view.tableId,\n }\n await publishEvent(Event.VIEW_FILTER_CREATED, properties, timestamp)\n}\n\nasync function filterUpdated(view: View) {\n const properties: ViewFilterUpdatedEvent = {\n tableId: view.tableId,\n }\n await publishEvent(Event.VIEW_FILTER_UPDATED, properties)\n}\n\nasync function filterDeleted(view: View) {\n const properties: ViewFilterDeletedEvent = {\n tableId: view.tableId,\n }\n await publishEvent(Event.VIEW_FILTER_DELETED, properties)\n}\n\nasync function calculationCreated(view: View, timestamp?: string | number) {\n const properties: ViewCalculationCreatedEvent = {\n tableId: view.tableId,\n calculation: view.calculation as ViewCalculation,\n }\n await publishEvent(Event.VIEW_CALCULATION_CREATED, properties, timestamp)\n}\n\nasync function calculationUpdated(view: View) {\n const properties: ViewCalculationUpdatedEvent = {\n tableId: view.tableId,\n calculation: view.calculation as ViewCalculation,\n }\n await publishEvent(Event.VIEW_CALCULATION_UPDATED, properties)\n}\n\nasync function calculationDeleted(existingView: View) {\n const properties: ViewCalculationDeletedEvent = {\n tableId: existingView.tableId,\n calculation: existingView.calculation as ViewCalculation,\n }\n await publishEvent(Event.VIEW_CALCULATION_DELETED, properties)\n}\n\nexport default {\n created,\n updated,\n deleted,\n exported,\n filterCreated,\n filterUpdated,\n filterDeleted,\n calculationCreated,\n calculationUpdated,\n calculationDeleted,\n}\n", "import { publishEvent } from \"../events\"\nimport { Event, VersionCheckedEvent, VersionChangeEvent } from \"@budibase/types\"\n\nasync function versionChecked(version: string) {\n const properties: VersionCheckedEvent = {\n currentVersion: version,\n }\n await publishEvent(Event.INSTALLATION_VERSION_CHECKED, properties)\n}\n\nasync function upgraded(from: string, to: string) {\n const properties: VersionChangeEvent = {\n from,\n to,\n }\n\n await publishEvent(Event.INSTALLATION_VERSION_UPGRADED, properties)\n}\n\nasync function downgraded(from: string, to: string) {\n const properties: VersionChangeEvent = {\n from,\n to,\n }\n await publishEvent(Event.INSTALLATION_VERSION_DOWNGRADED, properties)\n}\n\nasync function firstStartup() {\n const properties = {}\n await publishEvent(Event.INSTALLATION_FIRST_STARTUP, properties)\n}\n\nexport default {\n versionChecked,\n upgraded,\n downgraded,\n firstStartup,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n AppBackfillSucceededEvent,\n AppBackfillFailedEvent,\n TenantBackfillSucceededEvent,\n TenantBackfillFailedEvent,\n InstallationBackfillSucceededEvent,\n InstallationBackfillFailedEvent,\n} from \"@budibase/types\"\nimport env from \"../../environment\"\n\nconst shouldSkip = !env.SELF_HOSTED && !env.isDev()\n\nasync function appSucceeded(properties: AppBackfillSucceededEvent) {\n if (shouldSkip) {\n return\n }\n await publishEvent(Event.APP_BACKFILL_SUCCEEDED, properties)\n}\n\nasync function appFailed(error: any) {\n if (shouldSkip) {\n return\n }\n const properties: AppBackfillFailedEvent = {\n error: JSON.stringify(error, Object.getOwnPropertyNames(error)),\n }\n await publishEvent(Event.APP_BACKFILL_FAILED, properties)\n}\n\nasync function tenantSucceeded(properties: TenantBackfillSucceededEvent) {\n if (shouldSkip) {\n return\n }\n await publishEvent(Event.TENANT_BACKFILL_SUCCEEDED, properties)\n}\n\nasync function tenantFailed(error: any) {\n if (shouldSkip) {\n return\n }\n const properties: TenantBackfillFailedEvent = {\n error: JSON.stringify(error, Object.getOwnPropertyNames(error)),\n }\n await publishEvent(Event.TENANT_BACKFILL_FAILED, properties)\n}\n\nasync function installationSucceeded() {\n if (shouldSkip) {\n return\n }\n const properties: InstallationBackfillSucceededEvent = {}\n await publishEvent(Event.INSTALLATION_BACKFILL_SUCCEEDED, properties)\n}\n\nasync function installationFailed(error: any) {\n if (shouldSkip) {\n return\n }\n const properties: InstallationBackfillFailedEvent = {\n error: JSON.stringify(error, Object.getOwnPropertyNames(error)),\n }\n await publishEvent(Event.INSTALLATION_BACKFILL_FAILED, properties)\n}\n\nexport default {\n appSucceeded,\n appFailed,\n tenantSucceeded,\n tenantFailed,\n installationSucceeded,\n installationFailed,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n UserGroup,\n GroupCreatedEvent,\n GroupDeletedEvent,\n GroupUpdatedEvent,\n GroupUsersAddedEvent,\n GroupUsersDeletedEvent,\n GroupAddedOnboardingEvent,\n GroupPermissionsEditedEvent,\n} from \"@budibase/types\"\nimport { isScim } from \"../../context\"\n\nasync function created(group: UserGroup, timestamp?: number) {\n const properties: GroupCreatedEvent = {\n groupId: group._id as string,\n viaScim: isScim(),\n audited: {\n name: group.name,\n },\n }\n await publishEvent(Event.USER_GROUP_CREATED, properties, timestamp)\n}\n\nasync function updated(group: UserGroup) {\n const properties: GroupUpdatedEvent = {\n groupId: group._id as string,\n viaScim: isScim(),\n audited: {\n name: group.name,\n },\n }\n await publishEvent(Event.USER_GROUP_UPDATED, properties)\n}\n\nasync function deleted(group: UserGroup) {\n const properties: GroupDeletedEvent = {\n groupId: group._id as string,\n viaScim: isScim(),\n audited: {\n name: group.name,\n },\n }\n await publishEvent(Event.USER_GROUP_DELETED, properties)\n}\n\nasync function usersAdded(count: number, group: UserGroup) {\n const properties: GroupUsersAddedEvent = {\n count,\n groupId: group._id as string,\n viaScim: isScim(),\n audited: {\n name: group.name,\n },\n }\n await publishEvent(Event.USER_GROUP_USERS_ADDED, properties)\n}\n\nasync function usersDeleted(count: number, group: UserGroup) {\n const properties: GroupUsersDeletedEvent = {\n count,\n groupId: group._id as string,\n viaScim: isScim(),\n audited: {\n name: group.name,\n },\n }\n await publishEvent(Event.USER_GROUP_USERS_REMOVED, properties)\n}\n\nasync function createdOnboarding(groupId: string) {\n const properties: GroupAddedOnboardingEvent = {\n groupId: groupId,\n onboarding: true,\n }\n await publishEvent(Event.USER_GROUP_ONBOARDING, properties)\n}\n\nasync function permissionsEdited(group: UserGroup) {\n const properties: GroupPermissionsEditedEvent = {\n permissions: group.roles!,\n groupId: group._id as string,\n audited: {\n name: group.name,\n },\n }\n await publishEvent(Event.USER_GROUP_PERMISSIONS_EDITED, properties)\n}\n\nexport default {\n created,\n updated,\n deleted,\n usersAdded,\n usersDeleted,\n createdOnboarding,\n permissionsEdited,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n Plugin,\n PluginDeletedEvent,\n PluginImportedEvent,\n PluginInitEvent,\n} from \"@budibase/types\"\n\nasync function init(plugin: Plugin) {\n const properties: PluginInitEvent = {\n type: plugin.schema.type,\n name: plugin.name,\n description: plugin.description,\n version: plugin.version,\n }\n await publishEvent(Event.PLUGIN_INIT, properties)\n}\n\nasync function imported(plugin: Plugin) {\n const properties: PluginImportedEvent = {\n pluginId: plugin._id as string,\n type: plugin.schema.type,\n source: plugin.source,\n name: plugin.name,\n description: plugin.description,\n version: plugin.version,\n }\n await publishEvent(Event.PLUGIN_IMPORTED, properties)\n}\n\nasync function deleted(plugin: Plugin) {\n const properties: PluginDeletedEvent = {\n pluginId: plugin._id as string,\n type: plugin.schema.type,\n name: plugin.name,\n description: plugin.description,\n version: plugin.version,\n }\n await publishEvent(Event.PLUGIN_DELETED, properties)\n}\n\nexport default {\n init,\n imported,\n deleted,\n}\n", "import {\n AppBackup,\n AppBackupRestoreEvent,\n AppBackupTriggeredEvent,\n AppBackupTrigger,\n AppBackupType,\n Event,\n} from \"@budibase/types\"\nimport { publishEvent } from \"../events\"\n\nasync function appBackupRestored(backup: AppBackup) {\n const properties: AppBackupRestoreEvent = {\n appId: backup.appId,\n restoreId: backup._id!,\n backupCreatedAt: backup.timestamp,\n name: backup.name as string,\n }\n\n await publishEvent(Event.APP_BACKUP_RESTORED, properties)\n}\n\nasync function appBackupTriggered(\n appId: string,\n backupId: string,\n type: AppBackupType,\n trigger: AppBackupTrigger,\n name: string\n) {\n const properties: AppBackupTriggeredEvent = {\n appId: appId,\n backupId,\n type,\n trigger,\n name,\n }\n await publishEvent(Event.APP_BACKUP_TRIGGERED, properties)\n}\n\nexport default {\n appBackupRestored,\n appBackupTriggered,\n}\n", "import {\n Event,\n EnvironmentVariableCreatedEvent,\n EnvironmentVariableDeletedEvent,\n EnvironmentVariableUpgradePanelOpenedEvent,\n} from \"@budibase/types\"\nimport { publishEvent } from \"../events\"\n\nasync function created(name: string, environments: string[]) {\n const properties: EnvironmentVariableCreatedEvent = {\n name,\n environments,\n }\n await publishEvent(Event.ENVIRONMENT_VARIABLE_CREATED, properties)\n}\n\nasync function deleted(name: string) {\n const properties: EnvironmentVariableDeletedEvent = {\n name,\n }\n await publishEvent(Event.ENVIRONMENT_VARIABLE_DELETED, properties)\n}\n\nasync function upgradePanelOpened(userId: string) {\n const properties: EnvironmentVariableUpgradePanelOpenedEvent = {\n userId,\n }\n await publishEvent(\n Event.ENVIRONMENT_VARIABLE_UPGRADE_PANEL_OPENED,\n properties\n )\n}\n\nexport default {\n created,\n deleted,\n upgradePanelOpened,\n}\n", "import {\n Event,\n AuditLogSearchParams,\n AuditLogFilteredEvent,\n AuditLogDownloadedEvent,\n} from \"@budibase/types\"\nimport { publishEvent } from \"../events\"\n\nasync function filtered(search: AuditLogSearchParams) {\n const properties: AuditLogFilteredEvent = {\n filters: search,\n }\n await publishEvent(Event.AUDIT_LOGS_FILTERED, properties)\n}\n\nasync function downloaded(search: AuditLogSearchParams) {\n const properties: AuditLogDownloadedEvent = {\n filters: search,\n }\n await publishEvent(Event.AUDIT_LOGS_DOWNLOADED, properties)\n}\n\nexport default {\n filtered,\n downloaded,\n}\n", "import { DEFAULT_TENANT_ID } from \"../constants\"\nimport {\n DocumentType,\n StaticDatabases,\n getAllApps,\n getGlobalDBName,\n getDB,\n} from \"../db\"\nimport environment from \"../environment\"\nimport * as platform from \"../platform\"\nimport * as context from \"../context\"\nimport { DEFINITIONS } from \".\"\nimport {\n Migration,\n MigrationOptions,\n MigrationType,\n MigrationNoOpOptions,\n App,\n} from \"@budibase/types\"\n\nexport const getMigrationsDoc = async (db: any) => {\n // get the migrations doc\n try {\n return await db.get(DocumentType.MIGRATIONS)\n } catch (err: any) {\n if (err.status && err.status === 404) {\n return { _id: DocumentType.MIGRATIONS }\n } else {\n console.error(err)\n throw err\n }\n }\n}\n\nexport const backPopulateMigrations = async (opts: MigrationNoOpOptions) => {\n // filter migrations to the type and populate a no-op migration\n const migrations: Migration[] = DEFINITIONS.filter(\n def => def.type === opts.type\n ).map(d => ({ ...d, fn: () => {} }))\n await runMigrations(migrations, { noOp: opts })\n}\n\nexport const runMigration = async (\n migration: Migration,\n options: MigrationOptions = {}\n) => {\n const migrationType = migration.type\n let tenantId: string | undefined\n if (migrationType !== MigrationType.INSTALLATION) {\n tenantId = context.getTenantId()\n }\n const migrationName = migration.name\n const silent = migration.silent\n\n const log = (message: string) => {\n if (!silent) {\n console.log(message)\n }\n }\n\n // get the db to store the migration in\n let dbNames: string[]\n if (migrationType === MigrationType.GLOBAL) {\n dbNames = [getGlobalDBName()]\n } else if (migrationType === MigrationType.APP) {\n if (options.noOp) {\n if (!options.noOp.appId) {\n throw new Error(\"appId is required for noOp app migration\")\n }\n dbNames = [options.noOp.appId]\n } else {\n const apps = (await getAllApps(migration.appOpts)) as App[]\n dbNames = apps.map(app => app.appId)\n }\n } else if (migrationType === MigrationType.INSTALLATION) {\n dbNames = [StaticDatabases.PLATFORM_INFO.name]\n } else {\n throw new Error(`Unrecognised migration type [${migrationType}]`)\n }\n\n const length = dbNames.length\n let count = 0\n\n // run the migration against each db\n for (const dbName of dbNames) {\n count++\n const lengthStatement = length > 1 ? `[${count}/${length}]` : \"\"\n\n const db = getDB(dbName)\n\n try {\n const doc = await getMigrationsDoc(db)\n\n // the migration has already been run\n if (doc[migrationName]) {\n // check for force\n if (\n options.force &&\n options.force[migrationType] &&\n options.force[migrationType].includes(migrationName)\n ) {\n log(`[Migration: ${migrationName}] [DB: ${dbName}] Forcing`)\n } else {\n // no force, exit\n return\n }\n }\n\n // check if the migration is not a no-op\n if (!options.noOp) {\n log(\n `[Migration: ${migrationName}] [DB: ${dbName}] Running ${lengthStatement}`\n )\n\n if (migration.preventRetry) {\n // eagerly set the completion date\n // so that we never run this migration twice even upon failure\n doc[migrationName] = Date.now()\n const response = await db.put(doc)\n doc._rev = response.rev\n }\n\n // run the migration\n if (migrationType === MigrationType.APP) {\n await context.doInAppContext(db.name, async () => {\n await migration.fn(db)\n })\n } else {\n await migration.fn(db)\n }\n\n log(`[Migration: ${migrationName}] [DB: ${dbName}] Complete`)\n }\n\n // mark as complete\n doc[migrationName] = Date.now()\n await db.put(doc)\n } catch (err) {\n console.error(\n `[Migration: ${migrationName}] [DB: ${dbName}] Error: `,\n err\n )\n throw err\n }\n }\n}\n\nexport const runMigrations = async (\n migrations: Migration[],\n options: MigrationOptions = {}\n) => {\n let tenantIds\n\n if (environment.MULTI_TENANCY) {\n if (options.noOp) {\n tenantIds = [options.noOp.tenantId]\n } else if (!options.tenantIds || !options.tenantIds.length) {\n // run for all tenants\n tenantIds = await platform.tenants.getTenantIds()\n } else {\n tenantIds = options.tenantIds\n }\n } else {\n // single tenancy\n tenantIds = [DEFAULT_TENANT_ID]\n }\n\n if (tenantIds.length > 1) {\n console.log(`Checking migrations for ${tenantIds.length} tenants`)\n } else {\n console.log(\"Checking migrations\")\n }\n\n let count = 0\n // for all tenants\n for (const tenantId of tenantIds) {\n count++\n if (tenantIds.length > 1) {\n console.log(`Progress [${count}/${tenantIds.length}]`)\n }\n // for all migrations\n for (const migration of migrations) {\n // run the migration\n await context.doInTenant(\n tenantId,\n async () => await runMigration(migration, options)\n )\n }\n }\n console.log(\"Migrations complete\")\n}\n", "import {\n MigrationType,\n MigrationName,\n MigrationDefinition,\n} from \"@budibase/types\"\n\nexport const DEFINITIONS: MigrationDefinition[] = [\n {\n type: MigrationType.GLOBAL,\n name: MigrationName.USER_EMAIL_VIEW_CASING,\n },\n {\n type: MigrationType.GLOBAL,\n name: MigrationName.SYNC_QUOTAS,\n },\n {\n type: MigrationType.APP,\n name: MigrationName.APP_URLS,\n },\n {\n type: MigrationType.APP,\n name: MigrationName.EVENT_APP_BACKFILL,\n },\n {\n type: MigrationType.APP,\n name: MigrationName.TABLE_SETTINGS_LINKS_TO_ACTIONS,\n },\n {\n type: MigrationType.GLOBAL,\n name: MigrationName.EVENT_GLOBAL_BACKFILL,\n },\n {\n type: MigrationType.INSTALLATION,\n name: MigrationName.EVENT_INSTALLATION_BACKFILL,\n },\n {\n type: MigrationType.GLOBAL,\n name: MigrationName.GLOBAL_INFO_SYNC_USERS,\n },\n]\n", "import {\n directCouchFind,\n DocumentType,\n generateAppUserID,\n getGlobalUserParams,\n getProdAppID,\n getUsersByAppParams,\n pagination,\n queryGlobalView,\n queryGlobalViewRaw,\n SEPARATOR,\n UNICODE_MAX,\n ViewName,\n} from \"./db\"\nimport { BulkDocsResponse, SearchUsersRequest, User } from \"@budibase/types\"\nimport { getGlobalDB } from \"./context\"\nimport * as context from \"./context\"\n\ntype GetOpts = { cleanup?: boolean }\n\nfunction removeUserPassword(users: User | User[]) {\n if (Array.isArray(users)) {\n return users.map(user => {\n if (user) {\n delete user.password\n return user\n }\n })\n } else if (users) {\n delete users.password\n return users\n }\n return users\n}\n\nexport const bulkGetGlobalUsersById = async (\n userIds: string[],\n opts?: GetOpts\n) => {\n const db = getGlobalDB()\n let users = (\n await db.allDocs({\n keys: userIds,\n include_docs: true,\n })\n ).rows.map(row => row.doc) as User[]\n if (opts?.cleanup) {\n users = removeUserPassword(users) as User[]\n }\n return users\n}\n\nexport const getAllUserIds = async () => {\n const db = getGlobalDB()\n const startKey = `${DocumentType.USER}${SEPARATOR}`\n const response = await db.allDocs({\n startkey: startKey,\n endkey: `${startKey}${UNICODE_MAX}`,\n })\n return response.rows.map(row => row.id)\n}\n\nexport const bulkUpdateGlobalUsers = async (users: User[]) => {\n const db = getGlobalDB()\n return (await db.bulkDocs(users)) as BulkDocsResponse\n}\n\nexport async function getById(id: string, opts?: GetOpts): Promise<User> {\n const db = context.getGlobalDB()\n let user = await db.get(id)\n if (opts?.cleanup) {\n user = removeUserPassword(user)\n }\n return user\n}\n\n/**\n * Given an email address this will use a view to search through\n * all the users to find one with this email address.\n */\nexport const getGlobalUserByEmail = async (\n email: String,\n opts?: GetOpts\n): Promise<User | undefined> => {\n if (email == null) {\n throw \"Must supply an email address to view\"\n }\n\n const response = await queryGlobalView<User>(ViewName.USER_BY_EMAIL, {\n key: email.toLowerCase(),\n include_docs: true,\n })\n\n if (Array.isArray(response)) {\n // shouldn't be able to happen, but need to handle just in case\n throw new Error(`Multiple users found with email address: ${email}`)\n }\n\n let user = response as User\n if (opts?.cleanup) {\n user = removeUserPassword(user) as User\n }\n\n return user\n}\n\nexport const searchGlobalUsersByApp = async (\n appId: any,\n opts: any,\n getOpts?: GetOpts\n) => {\n if (typeof appId !== \"string\") {\n throw new Error(\"Must provide a string based app ID\")\n }\n const params = getUsersByAppParams(appId, {\n include_docs: true,\n })\n params.startkey = opts && opts.startkey ? opts.startkey : params.startkey\n let response = await queryGlobalView(ViewName.USER_BY_APP, params)\n\n if (!response) {\n response = []\n }\n let users: User[] = Array.isArray(response) ? response : [response]\n if (getOpts?.cleanup) {\n users = removeUserPassword(users) as User[]\n }\n return users\n}\n\n/*\n Return any user who potentially has access to the application\n Admins, developers and app users with the explicitly role.\n*/\nexport const searchGlobalUsersByAppAccess = async (appId: any, opts: any) => {\n const roleSelector = `roles.${appId}`\n\n let orQuery: any[] = [\n {\n \"builder.global\": true,\n },\n {\n \"admin.global\": true,\n },\n ]\n\n if (appId) {\n const roleCheck = {\n [roleSelector]: {\n $exists: true,\n },\n }\n orQuery.push(roleCheck)\n }\n\n let searchOptions = {\n selector: {\n $or: orQuery,\n _id: {\n $regex: \"^us_\",\n },\n },\n limit: opts?.limit || 50,\n }\n\n const resp = await directCouchFind(context.getGlobalDBName(), searchOptions)\n return resp?.rows\n}\n\nexport const getGlobalUserByAppPage = (appId: string, user: User) => {\n if (!user) {\n return\n }\n return generateAppUserID(getProdAppID(appId)!, user._id!)\n}\n\n/**\n * Performs a starts with search on the global email view.\n */\nexport const searchGlobalUsersByEmail = async (\n email: string,\n opts: any,\n getOpts?: GetOpts\n) => {\n if (typeof email !== \"string\") {\n throw new Error(\"Must provide a string to search by\")\n }\n const lcEmail = email.toLowerCase()\n // handle if passing up startkey for pagination\n const startkey = opts && opts.startkey ? opts.startkey : lcEmail\n let response = await queryGlobalView<User>(ViewName.USER_BY_EMAIL, {\n ...opts,\n startkey,\n endkey: `${lcEmail}${UNICODE_MAX}`,\n })\n if (!response) {\n response = []\n }\n let users: User[] = Array.isArray(response) ? response : [response]\n if (getOpts?.cleanup) {\n users = removeUserPassword(users) as User[]\n }\n return users\n}\n\nconst PAGE_LIMIT = 8\nexport const paginatedUsers = async ({\n page,\n email,\n appId,\n}: SearchUsersRequest = {}) => {\n const db = getGlobalDB()\n // get one extra document, to have the next page\n const opts: any = {\n include_docs: true,\n limit: PAGE_LIMIT + 1,\n }\n // add a startkey if the page was specified (anchor)\n if (page) {\n opts.startkey = page\n }\n // property specifies what to use for the page/anchor\n let userList: User[],\n property = \"_id\",\n getKey\n if (appId) {\n userList = await searchGlobalUsersByApp(appId, opts)\n getKey = (doc: any) => getGlobalUserByAppPage(appId, doc)\n } else if (email) {\n userList = await searchGlobalUsersByEmail(email, opts)\n property = \"email\"\n } else {\n // no search, query allDocs\n const response = await db.allDocs(getGlobalUserParams(null, opts))\n userList = response.rows.map((row: any) => row.doc)\n }\n return pagination(userList, PAGE_LIMIT, {\n paginate: true,\n property,\n getKey,\n })\n}\n\nexport async function getUserCount() {\n const response = await queryGlobalViewRaw(ViewName.USER_BY_EMAIL, {\n limit: 0, // to be as fast as possible - we just want the total rows count\n include_docs: false,\n })\n return response.total_rows\n}\n", "import { BuiltinPermissionID, PermissionLevel } from \"./permissions\"\nimport { generateRoleID, getRoleParams, DocumentType, SEPARATOR } from \"../db\"\nimport { getAppDB } from \"../context\"\nimport { doWithDB } from \"../db\"\nimport { Screen, Role as RoleDoc } from \"@budibase/types\"\nconst { cloneDeep } = require(\"lodash/fp\")\n\nexport const BUILTIN_ROLE_IDS = {\n ADMIN: \"ADMIN\",\n POWER: \"POWER\",\n BASIC: \"BASIC\",\n PUBLIC: \"PUBLIC\",\n}\n\nconst BUILTIN_IDS = {\n ...BUILTIN_ROLE_IDS,\n BUILDER: \"BUILDER\",\n}\n\n// exclude internal roles like builder\nconst EXTERNAL_BUILTIN_ROLE_IDS = [\n BUILTIN_IDS.ADMIN,\n BUILTIN_IDS.POWER,\n BUILTIN_IDS.BASIC,\n BUILTIN_IDS.PUBLIC,\n]\n\nexport class Role implements RoleDoc {\n _id: string\n _rev?: string\n name: string\n permissionId: string\n inherits?: string\n permissions = {}\n\n constructor(id: string, name: string, permissionId: string) {\n this._id = id\n this.name = name\n this.permissionId = permissionId\n }\n\n addInheritance(inherits: string) {\n this.inherits = inherits\n return this\n }\n}\n\nconst BUILTIN_ROLES = {\n ADMIN: new Role(\n BUILTIN_IDS.ADMIN,\n \"Admin\",\n BuiltinPermissionID.ADMIN\n ).addInheritance(BUILTIN_IDS.POWER),\n POWER: new Role(\n BUILTIN_IDS.POWER,\n \"Power\",\n BuiltinPermissionID.POWER\n ).addInheritance(BUILTIN_IDS.BASIC),\n BASIC: new Role(\n BUILTIN_IDS.BASIC,\n \"Basic\",\n BuiltinPermissionID.WRITE\n ).addInheritance(BUILTIN_IDS.PUBLIC),\n PUBLIC: new Role(BUILTIN_IDS.PUBLIC, \"Public\", BuiltinPermissionID.PUBLIC),\n BUILDER: new Role(BUILTIN_IDS.BUILDER, \"Builder\", BuiltinPermissionID.ADMIN),\n}\n\nexport function getBuiltinRoles(): { [key: string]: RoleDoc } {\n return cloneDeep(BUILTIN_ROLES)\n}\n\nexport const BUILTIN_ROLE_ID_ARRAY = Object.values(BUILTIN_ROLES).map(\n role => role._id\n)\n\nexport const BUILTIN_ROLE_NAME_ARRAY = Object.values(BUILTIN_ROLES).map(\n role => role.name\n)\n\nexport function isBuiltin(role?: string) {\n return BUILTIN_ROLE_ID_ARRAY.some(builtin => role?.includes(builtin))\n}\n\n/**\n * Works through the inheritance ranks to see how far up the builtin stack this ID is.\n */\nexport function builtinRoleToNumber(id?: string) {\n if (!id) {\n return 0\n }\n const builtins = getBuiltinRoles()\n const MAX = Object.values(builtins).length + 1\n if (id === BUILTIN_IDS.ADMIN || id === BUILTIN_IDS.BUILDER) {\n return MAX\n }\n let role = builtins[id],\n count = 0\n do {\n if (!role) {\n break\n }\n role = builtins[role.inherits!]\n count++\n } while (role !== null)\n return count\n}\n\n/**\n * Converts any role to a number, but has to be async to get the roles from db.\n */\nexport async function roleToNumber(id?: string) {\n if (isBuiltin(id)) {\n return builtinRoleToNumber(id)\n }\n const hierarchy = (await getUserRoleHierarchy(id)) as RoleDoc[]\n for (let role of hierarchy) {\n if (isBuiltin(role?.inherits)) {\n return builtinRoleToNumber(role.inherits) + 1\n }\n }\n return 0\n}\n\n/**\n * Returns whichever builtin roleID is lower.\n */\nexport function lowerBuiltinRoleID(roleId1?: string, roleId2?: string): string {\n if (!roleId1) {\n return roleId2 as string\n }\n if (!roleId2) {\n return roleId1 as string\n }\n return builtinRoleToNumber(roleId1) > builtinRoleToNumber(roleId2)\n ? roleId2\n : roleId1\n}\n\n/**\n * Gets the role object, this is mainly useful for two purposes, to check if the level exists and\n * to check if the role inherits any others.\n * @param {string|null} roleId The level ID to lookup.\n * @returns {Promise<Role|object|null>} The role object, which may contain an \"inherits\" property.\n */\nexport async function getRole(roleId?: string): Promise<RoleDoc | undefined> {\n if (!roleId) {\n return undefined\n }\n let role: any = {}\n // built in roles mostly come from the in-code implementation,\n // but can be extended by a doc stored about them (e.g. permissions)\n if (isBuiltin(roleId)) {\n role = cloneDeep(\n Object.values(BUILTIN_ROLES).find(role => role._id === roleId)\n )\n }\n try {\n const db = getAppDB()\n const dbRole = await db.get(getDBRoleID(roleId))\n role = Object.assign(role, dbRole)\n // finalise the ID\n role._id = getExternalRoleID(role._id)\n } catch (err) {\n // only throw an error if there is no role at all\n if (Object.keys(role).length === 0) {\n throw err\n }\n }\n return role\n}\n\n/**\n * Simple function to get all the roles based on the top level user role ID.\n */\nasync function getAllUserRoles(userRoleId?: string): Promise<RoleDoc[]> {\n // admins have access to all roles\n if (userRoleId === BUILTIN_IDS.ADMIN) {\n return getAllRoles()\n }\n let currentRole = await getRole(userRoleId)\n let roles = currentRole ? [currentRole] : []\n let roleIds = [userRoleId]\n // get all the inherited roles\n while (\n currentRole &&\n currentRole.inherits &&\n roleIds.indexOf(currentRole.inherits) === -1\n ) {\n roleIds.push(currentRole.inherits)\n currentRole = await getRole(currentRole.inherits)\n if (currentRole) {\n roles.push(currentRole)\n }\n }\n return roles\n}\n\n/**\n * Returns an ordered array of the user's inherited role IDs, this can be used\n * to determine if a user can access something that requires a specific role.\n * @param {string} userRoleId The user's role ID, this can be found in their access token.\n * @param {object} opts Various options, such as whether to only retrieve the IDs (default true).\n * @returns {Promise<string[]|object[]>} returns an ordered array of the roles, with the first being their\n * highest level of access and the last being the lowest level.\n */\nexport async function getUserRoleHierarchy(\n userRoleId?: string,\n opts = { idOnly: true }\n) {\n // special case, if they don't have a role then they are a public user\n const roles = await getAllUserRoles(userRoleId)\n return opts.idOnly ? roles.map(role => role._id) : roles\n}\n\n// this function checks that the provided permissions are in an array format\n// some templates/older apps will use a simple string instead of array for roles\n// convert the string to an array using the theory that write is higher than read\nexport function checkForRoleResourceArray(\n rolePerms: { [key: string]: string[] },\n resourceId: string\n) {\n if (rolePerms && !Array.isArray(rolePerms[resourceId])) {\n const permLevel = rolePerms[resourceId] as any\n rolePerms[resourceId] = [permLevel]\n if (permLevel === PermissionLevel.WRITE) {\n rolePerms[resourceId].push(PermissionLevel.READ)\n }\n }\n return rolePerms\n}\n\n/**\n * Given an app ID this will retrieve all of the roles that are currently within that app.\n * @return {Promise<object[]>} An array of the role objects that were found.\n */\nexport async function getAllRoles(appId?: string) {\n if (appId) {\n return doWithDB(appId, internal)\n } else {\n let appDB\n try {\n appDB = getAppDB()\n } catch (error) {\n // We don't have any apps, so we'll just use the built-in roles\n }\n return internal(appDB)\n }\n async function internal(db: any) {\n let roles: RoleDoc[] = []\n if (db) {\n const body = await db.allDocs(\n getRoleParams(null, {\n include_docs: true,\n })\n )\n roles = body.rows.map((row: any) => row.doc)\n }\n const builtinRoles = getBuiltinRoles()\n\n // need to combine builtin with any DB record of them (for sake of permissions)\n for (let builtinRoleId of EXTERNAL_BUILTIN_ROLE_IDS) {\n const builtinRole = builtinRoles[builtinRoleId]\n const dbBuiltin = roles.filter(\n dbRole => getExternalRoleID(dbRole._id) === builtinRoleId\n )[0]\n if (dbBuiltin == null) {\n roles.push(builtinRole || builtinRoles.BASIC)\n } else {\n // remove role and all back after combining with the builtin\n roles = roles.filter(role => role._id !== dbBuiltin._id)\n dbBuiltin._id = getExternalRoleID(dbBuiltin._id)\n roles.push(Object.assign(builtinRole, dbBuiltin))\n }\n }\n // check permissions\n for (let role of roles) {\n if (!role.permissions) {\n continue\n }\n for (let resourceId of Object.keys(role.permissions)) {\n role.permissions = checkForRoleResourceArray(\n role.permissions,\n resourceId\n )\n }\n }\n return roles\n }\n}\n\n/**\n * This retrieves the required role for a resource\n * @param permLevel The level of request\n * @param resourceId The resource being requested\n * @param subResourceId The sub resource being requested\n * @return {Promise<{permissions}|Object>} returns the permissions required to access.\n */\nexport async function getRequiredResourceRole(\n permLevel: string,\n { resourceId, subResourceId }: { resourceId?: string; subResourceId?: string }\n) {\n const roles = await getAllRoles()\n let main = [],\n sub = []\n for (let role of roles) {\n // no permissions, ignore it\n if (!role.permissions) {\n continue\n }\n const mainRes = resourceId ? role.permissions[resourceId] : undefined\n const subRes = subResourceId ? role.permissions[subResourceId] : undefined\n if (mainRes && mainRes.indexOf(permLevel) !== -1) {\n main.push(role._id)\n } else if (subRes && subRes.indexOf(permLevel) !== -1) {\n sub.push(role._id)\n }\n }\n // for now just return the IDs\n return main.concat(sub)\n}\n\nexport class AccessController {\n userHierarchies: { [key: string]: string[] }\n constructor() {\n this.userHierarchies = {}\n }\n\n async hasAccess(tryingRoleId?: string, userRoleId?: string) {\n // special cases, the screen has no role, the roles are the same or the user\n // is currently in the builder\n if (\n tryingRoleId == null ||\n tryingRoleId === \"\" ||\n tryingRoleId === userRoleId ||\n tryingRoleId === BUILTIN_IDS.BUILDER ||\n userRoleId === BUILTIN_IDS.BUILDER\n ) {\n return true\n }\n let roleIds = userRoleId ? this.userHierarchies[userRoleId] : null\n if (!roleIds && userRoleId) {\n roleIds = (await getUserRoleHierarchy(userRoleId, {\n idOnly: true,\n })) as string[]\n this.userHierarchies[userRoleId] = roleIds\n }\n\n return roleIds?.indexOf(tryingRoleId) !== -1\n }\n\n async checkScreensAccess(screens: Screen[], userRoleId: string) {\n let accessibleScreens = []\n // don't want to handle this with Promise.all as this would mean all custom roles would be\n // retrieved at same time, it is likely a custom role will be re-used and therefore want\n // to work in sync for performance save\n for (let screen of screens) {\n const accessible = await this.checkScreenAccess(screen, userRoleId)\n if (accessible) {\n accessibleScreens.push(accessible)\n }\n }\n return accessibleScreens\n }\n\n async checkScreenAccess(screen: Screen, userRoleId: string) {\n const roleId = screen && screen.routing ? screen.routing.roleId : undefined\n if (await this.hasAccess(roleId, userRoleId)) {\n return screen\n }\n return null\n }\n}\n\n/**\n * Adds the \"role_\" for builtin role IDs which are to be written to the DB (for permissions).\n */\nexport function getDBRoleID(roleId?: string) {\n if (roleId?.startsWith(DocumentType.ROLE)) {\n return roleId\n }\n return generateRoleID(roleId)\n}\n\n/**\n * Remove the \"role_\" from builtin role IDs that have been written to the DB (for permissions).\n */\nexport function getExternalRoleID(roleId?: string) {\n // for built-in roles we want to remove the DB role ID element (role_)\n if (roleId?.startsWith(DocumentType.ROLE) && isBuiltin(roleId)) {\n return roleId.split(`${DocumentType.ROLE}${SEPARATOR}`)[1]\n }\n return roleId\n}\n", "const { flatten } = require(\"lodash\")\nconst { cloneDeep } = require(\"lodash/fp\")\n\nexport type RoleHierarchy = {\n permissionId: string\n}[]\n\nexport enum PermissionLevel {\n READ = \"read\",\n WRITE = \"write\",\n EXECUTE = \"execute\",\n ADMIN = \"admin\",\n}\n\n// these are the global types, that govern the underlying default behaviour\nexport enum PermissionType {\n APP = \"app\",\n TABLE = \"table\",\n USER = \"user\",\n AUTOMATION = \"automation\",\n WEBHOOK = \"webhook\",\n BUILDER = \"builder\",\n VIEW = \"view\",\n QUERY = \"query\",\n}\n\nexport class Permission {\n type: PermissionType\n level: PermissionLevel\n\n constructor(type: PermissionType, level: PermissionLevel) {\n this.type = type\n this.level = level\n }\n}\n\nexport function levelToNumber(perm: PermissionLevel) {\n switch (perm) {\n // not everything has execute privileges\n case PermissionLevel.EXECUTE:\n return 0\n case PermissionLevel.READ:\n return 1\n case PermissionLevel.WRITE:\n return 2\n case PermissionLevel.ADMIN:\n return 3\n default:\n return -1\n }\n}\n\n/**\n * Given the specified permission level for the user return the levels they are allowed to carry out.\n * @param {string} userPermLevel The permission level of the user.\n * @return {string[]} All the permission levels this user is allowed to carry out.\n */\nexport function getAllowedLevels(userPermLevel: PermissionLevel): string[] {\n switch (userPermLevel) {\n case PermissionLevel.EXECUTE:\n return [PermissionLevel.EXECUTE]\n case PermissionLevel.READ:\n return [PermissionLevel.EXECUTE, PermissionLevel.READ]\n case PermissionLevel.WRITE:\n case PermissionLevel.ADMIN:\n return [\n PermissionLevel.EXECUTE,\n PermissionLevel.READ,\n PermissionLevel.WRITE,\n ]\n default:\n return []\n }\n}\n\nexport enum BuiltinPermissionID {\n PUBLIC = \"public\",\n READ_ONLY = \"read_only\",\n WRITE = \"write\",\n ADMIN = \"admin\",\n POWER = \"power\",\n}\n\nexport const BUILTIN_PERMISSIONS = {\n PUBLIC: {\n _id: BuiltinPermissionID.PUBLIC,\n name: \"Public\",\n permissions: [\n new Permission(PermissionType.WEBHOOK, PermissionLevel.EXECUTE),\n ],\n },\n READ_ONLY: {\n _id: BuiltinPermissionID.READ_ONLY,\n name: \"Read only\",\n permissions: [\n new Permission(PermissionType.QUERY, PermissionLevel.READ),\n new Permission(PermissionType.TABLE, PermissionLevel.READ),\n new Permission(PermissionType.VIEW, PermissionLevel.READ),\n ],\n },\n WRITE: {\n _id: BuiltinPermissionID.WRITE,\n name: \"Read/Write\",\n permissions: [\n new Permission(PermissionType.QUERY, PermissionLevel.WRITE),\n new Permission(PermissionType.TABLE, PermissionLevel.WRITE),\n new Permission(PermissionType.VIEW, PermissionLevel.READ),\n new Permission(PermissionType.AUTOMATION, PermissionLevel.EXECUTE),\n ],\n },\n POWER: {\n _id: BuiltinPermissionID.POWER,\n name: \"Power\",\n permissions: [\n new Permission(PermissionType.TABLE, PermissionLevel.WRITE),\n new Permission(PermissionType.USER, PermissionLevel.READ),\n new Permission(PermissionType.AUTOMATION, PermissionLevel.EXECUTE),\n new Permission(PermissionType.VIEW, PermissionLevel.READ),\n new Permission(PermissionType.WEBHOOK, PermissionLevel.READ),\n ],\n },\n ADMIN: {\n _id: BuiltinPermissionID.ADMIN,\n name: \"Admin\",\n permissions: [\n new Permission(PermissionType.TABLE, PermissionLevel.ADMIN),\n new Permission(PermissionType.USER, PermissionLevel.ADMIN),\n new Permission(PermissionType.AUTOMATION, PermissionLevel.ADMIN),\n new Permission(PermissionType.VIEW, PermissionLevel.ADMIN),\n new Permission(PermissionType.WEBHOOK, PermissionLevel.READ),\n new Permission(PermissionType.QUERY, PermissionLevel.ADMIN),\n ],\n },\n}\n\nexport function getBuiltinPermissions() {\n return cloneDeep(BUILTIN_PERMISSIONS)\n}\n\nexport function getBuiltinPermissionByID(id: string) {\n const perms = Object.values(BUILTIN_PERMISSIONS)\n return perms.find(perm => perm._id === id)\n}\n\nexport function doesHaveBasePermission(\n permType: PermissionType,\n permLevel: PermissionLevel,\n rolesHierarchy: RoleHierarchy\n) {\n const basePermissions = [\n ...new Set(rolesHierarchy.map(role => role.permissionId)),\n ]\n const builtins = Object.values(BUILTIN_PERMISSIONS)\n let permissions = flatten(\n builtins\n .filter(builtin => basePermissions.indexOf(builtin._id) !== -1)\n .map(builtin => builtin.permissions)\n )\n for (let permission of permissions) {\n if (\n permission.type === permType &&\n getAllowedLevels(permission.level).indexOf(permLevel) !== -1\n ) {\n return true\n }\n }\n return false\n}\n\nexport function isPermissionLevelHigherThanRead(level: PermissionLevel) {\n return levelToNumber(level) > 1\n}\n\n// utility as a lot of things need simply the builder permission\nexport const BUILDER = PermissionType.BUILDER\n", "import env from \"../environment\"\nimport * as context from \"../context\"\n\n/**\n * Read the TENANT_FEATURE_FLAGS env var and return an array of features flags for each tenant.\n * The env var is formatted as:\n * tenant1:feature1:feature2,tenant2:feature1\n */\nexport function buildFeatureFlags() {\n if (!env.TENANT_FEATURE_FLAGS) {\n return\n }\n\n const tenantFeatureFlags: Record<string, string[]> = {}\n\n env.TENANT_FEATURE_FLAGS.split(\",\").forEach(tenantToFeatures => {\n const [tenantId, ...features] = tenantToFeatures.split(\":\")\n\n features.forEach(feature => {\n if (!tenantFeatureFlags[tenantId]) {\n tenantFeatureFlags[tenantId] = []\n }\n tenantFeatureFlags[tenantId].push(feature)\n })\n })\n\n return tenantFeatureFlags\n}\n\nexport function isEnabled(featureFlag: string) {\n const tenantId = context.getTenantId()\n const flags = getTenantFeatureFlags(tenantId)\n return flags.includes(featureFlag)\n}\n\nexport function getTenantFeatureFlags(tenantId: string) {\n let flags: string[] = []\n const envFlags = buildFeatureFlags()\n if (envFlags) {\n const globalFlags = envFlags[\"*\"]\n const tenantFlags = envFlags[tenantId] || []\n\n // Explicitly exclude tenants from global features if required.\n // Prefix the tenant flag with '!'\n const tenantOverrides = tenantFlags.reduce(\n (acc: string[], flag: string) => {\n if (flag.startsWith(\"!\")) {\n let stripped = flag.substring(1)\n acc.push(stripped)\n }\n return acc\n },\n []\n )\n\n if (globalFlags) {\n flags.push(...globalFlags)\n }\n if (tenantFlags.length) {\n flags.push(...tenantFlags)\n }\n\n // Purge any tenant specific overrides\n flags = flags.filter(flag => {\n return tenantOverrides.indexOf(flag) == -1 && !flag.startsWith(\"!\")\n })\n }\n\n return flags\n}\n\nexport enum TenantFeatureFlag {\n LICENSING = \"LICENSING\",\n GOOGLE_SHEETS = \"GOOGLE_SHEETS\",\n USER_GROUPS = \"USER_GROUPS\",\n ONBOARDING_TOUR = \"ONBOARDING_TOUR\",\n}\n", "const redis = require(\"../redis/init\")\nconst { v4: uuidv4 } = require(\"uuid\")\nconst { logWarn } = require(\"../logging\")\nimport env from \"../environment\"\nimport {\n Session,\n ScannedSession,\n SessionKey,\n CreateSession,\n} from \"@budibase/types\"\n\n// a week in seconds\nconst EXPIRY_SECONDS = 86400 * 7\n\nfunction makeSessionID(userId: string, sessionId: string) {\n return `${userId}/${sessionId}`\n}\n\nexport async function getSessionsForUser(userId: string): Promise<Session[]> {\n if (!userId) {\n console.trace(\"Cannot get sessions for undefined userId\")\n return []\n }\n const client = await redis.getSessionClient()\n const sessions: ScannedSession[] = await client.scan(userId)\n return sessions.map(session => session.value)\n}\n\nexport async function invalidateSessions(\n userId: string,\n opts: { sessionIds?: string[]; reason?: string } = {}\n) {\n try {\n const reason = opts?.reason || \"unknown\"\n let sessionIds: string[] = opts.sessionIds || []\n let sessionKeys: SessionKey[]\n\n // If no sessionIds, get all the sessions for the user\n if (sessionIds.length === 0) {\n const sessions = await getSessionsForUser(userId)\n sessionKeys = sessions.map(session => ({\n key: makeSessionID(session.userId, session.sessionId),\n }))\n } else {\n // use the passed array of sessionIds\n sessionIds = Array.isArray(sessionIds) ? sessionIds : [sessionIds]\n sessionKeys = sessionIds.map(sessionId => ({\n key: makeSessionID(userId, sessionId),\n }))\n }\n\n if (sessionKeys && sessionKeys.length > 0) {\n const client = await redis.getSessionClient()\n const promises = []\n for (let sessionKey of sessionKeys) {\n promises.push(client.delete(sessionKey.key))\n }\n if (!env.isTest()) {\n logWarn(\n `Invalidating sessions for ${userId} (reason: ${reason}) - ${sessionKeys\n .map(sessionKey => sessionKey.key)\n .join(\", \")}`\n )\n }\n await Promise.all(promises)\n }\n } catch (err) {\n console.error(`Error invalidating sessions: ${err}`)\n }\n}\n\nexport async function createASession(\n userId: string,\n createSession: CreateSession\n) {\n // invalidate all other sessions\n await invalidateSessions(userId, { reason: \"creation\" })\n\n const client = await redis.getSessionClient()\n const sessionId = createSession.sessionId\n const csrfToken = createSession.csrfToken ? createSession.csrfToken : uuidv4()\n const key = makeSessionID(userId, sessionId)\n\n const session: Session = {\n ...createSession,\n csrfToken,\n createdAt: new Date().toISOString(),\n lastAccessedAt: new Date().toISOString(),\n userId,\n }\n await client.store(key, session, EXPIRY_SECONDS)\n return session\n}\n\nexport async function updateSessionTTL(session: Session) {\n const client = await redis.getSessionClient()\n const key = makeSessionID(session.userId, session.sessionId)\n session.lastAccessedAt = new Date().toISOString()\n await client.store(key, session, EXPIRY_SECONDS)\n}\n\nexport async function endSession(userId: string, sessionId: string) {\n const client = await redis.getSessionClient()\n await client.delete(makeSessionID(userId, sessionId))\n}\n\nexport async function getSession(\n userId: string,\n sessionId: string\n): Promise<Session> {\n if (!userId || !sessionId) {\n throw new Error(`Invalid session details - ${userId} - ${sessionId}`)\n }\n const client = await redis.getSessionClient()\n const session = await client.get(makeSessionID(userId, sessionId))\n if (!session) {\n throw new Error(`Session not found - ${userId} - ${sessionId}`)\n }\n return session\n}\n", "export * from \"./auth\"\n", "const _passport = require(\"koa-passport\")\nconst LocalStrategy = require(\"passport-local\").Strategy\nimport { getGlobalDB } from \"../context\"\nimport { Cookie } from \"../constants\"\nimport { getSessionsForUser, invalidateSessions } from \"../security/sessions\"\nimport {\n authenticated,\n csrf,\n google,\n local,\n oidc,\n tenancy,\n} from \"../middleware\"\nimport * as userCache from \"../cache/user\"\nimport { invalidateUser } from \"../cache/user\"\nimport {\n ConfigType,\n GoogleInnerConfig,\n OIDCInnerConfig,\n PlatformLogoutOpts,\n SSOProviderType,\n} from \"@budibase/types\"\nimport * as events from \"../events\"\nimport * as configs from \"../configs\"\nimport { clearCookie, getCookie } from \"../utils\"\nimport { ssoSaveUserNoOp } from \"../middleware/passport/sso/sso\"\n\nconst refresh = require(\"passport-oauth2-refresh\")\nexport {\n auditLog,\n authError,\n internalApi,\n ssoCallbackUrl,\n adminOnly,\n builderOnly,\n builderOrAdmin,\n joiValidator,\n google,\n oidc,\n} from \"../middleware\"\nexport const buildAuthMiddleware = authenticated\nexport const buildTenancyMiddleware = tenancy\nexport const buildCsrfMiddleware = csrf\nexport const passport = _passport\nexport const jwt = require(\"jsonwebtoken\")\n\n// Strategies\n_passport.use(new LocalStrategy(local.options, local.authenticate))\n\nasync function refreshOIDCAccessToken(\n chosenConfig: OIDCInnerConfig,\n refreshToken: string\n): Promise<RefreshResponse> {\n const callbackUrl = await oidc.getCallbackUrl()\n let enrichedConfig: any\n let strategy: any\n\n try {\n enrichedConfig = await oidc.fetchStrategyConfig(chosenConfig, callbackUrl)\n if (!enrichedConfig) {\n throw new Error(\"OIDC Config contents invalid\")\n }\n strategy = await oidc.strategyFactory(enrichedConfig, ssoSaveUserNoOp)\n } catch (err) {\n console.error(err)\n throw new Error(\"Could not refresh OAuth Token\")\n }\n\n refresh.use(strategy, {\n setRefreshOAuth2() {\n return strategy._getOAuth2Client(enrichedConfig)\n },\n })\n\n return new Promise(resolve => {\n refresh.requestNewAccessToken(\n ConfigType.OIDC,\n refreshToken,\n (err: any, accessToken: string, refreshToken: any, params: any) => {\n resolve({ err, accessToken, refreshToken, params })\n }\n )\n })\n}\n\nasync function refreshGoogleAccessToken(\n config: GoogleInnerConfig,\n refreshToken: any\n): Promise<RefreshResponse> {\n let callbackUrl = await google.getCallbackUrl(config)\n\n let strategy\n try {\n strategy = await google.strategyFactory(\n config,\n callbackUrl,\n ssoSaveUserNoOp\n )\n } catch (err: any) {\n console.error(err)\n throw new Error(\n `Error constructing OIDC refresh strategy: message=${err.message}`\n )\n }\n\n refresh.use(strategy)\n\n return new Promise(resolve => {\n refresh.requestNewAccessToken(\n ConfigType.GOOGLE,\n refreshToken,\n (err: any, accessToken: string, refreshToken: string, params: any) => {\n resolve({ err, accessToken, refreshToken, params })\n }\n )\n })\n}\n\ninterface RefreshResponse {\n err?: {\n data?: string\n }\n accessToken?: string\n refreshToken?: string\n params?: any\n}\n\nexport async function refreshOAuthToken(\n refreshToken: string,\n providerType: SSOProviderType,\n configId?: string\n): Promise<RefreshResponse> {\n switch (providerType) {\n case SSOProviderType.OIDC:\n if (!configId) {\n return { err: { data: \"OIDC config id not provided\" } }\n }\n const oidcConfig = await configs.getOIDCConfigById(configId)\n if (!oidcConfig) {\n return { err: { data: \"OIDC configuration not found\" } }\n }\n return refreshOIDCAccessToken(oidcConfig, refreshToken)\n case SSOProviderType.GOOGLE:\n let googleConfig = await configs.getGoogleConfig()\n if (!googleConfig) {\n return { err: { data: \"Google configuration not found\" } }\n }\n return refreshGoogleAccessToken(googleConfig, refreshToken)\n }\n}\n\n// TODO: Refactor to use user save function instead to prevent the need for\n// manually saving and invalidating on callback\nexport async function updateUserOAuth(userId: string, oAuthConfig: any) {\n const details = {\n accessToken: oAuthConfig.accessToken,\n refreshToken: oAuthConfig.refreshToken,\n }\n\n try {\n const db = getGlobalDB()\n const dbUser = await db.get(userId)\n\n //Do not overwrite the refresh token if a valid one is not provided.\n if (typeof details.refreshToken !== \"string\") {\n delete details.refreshToken\n }\n\n dbUser.oauth2 = {\n ...dbUser.oauth2,\n ...details,\n }\n\n await db.put(dbUser)\n\n await invalidateUser(userId)\n } catch (e) {\n console.error(\"Could not update OAuth details for current user\", e)\n }\n}\n\n/**\n * Logs a user out from budibase. Re-used across account portal and builder.\n */\nexport async function platformLogout(opts: PlatformLogoutOpts) {\n const ctx = opts.ctx\n const userId = opts.userId\n const keepActiveSession = opts.keepActiveSession\n\n if (!ctx) throw new Error(\"Koa context must be supplied to logout.\")\n\n const currentSession = getCookie(ctx, Cookie.Auth)\n let sessions = await getSessionsForUser(userId)\n\n if (keepActiveSession) {\n sessions = sessions.filter(\n session => session.sessionId !== currentSession.sessionId\n )\n } else {\n // clear cookies\n clearCookie(ctx, Cookie.Auth)\n }\n\n const sessionIds = sessions.map(({ sessionId }) => sessionId)\n await invalidateSessions(userId, { sessionIds, reason: \"logout\" })\n await events.auth.logout(ctx.user?.email)\n await userCache.invalidateUser(userId)\n}\n", "export * as local from \"./passport/local\"\nexport * as google from \"./passport/sso/google\"\nexport * as oidc from \"./passport/sso/oidc\"\nimport * as datasourceGoogle from \"./passport/datasource/google\"\nexport const datasource = {\n google: datasourceGoogle,\n}\nexport { authError, ssoCallbackUrl } from \"./passport/utils\"\nexport { default as authenticated } from \"./authenticated\"\nexport { default as auditLog } from \"./auditLog\"\nexport { default as tenancy } from \"./tenancy\"\nexport { default as internalApi } from \"./internalApi\"\nexport { default as csrf } from \"./csrf\"\nexport { default as adminOnly } from \"./adminOnly\"\nexport { default as builderOrAdmin } from \"./builderOrAdmin\"\nexport { default as builderOnly } from \"./builderOnly\"\nexport { default as pino } from \"../logging/pino/middleware\"\nexport { default as correlation } from \"../logging/correlation/middleware\"\nexport { default as errorHandling } from \"./errorHandling\"\nexport { default as querystringToBody } from \"./querystringToBody\"\nexport * as joiValidator from \"./joi-validator\"\n", "import { UserStatus } from \"../../constants\"\nimport { compare } from \"../../utils\"\nimport * as users from \"../../users\"\nimport { authError } from \"./utils\"\nimport { BBContext } from \"@budibase/types\"\n\nconst INVALID_ERR = \"Invalid credentials\"\nconst EXPIRED = \"This account has expired. Please reset your password\"\n\nexport const options = {\n passReqToCallback: true,\n}\n\n/**\n * Passport Local Authentication Middleware.\n * @param {*} ctx the request structure\n * @param {*} email username to login with\n * @param {*} password plain text password to log in with\n * @param {*} done callback from passport to return user information and errors\n * @returns The authenticated user, or errors if they occur\n */\nexport async function authenticate(\n ctx: BBContext,\n email: string,\n password: string,\n done: Function\n) {\n if (!email) return authError(done, \"Email Required\")\n if (!password) return authError(done, \"Password Required\")\n\n const dbUser = await users.getGlobalUserByEmail(email)\n if (dbUser == null) {\n console.info(`user=${email} could not be found`)\n return authError(done, INVALID_ERR)\n }\n\n if (dbUser.status === UserStatus.INACTIVE) {\n console.info(`user=${email} is inactive`, dbUser)\n return authError(done, INVALID_ERR)\n }\n\n if (!dbUser.password) {\n console.info(`user=${email} has no password set`, dbUser)\n return authError(done, EXPIRED)\n }\n\n if (!(await compare(password, dbUser.password))) {\n return authError(done, INVALID_ERR)\n }\n\n // intentionally remove the users password in payload\n delete dbUser.password\n return done(null, dbUser)\n}\n", "import { getTenantId, isMultiTenant } from \"../../context\"\nimport * as configs from \"../../configs\"\nimport { ConfigType, GoogleInnerConfig } from \"@budibase/types\"\n\n/**\n * Utility to handle authentication errors.\n *\n * @param {*} done The passport callback.\n * @param {*} message Message that will be returned in the response body\n * @param {*} err (Optional) error that will be logged\n */\n\nexport function authError(done: Function, message: string, err?: any) {\n return done(\n err,\n null, // never return a user\n { message: message }\n )\n}\n\nexport async function ssoCallbackUrl(\n type: ConfigType,\n config?: GoogleInnerConfig\n) {\n // incase there is a callback URL from before\n if (config && (config as GoogleInnerConfig).callbackURL) {\n return (config as GoogleInnerConfig).callbackURL as string\n }\n const settingsConfig = await configs.getSettingsConfig()\n\n let callbackUrl = `/api/global/auth`\n if (isMultiTenant()) {\n callbackUrl += `/${getTenantId()}`\n }\n callbackUrl += `/${type}/callback`\n\n return `${settingsConfig.platformUrl}${callbackUrl}`\n}\n", "import { ssoCallbackUrl } from \"../utils\"\nimport * as sso from \"./sso\"\nimport {\n ConfigType,\n SSOProfile,\n SSOAuthDetails,\n SSOProviderType,\n SaveSSOUserFunction,\n GoogleInnerConfig,\n} from \"@budibase/types\"\nconst GoogleStrategy = require(\"passport-google-oauth\").OAuth2Strategy\n\nexport function buildVerifyFn(saveUserFn: SaveSSOUserFunction) {\n return (\n accessToken: string,\n refreshToken: string,\n profile: SSOProfile,\n done: Function\n ) => {\n const details: SSOAuthDetails = {\n provider: \"google\",\n providerType: SSOProviderType.GOOGLE,\n userId: profile.id,\n profile: profile,\n email: profile._json.email,\n oauth2: {\n accessToken,\n refreshToken,\n },\n }\n\n return sso.authenticate(\n details,\n true, // require local accounts to exist\n done,\n saveUserFn\n )\n }\n}\n\n/**\n * Create an instance of the google passport strategy. This wrapper fetches the configuration\n * from couchDB rather than environment variables, using this factory is necessary for dynamically configuring passport.\n * @returns Dynamically configured Passport Google Strategy\n */\nexport async function strategyFactory(\n config: GoogleInnerConfig,\n callbackUrl: string,\n saveUserFn: SaveSSOUserFunction\n) {\n try {\n const { clientID, clientSecret } = config\n\n if (!clientID || !clientSecret) {\n throw new Error(\n \"Configuration invalid. Must contain google clientID and clientSecret\"\n )\n }\n\n const verify = buildVerifyFn(saveUserFn)\n return new GoogleStrategy(\n {\n clientID: config.clientID,\n clientSecret: config.clientSecret,\n callbackURL: callbackUrl,\n },\n verify\n )\n } catch (err: any) {\n console.error(err)\n throw new Error(`Error constructing google authentication strategy: ${err}`)\n }\n}\n\nexport async function getCallbackUrl(config: GoogleInnerConfig) {\n return ssoCallbackUrl(ConfigType.GOOGLE, config)\n}\n", "import { generateGlobalUserID } from \"../../../db\"\nimport { authError } from \"../utils\"\nimport * as users from \"../../../users\"\nimport * as context from \"../../../context\"\nimport fetch from \"node-fetch\"\nimport {\n SaveSSOUserFunction,\n SaveUserOpts,\n SSOAuthDetails,\n SSOUser,\n User,\n} from \"@budibase/types\"\n\n// no-op function for user save\n// - this allows datasource auth and access token refresh to work correctly\n// - prefer no-op over an optional argument to ensure function is provided to login flows\nexport const ssoSaveUserNoOp: SaveSSOUserFunction = (\n user: SSOUser,\n opts: SaveUserOpts\n) => Promise.resolve(user)\n\n/**\n * Common authentication logic for third parties. e.g. OAuth, OIDC.\n */\nexport async function authenticate(\n details: SSOAuthDetails,\n requireLocalAccount: boolean = true,\n done: any,\n saveUserFn: SaveSSOUserFunction\n) {\n if (!saveUserFn) {\n throw new Error(\"Save user function must be provided\")\n }\n if (!details.userId) {\n return authError(done, \"sso user id required\")\n }\n if (!details.email) {\n return authError(done, \"sso user email required\")\n }\n\n // use the third party id\n const userId = generateGlobalUserID(details.userId)\n\n let dbUser: User | undefined\n\n // try to load by id\n try {\n dbUser = await users.getById(userId)\n } catch (err: any) {\n // abort when not 404 error\n if (!err.status || err.status !== 404) {\n return authError(\n done,\n \"Unexpected error when retrieving existing user\",\n err\n )\n }\n }\n\n // fallback to loading by email\n if (!dbUser) {\n dbUser = await users.getGlobalUserByEmail(details.email)\n }\n\n // exit early if there is still no user and auto creation is disabled\n if (!dbUser && requireLocalAccount) {\n return authError(\n done,\n \"Email does not yet exist. You must set up your local budibase account first.\"\n )\n }\n\n // first time creation\n if (!dbUser) {\n // setup a blank user using the third party id\n dbUser = {\n _id: userId,\n email: details.email,\n roles: {},\n tenantId: context.getTenantId(),\n }\n }\n\n let ssoUser = await syncUser(dbUser, details)\n // never prompt for password reset\n ssoUser.forceResetPassword = false\n\n try {\n // don't try to re-save any existing password\n delete ssoUser.password\n // create or sync the user\n ssoUser = (await saveUserFn(ssoUser, {\n hashPassword: false,\n requirePassword: false,\n })) as SSOUser\n } catch (err: any) {\n return authError(done, \"Error saving user\", err)\n }\n\n return done(null, ssoUser)\n}\n\nasync function getProfilePictureUrl(user: User, details: SSOAuthDetails) {\n const pictureUrl = details.profile?._json.picture\n if (pictureUrl) {\n const response = await fetch(pictureUrl)\n if (response.status === 200) {\n const type = response.headers.get(\"content-type\") as string\n if (type.startsWith(\"image/\")) {\n return pictureUrl\n }\n }\n }\n}\n\n/**\n * @returns a user that has been sync'd with third party information\n */\nasync function syncUser(user: User, details: SSOAuthDetails): Promise<SSOUser> {\n let firstName\n let lastName\n let pictureUrl\n let oauth2\n let thirdPartyProfile\n\n if (details.profile) {\n const profile = details.profile\n\n if (profile.name) {\n const name = profile.name\n // first name\n if (name.givenName) {\n firstName = name.givenName\n }\n // last name\n if (name.familyName) {\n lastName = name.familyName\n }\n }\n\n pictureUrl = await getProfilePictureUrl(user, details)\n\n thirdPartyProfile = {\n ...profile._json,\n }\n }\n\n // oauth tokens for future use\n if (details.oauth2) {\n oauth2 = {\n ...details.oauth2,\n }\n }\n\n return {\n ...user,\n provider: details.provider,\n providerType: details.providerType,\n firstName,\n lastName,\n thirdPartyProfile,\n pictureUrl,\n oauth2,\n }\n}\n", "import fetch from \"node-fetch\"\nimport * as sso from \"./sso\"\nimport { ssoCallbackUrl } from \"../utils\"\nimport { validEmail } from \"../../../utils\"\nimport {\n ConfigType,\n OIDCInnerConfig,\n SSOProfile,\n OIDCStrategyConfiguration,\n SSOAuthDetails,\n SSOProviderType,\n JwtClaims,\n SaveSSOUserFunction,\n} from \"@budibase/types\"\n\nconst OIDCStrategy = require(\"@techpass/passport-openidconnect\").Strategy\n\nexport function buildVerifyFn(saveUserFn: SaveSSOUserFunction) {\n /**\n * @param {*} issuer The identity provider base URL\n * @param {*} sub The user ID\n * @param {*} profile The user profile information. Created by passport from the /userinfo response\n * @param {*} jwtClaims The parsed id_token claims\n * @param {*} accessToken The access_token for contacting the identity provider - may or may not be a JWT\n * @param {*} refreshToken The refresh_token for obtaining a new access_token - usually not a JWT\n * @param {*} idToken The id_token - always a JWT\n * @param {*} params The response body from requesting an access_token\n * @param {*} done The passport callback: err, user, info\n */\n return async (\n issuer: string,\n sub: string,\n profile: SSOProfile,\n jwtClaims: JwtClaims,\n accessToken: string,\n refreshToken: string,\n idToken: string,\n params: any,\n done: Function\n ) => {\n const details: SSOAuthDetails = {\n // store the issuer info to enable sync in future\n provider: issuer,\n providerType: SSOProviderType.OIDC,\n userId: profile.id,\n profile: profile,\n email: getEmail(profile, jwtClaims),\n oauth2: {\n accessToken: accessToken,\n refreshToken: refreshToken,\n },\n }\n\n return sso.authenticate(\n details,\n false, // don't require local accounts to exist\n done,\n saveUserFn\n )\n }\n}\n\n/**\n * @param {*} profile The structured profile created by passport using the user info endpoint\n * @param {*} jwtClaims The claims returned in the id token\n */\nfunction getEmail(profile: SSOProfile, jwtClaims: JwtClaims) {\n // profile not guaranteed to contain email e.g. github connected azure ad account\n if (profile._json.email) {\n return profile._json.email\n }\n\n // fallback to id token email\n if (jwtClaims.email) {\n return jwtClaims.email\n }\n\n // fallback to id token preferred username\n const username = jwtClaims.preferred_username\n if (username && validEmail(username)) {\n return username\n }\n\n throw new Error(\n `Could not determine user email from profile ${JSON.stringify(\n profile\n )} and claims ${JSON.stringify(jwtClaims)}`\n )\n}\n\n/**\n * Create an instance of the oidc passport strategy. This wrapper fetches the configuration\n * from couchDB rather than environment variables, using this factory is necessary for dynamically configuring passport.\n * @returns Dynamically configured Passport OIDC Strategy\n */\nexport async function strategyFactory(\n config: OIDCStrategyConfiguration,\n saveUserFn: SaveSSOUserFunction\n) {\n try {\n const verify = buildVerifyFn(saveUserFn)\n const strategy = new OIDCStrategy(config, verify)\n strategy.name = \"oidc\"\n return strategy\n } catch (err: any) {\n console.error(err)\n throw new Error(`Error constructing OIDC authentication strategy - ${err}`)\n }\n}\n\nexport async function fetchStrategyConfig(\n oidcConfig: OIDCInnerConfig,\n callbackUrl?: string\n): Promise<OIDCStrategyConfiguration> {\n try {\n const { clientID, clientSecret, configUrl } = oidcConfig\n\n if (!clientID || !clientSecret || !callbackUrl || !configUrl) {\n // check for remote config and all required elements\n throw new Error(\n \"Configuration invalid. Must contain clientID, clientSecret, callbackUrl and configUrl\"\n )\n }\n\n const response = await fetch(configUrl)\n\n if (!response.ok) {\n throw new Error(\n `Unexpected response when fetching openid-configuration: ${response.statusText}`\n )\n }\n\n const body = await response.json()\n\n return {\n issuer: body.issuer,\n authorizationURL: body.authorization_endpoint,\n tokenURL: body.token_endpoint,\n userInfoURL: body.userinfo_endpoint,\n clientID: clientID,\n clientSecret: clientSecret,\n callbackURL: callbackUrl,\n }\n } catch (err) {\n console.error(err)\n throw new Error(\n `Error constructing OIDC authentication configuration - ${err}`\n )\n }\n}\n\nexport async function getCallbackUrl() {\n return ssoCallbackUrl(ConfigType.OIDC)\n}\n", "import * as google from \"../sso/google\"\nimport { Cookie } from \"../../../constants\"\nimport { clearCookie, getCookie } from \"../../../utils\"\nimport { doWithDB } from \"../../../db\"\nimport * as configs from \"../../../configs\"\nimport { BBContext, Database, SSOProfile } from \"@budibase/types\"\nimport { ssoSaveUserNoOp } from \"../sso/sso\"\nconst GoogleStrategy = require(\"passport-google-oauth\").OAuth2Strategy\n\ntype Passport = {\n authenticate: any\n}\n\nasync function fetchGoogleCreds() {\n let config = await configs.getGoogleDatasourceConfig()\n\n if (!config) {\n throw new Error(\"No google configuration found\")\n }\n return config\n}\n\nexport async function preAuth(\n passport: Passport,\n ctx: BBContext,\n next: Function\n) {\n // get the relevant config\n const googleConfig = await fetchGoogleCreds()\n const platformUrl = await configs.getPlatformUrl({ tenantAware: false })\n\n let callbackUrl = `${platformUrl}/api/global/auth/datasource/google/callback`\n const strategy = await google.strategyFactory(\n googleConfig,\n callbackUrl,\n ssoSaveUserNoOp\n )\n\n if (!ctx.query.appId || !ctx.query.datasourceId) {\n ctx.throw(400, \"appId and datasourceId query params not present.\")\n }\n\n return passport.authenticate(strategy, {\n scope: [\"profile\", \"email\", \"https://www.googleapis.com/auth/spreadsheets\"],\n accessType: \"offline\",\n prompt: \"consent\",\n })(ctx, next)\n}\n\nexport async function postAuth(\n passport: Passport,\n ctx: BBContext,\n next: Function\n) {\n // get the relevant config\n const config = await fetchGoogleCreds()\n const platformUrl = await configs.getPlatformUrl({ tenantAware: false })\n\n let callbackUrl = `${platformUrl}/api/global/auth/datasource/google/callback`\n const authStateCookie = getCookie(ctx, Cookie.DatasourceAuth)\n\n return passport.authenticate(\n new GoogleStrategy(\n {\n clientID: config.clientID,\n clientSecret: config.clientSecret,\n callbackURL: callbackUrl,\n },\n (\n accessToken: string,\n refreshToken: string,\n profile: SSOProfile,\n done: Function\n ) => {\n clearCookie(ctx, Cookie.DatasourceAuth)\n done(null, { accessToken, refreshToken })\n }\n ),\n { successRedirect: \"/\", failureRedirect: \"/error\" },\n async (err: any, tokens: string[]) => {\n const baseUrl = `/builder/app/${authStateCookie.appId}/data`\n // update the DB for the datasource with all the user info\n await doWithDB(authStateCookie.appId, async (db: Database) => {\n let datasource\n try {\n datasource = await db.get(authStateCookie.datasourceId)\n } catch (err: any) {\n if (err.status === 404) {\n ctx.redirect(baseUrl)\n }\n }\n if (!datasource.config) {\n datasource.config = {}\n }\n datasource.config.auth = { type: \"google\", ...tokens }\n await db.put(datasource)\n ctx.redirect(`${baseUrl}/datasource/${authStateCookie.datasourceId}`)\n })\n }\n )(ctx, next)\n}\n", "import { Cookie, Header } from \"../constants\"\nimport {\n getCookie,\n clearCookie,\n openJwt,\n isValidInternalAPIKey,\n} from \"../utils\"\nimport { getUser } from \"../cache/user\"\nimport { getSession, updateSessionTTL } from \"../security/sessions\"\nimport { buildMatcherRegex, matches } from \"./matchers\"\nimport { SEPARATOR, queryGlobalView, ViewName } from \"../db\"\nimport { getGlobalDB, doInTenant } from \"../context\"\nimport { decrypt } from \"../security/encryption\"\nimport * as identity from \"../context/identity\"\nimport env from \"../environment\"\nimport { Ctx, EndpointMatcher } from \"@budibase/types\"\nimport { InvalidAPIKeyError, ErrorCode } from \"../errors\"\n\nconst ONE_MINUTE = env.SESSION_UPDATE_PERIOD\n ? parseInt(env.SESSION_UPDATE_PERIOD)\n : 60 * 1000\n\ninterface FinaliseOpts {\n authenticated?: boolean\n internal?: boolean\n publicEndpoint?: boolean\n version?: string\n user?: any\n}\n\nfunction timeMinusOneMinute() {\n return new Date(Date.now() - ONE_MINUTE).toISOString()\n}\n\nfunction finalise(ctx: any, opts: FinaliseOpts = {}) {\n ctx.publicEndpoint = opts.publicEndpoint || false\n ctx.isAuthenticated = opts.authenticated || false\n ctx.user = opts.user\n ctx.internal = opts.internal || false\n ctx.version = opts.version\n}\n\nasync function checkApiKey(apiKey: string, populateUser?: Function) {\n // check both the primary and the fallback internal api keys\n // this allows for rotation\n if (isValidInternalAPIKey(apiKey)) {\n return { valid: true, user: undefined }\n }\n const decrypted = decrypt(apiKey)\n const tenantId = decrypted.split(SEPARATOR)[0]\n return doInTenant(tenantId, async () => {\n let userId\n try {\n const db = getGlobalDB()\n // api key is encrypted in the database\n userId = (await queryGlobalView(\n ViewName.BY_API_KEY,\n {\n key: apiKey,\n },\n db\n )) as string\n } catch (err) {\n userId = undefined\n }\n if (userId) {\n return {\n valid: true,\n user: await getUser(userId, tenantId, populateUser),\n }\n } else {\n throw new InvalidAPIKeyError()\n }\n })\n}\n\n/**\n * This middleware is tenancy aware, so that it does not depend on other middlewares being used.\n * The tenancy modules should not be used here and it should be assumed that the tenancy context\n * has not yet been populated.\n */\nexport default function (\n noAuthPatterns: EndpointMatcher[] = [],\n opts: { publicAllowed?: boolean; populateUser?: Function } = {\n publicAllowed: false,\n }\n) {\n const noAuthOptions = noAuthPatterns ? buildMatcherRegex(noAuthPatterns) : []\n return async (ctx: Ctx | any, next: any) => {\n let publicEndpoint = false\n const version = ctx.request.headers[Header.API_VER]\n // the path is not authenticated\n const found = matches(ctx, noAuthOptions)\n if (found) {\n publicEndpoint = true\n }\n try {\n // check the actual user is authenticated first, try header or cookie\n let headerToken = ctx.request.headers[Header.TOKEN]\n\n const authCookie = getCookie(ctx, Cookie.Auth) || openJwt(headerToken)\n let apiKey = ctx.request.headers[Header.API_KEY]\n\n if (!apiKey && ctx.request.headers[Header.AUTHORIZATION]) {\n apiKey = ctx.request.headers[Header.AUTHORIZATION].split(\" \")[1]\n }\n\n const tenantId = ctx.request.headers[Header.TENANT_ID]\n let authenticated = false,\n user = null,\n internal = false\n if (authCookie && !apiKey) {\n const sessionId = authCookie.sessionId\n const userId = authCookie.userId\n let session\n try {\n // getting session handles error checking (if session exists etc)\n session = await getSession(userId, sessionId)\n if (opts && opts.populateUser) {\n user = await getUser(\n userId,\n session.tenantId,\n opts.populateUser(ctx)\n )\n } else {\n user = await getUser(userId, session.tenantId)\n }\n user.csrfToken = session.csrfToken\n\n if (session?.lastAccessedAt < timeMinusOneMinute()) {\n // make sure we denote that the session is still in use\n await updateSessionTTL(session)\n }\n authenticated = true\n } catch (err: any) {\n authenticated = false\n console.error(`Auth Error: ${err.message}`)\n console.error(err)\n // remove the cookie as the user does not exist anymore\n clearCookie(ctx, Cookie.Auth)\n }\n }\n // this is an internal request, no user made it\n if (!authenticated && apiKey) {\n const populateUser = opts.populateUser ? opts.populateUser(ctx) : null\n const { valid, user: foundUser } = await checkApiKey(\n apiKey,\n populateUser\n )\n if (valid && foundUser) {\n authenticated = true\n user = foundUser\n } else if (valid) {\n authenticated = true\n internal = true\n }\n }\n if (!user && tenantId) {\n user = { tenantId }\n } else if (user) {\n delete user.password\n }\n // be explicit\n if (!authenticated) {\n authenticated = false\n }\n // isAuthenticated is a function, so use a variable to be able to check authed state\n finalise(ctx, { authenticated, user, internal, version, publicEndpoint })\n\n if (user && user.email) {\n return identity.doInUserContext(user, ctx, next)\n } else {\n return next()\n }\n } catch (err: any) {\n console.error(`Auth Error: ${err.message}`)\n console.error(err)\n // invalid token, clear the cookie\n if (err?.name === \"JsonWebTokenError\") {\n clearCookie(ctx, Cookie.Auth)\n } else if (err?.code === ErrorCode.INVALID_API_KEY) {\n ctx.throw(403, err.message)\n }\n // allow configuring for public access\n if ((opts && opts.publicAllowed) || publicEndpoint) {\n finalise(ctx, { authenticated: false, version, publicEndpoint })\n return next()\n } else {\n ctx.throw(err.status || 403, err)\n }\n }\n }\n}\n", "import { BBContext, EndpointMatcher, RegexMatcher } from \"@budibase/types\"\n\nconst PARAM_REGEX = /\\/:(.*?)(\\/.*)?$/g\n\nexport const buildMatcherRegex = (\n patterns: EndpointMatcher[]\n): RegexMatcher[] => {\n if (!patterns) {\n return []\n }\n return patterns.map(pattern => {\n let route = pattern.route\n const method = pattern.method\n const strict = pattern.strict ? pattern.strict : false\n\n // if there is a param in the route\n // use a wildcard pattern\n const matches = route.match(PARAM_REGEX)\n if (matches) {\n for (let match of matches) {\n const suffix = match.endsWith(\"/\") ? \"/\" : \"\"\n const pattern = \"/.*\" + suffix\n route = route.replace(match, pattern)\n }\n }\n\n return { regex: new RegExp(route), method, strict, route }\n })\n}\n\nexport const matches = (ctx: BBContext, options: RegexMatcher[]) => {\n return options.find(({ regex, method, strict, route }) => {\n let urlMatch\n if (strict) {\n urlMatch = ctx.request.url === route\n } else {\n urlMatch = regex.test(ctx.request.url)\n }\n\n const methodMatch =\n method === \"ALL\"\n ? true\n : ctx.request.method.toLowerCase() === method.toLowerCase()\n\n return urlMatch && methodMatch\n })\n}\n", "import crypto from \"crypto\"\nimport env from \"../environment\"\n\nconst ALGO = \"aes-256-ctr\"\nconst SEPARATOR = \"-\"\nconst ITERATIONS = 10000\nconst RANDOM_BYTES = 16\nconst STRETCH_LENGTH = 32\n\nexport enum SecretOption {\n API = \"api\",\n ENCRYPTION = \"encryption\",\n}\n\nexport function getSecret(secretOption: SecretOption): string {\n let secret, secretName\n switch (secretOption) {\n case SecretOption.ENCRYPTION:\n secret = env.ENCRYPTION_KEY\n secretName = \"ENCRYPTION_KEY\"\n break\n case SecretOption.API:\n default:\n secret = env.API_ENCRYPTION_KEY\n secretName = \"API_ENCRYPTION_KEY\"\n break\n }\n if (!secret) {\n throw new Error(`Secret \"${secretName}\" has not been set in environment.`)\n }\n return secret\n}\n\nfunction stretchString(string: string, salt: Buffer) {\n return crypto.pbkdf2Sync(string, salt, ITERATIONS, STRETCH_LENGTH, \"sha512\")\n}\n\nexport function encrypt(\n input: string,\n secretOption: SecretOption = SecretOption.API\n) {\n const salt = crypto.randomBytes(RANDOM_BYTES)\n const stretched = stretchString(getSecret(secretOption), salt)\n const cipher = crypto.createCipheriv(ALGO, stretched, salt)\n const base = cipher.update(input)\n const final = cipher.final()\n const encrypted = Buffer.concat([base, final]).toString(\"hex\")\n return `${salt.toString(\"hex\")}${SEPARATOR}${encrypted}`\n}\n\nexport function decrypt(\n input: string,\n secretOption: SecretOption = SecretOption.API\n) {\n const [salt, encrypted] = input.split(SEPARATOR)\n const saltBuffer = Buffer.from(salt, \"hex\")\n const stretched = stretchString(getSecret(secretOption), saltBuffer)\n const decipher = crypto.createDecipheriv(ALGO, stretched, saltBuffer)\n const base = decipher.update(Buffer.from(encrypted, \"hex\"))\n const final = decipher.final()\n return Buffer.concat([base, final]).toString()\n}\n", "// BASE\n\nexport abstract class BudibaseError extends Error {\n code: string\n\n constructor(message: string, code: ErrorCode) {\n super(message)\n this.code = code\n }\n\n protected getPublicError?(): any\n}\n\n// ERROR HANDLING\n\nexport enum ErrorCode {\n USAGE_LIMIT_EXCEEDED = \"usage_limit_exceeded\",\n FEATURE_DISABLED = \"feature_disabled\",\n INVALID_API_KEY = \"invalid_api_key\",\n HTTP = \"http\",\n}\n\n/**\n * For the given error, build the public representation that is safe\n * to be exposed over an api.\n */\nexport const getPublicError = (err: any) => {\n let error\n if (err.code) {\n // add generic error information\n error = {\n code: err.code,\n }\n\n if (err.getPublicError) {\n error = {\n ...error,\n // get any additional context from this error\n ...err.getPublicError(),\n }\n }\n }\n\n return error\n}\n\n// HTTP\n\nexport class HTTPError extends BudibaseError {\n status: number\n\n constructor(message: string, httpStatus: number, code = ErrorCode.HTTP) {\n super(message, code)\n this.status = httpStatus\n }\n}\n\n// LICENSING\n\nexport class UsageLimitError extends HTTPError {\n limitName: string\n\n constructor(message: string, limitName: string) {\n super(message, 400, ErrorCode.USAGE_LIMIT_EXCEEDED)\n this.limitName = limitName\n }\n\n getPublicError() {\n return {\n limitName: this.limitName,\n }\n }\n}\n\nexport class FeatureDisabledError extends HTTPError {\n featureName: string\n\n constructor(message: string, featureName: string) {\n super(message, 400, ErrorCode.FEATURE_DISABLED)\n this.featureName = featureName\n }\n\n getPublicError() {\n return {\n featureName: this.featureName,\n }\n }\n}\n\n// AUTH\n\nexport class InvalidAPIKeyError extends BudibaseError {\n constructor() {\n super(\n \"Invalid API key - may need re-generated, or user doesn't exist\",\n ErrorCode.INVALID_API_KEY\n )\n }\n}\n\n// USERS\n\nexport class EmailUnavailableError extends Error {\n constructor(email: string) {\n super(`Email already in use: '${email}'`)\n }\n}\n", "import { BBContext } from \"@budibase/types\"\n\nexport default async (ctx: BBContext | any, next: any) => {\n // Placeholder for audit log middleware\n return next()\n}\n", "import { doInTenant } from \"../context\"\nimport { getTenantIDFromCtx } from \"../tenancy\"\nimport { buildMatcherRegex, matches } from \"./matchers\"\nimport { Header } from \"../constants\"\nimport {\n BBContext,\n EndpointMatcher,\n GetTenantIdOptions,\n TenantResolutionStrategy,\n} from \"@budibase/types\"\n\nexport default function (\n allowQueryStringPatterns: EndpointMatcher[],\n noTenancyPatterns: EndpointMatcher[],\n opts: { noTenancyRequired?: boolean } = { noTenancyRequired: false }\n) {\n const allowQsOptions = buildMatcherRegex(allowQueryStringPatterns)\n const noTenancyOptions = buildMatcherRegex(noTenancyPatterns)\n\n return async function (ctx: BBContext | any, next: any) {\n const allowNoTenant =\n opts.noTenancyRequired || !!matches(ctx, noTenancyOptions)\n const tenantOpts: GetTenantIdOptions = {\n allowNoTenant,\n }\n\n const allowQs = !!matches(ctx, allowQsOptions)\n if (!allowQs) {\n tenantOpts.excludeStrategies = [TenantResolutionStrategy.QUERY]\n }\n\n const tenantId = getTenantIDFromCtx(ctx, tenantOpts)\n ctx.set(Header.TENANT_ID, tenantId as string)\n return doInTenant(tenantId, next)\n }\n}\n", "import { Header } from \"../constants\"\nimport { BBContext } from \"@budibase/types\"\nimport { isValidInternalAPIKey } from \"../utils\"\n\n/**\n * API Key only endpoint.\n */\nexport default async (ctx: BBContext, next: any) => {\n const apiKey = ctx.request.headers[Header.API_KEY]\n if (!apiKey) {\n ctx.throw(403, \"Unauthorized\")\n }\n\n if (Array.isArray(apiKey)) {\n ctx.throw(403, \"Unauthorized\")\n }\n\n if (!isValidInternalAPIKey(apiKey)) {\n ctx.throw(403, \"Unauthorized\")\n }\n\n return next()\n}\n", "import { Header } from \"../constants\"\nimport { buildMatcherRegex, matches } from \"./matchers\"\nimport { BBContext, EndpointMatcher } from \"@budibase/types\"\n\n/**\n * GET, HEAD and OPTIONS methods are considered safe operations\n *\n * POST, PUT, PATCH, and DELETE methods, being state changing verbs,\n * should have a CSRF token attached to the request\n */\nconst EXCLUDED_METHODS = [\"GET\", \"HEAD\", \"OPTIONS\"]\n\n/**\n * There are only three content type values that can be used in cross domain requests.\n * If any other value is used, e.g. application/json, the browser will first make a OPTIONS\n * request which will be protected by CORS.\n */\nconst INCLUDED_CONTENT_TYPES = [\n \"application/x-www-form-urlencoded\",\n \"multipart/form-data\",\n \"text/plain\",\n]\n\n/**\n * Validate the CSRF token generated aganst the user session.\n * Compare the token with the x-csrf-token header.\n *\n * If the token is not found within the request or the value provided\n * does not match the value within the user session, the request is rejected.\n *\n * CSRF protection provided using the 'Synchronizer Token Pattern'\n * https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#synchronizer-token-pattern\n *\n */\nexport default function (\n opts: { noCsrfPatterns: EndpointMatcher[] } = { noCsrfPatterns: [] }\n) {\n const noCsrfOptions = buildMatcherRegex(opts.noCsrfPatterns)\n return async (ctx: BBContext | any, next: any) => {\n // don't apply for excluded paths\n const found = matches(ctx, noCsrfOptions)\n if (found) {\n return next()\n }\n\n // don't apply for the excluded http methods\n if (EXCLUDED_METHODS.indexOf(ctx.method) !== -1) {\n return next()\n }\n\n // don't apply when the content type isn't supported\n let contentType = ctx.get(\"content-type\")\n ? ctx.get(\"content-type\").toLowerCase()\n : \"\"\n if (\n !INCLUDED_CONTENT_TYPES.filter(type => contentType.includes(type)).length\n ) {\n return next()\n }\n\n // don't apply csrf when the internal api key has been used\n if (ctx.internal) {\n return next()\n }\n\n // apply csrf when there is a token in the session (new logins)\n // in future there should be a hard requirement that the token is present\n const userToken = ctx.user?.csrfToken\n if (!userToken) {\n return next()\n }\n\n // reject if no token in request or mismatch\n const requestToken = ctx.get(Header.CSRF_TOKEN)\n if (!requestToken || requestToken !== userToken) {\n ctx.throw(403, \"Invalid CSRF token\")\n }\n\n return next()\n }\n}\n", "import { BBContext } from \"@budibase/types\"\n\nexport default async (ctx: BBContext, next: any) => {\n if (\n !ctx.internal &&\n (!ctx.user || !ctx.user.admin || !ctx.user.admin.global)\n ) {\n ctx.throw(403, \"Admin user only endpoint.\")\n }\n return next()\n}\n", "import { BBContext } from \"@budibase/types\"\n\nexport default async (ctx: BBContext, next: any) => {\n if (\n !ctx.internal &&\n (!ctx.user || !ctx.user.builder || !ctx.user.builder.global) &&\n (!ctx.user || !ctx.user.admin || !ctx.user.admin.global)\n ) {\n ctx.throw(403, \"Builder user only endpoint.\")\n }\n return next()\n}\n", "import { BBContext } from \"@budibase/types\"\n\nexport default async (ctx: BBContext, next: any) => {\n if (\n !ctx.internal &&\n (!ctx.user || !ctx.user.builder || !ctx.user.builder.global)\n ) {\n ctx.throw(403, \"Builder user only endpoint.\")\n }\n return next()\n}\n", "import env from \"../../environment\"\nimport { logger } from \"./logger\"\nimport { IncomingMessage } from \"http\"\nconst pino = require(\"koa-pino-logger\")\nimport { Options } from \"pino-http\"\nimport { Ctx } from \"@budibase/types\"\nconst correlator = require(\"correlation-id\")\n\nexport function pinoSettings(): Options {\n return {\n logger,\n genReqId: correlator.getId,\n autoLogging: {\n ignore: (req: IncomingMessage) => !!req.url?.includes(\"/health\"),\n },\n serializers: {\n req: req => {\n return {\n method: req.method,\n url: req.url,\n correlationId: req.id,\n }\n },\n res: res => {\n return {\n status: res.statusCode,\n }\n },\n },\n }\n}\n\nfunction getMiddleware() {\n if (env.HTTP_LOGGING) {\n return pino(pinoSettings())\n } else {\n return (ctx: Ctx, next: any) => {\n return next()\n }\n }\n}\n\nconst pinoMiddleware = getMiddleware()\n\nexport default pinoMiddleware\n", "import { Header } from \"../../constants\"\nimport { v4 as uuid } from \"uuid\"\nconst correlator = require(\"correlation-id\")\n\nconst correlation = (ctx: any, next: any) => {\n // use the provided correlation id header if present\n let correlationId = ctx.headers[Header.CORRELATION_ID]\n if (!correlationId) {\n correlationId = uuid()\n }\n\n return correlator.withId(correlationId, () => {\n return next()\n })\n}\n\nexport default correlation\n", "import { APIError } from \"@budibase/types\"\nimport * as errors from \"../errors\"\n\nexport async function errorHandling(ctx: any, next: any) {\n try {\n await next()\n } catch (err: any) {\n const status = err.status || err.statusCode || 500\n ctx.status = status\n\n if (status >= 400 && status < 500) {\n console.warn(err)\n } else {\n console.error(err)\n }\n\n const error = errors.getPublicError(err)\n const body: APIError = {\n message: err.message,\n status: status,\n validationErrors: err.validation,\n error,\n }\n\n ctx.body = body\n }\n}\n\nexport default errorHandling\n", "import { Ctx } from \"@budibase/types\"\n\n/**\n * Expects a standard \"query\" query string property which is the JSON body\n * of the request, which has to be sent via query string due to the requirement\n * of making an endpoint a GET request e.g. downloading a file stream.\n */\nexport default function (ctx: Ctx, next: any) {\n const queryString = ctx.request.query?.query as string | undefined\n if (ctx.request.method.toLowerCase() !== \"get\") {\n ctx.throw(\n 500,\n \"Query to download middleware can only be used for get requests.\"\n )\n }\n if (!queryString) {\n return next()\n }\n const decoded = decodeURIComponent(queryString)\n let json\n try {\n json = JSON.parse(decoded)\n } catch (err) {\n return next()\n }\n ctx.request.body = json\n return next()\n}\n", "import Joi, { ObjectSchema } from \"joi\"\nimport { BBContext } from \"@budibase/types\"\n\nfunction validate(\n schema: Joi.ObjectSchema | Joi.ArraySchema,\n property: string\n) {\n // Return a Koa middleware function\n return (ctx: BBContext, next: any) => {\n if (!schema) {\n return next()\n }\n let params = null\n // @ts-ignore\n let reqProp = ctx.request?.[property]\n if (ctx[property] != null) {\n params = ctx[property]\n } else if (reqProp != null) {\n params = reqProp\n }\n\n // not all schemas have the append property e.g. array schemas\n if ((schema as Joi.ObjectSchema).append) {\n schema = (schema as Joi.ObjectSchema).append({\n createdAt: Joi.any().optional(),\n updatedAt: Joi.any().optional(),\n })\n }\n\n const { error } = schema.validate(params)\n if (error) {\n ctx.throw(400, `Invalid ${property} - ${error.message}`)\n return\n }\n return next()\n }\n}\n\nexport function body(schema: Joi.ObjectSchema | Joi.ArraySchema) {\n return validate(schema, \"body\")\n}\n\nexport function params(schema: Joi.ObjectSchema | Joi.ArraySchema) {\n return validate(schema, \"params\")\n}\n", "export * as configs from \"./configs\"\nexport * as events from \"./events\"\nexport * as migrations from \"./migrations\"\nexport * as users from \"./users\"\nexport * as roles from \"./security/roles\"\nexport * as permissions from \"./security/permissions\"\nexport * as accounts from \"./accounts\"\nexport * as installation from \"./installation\"\nexport * as featureFlags from \"./featureFlags\"\nexport * as sessions from \"./security/sessions\"\nexport * as platform from \"./platform\"\nexport * as auth from \"./auth\"\nexport * as constants from \"./constants\"\nexport * as logging from \"./logging\"\nexport * as middleware from \"./middleware\"\nexport * as plugins from \"./plugin\"\nexport * as encryption from \"./security/encryption\"\nexport * as queue from \"./queue\"\nexport * as db from \"./db\"\nexport * as context from \"./context\"\nexport * as cache from \"./cache\"\nexport * as objectStore from \"./objectStore\"\nexport * as redis from \"./redis\"\nexport * as locks from \"./redis/redlockImpl\"\nexport * as utils from \"./utils\"\nexport * as errors from \"./errors\"\nexport * as timers from \"./timers\"\nexport { default as env } from \"./environment\"\nexport * as blacklist from \"./blacklist\"\nexport * as docUpdates from \"./docUpdates\"\nexport { SearchParams } from \"./db\"\n// Add context to tenancy for backwards compatibility\n// only do this for external usages to prevent internal\n// circular dependencies\nimport * as context from \"./context\"\nimport * as _tenancy from \"./tenancy\"\nexport const tenancy = {\n ..._tenancy,\n ...context,\n}\n\n// expose error classes directly\nexport * from \"./errors\"\n\n// expose constants directly\nexport * from \"./constants\"\n\n// expose package init function\nimport * as db from \"./db\"\nexport const init = (opts: any = {}) => {\n db.init(opts.db)\n}\n", "export * from \"./utils\"\n", "import {\n DatasourceFieldType,\n QueryType,\n PluginType,\n AutomationStepType,\n AutomationStepIdArray,\n AutomationIOType,\n AutomationCustomIOType,\n} from \"@budibase/types\"\nimport joi from \"joi\"\n\nconst DATASOURCE_TYPES = [\n \"Relational\",\n \"Non-relational\",\n \"Spreadsheet\",\n \"Object store\",\n \"Graph\",\n \"API\",\n]\n\nfunction runJoi(validator: joi.Schema, schema: any) {\n const { error } = validator.validate(schema)\n if (error) {\n throw error\n }\n}\n\nfunction validateComponent(schema: any) {\n const validator = joi.object({\n type: joi.string().allow(PluginType.COMPONENT).required(),\n metadata: joi.object().unknown(true).required(),\n hash: joi.string().optional(),\n version: joi.string().optional(),\n schema: joi\n .object({\n name: joi.string().required(),\n settings: joi.array().items(joi.object().unknown(true)).required(),\n })\n .unknown(true),\n })\n runJoi(validator, schema)\n}\n\nfunction validateDatasource(schema: any) {\n const fieldValidator = joi.object({\n type: joi\n .string()\n .allow(...Object.values(DatasourceFieldType))\n .required(),\n required: joi.boolean().required(),\n default: joi.any(),\n display: joi.string(),\n })\n\n const queryValidator = joi\n .object({\n type: joi.string().allow(...Object.values(QueryType)),\n readable: joi.boolean(),\n fields: joi.object().pattern(joi.string(), fieldValidator),\n })\n .required()\n\n const validator = joi.object({\n type: joi.string().allow(PluginType.DATASOURCE).required(),\n metadata: joi.object().unknown(true).required(),\n hash: joi.string().optional(),\n version: joi.string().optional(),\n schema: joi.object({\n docs: joi.string(),\n friendlyName: joi.string().required(),\n type: joi.string().allow(...DATASOURCE_TYPES),\n description: joi.string().required(),\n datasource: joi.object().pattern(joi.string(), fieldValidator).required(),\n query: joi\n .object()\n .pattern(joi.string(), queryValidator)\n .unknown(true)\n .required(),\n extra: joi.object().pattern(\n joi.string(),\n joi.object({\n type: joi.string().required(),\n displayName: joi.string().required(),\n required: joi.boolean(),\n data: joi.object(),\n })\n ),\n }),\n })\n runJoi(validator, schema)\n}\n\nfunction validateAutomation(schema: any) {\n const basePropsValidator = joi.object().pattern(joi.string(), {\n type: joi\n .string()\n .allow(...Object.values(AutomationIOType))\n .required(),\n customType: joi.string().allow(...Object.values(AutomationCustomIOType)),\n title: joi.string(),\n description: joi.string(),\n enum: joi.array().items(joi.string()),\n pretty: joi.array().items(joi.string()),\n })\n const stepSchemaValidator = joi\n .object({\n properties: basePropsValidator,\n required: joi.array().items(joi.string()),\n })\n .concat(basePropsValidator)\n .required()\n const validator = joi.object({\n type: joi.string().allow(PluginType.AUTOMATION).required(),\n metadata: joi.object().unknown(true).required(),\n hash: joi.string().optional(),\n version: joi.string().optional(),\n schema: joi.object({\n name: joi.string().required(),\n tagline: joi.string().required(),\n icon: joi.string().required(),\n description: joi.string().required(),\n type: joi\n .string()\n .allow(AutomationStepType.ACTION, AutomationStepType.LOGIC)\n .required(),\n stepId: joi\n .string()\n .disallow(...AutomationStepIdArray)\n .required(),\n inputs: joi.object().optional(),\n schema: joi\n .object({\n inputs: stepSchemaValidator,\n outputs: stepSchemaValidator,\n })\n .required(),\n }),\n })\n runJoi(validator, schema)\n}\n\nexport function validate(schema: any) {\n switch (schema?.type) {\n case PluginType.COMPONENT:\n validateComponent(schema)\n break\n case PluginType.DATASOURCE:\n validateDatasource(schema)\n break\n case PluginType.AUTOMATION:\n validateAutomation(schema)\n break\n default:\n throw new Error(`Unknown plugin type - check schema.json: ${schema.type}`)\n }\n}\n", "export * from \"./objectStore\"\nexport * from \"./utils\"\nexport * from \"./buckets\"\n", "const sanitize = require(\"sanitize-s3-objectkey\")\nimport AWS from \"aws-sdk\"\nimport stream from \"stream\"\nimport fetch from \"node-fetch\"\nimport tar from \"tar-fs\"\nimport zlib from \"zlib\"\nimport { promisify } from \"util\"\nimport { join } from \"path\"\nimport fs from \"fs\"\nimport env from \"../environment\"\nimport { budibaseTempDir } from \"./utils\"\nimport { v4 } from \"uuid\"\nimport { APP_PREFIX, APP_DEV_PREFIX } from \"../db\"\n\nconst streamPipeline = promisify(stream.pipeline)\n// use this as a temporary store of buckets that are being created\nconst STATE = {\n bucketCreationPromises: {},\n}\n\ntype ListParams = {\n ContinuationToken?: string\n}\n\ntype UploadParams = {\n bucket: string\n filename: string\n path: string\n type?: string | null\n // can be undefined, we will remove it\n metadata?: {\n [key: string]: string | undefined\n }\n}\n\nconst CONTENT_TYPE_MAP: any = {\n txt: \"text/plain\",\n html: \"text/html\",\n css: \"text/css\",\n js: \"application/javascript\",\n json: \"application/json\",\n gz: \"application/gzip\",\n}\n\nconst STRING_CONTENT_TYPES = [\n CONTENT_TYPE_MAP.html,\n CONTENT_TYPE_MAP.css,\n CONTENT_TYPE_MAP.js,\n CONTENT_TYPE_MAP.json,\n]\n\n// does normal sanitization and then swaps dev apps to apps\nexport function sanitizeKey(input: string) {\n return sanitize(sanitizeBucket(input)).replace(/\\\\/g, \"/\")\n}\n\n// simply handles the dev app to app conversion\nexport function sanitizeBucket(input: string) {\n return input.replace(new RegExp(APP_DEV_PREFIX, \"g\"), APP_PREFIX)\n}\n\n/**\n * Gets a connection to the object store using the S3 SDK.\n * @param {string} bucket the name of the bucket which blobs will be uploaded/retrieved from.\n * @param {object} opts configuration for the object store.\n * @return {Object} an S3 object store object, check S3 Nodejs SDK for usage.\n * @constructor\n */\nexport const ObjectStore = (\n bucket: string,\n opts: { presigning: boolean } = { presigning: false }\n) => {\n const config: any = {\n s3ForcePathStyle: true,\n signatureVersion: \"v4\",\n apiVersion: \"2006-03-01\",\n accessKeyId: env.MINIO_ACCESS_KEY,\n secretAccessKey: env.MINIO_SECRET_KEY,\n region: env.AWS_REGION,\n }\n if (bucket) {\n config.params = {\n Bucket: sanitizeBucket(bucket),\n }\n }\n\n // custom S3 is in use i.e. minio\n if (env.MINIO_URL) {\n if (opts.presigning && env.MINIO_ENABLED) {\n // IMPORTANT: Signed urls will inspect the host header of the request.\n // Normally a signed url will need to be generated with a specified host in mind.\n // To support dynamic hosts, e.g. some unknown self-hosted installation url,\n // use a predefined host. The host 'minio-service' is also forwarded to minio requests via nginx\n config.endpoint = \"minio-service\"\n } else {\n config.endpoint = env.MINIO_URL\n }\n }\n\n return new AWS.S3(config)\n}\n\n/**\n * Given an object store and a bucket name this will make sure the bucket exists,\n * if it does not exist then it will create it.\n */\nexport const makeSureBucketExists = async (client: any, bucketName: string) => {\n bucketName = sanitizeBucket(bucketName)\n try {\n await client\n .headBucket({\n Bucket: bucketName,\n })\n .promise()\n } catch (err: any) {\n const promises: any = STATE.bucketCreationPromises\n const doesntExist = err.statusCode === 404,\n noAccess = err.statusCode === 403\n if (promises[bucketName]) {\n await promises[bucketName]\n } else if (doesntExist || noAccess) {\n if (doesntExist) {\n // bucket doesn't exist create it\n promises[bucketName] = client\n .createBucket({\n Bucket: bucketName,\n })\n .promise()\n await promises[bucketName]\n delete promises[bucketName]\n }\n } else {\n throw new Error(\"Unable to write to object store bucket.\")\n }\n }\n}\n\n/**\n * Uploads the contents of a file given the required parameters, useful when\n * temp files in use (for example file uploaded as an attachment).\n */\nexport const upload = async ({\n bucket: bucketName,\n filename,\n path,\n type,\n metadata,\n}: UploadParams) => {\n const extension = filename.split(\".\").pop()\n const fileBytes = fs.readFileSync(path)\n\n const objectStore = ObjectStore(bucketName)\n await makeSureBucketExists(objectStore, bucketName)\n\n let contentType = type\n if (!contentType) {\n contentType = extension\n ? CONTENT_TYPE_MAP[extension.toLowerCase()]\n : CONTENT_TYPE_MAP.txt\n }\n const config: any = {\n // windows file paths need to be converted to forward slashes for s3\n Key: sanitizeKey(filename),\n Body: fileBytes,\n ContentType: contentType,\n }\n if (metadata && typeof metadata === \"object\") {\n // remove any nullish keys from the metadata object, as these may be considered invalid\n for (let key of Object.keys(metadata)) {\n if (!metadata[key] || typeof metadata[key] !== \"string\") {\n delete metadata[key]\n }\n }\n config.Metadata = metadata\n }\n return objectStore.upload(config).promise()\n}\n\n/**\n * Similar to the upload function but can be used to send a file stream\n * through to the object store.\n */\nexport const streamUpload = async (\n bucketName: string,\n filename: string,\n stream: any,\n extra = {}\n) => {\n const objectStore = ObjectStore(bucketName)\n await makeSureBucketExists(objectStore, bucketName)\n\n // Set content type for certain known extensions\n if (filename?.endsWith(\".js\")) {\n extra = {\n ...extra,\n ContentType: \"application/javascript\",\n }\n } else if (filename?.endsWith(\".svg\")) {\n extra = {\n ...extra,\n ContentType: \"image\",\n }\n }\n\n const params = {\n Bucket: sanitizeBucket(bucketName),\n Key: sanitizeKey(filename),\n Body: stream,\n ...extra,\n }\n return objectStore.upload(params).promise()\n}\n\n/**\n * retrieves the contents of a file from the object store, if it is a known content type it\n * will be converted, otherwise it will be returned as a buffer stream.\n */\nexport const retrieve = async (bucketName: string, filepath: string) => {\n const objectStore = ObjectStore(bucketName)\n const params = {\n Bucket: sanitizeBucket(bucketName),\n Key: sanitizeKey(filepath),\n }\n const response: any = await objectStore.getObject(params).promise()\n // currently these are all strings\n if (STRING_CONTENT_TYPES.includes(response.ContentType)) {\n return response.Body.toString(\"utf8\")\n } else {\n return response.Body\n }\n}\n\nexport const listAllObjects = async (bucketName: string, path: string) => {\n const objectStore = ObjectStore(bucketName)\n const list = (params: ListParams = {}) => {\n return objectStore\n .listObjectsV2({\n ...params,\n Bucket: sanitizeBucket(bucketName),\n Prefix: sanitizeKey(path),\n })\n .promise()\n }\n let isTruncated = false,\n token,\n objects: AWS.S3.Types.Object[] = []\n do {\n let params: ListParams = {}\n if (token) {\n params.ContinuationToken = token\n }\n const response = await list(params)\n if (response.Contents) {\n objects = objects.concat(response.Contents)\n }\n isTruncated = !!response.IsTruncated\n } while (isTruncated)\n return objects\n}\n\n/**\n * Generate a presigned url with a default TTL of 1 hour\n */\nexport const getPresignedUrl = (\n bucketName: string,\n key: string,\n durationSeconds: number = 3600\n) => {\n const objectStore = ObjectStore(bucketName, { presigning: true })\n const params = {\n Bucket: sanitizeBucket(bucketName),\n Key: sanitizeKey(key),\n Expires: durationSeconds,\n }\n const url = objectStore.getSignedUrl(\"getObject\", params)\n\n if (!env.MINIO_ENABLED) {\n // return the full URL to the client\n return url\n } else {\n // return the path only to the client\n // use the presigned url route to ensure the static\n // hostname will be used in the request\n const signedUrl = new URL(url)\n const path = signedUrl.pathname\n const query = signedUrl.search\n return `/files/signed${path}${query}`\n }\n}\n\n/**\n * Same as retrieval function but puts to a temporary file.\n */\nexport const retrieveToTmp = async (bucketName: string, filepath: string) => {\n bucketName = sanitizeBucket(bucketName)\n filepath = sanitizeKey(filepath)\n const data = await retrieve(bucketName, filepath)\n const outputPath = join(budibaseTempDir(), v4())\n fs.writeFileSync(outputPath, data)\n return outputPath\n}\n\nexport const retrieveDirectory = async (bucketName: string, path: string) => {\n let writePath = join(budibaseTempDir(), v4())\n fs.mkdirSync(writePath)\n const objects = await listAllObjects(bucketName, path)\n let fullObjects = await Promise.all(\n objects.map(obj => retrieve(bucketName, obj.Key!))\n )\n let count = 0\n for (let obj of objects) {\n const filename = obj.Key!\n const data = fullObjects[count++]\n const possiblePath = filename.split(\"/\")\n if (possiblePath.length > 1) {\n const dirs = possiblePath.slice(0, possiblePath.length - 1)\n fs.mkdirSync(join(writePath, ...dirs), { recursive: true })\n }\n fs.writeFileSync(join(writePath, ...possiblePath), data)\n }\n return writePath\n}\n\n/**\n * Delete a single file.\n */\nexport const deleteFile = async (bucketName: string, filepath: string) => {\n const objectStore = ObjectStore(bucketName)\n await makeSureBucketExists(objectStore, bucketName)\n const params = {\n Bucket: bucketName,\n Key: sanitizeKey(filepath),\n }\n return objectStore.deleteObject(params).promise()\n}\n\nexport const deleteFiles = async (bucketName: string, filepaths: string[]) => {\n const objectStore = ObjectStore(bucketName)\n await makeSureBucketExists(objectStore, bucketName)\n const params = {\n Bucket: bucketName,\n Delete: {\n Objects: filepaths.map((path: any) => ({ Key: sanitizeKey(path) })),\n },\n }\n return objectStore.deleteObjects(params).promise()\n}\n\n/**\n * Delete a path, including everything within.\n */\nexport const deleteFolder = async (\n bucketName: string,\n folder: string\n): Promise<any> => {\n bucketName = sanitizeBucket(bucketName)\n folder = sanitizeKey(folder)\n const client = ObjectStore(bucketName)\n const listParams = {\n Bucket: bucketName,\n Prefix: folder,\n }\n\n const existingObjectsResponse = await client.listObjects(listParams).promise()\n if (existingObjectsResponse.Contents?.length === 0) {\n return\n }\n const deleteParams: any = {\n Bucket: bucketName,\n Delete: {\n Objects: [],\n },\n }\n\n existingObjectsResponse.Contents?.forEach((content: any) => {\n deleteParams.Delete.Objects.push({ Key: content.Key })\n })\n\n const deleteResponse = await client.deleteObjects(deleteParams).promise()\n // can only empty 1000 items at once\n if (deleteResponse.Deleted?.length === 1000) {\n return deleteFolder(bucketName, folder)\n }\n}\n\nexport const uploadDirectory = async (\n bucketName: string,\n localPath: string,\n bucketPath: string\n) => {\n bucketName = sanitizeBucket(bucketName)\n let uploads = []\n const files = fs.readdirSync(localPath, { withFileTypes: true })\n for (let file of files) {\n const path = sanitizeKey(join(bucketPath, file.name))\n const local = join(localPath, file.name)\n if (file.isDirectory()) {\n uploads.push(uploadDirectory(bucketName, local, path))\n } else {\n uploads.push(streamUpload(bucketName, path, fs.createReadStream(local)))\n }\n }\n await Promise.all(uploads)\n return files\n}\n\nexport const downloadTarballDirect = async (\n url: string,\n path: string,\n headers = {}\n) => {\n path = sanitizeKey(path)\n const response = await fetch(url, { headers })\n if (!response.ok) {\n throw new Error(`unexpected response ${response.statusText}`)\n }\n\n await streamPipeline(response.body, zlib.createUnzip(), tar.extract(path))\n}\n\nexport const downloadTarball = async (\n url: string,\n bucketName: string,\n path: string\n) => {\n bucketName = sanitizeBucket(bucketName)\n path = sanitizeKey(path)\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(`unexpected response ${response.statusText}`)\n }\n\n const tmpPath = join(budibaseTempDir(), path)\n await streamPipeline(response.body, zlib.createUnzip(), tar.extract(tmpPath))\n if (!env.isTest() && env.SELF_HOSTED) {\n await uploadDirectory(bucketName, tmpPath, path)\n }\n // return the temporary path incase there is a use for it\n return tmpPath\n}\n", "import { join } from \"path\"\nimport { tmpdir } from \"os\"\nimport fs from \"fs\"\nimport env from \"../environment\"\n\n/****************************************************\n * NOTE: When adding a new bucket - name *\n * sure that S3 usages (like budibase-infra) *\n * have been updated to have a unique bucket name. *\n ****************************************************/\n// can't be an enum - only numbers can be used for computed types\nexport const ObjectStoreBuckets = {\n BACKUPS: env.BACKUPS_BUCKET_NAME,\n APPS: env.APPS_BUCKET_NAME,\n TEMPLATES: env.TEMPLATES_BUCKET_NAME,\n GLOBAL: env.GLOBAL_BUCKET_NAME,\n PLUGINS: env.PLUGIN_BUCKET_NAME,\n}\n\nconst bbTmp = join(tmpdir(), \".budibase\")\nif (!fs.existsSync(bbTmp)) {\n fs.mkdirSync(bbTmp)\n}\n\nexport function budibaseTempDir() {\n return bbTmp\n}\n", "import env from \"../../environment\"\nimport * as objectStore from \"../objectStore\"\nimport * as cloudfront from \"../cloudfront\"\n\n/**\n * In production the client library is stored in the object store, however in development\n * we use the symlinked version produced by lerna, located in node modules. We link to this\n * via a specific endpoint (under /api/assets/client).\n * @param {string} appId In production we need the appId to look up the correct bucket, as the\n * version of the client lib may differ between apps.\n * @param {string} version The version to retrieve.\n * @return {string} The URL to be inserted into appPackage response or server rendered\n * app index file.\n */\nexport const clientLibraryUrl = (appId: string, version: string) => {\n if (env.isProd()) {\n let file = `${objectStore.sanitizeKey(appId)}/budibase-client.js`\n if (env.CLOUDFRONT_CDN) {\n // append app version to bust the cache\n if (version) {\n file += `?v=${version}`\n }\n // don't need to use presigned for client with cloudfront\n // file is public\n return cloudfront.getUrl(file)\n } else {\n return objectStore.getPresignedUrl(env.APPS_BUCKET_NAME, file)\n }\n } else {\n return `/api/assets/client`\n }\n}\n\nexport const getAppFileUrl = (s3Key: string) => {\n if (env.CLOUDFRONT_CDN) {\n return cloudfront.getPresignedUrl(s3Key)\n } else {\n return objectStore.getPresignedUrl(env.APPS_BUCKET_NAME, s3Key)\n }\n}\n", "import env from \"../environment\"\nconst cfsign = require(\"aws-cloudfront-sign\")\n\nlet PRIVATE_KEY: string | undefined\n\nfunction getPrivateKey() {\n if (!env.CLOUDFRONT_PRIVATE_KEY_64) {\n throw new Error(\"CLOUDFRONT_PRIVATE_KEY_64 is not set\")\n }\n\n if (PRIVATE_KEY) {\n return PRIVATE_KEY\n }\n\n PRIVATE_KEY = Buffer.from(env.CLOUDFRONT_PRIVATE_KEY_64, \"base64\").toString(\n \"utf-8\"\n )\n\n return PRIVATE_KEY\n}\n\nconst getCloudfrontSignParams = () => {\n return {\n keypairId: env.CLOUDFRONT_PUBLIC_KEY_ID,\n privateKeyString: getPrivateKey(),\n expireTime: new Date().getTime() + 1000 * 60 * 60, // 1 hour\n }\n}\n\nexport const getPresignedUrl = (s3Key: string) => {\n const url = getUrl(s3Key)\n return cfsign.getSignedUrl(url, getCloudfrontSignParams())\n}\n\nexport const getUrl = (s3Key: string) => {\n let prefix = \"/\"\n if (s3Key.startsWith(\"/\")) {\n prefix = \"\"\n }\n return `${env.CLOUDFRONT_CDN}${prefix}${s3Key}`\n}\n", "import env from \"../../environment\"\nimport * as context from \"../../context\"\nimport * as objectStore from \"../objectStore\"\nimport * as cloudfront from \"../cloudfront\"\n\n// URLs\n\nexport const getGlobalFileUrl = (type: string, name: string, etag?: string) => {\n let file = getGlobalFileS3Key(type, name)\n if (env.CLOUDFRONT_CDN) {\n if (etag) {\n file = `${file}?etag=${etag}`\n }\n return cloudfront.getPresignedUrl(file)\n } else {\n return objectStore.getPresignedUrl(env.GLOBAL_BUCKET_NAME, file)\n }\n}\n\n// KEYS\n\nexport const getGlobalFileS3Key = (type: string, name: string) => {\n let file = `${type}/${name}`\n if (env.MULTI_TENANCY) {\n const tenantId = context.getTenantId()\n file = `${tenantId}/${file}`\n }\n return file\n}\n", "import env from \"../../environment\"\nimport * as objectStore from \"../objectStore\"\nimport * as context from \"../../context\"\nimport * as cloudfront from \"../cloudfront\"\nimport { Plugin } from \"@budibase/types\"\n\n// URLS\n\nexport const enrichPluginURLs = (plugins: Plugin[]) => {\n if (!plugins || !plugins.length) {\n return []\n }\n return plugins.map(plugin => {\n const jsUrl = getPluginJSUrl(plugin)\n const iconUrl = getPluginIconUrl(plugin)\n return { ...plugin, jsUrl, iconUrl }\n })\n}\n\nconst getPluginJSUrl = (plugin: Plugin) => {\n const s3Key = getPluginJSKey(plugin)\n return getPluginUrl(s3Key)\n}\n\nconst getPluginIconUrl = (plugin: Plugin): string | undefined => {\n const s3Key = getPluginIconKey(plugin)\n if (!s3Key) {\n return\n }\n return getPluginUrl(s3Key)\n}\n\nconst getPluginUrl = (s3Key: string) => {\n if (env.CLOUDFRONT_CDN) {\n return cloudfront.getPresignedUrl(s3Key)\n } else {\n return objectStore.getPresignedUrl(env.PLUGIN_BUCKET_NAME, s3Key)\n }\n}\n\n// S3 KEYS\n\nexport const getPluginJSKey = (plugin: Plugin) => {\n return getPluginS3Key(plugin, \"plugin.min.js\")\n}\n\nexport const getPluginIconKey = (plugin: Plugin) => {\n // stored iconUrl is deprecated - hardcode to icon.svg in this case\n const iconFileName = plugin.iconUrl ? \"icon.svg\" : plugin.iconFileName\n if (!iconFileName) {\n return\n }\n return getPluginS3Key(plugin, iconFileName)\n}\n\nconst getPluginS3Key = (plugin: Plugin, fileName: string) => {\n const s3Key = getPluginS3Dir(plugin.name)\n return `${s3Key}/${fileName}`\n}\n\nexport const getPluginS3Dir = (pluginName: string) => {\n let s3Key = `${pluginName}`\n if (env.MULTI_TENANCY) {\n const tenantId = context.getTenantId()\n s3Key = `${tenantId}/${s3Key}`\n }\n if (env.CLOUDFRONT_CDN) {\n s3Key = `plugins/${s3Key}`\n }\n return s3Key\n}\n", "// Mimic the outer package export for usage in index.ts\n// The outer exports can't be used as they now reference dist directly\nexport { default as Client } from \"./redis\"\nexport * as utils from \"./utils\"\nexport * as clients from \"./init\"\nexport * as locks from \"./redlockImpl\"\n", "export * from \"./blacklist\"\n", "import dns from \"dns\"\nimport net from \"net\"\nimport env from \"../environment\"\nimport { promisify } from \"util\"\n\nlet blackListArray: string[] | undefined\nconst performLookup = promisify(dns.lookup)\n\nasync function lookup(address: string): Promise<string[]> {\n if (!net.isIP(address)) {\n // need this for URL parsing simply\n if (!address.startsWith(\"http\")) {\n address = `https://${address}`\n }\n address = new URL(address).hostname\n }\n const addresses = await performLookup(address, {\n all: true,\n })\n return addresses.map(addr => addr.address)\n}\n\nexport async function refreshBlacklist() {\n const blacklist = env.BLACKLIST_IPS\n const list = blacklist?.split(\",\") || []\n let final: string[] = []\n for (let addr of list) {\n const trimmed = addr.trim()\n if (!net.isIP(trimmed)) {\n const addresses = await lookup(trimmed)\n final = final.concat(addresses)\n } else {\n final.push(trimmed)\n }\n }\n blackListArray = final\n}\n\nexport async function isBlacklisted(address: string): Promise<boolean> {\n if (!blackListArray) {\n await refreshBlacklist()\n }\n if (blackListArray?.length === 0) {\n return false\n }\n // no need for DNS\n let ips: string[]\n if (!net.isIP(address)) {\n ips = await lookup(address)\n } else {\n ips = [address]\n }\n return !!blackListArray?.find(addr => ips.includes(addr))\n}\n", "import { EventProcessor } from \"../types\"\nimport { Event, Identity, DocUpdateEvent } from \"@budibase/types\"\nimport { doInTenant } from \"../../../context\"\nimport { getDocumentId } from \"../../documentId\"\nimport { shutdown } from \"../../asyncEvents\"\n\nexport type Processor = (update: DocUpdateEvent) => Promise<void>\nexport type ProcessorMap = { events: Event[]; processor: Processor }[]\n\nexport default class DocumentUpdateProcessor implements EventProcessor {\n processors: ProcessorMap = []\n\n constructor(processors: ProcessorMap) {\n this.processors = processors\n }\n\n async processEvent(\n event: Event,\n identity: Identity,\n properties: any,\n timestamp?: string | number\n ) {\n const tenantId = identity.realTenantId\n const docId = getDocumentId(event, properties)\n if (!tenantId || !docId) {\n return\n }\n for (let { events, processor } of this.processors) {\n if (events.includes(event)) {\n await doInTenant(tenantId, async () => {\n await processor({\n id: docId,\n tenantId,\n })\n })\n }\n }\n }\n\n shutdown() {\n return shutdown()\n }\n}\n", "import {\n Event,\n UserCreatedEvent,\n UserUpdatedEvent,\n UserDeletedEvent,\n UserPermissionAssignedEvent,\n UserPermissionRemovedEvent,\n GroupCreatedEvent,\n GroupUpdatedEvent,\n GroupDeletedEvent,\n GroupUsersAddedEvent,\n GroupUsersDeletedEvent,\n GroupPermissionsEditedEvent,\n} from \"@budibase/types\"\n\nconst getEventProperties: Record<\n string,\n (properties: any) => string | undefined\n> = {\n [Event.USER_CREATED]: (properties: UserCreatedEvent) => properties.userId,\n [Event.USER_UPDATED]: (properties: UserUpdatedEvent) => properties.userId,\n [Event.USER_DELETED]: (properties: UserDeletedEvent) => properties.userId,\n [Event.USER_PERMISSION_ADMIN_ASSIGNED]: (\n properties: UserPermissionAssignedEvent\n ) => properties.userId,\n [Event.USER_PERMISSION_ADMIN_REMOVED]: (\n properties: UserPermissionRemovedEvent\n ) => properties.userId,\n [Event.USER_PERMISSION_BUILDER_ASSIGNED]: (\n properties: UserPermissionAssignedEvent\n ) => properties.userId,\n [Event.USER_PERMISSION_BUILDER_REMOVED]: (\n properties: UserPermissionRemovedEvent\n ) => properties.userId,\n [Event.USER_GROUP_CREATED]: (properties: GroupCreatedEvent) =>\n properties.groupId,\n [Event.USER_GROUP_UPDATED]: (properties: GroupUpdatedEvent) =>\n properties.groupId,\n [Event.USER_GROUP_DELETED]: (properties: GroupDeletedEvent) =>\n properties.groupId,\n [Event.USER_GROUP_USERS_ADDED]: (properties: GroupUsersAddedEvent) =>\n properties.groupId,\n [Event.USER_GROUP_USERS_REMOVED]: (properties: GroupUsersDeletedEvent) =>\n properties.groupId,\n [Event.USER_GROUP_PERMISSIONS_EDITED]: (\n properties: GroupPermissionsEditedEvent\n ) => properties.groupId,\n}\n\nexport function getDocumentId(event: Event, properties: any) {\n const extractor = getEventProperties[event]\n if (!extractor) {\n throw new Error(\"Event does not have a method of document ID extraction\")\n }\n return extractor(properties)\n}\n", "import * as core from \"@budibase/backend-core\"\nimport env from \"../environment\"\n\nexport function init() {\n const dbConfig: any = {\n replication: true,\n find: true,\n }\n\n if (env.isTest() && !env.COUCH_DB_URL) {\n dbConfig.inMemory = true\n dbConfig.allDbs = true\n }\n\n core.init({ db: dbConfig })\n}\n", "import { QueryVariable } from \"./definitions\"\nimport env from \"../environment\"\nimport * as db from \"../db\"\nimport { redis, db as dbCore } from \"@budibase/backend-core\"\n\nconst VARIABLE_TTL_SECONDS = 3600\nlet client: any\n\nasync function getClient() {\n if (!client) {\n client = await new redis.Client(redis.utils.Databases.QUERY_VARS).init()\n }\n return client\n}\n\nprocess.on(\"exit\", async () => {\n if (client) {\n await client.finish()\n }\n})\n\nfunction makeVariableKey(queryId: string, variable: string) {\n return `${queryId}${dbCore.SEPARATOR}${variable}`\n}\n\nexport function threadSetup() {\n // don't run this if not threading\n if (env.isTest() || env.DISABLE_THREADING || !env.isInThread()) {\n console.debug(`[${env.FORKED_PROCESS_NAME}] thread setup skipped`)\n return\n }\n console.debug(`[${env.FORKED_PROCESS_NAME}] thread setup running`)\n db.init()\n}\n\nexport async function checkCacheForDynamicVariable(\n queryId: string,\n variable: string\n) {\n const cache = await getClient()\n return cache.get(makeVariableKey(queryId, variable))\n}\n\nexport async function invalidateDynamicVariables(cachedVars: QueryVariable[]) {\n const cache = await getClient()\n let promises = []\n for (let variable of cachedVars) {\n promises.push(\n cache.delete(makeVariableKey(variable.queryId, variable.name))\n )\n }\n await Promise.all(promises)\n}\n\nexport async function storeDynamicVariable(\n queryId: string,\n variable: string,\n value: any\n) {\n const cache = await getClient()\n await cache.store(\n makeVariableKey(queryId, variable),\n value,\n VARIABLE_TTL_SECONDS\n )\n}\n\nexport function formatResponse(resp: any) {\n if (typeof resp === \"string\") {\n try {\n resp = JSON.parse(resp)\n } catch (err) {\n resp = { response: resp }\n }\n }\n return resp\n}\n\nexport function hasExtraData(response: any) {\n return (\n typeof response === \"object\" &&\n !Array.isArray(response) &&\n response &&\n response.data != null &&\n response.info != null\n )\n}\n\nexport default {\n hasExtraData,\n formatResponse,\n storeDynamicVariable,\n invalidateDynamicVariables,\n checkCacheForDynamicVariable,\n threadSetup,\n}\n", "import fetch from \"node-fetch\"\nimport { VM, VMScript } from \"vm2\"\nconst JS_TIMEOUT_MS = 1000\n\nclass ScriptRunner {\n vm: VM\n results: { out: string }\n script: VMScript\n\n constructor(script: string, context: any) {\n const code = `let fn = () => {\\n${script}\\n}; results.out = fn();`\n this.vm = new VM({\n timeout: JS_TIMEOUT_MS,\n })\n this.results = { out: \"\" }\n this.vm.setGlobals(context)\n this.vm.setGlobal(\"fetch\", fetch)\n this.vm.setGlobal(\"results\", this.results)\n this.script = new VMScript(code)\n }\n\n execute() {\n this.vm.run(this.script)\n return this.results.out\n }\n}\n\nexport default ScriptRunner\n", "import {\n Integration,\n DatasourceFieldType,\n QueryType,\n QueryJson,\n SqlQuery,\n Table,\n DatasourcePlus,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\nimport {\n getSqlQuery,\n buildExternalTableId,\n convertSqlType,\n finaliseExternalTables,\n SqlClient,\n} from \"./utils\"\nimport Sql from \"./base/sql\"\nimport { PostgresColumn } from \"./base/types\"\nimport { escapeDangerousCharacters } from \"../utilities\"\n\nimport { Client, types } from \"pg\"\n\n// Return \"date\" and \"timestamp\" types as plain strings.\n// This lets us reference the original stored timezone.\n// types is undefined when running in a test env for some reason.\nif (types) {\n types.setTypeParser(1114, (val: any) => val) // timestamp\n types.setTypeParser(1082, (val: any) => val) // date\n types.setTypeParser(1184, (val: any) => val) // timestampz\n}\n\nconst JSON_REGEX = /'{.*}'::json/s\n\ninterface PostgresConfig {\n host: string\n port: number\n database: string\n user: string\n password: string\n schema: string\n ssl?: boolean\n ca?: string\n rejectUnauthorized?: boolean\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://node-postgres.com\",\n plus: true,\n friendlyName: \"PostgreSQL\",\n type: \"Relational\",\n description:\n \"PostgreSQL, also known as Postgres, is a free and open-source relational database management system emphasizing extensibility and SQL compliance.\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n [DatasourceFeature.FETCH_TABLE_NAMES]: true,\n },\n datasource: {\n host: {\n type: DatasourceFieldType.STRING,\n default: \"localhost\",\n required: true,\n },\n port: {\n type: DatasourceFieldType.NUMBER,\n required: true,\n default: 5432,\n },\n database: {\n type: DatasourceFieldType.STRING,\n default: \"postgres\",\n required: true,\n },\n user: {\n type: DatasourceFieldType.STRING,\n default: \"root\",\n required: true,\n },\n password: {\n type: DatasourceFieldType.PASSWORD,\n default: \"root\",\n required: true,\n },\n schema: {\n type: DatasourceFieldType.STRING,\n default: \"public\",\n required: true,\n },\n ssl: {\n type: DatasourceFieldType.BOOLEAN,\n default: false,\n required: false,\n },\n rejectUnauthorized: {\n type: DatasourceFieldType.BOOLEAN,\n default: false,\n required: false,\n },\n ca: {\n type: DatasourceFieldType.LONGFORM,\n default: false,\n required: false,\n },\n },\n query: {\n create: {\n type: QueryType.SQL,\n },\n read: {\n type: QueryType.SQL,\n },\n update: {\n type: QueryType.SQL,\n },\n delete: {\n type: QueryType.SQL,\n },\n },\n}\n\nclass PostgresIntegration extends Sql implements DatasourcePlus {\n private readonly client: Client\n private readonly config: PostgresConfig\n private index: number = 1\n private open: boolean\n public tables: Record<string, Table> = {}\n public schemaErrors: Record<string, string> = {}\n\n COLUMNS_SQL!: string\n\n PRIMARY_KEYS_SQL = () => `\n SELECT pg_namespace.nspname table_schema\n , pg_class.relname table_name\n , pg_attribute.attname primary_key\n FROM pg_class\n JOIN pg_index ON pg_class.oid = pg_index.indrelid AND pg_index.indisprimary\n JOIN pg_attribute ON pg_attribute.attrelid = pg_class.oid AND pg_attribute.attnum = ANY(pg_index.indkey)\n JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace\n WHERE pg_namespace.nspname = '${this.config.schema}';\n `\n\n constructor(config: PostgresConfig) {\n super(SqlClient.POSTGRES)\n this.config = config\n\n let newConfig = {\n ...this.config,\n ssl: this.config.ssl\n ? {\n rejectUnauthorized: this.config.rejectUnauthorized,\n ca: this.config.ca,\n }\n : undefined,\n }\n this.client = new Client(newConfig)\n this.open = false\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n try {\n await this.openConnection()\n response.connected = true\n } catch (e: any) {\n response.error = e.message as string\n } finally {\n await this.closeConnection()\n }\n return response\n }\n\n getBindingIdentifier(): string {\n return `$${this.index++}`\n }\n\n getStringConcat(parts: string[]): string {\n return parts.join(\" || \")\n }\n\n async openConnection() {\n await this.client.connect()\n if (!this.config.schema) {\n this.config.schema = \"public\"\n }\n await this.client.query(`SET search_path TO ${this.config.schema}`)\n this.COLUMNS_SQL = `select * from information_schema.columns where table_schema = '${this.config.schema}'`\n this.open = true\n }\n\n closeConnection() {\n const pg = this\n return new Promise<void>((resolve, reject) => {\n this.client.end((err: any) => {\n pg.open = false\n if (err) {\n reject(err)\n } else {\n resolve()\n }\n })\n })\n }\n\n async internalQuery(query: SqlQuery, close: boolean = true) {\n if (!this.open) {\n await this.openConnection()\n }\n const client = this.client\n this.index = 1\n // need to handle a specific issue with json data types in postgres,\n // new lines inside the JSON data will break it\n if (query && query.sql) {\n const matches = query.sql.match(JSON_REGEX)\n if (matches && matches.length > 0) {\n for (let match of matches) {\n const escaped = escapeDangerousCharacters(match)\n query.sql = query.sql.replace(match, escaped)\n }\n }\n }\n try {\n return await client.query(query.sql, query.bindings || [])\n } catch (err) {\n await this.closeConnection()\n // @ts-ignore\n throw new Error(err)\n } finally {\n if (close) {\n await this.closeConnection()\n }\n }\n }\n\n /**\n * Fetches the tables from the postgres table and assigns them to the datasource.\n * @param {*} datasourceId - datasourceId to fetch\n * @param entities - the tables that are to be built\n */\n async buildSchema(datasourceId: string, entities: Record<string, Table>) {\n let tableKeys: { [key: string]: string[] } = {}\n await this.openConnection()\n try {\n const primaryKeysResponse = await this.client.query(\n this.PRIMARY_KEYS_SQL()\n )\n for (let table of primaryKeysResponse.rows) {\n const tableName = table.table_name\n if (!tableKeys[tableName]) {\n tableKeys[tableName] = []\n }\n const key = table.column_name || table.primary_key\n // only add the unique keys\n if (key && tableKeys[tableName].indexOf(key) === -1) {\n tableKeys[tableName].push(key)\n }\n }\n } catch (err) {\n tableKeys = {}\n }\n\n try {\n const columnsResponse: { rows: PostgresColumn[] } =\n await this.client.query(this.COLUMNS_SQL)\n\n const tables: { [key: string]: Table } = {}\n\n for (let column of columnsResponse.rows) {\n const tableName: string = column.table_name\n const columnName: string = column.column_name\n\n // table key doesn't exist yet\n if (!tables[tableName] || !tables[tableName].schema) {\n tables[tableName] = {\n _id: buildExternalTableId(datasourceId, tableName),\n primary: tableKeys[tableName] || [],\n name: tableName,\n schema: {},\n }\n }\n\n const identity = !!(\n column.identity_generation ||\n column.identity_start ||\n column.identity_increment\n )\n const hasDefault = column.column_default != null\n const hasNextVal =\n typeof column.column_default === \"string\" &&\n column.column_default.startsWith(\"nextval\")\n const isGenerated =\n column.is_generated && column.is_generated !== \"NEVER\"\n const isAuto: boolean = hasNextVal || identity || isGenerated\n const required = column.is_nullable === \"NO\"\n const constraints = {\n presence: required && !hasDefault && !isGenerated,\n }\n tables[tableName].schema[columnName] = {\n autocolumn: isAuto,\n name: columnName,\n constraints,\n ...convertSqlType(column.data_type),\n externalType: column.data_type,\n }\n }\n\n const final = finaliseExternalTables(tables, entities)\n this.tables = final.tables\n this.schemaErrors = final.errors\n } catch (err) {\n // @ts-ignore\n throw new Error(err)\n } finally {\n await this.closeConnection()\n }\n }\n\n async getTableNames() {\n try {\n await this.openConnection()\n const columnsResponse: { rows: PostgresColumn[] } =\n await this.client.query(this.COLUMNS_SQL)\n return columnsResponse.rows.map(row => row.table_name)\n } finally {\n await this.closeConnection()\n }\n }\n\n async create(query: SqlQuery | string) {\n const response = await this.internalQuery(getSqlQuery(query))\n return response.rows.length ? response.rows : [{ created: true }]\n }\n\n async read(query: SqlQuery | string) {\n const response = await this.internalQuery(getSqlQuery(query))\n return response.rows\n }\n\n async update(query: SqlQuery | string) {\n const response = await this.internalQuery(getSqlQuery(query))\n return response.rows.length ? response.rows : [{ updated: true }]\n }\n\n async delete(query: SqlQuery | string) {\n const response = await this.internalQuery(getSqlQuery(query))\n return response.rows.length ? response.rows : [{ deleted: true }]\n }\n\n async query(json: QueryJson) {\n const operation = this._operation(json).toLowerCase()\n const input = this._query(json)\n if (Array.isArray(input)) {\n const responses = []\n for (let query of input) {\n responses.push(await this.internalQuery(query, false))\n }\n await this.closeConnection()\n return responses\n } else {\n const response = await this.internalQuery(input)\n return response.rows.length ? response.rows : [{ [operation]: true }]\n }\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: PostgresIntegration,\n}\n", "import { SourceName, SqlQuery, Datasource, Table } from \"@budibase/types\"\nimport { DocumentType, SEPARATOR } from \"../db/utils\"\nimport { FieldTypes, BuildSchemaErrors, InvalidColumns } from \"../constants\"\n\nconst DOUBLE_SEPARATOR = `${SEPARATOR}${SEPARATOR}`\nconst ROW_ID_REGEX = /^\\[.*]$/g\nconst ENCODED_SPACE = encodeURIComponent(\" \")\n\nconst SQL_NUMBER_TYPE_MAP = {\n integer: FieldTypes.NUMBER,\n int: FieldTypes.NUMBER,\n decimal: FieldTypes.NUMBER,\n smallint: FieldTypes.NUMBER,\n real: FieldTypes.NUMBER,\n float: FieldTypes.NUMBER,\n numeric: FieldTypes.NUMBER,\n mediumint: FieldTypes.NUMBER,\n dec: FieldTypes.NUMBER,\n double: FieldTypes.NUMBER,\n fixed: FieldTypes.NUMBER,\n \"double precision\": FieldTypes.NUMBER,\n number: FieldTypes.NUMBER,\n binary_float: FieldTypes.NUMBER,\n binary_double: FieldTypes.NUMBER,\n money: FieldTypes.NUMBER,\n smallmoney: FieldTypes.NUMBER,\n}\n\nconst SQL_DATE_TYPE_MAP = {\n timestamp: FieldTypes.DATETIME,\n time: FieldTypes.DATETIME,\n datetime: FieldTypes.DATETIME,\n smalldatetime: FieldTypes.DATETIME,\n date: FieldTypes.DATETIME,\n}\n\nconst SQL_DATE_ONLY_TYPES = [\"date\"]\nconst SQL_TIME_ONLY_TYPES = [\"time\"]\n\nconst SQL_STRING_TYPE_MAP = {\n varchar: FieldTypes.STRING,\n char: FieldTypes.STRING,\n nchar: FieldTypes.STRING,\n nvarchar: FieldTypes.STRING,\n ntext: FieldTypes.STRING,\n enum: FieldTypes.STRING,\n blob: FieldTypes.STRING,\n long: FieldTypes.STRING,\n text: FieldTypes.STRING,\n bigint: FieldTypes.STRING,\n}\n\nconst SQL_BOOLEAN_TYPE_MAP = {\n boolean: FieldTypes.BOOLEAN,\n bit: FieldTypes.BOOLEAN,\n tinyint: FieldTypes.BOOLEAN,\n}\n\nconst SQL_MISC_TYPE_MAP = {\n json: FieldTypes.JSON,\n}\n\nconst SQL_TYPE_MAP = {\n ...SQL_NUMBER_TYPE_MAP,\n ...SQL_DATE_TYPE_MAP,\n ...SQL_STRING_TYPE_MAP,\n ...SQL_BOOLEAN_TYPE_MAP,\n ...SQL_MISC_TYPE_MAP,\n}\n\nexport enum SqlClient {\n MS_SQL = \"mssql\",\n POSTGRES = \"pg\",\n MY_SQL = \"mysql2\",\n ORACLE = \"oracledb\",\n}\n\nexport function isExternalTable(tableId: string) {\n return tableId.includes(DocumentType.DATASOURCE)\n}\n\nexport function buildExternalTableId(datasourceId: string, tableName: string) {\n // encode spaces\n if (tableName.includes(\" \")) {\n tableName = encodeURIComponent(tableName)\n }\n return `${datasourceId}${DOUBLE_SEPARATOR}${tableName}`\n}\n\nexport function breakExternalTableId(tableId: string | undefined) {\n if (!tableId) {\n return {}\n }\n const parts = tableId.split(DOUBLE_SEPARATOR)\n let datasourceId = parts.shift()\n // if they need joined\n let tableName = parts.join(DOUBLE_SEPARATOR)\n // if contains encoded spaces, decode it\n if (tableName.includes(ENCODED_SPACE)) {\n tableName = decodeURIComponent(tableName)\n }\n return { datasourceId, tableName }\n}\n\nexport function generateRowIdField(keyProps: any[] = []) {\n if (!Array.isArray(keyProps)) {\n keyProps = [keyProps]\n }\n // this conserves order and types\n // we have to swap the double quotes to single quotes for use in HBS statements\n // when using the literal helper the double quotes can break things\n return encodeURIComponent(JSON.stringify(keyProps).replace(/\"/g, \"'\"))\n}\n\nexport function isRowId(field: any) {\n return (\n Array.isArray(field) ||\n (typeof field === \"string\" && field.match(ROW_ID_REGEX) != null)\n )\n}\n\nexport function convertRowId(field: any) {\n if (Array.isArray(field)) {\n return field[0]\n }\n if (typeof field === \"string\" && field.match(ROW_ID_REGEX) != null) {\n return field.substring(1, field.length - 1)\n }\n return field\n}\n\n// should always return an array\nexport function breakRowIdField(_id: string | { _id: string }): any[] {\n if (!_id) {\n return []\n }\n // have to replace on the way back as we swapped out the double quotes\n // when encoding, but JSON can't handle the single quotes\n const id = typeof _id === \"string\" ? _id : _id._id\n const decoded: string = decodeURIComponent(id).replace(/'/g, '\"')\n try {\n const parsed = JSON.parse(decoded)\n return Array.isArray(parsed) ? parsed : [parsed]\n } catch (err) {\n // wasn't json - likely was handlebars for a many to many\n return [_id]\n }\n}\n\nexport function convertSqlType(type: string) {\n let foundType = FieldTypes.STRING\n const lcType = type.toLowerCase()\n let matchingTypes = []\n for (let [external, internal] of Object.entries(SQL_TYPE_MAP)) {\n if (lcType.includes(external)) {\n matchingTypes.push({ external, internal })\n }\n }\n //Set the foundType based the longest match\n if (matchingTypes.length > 0) {\n foundType = matchingTypes.reduce((acc, val) => {\n return acc.external.length >= val.external.length ? acc : val\n }).internal\n }\n const schema: any = { type: foundType }\n if (foundType === FieldTypes.DATETIME) {\n schema.dateOnly = SQL_DATE_ONLY_TYPES.includes(lcType)\n schema.timeOnly = SQL_TIME_ONLY_TYPES.includes(lcType)\n }\n return schema\n}\n\nexport function getSqlQuery(query: SqlQuery | string): SqlQuery {\n if (typeof query === \"string\") {\n return { sql: query }\n } else {\n return query\n }\n}\n\nexport function isSQL(datasource: Datasource): boolean {\n if (!datasource || !datasource.source) {\n return false\n }\n const SQL = [\n SourceName.POSTGRES,\n SourceName.SQL_SERVER,\n SourceName.MYSQL,\n SourceName.ORACLE,\n ]\n return SQL.indexOf(datasource.source) !== -1\n}\n\nexport function isIsoDateString(str: string) {\n if (!/\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}.\\d{3}Z/.test(str)) {\n return false\n }\n let d = new Date(str)\n return d.toISOString() === str\n}\n\n/**\n * This function will determine whether a column is a relationship and whether it\n * is currently valid. The reason for the validity check is that tables can be deleted\n * outside of Budibase control and if this is the case it will break Budibase relationships.\n * The tableIds is a list passed down from the main finalise tables function, which is\n * based on the tables that have just been fetched. This will only really be used on subsequent\n * fetches to the first one - if the user is periodically refreshing Budibase knowledge of tables.\n * @param column The column to check, to see if it is a valid relationship.\n * @param tableIds The IDs of the tables which currently exist.\n */\nexport function shouldCopyRelationship(\n column: { type: string; tableId?: string },\n tableIds: string[]\n) {\n return (\n column.type === FieldTypes.LINK &&\n column.tableId &&\n tableIds.includes(column.tableId)\n )\n}\n\n/**\n * Similar function to the shouldCopyRelationship function, but instead this looks for options and boolean\n * types. It is possible to switch a string -> options and a number -> boolean (and vice versus) need to make\n * sure that these get copied over when tables are fetched. Also checks whether they are still valid, if a\n * column has changed type in the external database then copying it over may not be possible.\n * @param column The column to check for options or boolean type.\n * @param fetchedColumn The fetched column to check for the type in the external database.\n */\nexport function shouldCopySpecialColumn(\n column: { type: string },\n fetchedColumn: { type: string } | undefined\n) {\n const isFormula = column.type === FieldTypes.FORMULA\n const specialTypes = [\n FieldTypes.OPTIONS,\n FieldTypes.LONGFORM,\n FieldTypes.ARRAY,\n FieldTypes.FORMULA,\n ]\n // column has been deleted, remove - formulas will never exist, always copy\n if (!isFormula && column && !fetchedColumn) {\n return false\n }\n const fetchedIsNumber =\n !fetchedColumn || fetchedColumn.type === FieldTypes.NUMBER\n return (\n specialTypes.indexOf(column.type as FieldTypes) !== -1 ||\n (fetchedIsNumber && column.type === FieldTypes.BOOLEAN)\n )\n}\n\n/**\n * Looks for columns which need to be copied over into the new table definitions, like relationships\n * and options types.\n * @param tableName The name of the table which is being checked.\n * @param table The specific table which is being checked.\n * @param entities All the tables that existed before - the old table definitions.\n * @param tableIds The IDs of the tables which exist now, to check if anything has been removed.\n */\nfunction copyExistingPropsOver(\n tableName: string,\n table: Table,\n entities: { [key: string]: any },\n tableIds: [string]\n) {\n if (entities && entities[tableName]) {\n if (entities[tableName]?.primaryDisplay) {\n table.primaryDisplay = entities[tableName].primaryDisplay\n }\n if (entities[tableName]?.created) {\n table.created = entities[tableName]?.created\n }\n const existingTableSchema = entities[tableName].schema\n for (let key in existingTableSchema) {\n if (!existingTableSchema.hasOwnProperty(key)) {\n continue\n }\n const column = existingTableSchema[key]\n if (\n shouldCopyRelationship(column, tableIds) ||\n shouldCopySpecialColumn(column, table.schema[key])\n ) {\n table.schema[key] = existingTableSchema[key]\n }\n }\n }\n return table\n}\n\n/**\n * Look through the final table definitions to see if anything needs to be\n * copied over from the old and if any errors have occurred mark them so\n * that the user can be made aware.\n * @param tables The list of tables that have been retrieved from the external database.\n * @param entities The old list of tables, if there was any to look for definitions in.\n */\nexport function finaliseExternalTables(\n tables: { [key: string]: any },\n entities: { [key: string]: any }\n) {\n const invalidColumns = Object.values(InvalidColumns)\n let finalTables: { [key: string]: any } = {}\n const errors: { [key: string]: string } = {}\n // @ts-ignore\n const tableIds: [string] = Object.values(tables).map(table => table._id)\n for (let [name, table] of Object.entries(tables)) {\n const schemaFields = Object.keys(table.schema)\n // make sure every table has a key\n if (table.primary == null || table.primary.length === 0) {\n errors[name] = BuildSchemaErrors.NO_KEY\n continue\n } else if (\n schemaFields.find(field =>\n invalidColumns.includes(field as InvalidColumns)\n )\n ) {\n errors[name] = BuildSchemaErrors.INVALID_COLUMN\n continue\n }\n // make sure all previous props have been added back\n finalTables[name] = copyExistingPropsOver(name, table, entities, tableIds)\n }\n // sort the tables by name\n finalTables = Object.entries(finalTables)\n .sort(([a], [b]) => a.localeCompare(b))\n .reduce((r, [k, v]) => ({ ...r, [k]: v }), {})\n return { tables: finalTables, errors }\n}\n", "const { v4 } = require(\"uuid\")\n\nexport default function (): string {\n return v4().replace(/-/g, \"\")\n}\n", "import newid from \"./newid\"\nimport { db as dbCore } from \"@budibase/backend-core\"\n\ntype Optional = string | null\n\nexport const AppStatus = {\n DEV: \"development\",\n ALL: \"all\",\n DEPLOYED: \"published\",\n}\n\nexport const BudibaseInternalDB = {\n _id: \"bb_internal\",\n type: dbCore.BUDIBASE_DATASOURCE_TYPE,\n name: \"Budibase DB\",\n source: \"BUDIBASE\",\n config: {},\n}\n\nexport const SEPARATOR = dbCore.SEPARATOR\nexport const StaticDatabases = dbCore.StaticDatabases\nexport const DocumentType = dbCore.DocumentType\nexport const APP_PREFIX = dbCore.APP_PREFIX\nexport const APP_DEV_PREFIX = dbCore.APP_DEV_PREFIX\nexport const isDevAppID = dbCore.isDevAppID\nexport const isProdAppID = dbCore.isProdAppID\nexport const USER_METDATA_PREFIX = `${DocumentType.ROW}${SEPARATOR}${dbCore.InternalTable.USER_METADATA}${SEPARATOR}`\nexport const LINK_USER_METADATA_PREFIX = `${DocumentType.LINK}${SEPARATOR}${dbCore.InternalTable.USER_METADATA}${SEPARATOR}`\nexport const TABLE_ROW_PREFIX = `${DocumentType.ROW}${SEPARATOR}${DocumentType.TABLE}`\nexport const AUTOMATION_LOG_PREFIX = `${DocumentType.AUTOMATION_LOG}${SEPARATOR}`\nexport const ViewName = dbCore.ViewName\nexport const InternalTables = dbCore.InternalTable\nexport const UNICODE_MAX = dbCore.UNICODE_MAX\nexport const generateAppID = dbCore.generateAppID\nexport const generateDevAppID = dbCore.getDevelopmentAppID\nexport const generateRoleID = dbCore.generateRoleID\nexport const getRoleParams = dbCore.getRoleParams\nexport const getQueryIndex = dbCore.getQueryIndex\nexport const getDocParams = dbCore.getDocParams\nexport const getRowParams = dbCore.getRowParams\nexport const generateRowID = dbCore.generateRowID\nexport const getUserMetadataParams = dbCore.getUserMetadataParams\nexport const generateUserMetadataID = dbCore.generateUserMetadataID\nexport const getGlobalIDFromUserMetadataID =\n dbCore.getGlobalIDFromUserMetadataID\n\n/**\n * Gets parameters for retrieving tables, this is a utility function for the getDocParams function.\n */\nexport function getTableParams(tableId?: Optional, otherProps = {}) {\n return getDocParams(DocumentType.TABLE, tableId, otherProps)\n}\n\n/**\n * Generates a new table ID.\n * @returns {string} The new table ID which the table doc can be stored under.\n */\nexport function generateTableID() {\n return `${DocumentType.TABLE}${SEPARATOR}${newid()}`\n}\n\n/**\n * Given a row ID this will find the table ID within it (only works for internal tables).\n * @param {string} rowId The ID of the row.\n * @returns {string} The table ID.\n */\nexport function getTableIDFromRowID(rowId: string) {\n const components = rowId\n .split(DocumentType.TABLE + SEPARATOR)[1]\n .split(SEPARATOR)\n return `${DocumentType.TABLE}${SEPARATOR}${components[0]}`\n}\n\n/**\n * Gets parameters for retrieving automations, this is a utility function for the getDocParams function.\n */\nexport function getAutomationParams(\n automationId?: Optional,\n otherProps: any = {}\n) {\n return getDocParams(DocumentType.AUTOMATION, automationId, otherProps)\n}\n\n/**\n * Generates a new automation ID.\n * @returns {string} The new automation ID which the automation doc can be stored under.\n */\nexport function generateAutomationID() {\n return `${DocumentType.AUTOMATION}${SEPARATOR}${newid()}`\n}\n\n/**\n * Generates a new link doc ID. This is currently not usable with the alldocs call,\n * instead a view is built to make walking to tree easier.\n * @param {string} tableId1 The ID of the linker table.\n * @param {string} tableId2 The ID of the linked table.\n * @param {string} rowId1 The ID of the linker row.\n * @param {string} rowId2 The ID of the linked row.\n * @param {string} fieldName1 The name of the field in the linker row.\n * @param {string} fieldName2 the name of the field in the linked row.\n * @returns {string} The new link doc ID which the automation doc can be stored under.\n */\nexport function generateLinkID(\n tableId1: string,\n tableId2: string,\n rowId1: string,\n rowId2: string,\n fieldName1: string,\n fieldName2: string\n) {\n const tables = `${SEPARATOR}${tableId1}${SEPARATOR}${tableId2}`\n const rows = `${SEPARATOR}${rowId1}${SEPARATOR}${rowId2}`\n const fields = `${SEPARATOR}${fieldName1}${SEPARATOR}${fieldName2}`\n return `${DocumentType.LINK}${tables}${rows}${fields}`\n}\n\n/**\n * Gets parameters for retrieving link docs, this is a utility function for the getDocParams function.\n */\nexport function getLinkParams(otherProps: any = {}) {\n return getDocParams(DocumentType.LINK, null, otherProps)\n}\n\n/**\n * Generates a new layout ID.\n * @returns {string} The new layout ID which the layout doc can be stored under.\n */\nexport function generateLayoutID(id?: string) {\n return `${DocumentType.LAYOUT}${SEPARATOR}${id || newid()}`\n}\n\n/**\n * Gets parameters for retrieving layout, this is a utility function for the getDocParams function.\n */\nexport function getLayoutParams(layoutId?: Optional, otherProps: any = {}) {\n return getDocParams(DocumentType.LAYOUT, layoutId, otherProps)\n}\n\n/**\n * Generates a new screen ID.\n * @returns {string} The new screen ID which the screen doc can be stored under.\n */\nexport function generateScreenID() {\n return `${DocumentType.SCREEN}${SEPARATOR}${newid()}`\n}\n\n/**\n * Gets parameters for retrieving screens, this is a utility function for the getDocParams function.\n */\nexport function getScreenParams(screenId?: Optional, otherProps: any = {}) {\n return getDocParams(DocumentType.SCREEN, screenId, otherProps)\n}\n\n/**\n * Generates a new webhook ID.\n * @returns {string} The new webhook ID which the webhook doc can be stored under.\n */\nexport function generateWebhookID() {\n return `${DocumentType.WEBHOOK}${SEPARATOR}${newid()}`\n}\n\n/**\n * Gets parameters for retrieving a webhook, this is a utility function for the getDocParams function.\n */\nexport function getWebhookParams(webhookId?: Optional, otherProps: any = {}) {\n return getDocParams(DocumentType.WEBHOOK, webhookId, otherProps)\n}\n\n/**\n * Generates a new datasource ID.\n * @returns {string} The new datasource ID which the webhook doc can be stored under.\n */\nexport function generateDatasourceID({ plus = false } = {}) {\n return `${\n plus ? DocumentType.DATASOURCE_PLUS : DocumentType.DATASOURCE\n }${SEPARATOR}${newid()}`\n}\n\n/**\n * Gets parameters for retrieving a datasource, this is a utility function for the getDocParams function.\n */\nexport function getDatasourceParams(\n datasourceId?: Optional,\n otherProps: any = {}\n) {\n return getDocParams(DocumentType.DATASOURCE, datasourceId, otherProps)\n}\n\n/**\n * Generates a new query ID.\n * @returns {string} The new query ID which the query doc can be stored under.\n */\nexport function generateQueryID(datasourceId: string) {\n return `${\n DocumentType.QUERY\n }${SEPARATOR}${datasourceId}${SEPARATOR}${newid()}`\n}\n\n/**\n * Generates a metadata ID for automations, used to track errors in recurring\n * automations etc.\n */\nexport function generateAutomationMetadataID(automationId: string) {\n return `${DocumentType.AUTOMATION_METADATA}${SEPARATOR}${automationId}`\n}\n\n/**\n * Retrieve all automation metadata in an app database.\n */\nexport function getAutomationMetadataParams(otherProps: any = {}) {\n return getDocParams(DocumentType.AUTOMATION_METADATA, null, otherProps)\n}\n\n/**\n * Gets parameters for retrieving a query, this is a utility function for the getDocParams function.\n */\nexport function getQueryParams(datasourceId?: Optional, otherProps: any = {}) {\n if (datasourceId == null) {\n return getDocParams(DocumentType.QUERY, null, otherProps)\n }\n\n return getDocParams(\n DocumentType.QUERY,\n `${datasourceId}${SEPARATOR}`,\n otherProps\n )\n}\n\n/**\n * Generates a new flag document ID.\n * @returns {string} The ID of the flag document that was generated.\n */\nexport function generateUserFlagID(userId: string) {\n return `${DocumentType.USER_FLAG}${SEPARATOR}${userId}`\n}\n\nexport function generateMetadataID(type: string, entityId: string) {\n return `${DocumentType.METADATA}${SEPARATOR}${type}${SEPARATOR}${entityId}`\n}\n\nexport function getMetadataParams(\n type: string,\n entityId?: Optional,\n otherProps: any = {}\n) {\n let docId = `${type}${SEPARATOR}`\n if (entityId != null) {\n docId += entityId\n }\n return getDocParams(DocumentType.METADATA, docId, otherProps)\n}\n\nexport function generateMemoryViewID(viewName: string) {\n return `${DocumentType.MEM_VIEW}${SEPARATOR}${viewName}`\n}\n\nexport function getMemoryViewParams(otherProps: any = {}) {\n return getDocParams(DocumentType.MEM_VIEW, null, otherProps)\n}\n\nexport function generatePluginID(name: string) {\n return `${DocumentType.PLUGIN}${SEPARATOR}${name}`\n}\n\n/**\n * This can be used with the db.allDocs to get a list of IDs\n */\nexport function getMultiIDParams(ids: string[]) {\n return {\n keys: ids,\n include_docs: true,\n }\n}\n", "import { objectStore, roles, constants } from \"@budibase/backend-core\"\nimport { FieldType as FieldTypes } from \"@budibase/types\"\nexport { FieldType as FieldTypes, RelationshipTypes } from \"@budibase/types\"\n\nexport enum FilterTypes {\n STRING = \"string\",\n FUZZY = \"fuzzy\",\n RANGE = \"range\",\n EQUAL = \"equal\",\n NOT_EQUAL = \"notEqual\",\n EMPTY = \"empty\",\n NOT_EMPTY = \"notEmpty\",\n CONTAINS = \"contains\",\n NOT_CONTAINS = \"notContains\",\n ONE_OF = \"oneOf\",\n}\n\nexport const NoEmptyFilterStrings = [\n FilterTypes.STRING,\n FilterTypes.FUZZY,\n FilterTypes.EQUAL,\n FilterTypes.NOT_EQUAL,\n FilterTypes.CONTAINS,\n FilterTypes.NOT_CONTAINS,\n]\n\nexport const CanSwitchTypes = [\n [FieldTypes.JSON, FieldTypes.ARRAY],\n [\n FieldTypes.STRING,\n FieldTypes.OPTIONS,\n FieldTypes.LONGFORM,\n FieldTypes.BARCODEQR,\n ],\n [FieldTypes.BOOLEAN, FieldTypes.NUMBER],\n]\n\nexport const SwitchableTypes = CanSwitchTypes.reduce((prev, current) =>\n prev ? prev.concat(current) : current\n)\n\nexport enum FormulaTypes {\n STATIC = \"static\",\n DYNAMIC = \"dynamic\",\n}\n\nexport enum AuthTypes {\n APP = \"app\",\n BUILDER = \"builder\",\n EXTERNAL = \"external\",\n}\n\nexport enum DataSourceOperation {\n CREATE = \"CREATE\",\n READ = \"READ\",\n UPDATE = \"UPDATE\",\n DELETE = \"DELETE\",\n BULK_CREATE = \"BULK_CREATE\",\n CREATE_TABLE = \"CREATE_TABLE\",\n UPDATE_TABLE = \"UPDATE_TABLE\",\n DELETE_TABLE = \"DELETE_TABLE\",\n}\n\nexport enum DatasourceAuthTypes {\n GOOGLE = \"google\",\n}\n\nexport enum SortDirection {\n ASCENDING = \"ASCENDING\",\n DESCENDING = \"DESCENDING\",\n}\n\nexport const USERS_TABLE_SCHEMA = {\n _id: \"ta_users\",\n type: \"table\",\n views: {},\n name: \"Users\",\n // TODO: ADMIN PANEL - when implemented this doesn't need to be carried out\n schema: {\n email: {\n type: FieldTypes.STRING,\n constraints: {\n type: FieldTypes.STRING,\n email: true,\n length: {\n maximum: \"\",\n },\n presence: true,\n },\n fieldName: \"email\",\n name: \"email\",\n },\n firstName: {\n name: \"firstName\",\n fieldName: \"firstName\",\n type: FieldTypes.STRING,\n constraints: {\n type: FieldTypes.STRING,\n presence: false,\n },\n },\n lastName: {\n name: \"lastName\",\n fieldName: \"lastName\",\n type: FieldTypes.STRING,\n constraints: {\n type: FieldTypes.STRING,\n presence: false,\n },\n },\n roleId: {\n fieldName: \"roleId\",\n name: \"roleId\",\n type: FieldTypes.OPTIONS,\n constraints: {\n type: FieldTypes.STRING,\n presence: false,\n inclusion: Object.values(roles.BUILTIN_ROLE_IDS),\n },\n },\n status: {\n fieldName: \"status\",\n name: \"status\",\n type: FieldTypes.OPTIONS,\n constraints: {\n type: FieldTypes.STRING,\n presence: false,\n inclusion: Object.values(constants.UserStatus),\n },\n },\n },\n primaryDisplay: \"email\",\n}\n\nexport enum AutoFieldSubTypes {\n CREATED_BY = \"createdBy\",\n CREATED_AT = \"createdAt\",\n UPDATED_BY = \"updatedBy\",\n UPDATED_AT = \"updatedAt\",\n AUTO_ID = \"autoID\",\n}\n\nexport enum AutoFieldDefaultNames {\n CREATED_BY = \"Created By\",\n CREATED_AT = \"Created At\",\n UPDATED_BY = \"Updated By\",\n UPDATED_AT = \"Updated At\",\n AUTO_ID = \"Auto ID\",\n}\n\nexport const OBJ_STORE_DIRECTORY = \"/prod-budi-app-assets\"\nexport enum BaseQueryVerbs {\n CREATE = \"create\",\n READ = \"read\",\n UPDATE = \"update\",\n DELETE = \"delete\",\n}\n\nexport enum MetadataTypes {\n AUTOMATION_TEST_INPUT = \"automationTestInput\",\n AUTOMATION_TEST_HISTORY = \"automationTestHistory\",\n}\n\nexport enum InvalidColumns {\n ID = \"_id\",\n REV = \"_rev\",\n TABLE_ID = \"tableId\",\n}\n\nexport enum BuildSchemaErrors {\n NO_KEY = \"no_key\",\n INVALID_COLUMN = \"invalid_column\",\n}\n\nexport enum AutomationErrors {\n INCORRECT_TYPE = \"INCORRECT_TYPE\",\n MAX_ITERATIONS = \"MAX_ITERATIONS_REACHED\",\n FAILURE_CONDITION = \"FAILURE_CONDITION_MET\",\n}\n\n// pass through the list from the auth/core lib\nexport const ObjectStoreBuckets = objectStore.ObjectStoreBuckets\nexport const MAX_AUTOMATION_RECURRING_ERRORS = 5\nexport const GOOGLE_SHEETS_PRIMARY_KEY = \"rowNumber\"\n", "import { Knex, knex } from \"knex\"\nimport {\n Operation,\n QueryJson,\n RelationshipsJson,\n SearchFilters,\n SortDirection,\n} from \"@budibase/types\"\nimport { db as dbCore } from \"@budibase/backend-core\"\nimport { QueryOptions } from \"../../definitions/datasource\"\nimport { isIsoDateString, SqlClient } from \"../utils\"\nimport SqlTableQueryBuilder from \"./sqlTable\"\nimport environment from \"../../environment\"\n\nconst envLimit = environment.SQL_MAX_ROWS\n ? parseInt(environment.SQL_MAX_ROWS)\n : null\nconst BASE_LIMIT = envLimit || 5000\n\ntype KnexQuery = Knex.QueryBuilder | Knex\n// these are invalid dates sent by the client, need to convert them to a real max date\nconst MIN_ISO_DATE = \"0000-00-00T00:00:00.000Z\"\nconst MAX_ISO_DATE = \"9999-00-00T00:00:00.000Z\"\n\nfunction likeKey(client: string, key: string): string {\n let start: string, end: string\n switch (client) {\n case SqlClient.MY_SQL:\n start = end = \"`\"\n break\n case SqlClient.ORACLE:\n case SqlClient.POSTGRES:\n start = end = '\"'\n break\n case SqlClient.MS_SQL:\n start = \"[\"\n end = \"]\"\n break\n default:\n throw \"Unknown client\"\n }\n const parts = key.split(\".\")\n key = parts.map(part => `${start}${part}${end}`).join(\".\")\n return key\n}\n\nfunction parse(input: any) {\n if (Array.isArray(input)) {\n return JSON.stringify(input)\n }\n if (input == undefined) {\n return null\n }\n if (typeof input !== \"string\") {\n return input\n }\n if (input === MAX_ISO_DATE || input === MIN_ISO_DATE) {\n return null\n }\n if (isIsoDateString(input)) {\n return new Date(input)\n }\n return input\n}\n\nfunction parseBody(body: any) {\n for (let [key, value] of Object.entries(body)) {\n body[key] = parse(value)\n }\n return body\n}\n\nfunction parseFilters(filters: SearchFilters | undefined): SearchFilters {\n if (!filters) {\n return {}\n }\n for (let [key, value] of Object.entries(filters)) {\n let parsed\n if (typeof value === \"object\") {\n parsed = parseFilters(value)\n } else {\n parsed = parse(value)\n }\n // @ts-ignore\n filters[key] = parsed\n }\n return filters\n}\n\nfunction generateSelectStatement(\n json: QueryJson,\n knex: Knex\n): (string | Knex.Raw)[] | \"*\" {\n const { resource, meta } = json\n\n if (!resource) {\n return \"*\"\n }\n\n const schema = meta?.table?.schema\n return resource.fields.map(field => {\n const fieldNames = field.split(/\\./g)\n const tableName = fieldNames[0]\n const columnName = fieldNames[1]\n if (\n columnName &&\n schema?.[columnName] &&\n knex.client.config.client === SqlClient.POSTGRES\n ) {\n const externalType = schema[columnName].externalType\n if (externalType?.includes(\"money\")) {\n return knex.raw(\n `\"${tableName}\".\"${columnName}\"::money::numeric as \"${field}\"`\n )\n }\n }\n return `${field} as ${field}`\n })\n}\n\nclass InternalBuilder {\n private readonly client: string\n\n constructor(client: string) {\n this.client = client\n }\n\n // right now we only do filters on the specific table being queried\n addFilters(\n query: KnexQuery,\n filters: SearchFilters | undefined,\n opts: { relationship?: boolean; tableName?: string }\n ): KnexQuery {\n function iterate(\n structure: { [key: string]: any },\n fn: (key: string, value: any) => void\n ) {\n for (let [key, value] of Object.entries(structure)) {\n const updatedKey = dbCore.removeKeyNumbering(key)\n const isRelationshipField = updatedKey.includes(\".\")\n if (!opts.relationship && !isRelationshipField) {\n fn(`${opts.tableName}.${updatedKey}`, value)\n }\n if (opts.relationship && isRelationshipField) {\n fn(updatedKey, value)\n }\n }\n }\n\n const like = (key: string, value: any) => {\n const fnc = allOr ? \"orWhere\" : \"where\"\n // postgres supports ilike, nothing else does\n if (this.client === SqlClient.POSTGRES) {\n query = query[fnc](key, \"ilike\", `%${value}%`)\n } else {\n const rawFnc = `${fnc}Raw`\n // @ts-ignore\n query = query[rawFnc](`LOWER(${likeKey(this.client, key)}) LIKE ?`, [\n `%${value.toLowerCase()}%`,\n ])\n }\n }\n\n const contains = (mode: object, any: boolean = false) => {\n const fnc = allOr ? \"orWhere\" : \"where\"\n const rawFnc = `${fnc}Raw`\n const not = mode === filters?.notContains ? \"NOT \" : \"\"\n function stringifyArray(value: Array<any>, quoteStyle = '\"'): string {\n for (let i in value) {\n if (typeof value[i] === \"string\") {\n value[i] = `${quoteStyle}${value[i]}${quoteStyle}`\n }\n }\n return `[${value.join(\",\")}]`\n }\n if (this.client === SqlClient.POSTGRES) {\n iterate(mode, (key: string, value: Array<any>) => {\n const wrap = any ? \"\" : \"'\"\n const containsOp = any ? \"\\\\?| array\" : \"@>\"\n const fieldNames = key.split(/\\./g)\n const tableName = fieldNames[0]\n const columnName = fieldNames[1]\n // @ts-ignore\n query = query[rawFnc](\n `${not}\"${tableName}\".\"${columnName}\"::jsonb ${containsOp} ${wrap}${stringifyArray(\n value,\n any ? \"'\" : '\"'\n )}${wrap}`\n )\n })\n } else if (this.client === SqlClient.MY_SQL) {\n const jsonFnc = any ? \"JSON_OVERLAPS\" : \"JSON_CONTAINS\"\n iterate(mode, (key: string, value: Array<any>) => {\n // @ts-ignore\n query = query[rawFnc](\n `${not}${jsonFnc}(${key}, '${stringifyArray(value)}')`\n )\n })\n } else {\n const andOr = mode === filters?.containsAny ? \" OR \" : \" AND \"\n iterate(mode, (key: string, value: Array<any>) => {\n let statement = \"\"\n for (let i in value) {\n if (typeof value[i] === \"string\") {\n value[i] = `%\"${value[i].toLowerCase()}\"%`\n } else {\n value[i] = `%${value[i]}%`\n }\n statement +=\n (statement ? andOr : \"\") +\n `LOWER(${likeKey(this.client, key)}) LIKE ?`\n }\n // @ts-ignore\n query = query[rawFnc](`${not}(${statement})`, value)\n })\n }\n }\n\n if (!filters) {\n return query\n }\n filters = parseFilters(filters)\n // if all or specified in filters, then everything is an or\n const allOr = filters.allOr\n if (filters.oneOf) {\n iterate(filters.oneOf, (key, array) => {\n const fnc = allOr ? \"orWhereIn\" : \"whereIn\"\n query = query[fnc](key, Array.isArray(array) ? array : [array])\n })\n }\n if (filters.string) {\n iterate(filters.string, (key, value) => {\n const fnc = allOr ? \"orWhere\" : \"where\"\n // postgres supports ilike, nothing else does\n if (this.client === SqlClient.POSTGRES) {\n query = query[fnc](key, \"ilike\", `${value}%`)\n } else {\n const rawFnc = `${fnc}Raw`\n // @ts-ignore\n query = query[rawFnc](`LOWER(${likeKey(this.client, key)}) LIKE ?`, [\n `${value.toLowerCase()}%`,\n ])\n }\n })\n }\n if (filters.fuzzy) {\n iterate(filters.fuzzy, like)\n }\n if (filters.range) {\n iterate(filters.range, (key, value) => {\n const isEmptyObject = (val: any) => {\n return (\n val &&\n Object.keys(val).length === 0 &&\n Object.getPrototypeOf(val) === Object.prototype\n )\n }\n if (isEmptyObject(value.low)) {\n value.low = \"\"\n }\n if (isEmptyObject(value.high)) {\n value.high = \"\"\n }\n if (value.low && value.high) {\n // Use a between operator if we have 2 valid range values\n const fnc = allOr ? \"orWhereBetween\" : \"whereBetween\"\n query = query[fnc](key, [value.low, value.high])\n } else if (value.low) {\n // Use just a single greater than operator if we only have a low\n const fnc = allOr ? \"orWhere\" : \"where\"\n query = query[fnc](key, \">\", value.low)\n } else if (value.high) {\n // Use just a single less than operator if we only have a high\n const fnc = allOr ? \"orWhere\" : \"where\"\n query = query[fnc](key, \"<\", value.high)\n }\n })\n }\n if (filters.equal) {\n iterate(filters.equal, (key, value) => {\n const fnc = allOr ? \"orWhere\" : \"where\"\n query = query[fnc]({ [key]: value })\n })\n }\n if (filters.notEqual) {\n iterate(filters.notEqual, (key, value) => {\n const fnc = allOr ? \"orWhereNot\" : \"whereNot\"\n query = query[fnc]({ [key]: value })\n })\n }\n if (filters.empty) {\n iterate(filters.empty, key => {\n const fnc = allOr ? \"orWhereNull\" : \"whereNull\"\n query = query[fnc](key)\n })\n }\n if (filters.notEmpty) {\n iterate(filters.notEmpty, key => {\n const fnc = allOr ? \"orWhereNotNull\" : \"whereNotNull\"\n query = query[fnc](key)\n })\n }\n if (filters.contains) {\n contains(filters.contains)\n }\n if (filters.notContains) {\n contains(filters.notContains)\n }\n if (filters.containsAny) {\n contains(filters.containsAny, true)\n }\n return query\n }\n\n addSorting(query: KnexQuery, json: QueryJson): KnexQuery {\n let { sort, paginate } = json\n const table = json.meta?.table\n if (sort) {\n for (let [key, value] of Object.entries(sort)) {\n const direction =\n value.direction === SortDirection.ASCENDING ? \"asc\" : \"desc\"\n query = query.orderBy(`${table?.name}.${key}`, direction)\n }\n } else if (this.client === SqlClient.MS_SQL && paginate?.limit) {\n // @ts-ignore\n query = query.orderBy(`${table?.name}.${table?.primary[0]}`)\n }\n return query\n }\n\n addRelationships(\n query: KnexQuery,\n fromTable: string,\n relationships: RelationshipsJson[] | undefined,\n schema: string | undefined\n ): KnexQuery {\n if (!relationships) {\n return query\n }\n const tableSets: Record<string, [any]> = {}\n // aggregate into table sets (all the same to tables)\n for (let relationship of relationships) {\n const keyObj: { toTable: string; throughTable: string | undefined } = {\n toTable: relationship.tableName,\n throughTable: undefined,\n }\n if (relationship.through) {\n keyObj.throughTable = relationship.through\n }\n const key = JSON.stringify(keyObj)\n if (tableSets[key]) {\n tableSets[key].push(relationship)\n } else {\n tableSets[key] = [relationship]\n }\n }\n for (let [key, relationships] of Object.entries(tableSets)) {\n const { toTable, throughTable } = JSON.parse(key)\n const toTableWithSchema = schema ? `${schema}.${toTable}` : toTable\n const throughTableWithSchema = schema\n ? `${schema}.${throughTable}`\n : throughTable\n if (!throughTable) {\n // @ts-ignore\n query = query.leftJoin(toTableWithSchema, function () {\n for (let relationship of relationships) {\n const from = relationship.from,\n to = relationship.to\n // @ts-ignore\n this.orOn(`${fromTable}.${from}`, \"=\", `${toTable}.${to}`)\n }\n })\n } else {\n query = query\n // @ts-ignore\n .leftJoin(throughTableWithSchema, function () {\n for (let relationship of relationships) {\n const fromPrimary = relationship.fromPrimary\n const from = relationship.from\n // @ts-ignore\n this.orOn(\n `${fromTable}.${fromPrimary}`,\n \"=\",\n `${throughTable}.${from}`\n )\n }\n })\n .leftJoin(toTableWithSchema, function () {\n for (let relationship of relationships) {\n const toPrimary = relationship.toPrimary\n const to = relationship.to\n // @ts-ignore\n this.orOn(`${toTable}.${toPrimary}`, `${throughTable}.${to}`)\n }\n })\n }\n }\n return query.limit(BASE_LIMIT)\n }\n\n create(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {\n const { endpoint, body } = json\n let query: KnexQuery = knex(endpoint.entityId)\n if (endpoint.schema) {\n query = query.withSchema(endpoint.schema)\n }\n const parsedBody = parseBody(body)\n // make sure no null values in body for creation\n for (let [key, value] of Object.entries(parsedBody)) {\n if (value == null) {\n delete parsedBody[key]\n }\n }\n\n // mysql can't use returning\n if (opts.disableReturning) {\n return query.insert(parsedBody)\n } else {\n return query.insert(parsedBody).returning(\"*\")\n }\n }\n\n bulkCreate(knex: Knex, json: QueryJson): KnexQuery {\n const { endpoint, body } = json\n let query: KnexQuery = knex(endpoint.entityId)\n if (endpoint.schema) {\n query = query.withSchema(endpoint.schema)\n }\n if (!Array.isArray(body)) {\n return query\n }\n const parsedBody = body.map(row => parseBody(row))\n return query.insert(parsedBody)\n }\n\n read(knex: Knex, json: QueryJson, limit: number): KnexQuery {\n let { endpoint, resource, filters, paginate, relationships } = json\n const tableName = endpoint.entityId\n // select all if not specified\n if (!resource) {\n resource = { fields: [] }\n }\n let selectStatement: string | (string | Knex.Raw)[] = \"*\"\n // handle select\n if (resource.fields && resource.fields.length > 0) {\n // select the resources as the format \"table.columnName\" - this is what is provided\n // by the resource builder further up\n selectStatement = generateSelectStatement(json, knex)\n }\n let foundLimit = limit || BASE_LIMIT\n // handle pagination\n let foundOffset: number | null = null\n if (paginate && paginate.page && paginate.limit) {\n // @ts-ignore\n const page = paginate.page <= 1 ? 0 : paginate.page - 1\n const offset = page * paginate.limit\n foundLimit = paginate.limit\n foundOffset = offset\n } else if (paginate && paginate.limit) {\n foundLimit = paginate.limit\n }\n // start building the query\n let query: KnexQuery = knex(tableName).limit(foundLimit)\n if (endpoint.schema) {\n query = query.withSchema(endpoint.schema)\n }\n if (foundOffset) {\n query = query.offset(foundOffset)\n }\n query = this.addFilters(query, filters, { tableName })\n // add sorting to pre-query\n query = this.addSorting(query, json)\n // @ts-ignore\n let preQuery: KnexQuery = knex({\n // @ts-ignore\n [tableName]: query,\n }).select(selectStatement)\n // have to add after as well (this breaks MS-SQL)\n if (this.client !== SqlClient.MS_SQL) {\n preQuery = this.addSorting(preQuery, json)\n }\n // handle joins\n query = this.addRelationships(\n preQuery,\n tableName,\n relationships,\n endpoint.schema\n )\n return this.addFilters(query, filters, { relationship: true })\n }\n\n update(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {\n const { endpoint, body, filters } = json\n let query: KnexQuery = knex(endpoint.entityId)\n if (endpoint.schema) {\n query = query.withSchema(endpoint.schema)\n }\n const parsedBody = parseBody(body)\n query = this.addFilters(query, filters, { tableName: endpoint.entityId })\n // mysql can't use returning\n if (opts.disableReturning) {\n return query.update(parsedBody)\n } else {\n return query.update(parsedBody).returning(\"*\")\n }\n }\n\n delete(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {\n const { endpoint, filters } = json\n let query: KnexQuery = knex(endpoint.entityId)\n if (endpoint.schema) {\n query = query.withSchema(endpoint.schema)\n }\n query = this.addFilters(query, filters, { tableName: endpoint.entityId })\n // mysql can't use returning\n if (opts.disableReturning) {\n return query.delete()\n } else {\n return query.delete().returning(generateSelectStatement(json, knex))\n }\n }\n}\n\nclass SqlQueryBuilder extends SqlTableQueryBuilder {\n private readonly limit: number\n // pass through client to get flavour of SQL\n constructor(client: string, limit: number = BASE_LIMIT) {\n super(client)\n this.limit = limit\n }\n\n /**\n * @param json The JSON query DSL which is to be converted to SQL.\n * @param opts extra options which are to be passed into the query builder, e.g. disableReturning\n * which for the sake of mySQL stops adding the returning statement to inserts, updates and deletes.\n * @return {{ sql: string, bindings: object }} the query ready to be passed to the driver.\n */\n _query(json: QueryJson, opts: QueryOptions = {}) {\n const sqlClient = this.getSqlClient()\n const client = knex({ client: sqlClient })\n let query\n const builder = new InternalBuilder(sqlClient)\n switch (this._operation(json)) {\n case Operation.CREATE:\n query = builder.create(client, json, opts)\n break\n case Operation.READ:\n query = builder.read(client, json, this.limit)\n break\n case Operation.UPDATE:\n query = builder.update(client, json, opts)\n break\n case Operation.DELETE:\n query = builder.delete(client, json, opts)\n break\n case Operation.BULK_CREATE:\n query = builder.bulkCreate(client, json)\n break\n case Operation.CREATE_TABLE:\n case Operation.UPDATE_TABLE:\n case Operation.DELETE_TABLE:\n return this._tableQuery(json)\n default:\n throw `Operation type is not supported by SQL query builder`\n }\n\n // @ts-ignore\n return query.toSQL().toNative()\n }\n\n async getReturningRow(queryFn: Function, json: QueryJson) {\n if (!json.extra || !json.extra.idFilter) {\n return {}\n }\n const input = this._query({\n endpoint: {\n ...json.endpoint,\n operation: Operation.READ,\n },\n resource: {\n fields: [],\n },\n filters: json.extra.idFilter,\n paginate: {\n limit: 1,\n },\n meta: json.meta,\n })\n return queryFn(input, Operation.READ)\n }\n\n // when creating if an ID has been inserted need to make sure\n // the id filter is enriched with it before trying to retrieve the row\n checkLookupKeys(id: any, json: QueryJson) {\n if (!id || !json.meta?.table || !json.meta.table.primary) {\n return json\n }\n const primaryKey = json.meta.table.primary?.[0]\n json.extra = {\n idFilter: {\n equal: {\n [primaryKey]: id,\n },\n },\n }\n return json\n }\n\n // this function recreates the returning functionality of postgres\n async queryWithReturning(\n json: QueryJson,\n queryFn: Function,\n processFn: Function = (result: any) => result\n ) {\n const sqlClient = this.getSqlClient()\n const operation = this._operation(json)\n const input = this._query(json, { disableReturning: true })\n if (Array.isArray(input)) {\n const responses = []\n for (let query of input) {\n responses.push(await queryFn(query, operation))\n }\n return responses\n }\n let row\n // need to manage returning, a feature mySQL can't do\n if (operation === Operation.DELETE) {\n row = processFn(await this.getReturningRow(queryFn, json))\n }\n const response = await queryFn(input, operation)\n const results = processFn(response)\n // same as delete, manage returning\n if (operation === Operation.CREATE || operation === Operation.UPDATE) {\n let id\n if (sqlClient === SqlClient.MS_SQL) {\n id = results?.[0].id\n } else if (sqlClient === SqlClient.MY_SQL) {\n id = results?.insertId\n }\n row = processFn(\n await this.getReturningRow(queryFn, this.checkLookupKeys(id, json))\n )\n }\n if (operation !== Operation.READ) {\n return row\n }\n return results.length ? results : [{ [operation.toLowerCase()]: true }]\n }\n}\n\nexport default SqlQueryBuilder\n", "import { Knex, knex } from \"knex\"\nimport { Operation, QueryJson, RenameColumn, Table } from \"@budibase/types\"\nimport { breakExternalTableId } from \"../utils\"\nimport SchemaBuilder = Knex.SchemaBuilder\nimport CreateTableBuilder = Knex.CreateTableBuilder\nimport { FieldTypes, RelationshipTypes } from \"../../constants\"\n\nfunction generateSchema(\n schema: CreateTableBuilder,\n table: Table,\n tables: Record<string, Table>,\n oldTable: null | Table = null,\n renamed?: RenameColumn\n) {\n let primaryKey = table && table.primary ? table.primary[0] : null\n const columns = Object.values(table.schema)\n // all columns in a junction table will be meta\n let metaCols = columns.filter(col => col.meta)\n let isJunction = metaCols.length === columns.length\n // can't change primary once its set for now\n if (primaryKey && !oldTable && !isJunction) {\n schema.increments(primaryKey).primary()\n } else if (!oldTable && isJunction) {\n schema.primary(metaCols.map(col => col.name))\n }\n\n // check if any columns need added\n const foreignKeys = Object.values(table.schema).map(col => col.foreignKey)\n for (let [key, column] of Object.entries(table.schema)) {\n // skip things that are already correct\n const oldColumn = oldTable ? oldTable.schema[key] : null\n if (\n (oldColumn && oldColumn.type) ||\n (primaryKey === key && !isJunction) ||\n renamed?.updated === key\n ) {\n continue\n }\n switch (column.type) {\n case FieldTypes.STRING:\n case FieldTypes.OPTIONS:\n case FieldTypes.LONGFORM:\n case FieldTypes.BARCODEQR:\n schema.text(key)\n break\n case FieldTypes.NUMBER:\n // if meta is specified then this is a junction table entry\n if (column.meta && column.meta.toKey && column.meta.toTable) {\n const { toKey, toTable } = column.meta\n schema.integer(key).unsigned()\n schema.foreign(key).references(`${toTable}.${toKey}`)\n } else if (foreignKeys.indexOf(key) === -1) {\n schema.float(key)\n }\n break\n case FieldTypes.BOOLEAN:\n schema.boolean(key)\n break\n case FieldTypes.DATETIME:\n schema.datetime(key, {\n useTz: !column.ignoreTimezones,\n })\n break\n case FieldTypes.ARRAY:\n schema.json(key)\n break\n case FieldTypes.LINK:\n // this side of the relationship doesn't need any SQL work\n if (\n column.relationshipType !== RelationshipTypes.MANY_TO_ONE &&\n column.relationshipType !== RelationshipTypes.MANY_TO_MANY\n ) {\n if (!column.foreignKey || !column.tableId) {\n throw \"Invalid relationship schema\"\n }\n const { tableName } = breakExternalTableId(column.tableId)\n // @ts-ignore\n const relatedTable = tables[tableName]\n if (!relatedTable) {\n throw \"Referenced table doesn't exist\"\n }\n const relatedPrimary = relatedTable.primary[0]\n const externalType = relatedTable.schema[relatedPrimary].externalType\n if (externalType) {\n schema.specificType(column.foreignKey, externalType)\n } else {\n schema.integer(column.foreignKey).unsigned()\n }\n\n schema\n .foreign(column.foreignKey)\n .references(`${tableName}.${relatedPrimary}`)\n }\n break\n }\n }\n\n if (renamed) {\n schema.renameColumn(renamed.old, renamed.updated)\n }\n\n // need to check if any columns have been deleted\n if (oldTable) {\n const deletedColumns = Object.entries(oldTable.schema)\n .filter(\n ([key, schema]) =>\n schema.type !== FieldTypes.LINK &&\n schema.type !== FieldTypes.FORMULA &&\n table.schema[key] == null\n )\n .map(([key]) => key)\n deletedColumns.forEach(key => {\n if (renamed?.old === key) {\n return\n }\n if (oldTable.constrained && oldTable.constrained.indexOf(key) !== -1) {\n schema.dropForeign(key)\n }\n schema.dropColumn(key)\n })\n }\n\n return schema\n}\n\nfunction buildCreateTable(\n knex: SchemaBuilder,\n table: Table,\n tables: Record<string, Table>\n): SchemaBuilder {\n return knex.createTable(table.name, schema => {\n generateSchema(schema, table, tables)\n })\n}\n\nfunction buildUpdateTable(\n knex: SchemaBuilder,\n table: Table,\n tables: Record<string, Table>,\n oldTable: Table,\n renamed: RenameColumn\n): SchemaBuilder {\n return knex.alterTable(table.name, schema => {\n generateSchema(schema, table, tables, oldTable, renamed)\n })\n}\n\nfunction buildDeleteTable(knex: SchemaBuilder, table: Table): SchemaBuilder {\n return knex.dropTable(table.name)\n}\n\nclass SqlTableQueryBuilder {\n private readonly sqlClient: string\n\n // pass through client to get flavour of SQL\n constructor(client: string) {\n this.sqlClient = client\n }\n\n getSqlClient(): string {\n return this.sqlClient\n }\n\n /**\n * @param json the input JSON structure from which an SQL query will be built.\n * @return {string} the operation that was found in the JSON.\n */\n _operation(json: QueryJson): Operation {\n return json.endpoint.operation\n }\n\n _tableQuery(json: QueryJson): any {\n let client = knex({ client: this.sqlClient }).schema\n if (json?.endpoint?.schema) {\n client = client.withSchema(json.endpoint.schema)\n }\n\n let query\n if (!json.table || !json.meta || !json.meta.tables) {\n throw \"Cannot execute without table being specified\"\n }\n switch (this._operation(json)) {\n case Operation.CREATE_TABLE:\n query = buildCreateTable(client, json.table, json.meta.tables)\n break\n case Operation.UPDATE_TABLE:\n if (!json.meta || !json.meta.table) {\n throw \"Must specify old table for update\"\n }\n query = buildUpdateTable(\n client,\n json.table,\n json.meta.tables,\n json.meta.table,\n json.meta.renamed!\n )\n break\n case Operation.DELETE_TABLE:\n query = buildDeleteTable(client, json.table)\n break\n default:\n throw \"Table operation is of unknown type\"\n }\n return query.toSQL()\n }\n}\n\nexport default SqlTableQueryBuilder\n", "import env from \"../environment\"\nimport { context } from \"@budibase/backend-core\"\nimport { generateMetadataID } from \"../db/utils\"\nimport { Document } from \"@budibase/types\"\nimport stream from \"stream\"\nconst Readable = stream.Readable\n\nexport function wait(ms: number) {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n\nexport const isDev = env.isDev\n\nexport const NUMBER_REGEX = /^[+-]?([0-9]*[.])?[0-9]+$/g\n\nexport function removeFromArray(array: any[], element: any) {\n const index = array.indexOf(element)\n if (index !== -1) {\n array.splice(index, 1)\n }\n return array\n}\n\n/**\n * Makes sure that a URL has the correct number of slashes, while maintaining the\n * http(s):// double slashes.\n * @param {string} url The URL to test and remove any extra double slashes.\n * @return {string} The updated url.\n */\nexport function checkSlashesInUrl(url: string) {\n return url.replace(/(https?:\\/\\/)|(\\/)+/g, \"$1$2\")\n}\n\nexport async function updateEntityMetadata(\n type: string,\n entityId: string,\n updateFn: any\n) {\n const db = context.getAppDB()\n const id = generateMetadataID(type, entityId)\n // read it to see if it exists, we'll overwrite it no matter what\n let rev, metadata: Document\n try {\n const oldMetadata = await db.get(id)\n rev = oldMetadata._rev\n metadata = updateFn(oldMetadata)\n } catch (err) {\n rev = null\n metadata = updateFn({})\n }\n metadata._id = id\n if (rev) {\n metadata._rev = rev\n }\n const response = await db.put(metadata)\n return {\n ...metadata,\n _id: id,\n _rev: response.rev,\n }\n}\n\nexport async function saveEntityMetadata(\n type: string,\n entityId: string,\n metadata: Document\n) {\n return updateEntityMetadata(type, entityId, () => {\n return metadata\n })\n}\n\nexport async function deleteEntityMetadata(type: string, entityId: string) {\n const db = context.getAppDB()\n const id = generateMetadataID(type, entityId)\n let rev\n try {\n const metadata = await db.get(id)\n if (metadata) {\n rev = metadata._rev\n }\n } catch (err) {\n // don't need to error if it doesn't exist\n }\n if (id && rev) {\n await db.remove(id, rev)\n }\n}\n\nexport function escapeDangerousCharacters(string: string) {\n return string\n .replace(/[\\\\]/g, \"\\\\\\\\\")\n .replace(/[\\b]/g, \"\\\\b\")\n .replace(/[\\f]/g, \"\\\\f\")\n .replace(/[\\n]/g, \"\\\\n\")\n .replace(/[\\r]/g, \"\\\\r\")\n .replace(/[\\t]/g, \"\\\\t\")\n}\n\nexport function stringToReadStream(string: string) {\n return new Readable({\n read() {\n this.push(string)\n this.push(null)\n },\n })\n}\n\nexport function formatBytes(bytes: string) {\n const units = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\n const byteIncrements = 1024\n let unit = 0\n let size = parseInt(bytes, 10) || 0\n while (size >= byteIncrements && ++unit) {\n size /= byteIncrements\n }\n return `${size.toFixed(size < 10 && unit > 0 ? 1 : 0)}${units[unit]}`\n}\n\nexport function convertBookmark(bookmark: string) {\n const IS_NUMBER = /^\\d+\\.?\\d*$/\n if (typeof bookmark === \"string\" && bookmark.match(IS_NUMBER)) {\n return parseFloat(bookmark)\n }\n return bookmark\n}\n\nexport function isQsTrue(param: string) {\n if (typeof param === \"string\") {\n return param.toLowerCase() === \"true\"\n } else {\n return param === true\n }\n}\n", "import {\n Integration,\n DatasourceFieldType,\n QueryType,\n IntegrationBase,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\n\nimport AWS from \"aws-sdk\"\nimport { AWS_REGION } from \"../db/dynamoClient\"\nimport { DocumentClient } from \"aws-sdk/clients/dynamodb\"\n\ninterface DynamoDBConfig {\n region: string\n accessKeyId: string\n secretAccessKey: string\n endpoint?: string\n currentClockSkew?: boolean\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://github.com/dabit3/dynamodb-documentclient-cheat-sheet\",\n description:\n \"Amazon DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale.\",\n friendlyName: \"DynamoDB\",\n type: \"Non-relational\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n region: {\n type: DatasourceFieldType.STRING,\n required: true,\n default: \"us-east-1\",\n },\n accessKeyId: {\n type: DatasourceFieldType.PASSWORD,\n required: true,\n },\n secretAccessKey: {\n type: DatasourceFieldType.PASSWORD,\n required: true,\n },\n endpoint: {\n type: DatasourceFieldType.STRING,\n required: false,\n default: \"https://dynamodb.us-east-1.amazonaws.com\",\n },\n },\n query: {\n create: {\n type: QueryType.FIELDS,\n customisable: true,\n fields: {\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n read: {\n type: QueryType.FIELDS,\n customisable: true,\n readable: true,\n fields: {\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n index: {\n type: DatasourceFieldType.STRING,\n },\n },\n },\n scan: {\n type: QueryType.FIELDS,\n customisable: true,\n readable: true,\n fields: {\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n index: {\n type: DatasourceFieldType.STRING,\n },\n },\n },\n describe: {\n type: QueryType.FIELDS,\n customisable: true,\n readable: true,\n fields: {\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n get: {\n type: QueryType.FIELDS,\n customisable: true,\n readable: true,\n fields: {\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n update: {\n type: QueryType.FIELDS,\n customisable: true,\n fields: {\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n delete: {\n type: QueryType.FIELDS,\n customisable: true,\n fields: {\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n },\n}\n\nclass DynamoDBIntegration implements IntegrationBase {\n private config: DynamoDBConfig\n private client\n\n constructor(config: DynamoDBConfig) {\n this.config = config\n\n // User is using a local dynamoDB endpoint, don't auth with remote\n if (this.config?.endpoint?.includes(\"localhost\")) {\n // @ts-ignore\n this.config = {}\n }\n\n this.config = {\n ...this.config,\n currentClockSkew: true,\n region: config.region || AWS_REGION,\n endpoint: config.endpoint || undefined,\n }\n this.client = new AWS.DynamoDB.DocumentClient(this.config)\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n try {\n const scanRes = await new AWS.DynamoDB(this.config).listTables().promise()\n response.connected = !!scanRes.$response\n } catch (e: any) {\n response.error = e.message as string\n }\n return response\n }\n\n async create(query: {\n table: string\n json: Omit<DocumentClient.PutItemInput, \"TableName\">\n }) {\n const params = {\n TableName: query.table,\n ...query.json,\n }\n return this.client.put(params).promise()\n }\n\n async read(query: { table: string; json: object; index: null | string }) {\n const params = {\n TableName: query.table,\n IndexName: query.index ? query.index : undefined,\n ...query.json,\n }\n const response = await this.client.query(params).promise()\n if (response.Items) {\n return response.Items\n }\n return response\n }\n\n async scan(query: { table: string; json: object; index: null | string }) {\n const params = {\n TableName: query.table,\n IndexName: query.index ? query.index : undefined,\n ...query.json,\n }\n const response = await this.client.scan(params).promise()\n if (response.Items) {\n return response.Items\n }\n return response\n }\n\n async describe(query: { table: string }): Promise<any> {\n const params = {\n TableName: query.table,\n }\n return new AWS.DynamoDB(this.config).describeTable(params).promise()\n }\n\n async get(query: {\n table: string\n json: Omit<DocumentClient.GetItemInput, \"TableName\">\n }) {\n const params = {\n TableName: query.table,\n ...query.json,\n }\n return this.client.get(params).promise()\n }\n\n async update(query: {\n table: string\n json: Omit<DocumentClient.UpdateItemInput, \"TableName\">\n }) {\n const params = {\n TableName: query.table,\n ...query.json,\n }\n return this.client.update(params).promise()\n }\n\n async delete(query: {\n table: string\n json: Omit<DocumentClient.DeleteItemInput, \"TableName\">\n }) {\n const params = {\n TableName: query.table,\n ...query.json,\n }\n return this.client.delete(params).promise()\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: DynamoDBIntegration,\n}\n", "import { merge } from \"lodash\"\nimport env from \"../environment\"\n\nexport const AWS_REGION = env.AWS_REGION ? env.AWS_REGION : \"eu-west-1\"\n\nconst TableInfo = {\n API_KEYS: {\n name: \"beta-api-key-table\",\n primary: \"pk\",\n },\n USERS: {\n name: \"prod-budi-table\",\n primary: \"pk\",\n sort: \"sk\",\n },\n}\n\nlet docClient: any = null\n\ntype GetOpts = {\n primary: string\n sort?: string\n otherProps?: any\n}\n\ntype UpdateOpts = {\n primary: string\n sort?: string\n expression?: string\n condition?: string\n names?: string[]\n values?: any[]\n exists?: boolean\n otherProps?: any\n}\n\ntype PutOpts = {\n item: any\n otherProps?: any\n}\n\nclass Table {\n _name: string\n _primary: string\n _sort?: string\n\n constructor(tableInfo: { name: string; primary: string; sort?: string }) {\n if (!tableInfo.name || !tableInfo.primary) {\n throw \"Table info must specify a name and a primary key\"\n }\n this._name = tableInfo.name\n this._primary = tableInfo.primary\n this._sort = tableInfo.sort\n }\n\n async get({ primary, sort, otherProps }: GetOpts) {\n let params = {\n TableName: this._name,\n Key: {\n [this._primary]: primary,\n },\n }\n if (this._sort && sort) {\n params.Key[this._sort] = sort\n }\n if (otherProps) {\n params = merge(params, otherProps)\n }\n let response = await docClient.get(params).promise()\n return response.Item\n }\n\n async update({\n primary,\n sort,\n expression,\n condition,\n names,\n values,\n exists,\n otherProps,\n }: UpdateOpts) {\n let params: any = {\n TableName: this._name,\n Key: {\n [this._primary]: primary,\n },\n ExpressionAttributeNames: names,\n ExpressionAttributeValues: values,\n UpdateExpression: expression,\n }\n if (condition) {\n params.ConditionExpression = condition\n }\n if (this._sort && sort) {\n params.Key[this._sort] = sort\n }\n if (exists) {\n params.ExpressionAttributeNames[\"#PRIMARY\"] = this._primary\n if (params.ConditionExpression) {\n params.ConditionExpression += \" AND \"\n }\n params.ConditionExpression += \"attribute_exists(#PRIMARY)\"\n }\n if (otherProps) {\n params = merge(params, otherProps)\n }\n return docClient.update(params).promise()\n }\n\n async put({ item, otherProps }: PutOpts) {\n if (\n item[this._primary] == null ||\n (this._sort && item[this._sort] == null)\n ) {\n throw \"Cannot put item without primary and sort key (if required)\"\n }\n let params = {\n TableName: this._name,\n Item: item,\n }\n if (otherProps) {\n params = merge(params, otherProps)\n }\n return docClient.put(params).promise()\n }\n}\n\nexport function init(endpoint: string) {\n let AWS = require(\"aws-sdk\")\n let docClientParams: any = {\n correctClockSkew: true,\n region: AWS_REGION,\n }\n if (endpoint) {\n docClientParams.endpoint = endpoint\n } else if (env.DYNAMO_ENDPOINT) {\n docClientParams.endpoint = env.DYNAMO_ENDPOINT\n }\n docClient = new AWS.DynamoDB.DocumentClient(docClientParams)\n}\n\nif (!env.isProd() && !env.isJest()) {\n env._set(\"AWS_ACCESS_KEY_ID\", \"KEY_ID\")\n env._set(\"AWS_SECRET_ACCESS_KEY\", \"SECRET_KEY\")\n init(\"http://localhost:8333\")\n}\n", "import {\n Integration,\n DatasourceFieldType,\n QueryType,\n IntegrationBase,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\nimport {\n MongoClient,\n ObjectId,\n Filter,\n UpdateFilter,\n FindOneAndUpdateOptions,\n UpdateOptions,\n OperationOptions,\n MongoClientOptions,\n} from \"mongodb\"\nimport environment from \"../environment\"\n\ninterface MongoDBConfig {\n connectionString: string\n db: string\n tlsCertificateFile: string\n tlsCertificateKeyFile: string\n tlsCAFile: string\n}\n\ninterface MongoDBQuery {\n json: object | string\n extra: {\n [key: string]: string\n }\n}\n\nconst getSchema = () => {\n let schema = {\n docs: \"https://github.com/mongodb/node-mongodb-native\",\n friendlyName: \"MongoDB\",\n type: \"Non-relational\",\n description:\n \"MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era.\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n connectionString: {\n type: DatasourceFieldType.STRING,\n required: true,\n default: \"mongodb://localhost:27017\",\n display: \"Connection string\",\n },\n db: {\n type: DatasourceFieldType.STRING,\n required: true,\n display: \"DB\",\n },\n },\n query: {\n create: {\n type: QueryType.JSON,\n },\n read: {\n type: QueryType.JSON,\n },\n update: {\n type: QueryType.JSON,\n },\n delete: {\n type: QueryType.JSON,\n },\n aggregate: {\n type: QueryType.JSON,\n readable: true,\n steps: [\n {\n key: \"$addFields\",\n template: \"{\\n\\t\\n}\",\n },\n {\n key: \"$bucket\",\n template: `{\n \"groupBy\": \"\",\n \"boundaries\": [],\n \"default\": \"\",\n \"output\": {}\n }`,\n },\n {\n key: \"$bucketAuto\",\n template: `{\n \"groupBy\": \"\",\n \"buckets\": 1,\n \"output\": {},\n \"granularity\": \"R5\"\n }`,\n },\n {\n key: \"$changeStream\",\n template: `{\n \"allChangesForCluster\": true,\n \"fullDocument\": \"\",\n \"fullDocumentBeforeChange\": \"\",\n \"resumeAfter\": 1,\n \"showExpandedEvents\": true,\n \"startAfter\": {},\n \"startAtOperationTime\": \"\"\n }`,\n },\n {\n key: \"$collStats\",\n template: `{\n \"latencyStats\": { \"histograms\": true } },\n \"storageStats\": { \"scale\": 1 } },\n \"count\": {},\n \"queryExecStats\": {}\n }`,\n },\n {\n key: \"$count\",\n template: ``,\n },\n {\n key: \"$densify\",\n template: `{\n \"field\": \"\",\n \"partitionByFields\": [],\n \"range\": {\n \"step\": 1,\n \"unit\": 1,\n \"bounds\": \"full\"\n }\n }`,\n },\n {\n key: \"$documents\",\n template: `[]`,\n },\n {\n key: \"$facet\",\n template: `{\\n\\t\\n}`,\n },\n {\n key: \"$fill\",\n template: `{\n \"partitionBy\": \"\",\n \"partitionByFields\": [],\n \"sortBy\": {},\n \"output\": {}\n }`,\n },\n {\n key: \"$geoNear\",\n template: `{\n \"near\": { \n \"type\": \"Point\", \n \"coordinates\": [ \n -73.98142, 40.71782\n ] \n },\n \"key\": \"location\",\n \"distanceField\": \"dist.calculated\",\n \"query\": { \"category\": \"Parks\" }\n }`,\n },\n {\n key: \"$graphLookup\",\n template: `{\n \"from\": \"\",\n \"startWith\": \"\",\n \"connectFromField\": \"\",\n \"connectToField\": \"\",\n \"as\": \"\",\n \"maxDepth\": 1,\n \"depthField\": \"\",\n \"restrictSearchWithMatch\": {}\n }`,\n },\n {\n key: \"$group\",\n template: `{\n \"_id\": \"\"\n }`,\n },\n {\n key: \"$indexStats\",\n template: \"{\\n\\t\\n}\",\n },\n {\n key: \"$limit\",\n template: `1`,\n },\n {\n key: \"$listLocalSessions\",\n template: `{\\n\\t\\n}`,\n },\n {\n key: \"$listSessions\",\n template: `{\\n\\t\\n}`,\n },\n {\n key: \"$lookup\",\n template: `{\n \"from\": \"\",\n \"localField\": \"\",\n \"foreignField\": \"\",\n \"as\": \"\"\n }`,\n },\n {\n key: \"$match\",\n template: \"{\\n\\t\\n}\",\n },\n {\n key: \"$merge\",\n template: `{\n \"into\": {},\n \"on\": \"_id\",\n \"whenMatched\": \"replace\",\n \"whenNotMatched\": \"insert\"\n }`,\n },\n {\n key: \"$out\",\n template: `{\n \"db\": \"\",\n \"coll\": \"\"\n }`,\n },\n {\n key: \"$planCacheStats\",\n template: \"{\\n\\t\\n}\",\n },\n {\n key: \"$project\",\n template: \"{\\n\\t\\n}\",\n },\n {\n key: \"$redact\",\n template: \"\",\n },\n {\n key: \"$replaceRoot\",\n template: `{ \"newRoot\": \"\" }`,\n },\n {\n key: \"$replaceWith\",\n template: ``,\n },\n {\n key: \"$sample\",\n template: `{ \"size\": 3 }`,\n },\n {\n key: \"$set\",\n template: \"{\\n\\t\\n}\",\n },\n {\n key: \"$setWindowFields\",\n template: `{\n \"partitionBy\": \"\",\n \"sortBy\": {},\n \"output\": {}\n }`,\n },\n {\n key: \"$skip\",\n template: `1`,\n },\n {\n key: \"$sort\",\n template: \"{\\n\\t\\n}\",\n },\n {\n key: \"$sortByCount\",\n template: \"\",\n },\n {\n key: \"$unionWith\",\n template: `{\n \"coll\": \"\",\n \"pipeline\": []\n }`,\n },\n {\n key: \"$unset\",\n template: \"\",\n },\n {\n key: \"$unwind\",\n template: `{\n \"path\": \"\",\n \"includeArrayIndex\": \"\",\n \"preserveNullAndEmptyArrays\": true\n }`,\n },\n ],\n },\n },\n extra: {\n collection: {\n displayName: \"Collection\",\n type: DatasourceFieldType.STRING,\n required: true,\n },\n actionType: {\n displayName: \"Query Type\",\n type: DatasourceFieldType.LIST,\n required: true,\n data: {\n read: [\"find\", \"findOne\", \"findOneAndUpdate\", \"count\", \"distinct\"],\n create: [\"insertOne\", \"insertMany\"],\n update: [\"updateOne\", \"updateMany\"],\n delete: [\"deleteOne\", \"deleteMany\"],\n aggregate: [\"json\", \"pipeline\"],\n },\n },\n },\n }\n if (environment.SELF_HOSTED) {\n schema.datasource = {\n ...schema.datasource,\n //@ts-ignore\n tls: {\n type: DatasourceFieldType.FIELD_GROUP,\n display: \"Configure SSL\",\n fields: {\n tlsCertificateFile: {\n type: DatasourceFieldType.STRING,\n required: false,\n display: \"Certificate file path\",\n },\n tlsCertificateKeyFile: {\n type: DatasourceFieldType.STRING,\n required: false,\n display: \"Certificate Key file path\",\n },\n tlsCAFile: {\n type: DatasourceFieldType.STRING,\n required: false,\n display: \"CA file path\",\n },\n },\n },\n }\n }\n return schema\n}\n\nconst SCHEMA: Integration = getSchema()\n\nclass MongoIntegration implements IntegrationBase {\n private config: MongoDBConfig\n private client: any\n\n constructor(config: MongoDBConfig) {\n this.config = config\n const options: MongoClientOptions = {\n tlsCertificateFile: config.tlsCertificateFile || undefined,\n tlsCertificateKeyFile: config.tlsCertificateKeyFile || undefined,\n tlsCAFile: config.tlsCAFile || undefined,\n }\n this.client = new MongoClient(config.connectionString, options)\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n try {\n await this.connect()\n response.connected = true\n } catch (e: any) {\n response.error = e.message as string\n }\n return response\n }\n\n async connect() {\n return this.client.connect()\n }\n\n createObjectIds(json: any): object {\n const self = this\n function interpolateObjectIds(json: any) {\n for (let field of Object.keys(json)) {\n if (json[field] instanceof Object) {\n json[field] = self.createObjectIds(json[field])\n }\n if (\n typeof json[field] === \"string\" &&\n json[field].toLowerCase().startsWith(\"objectid\")\n ) {\n const id = json[field].match(/(?<=objectid\\(['\"]).*(?=['\"]\\))/gi)?.[0]\n if (id) {\n json[field] = ObjectId.createFromHexString(id)\n }\n }\n }\n return json\n }\n\n if (Array.isArray(json)) {\n for (let i = 0; i < json.length; i++) {\n json[i] = interpolateObjectIds(json[i])\n }\n return json\n }\n return interpolateObjectIds(json)\n }\n\n parseQueryParams(params: string, mode: string) {\n let queryParams = []\n let openCount = 0\n let inQuotes = false\n let i = 0\n let startIndex = 0\n for (let c of params) {\n if (c === '\"' && i > 0 && params[i - 1] !== \"\\\\\") {\n inQuotes = !inQuotes\n }\n if (c === \"{\" && !inQuotes) {\n openCount++\n if (openCount === 1) {\n startIndex = i\n }\n } else if (c === \"}\" && !inQuotes) {\n if (openCount === 1) {\n queryParams.push(JSON.parse(params.substring(startIndex, i + 1)))\n }\n openCount--\n }\n i++\n }\n let group1 = queryParams[0] ?? {}\n let group2 = queryParams[1] ?? {}\n let group3 = queryParams[2] ?? {}\n if (mode === \"update\") {\n return {\n filter: group1,\n update: group2,\n options: group3,\n }\n }\n return {\n filter: group1,\n options: group2,\n }\n }\n\n async create(query: MongoDBQuery) {\n try {\n await this.connect()\n const db = this.client.db(this.config.db)\n const collection = db.collection(query.extra.collection)\n let json = this.createObjectIds(query.json)\n\n // For mongodb we add an extra actionType to specify\n // which method we want to call on the collection\n switch (query.extra.actionType) {\n case \"insertOne\": {\n return await collection.insertOne(json)\n }\n case \"insertMany\": {\n return await collection.insertMany(json)\n }\n default: {\n throw new Error(\n `actionType ${query.extra.actionType} does not exist on DB for create`\n )\n }\n }\n } catch (err) {\n console.error(\"Error writing to mongodb\", err)\n throw err\n } finally {\n await this.client.close()\n }\n }\n\n async read(query: MongoDBQuery) {\n try {\n await this.connect()\n const db = this.client.db(this.config.db)\n const collection = db.collection(query.extra.collection)\n let json = this.createObjectIds(query.json)\n\n switch (query.extra.actionType) {\n case \"find\": {\n return await collection.find(json).toArray()\n }\n case \"findOne\": {\n return await collection.findOne(json)\n }\n case \"findOneAndUpdate\": {\n if (typeof query.json === \"string\") {\n json = this.parseQueryParams(query.json, \"update\")\n }\n let findAndUpdateJson = this.createObjectIds(json) as {\n filter: Filter<any>\n update: UpdateFilter<any>\n options: FindOneAndUpdateOptions\n }\n return await collection.findOneAndUpdate(\n findAndUpdateJson.filter,\n findAndUpdateJson.update,\n findAndUpdateJson.options\n )\n }\n case \"count\": {\n return await collection.countDocuments(json)\n }\n case \"distinct\": {\n return await collection.distinct(json)\n }\n default: {\n throw new Error(\n `actionType ${query.extra.actionType} does not exist on DB for read`\n )\n }\n }\n } catch (err) {\n console.error(\"Error querying mongodb\", err)\n throw err\n } finally {\n await this.client.close()\n }\n }\n\n async update(query: MongoDBQuery) {\n try {\n await this.connect()\n const db = this.client.db(this.config.db)\n const collection = db.collection(query.extra.collection)\n let queryJson = query.json\n if (typeof queryJson === \"string\") {\n queryJson = this.parseQueryParams(queryJson, \"update\")\n }\n let json = this.createObjectIds(queryJson) as {\n filter: Filter<any>\n update: UpdateFilter<any>\n options: object\n }\n\n switch (query.extra.actionType) {\n case \"updateOne\": {\n return await collection.updateOne(\n json.filter,\n json.update,\n json.options as UpdateOptions\n )\n }\n case \"updateMany\": {\n return await collection.updateMany(\n json.filter,\n json.update,\n json.options as UpdateOptions\n )\n }\n default: {\n throw new Error(\n `actionType ${query.extra.actionType} does not exist on DB for update`\n )\n }\n }\n } catch (err) {\n console.error(\"Error writing to mongodb\", err)\n throw err\n } finally {\n await this.client.close()\n }\n }\n\n async delete(query: MongoDBQuery) {\n try {\n await this.connect()\n const db = this.client.db(this.config.db)\n const collection = db.collection(query.extra.collection)\n let queryJson = query.json\n if (typeof queryJson === \"string\") {\n queryJson = this.parseQueryParams(queryJson, \"delete\")\n }\n let json = this.createObjectIds(queryJson) as {\n filter: Filter<any>\n options: OperationOptions\n }\n if (!json.options) {\n json = {\n filter: json,\n options: {},\n }\n }\n\n switch (query.extra.actionType) {\n case \"deleteOne\": {\n return await collection.deleteOne(json.filter, json.options)\n }\n case \"deleteMany\": {\n return await collection.deleteMany(json.filter, json.options)\n }\n default: {\n throw new Error(\n `actionType ${query.extra.actionType} does not exist on DB for delete`\n )\n }\n }\n } catch (err) {\n console.error(\"Error writing to mongodb\", err)\n throw err\n } finally {\n await this.client.close()\n }\n }\n\n async aggregate(query: {\n json: object\n steps: any[]\n extra: { [key: string]: string }\n }) {\n try {\n await this.connect()\n const db = this.client.db(this.config.db)\n const collection = db.collection(query.extra.collection)\n let response = []\n if (query.extra?.actionType === \"pipeline\") {\n for await (const doc of collection.aggregate(\n query.steps.map(({ key, value }) => {\n let temp: any = {}\n temp[key] = JSON.parse(value.value)\n return this.createObjectIds(temp)\n })\n )) {\n response.push(doc)\n }\n } else {\n const stages: Array<any> = query.json as Array<any>\n for await (const doc of collection.aggregate(\n stages ? this.createObjectIds(stages) : []\n )) {\n response.push(doc)\n }\n }\n return response\n } catch (err) {\n console.error(\"Error writing to mongodb\", err)\n throw err\n } finally {\n await this.client.close()\n }\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: MongoIntegration,\n}\n", "import {\n Integration,\n DatasourceFieldType,\n QueryType,\n IntegrationBase,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\n\nimport { Client, ClientOptions } from \"@elastic/elasticsearch\"\n\ninterface ElasticsearchConfig {\n url: string\n ssl?: boolean\n ca?: string\n rejectUnauthorized?: boolean\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/index.html\",\n description:\n \"Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents.\",\n friendlyName: \"ElasticSearch\",\n type: \"Non-relational\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n url: {\n type: DatasourceFieldType.STRING,\n required: true,\n default: \"http://localhost:9200\",\n },\n ssl: {\n type: DatasourceFieldType.BOOLEAN,\n default: false,\n required: false,\n },\n rejectUnauthorized: {\n type: DatasourceFieldType.BOOLEAN,\n default: true,\n required: false,\n },\n ca: {\n type: DatasourceFieldType.LONGFORM,\n default: false,\n required: false,\n },\n },\n query: {\n create: {\n type: QueryType.FIELDS,\n customisable: true,\n fields: {\n index: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n read: {\n type: QueryType.FIELDS,\n customisable: true,\n fields: {\n index: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n update: {\n type: QueryType.FIELDS,\n customisable: true,\n fields: {\n id: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n index: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n delete: {\n type: QueryType.FIELDS,\n fields: {\n id: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n index: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n },\n}\n\nclass ElasticSearchIntegration implements IntegrationBase {\n private config: ElasticsearchConfig\n private client\n\n constructor(config: ElasticsearchConfig) {\n this.config = config\n\n const clientConfig: ClientOptions = {\n node: this.config.url,\n }\n\n if (this.config.ssl) {\n clientConfig.ssl = {\n rejectUnauthorized: this.config.rejectUnauthorized,\n ca: this.config.ca || undefined,\n }\n }\n\n this.client = new Client(clientConfig)\n }\n\n async testConnection(): Promise<ConnectionInfo> {\n try {\n await this.client.info()\n return { connected: true }\n } catch (e: any) {\n return {\n connected: false,\n error: e.message as string,\n }\n }\n }\n\n async create(query: { index: string; json: object }) {\n const { index, json } = query\n\n try {\n const result = await this.client.index({\n index,\n body: json,\n })\n return result.body\n } catch (err) {\n console.error(\"Error writing to elasticsearch\", err)\n throw err\n } finally {\n await this.client.close()\n }\n }\n\n async read(query: { index: string; json: object }) {\n const { index, json } = query\n try {\n const result = await this.client.search({\n index: index,\n body: json,\n })\n return result.body.hits.hits.map(({ _source }: any) => _source)\n } catch (err) {\n console.error(\"Error querying elasticsearch\", err)\n throw err\n } finally {\n await this.client.close()\n }\n }\n\n async update(query: { id: string; index: string; json: object }) {\n const { id, index, json } = query\n try {\n const result = await this.client.update({\n id,\n index,\n body: json,\n })\n return result.body\n } catch (err) {\n console.error(\"Error querying elasticsearch\", err)\n throw err\n } finally {\n await this.client.close()\n }\n }\n\n async delete(query: { id: string; index: string }) {\n const { id, index } = query\n try {\n const result = await this.client.delete({\n id,\n index,\n })\n return result.body\n } catch (err) {\n console.error(\"Error deleting from elasticsearch\", err)\n throw err\n } finally {\n await this.client.close()\n }\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: ElasticSearchIntegration,\n}\n", "import {\n ConnectionInfo,\n DatasourceFeature,\n DatasourceFieldType,\n Document,\n Integration,\n IntegrationBase,\n QueryType,\n} from \"@budibase/types\"\nimport { db as dbCore } from \"@budibase/backend-core\"\n\ninterface CouchDBConfig {\n url: string\n database: string\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://docs.couchdb.org/en/stable/\",\n friendlyName: \"CouchDB\",\n type: \"Non-relational\",\n description:\n \"Apache CouchDB is an open-source document-oriented NoSQL database, implemented in Erlang.\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n url: {\n type: DatasourceFieldType.STRING,\n required: true,\n default: \"http://localhost:5984\",\n },\n database: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n query: {\n create: {\n type: QueryType.JSON,\n },\n read: {\n type: QueryType.JSON,\n },\n update: {\n type: QueryType.JSON,\n },\n get: {\n type: QueryType.FIELDS,\n fields: {\n id: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n delete: {\n type: QueryType.FIELDS,\n fields: {\n id: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n },\n}\n\nclass CouchDBIntegration implements IntegrationBase {\n private readonly client: dbCore.DatabaseImpl\n\n constructor(config: CouchDBConfig) {\n this.client = dbCore.DatabaseWithConnection(config.database, config.url)\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n try {\n const result = await this.query(\"exists\", \"validation error\", {})\n response.connected = result === true\n } catch (e: any) {\n response.error = e.message as string\n }\n return response\n }\n\n async query(\n command: string,\n errorMsg: string,\n query: { json?: object; id?: string }\n ) {\n try {\n return await (this.client as any)[command](query.id || query.json)\n } catch (err) {\n console.error(errorMsg, err)\n throw err\n }\n }\n\n private parse(query: { json: string | object }) {\n return typeof query.json === \"string\" ? JSON.parse(query.json) : query.json\n }\n\n async create(query: { json: string | object }) {\n const parsed = this.parse(query)\n return this.query(\"post\", \"Error writing to couchDB\", { json: parsed })\n }\n\n async read(query: { json: string | object }) {\n const parsed = this.parse(query)\n const result = await this.query(\"allDocs\", \"Error querying couchDB\", {\n json: {\n include_docs: true,\n ...parsed,\n },\n })\n return result.rows.map((row: { doc: object }) => row.doc)\n }\n\n async update(query: { json: string | object }) {\n const parsed: Document = this.parse(query)\n if (!parsed?._rev && parsed?._id) {\n const oldDoc = await this.get({ id: parsed._id })\n parsed._rev = oldDoc._rev\n }\n return this.query(\"put\", \"Error updating couchDB document\", {\n json: parsed,\n })\n }\n\n async get(query: { id: string }) {\n return this.query(\"get\", \"Error retrieving couchDB document by ID\", {\n id: query.id,\n })\n }\n\n async delete(query: { id: string }) {\n const doc = await this.query(\"get\", \"Cannot find doc to be deleted\", query)\n return this.query(\"remove\", \"Error deleting couchDB document\", {\n json: doc,\n })\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: CouchDBIntegration,\n}\n", "import {\n DatasourceFieldType,\n Integration,\n Operation,\n Table,\n TableSchema,\n QueryJson,\n QueryType,\n SqlQuery,\n DatasourcePlus,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\nimport {\n getSqlQuery,\n buildExternalTableId,\n convertSqlType,\n finaliseExternalTables,\n SqlClient,\n} from \"./utils\"\nimport Sql from \"./base/sql\"\nimport { MSSQLTablesResponse, MSSQLColumn } from \"./base/types\"\nconst sqlServer = require(\"mssql\")\nconst DEFAULT_SCHEMA = \"dbo\"\n\ninterface MSSQLConfig {\n user: string\n password: string\n server: string\n port: number | string\n database: string\n schema: string\n encrypt?: boolean\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://github.com/tediousjs/node-mssql\",\n plus: true,\n description:\n \"Microsoft SQL Server is a relational database management system developed by Microsoft. \",\n friendlyName: \"MS SQL Server\",\n type: \"Relational\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n [DatasourceFeature.FETCH_TABLE_NAMES]: true,\n },\n datasource: {\n user: {\n type: DatasourceFieldType.STRING,\n required: true,\n default: \"localhost\",\n },\n password: {\n type: DatasourceFieldType.PASSWORD,\n required: true,\n },\n server: {\n type: DatasourceFieldType.STRING,\n default: \"localhost\",\n },\n port: {\n type: DatasourceFieldType.NUMBER,\n required: false,\n default: 1433,\n },\n database: {\n type: DatasourceFieldType.STRING,\n default: \"root\",\n },\n schema: {\n type: DatasourceFieldType.STRING,\n default: DEFAULT_SCHEMA,\n },\n encrypt: {\n type: DatasourceFieldType.BOOLEAN,\n default: true,\n },\n },\n query: {\n create: {\n type: QueryType.SQL,\n },\n read: {\n type: QueryType.SQL,\n },\n update: {\n type: QueryType.SQL,\n },\n delete: {\n type: QueryType.SQL,\n },\n },\n}\n\nclass SqlServerIntegration extends Sql implements DatasourcePlus {\n private readonly config: MSSQLConfig\n private index: number = 0\n private readonly pool: any\n private client: any\n public tables: Record<string, Table> = {}\n public schemaErrors: Record<string, string> = {}\n\n MASTER_TABLES = [\n \"spt_fallback_db\",\n \"spt_fallback_dev\",\n \"spt_fallback_usg\",\n \"spt_monitor\",\n \"MSreplication_options\",\n ]\n TABLES_SQL =\n \"SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'\"\n\n constructor(config: MSSQLConfig) {\n super(SqlClient.MS_SQL)\n this.config = config\n const clientCfg = {\n ...this.config,\n options: {\n encrypt: this.config.encrypt,\n enableArithAbort: true,\n },\n }\n delete clientCfg.encrypt\n if (!this.pool) {\n this.pool = new sqlServer.ConnectionPool(clientCfg)\n }\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n try {\n await this.connect()\n response.connected = true\n } catch (e: any) {\n response.error = e.message as string\n }\n return response\n }\n\n getBindingIdentifier(): string {\n return `@p${this.index++}`\n }\n\n getStringConcat(parts: string[]): string {\n return `concat(${parts.join(\", \")})`\n }\n\n async connect() {\n try {\n this.client = await this.pool.connect()\n } catch (err) {\n // @ts-ignore\n throw new Error(err)\n }\n }\n\n async internalQuery(\n query: SqlQuery,\n operation: string | undefined = undefined\n ) {\n const client = this.client\n const request = client.request()\n this.index = 0\n try {\n if (Array.isArray(query.bindings)) {\n let count = 0\n for (let binding of query.bindings) {\n request.input(`p${count++}`, binding)\n }\n }\n // this is a hack to get the inserted ID back,\n // no way to do this with Knex nicely\n const sql =\n operation === Operation.CREATE\n ? `${query.sql}; SELECT SCOPE_IDENTITY() AS id;`\n : query.sql\n return await request.query(sql)\n } catch (err) {\n // @ts-ignore\n throw new Error(err)\n }\n }\n\n getDefinitionSQL(tableName: string) {\n return `select *\n from INFORMATION_SCHEMA.COLUMNS\n where TABLE_NAME='${tableName}'`\n }\n\n getConstraintsSQL(tableName: string) {\n return `SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC \n INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KU\n ON TC.CONSTRAINT_TYPE = 'PRIMARY KEY' \n AND TC.CONSTRAINT_NAME = KU.CONSTRAINT_NAME \n AND KU.table_name='${tableName}'\n ORDER BY \n KU.TABLE_NAME,\n KU.ORDINAL_POSITION;`\n }\n\n getAutoColumnsSQL(tableName: string) {\n return `SELECT \n COLUMNPROPERTY(OBJECT_ID(TABLE_SCHEMA+'.'+TABLE_NAME),COLUMN_NAME,'IsComputed') \n AS IS_COMPUTED,\n COLUMNPROPERTY(object_id(TABLE_SCHEMA+'.'+TABLE_NAME), COLUMN_NAME, 'IsIdentity')\n AS IS_IDENTITY,\n *\n FROM INFORMATION_SCHEMA.COLUMNS\n WHERE TABLE_NAME='${tableName}'`\n }\n\n async runSQL(sql: string) {\n return (await this.internalQuery(getSqlQuery(sql))).recordset\n }\n\n /**\n * Fetches the tables from the sql server database and assigns them to the datasource.\n * @param {*} datasourceId - datasourceId to fetch\n * @param entities - the tables that are to be built\n */\n async buildSchema(datasourceId: string, entities: Record<string, Table>) {\n await this.connect()\n let tableInfo: MSSQLTablesResponse[] = await this.runSQL(this.TABLES_SQL)\n if (tableInfo == null || !Array.isArray(tableInfo)) {\n throw \"Unable to get list of tables in database\"\n }\n\n const schema = this.config.schema || DEFAULT_SCHEMA\n const tableNames = tableInfo\n .filter((record: any) => record.TABLE_SCHEMA === schema)\n .map((record: any) => record.TABLE_NAME)\n .filter((name: string) => this.MASTER_TABLES.indexOf(name) === -1)\n\n const tables: Record<string, Table> = {}\n for (let tableName of tableNames) {\n // get the column definition (type)\n const definition = await this.runSQL(this.getDefinitionSQL(tableName))\n // find primary key constraints\n const constraints = await this.runSQL(this.getConstraintsSQL(tableName))\n // find the computed and identity columns (auto columns)\n const columns: MSSQLColumn[] = await this.runSQL(\n this.getAutoColumnsSQL(tableName)\n )\n const primaryKeys = constraints\n .filter(\n (constraint: any) => constraint.CONSTRAINT_TYPE === \"PRIMARY KEY\"\n )\n .map((constraint: any) => constraint.COLUMN_NAME)\n const autoColumns = columns\n .filter(col => col.IS_COMPUTED || col.IS_IDENTITY)\n .map(col => col.COLUMN_NAME)\n const requiredColumns = columns\n .filter(col => col.IS_NULLABLE === \"NO\")\n .map(col => col.COLUMN_NAME)\n\n let schema: TableSchema = {}\n for (let def of definition) {\n const name = def.COLUMN_NAME\n if (typeof name !== \"string\") {\n continue\n }\n const hasDefault = def.COLUMN_DEFAULT\n const isAuto = !!autoColumns.find(col => col === name)\n const required = !!requiredColumns.find(col => col === name)\n schema[name] = {\n autocolumn: isAuto,\n name: name,\n constraints: {\n presence: required && !isAuto && !hasDefault,\n },\n ...convertSqlType(def.DATA_TYPE),\n externalType: def.DATA_TYPE,\n }\n }\n tables[tableName] = {\n _id: buildExternalTableId(datasourceId, tableName),\n primary: primaryKeys,\n name: tableName,\n schema,\n }\n }\n const final = finaliseExternalTables(tables, entities)\n this.tables = final.tables\n this.schemaErrors = final.errors\n }\n\n async queryTableNames() {\n let tableInfo: MSSQLTablesResponse[] = await this.runSQL(this.TABLES_SQL)\n const schema = this.config.schema || DEFAULT_SCHEMA\n return tableInfo\n .filter((record: any) => record.TABLE_SCHEMA === schema)\n .map((record: any) => record.TABLE_NAME)\n .filter((name: string) => this.MASTER_TABLES.indexOf(name) === -1)\n }\n\n async getTableNames() {\n await this.connect()\n return this.queryTableNames()\n }\n\n async read(query: SqlQuery | string) {\n await this.connect()\n const response = await this.internalQuery(getSqlQuery(query))\n return response.recordset\n }\n\n async create(query: SqlQuery | string) {\n await this.connect()\n const response = await this.internalQuery(getSqlQuery(query))\n return response.recordset || [{ created: true }]\n }\n\n async update(query: SqlQuery | string) {\n await this.connect()\n const response = await this.internalQuery(getSqlQuery(query))\n return response.recordset || [{ updated: true }]\n }\n\n async delete(query: SqlQuery | string) {\n await this.connect()\n const response = await this.internalQuery(getSqlQuery(query))\n return response.recordset || [{ deleted: true }]\n }\n\n async query(json: QueryJson) {\n const schema = this.config.schema\n await this.connect()\n if (schema && schema !== DEFAULT_SCHEMA && json?.endpoint) {\n json.endpoint.schema = schema\n }\n const operation = this._operation(json)\n const queryFn = (query: any, op: string) => this.internalQuery(query, op)\n const processFn = (result: any) =>\n result.recordset ? result.recordset : [{ [operation]: true }]\n return this.queryWithReturning(json, queryFn, processFn)\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: SqlServerIntegration,\n}\n", "import {\n Integration,\n QueryType,\n IntegrationBase,\n DatasourceFieldType,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\n\nimport AWS from \"aws-sdk\"\nimport csv from \"csvtojson\"\n\ninterface S3Config {\n region: string\n accessKeyId: string\n secretAccessKey: string\n s3ForcePathStyle: boolean\n endpoint?: string\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html\",\n description:\n \"Amazon Simple Storage Service (Amazon S3) is an object storage service that offers industry-leading scalability, data availability, security, and performance.\",\n friendlyName: \"Amazon S3\",\n type: \"Object store\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n region: {\n type: \"string\",\n required: false,\n default: \"us-east-1\",\n },\n accessKeyId: {\n type: \"password\",\n required: true,\n },\n secretAccessKey: {\n type: \"password\",\n required: true,\n },\n endpoint: {\n type: \"string\",\n required: false,\n },\n signatureVersion: {\n type: \"string\",\n required: false,\n default: \"v4\",\n },\n },\n query: {\n create: {\n type: QueryType.FIELDS,\n fields: {\n bucket: {\n display: \"New Bucket\",\n type: DatasourceFieldType.STRING,\n required: true,\n },\n location: {\n required: true,\n default: \"us-east-1\",\n type: DatasourceFieldType.STRING,\n },\n grantFullControl: {\n display: \"Grant full control\",\n type: DatasourceFieldType.STRING,\n },\n grantRead: {\n display: \"Grant read\",\n type: DatasourceFieldType.STRING,\n },\n grantReadAcp: {\n display: \"Grant read ACP\",\n type: DatasourceFieldType.STRING,\n },\n grantWrite: {\n display: \"Grant write\",\n type: DatasourceFieldType.STRING,\n },\n grantWriteAcp: {\n display: \"Grant write ACP\",\n type: DatasourceFieldType.STRING,\n },\n },\n },\n read: {\n type: QueryType.FIELDS,\n fields: {\n bucket: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n delimiter: {\n type: DatasourceFieldType.STRING,\n },\n marker: {\n type: DatasourceFieldType.STRING,\n },\n maxKeys: {\n type: DatasourceFieldType.NUMBER,\n display: \"Max Keys\",\n },\n prefix: {\n type: DatasourceFieldType.STRING,\n },\n },\n },\n readCsv: {\n displayName: \"Read CSV\",\n type: QueryType.FIELDS,\n readable: true,\n fields: {\n bucket: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n key: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n delete: {\n type: QueryType.FIELDS,\n fields: {\n bucket: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n delete: {\n type: DatasourceFieldType.JSON,\n required: true,\n },\n },\n },\n },\n extra: {\n acl: {\n required: false,\n displayName: \"ACL\",\n type: DatasourceFieldType.LIST,\n data: {\n create: [\n \"private\",\n \"public-read\",\n \"public-read-write\",\n \"authenticated-read\",\n ],\n },\n },\n },\n}\n\nclass S3Integration implements IntegrationBase {\n private readonly config: S3Config\n private client\n\n constructor(config: S3Config) {\n this.config = config\n if (this.config.endpoint) {\n this.config.s3ForcePathStyle = true\n } else {\n delete this.config.endpoint\n }\n\n this.client = new AWS.S3(this.config)\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n try {\n await this.client.listBuckets().promise()\n response.connected = true\n } catch (e: any) {\n response.error = e.message as string\n }\n return response\n }\n\n async create(query: {\n bucket: string\n location: string\n grantFullControl: string\n grantRead: string\n grantReadAcp: string\n grantWrite: string\n grantWriteAcp: string\n extra: {\n acl: string\n }\n }) {\n let params: any = {\n Bucket: query.bucket,\n ACL: query.extra?.acl,\n GrantFullControl: query.grantFullControl,\n GrantRead: query.grantRead,\n GrantReadACP: query.grantReadAcp,\n GrantWrite: query.grantWrite,\n GrantWriteACP: query.grantWriteAcp,\n }\n if (query.location) {\n params[\"CreateBucketConfiguration\"] = {\n LocationConstraint: query.location,\n }\n }\n return await this.client.createBucket(params).promise()\n }\n\n async read(query: {\n bucket: string\n delimiter: string\n expectedBucketOwner: string\n marker: string\n maxKeys: number\n prefix: string\n }) {\n const response = await this.client\n .listObjects({\n Bucket: query.bucket,\n Delimiter: query.delimiter,\n Marker: query.marker,\n MaxKeys: query.maxKeys,\n Prefix: query.prefix,\n })\n .promise()\n return response.Contents\n }\n\n async readCsv(query: { bucket: string; key: string }) {\n const stream = this.client\n .getObject({\n Bucket: query.bucket,\n Key: query.key,\n })\n .createReadStream()\n\n let csvError = false\n return new Promise((resolve, reject) => {\n stream.on(\"error\", (err: Error) => {\n reject(err)\n })\n const response = csv()\n .fromStream(stream)\n .on(\"error\", () => {\n csvError = true\n })\n stream.on(\"finish\", () => {\n resolve(response)\n })\n }).catch(err => {\n if (csvError) {\n throw new Error(\"Could not read CSV\")\n } else {\n throw err\n }\n })\n }\n\n async delete(query: { bucket: string; delete: string }) {\n return await this.client\n .deleteObjects({\n Bucket: query.bucket,\n Delete: JSON.parse(query.delete),\n })\n .promise()\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: S3Integration,\n}\n", "import {\n ConnectionInfo,\n DatasourceFeature,\n DatasourceFieldType,\n Integration,\n IntegrationBase,\n QueryType,\n} from \"@budibase/types\"\n\nimport Airtable from \"airtable\"\n\ninterface AirtableConfig {\n apiKey: string\n base: string\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://airtable.com/api\",\n description:\n \"Airtable is a spreadsheet-database hybrid, with the features of a database but applied to a spreadsheet.\",\n friendlyName: \"Airtable\",\n type: \"Spreadsheet\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n apiKey: {\n type: DatasourceFieldType.PASSWORD,\n default: \"enter api key\",\n required: true,\n },\n base: {\n type: DatasourceFieldType.STRING,\n default: \"mybase\",\n required: true,\n },\n },\n query: {\n create: {\n type: QueryType.FIELDS,\n customisable: true,\n fields: {\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n read: {\n type: QueryType.FIELDS,\n fields: {\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n view: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n numRecords: {\n type: DatasourceFieldType.NUMBER,\n default: 10,\n },\n },\n },\n update: {\n type: QueryType.FIELDS,\n customisable: true,\n fields: {\n id: {\n display: \"Record ID\",\n type: DatasourceFieldType.STRING,\n required: true,\n },\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n delete: {\n type: QueryType.JSON,\n },\n },\n}\n\nclass AirtableIntegration implements IntegrationBase {\n private config: AirtableConfig\n private client\n\n constructor(config: AirtableConfig) {\n this.config = config\n this.client = new Airtable(config).base(config.base)\n }\n\n async testConnection(): Promise<ConnectionInfo> {\n const mockTable = Date.now().toString()\n try {\n await this.client.makeRequest({\n path: `/${mockTable}`,\n })\n\n return { connected: true }\n } catch (e: any) {\n if (\n e.message ===\n `Could not find table ${mockTable} in application ${this.config.base}`\n ) {\n // The request managed to check the application, so the credentials are valid\n return { connected: true }\n }\n\n return {\n connected: false,\n error: e.message as string,\n }\n }\n }\n\n async create(query: { table: any; json: any }) {\n const { table, json } = query\n\n try {\n return await this.client(table).create([\n {\n fields: json,\n },\n ])\n } catch (err) {\n console.error(\"Error writing to airtable\", err)\n throw err\n }\n }\n\n async read(query: { table: any; numRecords: any; view: any }) {\n try {\n const records = await this.client(query.table)\n .select({ maxRecords: query.numRecords || 10, view: query.view })\n .firstPage()\n // @ts-ignore\n return records.map(({ fields }) => fields)\n } catch (err) {\n console.error(\"Error writing to airtable\", err)\n return []\n }\n }\n\n async update(query: { table: any; id: any; json: any }) {\n const { table, id, json } = query\n\n try {\n return await this.client(table).update([\n {\n id,\n fields: json,\n },\n ])\n } catch (err) {\n console.error(\"Error writing to airtable\", err)\n throw err\n }\n }\n\n async delete(query: { table: any; ids: any }) {\n try {\n return await this.client(query.table).destroy(query.ids)\n } catch (err) {\n console.error(\"Error writing to airtable\", err)\n throw err\n }\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: AirtableIntegration,\n}\n", "import {\n Integration,\n DatasourceFieldType,\n QueryType,\n QueryJson,\n SqlQuery,\n Table,\n TableSchema,\n DatasourcePlus,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\nimport {\n getSqlQuery,\n SqlClient,\n buildExternalTableId,\n convertSqlType,\n finaliseExternalTables,\n} from \"./utils\"\nimport dayjs from \"dayjs\"\nimport { NUMBER_REGEX } from \"../utilities\"\nimport Sql from \"./base/sql\"\nimport { MySQLColumn } from \"./base/types\"\n\nimport mysql from \"mysql2/promise\"\n\ninterface MySQLConfig extends mysql.ConnectionOptions {\n database: string\n rejectUnauthorized: boolean\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://github.com/sidorares/node-mysql2\",\n plus: true,\n friendlyName: \"MySQL\",\n type: \"Relational\",\n description:\n \"MySQL Database Service is a fully managed database service to deploy cloud-native applications. \",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n [DatasourceFeature.FETCH_TABLE_NAMES]: true,\n },\n datasource: {\n host: {\n type: DatasourceFieldType.STRING,\n default: \"localhost\",\n required: true,\n },\n port: {\n type: DatasourceFieldType.NUMBER,\n default: 3306,\n required: false,\n },\n user: {\n type: DatasourceFieldType.STRING,\n default: \"root\",\n required: true,\n },\n password: {\n type: DatasourceFieldType.PASSWORD,\n default: \"root\",\n required: true,\n },\n database: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n ssl: {\n type: DatasourceFieldType.OBJECT,\n required: false,\n },\n rejectUnauthorized: {\n type: DatasourceFieldType.BOOLEAN,\n default: true,\n required: false,\n },\n },\n query: {\n create: {\n type: QueryType.SQL,\n },\n read: {\n type: QueryType.SQL,\n },\n update: {\n type: QueryType.SQL,\n },\n delete: {\n type: QueryType.SQL,\n },\n },\n}\n\nfunction bindingTypeCoerce(bindings: any[]) {\n for (let i = 0; i < bindings.length; i++) {\n const binding = bindings[i]\n if (typeof binding !== \"string\") {\n continue\n }\n const matches = binding.match(NUMBER_REGEX)\n // check if number first\n if (matches && matches[0] !== \"\" && !isNaN(Number(matches[0]))) {\n bindings[i] = parseFloat(binding)\n }\n // if not a number, see if it is a date - important to do in this order as any\n // integer will be considered a valid date\n else if (\n /^\\d/.test(binding) &&\n dayjs(binding).isValid() &&\n !binding.includes(\",\")\n ) {\n bindings[i] = dayjs(binding).toDate()\n }\n }\n return bindings\n}\n\nclass MySQLIntegration extends Sql implements DatasourcePlus {\n private config: MySQLConfig\n private client?: mysql.Connection\n public tables: Record<string, Table> = {}\n public schemaErrors: Record<string, string> = {}\n\n constructor(config: MySQLConfig) {\n super(SqlClient.MY_SQL)\n this.config = config\n if (config.ssl && Object.keys(config.ssl).length === 0) {\n delete config.ssl\n }\n // make sure this defaults to true\n if (\n config.rejectUnauthorized != null &&\n !config.rejectUnauthorized &&\n config.ssl &&\n typeof config.ssl !== \"string\"\n ) {\n config.ssl.rejectUnauthorized = config.rejectUnauthorized\n }\n // @ts-ignore\n delete config.rejectUnauthorized\n this.config = {\n ...config,\n multipleStatements: true,\n typeCast: function (field: any, next: any) {\n if (\n field.type == \"DATETIME\" ||\n field.type === \"DATE\" ||\n field.type === \"TIMESTAMP\" ||\n field.type === \"LONGLONG\"\n ) {\n return field.string()\n }\n if (field.type === \"BIT\" && field.length === 1) {\n return field.buffer()?.[0]\n }\n return next()\n },\n }\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n try {\n const [result] = await this.internalQuery(\n { sql: \"SELECT 1+1 AS checkRes\" },\n { connect: true }\n )\n response.connected = result?.checkRes == 2\n } catch (e: any) {\n response.error = e.message as string\n }\n return response\n }\n\n getBindingIdentifier(): string {\n return \"?\"\n }\n\n getStringConcat(parts: string[]): string {\n return `concat(${parts.join(\", \")})`\n }\n\n async connect() {\n this.client = await mysql.createConnection(this.config)\n }\n\n async disconnect() {\n await this.client!.end()\n }\n\n async internalQuery(\n query: SqlQuery,\n opts: { connect?: boolean; disableCoercion?: boolean } = {\n connect: true,\n disableCoercion: false,\n }\n ): Promise<any[] | any> {\n try {\n if (opts?.connect) {\n await this.connect()\n }\n const baseBindings = query.bindings || []\n const bindings = opts?.disableCoercion\n ? baseBindings\n : bindingTypeCoerce(baseBindings)\n // Node MySQL is callback based, so we must wrap our call in a promise\n const response = await this.client!.query(query.sql, bindings)\n return response[0]\n } finally {\n if (opts?.connect && this.client) {\n await this.disconnect()\n }\n }\n }\n\n async buildSchema(datasourceId: string, entities: Record<string, Table>) {\n const tables: { [key: string]: Table } = {}\n await this.connect()\n\n try {\n // get the tables first\n const tableNames = await this.queryTableNames()\n for (let tableName of tableNames) {\n const primaryKeys = []\n const schema: TableSchema = {}\n const descResp: MySQLColumn[] = await this.internalQuery(\n { sql: `DESCRIBE \\`${tableName}\\`;` },\n { connect: false }\n )\n for (let column of descResp) {\n const columnName = column.Field\n if (column.Key === \"PRI\" && primaryKeys.indexOf(column.Key) === -1) {\n primaryKeys.push(columnName)\n }\n const hasDefault = column.Default != null\n const isAuto: boolean =\n typeof column.Extra === \"string\" &&\n (column.Extra === \"auto_increment\" ||\n column.Extra.toLowerCase().includes(\"generated\"))\n const required = column.Null !== \"YES\"\n const constraints = {\n presence: required && !isAuto && !hasDefault,\n }\n schema[columnName] = {\n name: columnName,\n autocolumn: isAuto,\n constraints,\n ...convertSqlType(column.Type),\n externalType: column.Type,\n }\n }\n if (!tables[tableName]) {\n tables[tableName] = {\n _id: buildExternalTableId(datasourceId, tableName),\n primary: primaryKeys,\n name: tableName,\n schema,\n }\n }\n }\n } finally {\n await this.disconnect()\n }\n const final = finaliseExternalTables(tables, entities)\n this.tables = final.tables\n this.schemaErrors = final.errors\n }\n\n async queryTableNames() {\n const database = this.config.database\n const tablesResp: Record<string, string>[] = await this.internalQuery(\n { sql: \"SHOW TABLES;\" },\n { connect: false }\n )\n return tablesResp.map(\n (obj: any) =>\n obj[`Tables_in_${database}`] ||\n obj[`Tables_in_${database.toLowerCase()}`]\n )\n }\n\n async getTableNames() {\n await this.connect()\n try {\n return this.queryTableNames()\n } finally {\n await this.disconnect()\n }\n }\n\n async create(query: SqlQuery | string) {\n const results = await this.internalQuery(getSqlQuery(query))\n return results.length ? results : [{ created: true }]\n }\n\n async read(query: SqlQuery | string) {\n return this.internalQuery(getSqlQuery(query))\n }\n\n async update(query: SqlQuery | string) {\n const results = await this.internalQuery(getSqlQuery(query))\n return results.length ? results : [{ updated: true }]\n }\n\n async delete(query: SqlQuery | string) {\n const results = await this.internalQuery(getSqlQuery(query))\n return results.length ? results : [{ deleted: true }]\n }\n\n async query(json: QueryJson) {\n await this.connect()\n try {\n const queryFn = (query: any) =>\n this.internalQuery(query, { connect: false, disableCoercion: true })\n return await this.queryWithReturning(json, queryFn)\n } finally {\n await this.disconnect()\n }\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: MySQLIntegration,\n}\n", "import {\n Integration,\n DatasourceFieldType,\n QueryType,\n IntegrationBase,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\n\nimport { Database, aql } from \"arangojs\"\n\ninterface ArangodbConfig {\n url: string\n username: string\n password: string\n databaseName: string\n collection: string\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://github.com/arangodb/arangojs\",\n friendlyName: \"ArangoDB\",\n type: \"Non-relational\",\n description:\n \"ArangoDB is a scalable open-source multi-model database natively supporting graph, document and search. All supported data models & access patterns can be combined in queries allowing for maximal flexibility. \",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n url: {\n type: DatasourceFieldType.STRING,\n default: \"http://localhost:8529\",\n required: true,\n },\n username: {\n type: DatasourceFieldType.STRING,\n default: \"root\",\n required: true,\n },\n password: {\n type: DatasourceFieldType.PASSWORD,\n required: true,\n },\n databaseName: {\n type: DatasourceFieldType.STRING,\n default: \"_system\",\n required: true,\n },\n collection: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n query: {\n read: {\n type: QueryType.SQL,\n },\n create: {\n type: QueryType.JSON,\n },\n },\n}\n\nclass ArangoDBIntegration implements IntegrationBase {\n private config: ArangodbConfig\n private client\n\n constructor(config: ArangodbConfig) {\n const newConfig = {\n url: config.url,\n databaseName: config.databaseName,\n auth: {\n username: config.username,\n password: config.password,\n },\n }\n\n this.config = config\n this.client = new Database(newConfig)\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n try {\n await this.client.get()\n response.connected = true\n } catch (e: any) {\n response.error = e.message as string\n }\n return response\n }\n\n async read(query: { sql: any }) {\n try {\n const result = await this.client.query(query.sql)\n return result.all()\n } catch (err) {\n // @ts-ignore\n console.error(\"Error querying arangodb\", err.message)\n throw err\n } finally {\n this.client.close()\n }\n }\n\n async create(query: { json: any }) {\n const clc = this.client.collection(this.config.collection)\n try {\n const result = await this.client.query(\n aql`INSERT ${query.json} INTO ${clc} RETURN NEW`\n )\n return result.all()\n } catch (err) {\n // @ts-ignore\n console.error(\"Error querying arangodb\", err.message)\n throw err\n } finally {\n this.client.close()\n }\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: ArangoDBIntegration,\n}\n", "import {\n Integration,\n DatasourceFieldType,\n QueryType,\n PaginationConfig,\n IntegrationBase,\n PaginationValues,\n RestQueryFields as RestQuery,\n RestConfig,\n RestAuthType,\n RestBasicAuthConfig,\n RestBearerAuthConfig,\n} from \"@budibase/types\"\nimport { get } from \"lodash\"\nimport * as https from \"https\"\nimport qs from \"querystring\"\nimport fetch from \"node-fetch\"\nimport { formatBytes } from \"../utilities\"\nimport { performance } from \"perf_hooks\"\nimport FormData from \"form-data\"\nimport { URLSearchParams } from \"url\"\nimport { blacklist } from \"@budibase/backend-core\"\n\nconst BodyTypes = {\n NONE: \"none\",\n FORM_DATA: \"form\",\n XML: \"xml\",\n ENCODED: \"encoded\",\n JSON: \"json\",\n TEXT: \"text\",\n}\n\nconst coreFields = {\n path: {\n type: DatasourceFieldType.STRING,\n display: \"URL\",\n },\n queryString: {\n type: DatasourceFieldType.STRING,\n },\n headers: {\n type: DatasourceFieldType.OBJECT,\n },\n enabledHeaders: {\n type: DatasourceFieldType.OBJECT,\n },\n requestBody: {\n type: DatasourceFieldType.JSON,\n },\n bodyType: {\n type: DatasourceFieldType.STRING,\n enum: Object.values(BodyTypes),\n },\n pagination: {\n type: DatasourceFieldType.OBJECT,\n },\n}\n\nconst { parseStringPromise: xmlParser, Builder: XmlBuilder } = require(\"xml2js\")\n\nconst SCHEMA: Integration = {\n docs: \"https://github.com/node-fetch/node-fetch\",\n description:\n \"With the REST API datasource, you can connect, query and pull data from multiple REST APIs. You can then use the retrieved data to build apps.\",\n friendlyName: \"REST API\",\n type: \"API\",\n datasource: {\n url: {\n type: DatasourceFieldType.STRING,\n default: \"\",\n required: false,\n deprecated: true,\n },\n defaultHeaders: {\n type: DatasourceFieldType.OBJECT,\n required: false,\n default: {},\n },\n rejectUnauthorized: {\n display: \"Reject Unauthorized\",\n type: DatasourceFieldType.BOOLEAN,\n default: true,\n required: false,\n },\n },\n query: {\n create: {\n readable: true,\n displayName: \"POST\",\n type: QueryType.FIELDS,\n fields: coreFields,\n },\n read: {\n displayName: \"GET\",\n readable: true,\n type: QueryType.FIELDS,\n fields: coreFields,\n },\n update: {\n displayName: \"PUT\",\n readable: true,\n type: QueryType.FIELDS,\n fields: coreFields,\n },\n patch: {\n displayName: \"PATCH\",\n readable: true,\n type: QueryType.FIELDS,\n fields: coreFields,\n },\n delete: {\n displayName: \"DELETE\",\n type: QueryType.FIELDS,\n fields: coreFields,\n },\n },\n}\n\nclass RestIntegration implements IntegrationBase {\n private config: RestConfig\n private headers: {\n [key: string]: string\n } = {}\n private startTimeMs: number = performance.now()\n\n constructor(config: RestConfig) {\n this.config = config\n }\n\n async parseResponse(response: any, pagination: PaginationConfig | null) {\n let data, raw, headers\n const contentType = response.headers.get(\"content-type\") || \"\"\n try {\n if (contentType.includes(\"application/json\")) {\n data = await response.json()\n raw = JSON.stringify(data)\n } else if (\n contentType.includes(\"text/xml\") ||\n contentType.includes(\"application/xml\")\n ) {\n const rawXml = await response.text()\n data =\n (await xmlParser(rawXml, {\n explicitArray: false,\n trim: true,\n explicitRoot: false,\n })) || {}\n // there is only one structure, its an array, return the array so it appears as rows\n const keys = Object.keys(data)\n if (keys.length === 1 && Array.isArray(data[keys[0]])) {\n data = data[keys[0]]\n }\n raw = rawXml\n } else if (contentType.includes(\"application/pdf\")) {\n data = await response.arrayBuffer() // Save PDF as ArrayBuffer\n raw = Buffer.from(data)\n } else {\n data = await response.text()\n raw = data\n }\n } catch (err) {\n throw \"Failed to parse response body.\"\n }\n const size = formatBytes(\n response.headers.get(\"content-length\") || Buffer.byteLength(raw, \"utf8\")\n )\n const time = `${Math.round(performance.now() - this.startTimeMs)}ms`\n headers = response.headers.raw()\n for (let [key, value] of Object.entries(headers)) {\n headers[key] = Array.isArray(value) ? value[0] : value\n }\n\n // Check if a pagination cursor exists in the response\n let nextCursor = null\n if (pagination?.responseParam) {\n nextCursor = get(data, pagination.responseParam)\n }\n\n return {\n data,\n info: {\n code: response.status,\n size,\n time,\n },\n extra: {\n raw,\n headers,\n },\n pagination: {\n cursor: nextCursor,\n },\n }\n }\n\n getUrl(\n path: string,\n queryString: string,\n pagination: PaginationConfig | null,\n paginationValues: PaginationValues | null\n ): string {\n // Add pagination params to query string if required\n if (pagination?.location === \"query\" && paginationValues) {\n const { pageParam, sizeParam } = pagination\n const params = new URLSearchParams()\n\n // Append page number or cursor param if configured\n if (pageParam && paginationValues.page != null) {\n params.append(pageParam, paginationValues.page as string)\n }\n\n // Append page size param if configured\n if (sizeParam && paginationValues.limit != null) {\n params.append(sizeParam, String(paginationValues.limit))\n }\n\n // Prepend query string with pagination params\n let paginationString = params.toString()\n if (paginationString) {\n queryString = `${paginationString}&${queryString}`\n }\n }\n\n if (queryString) {\n // make sure the query string is fully encoded\n queryString = \"?\" + qs.encode(qs.decode(queryString))\n }\n const main = `${path}${queryString}`\n\n let complete = main\n if (this.config.url && !main.startsWith(\"http\")) {\n complete = !this.config.url ? main : `${this.config.url}/${main}`\n }\n if (!complete.startsWith(\"http\")) {\n complete = `http://${complete}`\n }\n return complete\n }\n\n addBody(\n bodyType: string,\n body: string | any,\n input: any,\n pagination: PaginationConfig | null,\n paginationValues: PaginationValues | null\n ) {\n if (!input.headers) {\n input.headers = {}\n }\n if (bodyType === BodyTypes.NONE) {\n return input\n }\n let error,\n object: any = {},\n string = \"\"\n try {\n if (body) {\n string = typeof body !== \"string\" ? JSON.stringify(body) : body\n object = typeof body === \"object\" ? body : JSON.parse(body)\n }\n } catch (err) {\n error = err\n }\n\n // Util to add pagination values to a certain body type\n const addPaginationToBody = (insertFn: Function) => {\n if (pagination?.location === \"body\") {\n if (pagination?.pageParam && paginationValues?.page != null) {\n insertFn(pagination.pageParam, paginationValues.page)\n }\n if (pagination?.sizeParam && paginationValues?.limit != null) {\n insertFn(pagination.sizeParam, paginationValues.limit)\n }\n }\n }\n\n switch (bodyType) {\n case BodyTypes.TEXT:\n // content type defaults to plaintext\n input.body = string\n break\n case BodyTypes.ENCODED:\n const params = new URLSearchParams()\n for (let [key, value] of Object.entries(object)) {\n params.append(key, value as string)\n }\n addPaginationToBody((key: string, value: any) => {\n params.append(key, value)\n })\n input.body = params\n break\n case BodyTypes.FORM_DATA:\n const form = new FormData()\n for (let [key, value] of Object.entries(object)) {\n form.append(key, value)\n }\n addPaginationToBody((key: string, value: any) => {\n form.append(key, value)\n })\n input.body = form\n break\n case BodyTypes.XML:\n if (object != null && Object.keys(object).length) {\n string = new XmlBuilder().buildObject(object)\n }\n input.body = string\n input.headers[\"Content-Type\"] = \"application/xml\"\n break\n case BodyTypes.JSON:\n // if JSON error, throw it\n if (error) {\n throw \"Invalid JSON for request body\"\n }\n addPaginationToBody((key: string, value: any) => {\n object[key] = value\n })\n input.body = JSON.stringify(object)\n input.headers[\"Content-Type\"] = \"application/json\"\n break\n }\n return input\n }\n\n getAuthHeaders(authConfigId: string): { [key: string]: any } {\n let headers: any = {}\n\n if (this.config.authConfigs && authConfigId) {\n const authConfig = this.config.authConfigs.filter(\n c => c._id === authConfigId\n )[0]\n // check the config still exists before proceeding\n // if not - do nothing\n if (authConfig) {\n let config\n switch (authConfig.type) {\n case RestAuthType.BASIC:\n config = authConfig.config as RestBasicAuthConfig\n headers.Authorization = `Basic ${Buffer.from(\n `${config.username}:${config.password}`\n ).toString(\"base64\")}`\n break\n case RestAuthType.BEARER:\n config = authConfig.config as RestBearerAuthConfig\n headers.Authorization = `Bearer ${config.token}`\n break\n }\n }\n }\n\n return headers\n }\n\n async _req(query: RestQuery) {\n const {\n path = \"\",\n queryString = \"\",\n headers = {},\n method = \"GET\",\n disabledHeaders,\n bodyType,\n requestBody,\n authConfigId,\n pagination,\n paginationValues,\n } = query\n const authHeaders = this.getAuthHeaders(authConfigId)\n\n this.headers = {\n ...this.config.defaultHeaders,\n ...headers,\n ...authHeaders,\n }\n\n if (disabledHeaders) {\n for (let headerKey of Object.keys(this.headers)) {\n if (disabledHeaders[headerKey]) {\n delete this.headers[headerKey]\n }\n }\n }\n\n let input: any = { method, headers: this.headers }\n input = this.addBody(\n bodyType,\n requestBody,\n input,\n pagination,\n paginationValues\n )\n\n if (this.config.rejectUnauthorized == false) {\n input.agent = new https.Agent({\n rejectUnauthorized: false,\n })\n }\n\n // Deprecated by rejectUnauthorized\n if (this.config.legacyHttpParser) {\n // https://github.com/nodejs/node/issues/43798\n input.extraHttpOptions = { insecureHTTPParser: true }\n }\n\n this.startTimeMs = performance.now()\n const url = this.getUrl(path, queryString, pagination, paginationValues)\n if (await blacklist.isBlacklisted(url)) {\n throw new Error(\"Cannot connect to URL.\")\n }\n const response = await fetch(url, input)\n return await this.parseResponse(response, pagination)\n }\n\n async create(opts: RestQuery) {\n return this._req({ ...opts, method: \"POST\" })\n }\n\n async read(opts: RestQuery) {\n return this._req({ ...opts, method: \"GET\" })\n }\n\n async update(opts: RestQuery) {\n return this._req({ ...opts, method: \"PUT\" })\n }\n\n async patch(opts: RestQuery) {\n return this._req({ ...opts, method: \"PATCH\" })\n }\n\n async delete(opts: RestQuery) {\n return this._req({ ...opts, method: \"DELETE\" })\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: RestIntegration,\n}\n", "import {\n ConnectionInfo,\n DatasourceFeature,\n DatasourceFieldType,\n DatasourcePlus,\n FieldType,\n Integration,\n Operation,\n PaginationJson,\n QueryJson,\n QueryType,\n Row,\n SearchFilters,\n SortJson,\n Table,\n TableRequest,\n} from \"@budibase/types\"\nimport { OAuth2Client } from \"google-auth-library\"\nimport { buildExternalTableId, finaliseExternalTables } from \"./utils\"\nimport { GoogleSpreadsheet, GoogleSpreadsheetRow } from \"google-spreadsheet\"\nimport fetch from \"node-fetch\"\nimport { configs, HTTPError } from \"@budibase/backend-core\"\nimport { dataFilters } from \"@budibase/shared-core\"\nimport { GOOGLE_SHEETS_PRIMARY_KEY } from \"../constants\"\n\ninterface GoogleSheetsConfig {\n spreadsheetId: string\n auth: OAuthClientConfig\n}\n\ninterface OAuthClientConfig {\n appId: string\n accessToken: string\n refreshToken: string\n}\n\ninterface AuthTokenRequest {\n client_id: string\n client_secret: string\n refresh_token: string\n}\n\ninterface AuthTokenResponse {\n access_token: string\n}\n\nconst ALLOWED_TYPES = [\n FieldType.STRING,\n FieldType.FORMULA,\n FieldType.NUMBER,\n FieldType.LONGFORM,\n FieldType.DATETIME,\n FieldType.OPTIONS,\n FieldType.BOOLEAN,\n FieldType.BARCODEQR,\n]\n\nconst SCHEMA: Integration = {\n plus: true,\n auth: {\n type: \"google\",\n },\n relationships: false,\n docs: \"https://developers.google.com/sheets/api/quickstart/nodejs\",\n description:\n \"Create and collaborate on online spreadsheets in real-time and from any device.\",\n friendlyName: \"Google Sheets\",\n type: \"Spreadsheet\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n [DatasourceFeature.FETCH_TABLE_NAMES]: true,\n },\n datasource: {\n spreadsheetId: {\n display: \"Google Sheet URL\",\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n query: {\n create: {\n type: QueryType.FIELDS,\n fields: {\n sheet: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n row: {\n type: QueryType.JSON,\n required: true,\n },\n },\n },\n read: {\n type: QueryType.FIELDS,\n fields: {\n sheet: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n update: {\n type: QueryType.FIELDS,\n fields: {\n sheet: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n rowIndex: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n row: {\n type: QueryType.JSON,\n required: true,\n },\n },\n },\n delete: {\n type: QueryType.FIELDS,\n fields: {\n sheet: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n rowIndex: {\n type: DatasourceFieldType.NUMBER,\n required: true,\n },\n },\n },\n },\n}\n\nclass GoogleSheetsIntegration implements DatasourcePlus {\n private readonly config: GoogleSheetsConfig\n private client: GoogleSpreadsheet\n public tables: Record<string, Table> = {}\n public schemaErrors: Record<string, string> = {}\n\n constructor(config: GoogleSheetsConfig) {\n this.config = config\n const spreadsheetId = this.cleanSpreadsheetUrl(this.config.spreadsheetId)\n this.client = new GoogleSpreadsheet(spreadsheetId)\n }\n\n async testConnection(): Promise<ConnectionInfo> {\n try {\n await this.connect()\n return { connected: true }\n } catch (e: any) {\n return {\n connected: false,\n error: e.message as string,\n }\n }\n }\n\n getBindingIdentifier() {\n return \"\"\n }\n\n getStringConcat(parts: string[]) {\n return \"\"\n }\n\n /**\n * Pull the spreadsheet ID out from a valid google sheets URL\n * @param spreadsheetId - the URL or standard spreadsheetId of the google sheet\n * @returns spreadsheet Id of the google sheet\n */\n cleanSpreadsheetUrl(spreadsheetId: string) {\n if (!spreadsheetId) {\n throw new Error(\n \"You must set a spreadsheet ID in your configuration to fetch tables.\"\n )\n }\n const parts = spreadsheetId.split(\"/\")\n return parts.length > 5 ? parts[5] : spreadsheetId\n }\n\n async fetchAccessToken(\n payload: AuthTokenRequest\n ): Promise<AuthTokenResponse> {\n const response = await fetch(\"https://www.googleapis.com/oauth2/v4/token\", {\n method: \"POST\",\n body: JSON.stringify({\n ...payload,\n grant_type: \"refresh_token\",\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n })\n\n const json = await response.json()\n\n if (response.status !== 200) {\n throw new Error(\n `Error authenticating with google sheets. ${json.error_description}`\n )\n }\n\n return json\n }\n\n async connect() {\n try {\n // Initialise oAuth client\n let googleConfig = await configs.getGoogleDatasourceConfig()\n if (!googleConfig) {\n throw new HTTPError(\"Google config not found\", 400)\n }\n\n const oauthClient = new OAuth2Client({\n clientId: googleConfig.clientID,\n clientSecret: googleConfig.clientSecret,\n })\n\n const tokenResponse = await this.fetchAccessToken({\n client_id: googleConfig.clientID,\n client_secret: googleConfig.clientSecret,\n refresh_token: this.config.auth.refreshToken,\n })\n\n oauthClient.setCredentials({\n refresh_token: this.config.auth.refreshToken,\n access_token: tokenResponse.access_token,\n })\n\n this.client.useOAuth2Client(oauthClient)\n await this.client.loadInfo()\n } catch (err: any) {\n // this happens for xlsx imports\n if (err.message?.includes(\"operation is not supported\")) {\n err.message =\n \"This operation is not supported - XLSX sheets must be converted.\"\n }\n console.error(\"Error connecting to google sheets\", err)\n throw err\n }\n }\n\n async getTableNames(): Promise<string[]> {\n await this.connect()\n const sheets = this.client.sheetsByIndex\n return sheets.map(s => s.title)\n }\n\n getTableSchema(title: string, headerValues: string[], id?: string) {\n // base table\n const table: Table = {\n name: title,\n primary: [GOOGLE_SHEETS_PRIMARY_KEY],\n schema: {},\n }\n if (id) {\n table._id = id\n }\n // build schema from headers\n for (let header of headerValues) {\n table.schema[header] = {\n name: header,\n type: FieldType.STRING,\n }\n }\n return table\n }\n\n async buildSchema(datasourceId: string, entities: Record<string, Table>) {\n // not fully configured yet\n if (!this.config.auth) {\n return\n }\n await this.connect()\n const sheets = this.client.sheetsByIndex\n const tables: Record<string, Table> = {}\n for (let sheet of sheets) {\n // must fetch rows to determine schema\n await sheet.getRows()\n\n const id = buildExternalTableId(datasourceId, sheet.title)\n tables[sheet.title] = this.getTableSchema(\n sheet.title,\n sheet.headerValues,\n id\n )\n }\n const final = finaliseExternalTables(tables, entities)\n this.tables = final.tables\n this.schemaErrors = final.errors\n }\n\n async query(json: QueryJson) {\n const sheet = json.endpoint.entityId\n switch (json.endpoint.operation) {\n case Operation.CREATE:\n return this.create({ sheet, row: json.body as Row })\n case Operation.BULK_CREATE:\n return this.createBulk({ sheet, rows: json.body as Row[] })\n case Operation.READ:\n return this.read({ ...json, sheet })\n case Operation.UPDATE:\n return this.update({\n // exclude the header row and zero index\n rowIndex: json.extra?.idFilter?.equal?.rowNumber - 2,\n sheet,\n row: json.body,\n })\n case Operation.DELETE:\n return this.delete({\n // exclude the header row and zero index\n rowIndex: json.extra?.idFilter?.equal?.rowNumber - 2,\n sheet,\n })\n case Operation.CREATE_TABLE:\n return this.createTable(json?.table?.name)\n case Operation.UPDATE_TABLE:\n return this.updateTable(json.table!)\n case Operation.DELETE_TABLE:\n return this.deleteTable(json?.table?.name)\n default:\n throw new Error(\n `GSheets integration does not support \"${json.endpoint.operation}\".`\n )\n }\n }\n\n buildRowObject(headers: string[], values: string[], rowNumber: number) {\n const rowObject: { rowNumber: number; [key: string]: any } = { rowNumber }\n for (let i = 0; i < headers.length; i++) {\n rowObject._id = rowNumber\n rowObject[headers[i]] = values[i]\n }\n return rowObject\n }\n\n async createTable(name?: string) {\n if (!name) {\n throw new Error(\"Must provide name for new sheet.\")\n }\n try {\n await this.connect()\n return await this.client.addSheet({ title: name, headerValues: [name] })\n } catch (err) {\n console.error(\"Error creating new table in google sheets\", err)\n throw err\n }\n }\n\n async updateTable(table: TableRequest) {\n await this.connect()\n const sheet = this.client.sheetsByTitle[table.name]\n await sheet.loadHeaderRow()\n\n if (table._rename) {\n const headers = []\n for (let header of sheet.headerValues) {\n if (header === table._rename.old) {\n headers.push(table._rename.updated)\n } else {\n headers.push(header)\n }\n }\n try {\n await sheet.setHeaderRow(headers)\n } catch (err) {\n console.error(\"Error updating column name in google sheets\", err)\n throw err\n }\n } else {\n const updatedHeaderValues = [...sheet.headerValues]\n\n // add new column - doesn't currently exist\n for (let [key, column] of Object.entries(table.schema)) {\n if (!ALLOWED_TYPES.includes(column.type)) {\n throw new Error(\n `Column type: ${column.type} not allowed for GSheets integration.`\n )\n }\n if (\n !sheet.headerValues.includes(key) &&\n column.type !== FieldType.FORMULA\n ) {\n updatedHeaderValues.push(key)\n }\n }\n\n // clear out deleted columns\n for (let key of sheet.headerValues) {\n if (!Object.keys(table.schema).includes(key)) {\n const idx = updatedHeaderValues.indexOf(key)\n updatedHeaderValues.splice(idx, 1)\n }\n }\n\n try {\n await sheet.setHeaderRow(updatedHeaderValues)\n } catch (err) {\n console.error(\"Error updating table in google sheets\", err)\n throw err\n }\n }\n }\n\n async deleteTable(sheet: any) {\n try {\n await this.connect()\n const sheetToDelete = this.client.sheetsByTitle[sheet]\n return await sheetToDelete.delete()\n } catch (err) {\n console.error(\"Error deleting table in google sheets\", err)\n throw err\n }\n }\n\n async create(query: { sheet: string; row: any }) {\n try {\n await this.connect()\n const sheet = this.client.sheetsByTitle[query.sheet]\n const rowToInsert =\n typeof query.row === \"string\" ? JSON.parse(query.row) : query.row\n const row = await sheet.addRow(rowToInsert)\n return [\n this.buildRowObject(sheet.headerValues, row._rawData, row._rowNumber),\n ]\n } catch (err) {\n console.error(\"Error writing to google sheets\", err)\n throw err\n }\n }\n\n async createBulk(query: { sheet: string; rows: any[] }) {\n try {\n await this.connect()\n const sheet = this.client.sheetsByTitle[query.sheet]\n let rowsToInsert = []\n for (let row of query.rows) {\n rowsToInsert.push(typeof row === \"string\" ? JSON.parse(row) : row)\n }\n const rows = await sheet.addRows(rowsToInsert)\n return rows.map(row =>\n this.buildRowObject(sheet.headerValues, row._rawData, row._rowNumber)\n )\n } catch (err) {\n console.error(\"Error bulk writing to google sheets\", err)\n throw err\n }\n }\n\n async read(query: {\n sheet: string\n filters?: SearchFilters\n sort?: SortJson\n paginate?: PaginationJson\n }) {\n try {\n await this.connect()\n const sheet = this.client.sheetsByTitle[query.sheet]\n let rows: GoogleSpreadsheetRow[] = []\n if (query.paginate) {\n const limit = query.paginate.limit || 100\n let page: number =\n typeof query.paginate.page === \"number\"\n ? query.paginate.page\n : parseInt(query.paginate.page || \"1\")\n rows = await sheet.getRows({\n limit,\n offset: (page - 1) * limit,\n })\n } else {\n rows = await sheet.getRows()\n }\n const filtered = dataFilters.runLuceneQuery(rows, query.filters)\n const headerValues = sheet.headerValues\n let response = []\n for (let row of filtered) {\n response.push(\n this.buildRowObject(headerValues, row._rawData, row._rowNumber)\n )\n }\n\n if (query.sort) {\n if (Object.keys(query.sort).length !== 1) {\n console.warn(\"Googlesheets does not support multiple sorting\", {\n sortInfo: query.sort,\n })\n }\n const [sortField, sortInfo] = Object.entries(query.sort)[0]\n response = dataFilters.luceneSort(\n response,\n sortField,\n sortInfo.direction,\n sortInfo.type\n )\n }\n\n return response\n } catch (err) {\n console.error(\"Error reading from google sheets\", err)\n throw err\n }\n }\n\n async update(query: { sheet: string; rowIndex: number; row: any }) {\n try {\n await this.connect()\n const sheet = this.client.sheetsByTitle[query.sheet]\n const rows = await sheet.getRows()\n const row = rows[query.rowIndex]\n if (row) {\n const updateValues =\n typeof query.row === \"string\" ? JSON.parse(query.row) : query.row\n for (let key in updateValues) {\n row[key] = updateValues[key]\n }\n await row.save()\n return [\n this.buildRowObject(sheet.headerValues, row._rawData, row._rowNumber),\n ]\n } else {\n throw new Error(\"Row does not exist.\")\n }\n } catch (err) {\n console.error(\"Error reading from google sheets\", err)\n throw err\n }\n }\n\n async delete(query: { sheet: string; rowIndex: number }) {\n await this.connect()\n const sheet = this.client.sheetsByTitle[query.sheet]\n const rows = await sheet.getRows()\n const row = rows[query.rowIndex]\n if (row) {\n await row.delete()\n return [{ deleted: query.rowIndex }]\n } else {\n throw new Error(\"Row does not exist.\")\n }\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: GoogleSheetsIntegration,\n}\n", "export const OperatorOptions = {\n Equals: {\n value: \"equal\",\n label: \"Equals\",\n },\n NotEquals: {\n value: \"notEqual\",\n label: \"Not equals\",\n },\n Empty: {\n value: \"empty\",\n label: \"Is empty\",\n },\n NotEmpty: {\n value: \"notEmpty\",\n label: \"Is not empty\",\n },\n StartsWith: {\n value: \"string\",\n label: \"Starts with\",\n },\n Like: {\n value: \"fuzzy\",\n label: \"Like\",\n },\n MoreThan: {\n value: \"rangeLow\",\n label: \"More than or equal to\",\n },\n LessThan: {\n value: \"rangeHigh\",\n label: \"Less than or equal to\",\n },\n Contains: {\n value: \"contains\",\n label: \"Contains\",\n },\n NotContains: {\n value: \"notContains\",\n label: \"Does not contain\",\n },\n In: {\n value: \"oneOf\",\n label: \"Is in\",\n },\n ContainsAny: {\n value: \"containsAny\",\n label: \"Has any\",\n },\n}\n\nexport const SqlNumberTypeRangeMap = {\n integer: {\n max: 2147483647,\n min: -2147483648,\n },\n int: {\n max: 2147483647,\n min: -2147483648,\n },\n smallint: {\n max: 32767,\n min: -32768,\n },\n mediumint: {\n max: 8388607,\n min: -8388608,\n },\n}\n\nexport enum SocketEvent {\n UserUpdate = \"UserUpdate\",\n UserDisconnect = \"UserDisconnect\",\n Heartbeat = \"Heartbeat\",\n}\n\nexport enum GridSocketEvent {\n RowChange = \"RowChange\",\n TableChange = \"TableChange\",\n SelectTable = \"SelectTable\",\n SelectCell = \"SelectCell\",\n}\n\nexport enum BuilderSocketEvent {\n SelectApp = \"SelectApp\",\n TableChange = \"TableChange\",\n DatasourceChange = \"DatasourceChange\",\n}\n\nexport const SocketSessionTTL = 60\n", "import { Datasource, FieldType, SortDirection, SortType } from \"@budibase/types\"\nimport { OperatorOptions, SqlNumberTypeRangeMap } from \"./constants\"\nimport { deepGet } from \"./helpers\"\n\nconst HBS_REGEX = /{{([^{].*?)}}/g\n\n/**\n * Returns the valid operator options for a certain data type\n * @param type the data type\n */\nexport const getValidOperatorsForType = (\n type: FieldType,\n field: string,\n datasource: Datasource & { tableId: any } // TODO: is this table id ever populated?\n) => {\n const Op = OperatorOptions\n const stringOps = [\n Op.Equals,\n Op.NotEquals,\n Op.StartsWith,\n Op.Like,\n Op.Empty,\n Op.NotEmpty,\n Op.In,\n ]\n const numOps = [\n Op.Equals,\n Op.NotEquals,\n Op.MoreThan,\n Op.LessThan,\n Op.Empty,\n Op.NotEmpty,\n Op.In,\n ]\n let ops: {\n value: string\n label: string\n }[] = []\n if (type === \"string\") {\n ops = stringOps\n } else if (type === \"number\") {\n ops = numOps\n } else if (type === \"options\") {\n ops = [Op.Equals, Op.NotEquals, Op.Empty, Op.NotEmpty, Op.In]\n } else if (type === \"array\") {\n ops = [Op.Contains, Op.NotContains, Op.Empty, Op.NotEmpty, Op.ContainsAny]\n } else if (type === \"boolean\") {\n ops = [Op.Equals, Op.NotEquals, Op.Empty, Op.NotEmpty]\n } else if (type === \"longform\") {\n ops = stringOps\n } else if (type === \"datetime\") {\n ops = numOps\n } else if (type === \"formula\") {\n ops = stringOps.concat([Op.MoreThan, Op.LessThan])\n }\n\n // Only allow equal/not equal for _id in SQL tables\n const externalTable = datasource?.tableId?.includes(\"datasource_plus\")\n if (field === \"_id\" && externalTable) {\n ops = [Op.Equals, Op.NotEquals, Op.In]\n }\n\n return ops\n}\n\n/**\n * Operators which do not support empty strings as values\n */\nexport const NoEmptyFilterStrings = [\n OperatorOptions.StartsWith.value,\n OperatorOptions.Like.value,\n OperatorOptions.Equals.value,\n OperatorOptions.NotEquals.value,\n OperatorOptions.Contains.value,\n OperatorOptions.NotContains.value,\n] as (keyof QueryFields)[]\n\n/**\n * Removes any fields that contain empty strings that would cause inconsistent\n * behaviour with how backend tables are filtered (no value means no filter).\n */\nconst cleanupQuery = (query: Query) => {\n if (!query) {\n return query\n }\n for (let filterField of NoEmptyFilterStrings) {\n if (!query[filterField]) {\n continue\n }\n\n for (let [key, value] of Object.entries(query[filterField]!)) {\n if (value == null || value === \"\") {\n delete query[filterField]![key]\n }\n }\n }\n return query\n}\n\n/**\n * Removes a numeric prefix on field names designed to give fields uniqueness\n */\nconst removeKeyNumbering = (key: string) => {\n if (typeof key === \"string\" && key.match(/\\d[0-9]*:/g) != null) {\n const parts = key.split(\":\")\n parts.shift()\n return parts.join(\":\")\n } else {\n return key\n }\n}\n\ntype Filter = {\n operator: keyof Query\n field: string\n type: any\n value: any\n externalType: keyof typeof SqlNumberTypeRangeMap\n}\n\ntype Query = QueryFields & QueryConfig\ntype QueryFields = {\n string?: {\n [key: string]: string\n }\n fuzzy?: {\n [key: string]: string\n }\n range?: {\n [key: string]: {\n high: number | string\n low: number | string\n }\n }\n equal?: {\n [key: string]: any\n }\n notEqual?: {\n [key: string]: any\n }\n empty?: {\n [key: string]: any\n }\n notEmpty?: {\n [key: string]: any\n }\n oneOf?: {\n [key: string]: any[]\n }\n contains?: {\n [key: string]: any[]\n }\n notContains?: {\n [key: string]: any[]\n }\n containsAny?: {\n [key: string]: any[]\n }\n}\n\ntype QueryConfig = {\n allOr?: boolean\n}\n\ntype QueryFieldsType = keyof QueryFields\n\n/**\n * Builds a lucene JSON query from the filter structure generated in the builder\n * @param filter the builder filter structure\n */\nexport const buildLuceneQuery = (filter: Filter[]) => {\n let query: Query = {\n string: {},\n fuzzy: {},\n range: {},\n equal: {},\n notEqual: {},\n empty: {},\n notEmpty: {},\n contains: {},\n notContains: {},\n oneOf: {},\n containsAny: {},\n }\n if (Array.isArray(filter)) {\n filter.forEach(expression => {\n let { operator, field, type, value, externalType } = expression\n const isHbs =\n typeof value === \"string\" && (value.match(HBS_REGEX) || []).length > 0\n // Parse all values into correct types\n if (operator === \"allOr\") {\n query.allOr = true\n return\n }\n if (\n type === \"datetime\" &&\n !isHbs &&\n operator !== \"empty\" &&\n operator !== \"notEmpty\"\n ) {\n // Ensure date value is a valid date and parse into correct format\n if (!value) {\n return\n }\n try {\n value = new Date(value).toISOString()\n } catch (error) {\n return\n }\n }\n if (type === \"number\" && typeof value === \"string\") {\n if (operator === \"oneOf\") {\n value = value.split(\",\").map(item => parseFloat(item))\n } else if (!isHbs) {\n value = parseFloat(value)\n }\n }\n if (type === \"boolean\") {\n value = `${value}`?.toLowerCase() === \"true\"\n }\n if (\n [\"contains\", \"notContains\", \"containsAny\"].includes(operator) &&\n type === \"array\" &&\n typeof value === \"string\"\n ) {\n value = value.split(\",\")\n }\n if (operator.startsWith(\"range\") && query.range) {\n const minint =\n SqlNumberTypeRangeMap[externalType]?.min || Number.MIN_SAFE_INTEGER\n const maxint =\n SqlNumberTypeRangeMap[externalType]?.max || Number.MAX_SAFE_INTEGER\n if (!query.range[field]) {\n query.range[field] = {\n low: type === \"number\" ? minint : \"0000-00-00T00:00:00.000Z\",\n high: type === \"number\" ? maxint : \"9999-00-00T00:00:00.000Z\",\n }\n }\n if ((operator as any) === \"rangeLow\" && value != null && value !== \"\") {\n query.range[field].low = value\n } else if (\n (operator as any) === \"rangeHigh\" &&\n value != null &&\n value !== \"\"\n ) {\n query.range[field].high = value\n }\n } else if (query[operator]) {\n if (type === \"boolean\") {\n // Transform boolean filters to cope with null.\n // \"equals false\" needs to be \"not equals true\"\n // \"not equals false\" needs to be \"equals true\"\n if (operator === \"equal\" && value === false) {\n query.notEqual = query.notEqual || {}\n query.notEqual[field] = true\n } else if (operator === \"notEqual\" && value === false) {\n query.equal = query.equal || {}\n query.equal[field] = true\n } else {\n query[operator] = query[operator] || {}\n query[operator]![field] = value\n }\n } else {\n query[operator] = query[operator] || {}\n query[operator]![field] = value\n }\n }\n })\n }\n return query\n}\n\n/**\n * Performs a client-side lucene search on an array of data\n * @param docs the data\n * @param query the JSON lucene query\n */\nexport const runLuceneQuery = (docs: any[], query?: Query) => {\n if (!docs || !Array.isArray(docs)) {\n return []\n }\n if (!query) {\n return docs\n }\n\n // Make query consistent first\n query = cleanupQuery(query)\n\n // Iterates over a set of filters and evaluates a fail function against a doc\n const match =\n (\n type: QueryFieldsType,\n failFn: (docValue: any, testValue: any) => boolean\n ) =>\n (doc: any) => {\n const filters = Object.entries(query![type] || {})\n for (let i = 0; i < filters.length; i++) {\n const [key, testValue] = filters[i]\n const docValue = deepGet(doc, removeKeyNumbering(key))\n if (failFn(docValue, testValue)) {\n return false\n }\n }\n return true\n }\n\n // Process a string match (fails if the value does not start with the string)\n const stringMatch = match(\"string\", (docValue: string, testValue: string) => {\n return (\n !docValue || !docValue?.toLowerCase().startsWith(testValue?.toLowerCase())\n )\n })\n\n // Process a fuzzy match (treat the same as starts with when running locally)\n const fuzzyMatch = match(\"fuzzy\", (docValue: string, testValue: string) => {\n return (\n !docValue || !docValue?.toLowerCase().startsWith(testValue?.toLowerCase())\n )\n })\n\n // Process a range match\n const rangeMatch = match(\n \"range\",\n (\n docValue: string | number | null,\n testValue: { low: number; high: number }\n ) => {\n return (\n docValue == null ||\n docValue === \"\" ||\n +docValue < testValue.low ||\n +docValue > testValue.high\n )\n }\n )\n\n // Process an equal match (fails if the value is different)\n const equalMatch = match(\n \"equal\",\n (docValue: any, testValue: string | null) => {\n return testValue != null && testValue !== \"\" && docValue !== testValue\n }\n )\n\n // Process a not-equal match (fails if the value is the same)\n const notEqualMatch = match(\n \"notEqual\",\n (docValue: any, testValue: string | null) => {\n return testValue != null && testValue !== \"\" && docValue === testValue\n }\n )\n\n // Process an empty match (fails if the value is not empty)\n const emptyMatch = match(\"empty\", (docValue: string | null) => {\n return docValue != null && docValue !== \"\"\n })\n\n // Process a not-empty match (fails is the value is empty)\n const notEmptyMatch = match(\"notEmpty\", (docValue: string | null) => {\n return docValue == null || docValue === \"\"\n })\n\n // Process an includes match (fails if the value is not included)\n const oneOf = match(\"oneOf\", (docValue: any, testValue: any) => {\n if (typeof testValue === \"string\") {\n testValue = testValue.split(\",\")\n if (typeof docValue === \"number\") {\n testValue = testValue.map((item: string) => parseFloat(item))\n }\n }\n return !testValue?.includes(docValue)\n })\n\n const containsAny = match(\"containsAny\", (docValue: any, testValue: any) => {\n return !docValue?.includes(...testValue)\n })\n\n const contains = match(\n \"contains\",\n (docValue: string | any[], testValue: any[]) => {\n return !testValue?.every((item: any) => docValue?.includes(item))\n }\n )\n\n const notContains = match(\n \"notContains\",\n (docValue: string | any[], testValue: any[]) => {\n return testValue?.every((item: any) => docValue?.includes(item))\n }\n )\n\n // Match a document against all criteria\n const docMatch = (doc: any) => {\n return (\n stringMatch(doc) &&\n fuzzyMatch(doc) &&\n rangeMatch(doc) &&\n equalMatch(doc) &&\n notEqualMatch(doc) &&\n emptyMatch(doc) &&\n notEmptyMatch(doc) &&\n oneOf(doc) &&\n contains(doc) &&\n containsAny(doc) &&\n notContains(doc)\n )\n }\n\n // Process all docs\n return docs.filter(docMatch)\n}\n\n/**\n * Performs a client-side sort from the equivalent server-side lucene sort\n * parameters.\n * @param docs the data\n * @param sort the sort column\n * @param sortOrder the sort order (\"ascending\" or \"descending\")\n * @param sortType the type of sort (\"string\" or \"number\")\n */\nexport const luceneSort = (\n docs: any[],\n sort: string,\n sortOrder: SortDirection,\n sortType = SortType.STRING\n) => {\n if (!sort || !sortOrder || !sortType) {\n return docs\n }\n const parse =\n sortType === \"string\" ? (x: any) => `${x}` : (x: string) => parseFloat(x)\n return docs\n .slice()\n .sort((a: { [x: string]: any }, b: { [x: string]: any }) => {\n const colA = parse(a[sort])\n const colB = parse(b[sort])\n if (sortOrder.toLowerCase() === \"descending\") {\n return colA > colB ? -1 : 1\n } else {\n return colA > colB ? 1 : -1\n }\n })\n}\n\n/**\n * Limits the specified docs to the specified number of rows from the equivalent\n * server-side lucene limit parameters.\n * @param docs the data\n * @param limit the number of docs to limit to\n */\nexport const luceneLimit = (docs: any[], limit: string) => {\n const numLimit = parseFloat(limit)\n if (isNaN(numLimit)) {\n return docs\n }\n return docs.slice(0, numLimit)\n}\n", "import { User } from \"@budibase/types\"\n\n/**\n * Gets a key within an object. The key supports dot syntax for retrieving deep\n * fields - e.g. \"a.b.c\".\n * Exact matches of keys with dots in them take precedence over nested keys of\n * the same path - e.g. getting \"a.b\" from { \"a.b\": \"foo\", a: { b: \"bar\" } }\n * will return \"foo\" over \"bar\".\n * @param obj the object\n * @param key the key\n * @return {*|null} the value or null if a value was not found for this key\n */\nexport const deepGet = (obj: { [x: string]: any }, key: string) => {\n if (!obj || !key) {\n return null\n }\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n return obj[key]\n }\n const split = key.split(\".\")\n for (let i = 0; i < split.length; i++) {\n obj = obj?.[split[i]]\n }\n return obj\n}\n\n/**\n * Gets the initials to show in a user avatar.\n * @param user the user\n */\nexport const getUserInitials = (user: User) => {\n if (!user) {\n return \"?\"\n }\n let initials = \"\"\n initials += user.firstName ? user.firstName[0] : \"\"\n initials += user.lastName ? user.lastName[0] : \"\"\n return initials === \"\" ? user.email[0] : initials\n}\n\n/**\n * Gets a deterministic colour for a particular user\n * @param user the user\n */\nexport const getUserColor = (user: User) => {\n let id = user?._id\n if (!id) {\n return \"var(--spectrum-global-color-blue-400)\"\n }\n\n // In order to generate the same color for global users as app users, we need\n // to remove the app-specific table prefix\n id = id.replace(\"ro_ta_users_\", \"\")\n\n // Generate a hue based on the ID\n let hue = 1\n for (let i = 0; i < id.length; i++) {\n hue += id.charCodeAt(i)\n hue = hue % 36\n }\n return `hsl(${hue * 10}, 50%, 40%)`\n}\n\n/**\n * Gets a friendly label to describe who a user is.\n * @param user the user\n */\nexport const getUserLabel = (user: User) => {\n if (!user) {\n return \"\"\n }\n const { firstName, lastName, email } = user\n if (firstName && lastName) {\n return `${firstName} ${lastName}`\n } else if (firstName) {\n return firstName\n } else if (lastName) {\n return lastName\n } else {\n return email\n }\n}\n", "import { SourceName } from \"@budibase/types\"\n\nexport function isGoogleSheets(type: SourceName) {\n return type === SourceName.GOOGLE_SHEETS\n}\n", "export function unreachable(\n value: never,\n message = `No such case in exhaustive switch: ${value}`\n) {\n throw new Error(message)\n}\n", "import {\n DatasourceFieldType,\n Integration,\n QueryType,\n IntegrationBase,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\nimport { Firestore, WhereFilterOp } from \"@google-cloud/firestore\"\n\ninterface FirebaseConfig {\n email: string\n privateKey: string\n projectId: string\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://firebase.google.com/docs/firestore/quickstart\",\n friendlyName: \"Firestore\",\n type: \"Non-relational\",\n description:\n \"Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud.\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n email: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n privateKey: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n projectId: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n query: {\n create: {\n type: QueryType.JSON,\n },\n read: {\n type: QueryType.JSON,\n },\n update: {\n type: QueryType.JSON,\n },\n delete: {\n type: QueryType.JSON,\n },\n },\n extra: {\n collection: {\n displayName: \"Collection\",\n type: DatasourceFieldType.STRING,\n required: true,\n },\n filterField: {\n displayName: \"Filter field\",\n type: DatasourceFieldType.STRING,\n required: false,\n },\n filter: {\n displayName: \"Filter comparison\",\n type: DatasourceFieldType.LIST,\n required: false,\n data: {\n read: [\n \"==\",\n \"<\",\n \"<=\",\n \"!=\",\n \">=\",\n \">\",\n \"array-contains\",\n \"in\",\n \"not-in\",\n \"array-contains-any\",\n ],\n },\n },\n filterValue: {\n displayName: \"Filter value\",\n type: DatasourceFieldType.STRING,\n required: false,\n },\n },\n}\n\nclass FirebaseIntegration implements IntegrationBase {\n private config: FirebaseConfig\n private client: Firestore\n\n constructor(config: FirebaseConfig) {\n this.config = config\n this.client = new Firestore({\n projectId: config.projectId,\n credentials: {\n client_email: config.email,\n private_key: config.privateKey?.replace(/\\\\n/g, \"\\n\"),\n },\n })\n }\n\n async testConnection(): Promise<ConnectionInfo> {\n try {\n await this.client.listCollections()\n return { connected: true }\n } catch (e: any) {\n return {\n connected: false,\n error: e.message as string,\n }\n }\n }\n\n async create(query: { json: object; extra: { [key: string]: string } }) {\n try {\n const documentReference = this.client\n .collection(query.extra.collection)\n .doc()\n await documentReference.set({ ...query.json, id: documentReference.id })\n const snapshot = await documentReference.get()\n return snapshot.data()\n } catch (err) {\n console.error(\"Error writing to Firestore\", err)\n throw err\n }\n }\n\n async read(query: { json: object; extra: { [key: string]: string } }) {\n try {\n let snapshot\n const collectionRef = this.client.collection(query.extra.collection)\n if (\n query.extra.filterField &&\n query.extra.filter &&\n query.extra.filterValue\n ) {\n snapshot = await collectionRef\n .where(\n query.extra.filterField,\n query.extra.filter as WhereFilterOp,\n query.extra.filterValue\n )\n .get()\n } else {\n snapshot = await collectionRef.get()\n }\n const result: any[] = []\n snapshot.forEach(doc => result.push(doc.data()))\n\n return result\n } catch (err) {\n console.error(\"Error querying Firestore\", err)\n throw err\n }\n }\n\n async update(query: {\n json: Record<string, any>\n extra: { [key: string]: string }\n }) {\n try {\n await this.client\n .collection(query.extra.collection)\n .doc(query.json.id)\n .update(query.json)\n\n return (\n await this.client\n .collection(query.extra.collection)\n .doc(query.json.id)\n .get()\n ).data()\n } catch (err) {\n console.error(\"Error writing to Firestore\", err)\n throw err\n }\n }\n\n async delete(query: {\n json: { id: string }\n extra: { [key: string]: string }\n }) {\n try {\n await this.client\n .collection(query.extra.collection)\n .doc(query.json.id)\n .delete()\n return true\n } catch (err) {\n console.error(\"Error deleting from Firestore\", err)\n throw err\n }\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: FirebaseIntegration,\n}\n", "import {\n ConnectionInfo,\n DatasourceFeature,\n DatasourceFieldType,\n Integration,\n QueryType,\n} from \"@budibase/types\"\nimport Redis from \"ioredis\"\n\ninterface RedisConfig {\n host: string\n port: number\n username: string\n password?: string\n db?: number\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://redis.io/docs/\",\n description:\n \"Redis is a caching tool, providing powerful key-value store capabilities.\",\n friendlyName: \"Redis\",\n type: \"Non-relational\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n host: {\n type: \"string\",\n required: true,\n default: \"localhost\",\n },\n port: {\n type: \"number\",\n required: true,\n default: 6379,\n },\n username: {\n type: \"string\",\n required: false,\n },\n password: {\n type: \"password\",\n required: false,\n },\n db: {\n type: \"number\",\n required: false,\n display: \"DB\",\n default: 0,\n },\n },\n query: {\n create: {\n type: QueryType.FIELDS,\n fields: {\n key: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n value: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n ttl: {\n type: DatasourceFieldType.NUMBER,\n },\n },\n },\n read: {\n readable: true,\n type: QueryType.FIELDS,\n fields: {\n key: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n delete: {\n type: QueryType.FIELDS,\n fields: {\n key: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n command: {\n readable: true,\n displayName: \"Redis Command\",\n type: QueryType.JSON,\n },\n },\n}\n\nclass RedisIntegration {\n private readonly config: RedisConfig\n private client\n\n constructor(config: RedisConfig) {\n this.config = config\n this.client = new Redis({\n host: this.config.host,\n port: this.config.port,\n username: this.config.username,\n password: this.config.password,\n db: this.config.db,\n })\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n try {\n await this.client.ping()\n response.connected = true\n } catch (e: any) {\n response.error = e.message as string\n } finally {\n await this.disconnect()\n }\n return response\n }\n\n async disconnect() {\n return this.client.quit()\n }\n\n async redisContext(query: Function) {\n try {\n return await query()\n } catch (err) {\n throw new Error(`Redis error: ${err}`)\n } finally {\n await this.disconnect()\n }\n }\n\n async create(query: { key: string; value: string; ttl: number }) {\n return this.redisContext(async () => {\n const response = await this.client.set(query.key, query.value)\n if (query.ttl) {\n await this.client.expire(query.key, query.ttl)\n }\n return response\n })\n }\n\n async read(query: { key: string }) {\n return this.redisContext(async () => {\n return await this.client.get(query.key)\n })\n }\n\n async delete(query: { key: string }) {\n return this.redisContext(async () => {\n return await this.client.del(query.key)\n })\n }\n\n async command(query: { json: string }) {\n return this.redisContext(async () => {\n // commands split line by line\n const commands = query.json.trim().split(\"\\n\")\n let pipelineCommands = []\n\n // process each command separately\n for (let command of commands) {\n const tokenised = command.trim().split(\" \")\n // Pipeline only accepts lower case commands\n tokenised[0] = tokenised[0].toLowerCase()\n pipelineCommands.push(tokenised)\n }\n\n const pipeline = this.client.pipeline(pipelineCommands)\n const result = await pipeline.exec()\n\n return result.map((output: string | string[]) => output[1])\n })\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: RedisIntegration,\n}\n", "import {\n ConnectionInfo,\n DatasourceFeature,\n Integration,\n QueryType,\n SqlQuery,\n} from \"@budibase/types\"\nimport { Snowflake } from \"snowflake-promise\"\n\ninterface SnowflakeConfig {\n account: string\n username: string\n password: string\n warehouse: string\n database: string\n schema: string\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://developers.snowflake.com/\",\n description:\n \"Snowflake is a solution for data warehousing, data lakes, data engineering, data science, data application development, and securely sharing and consuming shared data.\",\n friendlyName: \"Snowflake\",\n type: \"Relational\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n account: {\n type: \"string\",\n required: true,\n },\n username: {\n type: \"string\",\n required: true,\n },\n password: {\n type: \"password\",\n required: true,\n },\n warehouse: {\n type: \"string\",\n required: true,\n },\n database: {\n type: \"string\",\n required: true,\n },\n schema: {\n type: \"string\",\n required: true,\n },\n },\n query: {\n create: {\n type: QueryType.SQL,\n },\n read: {\n type: QueryType.SQL,\n },\n update: {\n type: QueryType.SQL,\n },\n delete: {\n type: QueryType.SQL,\n },\n },\n}\n\nclass SnowflakeIntegration {\n private client: Snowflake\n\n constructor(config: SnowflakeConfig) {\n this.client = new Snowflake(config)\n }\n\n async testConnection(): Promise<ConnectionInfo> {\n try {\n await this.client.connect()\n return { connected: true }\n } catch (e: any) {\n return {\n connected: false,\n error: e.message as string,\n }\n }\n }\n\n async internalQuery(query: SqlQuery) {\n await this.client.connect()\n try {\n return await this.client.execute(query.sql)\n } catch (err: any) {\n throw err?.message.split(\":\")[1] || err?.message\n }\n }\n\n async create(query: SqlQuery) {\n return this.internalQuery(query)\n }\n\n async read(query: SqlQuery) {\n return this.internalQuery(query)\n }\n\n async update(query: SqlQuery) {\n return this.internalQuery(query)\n }\n\n async delete(query: SqlQuery) {\n return this.internalQuery(query)\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: SnowflakeIntegration,\n}\n", "import {\n DatasourceFieldType,\n Integration,\n Operation,\n QueryJson,\n QueryType,\n SqlQuery,\n Table,\n DatasourcePlus,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\nimport {\n buildExternalTableId,\n convertSqlType,\n finaliseExternalTables,\n getSqlQuery,\n SqlClient,\n} from \"./utils\"\nimport Sql from \"./base/sql\"\nimport { FieldTypes } from \"../constants\"\nimport {\n BindParameters,\n Connection,\n ConnectionAttributes,\n ExecuteOptions,\n Result,\n} from \"oracledb\"\nimport { OracleTable, OracleColumn, OracleColumnsResponse } from \"./base/types\"\nlet oracledb: any\ntry {\n oracledb = require(\"oracledb\")\n oracledb.outFormat = oracledb.OUT_FORMAT_OBJECT\n} catch (err) {\n console.log(\"ORACLEDB is not installed\")\n}\n\ninterface OracleConfig {\n host: string\n port: number\n database: string\n user: string\n password: string\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://github.com/oracle/node-oracledb\",\n plus: true,\n friendlyName: \"Oracle\",\n type: \"Relational\",\n description:\n \"Oracle Database is an object-relational database management system developed by Oracle Corporation\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n [DatasourceFeature.FETCH_TABLE_NAMES]: true,\n },\n datasource: {\n host: {\n type: DatasourceFieldType.STRING,\n default: \"localhost\",\n required: true,\n },\n port: {\n type: DatasourceFieldType.NUMBER,\n required: true,\n default: 1521,\n },\n database: {\n type: DatasourceFieldType.STRING,\n required: true,\n display: \"Service Name\",\n },\n user: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n password: {\n type: DatasourceFieldType.PASSWORD,\n required: true,\n },\n },\n query: {\n create: {\n type: QueryType.SQL,\n },\n read: {\n type: QueryType.SQL,\n },\n update: {\n type: QueryType.SQL,\n },\n delete: {\n type: QueryType.SQL,\n },\n },\n}\n\nconst UNSUPPORTED_TYPES = [\"BLOB\", \"CLOB\", \"NCLOB\"]\n\nconst OracleContraintTypes = {\n PRIMARY: \"P\",\n NOT_NULL_OR_CHECK: \"C\",\n FOREIGN_KEY: \"R\",\n UNIQUE: \"U\",\n}\n\nclass OracleIntegration extends Sql implements DatasourcePlus {\n private readonly config: OracleConfig\n private index: number = 1\n\n public tables: Record<string, Table> = {}\n public schemaErrors: Record<string, string> = {}\n\n private readonly COLUMNS_SQL = `\n SELECT\n tabs.table_name,\n cols.column_name,\n cols.data_type,\n cols.data_default,\n cols.column_id,\n cons.constraint_name,\n cons.constraint_type,\n cons.r_constraint_name,\n cons.search_condition\n FROM\n user_tables tabs\n JOIN \n user_tab_columns cols\n ON tabs.table_name = cols.table_name \n LEFT JOIN \n user_cons_columns col_cons\n ON cols.column_name = col_cons.column_name\n AND cols.table_name = col_cons.table_name\n LEFT JOIN \n user_constraints cons\n ON col_cons.constraint_name = cons.constraint_name\n AND cons.table_name = cols.table_name\n WHERE\n (cons.status = 'ENABLED'\n OR cons.status IS NULL)\n `\n constructor(config: OracleConfig) {\n super(SqlClient.ORACLE)\n this.config = config\n }\n\n getBindingIdentifier(): string {\n return `:${this.index++}`\n }\n\n getStringConcat(parts: string[]): string {\n return parts.join(\" || \")\n }\n\n static isInstalled() {\n return oracledb != null\n }\n\n /**\n * Map the flat tabular columns and constraints data into a nested object\n */\n private mapColumns(result: Result<OracleColumnsResponse>): {\n [key: string]: OracleTable\n } {\n const oracleTables: { [key: string]: OracleTable } = {}\n\n if (result.rows) {\n result.rows.forEach(row => {\n const tableName = row.TABLE_NAME\n const columnName = row.COLUMN_NAME\n const dataType = row.DATA_TYPE\n const dataDefault = row.DATA_DEFAULT\n const columnId = row.COLUMN_ID\n const constraintName = row.CONSTRAINT_NAME\n const constraintType = row.CONSTRAINT_TYPE\n const relatedConstraintName = row.R_CONSTRAINT_NAME\n const searchCondition = row.SEARCH_CONDITION\n\n let table = oracleTables[tableName]\n if (!table) {\n table = {\n name: tableName,\n columns: {},\n }\n oracleTables[tableName] = table\n }\n\n let column = table.columns[columnName]\n if (!column) {\n column = {\n name: columnName,\n type: dataType,\n default: dataDefault,\n id: columnId,\n constraints: {},\n }\n table.columns[columnName] = column\n }\n\n if (constraintName && constraintType) {\n let constraint = column.constraints[constraintName]\n if (!constraint) {\n constraint = {\n name: constraintName,\n type: constraintType,\n relatedConstraintName: relatedConstraintName,\n searchCondition: searchCondition,\n }\n }\n column.constraints[constraintName] = constraint\n }\n })\n }\n\n return oracleTables\n }\n\n private static isSupportedColumn(column: OracleColumn) {\n return !UNSUPPORTED_TYPES.includes(column.type)\n }\n\n private static isAutoColumn(column: OracleColumn) {\n return !!(\n column.default && column.default.toLowerCase().includes(\"nextval\")\n )\n }\n\n /**\n * No native boolean in oracle. Best we can do is to check if a manual 1 or 0 number constraint has been set up\n * This matches the default behaviour for generating DDL used in knex.\n */\n private isBooleanType(column: OracleColumn): boolean {\n return (\n column.type.toLowerCase() === \"number\" &&\n Object.values(column.constraints).filter(c => {\n if (\n c.type === OracleContraintTypes.NOT_NULL_OR_CHECK &&\n c.searchCondition\n ) {\n const condition = c.searchCondition\n .replace(/\\s/g, \"\") // remove spaces\n .replace(/[']+/g, \"\") // remove quotes\n if (condition.includes(\"in(0,1)\") || condition.includes(\"in(1,0)\")) {\n return true\n }\n }\n return false\n }).length > 0\n )\n }\n\n private internalConvertType(column: OracleColumn): { type: FieldTypes } {\n if (this.isBooleanType(column)) {\n return { type: FieldTypes.BOOLEAN }\n }\n\n return convertSqlType(column.type)\n }\n\n /**\n * Fetches the tables from the oracle table and assigns them to the datasource.\n * @param {*} datasourceId - datasourceId to fetch\n * @param entities - the tables that are to be built\n */\n async buildSchema(datasourceId: string, entities: Record<string, Table>) {\n const columnsResponse = await this.internalQuery<OracleColumnsResponse>({\n sql: this.COLUMNS_SQL,\n })\n const oracleTables = this.mapColumns(columnsResponse)\n\n const tables: { [key: string]: Table } = {}\n\n // iterate each table\n Object.values(oracleTables).forEach(oracleTable => {\n let table = tables[oracleTable.name]\n if (!table) {\n table = {\n _id: buildExternalTableId(datasourceId, oracleTable.name),\n primary: [],\n name: oracleTable.name,\n schema: {},\n }\n tables[oracleTable.name] = table\n }\n\n // iterate each column on the table\n Object.values(oracleTable.columns)\n // remove columns that we can't read / save\n .filter(oracleColumn =>\n OracleIntegration.isSupportedColumn(oracleColumn)\n )\n // match the order of the columns in the db\n .sort((c1, c2) => c1.id - c2.id)\n .forEach(oracleColumn => {\n const columnName = oracleColumn.name\n let fieldSchema = table.schema[columnName]\n if (!fieldSchema) {\n fieldSchema = {\n autocolumn: OracleIntegration.isAutoColumn(oracleColumn),\n name: columnName,\n constraints: {\n presence: false,\n },\n ...this.internalConvertType(oracleColumn),\n }\n table.schema[columnName] = fieldSchema\n }\n\n // iterate each constraint on the column\n Object.values(oracleColumn.constraints).forEach(oracleConstraint => {\n if (oracleConstraint.type === OracleContraintTypes.PRIMARY) {\n table.primary!.push(columnName)\n } else if (\n oracleConstraint.type === OracleContraintTypes.NOT_NULL_OR_CHECK\n ) {\n table.schema[columnName].constraints = {\n presence: true,\n }\n }\n })\n })\n })\n\n const final = finaliseExternalTables(tables, entities)\n this.tables = final.tables\n this.schemaErrors = final.errors\n }\n\n async getTableNames() {\n const columnsResponse = await this.internalQuery<OracleColumnsResponse>({\n sql: this.COLUMNS_SQL,\n })\n return (columnsResponse.rows || []).map(row => row.TABLE_NAME)\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n let connection\n try {\n connection = await this.getConnection()\n response.connected = true\n } catch (err: any) {\n response.connected = false\n response.error = err.message\n } finally {\n if (connection) {\n try {\n await connection.close()\n } catch (err: any) {\n response.connected = false\n response.error = err.message\n }\n }\n }\n return response\n }\n\n private async internalQuery<T>(query: SqlQuery): Promise<Result<T>> {\n let connection\n try {\n this.index = 1\n connection = await this.getConnection()\n\n const options: ExecuteOptions = { autoCommit: true }\n const bindings: BindParameters = query.bindings || []\n\n return await connection.execute<T>(query.sql, bindings, options)\n } finally {\n if (connection) {\n try {\n await connection.close()\n } catch (err) {\n console.error(err)\n }\n }\n }\n }\n\n private getConnection = async (): Promise<Connection> => {\n //connectString : \"(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))(CONNECT_DATA =(SID= ORCL)))\"\n const connectString = `${this.config.host}:${this.config.port || 1521}/${\n this.config.database\n }`\n const attributes: ConnectionAttributes = {\n user: this.config.user,\n password: this.config.password,\n connectString,\n }\n return oracledb.getConnection(attributes)\n }\n\n async create(query: SqlQuery | string): Promise<any[]> {\n const response = await this.internalQuery<any>(getSqlQuery(query))\n return response.rows && response.rows.length\n ? response.rows\n : [{ created: true }]\n }\n\n async read(query: SqlQuery | string): Promise<any[]> {\n const response = await this.internalQuery<any>(getSqlQuery(query))\n return response.rows ? response.rows : []\n }\n\n async update(query: SqlQuery | string): Promise<any[]> {\n const response = await this.internalQuery(getSqlQuery(query))\n return response.rows && response.rows.length\n ? response.rows\n : [{ updated: true }]\n }\n\n async delete(query: SqlQuery | string): Promise<any[]> {\n const response = await this.internalQuery(getSqlQuery(query))\n return response.rows && response.rows.length\n ? response.rows\n : [{ deleted: true }]\n }\n\n async query(json: QueryJson) {\n const operation = this._operation(json)\n const input = this._query(json, { disableReturning: true })\n if (Array.isArray(input)) {\n const responses = []\n for (let query of input) {\n responses.push(await this.internalQuery(query))\n }\n return responses\n } else {\n // read the row to be deleted up front for the return\n let deletedRows\n if (operation === Operation.DELETE) {\n const queryFn = (query: any) => this.internalQuery(query)\n deletedRows = await this.getReturningRow(queryFn, json)\n }\n\n // run the query\n const response = await this.internalQuery(input)\n\n // get the results or return the created / updated / deleted row\n if (deletedRows?.rows?.length) {\n return deletedRows.rows\n } else if (response.rows?.length) {\n return response.rows\n } else {\n // get the last row that was updated\n if (\n response.lastRowid &&\n json.endpoint?.entityId &&\n operation !== Operation.DELETE\n ) {\n const lastRow = await this.internalQuery({\n sql: `SELECT * FROM \\\"${json.endpoint.entityId}\\\" WHERE ROWID = '${response.lastRowid}'`,\n })\n return lastRow.rows\n } else {\n return [{ [operation.toLowerCase()]: true }]\n }\n }\n }\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: OracleIntegration,\n}\n", "import postgres from \"./postgres\"\nimport dynamodb from \"./dynamodb\"\nimport mongodb from \"./mongodb\"\nimport elasticsearch from \"./elasticsearch\"\nimport couchdb from \"./couchdb\"\nimport sqlServer from \"./microsoftSqlServer\"\nimport s3 from \"./s3\"\nimport airtable from \"./airtable\"\nimport mysql from \"./mysql\"\nimport arangodb from \"./arangodb\"\nimport rest from \"./rest\"\nimport googlesheets from \"./googlesheets\"\nimport firebase from \"./firebase\"\nimport redis from \"./redis\"\nimport snowflake from \"./snowflake\"\nimport oracle from \"./oracle\"\nimport { SourceName, Integration, PluginType } from \"@budibase/types\"\nimport { getDatasourcePlugin } from \"../utilities/fileSystem\"\nimport env from \"../environment\"\nimport { cloneDeep } from \"lodash\"\nimport sdk from \"../sdk\"\n\nconst DEFINITIONS: Record<SourceName, Integration | undefined> = {\n [SourceName.POSTGRES]: postgres.schema,\n [SourceName.DYNAMODB]: dynamodb.schema,\n [SourceName.MONGODB]: mongodb.schema,\n [SourceName.ELASTICSEARCH]: elasticsearch.schema,\n [SourceName.COUCHDB]: couchdb.schema,\n [SourceName.SQL_SERVER]: sqlServer.schema,\n [SourceName.S3]: s3.schema,\n [SourceName.AIRTABLE]: airtable.schema,\n [SourceName.MYSQL]: mysql.schema,\n [SourceName.ARANGODB]: arangodb.schema,\n [SourceName.REST]: rest.schema,\n [SourceName.FIRESTORE]: firebase.schema,\n [SourceName.GOOGLE_SHEETS]: googlesheets.schema,\n [SourceName.REDIS]: redis.schema,\n [SourceName.SNOWFLAKE]: snowflake.schema,\n [SourceName.ORACLE]: undefined,\n}\n\nconst INTEGRATIONS: Record<SourceName, any> = {\n [SourceName.POSTGRES]: postgres.integration,\n [SourceName.DYNAMODB]: dynamodb.integration,\n [SourceName.MONGODB]: mongodb.integration,\n [SourceName.ELASTICSEARCH]: elasticsearch.integration,\n [SourceName.COUCHDB]: couchdb.integration,\n [SourceName.SQL_SERVER]: sqlServer.integration,\n [SourceName.S3]: s3.integration,\n [SourceName.AIRTABLE]: airtable.integration,\n [SourceName.MYSQL]: mysql.integration,\n [SourceName.ARANGODB]: arangodb.integration,\n [SourceName.REST]: rest.integration,\n [SourceName.FIRESTORE]: firebase.integration,\n [SourceName.GOOGLE_SHEETS]: googlesheets.integration,\n [SourceName.REDIS]: redis.integration,\n [SourceName.FIRESTORE]: firebase.integration,\n [SourceName.SNOWFLAKE]: snowflake.integration,\n [SourceName.ORACLE]: undefined,\n}\n\n// optionally add oracle integration if the oracle binary can be installed\nif (\n process.arch &&\n !process.arch.startsWith(\"arm\") &&\n oracle.integration.isInstalled()\n) {\n DEFINITIONS[SourceName.ORACLE] = oracle.schema\n INTEGRATIONS[SourceName.ORACLE] = oracle.integration\n}\n\nexport async function getDefinition(\n source: SourceName\n): Promise<Integration | undefined> {\n // check if its integrated, faster\n const definition = DEFINITIONS[source]\n if (definition) {\n return definition\n }\n const allDefinitions = await getDefinitions()\n return allDefinitions[source]\n}\n\nexport async function getDefinitions() {\n const pluginSchemas: { [key: string]: Integration } = {}\n if (env.SELF_HOSTED) {\n const plugins = await sdk.plugins.fetch(PluginType.DATASOURCE)\n // extract the actual schema from each custom\n for (let plugin of plugins) {\n const sourceId = plugin.name\n pluginSchemas[sourceId] = {\n ...plugin.schema[\"schema\"],\n custom: true,\n }\n if (plugin.iconUrl) {\n pluginSchemas[sourceId].iconUrl = plugin.iconUrl\n }\n }\n }\n return {\n ...cloneDeep(DEFINITIONS),\n ...pluginSchemas,\n }\n}\n\nexport async function getIntegration(integration: SourceName) {\n if (INTEGRATIONS[integration]) {\n return INTEGRATIONS[integration]\n }\n if (env.SELF_HOSTED) {\n const plugins = await sdk.plugins.fetch(PluginType.DATASOURCE)\n for (let plugin of plugins) {\n if (plugin.name === integration) {\n // need to use commonJS require due to its dynamic runtime nature\n const retrieved = await getDatasourcePlugin(plugin)\n if (retrieved.integration) {\n return retrieved.integration\n } else {\n return retrieved\n }\n }\n }\n }\n throw new Error(\"No datasource implementation found.\")\n}\n\nexport default {\n getDefinitions,\n getIntegration,\n}\n", "import { objectStore } from \"@budibase/backend-core\"\n\nexport const budibaseTempDir = objectStore.budibaseTempDir\n", "import { budibaseTempDir } from \"../budibaseDir\"\nimport fs from \"fs\"\nimport { join } from \"path\"\nimport { ObjectStoreBuckets } from \"../../constants\"\nimport { updateClientLibrary } from \"./clientLibrary\"\nimport env from \"../../environment\"\nimport { objectStore, context } from \"@budibase/backend-core\"\nimport { TOP_LEVEL_PATH } from \"./filesystem\"\n\nexport const NODE_MODULES_PATH = join(TOP_LEVEL_PATH, \"node_modules\")\n\n/**\n * Uploads the latest client library to the object store.\n * @param {string} appId The ID of the app which is being created.\n * @return {Promise<void>} once promise completes app resources should be ready in object store.\n */\nexport const createApp = async (appId: string) => {\n await updateClientLibrary(appId)\n}\n\n/**\n * Removes all of the assets created for an app in the object store.\n * @param {string} appId The ID of the app which is being deleted.\n * @return {Promise<void>} once promise completes the app resources will be removed from object store.\n */\nexport const deleteApp = async (appId: string) => {\n await objectStore.deleteFolder(ObjectStoreBuckets.APPS, `${appId}/`)\n}\n\n/**\n * Retrieves component libraries from object store (or tmp symlink if in local)\n */\nexport const getComponentLibraryManifest = async (library: string) => {\n const appId = context.getAppId()\n const filename = \"manifest.json\"\n\n if (env.isDev() || env.isTest()) {\n const paths = [\n join(TOP_LEVEL_PATH, \"packages/client\", filename),\n join(process.cwd(), \"client\", filename),\n ]\n for (let path of paths) {\n if (fs.existsSync(path)) {\n // always load from new so that updates are refreshed\n delete require.cache[require.resolve(path)]\n return require(path)\n }\n }\n throw new Error(\n `Unable to find ${filename} in development environment (may need to build).`\n )\n }\n\n if (!appId) {\n throw new Error(\"No app ID found - cannot get component libraries\")\n }\n\n let resp\n let path\n try {\n // Try to load the manifest from the new file location\n path = join(appId, filename)\n resp = await objectStore.retrieve(ObjectStoreBuckets.APPS, path)\n } catch (error) {\n console.error(\n `component-manifest-objectstore=failed appId=${appId} path=${path}`,\n error\n )\n // Fallback to loading it from the old location for old apps\n path = join(appId, \"node_modules\", library, \"package\", filename)\n resp = await objectStore.retrieve(ObjectStoreBuckets.APPS, path)\n }\n if (typeof resp !== \"string\") {\n resp = resp.toString(\"utf8\")\n }\n return JSON.parse(resp)\n}\n\n/**\n * Given a set of app IDs makes sure file system is cleared of any of their temp info.\n */\nexport const cleanup = (appIds: string[]) => {\n for (let appId of appIds) {\n const path = join(budibaseTempDir(), appId)\n if (fs.existsSync(path)) {\n fs.rmdirSync(path, { recursive: true })\n }\n }\n}\n", "import { PathLike } from \"fs\"\nimport fs from \"fs\"\nimport { budibaseTempDir } from \"../budibaseDir\"\nimport { join } from \"path\"\nimport env from \"../../environment\"\nimport tar from \"tar\"\nimport environment from \"../../environment\"\nconst uuid = require(\"uuid/v4\")\n\nexport const TOP_LEVEL_PATH =\n environment.TOP_LEVEL_PATH || join(__dirname, \"..\", \"..\", \"..\")\n\n/**\n * Upon first startup of instance there may not be everything we need in tmp directory, set it up.\n */\nexport const init = () => {\n const tempDir = budibaseTempDir()\n if (!fs.existsSync(tempDir)) {\n // some test cases fire this quickly enough that\n // synchronous cases can end up here at the same time\n try {\n fs.mkdirSync(tempDir)\n } catch (err: any) {\n if (!err || err.code !== \"EEXIST\") {\n throw err\n }\n }\n }\n}\n\n/**\n * Checks if the system is currently in development mode and if it is makes sure\n * everything required to function is ready.\n */\nexport const checkDevelopmentEnvironment = () => {\n if (!env.isDev() || env.isTest()) {\n return\n }\n if (!fs.existsSync(budibaseTempDir())) {\n fs.mkdirSync(budibaseTempDir())\n }\n let error\n if (!fs.existsSync(join(process.cwd(), \".env\"))) {\n error = \"Must run via yarn once to generate environment.\"\n }\n if (error) {\n console.error(error)\n process.exit(-1)\n }\n}\n\n/**\n * Used to retrieve a handlebars file from the system which will be used as a template.\n * This is allowable as the template handlebars files should be static and identical across\n * the cluster.\n * @param {string} path The path to the handlebars file which is to be loaded.\n * @returns {string} The loaded handlebars file as a string - loaded as utf8.\n */\nexport const loadHandlebarsFile = (path: PathLike) => {\n return fs.readFileSync(path, \"utf8\")\n}\n\n/**\n * When return a file from the API need to write the file to the system temporarily so we\n * can create a read stream to send.\n * @param {string} contents the contents of the file which is to be returned from the API.\n * @return {Object} the read stream which can be put into the koa context body.\n */\nexport const apiFileReturn = (contents: any) => {\n const path = join(budibaseTempDir(), uuid())\n fs.writeFileSync(path, contents)\n return fs.createReadStream(path)\n}\n\nexport const streamFile = (path: string) => {\n return fs.createReadStream(path)\n}\n\n/**\n * Writes the provided contents to a temporary file, which can be used briefly.\n * @param {string} fileContents contents which will be written to a temp file.\n * @return {string} the path to the temp file.\n */\nexport const storeTempFile = (fileContents: any) => {\n const path = join(budibaseTempDir(), uuid())\n fs.writeFileSync(path, fileContents)\n return path\n}\n\n/**\n * Utility function for getting a file read stream - a simple in memory buffered read\n * stream doesn't work for pouchdb.\n */\nexport const stringToFileStream = (contents: any) => {\n const path = storeTempFile(contents)\n return fs.createReadStream(path)\n}\n\n/**\n * Creates a temp file and returns it from the API.\n * @param {string} fileContents the contents to be returned in file.\n */\nexport const sendTempFile = (fileContents: any) => {\n const path = storeTempFile(fileContents)\n return fs.createReadStream(path)\n}\n\n/**\n * All file reads come through here just to make sure all of them make sense\n * allows a centralised location to check logic is all good.\n */\nexport const readFileSync = (filepath: PathLike, options = \"utf8\") => {\n // @ts-ignore\n return fs.readFileSync(filepath, options)\n}\n\nexport const createTempFolder = (item: any) => {\n const path = join(budibaseTempDir(), item)\n try {\n // remove old tmp directories automatically - don't combine\n if (fs.existsSync(path)) {\n fs.rmSync(path, { recursive: true, force: true })\n }\n fs.mkdirSync(path)\n } catch (err: any) {\n throw new Error(`Path cannot be created: ${err.message}`)\n }\n\n return path\n}\n\nexport const extractTarball = async (fromFilePath: string, toPath: string) => {\n await tar.extract({\n file: fromFilePath,\n C: toPath,\n })\n}\n\n/**\n * Find for a file recursively from start path applying filter, return first match\n */\nexport const findFileRec = (startPath: PathLike, filter: string): any => {\n if (!fs.existsSync(startPath)) {\n return\n }\n\n const files = fs.readdirSync(startPath)\n for (let i = 0, len = files.length; i < len; i++) {\n // @ts-ignore\n const filename = join(startPath, files[i])\n const stat = fs.lstatSync(filename)\n\n if (stat.isDirectory()) {\n return findFileRec(filename, filter)\n } else if (filename.endsWith(filter)) {\n return filename\n }\n }\n}\n\n/**\n * Remove a folder which is not empty from the file system\n */\nexport const deleteFolderFileSystem = (path: PathLike) => {\n if (!fs.existsSync(path)) {\n return\n }\n\n fs.rmSync(path, { recursive: true, force: true })\n}\n", "import { Plugin } from \"@budibase/types\"\nimport { budibaseTempDir } from \"../budibaseDir\"\nimport fs from \"fs\"\nimport { join } from \"path\"\nimport { objectStore } from \"@budibase/backend-core\"\n\nconst DATASOURCE_PATH = join(budibaseTempDir(), \"datasource\")\nconst AUTOMATION_PATH = join(budibaseTempDir(), \"automation\")\n\nexport const getPluginMetadata = async (path: string) => {\n let metadata: any = {}\n try {\n const pkg = fs.readFileSync(join(path, \"package.json\"), \"utf8\")\n const schema = fs.readFileSync(join(path, \"schema.json\"), \"utf8\")\n\n metadata.schema = JSON.parse(schema)\n metadata.package = JSON.parse(pkg)\n\n if (\n !metadata.package.name ||\n !metadata.package.version ||\n !metadata.package.description\n ) {\n throw new Error(\n \"package.json is missing one of 'name', 'version' or 'description'.\"\n )\n }\n } catch (err: any) {\n throw new Error(\n `Unable to process schema.json/package.json in plugin. ${err.message}`\n )\n }\n\n return { metadata, directory: path }\n}\n\nasync function getPluginImpl(path: string, plugin: Plugin) {\n const hash = plugin.schema?.hash\n if (!fs.existsSync(path)) {\n fs.mkdirSync(path)\n }\n const filename = join(path, plugin.name)\n const metadataName = `${filename}.bbmetadata`\n if (fs.existsSync(filename)) {\n const currentHash = fs.readFileSync(metadataName, \"utf8\")\n // if hash is the same return the file, otherwise remove it and re-download\n if (currentHash === hash) {\n return require(filename)\n } else {\n console.log(`Updating plugin: ${plugin.name}`)\n delete require.cache[require.resolve(filename)]\n fs.unlinkSync(filename)\n }\n }\n const pluginKey = objectStore.getPluginJSKey(plugin)\n const pluginJs = await objectStore.retrieve(\n objectStore.ObjectStoreBuckets.PLUGINS,\n pluginKey\n )\n\n fs.writeFileSync(filename, pluginJs)\n fs.writeFileSync(metadataName, hash)\n\n return require(filename)\n}\n\nexport const getDatasourcePlugin = async (plugin: Plugin) => {\n return getPluginImpl(DATASOURCE_PATH, plugin)\n}\n\nexport const getAutomationPlugin = async (plugin: Plugin) => {\n return getPluginImpl(AUTOMATION_PATH, plugin)\n}\n", "import fs from \"fs\"\nimport { join } from \"path\"\nimport { ObjectStoreBuckets } from \"../../constants\"\nimport { objectStore } from \"@budibase/backend-core\"\n\n/**\n * This function manages temporary template files which are stored by Koa.\n * @param {Object} template The template object retrieved from the Koa context object.\n * @returns {Object} Returns an fs read stream which can be loaded into the database.\n */\nexport const getTemplateStream = async (template: any) => {\n if (template.file) {\n return fs.createReadStream(template.file.path)\n } else {\n const [type, name] = template.key.split(\"/\")\n const tmpPath = await downloadTemplate(type, name)\n return fs.createReadStream(join(tmpPath, name, \"db\", \"dump.txt\"))\n }\n}\n\n/**\n * Retrieves a template and pipes it to minio as well as making it available temporarily.\n * @param {string} type The type of template which is to be retrieved.\n * @param name\n * @return {Promise<*>}\n */\nexport const downloadTemplate = async (type: string, name: string) => {\n const DEFAULT_TEMPLATES_BUCKET =\n \"prod-budi-templates.s3-eu-west-1.amazonaws.com\"\n const templateUrl = `https://${DEFAULT_TEMPLATES_BUCKET}/templates/${type}/${name}.tar.gz`\n return objectStore.downloadTarball(\n templateUrl,\n ObjectStoreBuckets.TEMPLATES,\n type\n )\n}\n", "import { db as dbCore, objectStore } from \"@budibase/backend-core\"\nimport { budibaseTempDir } from \"../../../utilities/budibaseDir\"\nimport { streamFile, createTempFolder } from \"../../../utilities/fileSystem\"\nimport { ObjectStoreBuckets } from \"../../../constants\"\nimport {\n AUTOMATION_LOG_PREFIX,\n LINK_USER_METADATA_PREFIX,\n TABLE_ROW_PREFIX,\n USER_METDATA_PREFIX,\n} from \"../../../db/utils\"\nimport {\n DB_EXPORT_FILE,\n GLOBAL_DB_EXPORT_FILE,\n STATIC_APP_FILES,\n} from \"./constants\"\nimport fs from \"fs\"\nimport { join } from \"path\"\nimport env from \"../../../environment\"\n\nconst uuid = require(\"uuid/v4\")\nconst tar = require(\"tar\")\nconst MemoryStream = require(\"memorystream\")\n\ninterface DBDumpOpts {\n filter?: any\n exportPath?: string\n}\n\ninterface ExportOpts extends DBDumpOpts {\n tar?: boolean\n excludeRows?: boolean\n excludeLogs?: boolean\n}\n\nfunction tarFilesToTmp(tmpDir: string, files: string[]) {\n const exportFile = join(budibaseTempDir(), `${uuid()}.tar.gz`)\n tar.create(\n {\n sync: true,\n gzip: true,\n file: exportFile,\n recursive: true,\n cwd: tmpDir,\n },\n files\n )\n return exportFile\n}\n\n/**\n * Exports a DB to either file or a variable (memory).\n * @param {string} dbName the DB which is to be exported.\n * @param {object} opts various options for the export, e.g. whether to stream,\n * a filter function or the name of the export.\n * @return {*} either a readable stream or a string\n */\nexport async function exportDB(dbName: string, opts: DBDumpOpts = {}) {\n const exportOpts = {\n filter: opts?.filter,\n batch_size: 1000,\n batch_limit: 5,\n style: \"main_only\",\n }\n return dbCore.doWithDB(dbName, async (db: any) => {\n // Write the dump to file if required\n if (opts?.exportPath) {\n const path = opts?.exportPath\n const writeStream = fs.createWriteStream(path)\n await db.dump(writeStream, exportOpts)\n return path\n } else {\n // Stringify the dump in memory if required\n const memStream = new MemoryStream()\n let appString = \"\"\n memStream.on(\"data\", (chunk: any) => {\n appString += chunk.toString()\n })\n await db.dump(memStream, exportOpts)\n return appString\n }\n })\n}\n\nfunction defineFilter(excludeRows?: boolean, excludeLogs?: boolean) {\n const ids = [USER_METDATA_PREFIX, LINK_USER_METADATA_PREFIX]\n if (excludeRows) {\n ids.push(TABLE_ROW_PREFIX)\n }\n if (excludeLogs) {\n ids.push(AUTOMATION_LOG_PREFIX)\n }\n return (doc: any) =>\n !ids.map(key => doc._id.includes(key)).reduce((prev, curr) => prev || curr)\n}\n\n/**\n * Local utility to back up the database state for an app, excluding global user\n * data or user relationships.\n * @param {string} appId The app to back up\n * @param {object} config Config to send to export DB/attachment export\n * @returns {*} either a string or a stream of the backup\n */\nexport async function exportApp(appId: string, config?: ExportOpts) {\n const prodAppId = dbCore.getProdAppID(appId)\n const appPath = `${prodAppId}/`\n // export bucket contents\n let tmpPath = createTempFolder(uuid())\n if (!env.isTest()) {\n // write just the static files\n if (config?.excludeRows) {\n for (let path of STATIC_APP_FILES) {\n const contents = await objectStore.retrieve(\n ObjectStoreBuckets.APPS,\n join(appPath, path)\n )\n fs.writeFileSync(join(tmpPath, path), contents)\n }\n }\n // get all of the files\n else {\n tmpPath = await objectStore.retrieveDirectory(\n ObjectStoreBuckets.APPS,\n appPath\n )\n }\n }\n const downloadedPath = join(tmpPath, appPath)\n if (fs.existsSync(downloadedPath)) {\n const allFiles = fs.readdirSync(downloadedPath)\n for (let file of allFiles) {\n const path = join(downloadedPath, file)\n // move out of app directory, simplify structure\n fs.renameSync(path, join(downloadedPath, \"..\", file))\n }\n // remove the old app directory created by object export\n fs.rmdirSync(downloadedPath)\n }\n // enforce an export of app DB to the tmp path\n const dbPath = join(tmpPath, DB_EXPORT_FILE)\n await exportDB(appId, {\n filter: defineFilter(config?.excludeRows, config?.excludeLogs),\n exportPath: dbPath,\n })\n // if tar requested, return where the tarball is\n if (config?.tar) {\n // now the tmpPath contains both the DB export and attachments, tar this\n const tarPath = tarFilesToTmp(tmpPath, fs.readdirSync(tmpPath))\n // cleanup the tmp export files as tarball returned\n fs.rmSync(tmpPath, { recursive: true, force: true })\n return tarPath\n }\n // tar not requested, turn the directory where export is\n else {\n return tmpPath\n }\n}\n\n/**\n * Streams a backup of the database state for an app\n * @param {string} appId The ID of the app which is to be backed up.\n * @param {boolean} excludeRows Flag to state whether the export should include data.\n * @returns {*} a readable stream of the backup which is written in real time\n */\nexport async function streamExportApp(appId: string, excludeRows: boolean) {\n const tmpPath = await exportApp(appId, {\n excludeRows,\n excludeLogs: true,\n tar: true,\n })\n return streamFile(tmpPath)\n}\n", "export const DB_EXPORT_FILE = \"db.txt\"\nexport const GLOBAL_DB_EXPORT_FILE = \"global.txt\"\nexport const STATIC_APP_FILES = [\"manifest.json\", \"budibase-client.js\"]\n", "import { db as dbCore, objectStore } from \"@budibase/backend-core\"\nimport { Database, Row } from \"@budibase/types\"\nimport { getAutomationParams, TABLE_ROW_PREFIX } from \"../../../db/utils\"\nimport { budibaseTempDir } from \"../../../utilities/budibaseDir\"\nimport { DB_EXPORT_FILE, GLOBAL_DB_EXPORT_FILE } from \"./constants\"\nimport { downloadTemplate } from \"../../../utilities/fileSystem\"\nimport { ObjectStoreBuckets } from \"../../../constants\"\nimport { join } from \"path\"\nimport fs from \"fs\"\nimport sdk from \"../../\"\nimport {\n Automation,\n AutomationTriggerStepId,\n RowAttachment,\n} from \"@budibase/types\"\nconst uuid = require(\"uuid/v4\")\nconst tar = require(\"tar\")\n\ntype TemplateType = {\n file?: {\n type: string\n path: string\n }\n key?: string\n}\n\nfunction rewriteAttachmentUrl(appId: string, attachment: RowAttachment) {\n // URL looks like: /prod-budi-app-assets/appId/attachments/file.csv\n const urlParts = attachment.key.split(\"/\")\n // remove the app ID\n urlParts.shift()\n // add new app ID\n urlParts.unshift(appId)\n const key = urlParts.join(\"/\")\n return {\n ...attachment,\n key,\n url: \"\", // calculated on retrieval using key\n }\n}\n\nexport async function updateAttachmentColumns(prodAppId: string, db: Database) {\n // iterate through attachment documents and update them\n const tables = await sdk.tables.getAllInternalTables(db)\n let updatedRows: Row[] = []\n for (let table of tables) {\n const { rows, columns } = await sdk.rows.getRowsWithAttachments(\n db.name,\n table\n )\n updatedRows = updatedRows.concat(\n rows.map(row => {\n for (let column of columns) {\n if (Array.isArray(row[column])) {\n row[column] = row[column].map((attachment: RowAttachment) =>\n rewriteAttachmentUrl(prodAppId, attachment)\n )\n }\n }\n return row\n })\n )\n }\n // write back the updated attachments\n await db.bulkDocs(updatedRows)\n}\n\nasync function updateAutomations(prodAppId: string, db: Database) {\n const automations = (\n await db.allDocs(\n getAutomationParams(null, {\n include_docs: true,\n })\n )\n ).rows.map(row => row.doc) as Automation[]\n const devAppId = dbCore.getDevAppID(prodAppId)\n let toSave: Automation[] = []\n for (let automation of automations) {\n const oldDevAppId = automation.appId,\n oldProdAppId = dbCore.getProdAppID(automation.appId)\n if (\n automation.definition.trigger?.stepId === AutomationTriggerStepId.WEBHOOK\n ) {\n const old = automation.definition.trigger.inputs\n automation.definition.trigger.inputs = {\n schemaUrl: old.schemaUrl.replace(oldDevAppId, devAppId),\n triggerUrl: old.triggerUrl.replace(oldProdAppId, prodAppId),\n }\n }\n automation.appId = devAppId\n toSave.push(automation)\n }\n await db.bulkDocs(toSave)\n}\n\n/**\n * This function manages temporary template files which are stored by Koa.\n * @param {Object} template The template object retrieved from the Koa context object.\n * @returns {Object} Returns a fs read stream which can be loaded into the database.\n */\nasync function getTemplateStream(template: TemplateType) {\n if (template.file && template.file.type !== \"text/plain\") {\n throw new Error(\"Cannot import a non-text based file.\")\n }\n if (template.file) {\n return fs.createReadStream(template.file.path)\n } else if (template.key) {\n const [type, name] = template.key.split(\"/\")\n const tmpPath = await downloadTemplate(type, name)\n return fs.createReadStream(join(tmpPath, name, \"db\", \"dump.txt\"))\n }\n}\n\nexport function untarFile(file: { path: string }) {\n const tmpPath = join(budibaseTempDir(), uuid())\n fs.mkdirSync(tmpPath)\n // extract the tarball\n tar.extract({\n sync: true,\n cwd: tmpPath,\n file: file.path,\n })\n return tmpPath\n}\n\nexport function getGlobalDBFile(tmpPath: string) {\n return fs.readFileSync(join(tmpPath, GLOBAL_DB_EXPORT_FILE), \"utf8\")\n}\n\nexport function getListOfAppsInMulti(tmpPath: string) {\n return fs.readdirSync(tmpPath).filter(dir => dir !== GLOBAL_DB_EXPORT_FILE)\n}\n\nexport async function importApp(\n appId: string,\n db: Database,\n template: TemplateType\n) {\n let prodAppId = dbCore.getProdAppID(appId)\n let dbStream: any\n const isTar = template.file && template?.file?.type?.endsWith(\"gzip\")\n const isDirectory =\n template.file && fs.lstatSync(template.file.path).isDirectory()\n if (template.file && (isTar || isDirectory)) {\n const tmpPath = isTar ? untarFile(template.file) : template.file.path\n const contents = fs.readdirSync(tmpPath)\n // have to handle object import\n if (contents.length) {\n let promises = []\n let excludedFiles = [GLOBAL_DB_EXPORT_FILE, DB_EXPORT_FILE]\n for (let filename of contents) {\n const path = join(tmpPath, filename)\n if (excludedFiles.includes(filename)) {\n continue\n }\n filename = join(prodAppId, filename)\n if (fs.lstatSync(path).isDirectory()) {\n promises.push(\n objectStore.uploadDirectory(ObjectStoreBuckets.APPS, path, filename)\n )\n } else {\n promises.push(\n objectStore.upload({\n bucket: ObjectStoreBuckets.APPS,\n path,\n filename,\n })\n )\n }\n }\n await Promise.all(promises)\n }\n dbStream = fs.createReadStream(join(tmpPath, DB_EXPORT_FILE))\n } else {\n dbStream = await getTemplateStream(template)\n }\n // @ts-ignore\n const { ok } = await db.load(dbStream)\n if (!ok) {\n throw \"Error loading database dump from template.\"\n }\n await updateAttachmentColumns(prodAppId, db)\n await updateAutomations(prodAppId, db)\n return ok\n}\n", "import { context, db as dbCore } from \"@budibase/backend-core\"\nimport { Database } from \"@budibase/types\"\nimport {\n getDatasourceParams,\n getTableParams,\n getAutomationParams,\n getScreenParams,\n} from \"../../../db/utils\"\n\nasync function runInContext(appId: string, cb: any, db?: Database) {\n if (db) {\n return cb(db)\n } else {\n const devAppId = dbCore.getDevAppID(appId)\n return context.doInAppContext(devAppId, () => {\n const db = context.getAppDB()\n return cb(db)\n })\n }\n}\n\nexport async function calculateDatasourceCount(appId: string, db?: Database) {\n return runInContext(\n appId,\n async (db: Database) => {\n const datasourceList = await db.allDocs(getDatasourceParams())\n const tableList = await db.allDocs(getTableParams())\n return datasourceList.rows.length + tableList.rows.length\n },\n db\n )\n}\n\nexport async function calculateAutomationCount(appId: string, db?: Database) {\n return runInContext(\n appId,\n async (db: Database) => {\n const automationList = await db.allDocs(getAutomationParams())\n return automationList.rows.length\n },\n db\n )\n}\n\nexport async function calculateScreenCount(appId: string, db?: Database) {\n return runInContext(\n appId,\n async (db: Database) => {\n const screenList = await db.allDocs(getScreenParams())\n return screenList.rows.length\n },\n db\n )\n}\n\nexport async function calculateBackupStats(appId: string) {\n return runInContext(appId, async (db: Database) => {\n const promises = []\n promises.push(calculateDatasourceCount(appId, db))\n promises.push(calculateAutomationCount(appId, db))\n promises.push(calculateScreenCount(appId, db))\n const responses = await Promise.all(promises)\n return {\n datasources: responses[0],\n automations: responses[1],\n screens: responses[2],\n }\n })\n}\n", "import * as exportApps from \"./exports\"\nimport * as importApps from \"./imports\"\nimport * as statistics from \"./statistics\"\n\nexport default {\n ...exportApps,\n ...importApps,\n ...statistics,\n}\n", "import { context } from \"@budibase/backend-core\"\nimport { findHBSBlocks, processObjectSync } from \"@budibase/string-templates\"\nimport {\n Datasource,\n DatasourceFieldType,\n Integration,\n PASSWORD_REPLACEMENT,\n RestAuthConfig,\n RestAuthType,\n RestBasicAuthConfig,\n SourceName,\n} from \"@budibase/types\"\nimport { cloneDeep } from \"lodash/fp\"\nimport { getEnvironmentVariables } from \"../../utils\"\nimport { getDefinitions, getDefinition } from \"../../../integrations\"\nimport _ from \"lodash\"\n\nconst ENV_VAR_PREFIX = \"env.\"\n\nexport function checkDatasourceTypes(schema: Integration, config: any) {\n for (let key of Object.keys(config)) {\n if (!schema.datasource[key]) {\n continue\n }\n const type = schema.datasource[key].type\n if (\n type === DatasourceFieldType.NUMBER &&\n typeof config[key] === \"string\"\n ) {\n config[key] = parseFloat(config[key])\n }\n }\n return config\n}\n\nasync function enrichDatasourceWithValues(datasource: Datasource) {\n const cloned = cloneDeep(datasource)\n const env = await getEnvironmentVariables()\n const processed = processObjectSync(\n cloned,\n { env },\n { onlyFound: true }\n ) as Datasource\n const definition = await getDefinition(processed.source)\n processed.config = checkDatasourceTypes(definition!, processed.config)\n return {\n datasource: processed,\n envVars: env as Record<string, string>,\n }\n}\n\nexport async function enrich(datasource: Datasource) {\n const { datasource: response } = await enrichDatasourceWithValues(datasource)\n return response\n}\n\nexport async function get(\n datasourceId: string,\n opts?: { enriched: boolean }\n): Promise<Datasource> {\n const appDb = context.getAppDB()\n const datasource = await appDb.get(datasourceId)\n if (opts?.enriched) {\n return (await enrichDatasourceWithValues(datasource)).datasource\n } else {\n return datasource\n }\n}\n\nexport async function getWithEnvVars(datasourceId: string) {\n const appDb = context.getAppDB()\n const datasource = await appDb.get(datasourceId)\n return enrichDatasourceWithValues(datasource)\n}\n\nfunction hasAuthConfigs(datasource: Datasource) {\n return datasource.source === SourceName.REST && datasource.config?.authConfigs\n}\n\nfunction useEnvVars(str: any) {\n if (typeof str !== \"string\") {\n return false\n }\n const blocks = findHBSBlocks(str)\n return blocks.find(block => block.includes(ENV_VAR_PREFIX)) != null\n}\n\nexport async function removeSecrets(datasources: Datasource[]) {\n const definitions = await getDefinitions()\n for (let datasource of datasources) {\n const schema = definitions[datasource.source]\n if (!schema) {\n continue\n }\n if (datasource.config) {\n // strip secrets from response, so they don't show in the network request\n if (datasource.config.auth) {\n delete datasource.config.auth\n }\n // specific to REST datasources, contains passwords\n if (hasAuthConfigs(datasource)) {\n const configs = datasource.config.authConfigs as RestAuthConfig[]\n for (let config of configs) {\n if (config.type !== RestAuthType.BASIC) {\n continue\n }\n const basic = config.config as RestBasicAuthConfig\n if (!useEnvVars(basic.password)) {\n basic.password = PASSWORD_REPLACEMENT\n }\n }\n }\n // remove general passwords\n for (let key of Object.keys(datasource.config)) {\n if (\n schema.datasource?.[key]?.type === DatasourceFieldType.PASSWORD &&\n !useEnvVars(datasource.config[key])\n ) {\n datasource.config[key] = PASSWORD_REPLACEMENT\n }\n }\n }\n }\n return datasources\n}\n\nexport async function removeSecretSingle(datasource: Datasource) {\n return (await removeSecrets([datasource]))[0]\n}\n\nexport function mergeConfigs(update: Datasource, old: Datasource) {\n if (!update.config) {\n return update\n }\n // specific to REST datasources, fix the auth configs again if required\n if (hasAuthConfigs(update)) {\n const configs = update.config.authConfigs as RestAuthConfig[]\n const oldConfigs = old.config?.authConfigs as RestAuthConfig[]\n for (let config of configs) {\n if (config.type !== RestAuthType.BASIC) {\n continue\n }\n const basic = config.config as RestBasicAuthConfig\n const oldBasic = oldConfigs.find(old => old.name === config.name)\n ?.config as RestBasicAuthConfig\n if (basic.password === PASSWORD_REPLACEMENT) {\n basic.password = oldBasic.password\n }\n }\n }\n\n if (old.config?.auth) {\n update.config = _.merge(old.config, update.config)\n }\n\n // update back to actual passwords for everything else\n for (let [key, value] of Object.entries(update.config)) {\n if (value !== PASSWORD_REPLACEMENT) {\n continue\n }\n if (old.config?.[key]) {\n update.config[key] = old.config?.[key]\n } else {\n delete update.config[key]\n }\n }\n return update\n}\n", "export * as branding from \"./branding\"\nexport * as licensing from \"./licensing\"\nexport * as quotas from \"./quotas\"\nexport * as users from \"./users\"\nexport * as automations from \"./automations\"\nexport * as features from \"./features\"\nexport * as groups from \"./groups\"\nexport * as plugins from \"./plugins\"\nexport * as environmentVariables from \"./environmentVariables\"\nexport * as auditLogs from \"./auditLogs\"\nexport { default as backups } from \"./backups\"\nexport * as utils from \"./utils\"\nexport * from \"./init\"\nexport * from \"./scim\"\n", "export * from \"./branding\"\n", "export * from \"./features\"\n", "import { Feature } from \"@budibase/types\"\nimport { FeatureDisabledError, configs, env } from \"@budibase/backend-core\"\nimport { cache } from \"../licensing\"\nimport { SettingsInnerConfig } from \"@budibase/types\"\n\n// UTILS\n\nasync function isFeatureEnabled(featureFlag: Feature) {\n const license = await cache.getCachedLicense()\n return license?.features.includes(featureFlag)\n}\n\nexport async function checkFeature(featureFlag: Feature) {\n if (!(await isFeatureEnabled(featureFlag))) {\n throw new FeatureDisabledError(\n `${featureFlag} is not currently enabled`,\n featureFlag\n )\n }\n}\n\n// BACKUPS\n\nexport function checkBackups<Args extends any[], Return>(\n targetFunction: (...parameters: Args) => Return\n): (...parameters: Args) => Promise<Return> {\n return async (...parameters: Args) => {\n await checkFeature(Feature.APP_BACKUPS)\n return targetFunction(...parameters)\n }\n}\n\nexport async function isBackupsEnabled() {\n return isFeatureEnabled(Feature.APP_BACKUPS)\n}\n\n// BRANDING\n\nexport async function isBrandingEnabled() {\n return isFeatureEnabled(Feature.BRANDING)\n}\n\n// SSO\n\nexport async function isEnforceableSSO() {\n return isFeatureEnabled(Feature.ENFORCEABLE_SSO)\n}\n\n// Synchronous Webhook\nexport async function isSyncAutomationsEnabled() {\n return isFeatureEnabled(Feature.SYNC_AUTOMATIONS)\n}\n\nexport async function isSSOEnforced(opts?: {\n config: SettingsInnerConfig\n}): Promise<boolean> {\n // never enforced in maintenance mode\n if (env.ENABLE_SSO_MAINTENANCE_MODE) {\n return false\n }\n\n // never enforced if the feature is not enabled\n const enforceable = await isEnforceableSSO()\n if (!enforceable) {\n return false\n }\n\n // get the enforced setting from config\n let config\n if (opts?.config) {\n config = opts.config\n } else {\n config = await configs.getSettingsConfig()\n }\n return !!config.isSSOEnforced\n}\n\nexport const checkSCIM = async (): Promise<boolean> => {\n const featureFlag = Feature.SCIM\n\n const featureEnabled = await isFeatureEnabled(featureFlag)\n const scimConfig = await configs.getSCIMConfig()\n\n if (!featureEnabled || !scimConfig?.enabled) {\n throw new FeatureDisabledError(\n `${featureFlag} is not currently enabled`,\n featureFlag\n )\n }\n\n return true\n}\n", "export * as cache from \"./cache\"\nexport * from \"./licenses\"\n", "export * from \"./cache\"\n", "import { redis } from \"@budibase/backend-core\"\n\nlet client: any\n\nconst init = async () => {\n client = await new redis.Client(redis.utils.Databases.LICENSES).init()\n}\n\nconst shutdown = async () => {\n if (client) {\n await client.finish()\n }\n}\n\nprocess.on(\"exit\", async () => {\n await shutdown()\n})\n\nexport const getClient = async () => {\n if (!client) {\n await init()\n }\n return client\n}\n", "import { API } from \"../../../utilities\"\nimport {\n GetLicenseRequest,\n License,\n LicenseActivateRequest,\n QuotaTriggeredRequest,\n QuotaUsageType,\n StaticQuotaName,\n} from \"@budibase/types\"\nimport {\n constants,\n env,\n events,\n HTTPError,\n installation,\n logging,\n tenancy,\n users,\n} from \"@budibase/backend-core\"\nimport { Response } from \"node-fetch\"\nimport * as db from \"../../../db\"\nimport { versions } from \"../../../constants\"\n\nconst api = new API(env.ACCOUNT_PORTAL_URL)\n\nconst getResponseErrorMessage = async (\n response: Response\n): Promise<string | undefined> => {\n try {\n const json = await response.json()\n if (json.message) {\n return json.message as string\n }\n } catch (e) {\n // do nothing\n }\n\n try {\n const text = await response.text()\n if (text) {\n return text\n }\n } catch (e) {\n // do nothing\n }\n}\n\nconst authAware = async <T>(fn: (authHeader: any) => Promise<T>) => {\n // don't send the request if self-hosted and no license key\n let licenseInfo\n let authHeader\n if (env.SELF_HOSTED) {\n licenseInfo = await db.licenseInfo.get()\n if (!licenseInfo) {\n return\n }\n authHeader = {\n [constants.Header.LICENSE_KEY]: licenseInfo.licenseKey,\n }\n } else {\n const tenantId = tenancy.getTenantId()\n authHeader = {\n [constants.Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,\n [constants.Header.TENANT_ID]: tenantId,\n }\n }\n\n return fn(authHeader)\n}\n\nlet _getLicense = async () => {\n return authAware(async (authHeader: any): Promise<License | undefined> => {\n const quotaUsage = await db.quotas.getQuotaUsage()\n\n // make sure user count is set\n if (quotaUsage.usageQuota.users == null) {\n const userCount = await users.getUserCount()\n console.info(`Syncing user count quota to ${userCount}`)\n quotaUsage.usageQuota.users = userCount\n await db.quotas.setUsage(\n userCount,\n StaticQuotaName.USERS,\n QuotaUsageType.STATIC\n )\n }\n\n const install = await installation.getInstallFromDB()\n const tenantId = tenancy.getTenantId()\n const installTenantId = await events.identification.getUniqueTenantId(\n tenantId\n )\n const installVersion = versions.getProVersion()\n\n const body: GetLicenseRequest = {\n quotaUsage,\n install: {\n id: install.installId,\n tenantId: installTenantId,\n version: installVersion,\n },\n }\n\n const response = await api.post(`/api/license`, {\n headers: { ...authHeader },\n body,\n })\n\n if (response.status === 404 || response.status === 403) {\n // no license for the tenant\n return\n }\n\n if (response.status !== 200) {\n const message = await getResponseErrorMessage(response)\n throw new HTTPError(`Error getting license: ${message}`, response.status)\n }\n\n return response.json()\n })\n}\n\n// special case for mocking this function\n// in other services - can't mock this externally\n// whenever pro is bundled into a single file\nif (env.isJest()) {\n _getLicense = jest.fn()\n}\n\nexport const getLicense = _getLicense\n\nexport const triggerQuota = (body: QuotaTriggeredRequest) => {\n return authAware(async (authHeader: any) => {\n const response = await api.post(`/api/license/usage/triggered`, {\n headers: { ...authHeader },\n body,\n })\n\n if (response.status !== 200) {\n const message = await getResponseErrorMessage(response)\n logging.logAlert(`Error triggering quota usage: ${message}`)\n }\n })\n}\n\nexport const activateLicenseKey = async (\n licenseKey: string\n): Promise<License | undefined> => {\n const installVersion = versions.getProVersion()\n\n const body: LicenseActivateRequest = {\n installVersion,\n }\n\n const response = await api.post(`/api/license/activate`, {\n headers: {\n [constants.Header.LICENSE_KEY]: licenseKey,\n },\n body,\n })\n\n // don't propagate the 403 to prevent logout\n if (response.status === 403) {\n throw new HTTPError(\"Invalid license key\", 400)\n }\n\n if (response.status !== 200) {\n const message = await getResponseErrorMessage(response)\n throw new HTTPError(\n `Error activating license key: ${message}`,\n response.status\n )\n }\n\n return response.json()\n}\n", "import fetch from \"node-fetch\"\nimport { Method, Options } from \"../types\"\nimport { logging } from \"@budibase/backend-core\"\n\nclass API {\n host: string\n\n constructor(host: string) {\n this.host = host\n }\n\n apiCall =\n (method: Method) =>\n async (url = \"\", options: Options = {}) => {\n if (!options.headers) {\n options.headers = {}\n }\n\n if (!options.headers[\"Content-Type\"]) {\n options.headers = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...options.headers,\n }\n }\n\n const json = options.headers[\"Content-Type\"] === \"application/json\"\n\n // add x-budibase-correlation-id header\n logging.correlation.setHeader(options.headers)\n\n const requestOptions = {\n method: method,\n body: json ? JSON.stringify(options.body) : options.body,\n headers: options.headers,\n // TODO: See if this is necessary\n credentials: \"include\",\n }\n\n return fetch(`${this.host}${url}`, requestOptions)\n }\n\n post = this.apiCall(Method.POST)\n get = this.apiCall(Method.GET)\n patch = this.apiCall(Method.PATCH)\n del = this.apiCall(Method.DELETE)\n put = this.apiCall(Method.PUT)\n}\n\nexport default API\n", "export * from \"./quotas\"\nexport * as utils from \"./utils\"\n", "import {\n UsageBreakdown,\n MonthlyUsage,\n MonthlyQuotaName,\n BREAKDOWN_QUOTA_NAMES,\n APP_QUOTA_NAMES,\n MeteredQuotaName,\n QuotaUsage,\n QuotaUsageType,\n StaticQuotaName,\n UsageValues,\n SetUsageValues,\n QuotaTriggers,\n} from \"@budibase/types\"\nimport { tenancy, db as dbCore, context, cache } from \"@budibase/backend-core\"\nimport * as utils from \"./utils\"\nconst { Writethrough } = cache.writethrough\n\nconst getDB = () => {\n return new Writethrough(tenancy.getGlobalDB())\n}\n\nexport const bustCache = async () => {\n const db = getDB()\n try {\n const usage = await db.get(dbCore.StaticDatabases.GLOBAL.docs.usageQuota)\n if (usage?._rev) {\n await db.remove(\n dbCore.StaticDatabases.GLOBAL.docs.usageQuota,\n usage?._rev\n )\n }\n } catch (e: any) {\n if (e.status !== 404) {\n throw e\n }\n }\n}\n\nexport const getQuotaUsage = async (): Promise<QuotaUsage> => {\n const db = getDB()\n let usage\n try {\n usage = await db.get(dbCore.StaticDatabases.GLOBAL.docs.usageQuota)\n utils.setCurrentMonth(usage)\n utils.setQuotaReset(usage)\n } catch (err: any) {\n if (err.status === 404) {\n // doc doesn't exist. Create it\n usage = utils.generateNewQuotaUsage()\n const response = await db.put(usage)\n usage._rev = response.rev\n } else {\n throw err\n }\n }\n\n // deprecated\n delete usage.usageLimits\n // unused\n delete usage.usageQuota.automationRuns\n delete usage.usageQuota.emails\n delete usage.usageQuota.storage\n delete usage.usageQuota.views\n delete usage.usageQuota.publishedApps\n delete usage.usageQuota.developers\n\n return usage\n}\n\nexport const setUsage = async (\n value: number,\n name: MeteredQuotaName,\n type: QuotaUsageType\n) => {\n return setAllUsage(name, type, { total: value })\n}\n\nexport const setUsagePerApp = async (\n appValues: { [key: string]: number },\n name: MeteredQuotaName,\n type: QuotaUsageType\n) => {\n const db = getDB()\n let quotaUsage = await getQuotaUsage()\n const total = Object.values(appValues).reduce((sum, num) => sum + num, 0)\n for (let [appId, value] of Object.entries(appValues)) {\n quotaUsage = coreUsageUpdate(\n quotaUsage,\n name,\n type,\n {\n total,\n app: value,\n },\n {\n appId,\n }\n )\n }\n const response = await db.put(quotaUsage)\n quotaUsage._rev = response.rev\n return quotaUsage\n}\n\nconst setBreakdown = (\n monthUsage: MonthlyUsage,\n name: MonthlyQuotaName,\n id: string,\n values: UsageValues\n) => {\n const breakdownName = utils.getBreakdownName(name, id)\n if (!breakdownName || !values?.breakdown) {\n return monthUsage\n }\n if (!monthUsage.breakdown) {\n monthUsage.breakdown = {}\n }\n if (!monthUsage.breakdown[breakdownName]) {\n monthUsage.breakdown[breakdownName] = {\n parent: name,\n values: {},\n }\n }\n const breakdown = monthUsage.breakdown[breakdownName] as UsageBreakdown\n breakdown.values[id] = values.breakdown\n return monthUsage\n}\n\nexport const setAppUsageValue = (\n quotaUsage: QuotaUsage,\n name: MeteredQuotaName,\n type: QuotaUsageType,\n opts: { id?: string; appId?: string } = {},\n values: UsageValues\n) => {\n let appId\n try {\n appId = dbCore.getProdAppID((opts?.appId || context.getAppId())!)\n } catch (err) {\n // ignore error for now\n }\n if (!appId || !values.app || !APP_QUOTA_NAMES.includes(name)) {\n return quotaUsage\n }\n if (!quotaUsage.apps?.[appId]) {\n quotaUsage.apps = {\n ...quotaUsage.apps,\n [appId]: utils.generateBaseQuotaUsage(),\n }\n }\n const appUsage = quotaUsage.apps[appId]\n switch (type) {\n case QuotaUsageType.STATIC:\n appUsage.usageQuota[name as StaticQuotaName] = values.app\n break\n case QuotaUsageType.MONTHLY:\n const currentMonth = utils.getCurrentMonthString()\n const monthlyName: MonthlyQuotaName = name as MonthlyQuotaName\n let monthUsage = appUsage.monthly[currentMonth]\n\n // init the new month if required\n if (!monthUsage) {\n appUsage.monthly[currentMonth] = utils.generateNewMonthlyQuotas()\n monthUsage = appUsage.monthly[currentMonth]\n }\n\n monthUsage[monthlyName] = values.app\n if (BREAKDOWN_QUOTA_NAMES.includes(monthlyName) && opts?.id) {\n monthUsage = setBreakdown(monthUsage, monthlyName, opts.id, values)\n }\n break\n }\n return quotaUsage\n}\n\nconst getAppUsageValue = (\n quotaUsage: QuotaUsage,\n type: QuotaUsageType,\n name: MeteredQuotaName,\n id?: string\n): { app?: number; breakdown?: number } => {\n if (!APP_QUOTA_NAMES.includes(name)) {\n return {}\n }\n let appId\n try {\n appId = dbCore.getProdAppID(context.getAppId()!)\n } catch (err) {\n // ignore error for now\n }\n if (!appId || !quotaUsage.apps || !quotaUsage.apps[appId]) {\n return { app: 0 }\n }\n const appUsage = quotaUsage.apps[appId]\n switch (type) {\n case QuotaUsageType.STATIC:\n if (appUsage.usageQuota?.[name as StaticQuotaName]) {\n return { app: appUsage.usageQuota[name as StaticQuotaName] }\n }\n break\n case QuotaUsageType.MONTHLY:\n const currentMonth = utils.getCurrentMonthString()\n const monthlyName = name as MonthlyQuotaName\n if (!appUsage.monthly?.[currentMonth]?.[monthlyName]) {\n break\n }\n const month = appUsage.monthly[currentMonth]\n const app = month[monthlyName]\n let breakdown\n const breakdownName = utils.getBreakdownName(monthlyName, id)\n\n if (breakdownName && id && month.breakdown?.[breakdownName]) {\n breakdown = month.breakdown[breakdownName]?.values[id]\n }\n return { app, breakdown: breakdown || 0 }\n }\n return { app: 0 }\n}\n\nconst setStaticTriggers = (\n name: StaticQuotaName,\n quotaUsage: QuotaUsage,\n triggers?: QuotaTriggers\n) => {\n // init triggers if not exists\n if (!quotaUsage.usageQuota.triggers) {\n quotaUsage.usageQuota.triggers = {}\n }\n // set triggers if supplied\n if (triggers) {\n quotaUsage.usageQuota.triggers[name] = triggers\n }\n}\n\nconst setMonthlyTriggers = (\n name: MonthlyQuotaName,\n currentMonth: string,\n quotaUsage: QuotaUsage,\n triggers?: QuotaTriggers\n) => {\n // init triggers if not exists\n if (!quotaUsage.monthly[currentMonth].triggers) {\n quotaUsage.monthly[currentMonth].triggers = {}\n }\n // set triggers if supplied\n if (triggers) {\n quotaUsage.monthly[currentMonth].triggers[name] = triggers\n }\n}\n\nconst coreUsageUpdate = (\n quotaUsage: QuotaUsage,\n name: MeteredQuotaName,\n type: QuotaUsageType,\n values: SetUsageValues,\n opts: { id?: string; appId?: string } = {}\n) => {\n if (type === QuotaUsageType.STATIC) {\n name = name as StaticQuotaName\n quotaUsage.usageQuota[name] = values.total\n setStaticTriggers(name, quotaUsage, values.triggers)\n } else if (type === QuotaUsageType.MONTHLY) {\n name = name as MonthlyQuotaName\n const currentMonth = utils.getCurrentMonthString()\n quotaUsage.monthly[currentMonth][name] = values.total\n setMonthlyTriggers(name, currentMonth, quotaUsage, values.triggers)\n } else {\n throw new Error(`Invalid usage type: ${type}`)\n }\n return setAppUsageValue(quotaUsage, name, type, opts, values)\n}\n\nexport const setAllUsage = async (\n name: MeteredQuotaName,\n type: QuotaUsageType,\n values: SetUsageValues,\n opts: { id?: string; appId?: string } = {}\n) => {\n const db = getDB()\n let quotaUsage = await getQuotaUsage()\n quotaUsage = coreUsageUpdate(quotaUsage, name, type, values, opts)\n const response = await db.put(quotaUsage)\n quotaUsage._rev = response.rev\n return quotaUsage\n}\n\nexport const getCurrentUsageValues = async (\n type: QuotaUsageType,\n name: MeteredQuotaName,\n id?: string\n): Promise<UsageValues> => {\n const quotaUsage = await getQuotaUsage()\n let total = 0,\n appValues: { app?: number; breakdown?: number } = {}\n switch (type) {\n case QuotaUsageType.STATIC:\n if (quotaUsage.usageQuota[name as StaticQuotaName]) {\n const staticName = name as StaticQuotaName\n total = quotaUsage.usageQuota[staticName]\n appValues = getAppUsageValue(quotaUsage, type, name, id)\n }\n break\n case QuotaUsageType.MONTHLY:\n const currentMonth = utils.getCurrentMonthString()\n const monthlyName = name as MonthlyQuotaName\n if (quotaUsage.monthly[currentMonth][monthlyName]) {\n total = quotaUsage.monthly[currentMonth][monthlyName]\n appValues = getAppUsageValue(quotaUsage, type, name, id)\n }\n break\n default:\n throw new Error(`Invalid usage type: ${type}`)\n }\n if (\n APP_QUOTA_NAMES.includes(name) &&\n !(appValues.app || appValues.breakdown)\n ) {\n appValues.app = appValues.app || 0\n appValues.breakdown = appValues.breakdown || 0\n }\n return { total, app: appValues.app, breakdown: appValues.breakdown }\n}\n", "import {\n BreakdownQuotaName,\n MonthlyUsage,\n MonthlyQuotaName,\n QuotaUsage,\n StaticQuotaName,\n BaseQuotaUsage,\n} from \"@budibase/types\"\nimport { db as dbCore } from \"@budibase/backend-core\"\n\nconst getNextQuotaReset = () => {\n const now = new Date()\n // first day of next month - always using the server time\n const nextMonth = new Date(now.getFullYear(), now.getMonth() + 1, 1)\n return nextMonth.toISOString()\n}\n\nexport const setQuotaReset = (usage: QuotaUsage) => {\n usage.quotaReset = getNextQuotaReset()\n}\n\nexport const getCurrentMonthString = (): string => {\n const date = new Date()\n const month = date.getMonth() + 1 // month is 0-based\n const year = date.getFullYear()\n return `${month}-${year}`\n}\n\nexport const generateBaseQuotaUsage = (): BaseQuotaUsage => {\n return {\n usageQuota: {\n [StaticQuotaName.APPS]: 0,\n [StaticQuotaName.ROWS]: 0,\n [StaticQuotaName.PLUGINS]: 0,\n [StaticQuotaName.USERS]: 0,\n [StaticQuotaName.USER_GROUPS]: 0,\n triggers: {},\n },\n monthly: {\n [getCurrentMonthString()]: generateNewMonthlyQuotas(),\n },\n }\n}\n\nexport const generateNewQuotaUsage = (): QuotaUsage => {\n const usage = {\n _id: dbCore.StaticDatabases.GLOBAL.docs.usageQuota,\n quotaReset: getNextQuotaReset(),\n ...generateBaseQuotaUsage(),\n apps: {},\n }\n setCurrentMonth(usage)\n return usage\n}\n\nexport const generateNewMonthlyQuotas = (): MonthlyUsage => {\n return {\n [MonthlyQuotaName.QUERIES]: 0,\n [MonthlyQuotaName.AUTOMATIONS]: 0,\n [MonthlyQuotaName.DAY_PASSES]: 0,\n triggers: {},\n }\n}\n\nexport const setCurrentMonth = (usage: QuotaUsage) => {\n const currentMonth = getCurrentMonthString()\n\n // set the monthly field if it doesn't exist\n if (!usage.monthly) {\n usage.monthly = {}\n }\n\n // set the monthly > currentMonth field if it doesn't exist\n if (!usage.monthly[currentMonth]) {\n usage.monthly[currentMonth] = generateNewMonthlyQuotas()\n }\n\n // set the current field to the current month\n usage.monthly.current = usage.monthly[currentMonth]\n}\n\nexport const getBreakdownName = (\n name: MonthlyQuotaName,\n id?: string\n): BreakdownQuotaName | undefined => {\n if (!id || !name) {\n return\n }\n switch (name) {\n case MonthlyQuotaName.AUTOMATIONS:\n return BreakdownQuotaName.AUTOMATIONS\n case MonthlyQuotaName.QUERIES:\n return dbCore.isTableId(id)\n ? BreakdownQuotaName.ROW_QUERIES\n : dbCore.isDatasourceId(id)\n ? BreakdownQuotaName.DATASOURCE_QUERIES\n : undefined\n }\n}\n", "import { SelfHostLicenseInfo } from \"../types\"\nimport { tenancy, StaticDatabases } from \"@budibase/backend-core\"\n\nconst newLicenseInfo = (licenseKey: string): SelfHostLicenseInfo => {\n return {\n _id: StaticDatabases.GLOBAL.docs.licenseInfo,\n licenseKey: licenseKey,\n }\n}\n\nconst save = async (licenseInfo: SelfHostLicenseInfo) => {\n const db = tenancy.getGlobalDB()\n const response = await db.put(licenseInfo)\n licenseInfo._rev = response.rev\n return licenseInfo\n}\n\nexport const create = async (\n licenseKey: string\n): Promise<SelfHostLicenseInfo> => {\n const licenseInfo = newLicenseInfo(licenseKey)\n return save(licenseInfo)\n}\n\nexport const get = async (): Promise<SelfHostLicenseInfo | undefined> => {\n const db = tenancy.getGlobalDB()\n try {\n // await to catch error\n return await db.get(StaticDatabases.GLOBAL.docs.licenseInfo)\n } catch (err: any) {\n if (err.status === 404) {\n return undefined\n }\n throw err\n }\n}\n\nexport const destroy = async (): Promise<{\n id?: string\n rev?: string\n} | void> => {\n const info = await get()\n if (!info) {\n // nothing to destroy\n return\n }\n const db = tenancy.getGlobalDB()\n return db.remove(StaticDatabases.GLOBAL.docs.licenseInfo, info._rev)\n}\n", "import { DatabaseQueryOpts, UserGroup } from \"@budibase/types\"\nimport {\n db as dbCore,\n users as usersCore,\n tenancy,\n utils,\n SEPARATOR,\n UNICODE_MAX,\n DocumentType,\n} from \"@budibase/backend-core\"\nimport { GroupViewMode, createGroupUserLookupView } from \"./views\"\n\nconst GROUP_PREFIX = `${DocumentType.GROUP}${SEPARATOR}`\n\ntype UserGroupsViewParams = DatabaseQueryOpts & {\n emailSearch?: string\n bookmark?: string\n}\n/**\n * Gets parameters for retrieving groups.\n */\nexport function getUserGroupsParams(\n groupId: string | null | undefined,\n otherProps = {}\n) {\n if (!groupId) {\n groupId = \"\"\n }\n const start = groupId?.startsWith(DocumentType.GROUP) ? \"\" : GROUP_PREFIX\n return {\n ...otherProps,\n startkey: `${start}${groupId}`,\n endkey: `${start}${groupId}${UNICODE_MAX}`,\n }\n}\n\n/**\n * Gets parameters for retrieving groups.\n */\nexport function getGroupUsersParams(\n groupId: string,\n otherProps: UserGroupsViewParams = {}\n): DatabaseQueryOpts {\n if (!groupId) {\n groupId = \"\"\n }\n const { emailSearch, bookmark, ...props } = otherProps\n\n if (!emailSearch) {\n return {\n ...otherProps,\n startkey: `${GroupViewMode.SEARCH_BY_ID}${groupId}`,\n endkey: `${GroupViewMode.SEARCH_BY_ID}${groupId}${UNICODE_MAX}`,\n startkey_docid: bookmark,\n }\n }\n\n const params = {\n ...props,\n startkey: `${GroupViewMode.SEARCH_BY_EMAIL}${groupId}${\n bookmark || emailSearch\n }`,\n endkey: `${GroupViewMode.SEARCH_BY_EMAIL}${groupId}${emailSearch}${UNICODE_MAX}`,\n }\n return params\n}\n\n/**\n * Generates a new user group ID\n * @returns {string} The new user group ID which info can be stored under.\n */\nexport function generateUserGroupID() {\n return `${GROUP_PREFIX}${utils.newid()}`\n}\n\nexport async function getGroupUsers(\n groupId: string,\n params?: UserGroupsViewParams\n) {\n const db = tenancy.getGlobalDB()\n\n const userDocs = (await dbCore.queryView(\n dbCore.ViewName.USER_BY_GROUP,\n getGroupUsersParams(groupId, params),\n db,\n createGroupUserLookupView,\n { arrayResponse: true }\n )) as { userId: string; email: string }[]\n\n const users =\n userDocs.map((doc: any) => ({\n _id: doc.userId,\n email: doc.email,\n })) || []\n return users\n}\n\nasync function enrichGroup(group: UserGroup) {\n group.users = await getGroupUsers(group._id!)\n return group\n}\n\nasync function cleanupUsers(group: UserGroup) {\n // get the users that need cleaned up\n const enriched = await enrichGroup(group)\n const userIds = enriched.users?.map(user => user._id) as string[]\n const users = await usersCore.bulkGetGlobalUsersById(userIds)\n const toUpdate = []\n for (let user of users) {\n if (!user.userGroups) {\n continue\n }\n const lengthBefore = user.userGroups.length\n user.userGroups = user.userGroups.filter(groupId => groupId !== group._id)\n if (user.userGroups.length !== lengthBefore) {\n toUpdate.push(user)\n }\n }\n if (toUpdate.length) {\n await usersCore.bulkUpdateGlobalUsers(toUpdate)\n }\n}\n\nexport async function fetch() {\n const db = tenancy.getGlobalDB()\n try {\n const groups = (\n await db.allDocs(\n getUserGroupsParams(null, {\n include_docs: true,\n })\n )\n ).rows.map((row: any) => row.doc)\n const enrichedGroups = []\n for (let group of groups) {\n enrichedGroups.push(enrichGroup(group))\n }\n return await Promise.all(enrichedGroups)\n } catch (err) {\n throw err\n }\n}\n\nexport async function get(groupId: string) {\n const db = tenancy.getGlobalDB()\n try {\n const group = await db.get(groupId)\n return await enrichGroup(group)\n } catch (err: any) {\n throw err\n }\n}\n\nexport async function getBulk(\n groupIds: string[],\n opts = { enriched: true }\n): Promise<UserGroup[]> {\n const db = tenancy.getGlobalDB()\n try {\n const groups = (\n await db.allDocs({\n keys: groupIds,\n include_docs: true,\n })\n ).rows.map((row: any) => row.doc)\n if (opts?.enriched) {\n const enrichedGroups: any = []\n for (let group of groups) {\n enrichedGroups.push(enrichGroup(group))\n }\n return await Promise.all(enrichedGroups)\n } else {\n return groups\n }\n } catch (err: any) {\n throw err\n }\n}\n\nexport async function save(\n group: UserGroup\n): Promise<{ id: string; rev: string }> {\n const db = tenancy.getGlobalDB()\n\n return await db.put(group)\n}\n\nexport async function bulkSave(\n groups: UserGroup[]\n): Promise<{ id: string; rev?: string }[]> {\n const db = tenancy.getGlobalDB()\n return await db.bulkDocs(groups)\n}\n\nexport async function destroy(\n groupId: string,\n revision: string\n): Promise<{ id: string }> {\n const db = tenancy.getGlobalDB()\n const group = await db.get(groupId)\n let resp = await db.remove(groupId, revision)\n await cleanupUsers(group)\n return resp\n}\n\nexport async function getByName(name: string) {\n try {\n const groups = await dbCore.directCouchFind(tenancy.getGlobalDBName(), {\n selector: {\n name: {\n $regex: `^(?i)${name}$`,\n },\n },\n limit: 1,\n })\n const [group] = groups.rows\n if (!group) {\n return\n }\n return await enrichGroup(group)\n } catch (err: any) {\n throw err\n }\n}\n", "import { AuditLogDoc, SearchIndex } from \"@budibase/types\"\nimport { context, db as dbCore } from \"@budibase/backend-core\"\n\nexport async function createAuditLogSearchIndex() {\n const db = context.getAuditLogsDB()\n let designDoc\n try {\n designDoc = await db.get(\"_design/database\")\n } catch (err: any) {\n if (err.status === 404) {\n designDoc = { _id: \"_design/database\" }\n }\n }\n // this is a very specific function given that it is only for audit logs\n const fn = function (auditLog: AuditLogDoc) {\n if (auditLog._id && !auditLog._id.startsWith(\"al_\")) {\n return\n }\n const ignoredFields = [\"_id\", \"_rev\", \"metadata\"]\n let wholeString = Object.values(auditLog.metadata).join(\" \")\n for (let key of Object.keys(auditLog)) {\n if (ignoredFields.includes(key)) {\n continue\n }\n const value = auditLog[key as keyof AuditLogDoc]\n if (typeof value === \"string\") {\n //@ts-ignore\n // eslint-disable-next-line no-undef\n index(key, value.toLowerCase(), { facet: true })\n wholeString += ` ${value}`\n }\n }\n if (auditLog.fallback) {\n for (let value of Object.values(auditLog.fallback)) {\n if (value && typeof value === \"string\") {\n wholeString += ` ${value}`\n }\n }\n }\n //@ts-ignore\n // eslint-disable-next-line no-undef\n index(\"all\", wholeString)\n }\n\n designDoc.indexes = {\n [SearchIndex.AUDIT]: {\n index: fn.toString(),\n analyzer: {\n default: \"whitespace\",\n fields: {\n all: \"standard\",\n },\n name: \"perfield\",\n },\n },\n }\n await db.put(designDoc)\n}\n", "import { tenancy, db as dbCore } from \"@budibase/backend-core\"\n\nconst { ViewName, SEPARATOR, DocumentType, createView } = dbCore\n\nconst USER_PREFIX = DocumentType.USER + SEPARATOR\n\nexport enum GroupViewMode {\n SEARCH_BY_ID = \"g_\",\n SEARCH_BY_EMAIL = \"e_\",\n}\n\nexport async function createGroupUserLookupView() {\n const db = tenancy.getGlobalDB()\n const viewJs = `function(doc) {\n if (doc._id.startsWith(\"${USER_PREFIX}\") && Array.isArray(doc.userGroups)) {\n for (let groupId of doc.userGroups) {\n emit(\"${GroupViewMode.SEARCH_BY_ID}\" + groupId, { email: doc.email, userId: doc._id })\n emit(\"${GroupViewMode.SEARCH_BY_EMAIL}\" + groupId + doc.email, { email: doc.email, userId: doc._id })\n }\n }\n }`\n await createView(db, viewJs, ViewName.USER_BY_GROUP)\n}\n", "import {\n db as dbCore,\n tenancy,\n users as userCore,\n} from \"@budibase/backend-core\"\nimport {\n AppBackup,\n AppBackupFetchOpts,\n AppBackupMetadata,\n AppBackupTrigger,\n AppBackupType,\n ConstantQuotaName,\n PutResponse,\n} from \"@budibase/types\"\nimport { pagination } from \"./utils/pagination\"\nimport { createAppBackupTriggerView } from \"./utils/views\"\nimport { getOldestRetentionDate } from \"./utils/retention\"\nimport { GENERIC_PAGE_SIZE } from \"../constants\"\n\ntype FilterOpts = {\n startDate?: string\n endDate?: string\n trigger?: AppBackupTrigger\n type?: AppBackupType\n}\n\nexport async function oldestBackupDate() {\n return getOldestRetentionDate(ConstantQuotaName.APP_BACKUPS_RETENTION_DAYS)\n}\n\nconst APP_BACKUP_PREFIX = `${dbCore.DocumentType.APP_BACKUP}${dbCore.SEPARATOR}`\n\nasync function getAppBackupParams(\n appId: string,\n filters: FilterOpts,\n otherProps: any = {}\n) {\n const maxStartDate = await oldestBackupDate()\n const prodAppId = dbCore.getProdAppID(appId)\n let startKey = prodAppId,\n endKey = prodAppId\n if (filters.trigger && filters.type) {\n let basePart = `${dbCore.SEPARATOR}${filters.trigger}`\n basePart += `${dbCore.SEPARATOR}${filters.type}`\n startKey += basePart\n endKey += basePart\n }\n // check start date within limits\n if (!filters.startDate || filters.startDate < maxStartDate) {\n filters.startDate = maxStartDate\n }\n if (filters.startDate) {\n endKey += `${dbCore.SEPARATOR}${filters.startDate}`\n }\n if (filters.endDate) {\n startKey += `${dbCore.SEPARATOR}${filters.endDate}`\n }\n return {\n ...otherProps,\n descending: true,\n startkey: `${APP_BACKUP_PREFIX}${startKey}${dbCore.UNICODE_MAX}`,\n endkey: `${APP_BACKUP_PREFIX}${endKey}`,\n }\n}\n\nasync function getAppBackupsByTrigger(\n db: any,\n params: any\n): Promise<AppBackup[]> {\n let backups: AppBackup[] = []\n try {\n const queryIndex = dbCore.getQueryIndex(\n dbCore.ViewName.APP_BACKUP_BY_TRIGGER\n )\n backups = await db.query(queryIndex, params)\n } catch (err: any) {\n if (err != null && err.error === \"not_found\") {\n await createAppBackupTriggerView()\n return getAppBackupsByTrigger(db, params)\n } else {\n throw err\n }\n }\n return backups\n}\n\nexport function generateAppBackupID(appId: string, timestamp: string) {\n return `${APP_BACKUP_PREFIX}${appId}${dbCore.SEPARATOR}${timestamp}`\n}\n\nexport async function fetchAppBackups(\n appId: string,\n opts: AppBackupFetchOpts = {}\n) {\n const db = tenancy.getGlobalDB()\n let backups\n const pageSize = opts.limit || GENERIC_PAGE_SIZE\n const params = await getAppBackupParams(appId, opts, {\n include_docs: true,\n limit: pageSize + 1,\n })\n if (opts.page) {\n params.startkey = opts.page\n }\n if (!opts.trigger || !opts.type) {\n backups = await db.allDocs(params)\n } else {\n backups = await getAppBackupsByTrigger(db, params)\n }\n const pageData = pagination<AppBackup>(backups, {\n paginate: opts.paginate,\n pageSize,\n })\n // add in users\n const userIds = [\n ...new Set(\n pageData.data\n .filter(backup => backup.createdBy)\n .map(backup => backup.createdBy!)\n ),\n ] as string[]\n const users = await userCore.bulkGetGlobalUsersById(userIds, {\n cleanup: true,\n })\n for (let user of users) {\n for (let data of pageData.data) {\n if (user?._id === data.createdBy) {\n data.createdBy = user\n }\n }\n }\n return pageData\n}\n\nexport async function storeAppBackupMetadata(\n metadata: AppBackupMetadata,\n opts: { filename?: string; docId?: string; docRev?: string } = {}\n) {\n const db = tenancy.getGlobalDB()\n const prodAppId = dbCore.getProdAppID(metadata.appId)\n let _id = generateAppBackupID(prodAppId, metadata.timestamp)\n const appBackupDoc: AppBackup = {\n ...metadata,\n _id,\n appId: prodAppId,\n name: metadata.name,\n }\n if (opts.filename) {\n appBackupDoc.filename = opts.filename\n }\n if (opts.docId && opts.docRev) {\n appBackupDoc._id = opts.docId\n appBackupDoc._rev = opts.docRev\n }\n if (metadata.createdBy) {\n appBackupDoc.createdBy = dbCore.getGlobalIDFromUserMetadataID(\n metadata.createdBy as string\n )\n }\n return (await db.put(appBackupDoc)) as PutResponse\n}\n\nexport async function updateAppBackupMetadata(backupId: string, name: string) {\n const db = tenancy.getGlobalDB()\n const metadata = (await db.get(backupId)) as AppBackup\n metadata.name = name\n return (await db.put(metadata)) as PutResponse\n}\n\nexport async function deleteAppBackupMetadata(backupId: string) {\n const db = tenancy.getGlobalDB()\n const backupDoc = await db.get(backupId)\n await db.remove(backupDoc._id, backupDoc._rev)\n}\n\nexport async function getAppBackupMetadata(backupId: string) {\n const db = tenancy.getGlobalDB()\n return (await db.get(backupId)) as AppBackup\n}\n", "export function pagination<T>(\n response: any,\n opts?: { paginate?: boolean; pageSize: number }\n): { data: T[]; hasNextPage: boolean; nextPage?: string } {\n const data = response.rows.map((row: any) => {\n return row.doc ? row.doc : row\n })\n if (!opts?.paginate) {\n return { data, hasNextPage: false }\n }\n const hasNextPage = data.length > opts?.pageSize\n return {\n data: data.slice(0, opts?.pageSize),\n hasNextPage,\n nextPage: hasNextPage ? data[opts?.pageSize]?._id : undefined,\n }\n}\n", "import { tenancy, context, db as dbCore } from \"@budibase/backend-core\"\nconst { ViewName, AutomationViewMode, SEPARATOR, DocumentType, createView } =\n dbCore\nconst LOG_PREFIX = DocumentType.AUTOMATION_LOG + SEPARATOR\nconst APP_BACKUP_PREFIX = DocumentType.APP_BACKUP + SEPARATOR\n\n/**\n * A separate view that allows us to perform queries by the automation ID and time series, while the\n * main all_docs allows access to time series only\n */\nexport async function createLogByAutomationView() {\n const db = context.getProdAppDB()\n const viewJs = `function(doc) {\n if (doc._id.startsWith(\"${LOG_PREFIX}\")) {\n let autoId = doc.automationId + \"${SEPARATOR}\"\n let status = doc.status + \"${SEPARATOR}\"\n let autoKey = \"${AutomationViewMode.AUTOMATION}${SEPARATOR}\" + autoId + doc.createdAt\n let statusKey = \"${AutomationViewMode.STATUS}${SEPARATOR}\" + status + doc.createdAt\n let allKey = \"${AutomationViewMode.ALL}${SEPARATOR}\" + status + autoId + doc.createdAt\n emit(statusKey)\n emit(autoKey)\n emit(allKey)\n }\n }`\n await createView(db, viewJs, ViewName.AUTOMATION_LOGS)\n}\n\nexport async function createAppBackupTriggerView() {\n const db = tenancy.getGlobalDB()\n const viewJs = `function(doc) {\n if (doc._id.startsWith(\"${APP_BACKUP_PREFIX}\") && doc.type && doc.trigger) {\n let full = doc.appId + \"${SEPARATOR}\"\n full += doc.trigger.toLowerCase() + \"${SEPARATOR}\"\n full += doc.type.toLowerCase() + \"${SEPARATOR}\"\n emit(\"${APP_BACKUP_PREFIX}\" + full + doc.timestamp) \n }\n }`\n await createView(db, viewJs, ViewName.APP_BACKUP_BY_TRIGGER)\n}\n", "import { ConstantQuotaName, QuotaType } from \"@budibase/types\"\nimport { licensing } from \"../../sdk\"\nimport { licenses } from \"../../constants\"\n\nconst MAX_DATE = new Date(8640000000000000).toISOString()\nconst ONE_DAY_MILLIS = 1000 * 60 * 60 * 24\n\nexport async function getOldestRetentionDate(quotaName: ConstantQuotaName) {\n const license = await licensing.cache.getCachedLicense()\n const retentionDays =\n license.quotas?.[QuotaType.CONSTANT]?.[quotaName]?.value || 0\n if (retentionDays === licenses.UNLIMITED) {\n return new Date(MAX_DATE).toISOString()\n } else {\n return new Date(\n new Date().getTime() - ONE_DAY_MILLIS * retentionDays\n ).toISOString()\n }\n}\n", "import { License, PlanModel, PlanType } from \"@budibase/types\"\nimport * as quotas from \"./quotas\"\n\nexport const UNLIMITED = -1\n\n/**\n * The license used when no license is present.\n */\nexport const CLOUD_FREE_LICENSE: License = {\n features: [],\n quotas: {\n usage: {\n monthly: {\n ...quotas.queries(UNLIMITED),\n ...quotas.automations(200),\n ...quotas.dayPasses(UNLIMITED),\n },\n static: {\n ...quotas.apps(UNLIMITED),\n ...quotas.rows(2000),\n ...quotas.users(5),\n ...quotas.userGroups(0),\n ...quotas.plugins(10),\n },\n },\n constant: {\n ...quotas.automationLogRetentionDays(1),\n ...quotas.appBackupRetentionDays(0),\n },\n },\n plan: {\n type: PlanType.FREE,\n usesInvoicing: false,\n model: PlanModel.PER_USER,\n },\n}\n\n/**\n * The license used when no license is present.\n */\nexport const SELF_FREE_LICENSE: License = {\n features: [],\n quotas: {\n usage: {\n monthly: {\n ...quotas.queries(UNLIMITED),\n ...quotas.automations(UNLIMITED),\n ...quotas.dayPasses(UNLIMITED),\n },\n static: {\n ...quotas.rows(UNLIMITED),\n ...quotas.apps(UNLIMITED),\n ...quotas.users(UNLIMITED),\n ...quotas.userGroups(0),\n ...quotas.plugins(10),\n },\n },\n constant: {\n ...quotas.automationLogRetentionDays(1),\n ...quotas.appBackupRetentionDays(0),\n },\n },\n plan: {\n type: PlanType.FREE,\n usesInvoicing: false,\n model: PlanModel.PER_USER,\n },\n}\n\n/**\n * Unlimited license to support unit tests.\n */\nexport const UNLIMITED_LICENSE: License = {\n features: [],\n quotas: {\n usage: {\n monthly: {\n ...quotas.queries(UNLIMITED),\n ...quotas.automations(UNLIMITED),\n ...quotas.dayPasses(UNLIMITED),\n },\n static: {\n ...quotas.apps(UNLIMITED),\n ...quotas.rows(UNLIMITED),\n ...quotas.users(UNLIMITED),\n ...quotas.userGroups(UNLIMITED),\n ...quotas.plugins(UNLIMITED),\n },\n },\n constant: {\n ...quotas.automationLogRetentionDays(UNLIMITED),\n ...quotas.appBackupRetentionDays(UNLIMITED),\n },\n },\n plan: {\n type: PlanType.FREE,\n usesInvoicing: false,\n model: PlanModel.PER_USER,\n },\n}\n", "import {\n StaticQuotaName,\n MonthlyQuotaName,\n ConstantQuotaName,\n} from \"@budibase/types\"\n\nexport const UNLIMITED = -1\n\n// Static\n\nexport const rows = (value: number) => {\n return {\n [StaticQuotaName.ROWS]: {\n name: \"Rows\",\n value,\n triggers: [90, 100],\n },\n }\n}\n\nexport const apps = (value: number) => {\n return {\n [StaticQuotaName.APPS]: {\n name: \"Apps\",\n value,\n triggers: [100],\n },\n }\n}\n\nexport const users = (value: number) => {\n return {\n [StaticQuotaName.USERS]: {\n name: \"Users\",\n value,\n triggers: [80, 100],\n },\n }\n}\n\nexport const userGroups = (value: number) => {\n return {\n [StaticQuotaName.USER_GROUPS]: {\n name: \"User Groups\",\n value,\n triggers: [80, 100],\n },\n }\n}\n\nexport const plugins = (value: number) => {\n return {\n [StaticQuotaName.PLUGINS]: {\n name: \"Plugins\",\n value,\n triggers: [90, 100],\n },\n }\n}\n\n// Monthly\n\nexport const queries = (value: number) => {\n return {\n [MonthlyQuotaName.QUERIES]: {\n name: \"Queries\",\n value,\n triggers: [],\n },\n }\n}\n\nexport const automations = (value: number) => {\n return {\n [MonthlyQuotaName.AUTOMATIONS]: {\n name: \"Automations\",\n value,\n triggers: [80, 90, 100],\n },\n }\n}\n\nexport const dayPasses = (value: number) => {\n return {\n [MonthlyQuotaName.DAY_PASSES]: {\n name: \"Day Passes\",\n value,\n triggers: [80, 90, 100],\n },\n }\n}\n\n// Constant\n\nexport const automationLogRetentionDays = (value: number) => {\n return {\n [ConstantQuotaName.AUTOMATION_LOG_RETENTION_DAYS]: {\n name: \"Automation Logs\",\n value,\n triggers: [], // n/a\n },\n }\n}\n\nexport const appBackupRetentionDays = (value: number) => {\n return {\n [ConstantQuotaName.APP_BACKUPS_RETENTION_DAYS]: {\n name: \"App Backups\",\n value,\n triggers: [], // n/a\n },\n }\n}\n", "import { env, objectStore, utils } from \"@budibase/backend-core\"\n\nimport fs from \"fs\"\nimport path from \"path\"\n\n/**\n * Retrieve the version to store against a license.\n * In local dev, a random id is used instead to facilitate easy license refreshing.\n */\nexport const getLicenseVersion = () => {\n if (env.isDev()) {\n const DEV_VER_FILENAME = \"dev-version.txt\"\n const verFile = path.join(objectStore.budibaseTempDir(), DEV_VER_FILENAME)\n if (fs.existsSync(verFile)) {\n return fs.readFileSync(verFile, \"utf8\")\n } else {\n const devVer = utils.newid()\n fs.writeFileSync(verFile, devVer)\n return devVer\n }\n } else {\n return getProVersion()\n }\n}\n\nexport const getProVersion = () => {\n const version = env.VERSION\n if (!version) {\n throw new Error(\"No budibase pro version was specified\")\n }\n return version\n}\n", "export const GENERIC_PAGE_SIZE = 9\n", "import {\n EnvironmentVariablesDoc,\n EnvironmentVariablesDocDecrypted,\n} from \"@budibase/types\"\nimport { tenancy, StaticDatabases, encryption } from \"@budibase/backend-core\"\nimport LRU from \"lru-cache\"\n\nconst MAX_CACHE_ITEMS = 1000\nconst cache = new LRU<string, EnvironmentVariablesDocDecrypted>({\n max: MAX_CACHE_ITEMS,\n})\n\nexport function getEnvVarID() {\n return StaticDatabases.GLOBAL.docs.environmentVariables\n}\n\nexport function getCacheEnvVarID(rev?: string) {\n const tenantId = tenancy.getTenantId()\n return `${tenantId}/${getEnvVarID()}/${rev || \"\"}`\n}\n\nexport async function get(): Promise<EnvironmentVariablesDocDecrypted> {\n const id = getEnvVarID()\n const db = tenancy.getGlobalDB()\n let encrypted: EnvironmentVariablesDoc | undefined,\n notFound = false\n try {\n encrypted = (await db.get(id)) as EnvironmentVariablesDoc\n } catch (err: any) {\n if (err.status == 404) {\n notFound = true\n } else {\n throw err\n }\n }\n // now we have the document, can check the revision, see if we have it cached\n const cacheKey = getCacheEnvVarID(encrypted?._rev)\n const cached = cache.get(cacheKey)\n if (cached) {\n return cached\n }\n // wasn't found, decrypt and return\n let finalDoc: EnvironmentVariablesDocDecrypted\n if (!notFound && encrypted) {\n finalDoc = {\n ...encrypted,\n variables: JSON.parse(\n encryption.decrypt(\n encrypted.variables,\n encryption.SecretOption.ENCRYPTION\n )\n ),\n }\n } else {\n finalDoc = {\n _id: id,\n variables: {},\n }\n }\n cache.set(cacheKey, finalDoc)\n return finalDoc\n}\n\nexport async function update(\n doc: EnvironmentVariablesDocDecrypted\n): Promise<{ id: string; rev: string }> {\n const id = getEnvVarID()\n const db = tenancy.getGlobalDB()\n return await db.put({\n _id: doc._id || id,\n _rev: doc._rev || undefined,\n variables: encryption.encrypt(\n JSON.stringify(doc.variables),\n encryption.SecretOption.ENCRYPTION\n ),\n })\n}\n", "import fs from \"fs\"\nimport { join } from \"path\"\nimport { tmpdir } from \"os\"\nimport jwt from \"jsonwebtoken\"\nimport { License } from \"@budibase/types\"\nimport { env } from \"@budibase/backend-core\"\n\nconst SUB_DIRECTORY = env.isTest() ? \".budibase-test\" : \".budibase\"\nconst DIRECTORY = join(tmpdir(), SUB_DIRECTORY)\n\nconst OFFLINE_LICENSE_FILE = \"offline_license.txt\"\nconst LICENSE_FILE_PATH = join(DIRECTORY, OFFLINE_LICENSE_FILE)\n\nif (!fs.existsSync(DIRECTORY)) {\n fs.mkdirSync(DIRECTORY)\n}\n\nconst PUBLIC_KEY =\n \"-----BEGIN PUBLIC KEY-----\\n\" +\n \"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvz3jePLCFBXZ19c8Dpkv\\n\" +\n \"XtSgOhKFOcvQdo/LV0KJRUzQWDPWuO4ILtBtnqhjtIzZH4CH0qCYBet5L6Qr4CM1\\n\" +\n \"l2HXiAD1Q2rlHNW9wDaYyKb1F5f+v4RyqCAyzlkwRdksmkLeECTboojNnmRCrE3C\\n\" +\n \"8suunQP5bEScqEY2kclqzSf8e6xqMzPUg3mL/pNa1iEv7TuLbU9nJfgR36l0WmZY\\n\" +\n \"94fWnSaT8OSXSqcxsaByf06gfS3HAoTJNc7eqz1Hf9fUORQGPUAnFK8cT3SfdA36\\n\" +\n \"d/o3ZWE1TTj1zYwlCLN5qRKr3hU8nC3xEYNEbkB9SfTRaOq9Q7P8WmfLkoCPm3pR\\n\" +\n \"mwIDAQAB\\n\" +\n \"-----END PUBLIC KEY-----\\n\"\n\nexport function getOfflineLicense(): License | undefined {\n try {\n return getOfflineLicenseFromDisk()\n } catch (e) {\n console.error(\"error retrieving offline license\", e)\n }\n}\n\nfunction getOfflineLicenseFromDisk(): License | undefined {\n if (fs.existsSync(LICENSE_FILE_PATH)) {\n const token = fs.readFileSync(LICENSE_FILE_PATH, { encoding: \"utf-8\" })\n return jwt.verify(token, PUBLIC_KEY, { algorithms: [\"RS256\"] }) as License\n }\n}\n\nexport function writeOfflineLicenseToDisk(signedLicense: string) {\n fs.writeFileSync(LICENSE_FILE_PATH, signedLicense, { encoding: \"utf-8\" })\n}\n\nexport function deleteOfflineLicense() {\n fs.rmSync(LICENSE_FILE_PATH, { force: true })\n}\n", "import * as licenseClient from \"./client\"\nimport * as db from \"../../../db\"\nimport * as Cache from \"../cache\"\nimport { licenses as constants } from \"../../../constants\"\nimport { env } from \"@budibase/backend-core\"\nimport { License } from \"@budibase/types\"\nimport * as offline from \"./offline\"\n\nexport const getLicenseInfo = async () => {\n return db.licenseInfo.get()\n}\n\nexport const deleteLicenseInfo = async () => {\n await db.licenseInfo.destroy()\n await Cache.refresh()\n}\n\nexport const activateLicenseKey = async (licenseKey: string) => {\n await licenseClient.activateLicenseKey(licenseKey)\n await db.licenseInfo.create(licenseKey)\n await Cache.refresh()\n}\n\nexport const getLicense = async () => {\n // try account portal first\n let license = await licenseClient.getLicense()\n\n // try offline license if not exists - limited to dev currently\n if (!license && env.isDev()) {\n license = offline.getOfflineLicense()\n }\n return license\n}\n\nexport const getFreeLicense = (): License => {\n if (env.SELF_HOSTED) {\n return constants.SELF_FREE_LICENSE\n } else {\n return constants.CLOUD_FREE_LICENSE\n }\n}\n", "import { GetCachedLicenseOptions, CachedLicense } from \"../../../types\"\nimport * as Redis from \"./redis\"\nimport * as Licenses from \"../licenses\"\nimport { tenancy, env } from \"@budibase/backend-core\"\nimport { versions } from \"../../../constants\"\n\nconst EXPIRY_SECONDS = 3600\n\nexport const refresh = async () => {\n await invalidate()\n await getCachedLicense()\n}\n\nlet _getCachedLicense = async (\n ctx?: any,\n opts: GetCachedLicenseOptions = { refreshVersion: true }\n): Promise<CachedLicense> => {\n const currentVersion = versions.getLicenseVersion()\n const tenantId = tenancy.getTenantId()\n\n // try cache\n const client = await Redis.getClient()\n let license: CachedLicense | undefined = await client.get(tenantId)\n\n // wipe the license to re-populate as it doesn't match pro version\n if (license && license.version !== currentVersion && opts.refreshVersion) {\n console.log(\n `Refreshing license version from=${license.version} to=${currentVersion}`\n )\n // delete so that we don't re-read the same cached\n // version from account-portal on fetch (in cloud)\n await client.delete(tenantId)\n license = undefined\n }\n\n if (!license) {\n // no license - re-populate the cache\n const populate = opts.populateLicense\n ? opts.populateLicense\n : Licenses.getLicense\n license = await populate(tenantId)\n\n // still no license - use the free license\n if (!license) {\n const populateFree = opts.populateFreeLicense\n ? opts.populateFreeLicense\n : Licenses.getFreeLicense\n license = populateFree(ctx, tenantId)\n }\n\n // store the refresh time before caching\n license!.refreshedAt = new Date().toISOString()\n // add the version to the license\n license!.version = currentVersion\n await client.store(tenantId, license, EXPIRY_SECONDS)\n }\n\n return license!\n}\n\n// special case for re-using pro mocks\n// in other services - can't mock this externally\n// whenever pro is bundled into a single file\nif (env.isJest()) {\n _getCachedLicense = jest.fn()\n}\n\nexport const getCachedLicense = _getCachedLicense\n\nexport const invalidate = async () => {\n const tenantId = tenancy.getTenantId()\n const client = await Redis.getClient()\n await client.delete(tenantId)\n}\n", "import { SettingsBrandingConfig, SettingsInnerConfig } from \"@budibase/types\"\nimport * as features from \"../features\"\n\nconst DEFAULT_BRANDING_CONFIG: SettingsBrandingConfig = {\n faviconUrl: undefined,\n faviconUrlEtag: undefined,\n\n emailBrandingEnabled: true,\n testimonialsEnabled: true,\n platformTitle: undefined,\n loginHeading: undefined,\n loginButton: undefined,\n\n metaDescription: undefined,\n metaImageUrl: undefined,\n metaTitle: undefined,\n}\n\nexport async function getBrandingConfig(\n config: SettingsInnerConfig & SettingsBrandingConfig\n): Promise<SettingsBrandingConfig> {\n // when branding is disabled we always return the default\n // values no matter what is in the database\n if (!(await features.isBrandingEnabled())) {\n return DEFAULT_BRANDING_CONFIG\n } else {\n return {\n faviconUrl: config.faviconUrl,\n faviconUrlEtag: config.faviconUrlEtag,\n emailBrandingEnabled: config.emailBrandingEnabled,\n testimonialsEnabled: config.testimonialsEnabled,\n platformTitle: config.platformTitle,\n loginHeading: config.loginHeading,\n loginButton: config.loginButton,\n metaDescription: config.metaDescription,\n metaImageUrl: config.metaImageUrl,\n metaTitle: config.metaTitle,\n }\n }\n}\n", "export * from \"../../db/quotas\"\nexport * from \"./helpers\"\nexport * from \"./quotas\"\n", "import { quotas as constants } from \"../../constants\"\nimport {\n APP_QUOTA_NAMES,\n ConstantQuotaName,\n isConstantQuota,\n isMonthlyQuota,\n isStaticQuota,\n LockName,\n LockType,\n MeteredQuotaName,\n MonthlyQuotaName,\n Quota,\n QuotaTriggeredRequest,\n QuotaTriggers,\n QuotaType,\n QuotaUsage,\n QuotaUsageType,\n StaticQuotaName,\n} from \"@budibase/types\"\nimport * as licensing from \"../licensing\"\nimport * as db from \"../../db\"\nimport {\n context,\n tenancy,\n UsageLimitError,\n locks,\n logging,\n ErrorCode,\n} from \"@budibase/backend-core\"\nimport { getQuotaUsage } from \"../../db/quotas\"\n\n// INCREMENT\n\ninterface IncrementOptions {\n /**\n * The function being wrapped by this quota usage.\n */\n fn?: () => Promise<any>\n /**\n * If provided, the new usage value will be calculated using this function.\n */\n valueFn?: () => Promise<number>\n /**\n * Turn on or off error logging when a quotas has been exceeded\n */\n suppressErrorLog?: boolean\n /**\n * If using a specific resource which has an ID, can pass this ID for granular quotas.\n */\n id?: string\n}\n\nexport const increment = (\n name: MeteredQuotaName,\n type: QuotaUsageType,\n opts?: IncrementOptions\n) => {\n return tryIncrement(1, name, type, opts)\n}\n\nexport const incrementMany = (\n change: number,\n name: MeteredQuotaName,\n type: QuotaUsageType,\n opts?: IncrementOptions\n) => {\n return tryIncrement(change, name, type, opts)\n}\n\nconst tryIncrement = async (\n change: number,\n name: MeteredQuotaName,\n type: QuotaUsageType,\n opts: IncrementOptions = {}\n) => {\n // dry run first to check that the quota is not exceeded\n await updateUsage(change, name, type, {\n dryRun: true,\n suppressErrorLog: opts.suppressErrorLog,\n id: opts.id,\n })\n\n // run the actual function\n let result\n if (opts.fn) {\n result = await opts.fn()\n }\n\n // increment the quota\n await updateUsage(change, name, type, {\n dryRun: false,\n valueFn: opts.valueFn,\n suppressErrorLog: opts.suppressErrorLog,\n id: opts.id,\n })\n\n return result\n}\n\n// DECREMENT\n\ninterface DecrementOptions {\n /**\n * If provided, the new usage value will be calculated using this function.\n */\n valueFn?: () => Promise<number>\n /**\n * If using a specific resource which has an ID, can pass this ID for granular quotas.\n */\n id?: string\n}\n\nexport const decrement = (\n name: MeteredQuotaName,\n type: QuotaUsageType,\n opts: DecrementOptions = {}\n) => {\n return updateUsage(-1, name, type, opts)\n}\n\nexport const decrementMany = (\n change: number,\n name: MeteredQuotaName,\n type: QuotaUsageType,\n opts: DecrementOptions = {}\n) => {\n return updateUsage(-change, name, type, opts)\n}\n\nexport const set = async (\n name: MeteredQuotaName,\n type: QuotaUsageType,\n value: number\n) => {\n return db.quotas.setUsage(value, name, type)\n}\n\ninterface UpdateUsageOptions {\n /**\n * If provided and true, the usage quota will not be updated.\n * Used to verify that a quota is not exceeded before running.\n */\n dryRun?: boolean\n /**\n * If provided, the new usage value will be calculated using this function.\n */\n valueFn?: () => Promise<number>\n /**\n * Turn on or off error logging when a quotas has been exceeded\n */\n suppressErrorLog?: boolean\n /**\n * If using a specific resource which has an ID, can pass this ID for granular quotas.\n */\n id?: string\n}\n\nconst getExistingTriggers = (\n type: QuotaUsageType,\n name: MeteredQuotaName,\n quotaUsage: QuotaUsage\n): QuotaTriggers => {\n if (type == QuotaUsageType.STATIC) {\n const triggers = quotaUsage.usageQuota.triggers\n return triggers ? triggers[name as StaticQuotaName] || {} : {}\n } else {\n const currentMonthString = db.quotas.utils.getCurrentMonthString()\n const triggers = quotaUsage.monthly[currentMonthString].triggers\n return triggers ? triggers[name as MonthlyQuotaName] || {} : {}\n }\n}\n\nconst triggerQuota = async (\n name: MeteredQuotaName,\n quota: Quota,\n percentage: number,\n resetDate?: string\n) => {\n try {\n // use a lock so that we never send the email more than once\n // under high throughput where there may be stale reads\n await locks.doWithLock(\n {\n type: LockType.TRY_ONCE,\n name: LockName.TRIGGER_QUOTA,\n resource: name, // use the quota name for extra uniqueness on the lock\n ttl: 10000, // auto expire after 10 seconds\n },\n async () => {\n const request: QuotaTriggeredRequest = {\n percentage,\n name: quota.name,\n }\n if (resetDate) {\n request.resetDate = resetDate\n }\n await licensing.client.triggerQuota(request)\n }\n )\n } catch (e: any) {\n // swallow error so we don't interrupt quota update\n logging.logAlert(\"Error triggering quota\", e)\n }\n}\n\nconst checkTriggers = async (\n type: QuotaUsageType,\n name: MeteredQuotaName,\n totalValue: number,\n quota: Quota\n): Promise<QuotaTriggers> => {\n const usage = await getQuotaUsage()\n const resetDate =\n type === QuotaUsageType.MONTHLY ? usage.quotaReset : undefined\n const triggers = await getExistingTriggers(type, name, usage)\n\n const quotaTriggers = quota.triggers\n let percentage = (totalValue / quota.value) * 100\n if (percentage > 100) {\n // sometimes quotas may overflow - set back to 100% for below logic\n percentage = 100\n }\n\n for (const [index, triggerPercentage] of quotaTriggers.entries()) {\n // set the trigger time for all triggers this update applies to\n const isTriggered =\n percentage >= triggerPercentage && quota.value !== constants.UNLIMITED\n if (isTriggered) {\n // don't overwrite the time if already set\n if (!triggers[triggerPercentage]) {\n triggers[triggerPercentage] = new Date().toISOString()\n\n // send the trigger request for the highest trigger met by this update\n const nextTriggerPercentage = quotaTriggers[index + 1] || 100\n const nextIsTriggered = percentage >= nextTriggerPercentage\n const isAtTrigger = percentage === triggerPercentage // to account for 100%\n const sendNotification = !nextIsTriggered || isAtTrigger\n\n if (sendNotification) {\n await triggerQuota(name, quota, percentage, resetDate)\n }\n }\n } else {\n triggers[triggerPercentage] = undefined\n }\n }\n\n return triggers\n}\n\nexport const updateUsage = async (\n usageChange: number,\n name: MeteredQuotaName,\n type: QuotaUsageType,\n opts: UpdateUsageOptions = {}\n) => {\n let appId = null\n try {\n appId = context.getAppId()\n } catch (err) {\n // ignore error for now\n }\n // need an app ID for these\n const isAppQuota = APP_QUOTA_NAMES.includes(name)\n if (isAppQuota && !appId) {\n throw new Error(\"App context required for quota update\")\n }\n try {\n const licensedQuota = await getLicensedQuota(QuotaType.USAGE, name, type)\n let {\n total: totalValue,\n app: appValue,\n breakdown: breakdownValue,\n } = await db.quotas.getCurrentUsageValues(type, name, opts.id)\n\n // increment / decrement the quota\n totalValue += usageChange\n if (appValue != null) {\n appValue += usageChange\n }\n if (breakdownValue != null) {\n breakdownValue += usageChange\n }\n\n let triggers: QuotaTriggers = {}\n if (!opts.dryRun) {\n triggers = await checkTriggers(type, name, totalValue, licensedQuota)\n }\n\n if (\n licensedQuota.value !== constants.UNLIMITED &&\n totalValue > licensedQuota.value &&\n usageChange > 0 // allow for decrementing usage when the quota is already exceeded\n ) {\n throw new UsageLimitError(\n `Licensed ${licensedQuota.name} of ${licensedQuota.value} has been exceeded`,\n licensedQuota.name\n )\n }\n\n // never go negative if the quota has previously been exceeded\n totalValue = Math.max(0, totalValue)\n if (appValue) {\n appValue = Math.max(0, appValue)\n }\n if (breakdownValue) {\n breakdownValue = Math.max(0, breakdownValue)\n }\n\n if (opts.dryRun) {\n // exit early\n return\n }\n\n // if a value function is provided\n // use it to calculate the new value instead of incrementing / decrementing\n if (opts.valueFn) {\n totalValue = await opts.valueFn()\n appValue = totalValue\n }\n // update the usage quotas\n await db.quotas.setAllUsage(\n name,\n type,\n {\n total: totalValue,\n app: appValue,\n breakdown: breakdownValue,\n triggers,\n },\n opts\n )\n } catch (err: any) {\n if (!opts.suppressErrorLog) {\n console.error(`Error updating usage quotas for ${name}`, err)\n }\n // re-throw any error - if the error was caused by a usage limit being exceeded\n // this will prevent the subsequent operation e.g. create app, from running\n throw err\n }\n}\n\nexport const getLicensedQuota = async (\n quotaType: QuotaType,\n name: MonthlyQuotaName | StaticQuotaName | ConstantQuotaName,\n usageType?: QuotaUsageType\n): Promise<Quota> => {\n const license = await licensing.cache.getCachedLicense()\n\n if (!license) {\n const tenantId = tenancy.getTenantId()\n throw new Error(\"License not found for tenant id \" + tenantId)\n }\n\n if (usageType && isStaticQuota(quotaType, usageType, name)) {\n return license.quotas[quotaType as QuotaType.USAGE][\n usageType as QuotaUsageType.STATIC\n ][name]\n } else if (usageType && isMonthlyQuota(quotaType, usageType, name)) {\n return license.quotas[quotaType as QuotaType.USAGE][\n usageType as QuotaUsageType.MONTHLY\n ][name]\n } else if (isConstantQuota(quotaType, name)) {\n return license.quotas[quotaType as QuotaType.CONSTANT][name]\n } else {\n throw new Error(\"Invalid quota type\")\n }\n}\n\nexport const usageLimitIsExceeded = async (\n name: MeteredQuotaName,\n type: QuotaUsageType\n) => {\n try {\n await updateUsage(1, name, type, { dryRun: true })\n return false\n } catch (e: any) {\n if (e.code === ErrorCode.USAGE_LIMIT_EXCEEDED) {\n return true\n }\n throw e\n }\n}\n", "import * as quotas from \"./../quotas\"\nimport { QuotaUsageType, StaticQuotaName } from \"@budibase/types\"\nimport { db } from \"@budibase/backend-core\"\n\ninterface AppOpts {\n appId?: string\n}\n\n// DEV\n\nconst getDevAppsCount = async () => {\n const apps = await db.getAllApps({ dev: true })\n return apps ? apps.length : 0\n}\n\nexport const addApp = async (addAppFn: any, { appId }: AppOpts = {}) => {\n return quotas.increment(StaticQuotaName.APPS, QuotaUsageType.STATIC, {\n fn: addAppFn,\n valueFn: getDevAppsCount,\n id: appId,\n })\n}\n\nexport const removeApp = async ({ appId }: AppOpts = {}) => {\n return quotas.decrement(StaticQuotaName.APPS, QuotaUsageType.STATIC, {\n valueFn: getDevAppsCount,\n id: appId,\n })\n}\n", "import * as quotas from \"./../quotas\"\nimport { QuotaUsageType, MonthlyQuotaName } from \"@budibase/types\"\n\ntype QueryOpts = {\n datasourceId?: string\n}\n\nexport const addQuery = async (\n runQueryFunction: any,\n { datasourceId }: QueryOpts = {}\n) => {\n return quotas.increment(MonthlyQuotaName.QUERIES, QuotaUsageType.MONTHLY, {\n fn: runQueryFunction,\n id: datasourceId,\n })\n}\n", "import * as quotas from \"./../quotas\"\nimport { QuotaUsageType, StaticQuotaName } from \"@budibase/types\"\n\ntype RowOpts = {\n tableId?: string\n}\n\nexport const addRow = async (addRowFn: any, { tableId }: RowOpts = {}) => {\n return quotas.increment(StaticQuotaName.ROWS, QuotaUsageType.STATIC, {\n fn: addRowFn,\n id: tableId,\n })\n}\n\nexport const removeRow = async ({ tableId }: RowOpts = {}) => {\n return quotas.decrement(StaticQuotaName.ROWS, QuotaUsageType.STATIC, {\n id: tableId,\n })\n}\n\nexport const addRows = async (\n change: number,\n addRowsFn?: () => Promise<any>,\n { tableId }: RowOpts = {}\n) => {\n return quotas.incrementMany(\n change,\n StaticQuotaName.ROWS,\n QuotaUsageType.STATIC,\n { fn: addRowsFn, id: tableId }\n )\n}\n\nexport const removeRows = async (change: number, { tableId }: RowOpts = {}) => {\n return quotas.decrementMany(\n change,\n StaticQuotaName.ROWS,\n QuotaUsageType.STATIC,\n { id: tableId }\n )\n}\n", "import * as quotas from \"./../quotas\"\nimport { QuotaUsageType, MonthlyQuotaName } from \"@budibase/types\"\n\ntype AutomationOpts = {\n automationId?: string\n}\n\nexport const addAutomation = async (\n runAutomationFn: any,\n { automationId }: AutomationOpts = {}\n) => {\n return quotas.increment(\n MonthlyQuotaName.AUTOMATIONS,\n QuotaUsageType.MONTHLY,\n { fn: runAutomationFn, id: automationId }\n )\n}\n", "import * as quotas from \"./../quotas\"\nimport {\n BBContext,\n ContextUser,\n PlanType,\n MonthlyQuotaName,\n QuotaUsageType,\n} from \"@budibase/types\"\nimport { cache, tenancy, utils, env } from \"@budibase/backend-core\"\nimport { users } from \"../../..\"\n\nconst ONE_DAY = 1000 * 60 * 60 * 24\n\nexport async function checkDayPass(ctx: BBContext) {\n const user = ctx.user\n // may be unauthenticated or an internal api endpoint with no user id\n if (!user || !user._id) {\n return\n }\n let dayPassRecordedAt\n if (user.dayPassRecordedAt) {\n dayPassRecordedAt = new Date(user.dayPassRecordedAt)\n }\n\n const nowMinus1Day = new Date(Date.now() - ONE_DAY)\n // if day pass is being used for first time in over 24 hours\n if (\n !dayPassRecordedAt ||\n dayPassRecordedAt.getTime() < nowMinus1Day.getTime()\n ) {\n try {\n await recordActivityInAccountPortal(user)\n await recordDayPassOnQuotas()\n await recordDayPassTimeOnUser(user)\n } catch (e: any) {\n // if there was a usage limit error check if we are serving an app\n // if we are - redirect to home page - not allowed to view app\n // messaging on the page will indicate the problem\n if (e.code == \"usage_limit_exceeded\") {\n if (utils.isServingApp(ctx)) {\n ctx.redirect(\"/\")\n }\n } else {\n throw e\n }\n }\n }\n}\n\n/**\n * Increment the day pass quota count.\n */\nasync function recordDayPassOnQuotas() {\n return quotas.increment(MonthlyQuotaName.DAY_PASSES, QuotaUsageType.MONTHLY, {\n suppressErrorLog: true,\n })\n}\n\n/**\n * Record the time a day pass has been used on a user.\n */\nasync function recordDayPassTimeOnUser(user: ContextUser) {\n // load the db user to avoid any staleness from redis\n const db = tenancy.getGlobalDB()\n let dbUser = await db.get(user._id)\n\n // set the recorded time on the user\n const now = new Date()\n const nowString = new Date().toISOString()\n user.dayPassRecordedAt = nowString\n dbUser.dayPassRecordedAt = nowString\n\n try {\n console.log(`Recording day pass for user=${user._id}`)\n await db.put(dbUser)\n } catch (e: any) {\n if (e.status === 409) {\n console.warn(`Conflict recording day pass for user=${user._id}`)\n // multiple requests being sent at once are prone to conflicts\n // check if the time has already been updated correctly before throwing\n dbUser = await db.get(user._id)\n if (\n !dbUser.dayPassRecordedAt ||\n new Date(dbUser.dayPassRecordedAt).getDay() !== now.getDay()\n ) {\n console.error(`Day pass not recorded for user=${user._id}`)\n throw e\n } else {\n console.log(`Day pass already recorded for user=${user._id}`)\n }\n } else {\n throw e\n }\n }\n\n // reset the user cache - next request will populate\n await cache.user.invalidateUser(user._id!)\n}\n\nasync function recordActivityInAccountPortal(user: ContextUser) {\n // self-hosted free plans don't record activity\n if (env.SELF_HOSTED && user.license?.plan?.type === PlanType.FREE) {\n return\n }\n // skip activity if account portal is disabled in dev\n if (env.isDev() && env.DISABLE_ACCOUNT_PORTAL) {\n return\n }\n await users.createActivity(user._id!)\n}\n", "import * as quotas from \"./../quotas\"\nimport { QuotaUsageType, StaticQuotaName } from \"@budibase/types\"\n\nexport const addGroup = async <T>(addGroupFn: () => Promise<T>): Promise<T> => {\n return quotas.increment(StaticQuotaName.USER_GROUPS, QuotaUsageType.STATIC, {\n fn: addGroupFn,\n })\n}\n\nexport const removeGroup = async () => {\n return quotas.decrement(StaticQuotaName.USER_GROUPS, QuotaUsageType.STATIC)\n}\n", "import * as quotas from \"./../quotas\"\nimport { QuotaUsageType, StaticQuotaName } from \"@budibase/types\"\n\nexport const addPlugin = async (addPluginFn: any) => {\n return quotas.increment(StaticQuotaName.PLUGINS, QuotaUsageType.STATIC, {\n fn: addPluginFn,\n })\n}\n\nexport const removePlugin = async () => {\n return quotas.decrement(StaticQuotaName.PLUGINS, QuotaUsageType.STATIC)\n}\n\nexport const updatePluginCount = async (count: number) => {\n return quotas.set(StaticQuotaName.PLUGINS, QuotaUsageType.STATIC, count)\n}\n", "import * as quotas from \"../quotas\"\nimport { QuotaUsageType, StaticQuotaName } from \"@budibase/types\"\nimport { users } from \"@budibase/backend-core\"\nimport * as licenseClient from \"../../licensing/licenses/client\"\n\nexport const addUsers = async <T>(\n change: number,\n addUsersFn?: () => Promise<T>\n): Promise<T> => {\n const res = await quotas.incrementMany(\n change,\n StaticQuotaName.USERS,\n QuotaUsageType.STATIC,\n {\n fn: addUsersFn,\n valueFn: users.getUserCount,\n }\n )\n\n // send a get license request to sync the user count to the account\n await licenseClient.getLicense()\n\n return res\n}\n\nexport const removeUsers = async (change: number) => {\n await quotas.decrementMany(\n change,\n StaticQuotaName.USERS,\n QuotaUsageType.STATIC,\n {\n valueFn: users.getUserCount,\n }\n )\n\n // send a get license request to sync the user count to the account\n await licenseClient.getLicense()\n}\n", "export * from \"./users\"\n", "import { API } from \"../../utilities\"\nimport * as db from \"../../db\"\nimport { Options } from \"../../types\"\nimport { Response } from \"node-fetch\"\nimport {\n PostAccountUserActivity,\n PostAccountUserActivityResponse,\n} from \"@budibase/types\"\nimport {\n env,\n constants,\n featureFlags,\n tenancy,\n logging,\n} from \"@budibase/backend-core\"\n\n// TODO: Migrate license client to use this new generic API\n\nconst api = new API(env.ACCOUNT_PORTAL_URL)\n\nexport const createActivity = async (\n userId: string,\n data: PostAccountUserActivity\n): Promise<PostAccountUserActivityResponse | undefined> => {\n const response = await send(\n (options: Options) => api.post(`/api/users/${userId}/activity`, options),\n {\n body: data,\n }\n )\n\n if (!response) {\n // not enabled - return\n return\n }\n\n if (response.status !== 201) {\n const text = await response.text()\n const message = `Error creating account user activity: ${text}`\n logging.logAlert(message)\n throw new Error(message)\n }\n\n return response.json()\n}\n\nconst send = async (\n requestFn: (options: Options) => Promise<Response>,\n baseOptions: Options\n) => {\n const isLicensingEnabled = await featureFlags.isEnabled(\n featureFlags.TenantFeatureFlag.LICENSING\n )\n\n if (isLicensingEnabled) {\n const headers = await authorizationHeaders()\n const options: Options = {\n ...baseOptions,\n headers: {\n ...baseOptions.headers,\n ...headers,\n },\n }\n return requestFn(options)\n }\n}\n\nconst authorizationHeaders = async (): Promise<{ [key: string]: string }> => {\n if (env.SELF_HOSTED) {\n const licenseInfo = await db.licenseInfo.get()\n if (licenseInfo) {\n const licenseKey = licenseInfo.licenseKey\n return {\n [constants.Header.LICENSE_KEY]: licenseKey,\n }\n } else {\n return {}\n }\n } else {\n const tenantId = tenancy.getTenantId()\n return {\n [constants.Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,\n [constants.Header.TENANT_ID]: tenantId,\n }\n }\n}\n", "import { PostAccountUserActivity } from \"@budibase/types\"\nimport * as api from \"../api\"\n\nexport const createActivity = async (userId: string) => {\n const data: PostAccountUserActivity = {\n timestamp: Date.now(),\n }\n\n return api.createActivity(userId, data)\n}\n", "// called logged to avoid IDEs detecting the \"logs\" directory as ignorable\nexport * as logs from \"./logging\"\n", "import {\n AutomationResults,\n AutomationStatus,\n Automation,\n AutomationLogPage,\n} from \"@budibase/types\"\nimport { context, db as dbUtils } from \"@budibase/backend-core\"\nimport {\n getAllLogs,\n getLogsByView,\n oldestLogDate as _oldestLogDate,\n writeLog,\n clearOldHistory,\n updateAppMetadataWithErrors,\n getStatus,\n} from \"../../../db/automations\"\n\nexport const oldestLogDate = _oldestLogDate\n\nasync function getLogs(\n startDate: string,\n status?: string,\n automationId?: string,\n page?: string\n): Promise<AutomationLogPage> {\n let response: AutomationLogPage\n let endDate = new Date().toISOString()\n const maxStartDate = await oldestLogDate()\n // check that the start date does not exceed license\n if (!startDate || startDate < maxStartDate) {\n startDate = maxStartDate\n }\n if (automationId || status) {\n response = await getLogsByView(startDate, endDate, {\n automationId,\n status,\n page,\n })\n } else {\n response = await getAllLogs(startDate, endDate, {\n status,\n page,\n docs: true,\n paginate: true,\n })\n }\n return response\n}\n\nexport interface LogSearchOptions {\n startDate: string\n status?: AutomationStatus\n automationId?: string\n page?: string\n}\n\nexport async function logSearch(options: LogSearchOptions) {\n // before querying logs, make sure old logs are cleared out\n await clearOldHistory()\n return await getLogs(\n options.startDate,\n options.status,\n options.automationId,\n options.page\n )\n}\n\nexport async function storeLog(\n automation: Automation,\n results: AutomationResults\n) {\n // can disable this if un-needed in self-host, also only do this for prod apps\n if (!dbUtils.isProdAppID(context.getAppId())) {\n return\n }\n const status = getStatus(results)\n const id = await writeLog(automation, results)\n // need to note on the app metadata that there is an error, store what the error is\n if (status === AutomationStatus.ERROR) {\n await updateAppMetadataWithErrors([id])\n }\n // clear up old logging for app\n await clearOldHistory()\n}\n", "import {\n AppMetadataErrors,\n Automation,\n AutomationLog,\n AutomationLogPage,\n AutomationResults,\n AutomationStatus,\n ConstantQuotaName,\n} from \"@budibase/types\"\nimport { createLogByAutomationView } from \"./utils/views\"\nimport { cache, context, db as dbUtils, logging } from \"@budibase/backend-core\"\nimport { backOff } from \"../utilities/delay\"\nimport { pagination } from \"./utils/pagination\"\nimport { getOldestRetentionDate } from \"./utils/retention\"\nconst {\n SEPARATOR,\n UNICODE_MAX,\n DocumentType,\n AutomationViewMode,\n ViewName,\n getQueryIndex,\n} = dbUtils\nimport { GENERIC_PAGE_SIZE } from \"../constants\"\n\nconst EARLIEST_DATE = new Date(0).toISOString()\n// set a maximum number that can be expired at once, control the speed of reads/writes\nconst EXPIRED_LIMIT = 100\n\nexport const oldestLogDate = async () => {\n return getOldestRetentionDate(ConstantQuotaName.AUTOMATION_LOG_RETENTION_DAYS)\n}\n\nfunction getAutomationLogParams(\n startDate: string,\n endDate: string,\n { status, automationId }: { status?: string; automationId?: string } = {},\n otherProps: any = {}\n) {\n const automationBase = automationId ? `${automationId}${SEPARATOR}` : \"\"\n const statusBase = status ? `${status}${SEPARATOR}` : \"\"\n let base\n if (status && automationId) {\n base = `${AutomationViewMode.ALL}${SEPARATOR}${statusBase}${automationBase}`\n } else if (status) {\n base = `${AutomationViewMode.STATUS}${SEPARATOR}${statusBase}`\n } else if (automationId) {\n base = `${AutomationViewMode.AUTOMATION}${SEPARATOR}${automationBase}`\n } else {\n base = `${DocumentType.AUTOMATION_LOG}${SEPARATOR}`\n }\n return {\n ...otherProps,\n descending: true,\n startkey: `${base}${endDate}${UNICODE_MAX}`,\n endkey: `${base}${startDate}`,\n }\n}\n\nexport function getStatus(results: AutomationResults) {\n let status = AutomationStatus.SUCCESS\n let first = true\n for (let step of results.steps) {\n const lcStatus = step.outputs?.status?.toLowerCase()\n const stoppedError = lcStatus === \"stopped_error\"\n // skip the trigger, its always successful if automation ran\n if (first && !stoppedError) {\n first = false\n continue\n }\n if (stoppedError) {\n status = AutomationStatus.STOPPED_ERROR\n break\n } else if (!step.outputs?.success) {\n status = AutomationStatus.ERROR\n break\n } else if (lcStatus === \"stopped\") {\n status = AutomationStatus.STOPPED\n break\n }\n }\n return status\n}\n\nexport function generateAutomationLogID(\n isoDate: string,\n status: string,\n automationId: string\n) {\n return `${DocumentType.AUTOMATION_LOG}${SEPARATOR}${isoDate}${SEPARATOR}${automationId}${SEPARATOR}${status}`\n}\n\nexport async function getAllLogs(\n startDate: string,\n endDate: string,\n opts: {\n docs: boolean\n status?: string\n paginate?: boolean\n page?: string\n limit?: number\n } = { docs: true }\n): Promise<AutomationLogPage> {\n let db = context.getProdAppDB()\n if (!(await db.exists())) {\n db = context.getDevAppDB()\n }\n let optional: any = { status: opts.status }\n let limit = opts?.limit\n ? opts.limit\n : opts?.paginate\n ? GENERIC_PAGE_SIZE + 1\n : undefined\n const params = getAutomationLogParams(startDate, endDate, optional, {\n include_docs: opts.docs,\n limit,\n })\n if (opts?.page) {\n params.startkey = opts.page\n }\n let response = await db.allDocs(params)\n return pagination<AutomationLog>(response, {\n paginate: opts?.paginate,\n pageSize: GENERIC_PAGE_SIZE,\n })\n}\n\nexport async function getLogsByView(\n startDate: string,\n endDate: string,\n viewParams: { automationId?: string; status?: string; page?: string } = {}\n): Promise<AutomationLogPage> {\n let db = context.getProdAppDB()\n if (!(await db.exists())) {\n db = context.getDevAppDB()\n }\n let response\n try {\n let optional = {\n automationId: viewParams?.automationId,\n status: viewParams?.status,\n }\n const params = getAutomationLogParams(startDate, endDate, optional, {\n include_docs: true,\n limit: GENERIC_PAGE_SIZE,\n })\n if (viewParams?.page) {\n params.startkey = viewParams.page\n }\n response = await db.query(getQueryIndex(ViewName.AUTOMATION_LOGS), params)\n } catch (err: any) {\n if (\n err != null &&\n (err.name === \"not_found\" || err.error === \"not_found\")\n ) {\n await createLogByAutomationView()\n return getLogsByView(startDate, endDate, viewParams)\n } else {\n throw err\n }\n }\n return pagination<AutomationLog>(response)\n}\n\nexport async function writeLog(\n automation: Automation,\n results: AutomationResults\n) {\n const db = context.getProdAppDB()\n const automationId = automation._id as string\n const name = automation.name\n const status = getStatus(results)\n const isoDate = new Date().toISOString()\n const id = generateAutomationLogID(isoDate, status, automationId)\n const log: AutomationLog = {\n // results contain automationId and status for view\n ...results,\n automationId,\n status,\n automationName: name,\n createdAt: isoDate,\n _id: id,\n }\n await db.put(log)\n return id\n}\n\nexport async function updateAppMetadataWithErrors(\n logIds: string[],\n { clearing } = { clearing: false }\n) {\n const db = context.getProdAppDB()\n // this will try multiple times with a delay between to update the metadata\n await backOff(async () => {\n const metadata = await db.get(dbUtils.DocumentType.APP_METADATA)\n for (let logId of logIds) {\n const parts = logId.split(dbUtils.SEPARATOR)\n const autoId = `${parts[parts.length - 3]}${dbUtils.SEPARATOR}${\n parts[parts.length - 2]\n }`\n let errors: AppMetadataErrors = {}\n if (metadata.automationErrors) {\n errors = metadata.automationErrors as AppMetadataErrors\n }\n if (!Array.isArray(errors[autoId])) {\n errors[autoId] = []\n }\n const idx = errors[autoId].indexOf(logId)\n if (clearing && idx !== -1) {\n errors[autoId].splice(idx, 1)\n } else {\n errors[autoId].push(logId)\n }\n // if clearing and reach zero, this will pass and will remove the element\n if (errors[autoId].length === 0) {\n delete errors[autoId]\n }\n metadata.automationErrors = errors\n }\n await db.put(metadata)\n // don't update cache until after DB put, make sure it has been stored successfully\n await cache.app.invalidateAppMetadata(metadata.appId, metadata)\n }, \"Failed to update app metadata with automation log error\")\n}\n\nexport async function getExpiredLogs(): Promise<AutomationLogPage> {\n const expiredEnd = await oldestLogDate()\n\n try {\n return await getAllLogs(EARLIEST_DATE, expiredEnd, {\n docs: false,\n paginate: false,\n limit: EXPIRED_LIMIT,\n })\n } catch (err) {\n return { data: [], hasNextPage: false }\n }\n}\n\nexport async function clearOldHistory() {\n const db = context.getProdAppDB()\n try {\n const expired = await getExpiredLogs()\n if (!expired.data || expired.data.length === 0) {\n return\n }\n const toDelete = expired.data.map((doc: any) => ({\n _id: doc.id,\n _rev: doc.value.rev,\n _deleted: true,\n }))\n const errorLogIds = expired.data\n .filter((doc: any) => {\n const parts = doc.id.split(dbUtils.SEPARATOR)\n const status = parts[parts.length - 1]\n return status === AutomationStatus.ERROR\n })\n .map((doc: any) => doc.id)\n await db.bulkDocs(toDelete)\n if (errorLogIds.length) {\n await updateAppMetadataWithErrors(errorLogIds, { clearing: true })\n }\n } catch (err) {\n logging.logAlert(\n `Failed to cleanup automation log history - Database \"${db.name}\"`,\n err\n )\n }\n}\n", "import { logging } from \"@budibase/backend-core\"\n\nexport function randomDelay(fn: any) {\n return new Promise((resolve, reject) => {\n setTimeout(async () => {\n try {\n resolve(await fn())\n } catch (err) {\n reject(err)\n }\n }, Math.floor(Math.random() * 1000))\n })\n}\n\nexport async function backOff(fn: any, errMsg: string) {\n let attempts = 5,\n success = false,\n response,\n first = true\n for (; attempts > 0; attempts--) {\n try {\n if (first) {\n response = await fn()\n } else {\n response = await exports.randomDelay(fn)\n }\n success = true\n break\n } catch (err) {\n // ignore error here\n }\n }\n if (!success) {\n logging.logAlert(`Failed to backoff`, errMsg)\n }\n return response\n}\n", "export * from \"./groups\"\n", "import { HTTPError } from \"@budibase/backend-core\"\n\nexport class GroupNameUnavailableError extends HTTPError {\n constructor(groupName: string) {\n super(`Group name \"${groupName}\" is unavailable`, 409)\n }\n}\n", "import {\n db as dbUtils,\n events,\n roles,\n users as usersCore,\n logging,\n cache,\n} from \"@budibase/backend-core\"\nimport { UserGroup, User } from \"@budibase/types\"\nimport * as db from \"../../db\"\nimport * as quotas from \"../quotas\"\nimport { GroupNameUnavailableError } from \"../../api/errors\"\n\nasync function findHighestRole(groups: UserGroup[], appId: string) {\n try {\n let potentialRoles: any[] = []\n for (let group of groups) {\n if (group.roles) {\n potentialRoles.push(group.roles[dbUtils.getProdAppID(appId)])\n }\n }\n const allRoleNumbersArr = await Promise.all(\n potentialRoles.map(async roleId => {\n return {\n [roleId]: await roles.roleToNumber(roleId),\n }\n })\n )\n let highestGroupRole\n let originalNum = 0\n const roleNumbersMap: {\n [key: string]: { roleId: string; roleNum: number }\n } = {}\n allRoleNumbersArr.forEach(entry => {\n const [roleId, roleNum] = Object.entries(entry)[0]\n roleNumbersMap[roleId] = { roleId, roleNum }\n })\n for (let { roleId, roleNum } of Object.values(roleNumbersMap)) {\n if (roleNum > originalNum) {\n originalNum = roleNum\n highestGroupRole = roleId\n }\n }\n return highestGroupRole\n } catch (error) {\n logging.logAlert(\n `Error finding higest role for ${groups.length} on app ${appId}`,\n error\n )\n throw error\n }\n}\n\nexport async function getGroupRoleId(\n user: User,\n appId: string,\n opts?: { groups?: UserGroup[] }\n) {\n // If the user is part of a group or groups, then we want to find the highest roleId for that user\n // within the group, and overwrite the user defined role, therefore providing group based access\n // on a user / app level\n if (!user.userGroups) {\n return null\n }\n\n let groupsToAdd: UserGroup[]\n if (opts?.groups) {\n groupsToAdd = opts.groups.filter(group =>\n user.userGroups!.includes(group._id!)\n )\n } else {\n groupsToAdd = await db.groups.getBulk(user.userGroups, {\n enriched: false,\n })\n }\n\n // if the user has a role for the app already, the group doesn't override it\n const prodAppId = dbUtils.getProdAppID(appId)\n if (user.roles?.[prodAppId]) {\n return user.roles[prodAppId]\n }\n\n // reduce the groups down to where the apps exist\n groupsToAdd = groupsToAdd.filter((group: UserGroup) => {\n if (!group?.roles) {\n return false\n }\n const appIds = Object.keys(group.roles)\n return appIds.includes(prodAppId)\n })\n\n return await findHighestRole(groupsToAdd, appId)\n}\n\nexport async function enrichUserRolesFromGroups(user: User) {\n if (!user || !user.userGroups) {\n return user\n }\n const retrievedGroups = await getBulk(user.userGroups, { enriched: false })\n let allGroupAppIds: string[] = []\n for (let group of retrievedGroups) {\n if (group?.roles) {\n allGroupAppIds = allGroupAppIds.concat(Object.keys(group.roles))\n }\n }\n // get the unique app IDs\n allGroupAppIds = [...new Set(allGroupAppIds)]\n for (let appId of allGroupAppIds) {\n if (user.roles[appId]) {\n continue\n }\n const role = await findHighestRole(retrievedGroups, appId)\n if (role) {\n user.roles[appId] = role\n }\n }\n return user\n}\n\nexport async function fetch() {\n return await db.groups.fetch()\n}\n\nexport async function get(id: string) {\n return (await db.groups.get(id)) as UserGroup\n}\n\nexport async function getBulk(ids: string[], opts = { enriched: true }) {\n return (await db.groups.getBulk(ids, opts)) as UserGroup[]\n}\n\nasync function guardNameAvailility(name: string) {\n const existingGroup = await db.groups.getByName(name)\n if (existingGroup) {\n throw new GroupNameUnavailableError(name)\n }\n}\n\nexport async function save(group: UserGroup) {\n let eventPromises = []\n // Config does not exist yet\n let isCreate = !group._id\n // make sure to clear out group users - these are enriched, should not be stored\n delete group.users\n\n db.groups.getUserGroupsParams\n if (!group._id) {\n group._id = db.groups.generateUserGroupID()\n await guardNameAvailility(group.name)\n eventPromises.push(events.group.created(group))\n } else {\n const oldGroup: UserGroup = await db.groups.get(group._id)\n if (oldGroup.name !== group.name) {\n await guardNameAvailility(group.name)\n }\n eventPromises.push(events.group.updated(group))\n if (JSON.stringify(oldGroup.roles) !== JSON.stringify(group.roles)) {\n eventPromises.push(events.group.permissionsEdited(group))\n }\n }\n\n try {\n await Promise.all(eventPromises)\n const saveGroup = () => {\n return db.groups.save(group)\n }\n if (isCreate) {\n return await quotas.addGroup(saveGroup)\n } else {\n return await saveGroup()\n }\n } catch (err: any) {\n throw err\n }\n}\n\nexport async function remove(groupId: string, revision: string) {\n let group\n try {\n group = await db.groups.get(groupId)\n } catch (err) {\n throw new Error(\"Group not found\")\n }\n try {\n let resp = await db.groups.destroy(groupId, revision)\n await events.group.deleted(group)\n await quotas.removeGroup()\n return resp as any\n } catch (err: any) {\n throw err\n }\n}\n\nexport async function addUsers(groupId: string, userIds: string[]) {\n const group = await db.groups.get(groupId)\n const users = await usersCore.bulkGetGlobalUsersById(userIds)\n let toUpdate: User[] = []\n for (let user of users) {\n if (!user.userGroups) {\n user.userGroups = []\n }\n if (!user.userGroups.includes(groupId)) {\n user.userGroups.push(groupId)\n toUpdate.push(user)\n }\n }\n await usersCore.bulkUpdateGlobalUsers(toUpdate)\n\n let promises = []\n for (let userId of userIds) {\n promises.push(cache.user.invalidateUser(userId))\n }\n await Promise.all(promises)\n\n if (toUpdate.length) {\n await events.group.usersAdded(toUpdate.length, group)\n }\n return toUpdate\n}\n\nexport async function removeUsers(groupId: string, userIds: string[]) {\n const group = await db.groups.get(groupId)\n const users = await usersCore.bulkGetGlobalUsersById(userIds)\n let toUpdate: User[] = []\n for (let user of users) {\n if (!user.userGroups || !user.userGroups.includes(groupId)) {\n continue\n }\n const idx = user.userGroups.indexOf(groupId)\n user.userGroups.splice(idx, 1)\n toUpdate.push(user)\n }\n await usersCore.bulkUpdateGlobalUsers(toUpdate)\n\n let promises = []\n for (let userId of userIds) {\n promises.push(cache.user.invalidateUser(userId))\n }\n await Promise.all(promises)\n\n if (toUpdate.length) {\n await events.group.usersDeleted(toUpdate.length, group)\n }\n return toUpdate\n}\n\nexport async function updateGroupApps(\n groupId: string,\n opts: {\n appsToRemove?: { appId: string }[]\n appsToAdd?: { appId: string; roleId: string }[]\n }\n) {\n const group = await get(groupId)\n if (!group.roles) {\n group.roles = {}\n }\n if (opts.appsToAdd) {\n for (let add of opts.appsToAdd) {\n group.roles[add.appId] = add.roleId\n }\n }\n if (opts.appsToRemove) {\n for (let remove of opts.appsToRemove) {\n delete group.roles[remove.appId]\n }\n }\n return await save(group)\n}\n\nexport async function cleanupApp(appId: string) {\n const groupList = await fetch()\n const toUpdate = []\n for (let group of groupList) {\n if (!group.roles || !group.roles[appId]) {\n continue\n }\n delete group.roles[appId]\n toUpdate.push(group)\n }\n return await db.groups.bulkSave(toUpdate)\n}\n", "import { Plugin, PluginSource, PluginType } from \"@budibase/types\"\nimport { events } from \"@budibase/backend-core\"\nimport {\n objectStore,\n db as dbCore,\n tenancy,\n logging,\n} from \"@budibase/backend-core\"\nimport { loadJSFile } from \"../../utilities/fileSystem\"\nimport * as quotas from \"../quotas\"\n\nexport async function storePlugin(\n metadata: any,\n directory: any,\n source?: PluginSource\n) {\n const db = tenancy.getGlobalDB()\n const version = metadata.package.version,\n name = metadata.package.name,\n description = metadata.package.description,\n hash = metadata.schema.hash\n\n // first open the tarball into tmp directory\n const bucketPath = objectStore.getPluginS3Dir(name)\n const files = await objectStore.uploadDirectory(\n objectStore.ObjectStoreBuckets.PLUGINS,\n directory,\n bucketPath\n )\n const jsFile = files.find((file: any) => file.name.endsWith(\".js\"))\n const iconFile = files.find((file: any) => file.name.endsWith(\".svg\"))\n if (!jsFile) {\n throw new Error(`Plugin missing .js file.`)\n }\n // validate the JS for a datasource\n if (metadata.schema.type === PluginType.DATASOURCE) {\n const js = loadJSFile(directory, jsFile.name)\n try {\n // down the line we might need a better way to confirm JS file\n ;(0, eval)(js)\n } catch (err: any) {\n const message = err?.message ? err.message : JSON.stringify(err)\n throw new Error(`JS invalid: ${message}`)\n }\n }\n const iconFileName = iconFile ? iconFile.name : null\n const pluginId = dbCore.generatePluginID(name)\n\n // overwrite existing docs entirely if they exist\n let rev\n try {\n const existing = await db.get(pluginId)\n rev = existing._rev\n } catch (err) {\n rev = undefined\n }\n let doc: Plugin = {\n _id: pluginId,\n _rev: rev,\n ...metadata,\n name,\n version,\n hash,\n description,\n }\n if (iconFileName) {\n doc.iconFileName = iconFileName\n }\n\n if (source) {\n doc = {\n ...doc,\n source,\n }\n }\n\n const write = async () => {\n const response = await db.put(doc)\n await events.plugin.imported(doc)\n return {\n ...doc,\n _rev: response.rev,\n }\n }\n // it doesn't exist, update the quota\n if (!rev) {\n return await quotas.addPlugin(write)\n } else {\n return await write()\n }\n}\n\nexport async function deletePlugin(pluginId: string) {\n const db = tenancy.getGlobalDB()\n try {\n const plugin: Plugin = await db.get(pluginId)\n const bucketPath = objectStore.getPluginS3Dir(plugin.name)\n await objectStore.deleteFolder(\n objectStore.ObjectStoreBuckets.PLUGINS,\n bucketPath\n )\n\n await db.remove(pluginId, plugin._rev!)\n await events.plugin.deleted(plugin)\n await quotas.removePlugin()\n } catch (err: any) {\n const errMsg = err?.message ? err?.message : err\n throw new Error(`Failed to delete plugin: ${errMsg}`)\n }\n}\n\nexport async function checkPluginQuotas() {\n const db = tenancy.getGlobalDB()\n try {\n const allPlugins = await db.allDocs(dbCore.getPluginParams())\n const pluginCount = allPlugins.rows.length\n console.log(`Syncing plugin count: ${pluginCount}`)\n await quotas.updatePluginCount(pluginCount)\n } catch (err) {\n logging.logAlert(\"Unable to retrieve plugins for quota check\", err)\n }\n}\n", "import fs from \"fs\"\nimport { join } from \"path\"\n\nexport function loadJSFile(directory: string, name: string) {\n return fs.readFileSync(join(directory, name), \"utf8\")\n}\n", "export * from \"./environmentVariables\"\n", "import {\n AppEnvironment,\n EnvironmentVariableValue,\n Feature,\n} from \"@budibase/types\"\nimport { env } from \"@budibase/backend-core\"\nimport { environmentVariables } from \"../../db\"\nimport { licensing } from \"../../sdk\"\n\ntype VariableMap = { [key: string]: EnvironmentVariableValue }\n\nexport function isEncryptionKeyAvailable() {\n return !!env.ENCRYPTION_KEY\n}\n\nexport async function fetch(): Promise<string[]> {\n const doc = await environmentVariables.get()\n return Object.keys(doc.variables)\n}\n\nexport async function fetchValues(environment: AppEnvironment) {\n const doc = await environmentVariables.get()\n const decrypted = doc.variables\n\n const output: { [key: string]: string } = {}\n for (let [key, value] of Object.entries(decrypted)) {\n switch (environment) {\n case AppEnvironment.DEVELOPMENT:\n output[key] = value.development\n break\n case AppEnvironment.PRODUCTION:\n default:\n output[key] = value.production\n break\n }\n }\n return output\n}\n\nasync function changeValues(cb: (values: VariableMap) => VariableMap) {\n // only block access when updating values, let users fetch\n const license = await licensing.cache.getCachedLicense()\n if (!license.features.includes(Feature.ENVIRONMENT_VARIABLES)) {\n throw new Error(\n \"User does not have access to environment variables feature.\"\n )\n }\n const doc = await environmentVariables.get()\n doc.variables = cb(doc.variables)\n await environmentVariables.update(doc)\n}\n\nexport async function update(varName: string, value: EnvironmentVariableValue) {\n const checkName = isValid(varName)\n if (checkName) {\n await changeValues(values => {\n values[varName] = value\n return values\n })\n } else {\n throw new Error(\"Variable name has characters that are not allowed\")\n }\n}\n\nexport async function remove(varName: string) {\n await changeValues(values => {\n delete values[varName]\n return values\n })\n}\n\nexport function isValid(str: string) {\n return /^[a-zA-Z0-9-_]+$/.test(str)\n}\n", "export * from \"./auditLogs\"\n", "import {\n AuditedEventFriendlyName,\n AuditLogDoc,\n AuditLogEnriched,\n AuditLogSearchParams,\n AuditLogSystemUser,\n AuditWriteOpts,\n Event,\n FallbackInfo,\n SearchFilters,\n} from \"@budibase/types\"\nimport * as auditLogs from \"../../db/auditLogs\"\nimport {\n cache,\n db as dbCore,\n users,\n utils,\n logging,\n} from \"@budibase/backend-core\"\nimport { Readable } from \"stream\"\nimport {\n auditLogsEnabled,\n deleted,\n fillDates,\n getEventFriendlyName,\n getSearchFilters,\n removeTemplateStrings,\n ResourceType,\n} from \"./utils\"\n\nexport async function write(\n event: Event,\n metadata: any,\n opts?: AuditWriteOpts\n): Promise<AuditLogDoc | undefined> {\n if (!(await auditLogsEnabled()) || !utils.isAudited(event)) {\n return\n }\n const friendly = getEventFriendlyName(event, metadata)\n let date = new Date()\n if (opts?.timestamp) {\n date = new Date(opts.timestamp)\n }\n const doc: AuditLogDoc = {\n timestamp: date.toISOString(),\n event,\n name: friendly,\n userId: opts?.userId || AuditLogSystemUser,\n metadata: {\n ...metadata,\n ...opts?.hostInfo,\n },\n }\n const fallback: FallbackInfo = {}\n // audit logs always use prod app ID\n try {\n if (opts?.appId) {\n doc.appId = dbCore.getProdAppID(opts.appId)\n const appMetadata = await cache.app.getAppMetadata(opts.appId)\n fallback.appName = appMetadata.name\n }\n if (opts?.userId) {\n const user = await users.getById(opts?.userId as string)\n fallback.email = user.email\n }\n } catch (err) {\n logging.logAlert(\n \"Failed to retrieve fallback information for audit log\",\n err\n )\n }\n doc.fallback = fallback\n return await auditLogs.save(doc)\n}\n\nasync function enrich(logs: AuditLogDoc[]): Promise<AuditLogEnriched[]> {\n const allUserIds = logs.map(log => log.userId)\n const hasAppIdLogs = logs.filter(log => log.appId)\n // get the dev app ID - enrich with dev app info as prod app may not exist\n const allAppIds = hasAppIdLogs.map(log =>\n dbCore.getDevAppID(log.appId as string)\n )\n const userList = await users.bulkGetGlobalUsersById(\n [...new Set(allUserIds)],\n { cleanup: true }\n )\n const appList = await dbCore.getAppsByIDs([...new Set(allAppIds)])\n\n let enriched: AuditLogEnriched[] = []\n for (let log of logs) {\n const user = userList.find(user => user?._id === log.userId)\n const app = appList.find(app => dbCore.isSameAppID(app?.appId, log.appId))\n const enrichedLog: AuditLogEnriched = {\n event: log.event,\n timestamp: log.timestamp,\n name: log.name,\n metadata: log.metadata,\n user: user || deleted(log.userId, ResourceType.USER, log.fallback),\n }\n if (log.appId) {\n enrichedLog.app =\n app || deleted(log.appId, ResourceType.APP, log.fallback)\n }\n enriched.push(enrichedLog)\n }\n return enriched\n}\n\nexport async function fetch(params: AuditLogSearchParams) {\n if (!(await auditLogsEnabled())) {\n throw new Error(\"Audit logs not available - license required.\")\n }\n\n const filter: SearchFilters = getSearchFilters(params)\n\n const response = await auditLogs.search(filter, params.bookmark)\n return {\n hasNextPage: response.hasNextPage,\n bookmark: response.bookmark,\n data: await enrich(response.rows),\n }\n}\n\n// like the fetch, but without pagination (uses filtered replication)\nexport function download(params: AuditLogSearchParams): {\n promise: Promise<void>\n stream: Readable\n} {\n params = fillDates(params)\n return auditLogs.dump(params)\n}\n\nexport function definitions() {\n const entries = Object.entries(AuditedEventFriendlyName).filter(\n entry => entry[1] != undefined\n )\n const events: Record<string, string> = {}\n for (let entry of entries) {\n events[entry[0]] = removeTemplateStrings(entry[1] as string)\n }\n return events\n}\n", "import {\n DocumentType,\n SEPARATOR,\n utils,\n context,\n db as dbCore,\n logging,\n} from \"@budibase/backend-core\"\nimport {\n AuditLogDoc,\n SearchFilters,\n AuditLogSearchParams,\n SortOrder,\n SortType,\n SearchIndex,\n} from \"@budibase/types\"\nimport { createAuditLogSearchIndex } from \"./views\"\nimport { GENERIC_PAGE_SIZE } from \"../constants\"\nimport { Readable } from \"stream\"\nconst MemoryStream = require(\"memorystream\")\n\nfunction generateAuditLogID(timestamp: string) {\n return `${\n DocumentType.AUDIT_LOG\n }${SEPARATOR}${timestamp}${SEPARATOR}${utils.newid()}`\n}\n\nexport async function save(doc: AuditLogDoc) {\n if (!doc._id) {\n doc._id = generateAuditLogID(doc.timestamp)\n }\n try {\n const db = context.getAuditLogsDB()\n const response = await db.put(doc)\n return {\n ...doc,\n _rev: response.rev,\n }\n } catch (err: any) {\n logging.logAlert(\"Failed to write audit log\", err)\n }\n}\n\nexport async function search(search: SearchFilters, bookmark?: string) {\n const dbName = context.getAuditLogDBName()\n return await dbCore.paginatedSearch<AuditLogDoc>(\n dbName,\n SearchIndex.AUDIT,\n search,\n {\n disableEscaping: true,\n indexer: createAuditLogSearchIndex,\n limit: GENERIC_PAGE_SIZE,\n bookmark: bookmark,\n sort: \"timestamp\",\n sortOrder: SortOrder.DESCENDING,\n sortType: SortType.STRING,\n }\n )\n}\n\nexport function dump(params: AuditLogSearchParams): {\n promise: Promise<void>\n stream: Readable\n} {\n const db = context.getAuditLogsDB()\n const stream = new MemoryStream()\n // dump the database, re-creating what the lucene filter looks for\n const promise = db.dump(stream, {\n filter: doc => {\n const auditLog = doc as AuditLogDoc\n if (!auditLog._id?.startsWith(DocumentType.AUDIT_LOG)) {\n return false\n }\n // do this as an AND like operation\n let allMatched = true\n const matcher = (\n param: string[] | undefined,\n value: string | undefined\n ) => {\n if (!param || param.length === 0) {\n return\n }\n allMatched = !!(allMatched && value && param.includes(value))\n }\n matcher(params.userIds, auditLog.userId)\n matcher(params.appIds, auditLog.appId)\n matcher(params.events, auditLog.event)\n // they should have both been filled if one was filled\n if (params.startDate || params.endDate) {\n allMatched =\n allMatched &&\n auditLog.timestamp >= params.startDate! &&\n auditLog.timestamp <= params.endDate!\n }\n // this can't be quite the same as the whitespace search, but good enough\n if (params.fullSearch) {\n const json = JSON.stringify(doc)\n allMatched = allMatched && json.includes(params.fullSearch)\n }\n return allMatched\n },\n })\n const returnStream = new MemoryStream()\n // need to run the original stream through a transform to get to the newline\n // delimited JSON structure required\n stream.on(\"data\", (data: any) => {\n const json = JSON.parse(Buffer.from(data).toString())\n if (Array.isArray(json.docs)) {\n let str = \"\"\n for (let doc of json.docs) {\n str += JSON.stringify(doc) + \"\\n\"\n }\n returnStream.write(str)\n }\n })\n stream.on(\"end\", () => {\n returnStream.end()\n })\n return { promise, stream: returnStream }\n}\n", "import { licensing } from \"../../sdk\"\nimport {\n Feature,\n AuditLogSearchParams,\n Event,\n AuditedEventFriendlyName,\n SearchFilters,\n AuditLogResourceStatus,\n FallbackInfo,\n DeletedResourceInfo,\n} from \"@budibase/types\"\nconst {\n processStringSync,\n findHBSBlocks,\n} = require(\"@budibase/string-templates\")\nimport { constants, db as dbCore } from \"@budibase/backend-core\"\n\nconst MIN_DATE = constants.MIN_VALID_DATE.toISOString()\nconst MAX_DATE = constants.MAX_VALID_DATE.toISOString()\n\nexport enum ResourceType {\n USER = \"user\",\n APP = \"app\",\n}\n\nexport function fillDates(params: AuditLogSearchParams) {\n if (params.startDate || params.endDate) {\n params.startDate = params.startDate || MIN_DATE\n params.endDate = params.endDate || MAX_DATE\n }\n return params\n}\n\nexport function getSearchFilters(params: AuditLogSearchParams) {\n // look for prod app IDs in audit log documents\n if (Array.isArray(params.appIds)) {\n params.appIds = params.appIds.map(appId => dbCore.getProdAppID(appId))\n }\n // escape events characters, still events just with escapes\n if (Array.isArray(params.events)) {\n params.events = params.events.map(\n event => escapeCharacter(event, [\":\"]) as Event\n )\n }\n const filter: SearchFilters = {}\n function addStringParams(key: string, params: string[] | undefined) {\n if (params?.length) {\n filter.oneOf = {\n ...filter.oneOf,\n [key]: params,\n }\n }\n }\n addStringParams(\"userId\", params.userIds)\n addStringParams(\"appId\", params.appIds)\n addStringParams(\"event\", params.events)\n\n if (params.fullSearch) {\n const search = escapeCharacter(params.fullSearch, [\":\", \" \"])\n // utilises a whitespace search\n filter.equal = {\n all: `(\"${search}\" OR ${search}*)`,\n }\n }\n if (params.startDate || params.endDate) {\n params = fillDates(params)\n filter.range = {\n timestamp: {\n high: params.endDate!,\n low: params.startDate!,\n },\n }\n }\n // no parameters, search for anything\n if (Object.keys(filter).length === 0) {\n filter.notEmpty = {\n event: true,\n }\n }\n return filter\n}\n\nexport function escapeCharacter(str: string, characters: string[]) {\n for (let character of characters) {\n str = str.replace(new RegExp(character, \"g\"), `\\\\${character}`)\n }\n return str\n}\n\nexport function deleted(\n id: string,\n resourceType: ResourceType,\n fallbackInfo?: FallbackInfo\n) {\n const deleteInfo: DeletedResourceInfo = {\n _id: id,\n status: AuditLogResourceStatus.DELETED,\n }\n switch (resourceType) {\n case ResourceType.APP:\n deleteInfo.name = fallbackInfo?.appName\n break\n case ResourceType.USER:\n deleteInfo.email = fallbackInfo?.email\n break\n }\n return deleteInfo\n}\n\nexport function removeTemplateStrings(friendlyName: string) {\n const blocks = findHBSBlocks(friendlyName)\n // remove any HBS blocks\n for (let block of blocks) {\n const quoted = ` \"${block}\"`\n friendlyName = friendlyName.replace(\n friendlyName.includes(quoted) ? quoted : ` ${block}`,\n \"\"\n )\n // Remove template strings\n friendlyName = processStringSync(friendlyName, {})\n }\n return friendlyName\n}\n\nexport async function auditLogsEnabled() {\n const license = await licensing.cache.getCachedLicense()\n return license.features.includes(Feature.AUDIT_LOGS)\n}\n\nexport function getEventFriendlyName(event: Event, metadata: any) {\n const friendly = AuditedEventFriendlyName[event]\n if (!friendly) {\n throw new Error(\"No friendly name found.\")\n }\n let processed = processStringSync(friendly, metadata)\n // this will occur if no enrichment could be found\n if (processed.includes(`\"\"`)) {\n processed = removeTemplateStrings(friendly)\n }\n return processed\n}\n", "import { objectStore, events } from \"@budibase/backend-core\"\nimport {\n AppBackupContents,\n AppBackupFetchOpts,\n AppBackupMetadata,\n AppBackupStatus,\n AppBackupTrigger,\n AppBackupType,\n} from \"@budibase/types\"\nimport { backups } from \"../../db\"\nimport { getBackupQueue } from \"./queue\"\nimport * as features from \"../features\"\n\nasync function storeAppBackupMetadata(\n metadata: AppBackupMetadata,\n opts: { filename?: string } = {}\n) {\n return backups.storeAppBackupMetadata(metadata, opts)\n}\n\nfunction getTimestamps(status: AppBackupStatus) {\n const timestamp = new Date().toISOString()\n switch (status) {\n case AppBackupStatus.COMPLETE:\n case AppBackupStatus.FAILED:\n return { timestamp, finishedAt: timestamp }\n case AppBackupStatus.STARTED:\n return { timestamp, startedAt: timestamp }\n case AppBackupStatus.PENDING:\n return { timestamp, createdAt: timestamp }\n }\n}\n\nasync function updateBackupStatus(\n id: string,\n rev: string,\n status: AppBackupStatus,\n contents?: AppBackupContents,\n filename?: string\n) {\n const backup: AppBackupMetadata = await getAppBackup(id)\n // keep backup event timestamp up to date with when it completes/fails\n return await backups.storeAppBackupMetadata(\n {\n ...backup,\n ...getTimestamps(status),\n contents,\n status,\n type: AppBackupType.BACKUP,\n },\n { filename, docId: id, docRev: rev }\n )\n}\n\nasync function updateRestoreStatus(\n id: string,\n rev: string,\n status: AppBackupStatus\n) {\n const restore: AppBackupMetadata = await getAppBackup(id)\n // keep restore event timestamp up to date with when it completes/fails\n return await backups.storeAppBackupMetadata(\n {\n ...restore,\n ...getTimestamps(status),\n status,\n type: AppBackupType.RESTORE,\n trigger: AppBackupTrigger.MANUAL,\n },\n { docId: id, docRev: rev }\n )\n}\n\nasync function getAppBackup(backupId: string) {\n return backups.getAppBackupMetadata(backupId)\n}\n\nasync function updateAppBackup(backupId: string, backupName: string) {\n return backups.updateAppBackupMetadata(backupId, backupName)\n}\n\nasync function deleteAppBackup(backupId: string) {\n const metadata = await backups.getAppBackupMetadata(backupId)\n if (metadata.filename) {\n await objectStore.deleteFile(\n objectStore.ObjectStoreBuckets.BACKUPS,\n metadata.filename\n )\n }\n return backups.deleteAppBackupMetadata(backupId)\n}\n\nasync function fetchAppBackups(appId: string, opts?: AppBackupFetchOpts) {\n return backups.fetchAppBackups(appId, opts)\n}\n\nasync function downloadAppBackup(backupId: string) {\n const metadata = await backups.getAppBackupMetadata(backupId)\n if (!metadata.filename) {\n throw new Error(\"Backup incomplete - cannot download.\")\n }\n const path = await objectStore.retrieveToTmp(\n objectStore.ObjectStoreBuckets.BACKUPS,\n metadata.filename\n )\n return { metadata, path }\n}\n\nasync function triggerAppBackup(\n appId: string,\n trigger: AppBackupTrigger,\n opts: { createdBy?: string; name?: string } = {}\n): Promise<string | undefined> {\n // store immediately, get rev and id as incomplete\n let backup\n try {\n backup = await storeAppBackupMetadata({\n appId,\n trigger,\n timestamp: new Date().toISOString(),\n status: AppBackupStatus.PENDING,\n type: AppBackupType.BACKUP,\n ...opts,\n })\n } catch (err: any) {\n // there already is a backup for this exact millisecond, no need\n // for a new one\n if (err.status === 409) {\n return\n } else {\n throw err\n }\n }\n // kick off job\n await getBackupQueue().add({\n docId: backup.id,\n docRev: backup.rev,\n appId,\n export: {\n trigger,\n ...opts,\n },\n })\n await events.backup.appBackupTriggered(\n appId,\n backup.id,\n AppBackupType.BACKUP,\n trigger,\n opts?.name as string\n )\n return backup.id\n}\n\nasync function triggerAppRestore(\n appId: string,\n backupId: string,\n nameForBackup: string,\n createdBy?: string\n): Promise<{ restoreId: string; metadata: any } | void> {\n const metadata = await getAppBackup(backupId)\n // store immediately, get rev and id as incomplete\n let restore\n try {\n restore = await storeAppBackupMetadata({\n appId,\n timestamp: new Date().toISOString(),\n status: AppBackupStatus.PENDING,\n type: AppBackupType.RESTORE,\n createdBy,\n })\n } catch (err: any) {\n // there already is a restore for this exact millisecond, no need\n // for a new one\n if (err?.status === 409) {\n return\n } else {\n throw err\n }\n }\n await getBackupQueue().add({\n appId,\n docId: restore.id,\n docRev: restore.rev,\n import: {\n nameForBackup,\n backupId,\n createdBy,\n },\n })\n return { restoreId: restore.id, metadata }\n}\n\n/**\n * Rather than exporting functions directly from licensed sdks,\n * we use the licensed function wrapper to apply license restrictions\n * with minimal interference to internal logic.\n */\nconst pkg = {\n isEnabled: features.isBackupsEnabled,\n triggerAppRestore: features.checkBackups(triggerAppRestore),\n triggerAppBackup: features.checkBackups(triggerAppBackup),\n downloadAppBackup: features.checkBackups(downloadAppBackup),\n fetchAppBackups: features.checkBackups(fetchAppBackups),\n storeAppBackupMetadata: features.checkBackups(storeAppBackupMetadata),\n updateBackupStatus: features.checkBackups(updateBackupStatus),\n updateRestoreStatus: features.checkBackups(updateRestoreStatus),\n getAppBackup: features.checkBackups(getAppBackup),\n updateAppBackup: features.checkBackups(updateAppBackup),\n deleteAppBackup: features.checkBackups(deleteAppBackup),\n}\n\nexport default pkg\n", "import { queue } from \"@budibase/backend-core\"\nimport { AppBackupQueueData } from \"@budibase/types\"\nimport { Queue } from \"bull\"\n\nlet backupQueue: Queue<AppBackupQueueData>\n\nexport function init() {\n backupQueue = queue.createQueue<AppBackupQueueData>(queue.JobQueue.APP_BACKUP)\n}\n\nexport function getBackupQueue() {\n return backupQueue\n}\n", "import {\n db as dbCore,\n logging,\n objectStore,\n tenancy,\n} from \"@budibase/backend-core\"\nimport backups from \"./backup\"\nimport {\n AppBackupContents,\n AppBackupQueueData,\n AppBackupStatus,\n AppBackupTrigger,\n AppBackupType,\n} from \"@budibase/types\"\nimport { getBackupQueue } from \"./queue\"\nimport { Job } from \"bull\"\nimport fs from \"fs\"\nimport { BackupProcessingOpts } from \"../../types\"\n\nexport async function init(opts: BackupProcessingOpts) {\n await getBackupQueue().process(async (job: Job) => {\n const data = job.data as AppBackupQueueData\n try {\n if (data.export) {\n return exportProcessor(job, opts)\n } else if (data.import) {\n return importProcessor(job, opts)\n }\n } catch (err: any) {\n logging.logAlert(\n `Failed to perform backup for app ID: ${data.appId}`,\n err\n )\n }\n })\n}\n\ntype RunBackupOpts = {\n processing: BackupProcessingOpts\n doc?: { id: string; rev: string }\n createdBy?: string\n name?: string\n}\n\nasync function removeExistingApp(devId: string) {\n const devDb = dbCore.getDB(devId, { skip_setup: true })\n await devDb.destroy()\n}\n\nasync function runBackup(\n trigger: AppBackupTrigger,\n tenantId: string,\n appId: string,\n opts: RunBackupOpts\n) {\n const devAppId = dbCore.getDevAppID(appId),\n prodAppId = dbCore.getProdAppID(appId)\n const timestamp = new Date().toISOString()\n const updateMetadata = async (\n status: AppBackupStatus,\n updateOpts?: { filename?: string; contents?: AppBackupContents }\n ) => {\n if (opts?.doc) {\n await backups.updateBackupStatus(\n opts.doc.id,\n opts.doc.rev,\n status,\n updateOpts?.contents,\n updateOpts?.filename\n )\n } else {\n await backups.storeAppBackupMetadata(\n {\n appId: prodAppId,\n timestamp,\n trigger,\n status,\n name: opts?.name,\n type: AppBackupType.BACKUP,\n contents: updateOpts?.contents,\n createdBy: opts?.createdBy,\n },\n { filename: updateOpts?.filename }\n )\n }\n }\n try {\n const tarPath = await opts.processing.exportAppFn(devAppId, { tar: true })\n const contents = await opts.processing.statsFn(devAppId)\n let filename = `${prodAppId}/backup-${timestamp}.tar.gz`\n const bucket = objectStore.ObjectStoreBuckets.BACKUPS\n await objectStore.upload({\n path: tarPath,\n type: \"application/gzip\",\n bucket,\n filename,\n metadata: {\n name: opts?.name,\n trigger,\n timestamp,\n appId: prodAppId,\n },\n })\n await updateMetadata(AppBackupStatus.COMPLETE, { filename, contents })\n // clear up the tarball after uploading it\n if (fs.existsSync(tarPath)) {\n fs.rmSync(tarPath)\n }\n } catch (err) {\n logging.logAlert(\"App backup error\", err)\n await updateMetadata(AppBackupStatus.FAILED)\n }\n}\n\nasync function importProcessor(job: Job, opts: BackupProcessingOpts) {\n const data: AppBackupQueueData = job.data\n const appId = data.appId,\n backupId = data.import!.backupId,\n nameForBackup = data.import!.nameForBackup,\n createdBy = data.import!.createdBy\n const tenantId = tenancy.getTenantIDFromAppID(appId) as string\n return tenancy.doInTenant(tenantId, async () => {\n const devAppId = dbCore.getDevAppID(appId)\n const { rev } = await backups.updateRestoreStatus(\n data.docId,\n data.docRev,\n AppBackupStatus.STARTED\n )\n // initially export the current state to disk - incase something goes wrong\n await runBackup(AppBackupTrigger.RESTORING, tenantId, appId, {\n processing: opts,\n createdBy,\n name: nameForBackup,\n })\n // get the backup ready on disk\n const { path } = await backups.downloadAppBackup(backupId)\n // start by removing app database and contents of bucket - which will be updated\n await removeExistingApp(devAppId)\n let status = AppBackupStatus.COMPLETE\n try {\n await opts.importAppFn(devAppId, dbCore.getDB(devAppId), {\n file: {\n type: \"application/gzip\",\n path,\n },\n key: path,\n })\n } catch (err) {\n logging.logAlert(\"App restore error\", err)\n status = AppBackupStatus.FAILED\n }\n await backups.updateRestoreStatus(data.docId, rev, status)\n })\n}\n\nasync function exportProcessor(job: Job, opts: BackupProcessingOpts) {\n const data: AppBackupQueueData = job.data\n const appId = data.appId,\n trigger = data.export!.trigger,\n name = data.export!.name\n const tenantId = tenancy.getTenantIDFromAppID(appId) as string\n await tenancy.doInTenant(tenantId, async () => {\n const { rev } = await backups.updateBackupStatus(\n data.docId,\n data.docRev,\n AppBackupStatus.STARTED\n )\n return runBackup(trigger, tenantId, appId, {\n processing: opts,\n doc: { id: data.docId, rev },\n name,\n })\n })\n}\n", "import backups from \"./backup\"\nimport * as processing from \"./processing\"\nimport { BackupInitOpts } from \"../../types\"\nimport { init as queueInit, getBackupQueue } from \"./queue\"\n\nconst init = async (opts: BackupInitOpts) => {\n queueInit()\n await processing.init(opts.processing)\n}\n\nexport default {\n ...backups,\n processing,\n init,\n getBackupQueue,\n}\n", "export * from \"./apps\"\n", "import { db as dbCore } from \"@budibase/backend-core\"\n\nexport async function appExists(appId: string) {\n const allAppIds = (await dbCore.getAllApps({\n all: true,\n idsOnly: true,\n })) as string[]\n return allAppIds.includes(appId)\n}\n", "import {\n db as dbCore,\n tenancy,\n users as usersCore,\n} from \"@budibase/backend-core\"\nimport { SaveUserOpts, SearchIndex, User } from \"@budibase/types\"\n\nexport interface ScimUserServiceConfig {\n functions: {\n saveUser: (user: User, opts?: SaveUserOpts) => Promise<User>\n removeUser: (id: string) => Promise<void>\n }\n}\n\nexport interface GetUsersFilters {\n equal?: Record<string, any>\n}\n\ninterface GetParams {\n pageSize: number\n skip?: number\n filters?: GetUsersFilters\n}\n\nclass ScimUserService {\n saveUser: (user: User, opts?: SaveUserOpts) => Promise<User>\n removeUser: (id: string) => Promise<void>\n\n constructor(config: ScimUserServiceConfig) {\n this.saveUser = config.functions.saveUser\n this.removeUser = config.functions.removeUser\n }\n\n get = async (\n params: GetParams\n ): Promise<{ users: User[]; total: number }> => {\n const db = tenancy.getGlobalDB()\n\n const builder = new dbCore.QueryBuilder<User>(db.name, SearchIndex.USER)\n builder.setIndexBuilder(dbCore.searchIndexes.createUserIndex)\n builder.setLimit(params.pageSize)\n builder.addEqual(\"scimInfo.isSync\", true)\n\n for (const [key, value] of Object.entries(params.filters?.equal ?? {})) {\n builder.addEqual(key, value)\n }\n\n builder.setSort(\"_id\")\n builder.setSkip(params.skip)\n\n const docs = await builder.run()\n\n return {\n users: docs.rows,\n total: docs.totalRows,\n }\n }\n\n find = async (id: string) => {\n const user = await usersCore.getById(id)\n return user\n }\n\n create = async (user: User) => {\n return await this.saveUser(user, { requirePassword: false })\n }\n\n update = async (user: User) => {\n return await this.saveUser(user, { requirePassword: false })\n }\n\n remove = async (id: string) => {\n return await this.removeUser(id)\n }\n}\n\nexport const init = (config: ScimUserServiceConfig) => {\n service = new ScimUserService(config)\n}\n\nlet service: ScimUserService\n\nexport const get = (query: GetParams) => service.get(query)\nexport const find = (id: string) => service.find(id)\nexport const create = (user: User) => service.create(user)\nexport const update = (user: User) => service.update(user)\nexport const remove = (id: string) => service.remove(id)\n", "import backups from \"./backups\"\nimport { InitOpts } from \"../types\"\nimport { init as initScimUserService } from \"./scim/users\"\n\nexport const init = async (opts: InitOpts) => {\n if (opts.scimUserServiceConfig) {\n initScimUserService(opts.scimUserServiceConfig)\n }\n if (opts.backups) {\n await backups.init(opts.backups)\n }\n}\n", "import { LicenseMiddlewareOptions } from \"../types\"\nimport { SELF_FREE_LICENSE } from \"../constants/licenses\"\nimport { env } from \"@budibase/backend-core\"\nimport { quotas, licensing as licenses } from \"../sdk\"\nimport { utils } from \"@budibase/backend-core\"\nimport { QuotaUsageType, StaticQuotaName } from \"@budibase/types\"\n\nconst licensing = (\n opts: LicenseMiddlewareOptions = {\n checkDayPasses: true,\n checkUsersLimit: true,\n refreshVersion: true,\n }\n) => {\n return async (ctx: any, next: any) => {\n const licensingCheck = opts.licensingCheck\n ? opts.licensingCheck\n : () => !!ctx.user\n\n if (licensingCheck(ctx)) {\n if (env.SELF_HOSTED && env.DEFAULT_LICENSE) {\n ctx.user.license = SELF_FREE_LICENSE\n return next()\n }\n\n // set the license on the current user\n ctx.user.license = await licenses.cache.getCachedLicense(ctx, {\n populateLicense: opts.populateLicense,\n populateFreeLicense: opts.populateFreeLicense,\n refreshVersion: opts.refreshVersion,\n })\n\n // check day passes for the current user\n if (opts.checkDayPasses) {\n await quotas.checkDayPass(ctx)\n }\n\n // check user limit for the current user\n if (\n opts.checkUsersLimit &&\n (utils.isServingApp(ctx) ||\n utils.isServingBuilder(ctx) ||\n utils.isServingBuilderPreview(ctx) ||\n utils.isPublicApiRequest(ctx))\n ) {\n await quotas.usageLimitIsExceeded(\n StaticQuotaName.USERS,\n QuotaUsageType.STATIC\n )\n }\n }\n\n return next()\n }\n}\n\nexport default licensing\n", "import { Next } from \"koa\"\nimport { Feature } from \"@budibase/types\"\nimport * as features from \"../sdk/features\"\n\nexport const requireFeature = (featureFlag: Feature) => {\n return async (ctx: any, next: Next) => {\n await features.checkFeature(featureFlag)\n await next()\n }\n}\n", "import { context } from \"@budibase/backend-core\"\nimport { Next } from \"koa\"\n\nexport const doInScimContext = async (ctx: any, next: Next) => {\n await context.doInScimContext(next)\n}\n", "import { Next } from \"koa\"\nimport * as features from \"../sdk/features\"\n\nexport const requireSCIM = async (ctx: any, next: Next) => {\n await features.checkSCIM()\n await next()\n}\n", "import {\n UserGroup,\n UserCtx,\n Ctx,\n SearchGroupRequest,\n SearchGroupResponse,\n SearchUserGroupResponse,\n DatabaseQueryOpts,\n} from \"@budibase/types\"\nimport * as groups from \"../../../sdk/groups\"\nimport { getGroupUsers } from \"../../../db/groups\"\n\nexport const save = async (ctx: UserCtx) => {\n const group: UserGroup = ctx.request.body\n group.name = group.name.trim()\n\n // don't allow updating the roles through this endpoint\n delete group.roles\n if (group._id) {\n const oldGroup = await groups.get(group._id)\n group.roles = oldGroup.roles\n }\n const response = await groups.save(group)\n ctx.body = {\n _id: response.id,\n _rev: response.rev,\n }\n}\n\nexport const updateGroupUsers = async (ctx: UserCtx) => {\n const groupId = ctx.params.id\n const toAdd = ctx.request.body.add,\n toRemove = ctx.request.body.remove\n if (\n (toAdd && !Array.isArray(toAdd)) ||\n (toRemove && !Array.isArray(toRemove))\n ) {\n ctx.throw(400, \"Must supply a list of users to add or to remove\")\n }\n let added, removed\n if (toAdd) {\n added = await groups.addUsers(groupId, toAdd)\n }\n if (toRemove) {\n removed = await groups.removeUsers(groupId, toRemove)\n }\n ctx.body = { added, removed }\n}\n\nexport const updateGroupApps = async (ctx: UserCtx) => {\n const groupId = ctx.params.id\n const toAdd = ctx.request.body.add,\n toRemove = ctx.request.body.remove\n if (\n (toAdd && !Array.isArray(toAdd)) ||\n (toRemove && !Array.isArray(toRemove))\n ) {\n ctx.throw(\n 400,\n \"Must supply a list of objects, with appId and roleId to add or remove\"\n )\n }\n ctx.body = await groups.updateGroupApps(groupId, {\n appsToAdd: toAdd,\n appsToRemove: toRemove,\n })\n}\n\nexport const fetch = async (\n ctx: Ctx<SearchGroupRequest, SearchGroupResponse>\n) => {\n ctx.body = { data: await groups.fetch() }\n}\n\nexport const destroy = async (ctx: UserCtx) => {\n const { id, rev } = ctx.params\n try {\n await groups.remove(id, rev)\n ctx.body = { message: \"Group deleted successfully\" }\n } catch (err: any) {\n ctx.throw(err.status, err)\n }\n}\n\n/**\n * Gets a group by ID from the global database.\n */\nexport const find = async (ctx: UserCtx) => {\n try {\n ctx.body = await groups.get(ctx.params.id)\n } catch (err: any) {\n ctx.throw(err.status, err)\n }\n}\n\nexport const searchUsers = async (ctx: Ctx<{}, SearchUserGroupResponse>) => {\n const { pageSize = 10, bookmark, emailSearch } = ctx.request.query as any\n const groupId = ctx.params.id\n\n const params: DatabaseQueryOpts = { limit: pageSize + 1 }\n\n const users = await getGroupUsers(groupId, {\n ...params,\n emailSearch,\n bookmark,\n })\n\n const nextBookmark = emailSearch\n ? users[pageSize]?.email\n : users[pageSize]?._id\n const hasNextPage = !!nextBookmark\n\n ctx.body = {\n users: users.slice(0, pageSize),\n bookmark: nextBookmark,\n hasNextPage,\n }\n}\n", "import {\n AppEnvironment,\n CreateEnvironmentVariableRequest,\n GetEnvironmentVariablesResponse,\n StatusEnvironmentVariableResponse,\n UpdateEnvironmentVariableRequest,\n UserCtx,\n} from \"@budibase/types\"\nimport { environmentVariables } from \"../../../sdk\"\nimport { events } from \"@budibase/backend-core\"\n\nexport async function status(\n ctx: UserCtx<void, StatusEnvironmentVariableResponse>\n) {\n ctx.body = {\n encryptionKeyAvailable: environmentVariables.isEncryptionKeyAvailable(),\n }\n}\n\nexport async function fetch(\n ctx: UserCtx<void, GetEnvironmentVariablesResponse>\n) {\n ctx.body = {\n variables: await environmentVariables.fetch(),\n }\n}\n\nexport async function create(\n ctx: UserCtx<CreateEnvironmentVariableRequest, void>\n) {\n const { name, production, development } = ctx.request.body\n await environmentVariables.update(name, { production, development })\n const environments = [AppEnvironment.PRODUCTION]\n if (production !== development) {\n environments.push(AppEnvironment.DEVELOPMENT)\n }\n await events.environmentVariable.created(name, environments)\n ctx.status = 200\n}\n\nexport async function update(\n ctx: UserCtx<UpdateEnvironmentVariableRequest, void>\n) {\n const { production, development } = ctx.request.body\n const varName = ctx.params.varName\n await environmentVariables.update(varName, { production, development })\n ctx.status = 200\n}\n\nexport async function destroy(ctx: UserCtx<void, void>) {\n const varName = ctx.params.varName\n await environmentVariables.remove(varName)\n await events.environmentVariable.deleted(varName)\n ctx.status = 200\n}\n", "import { groups } from \"../../controllers/global\"\nimport Router from \"@koa/router\"\nimport Joi from \"joi\"\nimport { feature } from \"../../../middleware\"\nimport { Feature } from \"@budibase/types\"\nimport { auth } from \"@budibase/backend-core\"\n\nconst router: Router = new Router()\n\nfunction buildGroupSaveValidation() {\n return auth.joiValidator.body(\n Joi.object({\n _id: Joi.string().optional(),\n _rev: Joi.string().optional(),\n color: Joi.string().required(),\n icon: Joi.string().required(),\n name: Joi.string().trim().required().max(50),\n role: Joi.string().optional(),\n users: Joi.array().optional(),\n apps: Joi.array().optional(),\n roles: Joi.object().optional(),\n createdAt: Joi.string().optional(),\n updatedAt: Joi.string().optional(),\n }).required()\n )\n}\n\nrouter\n .post(\n \"/api/global/groups\",\n auth.adminOnly,\n feature.requireFeature(Feature.USER_GROUPS),\n buildGroupSaveValidation(),\n groups.save\n )\n .get(\n \"/api/global/groups\",\n feature.requireFeature(Feature.USER_GROUPS),\n groups.fetch\n )\n\n .delete(\n \"/api/global/groups/:id/:rev\",\n feature.requireFeature(Feature.USER_GROUPS),\n auth.adminOnly,\n groups.destroy\n )\n .get(\n \"/api/global/groups/:id\",\n feature.requireFeature(Feature.USER_GROUPS),\n auth.adminOnly,\n groups.find\n )\n .get(\n \"/api/global/groups/:id/users\",\n feature.requireFeature(Feature.USER_GROUPS),\n auth.adminOnly,\n groups.searchUsers\n )\n // these endpoints adjust existing groups\n .post(\n \"/api/global/groups/:id/users\",\n auth.adminOnly,\n feature.requireFeature(Feature.USER_GROUPS),\n groups.updateGroupUsers\n )\n .post(\n \"/api/global/groups/:id/apps\",\n auth.builderOrAdmin,\n feature.requireFeature(Feature.USER_GROUPS),\n groups.updateGroupApps\n )\n\nexport default router\n", "import * as controllers from \"../../controllers/global/environmentVariables\"\nimport { auth } from \"@budibase/backend-core\"\nimport Router from \"@koa/router\"\nimport Joi from \"joi\"\n\nconst router: Router = new Router()\n\nfunction buildEnvVarUpdateValidator() {\n return auth.joiValidator.body(\n Joi.object({\n name: Joi.string().optional(),\n production: Joi.string().required(),\n development: Joi.string().required(),\n })\n )\n}\n\nrouter\n .get(\"/api/env/variables/status\", auth.builderOrAdmin, controllers.status)\n .get(\"/api/env/variables\", auth.builderOrAdmin, controllers.fetch)\n .post(\n \"/api/env/variables\",\n auth.builderOrAdmin,\n buildEnvVarUpdateValidator(),\n controllers.create\n )\n .patch(\n \"/api/env/variables/:varName\",\n auth.builderOrAdmin,\n buildEnvVarUpdateValidator(),\n controllers.update\n )\n .delete(\n \"/api/env/variables/:varName\",\n auth.builderOrAdmin,\n controllers.destroy\n )\n\nexport default router\n", "import {\n SearchAuditLogsRequest,\n SearchAuditLogsResponse,\n DownloadAuditLogsRequest,\n DefinitionsAuditLogsResponse,\n AuditLogSearchParams,\n UserCtx,\n} from \"@budibase/types\"\nimport { auditLogs } from \"../../../sdk\"\nimport { events } from \"@budibase/backend-core\"\nimport { Readable } from \"stream\"\n\nexport async function search(\n ctx: UserCtx<SearchAuditLogsRequest, SearchAuditLogsResponse>\n) {\n const search: AuditLogSearchParams = ctx.request.body\n const fetched = await auditLogs.fetch(search)\n await events.auditLog.filtered(search)\n ctx.body = fetched\n}\n\nexport async function download(\n ctx: UserCtx<DownloadAuditLogsRequest, Readable>\n) {\n const search: AuditLogSearchParams = ctx.request.body\n const { stream } = auditLogs.download(search)\n await events.auditLog.downloaded(search)\n ctx.attachment(`audit-logs-${Date.now()}.log`)\n ctx.body = stream\n}\n\nexport async function definitions(\n ctx: UserCtx<void, DefinitionsAuditLogsResponse>\n) {\n ctx.body = {\n events: auditLogs.definitions(),\n }\n}\n", "import * as controllers from \"../../controllers/global/auditLogs\"\nimport { Event } from \"@budibase/types\"\nimport { auth, middleware } from \"@budibase/backend-core\"\nimport Router from \"@koa/router\"\nimport Joi from \"joi\"\n\nfunction buildAuditLogSearchValidator() {\n return auth.joiValidator.body(\n Joi.object({\n userIds: Joi.array().items(Joi.string()).optional(),\n appIds: Joi.array().items(Joi.string()).optional(),\n events: Joi.array()\n .items(Joi.string().valid(...Object.values(Event)))\n .optional(),\n startDate: Joi.string().optional().allow(\"\"),\n endDate: Joi.string().optional().allow(\"\"),\n fullSearch: Joi.string().optional().allow(\"\"),\n bookmark: Joi.string().optional().allow(\"\"),\n })\n )\n}\n\nconst router: Router = new Router()\n\nrouter\n .post(\n \"/api/global/auditlogs/search\",\n auth.adminOnly,\n buildAuditLogSearchValidator(),\n controllers.search\n )\n .get(\n \"/api/global/auditlogs/download\",\n auth.adminOnly,\n // convert query string param to body\n middleware.querystringToBody,\n buildAuditLogSearchValidator(),\n controllers.download\n )\n .get(\n \"/api/global/auditlogs/definitions\",\n auth.adminOnly,\n controllers.definitions\n )\n\nexport default router\n", "import {\n CreateAppBackupRequest,\n SearchAppBackupsRequest,\n UpdateAppBackupRequest,\n AppBackupTrigger,\n UserCtx,\n} from \"@budibase/types\"\nimport { backups, utils } from \"../../../sdk\"\nimport { events } from \"@budibase/backend-core\"\nimport fs from \"fs\"\n\nasync function checkAppID(ctx: UserCtx, appId: string) {\n if (!(await utils.appExists(appId))) {\n ctx.throw(400, `Provided app ID: ${appId} - is invalid.`)\n }\n}\n\nexport async function manualBackup(ctx: UserCtx) {\n const appId = ctx.params.appId\n await checkAppID(ctx, appId)\n const body = ctx.request.body as CreateAppBackupRequest\n const createdBy = ctx.user?._id\n const backupId = await backups.triggerAppBackup(\n appId,\n AppBackupTrigger.MANUAL,\n {\n name: body.name,\n createdBy,\n }\n )\n if (!backupId) {\n ctx.throw(500, \"Unable to start backup.\")\n }\n ctx.body = {\n backupId,\n message: \"Backup triggered - process starting.\",\n }\n}\n\nexport async function importBackup(ctx: UserCtx) {\n const appId = ctx.params.appId\n await checkAppID(ctx, appId)\n const backupId = ctx.params.backupId\n const nameForBackup = ctx.request.body.name\n const response = await backups.triggerAppRestore(\n appId,\n backupId,\n nameForBackup,\n ctx.user?._id\n )\n if (!response) {\n ctx.throw(500, \"Unable to start restore.\")\n }\n await events.backup.appBackupRestored(response.metadata)\n ctx.body = {\n restoredId: response?.restoreId,\n message: \"Restore triggered - process starting.\",\n }\n}\n\nexport async function deleteBackup(ctx: UserCtx) {\n const appId = ctx.params.appId\n await checkAppID(ctx, appId)\n const backupId = ctx.params.backupId\n await backups.deleteAppBackup(backupId)\n ctx.body = {\n message: \"Backup deleted successfully.\",\n }\n}\n\nexport async function fetchBackups(ctx: UserCtx) {\n const appId = ctx.params.appId\n await checkAppID(ctx, appId)\n const body = ctx.request.body as SearchAppBackupsRequest\n if (body?.trigger) {\n body.trigger = body.trigger.toLowerCase() as AppBackupTrigger\n if (!Object.values(AppBackupTrigger).includes(body.trigger)) {\n ctx.throw(400, \"Provided trigger is not a valid option.\")\n }\n }\n ctx.body = await backups.fetchAppBackups(appId, {\n paginate: true,\n ...body,\n })\n}\n\nexport async function updateBackup(ctx: UserCtx) {\n const appId = ctx.params.appId\n await checkAppID(ctx, appId)\n const backupId = ctx.params.backupId\n const body = ctx.request.body as UpdateAppBackupRequest\n ctx.body = await backups.updateAppBackup(backupId, body.name)\n}\n\nexport async function downloadBackup(ctx: UserCtx) {\n const appId = ctx.params.appId\n await checkAppID(ctx, appId)\n const backupId = ctx.params.backupId\n const { metadata, path } = await backups.downloadAppBackup(backupId)\n ctx.attachment(`backup-${metadata.timestamp}.tar.gz`)\n ctx.body = fs.createReadStream(path)\n}\n", "import * as backups from \"../../controllers/apps/backups\"\nimport Router from \"@koa/router\"\nimport Joi from \"joi\"\nimport { AppBackupTrigger, AppBackupType } from \"@budibase/types\"\nimport { auth } from \"@budibase/backend-core\"\n\nconst router: Router = new Router()\n\nfunction validateBackupSearch() {\n return auth.joiValidator.body(\n Joi.object({\n trigger: Joi.string().valid(...Object.values(AppBackupTrigger)),\n type: Joi.string().valid(...Object.values(AppBackupType)),\n startDate: Joi.date(),\n endDate: Joi.date(),\n page: Joi.string(),\n })\n )\n}\n\nrouter\n .post(\"/api/apps/:appId/backups\", auth.builderOrAdmin, backups.manualBackup)\n .post(\n \"/api/apps/:appId/backups/search\",\n auth.builderOrAdmin,\n validateBackupSearch(),\n backups.fetchBackups\n )\n .get(\n \"/api/apps/:appId/backups/:backupId/file\",\n auth.builderOrAdmin,\n backups.downloadBackup\n )\n .patch(\n \"/api/apps/:appId/backups/:backupId\",\n auth.builderOrAdmin,\n backups.updateBackup\n )\n .delete(\n \"/api/apps/:appId/backups/:backupId\",\n auth.builderOrAdmin,\n backups.deleteBackup\n )\n .post(\n \"/api/apps/:appId/backups/:backupId/import\",\n auth.builderOrAdmin,\n backups.importBackup\n )\n\nexport default router\n", "import {\n BBContext,\n CreateScheduleRequest,\n UpdateScheduleRequest,\n} from \"@budibase/types\"\n\n/**\n * This file is a work in progress - to be filled out\n * in a future update.\n */\n\nexport function createSchedule(ctx: BBContext) {\n const body = ctx.body as CreateScheduleRequest\n ctx.status = 501\n}\n\nexport function fetchSchedules(ctx: BBContext) {\n const type = ctx.params.type\n ctx.status = 501\n}\n\nexport function updateSchedule(ctx: BBContext) {\n const scheduleId = ctx.params.scheduleId\n const body = ctx.body as UpdateScheduleRequest\n ctx.status = 501\n}\n\nexport function deleteSchedule(ctx: BBContext) {\n const scheduleId = ctx.params.scheduleId\n ctx.status = 501\n}\n", "import * as schedules from \"../../controllers/schedules\"\nimport Router from \"@koa/router\"\nimport Joi from \"joi\"\nimport { feature } from \"../../../middleware\"\nimport { Feature, ScheduleType, ScheduleRepeatPeriod } from \"@budibase/types\"\nimport { auth } from \"@budibase/backend-core\"\n\nconst router: Router = new Router()\n\nfunction validateSchedulesCreateOrUpdate() {\n return auth.joiValidator.body(\n Joi.object({\n type: Joi.string()\n .valid(...Object.keys(ScheduleType))\n .required(),\n name: Joi.string().required(),\n startDate: Joi.date().required(),\n repeat: Joi.string()\n .valid(...Object.keys(ScheduleRepeatPeriod))\n .required(),\n metadata: Joi.alternatives().conditional(\".type\", {\n switch: [\n {\n is: ScheduleType.APP_BACKUP,\n then: {\n apps: Joi.array().items(Joi.string()).required(),\n },\n },\n ],\n }),\n })\n )\n}\n\nrouter\n .get(\n \"/api/schedules/:type\",\n auth.builderOrAdmin,\n feature.requireFeature(Feature.APP_BACKUPS),\n schedules.fetchSchedules\n )\n .put(\n \"/api/schedules/:scheduleId\",\n auth.builderOrAdmin,\n feature.requireFeature(Feature.APP_BACKUPS),\n validateSchedulesCreateOrUpdate(),\n schedules.updateSchedule\n )\n .delete(\n \"/api/schedules/:scheduleId\",\n auth.builderOrAdmin,\n feature.requireFeature(Feature.APP_BACKUPS),\n schedules.deleteSchedule\n )\n .post(\n \"/api/schedules\",\n auth.builderOrAdmin,\n feature.requireFeature(Feature.APP_BACKUPS),\n validateSchedulesCreateOrUpdate(),\n schedules.createSchedule\n )\n\nexport default router\n", "import Router from \"@koa/router\"\nimport { requireSCIM, doInScimContext } from \"../../../middleware\"\n\nimport * as userController from \"../../controllers/global/scim/users\"\nimport * as groupController from \"../../controllers/global/scim/groups\"\n\nconst router: Router = new Router({\n prefix: \"/api/global/scim/v2\",\n})\n\n// @ts-ignore - this produces a type error on account portal unit tests\nrouter.use(requireSCIM)\nrouter.use(doInScimContext)\n\nrouter.get(\"/users\", userController.get)\nrouter.get(\"/users/:id\", userController.find)\nrouter.post(\"/users\", userController.create)\nrouter.patch(\"/users/:id\", userController.update)\nrouter.delete(\"/users/:id\", userController.remove)\n\nrouter.get(\"/groups\", groupController.get)\nrouter.post(\"/groups\", groupController.create)\nrouter.get(\"/groups/:id\", groupController.find)\nrouter.delete(\"/groups/:id\", groupController.remove)\nrouter.patch(\"/groups/:id\", groupController.update)\n\nexport default router\n", "import { patchBodyValidation, scimPatch } from \"scim-patch\"\nimport {\n Ctx,\n ScimUserListResponse,\n ScimCreateUserRequest,\n ScimUserResponse,\n ScimUpdateRequest,\n} from \"@budibase/types\"\nimport { mappers } from \"../../../../\"\nimport { scimUsers } from \"../../../../sdk\"\nimport { EmailUnavailableError } from \"@budibase/backend-core\"\n\nfunction tryGetQueryAsNumber(ctx: Ctx, name: string) {\n const value = ctx.request.query[name]\n if (value === undefined) {\n return undefined\n }\n\n return +value\n}\n\nexport const get = async (ctx: Ctx<void, ScimUserListResponse>) => {\n const pageSize = tryGetQueryAsNumber(ctx, \"pageSize\") ?? 20\n const skip = tryGetQueryAsNumber(ctx, \"startIndex\")\n\n let filters\n if (ctx.request.query.filter) {\n filters = mappers.user.userFilters(ctx.request.query.filter as string)\n }\n\n const getResponse = await scimUsers.get({ pageSize, skip, filters })\n ctx.body = {\n schemas: [\"urn:ietf:params:scim:api:messages:2.0:ListResponse\"],\n totalResults: getResponse.total,\n Resources: getResponse.users.map(mappers.user.toScimUserResponse),\n startIndex: (skip || 0) + 1,\n itemsPerPage: pageSize,\n }\n}\n\nexport const find = async (ctx: Ctx<void, ScimUserResponse>) => {\n const { id } = ctx.params\n if (typeof id !== \"string\") {\n ctx.throw(404)\n }\n\n const user = await scimUsers.find(id)\n ctx.body = mappers.user.toScimUserResponse(user)\n}\n\nexport const create = async (\n ctx: Ctx<ScimCreateUserRequest, ScimUserResponse>\n) => {\n const userToCreate = mappers.user.fromScimUser(ctx.request.body)\n try {\n const user = await scimUsers.create(userToCreate)\n ctx.body = mappers.user.toScimUserResponse(user)\n } catch (e) {\n if (e instanceof EmailUnavailableError) {\n ctx.throw(409, \"Email already in use\")\n }\n\n throw e\n }\n}\n\nfunction isDeactivation(request: ScimUpdateRequest) {\n const activeFieldChange = request.Operations.find(\n o => (o.op === \"Replace\" || o.op === \"replace\") && o.path === \"active\"\n )\n if (!activeFieldChange) {\n return false\n }\n\n return (\n activeFieldChange.value === false ||\n activeFieldChange.value?.toLowerCase?.() === \"false\"\n )\n}\n\nexport const update = async (ctx: Ctx<ScimUpdateRequest, ScimUserResponse>) => {\n const user = await scimUsers.find(ctx.params.id)\n if (!user) {\n ctx.throw(404)\n }\n\n const scimUser = mappers.user.toScimUserResponse(user)\n\n const patchs = ctx.request.body\n try {\n patchBodyValidation(patchs)\n } catch (error) {\n // Here if there are an error in you SCIM request.\n }\n\n if (isDeactivation(patchs)) {\n return remove(ctx)\n }\n\n let patchedScimUser\n try {\n patchedScimUser = scimPatch(scimUser, patchs.Operations)\n } catch (error) {\n // Here if there is an error during the patch.\n }\n\n if (!patchedScimUser) {\n ctx.throw(500)\n }\n\n const userToUpdate = mappers.user.fromScimUser(patchedScimUser)\n await scimUsers.update(userToUpdate)\n\n ctx.body = mappers.user.toScimUserResponse(userToUpdate)\n}\n\nexport const remove = async (ctx: Ctx) => {\n const { id } = ctx.params\n if (typeof id !== \"string\") {\n ctx.throw(404)\n }\n\n await scimUsers.remove(id)\n ctx.status = 204\n}\n", "import _ from \"lodash\"\nimport {\n Ctx,\n ScimCreateGroupRequest,\n ScimGroupListResponse,\n ScimGroupResponse,\n ScimUpdateRequest,\n UserGroup,\n} from \"@budibase/types\"\nimport { utils } from \"@budibase/shared-core\"\nimport { patchBodyValidation, scimPatch } from \"scim-patch\"\nimport { groups, mappers, scimUsers } from \"../../../../\"\nimport { filter, parse } from \"scim2-parse-filter\"\n\nfunction cleanResponse(group: ScimGroupResponse, excludedAttributes: string) {\n for (const attr of (excludedAttributes as string).split(\",\")) {\n delete (group as any)[attr]\n }\n}\n\nexport const get = async (ctx: Ctx<void, ScimGroupListResponse>) => {\n const fetchedGroups = await groups.fetch()\n let result = fetchedGroups.map(mappers.group.toScimGroupResponse)\n\n const { filter: reqFilter, excludedAttributes } = ctx.request.query\n\n if (reqFilter) {\n const filterFunc = filter(parse(reqFilter as string))\n result = result.filter(filterFunc)\n }\n\n if (excludedAttributes) {\n result.forEach((g: any) => {\n cleanResponse(g, excludedAttributes as string)\n })\n }\n\n ctx.body = {\n schemas: [\"urn:ietf:params:scim:api:messages:2.0:ListResponse\"],\n totalResults: result.length,\n Resources: result,\n startIndex: 1,\n itemsPerPage: result.length,\n }\n}\n\nexport const create = async (\n ctx: Ctx<ScimCreateGroupRequest, ScimGroupResponse>\n) => {\n const groupToCreate = mappers.group.fromScimGroup(ctx.request.body)\n const createdGroup = await groups.save(groupToCreate)\n const group = await groups.get(createdGroup!.id)\n ctx.body = mappers.group.toScimGroupResponse(group)\n}\n\nexport const find = async (ctx: Ctx<void, ScimGroupResponse>) => {\n const { id } = ctx.params\n if (typeof id !== \"string\") {\n ctx.throw(404)\n }\n\n const group = await groups.get(id)\n const response = mappers.group.toScimGroupResponse(group)\n\n const { excludedAttributes } = ctx.request.query\n if (excludedAttributes) {\n cleanResponse(response, excludedAttributes as string)\n }\n\n ctx.body = response\n}\n\nexport const remove = async (ctx: Ctx) => {\n const { id } = ctx.params\n if (typeof id !== \"string\") {\n ctx.throw(404)\n }\n\n const { _rev } = await groups.get(id)\n await groups.remove(id, _rev!)\n ctx.status = 204\n}\n\nexport const update = async (\n ctx: Ctx<ScimUpdateRequest, ScimGroupResponse>\n) => {\n const { id } = ctx.params\n const group = await groups.get(id)\n if (!group) {\n ctx.throw(404)\n }\n\n const scimGroup = mappers.group.toScimGroupResponse(group)\n\n const patchs = ctx.request.body\n try {\n // Validate request\n patchBodyValidation(patchs)\n } catch (error) {\n ctx.throw(400)\n }\n\n const { true: memberOps, false: fieldOps } = _.groupBy(\n patchs.Operations,\n p => p.path === \"members\"\n )\n\n if (fieldOps?.length) {\n const patchedScimGroup = scimPatch(scimGroup, fieldOps)\n if (!patchedScimGroup) {\n ctx.throw(500)\n }\n\n const groupToUpdate: UserGroup = {\n ...mappers.group.fromScimGroup(patchedScimGroup),\n _rev: group._rev,\n }\n await groups.save(groupToUpdate)\n }\n\n if (memberOps?.length) {\n const usersToAdd = []\n const usersToRemove = []\n for (const { op, value } of memberOps) {\n switch (op) {\n case \"add\":\n case \"Add\":\n for (const u of value) {\n usersToAdd.push(await scimUsers.find(u.value))\n }\n break\n case \"remove\":\n case \"Remove\":\n for (const u of value) {\n usersToRemove.push(await scimUsers.find(u.value))\n }\n break\n case \"replace\":\n case \"Replace\":\n throw new Error(\"Replacing members is not allowed\")\n default:\n utils.unreachable(op)\n }\n }\n\n if (usersToAdd.length) {\n await groups.addUsers(\n id,\n usersToAdd.map(u => u._id!)\n )\n }\n if (usersToRemove.length) {\n await groups.removeUsers(\n id,\n usersToRemove.map(u => u._id!)\n )\n }\n }\n\n ctx.body = mappers.group.toScimGroupResponse(await groups.get(id))\n}\n", "export * as user from \"./users\"\nexport * as group from \"./groups\"\n", "import {\n ScimUserResponse,\n ScimCreateUserRequest,\n User,\n UserStatus,\n} from \"@budibase/types\"\nimport { Filter, parse } from \"scim2-parse-filter\"\nimport { GetUsersFilters } from \"../sdk/scim/users\"\nimport { utils } from \"@budibase/backend-core\"\n\nexport const toScimUserResponse = (user: User): ScimUserResponse => {\n const { isSync, roles, ...scimInfo } = user.scimInfo || ({} as any)\n\n const response = {\n ...scimInfo,\n schemas: [\"urn:ietf:params:scim:schemas:core:2.0:User\"],\n id: user._id!,\n meta: {\n resourceType: \"User\",\n created: new Date(user.createdAt!),\n lastModified: new Date(user.updatedAt!),\n },\n active: user.status === UserStatus.ACTIVE,\n } as ScimUserResponse\n\n if (user.firstName || user.lastName) {\n response.name = {\n formatted: [user.firstName, user.lastName].filter(s => s).join(\" \"),\n familyName: user.lastName,\n givenName: user.firstName,\n }\n }\n\n return response\n}\n\nconst isScimUserResponse = (\n user: ScimUserResponse | ScimCreateUserRequest\n): user is ScimUserResponse => {\n return !!(user as ScimUserResponse)?.id\n}\n\nfunction tryGetEmail(\n user: ScimUserResponse | ScimCreateUserRequest\n): string | undefined {\n if (utils.validEmail(user.userName)) {\n return user.userName\n }\n\n if (!user.emails) {\n return undefined\n }\n\n return user.emails.find(x => x.primary)?.value || user.emails[0]?.value\n}\n\nexport const fromScimUser = (\n scimUser: ScimUserResponse | ScimCreateUserRequest\n): User => {\n const existingUser = isScimUserResponse(scimUser) ? scimUser : undefined\n\n const email = tryGetEmail(scimUser)\n if (!email) {\n throw new Error(\"Email is required\")\n }\n\n let isActive\n switch (scimUser.active) {\n case \"True\":\n case \"true\":\n case true:\n isActive = true\n break\n case \"False\":\n case \"false\":\n case false:\n isActive = false\n break\n default:\n ;(function unreachable(\n value: never,\n message = `No such case in exhaustive switch: ${value}`\n ) {\n throw new Error(message)\n })(scimUser.active)\n }\n\n const u: User = {\n // This is actually not required, but required in the types\n tenantId: \"\",\n _id: existingUser?.id,\n userId: existingUser?.id,\n email,\n firstName: scimUser.name?.givenName,\n lastName: scimUser.name?.familyName,\n scimInfo: {\n ...scimUser,\n isSync: true,\n },\n roles: {},\n status: isActive ? UserStatus.ACTIVE : UserStatus.INACTIVE,\n createdAt: existingUser?.meta.created.getTime(),\n updatedAt: existingUser?.meta.lastModified.toISOString(),\n }\n return u\n}\n\nexport const userFilters = (filter: string): GetUsersFilters => {\n const filters: GetUsersFilters = {\n equal: {},\n }\n\n const parsed = parse(filter)\n\n function parseFilters(filter: Filter) {\n switch (filter.op) {\n case \"eq\":\n const attribute = filter.attrPath\n let attributeToMap\n switch (attribute) {\n case \"emails.value\":\n attributeToMap = \"email\"\n break\n default:\n attributeToMap = `scimInfo.${attribute}`\n }\n\n filters.equal![attributeToMap] = filter.compValue\n break\n case \"and\":\n for (const f of filter.filters) {\n parseFilters(f)\n }\n break\n default:\n console.warn(\"Filter not handled\", { filter })\n }\n }\n\n parseFilters(parsed)\n\n return filters\n}\n", "import {\n ScimCreateGroupRequest,\n ScimGroupResponse,\n UserGroup,\n} from \"@budibase/types\"\n\nexport const toScimGroupResponse = (group: UserGroup): ScimGroupResponse => {\n return {\n schemas: [\"urn:ietf:params:scim:schemas:core:2.0:Group\"],\n id: group._id!,\n externalId: group.scimInfo!.externalId,\n meta: {\n resourceType: \"Group\",\n created: new Date(group.createdAt!),\n lastModified: new Date(group.updatedAt!),\n },\n displayName: group.name,\n members: group.users?.map(u => ({ value: u._id })),\n }\n}\n\nconst isScimGroup = (\n group: ScimGroupResponse | ScimCreateGroupRequest\n): group is ScimGroupResponse => {\n return !!(group as ScimGroupResponse)?.id\n}\n\nexport const fromScimGroup = (\n group: ScimGroupResponse | ScimCreateGroupRequest\n): UserGroup => {\n const existingGroup = isScimGroup(group) ? group : undefined\n\n const g: UserGroup = {\n _id: existingGroup?.id,\n name: group.displayName,\n scimInfo: {\n externalId: group.externalId,\n isSync: true,\n },\n icon: \"UserGroup\",\n color: \"var(--spectrum-global-color-blue-600)\",\n createdAt: existingGroup?.meta.created.getTime(),\n updatedAt: existingGroup?.meta.lastModified.toISOString(),\n }\n return g\n}\n", "import { environmentVariables } from \"@budibase/pro\"\nimport { context, db as dbCore } from \"@budibase/backend-core\"\nimport { AppEnvironment } from \"@budibase/types\"\n\nexport async function getEnvironmentVariables() {\n let envVars = context.getEnvironmentVariables()\n if (!envVars) {\n const appId = context.getAppId()\n const appEnv = dbCore.isDevAppID(appId)\n ? AppEnvironment.DEVELOPMENT\n : AppEnvironment.PRODUCTION\n\n envVars = await environmentVariables.fetchValues(appEnv)\n }\n return envVars\n}\n", "import * as datasources from \"./datasources\"\n\nexport default {\n ...datasources,\n}\n", "import { context } from \"@budibase/backend-core\"\nimport { BudibaseInternalDB, getTableParams } from \"../../../db/utils\"\nimport {\n breakExternalTableId,\n isExternalTable,\n isSQL,\n} from \"../../../integrations/utils\"\nimport { Table, Database } from \"@budibase/types\"\nimport datasources from \"../datasources\"\n\nasync function getAllInternalTables(db?: Database): Promise<Table[]> {\n if (!db) {\n db = context.getAppDB()\n }\n const internalTables = await db.allDocs(\n getTableParams(null, {\n include_docs: true,\n })\n )\n return internalTables.rows.map((tableDoc: any) => ({\n ...tableDoc.doc,\n type: \"internal\",\n sourceId: tableDoc.doc.sourceId || BudibaseInternalDB._id,\n }))\n}\n\nasync function getAllExternalTables(\n datasourceId: any\n): Promise<Record<string, Table>> {\n const db = context.getAppDB()\n const datasource = await datasources.get(datasourceId, { enriched: true })\n if (!datasource || !datasource.entities) {\n throw \"Datasource is not configured fully.\"\n }\n return datasource.entities\n}\n\nasync function getExternalTable(\n datasourceId: any,\n tableName: any\n): Promise<Table> {\n const entities = await getAllExternalTables(datasourceId)\n return entities[tableName]\n}\n\nasync function getTable(tableId: any): Promise<Table> {\n const db = context.getAppDB()\n if (isExternalTable(tableId)) {\n let { datasourceId, tableName } = breakExternalTableId(tableId)\n const datasource = await datasources.get(datasourceId!)\n const table = await getExternalTable(datasourceId, tableName)\n return { ...table, sql: isSQL(datasource) }\n } else {\n return db.get(tableId)\n }\n}\n\nexport default {\n getAllInternalTables,\n getAllExternalTables,\n getExternalTable,\n getTable,\n}\n", "import { Webhook, WebhookActionType } from \"@budibase/types\"\nimport { db as dbCore, context } from \"@budibase/backend-core\"\nimport { generateWebhookID } from \"../../../db/utils\"\n\nfunction isWebhookID(id: string) {\n return id.startsWith(dbCore.DocumentType.WEBHOOK)\n}\n\nexport function newDoc(\n name: string,\n type: WebhookActionType,\n target: string\n): Webhook {\n return {\n live: true,\n name,\n action: {\n type,\n target,\n },\n }\n}\n\nexport async function save(webhook: Webhook) {\n const db = context.getAppDB()\n // check that the webhook exists\n if (webhook._id && isWebhookID(webhook._id)) {\n await db.get(webhook._id)\n } else {\n webhook._id = generateWebhookID()\n }\n const response = await db.put(webhook)\n webhook._rev = response.rev\n return webhook\n}\n\nexport async function destroy(id: string, rev: string) {\n const db = context.getAppDB()\n if (!id || !isWebhookID(id)) {\n throw new Error(\"Provided webhook ID is not valid.\")\n }\n return await db.remove(id, rev)\n}\n", "import { Automation, AutomationActionStepId } from \"@budibase/types\"\n\nexport function checkForCollectStep(automation: Automation) {\n return automation.definition.steps.some(\n (step: any) => step.stepId === AutomationActionStepId.COLLECT\n )\n}\n", "import * as webhook from \"./webhook\"\nimport * as utils from \"./utils\"\n\nexport default {\n webhook,\n utils,\n}\n", "import env from \"../../../environment\"\nimport {\n db as dbCore,\n context,\n docUpdates,\n constants,\n logging,\n roles,\n} from \"@budibase/backend-core\"\nimport { User, ContextUser, UserGroup } from \"@budibase/types\"\nimport { sdk as proSdk } from \"@budibase/pro\"\nimport sdk from \"../../\"\nimport { getGlobalUsers, processUser } from \"../../../utilities/global\"\nimport { generateUserMetadataID, InternalTables } from \"../../../db/utils\"\n\ntype DeletedUser = { _id: string; deleted: boolean }\n\nasync function syncUsersToApp(\n appId: string,\n users: (User | DeletedUser)[],\n groups: UserGroup[]\n) {\n if (!(await dbCore.dbExists(appId))) {\n return\n }\n await context.doInAppContext(appId, async () => {\n const db = context.getAppDB()\n for (let user of users) {\n let ctxUser = user as ContextUser\n let deletedUser = false\n const metadataId = generateUserMetadataID(user._id!)\n if ((user as DeletedUser).deleted) {\n deletedUser = true\n }\n\n // make sure role is correct\n if (!deletedUser) {\n ctxUser = await processUser(ctxUser, { appId, groups })\n }\n let roleId = ctxUser.roleId\n if (roleId === roles.BUILTIN_ROLE_IDS.PUBLIC) {\n roleId = undefined\n }\n\n let metadata\n try {\n metadata = await db.get(metadataId)\n } catch (err: any) {\n if (err.status !== 404) {\n throw err\n }\n // no metadata and user is to be deleted, can skip\n // no role - user isn't in app anyway\n if (!roleId) {\n continue\n } else if (!deletedUser) {\n // doesn't exist yet, creating it\n metadata = {\n tableId: InternalTables.USER_METADATA,\n }\n }\n }\n\n // the user doesn't exist, or doesn't have a role anymore\n // get rid of their metadata\n if (deletedUser || !roleId) {\n await db.remove(metadata)\n continue\n }\n\n // assign the roleId for the metadata doc\n if (roleId) {\n metadata.roleId = roleId\n }\n\n let combined = sdk.users.combineMetadataAndUser(ctxUser, metadata)\n // if no combined returned, there are no updates to make\n if (combined) {\n await db.put(combined)\n }\n }\n })\n}\n\nexport async function syncUsersToAllApps(userIds: string[]) {\n // list of users, if one has been deleted it will be undefined in array\n const users = (await getGlobalUsers(userIds, {\n noProcessing: true,\n })) as User[]\n const groups = await proSdk.groups.fetch()\n const finalUsers: (User | DeletedUser)[] = []\n for (let userId of userIds) {\n const user = users.find(user => user._id === userId)\n if (!user) {\n finalUsers.push({ _id: userId, deleted: true })\n } else {\n finalUsers.push(user)\n }\n }\n const devAppIds = await dbCore.getDevAppIDs()\n let promises = []\n for (let devAppId of devAppIds) {\n const prodAppId = dbCore.getProdAppID(devAppId)\n for (let appId of [prodAppId, devAppId]) {\n promises.push(syncUsersToApp(appId, finalUsers, groups))\n }\n }\n const resp = await Promise.allSettled(promises)\n const failed = resp.filter(promise => promise.status === \"rejected\")\n if (failed.length > 0) {\n const reasons = failed.map(fail => (fail as PromiseRejectedResult).reason)\n logging.logAlert(\"Failed to sync users to apps\", reasons)\n }\n}\n\nexport async function syncApp(\n appId: string,\n opts?: { automationOnly?: boolean }\n) {\n if (env.DISABLE_AUTO_PROD_APP_SYNC) {\n return {\n message:\n \"App sync disabled. You can reenable with the DISABLE_AUTO_PROD_APP_SYNC environment variable.\",\n }\n }\n\n if (dbCore.isProdAppID(appId)) {\n throw new Error(\"This action cannot be performed for production apps\")\n }\n\n // replicate prod to dev\n const prodAppId = dbCore.getProdAppID(appId)\n\n // specific case, want to make sure setup is skipped\n const prodDb = context.getProdAppDB({ skip_setup: true })\n const exists = await prodDb.exists()\n\n let error\n if (exists) {\n const replication = new dbCore.Replication({\n source: prodAppId,\n target: appId,\n })\n try {\n const replOpts = replication.appReplicateOpts()\n if (opts?.automationOnly) {\n replOpts.filter = (doc: any) =>\n doc._id.startsWith(dbCore.DocumentType.AUTOMATION)\n }\n await replication.replicate(replOpts)\n } catch (err) {\n error = err\n } finally {\n await replication.close()\n }\n }\n\n // sync the users - kept for safe keeping\n await sdk.users.syncGlobalUsers()\n\n if (error) {\n throw error\n } else {\n return {\n message: \"App sync completed successfully.\",\n }\n }\n}\n", "import { getMultiIDParams, getGlobalIDFromUserMetadataID } from \"../db/utils\"\nimport {\n roles,\n db as dbCore,\n cache,\n tenancy,\n context,\n} from \"@budibase/backend-core\"\nimport env from \"../environment\"\nimport { groups } from \"@budibase/pro\"\nimport { UserCtx, ContextUser, User, UserGroup } from \"@budibase/types\"\nimport { global } from \"yargs\"\n\nexport function updateAppRole(\n user: ContextUser,\n { appId }: { appId?: string } = {}\n) {\n appId = appId || context.getAppId()\n\n if (!user || (!user.roles && !user.userGroups)) {\n return user\n }\n // if in an multi-tenancy environment make sure roles are never updated\n if (env.MULTI_TENANCY && appId && !tenancy.isUserInAppTenant(appId, user)) {\n delete user.builder\n delete user.admin\n user.roleId = roles.BUILTIN_ROLE_IDS.PUBLIC\n return user\n }\n // always use the deployed app\n if (appId && user.roles) {\n user.roleId = user.roles[dbCore.getProdAppID(appId)]\n }\n // if a role wasn't found then either set as admin (builder) or public (everyone else)\n if (!user.roleId && user.builder && user.builder.global) {\n user.roleId = roles.BUILTIN_ROLE_IDS.ADMIN\n } else if (!user.roleId && !user?.userGroups?.length) {\n user.roleId = roles.BUILTIN_ROLE_IDS.PUBLIC\n }\n\n delete user.roles\n return user\n}\n\nasync function checkGroupRoles(\n user: ContextUser,\n opts: { appId?: string; groups?: UserGroup[] } = {}\n) {\n if (user.roleId && user.roleId !== roles.BUILTIN_ROLE_IDS.PUBLIC) {\n return user\n }\n if (opts.appId) {\n user.roleId = await groups.getGroupRoleId(user as User, opts.appId, {\n groups: opts.groups,\n })\n }\n // final fallback, simply couldn't find a role - user must be public\n if (!user.roleId) {\n user.roleId = roles.BUILTIN_ROLE_IDS.PUBLIC\n }\n return user\n}\n\nexport async function processUser(\n user: ContextUser,\n opts: { appId?: string; groups?: UserGroup[] } = {}\n) {\n if (user) {\n delete user.password\n }\n const appId = opts.appId || context.getAppId()\n user = updateAppRole(user, { appId })\n if (!user.roleId && user?.userGroups?.length) {\n user = await checkGroupRoles(user, { appId, groups: opts?.groups })\n }\n\n return user\n}\n\nexport async function getCachedSelf(ctx: UserCtx, appId: string) {\n // this has to be tenant aware, can't depend on the context to find it out\n // running some middlewares before the tenancy causes context to break\n const user = await cache.user.getUser(ctx.user?._id!)\n return processUser(user, { appId })\n}\n\nexport async function getRawGlobalUser(userId: string) {\n const db = tenancy.getGlobalDB()\n return db.get(getGlobalIDFromUserMetadataID(userId))\n}\n\nexport async function getGlobalUser(userId: string) {\n const appId = context.getAppId()\n let user = await getRawGlobalUser(userId)\n return processUser(user, { appId })\n}\n\nexport async function getGlobalUsers(\n userIds?: string[],\n opts?: { noProcessing?: boolean }\n) {\n const appId = context.getAppId()\n const db = tenancy.getGlobalDB()\n let globalUsers\n if (userIds) {\n globalUsers = (await db.allDocs(getMultiIDParams(userIds))).rows.map(\n row => row.doc\n )\n } else {\n globalUsers = (\n await db.allDocs(\n dbCore.getGlobalUserParams(null, {\n include_docs: true,\n })\n )\n ).rows.map(row => row.doc)\n }\n globalUsers = globalUsers\n .filter(user => user != null)\n .map(user => {\n delete user.password\n delete user.forceResetPassword\n return user\n })\n if (!appId) {\n return globalUsers\n }\n\n if (opts?.noProcessing) {\n return globalUsers\n } else {\n // pass in the groups, meaning we don't actually need to retrieve them for\n // each user individually\n const allGroups = await groups.fetch()\n return Promise.all(\n globalUsers.map(user => processUser(user, { groups: allGroups }))\n )\n }\n}\n\nexport async function getGlobalUsersFromMetadata(users: ContextUser[]) {\n const globalUsers = await getGlobalUsers(users.map(user => user._id!))\n return users.map(user => {\n const globalUser = globalUsers.find(\n globalUser => globalUser && user._id?.includes(globalUser._id)\n )\n return {\n ...globalUser,\n // doing user second overwrites the id and rev (always metadata)\n ...user,\n }\n })\n}\n", "const URL_REGEX_SLASH = /\\/|\\\\/g\n\nexport function getAppUrl(opts?: { name?: string; url?: string }) {\n // construct the url\n let url\n if (opts?.url) {\n // if the url is provided, use that\n url = encodeURI(opts?.url)\n } else if (opts?.name) {\n // otherwise use the name\n url = encodeURI(`${opts?.name}`)\n }\n if (url) {\n url = `/${url.replace(URL_REGEX_SLASH, \"\")}`.toLowerCase()\n }\n return url as string\n}\n", "import * as sync from \"./sync\"\nimport * as utils from \"./utils\"\n\nexport default {\n ...sync,\n ...utils,\n}\n", "import { getEnvironmentVariables } from \"../../utils\"\nimport { processStringSync } from \"@budibase/string-templates\"\n\nexport async function enrichContext(\n fields: Record<string, any>,\n inputs = {}\n): Promise<Record<string, any>> {\n const enrichedQuery: Record<string, any> = Array.isArray(fields) ? [] : {}\n if (!fields || !inputs) {\n return enrichedQuery\n }\n const env = await getEnvironmentVariables()\n const parameters = { ...inputs, env }\n // enrich the fields with dynamic parameters\n for (let key of Object.keys(fields)) {\n if (fields[key] == null) {\n continue\n }\n if (typeof fields[key] === \"object\") {\n // enrich nested fields object\n enrichedQuery[key] = await enrichContext(fields[key], parameters)\n } else if (typeof fields[key] === \"string\") {\n // enrich string value as normal\n enrichedQuery[key] = processStringSync(fields[key], parameters, {\n noEscaping: true,\n noHelpers: true,\n escapeNewlines: true,\n })\n } else {\n enrichedQuery[key] = fields[key]\n }\n }\n if (\n enrichedQuery.json ||\n enrichedQuery.customData ||\n enrichedQuery.requestBody\n ) {\n try {\n enrichedQuery.json = JSON.parse(\n enrichedQuery.json ||\n enrichedQuery.customData ||\n enrichedQuery.requestBody\n )\n } catch (err) {\n // no json found, ignore\n }\n delete enrichedQuery.customData\n }\n return enrichedQuery\n}\n", "import * as queries from \"./queries\"\n\nexport default {\n ...queries,\n}\n", "import { CouchFindOptions, Table, Row } from \"@budibase/types\"\nimport { db as dbCore } from \"@budibase/backend-core\"\nimport { DocumentType, SEPARATOR } from \"../../../db/utils\"\nimport { FieldTypes } from \"../../../constants\"\n\n// default limit - seems to work well for performance\nexport const FIND_LIMIT = 25\n\nfunction generateAttachmentFindParams(\n tableId: string,\n attachmentCols: string[],\n bookmark: null | string\n) {\n const params: CouchFindOptions = {\n selector: {\n $or: attachmentCols.map(col => ({ [col]: { $exists: true } })),\n _id: {\n $regex: `^${DocumentType.ROW}${SEPARATOR}${tableId}`,\n },\n },\n limit: FIND_LIMIT,\n }\n if (bookmark) {\n params.bookmark = bookmark\n }\n return params\n}\n\nexport async function getRowsWithAttachments(appId: string, table: Table) {\n // iterate through attachment documents and update them\n const db = dbCore.getDB(appId)\n const attachmentCols: string[] = []\n for (let [key, column] of Object.entries(table.schema)) {\n if (column.type === FieldTypes.ATTACHMENT) {\n attachmentCols.push(key)\n }\n }\n // no attachment columns, nothing to do\n if (attachmentCols.length === 0) {\n return { rows: [], columns: [] }\n }\n let bookmark: null | string = null,\n rowsLength = 0,\n rowList: Row[] = []\n do {\n const params = generateAttachmentFindParams(\n table._id!,\n attachmentCols,\n bookmark\n )\n // use the CouchDB Mango query API to lookup rows that have attachments\n const resp = await dbCore.directCouchFind(db.name, params)\n bookmark = resp.bookmark\n rowsLength = resp.rows.length\n const rows = resp.rows\n rowList = rowList.concat(rows)\n } while (rowsLength === FIND_LIMIT)\n // write back the updated attachments\n return { rows: rowList, columns: attachmentCols }\n}\n", "import { db as dbCore, context } from \"@budibase/backend-core\"\nimport { Database, Row } from \"@budibase/types\"\nimport { getRowParams } from \"../../../db/utils\"\n\nexport async function getAllInternalRows(appId?: string) {\n let db: Database\n if (appId) {\n db = dbCore.getDB(appId)\n } else {\n db = context.getAppDB()\n }\n const response = await db.allDocs(\n getRowParams(null, null, {\n include_docs: true,\n })\n )\n return response.rows.map(row => row.doc) as Row[]\n}\n", "import * as attachments from \"./attachments\"\nimport * as rows from \"./rows\"\n\nexport default {\n ...attachments,\n ...rows,\n}\n", "import { getGlobalUsers } from \"../../utilities/global\"\nimport { context, roles as rolesCore } from \"@budibase/backend-core\"\nimport {\n getGlobalIDFromUserMetadataID,\n generateUserMetadataID,\n getUserMetadataParams,\n InternalTables,\n} from \"../../db/utils\"\nimport { isEqual } from \"lodash\"\nimport { ContextUser, UserMetadata, User } from \"@budibase/types\"\n\nexport function combineMetadataAndUser(\n user: ContextUser,\n metadata: UserMetadata | UserMetadata[]\n) {\n const metadataId = generateUserMetadataID(user._id!)\n const found = Array.isArray(metadata)\n ? metadata.find(doc => doc._id === metadataId)\n : metadata\n // skip users with no access\n if (\n user.roleId == null ||\n user.roleId === rolesCore.BUILTIN_ROLE_IDS.PUBLIC\n ) {\n // If it exists and it should not, we must remove it\n if (found?._id) {\n return { ...found, _deleted: true }\n }\n return null\n }\n delete user._rev\n const newDoc = {\n ...user,\n _id: metadataId,\n tableId: InternalTables.USER_METADATA,\n }\n // copy rev over for the purposes of equality check\n if (found) {\n newDoc._rev = found._rev\n }\n // clear fields that shouldn't be in metadata\n delete newDoc.password\n delete newDoc.forceResetPassword\n delete newDoc.roles\n if (found == null || !isEqual(newDoc, found)) {\n return {\n ...found,\n ...newDoc,\n }\n }\n return null\n}\n\nexport async function rawUserMetadata() {\n const db = context.getAppDB()\n return (\n await db.allDocs(\n getUserMetadataParams(null, {\n include_docs: true,\n })\n )\n ).rows.map(row => row.doc)\n}\n\nexport async function syncGlobalUsers() {\n // sync user metadata\n const db = context.getAppDB()\n const resp = await Promise.all([getGlobalUsers(), rawUserMetadata()])\n const users = resp[0] as User[]\n const metadata = resp[1] as UserMetadata[]\n const toWrite = []\n for (let user of users) {\n const combined = combineMetadataAndUser(user, metadata)\n if (combined) {\n toWrite.push(combined)\n }\n }\n let foundEmails: string[] = []\n for (let data of metadata) {\n if (!data._id) {\n continue\n }\n const alreadyExisting = data.email && foundEmails.indexOf(data.email) !== -1\n const globalId = getGlobalIDFromUserMetadataID(data._id)\n if (!users.find(user => user._id === globalId) || alreadyExisting) {\n toWrite.push({ ...data, _deleted: true })\n }\n if (data.email) {\n foundEmails.push(data.email)\n }\n }\n await db.bulkDocs(toWrite)\n}\n", "import * as utils from \"./utils\"\n\nexport default {\n ...utils,\n}\n", "import { FileType, Plugin, PluginSource, PluginType } from \"@budibase/types\"\nimport {\n db as dbCore,\n objectStore,\n plugins as pluginCore,\n tenancy,\n} from \"@budibase/backend-core\"\nimport { fileUpload } from \"../../api/controllers/plugin/file\"\nimport env from \"../../environment\"\nimport { clientAppSocket } from \"../../websockets\"\nimport { sdk as pro } from \"@budibase/pro\"\n\nexport async function fetch(type?: PluginType) {\n const db = tenancy.getGlobalDB()\n const response = await db.allDocs(\n dbCore.getPluginParams(null, {\n include_docs: true,\n })\n )\n let plugins = response.rows.map((row: any) => row.doc) as Plugin[]\n plugins = objectStore.enrichPluginURLs(plugins)\n if (type) {\n return plugins.filter((plugin: Plugin) => plugin.schema?.type === type)\n } else {\n return plugins\n }\n}\n\nexport async function processUploaded(plugin: FileType, source?: PluginSource) {\n const { metadata, directory } = await fileUpload(plugin)\n pluginCore.validate(metadata?.schema)\n\n // Only allow components in cloud\n if (!env.SELF_HOSTED && metadata?.schema?.type !== PluginType.COMPONENT) {\n throw new Error(\"Only component plugins are supported outside of self-host\")\n }\n\n const doc = await pro.plugins.storePlugin(metadata, directory, source)\n clientAppSocket.emit(\"plugin-update\", { name: doc.name, hash: doc.hash })\n return doc\n}\n", "import {\n createTempFolder,\n getPluginMetadata,\n extractTarball,\n} from \"../../../utilities/fileSystem\"\n\nexport async function fileUpload(file: { name: string; path: string }) {\n if (!file.name.endsWith(\".tar.gz\")) {\n throw new Error(\"Plugin must be compressed into a gzipped tarball.\")\n }\n const path = createTempFolder(file.name.split(\".tar.gz\")[0])\n await extractTarball(file.path, path)\n\n return await getPluginMetadata(path)\n}\n", "import { Server } from \"socket.io\"\nimport http from \"http\"\nimport Koa from \"koa\"\nimport Cookies from \"cookies\"\nimport { userAgent } from \"koa-useragent\"\nimport { auth, redis } from \"@budibase/backend-core\"\nimport currentApp from \"../middleware/currentapp\"\nimport { createAdapter } from \"@socket.io/redis-adapter\"\nimport { Socket } from \"socket.io\"\nimport { getSocketPubSubClients } from \"../utilities/redis\"\nimport { SocketEvent, SocketSessionTTL } from \"@budibase/shared-core\"\nimport { SocketSession } from \"@budibase/types\"\n\nexport class BaseSocket {\n io: Server\n path: string\n redisClient?: redis.Client\n\n constructor(\n app: Koa,\n server: http.Server,\n path: string = \"/\",\n additionalMiddlewares?: any[]\n ) {\n this.path = path\n this.io = new Server(server, {\n path,\n })\n\n // Attach default middlewares\n const authenticate = auth.buildAuthMiddleware([], {\n publicAllowed: true,\n })\n const middlewares = [\n userAgent,\n authenticate,\n currentApp,\n ...(additionalMiddlewares || []),\n ]\n\n // Apply middlewares\n this.io.use(async (socket, next) => {\n // Build fake koa context\n const res = new http.ServerResponse(socket.request)\n const ctx: any = {\n ...app.createContext(socket.request, res),\n\n // Additional overrides needed to make our middlewares work with this\n // fake koa context\n cookies: new Cookies(socket.request, res),\n get: (field: string) => socket.request.headers[field],\n throw: (code: number, message: string) => {\n throw new Error(message)\n },\n\n // Needed for koa-useragent middleware\n headers: socket.request.headers,\n header: socket.request.headers,\n\n // We don't really care about the path since it will never contain\n // an app ID\n path: \"/socket\",\n }\n\n // Run all koa middlewares\n try {\n for (let [idx, middleware] of middlewares.entries()) {\n await middleware(ctx, () => {\n if (idx === middlewares.length - 1) {\n // Middlewares are finished\n // Extract some data from our enriched koa context to persist\n // as metadata for the socket\n const { _id, email, firstName, lastName } = ctx.user\n socket.data = {\n _id,\n email,\n firstName,\n lastName,\n sessionId: socket.id,\n }\n next()\n }\n })\n }\n } catch (error: any) {\n next(error)\n }\n })\n\n // Initialise redis before handling connections\n this.initialise().then(() => {\n this.io.on(\"connection\", async socket => {\n // Add built in handler for heartbeats\n socket.on(SocketEvent.Heartbeat, async () => {\n console.log(socket.data.email, \"heartbeat received\")\n await this.extendSessionTTL(socket.data.sessionId)\n })\n\n // Add early disconnection handler to clean up and leave room\n socket.on(\"disconnect\", async () => {\n // Run any custom disconnection logic before we leave the room,\n // so that we have access to their room etc before disconnection\n await this.onDisconnect(socket)\n\n // Leave the current room when the user disconnects if we're in one\n await this.leaveRoom(socket)\n })\n\n // Add handlers for this socket\n await this.onConnect(socket)\n })\n })\n }\n\n async initialise() {\n // Instantiate redis adapter.\n // We use a fully qualified key name here as this bypasses the normal\n // redis client#s key prefixing.\n const { pub, sub } = getSocketPubSubClients()\n const opts = {\n key: `${redis.utils.Databases.SOCKET_IO}-${this.path}-pubsub`,\n }\n this.io.adapter(createAdapter(pub, sub, opts))\n\n // Fetch redis client\n this.redisClient = await redis.clients.getSocketClient()\n }\n\n // Gets the redis key for a certain session ID\n getSessionKey(sessionId: string) {\n return `${this.path}-session:${sessionId}`\n }\n\n // Gets the redis key for certain room name\n getRoomKey(room: string) {\n return `${this.path}-room:${room}`\n }\n\n async extendSessionTTL(sessionId: string) {\n const key = this.getSessionKey(sessionId)\n await this.redisClient?.setExpiry(key, SocketSessionTTL)\n }\n\n // Gets an array of all redis keys of users inside a certain room\n async getRoomSessionIds(room: string): Promise<string[]> {\n const keys = await this.redisClient?.get(this.getRoomKey(room))\n return keys || []\n }\n\n // Sets the list of redis keys for users inside a certain room.\n // There is no TTL on the actual room key map itself.\n async setRoomSessionIds(room: string, ids: string[]) {\n await this.redisClient?.store(this.getRoomKey(room), ids)\n }\n\n // Gets a list of all users inside a certain room\n async getRoomSessions(room?: string): Promise<SocketSession[]> {\n if (room) {\n const sessionIds = await this.getRoomSessionIds(room)\n const keys = sessionIds.map(this.getSessionKey.bind(this))\n const sessions = await this.redisClient?.bulkGet(keys)\n return Object.values(sessions || {})\n } else {\n return []\n }\n }\n\n // Detects keys which have been pruned from redis due to TTL expiry in a certain\n // room and broadcasts disconnection messages to ensure clients are aware\n async pruneRoom(room: string) {\n const sessionIds = await this.getRoomSessionIds(room)\n const sessionsExist = await Promise.all(\n sessionIds.map(id => this.redisClient?.exists(this.getSessionKey(id)))\n )\n const prunedSessionIds = sessionIds.filter((id, idx) => {\n if (!sessionsExist[idx]) {\n this.io.to(room).emit(SocketEvent.UserDisconnect, sessionIds[idx])\n return false\n }\n return true\n })\n\n // Store new pruned keys\n await this.setRoomSessionIds(room, prunedSessionIds)\n }\n\n // Adds a user to a certain room\n async joinRoom(socket: Socket, room: string) {\n if (!room) {\n return\n }\n // Prune room before joining\n await this.pruneRoom(room)\n\n // Check if we're already in a room, as we'll need to leave if we are before we\n // can join a different room\n const oldRoom = socket.data.room\n if (oldRoom && oldRoom !== room) {\n await this.leaveRoom(socket)\n }\n\n // Join new room\n if (!oldRoom || oldRoom !== room) {\n socket.join(room)\n socket.data.room = room\n }\n\n // Store in redis\n // @ts-ignore\n let user: SocketSession = socket.data\n const { sessionId } = user\n const key = this.getSessionKey(sessionId)\n await this.redisClient?.store(key, user, SocketSessionTTL)\n const sessionIds = await this.getRoomSessionIds(room)\n if (!sessionIds.includes(sessionId)) {\n await this.setRoomSessionIds(room, [...sessionIds, sessionId])\n }\n\n // Notify other users\n socket.to(room).emit(SocketEvent.UserUpdate, user)\n }\n\n // Disconnects a socket from its current room\n async leaveRoom(socket: Socket) {\n // @ts-ignore\n let user: SocketSession = socket.data\n const { room, sessionId } = user\n if (!room) {\n return\n }\n\n // Leave room\n socket.leave(room)\n socket.data.room = undefined\n\n // Delete from redis\n const key = this.getSessionKey(sessionId)\n await this.redisClient?.delete(key)\n const sessionIds = await this.getRoomSessionIds(room)\n await this.setRoomSessionIds(\n room,\n sessionIds.filter(id => id !== sessionId)\n )\n\n // Notify other users\n socket.to(room).emit(SocketEvent.UserDisconnect, sessionId)\n }\n\n // Updates a connected user's metadata, assuming a room change is not required.\n async updateUser(socket: Socket, patch: Object) {\n socket.data = {\n ...socket.data,\n ...patch,\n }\n\n // If we're in a room, notify others of this change and update redis\n if (socket.data.room) {\n await this.joinRoom(socket, socket.data.room)\n }\n }\n\n async onConnect(socket: Socket) {\n // Override\n }\n\n async onDisconnect(socket: Socket) {\n // Override\n }\n\n // Emit an event to all sockets\n emit(event: string, payload: any) {\n this.io.sockets.emit(event, payload)\n }\n}\n", "import { BBContext } from \"@budibase/types\"\n\nconst WEBHOOK_ENDPOINTS = new RegExp(\n [\"webhooks/trigger\", \"webhooks/schema\"].join(\"|\")\n)\n\nexport function isWebhookEndpoint(ctx: BBContext) {\n return WEBHOOK_ENDPOINTS.test(ctx.request.url)\n}\n", "import { roles, permissions, auth, context } from \"@budibase/backend-core\"\nimport { Role } from \"@budibase/types\"\nimport builderMiddleware from \"./builder\"\nimport { isWebhookEndpoint } from \"./utils\"\n\nfunction hasResource(ctx: any) {\n return ctx.resourceId != null\n}\n\nconst csrf = auth.buildCsrfMiddleware()\n\n/**\n * Apply authorization to the requested resource:\n * - If this is a builder resource the user must be a builder.\n * - Builders can access all resources.\n * - Otherwise the user must have the required role.\n */\nconst checkAuthorized = async (\n ctx: any,\n resourceRoles: any,\n permType: any,\n permLevel: any\n) => {\n // check if this is a builder api and the user is not a builder\n const isBuilder = ctx.user && ctx.user.builder && ctx.user.builder.global\n const isBuilderApi = permType === permissions.PermissionType.BUILDER\n if (isBuilderApi && !isBuilder) {\n return ctx.throw(403, \"Not Authorized\")\n }\n\n // check for resource authorization\n if (!isBuilder) {\n await checkAuthorizedResource(ctx, resourceRoles, permType, permLevel)\n }\n}\n\nconst checkAuthorizedResource = async (\n ctx: any,\n resourceRoles: any,\n permType: any,\n permLevel: any\n) => {\n // get the user's roles\n const roleId = ctx.roleId || roles.BUILTIN_ROLE_IDS.PUBLIC\n const userRoles = (await roles.getUserRoleHierarchy(roleId, {\n idOnly: false,\n })) as Role[]\n const permError = \"User does not have permission\"\n // check if the user has the required role\n if (resourceRoles.length > 0) {\n // deny access if the user doesn't have the required resource role\n const found = userRoles.find(\n (role: any) => resourceRoles.indexOf(role._id) !== -1\n )\n if (!found) {\n ctx.throw(403, permError)\n }\n // fallback to the base permissions when no resource roles are found\n } else if (\n !permissions.doesHaveBasePermission(permType, permLevel, userRoles)\n ) {\n ctx.throw(403, permError)\n }\n}\n\nexport default (\n permType: any,\n permLevel: any = null,\n opts = { schema: false }\n ) =>\n async (ctx: any, next: any) => {\n // webhooks don't need authentication, each webhook unique\n // also internal requests (between services) don't need authorized\n if (isWebhookEndpoint(ctx) || ctx.internal) {\n return next()\n }\n\n if (!ctx.user) {\n return ctx.throw(403, \"No user info found\")\n }\n\n // get the resource roles\n let resourceRoles: any = []\n let otherLevelRoles: any = []\n const otherLevel =\n permLevel === permissions.PermissionLevel.READ\n ? permissions.PermissionLevel.WRITE\n : permissions.PermissionLevel.READ\n const appId = context.getAppId()\n if (appId && hasResource(ctx)) {\n resourceRoles = await roles.getRequiredResourceRole(permLevel, ctx)\n if (opts && opts.schema) {\n otherLevelRoles = await roles.getRequiredResourceRole(otherLevel, ctx)\n }\n }\n\n // if the resource is public, proceed\n if (\n resourceRoles.includes(roles.BUILTIN_ROLE_IDS.PUBLIC) ||\n (otherLevelRoles &&\n otherLevelRoles.includes(roles.BUILTIN_ROLE_IDS.PUBLIC))\n ) {\n return next()\n }\n\n // check authenticated\n if (!ctx.isAuthenticated) {\n return ctx.throw(403, \"Session not authenticated\")\n }\n\n // check general builder stuff, this middleware is a good way\n // to find API endpoints which are builder focused\n if (permType === permissions.PermissionType.BUILDER) {\n await builderMiddleware(ctx)\n }\n\n try {\n // check authorized\n await checkAuthorized(ctx, resourceRoles, permType, permLevel)\n } catch (err) {\n // this is a schema, check if\n if (opts && opts.schema && permLevel) {\n await checkAuthorized(ctx, otherLevelRoles, permType, otherLevel)\n } else {\n throw err\n }\n }\n\n // csrf protection\n return csrf(ctx, next)\n }\n", "import { InternalTables } from \"../../../db/utils\"\nimport * as userController from \"../user\"\nimport { FieldTypes } from \"../../../constants\"\nimport { context } from \"@budibase/backend-core\"\nimport { makeExternalQuery } from \"../../../integrations/base/query\"\nimport { Row, Table } from \"@budibase/types\"\nimport { Format } from \"../view/exporters\"\nimport { UserCtx } from \"@budibase/types\"\nimport sdk from \"../../../sdk\"\nconst validateJs = require(\"validate.js\")\nconst { cloneDeep } = require(\"lodash/fp\")\n\nvalidateJs.extend(validateJs.validators.datetime, {\n parse: function (value: string) {\n return new Date(value).getTime()\n },\n // Input is a unix timestamp\n format: function (value: string) {\n return new Date(value).toISOString()\n },\n})\n\nexport async function getDatasourceAndQuery(json: any) {\n const datasourceId = json.endpoint.datasourceId\n const datasource = await sdk.datasources.get(datasourceId)\n return makeExternalQuery(datasource, json)\n}\n\nexport async function findRow(ctx: UserCtx, tableId: string, rowId: string) {\n const db = context.getAppDB()\n let row\n // TODO remove special user case in future\n if (tableId === InternalTables.USER_METADATA) {\n ctx.params = {\n id: rowId,\n }\n await userController.findMetadata(ctx)\n row = ctx.body\n } else {\n row = await db.get(rowId)\n }\n if (row.tableId !== tableId) {\n throw \"Supplied tableId does not match the rows tableId\"\n }\n return row\n}\n\nexport async function validate({\n tableId,\n row,\n table,\n}: {\n tableId?: string\n row: Row\n table?: Table\n}) {\n let fetchedTable: Table\n if (!table) {\n fetchedTable = await sdk.tables.getTable(tableId)\n } else {\n fetchedTable = table\n }\n const errors: any = {}\n for (let fieldName of Object.keys(fetchedTable.schema)) {\n const column = fetchedTable.schema[fieldName]\n const constraints = cloneDeep(column.constraints)\n const type = column.type\n // formulas shouldn't validated, data will be deleted anyway\n if (type === FieldTypes.FORMULA || column.autocolumn) {\n continue\n }\n // special case for options, need to always allow unselected (empty)\n if (type === FieldTypes.OPTIONS && constraints.inclusion) {\n constraints.inclusion.push(null, \"\")\n }\n let res\n\n // Validate.js doesn't seem to handle array\n if (type === FieldTypes.ARRAY && row[fieldName]) {\n if (row[fieldName].length) {\n if (!Array.isArray(row[fieldName])) {\n row[fieldName] = row[fieldName].split(\",\")\n }\n row[fieldName].map((val: any) => {\n if (\n !constraints.inclusion.includes(val) &&\n constraints.inclusion.length !== 0\n ) {\n errors[fieldName] = \"Field not in list\"\n }\n })\n } else if (constraints.presence && row[fieldName].length === 0) {\n // non required MultiSelect creates an empty array, which should not throw errors\n errors[fieldName] = [`${fieldName} is required`]\n }\n } else if (\n (type === FieldTypes.ATTACHMENT || type === FieldTypes.JSON) &&\n typeof row[fieldName] === \"string\"\n ) {\n // this should only happen if there is an error\n try {\n const json = JSON.parse(row[fieldName])\n if (type === FieldTypes.ATTACHMENT) {\n if (Array.isArray(json)) {\n row[fieldName] = json\n } else {\n errors[fieldName] = [`Must be an array`]\n }\n }\n } catch (err) {\n errors[fieldName] = [`Contains invalid JSON`]\n }\n } else {\n res = validateJs.single(row[fieldName], constraints)\n }\n if (res) errors[fieldName] = res\n }\n return { valid: Object.keys(errors).length === 0, errors }\n}\n\nexport function cleanExportRows(\n rows: any[],\n schema: any,\n format: string,\n columns: string[]\n) {\n let cleanRows = [...rows]\n\n const relationships = Object.entries(schema)\n .filter((entry: any[]) => entry[1].type === FieldTypes.LINK)\n .map(entry => entry[0])\n\n relationships.forEach(column => {\n cleanRows.forEach(row => {\n delete row[column]\n })\n delete schema[column]\n })\n\n if (format === Format.CSV) {\n // Intended to append empty values in export\n const schemaKeys = Object.keys(schema)\n for (let key of schemaKeys) {\n if (columns?.length && columns.indexOf(key) > 0) {\n continue\n }\n for (let row of cleanRows) {\n if (row[key] == null) {\n row[key] = undefined\n }\n }\n }\n }\n\n return cleanRows\n}\n\nexport function getTableId(ctx: any) {\n if (ctx.request.body && ctx.request.body.tableId) {\n return ctx.request.body.tableId\n }\n if (ctx.params && ctx.params.tableId) {\n return ctx.params.tableId\n }\n if (ctx.params && ctx.params.viewName) {\n return ctx.params.viewName\n }\n}\n", "import http from \"http\"\nimport Koa from \"koa\"\nimport ClientAppSocket from \"./client\"\nimport GridSocket from \"./grid\"\nimport BuilderSocket from \"./builder\"\n\nlet clientAppSocket: ClientAppSocket\nlet gridSocket: GridSocket\nlet builderSocket: BuilderSocket\n\nexport const initialise = (app: Koa, server: http.Server) => {\n clientAppSocket = new ClientAppSocket(app, server)\n gridSocket = new GridSocket(app, server)\n builderSocket = new BuilderSocket(app, server)\n}\n\nexport { clientAppSocket, gridSocket, builderSocket }\n", "import * as plugins from \"./plugins\"\n\nexport default {\n ...plugins,\n}\n", "import { default as backups } from \"./app/backups\"\nimport { default as tables } from \"./app/tables\"\nimport { default as automations } from \"./app/automations\"\nimport { default as applications } from \"./app/applications\"\nimport { default as datasources } from \"./app/datasources\"\nimport { default as queries } from \"./app/queries\"\nimport { default as rows } from \"./app/rows\"\nimport { default as users } from \"./users\"\nimport { default as plugins } from \"./plugins\"\n\nconst sdk = {\n backups,\n tables,\n automations,\n applications,\n rows,\n users,\n datasources,\n queries,\n plugins,\n}\n\n// default export for TS\nexport default sdk\n", "import { findHBSBlocks } from \"@budibase/string-templates\"\nimport { DatasourcePlus } from \"@budibase/types\"\nimport sdk from \"../../sdk\"\n\nconst CONST_CHAR_REGEX = new RegExp(\"'[^']*'\", \"g\")\n\nexport async function interpolateSQL(\n fields: { [key: string]: any },\n parameters: { [key: string]: any },\n integration: DatasourcePlus\n) {\n let sql = fields.sql\n if (!sql || typeof sql !== \"string\") {\n return fields\n }\n const bindings = findHBSBlocks(sql)\n let variables = [],\n arrays = []\n for (let binding of bindings) {\n // look for array/list operations in the SQL statement, which will need handled later\n const listRegexMatch = sql.match(\n new RegExp(`(in|IN|In|iN)( )+[(]?${binding}[)]?`)\n )\n // check if the variable was used as part of a string concat e.g. 'Hello {{binding}}'\n // start by finding all the instances of const character strings\n const charConstMatch = sql.match(CONST_CHAR_REGEX) || []\n // now look within them to see if a binding is used\n const charConstBindingMatch = charConstMatch.find((string: any) =>\n string.match(new RegExp(`'[^']*${binding}[^']*'`))\n )\n if (charConstBindingMatch) {\n let [part1, part2] = charConstBindingMatch.split(binding)\n part1 = `'${part1.substring(1)}'`\n part2 = `'${part2.substring(0, part2.length - 1)}'`\n sql = sql.replace(\n charConstBindingMatch,\n integration.getStringConcat([\n part1,\n integration.getBindingIdentifier(),\n part2,\n ])\n )\n }\n // generate SQL parameterised array\n else if (listRegexMatch) {\n arrays.push(binding)\n // determine the length of the array\n const value = (await sdk.queries.enrichContext([binding], parameters))[0]\n .split(\",\")\n .map((val: string) => val.trim())\n // build a string like ($1, $2, $3)\n let replacement = `${Array.apply(null, Array(value.length))\n .map(() => integration.getBindingIdentifier())\n .join(\",\")}`\n // check if parentheses are needed\n if (!listRegexMatch[0].includes(`(${binding})`)) {\n replacement = `(${replacement})`\n }\n sql = sql.replace(binding, replacement)\n } else {\n sql = sql.replace(binding, integration.getBindingIdentifier())\n }\n variables.push(binding)\n }\n // replicate the knex structure\n fields.sql = sql\n fields.bindings = await sdk.queries.enrichContext(variables, parameters)\n // check for arrays in the data\n let updated: string[] = []\n for (let i = 0; i < variables.length; i++) {\n if (arrays.includes(variables[i])) {\n updated = updated.concat(\n fields.bindings[i].split(\",\").map((val: string) => val.trim())\n )\n } else {\n updated.push(fields.bindings[i])\n }\n }\n fields.bindings = updated\n return fields\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["Event", "init_license", "init_license", "QueryType", "DatasourceFieldType", "SourceName", "init_auth", "TenantResolutionStrategy", "init_user", "init_auth", "init_user", "init_account", "init_user", "init_account", "init_user", "init_app", "init_automation", "AutomationIOType", "AutomationCustomIOType", "AutomationTriggerStepId", "AutomationActionStepId", "init_datasource", "init_layout", "init_query", "init_role", "init_table", "init_screen", "init_view", "init_user", "init_backup", "AppBackupType", "AppBackupTrigger", "init_app", "init_automation", "init_datasource", "init_layout", "init_query", "init_role", "init_table", "init_screen", "init_view", "init_user", "init_backup", "init_user", "init_userGroup", "init_plugin", "PluginType", "ScheduleType", "ScheduleRepeatPeriod", "init_environmentVariables", "init_auditLogs", "init_user", "init_userGroup", "init_plugin", "init_environmentVariables", "init_auditLogs", "init_account", "init_app", "init_accounts", "init_user", "init_license", "init_account", "init_accounts", "init_user", "init_license", "init_auth", "init_user", "init_schedule", "init_backup", "init_datasource", "init_app", "init_backup", "init_datasource", "init_environmentVariables", "init_auditLogs", "init_events", "init_users", "init_users", "init_global", "init_environmentVariables", "init_auditLogs", "init_events", "init_auth", "init_user", "init_schedule", "init_app", "init_global", "init_account", "init_db", "AutomationViewMode", "ViewName", "InternalTable", "DocumentType", "UserStatus", "Cookie", "Header", "GlobalRole", "Config", "init_constants", "init_db", "doInIdentityContext", "getIdentity", "init_context", "isTest", "isCypress", "isJest", "isDev", "LOADED", "environment", "environment_default", "init_environment", "init_constants", "init_environment", "environment_default", "path", "body", "params", "fetch", "options", "environment_default", "init_environment", "url", "opts", "PouchDB", "find", "Nano", "params", "stream", "environment_default", "init_db", "init_environment", "environment_default", "params", "init_environment", "init_db", "init_constants", "init_context", "init_constants", "SEPARATOR", "environment_default", "init_utils", "init_environment", "Databases", "SelectableDatabase", "init_timers", "timeout", "init", "client", "environment_default", "resolve", "stream", "keys", "init_environment", "init_utils", "init_timers", "SEPARATOR", "init", "init_utils", "init_context", "client", "init_constants", "init_correlation", "init_environment", "init_context", "init_correlation", "environment_default", "getLogParams", "getIdentity", "getTenantId", "getAppId", "getAutomationId", "pino", "exports", "module", "exports", "module", "dayjs", "options", "exports", "module", "exports", "module", "exports", "module", "start", "matches", "exports", "module", "exports", "module", "cloneDeep", "matches", "path", "exports", "module", "exports", "module", "exports", "module", "exports", "module", "process", "processors", "matches", "exports", "module", "exports", "module", "start", "end", "index", "exports", "module", "processors", "process", "matches", "invalidCase", "validCase", "handlebars", "require_src", "exports", "module", "VM", "init_constants", "BaseCache", "CacheKey", "TTL", "init_db", "init_context", "init_context", "init_constants", "_a", "params", "init_context", "init_constants", "init_db", "init_constants", "init_environment", "environment_default", "keys", "init_constants", "init_context", "init_environment", "environment_default", "options", "client", "Redlock", "init_environment", "import_node_fetch", "options", "fetch", "init_environment", "init_constants", "environment_default", "environment_default", "client", "init_db", "init_environment", "init_constants", "init_context", "init_db", "init_constants", "init_constants", "tenancy", "environment_default", "apps", "init_constants", "init_context", "init_environment", "params", "rows", "environment_default", "CreateFuncByName", "init_constants", "resolve", "init_db", "init_context", "import_node_fetch", "index", "builder", "body", "rows", "fetch", "params", "search", "init_context", "EXPIRY_SECONDS", "populateFromDB", "client", "client", "cache", "get", "init_context", "init_environment", "environment_default", "shutdown", "init", "init_environment", "init_environment", "init_context", "init_context", "PostHog", "environment_default", "environment_default", "init_environment", "environment_default", "init_context", "shutdown", "init_environment", "init_utils", "import_events", "utils_exports", "init_environment", "environment_default", "init_constants", "init_environment", "init_context", "APP_PREFIX", "environment_default", "apps", "options", "resolve", "events", "JobQueue", "init_context", "_a", "init_timers", "environment_default", "BullQueue", "shutdown", "init_environment", "environment_default", "processors", "init", "init_context", "init_environment", "init_context", "init_environment", "environment_default", "semver", "getIdentity", "environment", "environment_default", "builder", "verified", "recordEvent", "init_context", "events", "recordEvent", "eventKey", "keys", "init", "init", "recordEvent", "created", "deleted", "created", "deleted", "datasource", "created", "updated", "deleted", "created", "deleted", "created", "datasource", "updated", "deleted", "run", "created", "updated", "deleted", "created", "deleted", "created", "imported", "created", "updated", "deleted", "exported", "imported", "init_context", "created", "updated", "deleted", "created", "updated", "deleted", "exported", "init_environment", "environment_default", "init_context", "created", "updated", "deleted", "init", "imported", "deleted", "created", "deleted", "search", "shutdown", "init_constants", "init_environment", "init_context", "users_exports", "init_context", "users", "params", "Role", "init_context", "cloneDeep", "Role", "role", "body", "init_environment", "init_context", "environment_default", "TenantFeatureFlag", "init_environment", "logWarn", "EXPIRY_SECONDS", "client", "environment_default", "client", "EXPIRY_SECONDS", "client", "auditLog_default", "jwt", "init_context", "init_constants", "auditLog_default", "middleware_default", "init_constants", "init_context", "init_context", "import_node_fetch", "authenticate", "fetch", "authenticate", "buildVerifyFn", "getCallbackUrl", "strategyFactory", "import_node_fetch", "buildVerifyFn", "params", "authenticate", "strategyFactory", "fetch", "body", "getCallbackUrl", "google_exports", "init_constants", "GoogleStrategy", "passport", "datasource", "err", "init_constants", "matches", "pattern", "options", "init_context", "init_environment", "SEPARATOR", "SecretOption", "environment_default", "crypto", "init_environment", "environment_default", "auditLog_default", "init_context", "init_constants", "init_constants", "init_constants", "init_environment", "pino", "correlator", "environment_default", "init_constants", "import_uuid", "correlator", "uuid", "middleware_default", "status", "body", "params", "Joi", "google_exports", "jwt", "resolve", "refreshToken", "params", "init_constants", "validate", "import_joi", "joi", "validate", "init_context", "objectStore_exports", "import_node_fetch", "import_path", "import_fs", "init_environment", "import_path", "import_fs", "init_environment", "environment_default", "fs", "import_uuid", "stream", "environment_default", "AWS", "client", "path", "fs", "params", "fetch", "zlib", "tar", "init_environment", "init_environment", "environment_default", "getPresignedUrl", "environment_default", "getPresignedUrl", "init_environment", "init_context", "environment_default", "getPresignedUrl", "init_environment", "init_context", "plugins", "environment_default", "getPresignedUrl", "init_utils", "init_timers", "init_environment", "init_environment", "import_util", "dns", "net", "environment_default", "init_context", "init_context", "init_constants", "init", "init", "getClient", "init", "cache", "import_node_fetch", "fetch", "v4", "SEPARATOR", "StaticDatabases", "DocumentType", "APP_PREFIX", "APP_DEV_PREFIX", "isDevAppID", "isProdAppID", "ViewName", "UNICODE_MAX", "generateAppID", "generateRoleID", "getRoleParams", "getQueryIndex", "getDocParams", "getRowParams", "generateRowID", "getUserMetadataParams", "generateUserMetadataID", "getGlobalIDFromUserMetadataID", "getDocParams", "DocumentType", "getDocParams", "DocumentType", "SEPARATOR", "getDocParams", "DocumentType", "InvalidColumns", "ObjectStoreBuckets", "objectStore_exports", "SEPARATOR", "DocumentType", "datasource", "import_knex", "schema", "knex", "client", "client", "start", "end", "body", "knex", "relationships", "builder", "import_stream", "stream", "isDev", "resolve", "client", "matches", "import_aws_sdk", "init", "AWS", "SCHEMA", "AWS", "params", "SCHEMA", "options", "json", "params", "SCHEMA", "index", "SCHEMA", "SCHEMA", "client", "schema", "import_aws_sdk", "SCHEMA", "AWS", "params", "stream", "resolve", "csv", "SCHEMA", "Airtable", "SCHEMA", "matches", "dayjs", "mysql", "SCHEMA", "import_lodash", "import_node_fetch", "SCHEMA", "pagination", "keys", "path", "params", "qs", "body", "FormData", "fetch", "import_node_fetch", "datasource", "removeKeyNumbering", "filter", "parse", "utils_exports", "SCHEMA", "fetch", "rows", "filtered", "SCHEMA", "SCHEMA", "Redis", "redis_default", "SCHEMA", "SCHEMA", "options", "budibaseTempDir", "objectStore_exports", "import_path", "import_fs", "import_path", "uuid", "path", "fs", "path", "budibaseTempDir", "fs", "tar", "import_fs", "import_path", "budibaseTempDir", "path", "pkg", "fs", "hash", "objectStore_exports", "objectStore_exports", "ObjectStoreBuckets", "import_lodash", "import_fs", "import_path", "uuid", "tar", "budibaseTempDir", "path", "fs", "objectStore_exports", "ObjectStoreBuckets", "import_path", "import_fs", "uuid", "tar", "rows", "automations", "fs", "budibaseTempDir", "path", "objectStore_exports", "ObjectStoreBuckets", "db", "enrich", "get", "auditLogs_exports", "backups_default", "environmentVariables_exports", "groups_exports", "init", "quotas_exports", "users_exports", "utils_exports", "activateLicenseKey", "cache_exports", "getLicense", "cache_exports", "refresh", "client", "init", "shutdown", "getClient", "import_node_fetch", "API", "options", "fetch", "bustCache", "utils_exports", "utils_exports", "Writethrough", "getDB", "bustCache", "destroy", "get", "save", "get", "destroy", "destroy", "fetch", "get", "save", "ViewName", "SEPARATOR", "DocumentType", "createView", "createView", "ViewName", "start", "params", "utils_exports", "users", "users_exports", "fetch", "get", "save", "destroy", "pagination", "ViewName", "AutomationViewMode", "SEPARATOR", "DocumentType", "createView", "UNLIMITED", "quotas_exports", "UNLIMITED", "import_fs", "import_path", "environment_default", "path", "objectStore_exports", "fs", "utils_exports", "APP_BACKUP_PREFIX", "params", "pagination", "users", "users_exports", "get", "LRU", "get", "api", "environment_default", "users_exports", "body", "import_fs", "import_path", "import_os", "environment_default", "fs", "jwt", "refresh", "activateLicenseKey", "getLicense", "environment_default", "EXPIRY_SECONDS", "refresh", "client", "getClient", "getLicense", "environment_default", "cache_exports", "environment_default", "quotas_exports", "bustCache", "set", "utils_exports", "set", "triggerQuota", "index", "quotas_exports", "cache_exports", "apps", "utils_exports", "environment_default", "users_exports", "set", "users_exports", "users_exports", "createActivity", "api", "environment_default", "options", "createActivity", "logging_exports", "logging_exports", "oldestLogDate", "SEPARATOR", "UNICODE_MAX", "DocumentType", "AutomationViewMode", "ViewName", "getQueryIndex", "status", "params", "pagination", "oldestLogDate", "status", "options", "groups_exports", "addUsers", "fetch", "get", "getBulk", "remove", "removeUsers", "save", "getBulk", "fetch", "get", "save", "remove", "addUsers", "users", "users_exports", "removeUsers", "import_fs", "import_path", "fs", "hash", "objectStore_exports", "write", "environmentVariables_exports", "fetch", "remove", "update", "environment_default", "fetch", "environment", "update", "remove", "auditLogs_exports", "fetch", "MemoryStream", "utils_exports", "save", "search", "params", "stream", "MAX_DATE", "params", "MAX_DATE", "filter", "search", "deleted", "utils_exports", "users_exports", "save", "user", "app", "deleted", "fetch", "params", "filter", "events", "init", "storeAppBackupMetadata", "status", "objectStore_exports", "fetchAppBackups", "path", "backup_default", "init", "import_fs", "init", "status", "backup_default", "objectStore_exports", "fs", "path", "init", "backups_default", "backup_default", "utils_exports", "users_exports", "create", "get", "init", "remove", "update", "params", "builder", "users_exports", "init", "get", "create", "update", "remove", "init", "backups_default", "doInScimContext", "groups_exports", "destroy", "fetch", "find", "save", "updateGroupApps", "save", "get", "addUsers", "removeUsers", "updateGroupApps", "fetch", "destroy", "remove", "find", "params", "users", "environmentVariables_exports", "fetch", "create", "update", "destroy", "import_joi", "Router", "Joi", "groups_exports", "import_router", "import_joi", "router", "Router", "Joi", "fetch", "create", "update", "destroy", "search", "auditLogs_exports", "download", "stream", "definitions", "import_router", "import_joi", "Joi", "router", "Router", "search", "download", "definitions", "import_fs", "utils_exports", "body", "backups_default", "path", "fs", "import_router", "import_joi", "router", "Router", "Joi", "body", "import_router", "import_joi", "router", "Router", "Joi", "import_router", "get", "users_exports", "find", "create", "update", "remove", "import_lodash", "import_scim_patch", "get", "groups_exports", "create", "find", "remove", "update", "_", "users_exports", "utils_exports", "router", "Router", "doInScimContext", "get", "find", "create", "update", "remove", "groups_exports", "users_exports", "users_exports", "import_scim2_parse_filter", "utils_exports", "unreachable", "filter", "parseFilters", "groups_exports", "getEnvironmentVariables", "environmentVariables_exports", "import_lodash", "datasource", "getEnvironmentVariables", "enrich", "get", "definitions", "update", "old", "_", "datasource", "destroy", "save", "save", "destroy", "utils_exports", "utils_exports", "groups_exports", "groups_exports", "users", "generateUserMetadataID", "user", "utils_exports", "utils_exports", "import_string_templates", "getEnvironmentVariables", "params", "DocumentType", "SEPARATOR", "rows", "getRowParams", "rows_default", "utils_exports", "import_lodash", "generateUserMetadataID", "newDoc", "getUserMetadataParams", "users", "getGlobalIDFromUserMetadataID", "utils_exports", "plugins_exports", "fetch", "path", "cloneDeep", "fetch", "plugins", "objectStore_exports", "plugins_exports", "rows_default", "DEFINITIONS", "redis_default", "plugins", "import_string_templates", "import_fp", "import_string_templates", "updated", "datasource", "Integration", "rows", "pagination", "keys", "getGlobalIDFromUserMetadataID", "run"]
7
+ }