Typescript conversions - trying to get all of context/db layer into TS.
This commit is contained in:
parent
c63c3b48c5
commit
bc94f20794
|
@ -1,10 +1,10 @@
|
|||
const cls = require("../clshooked")
|
||||
const { newid } = require("../hashing")
|
||||
import cls from "../clshooked"
|
||||
import { newid } from "../hashing"
|
||||
|
||||
const REQUEST_ID_KEY = "requestId"
|
||||
const MAIN_CTX = cls.createNamespace("main")
|
||||
|
||||
function getContextStorage(namespace) {
|
||||
function getContextStorage(namespace: any) {
|
||||
if (namespace && namespace.active) {
|
||||
let contextData = namespace.active
|
||||
delete contextData.id
|
||||
|
@ -15,7 +15,7 @@ function getContextStorage(namespace) {
|
|||
}
|
||||
|
||||
class FunctionContext {
|
||||
static run(callback) {
|
||||
static run(callback: any) {
|
||||
return MAIN_CTX.runAndReturn(async () => {
|
||||
const namespaceId = newid()
|
||||
MAIN_CTX.set(REQUEST_ID_KEY, namespaceId)
|
||||
|
@ -26,13 +26,13 @@ class FunctionContext {
|
|||
})
|
||||
}
|
||||
|
||||
static setOnContext(key, value) {
|
||||
static setOnContext(key: string, value: any) {
|
||||
const namespaceId = MAIN_CTX.get(REQUEST_ID_KEY)
|
||||
const namespace = cls.getNamespace(namespaceId)
|
||||
namespace.set(key, value)
|
||||
}
|
||||
|
||||
static getFromContext(key) {
|
||||
static getFromContext(key: string) {
|
||||
const namespaceId = MAIN_CTX.get(REQUEST_ID_KEY)
|
||||
const namespace = cls.getNamespace(namespaceId)
|
||||
const context = getContextStorage(namespace)
|
||||
|
@ -44,4 +44,4 @@ class FunctionContext {
|
|||
}
|
||||
}
|
||||
|
||||
module.exports = FunctionContext
|
||||
export = FunctionContext
|
|
@ -1,16 +1,20 @@
|
|||
const { getGlobalUserParams, getAllApps } = require("../db/utils")
|
||||
const { doWithDB } = require("../db")
|
||||
const { doWithGlobalDB } = require("../tenancy")
|
||||
const { StaticDatabases } = require("../db/constants")
|
||||
import { getGlobalUserParams, getAllApps } from "../db/utils"
|
||||
import { doWithDB } from "../db"
|
||||
import { doWithGlobalDB } from "../tenancy"
|
||||
import { StaticDatabases } from "../db/constants"
|
||||
import { PouchLike } from "../couch"
|
||||
import { User } from "@budibase/types"
|
||||
|
||||
const TENANT_DOC = StaticDatabases.PLATFORM_INFO.docs.tenants
|
||||
const PLATFORM_INFO_DB = StaticDatabases.PLATFORM_INFO.name
|
||||
|
||||
const removeTenantFromInfoDB = async tenantId => {
|
||||
async function removeTenantFromInfoDB(tenantId: string) {
|
||||
try {
|
||||
await doWithDB(PLATFORM_INFO_DB, async infoDb => {
|
||||
await doWithDB(PLATFORM_INFO_DB, async (infoDb: PouchLike) => {
|
||||
let tenants = await infoDb.get(TENANT_DOC)
|
||||
tenants.tenantIds = tenants.tenantIds.filter(id => id !== tenantId)
|
||||
tenants.tenantIds = tenants.tenantIds.filter(
|
||||
(id: string) => id !== tenantId
|
||||
)
|
||||
|
||||
await infoDb.put(tenants)
|
||||
})
|
||||
|
@ -20,32 +24,15 @@ const removeTenantFromInfoDB = async tenantId => {
|
|||
}
|
||||
}
|
||||
|
||||
exports.removeUserFromInfoDB = async dbUser => {
|
||||
await doWithDB(PLATFORM_INFO_DB, async infoDb => {
|
||||
const keys = [dbUser._id, dbUser.email]
|
||||
const userDocs = await infoDb.allDocs({
|
||||
keys,
|
||||
include_docs: true,
|
||||
})
|
||||
const toDelete = userDocs.rows.map(row => {
|
||||
return {
|
||||
...row.doc,
|
||||
_deleted: true,
|
||||
}
|
||||
})
|
||||
await infoDb.bulkDocs(toDelete)
|
||||
})
|
||||
}
|
||||
|
||||
const removeUsersFromInfoDB = async tenantId => {
|
||||
return doWithGlobalDB(tenantId, async db => {
|
||||
async function removeUsersFromInfoDB(tenantId: string) {
|
||||
return doWithGlobalDB(tenantId, async (db: PouchLike) => {
|
||||
try {
|
||||
const allUsers = await db.allDocs(
|
||||
getGlobalUserParams(null, {
|
||||
include_docs: true,
|
||||
})
|
||||
)
|
||||
await doWithDB(PLATFORM_INFO_DB, async infoDb => {
|
||||
await doWithDB(PLATFORM_INFO_DB, async (infoDb: PouchLike) => {
|
||||
const allEmails = allUsers.rows.map(row => row.doc.email)
|
||||
// get the id docs
|
||||
let keys = allUsers.rows.map(row => row.id)
|
||||
|
@ -71,8 +58,8 @@ const removeUsersFromInfoDB = async tenantId => {
|
|||
})
|
||||
}
|
||||
|
||||
const removeGlobalDB = async tenantId => {
|
||||
return doWithGlobalDB(tenantId, async db => {
|
||||
async function removeGlobalDB(tenantId: string) {
|
||||
return doWithGlobalDB(tenantId, async (db: PouchLike) => {
|
||||
try {
|
||||
await db.destroy()
|
||||
} catch (err) {
|
||||
|
@ -82,11 +69,11 @@ const removeGlobalDB = async tenantId => {
|
|||
})
|
||||
}
|
||||
|
||||
const removeTenantApps = async tenantId => {
|
||||
async function removeTenantApps(tenantId: string) {
|
||||
try {
|
||||
const apps = await getAllApps({ all: true })
|
||||
const destroyPromises = apps.map(app =>
|
||||
doWithDB(app.appId, db => db.destroy())
|
||||
doWithDB(app.appId, (db: PouchLike) => db.destroy())
|
||||
)
|
||||
await Promise.allSettled(destroyPromises)
|
||||
} catch (err) {
|
||||
|
@ -95,8 +82,25 @@ const removeTenantApps = async tenantId => {
|
|||
}
|
||||
}
|
||||
|
||||
export async function removeUserFromInfoDB(dbUser: User) {
|
||||
await doWithDB(PLATFORM_INFO_DB, async (infoDb: PouchLike) => {
|
||||
const keys = [dbUser._id!, dbUser.email]
|
||||
const userDocs = await infoDb.allDocs({
|
||||
keys,
|
||||
include_docs: true,
|
||||
})
|
||||
const toDelete = userDocs.rows.map(row => {
|
||||
return {
|
||||
...row.doc,
|
||||
_deleted: true,
|
||||
}
|
||||
})
|
||||
await infoDb.bulkDocs(toDelete)
|
||||
})
|
||||
}
|
||||
|
||||
// can't live in tenancy package due to circular dependency on db/utils
|
||||
exports.deleteTenant = async tenantId => {
|
||||
export async function deleteTenant(tenantId: string) {
|
||||
await removeTenantFromInfoDB(tenantId)
|
||||
await removeUsersFromInfoDB(tenantId)
|
||||
await removeGlobalDB(tenantId)
|
|
@ -203,6 +203,9 @@ export function getAppDB(opts?: any): PouchLike {
|
|||
*/
|
||||
export function getProdAppDB(opts?: any): PouchLike {
|
||||
const appId = getAppId()
|
||||
if (!appId) {
|
||||
throw new Error("Unable to retrieve prod DB - no app ID.")
|
||||
}
|
||||
return new PouchLike(getProdAppID(appId), opts)
|
||||
}
|
||||
|
||||
|
@ -212,5 +215,8 @@ export function getProdAppDB(opts?: any): PouchLike {
|
|||
*/
|
||||
export function getDevAppDB(opts?: any): PouchLike {
|
||||
const appId = getAppId()
|
||||
if (!appId) {
|
||||
throw new Error("Unable to retrieve dev DB - no app ID.")
|
||||
}
|
||||
return new PouchLike(getDevelopmentAppID(appId), opts)
|
||||
}
|
||||
|
|
|
@ -1,32 +1,33 @@
|
|||
import { APP_DEV_PREFIX, APP_PREFIX } from "./constants"
|
||||
import { App } from "@budibase/types"
|
||||
const NO_APP_ERROR = "No app provided"
|
||||
const { APP_DEV_PREFIX, APP_PREFIX } = require("./constants")
|
||||
|
||||
exports.isDevAppID = appId => {
|
||||
export function isDevAppID(appId?: string) {
|
||||
if (!appId) {
|
||||
throw NO_APP_ERROR
|
||||
}
|
||||
return appId.startsWith(APP_DEV_PREFIX)
|
||||
}
|
||||
|
||||
exports.isProdAppID = appId => {
|
||||
export function isProdAppID(appId?: string) {
|
||||
if (!appId) {
|
||||
throw NO_APP_ERROR
|
||||
}
|
||||
return appId.startsWith(APP_PREFIX) && !exports.isDevAppID(appId)
|
||||
return appId.startsWith(APP_PREFIX) && !isDevAppID(appId)
|
||||
}
|
||||
|
||||
exports.isDevApp = app => {
|
||||
export function isDevApp(app: App) {
|
||||
if (!app) {
|
||||
throw NO_APP_ERROR
|
||||
}
|
||||
return exports.isDevAppID(app.appId)
|
||||
return isDevAppID(app.appId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a development app ID from a real app ID.
|
||||
* @returns {string} the dev app ID which can be used for dev database.
|
||||
*/
|
||||
exports.getDevelopmentAppID = appId => {
|
||||
export function getDevelopmentAppID(appId: string) {
|
||||
if (!appId || appId.startsWith(APP_DEV_PREFIX)) {
|
||||
return appId
|
||||
}
|
||||
|
@ -36,12 +37,12 @@ exports.getDevelopmentAppID = appId => {
|
|||
const rest = split.join(APP_PREFIX)
|
||||
return `${APP_DEV_PREFIX}${rest}`
|
||||
}
|
||||
exports.getDevAppID = exports.getDevelopmentAppID
|
||||
export const getDevAppID = getDevelopmentAppID
|
||||
|
||||
/**
|
||||
* Convert a development app ID to a deployed app ID.
|
||||
*/
|
||||
exports.getProdAppID = appId => {
|
||||
export function getProdAppID(appId: string) {
|
||||
if (!appId || !appId.startsWith(APP_DEV_PREFIX)) {
|
||||
return appId
|
||||
}
|
||||
|
@ -52,7 +53,7 @@ exports.getProdAppID = appId => {
|
|||
return `${APP_PREFIX}${rest}`
|
||||
}
|
||||
|
||||
exports.extractAppUUID = id => {
|
||||
export function extractAppUUID(id: string) {
|
||||
const split = id?.split("_") || []
|
||||
return split.length ? split[split.length - 1] : null
|
||||
}
|
|
@ -11,7 +11,7 @@ import env from "./environment"
|
|||
import tenancy from "./tenancy"
|
||||
import featureFlags from "./featureFlags"
|
||||
import * as sessions from "./security/sessions"
|
||||
import deprovisioning from "./context/deprovision"
|
||||
import * as deprovisioning from "./context/deprovision"
|
||||
import auth from "./auth"
|
||||
import constants from "./constants"
|
||||
import * as dbConstants from "./db/constants"
|
||||
|
|
|
@ -68,7 +68,7 @@ export const getGlobalUserByAppPage = (appId: string, user: User) => {
|
|||
if (!user) {
|
||||
return
|
||||
}
|
||||
return generateAppUserID(getProdAppID(appId), user._id!)
|
||||
return generateAppUserID(getProdAppID(appId)!, user._id!)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,23 +1,11 @@
|
|||
import Deployment from "./Deployment"
|
||||
import {
|
||||
getDevelopmentAppID,
|
||||
getProdAppID,
|
||||
Replication,
|
||||
} from "@budibase/backend-core/db"
|
||||
import { context, db as dbCore, events, cache } from "@budibase/backend-core"
|
||||
import { DocumentType, getAutomationParams } from "../../../db/utils"
|
||||
import {
|
||||
clearMetadata,
|
||||
disableAllCrons,
|
||||
enableCronTrigger,
|
||||
} from "../../../automations/utils"
|
||||
import { app as appCache } from "@budibase/backend-core/cache"
|
||||
import {
|
||||
getAppDB,
|
||||
getAppId,
|
||||
getDevAppDB,
|
||||
getProdAppDB,
|
||||
} from "@budibase/backend-core/context"
|
||||
import { events } from "@budibase/backend-core"
|
||||
import { backups } from "@budibase/pro"
|
||||
import { AppBackupTrigger } from "@budibase/types"
|
||||
|
||||
|
@ -49,7 +37,7 @@ async function checkAllDeployments(deployments: any) {
|
|||
|
||||
async function storeDeploymentHistory(deployment: any) {
|
||||
const deploymentJSON = deployment.getJSON()
|
||||
const db = getAppDB()
|
||||
const db = context.getAppDB()
|
||||
|
||||
let deploymentDoc
|
||||
try {
|
||||
|
@ -77,7 +65,7 @@ async function storeDeploymentHistory(deployment: any) {
|
|||
}
|
||||
|
||||
async function initDeployedApp(prodAppId: any) {
|
||||
const db = getProdAppDB()
|
||||
const db = context.getProdAppDB()
|
||||
console.log("Reading automation docs")
|
||||
const automations = (
|
||||
await db.allDocs(
|
||||
|
@ -103,9 +91,9 @@ async function initDeployedApp(prodAppId: any) {
|
|||
async function deployApp(deployment: any, userId: string) {
|
||||
let replication
|
||||
try {
|
||||
const appId = getAppId()
|
||||
const devAppId = getDevelopmentAppID(appId)
|
||||
const productionAppId = getProdAppID(appId)
|
||||
const appId = context.getAppId()!
|
||||
const devAppId = dbCore.getDevelopmentAppID(appId)
|
||||
const productionAppId = dbCore.getProdAppID(appId)
|
||||
|
||||
// don't try this if feature isn't allowed, will error
|
||||
if (await backups.isEnabled()) {
|
||||
|
@ -122,8 +110,8 @@ async function deployApp(deployment: any, userId: string) {
|
|||
source: devAppId,
|
||||
target: productionAppId,
|
||||
}
|
||||
replication = new Replication(config)
|
||||
const devDb = getDevAppDB()
|
||||
replication = new dbCore.Replication(config)
|
||||
const devDb = context.getDevAppDB()
|
||||
console.log("Compacting development DB")
|
||||
await devDb.compact()
|
||||
console.log("Replication object created")
|
||||
|
@ -131,7 +119,7 @@ async function deployApp(deployment: any, userId: string) {
|
|||
console.log("replication complete.. replacing app meta doc")
|
||||
// app metadata is excluded as it is likely to be in conflict
|
||||
// replicate the app metadata document manually
|
||||
const db = getProdAppDB()
|
||||
const db = context.getProdAppDB()
|
||||
const appDoc = await devDb.get(DocumentType.APP_METADATA)
|
||||
try {
|
||||
const prodAppDoc = await db.get(DocumentType.APP_METADATA)
|
||||
|
@ -147,7 +135,7 @@ async function deployApp(deployment: any, userId: string) {
|
|||
// remove automation errors if they exist
|
||||
delete appDoc.automationErrors
|
||||
await db.put(appDoc)
|
||||
await appCache.invalidateAppMetadata(productionAppId)
|
||||
await cache.app.invalidateAppMetadata(productionAppId)
|
||||
console.log("New app doc written successfully.")
|
||||
await initDeployedApp(productionAppId)
|
||||
console.log("Deployed app initialised, setting deployment to successful")
|
||||
|
@ -170,7 +158,7 @@ async function deployApp(deployment: any, userId: string) {
|
|||
|
||||
export async function fetchDeployments(ctx: any) {
|
||||
try {
|
||||
const db = getAppDB()
|
||||
const db = context.getAppDB()
|
||||
const deploymentDoc = await db.get(DocumentType.DEPLOYMENTS)
|
||||
const { updated, deployments } = await checkAllDeployments(deploymentDoc)
|
||||
if (updated) {
|
||||
|
@ -184,7 +172,7 @@ export async function fetchDeployments(ctx: any) {
|
|||
|
||||
export async function deploymentProgress(ctx: any) {
|
||||
try {
|
||||
const db = getAppDB()
|
||||
const db = context.getAppDB()
|
||||
const deploymentDoc = await db.get(DocumentType.DEPLOYMENTS)
|
||||
ctx.body = deploymentDoc[ctx.params.deploymentId]
|
||||
} catch (err) {
|
||||
|
@ -197,7 +185,7 @@ export async function deploymentProgress(ctx: any) {
|
|||
|
||||
const isFirstDeploy = async () => {
|
||||
try {
|
||||
const db = getProdAppDB()
|
||||
const db = context.getProdAppDB()
|
||||
await db.get(DocumentType.APP_METADATA)
|
||||
} catch (e: any) {
|
||||
if (e.status === 404) {
|
||||
|
|
|
@ -4,15 +4,9 @@ import { automationQueue } from "./bullboard"
|
|||
import newid from "../db/newid"
|
||||
import { updateEntityMetadata } from "../utilities"
|
||||
import { MetadataTypes } from "../constants"
|
||||
import { getProdAppID, doWithDB } from "@budibase/backend-core/db"
|
||||
import { db as dbCore, context } from "@budibase/backend-core"
|
||||
import { getAutomationMetadataParams } from "../db/utils"
|
||||
import { cloneDeep } from "lodash/fp"
|
||||
import {
|
||||
getAppDB,
|
||||
getAppId,
|
||||
getProdAppDB,
|
||||
} from "@budibase/backend-core/context"
|
||||
import { context } from "@budibase/backend-core"
|
||||
import { quotas } from "@budibase/pro"
|
||||
import { Automation, WebhookActionType } from "@budibase/types"
|
||||
import sdk from "../sdk"
|
||||
|
@ -102,7 +96,7 @@ export async function disableCronById(jobId: number | string) {
|
|||
}
|
||||
|
||||
export async function clearMetadata() {
|
||||
const db = getProdAppDB()
|
||||
const db = context.getProdAppDB()
|
||||
const automationMetadata = (
|
||||
await db.allDocs(
|
||||
getAutomationMetadataParams({
|
||||
|
@ -157,7 +151,7 @@ export async function enableCronTrigger(appId: any, automation: Automation) {
|
|||
// can't use getAppDB here as this is likely to be called from dev app,
|
||||
// but this call could be for dev app or prod app, need to just use what
|
||||
// was passed in
|
||||
await doWithDB(appId, async (db: any) => {
|
||||
await dbCore.doWithDB(appId, async (db: any) => {
|
||||
const response = await db.put(automation)
|
||||
automation._id = response.id
|
||||
automation._rev = response.rev
|
||||
|
@ -175,7 +169,10 @@ export async function enableCronTrigger(appId: any, automation: Automation) {
|
|||
* written to DB (this does not write to DB as it would be wasteful to repeat).
|
||||
*/
|
||||
export async function checkForWebhooks({ oldAuto, newAuto }: any) {
|
||||
const appId = getAppId()
|
||||
const appId = context.getAppId()
|
||||
if (!appId) {
|
||||
throw new Error("Unable to check webhooks - no app ID in context.")
|
||||
}
|
||||
const oldTrigger = oldAuto ? oldAuto.definition.trigger : null
|
||||
const newTrigger = newAuto ? newAuto.definition.trigger : null
|
||||
const triggerChanged =
|
||||
|
@ -194,7 +191,7 @@ export async function checkForWebhooks({ oldAuto, newAuto }: any) {
|
|||
oldTrigger.webhookId
|
||||
) {
|
||||
try {
|
||||
let db = getAppDB()
|
||||
let db = context.getAppDB()
|
||||
// need to get the webhook to get the rev
|
||||
const webhook = await db.get(oldTrigger.webhookId)
|
||||
// might be updating - reset the inputs to remove the URLs
|
||||
|
@ -224,7 +221,7 @@ export async function checkForWebhooks({ oldAuto, newAuto }: any) {
|
|||
// the app ID has to be development for this endpoint
|
||||
// it can only be used when building the app
|
||||
// but the trigger endpoint will always be used in production
|
||||
const prodAppId = getProdAppID(appId)
|
||||
const prodAppId = dbCore.getProdAppID(appId)
|
||||
newTrigger.inputs = {
|
||||
schemaUrl: `api/webhooks/schema/${appId}/${id}`,
|
||||
triggerUrl: `api/webhooks/trigger/${prodAppId}/${id}`,
|
||||
|
|
|
@ -8,7 +8,7 @@ export interface RowResponse<T> {
|
|||
key: string
|
||||
error: string
|
||||
value: RowValue
|
||||
doc?: T
|
||||
doc?: T | any
|
||||
}
|
||||
|
||||
export interface AllDocsResponse<T> {
|
||||
|
|
Loading…
Reference in New Issue