132 lines
3.3 KiB
JavaScript
132 lines
3.3 KiB
JavaScript
const fs = require("fs")
|
|
const sanitize = require("sanitize-s3-objectkey")
|
|
const { walkDir } = require("../../../utilities")
|
|
const { join } = require("../../../utilities/centralPath")
|
|
const { budibaseAppsDir } = require("../../../utilities/budibaseDir")
|
|
const fetch = require("node-fetch")
|
|
const PouchDB = require("../../../db")
|
|
const CouchDB = require("pouchdb")
|
|
|
|
const CONTENT_TYPE_MAP = {
|
|
html: "text/html",
|
|
css: "text/css",
|
|
js: "application/javascript",
|
|
}
|
|
|
|
exports.fetchCredentials = async function(url, body) {
|
|
const response = await fetch(url, {
|
|
method: "POST",
|
|
body: JSON.stringify(body),
|
|
headers: { "Content-Type": "application/json" },
|
|
})
|
|
|
|
const json = await response.json()
|
|
if (json.errors) {
|
|
throw new Error(json.errors)
|
|
}
|
|
|
|
if (response.status !== 200) {
|
|
throw new Error(
|
|
`Error fetching temporary credentials: ${JSON.stringify(json)}`
|
|
)
|
|
}
|
|
|
|
return json
|
|
}
|
|
|
|
exports.prepareUpload = async function({ s3Key, metadata, client, file }) {
|
|
const extension = [...file.name.split(".")].pop()
|
|
const fileBytes = fs.readFileSync(file.path)
|
|
|
|
const upload = await client
|
|
.upload({
|
|
// windows file paths need to be converted to forward slashes for s3
|
|
Key: sanitize(s3Key).replace(/\\/g, "/"),
|
|
Body: fileBytes,
|
|
ContentType: file.type || CONTENT_TYPE_MAP[extension.toLowerCase()],
|
|
Metadata: metadata,
|
|
})
|
|
.promise()
|
|
|
|
return {
|
|
size: file.size,
|
|
name: file.name,
|
|
extension,
|
|
url: upload.Location,
|
|
key: upload.Key,
|
|
}
|
|
}
|
|
|
|
exports.deployToObjectStore = async function(appId, objectClient, metadata) {
|
|
const appAssetsPath = join(budibaseAppsDir(), appId, "public")
|
|
|
|
let uploads = []
|
|
|
|
// Upload HTML, CSS and JS for each page of the web app
|
|
walkDir(appAssetsPath, function(filePath) {
|
|
const filePathParts = filePath.split("/")
|
|
const appAssetUpload = exports.prepareUpload({
|
|
file: {
|
|
path: filePath,
|
|
name: filePathParts.pop(),
|
|
},
|
|
s3Key: filePath.replace(appAssetsPath, `assets/${appId}`),
|
|
client: objectClient,
|
|
metadata,
|
|
})
|
|
uploads.push(appAssetUpload)
|
|
})
|
|
|
|
// Upload file attachments
|
|
const db = new PouchDB(appId)
|
|
let fileUploads
|
|
try {
|
|
fileUploads = await db.get("_local/fileuploads")
|
|
} catch (err) {
|
|
fileUploads = { _id: "_local/fileuploads", uploads: [] }
|
|
}
|
|
|
|
for (let file of fileUploads.uploads) {
|
|
if (file.uploaded) continue
|
|
|
|
const attachmentUpload = exports.prepareUpload({
|
|
file,
|
|
s3Key: `assets/${appId}/attachments/${file.processedFileName}`,
|
|
client: objectClient,
|
|
metadata,
|
|
})
|
|
|
|
uploads.push(attachmentUpload)
|
|
|
|
// mark file as uploaded
|
|
file.uploaded = true
|
|
}
|
|
|
|
db.put(fileUploads)
|
|
|
|
try {
|
|
return await Promise.all(uploads)
|
|
} catch (err) {
|
|
console.error("Error uploading budibase app assets to s3", err)
|
|
throw err
|
|
}
|
|
}
|
|
|
|
exports.performReplication = (appId, session, dbUrl) => {
|
|
return new Promise((resolve, reject) => {
|
|
const local = new PouchDB(appId)
|
|
|
|
const remote = new CouchDB(`${dbUrl}/${appId}`, {
|
|
fetch: function(url, opts) {
|
|
opts.headers.set("Cookie", `${session};`)
|
|
return CouchDB.fetch(url, opts)
|
|
},
|
|
})
|
|
|
|
const replication = local.sync(remote)
|
|
|
|
replication.on("complete", () => resolve())
|
|
replication.on("error", err => reject(err))
|
|
})
|
|
}
|