@budibase/server 1.0.217 → 1.0.219-alpha.1

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 (257) hide show
  1. package/__mocks__/node-fetch.ts +9 -0
  2. package/builder/assets/index.7786f497.css +6 -0
  3. package/builder/assets/index.832d3790.js +977 -0
  4. package/builder/assets/{vendor.9bf2fcb4.js → vendor.001dcf8c.js} +163 -163
  5. package/builder/index.html +3 -3
  6. package/coverage/clover.xml +866 -792
  7. package/coverage/coverage-final.json +26 -26
  8. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  9. package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
  10. package/coverage/lcov-report/api/controllers/automation.js.html +111 -12
  11. package/coverage/lcov-report/api/controllers/backup.js.html +9 -6
  12. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  13. package/coverage/lcov-report/api/controllers/component.js.html +1 -1
  14. package/coverage/lcov-report/api/controllers/datasource.js.html +16 -16
  15. package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
  16. package/coverage/lcov-report/api/controllers/index.html +21 -21
  17. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  18. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  20. package/coverage/lcov-report/api/controllers/migrations.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/query/index.html +1 -1
  23. package/coverage/lcov-report/api/controllers/query/validation.js.html +1 -1
  24. package/coverage/lcov-report/api/controllers/role.js.html +1 -1
  25. package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
  26. package/coverage/lcov-report/api/controllers/row/external.js.html +47 -17
  27. package/coverage/lcov-report/api/controllers/row/index.html +34 -34
  28. package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
  29. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +95 -11
  30. package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +1 -1
  31. package/coverage/lcov-report/api/controllers/row/utils.js.html +17 -8
  32. package/coverage/lcov-report/api/controllers/screen.js.html +1 -1
  33. package/coverage/lcov-report/api/controllers/script.js.html +1 -1
  34. package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +1 -1
  35. package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
  36. package/coverage/lcov-report/api/controllers/table/index.html +1 -1
  37. package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
  38. package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
  39. package/coverage/lcov-report/api/controllers/user.js.html +1 -1
  40. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  41. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  42. package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
  43. package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
  44. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
  45. package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
  46. package/coverage/lcov-report/api/index.html +15 -15
  47. package/coverage/lcov-report/api/index.js.html +22 -13
  48. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  49. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  50. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  51. package/coverage/lcov-report/api/routes/automation.js.html +32 -2
  52. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  53. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/dev.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/index.html +1 -1
  59. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/migrations.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/query.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/user.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/utils/index.html +1 -1
  73. package/coverage/lcov-report/api/routes/utils/validators.js.html +1 -1
  74. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  75. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  76. package/coverage/lcov-report/automations/actions.js.html +1 -1
  77. package/coverage/lcov-report/automations/automationUtils.js.html +57 -12
  78. package/coverage/lcov-report/automations/bullboard.js.html +1 -1
  79. package/coverage/lcov-report/automations/index.html +17 -17
  80. package/coverage/lcov-report/automations/index.js.html +1 -1
  81. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  82. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  83. package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
  84. package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
  85. package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
  86. package/coverage/lcov-report/automations/steps/filter.js.html +58 -34
  87. package/coverage/lcov-report/automations/steps/index.html +11 -11
  88. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  89. package/coverage/lcov-report/automations/steps/loop.js.html +1 -1
  90. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
  91. package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  94. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  95. package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
  96. package/coverage/lcov-report/automations/steps/utils.js.html +1 -1
  97. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  98. package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
  99. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
  100. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  101. package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
  102. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
  103. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
  104. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
  105. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
  106. package/coverage/lcov-report/automations/triggers.js.html +4 -4
  107. package/coverage/lcov-report/constants/index.html +1 -1
  108. package/coverage/lcov-report/constants/index.js.html +1 -1
  109. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  110. package/coverage/lcov-report/constants/screens.js.html +1 -1
  111. package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
  112. package/coverage/lcov-report/db/index.html +14 -14
  113. package/coverage/lcov-report/db/index.js.html +1 -1
  114. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +1 -1
  115. package/coverage/lcov-report/db/linkedRows/index.html +13 -13
  116. package/coverage/lcov-report/db/linkedRows/index.js.html +10 -7
  117. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
  118. package/coverage/lcov-report/db/newid.js.html +2 -2
  119. package/coverage/lcov-report/db/utils.js.html +27 -51
  120. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  121. package/coverage/lcov-report/events/index.html +1 -1
  122. package/coverage/lcov-report/events/index.js.html +1 -1
  123. package/coverage/lcov-report/events/utils.js.html +1 -1
  124. package/coverage/lcov-report/index.html +74 -74
  125. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  126. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  127. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  128. package/coverage/lcov-report/middleware/builder.js.html +12 -12
  129. package/coverage/lcov-report/middleware/currentapp.js.html +33 -33
  130. package/coverage/lcov-report/middleware/index.html +1 -1
  131. package/coverage/lcov-report/middleware/joi-validator.js.html +10 -10
  132. package/coverage/lcov-report/middleware/publicApi.js.html +1 -1
  133. package/coverage/lcov-report/middleware/resourceId.js.html +7 -7
  134. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  135. package/coverage/lcov-report/middleware/utils.js.html +2 -2
  136. package/coverage/lcov-report/threads/automation.js.html +18 -9
  137. package/coverage/lcov-report/threads/index.html +25 -25
  138. package/coverage/lcov-report/threads/query.js.html +280 -76
  139. package/coverage/lcov-report/threads/utils.js.html +4 -4
  140. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  141. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  142. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  143. package/coverage/lcov-report/utilities/global.js.html +14 -14
  144. package/coverage/lcov-report/utilities/index.html +1 -1
  145. package/coverage/lcov-report/utilities/index.js.html +9 -9
  146. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +2 -2
  147. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  148. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  149. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  150. package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
  151. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +1 -1
  152. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
  153. package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
  154. package/coverage/lcov-report/utilities/security.js.html +2 -2
  155. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  156. package/coverage/lcov-report/utilities/usageQuota/index.html +1 -1
  157. package/coverage/lcov-report/utilities/usageQuota/rows.js.html +1 -1
  158. package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
  159. package/coverage/lcov-report/utilities/users.js.html +1 -1
  160. package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
  161. package/coverage/lcov.info +1554 -1422
  162. package/dist/api/controllers/application.js +18 -15
  163. package/dist/api/controllers/automation.js +28 -2
  164. package/dist/api/controllers/backup.js +3 -2
  165. package/dist/api/controllers/query/index.js +25 -0
  166. package/dist/api/controllers/row/external.js +19 -7
  167. package/dist/api/controllers/row/internalSearch.js +22 -1
  168. package/dist/api/controllers/row/utils.js +3 -0
  169. package/dist/api/index.js +4 -1
  170. package/dist/api/routes/automation.js +2 -0
  171. package/dist/automations/automationUtils.js +16 -4
  172. package/dist/automations/logging/index.js +70 -0
  173. package/dist/automations/steps/filter.js +38 -29
  174. package/dist/automations/triggers.js +1 -1
  175. package/dist/db/linkedRows/index.js +1 -0
  176. package/dist/db/utils.js +4 -31
  177. package/dist/definitions/datasource.js +1 -0
  178. package/dist/environment.js +1 -0
  179. package/dist/integrations/airtable.js +1 -0
  180. package/dist/integrations/arangodb.js +1 -0
  181. package/dist/integrations/base/sql.js +20 -3
  182. package/dist/integrations/couchdb.js +1 -0
  183. package/dist/integrations/dynamodb.js +1 -0
  184. package/dist/integrations/elasticsearch.js +1 -0
  185. package/dist/integrations/firebase.js +1 -0
  186. package/dist/integrations/googlesheets.js +1 -0
  187. package/dist/integrations/index.js +4 -0
  188. package/dist/integrations/microsoftSqlServer.js +2 -1
  189. package/dist/integrations/mongodb.js +1 -0
  190. package/dist/integrations/mysql.js +2 -1
  191. package/dist/integrations/oracle.js +1 -0
  192. package/dist/integrations/postgres.js +2 -1
  193. package/dist/integrations/queries/sql.js +3 -0
  194. package/dist/integrations/redis.js +1 -0
  195. package/dist/integrations/rest.js +2 -1
  196. package/dist/integrations/s3.js +1 -0
  197. package/dist/integrations/snowflake.js +102 -0
  198. package/dist/package.json +7 -6
  199. package/dist/tests/utilities/TestConfiguration.js +19 -6
  200. package/dist/threads/automation.js +6 -3
  201. package/dist/threads/index.js +15 -1
  202. package/dist/threads/query.js +53 -8
  203. package/dist/tsconfig.build.tsbuildinfo +1 -1
  204. package/dist/utilities/fileSystem/index.js +16 -6
  205. package/package.json +8 -7
  206. package/scripts/integrations/oracle/instantclient/linux/arm64/basiclite-19.10.zip +0 -0
  207. package/scripts/integrations/oracle/instantclient/linux/arm64/install.sh +23 -0
  208. package/scripts/integrations/oracle/instantclient/linux/install.sh +10 -0
  209. package/src/api/controllers/application.ts +18 -14
  210. package/src/api/controllers/automation.js +35 -2
  211. package/src/api/controllers/backup.js +3 -2
  212. package/src/api/controllers/query/index.ts +29 -1
  213. package/src/api/controllers/row/external.js +19 -9
  214. package/src/api/controllers/row/internalSearch.js +28 -0
  215. package/src/api/controllers/row/utils.js +3 -0
  216. package/src/api/index.js +4 -1
  217. package/src/api/routes/automation.js +10 -0
  218. package/src/api/routes/tests/query.spec.js +166 -0
  219. package/src/automations/automationUtils.js +19 -4
  220. package/src/automations/logging/index.ts +35 -0
  221. package/src/automations/steps/filter.js +36 -28
  222. package/src/automations/tests/filter.spec.js +2 -1
  223. package/src/automations/triggers.js +1 -1
  224. package/src/db/linkedRows/index.js +1 -0
  225. package/src/db/utils.js +5 -13
  226. package/src/definitions/common.ts +1 -0
  227. package/src/definitions/datasource.ts +2 -0
  228. package/src/environment.js +1 -0
  229. package/src/integrations/airtable.ts +1 -0
  230. package/src/integrations/arangodb.ts +1 -0
  231. package/src/integrations/base/sql.ts +25 -11
  232. package/src/integrations/couchdb.ts +1 -0
  233. package/src/integrations/dynamodb.ts +1 -0
  234. package/src/integrations/elasticsearch.ts +1 -0
  235. package/src/integrations/firebase.ts +1 -0
  236. package/src/integrations/googlesheets.ts +1 -0
  237. package/src/integrations/index.ts +4 -0
  238. package/src/integrations/microsoftSqlServer.ts +2 -0
  239. package/src/integrations/mongodb.ts +1 -0
  240. package/src/integrations/mysql.ts +2 -0
  241. package/src/integrations/oracle.ts +1 -0
  242. package/src/integrations/postgres.ts +2 -0
  243. package/src/integrations/queries/sql.ts +3 -1
  244. package/src/integrations/redis.ts +1 -0
  245. package/src/integrations/rest.ts +2 -1
  246. package/src/integrations/s3.ts +1 -0
  247. package/src/integrations/snowflake.ts +99 -0
  248. package/src/integrations/tests/rest.spec.js +16 -1
  249. package/src/migrations/tests/index.spec.ts +18 -2
  250. package/src/module.d.ts +2 -0
  251. package/src/tests/utilities/TestConfiguration.js +22 -3
  252. package/src/threads/automation.js +6 -3
  253. package/src/threads/index.ts +5 -1
  254. package/src/threads/query.js +78 -10
  255. package/src/utilities/fileSystem/index.js +22 -8
  256. package/builder/assets/index.24307ca0.css +0 -6
  257. package/builder/assets/index.cc2e9cbe.js +0 -1316
@@ -89,6 +89,23 @@ function parseFilters(filters) {
89
89
  }
90
90
  return filters;
91
91
  }
92
+ function generateSelectStatement(json, knex) {
93
+ var _a;
94
+ const { resource, meta } = json;
95
+ const schema = (_a = meta === null || meta === void 0 ? void 0 : meta.table) === null || _a === void 0 ? void 0 : _a.schema;
96
+ return resource.fields.map(field => {
97
+ const fieldNames = field.split(/\./g);
98
+ const tableName = fieldNames[0];
99
+ const columnName = fieldNames[1];
100
+ if (columnName && knex.client.config.client === utils_1.SqlClients.POSTGRES) {
101
+ const externalType = schema === null || schema === void 0 ? void 0 : schema[columnName].externalType;
102
+ if (externalType === null || externalType === void 0 ? void 0 : externalType.includes("money")) {
103
+ return knex.raw(`"${tableName}"."${columnName}"::money::numeric as "${field}"`);
104
+ }
105
+ }
106
+ return `${field} as ${field}`;
107
+ });
108
+ }
92
109
  class InternalBuilder {
93
110
  constructor(client) {
94
111
  this.client = client;
@@ -209,7 +226,7 @@ class InternalBuilder {
209
226
  }
210
227
  return query;
211
228
  }
212
- addRelationships(knex, query, fields, fromTable, relationships) {
229
+ addRelationships(query, fromTable, relationships) {
213
230
  if (!relationships) {
214
231
  return query;
215
232
  }
@@ -311,7 +328,7 @@ class InternalBuilder {
311
328
  if (resource.fields && resource.fields.length > 0) {
312
329
  // select the resources as the format "table.columnName" - this is what is provided
313
330
  // by the resource builder further up
314
- selectStatement = resource.fields.map(field => `${field} as ${field}`);
331
+ selectStatement = generateSelectStatement(json, knex);
315
332
  }
316
333
  let foundLimit = limit || BASE_LIMIT;
317
334
  // handle pagination
@@ -347,7 +364,7 @@ class InternalBuilder {
347
364
  preQuery = this.addSorting(preQuery, json);
348
365
  }
349
366
  // handle joins
350
- query = this.addRelationships(knex, preQuery, selectStatement, tableName, relationships);
367
+ query = this.addRelationships(preQuery, tableName, relationships);
351
368
  return this.addFilters(query, filters, { relationship: true });
352
369
  }
353
370
  update(knex, json, opts) {
@@ -16,6 +16,7 @@ var CouchDBModule;
16
16
  const SCHEMA = {
17
17
  docs: "https://docs.couchdb.org/en/stable/",
18
18
  friendlyName: "CouchDB",
19
+ type: "Non-relational",
19
20
  description: "Apache CouchDB is an open-source document-oriented NoSQL database, implemented in Erlang.",
20
21
  datasource: {
21
22
  url: {
@@ -18,6 +18,7 @@ var DynamoModule;
18
18
  docs: "https://github.com/dabit3/dynamodb-documentclient-cheat-sheet",
19
19
  description: "Amazon DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale.",
20
20
  friendlyName: "DynamoDB",
21
+ type: "Non-relational",
21
22
  datasource: {
22
23
  region: {
23
24
  type: datasource_1.DatasourceFieldTypes.STRING,
@@ -17,6 +17,7 @@ var ElasticsearchModule;
17
17
  docs: "https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/index.html",
18
18
  description: "Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents.",
19
19
  friendlyName: "ElasticSearch",
20
+ type: "Non-relational",
20
21
  datasource: {
21
22
  url: {
22
23
  type: datasource_1.DatasourceFieldTypes.STRING,
@@ -16,6 +16,7 @@ var Firebase;
16
16
  const SCHEMA = {
17
17
  docs: "https://firebase.google.com/docs/firestore/quickstart",
18
18
  friendlyName: "Firestore",
19
+ type: "Non-relational",
19
20
  description: "Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud.",
20
21
  datasource: {
21
22
  email: {
@@ -33,6 +33,7 @@ var GoogleSheetsModule;
33
33
  docs: "https://developers.google.com/sheets/api/quickstart/nodejs",
34
34
  description: "Create and collaborate on online spreadsheets in real-time and from any device. ",
35
35
  friendlyName: "Google Sheets",
36
+ type: "Spreadsheet",
36
37
  datasource: {
37
38
  spreadsheetId: {
38
39
  display: "Google Sheet URL",
@@ -13,6 +13,7 @@ const rest = require("./rest");
13
13
  const googlesheets = require("./googlesheets");
14
14
  const firebase = require("./firebase");
15
15
  const redis = require("./redis");
16
+ const snowflake = require("./snowflake");
16
17
  const { SourceNames } = require("../definitions/datasource");
17
18
  const environment = require("../environment");
18
19
  const DEFINITIONS = {
@@ -29,6 +30,7 @@ const DEFINITIONS = {
29
30
  [SourceNames.REST]: rest.schema,
30
31
  [SourceNames.FIRESTORE]: firebase.schema,
31
32
  [SourceNames.REDIS]: redis.schema,
33
+ [SourceNames.SNOWFLAKE]: snowflake.schema,
32
34
  };
33
35
  const INTEGRATIONS = {
34
36
  [SourceNames.POSTGRES]: postgres.integration,
@@ -45,6 +47,8 @@ const INTEGRATIONS = {
45
47
  [SourceNames.FIRESTORE]: firebase.integration,
46
48
  [SourceNames.GOOGLE_SHEETS]: googlesheets.integration,
47
49
  [SourceNames.REDIS]: redis.integration,
50
+ [SourceNames.FIREBASE]: firebase.integration,
51
+ [SourceNames.SNOWFLAKE]: snowflake.integration,
48
52
  };
49
53
  // optionally add oracle integration if the oracle binary can be installed
50
54
  if (!(process.arch === "arm64" && process.platform === "darwin")) {
@@ -21,6 +21,7 @@ var MSSQLModule;
21
21
  plus: true,
22
22
  description: "Microsoft SQL Server is a relational database management system developed by Microsoft. ",
23
23
  friendlyName: "MS SQL Server",
24
+ type: "Relational",
24
25
  datasource: {
25
26
  user: {
26
27
  type: datasource_1.DatasourceFieldTypes.STRING,
@@ -201,7 +202,7 @@ var MSSQLModule;
201
202
  if (typeof name !== "string") {
202
203
  continue;
203
204
  }
204
- schema[name] = Object.assign({ autocolumn: !!autoColumns.find((col) => col === name), name: name }, (0, utils_1.convertSqlType)(def.DATA_TYPE));
205
+ schema[name] = Object.assign(Object.assign({ autocolumn: !!autoColumns.find((col) => col === name), name: name }, (0, utils_1.convertSqlType)(def.DATA_TYPE)), { externalType: def.DATA_TYPE });
205
206
  }
206
207
  tables[tableName] = {
207
208
  _id: (0, utils_1.buildExternalTableId)(datasourceId, tableName),
@@ -16,6 +16,7 @@ var MongoDBModule;
16
16
  const SCHEMA = {
17
17
  docs: "https://github.com/mongodb/node-mongodb-native",
18
18
  friendlyName: "MongoDB",
19
+ type: "Non-relational",
19
20
  description: "MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era.",
20
21
  datasource: {
21
22
  connectionString: {
@@ -24,6 +24,7 @@ var MySQLModule;
24
24
  docs: "https://github.com/sidorares/node-mysql2",
25
25
  plus: true,
26
26
  friendlyName: "MySQL",
27
+ type: "Relational",
27
28
  description: "MySQL Database Service is a fully managed database service to deploy cloud-native applications. ",
28
29
  datasource: {
29
30
  host: {
@@ -187,7 +188,7 @@ var MySQLModule;
187
188
  const isAuto = typeof column.Extra === "string" &&
188
189
  (column.Extra === "auto_increment" ||
189
190
  column.Extra.toLowerCase().includes("generated"));
190
- schema[columnName] = Object.assign({ name: columnName, autocolumn: isAuto, constraints }, (0, utils_1.convertSqlType)(column.Type));
191
+ schema[columnName] = Object.assign(Object.assign({ name: columnName, autocolumn: isAuto, constraints }, (0, utils_1.convertSqlType)(column.Type)), { externalType: column.Type });
191
192
  }
192
193
  if (!tables[tableName]) {
193
194
  tables[tableName] = {
@@ -24,6 +24,7 @@ var OracleModule;
24
24
  docs: "https://github.com/oracle/node-oracledb",
25
25
  plus: true,
26
26
  friendlyName: "Oracle",
27
+ type: "Relational",
27
28
  description: "Oracle Database is an object-relational database management system developed by Oracle Corporation",
28
29
  datasource: {
29
30
  host: {
@@ -29,6 +29,7 @@ var PostgresModule;
29
29
  docs: "https://node-postgres.com",
30
30
  plus: true,
31
31
  friendlyName: "PostgreSQL",
32
+ type: "Relational",
32
33
  description: "PostgreSQL, also known as Postgres, is a free and open-source relational database management system emphasizing extensibility and SQL compliance.",
33
34
  datasource: {
34
35
  host: {
@@ -229,7 +230,7 @@ var PostgresModule;
229
230
  column.column_default.startsWith("nextval");
230
231
  const isGenerated = column.is_generated && column.is_generated !== "NEVER";
231
232
  const isAuto = hasDefault || identity || isGenerated;
232
- tables[tableName].schema[columnName] = Object.assign({ autocolumn: isAuto, name: columnName }, (0, utils_1.convertSqlType)(column.data_type));
233
+ tables[tableName].schema[columnName] = Object.assign(Object.assign({ autocolumn: isAuto, name: columnName }, (0, utils_1.convertSqlType)(column.data_type)), { externalType: column.data_type });
233
234
  }
234
235
  const final = (0, utils_1.finaliseExternalTables)(tables, entities);
235
236
  this.tables = final.tables;
@@ -5,6 +5,9 @@ const string_templates_1 = require("@budibase/string-templates");
5
5
  const CONST_CHAR_REGEX = new RegExp("'[^']*'", "g");
6
6
  function enrichQueryFields(fields, parameters = {}) {
7
7
  const enrichedQuery = Array.isArray(fields) ? [] : {};
8
+ if (!fields || !parameters) {
9
+ return enrichedQuery;
10
+ }
8
11
  // enrich the fields with dynamic parameters
9
12
  for (let key of Object.keys(fields)) {
10
13
  if (fields[key] == null) {
@@ -20,6 +20,7 @@ var RedisModule;
20
20
  docs: "https://redis.io/docs/",
21
21
  description: "",
22
22
  friendlyName: "Redis",
23
+ type: "Non-relational",
23
24
  datasource: {
24
25
  host: {
25
26
  type: "string",
@@ -56,6 +56,7 @@ var RestModule;
56
56
  docs: "https://github.com/node-fetch/node-fetch",
57
57
  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.",
58
58
  friendlyName: "REST API",
59
+ type: "API",
59
60
  datasource: {
60
61
  url: {
61
62
  type: datasource_1.DatasourceFieldTypes.STRING,
@@ -251,7 +252,7 @@ var RestModule;
251
252
  input.body = form;
252
253
  break;
253
254
  case BodyTypes.XML:
254
- if (object != null) {
255
+ if (object != null && Object.keys(object).length) {
255
256
  string = new XmlBuilder().buildObject(object);
256
257
  }
257
258
  input.body = string;
@@ -17,6 +17,7 @@ var S3Module;
17
17
  docs: "https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html",
18
18
  description: "Amazon Simple Storage Service (Amazon S3) is an object storage service that offers industry-leading scalability, data availability, security, and performance.",
19
19
  friendlyName: "Amazon S3",
20
+ type: "Object store",
20
21
  datasource: {
21
22
  region: {
22
23
  type: "string",
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const datasource_1 = require("../definitions/datasource");
13
+ const snowflake_promise_1 = require("snowflake-promise");
14
+ var SnowflakeModule;
15
+ (function (SnowflakeModule) {
16
+ const SCHEMA = {
17
+ docs: "https://developers.snowflake.com/",
18
+ description: "Snowflake is a solution for data warehousing, data lakes, data engineering, data science, data application development, and securely sharing and consuming shared data.",
19
+ friendlyName: "Snowflake",
20
+ type: "Relational",
21
+ datasource: {
22
+ account: {
23
+ type: "string",
24
+ required: true,
25
+ },
26
+ username: {
27
+ type: "string",
28
+ required: true,
29
+ },
30
+ password: {
31
+ type: "password",
32
+ required: true,
33
+ },
34
+ warehouse: {
35
+ type: "string",
36
+ required: true,
37
+ },
38
+ database: {
39
+ type: "string",
40
+ required: true,
41
+ },
42
+ schema: {
43
+ type: "string",
44
+ required: true,
45
+ },
46
+ },
47
+ query: {
48
+ create: {
49
+ type: datasource_1.QueryTypes.SQL,
50
+ },
51
+ read: {
52
+ type: datasource_1.QueryTypes.SQL,
53
+ },
54
+ update: {
55
+ type: datasource_1.QueryTypes.SQL,
56
+ },
57
+ delete: {
58
+ type: datasource_1.QueryTypes.SQL,
59
+ },
60
+ },
61
+ };
62
+ class SnowflakeIntegration {
63
+ constructor(config) {
64
+ this.client = new snowflake_promise_1.Snowflake(config);
65
+ }
66
+ internalQuery(query) {
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ yield this.client.connect();
69
+ try {
70
+ return yield this.client.execute(query.sql);
71
+ }
72
+ catch (err) {
73
+ throw (err === null || err === void 0 ? void 0 : err.message.split(":")[1]) || (err === null || err === void 0 ? void 0 : err.message);
74
+ }
75
+ });
76
+ }
77
+ create(query) {
78
+ return __awaiter(this, void 0, void 0, function* () {
79
+ return this.internalQuery(query);
80
+ });
81
+ }
82
+ read(query) {
83
+ return __awaiter(this, void 0, void 0, function* () {
84
+ return this.internalQuery(query);
85
+ });
86
+ }
87
+ update(query) {
88
+ return __awaiter(this, void 0, void 0, function* () {
89
+ return this.internalQuery(query);
90
+ });
91
+ }
92
+ delete(query) {
93
+ return __awaiter(this, void 0, void 0, function* () {
94
+ return this.internalQuery(query);
95
+ });
96
+ }
97
+ }
98
+ module.exports = {
99
+ schema: SCHEMA,
100
+ integration: SnowflakeIntegration,
101
+ };
102
+ })(SnowflakeModule || (SnowflakeModule = {}));
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.216",
4
+ "version": "1.0.219-alpha.0",
5
5
  "description": "Budibase Web Server",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -77,10 +77,11 @@
77
77
  "license": "GPL-3.0",
78
78
  "dependencies": {
79
79
  "@apidevtools/swagger-parser": "10.0.3",
80
- "@budibase/backend-core": "^1.0.216",
81
- "@budibase/client": "^1.0.216",
82
- "@budibase/pro": "1.0.216",
83
- "@budibase/string-templates": "^1.0.216",
80
+ "@budibase/backend-core": "^1.0.219-alpha.0",
81
+ "@budibase/client": "^1.0.219-alpha.0",
82
+ "@budibase/pro": "1.0.219-alpha.0",
83
+ "@budibase/string-templates": "^1.0.219-alpha.0",
84
+ "@budibase/types": "^1.0.219-alpha.0",
84
85
  "@bull-board/api": "3.7.0",
85
86
  "@bull-board/koa": "3.9.4",
86
87
  "@elastic/elasticsearch": "7.10.0",
@@ -135,6 +136,7 @@
135
136
  "pouchdb-replication-stream": "1.2.9",
136
137
  "redis": "4",
137
138
  "server-destroy": "1.0.1",
139
+ "snowflake-promise": "^4.5.0",
138
140
  "svelte": "3.44.1",
139
141
  "swagger-parser": "10.0.3",
140
142
  "to-json-schema": "0.2.5",
@@ -150,7 +152,6 @@
150
152
  "@babel/core": "7.17.4",
151
153
  "@babel/preset-env": "7.16.11",
152
154
  "@budibase/standard-components": "^0.9.139",
153
- "@budibase/types": "^1.0.216",
154
155
  "@jest/test-sequencer": "24.9.0",
155
156
  "@types/apidoc": "0.50.0",
156
157
  "@types/bson": "4.2.0",
@@ -26,6 +26,8 @@ const { generateDevInfoID, SEPARATOR } = require("@budibase/backend-core/db");
26
26
  const { encrypt } = require("@budibase/backend-core/encryption");
27
27
  const GLOBAL_USER_ID = "us_uuid1";
28
28
  const EMAIL = "babs@babs.com";
29
+ const FIRSTNAME = "Barbara";
30
+ const LASTNAME = "Barbington";
29
31
  const CSRF_TOKEN = "e3727778-7af0-4226-b5eb-f43cbe60a306";
30
32
  class TestConfiguration {
31
33
  constructor(openServer = true) {
@@ -51,6 +53,14 @@ class TestConfiguration {
51
53
  getProdAppId() {
52
54
  return this.prodAppId;
53
55
  }
56
+ getUserDetails() {
57
+ return {
58
+ globalId: GLOBAL_USER_ID,
59
+ email: EMAIL,
60
+ firstName: FIRSTNAME,
61
+ lastName: LASTNAME,
62
+ };
63
+ }
54
64
  doInContext(appId, task) {
55
65
  return __awaiter(this, void 0, void 0, function* () {
56
66
  if (!appId) {
@@ -109,7 +119,7 @@ class TestConfiguration {
109
119
  });
110
120
  }
111
121
  // USER / AUTH
112
- globalUser({ id = GLOBAL_USER_ID, builder = true, admin = false, email = EMAIL, roles, } = {}) {
122
+ globalUser({ id = GLOBAL_USER_ID, firstName = FIRSTNAME, lastName = LASTNAME, builder = true, admin = false, email = EMAIL, roles, } = {}) {
113
123
  return __awaiter(this, void 0, void 0, function* () {
114
124
  return doWithGlobalDB(TENANT_ID, (db) => __awaiter(this, void 0, void 0, function* () {
115
125
  let existing;
@@ -119,7 +129,8 @@ class TestConfiguration {
119
129
  catch (err) {
120
130
  existing = { email };
121
131
  }
122
- const user = Object.assign(Object.assign({ _id: id }, existing), { roles: roles || {}, tenantId: TENANT_ID });
132
+ const user = Object.assign(Object.assign({ _id: id }, existing), { roles: roles || {}, tenantId: TENANT_ID, firstName,
133
+ lastName });
123
134
  yield createASession(id, {
124
135
  sessionId: "sessionid",
125
136
  tenantId: TENANT_ID,
@@ -142,11 +153,13 @@ class TestConfiguration {
142
153
  }));
143
154
  });
144
155
  }
145
- createUser(id = null, email = EMAIL, builder = true, admin = false, roles = {}) {
156
+ createUser(id = null, firstName = FIRSTNAME, lastName = LASTNAME, email = EMAIL, builder = true, admin = false, roles = {}) {
146
157
  return __awaiter(this, void 0, void 0, function* () {
147
158
  const globalId = !id ? `us_${Math.random()}` : `us_${id}`;
148
159
  const resp = yield this.globalUser({
149
160
  id: globalId,
161
+ firstName,
162
+ lastName,
150
163
  email,
151
164
  builder,
152
165
  admin,
@@ -466,15 +479,15 @@ class TestConfiguration {
466
479
  });
467
480
  }
468
481
  // QUERY
469
- previewQuery(request, config, datasource, fields) {
482
+ previewQuery(request, config, datasource, fields, params, verb) {
470
483
  return __awaiter(this, void 0, void 0, function* () {
471
484
  return request
472
485
  .post(`/api/queries/preview`)
473
486
  .send({
474
487
  datasourceId: datasource._id,
475
- parameters: {},
488
+ parameters: params || {},
476
489
  fields,
477
- queryVerb: "read",
490
+ queryVerb: verb || "read",
478
491
  name: datasource.name,
479
492
  })
480
493
  .set(config.defaultHeaders())
@@ -19,10 +19,11 @@ const { doInTenant } = require("@budibase/backend-core/tenancy");
19
19
  const { definitions: triggerDefs } = require("../automations/triggerInfo");
20
20
  const { doInAppContext, getAppDB } = require("@budibase/backend-core/context");
21
21
  const { AutomationErrors, LoopStepTypes } = require("../constants");
22
+ const { storeLog } = require("../automations/logging");
22
23
  const FILTER_STEP_ID = actions.ACTION_DEFINITIONS.FILTER.stepId;
23
24
  const LOOP_STEP_ID = actions.ACTION_DEFINITIONS.LOOP.stepId;
24
25
  const CRON_STEP_ID = triggerDefs.CRON.stepId;
25
- const STOPPED_STATUS = { success: false, status: "STOPPED" };
26
+ const STOPPED_STATUS = { success: true, status: "STOPPED" };
26
27
  const { cloneDeep } = require("lodash/fp");
27
28
  const env = require("../environment");
28
29
  function typecastForLooping(loopStep, input) {
@@ -195,7 +196,7 @@ class Orchestrator {
195
196
  }
196
197
  }
197
198
  }
198
- if (index === parseInt(env.AUTOMATION_MAX_ITERATIONS) ||
199
+ if (index === env.AUTOMATION_MAX_ITERATION ||
199
200
  index === parseInt(loopStep.inputs.iterations)) {
200
201
  this.updateContextAndOutput(loopStepNumber, step, tempOutput, {
201
202
  status: AutomationErrors.MAX_ITERATIONS,
@@ -248,7 +249,7 @@ class Orchestrator {
248
249
  this._context.steps[stepCount] = outputs;
249
250
  // if filter causes us to stop execution don't break the loop, set a var
250
251
  // so that we can finish iterating through the steps and record that it stopped
251
- if (step.stepId === FILTER_STEP_ID && !outputs.success) {
252
+ if (step.stepId === FILTER_STEP_ID && !outputs.result) {
252
253
  stopped = true;
253
254
  this.updateExecutionOutput(step.id, step.stepId, step.inputs, Object.assign(Object.assign({}, outputs), STOPPED_STATUS));
254
255
  continue;
@@ -289,6 +290,8 @@ class Orchestrator {
289
290
  loopSteps = null;
290
291
  }
291
292
  }
293
+ // store the logs for the automation run
294
+ yield storeLog(this._automation, this.executionOutput);
292
295
  return this.executionOutput;
293
296
  });
294
297
  }
@@ -22,6 +22,15 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
25
34
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
35
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
36
  };
@@ -92,7 +101,7 @@ class Thread {
92
101
  });
93
102
  });
94
103
  }
95
- static shutdown() {
104
+ static stopThreads() {
96
105
  return new Promise(resolve => {
97
106
  if (Thread.workerRefs.length === 0) {
98
107
  resolve();
@@ -110,6 +119,11 @@ class Thread {
110
119
  Thread.workerRefs = [];
111
120
  });
112
121
  }
122
+ static shutdown() {
123
+ return __awaiter(this, void 0, void 0, function* () {
124
+ yield Thread.stopThreads();
125
+ });
126
+ }
113
127
  }
114
128
  exports.Thread = Thread;
115
129
  Thread.workerRefs = [];
@@ -14,6 +14,8 @@ const ScriptRunner = require("../utilities/scriptRunner");
14
14
  const { integrations } = require("../integrations");
15
15
  const { processStringSync } = require("@budibase/string-templates");
16
16
  const { doInAppContext, getAppDB } = require("@budibase/backend-core/context");
17
+ const { refreshOAuthToken, updateUserOAuth, } = require("@budibase/backend-core/auth");
18
+ const { getGlobalIDFromUserMetadataID } = require("../db/utils");
17
19
  const { isSQL } = require("../integrations/utils");
18
20
  const { enrichQueryFields, interpolateSQL, } = require("../integrations/queries/sql");
19
21
  class QueryRunner {
@@ -27,29 +29,46 @@ class QueryRunner {
27
29
  this.queryId = input.queryId;
28
30
  this.noRecursiveQuery = flags.noRecursiveQuery;
29
31
  this.cachedVariables = [];
32
+ // Additional context items for enrichment
33
+ this.ctx = input.ctx;
30
34
  // allows the response from a query to be stored throughout this
31
35
  // execution so that if it needs to be re-used for another variable
32
36
  // it can be
33
37
  this.queryResponse = {};
34
38
  this.hasRerun = false;
39
+ this.hasRefreshedOAuth = false;
35
40
  }
36
41
  execute() {
42
+ var _a;
37
43
  return __awaiter(this, void 0, void 0, function* () {
38
44
  let { datasource, fields, queryVerb, transformer } = this;
39
45
  const Integration = integrations[datasource.source];
40
46
  if (!Integration) {
41
47
  throw "Integration type does not exist.";
42
48
  }
49
+ if (datasource.config.authConfigs) {
50
+ datasource.config.authConfigs = datasource.config.authConfigs.map(config => {
51
+ return enrichQueryFields(config, this.ctx);
52
+ });
53
+ }
43
54
  const integration = new Integration(datasource.config);
44
55
  // pre-query, make sure datasource variables are added to parameters
45
56
  const parameters = yield this.addDatasourceVariables();
57
+ // Enrich the parameters with the addition context items.
58
+ // 'user' is now a reserved variable key in mapping parameters
59
+ const enrichedParameters = enrichQueryFields(parameters, this.ctx);
60
+ const enrichedContext = Object.assign(Object.assign({}, enrichedParameters), this.ctx);
61
+ // Parse global headers
62
+ if (datasource.config.defaultHeaders) {
63
+ datasource.config.defaultHeaders = enrichQueryFields(datasource.config.defaultHeaders, enrichedContext);
64
+ }
46
65
  let query;
47
66
  // handle SQL injections by interpolating the variables
48
67
  if (isSQL(datasource)) {
49
- query = interpolateSQL(fields, parameters, integration);
68
+ query = interpolateSQL(fields, enrichedParameters, integration);
50
69
  }
51
70
  else {
52
- query = enrichQueryFields(fields, parameters);
71
+ query = enrichQueryFields(fields, enrichedContext);
53
72
  }
54
73
  // Add pagination values for REST queries
55
74
  if (this.pagination) {
@@ -67,17 +86,25 @@ class QueryRunner {
67
86
  if (transformer) {
68
87
  const runner = new ScriptRunner(transformer, {
69
88
  data: rows,
70
- params: parameters,
89
+ params: enrichedParameters,
71
90
  });
72
91
  rows = runner.execute();
73
92
  }
74
93
  // if the request fails we retry once, invalidating the cached value
75
- if (info &&
76
- info.code >= 400 &&
77
- this.cachedVariables.length > 0 &&
78
- !this.hasRerun) {
94
+ if (info && info.code >= 400 && !this.hasRerun) {
95
+ if (((_a = this.ctx.user) === null || _a === void 0 ? void 0 : _a.provider) &&
96
+ info.code === 401 &&
97
+ !this.hasRefreshedOAuth) {
98
+ // Attempt to refresh the access token from the provider
99
+ this.hasRefreshedOAuth = true;
100
+ const authResponse = yield this.refreshOAuth2(this.ctx);
101
+ if (!authResponse || authResponse.err) {
102
+ // In this event the user may have oAuth issues that
103
+ // could require re-authenticating with their provider.
104
+ throw new Error("OAuth2 access token could not be refreshed");
105
+ }
106
+ }
79
107
  this.hasRerun = true;
80
- // invalidate the cache value
81
108
  yield threadUtils.invalidateDynamicVariables(this.cachedVariables);
82
109
  return this.execute();
83
110
  }
@@ -115,6 +142,24 @@ class QueryRunner {
115
142
  }, { noRecursiveQuery: true }).execute();
116
143
  });
117
144
  }
145
+ refreshOAuth2(ctx) {
146
+ return __awaiter(this, void 0, void 0, function* () {
147
+ const { oauth2, providerType, _id } = ctx.user;
148
+ const { configId } = ctx.auth;
149
+ if (!providerType || !(oauth2 === null || oauth2 === void 0 ? void 0 : oauth2.refreshToken)) {
150
+ console.error("No refresh token found for authenticated user");
151
+ return;
152
+ }
153
+ const resp = yield refreshOAuthToken(oauth2.refreshToken, providerType, configId);
154
+ // Refresh session flow. Should be in same location as refreshOAuthToken
155
+ // There are several other properties available in 'resp'
156
+ if (!resp.error) {
157
+ const globalUserId = getGlobalIDFromUserMetadataID(_id);
158
+ yield updateUserOAuth(globalUserId, resp);
159
+ }
160
+ return resp;
161
+ });
162
+ }
118
163
  getDynamicVariable(variable) {
119
164
  return __awaiter(this, void 0, void 0, function* () {
120
165
  let { parameters } = this;