1
0
Fork 0
mirror of synced 2024-06-11 15:04:49 +12:00
budibase/packages/server/src/api/controllers/dev.ts

130 lines
3.3 KiB
TypeScript

import fetch from "node-fetch"
import env from "../../environment"
import { checkSlashesInUrl } from "../../utilities"
import { request } from "../../utilities/workerRequests"
import { clearLock as redisClearLock } from "../../utilities/redis"
import { DocumentType } from "../../db/utils"
import { context } from "@budibase/backend-core"
import { events, db as dbCore, cache } from "@budibase/backend-core"
async function redirect(ctx: any, method: string, path: string = "global") {
const { devPath } = ctx.params
const queryString = ctx.originalUrl.split("?")[1] || ""
const response = await fetch(
checkSlashesInUrl(
`${env.WORKER_URL}/api/${path}/${devPath}?${queryString}`
),
request(ctx, {
method,
body: ctx.request.body,
})
)
if (response.status !== 200) {
const err = await response.text()
ctx.throw(400, err)
}
const cookie = response.headers.get("set-cookie")
if (cookie) {
ctx.set("set-cookie", cookie)
}
let body
try {
body = await response.json()
} catch (err) {
// don't worry about errors, likely no JSON
}
ctx.status = response.status
if (body) {
ctx.body = body
}
ctx.cookies
}
export function buildRedirectGet(path: string) {
return async (ctx: any) => {
await redirect(ctx, "GET", path)
}
}
export function buildRedirectPost(path: string) {
return async (ctx: any) => {
await redirect(ctx, "POST", path)
}
}
export function buildRedirectDelete(path: string) {
return async (ctx: any) => {
await redirect(ctx, "DELETE", path)
}
}
export async function clearLock(ctx: any) {
const { appId } = ctx.params
try {
await redisClearLock(appId, ctx.user)
} catch (err) {
ctx.throw(400, `Unable to remove lock. ${err}`)
}
ctx.body = {
message: "Lock released successfully.",
}
}
export async function revert(ctx: any) {
const { appId } = ctx.params
const productionAppId = dbCore.getProdAppID(appId)
// App must have been deployed first
try {
const db = context.getProdAppDB({ skip_setup: true })
const exists = await db.exists()
if (!exists) {
throw new Error("App must be deployed to be reverted.")
}
const deploymentDoc = await db.get(DocumentType.DEPLOYMENTS)
if (
!deploymentDoc.history ||
Object.keys(deploymentDoc.history).length === 0
) {
throw new Error("No deployments for app")
}
} catch (err) {
return ctx.throw(400, "App has not yet been deployed")
}
const replication = new dbCore.Replication({
source: productionAppId,
target: appId,
})
try {
if (env.COUCH_DB_URL) {
// in-memory db stalls on rollback
await replication.rollback()
}
// update appID in reverted app to be dev version again
const db = context.getAppDB()
const appDoc = await db.get(DocumentType.APP_METADATA)
appDoc.appId = appId
appDoc.instance._id = appId
await db.put(appDoc)
await cache.app.invalidateAppMetadata(appId)
ctx.body = {
message: "Reverted changes successfully.",
}
await events.app.reverted(appDoc)
} catch (err) {
ctx.throw(400, `Unable to revert. ${err}`)
} finally {
await replication.close()
}
}
export async function getBudibaseVersion(ctx: any) {
const version = require("../../../package.json").version
ctx.body = {
version,
}
await events.installation.versionChecked(version)
}