@budibase/server 1.3.21 → 1.3.22-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__mocks__/mongodb.ts +1 -1
- package/builder/assets/index.96c69636.js +1008 -0
- package/builder/assets/index.c167b5c3.css +6 -0
- package/builder/index.html +2 -4
- package/coverage/clover.xml +308 -338
- package/coverage/coverage-final.json +19 -21
- package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/controllers/auth.js.html +41 -8
- package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
- package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
- package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
- package/coverage/lcov-report/api/controllers/datasource.js.html +73 -34
- package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
- package/coverage/lcov-report/api/controllers/index.html +27 -57
- package/coverage/lcov-report/api/controllers/integration.js.html +6 -6
- package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
- package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
- package/coverage/lcov-report/api/controllers/migrations.js.html +1 -1
- package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
- package/coverage/lcov-report/api/controllers/query/index.html +1 -1
- package/coverage/lcov-report/api/controllers/query/validation.js.html +1 -1
- package/coverage/lcov-report/api/controllers/role.js.html +1 -1
- package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/external.js.html +2 -2
- package/coverage/lcov-report/api/controllers/row/index.html +1 -1
- package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
- package/coverage/lcov-report/api/controllers/script.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/index.html +1 -1
- package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
- package/coverage/lcov-report/api/controllers/user.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
- package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
- package/coverage/lcov-report/api/index.html +1 -1
- package/coverage/lcov-report/api/index.js.html +13 -13
- package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
- package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/routes/auth.js.html +1 -1
- package/coverage/lcov-report/api/routes/automation.js.html +1 -1
- package/coverage/lcov-report/api/routes/backup.js.html +1 -1
- package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
- package/coverage/lcov-report/api/routes/component.js.html +1 -1
- package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
- package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
- package/coverage/lcov-report/api/routes/dev.js.html +1 -1
- package/coverage/lcov-report/api/routes/index.html +1 -1
- package/coverage/lcov-report/api/routes/integration.js.html +1 -1
- package/coverage/lcov-report/api/routes/layout.js.html +1 -1
- package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
- package/coverage/lcov-report/api/routes/migrations.js.html +1 -1
- package/coverage/lcov-report/api/routes/permission.js.html +1 -1
- package/coverage/lcov-report/api/routes/query.js.html +1 -1
- package/coverage/lcov-report/api/routes/role.js.html +1 -1
- package/coverage/lcov-report/api/routes/routing.js.html +1 -1
- package/coverage/lcov-report/api/routes/screen.js.html +1 -1
- package/coverage/lcov-report/api/routes/script.js.html +1 -1
- package/coverage/lcov-report/api/routes/table.js.html +2 -2
- package/coverage/lcov-report/api/routes/templates.js.html +1 -1
- package/coverage/lcov-report/api/routes/user.js.html +1 -1
- package/coverage/lcov-report/api/routes/utils/index.html +9 -9
- package/coverage/lcov-report/api/routes/utils/validators.js.html +75 -12
- package/coverage/lcov-report/api/routes/view.js.html +1 -1
- package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/actions.js.html +1 -1
- package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
- package/coverage/lcov-report/automations/bullboard.js.html +1 -1
- package/coverage/lcov-report/automations/index.html +1 -1
- package/coverage/lcov-report/automations/index.js.html +1 -1
- package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
- package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
- package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
- package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
- package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
- package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
- package/coverage/lcov-report/automations/steps/index.html +1 -1
- package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
- package/coverage/lcov-report/automations/steps/loop.js.html +1 -1
- package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
- package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
- package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
- package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
- package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
- package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
- package/coverage/lcov-report/automations/steps/utils.js.html +1 -1
- package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/triggers.js.html +1 -1
- package/coverage/lcov-report/constants/index.html +1 -1
- package/coverage/lcov-report/constants/index.js.html +1 -1
- package/coverage/lcov-report/constants/layouts.js.html +1 -1
- package/coverage/lcov-report/constants/screens.js.html +1 -1
- package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
- package/coverage/lcov-report/db/index.html +14 -14
- package/coverage/lcov-report/db/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/LinkController.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/index.html +1 -1
- package/coverage/lcov-report/db/linkedRows/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
- package/coverage/lcov-report/db/newid.js.html +2 -2
- package/coverage/lcov-report/db/utils.js.html +30 -18
- package/coverage/lcov-report/events/AutomationEmitter.js.html +3 -3
- package/coverage/lcov-report/events/index.html +1 -1
- package/coverage/lcov-report/events/index.js.html +1 -1
- package/coverage/lcov-report/events/utils.js.html +1 -1
- package/coverage/lcov-report/index.html +44 -44
- package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
- package/coverage/lcov-report/integrations/tests/index.html +1 -1
- package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
- package/coverage/lcov-report/middleware/builder.js.html +12 -12
- package/coverage/lcov-report/middleware/currentapp.js.html +46 -40
- package/coverage/lcov-report/middleware/index.html +15 -15
- package/coverage/lcov-report/middleware/joi-validator.js.html +1 -1
- package/coverage/lcov-report/middleware/publicApi.js.html +1 -1
- package/coverage/lcov-report/middleware/resourceId.js.html +7 -7
- package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
- package/coverage/lcov-report/middleware/utils.js.html +2 -2
- package/coverage/lcov-report/utilities/budibaseDir.js.html +3 -3
- package/coverage/lcov-report/utilities/centralPath.js.html +4 -4
- package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
- package/coverage/lcov-report/utilities/global.js.html +16 -16
- package/coverage/lcov-report/utilities/index.html +15 -15
- package/coverage/lcov-report/utilities/index.js.html +24 -24
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +2 -2
- package/coverage/lcov-report/utilities/queue/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
- package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
- package/coverage/lcov-report/utilities/security.js.html +2 -2
- package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/index.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/rows.js.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
- package/coverage/lcov-report/utilities/users.js.html +1 -1
- package/coverage/lcov-report/utilities/workerRequests.js.html +32 -8
- package/coverage/lcov.info +521 -558
- package/dist/api/controllers/application.js +5 -5
- package/dist/api/controllers/auth.js +9 -0
- package/dist/api/controllers/component.js +19 -6
- package/dist/api/controllers/datasource.js +21 -8
- package/dist/api/controllers/deploy/index.js +1 -8
- package/dist/api/controllers/integration.js +4 -4
- package/dist/{migrations/functions/usageQuotas/syncDevelopers.js → api/controllers/plugin/file.js} +13 -13
- package/dist/api/controllers/plugin/github.js +69 -0
- package/dist/api/controllers/plugin/index.js +144 -0
- package/dist/api/controllers/plugin/npm.js +58 -0
- package/dist/api/controllers/plugin/uploaders.js +11 -0
- package/dist/{migrations/functions/usageQuotas/syncPublishedApps.js → api/controllers/plugin/url.js} +13 -15
- package/dist/api/controllers/plugin/utils.js +26 -0
- package/dist/api/controllers/row/external.js +1 -1
- package/dist/api/controllers/screen.js +62 -14
- package/dist/api/controllers/static/index.js +1 -0
- package/dist/api/controllers/static/templates/BudibaseApp.svelte +10 -0
- package/dist/api/controllers/static/templates/preview.hbs +5 -1
- package/dist/api/index.js +1 -1
- package/dist/api/routes/application.js +3 -2
- package/dist/api/routes/index.js +2 -0
- package/dist/{migrations/functions/publishedAppsQuota.js → api/routes/plugin.js} +13 -21
- package/dist/api/routes/public/rows.js +1 -82
- package/dist/api/routes/public/tables.js +1 -1
- package/dist/api/routes/table.js +1 -1
- package/dist/api/routes/utils/validators.js +20 -2
- package/dist/app.js +16 -1
- package/dist/db/utils.js +3 -0
- package/dist/environment.js +1 -0
- package/dist/integrations/airtable.js +126 -129
- package/dist/integrations/arangodb.js +86 -89
- package/dist/integrations/base/query.js +2 -2
- package/dist/integrations/base/sqlTable.js +3 -1
- package/dist/integrations/couchdb.js +80 -83
- package/dist/integrations/dynamodb.js +161 -164
- package/dist/integrations/elasticsearch.js +135 -138
- package/dist/integrations/firebase.js +154 -157
- package/dist/integrations/googlesheets.js +323 -327
- package/dist/integrations/index.js +99 -51
- package/dist/integrations/microsoftSqlServer.js +240 -243
- package/dist/integrations/mongodb.js +239 -242
- package/dist/integrations/mysql.js +215 -219
- package/dist/integrations/oracle.js +318 -322
- package/dist/integrations/postgres.js +262 -265
- package/dist/integrations/redis.js +134 -139
- package/dist/integrations/rest.js +289 -292
- package/dist/integrations/s3.js +61 -64
- package/dist/integrations/snowflake.js +83 -86
- package/dist/middleware/currentapp.js +2 -0
- package/dist/migrations/functions/backfill/global.js +0 -3
- package/dist/migrations/index.js +0 -10
- package/dist/package.json +9 -6
- package/dist/tests/utilities/TestConfiguration.js +1 -1
- package/dist/threads/query.js +2 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utilities/fileSystem/index.js +105 -1
- package/dist/utilities/workerRequests.js +4 -0
- package/dist/watch.js +77 -0
- package/dist/websocket.js +22 -0
- package/package.json +10 -7
- package/scripts/dev/manage.js +4 -0
- package/scripts/localdomain.js +3 -1
- package/specs/openapi.json +115 -112
- package/specs/openapi.yaml +96 -94
- package/specs/resources/misc.js +116 -0
- package/specs/resources/query.js +1 -1
- package/src/api/controllers/application.ts +1 -2
- package/src/api/controllers/auth.js +11 -0
- package/src/api/controllers/component.ts +57 -0
- package/src/api/controllers/datasource.js +21 -8
- package/src/api/controllers/deploy/index.ts +1 -6
- package/src/api/controllers/integration.js +4 -4
- package/src/api/controllers/plugin/file.ts +15 -0
- package/src/api/controllers/plugin/github.ts +75 -0
- package/src/api/controllers/plugin/index.ts +134 -0
- package/src/api/controllers/plugin/npm.ts +56 -0
- package/src/api/controllers/plugin/uploaders.ts +4 -0
- package/src/api/controllers/plugin/url.ts +12 -0
- package/src/api/controllers/plugin/utils.ts +19 -0
- package/src/api/controllers/public/mapping/types.ts +8 -0
- package/src/api/controllers/row/external.js +1 -1
- package/src/api/controllers/screen.ts +122 -0
- package/src/api/controllers/static/index.ts +1 -1
- package/src/api/controllers/static/templates/BudibaseApp.svelte +10 -0
- package/src/api/controllers/static/templates/preview.hbs +5 -1
- package/src/api/index.js +1 -1
- package/src/api/routes/application.ts +13 -2
- package/src/api/routes/index.ts +2 -0
- package/src/api/routes/plugin.ts +14 -0
- package/src/api/routes/public/rows.ts +1 -82
- package/src/api/routes/public/tables.ts +1 -1
- package/src/api/routes/table.js +1 -1
- package/src/api/routes/tests/query.spec.js +8 -25
- package/src/api/routes/tests/user.spec.js +0 -2
- package/src/api/routes/utils/validators.js +26 -5
- package/src/app.ts +25 -2
- package/src/db/utils.js +4 -0
- package/src/definitions/openapi.ts +56 -55
- package/src/environment.js +1 -0
- package/src/integrations/airtable.ts +116 -118
- package/src/integrations/arangodb.ts +87 -89
- package/src/integrations/base/query.ts +2 -2
- package/src/integrations/base/sqlTable.ts +3 -1
- package/src/integrations/couchdb.ts +83 -89
- package/src/integrations/dynamodb.ts +173 -175
- package/src/integrations/elasticsearch.ts +120 -122
- package/src/integrations/firebase.ts +157 -159
- package/src/integrations/googlesheets.ts +328 -338
- package/src/integrations/index.ts +64 -21
- package/src/integrations/microsoftSqlServer.ts +249 -251
- package/src/integrations/mongodb.ts +261 -258
- package/src/integrations/mysql.ts +229 -234
- package/src/integrations/oracle.ts +373 -380
- package/src/integrations/postgres.ts +264 -268
- package/src/integrations/redis.ts +128 -132
- package/src/integrations/rest.ts +324 -329
- package/src/integrations/s3.ts +68 -71
- package/src/integrations/snowflake.ts +80 -82
- package/src/integrations/tests/{airtable.spec.js → airtable.spec.ts} +21 -18
- package/src/integrations/tests/{arangodb.spec.js → arangodb.spec.ts} +12 -9
- package/src/integrations/tests/{couchdb.spec.js → couchdb.spec.ts} +33 -27
- package/src/integrations/tests/{dynamodb.spec.js → dynamodb.spec.ts} +45 -41
- package/src/integrations/tests/{elasticsearch.spec.js → elasticsearch.spec.ts} +22 -21
- package/src/integrations/tests/{firebase.spec.js → firebase.spec.ts} +33 -28
- package/src/integrations/tests/{microsoftSqlServer.spec.js → microsoftSqlServer.spec.ts} +12 -11
- package/src/integrations/tests/{mongo.spec.js → mongo.spec.ts} +46 -35
- package/src/integrations/tests/{mysql.spec.js → mysql.spec.ts} +17 -15
- package/src/integrations/tests/{oracle.spec.js → oracle.spec.ts} +19 -17
- package/src/integrations/tests/{postgres.spec.js → postgres.spec.ts} +19 -17
- package/src/integrations/tests/{redis.spec.js → redis.spec.ts} +27 -18
- package/src/integrations/tests/{rest.spec.js → rest.spec.ts} +22 -14
- package/src/integrations/tests/{s3.spec.js → s3.spec.ts} +10 -8
- package/src/integrations/tests/{sql.spec.js → sql.spec.ts} +228 -177
- package/src/middleware/currentapp.js +2 -0
- package/src/migrations/functions/backfill/global.ts +0 -3
- package/src/migrations/index.ts +0 -16
- package/src/module.d.ts +2 -0
- package/src/tests/utilities/TestConfiguration.js +1 -1
- package/src/threads/query.ts +2 -2
- package/src/utilities/fileSystem/index.js +123 -0
- package/src/utilities/workerRequests.js +8 -0
- package/src/watch.ts +38 -0
- package/src/websocket.ts +26 -0
- package/builder/assets/index.8d12d461.css +0 -6
- package/builder/assets/index.d354271c.js +0 -879
- package/builder/assets/vendor.5e1fe644.css +0 -1
- package/builder/assets/vendor.67dbd8fa.js +0 -248
- package/coverage/lcov-report/api/controllers/component.js.html +0 -199
- package/coverage/lcov-report/api/controllers/screen.js.html +0 -259
- package/dist/migrations/functions/developerQuota.js +0 -49
- package/src/api/controllers/component.js +0 -38
- package/src/api/controllers/screen.js +0 -58
- package/src/migrations/functions/developerQuota.ts +0 -15
- package/src/migrations/functions/publishedAppsQuota.ts +0 -13
- package/src/migrations/functions/usageQuotas/syncDevelopers.ts +0 -19
- package/src/migrations/functions/usageQuotas/syncPublishedApps.ts +0 -21
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { npmUpload, urlUpload, githubUpload, fileUpload } from "./uploaders"
|
|
2
|
+
import { getGlobalDB } from "@budibase/backend-core/tenancy"
|
|
3
|
+
import { validate } from "@budibase/backend-core/plugins"
|
|
4
|
+
import { PluginType, FileType, PluginSource } from "@budibase/types"
|
|
5
|
+
import env from "../../../environment"
|
|
6
|
+
import { ClientAppSocket } from "../../../websocket"
|
|
7
|
+
import { db as dbCore } from "@budibase/backend-core"
|
|
8
|
+
import { plugins } from "@budibase/pro"
|
|
9
|
+
|
|
10
|
+
export async function getPlugins(type?: PluginType) {
|
|
11
|
+
const db = getGlobalDB()
|
|
12
|
+
const response = await db.allDocs(
|
|
13
|
+
dbCore.getPluginParams(null, {
|
|
14
|
+
include_docs: true,
|
|
15
|
+
})
|
|
16
|
+
)
|
|
17
|
+
const plugins = response.rows.map((row: any) => row.doc)
|
|
18
|
+
if (type) {
|
|
19
|
+
return plugins.filter((plugin: any) => plugin.schema?.type === type)
|
|
20
|
+
} else {
|
|
21
|
+
return plugins
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function upload(ctx: any) {
|
|
26
|
+
const plugins: FileType[] =
|
|
27
|
+
ctx.request.files.file.length > 1
|
|
28
|
+
? Array.from(ctx.request.files.file)
|
|
29
|
+
: [ctx.request.files.file]
|
|
30
|
+
try {
|
|
31
|
+
let docs = []
|
|
32
|
+
// can do single or multiple plugins
|
|
33
|
+
for (let plugin of plugins) {
|
|
34
|
+
const doc = await processUploadedPlugin(plugin, PluginSource.FILE)
|
|
35
|
+
docs.push(doc)
|
|
36
|
+
}
|
|
37
|
+
ctx.body = {
|
|
38
|
+
message: "Plugin(s) uploaded successfully",
|
|
39
|
+
plugins: docs,
|
|
40
|
+
}
|
|
41
|
+
} catch (err: any) {
|
|
42
|
+
const errMsg = err?.message ? err?.message : err
|
|
43
|
+
|
|
44
|
+
ctx.throw(400, `Failed to import plugin: ${errMsg}`)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function create(ctx: any) {
|
|
49
|
+
const { source, url, headers, githubToken } = ctx.request.body
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
let metadata
|
|
53
|
+
let directory
|
|
54
|
+
// Generating random name as a backup and needed for url
|
|
55
|
+
let name = "PLUGIN_" + Math.floor(100000 + Math.random() * 900000)
|
|
56
|
+
|
|
57
|
+
switch (source) {
|
|
58
|
+
case PluginSource.NPM:
|
|
59
|
+
const { metadata: metadataNpm, directory: directoryNpm } =
|
|
60
|
+
await npmUpload(url, name)
|
|
61
|
+
metadata = metadataNpm
|
|
62
|
+
directory = directoryNpm
|
|
63
|
+
break
|
|
64
|
+
case PluginSource.GITHUB:
|
|
65
|
+
const { metadata: metadataGithub, directory: directoryGithub } =
|
|
66
|
+
await githubUpload(url, name, githubToken)
|
|
67
|
+
metadata = metadataGithub
|
|
68
|
+
directory = directoryGithub
|
|
69
|
+
break
|
|
70
|
+
case PluginSource.URL:
|
|
71
|
+
const headersObj = headers || {}
|
|
72
|
+
const { metadata: metadataUrl, directory: directoryUrl } =
|
|
73
|
+
await urlUpload(url, name, headersObj)
|
|
74
|
+
metadata = metadataUrl
|
|
75
|
+
directory = directoryUrl
|
|
76
|
+
break
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
validate(metadata?.schema)
|
|
80
|
+
|
|
81
|
+
// Only allow components in cloud
|
|
82
|
+
if (!env.SELF_HOSTED && metadata?.schema?.type !== PluginType.COMPONENT) {
|
|
83
|
+
throw new Error(
|
|
84
|
+
"Only component plugins are supported outside of self-host"
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const doc = await plugins.storePlugin(metadata, directory, source)
|
|
89
|
+
|
|
90
|
+
ClientAppSocket.emit("plugins-update", { name, hash: doc.hash })
|
|
91
|
+
ctx.body = {
|
|
92
|
+
message: "Plugin uploaded successfully",
|
|
93
|
+
plugins: [doc],
|
|
94
|
+
}
|
|
95
|
+
ctx.body = { plugin: doc }
|
|
96
|
+
} catch (err: any) {
|
|
97
|
+
const errMsg = err?.message ? err?.message : err
|
|
98
|
+
|
|
99
|
+
ctx.throw(400, `Failed to import plugin: ${errMsg}`)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export async function fetch(ctx: any) {
|
|
104
|
+
ctx.body = await getPlugins()
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export async function destroy(ctx: any) {
|
|
108
|
+
const { pluginId } = ctx.params
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
await plugins.deletePlugin(pluginId)
|
|
112
|
+
|
|
113
|
+
ctx.body = { message: `Plugin ${ctx.params.pluginId} deleted.` }
|
|
114
|
+
} catch (err: any) {
|
|
115
|
+
ctx.throw(400, err.message)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export async function processUploadedPlugin(
|
|
120
|
+
plugin: FileType,
|
|
121
|
+
source?: PluginSource
|
|
122
|
+
) {
|
|
123
|
+
const { metadata, directory } = await fileUpload(plugin)
|
|
124
|
+
validate(metadata?.schema)
|
|
125
|
+
|
|
126
|
+
// Only allow components in cloud
|
|
127
|
+
if (!env.SELF_HOSTED && metadata?.schema?.type !== PluginType.COMPONENT) {
|
|
128
|
+
throw new Error("Only component plugins are supported outside of self-host")
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const doc = await plugins.storePlugin(metadata, directory, source)
|
|
132
|
+
ClientAppSocket.emit("plugins-update", { name: doc.name, hash: doc.hash })
|
|
133
|
+
return doc
|
|
134
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getPluginMetadata,
|
|
3
|
+
findFileRec,
|
|
4
|
+
extractTarball,
|
|
5
|
+
deleteFolderFileSystem,
|
|
6
|
+
} from "../../../utilities/fileSystem"
|
|
7
|
+
import fetch from "node-fetch"
|
|
8
|
+
import { join } from "path"
|
|
9
|
+
import { downloadUnzipTarball } from "./utils"
|
|
10
|
+
|
|
11
|
+
export async function npmUpload(url: string, name: string, headers = {}) {
|
|
12
|
+
let npmTarballUrl = url
|
|
13
|
+
let pluginName = name
|
|
14
|
+
|
|
15
|
+
if (
|
|
16
|
+
!npmTarballUrl.includes("https://www.npmjs.com") &&
|
|
17
|
+
!npmTarballUrl.includes("https://registry.npmjs.org")
|
|
18
|
+
) {
|
|
19
|
+
throw new Error("The plugin origin must be from NPM")
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (!npmTarballUrl.includes(".tgz")) {
|
|
23
|
+
const npmPackageURl = url.replace(
|
|
24
|
+
"https://www.npmjs.com/package/",
|
|
25
|
+
"https://registry.npmjs.org/"
|
|
26
|
+
)
|
|
27
|
+
const response = await fetch(npmPackageURl)
|
|
28
|
+
if (response.status !== 200) {
|
|
29
|
+
throw new Error("NPM Package not found")
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let npmDetails = await response.json()
|
|
33
|
+
pluginName = npmDetails.name
|
|
34
|
+
const npmVersion = npmDetails["dist-tags"].latest
|
|
35
|
+
npmTarballUrl = npmDetails?.versions?.[npmVersion]?.dist?.tarball
|
|
36
|
+
|
|
37
|
+
if (!npmTarballUrl) {
|
|
38
|
+
throw new Error("NPM tarball url not found")
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const path = await downloadUnzipTarball(npmTarballUrl, pluginName, headers)
|
|
43
|
+
const tarballPluginFile = findFileRec(path, ".tar.gz")
|
|
44
|
+
if (!tarballPluginFile) {
|
|
45
|
+
throw new Error("Tarball plugin file not found")
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
await extractTarball(tarballPluginFile, path)
|
|
50
|
+
deleteFolderFileSystem(join(path, "package"))
|
|
51
|
+
} catch (err: any) {
|
|
52
|
+
throw new Error(err)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return await getPluginMetadata(path)
|
|
56
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { downloadUnzipTarball } from "./utils"
|
|
2
|
+
import { getPluginMetadata } from "../../../utilities/fileSystem"
|
|
3
|
+
|
|
4
|
+
export async function urlUpload(url: string, name = "", headers = {}) {
|
|
5
|
+
if (!url.includes(".tar.gz")) {
|
|
6
|
+
throw new Error("Plugin must be compressed into a gzipped tarball.")
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const path = await downloadUnzipTarball(url, name, headers)
|
|
10
|
+
|
|
11
|
+
return await getPluginMetadata(path)
|
|
12
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createTempFolder,
|
|
3
|
+
downloadTarballDirect,
|
|
4
|
+
} from "../../../utilities/fileSystem"
|
|
5
|
+
|
|
6
|
+
export async function downloadUnzipTarball(
|
|
7
|
+
url: string,
|
|
8
|
+
name: string,
|
|
9
|
+
headers = {}
|
|
10
|
+
) {
|
|
11
|
+
try {
|
|
12
|
+
const path = createTempFolder(name)
|
|
13
|
+
await downloadTarballDirect(url, path, headers)
|
|
14
|
+
|
|
15
|
+
return path
|
|
16
|
+
} catch (e: any) {
|
|
17
|
+
throw new Error(e.message)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -4,10 +4,18 @@ export type Query = components["schemas"]["query"]
|
|
|
4
4
|
export type ExecuteQuery = components["schemas"]["executeQueryOutput"]
|
|
5
5
|
|
|
6
6
|
export type Application = components["schemas"]["applicationOutput"]["data"]
|
|
7
|
+
export type CreateApplicationParams = components["schemas"]["application"]
|
|
7
8
|
|
|
8
9
|
export type Table = components["schemas"]["tableOutput"]["data"]
|
|
10
|
+
export type CreateTableParams = components["schemas"]["table"]
|
|
9
11
|
|
|
10
12
|
export type Row = components["schemas"]["rowOutput"]["data"]
|
|
11
13
|
export type RowSearch = components["schemas"]["searchOutput"]
|
|
14
|
+
export type CreateRowParams = components["schemas"]["row"]
|
|
12
15
|
|
|
13
16
|
export type User = components["schemas"]["userOutput"]["data"]
|
|
17
|
+
export type CreateUserParams = components["schemas"]["user"]
|
|
18
|
+
|
|
19
|
+
export type SearchInputParams =
|
|
20
|
+
| components["schemas"]["nameSearch"]
|
|
21
|
+
| components["schemas"]["rowSearch"]
|
|
@@ -53,7 +53,7 @@ exports.save = async ctx => {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
exports.fetchView = async ctx => {
|
|
56
|
-
// there are no views in external
|
|
56
|
+
// there are no views in external datasources, shouldn't ever be called
|
|
57
57
|
// for now just fetch
|
|
58
58
|
const split = ctx.params.viewName.split("all_")
|
|
59
59
|
ctx.params.tableId = split[1] ? split[1] : split[0]
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { getScreenParams, generateScreenID, DocumentType } from "../../db/utils"
|
|
2
|
+
import {
|
|
3
|
+
events,
|
|
4
|
+
context,
|
|
5
|
+
tenancy,
|
|
6
|
+
db as dbCore,
|
|
7
|
+
roles,
|
|
8
|
+
} from "@budibase/backend-core"
|
|
9
|
+
import { updateAppPackage } from "./application"
|
|
10
|
+
import { Plugin, ScreenProps } from "@budibase/types"
|
|
11
|
+
|
|
12
|
+
exports.fetch = async (ctx: any) => {
|
|
13
|
+
const db = context.getAppDB()
|
|
14
|
+
|
|
15
|
+
const screens = (
|
|
16
|
+
await db.allDocs(
|
|
17
|
+
getScreenParams(null, {
|
|
18
|
+
include_docs: true,
|
|
19
|
+
})
|
|
20
|
+
)
|
|
21
|
+
).rows.map((el: any) => el.doc)
|
|
22
|
+
|
|
23
|
+
ctx.body = await new roles.AccessController().checkScreensAccess(
|
|
24
|
+
screens,
|
|
25
|
+
ctx.user.role._id
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
exports.save = async (ctx: any) => {
|
|
30
|
+
const db = context.getAppDB()
|
|
31
|
+
let screen = ctx.request.body
|
|
32
|
+
|
|
33
|
+
let eventFn
|
|
34
|
+
if (!screen._id) {
|
|
35
|
+
screen._id = generateScreenID()
|
|
36
|
+
eventFn = events.screen.created
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const response = await db.put(screen)
|
|
40
|
+
|
|
41
|
+
// Find any custom components being used
|
|
42
|
+
let pluginNames: string[] = []
|
|
43
|
+
let pluginAdded = false
|
|
44
|
+
findPlugins(screen.props, pluginNames)
|
|
45
|
+
if (pluginNames.length) {
|
|
46
|
+
const globalDB = tenancy.getGlobalDB()
|
|
47
|
+
const pluginsResponse = await globalDB.allDocs(
|
|
48
|
+
dbCore.getPluginParams(null, {
|
|
49
|
+
include_docs: true,
|
|
50
|
+
})
|
|
51
|
+
)
|
|
52
|
+
const requiredPlugins = pluginsResponse.rows
|
|
53
|
+
.map((row: any) => row.doc)
|
|
54
|
+
.filter((plugin: Plugin) => {
|
|
55
|
+
return (
|
|
56
|
+
plugin.schema.type === "component" &&
|
|
57
|
+
pluginNames.includes(`plugin/${plugin.name}`)
|
|
58
|
+
)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
// Update the app metadata
|
|
62
|
+
const application = await db.get(DocumentType.APP_METADATA)
|
|
63
|
+
let usedPlugins = application.usedPlugins || []
|
|
64
|
+
|
|
65
|
+
requiredPlugins.forEach((plugin: Plugin) => {
|
|
66
|
+
if (!usedPlugins.find((x: Plugin) => x._id === plugin._id)) {
|
|
67
|
+
pluginAdded = true
|
|
68
|
+
usedPlugins.push({
|
|
69
|
+
_id: plugin._id,
|
|
70
|
+
name: plugin.name,
|
|
71
|
+
version: plugin.version,
|
|
72
|
+
jsUrl: plugin.jsUrl,
|
|
73
|
+
hash: plugin.hash,
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
if (pluginAdded) {
|
|
79
|
+
await updateAppPackage({ usedPlugins }, ctx.appId)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (eventFn) {
|
|
84
|
+
await eventFn(screen)
|
|
85
|
+
}
|
|
86
|
+
ctx.message = `Screen ${screen.name} saved.`
|
|
87
|
+
ctx.body = {
|
|
88
|
+
...screen,
|
|
89
|
+
_id: response.id,
|
|
90
|
+
_rev: response.rev,
|
|
91
|
+
pluginAdded,
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
exports.destroy = async (ctx: any) => {
|
|
96
|
+
const db = context.getAppDB()
|
|
97
|
+
const id = ctx.params.screenId
|
|
98
|
+
const screen = await db.get(id)
|
|
99
|
+
|
|
100
|
+
await db.remove(id, ctx.params.screenRev)
|
|
101
|
+
|
|
102
|
+
await events.screen.deleted(screen)
|
|
103
|
+
ctx.body = {
|
|
104
|
+
message: "Screen deleted successfully",
|
|
105
|
+
}
|
|
106
|
+
ctx.status = 200
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const findPlugins = (component: ScreenProps, foundPlugins: string[]) => {
|
|
110
|
+
if (!component) {
|
|
111
|
+
return
|
|
112
|
+
}
|
|
113
|
+
if (component._component.startsWith("plugin")) {
|
|
114
|
+
if (!foundPlugins.includes(component._component)) {
|
|
115
|
+
foundPlugins.push(component._component)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (!component._children || !component._children.length) {
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
component._children.forEach(child => findPlugins(child, foundPlugins))
|
|
122
|
+
}
|
|
@@ -18,7 +18,6 @@ const { DocumentType } = require("../../../db/utils")
|
|
|
18
18
|
const { getAppDB, getAppId } = require("@budibase/backend-core/context")
|
|
19
19
|
const { setCookie, clearCookie } = require("@budibase/backend-core/utils")
|
|
20
20
|
const AWS = require("aws-sdk")
|
|
21
|
-
|
|
22
21
|
const fs = require("fs")
|
|
23
22
|
const {
|
|
24
23
|
downloadTarballDirect,
|
|
@@ -113,6 +112,7 @@ export const serveApp = async function (ctx: any) {
|
|
|
113
112
|
production: env.isProd(),
|
|
114
113
|
appId,
|
|
115
114
|
clientLibPath: clientLibraryPath(appId, appInfo.version, ctx),
|
|
115
|
+
usedPlugins: appInfo.usedPlugins,
|
|
116
116
|
})
|
|
117
117
|
|
|
118
118
|
const appHbs = loadHandlebarsFile(`${__dirname}/templates/app.hbs`)
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
export let favicon = ""
|
|
4
4
|
|
|
5
5
|
export let clientLibPath
|
|
6
|
+
export let usedPlugins
|
|
6
7
|
</script>
|
|
7
8
|
|
|
8
9
|
<svelte:head>
|
|
@@ -83,6 +84,15 @@
|
|
|
83
84
|
</script>
|
|
84
85
|
<script type="application/javascript" src={clientLibPath}>
|
|
85
86
|
</script>
|
|
87
|
+
<!-- Custom components need inserted after the core client library -->
|
|
88
|
+
<!-- But before loadBudibase is called -->
|
|
89
|
+
{#if usedPlugins?.length}
|
|
90
|
+
{#each usedPlugins as plugin}
|
|
91
|
+
<script
|
|
92
|
+
type="application/javascript"
|
|
93
|
+
src={`/plugins/${plugin.jsUrl}`}></script>
|
|
94
|
+
{/each}
|
|
95
|
+
{/if}
|
|
86
96
|
<script type="application/javascript">
|
|
87
97
|
if (window.loadBudibase) {
|
|
88
98
|
window.loadBudibase()
|
|
@@ -66,7 +66,9 @@
|
|
|
66
66
|
customTheme,
|
|
67
67
|
previewDevice,
|
|
68
68
|
navigation,
|
|
69
|
-
hiddenComponentIds
|
|
69
|
+
hiddenComponentIds,
|
|
70
|
+
usedPlugins,
|
|
71
|
+
location
|
|
70
72
|
} = parsed
|
|
71
73
|
|
|
72
74
|
// Set some flags so the app knows we're in the builder
|
|
@@ -81,6 +83,8 @@
|
|
|
81
83
|
window["##BUDIBASE_PREVIEW_DEVICE##"] = previewDevice
|
|
82
84
|
window["##BUDIBASE_PREVIEW_NAVIGATION##"] = navigation
|
|
83
85
|
window["##BUDIBASE_HIDDEN_COMPONENT_IDS##"] = hiddenComponentIds
|
|
86
|
+
window["##BUDIBASE_USED_PLUGINS##"] = usedPlugins
|
|
87
|
+
window["##BUDIBASE_LOCATION##"] = location
|
|
84
88
|
|
|
85
89
|
// Initialise app
|
|
86
90
|
try {
|
package/src/api/index.js
CHANGED
|
@@ -2,16 +2,27 @@ import Router from "@koa/router"
|
|
|
2
2
|
import * as controller from "../controllers/application"
|
|
3
3
|
import authorized from "../../middleware/authorized"
|
|
4
4
|
import { BUILDER } from "@budibase/backend-core/permissions"
|
|
5
|
+
import { applicationValidator } from "./utils/validators"
|
|
5
6
|
|
|
6
7
|
const router = new Router()
|
|
7
8
|
|
|
8
9
|
router
|
|
9
10
|
.post("/api/applications/:appId/sync", authorized(BUILDER), controller.sync)
|
|
10
|
-
.post(
|
|
11
|
+
.post(
|
|
12
|
+
"/api/applications",
|
|
13
|
+
authorized(BUILDER),
|
|
14
|
+
applicationValidator(),
|
|
15
|
+
controller.create
|
|
16
|
+
)
|
|
11
17
|
.get("/api/applications/:appId/definition", controller.fetchAppDefinition)
|
|
12
18
|
.get("/api/applications", controller.fetch)
|
|
13
19
|
.get("/api/applications/:appId/appPackage", controller.fetchAppPackage)
|
|
14
|
-
.put(
|
|
20
|
+
.put(
|
|
21
|
+
"/api/applications/:appId",
|
|
22
|
+
authorized(BUILDER),
|
|
23
|
+
applicationValidator({ isCreate: false }),
|
|
24
|
+
controller.update
|
|
25
|
+
)
|
|
15
26
|
.post(
|
|
16
27
|
"/api/applications/:appId/client/update",
|
|
17
28
|
authorized(BUILDER),
|
package/src/api/routes/index.ts
CHANGED
|
@@ -24,6 +24,7 @@ import metadataRoutes from "./metadata"
|
|
|
24
24
|
import devRoutes from "./dev"
|
|
25
25
|
import cloudRoutes from "./cloud"
|
|
26
26
|
import migrationRoutes from "./migrations"
|
|
27
|
+
import pluginRoutes from "./plugin"
|
|
27
28
|
|
|
28
29
|
export { default as staticRoutes } from "./static"
|
|
29
30
|
export { default as publicRoutes } from "./public"
|
|
@@ -57,4 +58,5 @@ export const mainRoutes = [
|
|
|
57
58
|
tableRoutes,
|
|
58
59
|
rowRoutes,
|
|
59
60
|
migrationRoutes,
|
|
61
|
+
pluginRoutes,
|
|
60
62
|
]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import Router from "@koa/router"
|
|
2
|
+
import * as controller from "../controllers/plugin"
|
|
3
|
+
import authorized from "../../middleware/authorized"
|
|
4
|
+
import { BUILDER } from "@budibase/backend-core/permissions"
|
|
5
|
+
|
|
6
|
+
const router = new Router()
|
|
7
|
+
|
|
8
|
+
router
|
|
9
|
+
.post("/api/plugin/upload", authorized(BUILDER), controller.upload)
|
|
10
|
+
.post("/api/plugin", authorized(BUILDER), controller.create)
|
|
11
|
+
.get("/api/plugin", authorized(BUILDER), controller.fetch)
|
|
12
|
+
.delete("/api/plugin/:pluginId", authorized(BUILDER), controller.destroy)
|
|
13
|
+
|
|
14
|
+
export default router
|
|
@@ -143,88 +143,7 @@ read.push(new Endpoint("get", "/tables/:tableId/rows/:rowId", controller.read))
|
|
|
143
143
|
* content:
|
|
144
144
|
* application/json:
|
|
145
145
|
* schema:
|
|
146
|
-
*
|
|
147
|
-
* required:
|
|
148
|
-
* - query
|
|
149
|
-
* properties:
|
|
150
|
-
* query:
|
|
151
|
-
* type: object
|
|
152
|
-
* properties:
|
|
153
|
-
* allOr:
|
|
154
|
-
* type: boolean
|
|
155
|
-
* description: Specifies that a row should be returned if it satisfies
|
|
156
|
-
* any of the specified options, rather than requiring it to fulfill all
|
|
157
|
-
* the search parameters. This defaults to false, meaning AND logic will be used.
|
|
158
|
-
* string:
|
|
159
|
-
* type: object
|
|
160
|
-
* example:
|
|
161
|
-
* columnName1: value
|
|
162
|
-
* columnName2: value
|
|
163
|
-
* description: A map of field name to the string to search for,
|
|
164
|
-
* this will look for rows that have a value starting with the
|
|
165
|
-
* string value.
|
|
166
|
-
* additionalProperties:
|
|
167
|
-
* type: string
|
|
168
|
-
* description: The value to search for in the column.
|
|
169
|
-
* fuzzy:
|
|
170
|
-
* type: object
|
|
171
|
-
* description: A fuzzy search, only supported by internal tables.
|
|
172
|
-
* range:
|
|
173
|
-
* type: object
|
|
174
|
-
* description: Searches within a range, the format of this must be
|
|
175
|
-
* in the format of an object with a "low" and "high" property.
|
|
176
|
-
* example:
|
|
177
|
-
* columnName1: { low: 10, high: 20 }
|
|
178
|
-
* equal:
|
|
179
|
-
* type: object
|
|
180
|
-
* description: Searches for rows that have a column value that is
|
|
181
|
-
* exactly the value set.
|
|
182
|
-
* notEqual:
|
|
183
|
-
* type: object
|
|
184
|
-
* description: Searches for any row which does not contain the specified
|
|
185
|
-
* column value.
|
|
186
|
-
* empty:
|
|
187
|
-
* type: object
|
|
188
|
-
* description: Searches for rows which do not contain the specified column.
|
|
189
|
-
* The object should simply contain keys of the column names, these
|
|
190
|
-
* can map to any value.
|
|
191
|
-
* example:
|
|
192
|
-
* columnName1: ""
|
|
193
|
-
* notEmpty:
|
|
194
|
-
* type: object
|
|
195
|
-
* description: Searches for rows which have the specified column.
|
|
196
|
-
* oneOf:
|
|
197
|
-
* type: object
|
|
198
|
-
* description: Searches for rows which have a column value that is any
|
|
199
|
-
* of the specified values. The format of this must be columnName -> [value1, value2].
|
|
200
|
-
* paginate:
|
|
201
|
-
* type: boolean
|
|
202
|
-
* description: Enables pagination, by default this is disabled.
|
|
203
|
-
* bookmark:
|
|
204
|
-
* oneOf:
|
|
205
|
-
* - type: string
|
|
206
|
-
* - type: integer
|
|
207
|
-
* description: If retrieving another page, the bookmark from the previous request must be supplied.
|
|
208
|
-
* limit:
|
|
209
|
-
* type: integer
|
|
210
|
-
* description: The maximum number of rows to return, useful when paginating, for internal tables this
|
|
211
|
-
* will be limited to 1000, for SQL tables it will be 5000.
|
|
212
|
-
* sort:
|
|
213
|
-
* type: object
|
|
214
|
-
* description: A set of parameters describing the sort behaviour of the search.
|
|
215
|
-
* properties:
|
|
216
|
-
* order:
|
|
217
|
-
* type: string
|
|
218
|
-
* enum: [ascending, descending]
|
|
219
|
-
* description: The order of the sort, by default this is ascending.
|
|
220
|
-
* column:
|
|
221
|
-
* type: string
|
|
222
|
-
* description: The name of the column by which the rows will be sorted.
|
|
223
|
-
* type:
|
|
224
|
-
* type: string
|
|
225
|
-
* enum: [string, number]
|
|
226
|
-
* description: Defines whether the column should be treated as a string
|
|
227
|
-
* or as numbers when sorting.
|
|
146
|
+
* $ref: '#/components/schemas/rowSearch'
|
|
228
147
|
* responses:
|
|
229
148
|
* 200:
|
|
230
149
|
* description: The response will contain an array of rows that match the search parameters.
|
|
@@ -26,7 +26,7 @@ const read = [],
|
|
|
26
26
|
* responses:
|
|
27
27
|
* 200:
|
|
28
28
|
* description: Returns the created table, including the ID which has been generated for it. This can be
|
|
29
|
-
* internal or external
|
|
29
|
+
* internal or external datasources.
|
|
30
30
|
* content:
|
|
31
31
|
* application/json:
|
|
32
32
|
* schema:
|
package/src/api/routes/table.js
CHANGED
|
@@ -55,7 +55,7 @@ router
|
|
|
55
55
|
* @apiParam (Body) {string} [_rev] If updating an existing internal table then the revision must also be specified.
|
|
56
56
|
* @apiParam (Body) {string} type] This should either be "internal" or "external" depending on the table type -
|
|
57
57
|
* this will default to internal.
|
|
58
|
-
* @apiParam (Body) {string} [sourceId] If creating an external table then this should be set to the
|
|
58
|
+
* @apiParam (Body) {string} [sourceId] If creating an external table then this should be set to the datasource ID. If
|
|
59
59
|
* building an internal table this does not need to be set, although it will be returned as "bb_internal".
|
|
60
60
|
* @apiParam (Body) {string} name The name of the table, this will be used in the UI. To rename the table simply
|
|
61
61
|
* supply the table structure to this endpoint with the name changed.
|
|
@@ -231,20 +231,6 @@ describe("/queries", () => {
|
|
|
231
231
|
url: `/api/queries/preview`,
|
|
232
232
|
})
|
|
233
233
|
})
|
|
234
|
-
|
|
235
|
-
it("should fail with invalid integration type", async () => {
|
|
236
|
-
const { datasource } = await createInvalidIntegration()
|
|
237
|
-
await request
|
|
238
|
-
.post(`/api/queries/preview`)
|
|
239
|
-
.send({
|
|
240
|
-
datasourceId: datasource._id,
|
|
241
|
-
parameters: {},
|
|
242
|
-
fields: {},
|
|
243
|
-
queryVerb: "read",
|
|
244
|
-
})
|
|
245
|
-
.set(config.defaultHeaders())
|
|
246
|
-
.expect(400)
|
|
247
|
-
})
|
|
248
234
|
})
|
|
249
235
|
|
|
250
236
|
describe("execute", () => {
|
|
@@ -261,17 +247,14 @@ describe("/queries", () => {
|
|
|
261
247
|
})
|
|
262
248
|
|
|
263
249
|
it("should fail with invalid integration type", async () => {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
})
|
|
273
|
-
.set(config.defaultHeaders())
|
|
274
|
-
.expect(400)
|
|
250
|
+
let error
|
|
251
|
+
try {
|
|
252
|
+
await createInvalidIntegration()
|
|
253
|
+
} catch (err) {
|
|
254
|
+
error = err
|
|
255
|
+
}
|
|
256
|
+
expect(error).toBeDefined()
|
|
257
|
+
expect(error.message).toBe("No datasource implementation found.")
|
|
275
258
|
})
|
|
276
259
|
})
|
|
277
260
|
|