From 1250aa666f1d29e80e15af040d30a5a5910ee981 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 11 Dec 2024 11:20:53 +0000 Subject: [PATCH 01/28] Fix scrollbar styles --- packages/bbui/src/Layout/Page.svelte | 3 +-- packages/builder/src/global.css | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/bbui/src/Layout/Page.svelte b/packages/bbui/src/Layout/Page.svelte index 62dd9cc909..e469927e60 100644 --- a/packages/bbui/src/Layout/Page.svelte +++ b/packages/bbui/src/Layout/Page.svelte @@ -43,12 +43,11 @@ flex-direction: row; justify-content: flex-start; align-items: stretch; - overflow-y: scroll !important; flex: 1 1 auto; overflow-x: hidden; } .main { - overflow: auto; + overflow-y: scroll; } .content { display: flex; diff --git a/packages/builder/src/global.css b/packages/builder/src/global.css index adf4a47070..a13d491416 100644 --- a/packages/builder/src/global.css +++ b/packages/builder/src/global.css @@ -61,7 +61,7 @@ a { height: 8px; } ::-webkit-scrollbar-track { - background: var(--spectrum-alias-background-color-default); + background: transparent; } ::-webkit-scrollbar-thumb { background-color: var(--spectrum-global-color-gray-400); @@ -71,6 +71,5 @@ a { background: var(--spectrum-alias-background-color-default); } html * { - scrollbar-color: var(--spectrum-global-color-gray-400) - var(--spectrum-alias-background-color-default); + scrollbar-color: var(--spectrum-global-color-gray-400) transparent; } From 62e47cc26841f677d040ee7619b96fd4e4bc1787 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 11 Dec 2024 15:51:11 +0000 Subject: [PATCH 02/28] Don't sync changes between users for views that are filtered by current user --- packages/server/src/websockets/grid.ts | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/server/src/websockets/grid.ts b/packages/server/src/websockets/grid.ts index 661d47cb6d..cfc04d8252 100644 --- a/packages/server/src/websockets/grid.ts +++ b/packages/server/src/websockets/grid.ts @@ -1,7 +1,7 @@ import authorized from "../middleware/authorized" import currentApp from "../middleware/currentapp" import { BaseSocket } from "./websocket" -import { auth, permissions } from "@budibase/backend-core" +import { auth, permissions, context } from "@budibase/backend-core" import http from "http" import Koa from "koa" import { getSourceId } from "../api/controllers/row/utils" @@ -10,6 +10,7 @@ import { Socket } from "socket.io" import { GridSocketEvent } from "@budibase/shared-core" import { userAgent } from "koa-useragent" import { createContext, runMiddlewares } from "./middleware" +import sdk from "../sdk" const { PermissionType, PermissionLevel } = permissions @@ -24,9 +25,26 @@ export default class GridSocket extends BaseSocket { const ds = payload.datasource const appId = payload.appId const resourceId = ds?.type === "table" ? ds?.tableId : ds?.id + let valid = true - // Ignore if no table or app specified + // Validate datasource if (!resourceId || !appId) { + // Ignore if no table or app specified + valid = false + } else if (ds.type === "viewV2") { + // If this is a view filtered by current user, don't sync changes + try { + await context.doInAppContext(appId, async () => { + const view = await sdk.views.get(ds.id) + if (JSON.stringify(view.query).includes("[user]")) { + valid = false + } + }) + } catch (err) { + valid = false + } + } + if (!valid) { socket.disconnect(true) return } From dc10bbf4c7e2fde5fa0953f6840222752f0a2b9c Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 12 Dec 2024 08:32:57 +0000 Subject: [PATCH 03/28] Account for JS current user bindings as well as HBS --- packages/server/src/websockets/grid.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/server/src/websockets/grid.ts b/packages/server/src/websockets/grid.ts index cfc04d8252..205c2896a3 100644 --- a/packages/server/src/websockets/grid.ts +++ b/packages/server/src/websockets/grid.ts @@ -11,6 +11,11 @@ import { GridSocketEvent } from "@budibase/shared-core" import { userAgent } from "koa-useragent" import { createContext, runMiddlewares } from "./middleware" import sdk from "../sdk" +import { + findHBSBlocks, + isJSBinding, + decodeJSBinding, +} from "@budibase/string-templates" const { PermissionType, PermissionLevel } = permissions @@ -19,6 +24,20 @@ export default class GridSocket extends BaseSocket { super(app, server, "/socket/grid") } + // Checks if a view's query contains any current user bindings + containsCurrentUserBinding(view: ViewV2): boolean { + return findHBSBlocks(JSON.stringify(view.query)) + .map(binding => { + const sanitizedBinding = binding.replace(/\\"/g, '"') + if (isJSBinding(sanitizedBinding)) { + return decodeJSBinding(sanitizedBinding) + } else { + return sanitizedBinding + } + }) + .some(binding => binding?.includes("[user]")) + } + async onConnect(socket: Socket) { // Initial identification of connected spreadsheet socket.on(GridSocketEvent.SelectDatasource, async (payload, callback) => { @@ -36,7 +55,7 @@ export default class GridSocket extends BaseSocket { try { await context.doInAppContext(appId, async () => { const view = await sdk.views.get(ds.id) - if (JSON.stringify(view.query).includes("[user]")) { + if (this.containsCurrentUserBinding(view)) { valid = false } }) From 77b9baa095eff6abfcc50a8af1a0bba26dfc2279 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 13 Dec 2024 16:48:47 +0000 Subject: [PATCH 04/28] Updating types to remove any instances of ctx.status = 200 being set and then no body provided. --- .../server/src/api/controllers/analytics.ts | 23 +++++++++----- .../server/src/api/controllers/application.ts | 24 +++++++-------- .../server/src/api/controllers/automation.ts | 2 -- .../server/src/api/controllers/datasource.ts | 4 +-- packages/server/src/api/controllers/layout.ts | 2 -- .../server/src/api/controllers/migrations.ts | 9 +++--- .../server/src/api/controllers/permission.ts | 4 +-- .../server/src/api/controllers/query/index.ts | 2 -- packages/server/src/api/controllers/role.ts | 3 +- .../server/src/api/controllers/row/index.ts | 4 --- .../src/api/controllers/rowAction/run.ts | 12 ++++++-- packages/server/src/api/controllers/screen.ts | 1 - .../server/src/api/controllers/table/index.ts | 7 ----- packages/types/src/api/web/analytics.ts | 4 +++ packages/types/src/api/web/app/application.ts | 11 +++++++ packages/types/src/api/web/app/permission.ts | 8 +++-- packages/types/src/api/web/app/rowAction.ts | 3 ++ packages/types/src/api/web/auth.ts | 7 +++++ .../api/web/global/environmentVariables.ts | 10 +++++++ packages/types/src/api/web/global/events.ts | 3 ++ packages/types/src/api/web/global/license.ts | 12 ++++++++ .../types/src/api/web/global/oldMigration.ts | 3 ++ .../types/src/api/web/system/migration.ts | 3 ++ packages/types/src/api/web/user.ts | 3 ++ .../worker/src/api/controllers/global/auth.ts | 20 ++++++++++--- .../src/api/controllers/global/events.ts | 7 +++-- .../src/api/controllers/global/license.ts | 30 ++++++++++++------- .../src/api/controllers/global/users.ts | 7 +++-- .../src/api/controllers/system/accounts.ts | 1 - .../src/api/controllers/system/migrations.ts | 6 ++-- 30 files changed, 159 insertions(+), 76 deletions(-) diff --git a/packages/server/src/api/controllers/analytics.ts b/packages/server/src/api/controllers/analytics.ts index 8c87af7251..27c981036a 100644 --- a/packages/server/src/api/controllers/analytics.ts +++ b/packages/server/src/api/controllers/analytics.ts @@ -1,10 +1,11 @@ -import { events, context } from "@budibase/backend-core" +import { context, events } from "@budibase/backend-core" import { - AnalyticsPingRequest, - App, - PingSource, - Ctx, AnalyticsEnabledResponse, + AnalyticsPingRequest, + AnalyticsPingResponse, + App, + Ctx, + PingSource, } from "@budibase/types" import { DocumentType, isDevAppID } from "../../db/utils" @@ -15,9 +16,12 @@ export const isEnabled = async (ctx: Ctx) => { } } -export const ping = async (ctx: Ctx) => { +export const ping = async ( + ctx: Ctx +) => { const body = ctx.request.body + let pingType: PingSource | undefined switch (body.source) { case PingSource.APP: { const db = context.getAppDB({ skip_setup: true }) @@ -29,13 +33,18 @@ export const ping = async (ctx: Ctx) => { } else { await events.serve.servedApp(appInfo, body.timezone, body.embedded) } + pingType = PingSource.APP break } case PingSource.BUILDER: { await events.serve.servedBuilder(body.timezone) + pingType = PingSource.BUILDER break } } - ctx.status = 200 + ctx.body = { + message: "pong", + source: pingType, + } } diff --git a/packages/server/src/api/controllers/application.ts b/packages/server/src/api/controllers/application.ts index d032f14150..4169087a63 100644 --- a/packages/server/src/api/controllers/application.ts +++ b/packages/server/src/api/controllers/application.ts @@ -68,6 +68,9 @@ import { ImportToUpdateAppRequest, ImportToUpdateAppResponse, SetRevertableAppVersionRequest, + AddAppSampleDataResponse, + UnpublishAppResponse, + SetRevertableAppVersionResponse, } from "@budibase/types" import { BASE_LAYOUT_PROP_IDS } from "../../constants/layouts" import sdk from "../../sdk" @@ -175,7 +178,9 @@ async function createInstance(appId: string, template: AppTemplate) { return { _id: appId } } -export const addSampleData = async (ctx: UserCtx) => { +export const addSampleData = async ( + ctx: UserCtx +) => { const db = context.getAppDB() try { @@ -188,7 +193,7 @@ export const addSampleData = async (ctx: UserCtx) => { await db.bulkDocs([...defaultDbDocs]) } - ctx.status = 200 + ctx.body = { message: "Sample tables added." } } export async function fetch(ctx: UserCtx) { @@ -528,7 +533,6 @@ export async function create( await appPostCreate(ctx, newApplication) await cache.bustCache(cache.CacheKey.CHECKLIST) ctx.body = newApplication - ctx.status = 200 } // This endpoint currently operates as a PATCH rather than a PUT @@ -551,7 +555,6 @@ export async function update( const app = await updateAppPackage(ctx.request.body, ctx.params.appId) await events.app.updated(app) - ctx.status = 200 ctx.body = app builderSocket?.emitAppMetadataUpdate(ctx, { theme: app.theme, @@ -592,7 +595,6 @@ export async function updateClient( } const app = await updateAppPackage(appPackageUpdates, ctx.params.appId) await events.app.versionUpdated(app, currentVersion, updatedToVersion) - ctx.status = 200 ctx.body = app } @@ -624,7 +626,6 @@ export async function revertClient( } const app = await updateAppPackage(appPackageUpdates, ctx.params.appId) await events.app.versionReverted(app, currentVersion, revertedToVersion) - ctx.status = 200 ctx.body = app } @@ -689,11 +690,10 @@ export async function destroy(ctx: UserCtx) { await preDestroyApp(ctx) const result = await destroyApp(ctx) await postDestroyApp(ctx) - ctx.status = 200 ctx.body = result } -export async function unpublish(ctx: UserCtx) { +export async function unpublish(ctx: UserCtx) { const prodAppId = dbCore.getProdAppID(ctx.params.appId) const dbExists = await dbCore.dbExists(prodAppId) @@ -705,8 +705,8 @@ export async function unpublish(ctx: UserCtx) { await preDestroyApp(ctx) await unpublishApp(ctx) await postDestroyApp(ctx) - ctx.status = 204 builderSocket?.emitAppUnpublish(ctx) + ctx.body = { message: "App unpublished." } } export async function sync(ctx: UserCtx) { @@ -802,7 +802,6 @@ export async function duplicateApp( duplicateAppId: newApplication?.appId, sourceAppId, } - ctx.status = 200 } export async function updateAppPackage( @@ -830,7 +829,7 @@ export async function updateAppPackage( } export async function setRevertableVersion( - ctx: UserCtx + ctx: UserCtx ) { if (!env.isDev()) { ctx.status = 403 @@ -840,8 +839,7 @@ export async function setRevertableVersion( const app = await sdk.applications.metadata.get() app.revertableVersion = ctx.request.body.revertableVersion await db.put(app) - - ctx.status = 200 + ctx.body = { message: "Revertable version updated." } } async function migrateAppNavigation() { diff --git a/packages/server/src/api/controllers/automation.ts b/packages/server/src/api/controllers/automation.ts index c843dca89b..abc0e492c0 100644 --- a/packages/server/src/api/controllers/automation.ts +++ b/packages/server/src/api/controllers/automation.ts @@ -62,7 +62,6 @@ export async function create( const createdAutomation = await sdk.automations.create(automation) - ctx.status = 200 ctx.body = { message: "Automation created successfully", automation: createdAutomation, @@ -84,7 +83,6 @@ export async function update( const updatedAutomation = await sdk.automations.update(automation) - ctx.status = 200 ctx.body = { message: `Automation ${automation._id} updated successfully.`, automation: updatedAutomation, diff --git a/packages/server/src/api/controllers/datasource.ts b/packages/server/src/api/controllers/datasource.ts index 7180f5f765..8a3d5cf2ca 100644 --- a/packages/server/src/api/controllers/datasource.ts +++ b/packages/server/src/api/controllers/datasource.ts @@ -182,7 +182,6 @@ export async function update( } } - ctx.status = 200 ctx.message = "Datasource saved successfully." ctx.body = { datasource: await sdk.datasources.removeSecretSingle(datasource), @@ -290,8 +289,7 @@ export async function destroy(ctx: UserCtx) { await db.remove(datasourceId, ctx.params.revId) await events.datasource.deleted(datasource) - ctx.message = `Datasource deleted.` - ctx.status = 200 + ctx.body = { message: `Datasource deleted.` } builderSocket?.emitDatasourceDeletion(ctx, datasourceId) } diff --git a/packages/server/src/api/controllers/layout.ts b/packages/server/src/api/controllers/layout.ts index a0eee000aa..4c996dde35 100644 --- a/packages/server/src/api/controllers/layout.ts +++ b/packages/server/src/api/controllers/layout.ts @@ -29,7 +29,6 @@ export async function save( layout._rev = response.rev ctx.body = layout - ctx.status = 200 } export async function destroy(ctx: UserCtx) { @@ -51,5 +50,4 @@ export async function destroy(ctx: UserCtx) { await db.remove(layoutId, layoutRev) await events.layout.deleted(layoutId) ctx.body = { message: "Layout deleted successfully" } - ctx.status = 200 } diff --git a/packages/server/src/api/controllers/migrations.ts b/packages/server/src/api/controllers/migrations.ts index a3ff0c5810..edf4ec6f51 100644 --- a/packages/server/src/api/controllers/migrations.ts +++ b/packages/server/src/api/controllers/migrations.ts @@ -4,6 +4,7 @@ import { Ctx, FetchOldMigrationResponse, GetOldMigrationStatus, + RuneOldMigrationResponse, RunOldMigrationRequest, } from "@budibase/types" import { @@ -11,18 +12,19 @@ import { getLatestEnabledMigrationId, } from "../../appMigrations" -export async function migrate(ctx: Ctx) { +export async function migrate( + ctx: Ctx +) { const options = ctx.request.body // don't await as can take a while, just return migrationImpl(options) - ctx.status = 200 + ctx.body = { message: "Migration started." } } export async function fetchDefinitions( ctx: Ctx ) { ctx.body = MIGRATIONS - ctx.status = 200 } export async function getMigrationStatus( @@ -41,5 +43,4 @@ export async function getMigrationStatus( !latestMigrationId || latestAppliedMigration >= latestMigrationId ctx.body = { migrated } - ctx.status = 200 } diff --git a/packages/server/src/api/controllers/permission.ts b/packages/server/src/api/controllers/permission.ts index e38c736c20..d1522ca292 100644 --- a/packages/server/src/api/controllers/permission.ts +++ b/packages/server/src/api/controllers/permission.ts @@ -99,7 +99,7 @@ export async function getDependantResources( export async function addPermission(ctx: UserCtx) { const params: AddPermissionRequest = ctx.params await sdk.permissions.updatePermissionOnRole(params, PermissionUpdateType.ADD) - ctx.status = 200 + ctx.body = { message: "Permission added." } } export async function removePermission( @@ -110,5 +110,5 @@ export async function removePermission( params, PermissionUpdateType.REMOVE ) - ctx.status = 200 + ctx.body = { message: "Permission removed." } } diff --git a/packages/server/src/api/controllers/query/index.ts b/packages/server/src/api/controllers/query/index.ts index d73bb8c024..7084d065fa 100644 --- a/packages/server/src/api/controllers/query/index.ts +++ b/packages/server/src/api/controllers/query/index.ts @@ -104,7 +104,6 @@ const _import = async ( ...importResult, datasourceId, } - ctx.status = 200 } export { _import as import } @@ -455,6 +454,5 @@ export async function destroy(ctx: UserCtx) { const datasource = await sdk.datasources.get(query.datasourceId) await db.remove(ctx.params.queryId, ctx.params.revId) ctx.body = { message: `Query deleted.` } - ctx.status = 200 await events.query.deleted(datasource, query) } diff --git a/packages/server/src/api/controllers/role.ts b/packages/server/src/api/controllers/role.ts index 30ca70b505..ae1d535a7c 100644 --- a/packages/server/src/api/controllers/role.ts +++ b/packages/server/src/api/controllers/role.ts @@ -234,8 +234,7 @@ export async function destroy(ctx: UserCtx) { // clean up inherits await removeRoleFromOthers(roleId) - ctx.message = `Role ${ctx.params.roleId} deleted successfully` - ctx.status = 200 + ctx.body = { message: `Role ${ctx.params.roleId} deleted successfully` } builderSocket?.emitRoleDeletion(ctx, role) } diff --git a/packages/server/src/api/controllers/row/index.ts b/packages/server/src/api/controllers/row/index.ts index 77c05abb95..8f4629a5b0 100644 --- a/packages/server/src/api/controllers/row/index.ts +++ b/packages/server/src/api/controllers/row/index.ts @@ -71,7 +71,6 @@ export async function patch( if (!row) { ctx.throw(404, "Row not found") } - ctx.status = 200 ctx.eventEmitter?.emitRow({ eventName: EventType.ROW_UPDATE, @@ -110,7 +109,6 @@ export const save = async (ctx: UserCtx) => { : await quotas.addRow(() => sdk.rows.save(sourceId, ctx.request.body, ctx.user?._id) ) - ctx.status = 200 ctx.eventEmitter?.emitRow({ eventName: EventType.ROW_SAVE, @@ -223,7 +221,6 @@ async function deleteRow(ctx: UserCtx) { export async function destroy(ctx: UserCtx) { let response, row - ctx.status = 200 if (isDeleteRows(ctx.request.body)) { response = await deleteRows(ctx) @@ -275,7 +272,6 @@ export async function search(ctx: Ctx) { rows: undefined, } - ctx.status = 200 ctx.body = await sdk.rows.search(searchParams) } diff --git a/packages/server/src/api/controllers/rowAction/run.ts b/packages/server/src/api/controllers/rowAction/run.ts index 05bdb7bace..069e38b86a 100644 --- a/packages/server/src/api/controllers/rowAction/run.ts +++ b/packages/server/src/api/controllers/rowAction/run.ts @@ -1,10 +1,16 @@ -import { RowActionTriggerRequest, Ctx } from "@budibase/types" +import { + RowActionTriggerRequest, + Ctx, + RowActionTriggerResponse, +} from "@budibase/types" import sdk from "../../../sdk" -export async function run(ctx: Ctx) { +export async function run( + ctx: Ctx +) { const { tableId, actionId } = ctx.params const { rowId } = ctx.request.body await sdk.rowActions.run(tableId, actionId, rowId, ctx.user) - ctx.status = 200 + ctx.body = { message: "Row action triggered." } } diff --git a/packages/server/src/api/controllers/screen.ts b/packages/server/src/api/controllers/screen.ts index cccc0c4d77..ad000871fe 100644 --- a/packages/server/src/api/controllers/screen.ts +++ b/packages/server/src/api/controllers/screen.ts @@ -123,7 +123,6 @@ export async function destroy(ctx: UserCtx) { ctx.body = { message: "Screen deleted successfully", } - ctx.status = 200 builderSocket?.emitScreenDeletion(ctx, id) } diff --git a/packages/server/src/api/controllers/table/index.ts b/packages/server/src/api/controllers/table/index.ts index 96599824c5..02134f0317 100644 --- a/packages/server/src/api/controllers/table/index.ts +++ b/packages/server/src/api/controllers/table/index.ts @@ -136,7 +136,6 @@ export async function save(ctx: UserCtx) { if (isImport) { await events.table.imported(savedTable) } - ctx.status = 200 ctx.message = `Table ${table.name} saved successfully.` ctx.eventEmitter?.emitTable(EventType.TABLE_SAVE, appId, { ...savedTable }) ctx.body = savedTable @@ -153,7 +152,6 @@ export async function destroy(ctx: UserCtx) { await events.table.deleted(deletedTable) ctx.eventEmitter?.emitTable(EventType.TABLE_DELETE, appId, deletedTable) - ctx.status = 200 ctx.table = deletedTable ctx.body = { message: `Table ${tableId} deleted.` } builderSocket?.emitTableDeletion(ctx, deletedTable) @@ -169,7 +167,6 @@ export async function bulkImport( // can only be done in the builder, but in the future we may need to // think about events for bulk items - ctx.status = 200 ctx.body = { message: `Bulk rows created.` } } @@ -180,7 +177,6 @@ export async function csvToJson( const result = await jsonFromCsvString(csvString) - ctx.status = 200 ctx.body = result } @@ -190,7 +186,6 @@ export async function validateNewTableImport( const { rows, schema } = ctx.request.body if (isRows(rows) && isSchema(schema)) { - ctx.status = 200 ctx.body = validateSchema(rows, schema, PROTECTED_INTERNAL_COLUMNS) } else { ctx.status = 422 @@ -224,7 +219,6 @@ export async function validateExistingTableImport( } if (tableId && isRows(rows) && isSchema(schema)) { - ctx.status = 200 ctx.body = validateSchema(rows, schema, protectedColumnNames) } else { ctx.status = 422 @@ -245,6 +239,5 @@ export async function migrate( }) } - ctx.status = 200 ctx.body = { message: `Column ${oldColumn} migrated.` } } diff --git a/packages/types/src/api/web/analytics.ts b/packages/types/src/api/web/analytics.ts index 2585964f94..3195da5df4 100644 --- a/packages/types/src/api/web/analytics.ts +++ b/packages/types/src/api/web/analytics.ts @@ -12,3 +12,7 @@ export interface AnalyticsPingRequest { timezone: string embedded?: boolean } +export interface AnalyticsPingResponse { + message: string + source?: PingSource +} diff --git a/packages/types/src/api/web/app/application.ts b/packages/types/src/api/web/app/application.ts index bc00ade217..a0f53a6ba4 100644 --- a/packages/types/src/api/web/app/application.ts +++ b/packages/types/src/api/web/app/application.ts @@ -44,6 +44,10 @@ export interface FetchAppPackageResponse { hasLock: boolean } +export interface AddAppSampleDataResponse { + message: string +} + export type FetchAppsResponse = App[] export interface PublishResponse { @@ -61,6 +65,10 @@ export interface DeleteAppResponse { ok: boolean } +export interface UnpublishAppResponse { + message: string +} + export interface ImportToUpdateAppRequest { encryptionPassword?: string } @@ -71,6 +79,9 @@ export interface ImportToUpdateAppResponse { export interface SetRevertableAppVersionRequest { revertableVersion: string } +export interface SetRevertableAppVersionResponse { + message: string +} export interface ExportAppDumpRequest { excludeRows: boolean diff --git a/packages/types/src/api/web/app/permission.ts b/packages/types/src/api/web/app/permission.ts index 407dc2be86..b449516eed 100644 --- a/packages/types/src/api/web/app/permission.ts +++ b/packages/types/src/api/web/app/permission.ts @@ -29,7 +29,9 @@ export interface AddedPermission { reason?: string } -export interface AddPermissionResponse {} +export interface AddPermissionResponse { + message: string +} export interface AddPermissionRequest { roleId: string @@ -38,4 +40,6 @@ export interface AddPermissionRequest { } export interface RemovePermissionRequest extends AddPermissionRequest {} -export interface RemovePermissionResponse {} +export interface RemovePermissionResponse { + message: string +} diff --git a/packages/types/src/api/web/app/rowAction.ts b/packages/types/src/api/web/app/rowAction.ts index 84e4e529ed..b4ff5538b5 100644 --- a/packages/types/src/api/web/app/rowAction.ts +++ b/packages/types/src/api/web/app/rowAction.ts @@ -21,6 +21,9 @@ export interface RowActionsResponse { export interface RowActionTriggerRequest { rowId: string } +export interface RowActionTriggerResponse { + message: string +} export interface RowActionPermissionsResponse extends RowActionPermissionsData {} diff --git a/packages/types/src/api/web/auth.ts b/packages/types/src/api/web/auth.ts index 0964d71576..5ef6169086 100644 --- a/packages/types/src/api/web/auth.ts +++ b/packages/types/src/api/web/auth.ts @@ -2,12 +2,19 @@ export interface LoginRequest { username: string password: string } +export interface LoginResponse { + message: string + userId?: string +} export interface LogoutResponse { message: string } export interface SetInitInfoRequest extends Record {} +export interface SetInitInfoResponse { + message: string +} export interface GetInitInfoResponse extends Record {} diff --git a/packages/types/src/api/web/global/environmentVariables.ts b/packages/types/src/api/web/global/environmentVariables.ts index 6f339eb821..b9399e246b 100644 --- a/packages/types/src/api/web/global/environmentVariables.ts +++ b/packages/types/src/api/web/global/environmentVariables.ts @@ -7,12 +7,22 @@ export interface CreateEnvironmentVariableRequest { production: string development: string } +export interface CreateEnvironmentVariableResponse { + message: string +} export interface UpdateEnvironmentVariableRequest { production: string development: string } +export interface UpdateEnvironmentVariableResponse { + message: string +} export interface GetEnvironmentVariablesResponse { variables: string[] } + +export interface DeleteEnvironmentVariablesResponse { + message: string +} diff --git a/packages/types/src/api/web/global/events.ts b/packages/types/src/api/web/global/events.ts index 907cfc74aa..e55808bd32 100644 --- a/packages/types/src/api/web/global/events.ts +++ b/packages/types/src/api/web/global/events.ts @@ -5,3 +5,6 @@ export enum EventPublishType { export interface PostEventPublishRequest { type: EventPublishType } +export interface PostEventPublishResponse { + message: string +} diff --git a/packages/types/src/api/web/global/license.ts b/packages/types/src/api/web/global/license.ts index 344ab829c2..d108880f93 100644 --- a/packages/types/src/api/web/global/license.ts +++ b/packages/types/src/api/web/global/license.ts @@ -5,6 +5,9 @@ import { QuotaUsage } from "../../../documents" export interface ActivateLicenseKeyRequest { licenseKey: string } +export interface ActivateLicenseKeyResponse { + message: string +} export interface GetLicenseKeyResponse { licenseKey: string @@ -15,11 +18,20 @@ export interface GetLicenseKeyResponse { export interface ActivateOfflineLicenseTokenRequest { offlineLicenseToken: string } +export interface ActivateOfflineLicenseTokenResponse { + message: string +} export interface GetOfflineLicenseTokenResponse { offlineLicenseToken: string } +// REFRESH + +export interface RefreshOfflineLicenseResponse { + message: string +} + // IDENTIFIER export interface GetOfflineIdentifierResponse { diff --git a/packages/types/src/api/web/global/oldMigration.ts b/packages/types/src/api/web/global/oldMigration.ts index 4b8ce9cc8d..812ee1e593 100644 --- a/packages/types/src/api/web/global/oldMigration.ts +++ b/packages/types/src/api/web/global/oldMigration.ts @@ -1,6 +1,9 @@ import { Migration, MigrationOptions } from "../../../sdk" export interface RunOldMigrationRequest extends MigrationOptions {} +export interface RuneOldMigrationResponse { + message: string +} export type FetchOldMigrationResponse = Migration[] diff --git a/packages/types/src/api/web/system/migration.ts b/packages/types/src/api/web/system/migration.ts index f9f6eac48a..a18112744c 100644 --- a/packages/types/src/api/web/system/migration.ts +++ b/packages/types/src/api/web/system/migration.ts @@ -1,5 +1,8 @@ import { MigrationDefinition, MigrationOptions } from "../../../sdk" export interface RunGlobalMigrationRequest extends MigrationOptions {} +export interface RunGlobalMigrationResponse { + message: string +} export type FetchMigrationDefinitionsResponse = MigrationDefinition[] diff --git a/packages/types/src/api/web/user.ts b/packages/types/src/api/web/user.ts index 2f83f012b3..a42449d550 100644 --- a/packages/types/src/api/web/user.ts +++ b/packages/types/src/api/web/user.ts @@ -110,6 +110,9 @@ export interface AddSSoUserRequest { ssoId: string email: string } +export interface AddSSoUserResponse { + message: string +} export interface CreateAdminUserResponse { _id: string diff --git a/packages/worker/src/api/controllers/global/auth.ts b/packages/worker/src/api/controllers/global/auth.ts index 1e6b0d3aab..0d49515700 100644 --- a/packages/worker/src/api/controllers/global/auth.ts +++ b/packages/worker/src/api/controllers/global/auth.ts @@ -22,6 +22,8 @@ import { GetInitInfoResponse, PasswordResetResponse, PasswordResetUpdateResponse, + SetInitInfoResponse, + LoginResponse, } from "@budibase/types" import env from "../../../environment" import { Next } from "koa" @@ -59,7 +61,10 @@ async function passportCallback( ctx.set(Header.TOKEN, token) } -export const login = async (ctx: Ctx, next: Next) => { +export const login = async ( + ctx: Ctx, + next: Next +) => { const email = ctx.request.body.username const user = await userSdk.db.getUserByEmail(email) @@ -74,7 +79,10 @@ export const login = async (ctx: Ctx, next: Next) => { await context.identity.doInUserContext(user, ctx, async () => { await events.auth.login("local", user.email) }) - ctx.status = 200 + ctx.body = { + message: "Login successful", + userId: user.userId, + } } )(ctx, next) } @@ -88,10 +96,14 @@ export const logout = async (ctx: UserCtx) => { // INIT -export const setInitInfo = (ctx: UserCtx) => { +export const setInitInfo = ( + ctx: UserCtx +) => { const initInfo = ctx.request.body setCookie(ctx, initInfo, Cookie.Init) - ctx.status = 200 + ctx.body = { + message: "Init info updated.", + } } export const getInitInfo = (ctx: UserCtx) => { diff --git a/packages/worker/src/api/controllers/global/events.ts b/packages/worker/src/api/controllers/global/events.ts index 758fb41b54..3d7ff4c29e 100644 --- a/packages/worker/src/api/controllers/global/events.ts +++ b/packages/worker/src/api/controllers/global/events.ts @@ -2,10 +2,13 @@ import { UserCtx, PostEventPublishRequest, EventPublishType, + PostEventPublishResponse, } from "@budibase/types" import { events } from "@budibase/backend-core" -export async function publish(ctx: UserCtx) { +export async function publish( + ctx: UserCtx +) { switch (ctx.request.body.type) { case EventPublishType.ENVIRONMENT_VARIABLE_UPGRADE_PANEL_OPENED: await events.environmentVariable.upgradePanelOpened(ctx.user._id!) @@ -13,5 +16,5 @@ export async function publish(ctx: UserCtx) { default: ctx.throw(400, "Invalid publish event type.") } - ctx.status = 200 + ctx.body = { message: "Event published." } } diff --git a/packages/worker/src/api/controllers/global/license.ts b/packages/worker/src/api/controllers/global/license.ts index 04f76a6593..014b01d87c 100644 --- a/packages/worker/src/api/controllers/global/license.ts +++ b/packages/worker/src/api/controllers/global/license.ts @@ -1,29 +1,33 @@ import { licensing, quotas } from "@budibase/pro" import { ActivateLicenseKeyRequest, + ActivateLicenseKeyResponse, ActivateOfflineLicenseTokenRequest, + ActivateOfflineLicenseTokenResponse, GetLicenseKeyResponse, GetOfflineIdentifierResponse, GetOfflineLicenseTokenResponse, GetQuotaUsageResponse, + RefreshOfflineLicenseResponse, UserCtx, } from "@budibase/types" // LICENSE KEY export async function activateLicenseKey( - ctx: UserCtx + ctx: UserCtx ) { const { licenseKey } = ctx.request.body await licensing.keys.activateLicenseKey(licenseKey) - ctx.status = 200 + ctx.body = { + message: "License activated.", + } } export async function getLicenseKey(ctx: UserCtx) { const licenseKey = await licensing.keys.getLicenseKey() if (licenseKey) { ctx.body = { licenseKey: "*" } - ctx.status = 200 } else { ctx.status = 404 } @@ -37,11 +41,16 @@ export async function deleteLicenseKey(ctx: UserCtx) { // OFFLINE LICENSE export async function activateOfflineLicenseToken( - ctx: UserCtx + ctx: UserCtx< + ActivateOfflineLicenseTokenRequest, + ActivateOfflineLicenseTokenResponse + > ) { const { offlineLicenseToken } = ctx.request.body await licensing.offline.activateOfflineLicenseToken(offlineLicenseToken) - ctx.status = 200 + ctx.body = { + message: "License token activated.", + } } export async function getOfflineLicenseToken( @@ -50,7 +59,6 @@ export async function getOfflineLicenseToken( const offlineLicenseToken = await licensing.offline.getOfflineLicenseToken() if (offlineLicenseToken) { ctx.body = { offlineLicenseToken: "*" } - ctx.status = 200 } else { ctx.status = 404 } @@ -66,14 +74,17 @@ export async function getOfflineLicenseIdentifier( ) { const identifierBase64 = await licensing.offline.getIdentifierBase64() ctx.body = { identifierBase64 } - ctx.status = 200 } // LICENSES -export const refresh = async (ctx: UserCtx) => { +export const refresh = async ( + ctx: UserCtx +) => { await licensing.cache.refresh() - ctx.status = 200 + ctx.body = { + message: "License refreshed.", + } } // USAGE @@ -82,5 +93,4 @@ export const getQuotaUsage = async ( ctx: UserCtx ) => { ctx.body = await quotas.getQuotaUsage() - ctx.status = 200 } diff --git a/packages/worker/src/api/controllers/global/users.ts b/packages/worker/src/api/controllers/global/users.ts index 1d36dd524c..a028f4fd33 100644 --- a/packages/worker/src/api/controllers/global/users.ts +++ b/packages/worker/src/api/controllers/global/users.ts @@ -4,6 +4,7 @@ import { AcceptUserInviteRequest, AcceptUserInviteResponse, AddSSoUserRequest, + AddSSoUserResponse, BulkUserRequest, BulkUserResponse, CheckInviteResponse, @@ -93,7 +94,9 @@ export const save = async (ctx: UserCtx) => { } } -export const addSsoSupport = async (ctx: Ctx) => { +export const addSsoSupport = async ( + ctx: Ctx +) => { const { email, ssoId } = ctx.request.body try { // Status is changed to 404 from getUserDoc if user is not found @@ -113,7 +116,7 @@ export const addSsoSupport = async (ctx: Ctx) => { email, ssoId, }) - ctx.status = 200 + ctx.body = { message: "SSO support added." } } catch (err: any) { ctx.throw(err.status || 400, err) } diff --git a/packages/worker/src/api/controllers/system/accounts.ts b/packages/worker/src/api/controllers/system/accounts.ts index e02c3f046d..e3fd9f2627 100644 --- a/packages/worker/src/api/controllers/system/accounts.ts +++ b/packages/worker/src/api/controllers/system/accounts.ts @@ -19,7 +19,6 @@ export const save = async ( metadata = await accounts.metadata.saveMetadata(metadata) ctx.body = metadata - ctx.status = 200 } export const destroy = async (ctx: Ctx) => { diff --git a/packages/worker/src/api/controllers/system/migrations.ts b/packages/worker/src/api/controllers/system/migrations.ts index dc66412e42..fc253d839d 100644 --- a/packages/worker/src/api/controllers/system/migrations.ts +++ b/packages/worker/src/api/controllers/system/migrations.ts @@ -1,23 +1,23 @@ import { FetchMigrationDefinitionsResponse, RunGlobalMigrationRequest, + RunGlobalMigrationResponse, UserCtx, } from "@budibase/types" const { migrate, MIGRATIONS } = require("../../../migrations") export const runMigrations = async ( - ctx: UserCtx + ctx: UserCtx ) => { const options = ctx.request.body // don't await as can take a while, just return migrate(options) - ctx.status = 200 + ctx.body = { message: "Migration started." } } export const fetchDefinitions = async ( ctx: UserCtx ) => { ctx.body = MIGRATIONS - ctx.status = 200 } From b976c57e1e890b7ac57b6d97c1bf2240edb46569 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 13 Dec 2024 16:59:19 +0000 Subject: [PATCH 05/28] Test fix. --- packages/worker/src/api/routes/system/tests/migrations.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/worker/src/api/routes/system/tests/migrations.spec.ts b/packages/worker/src/api/routes/system/tests/migrations.spec.ts index 4198d65ee9..fe91a1070c 100644 --- a/packages/worker/src/api/routes/system/tests/migrations.spec.ts +++ b/packages/worker/src/api/routes/system/tests/migrations.spec.ts @@ -36,7 +36,7 @@ describe("/api/system/migrations", () => { it("runs migrations", async () => { const res = await config.api.migrations.runMigrations() - expect(res.text).toBe("OK") + expect(res.body.message).toBeDefined() expect(migrateFn).toHaveBeenCalledTimes(1) }) }) From 6699b202b455ac60258b8e93ec26119880989c17 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 13 Dec 2024 17:10:05 +0000 Subject: [PATCH 06/28] Fixing some automation requirements. --- packages/server/src/automations/steps/createRow.ts | 2 +- packages/server/src/automations/steps/deleteRow.ts | 2 +- packages/server/src/automations/steps/updateRow.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/server/src/automations/steps/createRow.ts b/packages/server/src/automations/steps/createRow.ts index 4b9010dd01..e71b1e4556 100644 --- a/packages/server/src/automations/steps/createRow.ts +++ b/packages/server/src/automations/steps/createRow.ts @@ -112,7 +112,7 @@ export async function run({ response: ctx.body, id: ctx.body._id, revision: ctx.body._rev, - success: ctx.status === 200, + success: !!ctx.body._id, } } catch (err) { return { diff --git a/packages/server/src/automations/steps/deleteRow.ts b/packages/server/src/automations/steps/deleteRow.ts index c4c42d8200..8c61d256d1 100644 --- a/packages/server/src/automations/steps/deleteRow.ts +++ b/packages/server/src/automations/steps/deleteRow.ts @@ -94,7 +94,7 @@ export async function run({ return { response: ctx.body, row: ctx.row, - success: ctx.status === 200, + success: ctx.body.ok, } } catch (err) { return { diff --git a/packages/server/src/automations/steps/updateRow.ts b/packages/server/src/automations/steps/updateRow.ts index 65b9bf93d3..ecdbdc68c8 100644 --- a/packages/server/src/automations/steps/updateRow.ts +++ b/packages/server/src/automations/steps/updateRow.ts @@ -166,7 +166,7 @@ export async function run({ response: ctx.message, id: ctx.body._id, revision: ctx.body._rev, - success: ctx.status === 200, + success: !!ctx.body._id, } } catch (err) { return { From 7cf20ef16c861a11f1079851ac8ac55a5433ca2e Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 13 Dec 2024 17:11:35 +0000 Subject: [PATCH 07/28] Fixing query row. --- packages/server/src/automations/steps/queryRows.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/automations/steps/queryRows.ts b/packages/server/src/automations/steps/queryRows.ts index dc4dda4482..923f2efd8b 100644 --- a/packages/server/src/automations/steps/queryRows.ts +++ b/packages/server/src/automations/steps/queryRows.ts @@ -152,7 +152,7 @@ export async function run({ return { rows, - success: ctx.status === 200, + success: !!ctx.body.rows, } } catch (err) { return { From b58aa807bd69faeb87d33d43a547718cdc6dec00 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 13 Dec 2024 17:22:35 +0000 Subject: [PATCH 08/28] Another test change. --- packages/server/src/tests/utilities/api/application.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/tests/utilities/api/application.ts b/packages/server/src/tests/utilities/api/application.ts index 9dabc8cfe8..1fe9840c1d 100644 --- a/packages/server/src/tests/utilities/api/application.ts +++ b/packages/server/src/tests/utilities/api/application.ts @@ -48,7 +48,7 @@ export class ApplicationAPI extends TestAPI { unpublish = async (appId: string): Promise => { await this._post(`/api/applications/${appId}/unpublish`, { - expectations: { status: 204 }, + expectations: { status: 200 }, }) } From d20592e885147bc3e7eda8583f7b40c148239503 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 13 Dec 2024 17:33:40 +0000 Subject: [PATCH 09/28] Updating query row API to correctly state successful if not returning an error. --- packages/server/src/automations/steps/queryRows.ts | 2 +- packages/server/src/automations/tests/queryRows.spec.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/server/src/automations/steps/queryRows.ts b/packages/server/src/automations/steps/queryRows.ts index 923f2efd8b..93ca8a3f33 100644 --- a/packages/server/src/automations/steps/queryRows.ts +++ b/packages/server/src/automations/steps/queryRows.ts @@ -152,7 +152,7 @@ export async function run({ return { rows, - success: !!ctx.body.rows, + success: true, } } catch (err) { return { diff --git a/packages/server/src/automations/tests/queryRows.spec.ts b/packages/server/src/automations/tests/queryRows.spec.ts index 18d2e2d6cd..21e28673f3 100644 --- a/packages/server/src/automations/tests/queryRows.spec.ts +++ b/packages/server/src/automations/tests/queryRows.spec.ts @@ -96,7 +96,7 @@ describe("Test a query step automation", () => { ) .run() - expect(result.steps[0].outputs.success).toBe(false) + expect(result.steps[0].outputs.success).toBe(true) expect(result.steps[0].outputs.rows).toBeDefined() expect(result.steps[0].outputs.rows.length).toBe(0) }) @@ -125,7 +125,7 @@ describe("Test a query step automation", () => { ) .run() - expect(result.steps[0].outputs.success).toBe(false) + expect(result.steps[0].outputs.success).toBe(true) expect(result.steps[0].outputs.rows).toBeDefined() expect(result.steps[0].outputs.rows.length).toBe(0) }) From 8aebaa3717d682c22771369f6e8a4bb9aba2e364 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 13 Dec 2024 17:54:48 +0000 Subject: [PATCH 10/28] Updating pro to latest (small API change). --- packages/pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pro b/packages/pro index e7c9f08aeb..7fc699463b 160000 --- a/packages/pro +++ b/packages/pro @@ -1 +1 @@ -Subproject commit e7c9f08aeb0498a20594f3c912afedcfdc220a6a +Subproject commit 7fc699463b3957eb050351b983edef0d25a531ae From 8b56c6d0438965e30e4729996af9c78397893ba9 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Mon, 16 Dec 2024 10:55:27 +0000 Subject: [PATCH 11/28] Bump version to 3.2.29 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 055b5c3ce7..5e0bc09825 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "3.2.28", + "version": "3.2.29", "npmClient": "yarn", "concurrency": 20, "command": { From 8c4bb89412cc4e76e0ec031f1a8291fbc51e96fc Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 16 Dec 2024 16:53:59 +0000 Subject: [PATCH 12/28] Update type casting --- packages/builder/src/stores/portal/plugins.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/builder/src/stores/portal/plugins.ts b/packages/builder/src/stores/portal/plugins.ts index 5b1e04c2ff..0794e563eb 100644 --- a/packages/builder/src/stores/portal/plugins.ts +++ b/packages/builder/src/stores/portal/plugins.ts @@ -7,7 +7,7 @@ export function createPluginsStore() { const { subscribe, set, update } = writable([]) async function load() { - const plugins = (await API.getPlugins()) as Plugin[] + const plugins: Plugin[] = await API.getPlugins() set(plugins) } From 4fd47b5908d5605ed4181010b48b73943906e231 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 16 Dec 2024 16:56:52 +0000 Subject: [PATCH 13/28] Update auth endpoints to account for new JSON responses --- packages/frontend-core/src/api/auth.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/frontend-core/src/api/auth.ts b/packages/frontend-core/src/api/auth.ts index aa55c32a51..7d429c0c82 100644 --- a/packages/frontend-core/src/api/auth.ts +++ b/packages/frontend-core/src/api/auth.ts @@ -1,17 +1,23 @@ import { GetInitInfoResponse, LoginRequest, + LoginResponse, LogoutResponse, PasswordResetRequest, PasswordResetResponse, PasswordResetUpdateRequest, PasswordResetUpdateResponse, SetInitInfoRequest, + SetInitInfoResponse, } from "@budibase/types" import { BaseAPIClient } from "./types" export interface AuthEndpoints { - logIn: (tenantId: string, username: string, password: string) => Promise + logIn: ( + tenantId: string, + username: string, + password: string + ) => Promise logOut: () => Promise requestForgotPassword: ( tenantId: string, @@ -22,7 +28,7 @@ export interface AuthEndpoints { password: string, resetCode: string ) => Promise - setInitInfo: (info: SetInitInfoRequest) => Promise + setInitInfo: (info: SetInitInfoRequest) => Promise getInitInfo: () => Promise } @@ -34,13 +40,12 @@ export const buildAuthEndpoints = (API: BaseAPIClient): AuthEndpoints => ({ * @param password the password */ logIn: async (tenantId, username, password) => { - return await API.post({ + return await API.post({ url: `/api/global/auth/${tenantId}/login`, body: { username, password, }, - parseResponse: () => undefined, }) }, From d5eaa6ee3ed19d58256a3bc22ef0970dfa41c335 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 16 Dec 2024 16:58:58 +0000 Subject: [PATCH 14/28] Fix duplicating apps --- packages/builder/src/components/start/DuplicateAppModal.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/builder/src/components/start/DuplicateAppModal.svelte b/packages/builder/src/components/start/DuplicateAppModal.svelte index 0db92ff76d..79d91e35bb 100644 --- a/packages/builder/src/components/start/DuplicateAppModal.svelte +++ b/packages/builder/src/components/start/DuplicateAppModal.svelte @@ -68,7 +68,7 @@ } try { - const app = await API.duplicateApp(data, appId) + const app = await API.duplicateApp(appId, data) appsStore.load() if (!sdk.users.isBuilder($auth.user, app?.duplicateAppId)) { // Refresh for access to created applications From 22d8994431ce688a663ec6c167de4755eb608d35 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 16 Dec 2024 17:02:24 +0000 Subject: [PATCH 15/28] Account for responses from app endpoints --- packages/frontend-core/src/api/app.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/frontend-core/src/api/app.ts b/packages/frontend-core/src/api/app.ts index 20fc80cbee..eab5d33567 100644 --- a/packages/frontend-core/src/api/app.ts +++ b/packages/frontend-core/src/api/app.ts @@ -1,6 +1,7 @@ import { sdk } from "@budibase/shared-core" import { BaseAPIClient } from "./types" import { + AddAppSampleDataResponse, ClearDevLockResponse, CreateAppRequest, CreateAppResponse, @@ -18,7 +19,9 @@ import { RevertAppClientResponse, RevertAppResponse, SetRevertableAppVersionRequest, + SetRevertableAppVersionResponse, SyncAppResponse, + UnpublishAppResponse, UpdateAppClientResponse, UpdateAppRequest, UpdateAppResponse, @@ -30,7 +33,7 @@ export interface AppEndpoints { appId: string, metadata: UpdateAppRequest ) => Promise - unpublishApp: (appId: string) => Promise + unpublishApp: (appId: string) => Promise publishAppChanges: (appId: string) => Promise revertAppChanges: (appId: string) => Promise updateAppClientVersion: (appId: string) => Promise @@ -56,8 +59,8 @@ export interface AppEndpoints { setRevertableVersion: ( appId: string, revertableVersion: string - ) => Promise - addSampleData: (appId: string) => Promise + ) => Promise + addSampleData: (appId: string) => Promise // Missing request or response types importApps: (apps: any) => Promise @@ -272,7 +275,10 @@ export const buildAppEndpoints = (API: BaseAPIClient): AppEndpoints => ({ * @param revertableVersion the version number */ setRevertableVersion: async (appId, revertableVersion) => { - return await API.post({ + return await API.post< + SetRevertableAppVersionRequest, + SetRevertableAppVersionResponse + >({ url: `/api/applications/${appId}/setRevertableVersion`, body: { revertableVersion, From 4b499ca4870f0f8c68c7b2f5b9fea72b2e247459 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 16 Dec 2024 17:08:42 +0000 Subject: [PATCH 16/28] Update more endpoints with new response messages --- packages/frontend-core/src/api/analytics.ts | 11 ++++++---- .../src/api/environmentVariables.ts | 11 +++++++--- packages/frontend-core/src/api/events.ts | 10 ++++++--- packages/frontend-core/src/api/licensing.ts | 21 +++++++++++++------ 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/packages/frontend-core/src/api/analytics.ts b/packages/frontend-core/src/api/analytics.ts index de0de802e1..b57a8e5925 100644 --- a/packages/frontend-core/src/api/analytics.ts +++ b/packages/frontend-core/src/api/analytics.ts @@ -1,11 +1,15 @@ import { BaseAPIClient } from "./types" -import { AnalyticsEnabledResponse, AnalyticsPingRequest } from "@budibase/types" +import { + AnalyticsEnabledResponse, + AnalyticsPingRequest, + AnalyticsPingResponse, +} from "@budibase/types" export interface AnalyticsEndpoints { getAnalyticsStatus: () => Promise analyticsPing: ( payload: Omit - ) => Promise + ) => Promise } export const buildAnalyticsEndpoints = ( @@ -24,13 +28,12 @@ export const buildAnalyticsEndpoints = ( * Notifies analytics of a certain environment */ analyticsPing: async request => { - return await API.post({ + return await API.post({ url: "/api/bbtel/ping", body: { ...request, timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, }, - parseResponse: () => undefined, }) }, }) diff --git a/packages/frontend-core/src/api/environmentVariables.ts b/packages/frontend-core/src/api/environmentVariables.ts index ed7a284a4d..8dd2988c5f 100644 --- a/packages/frontend-core/src/api/environmentVariables.ts +++ b/packages/frontend-core/src/api/environmentVariables.ts @@ -1,8 +1,11 @@ import { CreateEnvironmentVariableRequest, + CreateEnvironmentVariableResponse, + DeleteEnvironmentVariablesResponse, GetEnvironmentVariablesResponse, StatusEnvironmentVariableResponse, UpdateEnvironmentVariableRequest, + UpdateEnvironmentVariableResponse, } from "@budibase/types" import { BaseAPIClient } from "./types" @@ -11,12 +14,14 @@ export interface EnvironmentVariableEndpoints { fetchEnvironmentVariables: () => Promise createEnvironmentVariable: ( data: CreateEnvironmentVariableRequest - ) => Promise - deleteEnvironmentVariable: (name: string) => Promise + ) => Promise + deleteEnvironmentVariable: ( + name: string + ) => Promise updateEnvironmentVariable: ( name: string, data: UpdateEnvironmentVariableRequest - ) => Promise + ) => Promise } export const buildEnvironmentVariableEndpoints = ( diff --git a/packages/frontend-core/src/api/events.ts b/packages/frontend-core/src/api/events.ts index 9e6cc40de3..2bec0ea680 100644 --- a/packages/frontend-core/src/api/events.ts +++ b/packages/frontend-core/src/api/events.ts @@ -1,13 +1,17 @@ -import { EventPublishType, PostEventPublishRequest } from "@budibase/types" +import { + EventPublishType, + PostEventPublishRequest, + PostEventPublishResponse, +} from "@budibase/types" import { BaseAPIClient } from "./types" export interface EventEndpoints { - publishEvent: (type: EventPublishType) => Promise + publishEvent: (type: EventPublishType) => Promise } export const buildEventEndpoints = (API: BaseAPIClient): EventEndpoints => ({ publishEvent: async type => { - return await API.post({ + return await API.post({ url: `/api/global/event/publish`, body: { type, diff --git a/packages/frontend-core/src/api/licensing.ts b/packages/frontend-core/src/api/licensing.ts index fd8ee36e83..bc499b92d4 100644 --- a/packages/frontend-core/src/api/licensing.ts +++ b/packages/frontend-core/src/api/licensing.ts @@ -1,22 +1,29 @@ import { ActivateLicenseKeyRequest, + ActivateLicenseKeyResponse, ActivateOfflineLicenseTokenRequest, + ActivateOfflineLicenseTokenResponse, GetLicenseKeyResponse, GetOfflineIdentifierResponse, GetOfflineLicenseTokenResponse, QuotaUsage, + RefreshOfflineLicenseResponse, } from "@budibase/types" import { BaseAPIClient } from "./types" export interface LicensingEndpoints { - activateLicenseKey: (licenseKey: string) => Promise + activateLicenseKey: ( + licenseKey: string + ) => Promise deleteLicenseKey: () => Promise getLicenseKey: () => Promise - activateOfflineLicense: (offlineLicenseToken: string) => Promise + activateOfflineLicense: ( + offlineLicenseToken: string + ) => Promise deleteOfflineLicense: () => Promise getOfflineLicense: () => Promise getOfflineLicenseIdentifier: () => Promise - refreshLicense: () => Promise + refreshLicense: () => Promise getQuotaUsage: () => Promise } @@ -25,7 +32,7 @@ export const buildLicensingEndpoints = ( ): LicensingEndpoints => ({ // LICENSE KEY activateLicenseKey: async licenseKey => { - return API.post({ + return API.post({ url: `/api/global/license/key`, body: { licenseKey }, }) @@ -49,7 +56,10 @@ export const buildLicensingEndpoints = ( // OFFLINE LICENSE activateOfflineLicense: async offlineLicenseToken => { - return API.post({ + return API.post< + ActivateOfflineLicenseTokenRequest, + ActivateOfflineLicenseTokenResponse + >({ url: "/api/global/license/offline", body: { offlineLicenseToken, @@ -84,7 +94,6 @@ export const buildLicensingEndpoints = ( refreshLicense: async () => { return API.post({ url: "/api/global/license/refresh", - parseResponse: () => undefined, }) }, /** From 9f645099dffc55ea141699f6c0236e3fdc629559 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 16 Dec 2024 17:51:49 +0000 Subject: [PATCH 17/28] Bringing back the old mechanism of removing stopped containers. --- .../tests/core/utilities/testContainerUtils.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/backend-core/tests/core/utilities/testContainerUtils.ts b/packages/backend-core/tests/core/utilities/testContainerUtils.ts index 7a8a6262cc..01906c9129 100644 --- a/packages/backend-core/tests/core/utilities/testContainerUtils.ts +++ b/packages/backend-core/tests/core/utilities/testContainerUtils.ts @@ -37,6 +37,10 @@ function getTestcontainers(): ContainerInfo[] { ) } +function removeContainer(container: ContainerInfo) { + execSync(`docker rm ${container.ID}`) +} + export function getContainerByImage(image: string) { const containers = getTestcontainers().filter(x => x.Image.startsWith(image)) if (containers.length > 1) { @@ -49,6 +53,10 @@ export function getContainerByImage(image: string) { return containers[0] } +function getContainerByName(name: string) { + return getTestcontainers().find(x => x.Names === name) +} + export function getContainerById(id: string) { return getTestcontainers().find(x => x.ID === id) } @@ -147,6 +155,15 @@ export async function startContainer(container: GenericContainer) { key = key.replace(/\//g, "-").replace(/:/g, "-") const name = `${key}_testcontainer` + // If a container has died it hangs around and future attempts to start a + // container with the same name will fail. What we do here is if we find a + // matching container and it has exited, we remove it before carrying on. This + // removes the need to do this removal manually. + const existingContainer = getContainerByName(name) + if (existingContainer?.State === "exited") { + removeContainer(existingContainer) + } + container = container .withReuse() .withLabels({ "com.budibase": "true" }) From 1d949fce2fa0f96714ace6eaf8705035bb017bfe Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 16 Dec 2024 18:07:05 +0000 Subject: [PATCH 18/28] Remove containers no matter what unless they are running. --- .../backend-core/tests/core/utilities/testContainerUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend-core/tests/core/utilities/testContainerUtils.ts b/packages/backend-core/tests/core/utilities/testContainerUtils.ts index 01906c9129..765ee2bb89 100644 --- a/packages/backend-core/tests/core/utilities/testContainerUtils.ts +++ b/packages/backend-core/tests/core/utilities/testContainerUtils.ts @@ -160,7 +160,7 @@ export async function startContainer(container: GenericContainer) { // matching container and it has exited, we remove it before carrying on. This // removes the need to do this removal manually. const existingContainer = getContainerByName(name) - if (existingContainer?.State === "exited") { + if (existingContainer && existingContainer.State !== "running") { removeContainer(existingContainer) } From a923a119c52a9f08acb0e2715b6a72d01428eb92 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 16 Dec 2024 18:07:43 +0000 Subject: [PATCH 19/28] Remove with force. --- .../backend-core/tests/core/utilities/testContainerUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend-core/tests/core/utilities/testContainerUtils.ts b/packages/backend-core/tests/core/utilities/testContainerUtils.ts index 765ee2bb89..04092fc6ea 100644 --- a/packages/backend-core/tests/core/utilities/testContainerUtils.ts +++ b/packages/backend-core/tests/core/utilities/testContainerUtils.ts @@ -38,7 +38,7 @@ function getTestcontainers(): ContainerInfo[] { } function removeContainer(container: ContainerInfo) { - execSync(`docker rm ${container.ID}`) + execSync(`docker rm -f ${container.ID}`) } export function getContainerByImage(image: string) { From fe5f76f27df3e15ffb0dcb26692c0c165f7dcefd Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 16 Dec 2024 18:13:28 +0000 Subject: [PATCH 20/28] Adding logging. --- packages/backend-core/tests/core/utilities/testContainerUtils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/backend-core/tests/core/utilities/testContainerUtils.ts b/packages/backend-core/tests/core/utilities/testContainerUtils.ts index 04092fc6ea..d6c16442f9 100644 --- a/packages/backend-core/tests/core/utilities/testContainerUtils.ts +++ b/packages/backend-core/tests/core/utilities/testContainerUtils.ts @@ -161,6 +161,7 @@ export async function startContainer(container: GenericContainer) { // removes the need to do this removal manually. const existingContainer = getContainerByName(name) if (existingContainer && existingContainer.State !== "running") { + console.log("--- REMOVING EXISTING CONTAINER --- ") removeContainer(existingContainer) } From 08f4e0d9ae62894161d710068e1e676d758f77d2 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 16 Dec 2024 18:29:15 +0000 Subject: [PATCH 21/28] Removing in specific scenarios. --- .../tests/core/utilities/testContainerUtils.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/backend-core/tests/core/utilities/testContainerUtils.ts b/packages/backend-core/tests/core/utilities/testContainerUtils.ts index d6c16442f9..bf0cb5228d 100644 --- a/packages/backend-core/tests/core/utilities/testContainerUtils.ts +++ b/packages/backend-core/tests/core/utilities/testContainerUtils.ts @@ -160,8 +160,11 @@ export async function startContainer(container: GenericContainer) { // matching container and it has exited, we remove it before carrying on. This // removes the need to do this removal manually. const existingContainer = getContainerByName(name) - if (existingContainer && existingContainer.State !== "running") { - console.log("--- REMOVING EXISTING CONTAINER --- ") + if ( + existingContainer?.State === "exited" || + existingContainer?.State === "dead" || + existingContainer?.State === "paused" + ) { removeContainer(existingContainer) } From 0b5faafaa295f2c2ca7f519bca677f50083fa426 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 16 Dec 2024 18:35:49 +0000 Subject: [PATCH 22/28] Adding pruning of old images. --- packages/backend-core/tests/core/utilities/testContainerUtils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/backend-core/tests/core/utilities/testContainerUtils.ts b/packages/backend-core/tests/core/utilities/testContainerUtils.ts index bf0cb5228d..b17cc2ea57 100644 --- a/packages/backend-core/tests/core/utilities/testContainerUtils.ts +++ b/packages/backend-core/tests/core/utilities/testContainerUtils.ts @@ -39,6 +39,7 @@ function getTestcontainers(): ContainerInfo[] { function removeContainer(container: ContainerInfo) { execSync(`docker rm -f ${container.ID}`) + execSync(`docker system prune -f`) } export function getContainerByImage(image: string) { From e5d4617ce9baacbc98513b1ce7f243cd153204da Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 16 Dec 2024 18:43:53 +0000 Subject: [PATCH 23/28] Updating to use old version of testcontainers that we used to use. --- packages/backend-core/package.json | 2 +- .../core/utilities/testContainerUtils.ts | 2 - packages/server/package.json | 2 +- yarn.lock | 144 +++++++++++++----- 4 files changed, 109 insertions(+), 41 deletions(-) diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index 3e1b5f324b..e43b65c6b4 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -91,7 +91,7 @@ "nock": "^13.5.6", "pino-pretty": "10.0.0", "pouchdb-adapter-memory": "7.2.2", - "testcontainers": "10.16.0", + "testcontainers": "10.7.2", "timekeeper": "2.2.0", "typescript": "5.7.2" }, diff --git a/packages/backend-core/tests/core/utilities/testContainerUtils.ts b/packages/backend-core/tests/core/utilities/testContainerUtils.ts index b17cc2ea57..c144e82eea 100644 --- a/packages/backend-core/tests/core/utilities/testContainerUtils.ts +++ b/packages/backend-core/tests/core/utilities/testContainerUtils.ts @@ -99,8 +99,6 @@ function getCurrentDockerContext(): DockerContext { } export function setupEnv(...envs: any[]) { - process.env.TESTCONTAINERS_RYUK_DISABLED = "true" - // For whatever reason, testcontainers doesn't always use the correct current // docker context. This bit of code forces the issue by finding the current // context and setting it as the DOCKER_HOST environment diff --git a/packages/server/package.json b/packages/server/package.json index 1dd3df1d73..11eea9e420 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -169,7 +169,7 @@ "rimraf": "3.0.2", "supertest": "6.3.3", "swagger-jsdoc": "6.1.0", - "testcontainers": "10.16.0", + "testcontainers": "10.7.2", "timekeeper": "2.2.0", "ts-node": "10.8.1", "tsconfig-paths": "4.0.0", diff --git a/yarn.lock b/yarn.lock index aa409fe4a1..dbf343c9dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2635,11 +2635,6 @@ dependencies: levn "^0.4.1" -"@fastify/busboy@^2.0.0": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d" - integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA== - "@fontsource/source-sans-pro@^5.0.3": version "5.0.3" resolved "https://registry.yarnpkg.com/@fontsource/source-sans-pro/-/source-sans-pro-5.0.3.tgz#7d6e84a8169ba12fa5e6ce70757aa2ca7e74d855" @@ -5461,7 +5456,7 @@ "@types/node" "*" "@types/ssh2" "*" -"@types/dockerode@^3.3.29": +"@types/dockerode@^3.3.24": version "3.3.32" resolved "https://registry.yarnpkg.com/@types/dockerode/-/dockerode-3.3.32.tgz#289dab161e59a0d62956194b394d7dc8145bae18" integrity sha512-xxcG0g5AWKtNyh7I7wswLdFvym4Mlqks5ZlKzxEUrGHS0r0PUOfxm2T0mspwu10mHQqu3Ck3MI3V2HqvLWE1fg== @@ -6770,6 +6765,38 @@ archive-type@^4.0.0: dependencies: file-type "^4.2.0" +archiver-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-2.1.0.tgz#e8a460e94b693c3e3da182a098ca6285ba9249e2" + integrity sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw== + dependencies: + glob "^7.1.4" + graceful-fs "^4.2.0" + lazystream "^1.0.0" + lodash.defaults "^4.2.0" + lodash.difference "^4.5.0" + lodash.flatten "^4.4.0" + lodash.isplainobject "^4.0.6" + lodash.union "^4.6.0" + normalize-path "^3.0.0" + readable-stream "^2.0.0" + +archiver-utils@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-3.0.4.tgz#a0d201f1cf8fce7af3b5a05aea0a337329e96ec7" + integrity sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw== + dependencies: + glob "^7.2.3" + graceful-fs "^4.2.0" + lazystream "^1.0.0" + lodash.defaults "^4.2.0" + lodash.difference "^4.5.0" + lodash.flatten "^4.4.0" + lodash.isplainobject "^4.0.6" + lodash.union "^4.6.0" + normalize-path "^3.0.0" + readable-stream "^3.6.0" + archiver-utils@^5.0.0, archiver-utils@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-5.0.2.tgz#63bc719d951803efc72cf961a56ef810760dd14d" @@ -6783,7 +6810,7 @@ archiver-utils@^5.0.0, archiver-utils@^5.0.2: normalize-path "^3.0.0" readable-stream "^4.0.0" -archiver@7.0.1, archiver@^7.0.1: +archiver@7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/archiver/-/archiver-7.0.1.tgz#c9d91c350362040b8927379c7aa69c0655122f61" integrity sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ== @@ -6796,6 +6823,19 @@ archiver@7.0.1, archiver@^7.0.1: tar-stream "^3.0.0" zip-stream "^6.0.1" +archiver@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/archiver/-/archiver-5.3.2.tgz#99991d5957e53bd0303a392979276ac4ddccf3b0" + integrity sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw== + dependencies: + archiver-utils "^2.1.0" + async "^3.2.4" + buffer-crc32 "^0.2.1" + readable-stream "^3.6.0" + readdir-glob "^1.1.2" + tar-stream "^2.2.0" + zip-stream "^4.1.0" + are-we-there-yet@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" @@ -7476,16 +7516,16 @@ buffer-alloc@^1.2.0: buffer-alloc-unsafe "^1.1.0" buffer-fill "^1.0.0" +buffer-crc32@^0.2.1, buffer-crc32@^0.2.13, buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + buffer-crc32@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-1.0.0.tgz#a10993b9055081d55304bd9feb4a072de179f405" integrity sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w== -buffer-crc32@~0.2.3: - version "0.2.13" - resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" - integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== - buffer-equal-constant-time@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" @@ -8173,6 +8213,16 @@ component-emitter@^1.3.0: resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== +compress-commons@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-4.1.2.tgz#6542e59cb63e1f46a8b21b0e06f9a32e4c8b06df" + integrity sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg== + dependencies: + buffer-crc32 "^0.2.13" + crc32-stream "^4.0.2" + normalize-path "^3.0.0" + readable-stream "^3.6.0" + compress-commons@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-6.0.2.tgz#26d31251a66b9d6ba23a84064ecd3a6a71d2609e" @@ -8461,6 +8511,14 @@ crc-32@^1.2.0: resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== +crc32-stream@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-4.0.3.tgz#85dd677eb78fa7cad1ba17cc506a597d41fc6f33" + integrity sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw== + dependencies: + crc-32 "^1.2.0" + readable-stream "^3.4.0" + crc32-stream@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-6.0.0.tgz#8529a3868f8b27abb915f6c3617c0fadedbf9430" @@ -8773,7 +8831,7 @@ dd-trace@5.26.0: shell-quote "^1.8.1" tlhunter-sorted-set "^0.1.0" -debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@^4.3.5, debug@~4.3.1, debug@~4.3.2, debug@~4.3.4: +debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2, debug@~4.3.4: version "4.3.7" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== @@ -9315,7 +9373,7 @@ docker-compose@0.24.0: dependencies: yaml "^1.10.2" -docker-compose@^0.24.8: +docker-compose@^0.24.6: version "0.24.8" resolved "https://registry.yarnpkg.com/docker-compose/-/docker-compose-0.24.8.tgz#6c125e6b9e04cf68ced47e2596ef2bb93ee9694e" integrity sha512-plizRs/Vf15H+GCVxq2EUvyPK7ei9b/cVesHvjnX4xaXjM9spHe2Ytq0BitndFgvTJ3E3NljPNUEl7BAN43iZw== @@ -11236,7 +11294,7 @@ glob@^5.0.15: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.5, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: +glob@^7.0.5, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.3: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -14116,6 +14174,11 @@ lodash.defaults@^4.2.0: resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== +lodash.difference@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c" + integrity sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA== + lodash.flatten@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" @@ -14206,6 +14269,11 @@ lodash.sortby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== +lodash.union@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" + integrity sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw== + lodash.without@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac" @@ -15106,7 +15174,7 @@ node-domexception@1.0.0: resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== -node-fetch@2.6.7, node-fetch@2.6.9, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.7, node-fetch@^2.6.9: +node-fetch@2.6.7, node-fetch@2.6.9, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.7, node-fetch@^2.6.9, node-fetch@^2.7.0: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== @@ -19169,7 +19237,7 @@ tar-fs@2.1.1, tar-fs@^2.0.0: pump "^3.0.0" tar-stream "^2.1.4" -tar-fs@^3.0.6: +tar-fs@^3.0.5: version "3.0.6" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.0.6.tgz#eaccd3a67d5672f09ca8e8f9c3d2b89fa173f217" integrity sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w== @@ -19203,7 +19271,7 @@ tar-stream@^1.5.2: to-buffer "^1.1.1" xtend "^4.0.0" -tar-stream@^2.0.0, tar-stream@^2.1.4, tar-stream@~2.2.0: +tar-stream@^2.0.0, tar-stream@^2.1.4, tar-stream@^2.2.0, tar-stream@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== @@ -19303,26 +19371,26 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" -testcontainers@10.16.0: - version "10.16.0" - resolved "https://registry.yarnpkg.com/testcontainers/-/testcontainers-10.16.0.tgz#8a7e69ada5cd2c6cce1c6db72b3a3e8e412fcaf6" - integrity sha512-oxPLuOtrRWS11A+Yn0+zXB7GkmNarflWqmy6CQJk8KJ75LZs2/zlUXDpizTbPpCGtk4kE2EQYwFZjrE967F8Wg== +testcontainers@10.7.2: + version "10.7.2" + resolved "https://registry.yarnpkg.com/testcontainers/-/testcontainers-10.7.2.tgz#619e93200dd47f174b307b40fa830cf023b74c25" + integrity sha512-7d+LVd/4YKp/cutiVMLL5cnj/8p8oYELAVRRyNUM4FyUDz1OLQuwW868nDl7Vd1ZAQxzGeCR+F86FlR9Yw9fMA== dependencies: "@balena/dockerignore" "^1.0.2" - "@types/dockerode" "^3.3.29" - archiver "^7.0.1" + "@types/dockerode" "^3.3.24" + archiver "^5.3.2" async-lock "^1.4.1" byline "^5.0.0" - debug "^4.3.5" - docker-compose "^0.24.8" + debug "^4.3.4" + docker-compose "^0.24.6" dockerode "^3.3.5" get-port "^5.1.1" + node-fetch "^2.7.0" proper-lockfile "^4.1.2" properties-reader "^2.3.0" ssh-remote-port-forward "^1.0.4" - tar-fs "^3.0.6" - tmp "^0.2.3" - undici "^5.28.4" + tar-fs "^3.0.5" + tmp "^0.2.1" text-extensions@^1.0.0: version "1.9.0" @@ -19446,7 +19514,7 @@ tlhunter-sorted-set@^0.1.0: resolved "https://registry.yarnpkg.com/tlhunter-sorted-set/-/tlhunter-sorted-set-0.1.0.tgz#1c3eae28c0fa4dff97e9501d2e3c204b86406f4b" integrity sha512-eGYW4bjf1DtrHzUYxYfAcSytpOkA44zsr7G2n3PV7yOUR23vmkGe3LL4R+1jL9OsXtbsFOwe8XtbCrabeaEFnw== -tmp@0.2.3, tmp@^0.2.3, tmp@~0.2.1: +tmp@0.2.3, tmp@^0.2.1, tmp@~0.2.1: version "0.2.3" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w== @@ -19914,13 +19982,6 @@ undici@^4.14.1: resolved "https://registry.yarnpkg.com/undici/-/undici-4.16.0.tgz#469bb87b3b918818d3d7843d91a1d08da357d5ff" integrity sha512-tkZSECUYi+/T1i4u+4+lwZmQgLXd4BLGlrc7KZPcLIW7Jpq99+Xpc30ONv7nS6F5UNOxp/HBZSSL9MafUrvJbw== -undici@^5.28.4: - version "5.28.4" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.4.tgz#6b280408edb6a1a604a9b20340f45b422e373068" - integrity sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g== - dependencies: - "@fastify/busboy" "^2.0.0" - unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" @@ -20932,6 +20993,15 @@ z-schema@^5.0.1: optionalDependencies: commander "^9.4.1" +zip-stream@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-4.1.1.tgz#1337fe974dbaffd2fa9a1ba09662a66932bd7135" + integrity sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ== + dependencies: + archiver-utils "^3.0.4" + compress-commons "^4.1.2" + readable-stream "^3.6.0" + zip-stream@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-6.0.1.tgz#e141b930ed60ccaf5d7fa9c8260e0d1748a2bbfb" From 618d8a5723799fd051914d490201fe09065564f4 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 16 Dec 2024 18:53:41 +0000 Subject: [PATCH 24/28] Extending startup timeout for SQL Server (other databases functioning fine). --- .../backend-core/tests/core/utilities/testContainerUtils.ts | 2 +- packages/server/src/integrations/tests/utils/mssql.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend-core/tests/core/utilities/testContainerUtils.ts b/packages/backend-core/tests/core/utilities/testContainerUtils.ts index c144e82eea..4a60ce6eb3 100644 --- a/packages/backend-core/tests/core/utilities/testContainerUtils.ts +++ b/packages/backend-core/tests/core/utilities/testContainerUtils.ts @@ -55,7 +55,7 @@ export function getContainerByImage(image: string) { } function getContainerByName(name: string) { - return getTestcontainers().find(x => x.Names === name) + return getTestcontainers().find(x => x.Names.includes(name)) } export function getContainerById(id: string) { diff --git a/packages/server/src/integrations/tests/utils/mssql.ts b/packages/server/src/integrations/tests/utils/mssql.ts index 548631a987..aa6ef7a1e3 100644 --- a/packages/server/src/integrations/tests/utils/mssql.ts +++ b/packages/server/src/integrations/tests/utils/mssql.ts @@ -24,7 +24,7 @@ export async function getDatasource(): Promise { .withWaitStrategy( Wait.forSuccessfulCommand( "/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P Password_123 -q 'SELECT 1'" - ).withStartupTimeout(20000) + ).withStartupTimeout(60000) ) ) } From 21aba2fc7102ab872992243a8df915a169678fb1 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 16 Dec 2024 21:21:30 +0000 Subject: [PATCH 25/28] Attempting to prune containers on startup always. --- .github/workflows/budibase_ci.yml | 1 + .../backend-core/tests/core/utilities/testContainerUtils.ts | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/budibase_ci.yml b/.github/workflows/budibase_ci.yml index e2f000cf7e..de1513d198 100644 --- a/.github/workflows/budibase_ci.yml +++ b/.github/workflows/budibase_ci.yml @@ -178,6 +178,7 @@ jobs: - name: Pull testcontainers images run: | + docker system prune -f if [ "${{ matrix.datasource }}" == "mssql" ]; then docker pull mcr.microsoft.com/mssql/server@${{ steps.dotenv.outputs.MSSQL_SHA }} elif [ "${{ matrix.datasource }}" == "mysql" ]; then diff --git a/packages/backend-core/tests/core/utilities/testContainerUtils.ts b/packages/backend-core/tests/core/utilities/testContainerUtils.ts index 4a60ce6eb3..f97d657c8c 100644 --- a/packages/backend-core/tests/core/utilities/testContainerUtils.ts +++ b/packages/backend-core/tests/core/utilities/testContainerUtils.ts @@ -39,7 +39,6 @@ function getTestcontainers(): ContainerInfo[] { function removeContainer(container: ContainerInfo) { execSync(`docker rm -f ${container.ID}`) - execSync(`docker system prune -f`) } export function getContainerByImage(image: string) { @@ -55,7 +54,9 @@ export function getContainerByImage(image: string) { } function getContainerByName(name: string) { - return getTestcontainers().find(x => x.Names.includes(name)) + return getTestcontainers().find(x => + x.Names.toLowerCase().includes(name.toLowerCase()) + ) } export function getContainerById(id: string) { From 8cd9c439c401139a0d003bf92072dee270b9cd79 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 16 Dec 2024 21:29:53 +0000 Subject: [PATCH 26/28] Test containers debug. --- .github/workflows/budibase_ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/budibase_ci.yml b/.github/workflows/budibase_ci.yml index de1513d198..840681c0ba 100644 --- a/.github/workflows/budibase_ci.yml +++ b/.github/workflows/budibase_ci.yml @@ -27,6 +27,7 @@ env: NX_BASE_BRANCH: origin/${{ github.base_ref }} ONLY_AFFECTED_TASKS: ${{ github.event_name == 'pull_request' }} IS_OSS_CONTRIBUTOR: ${{ inputs.run_as_oss == true || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != 'Budibase/budibase') }} + DEBUG: testcontainers* jobs: lint: @@ -178,7 +179,6 @@ jobs: - name: Pull testcontainers images run: | - docker system prune -f if [ "${{ matrix.datasource }}" == "mssql" ]; then docker pull mcr.microsoft.com/mssql/server@${{ steps.dotenv.outputs.MSSQL_SHA }} elif [ "${{ matrix.datasource }}" == "mysql" ]; then From 1b29fe702af395f56c591e4093ac7edb7c40dad2 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 16 Dec 2024 21:36:23 +0000 Subject: [PATCH 27/28] Using older github runner. --- .github/workflows/budibase_ci.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/budibase_ci.yml b/.github/workflows/budibase_ci.yml index 840681c0ba..4a76218c48 100644 --- a/.github/workflows/budibase_ci.yml +++ b/.github/workflows/budibase_ci.yml @@ -31,7 +31,7 @@ env: jobs: lint: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: Checkout repo uses: actions/checkout@v4 @@ -48,7 +48,7 @@ jobs: - run: yarn lint build: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: Checkout repo uses: actions/checkout@v4 @@ -77,7 +77,7 @@ jobs: fi helm-lint: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: Checkout repo uses: actions/checkout@v4 @@ -89,7 +89,7 @@ jobs: - run: cd charts/budibase && helm lint . test-libraries: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: Checkout repo uses: actions/checkout@v4 @@ -123,7 +123,7 @@ jobs: fi test-worker: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: Checkout repo uses: actions/checkout@v4 @@ -152,7 +152,7 @@ jobs: yarn test --verbose --reporters=default --reporters=github-actions test-server: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 strategy: matrix: datasource: @@ -238,7 +238,7 @@ jobs: yarn test --filter $FILTER --verbose --reporters=default --reporters=github-actions check-pro-submodule: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 if: inputs.run_as_oss != true && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'Budibase/budibase') steps: - name: Checkout repo and submodules @@ -297,7 +297,7 @@ jobs: fi check-lockfile: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 if: inputs.run_as_oss != true && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'Budibase/budibase') steps: - name: Checkout repo From b94e05c698b69a1fab4ca5c32c1f30c319fe2f66 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 16 Dec 2024 21:44:28 +0000 Subject: [PATCH 28/28] Reverting changes. --- .github/workflows/budibase_ci.yml | 1 - packages/backend-core/package.json | 2 +- .../core/utilities/testContainerUtils.ts | 25 +-- packages/server/package.json | 2 +- .../src/integrations/tests/utils/mssql.ts | 2 +- yarn.lock | 149 +++++------------- 6 files changed, 48 insertions(+), 133 deletions(-) diff --git a/.github/workflows/budibase_ci.yml b/.github/workflows/budibase_ci.yml index 4a76218c48..e81925876b 100644 --- a/.github/workflows/budibase_ci.yml +++ b/.github/workflows/budibase_ci.yml @@ -27,7 +27,6 @@ env: NX_BASE_BRANCH: origin/${{ github.base_ref }} ONLY_AFFECTED_TASKS: ${{ github.event_name == 'pull_request' }} IS_OSS_CONTRIBUTOR: ${{ inputs.run_as_oss == true || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != 'Budibase/budibase') }} - DEBUG: testcontainers* jobs: lint: diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index e43b65c6b4..3e1b5f324b 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -91,7 +91,7 @@ "nock": "^13.5.6", "pino-pretty": "10.0.0", "pouchdb-adapter-memory": "7.2.2", - "testcontainers": "10.7.2", + "testcontainers": "10.16.0", "timekeeper": "2.2.0", "typescript": "5.7.2" }, diff --git a/packages/backend-core/tests/core/utilities/testContainerUtils.ts b/packages/backend-core/tests/core/utilities/testContainerUtils.ts index f97d657c8c..7a8a6262cc 100644 --- a/packages/backend-core/tests/core/utilities/testContainerUtils.ts +++ b/packages/backend-core/tests/core/utilities/testContainerUtils.ts @@ -37,10 +37,6 @@ function getTestcontainers(): ContainerInfo[] { ) } -function removeContainer(container: ContainerInfo) { - execSync(`docker rm -f ${container.ID}`) -} - export function getContainerByImage(image: string) { const containers = getTestcontainers().filter(x => x.Image.startsWith(image)) if (containers.length > 1) { @@ -53,12 +49,6 @@ export function getContainerByImage(image: string) { return containers[0] } -function getContainerByName(name: string) { - return getTestcontainers().find(x => - x.Names.toLowerCase().includes(name.toLowerCase()) - ) -} - export function getContainerById(id: string) { return getTestcontainers().find(x => x.ID === id) } @@ -100,6 +90,8 @@ function getCurrentDockerContext(): DockerContext { } export function setupEnv(...envs: any[]) { + process.env.TESTCONTAINERS_RYUK_DISABLED = "true" + // For whatever reason, testcontainers doesn't always use the correct current // docker context. This bit of code forces the issue by finding the current // context and setting it as the DOCKER_HOST environment @@ -155,19 +147,6 @@ export async function startContainer(container: GenericContainer) { key = key.replace(/\//g, "-").replace(/:/g, "-") const name = `${key}_testcontainer` - // If a container has died it hangs around and future attempts to start a - // container with the same name will fail. What we do here is if we find a - // matching container and it has exited, we remove it before carrying on. This - // removes the need to do this removal manually. - const existingContainer = getContainerByName(name) - if ( - existingContainer?.State === "exited" || - existingContainer?.State === "dead" || - existingContainer?.State === "paused" - ) { - removeContainer(existingContainer) - } - container = container .withReuse() .withLabels({ "com.budibase": "true" }) diff --git a/packages/server/package.json b/packages/server/package.json index 11eea9e420..1dd3df1d73 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -169,7 +169,7 @@ "rimraf": "3.0.2", "supertest": "6.3.3", "swagger-jsdoc": "6.1.0", - "testcontainers": "10.7.2", + "testcontainers": "10.16.0", "timekeeper": "2.2.0", "ts-node": "10.8.1", "tsconfig-paths": "4.0.0", diff --git a/packages/server/src/integrations/tests/utils/mssql.ts b/packages/server/src/integrations/tests/utils/mssql.ts index aa6ef7a1e3..548631a987 100644 --- a/packages/server/src/integrations/tests/utils/mssql.ts +++ b/packages/server/src/integrations/tests/utils/mssql.ts @@ -24,7 +24,7 @@ export async function getDatasource(): Promise { .withWaitStrategy( Wait.forSuccessfulCommand( "/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P Password_123 -q 'SELECT 1'" - ).withStartupTimeout(60000) + ).withStartupTimeout(20000) ) ) } diff --git a/yarn.lock b/yarn.lock index dbf343c9dc..9e41875ec0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2635,6 +2635,11 @@ dependencies: levn "^0.4.1" +"@fastify/busboy@^2.0.0": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d" + integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA== + "@fontsource/source-sans-pro@^5.0.3": version "5.0.3" resolved "https://registry.yarnpkg.com/@fontsource/source-sans-pro/-/source-sans-pro-5.0.3.tgz#7d6e84a8169ba12fa5e6ce70757aa2ca7e74d855" @@ -5456,7 +5461,7 @@ "@types/node" "*" "@types/ssh2" "*" -"@types/dockerode@^3.3.24": +"@types/dockerode@^3.3.29": version "3.3.32" resolved "https://registry.yarnpkg.com/@types/dockerode/-/dockerode-3.3.32.tgz#289dab161e59a0d62956194b394d7dc8145bae18" integrity sha512-xxcG0g5AWKtNyh7I7wswLdFvym4Mlqks5ZlKzxEUrGHS0r0PUOfxm2T0mspwu10mHQqu3Ck3MI3V2HqvLWE1fg== @@ -6765,38 +6770,6 @@ archive-type@^4.0.0: dependencies: file-type "^4.2.0" -archiver-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-2.1.0.tgz#e8a460e94b693c3e3da182a098ca6285ba9249e2" - integrity sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw== - dependencies: - glob "^7.1.4" - graceful-fs "^4.2.0" - lazystream "^1.0.0" - lodash.defaults "^4.2.0" - lodash.difference "^4.5.0" - lodash.flatten "^4.4.0" - lodash.isplainobject "^4.0.6" - lodash.union "^4.6.0" - normalize-path "^3.0.0" - readable-stream "^2.0.0" - -archiver-utils@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-3.0.4.tgz#a0d201f1cf8fce7af3b5a05aea0a337329e96ec7" - integrity sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw== - dependencies: - glob "^7.2.3" - graceful-fs "^4.2.0" - lazystream "^1.0.0" - lodash.defaults "^4.2.0" - lodash.difference "^4.5.0" - lodash.flatten "^4.4.0" - lodash.isplainobject "^4.0.6" - lodash.union "^4.6.0" - normalize-path "^3.0.0" - readable-stream "^3.6.0" - archiver-utils@^5.0.0, archiver-utils@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-5.0.2.tgz#63bc719d951803efc72cf961a56ef810760dd14d" @@ -6810,7 +6783,7 @@ archiver-utils@^5.0.0, archiver-utils@^5.0.2: normalize-path "^3.0.0" readable-stream "^4.0.0" -archiver@7.0.1: +archiver@7.0.1, archiver@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/archiver/-/archiver-7.0.1.tgz#c9d91c350362040b8927379c7aa69c0655122f61" integrity sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ== @@ -6823,19 +6796,6 @@ archiver@7.0.1: tar-stream "^3.0.0" zip-stream "^6.0.1" -archiver@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/archiver/-/archiver-5.3.2.tgz#99991d5957e53bd0303a392979276ac4ddccf3b0" - integrity sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw== - dependencies: - archiver-utils "^2.1.0" - async "^3.2.4" - buffer-crc32 "^0.2.1" - readable-stream "^3.6.0" - readdir-glob "^1.1.2" - tar-stream "^2.2.0" - zip-stream "^4.1.0" - are-we-there-yet@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" @@ -7516,16 +7476,16 @@ buffer-alloc@^1.2.0: buffer-alloc-unsafe "^1.1.0" buffer-fill "^1.0.0" -buffer-crc32@^0.2.1, buffer-crc32@^0.2.13, buffer-crc32@~0.2.3: - version "0.2.13" - resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" - integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== - buffer-crc32@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-1.0.0.tgz#a10993b9055081d55304bd9feb4a072de179f405" integrity sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w== +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + buffer-equal-constant-time@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" @@ -8213,16 +8173,6 @@ component-emitter@^1.3.0: resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== -compress-commons@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-4.1.2.tgz#6542e59cb63e1f46a8b21b0e06f9a32e4c8b06df" - integrity sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg== - dependencies: - buffer-crc32 "^0.2.13" - crc32-stream "^4.0.2" - normalize-path "^3.0.0" - readable-stream "^3.6.0" - compress-commons@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-6.0.2.tgz#26d31251a66b9d6ba23a84064ecd3a6a71d2609e" @@ -8511,14 +8461,6 @@ crc-32@^1.2.0: resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== -crc32-stream@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-4.0.3.tgz#85dd677eb78fa7cad1ba17cc506a597d41fc6f33" - integrity sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw== - dependencies: - crc-32 "^1.2.0" - readable-stream "^3.4.0" - crc32-stream@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-6.0.0.tgz#8529a3868f8b27abb915f6c3617c0fadedbf9430" @@ -8852,6 +8794,13 @@ debug@^3.1.0, debug@^3.2.7: dependencies: ms "^2.1.1" +debug@^4.3.5: + version "4.4.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" + integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== + dependencies: + ms "^2.1.3" + debuglog@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" @@ -9373,7 +9322,7 @@ docker-compose@0.24.0: dependencies: yaml "^1.10.2" -docker-compose@^0.24.6: +docker-compose@^0.24.8: version "0.24.8" resolved "https://registry.yarnpkg.com/docker-compose/-/docker-compose-0.24.8.tgz#6c125e6b9e04cf68ced47e2596ef2bb93ee9694e" integrity sha512-plizRs/Vf15H+GCVxq2EUvyPK7ei9b/cVesHvjnX4xaXjM9spHe2Ytq0BitndFgvTJ3E3NljPNUEl7BAN43iZw== @@ -11294,7 +11243,7 @@ glob@^5.0.15: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.5, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.3: +glob@^7.0.5, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -14174,11 +14123,6 @@ lodash.defaults@^4.2.0: resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== -lodash.difference@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c" - integrity sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA== - lodash.flatten@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" @@ -14269,11 +14213,6 @@ lodash.sortby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== -lodash.union@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" - integrity sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw== - lodash.without@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac" @@ -15174,7 +15113,7 @@ node-domexception@1.0.0: resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== -node-fetch@2.6.7, node-fetch@2.6.9, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.7, node-fetch@^2.6.9, node-fetch@^2.7.0: +node-fetch@2.6.7, node-fetch@2.6.9, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.7, node-fetch@^2.6.9: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== @@ -19237,7 +19176,7 @@ tar-fs@2.1.1, tar-fs@^2.0.0: pump "^3.0.0" tar-stream "^2.1.4" -tar-fs@^3.0.5: +tar-fs@^3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.0.6.tgz#eaccd3a67d5672f09ca8e8f9c3d2b89fa173f217" integrity sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w== @@ -19271,7 +19210,7 @@ tar-stream@^1.5.2: to-buffer "^1.1.1" xtend "^4.0.0" -tar-stream@^2.0.0, tar-stream@^2.1.4, tar-stream@^2.2.0, tar-stream@~2.2.0: +tar-stream@^2.0.0, tar-stream@^2.1.4, tar-stream@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== @@ -19371,26 +19310,26 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" -testcontainers@10.7.2: - version "10.7.2" - resolved "https://registry.yarnpkg.com/testcontainers/-/testcontainers-10.7.2.tgz#619e93200dd47f174b307b40fa830cf023b74c25" - integrity sha512-7d+LVd/4YKp/cutiVMLL5cnj/8p8oYELAVRRyNUM4FyUDz1OLQuwW868nDl7Vd1ZAQxzGeCR+F86FlR9Yw9fMA== +testcontainers@10.16.0: + version "10.16.0" + resolved "https://registry.yarnpkg.com/testcontainers/-/testcontainers-10.16.0.tgz#8a7e69ada5cd2c6cce1c6db72b3a3e8e412fcaf6" + integrity sha512-oxPLuOtrRWS11A+Yn0+zXB7GkmNarflWqmy6CQJk8KJ75LZs2/zlUXDpizTbPpCGtk4kE2EQYwFZjrE967F8Wg== dependencies: "@balena/dockerignore" "^1.0.2" - "@types/dockerode" "^3.3.24" - archiver "^5.3.2" + "@types/dockerode" "^3.3.29" + archiver "^7.0.1" async-lock "^1.4.1" byline "^5.0.0" - debug "^4.3.4" - docker-compose "^0.24.6" + debug "^4.3.5" + docker-compose "^0.24.8" dockerode "^3.3.5" get-port "^5.1.1" - node-fetch "^2.7.0" proper-lockfile "^4.1.2" properties-reader "^2.3.0" ssh-remote-port-forward "^1.0.4" - tar-fs "^3.0.5" - tmp "^0.2.1" + tar-fs "^3.0.6" + tmp "^0.2.3" + undici "^5.28.4" text-extensions@^1.0.0: version "1.9.0" @@ -19514,7 +19453,7 @@ tlhunter-sorted-set@^0.1.0: resolved "https://registry.yarnpkg.com/tlhunter-sorted-set/-/tlhunter-sorted-set-0.1.0.tgz#1c3eae28c0fa4dff97e9501d2e3c204b86406f4b" integrity sha512-eGYW4bjf1DtrHzUYxYfAcSytpOkA44zsr7G2n3PV7yOUR23vmkGe3LL4R+1jL9OsXtbsFOwe8XtbCrabeaEFnw== -tmp@0.2.3, tmp@^0.2.1, tmp@~0.2.1: +tmp@0.2.3, tmp@^0.2.3, tmp@~0.2.1: version "0.2.3" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w== @@ -19982,6 +19921,13 @@ undici@^4.14.1: resolved "https://registry.yarnpkg.com/undici/-/undici-4.16.0.tgz#469bb87b3b918818d3d7843d91a1d08da357d5ff" integrity sha512-tkZSECUYi+/T1i4u+4+lwZmQgLXd4BLGlrc7KZPcLIW7Jpq99+Xpc30ONv7nS6F5UNOxp/HBZSSL9MafUrvJbw== +undici@^5.28.4: + version "5.28.4" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.4.tgz#6b280408edb6a1a604a9b20340f45b422e373068" + integrity sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g== + dependencies: + "@fastify/busboy" "^2.0.0" + unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" @@ -20993,15 +20939,6 @@ z-schema@^5.0.1: optionalDependencies: commander "^9.4.1" -zip-stream@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-4.1.1.tgz#1337fe974dbaffd2fa9a1ba09662a66932bd7135" - integrity sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ== - dependencies: - archiver-utils "^3.0.4" - compress-commons "^4.1.2" - readable-stream "^3.6.0" - zip-stream@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-6.0.1.tgz#e141b930ed60ccaf5d7fa9c8260e0d1748a2bbfb"