@budibase/server 1.0.18 → 1.0.19-alpha.3

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.540a5506.css} +1 -1
  4. package/builder/assets/{index.3587ba82.js → index.6de3403f.js} +236 -231
  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/definitions/datasource.js +6 -1
  186. package/dist/integrations/rest.js +136 -114
  187. package/dist/package.json +8 -4
  188. package/dist/threads/query.js +14 -2
  189. package/dist/tsconfig.tsbuildinfo +1 -1
  190. package/dist/utilities/index.js +10 -0
  191. package/package.json +9 -5
  192. package/src/api/controllers/query/import/index.ts +85 -0
  193. package/src/api/controllers/query/import/sources/base/index.ts +85 -0
  194. package/src/api/controllers/query/import/sources/base/openapi.ts +24 -0
  195. package/src/api/controllers/query/import/sources/curl.ts +94 -0
  196. package/src/api/controllers/query/import/sources/openapi2.ts +159 -0
  197. package/src/api/controllers/query/import/sources/tests/curl/curl.spec.js +104 -0
  198. package/src/api/controllers/query/import/sources/tests/curl/data/delete.txt +1 -0
  199. package/src/api/controllers/query/import/sources/tests/curl/data/empty-body.txt +2 -0
  200. package/src/api/controllers/query/import/sources/tests/curl/data/get.txt +1 -0
  201. package/src/api/controllers/query/import/sources/tests/curl/data/headers.txt +3 -0
  202. package/src/api/controllers/query/import/sources/tests/curl/data/patch.txt +2 -0
  203. package/src/api/controllers/query/import/sources/tests/curl/data/path.txt +1 -0
  204. package/src/api/controllers/query/import/sources/tests/curl/data/post.txt +2 -0
  205. package/src/api/controllers/query/import/sources/tests/curl/data/put.txt +2 -0
  206. package/src/api/controllers/query/import/sources/tests/curl/data/query.txt +1 -0
  207. package/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json +253 -0
  208. package/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.yaml +160 -0
  209. package/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json +1054 -0
  210. package/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.yaml +711 -0
  211. package/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js +239 -0
  212. package/src/api/controllers/query/import/tests/index.spec.js +115 -0
  213. package/src/api/controllers/{query.js → query/index.js} +50 -6
  214. package/src/api/controllers/query/validation.js +41 -0
  215. package/src/api/controllers/user.js +33 -0
  216. package/src/api/controllers/webhook.js +4 -0
  217. package/src/api/routes/query.js +5 -34
  218. package/src/api/routes/user.js +10 -0
  219. package/src/db/utils.js +9 -0
  220. package/src/definitions/common.ts +2 -16
  221. package/src/definitions/datasource.ts +73 -1
  222. package/src/integrations/base/IntegrationBase.ts +4 -4
  223. package/src/integrations/oracle.ts +1 -1
  224. package/src/integrations/rest.ts +145 -134
  225. package/src/integrations/tests/rest.spec.js +71 -7
  226. package/src/threads/query.js +19 -2
  227. package/src/utilities/index.js +11 -0
@@ -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
  };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FilterTypes = exports.IncludeRelationships = exports.SourceNames = exports.DatasourceFieldTypes = exports.QueryTypes = exports.SortDirection = exports.Operation = void 0;
3
+ exports.AuthType = exports.FilterTypes = exports.IncludeRelationships = exports.SourceNames = exports.DatasourceFieldTypes = exports.QueryTypes = exports.SortDirection = exports.Operation = void 0;
4
4
  var Operation;
5
5
  (function (Operation) {
6
6
  Operation["CREATE"] = "CREATE";
@@ -66,3 +66,8 @@ var FilterTypes;
66
66
  FilterTypes["NOT_EMPTY"] = "notEmpty";
67
67
  FilterTypes["ONE_OF"] = "oneOf";
68
68
  })(FilterTypes = exports.FilterTypes || (exports.FilterTypes = {}));
69
+ var AuthType;
70
+ (function (AuthType) {
71
+ AuthType["BASIC"] = "basic";
72
+ AuthType["BEARER"] = "bearer";
73
+ })(AuthType = exports.AuthType || (exports.AuthType = {}));
@@ -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,174 +66,164 @@ 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;
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;
144
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
+ getAuthHeaders(authConfigId) {
146
+ let headers = {};
147
+ if (this.config.authConfigs && authConfigId) {
148
+ const authConfig = this.config.authConfigs.filter(c => c._id === authConfigId)[0];
149
+ // check the config still exists before proceeding
150
+ // if not - do nothing
151
+ if (authConfig) {
152
+ let config;
153
+ switch (authConfig.type) {
154
+ case datasource_1.AuthType.BASIC:
155
+ config = authConfig.config;
156
+ headers.Authorization = `Basic ${Buffer.from(`${config.username}:${config.password}`).toString("base64")}`;
157
+ break;
158
+ case datasource_1.AuthType.BEARER:
159
+ config = authConfig.config;
160
+ headers.Authorization = `Bearer ${config.token}`;
161
+ break;
162
+ }
163
+ }
164
+ }
165
+ return headers;
166
+ }
167
+ _req(query) {
151
168
  return __awaiter(this, void 0, void 0, function* () {
152
- 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
- });
169
+ const { path = "", queryString = "", headers = {}, method = "GET", disabledHeaders, bodyType, requestBody, authConfigId } = query;
170
+ const authHeaders = this.getAuthHeaders(authConfigId);
171
+ this.headers = Object.assign(Object.assign(Object.assign({}, this.config.defaultHeaders), headers), authHeaders);
172
+ if (disabledHeaders) {
173
+ for (let headerKey of Object.keys(this.headers)) {
174
+ if (disabledHeaders[headerKey]) {
175
+ delete this.headers[headerKey];
176
+ }
177
+ }
178
+ }
179
+ let json;
180
+ if (bodyType === BodyTypes.JSON && requestBody) {
181
+ try {
182
+ json = JSON.parse(requestBody);
183
+ }
184
+ catch (err) {
185
+ throw "Invalid JSON for request body";
186
+ }
187
+ }
188
+ const input = { method, headers: this.headers };
189
+ if (json && typeof json === "object" && Object.keys(json).length > 0) {
190
+ input.body = JSON.stringify(json);
191
+ }
192
+ this.startTimeMs = performance.now();
193
+ const url = this.getUrl(path, queryString);
194
+ const response = yield fetch(url, input);
158
195
  return yield this.parseResponse(response);
159
196
  });
160
197
  }
161
- read({ path = "", queryString = "", headers = {} }) {
198
+ create(opts) {
162
199
  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);
200
+ return this._req(Object.assign(Object.assign({}, opts), { method: "POST" }));
168
201
  });
169
202
  }
170
- update({ path = "", queryString = "", headers = {}, json = {} }) {
203
+ read(opts) {
171
204
  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);
205
+ return this._req(Object.assign(Object.assign({}, opts), { method: "GET" }));
179
206
  });
180
207
  }
181
- patch({ path = "", queryString = "", headers = {}, json = {} }) {
208
+ update(opts) {
182
209
  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);
210
+ return this._req(Object.assign(Object.assign({}, opts), { method: "PUT" }));
190
211
  });
191
212
  }
192
- delete({ path = "", queryString = "", headers = {} }) {
213
+ patch(opts) {
193
214
  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);
215
+ return this._req(Object.assign(Object.assign({}, opts), { method: "PATCH" }));
216
+ });
217
+ }
218
+ delete(opts) {
219
+ return __awaiter(this, void 0, void 0, function* () {
220
+ return this._req(Object.assign(Object.assign({}, opts), { method: "DELETE" }));
200
221
  });
201
222
  }
202
223
  }
203
224
  module.exports = {
204
225
  schema: SCHEMA,
205
226
  integration: RestIntegration,
227
+ AuthType: datasource_1.AuthType,
206
228
  };
207
229
  })(RestModule || (RestModule = {}));
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.17",
4
+ "version": "1.0.19-alpha.2",
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.17",
73
- "@budibase/client": "^1.0.17",
74
- "@budibase/string-templates": "^1.0.17",
72
+ "@apidevtools/swagger-parser": "^10.0.3",
73
+ "@budibase/auth": "^1.0.19-alpha.2",
74
+ "@budibase/client": "^1.0.19-alpha.2",
75
+ "@budibase/string-templates": "^1.0.19-alpha.2",
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",