Merge pull request #15120 from Budibase/chore/api-typing-3
Final app service API typing
This commit is contained in:
commit
63a5821877
|
@ -83,6 +83,7 @@
|
||||||
"@types/semver": "7.3.7",
|
"@types/semver": "7.3.7",
|
||||||
"@types/tar-fs": "2.0.1",
|
"@types/tar-fs": "2.0.1",
|
||||||
"@types/uuid": "8.3.4",
|
"@types/uuid": "8.3.4",
|
||||||
|
"@types/koa": "2.13.4",
|
||||||
"chance": "1.1.8",
|
"chance": "1.1.8",
|
||||||
"ioredis-mock": "8.9.0",
|
"ioredis-mock": "8.9.0",
|
||||||
"jest": "29.7.0",
|
"jest": "29.7.0",
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
import { BBContext } from "@budibase/types"
|
import { Ctx } from "@budibase/types"
|
||||||
|
import type { Middleware, Next } from "koa"
|
||||||
|
|
||||||
export default async (ctx: BBContext | any, next: any) => {
|
// this middleware exists purely to be overridden by middlewares supplied by the @budibase/pro library
|
||||||
|
const middleware = (async (ctx: Ctx, next: Next) => {
|
||||||
// Placeholder for audit log middleware
|
// Placeholder for audit log middleware
|
||||||
return next()
|
return next()
|
||||||
}
|
}) as Middleware
|
||||||
|
|
||||||
|
export default middleware
|
||||||
|
|
|
@ -22,6 +22,7 @@ import {
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { ErrorCode, InvalidAPIKeyError } from "../errors"
|
import { ErrorCode, InvalidAPIKeyError } from "../errors"
|
||||||
import tracer from "dd-trace"
|
import tracer from "dd-trace"
|
||||||
|
import type { Middleware, Next } from "koa"
|
||||||
|
|
||||||
const ONE_MINUTE = env.SESSION_UPDATE_PERIOD
|
const ONE_MINUTE = env.SESSION_UPDATE_PERIOD
|
||||||
? parseInt(env.SESSION_UPDATE_PERIOD)
|
? parseInt(env.SESSION_UPDATE_PERIOD)
|
||||||
|
@ -94,6 +95,14 @@ async function checkApiKey(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getHeader(ctx: Ctx, header: Header): string | undefined {
|
||||||
|
const contents = ctx.request.headers[header]
|
||||||
|
if (Array.isArray(contents)) {
|
||||||
|
throw new Error("Unexpected header format")
|
||||||
|
}
|
||||||
|
return contents
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This middleware is tenancy aware, so that it does not depend on other middlewares being used.
|
* This middleware is tenancy aware, so that it does not depend on other middlewares being used.
|
||||||
* The tenancy modules should not be used here and it should be assumed that the tenancy context
|
* The tenancy modules should not be used here and it should be assumed that the tenancy context
|
||||||
|
@ -106,9 +115,9 @@ export default function (
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
const noAuthOptions = noAuthPatterns ? buildMatcherRegex(noAuthPatterns) : []
|
const noAuthOptions = noAuthPatterns ? buildMatcherRegex(noAuthPatterns) : []
|
||||||
return async (ctx: Ctx | any, next: any) => {
|
return (async (ctx: Ctx, next: Next) => {
|
||||||
let publicEndpoint = false
|
let publicEndpoint = false
|
||||||
const version = ctx.request.headers[Header.API_VER]
|
const version = getHeader(ctx, Header.API_VER)
|
||||||
// the path is not authenticated
|
// the path is not authenticated
|
||||||
const found = matches(ctx, noAuthOptions)
|
const found = matches(ctx, noAuthOptions)
|
||||||
if (found) {
|
if (found) {
|
||||||
|
@ -116,18 +125,18 @@ export default function (
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// check the actual user is authenticated first, try header or cookie
|
// check the actual user is authenticated first, try header or cookie
|
||||||
let headerToken = ctx.request.headers[Header.TOKEN]
|
let headerToken = getHeader(ctx, Header.TOKEN)
|
||||||
|
|
||||||
const authCookie =
|
const authCookie =
|
||||||
getCookie<SessionCookie>(ctx, Cookie.Auth) ||
|
getCookie<SessionCookie>(ctx, Cookie.Auth) ||
|
||||||
openJwt<SessionCookie>(headerToken)
|
openJwt<SessionCookie>(headerToken)
|
||||||
let apiKey = ctx.request.headers[Header.API_KEY]
|
let apiKey = getHeader(ctx, Header.API_KEY)
|
||||||
|
|
||||||
if (!apiKey && ctx.request.headers[Header.AUTHORIZATION]) {
|
if (!apiKey && ctx.request.headers[Header.AUTHORIZATION]) {
|
||||||
apiKey = ctx.request.headers[Header.AUTHORIZATION].split(" ")[1]
|
apiKey = ctx.request.headers[Header.AUTHORIZATION].split(" ")[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
const tenantId = ctx.request.headers[Header.TENANT_ID]
|
const tenantId = getHeader(ctx, Header.TENANT_ID)
|
||||||
let authenticated: boolean = false,
|
let authenticated: boolean = false,
|
||||||
user: User | { tenantId: string } | undefined = undefined,
|
user: User | { tenantId: string } | undefined = undefined,
|
||||||
internal: boolean = false,
|
internal: boolean = false,
|
||||||
|
@ -243,5 +252,5 @@ export default function (
|
||||||
ctx.throw(err.status || 403, err)
|
ctx.throw(err.status || 403, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}) as Middleware
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { Header } from "../constants"
|
import { Header } from "../constants"
|
||||||
import { buildMatcherRegex, matches } from "./matchers"
|
import { buildMatcherRegex, matches } from "./matchers"
|
||||||
import { BBContext, EndpointMatcher } from "@budibase/types"
|
import { Ctx, EndpointMatcher } from "@budibase/types"
|
||||||
|
import type { Middleware, Next } from "koa"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET, HEAD and OPTIONS methods are considered safe operations
|
* GET, HEAD and OPTIONS methods are considered safe operations
|
||||||
|
@ -36,7 +37,7 @@ export default function (
|
||||||
opts: { noCsrfPatterns: EndpointMatcher[] } = { noCsrfPatterns: [] }
|
opts: { noCsrfPatterns: EndpointMatcher[] } = { noCsrfPatterns: [] }
|
||||||
) {
|
) {
|
||||||
const noCsrfOptions = buildMatcherRegex(opts.noCsrfPatterns)
|
const noCsrfOptions = buildMatcherRegex(opts.noCsrfPatterns)
|
||||||
return async (ctx: BBContext | any, next: any) => {
|
return (async (ctx: Ctx, next: Next) => {
|
||||||
// don't apply for excluded paths
|
// don't apply for excluded paths
|
||||||
const found = matches(ctx, noCsrfOptions)
|
const found = matches(ctx, noCsrfOptions)
|
||||||
if (found) {
|
if (found) {
|
||||||
|
@ -77,5 +78,5 @@ export default function (
|
||||||
}
|
}
|
||||||
|
|
||||||
return next()
|
return next()
|
||||||
}
|
}) as Middleware
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { Header } from "../constants"
|
import { Header } from "../constants"
|
||||||
import { BBContext } from "@budibase/types"
|
import { Ctx } from "@budibase/types"
|
||||||
import { isValidInternalAPIKey } from "../utils"
|
import { isValidInternalAPIKey } from "../utils"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API Key only endpoint.
|
* API Key only endpoint.
|
||||||
*/
|
*/
|
||||||
export default async (ctx: BBContext, next: any) => {
|
export default async (ctx: Ctx, next: any) => {
|
||||||
const apiKey = ctx.request.headers[Header.API_KEY]
|
const apiKey = ctx.request.headers[Header.API_KEY]
|
||||||
if (!apiKey) {
|
if (!apiKey) {
|
||||||
ctx.throw(403, "Unauthorized")
|
ctx.throw(403, "Unauthorized")
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { BBContext, EndpointMatcher, RegexMatcher } from "@budibase/types"
|
import { Ctx, EndpointMatcher, RegexMatcher } from "@budibase/types"
|
||||||
|
|
||||||
const PARAM_REGEX = /\/:(.*?)(\/.*)?$/g
|
const PARAM_REGEX = /\/:(.*?)(\/.*)?$/g
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ export const buildMatcherRegex = (
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const matches = (ctx: BBContext, options: RegexMatcher[]) => {
|
export const matches = (ctx: Ctx, options: RegexMatcher[]) => {
|
||||||
return options.find(({ regex, method }) => {
|
return options.find(({ regex, method }) => {
|
||||||
const urlMatch = regex.test(ctx.request.url)
|
const urlMatch = regex.test(ctx.request.url)
|
||||||
const methodMatch =
|
const methodMatch =
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { UserStatus } from "../../constants"
|
||||||
import { compare } from "../../utils"
|
import { compare } from "../../utils"
|
||||||
import * as users from "../../users"
|
import * as users from "../../users"
|
||||||
import { authError } from "./utils"
|
import { authError } from "./utils"
|
||||||
import { BBContext } from "@budibase/types"
|
import { Ctx } from "@budibase/types"
|
||||||
|
|
||||||
const INVALID_ERR = "Invalid credentials"
|
const INVALID_ERR = "Invalid credentials"
|
||||||
const EXPIRED = "This account has expired. Please reset your password"
|
const EXPIRED = "This account has expired. Please reset your password"
|
||||||
|
@ -20,7 +20,7 @@ export const options = {
|
||||||
* @returns The authenticated user, or errors if they occur
|
* @returns The authenticated user, or errors if they occur
|
||||||
*/
|
*/
|
||||||
export async function authenticate(
|
export async function authenticate(
|
||||||
ctx: BBContext,
|
ctx: Ctx,
|
||||||
email: string,
|
email: string,
|
||||||
password: string,
|
password: string,
|
||||||
done: Function
|
done: Function
|
||||||
|
|
|
@ -3,11 +3,12 @@ import { getTenantIDFromCtx } from "../tenancy"
|
||||||
import { buildMatcherRegex, matches } from "./matchers"
|
import { buildMatcherRegex, matches } from "./matchers"
|
||||||
import { Header } from "../constants"
|
import { Header } from "../constants"
|
||||||
import {
|
import {
|
||||||
BBContext,
|
Ctx,
|
||||||
EndpointMatcher,
|
EndpointMatcher,
|
||||||
GetTenantIdOptions,
|
GetTenantIdOptions,
|
||||||
TenantResolutionStrategy,
|
TenantResolutionStrategy,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
import type { Next, Middleware } from "koa"
|
||||||
|
|
||||||
export default function (
|
export default function (
|
||||||
allowQueryStringPatterns: EndpointMatcher[],
|
allowQueryStringPatterns: EndpointMatcher[],
|
||||||
|
@ -17,7 +18,7 @@ export default function (
|
||||||
const allowQsOptions = buildMatcherRegex(allowQueryStringPatterns)
|
const allowQsOptions = buildMatcherRegex(allowQueryStringPatterns)
|
||||||
const noTenancyOptions = buildMatcherRegex(noTenancyPatterns)
|
const noTenancyOptions = buildMatcherRegex(noTenancyPatterns)
|
||||||
|
|
||||||
return async function (ctx: BBContext | any, next: any) {
|
return async function (ctx: Ctx, next: Next) {
|
||||||
const allowNoTenant =
|
const allowNoTenant =
|
||||||
opts.noTenancyRequired || !!matches(ctx, noTenancyOptions)
|
opts.noTenancyRequired || !!matches(ctx, noTenancyOptions)
|
||||||
const tenantOpts: GetTenantIdOptions = {
|
const tenantOpts: GetTenantIdOptions = {
|
||||||
|
@ -32,5 +33,5 @@ export default function (
|
||||||
const tenantId = getTenantIDFromCtx(ctx, tenantOpts)
|
const tenantId = getTenantIDFromCtx(ctx, tenantOpts)
|
||||||
ctx.set(Header.TENANT_ID, tenantId as string)
|
ctx.set(Header.TENANT_ID, tenantId as string)
|
||||||
return doInTenant(tenantId, next)
|
return doInTenant(tenantId, next)
|
||||||
}
|
} as Middleware
|
||||||
}
|
}
|
||||||
|
|
|
@ -592,7 +592,10 @@ export class AccessController {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkScreensAccess(screens: Screen[], userRoleId: string) {
|
async checkScreensAccess(
|
||||||
|
screens: Screen[],
|
||||||
|
userRoleId: string
|
||||||
|
): Promise<Screen[]> {
|
||||||
let accessibleScreens = []
|
let accessibleScreens = []
|
||||||
// don't want to handle this with Promise.all as this would mean all custom roles would be
|
// don't want to handle this with Promise.all as this would mean all custom roles would be
|
||||||
// retrieved at same time, it is likely a custom role will be re-used and therefore want
|
// retrieved at same time, it is likely a custom role will be re-used and therefore want
|
||||||
|
|
|
@ -6,7 +6,7 @@ import {
|
||||||
getPlatformURL,
|
getPlatformURL,
|
||||||
} from "../context"
|
} from "../context"
|
||||||
import {
|
import {
|
||||||
BBContext,
|
Ctx,
|
||||||
TenantResolutionStrategy,
|
TenantResolutionStrategy,
|
||||||
GetTenantIdOptions,
|
GetTenantIdOptions,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
@ -37,7 +37,7 @@ export const isUserInAppTenant = (appId: string, user?: any) => {
|
||||||
const ALL_STRATEGIES = Object.values(TenantResolutionStrategy)
|
const ALL_STRATEGIES = Object.values(TenantResolutionStrategy)
|
||||||
|
|
||||||
export const getTenantIDFromCtx = (
|
export const getTenantIDFromCtx = (
|
||||||
ctx: BBContext,
|
ctx: Ctx,
|
||||||
opts: GetTenantIdOptions
|
opts: GetTenantIdOptions
|
||||||
): string | undefined => {
|
): string | undefined => {
|
||||||
// exit early if not multi-tenant
|
// exit early if not multi-tenant
|
||||||
|
|
|
@ -5,7 +5,7 @@ import * as db from "../../db"
|
||||||
import { Header } from "../../constants"
|
import { Header } from "../../constants"
|
||||||
import { newid } from "../../utils"
|
import { newid } from "../../utils"
|
||||||
import env from "../../environment"
|
import env from "../../environment"
|
||||||
import { BBContext } from "@budibase/types"
|
import { Ctx } from "@budibase/types"
|
||||||
|
|
||||||
describe("utils", () => {
|
describe("utils", () => {
|
||||||
const config = new DBTestConfiguration()
|
const config = new DBTestConfiguration()
|
||||||
|
@ -109,7 +109,7 @@ describe("utils", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("isServingBuilder", () => {
|
describe("isServingBuilder", () => {
|
||||||
let ctx: BBContext
|
let ctx: Ctx
|
||||||
|
|
||||||
const expectResult = (result: boolean) =>
|
const expectResult = (result: boolean) =>
|
||||||
expect(utils.isServingBuilder(ctx)).toBe(result)
|
expect(utils.isServingBuilder(ctx)).toBe(result)
|
||||||
|
@ -133,7 +133,7 @@ describe("utils", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("isServingBuilderPreview", () => {
|
describe("isServingBuilderPreview", () => {
|
||||||
let ctx: BBContext
|
let ctx: Ctx
|
||||||
|
|
||||||
const expectResult = (result: boolean) =>
|
const expectResult = (result: boolean) =>
|
||||||
expect(utils.isServingBuilderPreview(ctx)).toBe(result)
|
expect(utils.isServingBuilderPreview(ctx)).toBe(result)
|
||||||
|
@ -157,7 +157,7 @@ describe("utils", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("isPublicAPIRequest", () => {
|
describe("isPublicAPIRequest", () => {
|
||||||
let ctx: BBContext
|
let ctx: Ctx
|
||||||
|
|
||||||
const expectResult = (result: boolean) =>
|
const expectResult = (result: boolean) =>
|
||||||
expect(utils.isPublicApiRequest(ctx)).toBe(result)
|
expect(utils.isPublicApiRequest(ctx)).toBe(result)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { createMockContext, createMockCookies } from "@shopify/jest-koa-mocks"
|
import { createMockContext, createMockCookies } from "@shopify/jest-koa-mocks"
|
||||||
import { BBContext } from "@budibase/types"
|
import { Ctx } from "@budibase/types"
|
||||||
|
|
||||||
export const newContext = (): BBContext => {
|
export const newContext = (): Ctx => {
|
||||||
const ctx = createMockContext() as any
|
const ctx = createMockContext() as Ctx
|
||||||
return {
|
return {
|
||||||
...ctx,
|
...ctx,
|
||||||
path: "/",
|
path: "/",
|
||||||
|
|
|
@ -10,13 +10,16 @@ import { updateAppPackage } from "./application"
|
||||||
import {
|
import {
|
||||||
Plugin,
|
Plugin,
|
||||||
ScreenProps,
|
ScreenProps,
|
||||||
BBContext,
|
|
||||||
Screen,
|
Screen,
|
||||||
UserCtx,
|
UserCtx,
|
||||||
|
FetchScreenResponse,
|
||||||
|
SaveScreenRequest,
|
||||||
|
SaveScreenResponse,
|
||||||
|
DeleteScreenResponse,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { builderSocket } from "../../websockets"
|
import { builderSocket } from "../../websockets"
|
||||||
|
|
||||||
export async function fetch(ctx: BBContext) {
|
export async function fetch(ctx: UserCtx<void, FetchScreenResponse>) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
|
|
||||||
const screens = (
|
const screens = (
|
||||||
|
@ -37,7 +40,9 @@ export async function fetch(ctx: BBContext) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function save(ctx: UserCtx<Screen, Screen>) {
|
export async function save(
|
||||||
|
ctx: UserCtx<SaveScreenRequest, SaveScreenResponse>
|
||||||
|
) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
let screen = ctx.request.body
|
let screen = ctx.request.body
|
||||||
|
|
||||||
|
@ -107,7 +112,7 @@ export async function save(ctx: UserCtx<Screen, Screen>) {
|
||||||
builderSocket?.emitScreenUpdate(ctx, savedScreen)
|
builderSocket?.emitScreenUpdate(ctx, savedScreen)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function destroy(ctx: BBContext) {
|
export async function destroy(ctx: UserCtx<void, DeleteScreenResponse>) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
const id = ctx.params.screenId
|
const id = ctx.params.screenId
|
||||||
const screen = await db.get<Screen>(id)
|
const screen = await db.get<Screen>(id)
|
||||||
|
|
|
@ -14,7 +14,3 @@ export async function execute(ctx: Ctx) {
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function save(ctx: Ctx) {
|
|
||||||
ctx.throw(501, "Not currently implemented")
|
|
||||||
}
|
|
||||||
|
|
|
@ -27,7 +27,13 @@ import {
|
||||||
Ctx,
|
Ctx,
|
||||||
DocumentType,
|
DocumentType,
|
||||||
Feature,
|
Feature,
|
||||||
|
GetSignedUploadUrlRequest,
|
||||||
|
GetSignedUploadUrlResponse,
|
||||||
ProcessAttachmentResponse,
|
ProcessAttachmentResponse,
|
||||||
|
ServeAppResponse,
|
||||||
|
ServeBuilderPreviewResponse,
|
||||||
|
ServeClientLibraryResponse,
|
||||||
|
ToggleBetaFeatureResponse,
|
||||||
UserCtx,
|
UserCtx,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import {
|
import {
|
||||||
|
@ -38,7 +44,9 @@ import {
|
||||||
import send from "koa-send"
|
import send from "koa-send"
|
||||||
import { getThemeVariables } from "../../../constants/themes"
|
import { getThemeVariables } from "../../../constants/themes"
|
||||||
|
|
||||||
export const toggleBetaUiFeature = async function (ctx: Ctx) {
|
export const toggleBetaUiFeature = async function (
|
||||||
|
ctx: Ctx<void, ToggleBetaFeatureResponse>
|
||||||
|
) {
|
||||||
const cookieName = `beta:${ctx.params.feature}`
|
const cookieName = `beta:${ctx.params.feature}`
|
||||||
|
|
||||||
if (ctx.cookies.get(cookieName)) {
|
if (ctx.cookies.get(cookieName)) {
|
||||||
|
@ -66,13 +74,13 @@ export const toggleBetaUiFeature = async function (ctx: Ctx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const serveBuilder = async function (ctx: Ctx) {
|
export const serveBuilder = async function (ctx: Ctx<void, void>) {
|
||||||
const builderPath = join(TOP_LEVEL_PATH, "builder")
|
const builderPath = join(TOP_LEVEL_PATH, "builder")
|
||||||
await send(ctx, ctx.file, { root: builderPath })
|
await send(ctx, ctx.file, { root: builderPath })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const uploadFile = async function (
|
export const uploadFile = async function (
|
||||||
ctx: Ctx<{}, ProcessAttachmentResponse>
|
ctx: Ctx<void, ProcessAttachmentResponse>
|
||||||
) {
|
) {
|
||||||
const file = ctx.request?.files?.file
|
const file = ctx.request?.files?.file
|
||||||
if (!file) {
|
if (!file) {
|
||||||
|
@ -144,7 +152,7 @@ const requiresMigration = async (ctx: Ctx) => {
|
||||||
return latestMigrationApplied !== latestMigration
|
return latestMigrationApplied !== latestMigration
|
||||||
}
|
}
|
||||||
|
|
||||||
export const serveApp = async function (ctx: UserCtx) {
|
export const serveApp = async function (ctx: UserCtx<void, ServeAppResponse>) {
|
||||||
if (ctx.url.includes("apple-touch-icon.png")) {
|
if (ctx.url.includes("apple-touch-icon.png")) {
|
||||||
ctx.redirect("/builder/bblogo.png")
|
ctx.redirect("/builder/bblogo.png")
|
||||||
return
|
return
|
||||||
|
@ -249,7 +257,9 @@ export const serveApp = async function (ctx: UserCtx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const serveBuilderPreview = async function (ctx: Ctx) {
|
export const serveBuilderPreview = async function (
|
||||||
|
ctx: Ctx<void, ServeBuilderPreviewResponse>
|
||||||
|
) {
|
||||||
const db = context.getAppDB({ skip_setup: true })
|
const db = context.getAppDB({ skip_setup: true })
|
||||||
const appInfo = await db.get<App>(DocumentType.APP_METADATA)
|
const appInfo = await db.get<App>(DocumentType.APP_METADATA)
|
||||||
|
|
||||||
|
@ -268,7 +278,9 @@ export const serveBuilderPreview = async function (ctx: Ctx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const serveClientLibrary = async function (ctx: Ctx) {
|
export const serveClientLibrary = async function (
|
||||||
|
ctx: Ctx<void, ServeClientLibraryResponse>
|
||||||
|
) {
|
||||||
const version = ctx.request.query.version
|
const version = ctx.request.query.version
|
||||||
|
|
||||||
if (Array.isArray(version)) {
|
if (Array.isArray(version)) {
|
||||||
|
@ -297,7 +309,9 @@ export const serveClientLibrary = async function (ctx: Ctx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getSignedUploadURL = async function (ctx: Ctx) {
|
export const getSignedUploadURL = async function (
|
||||||
|
ctx: Ctx<GetSignedUploadUrlRequest, GetSignedUploadUrlResponse>
|
||||||
|
) {
|
||||||
// Ensure datasource is valid
|
// Ensure datasource is valid
|
||||||
let datasource
|
let datasource
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -19,17 +19,18 @@ import {
|
||||||
EventType,
|
EventType,
|
||||||
FetchTablesResponse,
|
FetchTablesResponse,
|
||||||
FieldType,
|
FieldType,
|
||||||
MigrateRequest,
|
MigrateTableRequest,
|
||||||
MigrateResponse,
|
MigrateTableResponse,
|
||||||
SaveTableRequest,
|
SaveTableRequest,
|
||||||
SaveTableResponse,
|
SaveTableResponse,
|
||||||
Table,
|
Table,
|
||||||
TableResponse,
|
FindTableResponse,
|
||||||
TableSourceType,
|
TableSourceType,
|
||||||
UserCtx,
|
UserCtx,
|
||||||
ValidateNewTableImportRequest,
|
ValidateNewTableImportRequest,
|
||||||
ValidateTableImportRequest,
|
ValidateTableImportRequest,
|
||||||
ValidateTableImportResponse,
|
ValidateTableImportResponse,
|
||||||
|
DeleteTableResponse,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import sdk from "../../../sdk"
|
import sdk from "../../../sdk"
|
||||||
import { jsonFromCsvString } from "../../../utilities/csv"
|
import { jsonFromCsvString } from "../../../utilities/csv"
|
||||||
|
@ -94,7 +95,7 @@ export async function fetch(ctx: UserCtx<void, FetchTablesResponse>) {
|
||||||
ctx.body = result
|
ctx.body = result
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function find(ctx: UserCtx<void, TableResponse>) {
|
export async function find(ctx: UserCtx<void, FindTableResponse>) {
|
||||||
const tableId = ctx.params.tableId
|
const tableId = ctx.params.tableId
|
||||||
const table = await sdk.tables.getTable(tableId)
|
const table = await sdk.tables.getTable(tableId)
|
||||||
|
|
||||||
|
@ -137,7 +138,7 @@ export async function save(ctx: UserCtx<SaveTableRequest, SaveTableResponse>) {
|
||||||
builderSocket?.emitTableUpdate(ctx, cloneDeep(savedTable))
|
builderSocket?.emitTableUpdate(ctx, cloneDeep(savedTable))
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function destroy(ctx: UserCtx) {
|
export async function destroy(ctx: UserCtx<void, DeleteTableResponse>) {
|
||||||
const appId = ctx.appId
|
const appId = ctx.appId
|
||||||
const tableId = ctx.params.tableId
|
const tableId = ctx.params.tableId
|
||||||
await sdk.rowActions.deleteAll(tableId)
|
await sdk.rowActions.deleteAll(tableId)
|
||||||
|
@ -223,7 +224,9 @@ export async function validateExistingTableImport(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function migrate(ctx: UserCtx<MigrateRequest, MigrateResponse>) {
|
export async function migrate(
|
||||||
|
ctx: UserCtx<MigrateTableRequest, MigrateTableResponse>
|
||||||
|
) {
|
||||||
const { oldColumn, newColumn } = ctx.request.body
|
const { oldColumn, newColumn } = ctx.request.body
|
||||||
let tableId = ctx.params.tableId as string
|
let tableId = ctx.params.tableId as string
|
||||||
const table = await sdk.tables.getTable(tableId)
|
const table = await sdk.tables.getTable(tableId)
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
import nodeFetch from "node-fetch"
|
import nodeFetch from "node-fetch"
|
||||||
import { downloadTemplate as dlTemplate } from "../../utilities/fileSystem"
|
import { downloadTemplate as dlTemplate } from "../../utilities/fileSystem"
|
||||||
import env from "../../environment"
|
import env from "../../environment"
|
||||||
import { BBContext } from "@budibase/types"
|
import {
|
||||||
|
DownloadTemplateResponse,
|
||||||
|
FetchTemplateResponse,
|
||||||
|
UserCtx,
|
||||||
|
} from "@budibase/types"
|
||||||
|
|
||||||
// development flag, can be used to test against templates exported locally
|
// development flag, can be used to test against templates exported locally
|
||||||
const DEFAULT_TEMPLATES_BUCKET =
|
const DEFAULT_TEMPLATES_BUCKET =
|
||||||
"prod-budi-templates.s3-eu-west-1.amazonaws.com"
|
"prod-budi-templates.s3-eu-west-1.amazonaws.com"
|
||||||
|
|
||||||
export async function fetch(ctx: BBContext) {
|
export async function fetch(ctx: UserCtx<void, FetchTemplateResponse>) {
|
||||||
let type = env.TEMPLATE_REPOSITORY
|
let type = env.TEMPLATE_REPOSITORY
|
||||||
let response,
|
let response,
|
||||||
error = false
|
error = false
|
||||||
|
@ -32,7 +36,9 @@ export async function fetch(ctx: BBContext) {
|
||||||
|
|
||||||
// can't currently test this, have to ignore from coverage
|
// can't currently test this, have to ignore from coverage
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
export async function downloadTemplate(ctx: BBContext) {
|
export async function downloadTemplate(
|
||||||
|
ctx: UserCtx<void, DownloadTemplateResponse>
|
||||||
|
) {
|
||||||
const { type, name } = ctx.params
|
const { type, name } = ctx.params
|
||||||
|
|
||||||
await dlTemplate(type, name)
|
await dlTemplate(type, name)
|
||||||
|
|
|
@ -7,19 +7,24 @@ import {
|
||||||
FetchUserMetadataResponse,
|
FetchUserMetadataResponse,
|
||||||
FindUserMetadataResponse,
|
FindUserMetadataResponse,
|
||||||
Flags,
|
Flags,
|
||||||
SetFlagRequest,
|
SetUserFlagRequest,
|
||||||
|
UpdateSelfMetadataRequest,
|
||||||
|
UpdateSelfMetadataResponse,
|
||||||
|
UpdateUserMetadataResponse,
|
||||||
|
UpdateUserMetadataRequest,
|
||||||
UserCtx,
|
UserCtx,
|
||||||
UserMetadata,
|
DeleteUserMetadataResponse,
|
||||||
|
SetUserFlagResponse,
|
||||||
|
GetUserFlagsResponse,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import sdk from "../../sdk"
|
import sdk from "../../sdk"
|
||||||
import { DocumentInsertResponse } from "@budibase/nano"
|
|
||||||
|
|
||||||
export async function fetchMetadata(ctx: Ctx<void, FetchUserMetadataResponse>) {
|
export async function fetchMetadata(ctx: Ctx<void, FetchUserMetadataResponse>) {
|
||||||
ctx.body = await sdk.users.fetchMetadata()
|
ctx.body = await sdk.users.fetchMetadata()
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateSelfMetadata(
|
export async function updateSelfMetadata(
|
||||||
ctx: UserCtx<UserMetadata, DocumentInsertResponse>
|
ctx: UserCtx<UpdateSelfMetadataRequest, UpdateSelfMetadataResponse>
|
||||||
) {
|
) {
|
||||||
// overwrite the ID with current users
|
// overwrite the ID with current users
|
||||||
ctx.request.body._id = ctx.user?._id
|
ctx.request.body._id = ctx.user?._id
|
||||||
|
@ -31,7 +36,7 @@ export async function updateSelfMetadata(
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateMetadata(
|
export async function updateMetadata(
|
||||||
ctx: UserCtx<UserMetadata, DocumentInsertResponse>
|
ctx: UserCtx<UpdateUserMetadataRequest, UpdateUserMetadataResponse>
|
||||||
) {
|
) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
const user = ctx.request.body
|
const user = ctx.request.body
|
||||||
|
@ -44,7 +49,9 @@ export async function updateMetadata(
|
||||||
ctx.body = await db.put(metadata)
|
ctx.body = await db.put(metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function destroyMetadata(ctx: UserCtx<void, { message: string }>) {
|
export async function destroyMetadata(
|
||||||
|
ctx: UserCtx<void, DeleteUserMetadataResponse>
|
||||||
|
) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
try {
|
try {
|
||||||
const dbUser = await sdk.users.get(ctx.params.id)
|
const dbUser = await sdk.users.get(ctx.params.id)
|
||||||
|
@ -64,7 +71,7 @@ export async function findMetadata(
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function setFlag(
|
export async function setFlag(
|
||||||
ctx: UserCtx<SetFlagRequest, { message: string }>
|
ctx: UserCtx<SetUserFlagRequest, SetUserFlagResponse>
|
||||||
) {
|
) {
|
||||||
const userId = ctx.user?._id
|
const userId = ctx.user?._id
|
||||||
const { flag, value } = ctx.request.body
|
const { flag, value } = ctx.request.body
|
||||||
|
@ -84,7 +91,7 @@ export async function setFlag(
|
||||||
ctx.body = { message: "Flag set successfully" }
|
ctx.body = { message: "Flag set successfully" }
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getFlags(ctx: UserCtx<void, Flags>) {
|
export async function getFlags(ctx: UserCtx<void, GetUserFlagsResponse>) {
|
||||||
const userId = ctx.user?._id
|
const userId = ctx.user?._id
|
||||||
const docId = generateUserFlagID(userId!)
|
const docId = generateUserFlagID(userId!)
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
|
|
|
@ -4,7 +4,6 @@ import {
|
||||||
Ctx,
|
Ctx,
|
||||||
RequiredKeys,
|
RequiredKeys,
|
||||||
UpdateViewRequest,
|
UpdateViewRequest,
|
||||||
ViewResponse,
|
|
||||||
ViewResponseEnriched,
|
ViewResponseEnriched,
|
||||||
ViewV2,
|
ViewV2,
|
||||||
BasicViewFieldMetadata,
|
BasicViewFieldMetadata,
|
||||||
|
@ -15,6 +14,8 @@ import {
|
||||||
ViewFetchResponseEnriched,
|
ViewFetchResponseEnriched,
|
||||||
CountDistinctCalculationFieldMetadata,
|
CountDistinctCalculationFieldMetadata,
|
||||||
CountCalculationFieldMetadata,
|
CountCalculationFieldMetadata,
|
||||||
|
CreateViewResponse,
|
||||||
|
UpdateViewResponse,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { builderSocket, gridSocket } from "../../../websockets"
|
import { builderSocket, gridSocket } from "../../../websockets"
|
||||||
import { helpers } from "@budibase/shared-core"
|
import { helpers } from "@budibase/shared-core"
|
||||||
|
@ -132,7 +133,7 @@ export async function fetch(ctx: Ctx<void, ViewFetchResponseEnriched>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function create(ctx: Ctx<CreateViewRequest, ViewResponse>) {
|
export async function create(ctx: Ctx<CreateViewRequest, CreateViewResponse>) {
|
||||||
const view = ctx.request.body
|
const view = ctx.request.body
|
||||||
const { tableId } = view
|
const { tableId } = view
|
||||||
|
|
||||||
|
@ -159,7 +160,7 @@ export async function create(ctx: Ctx<CreateViewRequest, ViewResponse>) {
|
||||||
gridSocket?.emitViewUpdate(ctx, result)
|
gridSocket?.emitViewUpdate(ctx, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function update(ctx: Ctx<UpdateViewRequest, ViewResponse>) {
|
export async function update(ctx: Ctx<UpdateViewRequest, UpdateViewResponse>) {
|
||||||
const view = ctx.request.body
|
const view = ctx.request.body
|
||||||
|
|
||||||
if (view.version !== 2) {
|
if (view.version !== 2) {
|
||||||
|
@ -196,7 +197,7 @@ export async function update(ctx: Ctx<UpdateViewRequest, ViewResponse>) {
|
||||||
gridSocket?.emitViewUpdate(ctx, result)
|
gridSocket?.emitViewUpdate(ctx, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function remove(ctx: Ctx) {
|
export async function remove(ctx: Ctx<void, void>) {
|
||||||
const { viewId } = ctx.params
|
const { viewId } = ctx.params
|
||||||
|
|
||||||
const view = await sdk.views.remove(viewId)
|
const view = await sdk.views.remove(viewId)
|
||||||
|
|
|
@ -4,9 +4,17 @@ import { db as dbCore, context } from "@budibase/backend-core"
|
||||||
import {
|
import {
|
||||||
Webhook,
|
Webhook,
|
||||||
WebhookActionType,
|
WebhookActionType,
|
||||||
BBContext,
|
Ctx,
|
||||||
Automation,
|
Automation,
|
||||||
AutomationActionStepId,
|
AutomationActionStepId,
|
||||||
|
FetchWebhooksResponse,
|
||||||
|
SaveWebhookResponse,
|
||||||
|
SaveWebhookRequest,
|
||||||
|
DeleteWebhookResponse,
|
||||||
|
BuildWebhookSchemaRequest,
|
||||||
|
BuildWebhookSchemaResponse,
|
||||||
|
TriggerWebhookRequest,
|
||||||
|
TriggerWebhookResponse,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import sdk from "../../sdk"
|
import sdk from "../../sdk"
|
||||||
import * as pro from "@budibase/pro"
|
import * as pro from "@budibase/pro"
|
||||||
|
@ -16,17 +24,17 @@ const validate = require("jsonschema").validate
|
||||||
|
|
||||||
const AUTOMATION_DESCRIPTION = "Generated from Webhook Schema"
|
const AUTOMATION_DESCRIPTION = "Generated from Webhook Schema"
|
||||||
|
|
||||||
export async function fetch(ctx: BBContext) {
|
export async function fetch(ctx: Ctx<void, FetchWebhooksResponse>) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
const response = await db.allDocs(
|
const response = await db.allDocs<Webhook>(
|
||||||
getWebhookParams(null, {
|
getWebhookParams(null, {
|
||||||
include_docs: true,
|
include_docs: true,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
ctx.body = response.rows.map((row: any) => row.doc)
|
ctx.body = response.rows.filter(row => row.doc).map(row => row.doc!)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function save(ctx: BBContext) {
|
export async function save(ctx: Ctx<SaveWebhookRequest, SaveWebhookResponse>) {
|
||||||
const webhook = await sdk.automations.webhook.save(ctx.request.body)
|
const webhook = await sdk.automations.webhook.save(ctx.request.body)
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
message: "Webhook created successfully",
|
message: "Webhook created successfully",
|
||||||
|
@ -34,21 +42,23 @@ export async function save(ctx: BBContext) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function destroy(ctx: BBContext) {
|
export async function destroy(ctx: Ctx<void, DeleteWebhookResponse>) {
|
||||||
ctx.body = await sdk.automations.webhook.destroy(
|
ctx.body = await sdk.automations.webhook.destroy(
|
||||||
ctx.params.id,
|
ctx.params.id,
|
||||||
ctx.params.rev
|
ctx.params.rev
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function buildSchema(ctx: BBContext) {
|
export async function buildSchema(
|
||||||
|
ctx: Ctx<BuildWebhookSchemaRequest, BuildWebhookSchemaResponse>
|
||||||
|
) {
|
||||||
await context.doInAppContext(ctx.params.instance, async () => {
|
await context.doInAppContext(ctx.params.instance, async () => {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
const webhook = (await db.get(ctx.params.id)) as Webhook
|
const webhook = await db.get<Webhook>(ctx.params.id)
|
||||||
webhook.bodySchema = toJsonSchema(ctx.request.body)
|
webhook.bodySchema = toJsonSchema(ctx.request.body)
|
||||||
// update the automation outputs
|
// update the automation outputs
|
||||||
if (webhook.action.type === WebhookActionType.AUTOMATION) {
|
if (webhook.action.type === WebhookActionType.AUTOMATION) {
|
||||||
let automation = (await db.get(webhook.action.target)) as Automation
|
let automation = await db.get<Automation>(webhook.action.target)
|
||||||
const autoOutputs = automation.definition.trigger.schema.outputs
|
const autoOutputs = automation.definition.trigger.schema.outputs
|
||||||
let properties = webhook.bodySchema.properties
|
let properties = webhook.bodySchema.properties
|
||||||
// reset webhook outputs
|
// reset webhook outputs
|
||||||
|
@ -67,17 +77,29 @@ export async function buildSchema(ctx: BBContext) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function trigger(ctx: BBContext) {
|
export async function trigger(
|
||||||
|
ctx: Ctx<TriggerWebhookRequest, TriggerWebhookResponse>
|
||||||
|
) {
|
||||||
const prodAppId = dbCore.getProdAppID(ctx.params.instance)
|
const prodAppId = dbCore.getProdAppID(ctx.params.instance)
|
||||||
|
const appNotDeployed = () => {
|
||||||
|
ctx.body = {
|
||||||
|
message: "Application not deployed yet.",
|
||||||
|
}
|
||||||
|
}
|
||||||
await context.doInAppContext(prodAppId, async () => {
|
await context.doInAppContext(prodAppId, async () => {
|
||||||
try {
|
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
const webhook = (await db.get(ctx.params.id)) as Webhook
|
const webhook = await db.tryGet<Webhook>(ctx.params.id)
|
||||||
|
if (!webhook) {
|
||||||
|
return appNotDeployed()
|
||||||
|
}
|
||||||
// validate against the schema
|
// validate against the schema
|
||||||
if (webhook.bodySchema) {
|
if (webhook.bodySchema) {
|
||||||
validate(ctx.request.body, webhook.bodySchema)
|
validate(ctx.request.body, webhook.bodySchema)
|
||||||
}
|
}
|
||||||
const target = await db.get<Automation>(webhook.action.target)
|
const target = await db.tryGet<Automation>(webhook.action.target)
|
||||||
|
if (!target) {
|
||||||
|
return appNotDeployed()
|
||||||
|
}
|
||||||
if (webhook.action.type === WebhookActionType.AUTOMATION) {
|
if (webhook.action.type === WebhookActionType.AUTOMATION) {
|
||||||
// trigger with both the pure request and then expand it
|
// trigger with both the pure request and then expand it
|
||||||
// incase the user has produced a schema to bind to
|
// incase the user has produced a schema to bind to
|
||||||
|
@ -87,8 +109,10 @@ export async function trigger(ctx: BBContext) {
|
||||||
const response = await triggers.externalTrigger(
|
const response = await triggers.externalTrigger(
|
||||||
target,
|
target,
|
||||||
{
|
{
|
||||||
body: ctx.request.body,
|
fields: {
|
||||||
...ctx.request.body,
|
...ctx.request.body,
|
||||||
|
body: ctx.request.body,
|
||||||
|
},
|
||||||
appId: prodAppId,
|
appId: prodAppId,
|
||||||
},
|
},
|
||||||
{ getResponses: true }
|
{ getResponses: true }
|
||||||
|
@ -99,30 +123,22 @@ export async function trigger(ctx: BBContext) {
|
||||||
(step: any) => step.stepId === AutomationActionStepId.COLLECT
|
(step: any) => step.stepId === AutomationActionStepId.COLLECT
|
||||||
)
|
)
|
||||||
|
|
||||||
ctx.status = 200
|
|
||||||
ctx.body = collectedValue?.outputs
|
ctx.body = collectedValue?.outputs
|
||||||
} else {
|
} else {
|
||||||
ctx.throw(400, "Automation did not have a collect block.")
|
ctx.throw(400, "Automation did not have a collect block.")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await triggers.externalTrigger(target, {
|
await triggers.externalTrigger(target, {
|
||||||
body: ctx.request.body,
|
fields: {
|
||||||
...ctx.request.body,
|
...ctx.request.body,
|
||||||
|
body: ctx.request.body,
|
||||||
|
},
|
||||||
appId: prodAppId,
|
appId: prodAppId,
|
||||||
})
|
})
|
||||||
ctx.status = 200
|
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
message: "Webhook trigger fired successfully",
|
message: "Webhook trigger fired successfully",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
|
||||||
if (err.status === 404) {
|
|
||||||
ctx.status = 200
|
|
||||||
ctx.body = {
|
|
||||||
message: "Application not deployed yet.",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,12 +58,9 @@ if (apiEnabled()) {
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.use(pro.licensing())
|
.use(pro.licensing())
|
||||||
// @ts-ignore
|
|
||||||
.use(currentApp)
|
.use(currentApp)
|
||||||
.use(auth.auditLog)
|
.use(auth.auditLog)
|
||||||
// @ts-ignore
|
|
||||||
.use(migrations)
|
.use(migrations)
|
||||||
// @ts-ignore
|
|
||||||
.use(cleanup)
|
.use(cleanup)
|
||||||
|
|
||||||
// authenticated routes
|
// authenticated routes
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
import Router from "@koa/router"
|
|
||||||
import * as controller from "../controllers/script"
|
|
||||||
import authorized from "../../middleware/authorized"
|
|
||||||
import { permissions } from "@budibase/backend-core"
|
|
||||||
|
|
||||||
const router: Router = new Router()
|
|
||||||
|
|
||||||
router.post("/api/script", authorized(permissions.BUILDER), controller.save)
|
|
||||||
|
|
||||||
export default router
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { isDevAppID, isProdAppID } from "../db/utils"
|
import { isDevAppID, isProdAppID } from "../db/utils"
|
||||||
import { BBContext } from "@budibase/types"
|
import { Ctx } from "@budibase/types"
|
||||||
|
|
||||||
export enum AppType {
|
export enum AppType {
|
||||||
DEV = "dev",
|
DEV = "dev",
|
||||||
|
@ -7,7 +7,7 @@ export enum AppType {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function middleware({ appType }: { appType?: AppType } = {}) {
|
export function middleware({ appType }: { appType?: AppType } = {}) {
|
||||||
return (ctx: BBContext, next: any) => {
|
return (ctx: Ctx, next: any) => {
|
||||||
const appId = ctx.appId
|
const appId = ctx.appId
|
||||||
if (appType === AppType.DEV && appId && !isDevAppID(appId)) {
|
if (appType === AppType.DEV && appId && !isDevAppID(appId)) {
|
||||||
ctx.throw(400, "Only apps in development support this endpoint")
|
ctx.throw(400, "Only apps in development support this endpoint")
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { UserCtx } from "@budibase/types"
|
import { UserCtx } from "@budibase/types"
|
||||||
import { checkMissingMigrations } from "../appMigrations"
|
import { checkMissingMigrations } from "../appMigrations"
|
||||||
import env from "../environment"
|
import env from "../environment"
|
||||||
|
import type { Middleware, Next } from "koa"
|
||||||
|
|
||||||
export default async (ctx: UserCtx, next: any) => {
|
const middleware = (async (ctx: UserCtx, next: Next) => {
|
||||||
const { appId } = ctx
|
const { appId } = ctx
|
||||||
|
|
||||||
// migrations can be disabled via environment variable if you
|
// migrations can be disabled via environment variable if you
|
||||||
|
@ -16,4 +17,6 @@ export default async (ctx: UserCtx, next: any) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return checkMissingMigrations(ctx, next, appId)
|
return checkMissingMigrations(ctx, next, appId)
|
||||||
}
|
}) as Middleware
|
||||||
|
|
||||||
|
export default middleware
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { Ctx } from "@budibase/types"
|
import { Ctx } from "@budibase/types"
|
||||||
import { context } from "@budibase/backend-core"
|
import { context } from "@budibase/backend-core"
|
||||||
import { tracer } from "dd-trace"
|
import { tracer } from "dd-trace"
|
||||||
|
import type { Middleware, Next } from "koa"
|
||||||
|
|
||||||
export default async (ctx: Ctx, next: any) => {
|
const middleware = (async (ctx: Ctx, next: Next) => {
|
||||||
const resp = await next()
|
const resp = await next()
|
||||||
|
|
||||||
const current = context.getCurrentContext()
|
const current = context.getCurrentContext()
|
||||||
|
@ -30,4 +31,6 @@ export default async (ctx: Ctx, next: any) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp
|
return resp
|
||||||
}
|
}) as Middleware
|
||||||
|
|
||||||
|
export default middleware
|
||||||
|
|
|
@ -13,8 +13,9 @@ import env from "../environment"
|
||||||
import { isWebhookEndpoint, isBrowser, isApiKey } from "./utils"
|
import { isWebhookEndpoint, isBrowser, isApiKey } from "./utils"
|
||||||
import { UserCtx, ContextUser } from "@budibase/types"
|
import { UserCtx, ContextUser } from "@budibase/types"
|
||||||
import tracer from "dd-trace"
|
import tracer from "dd-trace"
|
||||||
|
import type { Middleware, Next } from "koa"
|
||||||
|
|
||||||
export default async (ctx: UserCtx, next: any) => {
|
const middleware = (async (ctx: UserCtx, next: Next) => {
|
||||||
// try to get the appID from the request
|
// try to get the appID from the request
|
||||||
let requestAppId = await utils.getAppIdFromCtx(ctx)
|
let requestAppId = await utils.getAppIdFromCtx(ctx)
|
||||||
if (!requestAppId) {
|
if (!requestAppId) {
|
||||||
|
@ -116,4 +117,6 @@ export default async (ctx: UserCtx, next: any) => {
|
||||||
|
|
||||||
return next()
|
return next()
|
||||||
})
|
})
|
||||||
}
|
}) as Middleware
|
||||||
|
|
||||||
|
export default middleware
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import Joi from "joi"
|
import Joi from "joi"
|
||||||
import { BBContext } from "@budibase/types"
|
import { Ctx } from "@budibase/types"
|
||||||
|
|
||||||
function validate(schema: Joi.Schema, property: string) {
|
function validate(schema: Joi.Schema, property: string) {
|
||||||
// Return a Koa middleware function
|
// Return a Koa middleware function
|
||||||
return (ctx: BBContext, next: any) => {
|
return (ctx: Ctx, next: any) => {
|
||||||
if (!schema) {
|
if (!schema) {
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { BBContext } from "@budibase/types"
|
import { Ctx } from "@budibase/types"
|
||||||
|
|
||||||
export class ResourceIdGetter {
|
export class ResourceIdGetter {
|
||||||
parameter: string
|
parameter: string
|
||||||
|
@ -26,7 +26,7 @@ export class ResourceIdGetter {
|
||||||
const parameter = this.parameter,
|
const parameter = this.parameter,
|
||||||
main = this.main,
|
main = this.main,
|
||||||
sub = this.sub
|
sub = this.sub
|
||||||
return (ctx: BBContext, next: any) => {
|
return (ctx: Ctx, next: any) => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const request = ctx.request[parameter] || ctx[parameter]
|
const request = ctx.request[parameter] || ctx[parameter]
|
||||||
if (request == null) {
|
if (request == null) {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import env from "../environment"
|
import env from "../environment"
|
||||||
import { BBContext } from "@budibase/types"
|
import { Ctx } from "@budibase/types"
|
||||||
|
|
||||||
// if added as a middleware will stop requests unless builder is in self host mode
|
// if added as a middleware will stop requests unless builder is in self host mode
|
||||||
// or cloud is in self host
|
// or cloud is in self host
|
||||||
export default async (ctx: BBContext, next: any) => {
|
export default async (ctx: Ctx, next: any) => {
|
||||||
if (env.SELF_HOSTED) {
|
if (env.SELF_HOSTED) {
|
||||||
await next()
|
await next()
|
||||||
return
|
return
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
Database,
|
Database,
|
||||||
INTERNAL_TABLE_SOURCE_ID,
|
INTERNAL_TABLE_SOURCE_ID,
|
||||||
Table,
|
Table,
|
||||||
TableResponse,
|
FindTableResponse,
|
||||||
TableSourceType,
|
TableSourceType,
|
||||||
TableViewsResponse,
|
TableViewsResponse,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
@ -173,7 +173,9 @@ export async function getTables(tableIds: string[]): Promise<Table[]> {
|
||||||
return await processTables(tables)
|
return await processTables(tables)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function enrichViewSchemas(table: Table): Promise<TableResponse> {
|
export async function enrichViewSchemas(
|
||||||
|
table: Table
|
||||||
|
): Promise<FindTableResponse> {
|
||||||
const views = []
|
const views = []
|
||||||
for (const view of Object.values(table.views ?? [])) {
|
for (const view of Object.values(table.views ?? [])) {
|
||||||
if (sdk.views.isV2(view)) {
|
if (sdk.views.isV2(view)) {
|
||||||
|
|
|
@ -3,8 +3,8 @@ import {
|
||||||
BulkImportResponse,
|
BulkImportResponse,
|
||||||
CsvToJsonRequest,
|
CsvToJsonRequest,
|
||||||
CsvToJsonResponse,
|
CsvToJsonResponse,
|
||||||
MigrateRequest,
|
MigrateTableRequest,
|
||||||
MigrateResponse,
|
MigrateTableResponse,
|
||||||
SaveTableRequest,
|
SaveTableRequest,
|
||||||
SaveTableResponse,
|
SaveTableResponse,
|
||||||
Table,
|
Table,
|
||||||
|
@ -38,13 +38,16 @@ export class TableAPI extends TestAPI {
|
||||||
|
|
||||||
migrate = async (
|
migrate = async (
|
||||||
tableId: string,
|
tableId: string,
|
||||||
data: MigrateRequest,
|
data: MigrateTableRequest,
|
||||||
expectations?: Expectations
|
expectations?: Expectations
|
||||||
): Promise<MigrateResponse> => {
|
): Promise<MigrateTableResponse> => {
|
||||||
return await this._post<MigrateResponse>(`/api/tables/${tableId}/migrate`, {
|
return await this._post<MigrateTableResponse>(
|
||||||
|
`/api/tables/${tableId}/migrate`,
|
||||||
|
{
|
||||||
body: data,
|
body: data,
|
||||||
expectations,
|
expectations,
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
import = async (
|
import = async (
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import type { PlanType } from "../../sdk"
|
import type { PlanType } from "../../../sdk"
|
||||||
import type { Layout, App, Screen } from "../../documents"
|
import type { Layout, App, Screen } from "../../../documents"
|
||||||
import { ReadStream } from "fs"
|
import { ReadStream } from "fs"
|
||||||
|
|
||||||
export interface SyncAppResponse {
|
export interface SyncAppResponse {
|
|
@ -1,9 +1,14 @@
|
||||||
import {
|
import {
|
||||||
|
Automation,
|
||||||
AutomationActionStepId,
|
AutomationActionStepId,
|
||||||
|
AutomationLogPage,
|
||||||
|
AutomationStatus,
|
||||||
AutomationStepDefinition,
|
AutomationStepDefinition,
|
||||||
AutomationTriggerDefinition,
|
AutomationTriggerDefinition,
|
||||||
AutomationTriggerStepId,
|
AutomationTriggerStepId,
|
||||||
|
Row,
|
||||||
} from "../../../documents"
|
} from "../../../documents"
|
||||||
|
import { DocumentDestroyResponse } from "@budibase/nano"
|
||||||
|
|
||||||
export type GetAutomationTriggerDefinitionsResponse = Record<
|
export type GetAutomationTriggerDefinitionsResponse = Record<
|
||||||
keyof typeof AutomationTriggerStepId,
|
keyof typeof AutomationTriggerStepId,
|
||||||
|
@ -19,3 +24,54 @@ export interface GetAutomationStepDefinitionsResponse {
|
||||||
trigger: GetAutomationTriggerDefinitionsResponse
|
trigger: GetAutomationTriggerDefinitionsResponse
|
||||||
action: GetAutomationActionDefinitionsResponse
|
action: GetAutomationActionDefinitionsResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DeleteAutomationResponse extends DocumentDestroyResponse {}
|
||||||
|
|
||||||
|
export interface FetchAutomationResponse {
|
||||||
|
automations: Automation[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FindAutomationResponse extends Automation {}
|
||||||
|
|
||||||
|
export interface UpdateAutomationRequest extends Automation {}
|
||||||
|
export interface UpdateAutomationResponse {
|
||||||
|
message: string
|
||||||
|
automation: Automation
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CreateAutomationRequest extends Automation {}
|
||||||
|
export interface CreateAutomationResponse {
|
||||||
|
message: string
|
||||||
|
automation: Automation
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SearchAutomationLogsRequest {
|
||||||
|
startDate?: string
|
||||||
|
status?: AutomationStatus
|
||||||
|
automationId?: string
|
||||||
|
page?: string
|
||||||
|
}
|
||||||
|
export interface SearchAutomationLogsResponse extends AutomationLogPage {}
|
||||||
|
|
||||||
|
export interface ClearAutomationLogRequest {
|
||||||
|
automationId: string
|
||||||
|
appId: string
|
||||||
|
}
|
||||||
|
export interface ClearAutomationLogResponse {
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TriggerAutomationRequest {
|
||||||
|
fields: Record<string, any>
|
||||||
|
// time in seconds
|
||||||
|
timeout: number
|
||||||
|
}
|
||||||
|
export type TriggerAutomationResponse = Record<string, any> | undefined
|
||||||
|
|
||||||
|
export interface TestAutomationRequest {
|
||||||
|
id?: string
|
||||||
|
revision?: string
|
||||||
|
fields: Record<string, any>
|
||||||
|
row?: Row
|
||||||
|
}
|
||||||
|
export interface TestAutomationResponse {}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { DeploymentDoc, DeploymentStatus } from "../../documents"
|
import { DeploymentDoc, DeploymentStatus } from "../../../documents"
|
||||||
|
|
||||||
export interface PublishAppResponse extends DeploymentDoc {}
|
export interface PublishAppResponse extends DeploymentDoc {}
|
||||||
|
|
|
@ -13,3 +13,9 @@ export * from "./integration"
|
||||||
export * from "./metadata"
|
export * from "./metadata"
|
||||||
export * from "./query"
|
export * from "./query"
|
||||||
export * from "./screen"
|
export * from "./screen"
|
||||||
|
export * from "./application"
|
||||||
|
export * from "./layout"
|
||||||
|
export * from "./deployment"
|
||||||
|
export * from "./role"
|
||||||
|
export * from "./webhook"
|
||||||
|
export * from "./static"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Layout } from "../../documents"
|
import { Layout } from "../../../documents"
|
||||||
|
|
||||||
export interface SaveLayoutRequest extends Layout {}
|
export interface SaveLayoutRequest extends Layout {}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Role, RoleUIMetadata } from "../../documents"
|
import { Role, RoleUIMetadata } from "../../../documents"
|
||||||
import { PermissionLevel, BuiltinPermissionID } from "../../sdk"
|
import { PermissionLevel, BuiltinPermissionID } from "../../../sdk"
|
||||||
|
|
||||||
export interface SaveRoleRequest {
|
export interface SaveRoleRequest {
|
||||||
_id?: string
|
_id?: string
|
|
@ -1,4 +1,4 @@
|
||||||
import { ScreenRoutingJson } from "../../../documents"
|
import { ScreenRoutingJson, Screen } from "../../../documents"
|
||||||
|
|
||||||
export interface FetchScreenRoutingResponse {
|
export interface FetchScreenRoutingResponse {
|
||||||
routes: ScreenRoutingJson
|
routes: ScreenRoutingJson
|
||||||
|
@ -6,3 +6,12 @@ export interface FetchScreenRoutingResponse {
|
||||||
|
|
||||||
export interface FetchClientScreenRoutingResponse
|
export interface FetchClientScreenRoutingResponse
|
||||||
extends FetchScreenRoutingResponse {}
|
extends FetchScreenRoutingResponse {}
|
||||||
|
|
||||||
|
export type FetchScreenResponse = Screen[]
|
||||||
|
|
||||||
|
export interface SaveScreenRequest extends Screen {}
|
||||||
|
export interface SaveScreenResponse extends Screen {}
|
||||||
|
|
||||||
|
export interface DeleteScreenResponse {
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { App } from "../../../documents"
|
||||||
|
import stream from "node:stream"
|
||||||
|
|
||||||
|
export interface ToggleBetaFeatureResponse {
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ServeAppResponse = string
|
||||||
|
|
||||||
|
interface BuilderPreview extends App {
|
||||||
|
builderPreview: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ServeBuilderPreviewResponse = BuilderPreview | string
|
||||||
|
|
||||||
|
export type ServeClientLibraryResponse = stream.Readable
|
||||||
|
|
||||||
|
export interface GetSignedUploadUrlRequest {
|
||||||
|
bucket: string
|
||||||
|
key: string
|
||||||
|
}
|
||||||
|
export interface GetSignedUploadUrlResponse {
|
||||||
|
signedUrl?: string
|
||||||
|
publicUrl?: string
|
||||||
|
}
|
|
@ -3,33 +3,30 @@ import { ViewV2Enriched } from "../../../sdk"
|
||||||
|
|
||||||
export type TableViewsResponse = { [key: string]: View | ViewV2Enriched }
|
export type TableViewsResponse = { [key: string]: View | ViewV2Enriched }
|
||||||
|
|
||||||
export interface TableResponse extends Table {
|
export interface FindTableResponse extends Table {
|
||||||
views?: TableViewsResponse
|
views?: TableViewsResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FetchTablesResponse = TableResponse[]
|
export type FetchTablesResponse = FindTableResponse[]
|
||||||
|
|
||||||
export interface SaveTableRequest extends TableRequest {
|
export interface SaveTableRequest extends TableRequest {
|
||||||
rows?: Row[]
|
rows?: Row[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SaveTableResponse = Table
|
export type SaveTableResponse = Table
|
||||||
|
|
||||||
export interface BulkImportRequest {
|
export interface BulkImportRequest {
|
||||||
rows: Row[]
|
rows: Row[]
|
||||||
identifierFields?: Array<string>
|
identifierFields?: Array<string>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BulkImportResponse {
|
export interface BulkImportResponse {
|
||||||
message: string
|
message: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MigrateRequest {
|
export interface MigrateTableRequest {
|
||||||
oldColumn: string
|
oldColumn: string
|
||||||
newColumn: string
|
newColumn: string
|
||||||
}
|
}
|
||||||
|
export interface MigrateTableResponse {
|
||||||
export interface MigrateResponse {
|
|
||||||
message: string
|
message: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,12 +34,10 @@ export interface ValidateNewTableImportRequest {
|
||||||
rows: Row[]
|
rows: Row[]
|
||||||
schema: TableSchema
|
schema: TableSchema
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ValidateTableImportRequest {
|
export interface ValidateTableImportRequest {
|
||||||
tableId?: string
|
tableId?: string
|
||||||
rows: Row[]
|
rows: Row[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ValidateTableImportResponse {
|
export interface ValidateTableImportResponse {
|
||||||
schemaValidation: {
|
schemaValidation: {
|
||||||
[field: string]: boolean
|
[field: string]: boolean
|
||||||
|
@ -55,5 +50,8 @@ export interface ValidateTableImportResponse {
|
||||||
export interface CsvToJsonRequest {
|
export interface CsvToJsonRequest {
|
||||||
csvString: string
|
csvString: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CsvToJsonResponse = any[]
|
export type CsvToJsonResponse = any[]
|
||||||
|
|
||||||
|
export interface DeleteTableResponse {
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,27 @@
|
||||||
import { ContextUserMetadata } from "../../../"
|
import { ContextUserMetadata, Flags, UserMetadata } from "../../../"
|
||||||
|
import { DocumentInsertResponse } from "@budibase/nano"
|
||||||
|
|
||||||
export type FetchUserMetadataResponse = ContextUserMetadata[]
|
export type FetchUserMetadataResponse = ContextUserMetadata[]
|
||||||
export type FindUserMetadataResponse = ContextUserMetadata
|
export type FindUserMetadataResponse = ContextUserMetadata
|
||||||
|
|
||||||
export interface SetFlagRequest {
|
export interface SetUserFlagRequest {
|
||||||
flag: string
|
flag: string
|
||||||
value: any
|
value: any
|
||||||
}
|
}
|
||||||
|
export interface SetUserFlagResponse {
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GetUserFlagsResponse extends Flags {}
|
||||||
|
|
||||||
export type AppSelfResponse = ContextUserMetadata | {}
|
export type AppSelfResponse = ContextUserMetadata | {}
|
||||||
|
|
||||||
|
export interface UpdateSelfMetadataRequest extends UserMetadata {}
|
||||||
|
export interface UpdateSelfMetadataResponse extends DocumentInsertResponse {}
|
||||||
|
|
||||||
|
export interface UpdateUserMetadataRequest extends UserMetadata {}
|
||||||
|
export interface UpdateUserMetadataResponse extends DocumentInsertResponse {}
|
||||||
|
|
||||||
|
export interface DeleteUserMetadataResponse {
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|
|
@ -14,5 +14,7 @@ export interface ViewFetchResponseEnriched {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateViewRequest extends Omit<ViewV2, "version" | "id"> {}
|
export interface CreateViewRequest extends Omit<ViewV2, "version" | "id"> {}
|
||||||
|
export interface CreateViewResponse extends ViewResponse {}
|
||||||
|
|
||||||
export interface UpdateViewRequest extends ViewV2 {}
|
export interface UpdateViewRequest extends ViewV2 {}
|
||||||
|
export interface UpdateViewResponse extends ViewResponse {}
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { Webhook } from "../../../documents"
|
||||||
|
import { DocumentDestroyResponse, DocumentInsertResponse } from "@budibase/nano"
|
||||||
|
|
||||||
|
export type FetchWebhooksResponse = Webhook[]
|
||||||
|
|
||||||
|
export interface SaveWebhookRequest extends Webhook {}
|
||||||
|
export interface SaveWebhookResponse {
|
||||||
|
message: string
|
||||||
|
webhook: Webhook
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeleteWebhookResponse extends DocumentDestroyResponse {}
|
||||||
|
|
||||||
|
export interface BuildWebhookSchemaRequest extends Record<string, any> {}
|
||||||
|
export interface BuildWebhookSchemaResponse extends DocumentInsertResponse {}
|
||||||
|
|
||||||
|
export interface TriggerWebhookRequest {}
|
||||||
|
export type TriggerWebhookResponse =
|
||||||
|
| Record<string, any>
|
||||||
|
| { message: string }
|
||||||
|
| undefined
|
|
@ -1,58 +0,0 @@
|
||||||
import { DocumentDestroyResponse } from "@budibase/nano"
|
|
||||||
import {
|
|
||||||
Automation,
|
|
||||||
AutomationLogPage,
|
|
||||||
AutomationStatus,
|
|
||||||
Row,
|
|
||||||
} from "../../documents"
|
|
||||||
|
|
||||||
export interface DeleteAutomationResponse extends DocumentDestroyResponse {}
|
|
||||||
|
|
||||||
export interface FetchAutomationResponse {
|
|
||||||
automations: Automation[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface FindAutomationResponse extends Automation {}
|
|
||||||
|
|
||||||
export interface UpdateAutomationRequest extends Automation {}
|
|
||||||
export interface UpdateAutomationResponse {
|
|
||||||
message: string
|
|
||||||
automation: Automation
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CreateAutomationRequest extends Automation {}
|
|
||||||
export interface CreateAutomationResponse {
|
|
||||||
message: string
|
|
||||||
automation: Automation
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SearchAutomationLogsRequest {
|
|
||||||
startDate?: string
|
|
||||||
status?: AutomationStatus
|
|
||||||
automationId?: string
|
|
||||||
page?: string
|
|
||||||
}
|
|
||||||
export interface SearchAutomationLogsResponse extends AutomationLogPage {}
|
|
||||||
|
|
||||||
export interface ClearAutomationLogRequest {
|
|
||||||
automationId: string
|
|
||||||
appId: string
|
|
||||||
}
|
|
||||||
export interface ClearAutomationLogResponse {
|
|
||||||
message: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TriggerAutomationRequest {
|
|
||||||
fields: Record<string, any>
|
|
||||||
// time in seconds
|
|
||||||
timeout: number
|
|
||||||
}
|
|
||||||
export type TriggerAutomationResponse = Record<string, any> | undefined
|
|
||||||
|
|
||||||
export interface TestAutomationRequest {
|
|
||||||
id?: string
|
|
||||||
revision?: string
|
|
||||||
fields: Record<string, any>
|
|
||||||
row?: Row
|
|
||||||
}
|
|
||||||
export interface TestAutomationResponse {}
|
|
|
@ -1,4 +1,3 @@
|
||||||
export * from "./application"
|
|
||||||
export * from "./analytics"
|
export * from "./analytics"
|
||||||
export * from "./auth"
|
export * from "./auth"
|
||||||
export * from "./user"
|
export * from "./user"
|
||||||
|
@ -11,10 +10,7 @@ export * from "./global"
|
||||||
export * from "./pagination"
|
export * from "./pagination"
|
||||||
export * from "./searchFilter"
|
export * from "./searchFilter"
|
||||||
export * from "./cookies"
|
export * from "./cookies"
|
||||||
export * from "./automation"
|
|
||||||
export * from "./layout"
|
|
||||||
export * from "./role"
|
|
||||||
export * from "./plugins"
|
export * from "./plugins"
|
||||||
export * from "./apikeys"
|
export * from "./apikeys"
|
||||||
export * from "./deployment"
|
|
||||||
export * from "./dev"
|
export * from "./dev"
|
||||||
|
export * from "./template"
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
export enum TemplateType {
|
||||||
|
APP = "app",
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TemplateMetadata {
|
||||||
|
background: string
|
||||||
|
icon: string
|
||||||
|
category: string
|
||||||
|
description: string
|
||||||
|
name: string
|
||||||
|
url: string
|
||||||
|
type: TemplateType
|
||||||
|
key: string
|
||||||
|
image: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FetchTemplateResponse = TemplateMetadata[]
|
||||||
|
|
||||||
|
export interface DownloadTemplateResponse {
|
||||||
|
message: string
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import { BBContext } from "./koa"
|
import { Ctx } from "./koa"
|
||||||
import { Hosting } from "./hosting"
|
import { Hosting } from "./hosting"
|
||||||
|
|
||||||
export interface AuthToken {
|
export interface AuthToken {
|
||||||
|
@ -32,7 +32,7 @@ export interface ScannedSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PlatformLogoutOpts {
|
export interface PlatformLogoutOpts {
|
||||||
ctx: BBContext
|
ctx: Ctx
|
||||||
userId: string
|
userId: string
|
||||||
keepActiveSession?: boolean
|
keepActiveSession?: boolean
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue