@budibase/server 2.2.12-alpha.20 → 2.2.12-alpha.21

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 (374) hide show
  1. package/builder/assets/{index.fa480d5b.css → index.34817feb.css} +1 -1
  2. package/builder/assets/{index.35af2c9c.js → index.61dfdc1c.js} +245 -244
  3. package/builder/index.html +2 -2
  4. package/coverage/clover.xml +772 -771
  5. package/coverage/coverage-final.json +40 -40
  6. package/coverage/lcov-report/index.html +55 -55
  7. package/coverage/lcov-report/src/api/controllers/analytics.ts.html +1 -1
  8. package/coverage/lcov-report/src/api/controllers/apikeys.ts.html +1 -1
  9. package/coverage/lcov-report/src/api/controllers/application.ts.html +56 -56
  10. package/coverage/lcov-report/src/api/controllers/auth.ts.html +1 -1
  11. package/coverage/lcov-report/src/api/controllers/automation.ts.html +1 -1
  12. package/coverage/lcov-report/src/api/controllers/backup.ts.html +1 -1
  13. package/coverage/lcov-report/src/api/controllers/cloud.ts.html +1 -1
  14. package/coverage/lcov-report/src/api/controllers/component.ts.html +1 -1
  15. package/coverage/lcov-report/src/api/controllers/datasource.ts.html +1 -1
  16. package/coverage/lcov-report/src/api/controllers/deploy/Deployment.ts.html +12 -12
  17. package/coverage/lcov-report/src/api/controllers/deploy/index.html +1 -1
  18. package/coverage/lcov-report/src/api/controllers/deploy/index.ts.html +69 -69
  19. package/coverage/lcov-report/src/api/controllers/dev.ts.html +1 -1
  20. package/coverage/lcov-report/src/api/controllers/index.html +1 -1
  21. package/coverage/lcov-report/src/api/controllers/integration.ts.html +1 -1
  22. package/coverage/lcov-report/src/api/controllers/layout.ts.html +1 -1
  23. package/coverage/lcov-report/src/api/controllers/metadata.ts.html +1 -1
  24. package/coverage/lcov-report/src/api/controllers/migrations.ts.html +1 -1
  25. package/coverage/lcov-report/src/api/controllers/permission.ts.html +1 -1
  26. package/coverage/lcov-report/src/api/controllers/plugin/file.ts.html +1 -1
  27. package/coverage/lcov-report/src/api/controllers/plugin/github.ts.html +1 -1
  28. package/coverage/lcov-report/src/api/controllers/plugin/index.html +1 -1
  29. package/coverage/lcov-report/src/api/controllers/plugin/index.ts.html +1 -1
  30. package/coverage/lcov-report/src/api/controllers/plugin/npm.ts.html +1 -1
  31. package/coverage/lcov-report/src/api/controllers/plugin/uploaders.ts.html +1 -1
  32. package/coverage/lcov-report/src/api/controllers/plugin/url.ts.html +1 -1
  33. package/coverage/lcov-report/src/api/controllers/plugin/utils.ts.html +1 -1
  34. package/coverage/lcov-report/src/api/controllers/public/applications.ts.html +1 -1
  35. package/coverage/lcov-report/src/api/controllers/public/index.html +1 -1
  36. package/coverage/lcov-report/src/api/controllers/public/mapping/applications.ts.html +1 -1
  37. package/coverage/lcov-report/src/api/controllers/public/mapping/index.html +1 -1
  38. package/coverage/lcov-report/src/api/controllers/public/mapping/index.ts.html +1 -1
  39. package/coverage/lcov-report/src/api/controllers/public/mapping/queries.ts.html +1 -1
  40. package/coverage/lcov-report/src/api/controllers/public/mapping/rows.ts.html +1 -1
  41. package/coverage/lcov-report/src/api/controllers/public/mapping/tables.ts.html +1 -1
  42. package/coverage/lcov-report/src/api/controllers/public/mapping/users.ts.html +1 -1
  43. package/coverage/lcov-report/src/api/controllers/public/queries.ts.html +1 -1
  44. package/coverage/lcov-report/src/api/controllers/public/rows.ts.html +1 -1
  45. package/coverage/lcov-report/src/api/controllers/public/tables.ts.html +1 -1
  46. package/coverage/lcov-report/src/api/controllers/public/users.ts.html +1 -1
  47. package/coverage/lcov-report/src/api/controllers/public/utils.ts.html +1 -1
  48. package/coverage/lcov-report/src/api/controllers/query/import/index.html +1 -1
  49. package/coverage/lcov-report/src/api/controllers/query/import/index.ts.html +1 -1
  50. package/coverage/lcov-report/src/api/controllers/query/import/sources/base/index.html +1 -1
  51. package/coverage/lcov-report/src/api/controllers/query/import/sources/base/index.ts.html +1 -1
  52. package/coverage/lcov-report/src/api/controllers/query/import/sources/base/openapi.ts.html +1 -1
  53. package/coverage/lcov-report/src/api/controllers/query/import/sources/curl.ts.html +1 -1
  54. package/coverage/lcov-report/src/api/controllers/query/import/sources/index.html +1 -1
  55. package/coverage/lcov-report/src/api/controllers/query/import/sources/openapi2.ts.html +1 -1
  56. package/coverage/lcov-report/src/api/controllers/query/import/sources/openapi3.ts.html +1 -1
  57. package/coverage/lcov-report/src/api/controllers/query/index.html +1 -1
  58. package/coverage/lcov-report/src/api/controllers/query/index.ts.html +1 -1
  59. package/coverage/lcov-report/src/api/controllers/query/validation.ts.html +1 -1
  60. package/coverage/lcov-report/src/api/controllers/role.ts.html +1 -1
  61. package/coverage/lcov-report/src/api/controllers/routing.ts.html +1 -1
  62. package/coverage/lcov-report/src/api/controllers/row/ExternalRequest.ts.html +1 -1
  63. package/coverage/lcov-report/src/api/controllers/row/external.ts.html +1 -1
  64. package/coverage/lcov-report/src/api/controllers/row/index.html +15 -15
  65. package/coverage/lcov-report/src/api/controllers/row/index.ts.html +1 -1
  66. package/coverage/lcov-report/src/api/controllers/row/internal.ts.html +23 -20
  67. package/coverage/lcov-report/src/api/controllers/row/internalSearch.ts.html +1 -1
  68. package/coverage/lcov-report/src/api/controllers/row/staticFormula.ts.html +1 -1
  69. package/coverage/lcov-report/src/api/controllers/row/utils.ts.html +1 -1
  70. package/coverage/lcov-report/src/api/controllers/screen.ts.html +1 -1
  71. package/coverage/lcov-report/src/api/controllers/script.ts.html +1 -1
  72. package/coverage/lcov-report/src/api/controllers/static/index.html +1 -1
  73. package/coverage/lcov-report/src/api/controllers/static/index.ts.html +1 -1
  74. package/coverage/lcov-report/src/api/controllers/table/bulkFormula.ts.html +1 -1
  75. package/coverage/lcov-report/src/api/controllers/table/external.ts.html +17 -17
  76. package/coverage/lcov-report/src/api/controllers/table/index.html +33 -33
  77. package/coverage/lcov-report/src/api/controllers/table/index.ts.html +122 -35
  78. package/coverage/lcov-report/src/api/controllers/table/internal.ts.html +5 -5
  79. package/coverage/lcov-report/src/api/controllers/table/utils.ts.html +23 -26
  80. package/coverage/lcov-report/src/api/controllers/templates.ts.html +1 -1
  81. package/coverage/lcov-report/src/api/controllers/user.ts.html +1 -1
  82. package/coverage/lcov-report/src/api/controllers/view/exporters.ts.html +61 -16
  83. package/coverage/lcov-report/src/api/controllers/view/index.html +28 -28
  84. package/coverage/lcov-report/src/api/controllers/view/index.ts.html +52 -25
  85. package/coverage/lcov-report/src/api/controllers/view/utils.ts.html +1 -1
  86. package/coverage/lcov-report/src/api/controllers/view/viewBuilder.ts.html +1 -1
  87. package/coverage/lcov-report/src/api/controllers/webhook.ts.html +1 -1
  88. package/coverage/lcov-report/src/api/index.html +1 -1
  89. package/coverage/lcov-report/src/api/index.ts.html +5 -5
  90. package/coverage/lcov-report/src/api/routes/analytics.ts.html +1 -1
  91. package/coverage/lcov-report/src/api/routes/apikeys.ts.html +1 -1
  92. package/coverage/lcov-report/src/api/routes/application.ts.html +1 -1
  93. package/coverage/lcov-report/src/api/routes/auth.ts.html +1 -1
  94. package/coverage/lcov-report/src/api/routes/automation.ts.html +1 -1
  95. package/coverage/lcov-report/src/api/routes/backup.ts.html +1 -1
  96. package/coverage/lcov-report/src/api/routes/cloud.ts.html +1 -1
  97. package/coverage/lcov-report/src/api/routes/component.ts.html +1 -1
  98. package/coverage/lcov-report/src/api/routes/datasource.ts.html +1 -1
  99. package/coverage/lcov-report/src/api/routes/deploy.ts.html +1 -1
  100. package/coverage/lcov-report/src/api/routes/dev.ts.html +1 -1
  101. package/coverage/lcov-report/src/api/routes/index.html +1 -1
  102. package/coverage/lcov-report/src/api/routes/index.ts.html +1 -1
  103. package/coverage/lcov-report/src/api/routes/integration.ts.html +1 -1
  104. package/coverage/lcov-report/src/api/routes/layout.ts.html +1 -1
  105. package/coverage/lcov-report/src/api/routes/metadata.ts.html +1 -1
  106. package/coverage/lcov-report/src/api/routes/migrations.ts.html +1 -1
  107. package/coverage/lcov-report/src/api/routes/permission.ts.html +1 -1
  108. package/coverage/lcov-report/src/api/routes/plugin.ts.html +1 -1
  109. package/coverage/lcov-report/src/api/routes/public/applications.ts.html +1 -1
  110. package/coverage/lcov-report/src/api/routes/public/index.html +1 -1
  111. package/coverage/lcov-report/src/api/routes/public/index.ts.html +1 -1
  112. package/coverage/lcov-report/src/api/routes/public/middleware/index.html +1 -1
  113. package/coverage/lcov-report/src/api/routes/public/middleware/mapper.ts.html +1 -1
  114. package/coverage/lcov-report/src/api/routes/public/queries.ts.html +1 -1
  115. package/coverage/lcov-report/src/api/routes/public/rows.ts.html +1 -1
  116. package/coverage/lcov-report/src/api/routes/public/tables.ts.html +1 -1
  117. package/coverage/lcov-report/src/api/routes/public/tests/index.html +1 -1
  118. package/coverage/lcov-report/src/api/routes/public/tests/utils.ts.html +1 -1
  119. package/coverage/lcov-report/src/api/routes/public/users.ts.html +1 -1
  120. package/coverage/lcov-report/src/api/routes/public/utils/Endpoint.ts.html +1 -1
  121. package/coverage/lcov-report/src/api/routes/public/utils/index.html +1 -1
  122. package/coverage/lcov-report/src/api/routes/query.ts.html +1 -1
  123. package/coverage/lcov-report/src/api/routes/role.ts.html +1 -1
  124. package/coverage/lcov-report/src/api/routes/routing.ts.html +1 -1
  125. package/coverage/lcov-report/src/api/routes/row.ts.html +1 -1
  126. package/coverage/lcov-report/src/api/routes/screen.ts.html +1 -1
  127. package/coverage/lcov-report/src/api/routes/script.ts.html +1 -1
  128. package/coverage/lcov-report/src/api/routes/static.ts.html +1 -1
  129. package/coverage/lcov-report/src/api/routes/table.ts.html +17 -86
  130. package/coverage/lcov-report/src/api/routes/templates.ts.html +1 -1
  131. package/coverage/lcov-report/src/api/routes/tests/utilities/TestFunctions.ts.html +1 -1
  132. package/coverage/lcov-report/src/api/routes/tests/utilities/index.html +1 -1
  133. package/coverage/lcov-report/src/api/routes/tests/utilities/index.ts.html +1 -1
  134. package/coverage/lcov-report/src/api/routes/user.ts.html +1 -1
  135. package/coverage/lcov-report/src/api/routes/utils/index.html +1 -1
  136. package/coverage/lcov-report/src/api/routes/utils/validators.ts.html +2 -2
  137. package/coverage/lcov-report/src/api/routes/view.ts.html +1 -1
  138. package/coverage/lcov-report/src/api/routes/webhook.ts.html +1 -1
  139. package/coverage/lcov-report/src/app.ts.html +1 -1
  140. package/coverage/lcov-report/src/automations/actions.ts.html +1 -1
  141. package/coverage/lcov-report/src/automations/automationUtils.ts.html +1 -1
  142. package/coverage/lcov-report/src/automations/bullboard.ts.html +2 -2
  143. package/coverage/lcov-report/src/automations/index.html +1 -1
  144. package/coverage/lcov-report/src/automations/index.ts.html +1 -1
  145. package/coverage/lcov-report/src/automations/logging/index.html +1 -1
  146. package/coverage/lcov-report/src/automations/logging/index.ts.html +1 -1
  147. package/coverage/lcov-report/src/automations/steps/bash.ts.html +1 -1
  148. package/coverage/lcov-report/src/automations/steps/createRow.ts.html +1 -1
  149. package/coverage/lcov-report/src/automations/steps/delay.ts.html +1 -1
  150. package/coverage/lcov-report/src/automations/steps/deleteRow.ts.html +1 -1
  151. package/coverage/lcov-report/src/automations/steps/discord.ts.html +1 -1
  152. package/coverage/lcov-report/src/automations/steps/executeQuery.ts.html +1 -1
  153. package/coverage/lcov-report/src/automations/steps/executeScript.ts.html +1 -1
  154. package/coverage/lcov-report/src/automations/steps/filter.ts.html +1 -1
  155. package/coverage/lcov-report/src/automations/steps/index.html +1 -1
  156. package/coverage/lcov-report/src/automations/steps/integromat.ts.html +1 -1
  157. package/coverage/lcov-report/src/automations/steps/loop.ts.html +1 -1
  158. package/coverage/lcov-report/src/automations/steps/outgoingWebhook.ts.html +1 -1
  159. package/coverage/lcov-report/src/automations/steps/queryRows.ts.html +1 -1
  160. package/coverage/lcov-report/src/automations/steps/sendSmtpEmail.ts.html +1 -1
  161. package/coverage/lcov-report/src/automations/steps/serverLog.ts.html +1 -1
  162. package/coverage/lcov-report/src/automations/steps/slack.ts.html +1 -1
  163. package/coverage/lcov-report/src/automations/steps/updateRow.ts.html +1 -1
  164. package/coverage/lcov-report/src/automations/steps/utils.ts.html +1 -1
  165. package/coverage/lcov-report/src/automations/steps/zapier.ts.html +1 -1
  166. package/coverage/lcov-report/src/automations/tests/utilities/index.html +1 -1
  167. package/coverage/lcov-report/src/automations/tests/utilities/index.ts.html +1 -1
  168. package/coverage/lcov-report/src/automations/triggerInfo/app.ts.html +1 -1
  169. package/coverage/lcov-report/src/automations/triggerInfo/cron.ts.html +1 -1
  170. package/coverage/lcov-report/src/automations/triggerInfo/index.html +1 -1
  171. package/coverage/lcov-report/src/automations/triggerInfo/index.ts.html +1 -1
  172. package/coverage/lcov-report/src/automations/triggerInfo/rowDeleted.ts.html +1 -1
  173. package/coverage/lcov-report/src/automations/triggerInfo/rowSaved.ts.html +1 -1
  174. package/coverage/lcov-report/src/automations/triggerInfo/rowUpdated.ts.html +1 -1
  175. package/coverage/lcov-report/src/automations/triggerInfo/webhook.ts.html +1 -1
  176. package/coverage/lcov-report/src/automations/triggers.ts.html +1 -1
  177. package/coverage/lcov-report/src/automations/utils.ts.html +11 -11
  178. package/coverage/lcov-report/src/constants/index.html +1 -1
  179. package/coverage/lcov-report/src/constants/index.ts.html +25 -25
  180. package/coverage/lcov-report/src/constants/layouts.ts.html +1 -1
  181. package/coverage/lcov-report/src/constants/screens.ts.html +1 -1
  182. package/coverage/lcov-report/src/db/defaultData/datasource_bb_default.ts.html +1 -1
  183. package/coverage/lcov-report/src/db/defaultData/employeeImport.ts.html +1 -1
  184. package/coverage/lcov-report/src/db/defaultData/expensesImport.ts.html +1 -1
  185. package/coverage/lcov-report/src/db/defaultData/index.html +1 -1
  186. package/coverage/lcov-report/src/db/defaultData/inventoryImport.ts.html +1 -1
  187. package/coverage/lcov-report/src/db/defaultData/jobsImport.ts.html +1 -1
  188. package/coverage/lcov-report/src/db/dynamoClient.ts.html +1 -1
  189. package/coverage/lcov-report/src/db/inMemoryView.ts.html +1 -1
  190. package/coverage/lcov-report/src/db/index.html +1 -1
  191. package/coverage/lcov-report/src/db/index.ts.html +1 -1
  192. package/coverage/lcov-report/src/db/linkedRows/LinkController.ts.html +1 -1
  193. package/coverage/lcov-report/src/db/linkedRows/LinkDocument.ts.html +1 -1
  194. package/coverage/lcov-report/src/db/linkedRows/index.html +1 -1
  195. package/coverage/lcov-report/src/db/linkedRows/index.ts.html +1 -1
  196. package/coverage/lcov-report/src/db/linkedRows/linkUtils.ts.html +1 -1
  197. package/coverage/lcov-report/src/db/newid.ts.html +3 -3
  198. package/coverage/lcov-report/src/db/utils.ts.html +15 -15
  199. package/coverage/lcov-report/src/definitions/automations.ts.html +1 -1
  200. package/coverage/lcov-report/src/definitions/datasource.ts.html +1 -1
  201. package/coverage/lcov-report/src/definitions/index.html +1 -1
  202. package/coverage/lcov-report/src/environment.ts.html +19 -19
  203. package/coverage/lcov-report/src/events/AutomationEmitter.ts.html +1 -1
  204. package/coverage/lcov-report/src/events/BudibaseEmitter.ts.html +1 -1
  205. package/coverage/lcov-report/src/events/index.html +1 -1
  206. package/coverage/lcov-report/src/events/index.ts.html +1 -1
  207. package/coverage/lcov-report/src/events/utils.ts.html +1 -1
  208. package/coverage/lcov-report/src/index.html +1 -1
  209. package/coverage/lcov-report/src/index.ts.html +1 -1
  210. package/coverage/lcov-report/src/integrations/airtable.ts.html +1 -1
  211. package/coverage/lcov-report/src/integrations/arangodb.ts.html +1 -1
  212. package/coverage/lcov-report/src/integrations/base/index.html +1 -1
  213. package/coverage/lcov-report/src/integrations/base/query.ts.html +1 -1
  214. package/coverage/lcov-report/src/integrations/base/sql.ts.html +1 -1
  215. package/coverage/lcov-report/src/integrations/base/sqlTable.ts.html +1 -1
  216. package/coverage/lcov-report/src/integrations/base/utils.ts.html +1 -1
  217. package/coverage/lcov-report/src/integrations/couchdb.ts.html +1 -1
  218. package/coverage/lcov-report/src/integrations/dynamodb.ts.html +1 -1
  219. package/coverage/lcov-report/src/integrations/elasticsearch.ts.html +1 -1
  220. package/coverage/lcov-report/src/integrations/firebase.ts.html +1 -1
  221. package/coverage/lcov-report/src/integrations/googlesheets.ts.html +1 -1
  222. package/coverage/lcov-report/src/integrations/index.html +1 -1
  223. package/coverage/lcov-report/src/integrations/index.ts.html +1 -1
  224. package/coverage/lcov-report/src/integrations/microsoftSqlServer.ts.html +1 -1
  225. package/coverage/lcov-report/src/integrations/mongodb.ts.html +1 -1
  226. package/coverage/lcov-report/src/integrations/mysql.ts.html +1 -1
  227. package/coverage/lcov-report/src/integrations/oracle.ts.html +1 -1
  228. package/coverage/lcov-report/src/integrations/postgres.ts.html +1 -1
  229. package/coverage/lcov-report/src/integrations/queries/index.html +1 -1
  230. package/coverage/lcov-report/src/integrations/queries/sql.ts.html +1 -1
  231. package/coverage/lcov-report/src/integrations/redis.ts.html +1 -1
  232. package/coverage/lcov-report/src/integrations/rest.ts.html +1 -1
  233. package/coverage/lcov-report/src/integrations/s3.ts.html +1 -1
  234. package/coverage/lcov-report/src/integrations/snowflake.ts.html +1 -1
  235. package/coverage/lcov-report/src/integrations/tests/TestConfiguration.js.html +1 -1
  236. package/coverage/lcov-report/src/integrations/tests/index.html +1 -1
  237. package/coverage/lcov-report/src/integrations/utils.ts.html +1 -1
  238. package/coverage/lcov-report/src/middleware/appInfo.ts.html +1 -1
  239. package/coverage/lcov-report/src/middleware/authorized.ts.html +21 -21
  240. package/coverage/lcov-report/src/middleware/builder.ts.html +12 -12
  241. package/coverage/lcov-report/src/middleware/currentapp.ts.html +33 -33
  242. package/coverage/lcov-report/src/middleware/index.html +1 -1
  243. package/coverage/lcov-report/src/middleware/joi-validator.ts.html +1 -1
  244. package/coverage/lcov-report/src/middleware/publicApi.ts.html +1 -1
  245. package/coverage/lcov-report/src/middleware/resourceId.ts.html +1 -1
  246. package/coverage/lcov-report/src/middleware/selfhost.ts.html +1 -1
  247. package/coverage/lcov-report/src/middleware/utils.ts.html +3 -3
  248. package/coverage/lcov-report/src/migrations/functions/appUrls.ts.html +1 -1
  249. package/coverage/lcov-report/src/migrations/functions/backfill/app/automations.ts.html +1 -1
  250. package/coverage/lcov-report/src/migrations/functions/backfill/app/datasources.ts.html +1 -1
  251. package/coverage/lcov-report/src/migrations/functions/backfill/app/index.html +1 -1
  252. package/coverage/lcov-report/src/migrations/functions/backfill/app/layouts.ts.html +1 -1
  253. package/coverage/lcov-report/src/migrations/functions/backfill/app/queries.ts.html +1 -1
  254. package/coverage/lcov-report/src/migrations/functions/backfill/app/roles.ts.html +1 -1
  255. package/coverage/lcov-report/src/migrations/functions/backfill/app/screens.ts.html +1 -1
  256. package/coverage/lcov-report/src/migrations/functions/backfill/app/tables.ts.html +1 -1
  257. package/coverage/lcov-report/src/migrations/functions/backfill/app.ts.html +1 -1
  258. package/coverage/lcov-report/src/migrations/functions/backfill/global/configs.ts.html +1 -1
  259. package/coverage/lcov-report/src/migrations/functions/backfill/global/index.html +1 -1
  260. package/coverage/lcov-report/src/migrations/functions/backfill/global/quotas.ts.html +1 -1
  261. package/coverage/lcov-report/src/migrations/functions/backfill/global/users.ts.html +1 -1
  262. package/coverage/lcov-report/src/migrations/functions/backfill/global.ts.html +1 -1
  263. package/coverage/lcov-report/src/migrations/functions/backfill/index.html +1 -1
  264. package/coverage/lcov-report/src/migrations/functions/backfill/index.ts.html +1 -1
  265. package/coverage/lcov-report/src/migrations/functions/backfill/installation.ts.html +1 -1
  266. package/coverage/lcov-report/src/migrations/functions/index.html +1 -1
  267. package/coverage/lcov-report/src/migrations/functions/syncQuotas.ts.html +1 -1
  268. package/coverage/lcov-report/src/migrations/functions/tableSettings.ts.html +1 -1
  269. package/coverage/lcov-report/src/migrations/functions/usageQuotas/index.html +1 -1
  270. package/coverage/lcov-report/src/migrations/functions/usageQuotas/index.ts.html +1 -1
  271. package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncApps.ts.html +1 -1
  272. package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncPlugins.ts.html +1 -1
  273. package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncRows.ts.html +1 -1
  274. package/coverage/lcov-report/src/migrations/functions/userEmailViewCasing.ts.html +1 -1
  275. package/coverage/lcov-report/src/migrations/index.html +1 -1
  276. package/coverage/lcov-report/src/migrations/index.ts.html +1 -1
  277. package/coverage/lcov-report/src/migrations/tests/helpers.ts.html +1 -1
  278. package/coverage/lcov-report/src/migrations/tests/index.html +1 -1
  279. package/coverage/lcov-report/src/migrations/tests/structures.ts.html +1 -1
  280. package/coverage/lcov-report/src/sdk/app/applications/index.html +1 -1
  281. package/coverage/lcov-report/src/sdk/app/applications/index.ts.html +1 -1
  282. package/coverage/lcov-report/src/sdk/app/applications/sync.ts.html +18 -18
  283. package/coverage/lcov-report/src/sdk/app/applications/utils.ts.html +7 -7
  284. package/coverage/lcov-report/src/sdk/app/automations/index.html +1 -1
  285. package/coverage/lcov-report/src/sdk/app/automations/index.ts.html +1 -1
  286. package/coverage/lcov-report/src/sdk/app/automations/webhook.ts.html +1 -1
  287. package/coverage/lcov-report/src/sdk/app/backups/constants.ts.html +1 -1
  288. package/coverage/lcov-report/src/sdk/app/backups/exports.ts.html +1 -1
  289. package/coverage/lcov-report/src/sdk/app/backups/imports.ts.html +1 -1
  290. package/coverage/lcov-report/src/sdk/app/backups/index.html +1 -1
  291. package/coverage/lcov-report/src/sdk/app/backups/index.ts.html +1 -1
  292. package/coverage/lcov-report/src/sdk/app/backups/statistics.ts.html +1 -1
  293. package/coverage/lcov-report/src/sdk/app/rows/attachments.ts.html +1 -1
  294. package/coverage/lcov-report/src/sdk/app/rows/index.html +1 -1
  295. package/coverage/lcov-report/src/sdk/app/rows/index.ts.html +1 -1
  296. package/coverage/lcov-report/src/sdk/app/rows/rows.ts.html +1 -1
  297. package/coverage/lcov-report/src/sdk/app/tables/index.html +1 -1
  298. package/coverage/lcov-report/src/sdk/app/tables/index.ts.html +1 -1
  299. package/coverage/lcov-report/src/sdk/index.html +1 -1
  300. package/coverage/lcov-report/src/sdk/index.ts.html +2 -2
  301. package/coverage/lcov-report/src/sdk/users/index.html +1 -1
  302. package/coverage/lcov-report/src/sdk/users/index.ts.html +1 -1
  303. package/coverage/lcov-report/src/sdk/users/utils.ts.html +20 -20
  304. package/coverage/lcov-report/src/startup.ts.html +1 -1
  305. package/coverage/lcov-report/src/tests/utilities/TestConfiguration.ts.html +59 -59
  306. package/coverage/lcov-report/src/tests/utilities/controllers.ts.html +3 -3
  307. package/coverage/lcov-report/src/tests/utilities/index.html +1 -1
  308. package/coverage/lcov-report/src/tests/utilities/index.ts.html +1 -1
  309. package/coverage/lcov-report/src/tests/utilities/structures.ts.html +2 -2
  310. package/coverage/lcov-report/src/threads/automation.ts.html +1 -1
  311. package/coverage/lcov-report/src/threads/index.html +1 -1
  312. package/coverage/lcov-report/src/threads/index.ts.html +1 -1
  313. package/coverage/lcov-report/src/threads/query.ts.html +1 -1
  314. package/coverage/lcov-report/src/threads/utils.ts.html +1 -1
  315. package/coverage/lcov-report/src/utilities/budibaseDir.ts.html +3 -3
  316. package/coverage/lcov-report/src/utilities/centralPath.ts.html +2 -2
  317. package/coverage/lcov-report/src/utilities/fileSystem/app.ts.html +16 -16
  318. package/coverage/lcov-report/src/utilities/fileSystem/clientLibrary.ts.html +8 -8
  319. package/coverage/lcov-report/src/utilities/fileSystem/filesystem.ts.html +30 -30
  320. package/coverage/lcov-report/src/utilities/fileSystem/index.html +15 -15
  321. package/coverage/lcov-report/src/utilities/fileSystem/index.ts.html +6 -6
  322. package/coverage/lcov-report/src/utilities/fileSystem/plugin.ts.html +8 -8
  323. package/coverage/lcov-report/src/utilities/fileSystem/processor.ts.html +1 -1
  324. package/coverage/lcov-report/src/utilities/fileSystem/template.ts.html +7 -7
  325. package/coverage/lcov-report/src/utilities/global.ts.html +33 -33
  326. package/coverage/lcov-report/src/utilities/index.html +24 -24
  327. package/coverage/lcov-report/src/utilities/index.ts.html +4 -4
  328. package/coverage/lcov-report/src/utilities/redis.ts.html +1 -1
  329. package/coverage/lcov-report/src/utilities/routing/index.html +1 -1
  330. package/coverage/lcov-report/src/utilities/routing/index.ts.html +1 -1
  331. package/coverage/lcov-report/src/utilities/rowProcessor/index.html +1 -1
  332. package/coverage/lcov-report/src/utilities/rowProcessor/index.ts.html +1 -1
  333. package/coverage/lcov-report/src/utilities/rowProcessor/map.ts.html +1 -1
  334. package/coverage/lcov-report/src/utilities/rowProcessor/utils.ts.html +1 -1
  335. package/coverage/lcov-report/src/utilities/{csvParser.ts.html → schema.ts.html} +173 -233
  336. package/coverage/lcov-report/src/utilities/scriptRunner.ts.html +1 -1
  337. package/coverage/lcov-report/src/utilities/security.ts.html +1 -1
  338. package/coverage/lcov-report/src/utilities/usageQuota/index.html +1 -1
  339. package/coverage/lcov-report/src/utilities/usageQuota/rows.ts.html +1 -1
  340. package/coverage/lcov-report/src/utilities/usageQuota/usageQuoteReset.ts.html +1 -1
  341. package/coverage/lcov-report/src/utilities/users.ts.html +1 -1
  342. package/coverage/lcov-report/src/utilities/workerRequests.ts.html +1 -1
  343. package/coverage/lcov-report/src/watch.ts.html +1 -1
  344. package/coverage/lcov-report/src/websocket.ts.html +1 -1
  345. package/coverage/lcov.info +1303 -1267
  346. package/dist/api/controllers/row/internal.js +12 -8
  347. package/dist/api/controllers/table/external.js +8 -30
  348. package/dist/api/controllers/table/index.js +44 -15
  349. package/dist/api/controllers/table/internal.js +4 -4
  350. package/dist/api/controllers/table/utils.js +9 -9
  351. package/dist/api/controllers/view/exporters.js +22 -6
  352. package/dist/api/controllers/view/index.js +19 -34
  353. package/dist/api/routes/table.js +6 -37
  354. package/dist/api/routes/utils/validators.js +1 -1
  355. package/dist/package.json +6 -6
  356. package/dist/tsconfig.build.tsbuildinfo +1 -1
  357. package/dist/utilities/schema.js +108 -0
  358. package/package.json +7 -7
  359. package/src/api/controllers/row/internal.ts +10 -9
  360. package/src/api/controllers/table/external.ts +10 -10
  361. package/src/api/controllers/table/index.ts +46 -17
  362. package/src/api/controllers/table/internal.ts +4 -4
  363. package/src/api/controllers/table/utils.ts +12 -13
  364. package/src/api/controllers/view/exporters.ts +20 -5
  365. package/src/api/controllers/view/index.ts +21 -12
  366. package/src/api/routes/table.ts +15 -38
  367. package/src/api/routes/tests/misc.spec.js +4 -10
  368. package/src/api/routes/tests/table.spec.js +8 -30
  369. package/src/api/routes/utils/validators.ts +1 -1
  370. package/src/utilities/schema.ts +141 -0
  371. package/dist/utilities/csvParser.js +0 -152
  372. package/src/utilities/csvParser.ts +0 -161
  373. package/src/utilities/tests/__snapshots__/csvParser.spec.js.snap +0 -15
  374. package/src/utilities/tests/csvParser.spec.js +0 -112
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parse = exports.validate = exports.isRows = exports.isSchema = void 0;
4
+ const constants_1 = require("../constants");
5
+ const PARSERS = {
6
+ [constants_1.FieldTypes.NUMBER]: (attribute) => {
7
+ if (!attribute) {
8
+ return attribute;
9
+ }
10
+ return Number(attribute);
11
+ },
12
+ [constants_1.FieldTypes.DATETIME]: (attribute) => {
13
+ if (!attribute) {
14
+ return attribute;
15
+ }
16
+ return new Date(attribute).toISOString();
17
+ },
18
+ };
19
+ function isSchema(schema) {
20
+ return (typeof schema === "object" &&
21
+ Object.values(schema).every(rawColumn => {
22
+ const column = rawColumn;
23
+ return (column !== null &&
24
+ typeof column === "object" &&
25
+ typeof column.type === "string" &&
26
+ Object.values(constants_1.FieldTypes).includes(column.type));
27
+ }));
28
+ }
29
+ exports.isSchema = isSchema;
30
+ function isRows(rows) {
31
+ return Array.isArray(rows) && rows.every(row => typeof row === "object");
32
+ }
33
+ exports.isRows = isRows;
34
+ function validate(rows, schema) {
35
+ const results = {
36
+ schemaValidation: {},
37
+ allValid: false,
38
+ invalidColumns: [],
39
+ };
40
+ rows.forEach(row => {
41
+ Object.entries(row).forEach(([columnName, columnData]) => {
42
+ var _a, _b;
43
+ const columnType = (_a = schema[columnName]) === null || _a === void 0 ? void 0 : _a.type;
44
+ const isAutoColumn = (_b = schema[columnName]) === null || _b === void 0 ? void 0 : _b.autocolumn;
45
+ // If the columnType is not a string, then it's not present in the schema, and should be added to the invalid columns array
46
+ if (typeof columnType !== "string") {
47
+ results.invalidColumns.push(columnName);
48
+ }
49
+ else if (
50
+ // If there's no data for this field don't bother with further checks
51
+ // If the field is already marked as invalid there's no need for further checks
52
+ results.schemaValidation[columnName] === false ||
53
+ columnData == null ||
54
+ isAutoColumn) {
55
+ return;
56
+ }
57
+ else if (columnType === constants_1.FieldTypes.NUMBER &&
58
+ isNaN(Number(columnData))) {
59
+ // If provided must be a valid number
60
+ results.schemaValidation[columnName] = false;
61
+ }
62
+ else if (
63
+ // If provided must be a valid date
64
+ columnType === constants_1.FieldTypes.DATETIME &&
65
+ isNaN(new Date(columnData).getTime())) {
66
+ results.schemaValidation[columnName] = false;
67
+ }
68
+ else {
69
+ results.schemaValidation[columnName] = true;
70
+ }
71
+ });
72
+ });
73
+ results.allValid =
74
+ Object.values(results.schemaValidation).length > 0 &&
75
+ Object.values(results.schemaValidation).every(column => column);
76
+ // Select unique values
77
+ results.invalidColumns = [...new Set(results.invalidColumns)];
78
+ return results;
79
+ }
80
+ exports.validate = validate;
81
+ function parse(rows, schema) {
82
+ return rows.map(row => {
83
+ const parsedRow = {};
84
+ Object.entries(row).forEach(([columnName, columnData]) => {
85
+ var _a;
86
+ if (!(columnName in schema) || ((_a = schema[columnName]) === null || _a === void 0 ? void 0 : _a.autocolumn)) {
87
+ // Objects can be present in the row data but not in the schema, so make sure we don't proceed in such a case
88
+ return;
89
+ }
90
+ const columnType = schema[columnName].type;
91
+ if (columnType === constants_1.FieldTypes.NUMBER) {
92
+ // If provided must be a valid number
93
+ parsedRow[columnName] = columnData ? Number(columnData) : columnData;
94
+ }
95
+ else if (columnType === constants_1.FieldTypes.DATETIME) {
96
+ // If provided must be a valid date
97
+ parsedRow[columnName] = columnData
98
+ ? new Date(columnData).toISOString()
99
+ : columnData;
100
+ }
101
+ else {
102
+ parsedRow[columnName] = columnData;
103
+ }
104
+ });
105
+ return parsedRow;
106
+ });
107
+ }
108
+ exports.parse = parse;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@budibase/server",
3
3
  "email": "hi@budibase.com",
4
- "version": "2.2.12-alpha.20",
4
+ "version": "2.2.12-alpha.21",
5
5
  "description": "Budibase Web Server",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -43,11 +43,11 @@
43
43
  "license": "GPL-3.0",
44
44
  "dependencies": {
45
45
  "@apidevtools/swagger-parser": "10.0.3",
46
- "@budibase/backend-core": "2.2.12-alpha.20",
47
- "@budibase/client": "2.2.12-alpha.20",
48
- "@budibase/pro": "2.2.12-alpha.19",
49
- "@budibase/string-templates": "2.2.12-alpha.20",
50
- "@budibase/types": "2.2.12-alpha.20",
46
+ "@budibase/backend-core": "2.2.12-alpha.21",
47
+ "@budibase/client": "2.2.12-alpha.21",
48
+ "@budibase/pro": "2.2.12-alpha.20",
49
+ "@budibase/string-templates": "2.2.12-alpha.21",
50
+ "@budibase/types": "2.2.12-alpha.21",
51
51
  "@bull-board/api": "3.7.0",
52
52
  "@bull-board/koa": "3.9.4",
53
53
  "@elastic/elasticsearch": "7.10.0",
@@ -169,5 +169,5 @@
169
169
  "optionalDependencies": {
170
170
  "oracledb": "5.3.0"
171
171
  },
172
- "gitHead": "bf18dd279d7241ab5945639cf3ded4ffb9e4fa07"
172
+ "gitHead": "4aadbcd8a1ad4becff6f719fe24553fb8287f9fc"
173
173
  }
@@ -27,7 +27,7 @@ import {
27
27
  import { cloneDeep } from "lodash/fp"
28
28
  import { context, db as dbCore } from "@budibase/backend-core"
29
29
  import { finaliseRow, updateRelatedFormula } from "./staticFormula"
30
- import * as exporters from "../view/exporters"
30
+ import { csv, json, jsonWithSchema, Format, isFormat } from "../view/exporters"
31
31
  import { apiFileReturn } from "../../../utilities/fileSystem"
32
32
  import {
33
33
  Ctx,
@@ -412,14 +412,15 @@ export async function exportRows(ctx: Ctx) {
412
412
  rows = result
413
413
  }
414
414
 
415
- let headers = Object.keys(rows[0])
416
- // @ts-ignore
417
- const exporter = exporters[format]
418
- const filename = `export.${format}`
419
-
420
- // send down the file
421
- ctx.attachment(filename)
422
- return apiFileReturn(exporter(headers, rows))
415
+ if (format === Format.CSV) {
416
+ ctx.attachment("export.csv")
417
+ return apiFileReturn(csv(Object.keys(rows[0]), rows))
418
+ } else if (format === Format.JSON) {
419
+ ctx.attachment("export.json")
420
+ return apiFileReturn(json(rows))
421
+ } else {
422
+ throw "Format not recognised"
423
+ }
423
424
  }
424
425
 
425
426
  export async function fetchEnrichedRow(ctx: Ctx) {
@@ -10,9 +10,9 @@ import {
10
10
  } from "./utils"
11
11
  import { FieldTypes, RelationshipTypes } from "../../../constants"
12
12
  import { makeExternalQuery } from "../../../integrations/base/query"
13
- import * as csvParser from "../../../utilities/csvParser"
14
13
  import { handleRequest } from "../row/external"
15
14
  import { events, context } from "@budibase/backend-core"
15
+ import { parse, isRows, isSchema } from "../../../utilities/schema"
16
16
  import {
17
17
  Datasource,
18
18
  Table,
@@ -197,7 +197,7 @@ export async function save(ctx: BBContext) {
197
197
  const table: TableRequest = ctx.request.body
198
198
  const renamed = table?._rename
199
199
  // can't do this right now
200
- delete table.dataImport
200
+ delete table.rows
201
201
  const datasourceId = getDatasourceId(ctx.request.body)!
202
202
  // table doesn't exist already, note that it is created
203
203
  if (!table._id) {
@@ -338,17 +338,17 @@ export async function destroy(ctx: BBContext) {
338
338
 
339
339
  export async function bulkImport(ctx: BBContext) {
340
340
  const table = await sdk.tables.getTable(ctx.params.tableId)
341
- const { dataImport } = ctx.request.body
342
- if (!dataImport || !dataImport.schema || !dataImport.csvString) {
341
+ const { rows }: { rows: unknown } = ctx.request.body
342
+ const schema: unknown = table.schema
343
+
344
+ if (!rows || !isRows(rows) || !isSchema(schema)) {
343
345
  ctx.throw(400, "Provided data import information is invalid.")
344
346
  }
345
- const rows = await csvParser.transform({
346
- ...dataImport,
347
- existingTable: table,
348
- })
347
+
348
+ const parsedRows = await parse(rows, schema)
349
349
  await handleRequest(Operation.BULK_CREATE, table._id!, {
350
- rows,
350
+ rows: parsedRows,
351
351
  })
352
- await events.rows.imported(table, "csv", rows.length)
352
+ await events.rows.imported(table, parsedRows.length)
353
353
  return table
354
354
  }
@@ -1,11 +1,16 @@
1
1
  import * as internal from "./internal"
2
2
  import * as external from "./external"
3
- import * as csvParser from "../../../utilities/csvParser"
3
+ import {
4
+ validate as validateSchema,
5
+ isSchema,
6
+ isRows,
7
+ } from "../../../utilities/schema"
4
8
  import { isExternalTable, isSQL } from "../../../integrations/utils"
5
9
  import { getDatasourceParams } from "../../../db/utils"
6
10
  import { context, events } from "@budibase/backend-core"
7
11
  import { Table, BBContext } from "@budibase/types"
8
12
  import sdk from "../../../sdk"
13
+ import csv from "csvtojson"
9
14
 
10
15
  function pickApi({ tableId, table }: { tableId?: string; table?: Table }) {
11
16
  if (table && !tableId) {
@@ -56,16 +61,16 @@ export async function find(ctx: BBContext) {
56
61
  export async function save(ctx: BBContext) {
57
62
  const appId = ctx.appId
58
63
  const table = ctx.request.body
59
- const importFormat =
60
- table.dataImport && table.dataImport.csvString ? "csv" : undefined
64
+ const isImport = table.rows
65
+
61
66
  const savedTable = await pickApi({ table }).save(ctx)
62
67
  if (!table._id) {
63
68
  await events.table.created(savedTable)
64
69
  } else {
65
70
  await events.table.updated(savedTable)
66
71
  }
67
- if (importFormat) {
68
- await events.table.imported(savedTable, importFormat)
72
+ if (isImport) {
73
+ await events.table.imported(savedTable)
69
74
  }
70
75
  ctx.status = 200
71
76
  ctx.message = `Table ${table.name} saved successfully.`
@@ -96,19 +101,43 @@ export async function bulkImport(ctx: BBContext) {
96
101
  ctx.body = { message: `Bulk rows created.` }
97
102
  }
98
103
 
99
- export async function validateCSVSchema(ctx: BBContext) {
100
- // tableId being specified means its an import to an existing table
101
- const { csvString, schema = {}, tableId } = ctx.request.body
102
- let existingTable
104
+ export async function csvToJson(ctx: BBContext) {
105
+ const { csvString } = ctx.request.body
106
+
107
+ const result = await csv().fromString(csvString)
108
+
109
+ ctx.status = 200
110
+ ctx.body = result
111
+ }
112
+
113
+ export async function validateNewTableImport(ctx: BBContext) {
114
+ const { rows, schema }: { rows: unknown; schema: unknown } = ctx.request.body
115
+
116
+ if (isRows(rows) && isSchema(schema)) {
117
+ ctx.status = 200
118
+ ctx.body = validateSchema(rows, schema)
119
+ } else {
120
+ ctx.status = 422
121
+ }
122
+ }
123
+
124
+ export async function validateExistingTableImport(ctx: BBContext) {
125
+ const { rows, tableId }: { rows: unknown; tableId: unknown } =
126
+ ctx.request.body
127
+
128
+ let schema = null
103
129
  if (tableId) {
104
- existingTable = await sdk.tables.getTable(tableId)
130
+ const table = await sdk.tables.getTable(tableId)
131
+ schema = table.schema
132
+ } else {
133
+ ctx.status = 422
134
+ return
105
135
  }
106
- let result: Record<string, any> | undefined = await csvParser.parse(
107
- csvString,
108
- schema
109
- )
110
- if (existingTable) {
111
- result = csvParser.updateSchema({ schema: result, existingTable })
136
+
137
+ if (tableId && isRows(rows) && isSchema(schema)) {
138
+ ctx.status = 200
139
+ ctx.body = validateSchema(rows, schema)
140
+ } else {
141
+ ctx.status = 422
112
142
  }
113
- ctx.body = { schema: result }
114
143
  }
@@ -35,7 +35,7 @@ function checkAutoColumns(table: Table, oldTable: Table) {
35
35
 
36
36
  export async function save(ctx: any) {
37
37
  const db = context.getAppDB()
38
- const { dataImport, ...rest } = ctx.request.body
38
+ const { rows, ...rest } = ctx.request.body
39
39
  let tableToSave = {
40
40
  type: "table",
41
41
  _id: generateTableID(),
@@ -61,7 +61,7 @@ export async function save(ctx: any) {
61
61
  const tableSaveFunctions = new TableSaveFunctions({
62
62
  user: ctx.user,
63
63
  oldTable,
64
- dataImport,
64
+ importRows: rows,
65
65
  })
66
66
  tableToSave = await tableSaveFunctions.before(tableToSave)
67
67
 
@@ -185,7 +185,7 @@ export async function destroy(ctx: any) {
185
185
 
186
186
  export async function bulkImport(ctx: any) {
187
187
  const table = await sdk.tables.getTable(ctx.params.tableId)
188
- const { dataImport } = ctx.request.body
189
- await handleDataImport(ctx.user, table, dataImport)
188
+ const { rows } = ctx.request.body
189
+ await handleDataImport(ctx.user, table, rows)
190
190
  return table
191
191
  }
@@ -1,4 +1,4 @@
1
- import { transform } from "../../../utilities/csvParser"
1
+ import { parse, isSchema, isRows } from "../../../utilities/schema"
2
2
  import { getRowParams, generateRowID, InternalTables } from "../../../db/utils"
3
3
  import { isEqual } from "lodash"
4
4
  import { AutoFieldSubTypes, FieldTypes } from "../../../constants"
@@ -128,24 +128,23 @@ export function importToRows(data: any, table: any, user: any = {}) {
128
128
  return finalData
129
129
  }
130
130
 
131
- export async function handleDataImport(user: any, table: any, dataImport: any) {
132
- if (!dataImport || !dataImport.csvString) {
131
+ export async function handleDataImport(user: any, table: any, rows: any) {
132
+ const schema: unknown = table.schema
133
+
134
+ if (!rows || !isRows(rows) || !isSchema(schema)) {
133
135
  return table
134
136
  }
135
137
 
136
138
  const db = context.getAppDB()
137
- // Populate the table with rows imported from CSV in a bulk update
138
- const data = await transform({
139
- ...dataImport,
140
- existingTable: table,
141
- })
139
+ const data = parse(rows, schema)
142
140
 
143
141
  let finalData: any = importToRows(data, table, user)
144
142
 
145
143
  await quotas.addRows(finalData.length, () => db.bulkDocs(finalData), {
146
144
  tableId: table._id,
147
145
  })
148
- await events.rows.imported(table, "csv", finalData.length)
146
+
147
+ await events.rows.imported(table, finalData.length)
149
148
  return table
150
149
  }
151
150
 
@@ -210,14 +209,14 @@ class TableSaveFunctions {
210
209
  db: any
211
210
  user: any
212
211
  oldTable: any
213
- dataImport: any
212
+ importRows: any
214
213
  rows: any
215
214
 
216
- constructor({ user, oldTable, dataImport }: any) {
215
+ constructor({ user, oldTable, importRows }: any) {
217
216
  this.db = context.getAppDB()
218
217
  this.user = user
219
218
  this.oldTable = oldTable
220
- this.dataImport = dataImport
219
+ this.importRows = importRows
221
220
  // any rows that need updated
222
221
  this.rows = []
223
222
  }
@@ -241,7 +240,7 @@ class TableSaveFunctions {
241
240
  // after saving
242
241
  async after(table: any) {
243
242
  table = await handleSearchIndexes(table)
244
- table = await handleDataImport(this.user, table, this.dataImport)
243
+ table = await handleDataImport(this.user, table, this.importRows)
245
244
  return table
246
245
  }
247
246
 
@@ -1,4 +1,4 @@
1
- import { Row } from "@budibase/types"
1
+ import { Row, TableSchema } from "@budibase/types"
2
2
 
3
3
  export function csv(headers: string[], rows: Row[]) {
4
4
  let csv = headers.map(key => `"${key}"`).join(",")
@@ -18,11 +18,26 @@ export function csv(headers: string[], rows: Row[]) {
18
18
  return csv
19
19
  }
20
20
 
21
- export function json(headers: string[], rows: Row[]) {
21
+ export function json(rows: Row[]) {
22
22
  return JSON.stringify(rows, undefined, 2)
23
23
  }
24
24
 
25
- export const ExportFormats = {
26
- CSV: "csv",
27
- JSON: "json",
25
+ export function jsonWithSchema(schema: TableSchema, rows: Row[]) {
26
+ const newSchema: TableSchema = {}
27
+ Object.values(schema).forEach(column => {
28
+ if (!column.autocolumn) {
29
+ newSchema[column.name] = column
30
+ }
31
+ })
32
+ return JSON.stringify({ schema: newSchema, rows }, undefined, 2)
33
+ }
34
+
35
+ export enum Format {
36
+ CSV = "csv",
37
+ JSON = "json",
38
+ JSON_WITH_SCHEMA = "jsonWithSchema",
39
+ }
40
+
41
+ export function isFormat(format: any): format is Format {
42
+ return Object.values(Format).includes(format as Format)
28
43
  }
@@ -1,6 +1,6 @@
1
1
  import viewTemplate from "./viewBuilder"
2
2
  import { apiFileReturn } from "../../../utilities/fileSystem"
3
- import * as exporters from "./exporters"
3
+ import { csv, json, jsonWithSchema, Format, isFormat } from "./exporters"
4
4
  import { deleteView, getView, getViews, saveView } from "./utils"
5
5
  import { fetchView } from "../row"
6
6
  import { FieldTypes } from "../../../constants"
@@ -127,9 +127,13 @@ export async function exportView(ctx: BBContext) {
127
127
  const viewName = decodeURIComponent(ctx.query.view as string)
128
128
  const view = await getView(viewName)
129
129
 
130
- const format = ctx.query.format as string
131
- if (!format || !Object.values(exporters.ExportFormats).includes(format)) {
132
- ctx.throw(400, "Format must be specified, either csv or json")
130
+ const format = ctx.query.format as unknown
131
+
132
+ if (!isFormat(format)) {
133
+ ctx.throw(
134
+ 400,
135
+ "Format must be specified, either csv, json or jsonWithSchema"
136
+ )
133
137
  }
134
138
 
135
139
  if (view) {
@@ -171,7 +175,7 @@ export async function exportView(ctx: BBContext) {
171
175
  })
172
176
 
173
177
  // make sure no "undefined" entries appear in the CSV
174
- if (format === exporters.ExportFormats.CSV) {
178
+ if (format === Format.CSV) {
175
179
  const schemaKeys = Object.keys(schema)
176
180
  for (let key of schemaKeys) {
177
181
  for (let row of rows) {
@@ -182,13 +186,18 @@ export async function exportView(ctx: BBContext) {
182
186
  }
183
187
  }
184
188
 
185
- // Export part
186
- let headers = Object.keys(schema)
187
- const exporter = format === "csv" ? exporters.csv : exporters.json
188
- const filename = `${viewName}.${format}`
189
- // send down the file
190
- ctx.attachment(filename)
191
- ctx.body = apiFileReturn(exporter(headers, rows))
189
+ if (format === Format.CSV) {
190
+ ctx.attachment(`${viewName}.csv`)
191
+ ctx.body = apiFileReturn(csv(Object.keys(schema), rows))
192
+ } else if (format === Format.JSON) {
193
+ ctx.attachment(`${viewName}.json`)
194
+ ctx.body = apiFileReturn(json(rows))
195
+ } else if (format === Format.JSON_WITH_SCHEMA) {
196
+ ctx.attachment(`${viewName}.json`)
197
+ ctx.body = apiFileReturn(jsonWithSchema(schema, rows))
198
+ } else {
199
+ throw "Format not recognised"
200
+ }
192
201
 
193
202
  if (viewName.startsWith(DocumentType.TABLE)) {
194
203
  await events.table.exported(table, format as TableExportFormat)
@@ -67,10 +67,7 @@ router
67
67
  * structure, and the "updated", new column name should also be supplied. The schema should also be updated, this field
68
68
  * lets the server know that a field hasn't just been deleted, that the data has moved to a new name, this will fix
69
69
  * the rows in the table. This functionality is only available for internal tables.
70
- * @apiParam (Body) {object} [dataImport] When creating an internal table it can be built from a CSV, by using the
71
- * CSV validation endpoint. Send the CSV data to the validation endpoint, then put the results of that call
72
- * into this property, along with the CSV and a table/rows will be built from it. This is not supported when updating
73
- * or for external tables.
70
+ * @apiParam (Body) {object[]} [rows] When creating a table using a compatible data source, an array of objects to be imported into the new table can be provided.
74
71
  *
75
72
  * @apiParamExample {json} Example:
76
73
  * {
@@ -99,15 +96,7 @@ router
99
96
  * "old": "columnName",
100
97
  * "updated": "newColumnName",
101
98
  * },
102
- * "dataImport": {
103
- * "csvString": "column\nvalue",
104
- * "primaryDisplay": "column",
105
- * "schema": {
106
- * "column": {
107
- * "type": "string"
108
- * }
109
- * }
110
- * }
99
+ * "rows": []
111
100
  * }
112
101
  *
113
102
  * @apiSuccess {object} table The response body will contain the table structure after being cleaned up and
@@ -121,30 +110,20 @@ router
121
110
  tableValidator(),
122
111
  tableController.save
123
112
  )
124
- /**
125
- * @api {post} /api/tables/csv/validate Validate a CSV for a table
126
- * @apiName Validate a CSV for a table
127
- * @apiGroup tables
128
- * @apiPermission builder
129
- * @apiDescription When creating a new table, or importing a CSV to an existing table the CSV must be validated and
130
- * converted into a Budibase schema; this endpoint does this.
131
- *
132
- * @apiParam (Body) {string} csvString The CSV which is to be validated as a string.
133
- * @apiParam (Body) {object} [schema] When a CSV has been validated it is possible to re-validate after changing the
134
- * type of a field, by default everything will be strings as there is no way to infer types. The returned schema can
135
- * be updated and then returned to the endpoint to re-validate and check if the type will work for the CSV, e.g.
136
- * using a number instead of strings.
137
- * @apiParam (Body) {string} [tableId] If importing data to an existing table this will pull the current table and
138
- * remove any fields from the CSV schema which do not exist on the table/don't match the type of the table. When
139
- * importing a CSV to an existing table only fields that are present on the table can be imported.
140
- *
141
- * @apiSuccess {object} schema The response body will contain a "schema" object that represents the schema found for
142
- * the CSV - this will be in the same format used for table schema.s
143
- */
144
113
  .post(
145
- "/api/tables/csv/validate",
114
+ "/api/convert/csvToJson",
115
+ authorized(BUILDER),
116
+ tableController.csvToJson
117
+ )
118
+ .post(
119
+ "/api/tables/validateNewTableImport",
120
+ authorized(BUILDER),
121
+ tableController.validateNewTableImport
122
+ )
123
+ .post(
124
+ "/api/tables/validateExistingTableImport",
146
125
  authorized(BUILDER),
147
- tableController.validateCSVSchema
126
+ tableController.validateExistingTableImport
148
127
  )
149
128
  /**
150
129
  * @api {post} /api/tables/:tableId/:revId Delete a table
@@ -177,9 +156,7 @@ router
177
156
  *
178
157
  * @apiParam {string} tableId The ID of the table which the data should be imported to.
179
158
  *
180
- * @apiParam (Body) {object} dataImport This is the same as the structure used when creating an internal table with
181
- * a CSV, it will have the "schema" returned from the CSV validation endpoint and the "csvString" which is to be
182
- * turned into rows.
159
+ * @apiParam (Body) {object[]} rows An array of objects representing the rows to be imported, key-value pairs not matching the table schema will be ignored.
183
160
  *
184
161
  * @apiSuccess {string} message A message stating that the data was imported successfully.
185
162
  */
@@ -42,7 +42,7 @@ describe("run misc tests", () => {
42
42
  })
43
43
 
44
44
  describe("test table utilities", () => {
45
- it("should be able to import a CSV", async () => {
45
+ it("should be able to import data", async () => {
46
46
  return config.doInContext(null, async () => {
47
47
  const table = await config.createTable({
48
48
  name: "table",
@@ -75,17 +75,11 @@ describe("run misc tests", () => {
75
75
  },
76
76
  },
77
77
  })
78
- const dataImport = {
79
- csvString: "a,b,c,d\n1,2,3,4",
80
- schema: {},
81
- }
82
- for (let col of ["a", "b", "c", "d"]) {
83
- dataImport.schema[col] = { type: "string" }
84
- }
78
+
85
79
  await tableUtils.handleDataImport(
86
80
  { userId: "test" },
87
81
  table,
88
- dataImport
82
+ [{ a: '1', b: '2', c: '3', d: '4'}]
89
83
  )
90
84
  const rows = await config.getRows()
91
85
  expect(rows[0].a).toEqual("1")
@@ -94,4 +88,4 @@ describe("run misc tests", () => {
94
88
  })
95
89
  })
96
90
  })
97
- })
91
+ })