Make import/export fs calls as async as possible.

This commit is contained in:
Sam Rose 2024-02-09 10:49:24 +00:00
parent 34edf19965
commit 51280b5526
No known key found for this signature in database
2 changed files with 17 additions and 15 deletions

View File

@ -14,6 +14,7 @@ import {
ATTACHMENT_DIRECTORY, ATTACHMENT_DIRECTORY,
} from "./constants" } from "./constants"
import fs from "fs" import fs from "fs"
import fsp from "fs/promises"
import { join } from "path" import { join } from "path"
import env from "../../../environment" import env from "../../../environment"
import { v4 as uuid } from "uuid" import { v4 as uuid } from "uuid"
@ -117,7 +118,7 @@ export async function exportApp(appId: string, config?: ExportOpts) {
ObjectStoreBuckets.APPS, ObjectStoreBuckets.APPS,
join(appPath, path) join(appPath, path)
) )
fs.writeFileSync(join(tmpPath, path), contents) await fsp.writeFile(join(tmpPath, path), contents)
} }
} }
// get all the files // get all the files
@ -131,14 +132,14 @@ export async function exportApp(appId: string, config?: ExportOpts) {
const downloadedPath = join(tmpPath, appPath) const downloadedPath = join(tmpPath, appPath)
if (fs.existsSync(downloadedPath)) { if (fs.existsSync(downloadedPath)) {
const allFiles = fs.readdirSync(downloadedPath) const allFiles = await fsp.readdir(downloadedPath)
for (let file of allFiles) { for (let file of allFiles) {
const path = join(downloadedPath, file) const path = join(downloadedPath, file)
// move out of app directory, simplify structure // move out of app directory, simplify structure
fs.renameSync(path, join(downloadedPath, "..", file)) await fsp.rename(path, join(downloadedPath, "..", file))
} }
// remove the old app directory created by object export // remove the old app directory created by object export
fs.rmdirSync(downloadedPath) await fsp.rmdir(downloadedPath)
} }
// enforce an export of app DB to the tmp path // enforce an export of app DB to the tmp path
const dbPath = join(tmpPath, DB_EXPORT_FILE) const dbPath = join(tmpPath, DB_EXPORT_FILE)
@ -148,7 +149,7 @@ export async function exportApp(appId: string, config?: ExportOpts) {
}) })
if (config?.encryptPassword) { if (config?.encryptPassword) {
for (let file of fs.readdirSync(tmpPath)) { for (let file of await fsp.readdir(tmpPath)) {
const path = join(tmpPath, file) const path = join(tmpPath, file)
// skip the attachments - too big to encrypt // skip the attachments - too big to encrypt
@ -157,7 +158,7 @@ export async function exportApp(appId: string, config?: ExportOpts) {
{ dir: tmpPath, filename: file }, { dir: tmpPath, filename: file },
config.encryptPassword config.encryptPassword
) )
fs.rmSync(path) await fsp.rm(path)
} }
} }
} }
@ -165,9 +166,9 @@ export async function exportApp(appId: string, config?: ExportOpts) {
// if tar requested, return where the tarball is // if tar requested, return where the tarball is
if (config?.tar) { if (config?.tar) {
// now the tmpPath contains both the DB export and attachments, tar this // now the tmpPath contains both the DB export and attachments, tar this
const tarPath = await tarFilesToTmp(tmpPath, fs.readdirSync(tmpPath)) const tarPath = await tarFilesToTmp(tmpPath, await fsp.readdir(tmpPath))
// cleanup the tmp export files as tarball returned // cleanup the tmp export files as tarball returned
fs.rmSync(tmpPath, { recursive: true, force: true }) await fsp.rm(tmpPath, { recursive: true, force: true })
return tarPath return tarPath
} }

View File

@ -17,6 +17,7 @@ import { downloadTemplate } from "../../../utilities/fileSystem"
import { ObjectStoreBuckets } from "../../../constants" import { ObjectStoreBuckets } from "../../../constants"
import { join } from "path" import { join } from "path"
import fs from "fs" import fs from "fs"
import fsp from "fs/promises"
import sdk from "../../" import sdk from "../../"
import { v4 as uuid } from "uuid" import { v4 as uuid } from "uuid"
import tar from "tar" import tar from "tar"
@ -119,7 +120,7 @@ async function getTemplateStream(template: TemplateType) {
export async function untarFile(file: { path: string }) { export async function untarFile(file: { path: string }) {
const tmpPath = join(budibaseTempDir(), uuid()) const tmpPath = join(budibaseTempDir(), uuid())
fs.mkdirSync(tmpPath) await fsp.mkdir(tmpPath)
// extract the tarball // extract the tarball
await tar.extract({ await tar.extract({
cwd: tmpPath, cwd: tmpPath,
@ -130,12 +131,12 @@ export async function untarFile(file: { path: string }) {
async function decryptFiles(path: string, password: string) { async function decryptFiles(path: string, password: string) {
try { try {
for (let file of fs.readdirSync(path)) { for (let file of await fsp.readdir(path)) {
const inputPath = join(path, file) const inputPath = join(path, file)
if (!inputPath.endsWith(ATTACHMENT_DIRECTORY)) { if (!inputPath.endsWith(ATTACHMENT_DIRECTORY)) {
const outputPath = inputPath.replace(/\.enc$/, "") const outputPath = inputPath.replace(/\.enc$/, "")
await encryption.decryptFile(inputPath, outputPath, password) await encryption.decryptFile(inputPath, outputPath, password)
fs.rmSync(inputPath) await fsp.rm(inputPath)
} }
} }
} catch (err: any) { } catch (err: any) {
@ -164,14 +165,14 @@ export async function importApp(
let dbStream: any let dbStream: any
const isTar = template.file && template?.file?.type?.endsWith("gzip") const isTar = template.file && template?.file?.type?.endsWith("gzip")
const isDirectory = const isDirectory =
template.file && fs.lstatSync(template.file.path).isDirectory() template.file && (await fsp.lstat(template.file.path)).isDirectory()
let tmpPath: string | undefined = undefined let tmpPath: string | undefined = undefined
if (template.file && (isTar || isDirectory)) { if (template.file && (isTar || isDirectory)) {
tmpPath = isTar ? await untarFile(template.file) : template.file.path tmpPath = isTar ? await untarFile(template.file) : template.file.path
if (isTar && template.file.password) { if (isTar && template.file.password) {
await decryptFiles(tmpPath, template.file.password) await decryptFiles(tmpPath, template.file.password)
} }
const contents = fs.readdirSync(tmpPath) const contents = await fsp.readdir(tmpPath)
// have to handle object import // have to handle object import
if (contents.length && opts.importObjStoreContents) { if (contents.length && opts.importObjStoreContents) {
let promises = [] let promises = []
@ -182,7 +183,7 @@ export async function importApp(
continue continue
} }
filename = join(prodAppId, filename) filename = join(prodAppId, filename)
if (fs.lstatSync(path).isDirectory()) { if ((await fsp.lstat(path)).isDirectory()) {
promises.push( promises.push(
objectStore.uploadDirectory(ObjectStoreBuckets.APPS, path, filename) objectStore.uploadDirectory(ObjectStoreBuckets.APPS, path, filename)
) )
@ -211,7 +212,7 @@ export async function importApp(
await updateAutomations(prodAppId, db) await updateAutomations(prodAppId, db)
// clear up afterward // clear up afterward
if (tmpPath) { if (tmpPath) {
fs.rmSync(tmpPath, { recursive: true, force: true }) await fsp.rm(tmpPath, { recursive: true, force: true })
} }
return ok return ok
} }