@budibase/server 1.0.26 → 1.0.27-alpha.11

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 (258) hide show
  1. package/__mocks__/node-fetch.ts +21 -0
  2. package/builder/assets/bb-spaceship.8f6e81e1.svg +227 -0
  3. package/builder/assets/{index.4fb3f887.css → index.0dce895b.css} +1 -1
  4. package/builder/assets/index.b98dd7ca.js +1348 -0
  5. package/builder/assets/{vendor.470042a4.js → vendor.f9faf6ab.js} +88 -88
  6. package/builder/index.html +3 -3
  7. package/coverage/clover.xml +1364 -1121
  8. package/coverage/coverage-final.json +37 -36
  9. package/coverage/lcov-report/api/controllers/analytics.js.html +1 -1
  10. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  11. package/coverage/lcov-report/api/controllers/application.js.html +59 -59
  12. package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
  13. package/coverage/lcov-report/api/controllers/automation.js.html +22 -10
  14. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  15. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  16. package/coverage/lcov-report/api/controllers/component.js.html +4 -4
  17. package/coverage/lcov-report/api/controllers/datasource.js.html +170 -68
  18. package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/hosting.js.html +1 -1
  20. package/coverage/lcov-report/api/controllers/index.html +39 -54
  21. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  23. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  24. package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
  25. package/coverage/lcov-report/api/controllers/query/index.html +126 -0
  26. package/coverage/lcov-report/api/controllers/{query.js.html → query/index.js.html} +225 -114
  27. package/coverage/lcov-report/api/controllers/query/validation.js.html +206 -0
  28. package/coverage/lcov-report/api/controllers/role.js.html +1 -1
  29. package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
  30. package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
  31. package/coverage/lcov-report/api/controllers/row/index.html +22 -22
  32. package/coverage/lcov-report/api/controllers/row/index.js.html +1 -1
  33. package/coverage/lcov-report/api/controllers/row/internal.js.html +38 -11
  34. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +7 -4
  35. package/coverage/lcov-report/api/controllers/row/utils.js.html +29 -20
  36. package/coverage/lcov-report/api/controllers/screen.js.html +1 -1
  37. package/coverage/lcov-report/api/controllers/script.js.html +1 -1
  38. package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
  39. package/coverage/lcov-report/api/controllers/table/index.html +1 -1
  40. package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
  41. package/coverage/lcov-report/api/controllers/table/internal.js.html +1 -1
  42. package/coverage/lcov-report/api/controllers/table/utils.js.html +1 -1
  43. package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
  44. package/coverage/lcov-report/api/controllers/user.js.html +108 -9
  45. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  46. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  47. package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
  48. package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
  49. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
  50. package/coverage/lcov-report/api/controllers/webhook.js.html +18 -6
  51. package/coverage/lcov-report/api/index.html +1 -1
  52. package/coverage/lcov-report/api/index.js.html +5 -5
  53. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/application.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/dev.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/hosting.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/index.html +9 -9
  66. package/coverage/lcov-report/api/routes/index.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/query.js.html +19 -85
  72. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  73. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  74. package/coverage/lcov-report/api/routes/row.js.html +1 -1
  75. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  76. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  77. package/coverage/lcov-report/api/routes/static.js.html +1 -1
  78. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  79. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  80. package/coverage/lcov-report/api/routes/user.js.html +32 -2
  81. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  82. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  83. package/coverage/lcov-report/automations/actions.js.html +1 -1
  84. package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
  85. package/coverage/lcov-report/automations/bullboard.js.html +1 -1
  86. package/coverage/lcov-report/automations/index.html +20 -20
  87. package/coverage/lcov-report/automations/index.js.html +1 -1
  88. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  89. package/coverage/lcov-report/automations/steps/createRow.js.html +1 -1
  90. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  91. package/coverage/lcov-report/automations/steps/deleteRow.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/executeQuery.js.html +31 -7
  94. package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
  95. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  96. package/coverage/lcov-report/automations/steps/index.html +11 -11
  97. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  98. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +5 -8
  99. package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
  100. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  101. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  102. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  103. package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
  104. package/coverage/lcov-report/automations/steps/utils.js.html +1 -1
  105. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  106. package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
  107. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
  108. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  109. package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
  110. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
  111. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
  112. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
  113. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
  114. package/coverage/lcov-report/automations/triggers.js.html +1 -1
  115. package/coverage/lcov-report/automations/utils.js.html +48 -15
  116. package/coverage/lcov-report/constants/index.html +1 -1
  117. package/coverage/lcov-report/constants/index.js.html +22 -22
  118. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  119. package/coverage/lcov-report/constants/screens.js.html +1 -1
  120. package/coverage/lcov-report/db/client.js.html +18 -18
  121. package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
  122. package/coverage/lcov-report/db/index.html +15 -15
  123. package/coverage/lcov-report/db/index.js.html +3 -3
  124. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +1 -1
  125. package/coverage/lcov-report/db/linkedRows/index.html +1 -1
  126. package/coverage/lcov-report/db/linkedRows/index.js.html +1 -1
  127. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
  128. package/coverage/lcov-report/db/newid.js.html +4 -4
  129. package/coverage/lcov-report/db/utils.js.html +107 -80
  130. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  131. package/coverage/lcov-report/events/index.html +1 -1
  132. package/coverage/lcov-report/events/index.js.html +1 -1
  133. package/coverage/lcov-report/events/utils.js.html +1 -1
  134. package/coverage/lcov-report/index.html +99 -84
  135. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  136. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  137. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  138. package/coverage/lcov-report/middleware/authorized.js.html +10 -10
  139. package/coverage/lcov-report/middleware/builder.js.html +8 -8
  140. package/coverage/lcov-report/middleware/currentapp.js.html +28 -28
  141. package/coverage/lcov-report/middleware/index.html +1 -1
  142. package/coverage/lcov-report/middleware/joi-validator.js.html +11 -11
  143. package/coverage/lcov-report/middleware/resourceId.js.html +18 -18
  144. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  145. package/coverage/lcov-report/middleware/usageQuota.js.html +1 -1
  146. package/coverage/lcov-report/middleware/utils.js.html +2 -2
  147. package/coverage/lcov-report/threads/automation.js.html +1 -1
  148. package/coverage/lcov-report/threads/index.html +31 -31
  149. package/coverage/lcov-report/threads/index.js.html +12 -12
  150. package/coverage/lcov-report/threads/query.js.html +396 -69
  151. package/coverage/lcov-report/threads/utils.js.html +358 -13
  152. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  153. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  154. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  155. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  156. package/coverage/lcov-report/utilities/global.js.html +13 -13
  157. package/coverage/lcov-report/utilities/index.html +19 -19
  158. package/coverage/lcov-report/utilities/index.js.html +69 -36
  159. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +2 -2
  160. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  161. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  162. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  163. package/coverage/lcov-report/utilities/rowProcessor/index.html +19 -19
  164. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +235 -10
  165. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
  166. package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
  167. package/coverage/lcov-report/utilities/security.js.html +2 -2
  168. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  169. package/coverage/lcov-report/utilities/users.js.html +1 -1
  170. package/coverage/lcov-report/utilities/workerRequests.js.html +19 -19
  171. package/coverage/lcov.info +2294 -1874
  172. package/dist/api/controllers/automation.js +7 -5
  173. package/dist/api/controllers/datasource.js +29 -0
  174. package/dist/api/controllers/query/import/index.js +79 -0
  175. package/dist/api/controllers/query/import/sources/base/index.js +64 -0
  176. package/dist/api/controllers/query/import/sources/base/openapi.js +42 -0
  177. package/dist/api/controllers/query/import/sources/curl.js +96 -0
  178. package/dist/api/controllers/query/import/sources/openapi2.js +142 -0
  179. package/dist/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json +253 -0
  180. package/dist/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json +1054 -0
  181. package/dist/api/controllers/{query.js → query/index.js} +86 -52
  182. package/dist/api/controllers/query/validation.js +38 -0
  183. package/dist/api/controllers/row/internal.js +14 -6
  184. package/dist/api/controllers/row/internalSearch.js +2 -1
  185. package/dist/api/controllers/row/utils.js +13 -6
  186. package/dist/api/controllers/user.js +37 -1
  187. package/dist/api/controllers/webhook.js +4 -0
  188. package/dist/api/routes/query.js +5 -33
  189. package/dist/api/routes/user.js +3 -1
  190. package/dist/automations/steps/executeQuery.js +8 -1
  191. package/dist/automations/steps/outgoingWebhook.js +2 -3
  192. package/dist/automations/utils.js +10 -0
  193. package/dist/db/utils.js +8 -0
  194. package/dist/definitions/datasource.js +6 -1
  195. package/dist/integrations/base/sqlTable.js +1 -1
  196. package/dist/integrations/rest.js +207 -117
  197. package/dist/package.json +11 -4
  198. package/dist/tests/utilities/TestConfiguration.js +47 -0
  199. package/dist/threads/query.js +148 -40
  200. package/dist/threads/utils.js +105 -0
  201. package/dist/tsconfig.tsbuildinfo +1 -1
  202. package/dist/utilities/fileSystem/utilities.js +2 -1
  203. package/dist/utilities/index.js +10 -0
  204. package/dist/utilities/rowProcessor/index.js +76 -0
  205. package/package.json +12 -5
  206. package/src/api/controllers/automation.js +8 -4
  207. package/src/api/controllers/datasource.js +34 -0
  208. package/src/api/controllers/query/import/index.ts +85 -0
  209. package/src/api/controllers/query/import/sources/base/index.ts +87 -0
  210. package/src/api/controllers/query/import/sources/base/openapi.ts +24 -0
  211. package/src/api/controllers/query/import/sources/curl.ts +102 -0
  212. package/src/api/controllers/query/import/sources/openapi2.ts +163 -0
  213. package/src/api/controllers/query/import/sources/tests/curl/curl.spec.js +103 -0
  214. package/src/api/controllers/query/import/sources/tests/curl/data/delete.txt +1 -0
  215. package/src/api/controllers/query/import/sources/tests/curl/data/empty-body.txt +2 -0
  216. package/src/api/controllers/query/import/sources/tests/curl/data/get.txt +1 -0
  217. package/src/api/controllers/query/import/sources/tests/curl/data/headers.txt +3 -0
  218. package/src/api/controllers/query/import/sources/tests/curl/data/patch.txt +2 -0
  219. package/src/api/controllers/query/import/sources/tests/curl/data/path.txt +1 -0
  220. package/src/api/controllers/query/import/sources/tests/curl/data/post.txt +2 -0
  221. package/src/api/controllers/query/import/sources/tests/curl/data/put.txt +2 -0
  222. package/src/api/controllers/query/import/sources/tests/curl/data/query.txt +1 -0
  223. package/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json +253 -0
  224. package/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.yaml +160 -0
  225. package/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json +1054 -0
  226. package/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.yaml +711 -0
  227. package/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js +238 -0
  228. package/src/api/controllers/query/import/tests/index.spec.js +109 -0
  229. package/src/api/controllers/query/index.js +195 -0
  230. package/src/api/controllers/query/validation.js +42 -0
  231. package/src/api/controllers/row/internal.js +14 -5
  232. package/src/api/controllers/row/internalSearch.js +2 -1
  233. package/src/api/controllers/row/utils.js +11 -8
  234. package/src/api/controllers/user.js +33 -0
  235. package/src/api/controllers/webhook.js +4 -0
  236. package/src/api/routes/query.js +13 -35
  237. package/src/api/routes/tests/datasource.spec.js +45 -0
  238. package/src/api/routes/tests/query.spec.js +69 -0
  239. package/src/api/routes/user.js +10 -0
  240. package/src/automations/steps/executeQuery.js +9 -1
  241. package/src/automations/steps/outgoingWebhook.js +2 -3
  242. package/src/automations/utils.js +11 -0
  243. package/src/db/utils.js +9 -0
  244. package/src/definitions/common.ts +2 -16
  245. package/src/definitions/datasource.ts +83 -1
  246. package/src/integrations/base/IntegrationBase.ts +4 -4
  247. package/src/integrations/base/sqlTable.ts +1 -1
  248. package/src/integrations/oracle.ts +1 -1
  249. package/src/integrations/rest.ts +230 -137
  250. package/src/integrations/tests/rest.spec.js +167 -19
  251. package/src/tests/utilities/TestConfiguration.js +57 -0
  252. package/src/threads/query.js +149 -40
  253. package/src/threads/utils.js +115 -0
  254. package/src/utilities/fileSystem/utilities.js +2 -0
  255. package/src/utilities/index.js +11 -0
  256. package/src/utilities/rowProcessor/index.js +75 -0
  257. package/builder/assets/index.8adef83f.js +0 -1316
  258. package/src/api/controllers/query.js +0 -158
@@ -50,10 +50,10 @@ exports.validate = async ({ appId, tableId, row, table }) => {
50
50
  const errors = {}
51
51
  for (let fieldName of Object.keys(table.schema)) {
52
52
  const constraints = cloneDeep(table.schema[fieldName].constraints)
53
+ const type = table.schema[fieldName].type
53
54
  // special case for options, need to always allow unselected (null)
54
55
  if (
55
- table.schema[fieldName].type ===
56
- (FieldTypes.OPTIONS || FieldTypes.ARRAY) &&
56
+ (type === FieldTypes.OPTIONS || type === FieldTypes.ARRAY) &&
57
57
  constraints.inclusion
58
58
  ) {
59
59
  constraints.inclusion.push(null)
@@ -61,17 +61,20 @@ exports.validate = async ({ appId, tableId, row, table }) => {
61
61
  let res
62
62
 
63
63
  // Validate.js doesn't seem to handle array
64
- if (
65
- table.schema[fieldName].type === FieldTypes.ARRAY &&
66
- row[fieldName] &&
67
- row[fieldName].length
68
- ) {
64
+ if (type === FieldTypes.ARRAY && row[fieldName] && row[fieldName].length) {
69
65
  row[fieldName].map(val => {
70
66
  if (!constraints.inclusion.includes(val)) {
71
67
  errors[fieldName] = "Field not in list"
72
68
  }
73
69
  })
74
- } else if (table.schema[fieldName].type === FieldTypes.FORMULA) {
70
+ } else if (type === FieldTypes.JSON && typeof row[fieldName] === "string") {
71
+ // this should only happen if there is an error
72
+ try {
73
+ JSON.parse(row[fieldName])
74
+ } catch (err) {
75
+ errors[fieldName] = [`Contains invalid JSON`]
76
+ }
77
+ } else if (type === FieldTypes.FORMULA) {
75
78
  res = validateJs.single(
76
79
  processStringSync(table.schema[fieldName].formula, row),
77
80
  constraints
@@ -2,6 +2,7 @@ const CouchDB = require("../../db")
2
2
  const {
3
3
  generateUserMetadataID,
4
4
  getUserMetadataParams,
5
+ generateUserFlagID,
5
6
  } = require("../../db/utils")
6
7
  const { InternalTables } = require("../../db/utils")
7
8
  const { getGlobalUsers, getRawGlobalUser } = require("../../utilities/global")
@@ -195,3 +196,35 @@ exports.destroyMetadata = async function (ctx) {
195
196
  exports.findMetadata = async function (ctx) {
196
197
  ctx.body = await getFullUser(ctx, ctx.params.id)
197
198
  }
199
+
200
+ exports.setFlag = async function (ctx) {
201
+ const userId = ctx.user._id
202
+ const { flag, value } = ctx.request.body
203
+ if (!flag) {
204
+ ctx.throw(400, "Must supply a 'flag' field in request body.")
205
+ }
206
+ const flagDocId = generateUserFlagID(userId)
207
+ const db = new CouchDB(ctx.appId)
208
+ let doc
209
+ try {
210
+ doc = await db.get(flagDocId)
211
+ } catch (err) {
212
+ doc = { _id: flagDocId }
213
+ }
214
+ doc[flag] = value || true
215
+ await db.put(doc)
216
+ ctx.body = { message: "Flag set successfully" }
217
+ }
218
+
219
+ exports.getFlags = async function (ctx) {
220
+ const userId = ctx.user._id
221
+ const docId = generateUserFlagID(userId)
222
+ const db = new CouchDB(ctx.appId)
223
+ let doc
224
+ try {
225
+ doc = await db.get(docId)
226
+ } catch (err) {
227
+ doc = { _id: docId }
228
+ }
229
+ ctx.body = doc
230
+ }
@@ -65,6 +65,10 @@ exports.buildSchema = async ctx => {
65
65
  let automation = await db.get(webhook.action.target)
66
66
  const autoOutputs = automation.definition.trigger.schema.outputs
67
67
  let properties = webhook.bodySchema.properties
68
+ // reset webhook outputs
69
+ autoOutputs.properties = {
70
+ body: autoOutputs.properties.body,
71
+ }
68
72
  for (let prop of Object.keys(properties)) {
69
73
  autoOutputs.properties[prop] = {
70
74
  type: properties[prop].type,
@@ -1,53 +1,23 @@
1
1
  const Router = require("@koa/router")
2
2
  const queryController = require("../controllers/query")
3
3
  const authorized = require("../../middleware/authorized")
4
- const Joi = require("joi")
5
4
  const {
6
5
  PermissionLevels,
7
6
  PermissionTypes,
8
7
  BUILDER,
9
8
  } = require("@budibase/auth/permissions")
10
- const joiValidator = require("../../middleware/joi-validator")
11
9
  const {
12
10
  bodyResource,
13
11
  bodySubResource,
14
12
  paramResource,
15
13
  } = require("../../middleware/resourceId")
14
+ const {
15
+ generateQueryPreviewValidation,
16
+ generateQueryValidation,
17
+ } = require("../controllers/query/validation")
16
18
 
17
19
  const router = Router()
18
20
 
19
- function generateQueryValidation() {
20
- // prettier-ignore
21
- return joiValidator.body(Joi.object({
22
- _id: Joi.string(),
23
- _rev: Joi.string(),
24
- name: Joi.string().required(),
25
- fields: Joi.object().required(),
26
- datasourceId: Joi.string().required(),
27
- readable: Joi.boolean(),
28
- parameters: Joi.array().items(Joi.object({
29
- name: Joi.string(),
30
- default: Joi.string().allow(""),
31
- })),
32
- queryVerb: Joi.string().allow().required(),
33
- extra: Joi.object().optional(),
34
- schema: Joi.object({}).required().unknown(true),
35
- transformer: Joi.string().optional(),
36
- }))
37
- }
38
-
39
- function generateQueryPreviewValidation() {
40
- // prettier-ignore
41
- return joiValidator.body(Joi.object({
42
- fields: Joi.object().required(),
43
- queryVerb: Joi.string().allow().required(),
44
- extra: Joi.object().optional(),
45
- datasourceId: Joi.string().required(),
46
- transformer: Joi.string().optional(),
47
- parameters: Joi.object({}).required().unknown(true)
48
- }))
49
- }
50
-
51
21
  router
52
22
  .get("/api/queries", authorized(BUILDER), queryController.fetch)
53
23
  .post(
@@ -57,6 +27,7 @@ router
57
27
  generateQueryValidation(),
58
28
  queryController.save
59
29
  )
30
+ .post("/api/queries/import", authorized(BUILDER), queryController.import)
60
31
  .post(
61
32
  "/api/queries/preview",
62
33
  bodyResource("datasourceId"),
@@ -70,11 +41,18 @@ router
70
41
  authorized(PermissionTypes.QUERY, PermissionLevels.READ),
71
42
  queryController.find
72
43
  )
44
+ // DEPRECATED - use new query endpoint for future work
73
45
  .post(
74
46
  "/api/queries/:queryId",
75
47
  paramResource("queryId"),
76
48
  authorized(PermissionTypes.QUERY, PermissionLevels.WRITE),
77
- queryController.execute
49
+ queryController.executeV1
50
+ )
51
+ .post(
52
+ "/api/v2/queries/:queryId",
53
+ paramResource("queryId"),
54
+ authorized(PermissionTypes.QUERY, PermissionLevels.WRITE),
55
+ queryController.executeV2
78
56
  )
79
57
  .delete(
80
58
  "/api/queries/:queryId/:revId",
@@ -4,6 +4,7 @@ let setup = require("./utilities")
4
4
  let { basicDatasource } = setup.structures
5
5
  let { checkBuilderEndpoint } = require("./utilities/TestFunctions")
6
6
  const pg = require("pg")
7
+ const { checkCacheForDynamicVariable } = require("../../../threads/utils")
7
8
 
8
9
  describe("/datasources", () => {
9
10
  let request = setup.getRequest()
@@ -31,6 +32,50 @@ describe("/datasources", () => {
31
32
  })
32
33
  })
33
34
 
35
+ describe("update", () => {
36
+ it("should update an existing datasource", async () => {
37
+ datasource.name = "Updated Test"
38
+ const res = await request
39
+ .put(`/api/datasources/${datasource._id}`)
40
+ .send(datasource)
41
+ .set(config.defaultHeaders())
42
+ .expect('Content-Type', /json/)
43
+ .expect(200)
44
+
45
+ expect(res.body.datasource.name).toEqual("Updated Test")
46
+ expect(res.body.errors).toBeUndefined()
47
+ })
48
+
49
+ describe("dynamic variables", () => {
50
+ async function preview(datasource, fields) {
51
+ return config.previewQuery(request, config, datasource, fields)
52
+ }
53
+
54
+ it("should invalidate changed or removed variables", async () => {
55
+ const { datasource, query } = await config.dynamicVariableDatasource()
56
+ // preview once to cache variables
57
+ await preview(datasource, { path: "www.test.com", queryString: "test={{ variable3 }}" })
58
+ // check variables in cache
59
+ let contents = await checkCacheForDynamicVariable(query._id, "variable3")
60
+ expect(contents.rows.length).toEqual(1)
61
+
62
+ // update the datasource to remove the variables
63
+ datasource.config.dynamicVariables = []
64
+ const res = await request
65
+ .put(`/api/datasources/${datasource._id}`)
66
+ .send(datasource)
67
+ .set(config.defaultHeaders())
68
+ .expect('Content-Type', /json/)
69
+ .expect(200)
70
+ expect(res.body.errors).toBeUndefined()
71
+
72
+ // check variables no longer in cache
73
+ contents = await checkCacheForDynamicVariable(query._id, "variable3")
74
+ expect(contents).toBe(null)
75
+ })
76
+ })
77
+ })
78
+
34
79
  describe("fetch", () => {
35
80
  it("returns all the datasources from the server", async () => {
36
81
  const res = await request
@@ -1,5 +1,6 @@
1
1
  // Mock out postgres for this
2
2
  jest.mock("pg")
3
+ jest.mock("node-fetch")
3
4
 
4
5
  // Mock isProdAppID to we can later mock the implementation and pretend we are
5
6
  // using prod app IDs
@@ -10,6 +11,7 @@ authDb.isProdAppID = mockIsProdAppID
10
11
 
11
12
  const setup = require("./utilities")
12
13
  const { checkBuilderEndpoint } = require("./utilities/TestFunctions")
14
+ const { checkCacheForDynamicVariable } = require("../../../threads/utils")
13
15
  const { basicQuery, basicDatasource } = setup.structures
14
16
 
15
17
  describe("/queries", () => {
@@ -226,4 +228,71 @@ describe("/queries", () => {
226
228
  .expect(400)
227
229
  })
228
230
  })
231
+
232
+ describe("variables", () => {
233
+
234
+ async function preview(datasource, fields) {
235
+ return config.previewQuery(request, config, datasource, fields)
236
+ }
237
+
238
+ it("should work with static variables", async () => {
239
+ const datasource = await config.restDatasource({
240
+ staticVariables: {
241
+ variable: "google",
242
+ variable2: "1",
243
+ },
244
+ })
245
+ const res = await preview(datasource, {
246
+ path: "www.{{ variable }}.com",
247
+ queryString: "test={{ variable2 }}",
248
+ })
249
+ // these responses come from the mock
250
+ expect(res.body.schemaFields).toEqual(["url", "opts", "value"])
251
+ expect(res.body.rows[0].url).toEqual("http://www.google.com?test=1")
252
+ })
253
+
254
+ it("should work with dynamic variables", async () => {
255
+ const { datasource } = await config.dynamicVariableDatasource()
256
+ const res = await preview(datasource, {
257
+ path: "www.google.com",
258
+ queryString: "test={{ variable3 }}",
259
+ })
260
+ expect(res.body.schemaFields).toEqual(["url", "opts", "value"])
261
+ expect(res.body.rows[0].url).toContain("doctype html")
262
+ })
263
+
264
+ it("check that it automatically retries on fail with cached dynamics", async () => {
265
+ const { datasource, query: base } = await config.dynamicVariableDatasource()
266
+ // preview once to cache
267
+ await preview(datasource, { path: "www.google.com", queryString: "test={{ variable3 }}" })
268
+ // check its in cache
269
+ const contents = await checkCacheForDynamicVariable(base._id, "variable3")
270
+ expect(contents.rows.length).toEqual(1)
271
+ const res = await preview(datasource, {
272
+ path: "www.failonce.com",
273
+ queryString: "test={{ variable3 }}",
274
+ })
275
+ expect(res.body.schemaFields).toEqual(["fails", "url", "opts"])
276
+ expect(res.body.rows[0].fails).toEqual(1)
277
+ })
278
+
279
+ it("deletes variables when linked query is deleted", async () => {
280
+ const { datasource, query: base } = await config.dynamicVariableDatasource()
281
+ // preview once to cache
282
+ await preview(datasource, { path: "www.google.com", queryString: "test={{ variable3 }}" })
283
+ // check its in cache
284
+ let contents = await checkCacheForDynamicVariable(base._id, "variable3")
285
+ expect(contents.rows.length).toEqual(1)
286
+
287
+ // delete the query
288
+ await request
289
+ .delete(`/api/queries/${base._id}/${base._rev}`)
290
+ .set(config.defaultHeaders())
291
+ .expect(200)
292
+
293
+ // check variables no longer in cache
294
+ contents = await checkCacheForDynamicVariable(base._id, "variable3")
295
+ expect(contents).toBe(null)
296
+ })
297
+ })
229
298
  })
@@ -39,5 +39,15 @@ router
39
39
  authorized(PermissionTypes.USER, PermissionLevels.WRITE),
40
40
  controller.syncUser
41
41
  )
42
+ .post(
43
+ "/api/users/flags",
44
+ authorized(PermissionTypes.USER, PermissionLevels.WRITE),
45
+ controller.setFlag
46
+ )
47
+ .get(
48
+ "/api/users/flags",
49
+ authorized(PermissionTypes.USER, PermissionLevels.READ),
50
+ controller.getFlags
51
+ )
42
52
 
43
53
  module.exports = router
@@ -35,6 +35,11 @@ exports.definition = {
35
35
  type: "object",
36
36
  description: "The response from the datasource execution",
37
37
  },
38
+ info: {
39
+ type: "object",
40
+ description:
41
+ "Some query types may return extra data, like headers from a REST query",
42
+ },
38
43
  success: {
39
44
  type: "boolean",
40
45
  description: "Whether the action was successful",
@@ -68,13 +73,16 @@ exports.run = async function ({ inputs, appId, emitter }) {
68
73
 
69
74
  try {
70
75
  await queryController.execute(ctx)
76
+ const { data, ...rest } = ctx.body
71
77
  return {
72
- response: ctx.body,
78
+ response: data,
79
+ info: rest,
73
80
  success: true,
74
81
  }
75
82
  } catch (err) {
76
83
  return {
77
84
  success: false,
85
+ info: {},
78
86
  response: automationUtils.getError(err),
79
87
  }
80
88
  }
@@ -13,12 +13,11 @@ const RequestType = {
13
13
  const BODY_REQUESTS = [RequestType.POST, RequestType.PUT, RequestType.PATCH]
14
14
 
15
15
  /**
16
- * Note, there is some functionality in this that is not currently exposed as it
17
- * is complex and maybe better to be opinionated here.
18
- * GET/DELETE requests cannot handle body elements so they will not be sent if configured.
16
+ * NOTE: this functionality is deprecated - it no longer should be used.
19
17
  */
20
18
 
21
19
  exports.definition = {
20
+ deprecated: true,
22
21
  name: "Outgoing webhook",
23
22
  tagline: "Send a {{inputs.requestMethod}} request",
24
23
  icon: "Send",
@@ -7,6 +7,7 @@ const newid = require("../db/newid")
7
7
  const { updateEntityMetadata } = require("../utilities")
8
8
  const { MetadataTypes } = require("../constants")
9
9
  const { getDeployedAppID } = require("@budibase/auth/db")
10
+ const { cloneDeep } = require("lodash/fp")
10
11
 
11
12
  const WH_STEP_ID = definitions.WEBHOOK.stepId
12
13
  const CRON_STEP_ID = definitions.CRON.stepId
@@ -42,6 +43,16 @@ exports.updateTestHistory = async (appId, automation, history) => {
42
43
  )
43
44
  }
44
45
 
46
+ exports.removeDeprecated = definitions => {
47
+ const base = cloneDeep(definitions)
48
+ for (let key of Object.keys(base)) {
49
+ if (base[key].deprecated) {
50
+ delete base[key]
51
+ }
52
+ }
53
+ return base
54
+ }
55
+
45
56
  // end the repetition and the job itself
46
57
  exports.disableAllCrons = async appId => {
47
58
  const promises = []
package/src/db/utils.js CHANGED
@@ -40,6 +40,7 @@ const DocumentTypes = {
40
40
  DEPLOYMENTS: "deployments",
41
41
  METADATA: "metadata",
42
42
  MEM_VIEW: "view",
43
+ USER_FLAG: "flag",
43
44
  }
44
45
 
45
46
  const ViewNames = {
@@ -339,6 +340,14 @@ exports.getQueryParams = (datasourceId = null, otherProps = {}) => {
339
340
  )
340
341
  }
341
342
 
343
+ /**
344
+ * Generates a new flag document ID.
345
+ * @returns {string} The ID of the flag document that was generated.
346
+ */
347
+ exports.generateUserFlagID = userId => {
348
+ return `${DocumentTypes.USER_FLAG}${SEPARATOR}${userId}`
349
+ }
350
+
342
351
  exports.generateMetadataID = (type, entityId) => {
343
352
  return `${DocumentTypes.METADATA}${SEPARATOR}${type}${SEPARATOR}${entityId}`
344
353
  }
@@ -1,6 +1,6 @@
1
- import { SourceNames } from "./datasource"
1
+ export { Query, Datasource } from "./datasource"
2
2
 
3
- interface Base {
3
+ export interface Base {
4
4
  _id?: string
5
5
  _rev?: string
6
6
  }
@@ -93,17 +93,3 @@ export interface Automation extends Base {
93
93
  trigger?: AutomationStep
94
94
  }
95
95
  }
96
-
97
- export interface Datasource extends Base {
98
- type: string
99
- name: string
100
- source: SourceNames
101
- // the config is defined by the schema
102
- config: {
103
- [key: string]: string | number | boolean
104
- }
105
- plus: boolean
106
- entities?: {
107
- [key: string]: Table
108
- }
109
- }
@@ -1,4 +1,4 @@
1
- import { Row, Table } from "./common"
1
+ import { Row, Table, Base } from "./common"
2
2
 
3
3
  export enum Operation {
4
4
  CREATE = "CREATE",
@@ -181,3 +181,85 @@ export interface SqlQuery {
181
181
  export interface QueryOptions {
182
182
  disableReturning?: boolean
183
183
  }
184
+
185
+ export interface Datasource extends Base {
186
+ type: string
187
+ name: string
188
+ source: SourceNames
189
+ // the config is defined by the schema
190
+ config: {
191
+ [key: string]: string | number | boolean
192
+ }
193
+ plus: boolean
194
+ entities?: {
195
+ [key: string]: Table
196
+ }
197
+ }
198
+
199
+ export enum AuthType {
200
+ BASIC = "basic",
201
+ BEARER = "bearer",
202
+ }
203
+
204
+ interface AuthConfig {
205
+ _id: string
206
+ name: string
207
+ type: AuthType
208
+ config: BasicAuthConfig | BearerAuthConfig
209
+ }
210
+
211
+ export interface BasicAuthConfig {
212
+ username: string
213
+ password: string
214
+ }
215
+
216
+ export interface BearerAuthConfig {
217
+ token: string
218
+ }
219
+
220
+ export interface QueryParameter {
221
+ name: string
222
+ default: string
223
+ }
224
+
225
+ export interface RestQueryFields {
226
+ path: string
227
+ queryString?: string
228
+ headers: { [key: string]: any }
229
+ disabledHeaders: { [key: string]: any }
230
+ requestBody: any
231
+ bodyType: string
232
+ json: object
233
+ method: string
234
+ authConfigId: string
235
+ }
236
+
237
+ export interface RestConfig {
238
+ url: string
239
+ defaultHeaders: {
240
+ [key: string]: any
241
+ }
242
+ authConfigs: AuthConfig[]
243
+ staticVariables: {
244
+ [key: string]: string
245
+ }
246
+ dynamicVariables: [
247
+ {
248
+ name: string
249
+ queryId: string
250
+ value: string
251
+ }
252
+ ]
253
+ }
254
+
255
+ export interface Query {
256
+ _id?: string
257
+ datasourceId: string
258
+ name: string
259
+ parameters: QueryParameter[]
260
+ fields: RestQueryFields | any
261
+ transformer: string | null
262
+ schema: any
263
+ readable: boolean
264
+ queryVerb: string
265
+ }
@@ -1,6 +1,6 @@
1
1
  export interface IntegrationBase {
2
- create?(query: any): Promise<any[]>
3
- read?(query: any): Promise<any[]>
4
- update?(query: any): Promise<any[]>
5
- delete?(query: any): Promise<any[]>
2
+ create?(query: any): Promise<any[] | any>
3
+ read?(query: any): Promise<any[] | any>
4
+ update?(query: any): Promise<any[] | any>
5
+ delete?(query: any): Promise<any[] | any>
6
6
  }
@@ -36,7 +36,7 @@ function generateSchema(
36
36
  case FieldTypes.STRING:
37
37
  case FieldTypes.OPTIONS:
38
38
  case FieldTypes.LONGFORM:
39
- schema.string(key)
39
+ schema.text(key)
40
40
  break
41
41
  case FieldTypes.NUMBER:
42
42
  // if meta is specified then this is a junction table entry
@@ -450,7 +450,7 @@ module OracleModule {
450
450
  })
451
451
  return lastRow.rows
452
452
  } else {
453
- return [{ [ operation.toLowerCase() ]: true }]
453
+ return [{ [operation.toLowerCase()]: true }]
454
454
  }
455
455
  }
456
456
  }