diff --git a/packages/builder/src/components/common/Dropzone.svelte b/packages/builder/src/components/common/Dropzone.svelte
index 692bb5b0b5..7ec394063c 100644
--- a/packages/builder/src/components/common/Dropzone.svelte
+++ b/packages/builder/src/components/common/Dropzone.svelte
@@ -1,36 +1,13 @@
-
diff --git a/packages/builder/src/components/database/DataTable/ModelDataTable.svelte b/packages/builder/src/components/database/DataTable/ModelDataTable.svelte
index 038c2d7481..9726b053fa 100644
--- a/packages/builder/src/components/database/DataTable/ModelDataTable.svelte
+++ b/packages/builder/src/components/database/DataTable/ModelDataTable.svelte
@@ -112,6 +112,11 @@
section {
margin-bottom: 20px;
}
+
+ img {
+ object-fit: contain;
+ }
+
.title {
font-size: 24px;
font-weight: 600;
diff --git a/packages/server/src/api/controllers/deploy/aws.js b/packages/server/src/api/controllers/deploy/aws.js
index 4e52c179b4..9d994b3091 100644
--- a/packages/server/src/api/controllers/deploy/aws.js
+++ b/packages/server/src/api/controllers/deploy/aws.js
@@ -2,6 +2,7 @@ const fs = require("fs")
const AWS = require("aws-sdk")
const fetch = require("node-fetch")
const { budibaseAppsDir } = require("../../../utilities/budibaseDir")
+const PouchDB = require("../../../db")
async function invalidateCDN(cfDistribution, appId) {
const cf = new AWS.CloudFront({})
@@ -62,7 +63,6 @@ function walkDir(dirPath, callback) {
}
}
}
-
/**
* Walk a directory and return an array of promises for uploading all the files
* inside that directory to s3.
@@ -79,19 +79,8 @@ function uploadFiles({
}) {
const uploads = []
- walkDir(path, function prepareUploadsForS3(filePath) {
- const fileExtension = [...filePath.split(".")].pop()
- const fileBytes = fs.readFileSync(filePath)
-
- const upload = s3
- .upload({
- Key: filePath.replace(path, s3Key),
- Body: fileBytes,
- ContentType: CONTENT_TYPE_MAP[fileExtension],
- Metadata: metadata,
- })
- .promise()
-
+ walkDir(path, function(filePath) {
+ const upload = prepareUploadForS3(filePath, metadata)
uploads.push(upload)
})
@@ -99,8 +88,24 @@ function uploadFiles({
}
+function prepareUploadForS3({ filePath, s3Key, metadata }) {
+ const fileExtension = [...filePath.split(".")].pop()
+ const fileBytes = fs.readFileSync(filePath)
+ return s3
+ .upload({
+ Key: s3Key,
+ Body: fileBytes,
+ ContentType: CONTENT_TYPE_MAP[fileExtension],
+ Metadata: metadata,
+ })
+ .promise()
+}
+
+
+
exports.uploadAppAssets = async function({
appId,
+ instanceId,
credentials,
bucket,
cfDistribution,
@@ -126,25 +131,40 @@ exports.uploadAppAssets = async function({
for (let page of appPages) {
// Upload HTML, CSS and JS for each page of the web app
- const pageAssetUploads = uploadFiles({
- path: `${appAssetsPath}/${page}`,
- s3Key: `assets/${appId}`,
- s3,
- metadata: { accountId }
- });
+ walkDir(path, function(filePath) {
+ const appAssetUpload = prepareUploadForS3({
+ filePath,
+ s3Key: filePath.replace(path, `assets/${appId}`),
+ s3,
+ metadata: { accountId }
+ })
+ uploads.push(appAssetUpload)
+ })
uploads = [...uploads, ...pageAssetUploads];
}
// Upload file attachments
- const attachmentUploads = uploadFiles({
- path: `${budibaseAppsDir()}/${appId}/attachments`,
- s3Key: `assets/${appId}/attachments`,
- s3,
- metadata: { accountId }
- })
+ const db = new PouchDB(instanceId)
+ const fileUploads = await db.get("_local/fileuploads")
+ if (fileUploads) {
+ fileUploads.awaitingUpload.forEach((file, idx) => {
- uploads = [...uploads, ...attachmentUploads]
+ const attachmentUpload = prepareUploadForS3({
+ filePath: file.path,
+ s3Key: `assets/${appId}/${file.name}`,
+ s3,
+ metadata: { accountId }
+ })
+
+ uploads.push(attachmentUpload)
+
+ // move the pending upload to the uploaded array
+ fileUploads.awaitingUpload.splice(idx, 1);
+ fileUploads.uploaded.push(awaitingUpload);
+ })
+ db.put(fileUploads);
+ }
try {
await Promise.all(uploads)
diff --git a/packages/server/src/api/controllers/deploy/index.js b/packages/server/src/api/controllers/deploy/index.js
index 8e35d45ef2..34579b64c7 100644
--- a/packages/server/src/api/controllers/deploy/index.js
+++ b/packages/server/src/api/controllers/deploy/index.js
@@ -42,6 +42,7 @@ exports.deployApp = async function(ctx) {
await uploadAppAssets({
clientId,
appId: ctx.user.appId,
+ instanceId: ctx.user.instanceId,
...credentials,
})
diff --git a/packages/server/src/api/controllers/static/index.js b/packages/server/src/api/controllers/static/index.js
index d9e030026a..f93e345bba 100644
--- a/packages/server/src/api/controllers/static/index.js
+++ b/packages/server/src/api/controllers/static/index.js
@@ -4,12 +4,14 @@ const {
budibaseAppsDir,
budibaseTempDir,
} = require("../../../utilities/budibaseDir")
+const CouchDB = require("../../../db")
const setBuilderToken = require("../../../utilities/builder/setBuilderToken")
const { ANON_LEVEL_ID } = require("../../../utilities/accessLevels")
const jwt = require("jsonwebtoken")
const fetch = require("node-fetch")
const imageProcessing = require("./imageProcessing")
const fs = require("fs")
+const uuid = require("uuid")
exports.serveBuilder = async function(ctx) {
let builderPath = resolve(__dirname, "../../../../builder")
@@ -27,19 +29,43 @@ exports.processLocalFileUpload = async function(ctx) {
// create attachments dir if it doesnt exist
!fs.existsSync(attachmentsPath) && fs.mkdirSync(attachmentsPath, { recursive: true })
+ const filesToProcess = files.map(file => {
+ const fileExtension = [...file.path.split(".")].pop()
+ // filenames converted to UUIDs so they are unique
+ const fileName = `${uuid.v4()}.${fileExtension}`
- const filesToProcess = files.map(file => ({
- ...file,
- outputPath: join(attachmentsPath, file.name),
- clientUrl: join("/attachments", file.name),
- uploaded: false
- }))
+ return {
+ ...file,
+ name: fileName,
+ extension: fileExtension,
+ outputPath: join(attachmentsPath, fileName),
+ clientUrl: join("/attachments", fileName)
+ }
+ })
// TODO: read the file (into memory first, then we will stream it)
const imageProcessOperations = filesToProcess.map(file => imageProcessing.processImage(file))
try {
+ // TODO: get file sizes of images after resize
const responses = await Promise.all(imageProcessOperations);
+
+ let fileUploads
+ // local document used to track which files need to be uploaded
+ // db.get throws an error if the document doesn't exist
+ // need to use a promise to default
+ const db = new CouchDB(ctx.user.instanceId);
+ await db.get("_local/fileuploads")
+ .then(data => fileUploads = data)
+ .catch(() => fileUploads = {
+ _id: "_local/fileuploads",
+ awaitingUpload: [],
+ uploaded: []
+ })
+
+ fileUploads.awaitingUpload = [...filesToProcess, ...fileUploads.awaitingUpload]
+ await db.put(fileUploads)
+
ctx.body = filesToProcess
} catch (err) {
ctx.throw(500, err);