@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.
- package/builder/assets/{index.fa480d5b.css → index.34817feb.css} +1 -1
- package/builder/assets/{index.35af2c9c.js → index.61dfdc1c.js} +245 -244
- package/builder/index.html +2 -2
- package/coverage/clover.xml +772 -771
- package/coverage/coverage-final.json +40 -40
- package/coverage/lcov-report/index.html +55 -55
- package/coverage/lcov-report/src/api/controllers/analytics.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/apikeys.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/application.ts.html +56 -56
- package/coverage/lcov-report/src/api/controllers/auth.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/automation.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/backup.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/cloud.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/component.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/datasource.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/deploy/Deployment.ts.html +12 -12
- package/coverage/lcov-report/src/api/controllers/deploy/index.html +1 -1
- package/coverage/lcov-report/src/api/controllers/deploy/index.ts.html +69 -69
- package/coverage/lcov-report/src/api/controllers/dev.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/index.html +1 -1
- package/coverage/lcov-report/src/api/controllers/integration.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/layout.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/metadata.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/migrations.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/permission.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/plugin/file.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/plugin/github.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/plugin/index.html +1 -1
- package/coverage/lcov-report/src/api/controllers/plugin/index.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/plugin/npm.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/plugin/uploaders.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/plugin/url.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/plugin/utils.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/public/applications.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/public/index.html +1 -1
- package/coverage/lcov-report/src/api/controllers/public/mapping/applications.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/public/mapping/index.html +1 -1
- package/coverage/lcov-report/src/api/controllers/public/mapping/index.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/public/mapping/queries.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/public/mapping/rows.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/public/mapping/tables.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/public/mapping/users.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/public/queries.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/public/rows.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/public/tables.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/public/users.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/public/utils.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/query/import/index.html +1 -1
- package/coverage/lcov-report/src/api/controllers/query/import/index.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/query/import/sources/base/index.html +1 -1
- package/coverage/lcov-report/src/api/controllers/query/import/sources/base/index.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/query/import/sources/base/openapi.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/query/import/sources/curl.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/query/import/sources/index.html +1 -1
- package/coverage/lcov-report/src/api/controllers/query/import/sources/openapi2.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/query/import/sources/openapi3.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/query/index.html +1 -1
- package/coverage/lcov-report/src/api/controllers/query/index.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/query/validation.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/role.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/routing.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/row/ExternalRequest.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/row/external.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/row/index.html +15 -15
- package/coverage/lcov-report/src/api/controllers/row/index.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/row/internal.ts.html +23 -20
- package/coverage/lcov-report/src/api/controllers/row/internalSearch.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/row/staticFormula.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/row/utils.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/screen.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/script.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/static/index.html +1 -1
- package/coverage/lcov-report/src/api/controllers/static/index.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/table/bulkFormula.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/table/external.ts.html +17 -17
- package/coverage/lcov-report/src/api/controllers/table/index.html +33 -33
- package/coverage/lcov-report/src/api/controllers/table/index.ts.html +122 -35
- package/coverage/lcov-report/src/api/controllers/table/internal.ts.html +5 -5
- package/coverage/lcov-report/src/api/controllers/table/utils.ts.html +23 -26
- package/coverage/lcov-report/src/api/controllers/templates.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/user.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/view/exporters.ts.html +61 -16
- package/coverage/lcov-report/src/api/controllers/view/index.html +28 -28
- package/coverage/lcov-report/src/api/controllers/view/index.ts.html +52 -25
- package/coverage/lcov-report/src/api/controllers/view/utils.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/view/viewBuilder.ts.html +1 -1
- package/coverage/lcov-report/src/api/controllers/webhook.ts.html +1 -1
- package/coverage/lcov-report/src/api/index.html +1 -1
- package/coverage/lcov-report/src/api/index.ts.html +5 -5
- package/coverage/lcov-report/src/api/routes/analytics.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/apikeys.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/application.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/auth.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/automation.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/backup.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/cloud.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/component.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/datasource.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/deploy.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/dev.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/index.html +1 -1
- package/coverage/lcov-report/src/api/routes/index.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/integration.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/layout.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/metadata.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/migrations.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/permission.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/plugin.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/public/applications.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/public/index.html +1 -1
- package/coverage/lcov-report/src/api/routes/public/index.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/public/middleware/index.html +1 -1
- package/coverage/lcov-report/src/api/routes/public/middleware/mapper.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/public/queries.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/public/rows.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/public/tables.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/public/tests/index.html +1 -1
- package/coverage/lcov-report/src/api/routes/public/tests/utils.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/public/users.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/public/utils/Endpoint.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/public/utils/index.html +1 -1
- package/coverage/lcov-report/src/api/routes/query.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/role.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/routing.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/row.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/screen.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/script.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/static.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/table.ts.html +17 -86
- package/coverage/lcov-report/src/api/routes/templates.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/tests/utilities/TestFunctions.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/tests/utilities/index.html +1 -1
- package/coverage/lcov-report/src/api/routes/tests/utilities/index.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/user.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/utils/index.html +1 -1
- package/coverage/lcov-report/src/api/routes/utils/validators.ts.html +2 -2
- package/coverage/lcov-report/src/api/routes/view.ts.html +1 -1
- package/coverage/lcov-report/src/api/routes/webhook.ts.html +1 -1
- package/coverage/lcov-report/src/app.ts.html +1 -1
- package/coverage/lcov-report/src/automations/actions.ts.html +1 -1
- package/coverage/lcov-report/src/automations/automationUtils.ts.html +1 -1
- package/coverage/lcov-report/src/automations/bullboard.ts.html +2 -2
- package/coverage/lcov-report/src/automations/index.html +1 -1
- package/coverage/lcov-report/src/automations/index.ts.html +1 -1
- package/coverage/lcov-report/src/automations/logging/index.html +1 -1
- package/coverage/lcov-report/src/automations/logging/index.ts.html +1 -1
- package/coverage/lcov-report/src/automations/steps/bash.ts.html +1 -1
- package/coverage/lcov-report/src/automations/steps/createRow.ts.html +1 -1
- package/coverage/lcov-report/src/automations/steps/delay.ts.html +1 -1
- package/coverage/lcov-report/src/automations/steps/deleteRow.ts.html +1 -1
- package/coverage/lcov-report/src/automations/steps/discord.ts.html +1 -1
- package/coverage/lcov-report/src/automations/steps/executeQuery.ts.html +1 -1
- package/coverage/lcov-report/src/automations/steps/executeScript.ts.html +1 -1
- package/coverage/lcov-report/src/automations/steps/filter.ts.html +1 -1
- package/coverage/lcov-report/src/automations/steps/index.html +1 -1
- package/coverage/lcov-report/src/automations/steps/integromat.ts.html +1 -1
- package/coverage/lcov-report/src/automations/steps/loop.ts.html +1 -1
- package/coverage/lcov-report/src/automations/steps/outgoingWebhook.ts.html +1 -1
- package/coverage/lcov-report/src/automations/steps/queryRows.ts.html +1 -1
- package/coverage/lcov-report/src/automations/steps/sendSmtpEmail.ts.html +1 -1
- package/coverage/lcov-report/src/automations/steps/serverLog.ts.html +1 -1
- package/coverage/lcov-report/src/automations/steps/slack.ts.html +1 -1
- package/coverage/lcov-report/src/automations/steps/updateRow.ts.html +1 -1
- package/coverage/lcov-report/src/automations/steps/utils.ts.html +1 -1
- package/coverage/lcov-report/src/automations/steps/zapier.ts.html +1 -1
- package/coverage/lcov-report/src/automations/tests/utilities/index.html +1 -1
- package/coverage/lcov-report/src/automations/tests/utilities/index.ts.html +1 -1
- package/coverage/lcov-report/src/automations/triggerInfo/app.ts.html +1 -1
- package/coverage/lcov-report/src/automations/triggerInfo/cron.ts.html +1 -1
- package/coverage/lcov-report/src/automations/triggerInfo/index.html +1 -1
- package/coverage/lcov-report/src/automations/triggerInfo/index.ts.html +1 -1
- package/coverage/lcov-report/src/automations/triggerInfo/rowDeleted.ts.html +1 -1
- package/coverage/lcov-report/src/automations/triggerInfo/rowSaved.ts.html +1 -1
- package/coverage/lcov-report/src/automations/triggerInfo/rowUpdated.ts.html +1 -1
- package/coverage/lcov-report/src/automations/triggerInfo/webhook.ts.html +1 -1
- package/coverage/lcov-report/src/automations/triggers.ts.html +1 -1
- package/coverage/lcov-report/src/automations/utils.ts.html +11 -11
- package/coverage/lcov-report/src/constants/index.html +1 -1
- package/coverage/lcov-report/src/constants/index.ts.html +25 -25
- package/coverage/lcov-report/src/constants/layouts.ts.html +1 -1
- package/coverage/lcov-report/src/constants/screens.ts.html +1 -1
- package/coverage/lcov-report/src/db/defaultData/datasource_bb_default.ts.html +1 -1
- package/coverage/lcov-report/src/db/defaultData/employeeImport.ts.html +1 -1
- package/coverage/lcov-report/src/db/defaultData/expensesImport.ts.html +1 -1
- package/coverage/lcov-report/src/db/defaultData/index.html +1 -1
- package/coverage/lcov-report/src/db/defaultData/inventoryImport.ts.html +1 -1
- package/coverage/lcov-report/src/db/defaultData/jobsImport.ts.html +1 -1
- package/coverage/lcov-report/src/db/dynamoClient.ts.html +1 -1
- package/coverage/lcov-report/src/db/inMemoryView.ts.html +1 -1
- package/coverage/lcov-report/src/db/index.html +1 -1
- package/coverage/lcov-report/src/db/index.ts.html +1 -1
- package/coverage/lcov-report/src/db/linkedRows/LinkController.ts.html +1 -1
- package/coverage/lcov-report/src/db/linkedRows/LinkDocument.ts.html +1 -1
- package/coverage/lcov-report/src/db/linkedRows/index.html +1 -1
- package/coverage/lcov-report/src/db/linkedRows/index.ts.html +1 -1
- package/coverage/lcov-report/src/db/linkedRows/linkUtils.ts.html +1 -1
- package/coverage/lcov-report/src/db/newid.ts.html +3 -3
- package/coverage/lcov-report/src/db/utils.ts.html +15 -15
- package/coverage/lcov-report/src/definitions/automations.ts.html +1 -1
- package/coverage/lcov-report/src/definitions/datasource.ts.html +1 -1
- package/coverage/lcov-report/src/definitions/index.html +1 -1
- package/coverage/lcov-report/src/environment.ts.html +19 -19
- package/coverage/lcov-report/src/events/AutomationEmitter.ts.html +1 -1
- package/coverage/lcov-report/src/events/BudibaseEmitter.ts.html +1 -1
- package/coverage/lcov-report/src/events/index.html +1 -1
- package/coverage/lcov-report/src/events/index.ts.html +1 -1
- package/coverage/lcov-report/src/events/utils.ts.html +1 -1
- package/coverage/lcov-report/src/index.html +1 -1
- package/coverage/lcov-report/src/index.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/airtable.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/arangodb.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/base/index.html +1 -1
- package/coverage/lcov-report/src/integrations/base/query.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/base/sql.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/base/sqlTable.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/base/utils.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/couchdb.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/dynamodb.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/elasticsearch.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/firebase.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/googlesheets.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/index.html +1 -1
- package/coverage/lcov-report/src/integrations/index.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/microsoftSqlServer.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/mongodb.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/mysql.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/oracle.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/postgres.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/queries/index.html +1 -1
- package/coverage/lcov-report/src/integrations/queries/sql.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/redis.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/rest.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/s3.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/snowflake.ts.html +1 -1
- package/coverage/lcov-report/src/integrations/tests/TestConfiguration.js.html +1 -1
- package/coverage/lcov-report/src/integrations/tests/index.html +1 -1
- package/coverage/lcov-report/src/integrations/utils.ts.html +1 -1
- package/coverage/lcov-report/src/middleware/appInfo.ts.html +1 -1
- package/coverage/lcov-report/src/middleware/authorized.ts.html +21 -21
- package/coverage/lcov-report/src/middleware/builder.ts.html +12 -12
- package/coverage/lcov-report/src/middleware/currentapp.ts.html +33 -33
- package/coverage/lcov-report/src/middleware/index.html +1 -1
- package/coverage/lcov-report/src/middleware/joi-validator.ts.html +1 -1
- package/coverage/lcov-report/src/middleware/publicApi.ts.html +1 -1
- package/coverage/lcov-report/src/middleware/resourceId.ts.html +1 -1
- package/coverage/lcov-report/src/middleware/selfhost.ts.html +1 -1
- package/coverage/lcov-report/src/middleware/utils.ts.html +3 -3
- package/coverage/lcov-report/src/migrations/functions/appUrls.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/backfill/app/automations.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/backfill/app/datasources.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/backfill/app/index.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/backfill/app/layouts.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/backfill/app/queries.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/backfill/app/roles.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/backfill/app/screens.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/backfill/app/tables.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/backfill/app.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/backfill/global/configs.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/backfill/global/index.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/backfill/global/quotas.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/backfill/global/users.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/backfill/global.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/backfill/index.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/backfill/index.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/backfill/installation.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/index.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/syncQuotas.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/tableSettings.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/usageQuotas/index.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/usageQuotas/index.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncApps.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncPlugins.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncRows.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/functions/userEmailViewCasing.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/index.html +1 -1
- package/coverage/lcov-report/src/migrations/index.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/tests/helpers.ts.html +1 -1
- package/coverage/lcov-report/src/migrations/tests/index.html +1 -1
- package/coverage/lcov-report/src/migrations/tests/structures.ts.html +1 -1
- package/coverage/lcov-report/src/sdk/app/applications/index.html +1 -1
- package/coverage/lcov-report/src/sdk/app/applications/index.ts.html +1 -1
- package/coverage/lcov-report/src/sdk/app/applications/sync.ts.html +18 -18
- package/coverage/lcov-report/src/sdk/app/applications/utils.ts.html +7 -7
- package/coverage/lcov-report/src/sdk/app/automations/index.html +1 -1
- package/coverage/lcov-report/src/sdk/app/automations/index.ts.html +1 -1
- package/coverage/lcov-report/src/sdk/app/automations/webhook.ts.html +1 -1
- package/coverage/lcov-report/src/sdk/app/backups/constants.ts.html +1 -1
- package/coverage/lcov-report/src/sdk/app/backups/exports.ts.html +1 -1
- package/coverage/lcov-report/src/sdk/app/backups/imports.ts.html +1 -1
- package/coverage/lcov-report/src/sdk/app/backups/index.html +1 -1
- package/coverage/lcov-report/src/sdk/app/backups/index.ts.html +1 -1
- package/coverage/lcov-report/src/sdk/app/backups/statistics.ts.html +1 -1
- package/coverage/lcov-report/src/sdk/app/rows/attachments.ts.html +1 -1
- package/coverage/lcov-report/src/sdk/app/rows/index.html +1 -1
- package/coverage/lcov-report/src/sdk/app/rows/index.ts.html +1 -1
- package/coverage/lcov-report/src/sdk/app/rows/rows.ts.html +1 -1
- package/coverage/lcov-report/src/sdk/app/tables/index.html +1 -1
- package/coverage/lcov-report/src/sdk/app/tables/index.ts.html +1 -1
- package/coverage/lcov-report/src/sdk/index.html +1 -1
- package/coverage/lcov-report/src/sdk/index.ts.html +2 -2
- package/coverage/lcov-report/src/sdk/users/index.html +1 -1
- package/coverage/lcov-report/src/sdk/users/index.ts.html +1 -1
- package/coverage/lcov-report/src/sdk/users/utils.ts.html +20 -20
- package/coverage/lcov-report/src/startup.ts.html +1 -1
- package/coverage/lcov-report/src/tests/utilities/TestConfiguration.ts.html +59 -59
- package/coverage/lcov-report/src/tests/utilities/controllers.ts.html +3 -3
- package/coverage/lcov-report/src/tests/utilities/index.html +1 -1
- package/coverage/lcov-report/src/tests/utilities/index.ts.html +1 -1
- package/coverage/lcov-report/src/tests/utilities/structures.ts.html +2 -2
- package/coverage/lcov-report/src/threads/automation.ts.html +1 -1
- package/coverage/lcov-report/src/threads/index.html +1 -1
- package/coverage/lcov-report/src/threads/index.ts.html +1 -1
- package/coverage/lcov-report/src/threads/query.ts.html +1 -1
- package/coverage/lcov-report/src/threads/utils.ts.html +1 -1
- package/coverage/lcov-report/src/utilities/budibaseDir.ts.html +3 -3
- package/coverage/lcov-report/src/utilities/centralPath.ts.html +2 -2
- package/coverage/lcov-report/src/utilities/fileSystem/app.ts.html +16 -16
- package/coverage/lcov-report/src/utilities/fileSystem/clientLibrary.ts.html +8 -8
- package/coverage/lcov-report/src/utilities/fileSystem/filesystem.ts.html +30 -30
- package/coverage/lcov-report/src/utilities/fileSystem/index.html +15 -15
- package/coverage/lcov-report/src/utilities/fileSystem/index.ts.html +6 -6
- package/coverage/lcov-report/src/utilities/fileSystem/plugin.ts.html +8 -8
- package/coverage/lcov-report/src/utilities/fileSystem/processor.ts.html +1 -1
- package/coverage/lcov-report/src/utilities/fileSystem/template.ts.html +7 -7
- package/coverage/lcov-report/src/utilities/global.ts.html +33 -33
- package/coverage/lcov-report/src/utilities/index.html +24 -24
- package/coverage/lcov-report/src/utilities/index.ts.html +4 -4
- package/coverage/lcov-report/src/utilities/redis.ts.html +1 -1
- package/coverage/lcov-report/src/utilities/routing/index.html +1 -1
- package/coverage/lcov-report/src/utilities/routing/index.ts.html +1 -1
- package/coverage/lcov-report/src/utilities/rowProcessor/index.html +1 -1
- package/coverage/lcov-report/src/utilities/rowProcessor/index.ts.html +1 -1
- package/coverage/lcov-report/src/utilities/rowProcessor/map.ts.html +1 -1
- package/coverage/lcov-report/src/utilities/rowProcessor/utils.ts.html +1 -1
- package/coverage/lcov-report/src/utilities/{csvParser.ts.html → schema.ts.html} +173 -233
- package/coverage/lcov-report/src/utilities/scriptRunner.ts.html +1 -1
- package/coverage/lcov-report/src/utilities/security.ts.html +1 -1
- package/coverage/lcov-report/src/utilities/usageQuota/index.html +1 -1
- package/coverage/lcov-report/src/utilities/usageQuota/rows.ts.html +1 -1
- package/coverage/lcov-report/src/utilities/usageQuota/usageQuoteReset.ts.html +1 -1
- package/coverage/lcov-report/src/utilities/users.ts.html +1 -1
- package/coverage/lcov-report/src/utilities/workerRequests.ts.html +1 -1
- package/coverage/lcov-report/src/watch.ts.html +1 -1
- package/coverage/lcov-report/src/websocket.ts.html +1 -1
- package/coverage/lcov.info +1303 -1267
- package/dist/api/controllers/row/internal.js +12 -8
- package/dist/api/controllers/table/external.js +8 -30
- package/dist/api/controllers/table/index.js +44 -15
- package/dist/api/controllers/table/internal.js +4 -4
- package/dist/api/controllers/table/utils.js +9 -9
- package/dist/api/controllers/view/exporters.js +22 -6
- package/dist/api/controllers/view/index.js +19 -34
- package/dist/api/routes/table.js +6 -37
- package/dist/api/routes/utils/validators.js +1 -1
- package/dist/package.json +6 -6
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utilities/schema.js +108 -0
- package/package.json +7 -7
- package/src/api/controllers/row/internal.ts +10 -9
- package/src/api/controllers/table/external.ts +10 -10
- package/src/api/controllers/table/index.ts +46 -17
- package/src/api/controllers/table/internal.ts +4 -4
- package/src/api/controllers/table/utils.ts +12 -13
- package/src/api/controllers/view/exporters.ts +20 -5
- package/src/api/controllers/view/index.ts +21 -12
- package/src/api/routes/table.ts +15 -38
- package/src/api/routes/tests/misc.spec.js +4 -10
- package/src/api/routes/tests/table.spec.js +8 -30
- package/src/api/routes/utils/validators.ts +1 -1
- package/src/utilities/schema.ts +141 -0
- package/dist/utilities/csvParser.js +0 -152
- package/src/utilities/csvParser.ts +0 -161
- package/src/utilities/tests/__snapshots__/csvParser.spec.js.snap +0 -15
- 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.
|
|
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.
|
|
47
|
-
"@budibase/client": "2.2.12-alpha.
|
|
48
|
-
"@budibase/pro": "2.2.12-alpha.
|
|
49
|
-
"@budibase/string-templates": "2.2.12-alpha.
|
|
50
|
-
"@budibase/types": "2.2.12-alpha.
|
|
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": "
|
|
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
|
|
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
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
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.
|
|
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 {
|
|
342
|
-
|
|
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
|
-
|
|
346
|
-
|
|
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,
|
|
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
|
|
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
|
|
60
|
-
|
|
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 (
|
|
68
|
-
await events.table.imported(savedTable
|
|
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
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
-
|
|
130
|
+
const table = await sdk.tables.getTable(tableId)
|
|
131
|
+
schema = table.schema
|
|
132
|
+
} else {
|
|
133
|
+
ctx.status = 422
|
|
134
|
+
return
|
|
105
135
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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 {
|
|
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
|
-
|
|
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 {
|
|
189
|
-
await handleDataImport(ctx.user, table,
|
|
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 {
|
|
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,
|
|
132
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
212
|
+
importRows: any
|
|
214
213
|
rows: any
|
|
215
214
|
|
|
216
|
-
constructor({ user, oldTable,
|
|
215
|
+
constructor({ user, oldTable, importRows }: any) {
|
|
217
216
|
this.db = context.getAppDB()
|
|
218
217
|
this.user = user
|
|
219
218
|
this.oldTable = oldTable
|
|
220
|
-
this.
|
|
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.
|
|
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(
|
|
21
|
+
export function json(rows: Row[]) {
|
|
22
22
|
return JSON.stringify(rows, undefined, 2)
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
export
|
|
26
|
-
|
|
27
|
-
|
|
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
|
|
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
|
|
131
|
-
|
|
132
|
-
|
|
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 ===
|
|
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
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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)
|
package/src/api/routes/table.ts
CHANGED
|
@@ -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} [
|
|
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
|
-
* "
|
|
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/
|
|
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.
|
|
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}
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
+
})
|