import { executeAppBuilder, log } from "builder-util"
import { BaseS3Options } from "builder-util-runtime"
import { mkdir, symlink } from "fs/promises"
import * as path from "path"
import { PublishContext, UploadTask } from ".."
import { Publisher } from "../publisher"
export abstract class BaseS3Publisher extends Publisher {
protected constructor(
context: PublishContext,
private options: BaseS3Options
) {
super(context)
}
protected abstract getBucketName(): string
protected configureS3Options(args: Array<string>) {
if (this.options.acl !== null) {
args.push("--acl", this.options.acl || "public-read")
}
}
async upload(task: UploadTask): Promise<any> {
const fileName = path.basename(task.file)
const cancellationToken = this.context.cancellationToken
const target = (this.options.path == null ? "" : `${this.options.path}/`) + fileName
const args = ["publish-s3", "--bucket", this.getBucketName(), "--key", target, "--file", task.file]
this.configureS3Options(args)
if (process.env.__TEST_S3_PUBLISHER__ != null) {
const testFile = path.join(process.env.__TEST_S3_PUBLISHER__, target)
await mkdir(path.dirname(testFile), { recursive: true })
await symlink(task.file, testFile)
return
}
this.createProgressBar(fileName, -1)
return await cancellationToken.createPromise((resolve, reject, onCancel) => {
executeAppBuilder(args, process => {
onCancel(() => {
process.kill("SIGINT")
})
})
.then(() => {
try {
log.debug({ provider: this.providerName, file: fileName, bucket: this.getBucketName() }, "uploaded")
} finally {
resolve(undefined)
}
})
.catch(reject)
})
}
toString() {
return `${this.providerName} (bucket: ${this.getBucketName()})`
}
}