@budibase/server 0.9.140-alpha.1 → 0.9.140-alpha.5

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 (203) hide show
  1. package/builder/assets/{index.e8745f5e.js → index.80d850d1.js} +35 -35
  2. package/builder/assets/{vendor.d39b3c1e.js → vendor.820de34b.js} +10 -2
  3. package/builder/index.html +2 -2
  4. package/coverage/clover.xml +798 -530
  5. package/coverage/coverage-final.json +19 -16
  6. package/coverage/lcov-report/api/controllers/analytics.js.html +4 -4
  7. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  8. package/coverage/lcov-report/api/controllers/application.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 +1 -1
  11. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  12. package/coverage/lcov-report/api/controllers/component.js.html +1 -1
  13. package/coverage/lcov-report/api/controllers/datasource.js.html +3 -3
  14. package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
  15. package/coverage/lcov-report/api/controllers/hosting.js.html +1 -1
  16. package/coverage/lcov-report/api/controllers/index.html +5 -5
  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/permission.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/query.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/role.js.html +1 -1
  23. package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
  24. package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
  25. package/coverage/lcov-report/api/controllers/row/index.html +34 -19
  26. package/coverage/lcov-report/api/controllers/row/index.js.html +1 -1
  27. package/coverage/lcov-report/api/controllers/row/internal.js.html +242 -47
  28. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1244 -0
  29. package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
  30. package/coverage/lcov-report/api/controllers/screen.js.html +1 -1
  31. package/coverage/lcov-report/api/controllers/script.js.html +1 -1
  32. package/coverage/lcov-report/api/controllers/table/index.html +1 -1
  33. package/coverage/lcov-report/api/controllers/table/index.js.html +2 -2
  34. package/coverage/lcov-report/api/controllers/table/utils.js.html +31 -19
  35. package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
  36. package/coverage/lcov-report/api/controllers/user.js.html +1 -1
  37. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  38. package/coverage/lcov-report/api/controllers/view/index.html +32 -17
  39. package/coverage/lcov-report/api/controllers/view/index.js.html +84 -186
  40. package/coverage/lcov-report/api/controllers/view/utils.js.html +407 -0
  41. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
  42. package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
  43. package/coverage/lcov-report/api/index.html +1 -1
  44. package/coverage/lcov-report/api/index.js.html +1 -1
  45. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  46. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  47. package/coverage/lcov-report/api/routes/application.js.html +1 -1
  48. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  49. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  50. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  51. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  52. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  53. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/dev.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/hosting.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/index.html +1 -1
  57. package/coverage/lcov-report/api/routes/index.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/query.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/row.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/static.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/view.js.html +1 -1
  73. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  74. package/coverage/lcov-report/automations/actions.js.html +1 -1
  75. package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
  76. package/coverage/lcov-report/automations/bullboard.js.html +1 -1
  77. package/coverage/lcov-report/automations/index.html +1 -1
  78. package/coverage/lcov-report/automations/index.js.html +1 -1
  79. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  80. package/coverage/lcov-report/automations/steps/createRow.js.html +10 -19
  81. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  82. package/coverage/lcov-report/automations/steps/deleteRow.js.html +14 -20
  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 +1 -1
  87. package/coverage/lcov-report/automations/steps/index.html +31 -31
  88. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  89. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
  90. package/coverage/lcov-report/automations/steps/queryRows.js.html +18 -27
  91. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  94. package/coverage/lcov-report/automations/steps/updateRow.js.html +12 -21
  95. package/coverage/lcov-report/automations/steps/utils.js.html +23 -23
  96. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  97. package/coverage/lcov-report/automations/thread.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 +1 -1
  107. package/coverage/lcov-report/automations/utils.js.html +1 -1
  108. package/coverage/lcov-report/constants/index.html +1 -1
  109. package/coverage/lcov-report/constants/index.js.html +1 -1
  110. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  111. package/coverage/lcov-report/constants/screens.js.html +1 -1
  112. package/coverage/lcov-report/db/client.js.html +1 -1
  113. package/coverage/lcov-report/db/inMemoryView.js.html +224 -0
  114. package/coverage/lcov-report/db/index.html +34 -19
  115. package/coverage/lcov-report/db/index.js.html +1 -1
  116. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +4 -4
  117. package/coverage/lcov-report/db/linkedRows/index.html +14 -14
  118. package/coverage/lcov-report/db/linkedRows/index.js.html +18 -9
  119. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
  120. package/coverage/lcov-report/db/newid.js.html +1 -1
  121. package/coverage/lcov-report/db/utils.js.html +37 -10
  122. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  123. package/coverage/lcov-report/events/index.html +1 -1
  124. package/coverage/lcov-report/events/index.js.html +1 -1
  125. package/coverage/lcov-report/events/utils.js.html +1 -1
  126. package/coverage/lcov-report/index.html +68 -68
  127. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  128. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  129. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  130. package/coverage/lcov-report/middleware/authorized.js.html +1 -1
  131. package/coverage/lcov-report/middleware/builder.js.html +1 -1
  132. package/coverage/lcov-report/middleware/currentapp.js.html +1 -1
  133. package/coverage/lcov-report/middleware/index.html +1 -1
  134. package/coverage/lcov-report/middleware/joi-validator.js.html +1 -1
  135. package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
  136. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  137. package/coverage/lcov-report/middleware/usageQuota.js.html +1 -1
  138. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  139. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  140. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  141. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  142. package/coverage/lcov-report/utilities/global.js.html +1 -1
  143. package/coverage/lcov-report/utilities/index.html +1 -1
  144. package/coverage/lcov-report/utilities/index.js.html +1 -1
  145. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +1 -1
  146. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  147. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  148. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  149. package/coverage/lcov-report/utilities/rowProcessor/index.html +15 -15
  150. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +58 -13
  151. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
  152. package/coverage/lcov-report/utilities/security.js.html +2 -2
  153. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  154. package/coverage/lcov-report/utilities/users.js.html +1 -1
  155. package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
  156. package/coverage/lcov.info +1405 -886
  157. package/dist/api/controllers/analytics.js +1 -1
  158. package/dist/api/controllers/datasource.js +2 -2
  159. package/dist/api/controllers/row/ExternalRequest.js +4 -0
  160. package/dist/api/controllers/row/internal.js +97 -23
  161. package/dist/api/controllers/table/index.js +1 -1
  162. package/dist/api/controllers/table/utils.js +13 -11
  163. package/dist/api/controllers/view/index.js +74 -96
  164. package/dist/api/controllers/view/utils.js +102 -0
  165. package/dist/automations/steps/createRow.js +5 -8
  166. package/dist/automations/steps/deleteRow.js +7 -10
  167. package/dist/automations/steps/queryRows.js +11 -14
  168. package/dist/automations/steps/updateRow.js +4 -7
  169. package/dist/db/inMemoryView.js +51 -0
  170. package/dist/db/linkedRows/index.js +5 -2
  171. package/dist/db/utils.js +7 -0
  172. package/dist/environment.js +7 -1
  173. package/dist/integrations/mysql.js +2 -13
  174. package/dist/integrations/postgres.js +8 -14
  175. package/dist/integrations/utils.js +19 -1
  176. package/dist/package.json +10 -12
  177. package/dist/tsconfig.tsbuildinfo +1 -1
  178. package/dist/utilities/rowProcessor/index.js +10 -5
  179. package/package.json +11 -13
  180. package/scripts/integrations/service-vehicles/docker-compose.yml +28 -0
  181. package/scripts/integrations/service-vehicles/init.sql +52 -0
  182. package/scripts/integrations/service-vehicles/reset.sh +3 -0
  183. package/src/api/controllers/analytics.js +1 -1
  184. package/src/api/controllers/datasource.js +2 -2
  185. package/src/api/controllers/row/ExternalRequest.ts +5 -1
  186. package/src/api/controllers/row/internal.js +88 -23
  187. package/src/api/controllers/table/index.js +1 -1
  188. package/src/api/controllers/table/utils.js +16 -12
  189. package/src/api/controllers/view/index.js +82 -116
  190. package/src/api/controllers/view/utils.js +109 -0
  191. package/src/api/routes/tests/view.spec.js +1 -1
  192. package/src/automations/steps/createRow.js +5 -8
  193. package/src/automations/steps/deleteRow.js +8 -10
  194. package/src/automations/steps/queryRows.js +11 -14
  195. package/src/automations/steps/updateRow.js +7 -10
  196. package/src/db/inMemoryView.js +48 -0
  197. package/src/db/linkedRows/index.js +5 -2
  198. package/src/db/utils.js +9 -0
  199. package/src/environment.js +8 -1
  200. package/src/integrations/mysql.ts +2 -13
  201. package/src/integrations/postgres.ts +9 -16
  202. package/src/integrations/utils.ts +18 -0
  203. package/src/utilities/rowProcessor/index.js +20 -5
@@ -12,7 +12,7 @@ const env = require("../../environment");
12
12
  exports.isEnabled = function (ctx) {
13
13
  return __awaiter(this, void 0, void 0, function* () {
14
14
  ctx.body = {
15
- enabled: env.ENABLE_ANALYTICS === "true",
15
+ enabled: !env.SELF_HOSTED && env.ENABLE_ANALYTICS === "true",
16
16
  };
17
17
  });
18
18
  };
@@ -39,7 +39,7 @@ exports.buildSchemaFromDb = function (ctx) {
39
39
  const connector = new Connector(datasource.config);
40
40
  yield connector.buildSchema(datasource._id, datasource.entities);
41
41
  datasource.entities = connector.tables;
42
- const response = yield db.post(datasource);
42
+ const response = yield db.put(datasource);
43
43
  datasource._rev = response.rev;
44
44
  ctx.body = datasource;
45
45
  });
@@ -69,7 +69,7 @@ exports.save = function (ctx) {
69
69
  const db = new CouchDB(ctx.appId);
70
70
  const plus = ctx.request.body.plus;
71
71
  const datasource = Object.assign({ _id: generateDatasourceID({ plus }), type: plus ? DocumentTypes.DATASOURCE_PLUS : DocumentTypes.DATASOURCE }, ctx.request.body);
72
- const response = yield db.post(datasource);
72
+ const response = yield db.put(datasource);
73
73
  datasource._rev = response.rev;
74
74
  // Drain connection pools when configuration is changed
75
75
  if (datasource.source) {
@@ -368,6 +368,10 @@ var External;
368
368
  // finally cleanup anything that needs to be removed
369
369
  for (let [colName, { isMany, rows, tableId }] of Object.entries(related)) {
370
370
  const table = this.getTable(tableId);
371
+ // if its not the foreign key skip it, nothing to do
372
+ if (table.primary && table.primary.indexOf(colName) !== -1) {
373
+ continue;
374
+ }
371
375
  for (let row of rows) {
372
376
  const filters = buildFilters(generateIdForRow(row, table), {}, table);
373
377
  // safety check, if there are no filters on deletion bad things happen
@@ -21,14 +21,17 @@ var __rest = (this && this.__rest) || function (s, e) {
21
21
  };
22
22
  const CouchDB = require("../../../db");
23
23
  const linkRows = require("../../../db/linkedRows");
24
- const { getRowParams, generateRowID, DocumentTypes, InternalTables, } = require("../../../db/utils");
24
+ const { getRowParams, generateRowID, DocumentTypes, InternalTables, generateMemoryViewID, } = require("../../../db/utils");
25
25
  const userController = require("../user");
26
- const { inputProcessing, outputProcessing, } = require("../../../utilities/rowProcessor");
26
+ const { inputProcessing, outputProcessing, processAutoColumn, } = require("../../../utilities/rowProcessor");
27
27
  const { FieldTypes } = require("../../../constants");
28
28
  const { isEqual } = require("lodash");
29
29
  const { validate, findRow } = require("./utils");
30
30
  const { fullSearch, paginatedSearch } = require("./internalSearch");
31
31
  const { getGlobalUsersFromMetadata } = require("../../../utilities/global");
32
+ const inMemoryViews = require("../../../db/inMemoryView");
33
+ const env = require("../../../environment");
34
+ const { migrateToInMemoryView } = require("../view/utils");
32
35
  const CALCULATION_TYPES = {
33
36
  SUM: "sum",
34
37
  COUNT: "count",
@@ -37,17 +40,92 @@ const CALCULATION_TYPES = {
37
40
  function storeResponse(ctx, db, row, oldTable, table) {
38
41
  return __awaiter(this, void 0, void 0, function* () {
39
42
  row.type = "row";
40
- const response = yield db.put(row);
41
43
  // don't worry about rev, tables handle rev/lastID updates
44
+ // if another row has been written since processing this will
45
+ // handle the auto ID clash
42
46
  if (!isEqual(oldTable, table)) {
43
- yield db.put(table);
47
+ try {
48
+ yield db.put(table);
49
+ }
50
+ catch (err) {
51
+ if (err.status === 409) {
52
+ const updatedTable = yield db.get(table._id);
53
+ let response = processAutoColumn(null, updatedTable, row, {
54
+ reprocessing: true,
55
+ });
56
+ yield db.put(response.table);
57
+ row = response.row;
58
+ }
59
+ else {
60
+ throw err;
61
+ }
62
+ }
44
63
  }
64
+ const response = yield db.put(row);
45
65
  row._rev = response.rev;
46
66
  // process the row before return, to include relationships
47
67
  row = yield outputProcessing(ctx, table, row, { squash: false });
48
68
  return { row, table };
49
69
  });
50
70
  }
71
+ // doesn't do the outputProcessing
72
+ function getRawTableData(ctx, db, tableId) {
73
+ return __awaiter(this, void 0, void 0, function* () {
74
+ let rows;
75
+ if (tableId === InternalTables.USER_METADATA) {
76
+ yield userController.fetchMetadata(ctx);
77
+ rows = ctx.body;
78
+ }
79
+ else {
80
+ const response = yield db.allDocs(getRowParams(tableId, null, {
81
+ include_docs: true,
82
+ }));
83
+ rows = response.rows.map(row => row.doc);
84
+ }
85
+ return rows;
86
+ });
87
+ }
88
+ function getView(db, viewName) {
89
+ return __awaiter(this, void 0, void 0, function* () {
90
+ let viewInfo;
91
+ function getFromDesignDoc() {
92
+ return __awaiter(this, void 0, void 0, function* () {
93
+ const designDoc = yield db.get("_design/database");
94
+ viewInfo = designDoc.views[viewName];
95
+ return viewInfo;
96
+ });
97
+ }
98
+ let migrate = false;
99
+ if (env.SELF_HOSTED) {
100
+ viewInfo = yield getFromDesignDoc();
101
+ }
102
+ else {
103
+ try {
104
+ viewInfo = yield db.get(generateMemoryViewID(viewName));
105
+ if (viewInfo) {
106
+ viewInfo = viewInfo.view;
107
+ }
108
+ }
109
+ catch (err) {
110
+ // check if it can be retrieved from design doc (needs migrated)
111
+ if (err.status !== 404) {
112
+ viewInfo = null;
113
+ }
114
+ else {
115
+ viewInfo = yield getFromDesignDoc();
116
+ migrate = !!viewInfo;
117
+ }
118
+ }
119
+ }
120
+ if (migrate) {
121
+ yield migrateToInMemoryView(db, viewName);
122
+ }
123
+ if (!viewInfo) {
124
+ throw "View does not exist.";
125
+ }
126
+ return viewInfo;
127
+ });
128
+ }
51
129
  exports.patch = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
52
130
  const appId = ctx.appId;
53
131
  const db = new CouchDB(appId);
@@ -142,15 +220,19 @@ exports.fetchView = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
142
220
  }
143
221
  const db = new CouchDB(appId);
144
222
  const { calculation, group, field } = ctx.query;
145
- const designDoc = yield db.get("_design/database");
146
- const viewInfo = designDoc.views[viewName];
147
- if (!viewInfo) {
148
- throw "View does not exist.";
223
+ const viewInfo = yield getView(db, viewName);
224
+ let response;
225
+ if (env.SELF_HOSTED) {
226
+ response = yield db.query(`database/${viewName}`, {
227
+ include_docs: !calculation,
228
+ group: !!group,
229
+ });
230
+ }
231
+ else {
232
+ const tableId = viewInfo.meta.tableId;
233
+ const data = yield getRawTableData(ctx, db, tableId);
234
+ response = yield inMemoryViews.runView(viewInfo, calculation, group, data);
149
235
  }
150
- const response = yield db.query(`database/${viewName}`, {
151
- include_docs: !calculation,
152
- group: !!group,
153
- });
154
236
  let rows;
155
237
  if (!calculation) {
156
238
  response.rows = response.rows.map(row => row.doc);
@@ -183,17 +265,9 @@ exports.fetchView = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
183
265
  exports.fetch = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
184
266
  const appId = ctx.appId;
185
267
  const db = new CouchDB(appId);
186
- let rows, table = yield db.get(ctx.params.tableId);
187
- if (ctx.params.tableId === InternalTables.USER_METADATA) {
188
- yield userController.fetchMetadata(ctx);
189
- rows = ctx.body;
190
- }
191
- else {
192
- const response = yield db.allDocs(getRowParams(ctx.params.tableId, null, {
193
- include_docs: true,
194
- }));
195
- rows = response.rows.map(row => row.doc);
196
- }
268
+ const tableId = ctx.params.tableId;
269
+ let table = yield db.get(tableId);
270
+ let rows = yield getRawTableData(ctx, db, tableId);
197
271
  return outputProcessing(ctx, table, rows);
198
272
  });
199
273
  exports.find = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
@@ -131,7 +131,7 @@ exports.save = function (ctx) {
131
131
  if (updatedRows && updatedRows.length !== 0) {
132
132
  yield db.bulkDocs(updatedRows);
133
133
  }
134
- const result = yield db.post(tableToSave);
134
+ const result = yield db.put(tableToSave);
135
135
  tableToSave._rev = result.rev;
136
136
  tableToSave = yield tableSaveFunctions.after(tableToSave);
137
137
  ctx.eventEmitter &&
@@ -65,21 +65,16 @@ exports.handleDataImport = (appId, user, table, dataImport) => __awaiter(void 0,
65
65
  if (dataImport && dataImport.csvString) {
66
66
  // Populate the table with rows imported from CSV in a bulk update
67
67
  const data = yield csvParser.transform(dataImport);
68
+ let finalData = [];
68
69
  for (let i = 0; i < data.length; i++) {
69
70
  let row = data[i];
70
71
  row._id = generateRowID(table._id);
71
72
  row.tableId = table._id;
72
- const processed = inputProcessing(user, table, row);
73
+ const processed = inputProcessing(user, table, row, {
74
+ noAutoRelationships: true,
75
+ });
73
76
  table = processed.table;
74
77
  row = processed.row;
75
- // make sure link rows are up to date
76
- row = yield linkRows.updateLinks({
77
- appId,
78
- eventType: linkRows.EventType.ROW_SAVE,
79
- row,
80
- tableId: row.tableId,
81
- table,
82
- });
83
78
  for (let [fieldName, schema] of Object.entries(table.schema)) {
84
79
  // check whether the options need to be updated for inclusion as part of the data import
85
80
  if (schema.type === FieldTypes.OPTIONS &&
@@ -91,9 +86,16 @@ exports.handleDataImport = (appId, user, table, dataImport) => __awaiter(void 0,
91
86
  ];
92
87
  }
93
88
  }
94
- data[i] = row;
89
+ // make sure link rows are up to date
90
+ finalData.push(linkRows.updateLinks({
91
+ appId,
92
+ eventType: linkRows.EventType.ROW_SAVE,
93
+ row,
94
+ tableId: row.tableId,
95
+ table,
96
+ }));
95
97
  }
96
- yield db.bulkDocs(data);
98
+ yield db.bulkDocs(yield Promise.all(finalData));
97
99
  let response = yield db.put(table);
98
100
  table._rev = response._rev;
99
101
  }
@@ -23,100 +23,78 @@ const CouchDB = require("../../../db");
23
23
  const viewTemplate = require("./viewBuilder");
24
24
  const { apiFileReturn } = require("../../../utilities/fileSystem");
25
25
  const exporters = require("./exporters");
26
+ const { saveView, getView, getViews, deleteView } = require("./utils");
26
27
  const { fetchView } = require("../row");
27
- const { ViewNames } = require("../../../db/utils");
28
- const controller = {
29
- fetch: (ctx) => __awaiter(void 0, void 0, void 0, function* () {
30
- const db = new CouchDB(ctx.appId);
31
- const designDoc = yield db.get("_design/database");
32
- const response = [];
33
- for (let name of Object.keys(designDoc.views)) {
34
- // Only return custom views, not built ins
35
- if (Object.values(ViewNames).indexOf(name) !== -1) {
36
- continue;
37
- }
38
- response.push(Object.assign({ name }, designDoc.views[name]));
39
- }
40
- ctx.body = response;
41
- }),
42
- save: (ctx) => __awaiter(void 0, void 0, void 0, function* () {
43
- const db = new CouchDB(ctx.appId);
44
- const _a = ctx.request.body, { originalName } = _a, viewToSave = __rest(_a, ["originalName"]);
45
- const designDoc = yield db.get("_design/database");
46
- const view = viewTemplate(viewToSave);
47
- if (!viewToSave.name) {
48
- ctx.throw(400, "Cannot create view without a name");
49
- }
50
- designDoc.views = Object.assign(Object.assign({}, designDoc.views), { [viewToSave.name]: view });
51
- // view has been renamed
52
- if (originalName) {
53
- delete designDoc.views[originalName];
54
- }
55
- yield db.put(designDoc);
56
- // add views to table document
57
- const table = yield db.get(ctx.request.body.tableId);
58
- if (!table.views)
59
- table.views = {};
60
- if (!view.meta.schema) {
61
- view.meta.schema = table.schema;
62
- }
63
- table.views[viewToSave.name] = view.meta;
64
- if (originalName) {
65
- delete table.views[originalName];
66
- }
67
- yield db.put(table);
68
- ctx.body = Object.assign(Object.assign({}, table.views[viewToSave.name]), { name: viewToSave.name });
69
- }),
70
- destroy: (ctx) => __awaiter(void 0, void 0, void 0, function* () {
71
- const db = new CouchDB(ctx.appId);
72
- const designDoc = yield db.get("_design/database");
73
- const viewName = decodeURI(ctx.params.viewName);
74
- const view = designDoc.views[viewName];
75
- delete designDoc.views[viewName];
76
- yield db.put(designDoc);
77
- const table = yield db.get(view.meta.tableId);
78
- delete table.views[viewName];
79
- yield db.put(table);
80
- ctx.body = view;
81
- }),
82
- exportView: (ctx) => __awaiter(void 0, void 0, void 0, function* () {
83
- const db = new CouchDB(ctx.appId);
84
- const designDoc = yield db.get("_design/database");
85
- const viewName = decodeURI(ctx.query.view);
86
- const view = designDoc.views[viewName];
87
- const format = ctx.query.format;
88
- if (!format) {
89
- ctx.throw(400, "Format must be specified, either csv or json");
90
- }
91
- if (view) {
92
- ctx.params.viewName = viewName;
93
- // Fetch view rows
94
- ctx.query = {
95
- group: view.meta.groupBy,
96
- calculation: view.meta.calculation,
97
- stats: !!view.meta.field,
98
- field: view.meta.field,
99
- };
100
- }
101
- else {
102
- // table all_ view
103
- /* istanbul ignore next */
104
- ctx.params.viewName = viewName;
105
- }
106
- yield fetchView(ctx);
107
- let schema = view && view.meta && view.meta.schema;
108
- if (!schema) {
109
- const tableId = ctx.params.tableId || view.meta.tableId;
110
- const table = yield db.get(tableId);
111
- schema = table.schema;
112
- }
113
- // Export part
114
- let headers = Object.keys(schema);
115
- const exporter = exporters[format];
116
- const filename = `${viewName}.${format}`;
117
- // send down the file
118
- ctx.attachment(filename);
119
- ctx.body = apiFileReturn(exporter(headers, ctx.body));
120
- }),
121
- };
122
- module.exports = controller;
28
+ exports.fetch = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
29
+ const db = new CouchDB(ctx.appId);
30
+ ctx.body = yield getViews(db);
31
+ });
32
+ exports.save = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
33
+ const db = new CouchDB(ctx.appId);
34
+ const _a = ctx.request.body, { originalName } = _a, viewToSave = __rest(_a, ["originalName"]);
35
+ const view = viewTemplate(viewToSave);
36
+ if (!viewToSave.name) {
37
+ ctx.throw(400, "Cannot create view without a name");
38
+ }
39
+ yield saveView(db, originalName, viewToSave.name, view);
40
+ // add views to table document
41
+ const table = yield db.get(ctx.request.body.tableId);
42
+ if (!table.views)
43
+ table.views = {};
44
+ if (!view.meta.schema) {
45
+ view.meta.schema = table.schema;
46
+ }
47
+ table.views[viewToSave.name] = view.meta;
48
+ if (originalName) {
49
+ delete table.views[originalName];
50
+ }
51
+ yield db.put(table);
52
+ ctx.body = Object.assign(Object.assign({}, table.views[viewToSave.name]), { name: viewToSave.name });
53
+ });
54
+ exports.destroy = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
55
+ const db = new CouchDB(ctx.appId);
56
+ const viewName = decodeURI(ctx.params.viewName);
57
+ const view = yield deleteView(db, viewName);
58
+ const table = yield db.get(view.meta.tableId);
59
+ delete table.views[viewName];
60
+ yield db.put(table);
61
+ ctx.body = view;
62
+ });
63
+ exports.exportView = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
64
+ const db = new CouchDB(ctx.appId);
65
+ const viewName = decodeURI(ctx.query.view);
66
+ const view = yield getView(db, viewName);
67
+ const format = ctx.query.format;
68
+ if (!format) {
69
+ ctx.throw(400, "Format must be specified, either csv or json");
70
+ }
71
+ if (view) {
72
+ ctx.params.viewName = viewName;
73
+ // Fetch view rows
74
+ ctx.query = {
75
+ group: view.meta.groupBy,
76
+ calculation: view.meta.calculation,
77
+ stats: !!view.meta.field,
78
+ field: view.meta.field,
79
+ };
80
+ }
81
+ else {
82
+ // table all_ view
83
+ /* istanbul ignore next */
84
+ ctx.params.viewName = viewName;
85
+ }
86
+ yield fetchView(ctx);
87
+ let schema = view && view.meta && view.meta.schema;
88
+ if (!schema) {
89
+ const tableId = ctx.params.tableId || view.meta.tableId;
90
+ const table = yield db.get(tableId);
91
+ schema = table.schema;
92
+ }
93
+ // Export part
94
+ let headers = Object.keys(schema);
95
+ const exporter = exporters[format];
96
+ const filename = `${viewName}.${format}`;
97
+ // send down the file
98
+ ctx.attachment(filename);
99
+ ctx.body = apiFileReturn(exporter(headers, ctx.body));
100
+ });
@@ -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
+ const { ViewNames, generateMemoryViewID, getMemoryViewParams, } = require("../../../db/utils");
12
+ const env = require("../../../environment");
13
+ exports.getView = (db, viewName) => __awaiter(void 0, void 0, void 0, function* () {
14
+ if (env.SELF_HOSTED) {
15
+ const designDoc = yield db.get("_design/database");
16
+ return designDoc.views[viewName];
17
+ }
18
+ else {
19
+ const viewDoc = yield db.get(generateMemoryViewID(viewName));
20
+ return viewDoc.view;
21
+ }
22
+ });
23
+ exports.getViews = (db) => __awaiter(void 0, void 0, void 0, function* () {
24
+ const response = [];
25
+ if (env.SELF_HOSTED) {
26
+ const designDoc = yield db.get("_design/database");
27
+ for (let name of Object.keys(designDoc.views)) {
28
+ // Only return custom views, not built ins
29
+ if (Object.values(ViewNames).indexOf(name) !== -1) {
30
+ continue;
31
+ }
32
+ response.push(Object.assign({ name }, designDoc.views[name]));
33
+ }
34
+ }
35
+ else {
36
+ const views = (yield db.allDocs(getMemoryViewParams({
37
+ include_docs: true,
38
+ }))).rows.map(row => row.doc);
39
+ for (let viewDoc of views) {
40
+ response.push(Object.assign({ name: viewDoc.name }, viewDoc.view));
41
+ }
42
+ }
43
+ return response;
44
+ });
45
+ exports.saveView = (db, originalName, viewName, viewTemplate) => __awaiter(void 0, void 0, void 0, function* () {
46
+ if (env.SELF_HOSTED) {
47
+ const designDoc = yield db.get("_design/database");
48
+ designDoc.views = Object.assign(Object.assign({}, designDoc.views), { [viewName]: viewTemplate });
49
+ // view has been renamed
50
+ if (originalName) {
51
+ delete designDoc.views[originalName];
52
+ }
53
+ yield db.put(designDoc);
54
+ }
55
+ else {
56
+ const id = generateMemoryViewID(viewName);
57
+ const originalId = originalName ? generateMemoryViewID(originalName) : null;
58
+ const viewDoc = {
59
+ _id: id,
60
+ view: viewTemplate,
61
+ name: viewName,
62
+ tableId: viewTemplate.meta.tableId,
63
+ };
64
+ try {
65
+ const old = yield db.get(id);
66
+ if (originalId) {
67
+ const originalDoc = yield db.get(originalId);
68
+ yield db.remove(originalDoc._id, originalDoc._rev);
69
+ }
70
+ if (old && old._rev) {
71
+ viewDoc._rev = old._rev;
72
+ }
73
+ }
74
+ catch (err) {
75
+ // didn't exist, just skip
76
+ }
77
+ yield db.put(viewDoc);
78
+ }
79
+ });
80
+ exports.deleteView = (db, viewName) => __awaiter(void 0, void 0, void 0, function* () {
81
+ if (env.SELF_HOSTED) {
82
+ const designDoc = yield db.get("_design/database");
83
+ const view = designDoc.views[viewName];
84
+ delete designDoc.views[viewName];
85
+ yield db.put(designDoc);
86
+ return view;
87
+ }
88
+ else {
89
+ const id = generateMemoryViewID(viewName);
90
+ const viewDoc = yield db.get(id);
91
+ yield db.remove(viewDoc._id, viewDoc._rev);
92
+ return viewDoc.view;
93
+ }
94
+ });
95
+ exports.migrateToInMemoryView = (db, viewName) => __awaiter(void 0, void 0, void 0, function* () {
96
+ // delete the view initially
97
+ const designDoc = yield db.get("_design/database");
98
+ const view = designDoc.views[viewName];
99
+ delete designDoc.views[viewName];
100
+ yield db.put(designDoc);
101
+ yield exports.saveView(db, null, viewName, view);
102
+ });
@@ -12,6 +12,7 @@ const rowController = require("../../api/controllers/row");
12
12
  const automationUtils = require("../automationUtils");
13
13
  const env = require("../../environment");
14
14
  const usage = require("../../utilities/usageQuota");
15
+ const { buildCtx } = require("./utils");
15
16
  exports.definition = {
16
17
  name: "Create Row",
17
18
  tagline: "Create a {{inputs.enriched.table.name}} row",
@@ -78,19 +79,15 @@ exports.run = function ({ inputs, appId, apiKey, emitter }) {
78
79
  };
79
80
  }
80
81
  // have to clean up the row, remove the table from it
81
- const ctx = {
82
+ const ctx = buildCtx(appId, emitter, {
83
+ body: inputs.row,
82
84
  params: {
83
85
  tableId: inputs.row.tableId,
84
86
  },
85
- request: {
86
- body: inputs.row,
87
- },
88
- appId,
89
- eventEmitter: emitter,
90
- };
87
+ });
91
88
  try {
92
89
  inputs.row = yield automationUtils.cleanUpRow(appId, inputs.row.tableId, inputs.row);
93
- if (env.isProd()) {
90
+ if (env.USE_QUOTAS) {
94
91
  yield usage.update(apiKey, usage.Properties.ROW, 1);
95
92
  }
96
93
  yield rowController.save(ctx);
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  const rowController = require("../../api/controllers/row");
12
12
  const env = require("../../environment");
13
13
  const usage = require("../../utilities/usageQuota");
14
+ const { buildCtx } = require("./utils");
14
15
  exports.definition = {
15
16
  description: "Delete a row from your database",
16
17
  icon: "TableRowRemoveCenter",
@@ -69,19 +70,15 @@ exports.run = function ({ inputs, appId, apiKey, emitter }) {
69
70
  },
70
71
  };
71
72
  }
72
- let ctx = {
73
+ let ctx = buildCtx(appId, emitter, {
74
+ body: {
75
+ _id: inputs.id,
76
+ _rev: inputs.revision,
77
+ },
73
78
  params: {
74
79
  tableId: inputs.tableId,
75
80
  },
76
- request: {
77
- body: {
78
- _id: inputs.id,
79
- _rev: inputs.revision,
80
- },
81
- },
82
- appId,
83
- eventEmitter: emitter,
84
- };
81
+ });
85
82
  try {
86
83
  if (env.isProd()) {
87
84
  yield usage.update(apiKey, usage.Properties.ROW, -1);
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  const rowController = require("../../api/controllers/row");
12
12
  const tableController = require("../../api/controllers/table");
13
13
  const { FieldTypes } = require("../../constants");
14
+ const { buildCtx } = require("./utils");
14
15
  const SortOrders = {
15
16
  ASCENDING: "ascending",
16
17
  DESCENDING: "descending",
@@ -77,12 +78,11 @@ exports.definition = {
77
78
  };
78
79
  function getTable(appId, tableId) {
79
80
  return __awaiter(this, void 0, void 0, function* () {
80
- const ctx = {
81
+ const ctx = buildCtx(appId, null, {
81
82
  params: {
82
83
  id: tableId,
83
84
  },
84
- appId,
85
- };
85
+ });
86
86
  yield tableController.find(ctx);
87
87
  return ctx.body;
88
88
  });
@@ -97,21 +97,18 @@ exports.run = function ({ inputs, appId }) {
97
97
  sortType =
98
98
  fieldType === FieldTypes.NUMBER ? FieldTypes.NUMBER : FieldTypes.STRING;
99
99
  }
100
- const ctx = {
100
+ const ctx = buildCtx(appId, null, {
101
101
  params: {
102
102
  tableId,
103
103
  },
104
- request: {
105
- body: {
106
- sortOrder,
107
- sortType,
108
- sort: sortColumn,
109
- query: filters || {},
110
- limit,
111
- },
104
+ body: {
105
+ sortOrder,
106
+ sortType,
107
+ sort: sortColumn,
108
+ query: filters || {},
109
+ limit,
112
110
  },
113
- appId,
114
- };
111
+ });
115
112
  try {
116
113
  yield rowController.search(ctx);
117
114
  return {