@budibase/server 1.2.44 → 1.2.47

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 (167) hide show
  1. package/builder/assets/{index.cd024733.js → index.5686a36e.js} +1 -1
  2. package/builder/index.html +1 -1
  3. package/coverage/clover.xml +32 -30
  4. package/coverage/coverage-final.json +3 -3
  5. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  6. package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
  7. package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
  8. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  9. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  10. package/coverage/lcov-report/api/controllers/component.js.html +1 -1
  11. package/coverage/lcov-report/api/controllers/datasource.js.html +1 -1
  12. package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
  13. package/coverage/lcov-report/api/controllers/index.html +1 -1
  14. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  15. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  16. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  17. package/coverage/lcov-report/api/controllers/migrations.js.html +1 -1
  18. package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/query/index.html +1 -1
  20. package/coverage/lcov-report/api/controllers/query/validation.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/role.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
  23. package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
  24. package/coverage/lcov-report/api/controllers/row/index.html +1 -1
  25. package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
  26. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
  27. package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +1 -1
  28. package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
  29. package/coverage/lcov-report/api/controllers/screen.js.html +1 -1
  30. package/coverage/lcov-report/api/controllers/script.js.html +1 -1
  31. package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +1 -1
  32. package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
  33. package/coverage/lcov-report/api/controllers/table/index.html +1 -1
  34. package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
  35. package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
  36. package/coverage/lcov-report/api/controllers/user.js.html +1 -1
  37. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  38. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  39. package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
  40. package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
  41. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
  42. package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
  43. package/coverage/lcov-report/api/index.html +1 -1
  44. package/coverage/lcov-report/api/index.js.html +1 -1
  45. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  46. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  47. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  48. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  49. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  50. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  51. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  52. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  53. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/dev.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/index.html +1 -1
  56. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/migrations.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/query.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/user.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/utils/index.html +1 -1
  70. package/coverage/lcov-report/api/routes/utils/validators.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  73. package/coverage/lcov-report/automations/actions.js.html +1 -1
  74. package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
  75. package/coverage/lcov-report/automations/bullboard.js.html +13 -7
  76. package/coverage/lcov-report/automations/index.html +12 -12
  77. package/coverage/lcov-report/automations/index.js.html +1 -1
  78. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  79. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  80. package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
  81. package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
  82. package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
  83. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  84. package/coverage/lcov-report/automations/steps/index.html +1 -1
  85. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  86. package/coverage/lcov-report/automations/steps/loop.js.html +1 -1
  87. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
  88. package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
  89. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  90. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  91. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/utils.js.html +1 -1
  94. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  95. package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
  96. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
  97. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  98. package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
  99. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
  100. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
  101. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
  102. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
  103. package/coverage/lcov-report/automations/triggers.js.html +1 -1
  104. package/coverage/lcov-report/constants/index.html +1 -1
  105. package/coverage/lcov-report/constants/index.js.html +1 -1
  106. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  107. package/coverage/lcov-report/constants/screens.js.html +1 -1
  108. package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
  109. package/coverage/lcov-report/db/index.html +1 -1
  110. package/coverage/lcov-report/db/index.js.html +1 -1
  111. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +1 -1
  112. package/coverage/lcov-report/db/linkedRows/index.html +1 -1
  113. package/coverage/lcov-report/db/linkedRows/index.js.html +1 -1
  114. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
  115. package/coverage/lcov-report/db/newid.js.html +1 -1
  116. package/coverage/lcov-report/db/utils.js.html +1 -1
  117. package/coverage/lcov-report/events/AutomationEmitter.js.html +5 -5
  118. package/coverage/lcov-report/events/index.html +1 -1
  119. package/coverage/lcov-report/events/index.js.html +1 -1
  120. package/coverage/lcov-report/events/utils.js.html +1 -1
  121. package/coverage/lcov-report/index.html +15 -15
  122. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  123. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  124. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  125. package/coverage/lcov-report/middleware/builder.js.html +1 -1
  126. package/coverage/lcov-report/middleware/currentapp.js.html +1 -1
  127. package/coverage/lcov-report/middleware/index.html +1 -1
  128. package/coverage/lcov-report/middleware/joi-validator.js.html +1 -1
  129. package/coverage/lcov-report/middleware/publicApi.js.html +1 -1
  130. package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
  131. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  132. package/coverage/lcov-report/middleware/utils.js.html +1 -1
  133. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  134. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  135. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  136. package/coverage/lcov-report/utilities/global.js.html +1 -1
  137. package/coverage/lcov-report/utilities/index.html +1 -1
  138. package/coverage/lcov-report/utilities/index.js.html +1 -1
  139. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +16 -4
  140. package/coverage/lcov-report/utilities/queue/index.html +5 -5
  141. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  142. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  143. package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
  144. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +1 -1
  145. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
  146. package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
  147. package/coverage/lcov-report/utilities/security.js.html +1 -1
  148. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  149. package/coverage/lcov-report/utilities/usageQuota/index.html +1 -1
  150. package/coverage/lcov-report/utilities/usageQuota/rows.js.html +1 -1
  151. package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
  152. package/coverage/lcov-report/utilities/users.js.html +1 -1
  153. package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
  154. package/coverage/lcov.info +38 -34
  155. package/dist/automations/bullboard.js +2 -0
  156. package/dist/automations/listeners.js +102 -0
  157. package/dist/automations/utils.js +6 -2
  158. package/dist/package.json +6 -6
  159. package/dist/threads/automation.js +27 -11
  160. package/dist/tsconfig.build.tsbuildinfo +1 -1
  161. package/dist/utilities/queue/inMemoryQueue.js +3 -0
  162. package/package.json +7 -7
  163. package/src/automations/bullboard.js +2 -0
  164. package/src/automations/listeners.ts +78 -0
  165. package/src/automations/utils.ts +7 -6
  166. package/src/threads/automation.ts +35 -16
  167. package/src/utilities/queue/inMemoryQueue.js +4 -0
@@ -119,5 +119,8 @@ class InMemoryQueue {
119
119
  return {};
120
120
  });
121
121
  }
122
+ on() {
123
+ // do nothing
124
+ }
122
125
  }
123
126
  module.exports = InMemoryQueue;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@budibase/server",
3
3
  "email": "hi@budibase.com",
4
- "version": "1.2.44",
4
+ "version": "1.2.47",
5
5
  "description": "Budibase Web Server",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -77,11 +77,11 @@
77
77
  "license": "GPL-3.0",
78
78
  "dependencies": {
79
79
  "@apidevtools/swagger-parser": "10.0.3",
80
- "@budibase/backend-core": "^1.2.44",
81
- "@budibase/client": "^1.2.44",
82
- "@budibase/pro": "1.2.43",
83
- "@budibase/string-templates": "^1.2.44",
84
- "@budibase/types": "^1.2.44",
80
+ "@budibase/backend-core": "^1.2.47",
81
+ "@budibase/client": "^1.2.47",
82
+ "@budibase/pro": "1.2.46",
83
+ "@budibase/string-templates": "^1.2.47",
84
+ "@budibase/types": "^1.2.47",
85
85
  "@bull-board/api": "3.7.0",
86
86
  "@bull-board/koa": "3.9.4",
87
87
  "@elastic/elasticsearch": "7.10.0",
@@ -195,5 +195,5 @@
195
195
  "optionalDependencies": {
196
196
  "oracledb": "5.3.0"
197
197
  },
198
- "gitHead": "e56a1cd84ba42ba2e565ac22d39cbb66df9cb66b"
198
+ "gitHead": "3c29afb3b2c0fcb8abbc252ce02ec178628c360f"
199
199
  }
@@ -8,12 +8,14 @@ const Queue = env.isTest()
8
8
  const { JobQueues } = require("../constants")
9
9
  const { utils } = require("@budibase/backend-core/redis")
10
10
  const { opts, redisProtocolUrl } = utils.getRedisOptions()
11
+ const listeners = require("./listeners")
11
12
 
12
13
  const CLEANUP_PERIOD_MS = 60 * 1000
13
14
  const queueConfig = redisProtocolUrl || { redis: opts }
14
15
  let cleanupInternal = null
15
16
 
16
17
  let automationQueue = new Queue(JobQueues.AUTOMATIONS, queueConfig)
18
+ listeners.addListeners(automationQueue)
17
19
 
18
20
  async function cleanup() {
19
21
  await automationQueue.clean(CLEANUP_PERIOD_MS, "completed")
@@ -0,0 +1,78 @@
1
+ import { Queue, Job, JobId } from "bull"
2
+ import { AutomationEvent } from "../definitions/automations"
3
+ import * as automation from "../threads/automation"
4
+
5
+ export const addListeners = (queue: Queue) => {
6
+ logging(queue)
7
+ handleStalled(queue)
8
+ }
9
+
10
+ const handleStalled = (queue: Queue) => {
11
+ queue.on("stalled", async (job: Job) => {
12
+ await automation.removeStalled(job as AutomationEvent)
13
+ })
14
+ }
15
+
16
+ const logging = (queue: Queue) => {
17
+ if (process.env.NODE_DEBUG?.includes("bull")) {
18
+ queue
19
+ .on("error", (error: any) => {
20
+ // An error occurred.
21
+ console.error(`automation-event=error error=${JSON.stringify(error)}`)
22
+ })
23
+ .on("waiting", (jobId: JobId) => {
24
+ // A Job is waiting to be processed as soon as a worker is idling.
25
+ console.log(`automation-event=waiting jobId=${jobId}`)
26
+ })
27
+ .on("active", (job: Job, jobPromise: any) => {
28
+ // A job has started. You can use `jobPromise.cancel()`` to abort it.
29
+ console.log(`automation-event=active jobId=${job.id}`)
30
+ })
31
+ .on("stalled", (job: Job) => {
32
+ // A job has been marked as stalled. This is useful for debugging job
33
+ // workers that crash or pause the event loop.
34
+ console.error(
35
+ `automation-event=stalled jobId=${job.id} job=${JSON.stringify(job)}`
36
+ )
37
+ })
38
+ .on("progress", (job: Job, progress: any) => {
39
+ // A job's progress was updated!
40
+ console.log(
41
+ `automation-event=progress jobId=${job.id} progress=${progress}`
42
+ )
43
+ })
44
+ .on("completed", (job: Job, result) => {
45
+ // A job successfully completed with a `result`.
46
+ console.log(
47
+ `automation-event=completed jobId=${job.id} result=${result}`
48
+ )
49
+ })
50
+ .on("failed", (job, err: any) => {
51
+ // A job failed with reason `err`!
52
+ console.log(`automation-event=failed jobId=${job.id} error=${err}`)
53
+ })
54
+ .on("paused", () => {
55
+ // The queue has been paused.
56
+ console.log(`automation-event=paused`)
57
+ })
58
+ .on("resumed", (job: Job) => {
59
+ // The queue has been resumed.
60
+ console.log(`automation-event=paused jobId=${job.id}`)
61
+ })
62
+ .on("cleaned", (jobs: Job[], type: string) => {
63
+ // Old jobs have been cleaned from the queue. `jobs` is an array of cleaned
64
+ // jobs, and `type` is the type of jobs cleaned.
65
+ console.log(
66
+ `automation-event=cleaned length=${jobs.length} type=${type}`
67
+ )
68
+ })
69
+ .on("drained", () => {
70
+ // Emitted every time the queue has processed all the waiting jobs (even if there can be some delayed jobs not yet processed)
71
+ console.log(`automation-event=drained`)
72
+ })
73
+ .on("removed", (job: Job) => {
74
+ // A job successfully removed.
75
+ console.log(`automation-event=removed jobId=${job.id}`)
76
+ })
77
+ }
78
+ }
@@ -21,11 +21,13 @@ const WH_STEP_ID = definitions.WEBHOOK.stepId
21
21
  const CRON_STEP_ID = definitions.CRON.stepId
22
22
  const Runner = new Thread(ThreadType.AUTOMATION)
23
23
 
24
+ const jobMessage = (job: any, message: string) => {
25
+ return `app=${job.data.event.appId} automation=${job.data.automation._id} jobId=${job.id} trigger=${job.data.automation.definition.trigger.event} : ${message}`
26
+ }
27
+
24
28
  export async function processEvent(job: any) {
25
29
  try {
26
- console.log(
27
- `${job.data.automation.appId} automation ${job.data.automation._id} running`
28
- )
30
+ console.log(jobMessage(job, "running"))
29
31
  // need to actually await these so that an error can be captured properly
30
32
  const tenantId = tenancy.getTenantIDFromAppID(job.data.event.appId)
31
33
  return await tenancy.doInTenant(tenantId, async () => {
@@ -34,9 +36,7 @@ export async function processEvent(job: any) {
34
36
  })
35
37
  } catch (err) {
36
38
  const errJson = JSON.stringify(err)
37
- console.error(
38
- `${job.data.automation.appId} automation ${job.data.automation._id} was unable to run - ${errJson}`
39
- )
39
+ console.error(jobMessage(job, `was unable to run - ${errJson}`))
40
40
  console.trace(err)
41
41
  return { err }
42
42
  }
@@ -91,6 +91,7 @@ export async function disableAllCrons(appId: any) {
91
91
  export async function disableCron(jobId: string, jobKey: string) {
92
92
  await queue.removeRepeatableByKey(jobKey)
93
93
  await queue.removeJobs(jobId)
94
+ console.log(`jobId=${jobId} disabled`)
94
95
  }
95
96
 
96
97
  export async function clearMetadata() {
@@ -133,27 +133,34 @@ class Orchestrator {
133
133
  return metadata
134
134
  }
135
135
 
136
+ async stopCron(reason: string) {
137
+ if (!this._repeat) {
138
+ return
139
+ }
140
+ logWarn(
141
+ `CRON disabled reason=${reason} - ${this._appId}/${this._automation._id}`
142
+ )
143
+ const automation = this._automation
144
+ const trigger = automation.definition.trigger
145
+ await disableCron(this._repeat?.jobId, this._repeat?.jobKey)
146
+ this.updateExecutionOutput(
147
+ trigger.id,
148
+ trigger.stepId,
149
+ {},
150
+ {
151
+ status: AutomationStatus.STOPPED_ERROR,
152
+ success: false,
153
+ }
154
+ )
155
+ await storeLog(automation, this.executionOutput)
156
+ }
157
+
136
158
  async checkIfShouldStop(metadata: AutomationMetadata): Promise<boolean> {
137
159
  if (!metadata.errorCount || !this._repeat) {
138
160
  return false
139
161
  }
140
- const automation = this._automation
141
- const trigger = automation.definition.trigger
142
162
  if (metadata.errorCount >= MAX_AUTOMATION_RECURRING_ERRORS) {
143
- logWarn(
144
- `CRON disabled due to errors - ${this._appId}/${this._automation._id}`
145
- )
146
- await disableCron(this._repeat?.jobId, this._repeat?.jobKey)
147
- this.updateExecutionOutput(
148
- trigger.id,
149
- trigger.stepId,
150
- {},
151
- {
152
- status: AutomationStatus.STOPPED_ERROR,
153
- success: false,
154
- }
155
- )
156
- await storeLog(automation, this.executionOutput)
163
+ await this.stopCron("errors")
157
164
  return true
158
165
  }
159
166
  return false
@@ -465,3 +472,15 @@ export function execute(input: AutomationEvent, callback: WorkerCallback) {
465
472
  }
466
473
  })
467
474
  }
475
+
476
+ export const removeStalled = async (input: AutomationEvent) => {
477
+ const appId = input.data.event.appId
478
+ await doInAppContext(appId, async () => {
479
+ const automationOrchestrator = new Orchestrator(
480
+ input.data.automation,
481
+ input.data.event,
482
+ input.opts
483
+ )
484
+ await automationOrchestrator.stopCron("stalled")
485
+ })
486
+ }
@@ -113,6 +113,10 @@ class InMemoryQueue {
113
113
  async getJob() {
114
114
  return {}
115
115
  }
116
+
117
+ on() {
118
+ // do nothing
119
+ }
116
120
  }
117
121
 
118
122
  module.exports = InMemoryQueue