@budibase/server 1.0.25 → 1.0.27-alpha.10

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 (255) 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.39751e34.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 +1263 -1036
  8. package/coverage/coverage-final.json +36 -35
  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 +54 -54
  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 +62 -62
  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 +17 -17
  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 +11 -11
  150. package/coverage/lcov-report/threads/query.js.html +394 -67
  151. package/coverage/lcov-report/threads/utils.js.html +356 -11
  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 +68 -35
  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 +1 -1
  171. package/coverage/lcov.info +2117 -1728
  172. package/dist/api/controllers/automation.js +7 -5
  173. package/dist/api/controllers/query/import/index.js +79 -0
  174. package/dist/api/controllers/query/import/sources/base/index.js +64 -0
  175. package/dist/api/controllers/query/import/sources/base/openapi.js +42 -0
  176. package/dist/api/controllers/query/import/sources/curl.js +96 -0
  177. package/dist/api/controllers/query/import/sources/openapi2.js +142 -0
  178. package/dist/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json +253 -0
  179. package/dist/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json +1054 -0
  180. package/dist/api/controllers/{query.js → query/index.js} +86 -52
  181. package/dist/api/controllers/query/validation.js +38 -0
  182. package/dist/api/controllers/row/internal.js +14 -6
  183. package/dist/api/controllers/row/internalSearch.js +2 -1
  184. package/dist/api/controllers/row/utils.js +13 -6
  185. package/dist/api/controllers/user.js +37 -1
  186. package/dist/api/controllers/webhook.js +4 -0
  187. package/dist/api/routes/query.js +5 -33
  188. package/dist/api/routes/user.js +3 -1
  189. package/dist/automations/steps/executeQuery.js +8 -1
  190. package/dist/automations/steps/outgoingWebhook.js +2 -3
  191. package/dist/automations/utils.js +10 -0
  192. package/dist/db/utils.js +8 -0
  193. package/dist/definitions/datasource.js +6 -1
  194. package/dist/integrations/base/sqlTable.js +1 -1
  195. package/dist/integrations/rest.js +207 -117
  196. package/dist/package.json +11 -4
  197. package/dist/tests/utilities/TestConfiguration.js +7 -0
  198. package/dist/threads/query.js +148 -40
  199. package/dist/threads/utils.js +105 -0
  200. package/dist/tsconfig.tsbuildinfo +1 -1
  201. package/dist/utilities/fileSystem/utilities.js +2 -1
  202. package/dist/utilities/index.js +10 -0
  203. package/dist/utilities/rowProcessor/index.js +76 -0
  204. package/package.json +12 -5
  205. package/src/api/controllers/automation.js +8 -4
  206. package/src/api/controllers/query/import/index.ts +85 -0
  207. package/src/api/controllers/query/import/sources/base/index.ts +87 -0
  208. package/src/api/controllers/query/import/sources/base/openapi.ts +24 -0
  209. package/src/api/controllers/query/import/sources/curl.ts +102 -0
  210. package/src/api/controllers/query/import/sources/openapi2.ts +163 -0
  211. package/src/api/controllers/query/import/sources/tests/curl/curl.spec.js +103 -0
  212. package/src/api/controllers/query/import/sources/tests/curl/data/delete.txt +1 -0
  213. package/src/api/controllers/query/import/sources/tests/curl/data/empty-body.txt +2 -0
  214. package/src/api/controllers/query/import/sources/tests/curl/data/get.txt +1 -0
  215. package/src/api/controllers/query/import/sources/tests/curl/data/headers.txt +3 -0
  216. package/src/api/controllers/query/import/sources/tests/curl/data/patch.txt +2 -0
  217. package/src/api/controllers/query/import/sources/tests/curl/data/path.txt +1 -0
  218. package/src/api/controllers/query/import/sources/tests/curl/data/post.txt +2 -0
  219. package/src/api/controllers/query/import/sources/tests/curl/data/put.txt +2 -0
  220. package/src/api/controllers/query/import/sources/tests/curl/data/query.txt +1 -0
  221. package/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json +253 -0
  222. package/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.yaml +160 -0
  223. package/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json +1054 -0
  224. package/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.yaml +711 -0
  225. package/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js +238 -0
  226. package/src/api/controllers/query/import/tests/index.spec.js +109 -0
  227. package/src/api/controllers/query/index.js +195 -0
  228. package/src/api/controllers/query/validation.js +42 -0
  229. package/src/api/controllers/row/internal.js +14 -5
  230. package/src/api/controllers/row/internalSearch.js +2 -1
  231. package/src/api/controllers/row/utils.js +11 -8
  232. package/src/api/controllers/user.js +33 -0
  233. package/src/api/controllers/webhook.js +4 -0
  234. package/src/api/routes/query.js +13 -35
  235. package/src/api/routes/tests/query.spec.js +88 -0
  236. package/src/api/routes/user.js +10 -0
  237. package/src/automations/steps/executeQuery.js +9 -1
  238. package/src/automations/steps/outgoingWebhook.js +2 -3
  239. package/src/automations/utils.js +11 -0
  240. package/src/db/utils.js +9 -0
  241. package/src/definitions/common.ts +2 -16
  242. package/src/definitions/datasource.ts +83 -1
  243. package/src/integrations/base/IntegrationBase.ts +4 -4
  244. package/src/integrations/base/sqlTable.ts +1 -1
  245. package/src/integrations/oracle.ts +1 -1
  246. package/src/integrations/rest.ts +230 -137
  247. package/src/integrations/tests/rest.spec.js +167 -19
  248. package/src/tests/utilities/TestConfiguration.js +10 -0
  249. package/src/threads/query.js +149 -40
  250. package/src/threads/utils.js +115 -0
  251. package/src/utilities/fileSystem/utilities.js +2 -0
  252. package/src/utilities/index.js +11 -0
  253. package/src/utilities/rowProcessor/index.js +75 -0
  254. package/builder/assets/index.f01106f0.js +0 -1316
  255. 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",
@@ -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,90 @@ describe("/queries", () => {
226
228
  .expect(400)
227
229
  })
228
230
  })
231
+
232
+ describe("test variables", () => {
233
+ async function restDatasource(cfg) {
234
+ return await config.createDatasource({
235
+ datasource: {
236
+ ...basicDatasource().datasource,
237
+ source: "REST",
238
+ config: cfg || {},
239
+ },
240
+ })
241
+ }
242
+
243
+ async function dynamicVariableDatasource() {
244
+ const datasource = await restDatasource()
245
+ const basedOnQuery = await config.createQuery({
246
+ ...basicQuery(datasource._id),
247
+ fields: {
248
+ path: "www.google.com",
249
+ },
250
+ })
251
+ await config.updateDatasource({
252
+ ...datasource,
253
+ config: {
254
+ dynamicVariables: [
255
+ { queryId: basedOnQuery._id, name: "variable3", value: "{{ data.0.[value] }}" }
256
+ ]
257
+ }
258
+ })
259
+ return { datasource, query: basedOnQuery }
260
+ }
261
+
262
+ async function preview(datasource, fields) {
263
+ return await request
264
+ .post(`/api/queries/preview`)
265
+ .send({
266
+ datasourceId: datasource._id,
267
+ parameters: {},
268
+ fields,
269
+ queryVerb: "read",
270
+ })
271
+ .set(config.defaultHeaders())
272
+ .expect("Content-Type", /json/)
273
+ .expect(200)
274
+ }
275
+
276
+ it("should work with static variables", async () => {
277
+ const datasource = await restDatasource({
278
+ staticVariables: {
279
+ variable: "google",
280
+ variable2: "1",
281
+ },
282
+ })
283
+ const res = await preview(datasource, {
284
+ path: "www.{{ variable }}.com",
285
+ queryString: "test={{ variable2 }}",
286
+ })
287
+ // these responses come from the mock
288
+ expect(res.body.schemaFields).toEqual(["url", "opts", "value"])
289
+ expect(res.body.rows[0].url).toEqual("http://www.google.com?test=1")
290
+ })
291
+
292
+ it("should work with dynamic variables", async () => {
293
+ const { datasource } = await dynamicVariableDatasource()
294
+ const res = await preview(datasource, {
295
+ path: "www.google.com",
296
+ queryString: "test={{ variable3 }}",
297
+ })
298
+ expect(res.body.schemaFields).toEqual(["url", "opts", "value"])
299
+ expect(res.body.rows[0].url).toContain("doctype html")
300
+ })
301
+
302
+ it("check that it automatically retries on fail with cached dynamics", async () => {
303
+ const { datasource, query: base } = await dynamicVariableDatasource()
304
+ // preview once to cache
305
+ await preview(datasource, { path: "www.google.com", queryString: "test={{ variable3 }}" })
306
+ // check its in cache
307
+ const contents = await checkCacheForDynamicVariable(base._id, "variable3")
308
+ expect(contents.rows.length).toEqual(1)
309
+ const res = await preview(datasource, {
310
+ path: "www.failonce.com",
311
+ queryString: "test={{ variable3 }}",
312
+ })
313
+ expect(res.body.schemaFields).toEqual(["fails", "url", "opts"])
314
+ expect(res.body.rows[0].fails).toEqual(1)
315
+ })
316
+ })
229
317
  })
@@ -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
  }