Merge pull request #15100 from Budibase/chore/api-typing
API typing - app service A -> D
This commit is contained in:
commit
10cf58e9a1
|
@ -1,16 +1,22 @@
|
|||
import { events, context } from "@budibase/backend-core"
|
||||
import { AnalyticsPingRequest, App, PingSource } from "@budibase/types"
|
||||
import {
|
||||
AnalyticsPingRequest,
|
||||
App,
|
||||
PingSource,
|
||||
Ctx,
|
||||
AnalyticsEnabledResponse,
|
||||
} from "@budibase/types"
|
||||
import { DocumentType, isDevAppID } from "../../db/utils"
|
||||
|
||||
export const isEnabled = async (ctx: any) => {
|
||||
export const isEnabled = async (ctx: Ctx<void, AnalyticsEnabledResponse>) => {
|
||||
const enabled = await events.analytics.enabled()
|
||||
ctx.body = {
|
||||
enabled,
|
||||
}
|
||||
}
|
||||
|
||||
export const ping = async (ctx: any) => {
|
||||
const body = ctx.request.body as AnalyticsPingRequest
|
||||
export const ping = async (ctx: Ctx<AnalyticsPingRequest, void>) => {
|
||||
const body = ctx.request.body
|
||||
|
||||
switch (body.source) {
|
||||
case PingSource.APP: {
|
||||
|
|
|
@ -1,18 +1,25 @@
|
|||
import { db as dbCore, tenancy } from "@budibase/backend-core"
|
||||
import { BBContext, Document } from "@budibase/types"
|
||||
import {
|
||||
Document,
|
||||
UserCtx,
|
||||
ApiKeyDoc,
|
||||
ApiKeyFetchResponse,
|
||||
UpdateApiKeyRequest,
|
||||
UpdateApiKeyResponse,
|
||||
} from "@budibase/types"
|
||||
|
||||
const KEYS_DOC = dbCore.StaticDatabases.GLOBAL.docs.apiKeys
|
||||
|
||||
async function getBuilderMainDoc() {
|
||||
const db = tenancy.getGlobalDB()
|
||||
try {
|
||||
return await db.get<any>(KEYS_DOC)
|
||||
} catch (err) {
|
||||
// doesn't exist yet, nothing to get
|
||||
const doc = await db.tryGet<ApiKeyDoc>(KEYS_DOC)
|
||||
if (!doc) {
|
||||
return {
|
||||
_id: KEYS_DOC,
|
||||
apiKeys: {},
|
||||
}
|
||||
}
|
||||
return doc
|
||||
}
|
||||
|
||||
async function setBuilderMainDoc(doc: Document) {
|
||||
|
@ -22,7 +29,7 @@ async function setBuilderMainDoc(doc: Document) {
|
|||
return db.put(doc)
|
||||
}
|
||||
|
||||
export async function fetch(ctx: BBContext) {
|
||||
export async function fetch(ctx: UserCtx<void, ApiKeyFetchResponse>) {
|
||||
try {
|
||||
const mainDoc = await getBuilderMainDoc()
|
||||
ctx.body = mainDoc.apiKeys ? mainDoc.apiKeys : {}
|
||||
|
@ -32,7 +39,9 @@ export async function fetch(ctx: BBContext) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function update(ctx: BBContext) {
|
||||
export async function update(
|
||||
ctx: UserCtx<UpdateApiKeyRequest, UpdateApiKeyResponse>
|
||||
) {
|
||||
const key = ctx.params.key
|
||||
const value = ctx.request.body.value
|
||||
|
||||
|
|
|
@ -59,6 +59,15 @@ import {
|
|||
BBReferenceFieldSubType,
|
||||
Row,
|
||||
BBRequest,
|
||||
SyncAppResponse,
|
||||
CreateAppResponse,
|
||||
FetchAppsResponse,
|
||||
UpdateAppClientResponse,
|
||||
RevertAppClientResponse,
|
||||
DeleteAppResponse,
|
||||
ImportToUpdateAppRequest,
|
||||
ImportToUpdateAppResponse,
|
||||
SetRevertableAppVersionRequest,
|
||||
} from "@budibase/types"
|
||||
import { BASE_LAYOUT_PROP_IDS } from "../../constants/layouts"
|
||||
import sdk from "../../sdk"
|
||||
|
@ -166,7 +175,7 @@ async function createInstance(appId: string, template: AppTemplate) {
|
|||
return { _id: appId }
|
||||
}
|
||||
|
||||
export const addSampleData = async (ctx: UserCtx) => {
|
||||
export const addSampleData = async (ctx: UserCtx<void, void>) => {
|
||||
const db = context.getAppDB()
|
||||
|
||||
try {
|
||||
|
@ -182,7 +191,7 @@ export const addSampleData = async (ctx: UserCtx) => {
|
|||
ctx.status = 200
|
||||
}
|
||||
|
||||
export async function fetch(ctx: UserCtx<void, App[]>) {
|
||||
export async function fetch(ctx: UserCtx<void, FetchAppsResponse>) {
|
||||
ctx.body = await sdk.applications.fetch(
|
||||
ctx.query.status as AppStatus,
|
||||
ctx.user
|
||||
|
@ -242,7 +251,9 @@ export async function fetchAppPackage(
|
|||
}
|
||||
}
|
||||
|
||||
async function performAppCreate(ctx: UserCtx<CreateAppRequest, App>) {
|
||||
async function performAppCreate(
|
||||
ctx: UserCtx<CreateAppRequest, CreateAppResponse>
|
||||
) {
|
||||
const apps = (await dbCore.getAllApps({ dev: true })) as App[]
|
||||
const { body } = ctx.request
|
||||
const { name, url, encryptionPassword, templateKey } = body
|
||||
|
@ -510,7 +521,9 @@ async function appPostCreate(ctx: UserCtx<CreateAppRequest, App>, app: App) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function create(ctx: UserCtx<CreateAppRequest, App>) {
|
||||
export async function create(
|
||||
ctx: UserCtx<CreateAppRequest, CreateAppResponse>
|
||||
) {
|
||||
const newApplication = await quotas.addApp(() => performAppCreate(ctx))
|
||||
await appPostCreate(ctx, newApplication)
|
||||
await cache.bustCache(cache.CacheKey.CHECKLIST)
|
||||
|
@ -553,7 +566,9 @@ export async function update(
|
|||
})
|
||||
}
|
||||
|
||||
export async function updateClient(ctx: UserCtx) {
|
||||
export async function updateClient(
|
||||
ctx: UserCtx<void, UpdateAppClientResponse>
|
||||
) {
|
||||
// Get current app version
|
||||
const application = await sdk.applications.metadata.get()
|
||||
const currentVersion = application.version
|
||||
|
@ -581,7 +596,9 @@ export async function updateClient(ctx: UserCtx) {
|
|||
ctx.body = app
|
||||
}
|
||||
|
||||
export async function revertClient(ctx: UserCtx) {
|
||||
export async function revertClient(
|
||||
ctx: UserCtx<void, RevertAppClientResponse>
|
||||
) {
|
||||
// Check app can be reverted
|
||||
const application = await sdk.applications.metadata.get()
|
||||
if (!application.revertableVersion) {
|
||||
|
@ -668,7 +685,7 @@ async function postDestroyApp(ctx: UserCtx) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function destroy(ctx: UserCtx) {
|
||||
export async function destroy(ctx: UserCtx<void, DeleteAppResponse>) {
|
||||
await preDestroyApp(ctx)
|
||||
const result = await destroyApp(ctx)
|
||||
await postDestroyApp(ctx)
|
||||
|
@ -676,7 +693,7 @@ export async function destroy(ctx: UserCtx) {
|
|||
ctx.body = result
|
||||
}
|
||||
|
||||
export async function unpublish(ctx: UserCtx) {
|
||||
export async function unpublish(ctx: UserCtx<void, void>) {
|
||||
const prodAppId = dbCore.getProdAppID(ctx.params.appId)
|
||||
const dbExists = await dbCore.dbExists(prodAppId)
|
||||
|
||||
|
@ -692,7 +709,7 @@ export async function unpublish(ctx: UserCtx) {
|
|||
builderSocket?.emitAppUnpublish(ctx)
|
||||
}
|
||||
|
||||
export async function sync(ctx: UserCtx) {
|
||||
export async function sync(ctx: UserCtx<void, SyncAppResponse>) {
|
||||
const appId = ctx.params.appId
|
||||
try {
|
||||
ctx.body = await sdk.applications.syncApp(appId)
|
||||
|
@ -701,10 +718,12 @@ export async function sync(ctx: UserCtx) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function importToApp(ctx: UserCtx) {
|
||||
export async function importToApp(
|
||||
ctx: UserCtx<ImportToUpdateAppRequest, ImportToUpdateAppResponse>
|
||||
) {
|
||||
const { appId } = ctx.params
|
||||
const appExport = ctx.request.files?.appExport
|
||||
const password = ctx.request.body.encryptionPassword as string
|
||||
const password = ctx.request.body.encryptionPassword
|
||||
if (!appExport) {
|
||||
ctx.throw(400, "Must supply app export to import")
|
||||
}
|
||||
|
@ -811,7 +830,7 @@ export async function updateAppPackage(
|
|||
}
|
||||
|
||||
export async function setRevertableVersion(
|
||||
ctx: UserCtx<{ revertableVersion: string }, App>
|
||||
ctx: UserCtx<SetRevertableAppVersionRequest, void>
|
||||
) {
|
||||
if (!env.isDev()) {
|
||||
ctx.status = 403
|
||||
|
|
|
@ -2,7 +2,7 @@ import { outputProcessing } from "../../utilities/rowProcessor"
|
|||
import { InternalTables } from "../../db/utils"
|
||||
import { getFullUser } from "../../utilities/users"
|
||||
import { roles, context, db as dbCore } from "@budibase/backend-core"
|
||||
import { ContextUser, Row, UserCtx } from "@budibase/types"
|
||||
import { AppSelfResponse, ContextUser, UserCtx } from "@budibase/types"
|
||||
import sdk from "../../sdk"
|
||||
import { processUser } from "../../utilities/global"
|
||||
|
||||
|
@ -17,7 +17,7 @@ const addSessionAttributesToUser = (ctx: any) => {
|
|||
}
|
||||
}
|
||||
|
||||
export async function fetchSelf(ctx: UserCtx) {
|
||||
export async function fetchSelf(ctx: UserCtx<void, AppSelfResponse>) {
|
||||
let userId = ctx.user.userId || ctx.user._id
|
||||
/* istanbul ignore next */
|
||||
if (!userId || !ctx.isAuthenticated) {
|
||||
|
@ -45,9 +45,9 @@ export async function fetchSelf(ctx: UserCtx) {
|
|||
try {
|
||||
const userTable = await sdk.tables.getTable(InternalTables.USER_METADATA)
|
||||
// specifically needs to make sure is enriched
|
||||
ctx.body = await outputProcessing(userTable, user as Row)
|
||||
ctx.body = await outputProcessing(userTable, user)
|
||||
} catch (err: any) {
|
||||
let response
|
||||
let response: ContextUser | {}
|
||||
// user didn't exist in app, don't pretend they do
|
||||
if (user.roleId === PUBLIC_ROLE) {
|
||||
response = {}
|
||||
|
|
|
@ -9,10 +9,25 @@ import {
|
|||
App,
|
||||
Automation,
|
||||
AutomationActionStepId,
|
||||
AutomationResults,
|
||||
UserCtx,
|
||||
DeleteAutomationResponse,
|
||||
FetchAutomationResponse,
|
||||
GetAutomationTriggerDefinitionsResponse,
|
||||
GetAutomationStepDefinitionsResponse,
|
||||
GetAutomationActionDefinitionsResponse,
|
||||
FindAutomationResponse,
|
||||
UpdateAutomationRequest,
|
||||
UpdateAutomationResponse,
|
||||
CreateAutomationRequest,
|
||||
CreateAutomationResponse,
|
||||
SearchAutomationLogsRequest,
|
||||
SearchAutomationLogsResponse,
|
||||
ClearAutomationLogRequest,
|
||||
ClearAutomationLogResponse,
|
||||
TriggerAutomationRequest,
|
||||
TriggerAutomationResponse,
|
||||
TestAutomationRequest,
|
||||
TestAutomationResponse,
|
||||
} from "@budibase/types"
|
||||
import { getActionDefinitions as actionDefs } from "../../automations/actions"
|
||||
import sdk from "../../sdk"
|
||||
|
@ -34,7 +49,7 @@ function getTriggerDefinitions() {
|
|||
*************************/
|
||||
|
||||
export async function create(
|
||||
ctx: UserCtx<Automation, { message: string; automation: Automation }>
|
||||
ctx: UserCtx<CreateAutomationRequest, CreateAutomationResponse>
|
||||
) {
|
||||
let automation = ctx.request.body
|
||||
automation.appId = ctx.appId
|
||||
|
@ -55,7 +70,9 @@ export async function create(
|
|||
builderSocket?.emitAutomationUpdate(ctx, automation)
|
||||
}
|
||||
|
||||
export async function update(ctx: UserCtx) {
|
||||
export async function update(
|
||||
ctx: UserCtx<UpdateAutomationRequest, UpdateAutomationResponse>
|
||||
) {
|
||||
let automation = ctx.request.body
|
||||
automation.appId = ctx.appId
|
||||
|
||||
|
@ -80,7 +97,7 @@ export async function fetch(ctx: UserCtx<void, FetchAutomationResponse>) {
|
|||
ctx.body = { automations }
|
||||
}
|
||||
|
||||
export async function find(ctx: UserCtx) {
|
||||
export async function find(ctx: UserCtx<void, FindAutomationResponse>) {
|
||||
ctx.body = await sdk.automations.get(ctx.params.id)
|
||||
}
|
||||
|
||||
|
@ -96,11 +113,15 @@ export async function destroy(ctx: UserCtx<void, DeleteAutomationResponse>) {
|
|||
builderSocket?.emitAutomationDeletion(ctx, automationId)
|
||||
}
|
||||
|
||||
export async function logSearch(ctx: UserCtx) {
|
||||
export async function logSearch(
|
||||
ctx: UserCtx<SearchAutomationLogsRequest, SearchAutomationLogsResponse>
|
||||
) {
|
||||
ctx.body = await automations.logs.logSearch(ctx.request.body)
|
||||
}
|
||||
|
||||
export async function clearLogError(ctx: UserCtx) {
|
||||
export async function clearLogError(
|
||||
ctx: UserCtx<ClearAutomationLogRequest, ClearAutomationLogResponse>
|
||||
) {
|
||||
const { automationId, appId } = ctx.request.body
|
||||
await context.doInAppContext(appId, async () => {
|
||||
const db = context.getProdAppDB()
|
||||
|
@ -119,15 +140,21 @@ export async function clearLogError(ctx: UserCtx) {
|
|||
})
|
||||
}
|
||||
|
||||
export async function getActionList(ctx: UserCtx) {
|
||||
export async function getActionList(
|
||||
ctx: UserCtx<void, GetAutomationActionDefinitionsResponse>
|
||||
) {
|
||||
ctx.body = await getActionDefinitions()
|
||||
}
|
||||
|
||||
export async function getTriggerList(ctx: UserCtx) {
|
||||
export async function getTriggerList(
|
||||
ctx: UserCtx<void, GetAutomationTriggerDefinitionsResponse>
|
||||
) {
|
||||
ctx.body = getTriggerDefinitions()
|
||||
}
|
||||
|
||||
export async function getDefinitionList(ctx: UserCtx) {
|
||||
export async function getDefinitionList(
|
||||
ctx: UserCtx<void, GetAutomationStepDefinitionsResponse>
|
||||
) {
|
||||
ctx.body = {
|
||||
trigger: getTriggerDefinitions(),
|
||||
action: await getActionDefinitions(),
|
||||
|
@ -140,14 +167,16 @@ export async function getDefinitionList(ctx: UserCtx) {
|
|||
* *
|
||||
*********************/
|
||||
|
||||
export async function trigger(ctx: UserCtx) {
|
||||
export async function trigger(
|
||||
ctx: UserCtx<TriggerAutomationRequest, TriggerAutomationResponse>
|
||||
) {
|
||||
const db = context.getAppDB()
|
||||
let automation = await db.get<Automation>(ctx.params.id)
|
||||
|
||||
let hasCollectStep = sdk.automations.utils.checkForCollectStep(automation)
|
||||
if (hasCollectStep && (await features.isSyncAutomationsEnabled())) {
|
||||
try {
|
||||
const response: AutomationResults = await triggers.externalTrigger(
|
||||
const response = await triggers.externalTrigger(
|
||||
automation,
|
||||
{
|
||||
fields: ctx.request.body.fields,
|
||||
|
@ -158,6 +187,10 @@ export async function trigger(ctx: UserCtx) {
|
|||
{ getResponses: true }
|
||||
)
|
||||
|
||||
if (!("steps" in response)) {
|
||||
ctx.throw(400, "Unable to collect response")
|
||||
}
|
||||
|
||||
let collectedValue = response.steps.find(
|
||||
step => step.stepId === AutomationActionStepId.COLLECT
|
||||
)
|
||||
|
@ -185,7 +218,7 @@ export async function trigger(ctx: UserCtx) {
|
|||
}
|
||||
}
|
||||
|
||||
function prepareTestInput(input: any) {
|
||||
function prepareTestInput(input: TestAutomationRequest) {
|
||||
// prepare the test parameters
|
||||
if (input.id && input.row) {
|
||||
input.row._id = input.id
|
||||
|
@ -196,7 +229,9 @@ function prepareTestInput(input: any) {
|
|||
return input
|
||||
}
|
||||
|
||||
export async function test(ctx: UserCtx) {
|
||||
export async function test(
|
||||
ctx: UserCtx<TestAutomationRequest, TestAutomationResponse>
|
||||
) {
|
||||
const db = context.getAppDB()
|
||||
let automation = await db.get<Automation>(ctx.params.id)
|
||||
await setTestFlag(automation._id!)
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
import sdk from "../../sdk"
|
||||
import { events, context, db } from "@budibase/backend-core"
|
||||
import { DocumentType } from "../../db/utils"
|
||||
import { App, Ctx } from "@budibase/types"
|
||||
import {
|
||||
App,
|
||||
Ctx,
|
||||
ExportAppDumpRequest,
|
||||
ExportAppDumpResponse,
|
||||
} from "@budibase/types"
|
||||
|
||||
interface ExportAppDumpRequest {
|
||||
excludeRows: boolean
|
||||
encryptPassword?: string
|
||||
}
|
||||
|
||||
export async function exportAppDump(ctx: Ctx<ExportAppDumpRequest>) {
|
||||
export async function exportAppDump(
|
||||
ctx: Ctx<ExportAppDumpRequest, ExportAppDumpResponse>
|
||||
) {
|
||||
const { appId } = ctx.query as any
|
||||
const { excludeRows, encryptPassword } = ctx.request.body
|
||||
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
import { DocumentType } from "../../db/utils"
|
||||
import { App, Plugin, UserCtx } from "@budibase/types"
|
||||
import {
|
||||
App,
|
||||
FetchComponentDefinitionResponse,
|
||||
Plugin,
|
||||
UserCtx,
|
||||
} from "@budibase/types"
|
||||
import { db as dbCore, context, tenancy } from "@budibase/backend-core"
|
||||
import { getComponentLibraryManifest } from "../../utilities/fileSystem"
|
||||
|
||||
export async function fetchAppComponentDefinitions(ctx: UserCtx) {
|
||||
export async function fetchAppComponentDefinitions(
|
||||
ctx: UserCtx<void, FetchComponentDefinitionResponse>
|
||||
) {
|
||||
try {
|
||||
const db = context.getAppDB()
|
||||
const app = await db.get<App>(DocumentType.APP_METADATA)
|
||||
|
|
|
@ -23,13 +23,17 @@ import {
|
|||
Table,
|
||||
RowValue,
|
||||
DynamicVariable,
|
||||
FetchDatasourcesResponse,
|
||||
FindDatasourcesResponse,
|
||||
DeleteDatasourceResponse,
|
||||
FetchExternalSchemaResponse,
|
||||
} from "@budibase/types"
|
||||
import sdk from "../../sdk"
|
||||
import { builderSocket } from "../../websockets"
|
||||
import { isEqual } from "lodash"
|
||||
import { processTable } from "../../sdk/app/tables/getters"
|
||||
|
||||
export async function fetch(ctx: UserCtx) {
|
||||
export async function fetch(ctx: UserCtx<void, FetchDatasourcesResponse>) {
|
||||
ctx.body = await sdk.datasources.fetch()
|
||||
}
|
||||
|
||||
|
@ -260,7 +264,7 @@ async function destroyInternalTablesBySourceId(datasourceId: string) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function destroy(ctx: UserCtx) {
|
||||
export async function destroy(ctx: UserCtx<void, DeleteDatasourceResponse>) {
|
||||
const db = context.getAppDB()
|
||||
const datasourceId = ctx.params.datasourceId
|
||||
|
||||
|
@ -291,12 +295,14 @@ export async function destroy(ctx: UserCtx) {
|
|||
builderSocket?.emitDatasourceDeletion(ctx, datasourceId)
|
||||
}
|
||||
|
||||
export async function find(ctx: UserCtx) {
|
||||
export async function find(ctx: UserCtx<void, FindDatasourcesResponse>) {
|
||||
const datasource = await sdk.datasources.get(ctx.params.datasourceId)
|
||||
ctx.body = await sdk.datasources.removeSecretSingle(datasource)
|
||||
}
|
||||
|
||||
export async function getExternalSchema(ctx: UserCtx) {
|
||||
export async function getExternalSchema(
|
||||
ctx: UserCtx<void, FetchExternalSchemaResponse>
|
||||
) {
|
||||
const datasource = await sdk.datasources.get(ctx.params.datasourceId)
|
||||
const enrichedDatasource = await sdk.datasources.getAndMergeDatasource(
|
||||
datasource
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { context, utils } from "@budibase/backend-core"
|
||||
import { DeploymentStatus } from "@budibase/types"
|
||||
|
||||
/**
|
||||
* This is used to pass around information about the deployment that is occurring
|
||||
|
@ -6,7 +7,7 @@ import { context, utils } from "@budibase/backend-core"
|
|||
export default class Deployment {
|
||||
_id: string
|
||||
verification: any
|
||||
status?: string
|
||||
status?: DeploymentStatus
|
||||
err?: any
|
||||
appUrl?: string
|
||||
|
||||
|
@ -25,7 +26,7 @@ export default class Deployment {
|
|||
return this.verification
|
||||
}
|
||||
|
||||
setStatus(status: string, err?: any) {
|
||||
setStatus(status: DeploymentStatus, err?: any) {
|
||||
this.status = status
|
||||
if (err) {
|
||||
this.err = err
|
||||
|
|
|
@ -7,20 +7,26 @@ import {
|
|||
enableCronTrigger,
|
||||
} from "../../../automations/utils"
|
||||
import { backups } from "@budibase/pro"
|
||||
import { App, AppBackupTrigger } from "@budibase/types"
|
||||
import {
|
||||
App,
|
||||
AppBackupTrigger,
|
||||
DeploymentDoc,
|
||||
FetchDeploymentResponse,
|
||||
PublishAppResponse,
|
||||
UserCtx,
|
||||
DeploymentStatus,
|
||||
DeploymentProgressResponse,
|
||||
} from "@budibase/types"
|
||||
import sdk from "../../../sdk"
|
||||
import { builderSocket } from "../../../websockets"
|
||||
|
||||
// the max time we can wait for an invalidation to complete before considering it failed
|
||||
const MAX_PENDING_TIME_MS = 30 * 60000
|
||||
const DeploymentStatus = {
|
||||
SUCCESS: "SUCCESS",
|
||||
PENDING: "PENDING",
|
||||
FAILURE: "FAILURE",
|
||||
}
|
||||
|
||||
// checks that deployments are in a good state, any pending will be updated
|
||||
async function checkAllDeployments(deployments: any) {
|
||||
async function checkAllDeployments(
|
||||
deployments: any
|
||||
): Promise<{ updated: boolean; deployments: DeploymentDoc }> {
|
||||
let updated = false
|
||||
let deployment: any
|
||||
for (deployment of Object.values(deployments.history)) {
|
||||
|
@ -96,7 +102,9 @@ async function initDeployedApp(prodAppId: any) {
|
|||
})
|
||||
}
|
||||
|
||||
export async function fetchDeployments(ctx: any) {
|
||||
export async function fetchDeployments(
|
||||
ctx: UserCtx<void, FetchDeploymentResponse>
|
||||
) {
|
||||
try {
|
||||
const db = context.getAppDB()
|
||||
const deploymentDoc = await db.get(DocumentType.DEPLOYMENTS)
|
||||
|
@ -104,17 +112,24 @@ export async function fetchDeployments(ctx: any) {
|
|||
if (updated) {
|
||||
await db.put(deployments)
|
||||
}
|
||||
ctx.body = Object.values(deployments.history).reverse()
|
||||
ctx.body = deployments.history
|
||||
? Object.values(deployments.history).reverse()
|
||||
: []
|
||||
} catch (err) {
|
||||
ctx.body = []
|
||||
}
|
||||
}
|
||||
|
||||
export async function deploymentProgress(ctx: any) {
|
||||
export async function deploymentProgress(
|
||||
ctx: UserCtx<void, DeploymentProgressResponse>
|
||||
) {
|
||||
try {
|
||||
const db = context.getAppDB()
|
||||
const deploymentDoc = await db.get<any>(DocumentType.DEPLOYMENTS)
|
||||
ctx.body = deploymentDoc[ctx.params.deploymentId]
|
||||
const deploymentDoc = await db.get<DeploymentDoc>(DocumentType.DEPLOYMENTS)
|
||||
if (!deploymentDoc.history?.[ctx.params.deploymentId]) {
|
||||
ctx.throw(404, "No deployment found")
|
||||
}
|
||||
ctx.body = deploymentDoc.history?.[ctx.params.deploymentId]
|
||||
} catch (err) {
|
||||
ctx.throw(
|
||||
500,
|
||||
|
@ -123,7 +138,9 @@ export async function deploymentProgress(ctx: any) {
|
|||
}
|
||||
}
|
||||
|
||||
export const publishApp = async function (ctx: any) {
|
||||
export const publishApp = async function (
|
||||
ctx: UserCtx<void, PublishAppResponse>
|
||||
) {
|
||||
let deployment = new Deployment()
|
||||
console.log("Deployment object created")
|
||||
deployment.setStatus(DeploymentStatus.PENDING)
|
||||
|
|
|
@ -11,7 +11,13 @@ import {
|
|||
db as dbCore,
|
||||
cache,
|
||||
} from "@budibase/backend-core"
|
||||
import { App } from "@budibase/types"
|
||||
import {
|
||||
App,
|
||||
ClearDevLockResponse,
|
||||
Ctx,
|
||||
GetVersionResponse,
|
||||
RevertAppResponse,
|
||||
} from "@budibase/types"
|
||||
|
||||
async function redirect(
|
||||
ctx: any,
|
||||
|
@ -69,7 +75,7 @@ export function buildRedirectDelete(path: string) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function clearLock(ctx: any) {
|
||||
export async function clearLock(ctx: Ctx<void, ClearDevLockResponse>) {
|
||||
const { appId } = ctx.params
|
||||
try {
|
||||
await redisClearLock(appId, ctx.user)
|
||||
|
@ -81,7 +87,7 @@ export async function clearLock(ctx: any) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function revert(ctx: any) {
|
||||
export async function revert(ctx: Ctx<void, RevertAppResponse>) {
|
||||
const { appId } = ctx.params
|
||||
const productionAppId = dbCore.getProdAppID(appId)
|
||||
|
||||
|
@ -131,7 +137,7 @@ export async function revert(ctx: any) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function getBudibaseVersion(ctx: any) {
|
||||
export async function getBudibaseVersion(ctx: Ctx<void, GetVersionResponse>) {
|
||||
const version = envCore.VERSION
|
||||
ctx.body = {
|
||||
version,
|
||||
|
|
|
@ -94,12 +94,16 @@ export async function trigger(ctx: BBContext) {
|
|||
{ getResponses: true }
|
||||
)
|
||||
|
||||
let collectedValue = response.steps.find(
|
||||
(step: any) => step.stepId === AutomationActionStepId.COLLECT
|
||||
)
|
||||
if (triggers.isAutomationResults(response)) {
|
||||
let collectedValue = response.steps.find(
|
||||
(step: any) => step.stepId === AutomationActionStepId.COLLECT
|
||||
)
|
||||
|
||||
ctx.status = 200
|
||||
ctx.body = collectedValue.outputs
|
||||
ctx.status = 200
|
||||
ctx.body = collectedValue?.outputs
|
||||
} else {
|
||||
ctx.throw(400, "Automation did not have a collect block.")
|
||||
}
|
||||
} else {
|
||||
await triggers.externalTrigger(target, {
|
||||
body: ctx.request.body,
|
||||
|
|
|
@ -102,7 +102,9 @@ if (env.SELF_HOSTED) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function getActionDefinitions() {
|
||||
export async function getActionDefinitions(): Promise<
|
||||
Record<keyof typeof AutomationActionStepId, AutomationStepDefinition>
|
||||
> {
|
||||
if (await features.flags.isEnabled(FeatureFlag.AUTOMATION_BRANCHING)) {
|
||||
BUILTIN_ACTION_DEFINITIONS["BRANCH"] = branch.definition
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ import {
|
|||
AutomationStepDefinition,
|
||||
AutomationStepType,
|
||||
AutomationIOType,
|
||||
AutomationResults,
|
||||
Automation,
|
||||
AutomationCustomIOType,
|
||||
TriggerAutomationStepInputs,
|
||||
|
@ -78,7 +77,7 @@ export async function run({
|
|||
const db = context.getAppDB()
|
||||
let automation = await db.get<Automation>(inputs.automation.automationId)
|
||||
|
||||
const response: AutomationResults = await triggers.externalTrigger(
|
||||
const response = await triggers.externalTrigger(
|
||||
automation,
|
||||
{
|
||||
fields: { ...fieldParams },
|
||||
|
@ -88,9 +87,13 @@ export async function run({
|
|||
{ getResponses: true }
|
||||
)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
value: response.steps,
|
||||
if (triggers.isAutomationResults(response)) {
|
||||
return {
|
||||
success: true,
|
||||
value: response.steps,
|
||||
}
|
||||
} else {
|
||||
throw new Error("Automation did not have a collect block")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -3,7 +3,7 @@ import * as triggers from "../triggers"
|
|||
import { loopAutomation } from "../../tests/utilities/structures"
|
||||
import { context } from "@budibase/backend-core"
|
||||
import * as setup from "./utilities"
|
||||
import { Table, LoopStepType } from "@budibase/types"
|
||||
import { Table, LoopStepType, AutomationResults } from "@budibase/types"
|
||||
import * as loopUtils from "../loopUtils"
|
||||
import { LoopInput } from "../../definitions/automations"
|
||||
|
||||
|
@ -20,15 +20,19 @@ describe("Attempt to run a basic loop automation", () => {
|
|||
|
||||
afterAll(setup.afterAll)
|
||||
|
||||
async function runLoop(loopOpts?: LoopInput) {
|
||||
async function runLoop(loopOpts?: LoopInput): Promise<AutomationResults> {
|
||||
const appId = config.getAppId()
|
||||
return await context.doInAppContext(appId, async () => {
|
||||
const params = { fields: { appId } }
|
||||
return await triggers.externalTrigger(
|
||||
const result = await triggers.externalTrigger(
|
||||
loopAutomation(table._id!, loopOpts),
|
||||
params,
|
||||
{ getResponses: true }
|
||||
)
|
||||
if ("outputs" in result && !result.outputs.success) {
|
||||
throw new Error("Unable to proceed - failed to return anything.")
|
||||
}
|
||||
return result as AutomationResults
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import {
|
|||
AutomationStatus,
|
||||
AutomationRowEvent,
|
||||
UserBindings,
|
||||
AutomationResults,
|
||||
} from "@budibase/types"
|
||||
import { executeInThread } from "../threads/automation"
|
||||
import { dataFilters, sdk } from "@budibase/shared-core"
|
||||
|
@ -32,6 +33,14 @@ const JOB_OPTS = {
|
|||
import * as automationUtils from "../automations/automationUtils"
|
||||
import { doesTableExist } from "../sdk/app/tables/getters"
|
||||
|
||||
type DidNotTriggerResponse = {
|
||||
outputs: {
|
||||
success: false
|
||||
status: AutomationStatus.STOPPED
|
||||
}
|
||||
message: AutomationStoppedReason.TRIGGER_FILTER_NOT_MET
|
||||
}
|
||||
|
||||
async function getAllAutomations() {
|
||||
const db = context.getAppDB()
|
||||
let automations = await db.allDocs<Automation>(
|
||||
|
@ -139,6 +148,14 @@ function rowPassesFilters(row: Row, filters: SearchFilters) {
|
|||
return filteredRows.length > 0
|
||||
}
|
||||
|
||||
export function isAutomationResults(
|
||||
response: AutomationResults | DidNotTriggerResponse | AutomationJob
|
||||
): response is AutomationResults {
|
||||
return (
|
||||
response !== null && "steps" in response && Array.isArray(response.steps)
|
||||
)
|
||||
}
|
||||
|
||||
export async function externalTrigger(
|
||||
automation: Automation,
|
||||
params: {
|
||||
|
@ -148,7 +165,7 @@ export async function externalTrigger(
|
|||
user?: UserBindings
|
||||
},
|
||||
{ getResponses }: { getResponses?: boolean } = {}
|
||||
): Promise<any> {
|
||||
): Promise<AutomationResults | DidNotTriggerResponse | AutomationJob> {
|
||||
if (automation.disabled) {
|
||||
throw new Error("Automation is disabled")
|
||||
}
|
||||
|
|
|
@ -9,9 +9,11 @@ import { cloneDeep } from "lodash/fp"
|
|||
import { quotas } from "@budibase/pro"
|
||||
import {
|
||||
Automation,
|
||||
AutomationActionStepId,
|
||||
AutomationJob,
|
||||
AutomationStepDefinition,
|
||||
AutomationTriggerDefinition,
|
||||
AutomationTriggerStepId,
|
||||
} from "@budibase/types"
|
||||
import { automationsEnabled } from "../features"
|
||||
import { helpers, REBOOT_CRON } from "@budibase/shared-core"
|
||||
|
@ -120,19 +122,21 @@ export async function updateTestHistory(
|
|||
)
|
||||
}
|
||||
|
||||
export function removeDeprecated(
|
||||
definitions: Record<
|
||||
export function removeDeprecated<
|
||||
T extends
|
||||
| Record<keyof typeof AutomationTriggerStepId, AutomationTriggerDefinition>
|
||||
| Record<keyof typeof AutomationActionStepId, AutomationStepDefinition>
|
||||
>(definitions: T): T {
|
||||
const base: Record<
|
||||
string,
|
||||
AutomationStepDefinition | AutomationTriggerDefinition
|
||||
>
|
||||
) {
|
||||
const base = cloneDeep(definitions)
|
||||
AutomationTriggerDefinition | AutomationStepDefinition
|
||||
> = cloneDeep(definitions)
|
||||
for (let key of Object.keys(base)) {
|
||||
if (base[key].deprecated) {
|
||||
delete base[key]
|
||||
}
|
||||
}
|
||||
return base
|
||||
return base as T
|
||||
}
|
||||
|
||||
// end the repetition and the job itself
|
||||
|
|
|
@ -26,3 +26,6 @@ export interface AutomationContext extends AutomationResults {
|
|||
company?: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface AutomationResponse
|
||||
extends Omit<AutomationContext, "stepsByName" | "stepsById"> {}
|
||||
|
|
|
@ -113,7 +113,7 @@ export async function syncUsersToAllApps(userIds: string[]) {
|
|||
export async function syncApp(
|
||||
appId: string,
|
||||
opts?: { automationOnly?: boolean }
|
||||
) {
|
||||
): Promise<{ message: string }> {
|
||||
if (env.DISABLE_AUTO_PROD_APP_SYNC) {
|
||||
return {
|
||||
message:
|
||||
|
|
|
@ -621,7 +621,7 @@ export default class TestConfiguration {
|
|||
}
|
||||
|
||||
async unpublish() {
|
||||
const response = await this._req(appController.unpublish, {
|
||||
const response = await this._req(appController.unpublish, undefined, {
|
||||
appId: this.appId,
|
||||
})
|
||||
this.prodAppId = undefined
|
||||
|
|
|
@ -30,7 +30,11 @@ import {
|
|||
UserBindings,
|
||||
isBasicSearchOperator,
|
||||
} from "@budibase/types"
|
||||
import { AutomationContext, TriggerOutput } from "../definitions/automations"
|
||||
import {
|
||||
AutomationContext,
|
||||
AutomationResponse,
|
||||
TriggerOutput,
|
||||
} from "../definitions/automations"
|
||||
import { WorkerCallback } from "./definitions"
|
||||
import { context, logging, configs } from "@budibase/backend-core"
|
||||
import {
|
||||
|
@ -81,7 +85,7 @@ class Orchestrator {
|
|||
private job: Job
|
||||
private loopStepOutputs: LoopStep[]
|
||||
private stopped: boolean
|
||||
private executionOutput: Omit<AutomationContext, "stepsByName" | "stepsById">
|
||||
private executionOutput: AutomationResponse
|
||||
private currentUser: UserBindings | undefined
|
||||
|
||||
constructor(job: AutomationJob) {
|
||||
|
@ -257,7 +261,7 @@ class Orchestrator {
|
|||
})
|
||||
}
|
||||
|
||||
async execute(): Promise<any> {
|
||||
async execute(): Promise<AutomationResponse | undefined> {
|
||||
return tracer.trace(
|
||||
"Orchestrator.execute",
|
||||
{ resource: "automation" },
|
||||
|
@ -723,7 +727,9 @@ export function execute(job: Job<AutomationData>, callback: WorkerCallback) {
|
|||
})
|
||||
}
|
||||
|
||||
export async function executeInThread(job: Job<AutomationData>) {
|
||||
export async function executeInThread(
|
||||
job: Job<AutomationData>
|
||||
): Promise<AutomationResponse> {
|
||||
const appId = job.data.event.appId
|
||||
if (!appId) {
|
||||
throw new Error("Unable to execute, event doesn't contain app ID.")
|
||||
|
@ -735,7 +741,7 @@ export async function executeInThread(job: Job<AutomationData>) {
|
|||
}, job.data.event.timeout || env.AUTOMATION_THREAD_TIMEOUT)
|
||||
})
|
||||
|
||||
return await context.doInAppContext(appId, async () => {
|
||||
return (await context.doInAppContext(appId, async () => {
|
||||
await context.ensureSnippetContext()
|
||||
const envVars = await sdkUtils.getEnvironmentVariables()
|
||||
// put into automation thread for whole context
|
||||
|
@ -746,7 +752,7 @@ export async function executeInThread(job: Job<AutomationData>) {
|
|||
timeoutPromise,
|
||||
])
|
||||
})
|
||||
})
|
||||
})) as AutomationResponse
|
||||
}
|
||||
|
||||
export const removeStalled = async (job: Job) => {
|
||||
|
|
|
@ -3,6 +3,10 @@ export enum PingSource {
|
|||
APP = "app",
|
||||
}
|
||||
|
||||
export interface AnalyticsEnabledResponse {
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
export interface AnalyticsPingRequest {
|
||||
source: PingSource
|
||||
timezone: string
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
export type ApiKeyFetchResponse = Record<string, string>
|
||||
|
||||
export interface UpdateApiKeyRequest {
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface UpdateApiKeyResponse {
|
||||
_id: string
|
||||
_rev: string
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
import {
|
||||
AutomationActionStepId,
|
||||
AutomationStepDefinition,
|
||||
AutomationTriggerDefinition,
|
||||
AutomationTriggerStepId,
|
||||
} from "../../../documents"
|
||||
|
||||
export type GetAutomationTriggerDefinitionsResponse = Record<
|
||||
keyof typeof AutomationTriggerStepId,
|
||||
AutomationTriggerDefinition
|
||||
>
|
||||
|
||||
export type GetAutomationActionDefinitionsResponse = Record<
|
||||
keyof typeof AutomationActionStepId,
|
||||
AutomationStepDefinition
|
||||
>
|
||||
|
||||
export interface GetAutomationStepDefinitionsResponse {
|
||||
trigger: GetAutomationTriggerDefinitionsResponse
|
||||
action: GetAutomationActionDefinitionsResponse
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
export type FetchComponentDefinitionResponse = Record<
|
||||
string,
|
||||
Record<string, any>
|
||||
>
|
|
@ -42,3 +42,14 @@ export interface BuildSchemaFromSourceResponse {
|
|||
datasource: Datasource
|
||||
errors: Record<string, string>
|
||||
}
|
||||
|
||||
export type FetchDatasourcesResponse = Datasource[]
|
||||
export type FindDatasourcesResponse = Datasource
|
||||
|
||||
export interface DeleteDatasourceResponse {
|
||||
message: string
|
||||
}
|
||||
|
||||
export interface FetchExternalSchemaResponse {
|
||||
schema: string
|
||||
}
|
||||
|
|
|
@ -8,3 +8,5 @@ export * from "./permission"
|
|||
export * from "./attachment"
|
||||
export * from "./user"
|
||||
export * from "./rowAction"
|
||||
export * from "./automation"
|
||||
export * from "./component"
|
||||
|
|
|
@ -7,3 +7,5 @@ export interface SetFlagRequest {
|
|||
flag: string
|
||||
value: any
|
||||
}
|
||||
|
||||
export type AppSelfResponse = ContextUserMetadata | {}
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
import type { PlanType } from "../../sdk"
|
||||
import type { Layout, App, Screen } from "../../documents"
|
||||
import { ReadStream } from "fs"
|
||||
|
||||
export interface SyncAppResponse {
|
||||
message: string
|
||||
}
|
||||
|
||||
export interface CreateAppRequest {
|
||||
name: string
|
||||
|
@ -12,6 +17,8 @@ export interface CreateAppRequest {
|
|||
file?: { path: string }
|
||||
}
|
||||
|
||||
export interface CreateAppResponse extends App {}
|
||||
|
||||
export interface DuplicateAppRequest {
|
||||
name: string
|
||||
url?: string
|
||||
|
@ -37,6 +44,8 @@ export interface FetchAppPackageResponse {
|
|||
hasLock: boolean
|
||||
}
|
||||
|
||||
export type FetchAppsResponse = App[]
|
||||
|
||||
export interface PublishResponse {
|
||||
_id: string
|
||||
status: string
|
||||
|
@ -45,3 +54,27 @@ export interface PublishResponse {
|
|||
|
||||
export interface UpdateAppRequest extends Partial<App> {}
|
||||
export interface UpdateAppResponse extends App {}
|
||||
export interface UpdateAppClientResponse extends App {}
|
||||
export interface RevertAppClientResponse extends App {}
|
||||
|
||||
export interface DeleteAppResponse {
|
||||
ok: boolean
|
||||
}
|
||||
|
||||
export interface ImportToUpdateAppRequest {
|
||||
encryptionPassword?: string
|
||||
}
|
||||
export interface ImportToUpdateAppResponse {
|
||||
message: string
|
||||
}
|
||||
|
||||
export interface SetRevertableAppVersionRequest {
|
||||
revertableVersion: string
|
||||
}
|
||||
|
||||
export interface ExportAppDumpRequest {
|
||||
excludeRows: boolean
|
||||
encryptPassword?: string
|
||||
}
|
||||
|
||||
export type ExportAppDumpResponse = ReadStream
|
||||
|
|
|
@ -1,8 +1,58 @@
|
|||
import { DocumentDestroyResponse } from "@budibase/nano"
|
||||
import { Automation } from "../../documents"
|
||||
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 {}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
import { DeploymentDoc, DeploymentStatus } from "../../documents"
|
||||
|
||||
export interface PublishAppResponse extends DeploymentDoc {}
|
||||
|
||||
export interface DeploymentProgressResponse {
|
||||
_id: string
|
||||
appId: string
|
||||
status?: DeploymentStatus
|
||||
updatedAt: number
|
||||
}
|
||||
|
||||
export type FetchDeploymentResponse = DeploymentProgressResponse[]
|
|
@ -0,0 +1,11 @@
|
|||
export interface GetVersionResponse {
|
||||
version: string
|
||||
}
|
||||
|
||||
export interface ClearDevLockResponse {
|
||||
message: string
|
||||
}
|
||||
|
||||
export interface RevertAppResponse {
|
||||
message: string
|
||||
}
|
|
@ -16,3 +16,6 @@ export * from "./layout"
|
|||
export * from "./query"
|
||||
export * from "./role"
|
||||
export * from "./plugins"
|
||||
export * from "./apikeys"
|
||||
export * from "./deployment"
|
||||
export * from "./dev"
|
||||
|
|
|
@ -311,6 +311,7 @@ export type AutomationStep =
|
|||
type EmptyInputs = {}
|
||||
export type AutomationStepDefinition = Omit<AutomationStep, "id" | "inputs"> & {
|
||||
inputs: EmptyInputs
|
||||
deprecated?: boolean
|
||||
}
|
||||
|
||||
export type AutomationTriggerDefinition = Omit<
|
||||
|
@ -318,6 +319,7 @@ export type AutomationTriggerDefinition = Omit<
|
|||
"id" | "inputs"
|
||||
> & {
|
||||
inputs: EmptyInputs
|
||||
deprecated?: boolean
|
||||
}
|
||||
|
||||
export type AutomationTriggerInputs<T extends AutomationTriggerStepId> =
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
export enum DeploymentStatus {
|
||||
SUCCESS = "SUCCESS",
|
||||
PENDING = "PENDING",
|
||||
FAILURE = "FAILURE",
|
||||
}
|
||||
|
||||
export interface DeploymentDoc {
|
||||
_id: string
|
||||
verification: any
|
||||
status?: DeploymentStatus
|
||||
history?: Record<
|
||||
string,
|
||||
{
|
||||
_id: string
|
||||
appId: string
|
||||
status?: DeploymentStatus
|
||||
updatedAt: number
|
||||
}
|
||||
>
|
||||
err?: any
|
||||
appUrl?: string
|
||||
}
|
|
@ -18,3 +18,4 @@ export * from "./sqlite"
|
|||
export * from "./snippet"
|
||||
export * from "./rowAction"
|
||||
export * from "./theme"
|
||||
export * from "./deployment"
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
import { Document } from "../../"
|
||||
|
||||
export interface ApiKeyDoc extends Document {
|
||||
apiKeys: Record<string, string>
|
||||
}
|
|
@ -7,3 +7,4 @@ export * from "./schedule"
|
|||
export * from "./templates"
|
||||
export * from "./environmentVariables"
|
||||
export * from "./auditLogs"
|
||||
export * from "./apikeys"
|
||||
|
|
Loading…
Reference in New Issue