Merge branch 'master' of github.com:budibase/budibase into budi-8882-ms-sql-export-schema-feature-creates-and-downloads
This commit is contained in:
commit
0e6b3c258a
|
@ -2,6 +2,8 @@ import {
|
||||||
PermissionLevel,
|
PermissionLevel,
|
||||||
PermissionType,
|
PermissionType,
|
||||||
BuiltinPermissionID,
|
BuiltinPermissionID,
|
||||||
|
Permission,
|
||||||
|
BuiltinPermissions,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import flatten from "lodash/flatten"
|
import flatten from "lodash/flatten"
|
||||||
import cloneDeep from "lodash/fp/cloneDeep"
|
import cloneDeep from "lodash/fp/cloneDeep"
|
||||||
|
@ -12,7 +14,7 @@ export type RoleHierarchy = {
|
||||||
permissionId: string
|
permissionId: string
|
||||||
}[]
|
}[]
|
||||||
|
|
||||||
export class Permission {
|
export class PermissionImpl implements Permission {
|
||||||
type: PermissionType
|
type: PermissionType
|
||||||
level: PermissionLevel
|
level: PermissionLevel
|
||||||
|
|
||||||
|
@ -61,68 +63,62 @@ export function getAllowedLevels(userPermLevel: PermissionLevel): string[] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BUILTIN_PERMISSIONS: {
|
export const BUILTIN_PERMISSIONS: BuiltinPermissions = {
|
||||||
[key in keyof typeof BuiltinPermissionID]: {
|
|
||||||
_id: (typeof BuiltinPermissionID)[key]
|
|
||||||
name: string
|
|
||||||
permissions: Permission[]
|
|
||||||
}
|
|
||||||
} = {
|
|
||||||
PUBLIC: {
|
PUBLIC: {
|
||||||
_id: BuiltinPermissionID.PUBLIC,
|
_id: BuiltinPermissionID.PUBLIC,
|
||||||
name: "Public",
|
name: "Public",
|
||||||
permissions: [
|
permissions: [
|
||||||
new Permission(PermissionType.WEBHOOK, PermissionLevel.EXECUTE),
|
new PermissionImpl(PermissionType.WEBHOOK, PermissionLevel.EXECUTE),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
READ_ONLY: {
|
READ_ONLY: {
|
||||||
_id: BuiltinPermissionID.READ_ONLY,
|
_id: BuiltinPermissionID.READ_ONLY,
|
||||||
name: "Read only",
|
name: "Read only",
|
||||||
permissions: [
|
permissions: [
|
||||||
new Permission(PermissionType.QUERY, PermissionLevel.READ),
|
new PermissionImpl(PermissionType.QUERY, PermissionLevel.READ),
|
||||||
new Permission(PermissionType.TABLE, PermissionLevel.READ),
|
new PermissionImpl(PermissionType.TABLE, PermissionLevel.READ),
|
||||||
new Permission(PermissionType.APP, PermissionLevel.READ),
|
new PermissionImpl(PermissionType.APP, PermissionLevel.READ),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
WRITE: {
|
WRITE: {
|
||||||
_id: BuiltinPermissionID.WRITE,
|
_id: BuiltinPermissionID.WRITE,
|
||||||
name: "Read/Write",
|
name: "Read/Write",
|
||||||
permissions: [
|
permissions: [
|
||||||
new Permission(PermissionType.QUERY, PermissionLevel.WRITE),
|
new PermissionImpl(PermissionType.QUERY, PermissionLevel.WRITE),
|
||||||
new Permission(PermissionType.TABLE, PermissionLevel.WRITE),
|
new PermissionImpl(PermissionType.TABLE, PermissionLevel.WRITE),
|
||||||
new Permission(PermissionType.AUTOMATION, PermissionLevel.EXECUTE),
|
new PermissionImpl(PermissionType.AUTOMATION, PermissionLevel.EXECUTE),
|
||||||
new Permission(PermissionType.LEGACY_VIEW, PermissionLevel.READ),
|
new PermissionImpl(PermissionType.LEGACY_VIEW, PermissionLevel.READ),
|
||||||
new Permission(PermissionType.APP, PermissionLevel.READ),
|
new PermissionImpl(PermissionType.APP, PermissionLevel.READ),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
POWER: {
|
POWER: {
|
||||||
_id: BuiltinPermissionID.POWER,
|
_id: BuiltinPermissionID.POWER,
|
||||||
name: "Power",
|
name: "Power",
|
||||||
permissions: [
|
permissions: [
|
||||||
new Permission(PermissionType.TABLE, PermissionLevel.WRITE),
|
new PermissionImpl(PermissionType.TABLE, PermissionLevel.WRITE),
|
||||||
new Permission(PermissionType.USER, PermissionLevel.READ),
|
new PermissionImpl(PermissionType.USER, PermissionLevel.READ),
|
||||||
new Permission(PermissionType.AUTOMATION, PermissionLevel.EXECUTE),
|
new PermissionImpl(PermissionType.AUTOMATION, PermissionLevel.EXECUTE),
|
||||||
new Permission(PermissionType.WEBHOOK, PermissionLevel.READ),
|
new PermissionImpl(PermissionType.WEBHOOK, PermissionLevel.READ),
|
||||||
new Permission(PermissionType.LEGACY_VIEW, PermissionLevel.READ),
|
new PermissionImpl(PermissionType.LEGACY_VIEW, PermissionLevel.READ),
|
||||||
new Permission(PermissionType.APP, PermissionLevel.READ),
|
new PermissionImpl(PermissionType.APP, PermissionLevel.READ),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
ADMIN: {
|
ADMIN: {
|
||||||
_id: BuiltinPermissionID.ADMIN,
|
_id: BuiltinPermissionID.ADMIN,
|
||||||
name: "Admin",
|
name: "Admin",
|
||||||
permissions: [
|
permissions: [
|
||||||
new Permission(PermissionType.TABLE, PermissionLevel.ADMIN),
|
new PermissionImpl(PermissionType.TABLE, PermissionLevel.ADMIN),
|
||||||
new Permission(PermissionType.USER, PermissionLevel.ADMIN),
|
new PermissionImpl(PermissionType.USER, PermissionLevel.ADMIN),
|
||||||
new Permission(PermissionType.AUTOMATION, PermissionLevel.ADMIN),
|
new PermissionImpl(PermissionType.AUTOMATION, PermissionLevel.ADMIN),
|
||||||
new Permission(PermissionType.WEBHOOK, PermissionLevel.READ),
|
new PermissionImpl(PermissionType.WEBHOOK, PermissionLevel.READ),
|
||||||
new Permission(PermissionType.QUERY, PermissionLevel.ADMIN),
|
new PermissionImpl(PermissionType.QUERY, PermissionLevel.ADMIN),
|
||||||
new Permission(PermissionType.LEGACY_VIEW, PermissionLevel.READ),
|
new PermissionImpl(PermissionType.LEGACY_VIEW, PermissionLevel.READ),
|
||||||
new Permission(PermissionType.APP, PermissionLevel.READ),
|
new PermissionImpl(PermissionType.APP, PermissionLevel.READ),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getBuiltinPermissions() {
|
export function getBuiltinPermissions(): BuiltinPermissions {
|
||||||
return cloneDeep(BUILTIN_PERMISSIONS)
|
return cloneDeep(BUILTIN_PERMISSIONS)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -133,7 +133,7 @@ describe("getBuiltinPermissionByID", () => {
|
||||||
_id: BuiltinPermissionID.PUBLIC,
|
_id: BuiltinPermissionID.PUBLIC,
|
||||||
name: "Public",
|
name: "Public",
|
||||||
permissions: [
|
permissions: [
|
||||||
new permissions.Permission(
|
new permissions.PermissionImpl(
|
||||||
permissions.PermissionType.WEBHOOK,
|
permissions.PermissionType.WEBHOOK,
|
||||||
permissions.PermissionLevel.EXECUTE
|
permissions.PermissionLevel.EXECUTE
|
||||||
),
|
),
|
||||||
|
|
|
@ -52,9 +52,16 @@
|
||||||
let modal
|
let modal
|
||||||
|
|
||||||
$: text = value?.label ?? "Choose an option"
|
$: text = value?.label ?? "Choose an option"
|
||||||
$: tables = $tablesStore.list.map(table =>
|
$: tables = $tablesStore.list
|
||||||
format.table(table, $datasources.list)
|
.map(table => format.table(table, $datasources.list))
|
||||||
)
|
.sort((a, b) => {
|
||||||
|
// sort tables alphabetically, grouped by datasource
|
||||||
|
const dsComparison = a.datasourceName.localeCompare(b.datasourceName)
|
||||||
|
if (dsComparison !== 0) {
|
||||||
|
return dsComparison
|
||||||
|
}
|
||||||
|
return a.label.localeCompare(b.label)
|
||||||
|
})
|
||||||
$: viewsV1 = $viewsStore.list.map(view => ({
|
$: viewsV1 = $viewsStore.list.map(view => ({
|
||||||
...view,
|
...view,
|
||||||
label: view.name,
|
label: view.name,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { Heading, Body, Layout, Button, Modal } from "@budibase/bbui"
|
import { Heading, Body, Layout, Button, Modal, Icon } from "@budibase/bbui"
|
||||||
import AutomationPanel from "components/automation/AutomationPanel/AutomationPanel.svelte"
|
import AutomationPanel from "components/automation/AutomationPanel/AutomationPanel.svelte"
|
||||||
import CreateAutomationModal from "components/automation/AutomationPanel/CreateAutomationModal.svelte"
|
import CreateAutomationModal from "components/automation/AutomationPanel/CreateAutomationModal.svelte"
|
||||||
import CreateWebhookModal from "components/automation/Shared/CreateWebhookModal.svelte"
|
import CreateWebhookModal from "components/automation/Shared/CreateWebhookModal.svelte"
|
||||||
|
@ -12,11 +12,13 @@
|
||||||
automationStore,
|
automationStore,
|
||||||
selectedAutomation,
|
selectedAutomation,
|
||||||
} from "stores/builder"
|
} from "stores/builder"
|
||||||
|
import { createLocalStorageStore } from "@budibase/frontend-core"
|
||||||
|
import { fly } from "svelte/transition"
|
||||||
|
|
||||||
$: automationId = $selectedAutomation?.data?._id
|
$: automationId = $selectedAutomation?.data?._id
|
||||||
$: builderStore.selectResource(automationId)
|
$: builderStore.selectResource(automationId)
|
||||||
|
|
||||||
// Keep URL and state in sync for selected screen ID
|
const surveyDismissed = createLocalStorageStore("automation-survey", false)
|
||||||
const stopSyncing = syncURLToState({
|
const stopSyncing = syncURLToState({
|
||||||
urlParam: "automationId",
|
urlParam: "automationId",
|
||||||
stateKey: "selectedAutomationId",
|
stateKey: "selectedAutomationId",
|
||||||
|
@ -29,9 +31,11 @@
|
||||||
|
|
||||||
let modal
|
let modal
|
||||||
let webhookModal
|
let webhookModal
|
||||||
|
let mounted = false
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
$automationStore.showTestPanel = false
|
$automationStore.showTestPanel = false
|
||||||
|
mounted = true
|
||||||
})
|
})
|
||||||
|
|
||||||
onDestroy(stopSyncing)
|
onDestroy(stopSyncing)
|
||||||
|
@ -79,6 +83,43 @@
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{#if !$surveyDismissed && mounted}
|
||||||
|
<div
|
||||||
|
class="survey"
|
||||||
|
in:fly={{ x: 600, duration: 260, delay: 1000 }}
|
||||||
|
out:fly={{ x: 600, duration: 260 }}
|
||||||
|
>
|
||||||
|
<div class="survey__body">
|
||||||
|
<div class="survey__title">We value your feedback!</div>
|
||||||
|
<div class="survey__text">
|
||||||
|
<a
|
||||||
|
href="https://t.maze.co/310149185"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
on:click={() => surveyDismissed.set(true)}
|
||||||
|
>
|
||||||
|
Complete our survey on Automations</a
|
||||||
|
>
|
||||||
|
and receive a $20 thank-you gift.
|
||||||
|
<a
|
||||||
|
href="https://drive.google.com/file/d/12-qk_2F9g5PdbM6wuKoz2KkIyLI-feMX/view?usp=sharing"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
Terms apply.
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Icon
|
||||||
|
name="Close"
|
||||||
|
hoverable
|
||||||
|
color="var(--spectrum-global-color-static-gray-300)"
|
||||||
|
hoverColor="var(--spectrum-global-color-static-gray-100)"
|
||||||
|
on:click={() => surveyDismissed.set(true)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.root {
|
.root {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
|
@ -108,11 +149,9 @@
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main {
|
.main {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.setup {
|
.setup {
|
||||||
padding-top: 9px;
|
padding-top: 9px;
|
||||||
border-left: var(--border-light);
|
border-left: var(--border-light);
|
||||||
|
@ -125,4 +164,39 @@
|
||||||
grid-column: 3;
|
grid-column: 3;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Survey */
|
||||||
|
.survey {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 32px;
|
||||||
|
right: 32px;
|
||||||
|
background: var(--spectrum-semantic-positive-color-background);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
padding: var(--spacing-l) var(--spacing-xl);
|
||||||
|
border-radius: 4px;
|
||||||
|
gap: var(--spacing-xl);
|
||||||
|
}
|
||||||
|
.survey * {
|
||||||
|
color: var(--spectrum-global-color-static-gray-300);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.survey a {
|
||||||
|
text-decoration: underline;
|
||||||
|
transition: color 130ms ease-out;
|
||||||
|
}
|
||||||
|
.survey a:hover {
|
||||||
|
color: var(--spectrum-global-color-static-gray-100);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.survey__body {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2px;
|
||||||
|
}
|
||||||
|
.survey__title {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
import { getDefinition, getDefinitions } from "../../integrations"
|
import { getDefinition, getDefinitions } from "../../integrations"
|
||||||
import { SourceName, UserCtx } from "@budibase/types"
|
import {
|
||||||
|
SourceName,
|
||||||
|
UserCtx,
|
||||||
|
FetchIntegrationsResponse,
|
||||||
|
FindIntegrationResponse,
|
||||||
|
} from "@budibase/types"
|
||||||
|
|
||||||
const DISABLED_EXTERNAL_INTEGRATIONS = [
|
const DISABLED_EXTERNAL_INTEGRATIONS = [
|
||||||
SourceName.AIRTABLE,
|
SourceName.AIRTABLE,
|
||||||
SourceName.BUDIBASE,
|
SourceName.BUDIBASE,
|
||||||
]
|
]
|
||||||
|
|
||||||
export async function fetch(ctx: UserCtx) {
|
export async function fetch(ctx: UserCtx<void, FetchIntegrationsResponse>) {
|
||||||
const definitions = await getDefinitions()
|
const definitions = await getDefinitions()
|
||||||
for (let disabledIntegration of DISABLED_EXTERNAL_INTEGRATIONS) {
|
for (let disabledIntegration of DISABLED_EXTERNAL_INTEGRATIONS) {
|
||||||
delete definitions[disabledIntegration]
|
delete definitions[disabledIntegration]
|
||||||
|
@ -14,10 +19,14 @@ export async function fetch(ctx: UserCtx) {
|
||||||
ctx.body = definitions
|
ctx.body = definitions
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function find(ctx: UserCtx) {
|
export async function find(ctx: UserCtx<void, FindIntegrationResponse>) {
|
||||||
const sourceType = ctx.params?.type
|
const sourceType = ctx.params?.type
|
||||||
if (DISABLED_EXTERNAL_INTEGRATIONS.indexOf(sourceType) !== -1) {
|
if (DISABLED_EXTERNAL_INTEGRATIONS.indexOf(sourceType) !== -1) {
|
||||||
ctx.throw(400, `Invalid source type - ${sourceType} is not supported.`)
|
ctx.throw(400, `Invalid source type - ${sourceType} is not supported.`)
|
||||||
}
|
}
|
||||||
ctx.body = await getDefinition(ctx.params.type)
|
const integration = await getDefinition(ctx.params.type)
|
||||||
|
if (!integration) {
|
||||||
|
ctx.throw(404, "Integration not found")
|
||||||
|
}
|
||||||
|
ctx.body = integration
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { EMPTY_LAYOUT } from "../../constants/layouts"
|
||||||
import { generateLayoutID, getScreenParams } from "../../db/utils"
|
import { generateLayoutID, getScreenParams } from "../../db/utils"
|
||||||
import { events, context } from "@budibase/backend-core"
|
import { events, context } from "@budibase/backend-core"
|
||||||
import {
|
import {
|
||||||
BBContext,
|
DeleteLayoutResponse,
|
||||||
Layout,
|
Layout,
|
||||||
SaveLayoutRequest,
|
SaveLayoutRequest,
|
||||||
SaveLayoutResponse,
|
SaveLayoutResponse,
|
||||||
|
@ -32,7 +32,7 @@ export async function save(
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function destroy(ctx: BBContext) {
|
export async function destroy(ctx: UserCtx<void, DeleteLayoutResponse>) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
const layoutId = ctx.params.layoutId,
|
const layoutId = ctx.params.layoutId,
|
||||||
layoutRev = ctx.params.layoutRev
|
layoutRev = ctx.params.layoutRev
|
||||||
|
|
|
@ -1,24 +1,35 @@
|
||||||
import { MetadataTypes } from "../../constants"
|
|
||||||
import { generateMetadataID } from "../../db/utils"
|
import { generateMetadataID } from "../../db/utils"
|
||||||
import { saveEntityMetadata, deleteEntityMetadata } from "../../utilities"
|
import { saveEntityMetadata, deleteEntityMetadata } from "../../utilities"
|
||||||
import { context } from "@budibase/backend-core"
|
import { context } from "@budibase/backend-core"
|
||||||
import { BBContext } from "@budibase/types"
|
import {
|
||||||
|
UserCtx,
|
||||||
|
MetadataType,
|
||||||
|
GetMetadataTypesResponse,
|
||||||
|
SaveMetadataRequest,
|
||||||
|
SaveMetadataResponse,
|
||||||
|
DeleteMetadataResponse,
|
||||||
|
FindMetadataResponse,
|
||||||
|
} from "@budibase/types"
|
||||||
|
|
||||||
export async function getTypes(ctx: BBContext) {
|
export async function getTypes(ctx: UserCtx<void, GetMetadataTypesResponse>) {
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
types: MetadataTypes,
|
types: MetadataType,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function saveMetadata(ctx: BBContext) {
|
export async function saveMetadata(
|
||||||
|
ctx: UserCtx<SaveMetadataRequest, SaveMetadataResponse>
|
||||||
|
) {
|
||||||
const { type, entityId } = ctx.params
|
const { type, entityId } = ctx.params
|
||||||
if (type === MetadataTypes.AUTOMATION_TEST_HISTORY) {
|
if (type === MetadataType.AUTOMATION_TEST_HISTORY) {
|
||||||
ctx.throw(400, "Cannot save automation history type")
|
ctx.throw(400, "Cannot save automation history type")
|
||||||
}
|
}
|
||||||
ctx.body = await saveEntityMetadata(type, entityId, ctx.request.body)
|
ctx.body = await saveEntityMetadata(type, entityId, ctx.request.body)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteMetadata(ctx: BBContext) {
|
export async function deleteMetadata(
|
||||||
|
ctx: UserCtx<void, DeleteMetadataResponse>
|
||||||
|
) {
|
||||||
const { type, entityId } = ctx.params
|
const { type, entityId } = ctx.params
|
||||||
await deleteEntityMetadata(type, entityId)
|
await deleteEntityMetadata(type, entityId)
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
|
@ -26,17 +37,9 @@ export async function deleteMetadata(ctx: BBContext) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getMetadata(ctx: BBContext) {
|
export async function getMetadata(ctx: UserCtx<void, FindMetadataResponse>) {
|
||||||
const { type, entityId } = ctx.params
|
const { type, entityId } = ctx.params
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
const id = generateMetadataID(type, entityId)
|
const id = generateMetadataID(type, entityId)
|
||||||
try {
|
ctx.body = (await db.tryGet(id)) || {}
|
||||||
ctx.body = await db.get(id)
|
|
||||||
} catch (err: any) {
|
|
||||||
if (err.status === 404) {
|
|
||||||
ctx.body = {}
|
|
||||||
} else {
|
|
||||||
ctx.throw(err.status, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,33 @@
|
||||||
import { context } from "@budibase/backend-core"
|
import { context } from "@budibase/backend-core"
|
||||||
import { migrate as migrationImpl, MIGRATIONS } from "../../migrations"
|
import { migrate as migrationImpl, MIGRATIONS } from "../../migrations"
|
||||||
import { Ctx } from "@budibase/types"
|
import {
|
||||||
|
Ctx,
|
||||||
|
FetchOldMigrationResponse,
|
||||||
|
GetOldMigrationStatus,
|
||||||
|
RunOldMigrationRequest,
|
||||||
|
} from "@budibase/types"
|
||||||
import {
|
import {
|
||||||
getAppMigrationVersion,
|
getAppMigrationVersion,
|
||||||
getLatestEnabledMigrationId,
|
getLatestEnabledMigrationId,
|
||||||
} from "../../appMigrations"
|
} from "../../appMigrations"
|
||||||
|
|
||||||
export async function migrate(ctx: Ctx) {
|
export async function migrate(ctx: Ctx<RunOldMigrationRequest, void>) {
|
||||||
const options = ctx.request.body
|
const options = ctx.request.body
|
||||||
// don't await as can take a while, just return
|
// don't await as can take a while, just return
|
||||||
migrationImpl(options)
|
migrationImpl(options)
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchDefinitions(ctx: Ctx) {
|
export async function fetchDefinitions(
|
||||||
|
ctx: Ctx<void, FetchOldMigrationResponse>
|
||||||
|
) {
|
||||||
ctx.body = MIGRATIONS
|
ctx.body = MIGRATIONS
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getMigrationStatus(ctx: Ctx) {
|
export async function getMigrationStatus(
|
||||||
|
ctx: Ctx<void, GetOldMigrationStatus>
|
||||||
|
) {
|
||||||
const appId = context.getAppId()
|
const appId = context.getAppId()
|
||||||
|
|
||||||
if (!appId) {
|
if (!appId) {
|
||||||
|
|
|
@ -1,16 +1,7 @@
|
||||||
import { Ctx } from "@budibase/types"
|
import { Ctx, LogOpsRequest, ErrorOpsRequest } from "@budibase/types"
|
||||||
import { logging } from "@budibase/backend-core"
|
import { logging } from "@budibase/backend-core"
|
||||||
|
|
||||||
interface LogRequest {
|
export async function log(ctx: Ctx<LogOpsRequest, void>) {
|
||||||
message: string
|
|
||||||
data?: any
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ErrorRequest {
|
|
||||||
message: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function log(ctx: Ctx<LogRequest>) {
|
|
||||||
const body = ctx.request.body
|
const body = ctx.request.body
|
||||||
console.trace(body.message, body.data)
|
console.trace(body.message, body.data)
|
||||||
console.debug(body.message, body.data)
|
console.debug(body.message, body.data)
|
||||||
|
@ -20,13 +11,13 @@ export async function log(ctx: Ctx<LogRequest>) {
|
||||||
ctx.status = 204
|
ctx.status = 204
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function alert(ctx: Ctx<ErrorRequest>) {
|
export async function alert(ctx: Ctx<ErrorOpsRequest, void>) {
|
||||||
const body = ctx.request.body
|
const body = ctx.request.body
|
||||||
logging.logAlert(body.message, new Error(body.message))
|
logging.logAlert(body.message, new Error(body.message))
|
||||||
ctx.status = 204
|
ctx.status = 204
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function error(ctx: Ctx<ErrorRequest>) {
|
export async function error(ctx: Ctx<ErrorOpsRequest, void>) {
|
||||||
const body = ctx.request.body
|
const body = ctx.request.body
|
||||||
throw new Error(body.message)
|
throw new Error(body.message)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ import {
|
||||||
RemovePermissionRequest,
|
RemovePermissionRequest,
|
||||||
RemovePermissionResponse,
|
RemovePermissionResponse,
|
||||||
FetchResourcePermissionInfoResponse,
|
FetchResourcePermissionInfoResponse,
|
||||||
|
FetchBuiltinPermissionsRequest,
|
||||||
|
FetchPermissionLevelsRequest,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import {
|
import {
|
||||||
CURRENTLY_SUPPORTED_LEVELS,
|
CURRENTLY_SUPPORTED_LEVELS,
|
||||||
|
@ -19,11 +21,13 @@ import { PermissionUpdateType } from "../../sdk/app/permissions"
|
||||||
|
|
||||||
const SUPPORTED_LEVELS = CURRENTLY_SUPPORTED_LEVELS
|
const SUPPORTED_LEVELS = CURRENTLY_SUPPORTED_LEVELS
|
||||||
|
|
||||||
export function fetchBuiltin(ctx: UserCtx) {
|
export function fetchBuiltin(
|
||||||
|
ctx: UserCtx<void, FetchBuiltinPermissionsRequest>
|
||||||
|
) {
|
||||||
ctx.body = Object.values(permissions.getBuiltinPermissions())
|
ctx.body = Object.values(permissions.getBuiltinPermissions())
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchLevels(ctx: UserCtx) {
|
export function fetchLevels(ctx: UserCtx<void, FetchPermissionLevelsRequest>) {
|
||||||
// for now only provide the read/write perms externally
|
// for now only provide the read/write perms externally
|
||||||
ctx.body = SUPPORTED_LEVELS
|
ctx.body = SUPPORTED_LEVELS
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,12 @@ import {
|
||||||
getPluginMetadata,
|
getPluginMetadata,
|
||||||
extractTarball,
|
extractTarball,
|
||||||
} from "../../../utilities/fileSystem"
|
} from "../../../utilities/fileSystem"
|
||||||
|
import { KoaFile } from "@budibase/types"
|
||||||
|
|
||||||
export async function fileUpload(file: { name: string; path: string }) {
|
export async function fileUpload(file: KoaFile) {
|
||||||
|
if (!file.name || !file.path) {
|
||||||
|
throw new Error("File is not valid - cannot upload.")
|
||||||
|
}
|
||||||
if (!file.name.endsWith(".tar.gz")) {
|
if (!file.name.endsWith(".tar.gz")) {
|
||||||
throw new Error("Plugin must be compressed into a gzipped tarball.")
|
throw new Error("Plugin must be compressed into a gzipped tarball.")
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,26 +2,37 @@ import { npmUpload, urlUpload, githubUpload } from "./uploaders"
|
||||||
import { plugins as pluginCore } from "@budibase/backend-core"
|
import { plugins as pluginCore } from "@budibase/backend-core"
|
||||||
import {
|
import {
|
||||||
PluginType,
|
PluginType,
|
||||||
FileType,
|
|
||||||
PluginSource,
|
PluginSource,
|
||||||
Ctx,
|
|
||||||
CreatePluginRequest,
|
CreatePluginRequest,
|
||||||
CreatePluginResponse,
|
CreatePluginResponse,
|
||||||
|
UserCtx,
|
||||||
|
UploadPluginRequest,
|
||||||
|
Plugin,
|
||||||
|
UploadPluginResponse,
|
||||||
|
FetchPluginResponse,
|
||||||
|
DeletePluginResponse,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import env from "../../../environment"
|
import env from "../../../environment"
|
||||||
import { clientAppSocket } from "../../../websockets"
|
import { clientAppSocket } from "../../../websockets"
|
||||||
import sdk from "../../../sdk"
|
import sdk from "../../../sdk"
|
||||||
import { sdk as pro } from "@budibase/pro"
|
import { sdk as pro } from "@budibase/pro"
|
||||||
|
|
||||||
export async function upload(ctx: any) {
|
export async function upload(
|
||||||
const plugins: FileType[] =
|
ctx: UserCtx<UploadPluginRequest, UploadPluginResponse>
|
||||||
ctx.request.files.file.length > 1
|
) {
|
||||||
? Array.from(ctx.request.files.file)
|
const files = ctx.request.files
|
||||||
: [ctx.request.files.file]
|
const plugins =
|
||||||
|
files && Array.isArray(files.file) && files.file.length > 1
|
||||||
|
? Array.from(files.file)
|
||||||
|
: [files?.file]
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let docs = []
|
let docs: Plugin[] = []
|
||||||
// can do single or multiple plugins
|
// can do single or multiple plugins
|
||||||
for (let plugin of plugins) {
|
for (let plugin of plugins) {
|
||||||
|
if (!plugin || Array.isArray(plugin)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
const doc = await sdk.plugins.processUploaded(plugin, PluginSource.FILE)
|
const doc = await sdk.plugins.processUploaded(plugin, PluginSource.FILE)
|
||||||
docs.push(doc)
|
docs.push(doc)
|
||||||
}
|
}
|
||||||
|
@ -37,7 +48,7 @@ export async function upload(ctx: any) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function create(
|
export async function create(
|
||||||
ctx: Ctx<CreatePluginRequest, CreatePluginResponse>
|
ctx: UserCtx<CreatePluginRequest, CreatePluginResponse>
|
||||||
) {
|
) {
|
||||||
const { source, url, headers, githubToken } = ctx.request.body
|
const { source, url, headers, githubToken } = ctx.request.body
|
||||||
|
|
||||||
|
@ -91,11 +102,11 @@ export async function create(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetch(ctx: any) {
|
export async function fetch(ctx: UserCtx<void, FetchPluginResponse>) {
|
||||||
ctx.body = await sdk.plugins.fetch()
|
ctx.body = await sdk.plugins.fetch()
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function destroy(ctx: any) {
|
export async function destroy(ctx: UserCtx<void, DeletePluginResponse>) {
|
||||||
const { pluginId } = ctx.params
|
const { pluginId } = ctx.params
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -4,26 +4,38 @@ import { save as saveDatasource } from "../datasource"
|
||||||
import { RestImporter } from "./import"
|
import { RestImporter } from "./import"
|
||||||
import { invalidateCachedVariable } from "../../../threads/utils"
|
import { invalidateCachedVariable } from "../../../threads/utils"
|
||||||
import env from "../../../environment"
|
import env from "../../../environment"
|
||||||
import { events, context, utils, constants } from "@budibase/backend-core"
|
import { constants, context, events, utils } from "@budibase/backend-core"
|
||||||
import sdk from "../../../sdk"
|
import sdk from "../../../sdk"
|
||||||
import { QueryEvent, QueryEventParameters } from "../../../threads/definitions"
|
import { QueryEvent, QueryEventParameters } from "../../../threads/definitions"
|
||||||
import {
|
import {
|
||||||
ConfigType,
|
ConfigType,
|
||||||
Query,
|
CreateDatasourceRequest,
|
||||||
UserCtx,
|
Datasource,
|
||||||
SessionCookie,
|
|
||||||
JsonFieldSubType,
|
|
||||||
QueryResponse,
|
|
||||||
QuerySchema,
|
|
||||||
FieldType,
|
|
||||||
ExecuteQueryRequest,
|
ExecuteQueryRequest,
|
||||||
ExecuteQueryResponse,
|
ExecuteV2QueryResponse,
|
||||||
|
ExecuteV1QueryResponse,
|
||||||
|
FetchQueriesResponse,
|
||||||
|
FieldType,
|
||||||
|
FindQueryResponse,
|
||||||
|
ImportRestQueryRequest,
|
||||||
|
ImportRestQueryResponse,
|
||||||
|
JsonFieldSubType,
|
||||||
PreviewQueryRequest,
|
PreviewQueryRequest,
|
||||||
PreviewQueryResponse,
|
PreviewQueryResponse,
|
||||||
|
Query,
|
||||||
|
QueryResponse,
|
||||||
|
QuerySchema,
|
||||||
|
SaveQueryRequest,
|
||||||
|
SaveQueryResponse,
|
||||||
|
SessionCookie,
|
||||||
|
SourceName,
|
||||||
|
UserCtx,
|
||||||
|
DeleteQueryResponse,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { ValidQueryNameRegex, utils as JsonUtils } from "@budibase/shared-core"
|
import { utils as JsonUtils, ValidQueryNameRegex } from "@budibase/shared-core"
|
||||||
import { findHBSBlocks } from "@budibase/string-templates"
|
import { findHBSBlocks } from "@budibase/string-templates"
|
||||||
import { ObjectId } from "mongodb"
|
import { ObjectId } from "mongodb"
|
||||||
|
import { merge } from "lodash"
|
||||||
|
|
||||||
const Runner = new Thread(ThreadType.QUERY, {
|
const Runner = new Thread(ThreadType.QUERY, {
|
||||||
timeoutMs: env.QUERY_THREAD_TIMEOUT,
|
timeoutMs: env.QUERY_THREAD_TIMEOUT,
|
||||||
|
@ -43,11 +55,13 @@ function validateQueryInputs(parameters: QueryEventParameters) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetch(ctx: UserCtx) {
|
export async function fetch(ctx: UserCtx<void, FetchQueriesResponse>) {
|
||||||
ctx.body = await sdk.queries.fetch()
|
ctx.body = await sdk.queries.fetch()
|
||||||
}
|
}
|
||||||
|
|
||||||
const _import = async (ctx: UserCtx) => {
|
const _import = async (
|
||||||
|
ctx: UserCtx<ImportRestQueryRequest, ImportRestQueryResponse>
|
||||||
|
) => {
|
||||||
const body = ctx.request.body
|
const body = ctx.request.body
|
||||||
const data = body.data
|
const data = body.data
|
||||||
|
|
||||||
|
@ -58,9 +72,9 @@ const _import = async (ctx: UserCtx) => {
|
||||||
if (!body.datasourceId) {
|
if (!body.datasourceId) {
|
||||||
// construct new datasource
|
// construct new datasource
|
||||||
const info: any = await importer.getInfo()
|
const info: any = await importer.getInfo()
|
||||||
let datasource = {
|
let datasource: Datasource = {
|
||||||
type: "datasource",
|
type: "datasource",
|
||||||
source: "REST",
|
source: SourceName.REST,
|
||||||
config: {
|
config: {
|
||||||
url: info.url,
|
url: info.url,
|
||||||
defaultHeaders: [],
|
defaultHeaders: [],
|
||||||
|
@ -69,8 +83,14 @@ const _import = async (ctx: UserCtx) => {
|
||||||
name: info.name,
|
name: info.name,
|
||||||
}
|
}
|
||||||
// save the datasource
|
// save the datasource
|
||||||
const datasourceCtx = { ...ctx }
|
const datasourceCtx: UserCtx<CreateDatasourceRequest> = merge(ctx, {
|
||||||
datasourceCtx.request.body.datasource = datasource
|
request: {
|
||||||
|
body: {
|
||||||
|
datasource,
|
||||||
|
tablesFilter: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
await saveDatasource(datasourceCtx)
|
await saveDatasource(datasourceCtx)
|
||||||
datasourceId = datasourceCtx.body.datasource._id
|
datasourceId = datasourceCtx.body.datasource._id
|
||||||
} else {
|
} else {
|
||||||
|
@ -88,7 +108,7 @@ const _import = async (ctx: UserCtx) => {
|
||||||
}
|
}
|
||||||
export { _import as import }
|
export { _import as import }
|
||||||
|
|
||||||
export async function save(ctx: UserCtx<Query, Query>) {
|
export async function save(ctx: UserCtx<SaveQueryRequest, SaveQueryResponse>) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
const query: Query = ctx.request.body
|
const query: Query = ctx.request.body
|
||||||
|
|
||||||
|
@ -119,10 +139,9 @@ export async function save(ctx: UserCtx<Query, Query>) {
|
||||||
query._rev = response.rev
|
query._rev = response.rev
|
||||||
|
|
||||||
ctx.body = query
|
ctx.body = query
|
||||||
ctx.message = `Query ${query.name} saved successfully.`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function find(ctx: UserCtx) {
|
export async function find(ctx: UserCtx<void, FindQueryResponse>) {
|
||||||
const queryId = ctx.params.queryId
|
const queryId = ctx.params.queryId
|
||||||
ctx.body = await sdk.queries.find(queryId)
|
ctx.body = await sdk.queries.find(queryId)
|
||||||
}
|
}
|
||||||
|
@ -335,7 +354,7 @@ export async function preview(
|
||||||
async function execute(
|
async function execute(
|
||||||
ctx: UserCtx<
|
ctx: UserCtx<
|
||||||
ExecuteQueryRequest,
|
ExecuteQueryRequest,
|
||||||
ExecuteQueryResponse | Record<string, any>[]
|
ExecuteV2QueryResponse | ExecuteV1QueryResponse
|
||||||
>,
|
>,
|
||||||
opts: any = { rowsOnly: false, isAutomation: false }
|
opts: any = { rowsOnly: false, isAutomation: false }
|
||||||
) {
|
) {
|
||||||
|
@ -390,19 +409,21 @@ async function execute(
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function executeV1(
|
export async function executeV1(
|
||||||
ctx: UserCtx<ExecuteQueryRequest, Record<string, any>[]>
|
ctx: UserCtx<ExecuteQueryRequest, ExecuteV1QueryResponse>
|
||||||
) {
|
) {
|
||||||
return execute(ctx, { rowsOnly: true, isAutomation: false })
|
return execute(ctx, { rowsOnly: true, isAutomation: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function executeV2(
|
export async function executeV2(
|
||||||
ctx: UserCtx<
|
ctx: UserCtx<ExecuteQueryRequest, ExecuteV2QueryResponse>
|
||||||
ExecuteQueryRequest,
|
|
||||||
ExecuteQueryResponse | Record<string, any>[]
|
|
||||||
>,
|
|
||||||
{ isAutomation }: { isAutomation?: boolean } = {}
|
|
||||||
) {
|
) {
|
||||||
return execute(ctx, { rowsOnly: false, isAutomation })
|
return execute(ctx, { rowsOnly: false })
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function executeV2AsAutomation(
|
||||||
|
ctx: UserCtx<ExecuteQueryRequest, ExecuteV2QueryResponse>
|
||||||
|
) {
|
||||||
|
return execute(ctx, { rowsOnly: false, isAutomation: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
const removeDynamicVariables = async (queryId: string) => {
|
const removeDynamicVariables = async (queryId: string) => {
|
||||||
|
@ -426,14 +447,14 @@ const removeDynamicVariables = async (queryId: string) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function destroy(ctx: UserCtx) {
|
export async function destroy(ctx: UserCtx<void, DeleteQueryResponse>) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
const queryId = ctx.params.queryId as string
|
const queryId = ctx.params.queryId as string
|
||||||
await removeDynamicVariables(queryId)
|
await removeDynamicVariables(queryId)
|
||||||
const query = await db.get<Query>(queryId)
|
const query = await db.get<Query>(queryId)
|
||||||
const datasource = await sdk.datasources.get(query.datasourceId)
|
const datasource = await sdk.datasources.get(query.datasourceId)
|
||||||
await db.remove(ctx.params.queryId, ctx.params.revId)
|
await db.remove(ctx.params.queryId, ctx.params.revId)
|
||||||
ctx.message = `Query deleted.`
|
ctx.body = { message: `Query deleted.` }
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
await events.query.deleted(datasource, query)
|
await events.query.deleted(datasource, query)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { getUserMetadataParams, InternalTables } from "../../db/utils"
|
||||||
import {
|
import {
|
||||||
AccessibleRolesResponse,
|
AccessibleRolesResponse,
|
||||||
Database,
|
Database,
|
||||||
DestroyRoleResponse,
|
DeleteRoleResponse,
|
||||||
FetchRolesResponse,
|
FetchRolesResponse,
|
||||||
FindRoleResponse,
|
FindRoleResponse,
|
||||||
Role,
|
Role,
|
||||||
|
@ -199,7 +199,7 @@ export async function save(ctx: UserCtx<SaveRoleRequest, SaveRoleResponse>) {
|
||||||
builderSocket?.emitRoleUpdate(ctx, role)
|
builderSocket?.emitRoleUpdate(ctx, role)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function destroy(ctx: UserCtx<void, DestroyRoleResponse>) {
|
export async function destroy(ctx: UserCtx<void, DeleteRoleResponse>) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
let roleId = ctx.params.roleId as string
|
let roleId = ctx.params.roleId as string
|
||||||
if (roles.isBuiltin(roleId)) {
|
if (roles.isBuiltin(roleId)) {
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
import { getRoutingInfo } from "../../utilities/routing"
|
import { getRoutingInfo } from "../../utilities/routing"
|
||||||
import { roles } from "@budibase/backend-core"
|
import { roles } from "@budibase/backend-core"
|
||||||
import { UserCtx } from "@budibase/types"
|
import {
|
||||||
|
FetchClientScreenRoutingResponse,
|
||||||
|
FetchScreenRoutingResponse,
|
||||||
|
ScreenRoutingJson,
|
||||||
|
UserCtx,
|
||||||
|
} from "@budibase/types"
|
||||||
|
|
||||||
const URL_SEPARATOR = "/"
|
const URL_SEPARATOR = "/"
|
||||||
|
|
||||||
class Routing {
|
class Routing {
|
||||||
json: any
|
json: ScreenRoutingJson
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.json = {}
|
this.json = {}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +49,7 @@ class Routing {
|
||||||
* @returns The routing structure, this is the full structure designed for use in the builder,
|
* @returns The routing structure, this is the full structure designed for use in the builder,
|
||||||
* if the client routing is required then the updateRoutingStructureForUserRole should be used.
|
* if the client routing is required then the updateRoutingStructureForUserRole should be used.
|
||||||
*/
|
*/
|
||||||
async function getRoutingStructure() {
|
async function getRoutingStructure(): Promise<{ routes: ScreenRoutingJson }> {
|
||||||
const screenRoutes = await getRoutingInfo()
|
const screenRoutes = await getRoutingInfo()
|
||||||
const routing = new Routing()
|
const routing = new Routing()
|
||||||
|
|
||||||
|
@ -56,11 +62,13 @@ async function getRoutingStructure() {
|
||||||
return { routes: routing.json }
|
return { routes: routing.json }
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetch(ctx: UserCtx) {
|
export async function fetch(ctx: UserCtx<void, FetchScreenRoutingResponse>) {
|
||||||
ctx.body = await getRoutingStructure()
|
ctx.body = await getRoutingStructure()
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function clientFetch(ctx: UserCtx) {
|
export async function clientFetch(
|
||||||
|
ctx: UserCtx<void, FetchClientScreenRoutingResponse>
|
||||||
|
) {
|
||||||
const routing = await getRoutingStructure()
|
const routing = await getRoutingStructure()
|
||||||
let roleId = ctx.user?.role?._id
|
let roleId = ctx.user?.role?._id
|
||||||
const roleIds = roleId ? await roles.getUserRoleIdHierarchy(roleId) : []
|
const roleIds = roleId ? await roles.getUserRoleIdHierarchy(roleId) : []
|
||||||
|
|
|
@ -11,11 +11,14 @@ import {
|
||||||
DeleteRow,
|
DeleteRow,
|
||||||
DeleteRowRequest,
|
DeleteRowRequest,
|
||||||
DeleteRows,
|
DeleteRows,
|
||||||
|
DownloadAttachmentResponse,
|
||||||
EventType,
|
EventType,
|
||||||
ExportRowsRequest,
|
ExportRowsRequest,
|
||||||
ExportRowsResponse,
|
ExportRowsResponse,
|
||||||
|
FetchEnrichedRowResponse,
|
||||||
|
FetchRowsResponse,
|
||||||
FieldType,
|
FieldType,
|
||||||
GetRowResponse,
|
FindRowResponse,
|
||||||
isRelationshipField,
|
isRelationshipField,
|
||||||
PatchRowRequest,
|
PatchRowRequest,
|
||||||
PatchRowResponse,
|
PatchRowResponse,
|
||||||
|
@ -23,12 +26,15 @@ import {
|
||||||
Row,
|
Row,
|
||||||
RowAttachment,
|
RowAttachment,
|
||||||
RowSearchParams,
|
RowSearchParams,
|
||||||
|
SaveRowRequest,
|
||||||
|
SaveRowResponse,
|
||||||
SearchFilters,
|
SearchFilters,
|
||||||
SearchRowRequest,
|
SearchRowRequest,
|
||||||
SearchRowResponse,
|
SearchRowResponse,
|
||||||
Table,
|
Table,
|
||||||
UserCtx,
|
UserCtx,
|
||||||
ValidateResponse,
|
ValidateRowRequest,
|
||||||
|
ValidateRowResponse,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import * as utils from "./utils"
|
import * as utils from "./utils"
|
||||||
import { gridSocket } from "../../../websockets"
|
import { gridSocket } from "../../../websockets"
|
||||||
|
@ -83,7 +89,7 @@ export async function patch(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const save = async (ctx: UserCtx<Row, Row>) => {
|
export const save = async (ctx: UserCtx<SaveRowRequest, SaveRowResponse>) => {
|
||||||
const { tableId, viewId } = utils.getSourceId(ctx)
|
const { tableId, viewId } = utils.getSourceId(ctx)
|
||||||
const sourceId = viewId || tableId
|
const sourceId = viewId || tableId
|
||||||
|
|
||||||
|
@ -131,12 +137,12 @@ export async function fetchLegacyView(ctx: any) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetch(ctx: any) {
|
export async function fetch(ctx: UserCtx<void, FetchRowsResponse>) {
|
||||||
const { tableId } = utils.getSourceId(ctx)
|
const { tableId } = utils.getSourceId(ctx)
|
||||||
ctx.body = await sdk.rows.fetch(tableId)
|
ctx.body = await sdk.rows.fetch(tableId)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function find(ctx: UserCtx<void, GetRowResponse>) {
|
export async function find(ctx: UserCtx<void, FindRowResponse>) {
|
||||||
const { tableId, viewId } = utils.getSourceId(ctx)
|
const { tableId, viewId } = utils.getSourceId(ctx)
|
||||||
const sourceId = viewId || tableId
|
const sourceId = viewId || tableId
|
||||||
const rowId = ctx.params.rowId
|
const rowId = ctx.params.rowId
|
||||||
|
@ -314,7 +320,9 @@ function replaceTableNamesInFilters(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function validate(ctx: Ctx<Row, ValidateResponse>) {
|
export async function validate(
|
||||||
|
ctx: Ctx<ValidateRowRequest, ValidateRowResponse>
|
||||||
|
) {
|
||||||
const source = await utils.getSource(ctx)
|
const source = await utils.getSource(ctx)
|
||||||
const table = await utils.getTableFromSource(source)
|
const table = await utils.getTableFromSource(source)
|
||||||
// external tables are hard to validate currently
|
// external tables are hard to validate currently
|
||||||
|
@ -328,7 +336,9 @@ export async function validate(ctx: Ctx<Row, ValidateResponse>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchEnrichedRow(ctx: UserCtx<void, Row>) {
|
export async function fetchEnrichedRow(
|
||||||
|
ctx: UserCtx<void, FetchEnrichedRowResponse>
|
||||||
|
) {
|
||||||
const { tableId } = utils.getSourceId(ctx)
|
const { tableId } = utils.getSourceId(ctx)
|
||||||
ctx.body = await pickApi(tableId).fetchEnrichedRow(ctx)
|
ctx.body = await pickApi(tableId).fetchEnrichedRow(ctx)
|
||||||
}
|
}
|
||||||
|
@ -366,7 +376,9 @@ export const exportRows = async (
|
||||||
ctx.body = apiFileReturn(content)
|
ctx.body = apiFileReturn(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function downloadAttachment(ctx: UserCtx) {
|
export async function downloadAttachment(
|
||||||
|
ctx: UserCtx<void, DownloadAttachmentResponse>
|
||||||
|
) {
|
||||||
const { columnName } = ctx.params
|
const { columnName } = ctx.params
|
||||||
|
|
||||||
const { tableId } = utils.getSourceId(ctx)
|
const { tableId } = utils.getSourceId(ctx)
|
||||||
|
|
|
@ -56,7 +56,7 @@ router
|
||||||
"/api/v2/queries/:queryId",
|
"/api/v2/queries/:queryId",
|
||||||
paramResource("queryId"),
|
paramResource("queryId"),
|
||||||
authorized(PermissionType.QUERY, PermissionLevel.WRITE),
|
authorized(PermissionType.QUERY, PermissionLevel.WRITE),
|
||||||
queryController.executeV2 as any
|
queryController.executeV2
|
||||||
)
|
)
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
const { testAutomation } = require("./utilities/TestFunctions")
|
import { testAutomation } from "./utilities/TestFunctions"
|
||||||
const setup = require("./utilities")
|
import * as setup from "./utilities"
|
||||||
const { MetadataTypes } = require("../../../constants")
|
import { MetadataType, Automation } from "@budibase/types"
|
||||||
|
|
||||||
describe("/metadata", () => {
|
describe("/metadata", () => {
|
||||||
let request = setup.getRequest()
|
let request = setup.getRequest()
|
||||||
let config = setup.getConfig()
|
let config = setup.getConfig()
|
||||||
let automation
|
let automation: Automation
|
||||||
|
|
||||||
afterAll(setup.afterAll)
|
afterAll(setup.afterAll)
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@ describe("/metadata", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
async function createMetadata(
|
async function createMetadata(
|
||||||
data,
|
data: Record<string, string>,
|
||||||
type = MetadataTypes.AUTOMATION_TEST_INPUT
|
type = MetadataType.AUTOMATION_TEST_INPUT
|
||||||
) {
|
) {
|
||||||
const res = await request
|
const res = await request
|
||||||
.post(`/api/metadata/${type}/${automation._id}`)
|
.post(`/api/metadata/${type}/${automation._id}`)
|
||||||
|
@ -27,7 +27,7 @@ describe("/metadata", () => {
|
||||||
expect(res.body._rev).toBeDefined()
|
expect(res.body._rev).toBeDefined()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getMetadata(type) {
|
async function getMetadata(type: MetadataType) {
|
||||||
const res = await request
|
const res = await request
|
||||||
.get(`/api/metadata/${type}/${automation._id}`)
|
.get(`/api/metadata/${type}/${automation._id}`)
|
||||||
.set(config.defaultHeaders())
|
.set(config.defaultHeaders())
|
||||||
|
@ -39,14 +39,14 @@ describe("/metadata", () => {
|
||||||
describe("save", () => {
|
describe("save", () => {
|
||||||
it("should be able to save some metadata", async () => {
|
it("should be able to save some metadata", async () => {
|
||||||
await createMetadata({ test: "a" })
|
await createMetadata({ test: "a" })
|
||||||
const testInput = await getMetadata(MetadataTypes.AUTOMATION_TEST_INPUT)
|
const testInput = await getMetadata(MetadataType.AUTOMATION_TEST_INPUT)
|
||||||
expect(testInput.test).toBe("a")
|
expect(testInput.test).toBe("a")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should save history metadata on automation run", async () => {
|
it("should save history metadata on automation run", async () => {
|
||||||
// this should have created some history
|
// this should have created some history
|
||||||
await testAutomation(config, automation)
|
await testAutomation(config, automation, {})
|
||||||
const metadata = await getMetadata(MetadataTypes.AUTOMATION_TEST_HISTORY)
|
const metadata = await getMetadata(MetadataType.AUTOMATION_TEST_HISTORY)
|
||||||
expect(metadata).toBeDefined()
|
expect(metadata).toBeDefined()
|
||||||
expect(metadata.history.length).toBe(1)
|
expect(metadata.history.length).toBe(1)
|
||||||
expect(typeof metadata.history[0].occurredAt).toBe("number")
|
expect(typeof metadata.history[0].occurredAt).toBe("number")
|
||||||
|
@ -57,13 +57,13 @@ describe("/metadata", () => {
|
||||||
it("should be able to delete some test inputs", async () => {
|
it("should be able to delete some test inputs", async () => {
|
||||||
const res = await request
|
const res = await request
|
||||||
.delete(
|
.delete(
|
||||||
`/api/metadata/${MetadataTypes.AUTOMATION_TEST_INPUT}/${automation._id}`
|
`/api/metadata/${MetadataType.AUTOMATION_TEST_INPUT}/${automation._id}`
|
||||||
)
|
)
|
||||||
.set(config.defaultHeaders())
|
.set(config.defaultHeaders())
|
||||||
.expect("Content-Type", /json/)
|
.expect("Content-Type", /json/)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
expect(res.body.message).toBeDefined()
|
expect(res.body.message).toBeDefined()
|
||||||
const metadata = await getMetadata(MetadataTypes.AUTOMATION_TEST_INPUT)
|
const metadata = await getMetadata(MetadataType.AUTOMATION_TEST_INPUT)
|
||||||
expect(metadata.test).toBeUndefined()
|
expect(metadata.test).toBeUndefined()
|
||||||
})
|
})
|
||||||
})
|
})
|
|
@ -94,7 +94,7 @@ export async function run({
|
||||||
})
|
})
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await queryController.executeV2(ctx, { isAutomation: true })
|
await queryController.executeV2AsAutomation(ctx)
|
||||||
const { data, ...rest } = ctx.body
|
const { data, ...rest } = ctx.body
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -2,7 +2,6 @@ import { Thread, ThreadType } from "../threads"
|
||||||
import { definitions } from "./triggerInfo"
|
import { definitions } from "./triggerInfo"
|
||||||
import { automationQueue } from "./bullboard"
|
import { automationQueue } from "./bullboard"
|
||||||
import { updateEntityMetadata } from "../utilities"
|
import { updateEntityMetadata } from "../utilities"
|
||||||
import { MetadataTypes } from "../constants"
|
|
||||||
import { context, db as dbCore, utils } from "@budibase/backend-core"
|
import { context, db as dbCore, utils } from "@budibase/backend-core"
|
||||||
import { getAutomationMetadataParams } from "../db/utils"
|
import { getAutomationMetadataParams } from "../db/utils"
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
|
@ -14,6 +13,7 @@ import {
|
||||||
AutomationStepDefinition,
|
AutomationStepDefinition,
|
||||||
AutomationTriggerDefinition,
|
AutomationTriggerDefinition,
|
||||||
AutomationTriggerStepId,
|
AutomationTriggerStepId,
|
||||||
|
MetadataType,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { automationsEnabled } from "../features"
|
import { automationsEnabled } from "../features"
|
||||||
import { helpers, REBOOT_CRON } from "@budibase/shared-core"
|
import { helpers, REBOOT_CRON } from "@budibase/shared-core"
|
||||||
|
@ -107,7 +107,7 @@ export async function updateTestHistory(
|
||||||
history: any
|
history: any
|
||||||
) {
|
) {
|
||||||
return updateEntityMetadata(
|
return updateEntityMetadata(
|
||||||
MetadataTypes.AUTOMATION_TEST_HISTORY,
|
MetadataType.AUTOMATION_TEST_HISTORY,
|
||||||
automation._id,
|
automation._id,
|
||||||
(metadata: any) => {
|
(metadata: any) => {
|
||||||
if (metadata && Array.isArray(metadata.history)) {
|
if (metadata && Array.isArray(metadata.history)) {
|
||||||
|
|
|
@ -124,11 +124,6 @@ export enum BaseQueryVerbs {
|
||||||
DELETE = "delete",
|
DELETE = "delete",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum MetadataTypes {
|
|
||||||
AUTOMATION_TEST_INPUT = "automationTestInput",
|
|
||||||
AUTOMATION_TEST_HISTORY = "automationTestHistory",
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum InvalidColumns {
|
export enum InvalidColumns {
|
||||||
ID = "_id",
|
ID = "_id",
|
||||||
REV = "_rev",
|
REV = "_rev",
|
||||||
|
|
|
@ -3,10 +3,10 @@ import {
|
||||||
RequiredKeys,
|
RequiredKeys,
|
||||||
Webhook,
|
Webhook,
|
||||||
WebhookActionType,
|
WebhookActionType,
|
||||||
|
MetadataType,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { generateAutomationID, getAutomationParams } from "../../../db/utils"
|
import { generateAutomationID, getAutomationParams } from "../../../db/utils"
|
||||||
import { deleteEntityMetadata } from "../../../utilities"
|
import { deleteEntityMetadata } from "../../../utilities"
|
||||||
import { MetadataTypes } from "../../../constants"
|
|
||||||
import {
|
import {
|
||||||
context,
|
context,
|
||||||
events,
|
events,
|
||||||
|
@ -161,7 +161,7 @@ export async function update(automation: Automation) {
|
||||||
if (oldAutoTrigger && oldAutoTrigger.id !== newAutoTrigger?.id) {
|
if (oldAutoTrigger && oldAutoTrigger.id !== newAutoTrigger?.id) {
|
||||||
await events.automation.triggerUpdated(automation)
|
await events.automation.triggerUpdated(automation)
|
||||||
await deleteEntityMetadata(
|
await deleteEntityMetadata(
|
||||||
MetadataTypes.AUTOMATION_TEST_INPUT,
|
MetadataType.AUTOMATION_TEST_INPUT,
|
||||||
automation._id!
|
automation._id!
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -183,11 +183,8 @@ export async function remove(automationId: string, rev: string) {
|
||||||
})
|
})
|
||||||
|
|
||||||
// delete metadata first
|
// delete metadata first
|
||||||
await deleteEntityMetadata(MetadataTypes.AUTOMATION_TEST_INPUT, automationId)
|
await deleteEntityMetadata(MetadataType.AUTOMATION_TEST_INPUT, automationId)
|
||||||
await deleteEntityMetadata(
|
await deleteEntityMetadata(MetadataType.AUTOMATION_TEST_HISTORY, automationId)
|
||||||
MetadataTypes.AUTOMATION_TEST_HISTORY,
|
|
||||||
automationId
|
|
||||||
)
|
|
||||||
|
|
||||||
const result = await db.remove(automationId, rev)
|
const result = await db.remove(automationId, rev)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { FileType, Plugin, PluginSource, PluginType } from "@budibase/types"
|
import { KoaFile, Plugin, PluginSource, PluginType } from "@budibase/types"
|
||||||
import {
|
import {
|
||||||
db as dbCore,
|
db as dbCore,
|
||||||
objectStore,
|
objectStore,
|
||||||
|
@ -10,7 +10,7 @@ import env from "../../environment"
|
||||||
import { clientAppSocket } from "../../websockets"
|
import { clientAppSocket } from "../../websockets"
|
||||||
import { sdk as pro } from "@budibase/pro"
|
import { sdk as pro } from "@budibase/pro"
|
||||||
|
|
||||||
export async function fetch(type?: PluginType) {
|
export async function fetch(type?: PluginType): Promise<Plugin[]> {
|
||||||
const db = tenancy.getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
const response = await db.allDocs(
|
const response = await db.allDocs(
|
||||||
dbCore.getPluginParams(null, {
|
dbCore.getPluginParams(null, {
|
||||||
|
@ -26,7 +26,7 @@ export async function fetch(type?: PluginType) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function processUploaded(plugin: FileType, source?: PluginSource) {
|
export async function processUploaded(plugin: KoaFile, source?: PluginSource) {
|
||||||
const { metadata, directory } = await fileUpload(plugin)
|
const { metadata, directory } = await fileUpload(plugin)
|
||||||
pluginCore.validate(metadata?.schema)
|
pluginCore.validate(metadata?.schema)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {
|
import {
|
||||||
Query,
|
Query,
|
||||||
ExecuteQueryRequest,
|
ExecuteQueryRequest,
|
||||||
ExecuteQueryResponse,
|
ExecuteV2QueryResponse,
|
||||||
PreviewQueryRequest,
|
PreviewQueryRequest,
|
||||||
PreviewQueryResponse,
|
PreviewQueryResponse,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
@ -17,8 +17,8 @@ export class QueryAPI extends TestAPI {
|
||||||
queryId: string,
|
queryId: string,
|
||||||
body?: ExecuteQueryRequest,
|
body?: ExecuteQueryRequest,
|
||||||
expectations?: Expectations
|
expectations?: Expectations
|
||||||
): Promise<ExecuteQueryResponse> => {
|
): Promise<ExecuteV2QueryResponse> => {
|
||||||
return await this._post<ExecuteQueryResponse>(
|
return await this._post<ExecuteV2QueryResponse>(
|
||||||
`/api/v2/queries/${queryId}`,
|
`/api/v2/queries/${queryId}`,
|
||||||
{
|
{
|
||||||
body,
|
body,
|
||||||
|
|
|
@ -2,7 +2,7 @@ import {
|
||||||
PatchRowRequest,
|
PatchRowRequest,
|
||||||
SaveRowRequest,
|
SaveRowRequest,
|
||||||
Row,
|
Row,
|
||||||
ValidateResponse,
|
ValidateRowResponse,
|
||||||
ExportRowsRequest,
|
ExportRowsRequest,
|
||||||
BulkImportRequest,
|
BulkImportRequest,
|
||||||
BulkImportResponse,
|
BulkImportResponse,
|
||||||
|
@ -51,8 +51,8 @@ export class RowAPI extends TestAPI {
|
||||||
sourceId: string,
|
sourceId: string,
|
||||||
row: SaveRowRequest,
|
row: SaveRowRequest,
|
||||||
expectations?: Expectations
|
expectations?: Expectations
|
||||||
): Promise<ValidateResponse> => {
|
): Promise<ValidateRowResponse> => {
|
||||||
return await this._post<ValidateResponse>(
|
return await this._post<ValidateRowResponse>(
|
||||||
`/api/${sourceId}/rows/validate`,
|
`/api/${sourceId}/rows/validate`,
|
||||||
{
|
{
|
||||||
body: row,
|
body: row,
|
||||||
|
|
|
@ -88,7 +88,7 @@ export async function saveEntityMetadata(
|
||||||
type: string,
|
type: string,
|
||||||
entityId: string,
|
entityId: string,
|
||||||
metadata: Document
|
metadata: Document
|
||||||
) {
|
): Promise<Document> {
|
||||||
return updateEntityMetadata(type, entityId, () => {
|
return updateEntityMetadata(type, entityId, () => {
|
||||||
return metadata
|
return metadata
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,24 +1,19 @@
|
||||||
import { createRoutingView } from "../../db/views/staticViews"
|
import { createRoutingView } from "../../db/views/staticViews"
|
||||||
import { ViewName, getQueryIndex, UNICODE_MAX } from "../../db/utils"
|
import { ViewName, getQueryIndex, UNICODE_MAX } from "../../db/utils"
|
||||||
import { context } from "@budibase/backend-core"
|
import { context } from "@budibase/backend-core"
|
||||||
import { ScreenRouting, Document } from "@budibase/types"
|
import { ScreenRoutesViewOutput } from "@budibase/types"
|
||||||
|
|
||||||
interface ScreenRoutesView extends Document {
|
export async function getRoutingInfo(): Promise<ScreenRoutesViewOutput[]> {
|
||||||
id: string
|
|
||||||
routing: ScreenRouting
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getRoutingInfo(): Promise<ScreenRoutesView[]> {
|
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
try {
|
try {
|
||||||
const allRouting = await db.query<ScreenRoutesView>(
|
const allRouting = await db.query<ScreenRoutesViewOutput>(
|
||||||
getQueryIndex(ViewName.ROUTING),
|
getQueryIndex(ViewName.ROUTING),
|
||||||
{
|
{
|
||||||
startkey: "",
|
startkey: "",
|
||||||
endkey: UNICODE_MAX,
|
endkey: UNICODE_MAX,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return allRouting.rows.map(row => row.value as ScreenRoutesView)
|
return allRouting.rows.map(row => row.value)
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
// check if the view doesn't exist, it should for all new instances
|
// check if the view doesn't exist, it should for all new instances
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
export * from "./backup"
|
export * from "./backup"
|
||||||
export * from "./datasource"
|
export * from "./datasource"
|
||||||
export * from "./row"
|
|
||||||
export * from "./view"
|
export * from "./view"
|
||||||
export * from "./rows"
|
export * from "./rows"
|
||||||
export * from "./table"
|
export * from "./table"
|
||||||
|
@ -10,3 +9,7 @@ export * from "./user"
|
||||||
export * from "./rowAction"
|
export * from "./rowAction"
|
||||||
export * from "./automation"
|
export * from "./automation"
|
||||||
export * from "./component"
|
export * from "./component"
|
||||||
|
export * from "./integration"
|
||||||
|
export * from "./metadata"
|
||||||
|
export * from "./query"
|
||||||
|
export * from "./screen"
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { Integration, SourceName } from "../../../sdk"
|
||||||
|
|
||||||
|
export type FetchIntegrationsResponse = Record<
|
||||||
|
SourceName,
|
||||||
|
Integration | undefined
|
||||||
|
>
|
||||||
|
|
||||||
|
export type FindIntegrationResponse = Integration
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { MetadataType, Document } from "../../../documents"
|
||||||
|
|
||||||
|
export interface GetMetadataTypesResponse {
|
||||||
|
types: typeof MetadataType
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SaveMetadataRequest extends Document {}
|
||||||
|
export interface SaveMetadataResponse extends Document {}
|
||||||
|
|
||||||
|
export interface DeleteMetadataResponse {
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FindMetadataResponse extends Document {}
|
|
@ -1,4 +1,8 @@
|
||||||
import { PermissionLevel } from "../../../sdk"
|
import { BuiltinPermission, PermissionLevel } from "../../../sdk"
|
||||||
|
|
||||||
|
export type FetchBuiltinPermissionsRequest = BuiltinPermission[]
|
||||||
|
|
||||||
|
export type FetchPermissionLevelsRequest = string[]
|
||||||
|
|
||||||
export interface FetchResourcePermissionInfoResponse {
|
export interface FetchResourcePermissionInfoResponse {
|
||||||
[key: string]: Record<string, string>
|
[key: string]: Record<string, string>
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
import {
|
||||||
|
Datasource,
|
||||||
|
Query,
|
||||||
|
QueryPreview,
|
||||||
|
QuerySchema,
|
||||||
|
} from "../../../documents"
|
||||||
|
|
||||||
|
export type FetchQueriesResponse = Query[]
|
||||||
|
|
||||||
|
export interface SaveQueryRequest extends Query {}
|
||||||
|
export interface SaveQueryResponse extends Query {}
|
||||||
|
|
||||||
|
export interface ImportRestQueryRequest {
|
||||||
|
datasourceId: string
|
||||||
|
data: string
|
||||||
|
datasource: Datasource
|
||||||
|
}
|
||||||
|
export interface ImportRestQueryResponse {
|
||||||
|
errorQueries: Query[]
|
||||||
|
queries: Query[]
|
||||||
|
datasourceId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FindQueryResponse extends Query {}
|
||||||
|
|
||||||
|
export interface PreviewQueryRequest extends QueryPreview {}
|
||||||
|
|
||||||
|
export interface PreviewQueryResponse {
|
||||||
|
rows: any[]
|
||||||
|
nestedSchemaFields: { [key: string]: { [key: string]: string | QuerySchema } }
|
||||||
|
schema: { [key: string]: string | QuerySchema }
|
||||||
|
info: any
|
||||||
|
extra: any
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ExecuteQueryRequest {
|
||||||
|
parameters?: Record<string, string>
|
||||||
|
pagination?: any
|
||||||
|
}
|
||||||
|
export type ExecuteV1QueryResponse = Record<string, any>[]
|
||||||
|
export interface ExecuteV2QueryResponse {
|
||||||
|
data: Record<string, any>[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeleteQueryResponse {
|
||||||
|
message: string
|
||||||
|
}
|
|
@ -1,18 +0,0 @@
|
||||||
import { Row } from "../../../documents/app/row"
|
|
||||||
|
|
||||||
export interface GetRowResponse extends Row {}
|
|
||||||
|
|
||||||
export interface DeleteRows {
|
|
||||||
rows: (Row | string)[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DeleteRow {
|
|
||||||
_id: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type DeleteRowRequest = DeleteRows | DeleteRow
|
|
||||||
|
|
||||||
export interface ValidateResponse {
|
|
||||||
valid: boolean
|
|
||||||
errors: Record<string, any>
|
|
||||||
}
|
|
|
@ -1,11 +1,17 @@
|
||||||
import { SearchFilters } from "../../../../sdk"
|
import { SearchFilters } from "../../../../sdk"
|
||||||
import { Row } from "../../../../documents"
|
import { Row } from "../../../../documents"
|
||||||
import { SortOrder } from "../../../../api/web/pagination"
|
import { SortOrder } from "../../pagination"
|
||||||
import { ReadStream } from "fs"
|
import { ReadStream } from "fs"
|
||||||
|
import stream from "node:stream"
|
||||||
|
|
||||||
export * from "./search"
|
export * from "./search"
|
||||||
|
|
||||||
|
export interface FetchEnrichedRowResponse extends Row {}
|
||||||
|
|
||||||
|
export type FetchRowsResponse = Row[]
|
||||||
|
|
||||||
export interface SaveRowRequest extends Row {}
|
export interface SaveRowRequest extends Row {}
|
||||||
|
export interface SaveRowResponse extends Row {}
|
||||||
|
|
||||||
export interface PatchRowRequest extends Row {
|
export interface PatchRowRequest extends Row {
|
||||||
_id: string
|
_id: string
|
||||||
|
@ -26,3 +32,23 @@ export interface ExportRowsRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ExportRowsResponse = ReadStream
|
export type ExportRowsResponse = ReadStream
|
||||||
|
|
||||||
|
export type DownloadAttachmentResponse = stream.PassThrough | stream.Readable
|
||||||
|
|
||||||
|
export interface FindRowResponse extends Row {}
|
||||||
|
|
||||||
|
export interface DeleteRows {
|
||||||
|
rows: (Row | string)[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeleteRow {
|
||||||
|
_id: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DeleteRowRequest = DeleteRows | DeleteRow
|
||||||
|
|
||||||
|
export interface ValidateRowRequest extends Row {}
|
||||||
|
export interface ValidateRowResponse {
|
||||||
|
valid: boolean
|
||||||
|
errors: Record<string, any>
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { ScreenRoutingJson } from "../../../documents"
|
||||||
|
|
||||||
|
export interface FetchScreenRoutingResponse {
|
||||||
|
routes: ScreenRoutingJson
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FetchClientScreenRoutingResponse
|
||||||
|
extends FetchScreenRoutingResponse {}
|
|
@ -4,3 +4,4 @@ export * from "./events"
|
||||||
export * from "./configs"
|
export * from "./configs"
|
||||||
export * from "./scim"
|
export * from "./scim"
|
||||||
export * from "./license"
|
export * from "./license"
|
||||||
|
export * from "./oldMigration"
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { Migration, MigrationOptions } from "../../../sdk"
|
||||||
|
|
||||||
|
export interface RunOldMigrationRequest extends MigrationOptions {}
|
||||||
|
|
||||||
|
export type FetchOldMigrationResponse = Migration[]
|
||||||
|
|
||||||
|
export interface GetOldMigrationStatus {
|
||||||
|
migrated: boolean
|
||||||
|
}
|
|
@ -13,7 +13,6 @@ export * from "./searchFilter"
|
||||||
export * from "./cookies"
|
export * from "./cookies"
|
||||||
export * from "./automation"
|
export * from "./automation"
|
||||||
export * from "./layout"
|
export * from "./layout"
|
||||||
export * from "./query"
|
|
||||||
export * from "./role"
|
export * from "./role"
|
||||||
export * from "./plugins"
|
export * from "./plugins"
|
||||||
export * from "./apikeys"
|
export * from "./apikeys"
|
||||||
|
|
|
@ -3,3 +3,7 @@ import { Layout } from "../../documents"
|
||||||
export interface SaveLayoutRequest extends Layout {}
|
export interface SaveLayoutRequest extends Layout {}
|
||||||
|
|
||||||
export interface SaveLayoutResponse extends Layout {}
|
export interface SaveLayoutResponse extends Layout {}
|
||||||
|
|
||||||
|
export interface DeleteLayoutResponse {
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
import { PluginSource } from "../../documents"
|
import { PluginSource, Plugin } from "../../documents"
|
||||||
|
|
||||||
|
export interface UploadPluginRequest {}
|
||||||
|
export interface UploadPluginResponse {
|
||||||
|
message: string
|
||||||
|
plugins: Plugin[]
|
||||||
|
}
|
||||||
|
|
||||||
export interface CreatePluginRequest {
|
export interface CreatePluginRequest {
|
||||||
source: PluginSource
|
source: PluginSource
|
||||||
|
@ -10,3 +16,9 @@ export interface CreatePluginRequest {
|
||||||
export interface CreatePluginResponse {
|
export interface CreatePluginResponse {
|
||||||
plugin: any
|
plugin: any
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type FetchPluginResponse = Plugin[]
|
||||||
|
|
||||||
|
export interface DeletePluginResponse {
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
import { QueryPreview, QuerySchema } from "../../documents"
|
|
||||||
|
|
||||||
export interface PreviewQueryRequest extends QueryPreview {}
|
|
||||||
|
|
||||||
export interface PreviewQueryResponse {
|
|
||||||
rows: any[]
|
|
||||||
nestedSchemaFields: { [key: string]: { [key: string]: string | QuerySchema } }
|
|
||||||
schema: { [key: string]: string | QuerySchema }
|
|
||||||
info: any
|
|
||||||
extra: any
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ExecuteQueryRequest {
|
|
||||||
parameters?: Record<string, string>
|
|
||||||
pagination?: any
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ExecuteQueryResponse {
|
|
||||||
data: Record<string, any>[]
|
|
||||||
}
|
|
|
@ -18,7 +18,7 @@ export interface FindRoleResponse extends Role {}
|
||||||
|
|
||||||
export type FetchRolesResponse = Role[]
|
export type FetchRolesResponse = Role[]
|
||||||
|
|
||||||
export interface DestroyRoleResponse {
|
export interface DeleteRoleResponse {
|
||||||
message: string
|
message: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
export * from "./environment"
|
export * from "./environment"
|
||||||
export * from "./status"
|
export * from "./status"
|
||||||
|
export * from "./ops"
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
export interface LogOpsRequest {
|
||||||
|
message: string
|
||||||
|
data?: any
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ErrorOpsRequest {
|
||||||
|
message: string
|
||||||
|
}
|
|
@ -19,3 +19,4 @@ export * from "./snippet"
|
||||||
export * from "./rowAction"
|
export * from "./rowAction"
|
||||||
export * from "./theme"
|
export * from "./theme"
|
||||||
export * from "./deployment"
|
export * from "./deployment"
|
||||||
|
export * from "./metadata"
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
export enum MetadataType {
|
||||||
|
AUTOMATION_TEST_INPUT = "automationTestInput",
|
||||||
|
AUTOMATION_TEST_HISTORY = "automationTestHistory",
|
||||||
|
}
|
|
@ -24,3 +24,20 @@ export interface Screen extends Document {
|
||||||
name?: string
|
name?: string
|
||||||
pluginAdded?: boolean
|
pluginAdded?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ScreenRoutesViewOutput extends Document {
|
||||||
|
id: string
|
||||||
|
routing: ScreenRouting
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ScreenRoutingJson = Record<
|
||||||
|
string,
|
||||||
|
{
|
||||||
|
subpaths: Record<
|
||||||
|
string,
|
||||||
|
{
|
||||||
|
screens: Record<string, string>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
|
|
@ -12,9 +12,9 @@ export enum PluginSource {
|
||||||
URL = "URL",
|
URL = "URL",
|
||||||
FILE = "File Upload",
|
FILE = "File Upload",
|
||||||
}
|
}
|
||||||
export interface FileType {
|
export interface KoaFile {
|
||||||
path: string
|
path: string | null
|
||||||
name: string
|
name: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Plugin extends Document {
|
export interface Plugin extends Document {
|
||||||
|
|
|
@ -36,3 +36,22 @@ export enum PermissionSource {
|
||||||
INHERITED = "INHERITED",
|
INHERITED = "INHERITED",
|
||||||
BASE = "BASE",
|
BASE = "BASE",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Permission {
|
||||||
|
type: PermissionType
|
||||||
|
level: PermissionLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BuiltinPermission {
|
||||||
|
_id: BuiltinPermissionID
|
||||||
|
name: string
|
||||||
|
permissions: Permission[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BuiltinPermissions = {
|
||||||
|
[key in keyof typeof BuiltinPermissionID]: {
|
||||||
|
_id: (typeof BuiltinPermissionID)[key]
|
||||||
|
name: string
|
||||||
|
permissions: Permission[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue