diff --git a/packages/builder/src/components/start/ImportAppModal.svelte b/packages/builder/src/components/start/ImportAppModal.svelte
index 7d30ded896..1bc32dc7a4 100644
--- a/packages/builder/src/components/start/ImportAppModal.svelte
+++ b/packages/builder/src/components/start/ImportAppModal.svelte
@@ -54,6 +54,7 @@
label="App export"
on:change={e => {
file = e.detail?.[0]
+ encrypted = file?.name?.endsWith(".enc.tar.gz")
}}
/>
diff --git a/packages/builder/src/pages/builder/app/[application]/settings/exportImport.svelte b/packages/builder/src/pages/builder/app/[application]/settings/exportImport.svelte
index bfa0274781..64ca0e0a2c 100644
--- a/packages/builder/src/pages/builder/app/[application]/settings/exportImport.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/settings/exportImport.svelte
@@ -13,7 +13,7 @@
import ExportAppModal from "components/start/ExportAppModal.svelte"
import ImportAppModal from "components/start/ImportAppModal.svelte"
- $: filteredApps = $apps.filter(app => app.devId == $store.appId)
+ $: filteredApps = $apps.filter(app => app.devId === $store.appId)
$: app = filteredApps.length ? filteredApps[0] : {}
$: appDeployed = app?.status === AppStatus.DEPLOYED
diff --git a/packages/server/src/api/routes/tests/appImport.spec.ts b/packages/server/src/api/routes/tests/appImport.spec.ts
index ef3c739e72..51331323de 100644
--- a/packages/server/src/api/routes/tests/appImport.spec.ts
+++ b/packages/server/src/api/routes/tests/appImport.spec.ts
@@ -23,7 +23,10 @@ describe("/applications/:appId/import", () => {
.set(config.defaultHeaders())
.expect("Content-Type", /json/)
.expect(200)
- expect(res.body.message).toBe("app updated")
+ const appPackage = await config.api.application.get(appId!)
+ expect(appPackage.navigation?.links?.length).toBe(2)
+ expect(expect(appPackage.navigation?.links?.[0].url).toBe("/blank"))
+ expect(expect(appPackage.navigation?.links?.[1].url).toBe("/derp"))
const screens = await config.api.screen.list()
expect(screens.length).toBe(2)
expect(screens[0].routing.route).toBe("/derp")
diff --git a/packages/server/src/sdk/app/applications/import.ts b/packages/server/src/sdk/app/applications/import.ts
index a7788924d8..158e4772b2 100644
--- a/packages/server/src/sdk/app/applications/import.ts
+++ b/packages/server/src/sdk/app/applications/import.ts
@@ -4,6 +4,8 @@ import {
Document,
Database,
RowValue,
+ DocumentType,
+ App,
} from "@budibase/types"
import backups from "../backups"
@@ -12,9 +14,39 @@ export type FileAttributes = {
path: string
}
+async function getNewAppMetadata(
+ tempDb: Database,
+ appDb: Database
+): Promise {
+ // static doc denoting app information
+ const docId = DocumentType.APP_METADATA
+ try {
+ const [tempMetadata, appMetadata] = await Promise.all([
+ tempDb.get(docId),
+ appDb.get(docId),
+ ])
+ return {
+ ...appMetadata,
+ automationErrors: undefined,
+ theme: tempMetadata.theme,
+ customTheme: tempMetadata.customTheme,
+ features: tempMetadata.features,
+ icon: tempMetadata.icon,
+ navigation: tempMetadata.navigation,
+ type: tempMetadata.type,
+ version: tempMetadata.version,
+ }
+ } catch (err: any) {
+ throw new Error(
+ `Unable to retrieve app metadata for import - ${err.message}`
+ )
+ }
+}
+
function mergeUpdateAndDeleteDocuments(
updateDocs: Document[],
- deleteDocs: Document[]
+ deleteDocs: Document[],
+ metadata: App
) {
// compress the documents to create and to delete (if same ID, then just update the rev)
const finalToDelete = []
@@ -26,7 +58,7 @@ function mergeUpdateAndDeleteDocuments(
finalToDelete.push(deleteDoc)
}
}
- return [...updateDocs, ...finalToDelete]
+ return [...updateDocs, ...finalToDelete, metadata]
}
async function removeImportableDocuments(db: Database) {
@@ -90,12 +122,15 @@ export async function updateWithExport(
await backups.importApp(devId, tempDb, template, {
importObjStoreContents: false,
})
+ const newMetadata = await getNewAppMetadata(tempDb, appDb)
// get the documents to copy
const toUpdate = await getImportableDocuments(tempDb)
// clear out the old documents
const toDelete = await removeImportableDocuments(appDb)
// now bulk update documents - add new ones, delete old ones and update common ones
- await appDb.bulkDocs(mergeUpdateAndDeleteDocuments(toUpdate, toDelete))
+ await appDb.bulkDocs(
+ mergeUpdateAndDeleteDocuments(toUpdate, toDelete, newMetadata)
+ )
} finally {
await tempDb.destroy()
}
diff --git a/packages/server/src/tests/utilities/api/application.ts b/packages/server/src/tests/utilities/api/application.ts
new file mode 100644
index 0000000000..85bc4e4173
--- /dev/null
+++ b/packages/server/src/tests/utilities/api/application.ts
@@ -0,0 +1,18 @@
+import { App } from "@budibase/types"
+import TestConfiguration from "../TestConfiguration"
+import { TestAPI } from "./base"
+
+export class ApplicationAPI extends TestAPI {
+ constructor(config: TestConfiguration) {
+ super(config)
+ }
+
+ get = async (appId: string): Promise => {
+ const result = await this.request
+ .get(`/api/applications/${appId}/appPackage`)
+ .set(this.config.defaultHeaders())
+ .expect("Content-Type", /json/)
+ .expect(200)
+ return result.body.application as App
+ }
+}
diff --git a/packages/server/src/tests/utilities/api/index.ts b/packages/server/src/tests/utilities/api/index.ts
index 889133b847..fce8237760 100644
--- a/packages/server/src/tests/utilities/api/index.ts
+++ b/packages/server/src/tests/utilities/api/index.ts
@@ -6,6 +6,7 @@ import { ViewV2API } from "./viewV2"
import { DatasourceAPI } from "./datasource"
import { LegacyViewAPI } from "./legacyView"
import { ScreenAPI } from "./screen"
+import { ApplicationAPI } from "./application"
export default class API {
table: TableAPI
@@ -15,6 +16,7 @@ export default class API {
permission: PermissionAPI
datasource: DatasourceAPI
screen: ScreenAPI
+ application: ApplicationAPI
constructor(config: TestConfiguration) {
this.table = new TableAPI(config)
@@ -24,5 +26,6 @@ export default class API {
this.permission = new PermissionAPI(config)
this.datasource = new DatasourceAPI(config)
this.screen = new ScreenAPI(config)
+ this.application = new ApplicationAPI(config)
}
}