@budibase/server 0.9.125-alpha.4 → 0.9.125-alpha.5

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 (266) hide show
  1. package/builder/assets/{index.dc48c234.js → index.a6e64238.js} +1 -1
  2. package/builder/index.html +1 -1
  3. package/coverage/clover.xml +1659 -1493
  4. package/coverage/coverage-final.json +101 -87
  5. package/coverage/lcov-report/api/controllers/analytics.js.html +3 -3
  6. package/coverage/lcov-report/api/controllers/apikeys.js.html +6 -6
  7. package/coverage/lcov-report/api/controllers/application.js.html +39 -39
  8. package/coverage/lcov-report/api/controllers/auth.js.html +6 -6
  9. package/coverage/lcov-report/api/controllers/automation.js.html +151 -361
  10. package/coverage/lcov-report/api/controllers/backup.js.html +3 -3
  11. package/coverage/lcov-report/api/controllers/component.js.html +5 -5
  12. package/coverage/lcov-report/api/controllers/datasource.js.html +1 -1
  13. package/coverage/lcov-report/api/controllers/dev.js.html +15 -15
  14. package/coverage/lcov-report/api/controllers/hosting.js.html +8 -8
  15. package/coverage/lcov-report/api/controllers/index.html +39 -24
  16. package/coverage/lcov-report/api/controllers/integration.js.html +4 -4
  17. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  18. package/coverage/lcov-report/api/controllers/metadata.js.html +218 -0
  19. package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
  20. package/coverage/lcov-report/api/controllers/query.js.html +6 -12
  21. package/coverage/lcov-report/api/controllers/role.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/routing.js.html +9 -9
  23. package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
  24. package/coverage/lcov-report/api/controllers/row/index.html +20 -20
  25. package/coverage/lcov-report/api/controllers/row/index.js.html +14 -14
  26. package/coverage/lcov-report/api/controllers/row/internal.js.html +95 -62
  27. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
  28. package/coverage/lcov-report/api/controllers/row/utils.js.html +10 -10
  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/index.html +1 -1
  32. package/coverage/lcov-report/api/controllers/table/index.js.html +24 -24
  33. package/coverage/lcov-report/api/controllers/table/utils.js.html +32 -32
  34. package/coverage/lcov-report/api/controllers/templates.js.html +5 -5
  35. package/coverage/lcov-report/api/controllers/user.js.html +1 -1
  36. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  37. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  38. package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
  39. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
  40. package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
  41. package/coverage/lcov-report/api/index.html +1 -1
  42. package/coverage/lcov-report/api/index.js.html +23 -23
  43. package/coverage/lcov-report/api/routes/analytics.js.html +6 -6
  44. package/coverage/lcov-report/api/routes/apikeys.js.html +8 -8
  45. package/coverage/lcov-report/api/routes/application.js.html +8 -8
  46. package/coverage/lcov-report/api/routes/auth.js.html +6 -6
  47. package/coverage/lcov-report/api/routes/automation.js.html +41 -26
  48. package/coverage/lcov-report/api/routes/backup.js.html +8 -8
  49. package/coverage/lcov-report/api/routes/component.js.html +8 -8
  50. package/coverage/lcov-report/api/routes/datasource.js.html +13 -13
  51. package/coverage/lcov-report/api/routes/deploy.js.html +8 -8
  52. package/coverage/lcov-report/api/routes/dev.js.html +11 -11
  53. package/coverage/lcov-report/api/routes/hosting.js.html +8 -8
  54. package/coverage/lcov-report/api/routes/index.html +24 -9
  55. package/coverage/lcov-report/api/routes/index.js.html +36 -30
  56. package/coverage/lcov-report/api/routes/integration.js.html +8 -8
  57. package/coverage/lcov-report/api/routes/layout.js.html +8 -8
  58. package/coverage/lcov-report/api/routes/metadata.js.html +194 -0
  59. package/coverage/lcov-report/api/routes/permission.js.html +12 -12
  60. package/coverage/lcov-report/api/routes/query.js.html +13 -13
  61. package/coverage/lcov-report/api/routes/role.js.html +12 -12
  62. package/coverage/lcov-report/api/routes/routing.js.html +8 -8
  63. package/coverage/lcov-report/api/routes/row.js.html +10 -10
  64. package/coverage/lcov-report/api/routes/screen.js.html +11 -11
  65. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/static.js.html +13 -13
  67. package/coverage/lcov-report/api/routes/table.js.html +12 -12
  68. package/coverage/lcov-report/api/routes/templates.js.html +8 -8
  69. package/coverage/lcov-report/api/routes/user.js.html +9 -9
  70. package/coverage/lcov-report/api/routes/view.js.html +11 -11
  71. package/coverage/lcov-report/api/routes/webhook.js.html +11 -11
  72. package/coverage/lcov-report/automations/actions.js.html +38 -107
  73. package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
  74. package/coverage/lcov-report/automations/bullboard.js.html +46 -16
  75. package/coverage/lcov-report/automations/index.html +67 -67
  76. package/coverage/lcov-report/automations/index.js.html +26 -128
  77. package/coverage/lcov-report/automations/steps/bash.js.html +33 -12
  78. package/coverage/lcov-report/automations/steps/createRow.js.html +8 -8
  79. package/coverage/lcov-report/automations/steps/delay.js.html +45 -6
  80. package/coverage/lcov-report/automations/steps/deleteRow.js.html +8 -8
  81. package/coverage/lcov-report/automations/steps/discord.js.html +329 -0
  82. package/coverage/lcov-report/automations/steps/executeQuery.js.html +19 -31
  83. package/coverage/lcov-report/automations/steps/executeScript.js.html +18 -30
  84. package/coverage/lcov-report/automations/steps/filter.js.html +22 -19
  85. package/coverage/lcov-report/automations/steps/index.html +125 -65
  86. package/coverage/lcov-report/automations/steps/integromat.js.html +341 -0
  87. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +26 -32
  88. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +9 -9
  89. package/coverage/lcov-report/automations/steps/serverLog.js.html +20 -8
  90. package/coverage/lcov-report/automations/steps/{sendgridEmail.js.html → slack.js.html} +57 -87
  91. package/coverage/lcov-report/automations/steps/updateRow.js.html +7 -7
  92. package/coverage/lcov-report/automations/steps/utils.js.html +188 -0
  93. package/coverage/lcov-report/automations/steps/zapier.js.html +332 -0
  94. package/coverage/lcov-report/automations/thread.js.html +79 -76
  95. package/coverage/lcov-report/automations/triggerInfo/app.js.html +173 -0
  96. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +173 -0
  97. package/coverage/lcov-report/automations/triggerInfo/index.html +201 -0
  98. package/coverage/lcov-report/automations/triggerInfo/index.js.html +125 -0
  99. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +176 -0
  100. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +200 -0
  101. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +200 -0
  102. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +188 -0
  103. package/coverage/lcov-report/automations/triggers.js.html +54 -819
  104. package/coverage/lcov-report/automations/utils.js.html +557 -0
  105. package/coverage/lcov-report/constants/index.html +5 -5
  106. package/coverage/lcov-report/constants/index.js.html +19 -4
  107. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  108. package/coverage/lcov-report/constants/screens.js.html +2 -2
  109. package/coverage/lcov-report/db/client.js.html +1 -1
  110. package/coverage/lcov-report/db/index.html +19 -19
  111. package/coverage/lcov-report/db/index.js.html +1 -1
  112. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +73 -73
  113. package/coverage/lcov-report/db/linkedRows/index.html +17 -17
  114. package/coverage/lcov-report/db/linkedRows/index.js.html +79 -115
  115. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +31 -31
  116. package/coverage/lcov-report/db/newid.js.html +2 -2
  117. package/coverage/lcov-report/db/utils.js.html +79 -28
  118. package/coverage/lcov-report/events/AutomationEmitter.js.html +7 -7
  119. package/coverage/lcov-report/events/index.html +1 -1
  120. package/coverage/lcov-report/events/index.js.html +2 -2
  121. package/coverage/lcov-report/events/utils.js.html +1 -1
  122. package/coverage/lcov-report/index.html +115 -100
  123. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  124. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  125. package/coverage/lcov-report/{automations/logic.js.html → middleware/appInfo.js.html} +35 -38
  126. package/coverage/lcov-report/middleware/authorized.js.html +16 -16
  127. package/coverage/lcov-report/middleware/builder.js.html +15 -15
  128. package/coverage/lcov-report/middleware/currentapp.js.html +33 -33
  129. package/coverage/lcov-report/middleware/index.html +23 -8
  130. package/coverage/lcov-report/middleware/joi-validator.js.html +6 -6
  131. package/coverage/lcov-report/middleware/resourceId.js.html +28 -28
  132. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  133. package/coverage/lcov-report/middleware/usageQuota.js.html +8 -8
  134. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  135. package/coverage/lcov-report/utilities/budibaseDir.js.html +7 -7
  136. package/coverage/lcov-report/utilities/centralPath.js.html +4 -4
  137. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  138. package/coverage/lcov-report/utilities/global.js.html +21 -21
  139. package/coverage/lcov-report/utilities/index.html +18 -18
  140. package/coverage/lcov-report/utilities/index.js.html +167 -14
  141. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +12 -12
  142. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  143. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  144. package/coverage/lcov-report/utilities/routing/index.js.html +6 -6
  145. package/coverage/lcov-report/utilities/rowProcessor/index.html +14 -14
  146. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +87 -51
  147. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +8 -8
  148. package/coverage/lcov-report/utilities/security.js.html +2 -2
  149. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  150. package/coverage/lcov-report/utilities/users.js.html +1 -1
  151. package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
  152. package/coverage/lcov.info +2641 -2357
  153. package/dist/api/controllers/automation.js +49 -127
  154. package/dist/api/controllers/deploy/index.js +17 -1
  155. package/dist/api/controllers/metadata.js +49 -0
  156. package/dist/api/controllers/query.js +0 -2
  157. package/dist/api/controllers/row/internal.js +33 -23
  158. package/dist/api/routes/automation.js +4 -5
  159. package/dist/api/routes/index.js +2 -0
  160. package/dist/api/routes/metadata.js +13 -0
  161. package/dist/api/routes/tests/utilities/TestFunctions.js +13 -0
  162. package/dist/app.js +1 -1
  163. package/dist/automations/actions.js +26 -46
  164. package/dist/automations/bullboard.js +10 -2
  165. package/dist/automations/index.js +11 -48
  166. package/dist/automations/steps/bash.js +11 -5
  167. package/dist/automations/steps/createRow.js +4 -4
  168. package/dist/automations/steps/delay.js +15 -2
  169. package/dist/automations/steps/deleteRow.js +4 -4
  170. package/dist/automations/steps/discord.js +91 -0
  171. package/dist/automations/steps/executeQuery.js +11 -14
  172. package/dist/automations/steps/executeScript.js +11 -14
  173. package/dist/automations/steps/filter.js +18 -17
  174. package/dist/automations/steps/integromat.js +94 -0
  175. package/dist/automations/steps/outgoingWebhook.js +12 -16
  176. package/dist/automations/steps/sendSmtpEmail.js +3 -3
  177. package/dist/automations/steps/serverLog.js +6 -2
  178. package/dist/automations/steps/slack.js +73 -0
  179. package/dist/automations/steps/updateRow.js +3 -3
  180. package/dist/automations/steps/utils.js +46 -0
  181. package/dist/automations/steps/zapier.js +91 -0
  182. package/dist/automations/tests/utilities/index.js +2 -12
  183. package/dist/automations/thread.js +23 -25
  184. package/dist/automations/triggerInfo/app.js +32 -0
  185. package/dist/automations/triggerInfo/cron.js +32 -0
  186. package/dist/automations/triggerInfo/index.js +15 -0
  187. package/dist/automations/triggerInfo/rowDeleted.js +33 -0
  188. package/dist/automations/triggerInfo/rowSaved.js +41 -0
  189. package/dist/automations/triggerInfo/rowUpdated.js +41 -0
  190. package/dist/automations/triggerInfo/webhook.js +37 -0
  191. package/dist/automations/triggers.js +27 -284
  192. package/dist/automations/utils.js +143 -0
  193. package/dist/constants/index.js +4 -0
  194. package/dist/db/linkedRows/index.js +14 -26
  195. package/dist/db/utils.js +14 -1
  196. package/dist/environment.js +1 -0
  197. package/dist/middleware/appInfo.js +17 -0
  198. package/dist/middleware/usageQuota.js +1 -1
  199. package/dist/package.json +4 -5
  200. package/dist/tsconfig.tsbuildinfo +1 -1
  201. package/dist/utilities/fileSystem/index.js +0 -26
  202. package/dist/utilities/index.js +54 -0
  203. package/dist/utilities/redis.js +16 -1
  204. package/dist/utilities/rowProcessor/index.js +7 -4
  205. package/package.json +5 -6
  206. package/src/api/controllers/automation.js +75 -145
  207. package/src/api/controllers/deploy/index.js +23 -1
  208. package/src/api/controllers/metadata.js +46 -0
  209. package/src/api/controllers/query.js +0 -2
  210. package/src/api/controllers/row/internal.js +34 -23
  211. package/src/api/routes/automation.js +16 -11
  212. package/src/api/routes/index.js +2 -0
  213. package/src/api/routes/metadata.js +38 -0
  214. package/src/api/routes/tests/automation.spec.js +4 -26
  215. package/src/api/routes/tests/metadata.spec.js +65 -0
  216. package/src/api/routes/tests/utilities/TestFunctions.js +14 -0
  217. package/src/app.ts +1 -1
  218. package/src/automations/actions.js +26 -49
  219. package/src/automations/bullboard.js +12 -2
  220. package/src/automations/index.js +11 -45
  221. package/src/automations/steps/bash.js +12 -5
  222. package/src/automations/steps/createRow.js +4 -4
  223. package/src/automations/steps/delay.js +15 -2
  224. package/src/automations/steps/deleteRow.js +4 -4
  225. package/src/automations/steps/discord.js +83 -0
  226. package/src/automations/steps/executeQuery.js +11 -15
  227. package/src/automations/steps/executeScript.js +11 -15
  228. package/src/automations/steps/filter.js +18 -17
  229. package/src/automations/steps/integromat.js +87 -0
  230. package/src/automations/steps/outgoingWebhook.js +12 -14
  231. package/src/automations/steps/sendSmtpEmail.js +3 -3
  232. package/src/automations/steps/serverLog.js +6 -2
  233. package/src/automations/steps/slack.js +64 -0
  234. package/src/automations/steps/updateRow.js +3 -3
  235. package/src/automations/steps/utils.js +36 -0
  236. package/src/automations/steps/zapier.js +84 -0
  237. package/src/automations/tests/automation.spec.js +3 -66
  238. package/src/automations/tests/delay.spec.js +1 -1
  239. package/src/automations/tests/filter.spec.js +13 -13
  240. package/src/automations/tests/utilities/index.js +2 -13
  241. package/src/automations/thread.js +27 -26
  242. package/src/automations/triggerInfo/app.js +31 -0
  243. package/src/automations/triggerInfo/cron.js +31 -0
  244. package/src/automations/triggerInfo/index.js +15 -0
  245. package/src/automations/triggerInfo/rowDeleted.js +32 -0
  246. package/src/automations/triggerInfo/rowSaved.js +40 -0
  247. package/src/automations/triggerInfo/rowUpdated.js +40 -0
  248. package/src/automations/triggerInfo/webhook.js +36 -0
  249. package/src/automations/triggers.js +33 -288
  250. package/src/automations/utils.js +159 -0
  251. package/src/constants/index.js +5 -0
  252. package/src/db/linkedRows/index.js +15 -27
  253. package/src/db/tests/linkTests.spec.js +0 -12
  254. package/src/db/utils.js +17 -0
  255. package/src/environment.js +1 -0
  256. package/src/middleware/appInfo.js +19 -0
  257. package/src/middleware/usageQuota.js +1 -1
  258. package/src/utilities/fileSystem/index.js +0 -30
  259. package/src/utilities/index.js +51 -0
  260. package/src/utilities/redis.js +18 -1
  261. package/src/utilities/rowProcessor/index.js +16 -4
  262. package/dist/automations/logic.js +0 -17
  263. package/dist/automations/steps/sendgridEmail.js +0 -85
  264. package/src/automations/logic.js +0 -20
  265. package/src/automations/steps/sendgridEmail.js +0 -74
  266. package/src/automations/tests/sendEmail.spec.js +0 -36
@@ -123,5 +123,10 @@ exports.BaseQueryVerbs = {
123
123
  DELETE: "delete",
124
124
  }
125
125
 
126
+ exports.MetadataTypes = {
127
+ AUTOMATION_TEST_INPUT: "automationTestInput",
128
+ AUTOMATION_TEST_HISTORY: "automationTestHistory",
129
+ }
130
+
126
131
  // pass through the list from the auth/core lib
127
132
  exports.ObjectStoreBuckets = ObjectStoreBuckets
@@ -36,6 +36,18 @@ exports.IncludeDocs = IncludeDocs
36
36
  exports.getLinkDocuments = getLinkDocuments
37
37
  exports.createLinkView = createLinkView
38
38
 
39
+ function clearRelationshipFields(table, rows) {
40
+ for (let [key, field] of Object.entries(table.schema)) {
41
+ if (field.type === FieldTypes.LINK) {
42
+ rows = rows.map(row => {
43
+ delete row[key]
44
+ return row
45
+ })
46
+ }
47
+ }
48
+ return rows
49
+ }
50
+
39
51
  async function getLinksForRows(appId, rows) {
40
52
  const tableIds = [...new Set(rows.map(el => el.tableId))]
41
53
  // start by getting all the link values for performance reasons
@@ -126,33 +138,6 @@ exports.updateLinks = async function (args) {
126
138
  }
127
139
  }
128
140
 
129
- /**
130
- * Update a row with information about the links that pertain to it.
131
- * @param {string} appId The instance in which this row has been created.
132
- * @param {object} rows The row(s) themselves which is to be updated with info (if applicable). This can be
133
- * a single row object or an array of rows - both will be handled.
134
- * @returns {Promise<object>} The updated row (this may be the same if no links were found). If an array was input
135
- * then an array will be output, object input -> object output.
136
- */
137
- exports.attachLinkIDs = async (appId, rows) => {
138
- const links = await getLinksForRows(appId, rows)
139
- // now iterate through the rows and all field information
140
- for (let row of rows) {
141
- // find anything that matches the row's ID we are searching for and join it
142
- links
143
- .filter(el => el.thisId === row._id)
144
- .forEach(link => {
145
- if (row[link.fieldName] == null) {
146
- row[link.fieldName] = []
147
- }
148
- row[link.fieldName].push(link.id)
149
- })
150
- }
151
- // if it was an array when it came in then handle it as an array in response
152
- // otherwise return the first element as there was only one input
153
- return rows
154
- }
155
-
156
141
  /**
157
142
  * Given a table and a list of rows this will retrieve all of the attached docs and enrich them into the row.
158
143
  * This is required for formula fields, this may only be utilised internally (for now).
@@ -173,6 +158,9 @@ exports.attachFullLinkedDocs = async (ctx, table, rows) => {
173
158
  const links = (await getLinksForRows(appId, rows)).filter(link =>
174
159
  rows.some(row => row._id === link.thisId)
175
160
  )
161
+ // clear any existing links that could be dupe'd
162
+ rows = clearRelationshipFields(table, rows)
163
+ // now get the docs and combine into the rows
176
164
  let linked = await getFullLinkedDocs(ctx, appId, links)
177
165
  const linkedTables = []
178
166
  for (let row of rows) {
@@ -59,16 +59,4 @@ describe("test link functionality", () => {
59
59
  expect(Array.isArray(output)).toBe(true)
60
60
  })
61
61
  })
62
-
63
- describe("attachLinkIDs", () => {
64
- it("should be able to attach linkIDs", async () => {
65
- await config.init()
66
- await config.createTable()
67
- const table = await config.createLinkedTable()
68
- const row = await config.createRow()
69
- const linkRow = await config.createRow(basicLinkedRow(table._id, row._id))
70
- const attached = await links.attachLinkIDs(config.getAppId(), [linkRow])
71
- expect(attached[0].link[0]).toBe(row._id)
72
- })
73
- })
74
62
  })
package/src/db/utils.js CHANGED
@@ -7,6 +7,8 @@ const {
7
7
  APP_PREFIX,
8
8
  SEPARATOR,
9
9
  StaticDatabases,
10
+ isDevAppID,
11
+ isProdAppID,
10
12
  } = require("@budibase/auth/db")
11
13
 
12
14
  const UNICODE_MAX = "\ufff0"
@@ -36,6 +38,7 @@ const DocumentTypes = {
36
38
  DATASOURCE_PLUS: "datasource_plus",
37
39
  QUERY: "query",
38
40
  DEPLOYMENTS: "deployments",
41
+ METADATA: "metadata",
39
42
  }
40
43
 
41
44
  const ViewNames = {
@@ -63,6 +66,8 @@ const BudibaseInternalDB = {
63
66
 
64
67
  exports.APP_PREFIX = APP_PREFIX
65
68
  exports.APP_DEV_PREFIX = APP_DEV_PREFIX
69
+ exports.isDevAppID = isDevAppID
70
+ exports.isProdAppID = isProdAppID
66
71
  exports.USER_METDATA_PREFIX = `${DocumentTypes.ROW}${SEPARATOR}${InternalTables.USER_METADATA}${SEPARATOR}`
67
72
  exports.LINK_USER_METADATA_PREFIX = `${DocumentTypes.LINK}${SEPARATOR}${InternalTables.USER_METADATA}${SEPARATOR}`
68
73
  exports.ViewNames = ViewNames
@@ -331,6 +336,18 @@ exports.getQueryParams = (datasourceId = null, otherProps = {}) => {
331
336
  )
332
337
  }
333
338
 
339
+ exports.generateMetadataID = (type, entityId) => {
340
+ return `${DocumentTypes.METADATA}${SEPARATOR}${type}${SEPARATOR}${entityId}`
341
+ }
342
+
343
+ exports.getMetadataParams = (type, entityId = null, otherProps = {}) => {
344
+ let docId = `${type}${SEPARATOR}`
345
+ if (entityId != null) {
346
+ docId += entityId
347
+ }
348
+ return getDocParams(DocumentTypes.METADATA, docId, otherProps)
349
+ }
350
+
334
351
  /**
335
352
  * This can be used with the db.allDocs to get a list of IDs
336
353
  */
@@ -55,6 +55,7 @@ module.exports = {
55
55
  BUDIBASE_API_KEY: process.env.BUDIBASE_API_KEY,
56
56
  USERID_API_KEY: process.env.USERID_API_KEY,
57
57
  DEPLOYMENT_CREDENTIALS_URL: process.env.DEPLOYMENT_CREDENTIALS_URL,
58
+ ALLOW_DEV_AUTOMATIONS: process.env.ALLOW_DEV_AUTOMATIONS,
58
59
  _set(key, value) {
59
60
  process.env[key] = value
60
61
  module.exports[key] = value
@@ -0,0 +1,19 @@
1
+ const { isDevAppID, isProdAppID } = require("../db/utils")
2
+
3
+ exports.AppType = {
4
+ DEV: "dev",
5
+ PROD: "prod",
6
+ }
7
+
8
+ exports.middleware =
9
+ ({ appType } = {}) =>
10
+ (ctx, next) => {
11
+ const appId = ctx.appId
12
+ if (appType === exports.AppType.DEV && appId && !isDevAppID(appId)) {
13
+ ctx.throw(400, "Only apps in development support this endpoint")
14
+ }
15
+ if (appType === exports.AppType.PROD && appId && !isProdAppID(appId)) {
16
+ ctx.throw(400, "Only apps in production support this endpoint")
17
+ }
18
+ return next()
19
+ }
@@ -14,7 +14,7 @@ const DOMAIN_MAP = {
14
14
  views: usageQuota.Properties.VIEW,
15
15
  users: usageQuota.Properties.USER,
16
16
  // this will not be updated by endpoint calls
17
- // instead it will be updated by triggers
17
+ // instead it will be updated by triggerInfo
18
18
  automationRuns: usageQuota.Properties.AUTOMATION,
19
19
  }
20
20
 
@@ -14,18 +14,12 @@ const {
14
14
  downloadTarball,
15
15
  } = require("./utilities")
16
16
  const { updateClientLibrary } = require("./clientLibrary")
17
- const download = require("download")
18
17
  const env = require("../../environment")
19
- const { homedir } = require("os")
20
- const fetch = require("node-fetch")
21
18
  const {
22
19
  USER_METDATA_PREFIX,
23
20
  LINK_USER_METADATA_PREFIX,
24
21
  } = require("../../db/utils")
25
22
 
26
- const DEFAULT_AUTOMATION_BUCKET =
27
- "https://prod-budi-automations.s3-eu-west-1.amazonaws.com"
28
- const DEFAULT_AUTOMATION_DIRECTORY = ".budibase-automations"
29
23
  const TOP_LEVEL_PATH = join(__dirname, "..", "..", "..")
30
24
  const NODE_MODULES_PATH = join(TOP_LEVEL_PATH, "node_modules")
31
25
 
@@ -205,30 +199,6 @@ exports.getComponentLibraryManifest = async (appId, library) => {
205
199
  return JSON.parse(resp)
206
200
  }
207
201
 
208
- exports.automationInit = async () => {
209
- const directory =
210
- env.AUTOMATION_DIRECTORY || join(homedir(), DEFAULT_AUTOMATION_DIRECTORY)
211
- const bucket = env.AUTOMATION_BUCKET || DEFAULT_AUTOMATION_BUCKET
212
- if (!fs.existsSync(directory)) {
213
- fs.mkdirSync(directory, { recursive: true })
214
- }
215
- // env setup to get async packages
216
- let response = await fetch(`${bucket}/manifest.json`)
217
- return response.json()
218
- }
219
-
220
- exports.getExternalAutomationStep = async (name, version, bundleName) => {
221
- const directory =
222
- env.AUTOMATION_DIRECTORY || join(homedir(), DEFAULT_AUTOMATION_DIRECTORY)
223
- const bucket = env.AUTOMATION_BUCKET || DEFAULT_AUTOMATION_BUCKET
224
- try {
225
- return require(join(directory, bundleName))
226
- } catch (err) {
227
- await download(`${bucket}/${name}/${version}/${bundleName}`, directory)
228
- return require(join(directory, bundleName))
229
- }
230
- }
231
-
232
202
  /**
233
203
  * All file reads come through here just to make sure all of them make sense
234
204
  * allows a centralised location to check logic is all good.
@@ -1,6 +1,8 @@
1
1
  const env = require("../environment")
2
2
  const { OBJ_STORE_DIRECTORY } = require("../constants")
3
3
  const { sanitizeKey } = require("@budibase/auth/src/objectStore")
4
+ const CouchDB = require("../db")
5
+ const { generateMetadataID } = require("../db/utils")
4
6
 
5
7
  const BB_CDN = "https://cdn.budi.live"
6
8
 
@@ -55,3 +57,52 @@ exports.attachmentsRelativeURL = attachmentKey => {
55
57
  `${exports.objectStoreUrl()}/${attachmentKey}`
56
58
  )
57
59
  }
60
+
61
+ exports.updateEntityMetadata = async (appId, type, entityId, updateFn) => {
62
+ const db = new CouchDB(appId)
63
+ const id = generateMetadataID(type, entityId)
64
+ // read it to see if it exists, we'll overwrite it no matter what
65
+ let rev,
66
+ metadata = {}
67
+ try {
68
+ const oldMetadata = await db.get(id)
69
+ rev = oldMetadata._rev
70
+ metadata = updateFn(oldMetadata)
71
+ } catch (err) {
72
+ rev = null
73
+ metadata = updateFn({})
74
+ }
75
+ metadata._id = id
76
+ if (rev) {
77
+ metadata._rev = rev
78
+ }
79
+ const response = await db.put(metadata)
80
+ return {
81
+ ...metadata,
82
+ _id: id,
83
+ _rev: response.rev,
84
+ }
85
+ }
86
+
87
+ exports.saveEntityMetadata = async (appId, type, entityId, metadata) => {
88
+ return exports.updateEntityMetadata(appId, type, entityId, () => {
89
+ return metadata
90
+ })
91
+ }
92
+
93
+ exports.deleteEntityMetadata = async (appId, type, entityId) => {
94
+ const db = new CouchDB(appId)
95
+ const id = generateMetadataID(type, entityId)
96
+ let rev
97
+ try {
98
+ const metadata = await db.get(id)
99
+ if (metadata) {
100
+ rev = metadata._rev
101
+ }
102
+ } catch (err) {
103
+ // don't need to error if it doesn't exist
104
+ }
105
+ if (id && rev) {
106
+ await db.remove(id, rev)
107
+ }
108
+ }
@@ -2,20 +2,24 @@ const { Client, utils } = require("@budibase/auth/redis")
2
2
  const { getGlobalIDFromUserMetadataID } = require("../db/utils")
3
3
 
4
4
  const APP_DEV_LOCK_SECONDS = 600
5
- let devAppClient, debounceClient
5
+ const AUTOMATION_TEST_FLAG_SECONDS = 60
6
+ let devAppClient, debounceClient, flagClient
6
7
 
7
8
  // we init this as we want to keep the connection open all the time
8
9
  // reduces the performance hit
9
10
  exports.init = async () => {
10
11
  devAppClient = new Client(utils.Databases.DEV_LOCKS)
11
12
  debounceClient = new Client(utils.Databases.DEBOUNCE)
13
+ flagClient = new Client(utils.Databases.FLAGS)
12
14
  await devAppClient.init()
13
15
  await debounceClient.init()
16
+ await flagClient.init()
14
17
  }
15
18
 
16
19
  exports.shutdown = async () => {
17
20
  if (devAppClient) await devAppClient.finish()
18
21
  if (debounceClient) await debounceClient.finish()
22
+ if (flagClient) await flagClient.finish()
19
23
  }
20
24
 
21
25
  exports.doesUserHaveLock = async (devAppId, user) => {
@@ -67,3 +71,16 @@ exports.checkDebounce = async id => {
67
71
  exports.setDebounce = async (id, seconds) => {
68
72
  await debounceClient.store(id, "debouncing", seconds)
69
73
  }
74
+
75
+ exports.setTestFlag = async id => {
76
+ await flagClient.store(id, { testing: true }, AUTOMATION_TEST_FLAG_SECONDS)
77
+ }
78
+
79
+ exports.checkTestFlag = async id => {
80
+ const flag = await flagClient.get(id)
81
+ return !!(flag && flag.testing)
82
+ }
83
+
84
+ exports.clearTestFlag = async id => {
85
+ await devAppClient.delete(id)
86
+ }
@@ -185,10 +185,16 @@ exports.inputProcessing = (user = {}, table, row) => {
185
185
  * @param {object} ctx the request which is looking for enriched rows.
186
186
  * @param {object} table the table from which these rows came from originally, this is used to determine
187
187
  * the schema of the rows and then enrich.
188
- * @param {object[]} rows the rows which are to be enriched.
189
- * @returns {object[]} the enriched rows will be returned.
188
+ * @param {object[]|object} rows the rows which are to be enriched.
189
+ * @param {object} opts used to set some options for the output, such as disabling relationship squashing.
190
+ * @returns {object[]|object} the enriched rows will be returned.
190
191
  */
191
- exports.outputProcessing = async (ctx, table, rows) => {
192
+ exports.outputProcessing = async (
193
+ ctx,
194
+ table,
195
+ rows,
196
+ opts = { squash: true }
197
+ ) => {
192
198
  const appId = ctx.appId
193
199
  let wasArray = true
194
200
  if (!(rows instanceof Array)) {
@@ -214,6 +220,12 @@ exports.outputProcessing = async (ctx, table, rows) => {
214
220
  }
215
221
  }
216
222
  }
217
- enriched = await linkRows.squashLinksToPrimaryDisplay(appId, table, enriched)
223
+ if (opts.squash) {
224
+ enriched = await linkRows.squashLinksToPrimaryDisplay(
225
+ appId,
226
+ table,
227
+ enriched
228
+ )
229
+ }
218
230
  return wasArray ? enriched : enriched[0]
219
231
  }
@@ -1,17 +0,0 @@
1
- "use strict";
2
- let filter = require("./steps/filter");
3
- let delay = require("./steps/delay");
4
- let BUILTIN_LOGIC = {
5
- DELAY: delay.run,
6
- FILTER: filter.run,
7
- };
8
- let BUILTIN_DEFINITIONS = {
9
- DELAY: delay.definition,
10
- FILTER: filter.definition,
11
- };
12
- module.exports.getLogic = function (logicName) {
13
- if (BUILTIN_LOGIC[logicName] != null) {
14
- return BUILTIN_LOGIC[logicName];
15
- }
16
- };
17
- module.exports.BUILTIN_DEFINITIONS = BUILTIN_DEFINITIONS;
@@ -1,85 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- module.exports.definition = {
12
- description: "Send an email using SendGrid",
13
- tagline: "Send email to {{inputs.to}}",
14
- icon: "ri-mail-open-line",
15
- name: "Send Email (SendGrid)",
16
- type: "ACTION",
17
- stepId: "SEND_EMAIL",
18
- inputs: {},
19
- schema: {
20
- inputs: {
21
- properties: {
22
- apiKey: {
23
- type: "string",
24
- title: "SendGrid API key",
25
- },
26
- to: {
27
- type: "string",
28
- title: "Send To",
29
- },
30
- from: {
31
- type: "string",
32
- title: "Send From",
33
- },
34
- subject: {
35
- type: "string",
36
- title: "Email Subject",
37
- },
38
- contents: {
39
- type: "string",
40
- title: "Email Contents",
41
- },
42
- },
43
- required: ["to", "from", "subject", "contents"],
44
- },
45
- outputs: {
46
- properties: {
47
- success: {
48
- type: "boolean",
49
- description: "Whether the email was sent",
50
- },
51
- response: {
52
- type: "object",
53
- description: "A response from the email client, this may be an error",
54
- },
55
- },
56
- required: ["success"],
57
- },
58
- },
59
- };
60
- module.exports.run = function ({ inputs }) {
61
- return __awaiter(this, void 0, void 0, function* () {
62
- const sgMail = require("@sendgrid/mail");
63
- sgMail.setApiKey(inputs.apiKey);
64
- const msg = {
65
- to: inputs.to,
66
- from: inputs.from,
67
- subject: inputs.subject,
68
- text: inputs.contents ? inputs.contents : "Empty",
69
- };
70
- try {
71
- let response = yield sgMail.send(msg);
72
- return {
73
- success: true,
74
- response,
75
- };
76
- }
77
- catch (err) {
78
- console.error(err);
79
- return {
80
- success: false,
81
- response: err,
82
- };
83
- }
84
- });
85
- };