Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Final app service API typing #15120

Merged
merged 17 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/backend-core/src/middleware/auditLog.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BBContext } from "@budibase/types"
import { Ctx } from "@budibase/types"

export default async (ctx: BBContext | any, next: any) => {
export default async (ctx: Ctx, next: any) => {
// Placeholder for audit log middleware
samwho marked this conversation as resolved.
Show resolved Hide resolved
return next()
}
4 changes: 2 additions & 2 deletions packages/backend-core/src/middleware/csrf.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Header } from "../constants"
import { buildMatcherRegex, matches } from "./matchers"
import { BBContext, EndpointMatcher } from "@budibase/types"
import { Ctx, EndpointMatcher } from "@budibase/types"

/**
* GET, HEAD and OPTIONS methods are considered safe operations
Expand Down Expand Up @@ -36,7 +36,7 @@ export default function (
opts: { noCsrfPatterns: EndpointMatcher[] } = { noCsrfPatterns: [] }
) {
const noCsrfOptions = buildMatcherRegex(opts.noCsrfPatterns)
return async (ctx: BBContext | any, next: any) => {
return async (ctx: Ctx, next: any) => {
// don't apply for excluded paths
const found = matches(ctx, noCsrfOptions)
if (found) {
Expand Down
4 changes: 2 additions & 2 deletions packages/backend-core/src/middleware/internalApi.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Header } from "../constants"
import { BBContext } from "@budibase/types"
import { Ctx } from "@budibase/types"
import { isValidInternalAPIKey } from "../utils"

/**
* 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]
if (!apiKey) {
ctx.throw(403, "Unauthorized")
Expand Down
4 changes: 2 additions & 2 deletions packages/backend-core/src/middleware/matchers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BBContext, EndpointMatcher, RegexMatcher } from "@budibase/types"
import { Ctx, EndpointMatcher, RegexMatcher } from "@budibase/types"

const PARAM_REGEX = /\/:(.*?)(\/.*)?$/g

Expand Down Expand Up @@ -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 }) => {
const urlMatch = regex.test(ctx.request.url)
const methodMatch =
Expand Down
4 changes: 2 additions & 2 deletions packages/backend-core/src/middleware/passport/local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { UserStatus } from "../../constants"
import { compare } from "../../utils"
import * as users from "../../users"
import { authError } from "./utils"
import { BBContext } from "@budibase/types"
import { Ctx } from "@budibase/types"

const INVALID_ERR = "Invalid credentials"
const EXPIRED = "This account has expired. Please reset your password"
Expand All @@ -20,7 +20,7 @@ export const options = {
* @returns The authenticated user, or errors if they occur
*/
export async function authenticate(
ctx: BBContext,
ctx: Ctx,
email: string,
password: string,
done: Function
Expand Down
4 changes: 2 additions & 2 deletions packages/backend-core/src/middleware/tenancy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { getTenantIDFromCtx } from "../tenancy"
import { buildMatcherRegex, matches } from "./matchers"
import { Header } from "../constants"
import {
BBContext,
Ctx,
EndpointMatcher,
GetTenantIdOptions,
TenantResolutionStrategy,
Expand All @@ -17,7 +17,7 @@ export default function (
const allowQsOptions = buildMatcherRegex(allowQueryStringPatterns)
const noTenancyOptions = buildMatcherRegex(noTenancyPatterns)

return async function (ctx: BBContext | any, next: any) {
return async function (ctx: Ctx, next: any) {
const allowNoTenant =
opts.noTenancyRequired || !!matches(ctx, noTenancyOptions)
const tenantOpts: GetTenantIdOptions = {
Expand Down
5 changes: 4 additions & 1 deletion packages/backend-core/src/security/roles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,10 @@ export class AccessController {
)
}

async checkScreensAccess(screens: Screen[], userRoleId: string) {
async checkScreensAccess(
screens: Screen[],
userRoleId: string
): Promise<Screen[]> {
let accessibleScreens = []
// 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
Expand Down
4 changes: 2 additions & 2 deletions packages/backend-core/src/tenancy/tenancy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
getPlatformURL,
} from "../context"
import {
BBContext,
Ctx,
TenantResolutionStrategy,
GetTenantIdOptions,
} from "@budibase/types"
Expand Down Expand Up @@ -37,7 +37,7 @@ export const isUserInAppTenant = (appId: string, user?: any) => {
const ALL_STRATEGIES = Object.values(TenantResolutionStrategy)

export const getTenantIDFromCtx = (
ctx: BBContext,
ctx: Ctx,
opts: GetTenantIdOptions
): string | undefined => {
// exit early if not multi-tenant
Expand Down
8 changes: 4 additions & 4 deletions packages/backend-core/src/utils/tests/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as db from "../../db"
import { Header } from "../../constants"
import { newid } from "../../utils"
import env from "../../environment"
import { BBContext } from "@budibase/types"
import { Ctx } from "@budibase/types"

describe("utils", () => {
const config = new DBTestConfiguration()
Expand Down Expand Up @@ -109,7 +109,7 @@ describe("utils", () => {
})

describe("isServingBuilder", () => {
let ctx: BBContext
let ctx: Ctx

const expectResult = (result: boolean) =>
expect(utils.isServingBuilder(ctx)).toBe(result)
Expand All @@ -133,7 +133,7 @@ describe("utils", () => {
})

describe("isServingBuilderPreview", () => {
let ctx: BBContext
let ctx: Ctx

const expectResult = (result: boolean) =>
expect(utils.isServingBuilderPreview(ctx)).toBe(result)
Expand All @@ -157,7 +157,7 @@ describe("utils", () => {
})

describe("isPublicAPIRequest", () => {
let ctx: BBContext
let ctx: Ctx

const expectResult = (result: boolean) =>
expect(utils.isPublicApiRequest(ctx)).toBe(result)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { createMockContext, createMockCookies } from "@shopify/jest-koa-mocks"
import { BBContext } from "@budibase/types"
import { Ctx } from "@budibase/types"

export const newContext = (): BBContext => {
const ctx = createMockContext() as any
export const newContext = (): Ctx => {
const ctx = createMockContext() as Ctx
return {
...ctx,
path: "/",
Expand Down
13 changes: 9 additions & 4 deletions packages/server/src/api/controllers/screen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ import { updateAppPackage } from "./application"
import {
Plugin,
ScreenProps,
BBContext,
Screen,
UserCtx,
FetchScreenResponse,
SaveScreenRequest,
SaveScreenResponse,
DeleteScreenResponse,
} from "@budibase/types"
import { builderSocket } from "../../websockets"

export async function fetch(ctx: BBContext) {
export async function fetch(ctx: UserCtx<void, FetchScreenResponse>) {
const db = context.getAppDB()

const screens = (
Expand All @@ -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()
let screen = ctx.request.body

Expand Down Expand Up @@ -107,7 +112,7 @@ export async function save(ctx: UserCtx<Screen, Screen>) {
builderSocket?.emitScreenUpdate(ctx, savedScreen)
}

export async function destroy(ctx: BBContext) {
export async function destroy(ctx: UserCtx<void, DeleteScreenResponse>) {
const db = context.getAppDB()
const id = ctx.params.screenId
const screen = await db.get<Screen>(id)
Expand Down
4 changes: 0 additions & 4 deletions packages/server/src/api/controllers/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,3 @@ export async function execute(ctx: Ctx) {
throw err
}
}

export async function save(ctx: Ctx) {
ctx.throw(501, "Not currently implemented")
}
28 changes: 21 additions & 7 deletions packages/server/src/api/controllers/static/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,13 @@ import {
Ctx,
DocumentType,
Feature,
GetSignedUploadUrlRequest,
GetSignedUploadUrlResponse,
ProcessAttachmentResponse,
ServeAppResponse,
ServeBuilderPreviewResponse,
ServeClientLibraryResponse,
ToggleBetaFeatureResponse,
UserCtx,
} from "@budibase/types"
import {
Expand All @@ -38,7 +44,9 @@ import {
import send from "koa-send"
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}`

if (ctx.cookies.get(cookieName)) {
Expand Down Expand Up @@ -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")
await send(ctx, ctx.file, { root: builderPath })
}

export const uploadFile = async function (
ctx: Ctx<{}, ProcessAttachmentResponse>
ctx: Ctx<void, ProcessAttachmentResponse>
) {
const file = ctx.request?.files?.file
if (!file) {
Expand Down Expand Up @@ -144,7 +152,7 @@ const requiresMigration = async (ctx: Ctx) => {
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")) {
ctx.redirect("/builder/bblogo.png")
return
Expand Down Expand Up @@ -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 appInfo = await db.get<App>(DocumentType.APP_METADATA)

Expand All @@ -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

if (Array.isArray(version)) {
Expand Down Expand Up @@ -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
let datasource
try {
Expand Down
15 changes: 9 additions & 6 deletions packages/server/src/api/controllers/table/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,18 @@ import {
EventType,
FetchTablesResponse,
FieldType,
MigrateRequest,
MigrateResponse,
MigrateTableRequest,
MigrateTableResponse,
SaveTableRequest,
SaveTableResponse,
Table,
TableResponse,
FindTableResponse,
TableSourceType,
UserCtx,
ValidateNewTableImportRequest,
ValidateTableImportRequest,
ValidateTableImportResponse,
DeleteTableResponse,
} from "@budibase/types"
import sdk from "../../../sdk"
import { jsonFromCsvString } from "../../../utilities/csv"
Expand Down Expand Up @@ -94,7 +95,7 @@ export async function fetch(ctx: UserCtx<void, FetchTablesResponse>) {
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 table = await sdk.tables.getTable(tableId)

Expand Down Expand Up @@ -137,7 +138,7 @@ export async function save(ctx: UserCtx<SaveTableRequest, SaveTableResponse>) {
builderSocket?.emitTableUpdate(ctx, cloneDeep(savedTable))
}

export async function destroy(ctx: UserCtx) {
export async function destroy(ctx: UserCtx<void, DeleteTableResponse>) {
const appId = ctx.appId
const tableId = ctx.params.tableId
await sdk.rowActions.deleteAll(tableId)
Expand Down Expand Up @@ -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
let tableId = ctx.params.tableId as string
const table = await sdk.tables.getTable(tableId)
Expand Down
12 changes: 9 additions & 3 deletions packages/server/src/api/controllers/templates.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import nodeFetch from "node-fetch"
import { downloadTemplate as dlTemplate } from "../../utilities/fileSystem"
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
const DEFAULT_TEMPLATES_BUCKET =
"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 response,
error = false
Expand All @@ -32,7 +36,9 @@ export async function fetch(ctx: BBContext) {

// can't currently test this, have to ignore from coverage
/* istanbul ignore next */
export async function downloadTemplate(ctx: BBContext) {
export async function downloadTemplate(
ctx: UserCtx<void, DownloadTemplateResponse>
) {
const { type, name } = ctx.params

await dlTemplate(type, name)
Expand Down
Loading
Loading