@budibase/server 1.0.17 → 1.0.19-alpha.2

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 (227) hide show
  1. package/__mocks__/node-fetch.ts +3 -0
  2. package/builder/assets/bb-spaceship.8f6e81e1.svg +227 -0
  3. package/builder/assets/{index.4fb3f887.css → index.2fc6da87.css} +1 -1
  4. package/builder/assets/index.86b28e1c.js +1320 -0
  5. package/builder/assets/{vendor.470042a4.js → vendor.a9288856.js} +1 -1
  6. package/builder/index.html +3 -3
  7. package/coverage/clover.xml +440 -372
  8. package/coverage/coverage-final.json +17 -16
  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 +1 -1
  12. package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
  13. package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
  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 +1 -1
  17. package/coverage/lcov-report/api/controllers/datasource.js.html +14 -14
  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 +23 -38
  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} +159 -27
  27. package/coverage/lcov-report/api/controllers/query/validation.js.html +203 -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 +1 -1
  32. package/coverage/lcov-report/api/controllers/row/index.js.html +1 -1
  33. package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
  34. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
  35. package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
  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 +1 -1
  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 +11 -98
  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 +1 -1
  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 +1 -1
  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 +1 -1
  97. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  98. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
  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 +1 -1
  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 +91 -64
  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 +67 -52
  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 +2 -2
  139. package/coverage/lcov-report/middleware/builder.js.html +1 -1
  140. package/coverage/lcov-report/middleware/currentapp.js.html +1 -1
  141. package/coverage/lcov-report/middleware/index.html +1 -1
  142. package/coverage/lcov-report/middleware/joi-validator.js.html +3 -3
  143. package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
  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 +1 -1
  147. package/coverage/lcov-report/threads/automation.js.html +1 -1
  148. package/coverage/lcov-report/threads/index.html +20 -20
  149. package/coverage/lcov-report/threads/index.js.html +1 -1
  150. package/coverage/lcov-report/threads/query.js.html +63 -12
  151. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  152. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  153. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  154. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  155. package/coverage/lcov-report/utilities/global.js.html +1 -1
  156. package/coverage/lcov-report/utilities/index.html +19 -19
  157. package/coverage/lcov-report/utilities/index.js.html +66 -33
  158. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +1 -1
  159. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  160. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  161. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  162. package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
  163. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +1 -1
  164. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
  165. package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
  166. package/coverage/lcov-report/utilities/security.js.html +2 -2
  167. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  168. package/coverage/lcov-report/utilities/users.js.html +1 -1
  169. package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
  170. package/coverage/lcov.info +688 -583
  171. package/dist/api/controllers/query/import/index.js +79 -0
  172. package/dist/api/controllers/query/import/sources/base/index.js +63 -0
  173. package/dist/api/controllers/query/import/sources/base/openapi.js +42 -0
  174. package/dist/api/controllers/query/import/sources/curl.js +90 -0
  175. package/dist/api/controllers/query/import/sources/openapi2.js +139 -0
  176. package/dist/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json +253 -0
  177. package/dist/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json +1054 -0
  178. package/dist/api/controllers/{query.js → query/index.js} +42 -6
  179. package/dist/api/controllers/query/validation.js +37 -0
  180. package/dist/api/controllers/user.js +37 -1
  181. package/dist/api/controllers/webhook.js +4 -0
  182. package/dist/api/routes/query.js +2 -32
  183. package/dist/api/routes/user.js +3 -1
  184. package/dist/db/utils.js +8 -0
  185. package/dist/integrations/rest.js +110 -113
  186. package/dist/package.json +8 -4
  187. package/dist/threads/query.js +14 -2
  188. package/dist/tsconfig.tsbuildinfo +1 -1
  189. package/dist/utilities/index.js +10 -0
  190. package/package.json +9 -5
  191. package/src/api/controllers/query/import/index.ts +85 -0
  192. package/src/api/controllers/query/import/sources/base/index.ts +85 -0
  193. package/src/api/controllers/query/import/sources/base/openapi.ts +24 -0
  194. package/src/api/controllers/query/import/sources/curl.ts +94 -0
  195. package/src/api/controllers/query/import/sources/openapi2.ts +159 -0
  196. package/src/api/controllers/query/import/sources/tests/curl/curl.spec.js +104 -0
  197. package/src/api/controllers/query/import/sources/tests/curl/data/delete.txt +1 -0
  198. package/src/api/controllers/query/import/sources/tests/curl/data/empty-body.txt +2 -0
  199. package/src/api/controllers/query/import/sources/tests/curl/data/get.txt +1 -0
  200. package/src/api/controllers/query/import/sources/tests/curl/data/headers.txt +3 -0
  201. package/src/api/controllers/query/import/sources/tests/curl/data/patch.txt +2 -0
  202. package/src/api/controllers/query/import/sources/tests/curl/data/path.txt +1 -0
  203. package/src/api/controllers/query/import/sources/tests/curl/data/post.txt +2 -0
  204. package/src/api/controllers/query/import/sources/tests/curl/data/put.txt +2 -0
  205. package/src/api/controllers/query/import/sources/tests/curl/data/query.txt +1 -0
  206. package/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json +253 -0
  207. package/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.yaml +160 -0
  208. package/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json +1054 -0
  209. package/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.yaml +711 -0
  210. package/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js +239 -0
  211. package/src/api/controllers/query/import/tests/index.spec.js +115 -0
  212. package/src/api/controllers/{query.js → query/index.js} +50 -6
  213. package/src/api/controllers/query/validation.js +41 -0
  214. package/src/api/controllers/user.js +33 -0
  215. package/src/api/controllers/webhook.js +4 -0
  216. package/src/api/routes/query.js +5 -34
  217. package/src/api/routes/user.js +10 -0
  218. package/src/db/utils.js +9 -0
  219. package/src/definitions/common.ts +2 -16
  220. package/src/definitions/datasource.ts +50 -1
  221. package/src/integrations/base/IntegrationBase.ts +4 -4
  222. package/src/integrations/oracle.ts +1 -1
  223. package/src/integrations/rest.ts +111 -137
  224. package/src/integrations/tests/rest.spec.js +16 -7
  225. package/src/threads/query.js +19 -2
  226. package/src/utilities/index.js +11 -0
  227. package/builder/assets/index.3ba0b30e.js +0 -1316
@@ -9,10 +9,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  const { processString } = require("@budibase/string-templates");
12
- const CouchDB = require("../../db");
13
- const { generateQueryID, getQueryParams, isProdAppID, } = require("../../db/utils");
14
- const { BaseQueryVerbs } = require("../../constants");
15
- const { Thread, ThreadType } = require("../../threads");
12
+ const CouchDB = require("../../../db");
13
+ const { generateQueryID, getQueryParams, isProdAppID, } = require("../../../db/utils");
14
+ const { BaseQueryVerbs } = require("../../../constants");
15
+ const { Thread, ThreadType } = require("../../../threads");
16
+ const { save: saveDatasource } = require("../datasource");
17
+ const { RestImporter } = require("./import");
16
18
  const Runner = new Thread(ThreadType.QUERY, { timeoutMs: 10000 });
17
19
  // simple function to append "readable" to all read queries
18
20
  function enrichQueries(input) {
@@ -34,6 +36,38 @@ exports.fetch = function (ctx) {
34
36
  ctx.body = enrichQueries(body.rows.map(row => row.doc));
35
37
  });
36
38
  };
39
+ exports.import = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
40
+ const body = ctx.request.body;
41
+ const data = body.data;
42
+ const importer = new RestImporter(data);
43
+ yield importer.init();
44
+ let datasourceId;
45
+ if (!body.datasourceId) {
46
+ // construct new datasource
47
+ const info = yield importer.getInfo();
48
+ let datasource = {
49
+ type: "datasource",
50
+ source: "REST",
51
+ config: {
52
+ url: info.url,
53
+ defaultHeaders: [],
54
+ },
55
+ name: info.name,
56
+ };
57
+ // save the datasource
58
+ const datasourceCtx = Object.assign({}, ctx);
59
+ datasourceCtx.request.body.datasource = datasource;
60
+ yield saveDatasource(datasourceCtx);
61
+ datasourceId = datasourceCtx.body.datasource._id;
62
+ }
63
+ else {
64
+ // use existing datasource
65
+ datasourceId = body.datasourceId;
66
+ }
67
+ const importResult = yield importer.importQueries(ctx.appId, datasourceId);
68
+ ctx.body = Object.assign(Object.assign({}, importResult), { datasourceId });
69
+ ctx.status = 200;
70
+ });
37
71
  exports.save = function (ctx) {
38
72
  return __awaiter(this, void 0, void 0, function* () {
39
73
  const db = new CouchDB(ctx.appId);
@@ -78,7 +112,7 @@ function enrichQueryFields(fields, parameters = {}) {
78
112
  enrichedQuery.requestBody);
79
113
  }
80
114
  catch (err) {
81
- throw { message: `JSON Invalid - error: ${err}` };
115
+ // no json found, ignore
82
116
  }
83
117
  delete enrichedQuery.customData;
84
118
  }
@@ -104,7 +138,7 @@ exports.preview = function (ctx) {
104
138
  const { fields, parameters, queryVerb, transformer } = ctx.request.body;
105
139
  const enrichedQuery = yield enrichQueryFields(fields, parameters);
106
140
  try {
107
- const { rows, keys } = yield Runner.run({
141
+ const { rows, keys, info, extra } = yield Runner.run({
108
142
  datasource,
109
143
  queryVerb,
110
144
  query: enrichedQuery,
@@ -113,6 +147,8 @@ exports.preview = function (ctx) {
113
147
  ctx.body = {
114
148
  rows,
115
149
  schemaFields: [...new Set(keys)],
150
+ info,
151
+ extra,
116
152
  };
117
153
  }
118
154
  catch (err) {
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ const joiValidator = require("../../../middleware/joi-validator");
3
+ const Joi = require("joi");
4
+ exports.queryValidation = () => {
5
+ return Joi.object({
6
+ _id: Joi.string(),
7
+ _rev: Joi.string(),
8
+ name: Joi.string().required(),
9
+ fields: Joi.object().required(),
10
+ datasourceId: Joi.string().required(),
11
+ readable: Joi.boolean(),
12
+ parameters: Joi.array().items(Joi.object({
13
+ name: Joi.string(),
14
+ default: Joi.string().allow(""),
15
+ })),
16
+ queryVerb: Joi.string().allow().required(),
17
+ extra: Joi.object().optional(),
18
+ schema: Joi.object({}).required().unknown(true),
19
+ transformer: Joi.string().optional(),
20
+ flags: Joi.object().optional(),
21
+ });
22
+ };
23
+ exports.generateQueryValidation = () => {
24
+ // prettier-ignore
25
+ return joiValidator.body(exports.queryValidation());
26
+ };
27
+ exports.generateQueryPreviewValidation = () => {
28
+ // prettier-ignore
29
+ return joiValidator.body(Joi.object({
30
+ fields: Joi.object().required(),
31
+ queryVerb: Joi.string().allow().required(),
32
+ extra: Joi.object().optional(),
33
+ datasourceId: Joi.string().required(),
34
+ transformer: Joi.string().optional(),
35
+ parameters: Joi.object({}).required().unknown(true)
36
+ }));
37
+ };
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  const CouchDB = require("../../db");
12
- const { generateUserMetadataID, getUserMetadataParams, } = require("../../db/utils");
12
+ const { generateUserMetadataID, getUserMetadataParams, generateUserFlagID, } = require("../../db/utils");
13
13
  const { InternalTables } = require("../../db/utils");
14
14
  const { getGlobalUsers, getRawGlobalUser } = require("../../utilities/global");
15
15
  const { getFullUser } = require("../../utilities/users");
@@ -189,3 +189,39 @@ exports.findMetadata = function (ctx) {
189
189
  ctx.body = yield getFullUser(ctx, ctx.params.id);
190
190
  });
191
191
  };
192
+ exports.setFlag = function (ctx) {
193
+ return __awaiter(this, void 0, void 0, function* () {
194
+ const userId = ctx.user._id;
195
+ const { flag, value } = ctx.request.body;
196
+ if (!flag) {
197
+ ctx.throw(400, "Must supply a 'flag' field in request body.");
198
+ }
199
+ const flagDocId = generateUserFlagID(userId);
200
+ const db = new CouchDB(ctx.appId);
201
+ let doc;
202
+ try {
203
+ doc = yield db.get(flagDocId);
204
+ }
205
+ catch (err) {
206
+ doc = { _id: flagDocId };
207
+ }
208
+ doc[flag] = value || true;
209
+ yield db.put(doc);
210
+ ctx.body = { message: "Flag set successfully" };
211
+ });
212
+ };
213
+ exports.getFlags = function (ctx) {
214
+ return __awaiter(this, void 0, void 0, function* () {
215
+ const userId = ctx.user._id;
216
+ const docId = generateUserFlagID(userId);
217
+ const db = new CouchDB(ctx.appId);
218
+ let doc;
219
+ try {
220
+ doc = yield db.get(docId);
221
+ }
222
+ catch (err) {
223
+ doc = { _id: docId };
224
+ }
225
+ ctx.body = doc;
226
+ });
227
+ };
@@ -65,6 +65,10 @@ exports.buildSchema = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
65
65
  let automation = yield 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,
@@ -2,44 +2,14 @@
2
2
  const Router = require("@koa/router");
3
3
  const queryController = require("../controllers/query");
4
4
  const authorized = require("../../middleware/authorized");
5
- const Joi = require("joi");
6
5
  const { PermissionLevels, PermissionTypes, BUILDER, } = require("@budibase/auth/permissions");
7
- const joiValidator = require("../../middleware/joi-validator");
8
6
  const { bodyResource, bodySubResource, paramResource, } = require("../../middleware/resourceId");
7
+ const { generateQueryPreviewValidation, generateQueryValidation, } = require("../controllers/query/validation");
9
8
  const router = Router();
10
- function generateQueryValidation() {
11
- // prettier-ignore
12
- return joiValidator.body(Joi.object({
13
- _id: Joi.string(),
14
- _rev: Joi.string(),
15
- name: Joi.string().required(),
16
- fields: Joi.object().required(),
17
- datasourceId: Joi.string().required(),
18
- readable: Joi.boolean(),
19
- parameters: Joi.array().items(Joi.object({
20
- name: Joi.string(),
21
- default: Joi.string().allow(""),
22
- })),
23
- queryVerb: Joi.string().allow().required(),
24
- extra: Joi.object().optional(),
25
- schema: Joi.object({}).required().unknown(true),
26
- transformer: Joi.string().optional(),
27
- }));
28
- }
29
- function generateQueryPreviewValidation() {
30
- // prettier-ignore
31
- return joiValidator.body(Joi.object({
32
- fields: Joi.object().required(),
33
- queryVerb: Joi.string().allow().required(),
34
- extra: Joi.object().optional(),
35
- datasourceId: Joi.string().required(),
36
- transformer: Joi.string().optional(),
37
- parameters: Joi.object({}).required().unknown(true)
38
- }));
39
- }
40
9
  router
41
10
  .get("/api/queries", authorized(BUILDER), queryController.fetch)
42
11
  .post("/api/queries", bodySubResource("datasourceId", "_id"), authorized(BUILDER), generateQueryValidation(), queryController.save)
12
+ .post("/api/queries/import", authorized(BUILDER), queryController.import)
43
13
  .post("/api/queries/preview", bodyResource("datasourceId"), authorized(BUILDER), generateQueryPreviewValidation(), queryController.preview)
44
14
  .get("/api/queries/:queryId", paramResource("queryId"), authorized(PermissionTypes.QUERY, PermissionLevels.READ), queryController.find)
45
15
  .post("/api/queries/:queryId", paramResource("queryId"), authorized(PermissionTypes.QUERY, PermissionLevels.WRITE), queryController.execute)
@@ -10,5 +10,7 @@ router
10
10
  .put("/api/users/metadata", authorized(PermissionTypes.USER, PermissionLevels.WRITE), controller.updateMetadata)
11
11
  .post("/api/users/metadata/self", authorized(PermissionTypes.USER, PermissionLevels.WRITE), controller.updateSelfMetadata)
12
12
  .delete("/api/users/metadata/:id", authorized(PermissionTypes.USER, PermissionLevels.WRITE), controller.destroyMetadata)
13
- .post("/api/users/metadata/sync/:id", authorized(PermissionTypes.USER, PermissionLevels.WRITE), controller.syncUser);
13
+ .post("/api/users/metadata/sync/:id", authorized(PermissionTypes.USER, PermissionLevels.WRITE), controller.syncUser)
14
+ .post("/api/users/flags", authorized(PermissionTypes.USER, PermissionLevels.WRITE), controller.setFlag)
15
+ .get("/api/users/flags", authorized(PermissionTypes.USER, PermissionLevels.READ), controller.getFlags);
14
16
  module.exports = router;
package/dist/db/utils.js CHANGED
@@ -28,6 +28,7 @@ const DocumentTypes = {
28
28
  DEPLOYMENTS: "deployments",
29
29
  METADATA: "metadata",
30
30
  MEM_VIEW: "view",
31
+ USER_FLAG: "flag",
31
32
  };
32
33
  const ViewNames = {
33
34
  LINK: "by_link",
@@ -271,6 +272,13 @@ exports.getQueryParams = (datasourceId = null, otherProps = {}) => {
271
272
  }
272
273
  return getDocParams(DocumentTypes.QUERY, `${datasourceId}${SEPARATOR}`, otherProps);
273
274
  };
275
+ /**
276
+ * Generates a new flag document ID.
277
+ * @returns {string} The ID of the flag document that was generated.
278
+ */
279
+ exports.generateUserFlagID = userId => {
280
+ return `${DocumentTypes.USER_FLAG}${SEPARATOR}${userId}`;
281
+ };
274
282
  exports.generateMetadataID = (type, entityId) => {
275
283
  return `${DocumentTypes.METADATA}${SEPARATOR}${type}${SEPARATOR}${entityId}`;
276
284
  };
@@ -10,18 +10,50 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const datasource_1 = require("../definitions/datasource");
13
+ const BodyTypes = {
14
+ NONE: "none",
15
+ FORM_DATA: "form",
16
+ ENCODED: "encoded",
17
+ JSON: "json",
18
+ TEXT: "text",
19
+ };
20
+ const coreFields = {
21
+ path: {
22
+ type: datasource_1.DatasourceFieldTypes.STRING,
23
+ display: "URL",
24
+ },
25
+ queryString: {
26
+ type: datasource_1.DatasourceFieldTypes.STRING,
27
+ },
28
+ headers: {
29
+ type: datasource_1.DatasourceFieldTypes.OBJECT,
30
+ },
31
+ enabledHeaders: {
32
+ type: datasource_1.DatasourceFieldTypes.OBJECT,
33
+ },
34
+ requestBody: {
35
+ type: datasource_1.DatasourceFieldTypes.JSON,
36
+ },
37
+ bodyType: {
38
+ type: datasource_1.DatasourceFieldTypes.STRING,
39
+ enum: Object.values(BodyTypes),
40
+ },
41
+ };
13
42
  var RestModule;
14
43
  (function (RestModule) {
15
44
  const fetch = require("node-fetch");
45
+ const { formatBytes } = require("../utilities");
46
+ const { performance } = require("perf_hooks");
16
47
  const SCHEMA = {
17
48
  docs: "https://github.com/node-fetch/node-fetch",
18
- description: "Representational state transfer (REST) is a de-facto standard for a software architecture for interactive applications that typically use multiple Web services. ",
49
+ description: "With the REST API datasource, you can connect, query and pull data from multiple REST APIs. You can then use the retrieved data to build apps.",
19
50
  friendlyName: "REST API",
20
51
  datasource: {
21
52
  url: {
22
53
  type: datasource_1.DatasourceFieldTypes.STRING,
23
- default: "localhost",
24
- required: true,
54
+ default: "",
55
+ required: false,
56
+ deprecated: true,
25
57
  },
26
58
  defaultHeaders: {
27
59
  type: datasource_1.DatasourceFieldTypes.OBJECT,
@@ -34,169 +66,134 @@ var RestModule;
34
66
  readable: true,
35
67
  displayName: "POST",
36
68
  type: datasource_1.QueryTypes.FIELDS,
37
- urlDisplay: true,
38
- fields: {
39
- path: {
40
- type: datasource_1.DatasourceFieldTypes.STRING,
41
- },
42
- queryString: {
43
- type: datasource_1.DatasourceFieldTypes.STRING,
44
- },
45
- headers: {
46
- type: datasource_1.DatasourceFieldTypes.OBJECT,
47
- },
48
- requestBody: {
49
- type: datasource_1.DatasourceFieldTypes.JSON,
50
- },
51
- },
69
+ fields: coreFields,
52
70
  },
53
71
  read: {
54
72
  displayName: "GET",
55
73
  readable: true,
56
74
  type: datasource_1.QueryTypes.FIELDS,
57
- urlDisplay: true,
58
- fields: {
59
- path: {
60
- type: datasource_1.DatasourceFieldTypes.STRING,
61
- },
62
- queryString: {
63
- type: datasource_1.DatasourceFieldTypes.STRING,
64
- },
65
- headers: {
66
- type: datasource_1.DatasourceFieldTypes.OBJECT,
67
- },
68
- },
75
+ fields: coreFields,
69
76
  },
70
77
  update: {
71
78
  displayName: "PUT",
72
79
  readable: true,
73
80
  type: datasource_1.QueryTypes.FIELDS,
74
- urlDisplay: true,
75
- fields: {
76
- path: {
77
- type: datasource_1.DatasourceFieldTypes.STRING,
78
- },
79
- queryString: {
80
- type: datasource_1.DatasourceFieldTypes.STRING,
81
- },
82
- headers: {
83
- type: datasource_1.DatasourceFieldTypes.OBJECT,
84
- },
85
- requestBody: {
86
- type: datasource_1.DatasourceFieldTypes.JSON,
87
- },
88
- },
81
+ fields: coreFields,
89
82
  },
90
83
  patch: {
91
84
  displayName: "PATCH",
92
85
  readable: true,
93
86
  type: datasource_1.QueryTypes.FIELDS,
94
- urlDisplay: true,
95
- fields: {
96
- path: {
97
- type: datasource_1.DatasourceFieldTypes.STRING,
98
- },
99
- queryString: {
100
- type: datasource_1.DatasourceFieldTypes.STRING,
101
- },
102
- headers: {
103
- type: datasource_1.DatasourceFieldTypes.OBJECT,
104
- },
105
- requestBody: {
106
- type: datasource_1.DatasourceFieldTypes.JSON,
107
- },
108
- },
87
+ fields: coreFields,
109
88
  },
110
89
  delete: {
111
90
  displayName: "DELETE",
112
91
  type: datasource_1.QueryTypes.FIELDS,
113
- urlDisplay: true,
114
- fields: {
115
- path: {
116
- type: datasource_1.DatasourceFieldTypes.STRING,
117
- },
118
- queryString: {
119
- type: datasource_1.DatasourceFieldTypes.STRING,
120
- },
121
- headers: {
122
- type: datasource_1.DatasourceFieldTypes.OBJECT,
123
- },
124
- requestBody: {
125
- type: datasource_1.DatasourceFieldTypes.JSON,
126
- },
127
- },
92
+ fields: coreFields,
128
93
  },
129
94
  },
130
95
  };
131
96
  class RestIntegration {
132
97
  constructor(config) {
133
98
  this.headers = {};
99
+ this.startTimeMs = performance.now();
134
100
  this.config = config;
135
101
  }
136
102
  parseResponse(response) {
137
103
  return __awaiter(this, void 0, void 0, function* () {
104
+ let data, raw, headers;
138
105
  const contentType = response.headers.get("content-type");
139
106
  if (contentType && contentType.indexOf("application/json") !== -1) {
140
- return yield response.json();
107
+ data = yield response.json();
108
+ raw = JSON.stringify(data);
141
109
  }
142
110
  else {
143
- return yield response.text();
111
+ data = yield response.text();
112
+ raw = data;
144
113
  }
114
+ const size = formatBytes(response.headers.get("content-length") || Buffer.byteLength(raw, "utf8"));
115
+ const time = `${Math.round(performance.now() - this.startTimeMs)}ms`;
116
+ headers = response.headers.raw();
117
+ for (let [key, value] of Object.entries(headers)) {
118
+ headers[key] = Array.isArray(value) ? value[0] : value;
119
+ }
120
+ return {
121
+ data,
122
+ info: {
123
+ code: response.status,
124
+ size,
125
+ time,
126
+ },
127
+ extra: {
128
+ raw,
129
+ headers,
130
+ },
131
+ };
145
132
  });
146
133
  }
147
134
  getUrl(path, queryString) {
148
- return `${this.config.url}/${path}?${queryString}`;
135
+ const main = `${path}?${queryString}`;
136
+ let complete = main;
137
+ if (this.config.url && !main.startsWith(this.config.url)) {
138
+ complete = !this.config.url ? main : `${this.config.url}/${main}`;
139
+ }
140
+ if (!complete.startsWith("http")) {
141
+ complete = `http://${complete}`;
142
+ }
143
+ return complete;
149
144
  }
150
- create({ path = "", queryString = "", headers = {}, json = {} }) {
145
+ _req(query) {
151
146
  return __awaiter(this, void 0, void 0, function* () {
147
+ const { path = "", queryString = "", headers = {}, method = "GET", disabledHeaders, bodyType, requestBody } = query;
152
148
  this.headers = Object.assign(Object.assign({}, this.config.defaultHeaders), headers);
153
- const response = yield fetch(this.getUrl(path, queryString), {
154
- method: "POST",
155
- headers: this.headers,
156
- body: JSON.stringify(json),
157
- });
149
+ if (disabledHeaders) {
150
+ for (let headerKey of Object.keys(this.headers)) {
151
+ if (disabledHeaders[headerKey]) {
152
+ delete this.headers[headerKey];
153
+ }
154
+ }
155
+ }
156
+ let json;
157
+ if (bodyType === BodyTypes.JSON && requestBody) {
158
+ try {
159
+ json = JSON.parse(requestBody);
160
+ }
161
+ catch (err) {
162
+ throw "Invalid JSON for request body";
163
+ }
164
+ }
165
+ const input = { method, headers: this.headers };
166
+ if (json && typeof json === "object" && Object.keys(json).length > 0) {
167
+ input.body = JSON.stringify(json);
168
+ }
169
+ this.startTimeMs = performance.now();
170
+ const response = yield fetch(this.getUrl(path, queryString), input);
158
171
  return yield this.parseResponse(response);
159
172
  });
160
173
  }
161
- read({ path = "", queryString = "", headers = {} }) {
174
+ create(opts) {
162
175
  return __awaiter(this, void 0, void 0, function* () {
163
- this.headers = Object.assign(Object.assign({}, this.config.defaultHeaders), headers);
164
- const response = yield fetch(this.getUrl(path, queryString), {
165
- headers: this.headers,
166
- });
167
- return yield this.parseResponse(response);
176
+ return this._req(Object.assign(Object.assign({}, opts), { method: "POST" }));
168
177
  });
169
178
  }
170
- update({ path = "", queryString = "", headers = {}, json = {} }) {
179
+ read(opts) {
171
180
  return __awaiter(this, void 0, void 0, function* () {
172
- this.headers = Object.assign(Object.assign({}, this.config.defaultHeaders), headers);
173
- const response = yield fetch(this.getUrl(path, queryString), {
174
- method: "PUT",
175
- headers: this.headers,
176
- body: JSON.stringify(json),
177
- });
178
- return yield this.parseResponse(response);
181
+ return this._req(Object.assign(Object.assign({}, opts), { method: "GET" }));
179
182
  });
180
183
  }
181
- patch({ path = "", queryString = "", headers = {}, json = {} }) {
184
+ update(opts) {
182
185
  return __awaiter(this, void 0, void 0, function* () {
183
- this.headers = Object.assign(Object.assign({}, this.config.defaultHeaders), headers);
184
- const response = yield fetch(this.getUrl(path, queryString), {
185
- method: "PATCH",
186
- headers: this.headers,
187
- body: JSON.stringify(json),
188
- });
189
- return yield this.parseResponse(response);
186
+ return this._req(Object.assign(Object.assign({}, opts), { method: "PUT" }));
190
187
  });
191
188
  }
192
- delete({ path = "", queryString = "", headers = {} }) {
189
+ patch(opts) {
193
190
  return __awaiter(this, void 0, void 0, function* () {
194
- this.headers = Object.assign(Object.assign({}, this.config.defaultHeaders), headers);
195
- const response = yield fetch(this.getUrl(path, queryString), {
196
- method: "DELETE",
197
- headers: this.headers,
198
- });
199
- return yield this.parseResponse(response);
191
+ return this._req(Object.assign(Object.assign({}, opts), { method: "PATCH" }));
192
+ });
193
+ }
194
+ delete(opts) {
195
+ return __awaiter(this, void 0, void 0, function* () {
196
+ return this._req(Object.assign(Object.assign({}, opts), { method: "DELETE" }));
200
197
  });
201
198
  }
202
199
  }
package/dist/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@budibase/server",
3
3
  "email": "hi@budibase.com",
4
- "version": "1.0.16",
4
+ "version": "1.0.19-alpha.1",
5
5
  "description": "Budibase Web Server",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -69,9 +69,10 @@
69
69
  "author": "Budibase",
70
70
  "license": "GPL-3.0",
71
71
  "dependencies": {
72
- "@budibase/auth": "^1.0.16",
73
- "@budibase/client": "^1.0.16",
74
- "@budibase/string-templates": "^1.0.16",
72
+ "@apidevtools/swagger-parser": "^10.0.3",
73
+ "@budibase/auth": "^1.0.19-alpha.1",
74
+ "@budibase/client": "^1.0.19-alpha.1",
75
+ "@budibase/string-templates": "^1.0.19-alpha.1",
75
76
  "@bull-board/api": "^3.7.0",
76
77
  "@bull-board/koa": "^3.7.0",
77
78
  "@elastic/elasticsearch": "7.10.0",
@@ -85,12 +86,14 @@
85
86
  "bull": "^3.22.4",
86
87
  "chmodr": "1.2.0",
87
88
  "csvtojson": "2.0.10",
89
+ "curlconverter": "^3.21.0",
88
90
  "dotenv": "8.2.0",
89
91
  "download": "8.0.0",
90
92
  "fix-path": "3.0.0",
91
93
  "fs-extra": "8.1.0",
92
94
  "jimp": "0.16.1",
93
95
  "joi": "17.2.1",
96
+ "js-yaml": "^4.1.0",
94
97
  "jsonschema": "1.4.0",
95
98
  "knex": "^0.95.6",
96
99
  "koa": "2.7.0",
@@ -146,6 +149,7 @@
146
149
  "eslint": "^6.8.0",
147
150
  "jest": "^27.0.5",
148
151
  "nodemon": "^2.0.4",
152
+ "openapi-types": "^9.3.1",
149
153
  "path-to-regexp": "^6.2.0",
150
154
  "prettier": "^2.3.1",
151
155
  "rimraf": "^3.0.2",
@@ -24,6 +24,12 @@ function formatResponse(resp) {
24
24
  }
25
25
  return resp;
26
26
  }
27
+ function hasExtraData(response) {
28
+ return (typeof response === "object" &&
29
+ !Array.isArray(response) &&
30
+ response.data != null &&
31
+ response.info != null);
32
+ }
27
33
  function runAndTransform(datasource, queryVerb, query, transformer) {
28
34
  return __awaiter(this, void 0, void 0, function* () {
29
35
  const Integration = integrations[datasource.source];
@@ -31,7 +37,13 @@ function runAndTransform(datasource, queryVerb, query, transformer) {
31
37
  throw "Integration type does not exist.";
32
38
  }
33
39
  const integration = new Integration(datasource.config);
34
- let rows = formatResponse(yield integration[queryVerb](query));
40
+ let output = formatResponse(yield integration[queryVerb](query));
41
+ let rows = output, info = undefined, extra = undefined;
42
+ if (hasExtraData(output)) {
43
+ rows = output.data;
44
+ info = output.info;
45
+ extra = output.extra;
46
+ }
35
47
  // transform as required
36
48
  if (transformer) {
37
49
  const runner = new ScriptRunner(transformer, { data: rows });
@@ -50,7 +62,7 @@ function runAndTransform(datasource, queryVerb, query, transformer) {
50
62
  if (integration.end) {
51
63
  integration.end();
52
64
  }
53
- return { rows, keys };
65
+ return { rows, keys, info, extra };
54
66
  });
55
67
  }
56
68
  module.exports = (input, callback) => {