update electron to v43

This commit is contained in:
olcxja 2026-07-09 22:38:33 +02:00
commit fb6c8b6ee9
5385 changed files with 513060 additions and 123058 deletions

View file

@ -0,0 +1,14 @@
export interface AwsCredentials {
accessKeyId: string;
secretAccessKey: string;
sessionToken?: string;
}
/**
* Resolves AWS credentials using the standard provider chain:
* 1. Environment variables (AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY)
* 2. Shared credentials file (~/.aws/credentials, respects AWS_PROFILE)
*
* Returns undefined when no credentials are found callers should let aws4 sign
* with anonymous credentials or throw a descriptive error as appropriate.
*/
export declare function resolveAwsCredentials(): AwsCredentials | undefined;

View file

@ -0,0 +1,64 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveAwsCredentials = resolveAwsCredentials;
const fs = require("fs");
const os = require("os");
const path = require("path");
function parseIniSection(content, sectionName) {
let inSection = false;
let found = false;
const result = {};
for (const rawLine of content.split(/\r?\n/)) {
const line = rawLine.trim();
if (line.startsWith("[")) {
const name = line.slice(1, line.indexOf("]")).trim();
inSection = name === sectionName;
if (inSection) {
found = true;
}
}
else if (inSection && line && !line.startsWith("#") && !line.startsWith(";")) {
const eq = line.indexOf("=");
if (eq > 0) {
result[line.slice(0, eq).trim()] = line.slice(eq + 1).trim();
}
}
}
return found ? result : null;
}
/**
* Resolves AWS credentials using the standard provider chain:
* 1. Environment variables (AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY)
* 2. Shared credentials file (~/.aws/credentials, respects AWS_PROFILE)
*
* Returns undefined when no credentials are found callers should let aws4 sign
* with anonymous credentials or throw a descriptive error as appropriate.
*/
function resolveAwsCredentials() {
var _a;
if (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) {
return {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
sessionToken: process.env.AWS_SESSION_TOKEN || undefined,
};
}
try {
const profile = (_a = process.env.AWS_PROFILE) !== null && _a !== void 0 ? _a : "default";
const credsPath = path.join(os.homedir(), ".aws", "credentials");
const raw = fs.readFileSync(credsPath, "utf8");
const section = parseIniSection(raw, profile);
if ((section === null || section === void 0 ? void 0 : section.aws_access_key_id) && (section === null || section === void 0 ? void 0 : section.aws_secret_access_key)) {
return {
accessKeyId: section.aws_access_key_id,
secretAccessKey: section.aws_secret_access_key,
sessionToken: section.aws_session_token || undefined,
};
}
}
catch {
// file absent or unreadable — fall through
}
return undefined;
}
//# sourceMappingURL=awsCredentials.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"awsCredentials.js","sourceRoot":"","sources":["../../src/s3/awsCredentials.ts"],"names":[],"mappings":";;AA0CA,sDA0BC;AApED,yBAAwB;AACxB,yBAAwB;AACxB,6BAA4B;AAQ5B,SAAS,eAAe,CAAC,OAAe,EAAE,WAAmB;IAC3D,IAAI,SAAS,GAAG,KAAK,CAAA;IACrB,IAAI,KAAK,GAAG,KAAK,CAAA;IACjB,MAAM,MAAM,GAA2B,EAAE,CAAA;IAEzC,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAA;QAC3B,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;YACpD,SAAS,GAAG,IAAI,KAAK,WAAW,CAAA;YAChC,IAAI,SAAS,EAAE,CAAC;gBACd,KAAK,GAAG,IAAI,CAAA;YACd,CAAC;QACH,CAAC;aAAM,IAAI,SAAS,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/E,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAC5B,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;YAC9D,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAA;AAC9B,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,qBAAqB;;IACnC,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC;QACvE,OAAO;YACL,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;YAC1C,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB;YAClD,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,SAAS;SACzD,CAAA;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAA,OAAO,CAAC,GAAG,CAAC,WAAW,mCAAI,SAAS,CAAA;QACpD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,CAAA;QAChE,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;QAC9C,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;QAC7C,IAAI,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,iBAAiB,MAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,qBAAqB,CAAA,EAAE,CAAC;YACjE,OAAO;gBACL,WAAW,EAAE,OAAO,CAAC,iBAAiB;gBACtC,eAAe,EAAE,OAAO,CAAC,qBAAqB;gBAC9C,YAAY,EAAE,OAAO,CAAC,iBAAiB,IAAI,SAAS;aACrD,CAAA;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,2CAA2C;IAC7C,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC","sourcesContent":["import * as fs from \"fs\"\nimport * as os from \"os\"\nimport * as path from \"path\"\n\nexport interface AwsCredentials {\n accessKeyId: string\n secretAccessKey: string\n sessionToken?: string\n}\n\nfunction parseIniSection(content: string, sectionName: string): Record<string, string> | null {\n let inSection = false\n let found = false\n const result: Record<string, string> = {}\n\n for (const rawLine of content.split(/\\r?\\n/)) {\n const line = rawLine.trim()\n if (line.startsWith(\"[\")) {\n const name = line.slice(1, line.indexOf(\"]\")).trim()\n inSection = name === sectionName\n if (inSection) {\n found = true\n }\n } else if (inSection && line && !line.startsWith(\"#\") && !line.startsWith(\";\")) {\n const eq = line.indexOf(\"=\")\n if (eq > 0) {\n result[line.slice(0, eq).trim()] = line.slice(eq + 1).trim()\n }\n }\n }\n\n return found ? result : null\n}\n\n/**\n * Resolves AWS credentials using the standard provider chain:\n * 1. Environment variables (AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY)\n * 2. Shared credentials file (~/.aws/credentials, respects AWS_PROFILE)\n *\n * Returns undefined when no credentials are found — callers should let aws4 sign\n * with anonymous credentials or throw a descriptive error as appropriate.\n */\nexport function resolveAwsCredentials(): AwsCredentials | undefined {\n if (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) {\n return {\n accessKeyId: process.env.AWS_ACCESS_KEY_ID,\n secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,\n sessionToken: process.env.AWS_SESSION_TOKEN || undefined,\n }\n }\n\n try {\n const profile = process.env.AWS_PROFILE ?? \"default\"\n const credsPath = path.join(os.homedir(), \".aws\", \"credentials\")\n const raw = fs.readFileSync(credsPath, \"utf8\")\n const section = parseIniSection(raw, profile)\n if (section?.aws_access_key_id && section?.aws_secret_access_key) {\n return {\n accessKeyId: section.aws_access_key_id,\n secretAccessKey: section.aws_secret_access_key,\n sessionToken: section.aws_session_token || undefined,\n }\n }\n } catch {\n // file absent or unreadable — fall through\n }\n\n return undefined\n}\n"]}

View file

@ -0,0 +1,24 @@
import { BaseS3Options } from "builder-util-runtime";
import { PublishContext, UploadTask } from "..";
import { Publisher } from "../publisher";
import type { AwsCredentials } from "./awsCredentials";
export interface S3UploadConfig {
region: string;
endpoint?: string;
forcePathStyle?: boolean;
credentials?: AwsCredentials;
}
export interface S3UploadExtraParams {
acl?: string;
storageClass?: string;
serverSideEncryption?: string;
}
export declare abstract class BaseS3Publisher extends Publisher {
private readonly options;
protected constructor(context: PublishContext, options: BaseS3Options);
protected abstract getBucketName(): string;
abstract getS3UploadConfig(): S3UploadConfig;
getUploadExtraParams(): S3UploadExtraParams;
upload(task: UploadTask): Promise<any>;
toString(): string;
}

View file

@ -0,0 +1,61 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseS3Publisher = void 0;
const builder_util_1 = require("builder-util");
const promises_1 = require("fs/promises");
const path = require("path");
const publisher_1 = require("../publisher");
const s3UploadHelper_1 = require("./s3UploadHelper");
class BaseS3Publisher extends publisher_1.Publisher {
constructor(context, options) {
super(context);
this.options = options;
}
getUploadExtraParams() {
var _a;
return {
acl: this.options.acl !== null ? ((_a = this.options.acl) !== null && _a !== void 0 ? _a : "public-read") : undefined,
};
}
// http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/s3-example-creating-buckets.html
async upload(task) {
const fileName = path.basename(task.file);
const cancellationToken = this.context.cancellationToken;
const key = (this.options.path == null ? "" : `${this.options.path}/`) + fileName;
if (process.env.__TEST_S3_PUBLISHER__ != null) {
const testFile = path.join(process.env.__TEST_S3_PUBLISHER__, key);
await (0, promises_1.mkdir)(path.dirname(testFile), { recursive: true });
await (0, promises_1.symlink)(task.file, testFile);
return;
}
this.createProgressBar(fileName, -1);
const config = this.getS3UploadConfig();
const extraParams = this.getUploadExtraParams();
return await cancellationToken.createPromise((resolve, reject, onCancel) => {
const { req, done } = (0, s3UploadHelper_1.startS3PutObject)({
bucket: this.getBucketName(),
key,
file: task.file,
contentType: (0, s3UploadHelper_1.getS3ContentType)(task.file),
...config,
...extraParams,
});
onCancel(() => req.destroy());
done
.then(() => {
try {
builder_util_1.log.debug({ provider: this.providerName, file: fileName, bucket: this.getBucketName() }, "uploaded");
}
finally {
resolve(undefined);
}
})
.catch(reject);
});
}
toString() {
return `${this.providerName} (bucket: ${this.getBucketName()})`;
}
}
exports.BaseS3Publisher = BaseS3Publisher;
//# sourceMappingURL=baseS3Publisher.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"baseS3Publisher.js","sourceRoot":"","sources":["../../src/s3/baseS3Publisher.ts"],"names":[],"mappings":";;;AAAA,+CAAkC;AAElC,0CAA4C;AAC5C,6BAA4B;AAE5B,4CAAwC;AAExC,qDAAqE;AAerE,MAAsB,eAAgB,SAAQ,qBAAS;IACrD,YACE,OAAuB,EACN,OAAsB;QAEvC,KAAK,CAAC,OAAO,CAAC,CAAA;QAFG,YAAO,GAAP,OAAO,CAAe;IAGzC,CAAC;IAMM,oBAAoB;;QACzB,OAAO;YACL,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,MAAA,IAAI,CAAC,OAAO,CAAC,GAAG,mCAAI,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS;SACjF,CAAA;IACH,CAAC;IAED,oGAAoG;IACpG,KAAK,CAAC,MAAM,CAAC,IAAgB;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACzC,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAA;QACxD,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAA;QAEjF,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,IAAI,EAAE,CAAC;YAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAA;YAClE,MAAM,IAAA,gBAAK,EAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YACxD,MAAM,IAAA,kBAAO,EAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;YAClC,OAAM;QACR,CAAC;QAED,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAA;QAEpC,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAA;QACvC,MAAM,WAAW,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAA;QAE/C,OAAO,MAAM,iBAAiB,CAAC,aAAa,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;YACzE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,IAAA,iCAAgB,EAAC;gBACrC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE;gBAC5B,GAAG;gBACH,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAA,iCAAgB,EAAC,IAAI,CAAC,IAAI,CAAC;gBACxC,GAAG,MAAM;gBACT,GAAG,WAAW;aACf,CAAC,CAAA;YAEF,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;YAE7B,IAAI;iBACD,IAAI,CAAC,GAAG,EAAE;gBACT,IAAI,CAAC;oBACH,kBAAG,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,EAAE,EAAE,UAAU,CAAC,CAAA;gBACtG,CAAC;wBAAS,CAAC;oBACT,OAAO,CAAC,SAAS,CAAC,CAAA;gBACpB,CAAC;YACH,CAAC,CAAC;iBACD,KAAK,CAAC,MAAM,CAAC,CAAA;QAClB,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,QAAQ;QACN,OAAO,GAAG,IAAI,CAAC,YAAY,aAAa,IAAI,CAAC,aAAa,EAAE,GAAG,CAAA;IACjE,CAAC;CACF;AA/DD,0CA+DC","sourcesContent":["import { log } from \"builder-util\"\nimport { BaseS3Options } from \"builder-util-runtime\"\nimport { mkdir, symlink } from \"fs/promises\"\nimport * as path from \"path\"\nimport { PublishContext, UploadTask } from \"..\"\nimport { Publisher } from \"../publisher\"\nimport type { AwsCredentials } from \"./awsCredentials\"\nimport { getS3ContentType, startS3PutObject } from \"./s3UploadHelper\"\n\nexport interface S3UploadConfig {\n region: string\n endpoint?: string\n forcePathStyle?: boolean\n credentials?: AwsCredentials\n}\n\nexport interface S3UploadExtraParams {\n acl?: string\n storageClass?: string\n serverSideEncryption?: string\n}\n\nexport abstract class BaseS3Publisher extends Publisher {\n protected constructor(\n context: PublishContext,\n private readonly options: BaseS3Options\n ) {\n super(context)\n }\n\n protected abstract getBucketName(): string\n\n public abstract getS3UploadConfig(): S3UploadConfig\n\n public getUploadExtraParams(): S3UploadExtraParams {\n return {\n acl: this.options.acl !== null ? (this.options.acl ?? \"public-read\") : undefined,\n }\n }\n\n // http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/s3-example-creating-buckets.html\n async upload(task: UploadTask): Promise<any> {\n const fileName = path.basename(task.file)\n const cancellationToken = this.context.cancellationToken\n const key = (this.options.path == null ? \"\" : `${this.options.path}/`) + fileName\n\n if (process.env.__TEST_S3_PUBLISHER__ != null) {\n const testFile = path.join(process.env.__TEST_S3_PUBLISHER__, key)\n await mkdir(path.dirname(testFile), { recursive: true })\n await symlink(task.file, testFile)\n return\n }\n\n this.createProgressBar(fileName, -1)\n\n const config = this.getS3UploadConfig()\n const extraParams = this.getUploadExtraParams()\n\n return await cancellationToken.createPromise((resolve, reject, onCancel) => {\n const { req, done } = startS3PutObject({\n bucket: this.getBucketName(),\n key,\n file: task.file,\n contentType: getS3ContentType(task.file),\n ...config,\n ...extraParams,\n })\n\n onCancel(() => req.destroy())\n\n done\n .then(() => {\n try {\n log.debug({ provider: this.providerName, file: fileName, bucket: this.getBucketName() }, \"uploaded\")\n } finally {\n resolve(undefined)\n }\n })\n .catch(reject)\n })\n }\n\n toString() {\n return `${this.providerName} (bucket: ${this.getBucketName()})`\n }\n}\n"]}

View file

@ -0,0 +1,8 @@
/**
* Resolves the AWS region for a bucket via the S3 GetBucketLocation API (SigV4-signed).
* Uses path-style endpoint so dotted bucket names pass TLS hostname validation.
* Credentials are resolved via the standard provider chain (env vars ~/.aws/credentials).
* AWS returns an empty LocationConstraint element for us-east-1 (the implicit default region).
* Mirrors the behaviour of the `get-bucket-location` app-builder subcommand.
*/
export declare function getBucketLocation(bucket: string): Promise<string>;

View file

@ -0,0 +1,71 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getBucketLocation = getBucketLocation;
const aws4_1 = require("aws4");
const https_1 = require("https");
const awsCredentials_1 = require("./awsCredentials");
/**
* Resolves the AWS region for a bucket via the S3 GetBucketLocation API (SigV4-signed).
* Uses path-style endpoint so dotted bucket names pass TLS hostname validation.
* Credentials are resolved via the standard provider chain (env vars ~/.aws/credentials).
* AWS returns an empty LocationConstraint element for us-east-1 (the implicit default region).
* Mirrors the behaviour of the `get-bucket-location` app-builder subcommand.
*/
function getBucketLocation(bucket) {
return new Promise((resolve, reject) => {
let settled = false;
const settle = (fn, v) => {
if (!settled) {
settled = true;
fn(v);
}
};
const opts = (0, aws4_1.sign)({
service: "s3",
region: "us-east-1",
method: "GET",
host: "s3.amazonaws.com",
path: `/${bucket}?location`,
}, (0, awsCredentials_1.resolveAwsCredentials)());
const req = (0, https_1.request)({
hostname: opts.host,
path: opts.path,
method: opts.method,
headers: opts.headers,
}, res => {
let body = "";
let bodySize = 0;
const MAX_BODY = 65536;
res.on("data", (chunk) => {
bodySize += chunk.length;
if (bodySize > MAX_BODY) {
req.destroy();
settle(reject, new Error("GetBucketLocation response too large"));
return;
}
body += chunk;
});
res.on("end", () => {
if (res.statusCode !== 200) {
settle(reject, new Error(`GetBucketLocation failed (HTTP ${res.statusCode}): ${body}`));
return;
}
// Response: <LocationConstraint>us-west-2</LocationConstraint> or empty element for us-east-1
const match = body.match(/<LocationConstraint[^>]*>([^<]*)<\/LocationConstraint>/);
const rawRegion = (match === null || match === void 0 ? void 0 : match[1]) || "";
// "EU" is the only non-standard token GetBucketLocation ever returns — a legacy alias
// for eu-west-1 used by buckets created before August 2014. Simple lowercasing is not
// sufficient because "eu" is not a valid region identifier.
const region = rawRegion === "EU" ? "eu-west-1" : rawRegion;
if (region !== "" && !/^[a-z][a-z0-9-]+$/.test(region)) {
settle(reject, new Error(`GetBucketLocation returned unexpected region: ${region}`));
return;
}
settle(resolve, region || "us-east-1");
});
});
req.on("error", e => settle(reject, e));
req.end();
});
}
//# sourceMappingURL=bucketLocation.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"bucketLocation.js","sourceRoot":"","sources":["../../src/s3/bucketLocation.ts"],"names":[],"mappings":"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","sourcesContent":["import { sign } from \"aws4\"\nimport { request } from \"https\"\nimport { resolveAwsCredentials } from \"./awsCredentials\"\n\n/**\n * Resolves the AWS region for a bucket via the S3 GetBucketLocation API (SigV4-signed).\n * Uses path-style endpoint so dotted bucket names pass TLS hostname validation.\n * Credentials are resolved via the standard provider chain (env vars → ~/.aws/credentials).\n * AWS returns an empty LocationConstraint element for us-east-1 (the implicit default region).\n * Mirrors the behaviour of the `get-bucket-location` app-builder subcommand.\n */\nexport function getBucketLocation(bucket: string): Promise<string> {\n return new Promise((resolve, reject) => {\n let settled = false\n const settle = (fn: (v: any) => void, v: any) => {\n if (!settled) {\n settled = true\n fn(v)\n }\n }\n\n const opts = sign(\n {\n service: \"s3\",\n region: \"us-east-1\",\n method: \"GET\",\n host: \"s3.amazonaws.com\",\n path: `/${bucket}?location`,\n },\n resolveAwsCredentials()\n )\n\n const req = request(\n {\n hostname: opts.host,\n path: opts.path,\n method: opts.method,\n headers: opts.headers,\n },\n res => {\n let body = \"\"\n let bodySize = 0\n const MAX_BODY = 65536\n res.on(\"data\", (chunk: string) => {\n bodySize += chunk.length\n if (bodySize > MAX_BODY) {\n req.destroy()\n settle(reject, new Error(\"GetBucketLocation response too large\"))\n return\n }\n body += chunk\n })\n res.on(\"end\", () => {\n if (res.statusCode !== 200) {\n settle(reject, new Error(`GetBucketLocation failed (HTTP ${res.statusCode}): ${body}`))\n return\n }\n // Response: <LocationConstraint>us-west-2</LocationConstraint> or empty element for us-east-1\n const match = body.match(/<LocationConstraint[^>]*>([^<]*)<\\/LocationConstraint>/)\n const rawRegion = match?.[1] || \"\"\n // \"EU\" is the only non-standard token GetBucketLocation ever returns — a legacy alias\n // for eu-west-1 used by buckets created before August 2014. Simple lowercasing is not\n // sufficient because \"eu\" is not a valid region identifier.\n const region = rawRegion === \"EU\" ? \"eu-west-1\" : rawRegion\n if (region !== \"\" && !/^[a-z][a-z0-9-]+$/.test(region)) {\n settle(reject, new Error(`GetBucketLocation returned unexpected region: ${region}`))\n return\n }\n settle(resolve, region || \"us-east-1\")\n })\n }\n )\n\n req.on(\"error\", e => settle(reject, e))\n req.end()\n })\n}\n"]}

View file

@ -0,0 +1,13 @@
import { S3Options } from "builder-util-runtime";
import { PublishContext } from "..";
import { BaseS3Publisher, S3UploadConfig, S3UploadExtraParams } from "./baseS3Publisher";
export declare class S3Publisher extends BaseS3Publisher {
private readonly info;
readonly providerName = "s3";
constructor(context: PublishContext, info: S3Options);
static checkAndResolveOptions(options: S3Options, channelFromAppVersion: string | null, errorIfCannot: boolean): Promise<void>;
protected getBucketName(): string;
getS3UploadConfig(): S3UploadConfig;
getUploadExtraParams(): S3UploadExtraParams;
toString(): string;
}

View file

@ -0,0 +1,72 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.S3Publisher = void 0;
const builder_util_1 = require("builder-util");
const awsCredentials_1 = require("./awsCredentials");
const baseS3Publisher_1 = require("./baseS3Publisher");
const bucketLocation_1 = require("./bucketLocation");
class S3Publisher extends baseS3Publisher_1.BaseS3Publisher {
constructor(context, info) {
super(context, info);
this.info = info;
this.providerName = "s3";
}
static async checkAndResolveOptions(options, channelFromAppVersion, errorIfCannot) {
const bucket = options.bucket;
if (bucket == null) {
throw new builder_util_1.InvalidConfigurationError(`Please specify "bucket" for "s3" publish provider`);
}
if (options.endpoint == null && bucket.includes(".") && options.region == null) {
// on dotted bucket names, we need to use a path-based endpoint URL. Path-based endpoint URLs need to include the region.
try {
options.region = await (0, bucketLocation_1.getBucketLocation)(bucket);
}
catch (e) {
if (errorIfCannot) {
throw e;
}
else {
builder_util_1.log.warn(`cannot compute region for bucket (required because on dotted bucket names, we need to use a path-based endpoint URL): ${e}`);
}
}
}
if (options.channel == null && channelFromAppVersion != null) {
options.channel = channelFromAppVersion;
}
if (options.endpoint != null && options.endpoint.endsWith("/")) {
;
options.endpoint = options.endpoint.slice(0, -1);
}
}
getBucketName() {
return this.info.bucket;
}
getS3UploadConfig() {
var _a, _b, _c;
return {
region: (_a = this.info.region) !== null && _a !== void 0 ? _a : "us-east-1",
endpoint: (_b = this.info.endpoint) !== null && _b !== void 0 ? _b : undefined,
forcePathStyle: (_c = this.info.forcePathStyle) !== null && _c !== void 0 ? _c : undefined,
credentials: (0, awsCredentials_1.resolveAwsCredentials)(),
};
}
getUploadExtraParams() {
var _a, _b;
const base = super.getUploadExtraParams();
return {
...base,
storageClass: (_a = this.info.storageClass) !== null && _a !== void 0 ? _a : undefined,
serverSideEncryption: (_b = this.info.encryption) !== null && _b !== void 0 ? _b : undefined,
};
}
toString() {
const result = super.toString();
const endpoint = this.info.endpoint;
if (endpoint != null) {
return result.substring(0, result.length - 1) + `, endpoint: ${endpoint})`;
}
return result;
}
}
exports.S3Publisher = S3Publisher;
//# sourceMappingURL=s3Publisher.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"s3Publisher.js","sourceRoot":"","sources":["../../src/s3/s3Publisher.ts"],"names":[],"mappings":";;;AAAA,+CAA6D;AAG7D,qDAAwD;AACxD,uDAAwF;AACxF,qDAAoD;AAEpD,MAAa,WAAY,SAAQ,iCAAe;IAG9C,YACE,OAAuB,EACN,IAAe;QAEhC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;QAFH,SAAI,GAAJ,IAAI,CAAW;QAJzB,iBAAY,GAAG,IAAI,CAAA;IAO5B,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,OAAkB,EAAE,qBAAoC,EAAE,aAAsB;QAClH,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;QAC7B,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,MAAM,IAAI,wCAAyB,CAAC,mDAAmD,CAAC,CAAA;QAC1F,CAAC;QAED,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;YAC/E,yHAAyH;YACzH,IAAI,CAAC;gBACH,OAAO,CAAC,MAAM,GAAG,MAAM,IAAA,kCAAiB,EAAC,MAAM,CAAC,CAAA;YAClD,CAAC;YAAC,OAAO,CAAM,EAAE,CAAC;gBAChB,IAAI,aAAa,EAAE,CAAC;oBAClB,MAAM,CAAC,CAAA;gBACT,CAAC;qBAAM,CAAC;oBACN,kBAAG,CAAC,IAAI,CAAC,yHAAyH,CAAC,EAAE,CAAC,CAAA;gBACxI,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,OAAO,CAAC,OAAO,IAAI,IAAI,IAAI,qBAAqB,IAAI,IAAI,EAAE,CAAC;YAC7D,OAAO,CAAC,OAAO,GAAG,qBAAqB,CAAA;QACzC,CAAC;QAED,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/D,CAAC;YAAC,OAAe,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAC5D,CAAC;IACH,CAAC;IAES,aAAa;QACrB,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAA;IACzB,CAAC;IAEM,iBAAiB;;QACtB,OAAO;YACL,MAAM,EAAE,MAAA,IAAI,CAAC,IAAI,CAAC,MAAM,mCAAI,WAAW;YACvC,QAAQ,EAAE,MAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,mCAAI,SAAS;YACzC,cAAc,EAAE,MAAA,IAAI,CAAC,IAAI,CAAC,cAAc,mCAAI,SAAS;YACrD,WAAW,EAAE,IAAA,sCAAqB,GAAE;SACrC,CAAA;IACH,CAAC;IAEM,oBAAoB;;QACzB,MAAM,IAAI,GAAG,KAAK,CAAC,oBAAoB,EAAE,CAAA;QACzC,OAAO;YACL,GAAG,IAAI;YACP,YAAY,EAAE,MAAA,IAAI,CAAC,IAAI,CAAC,YAAY,mCAAI,SAAS;YACjD,oBAAoB,EAAE,MAAA,IAAI,CAAC,IAAI,CAAC,UAAU,mCAAI,SAAS;SACxD,CAAA;IACH,CAAC;IAED,QAAQ;QACN,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAA;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAA;QACnC,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;YACrB,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,eAAe,QAAQ,GAAG,CAAA;QAC5E,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC;CACF;AApED,kCAoEC","sourcesContent":["import { InvalidConfigurationError, log } from \"builder-util\"\nimport { S3Options } from \"builder-util-runtime\"\nimport { PublishContext } from \"..\"\nimport { resolveAwsCredentials } from \"./awsCredentials\"\nimport { BaseS3Publisher, S3UploadConfig, S3UploadExtraParams } from \"./baseS3Publisher\"\nimport { getBucketLocation } from \"./bucketLocation\"\n\nexport class S3Publisher extends BaseS3Publisher {\n readonly providerName = \"s3\"\n\n constructor(\n context: PublishContext,\n private readonly info: S3Options\n ) {\n super(context, info)\n }\n\n static async checkAndResolveOptions(options: S3Options, channelFromAppVersion: string | null, errorIfCannot: boolean) {\n const bucket = options.bucket\n if (bucket == null) {\n throw new InvalidConfigurationError(`Please specify \"bucket\" for \"s3\" publish provider`)\n }\n\n if (options.endpoint == null && bucket.includes(\".\") && options.region == null) {\n // on dotted bucket names, we need to use a path-based endpoint URL. Path-based endpoint URLs need to include the region.\n try {\n options.region = await getBucketLocation(bucket)\n } catch (e: any) {\n if (errorIfCannot) {\n throw e\n } else {\n log.warn(`cannot compute region for bucket (required because on dotted bucket names, we need to use a path-based endpoint URL): ${e}`)\n }\n }\n }\n\n if (options.channel == null && channelFromAppVersion != null) {\n options.channel = channelFromAppVersion\n }\n\n if (options.endpoint != null && options.endpoint.endsWith(\"/\")) {\n ;(options as any).endpoint = options.endpoint.slice(0, -1)\n }\n }\n\n protected getBucketName(): string {\n return this.info.bucket\n }\n\n public getS3UploadConfig(): S3UploadConfig {\n return {\n region: this.info.region ?? \"us-east-1\",\n endpoint: this.info.endpoint ?? undefined,\n forcePathStyle: this.info.forcePathStyle ?? undefined,\n credentials: resolveAwsCredentials(),\n }\n }\n\n public getUploadExtraParams(): S3UploadExtraParams {\n const base = super.getUploadExtraParams()\n return {\n ...base,\n storageClass: this.info.storageClass ?? undefined,\n serverSideEncryption: this.info.encryption ?? undefined,\n }\n }\n\n toString() {\n const result = super.toString()\n const endpoint = this.info.endpoint\n if (endpoint != null) {\n return result.substring(0, result.length - 1) + `, endpoint: ${endpoint})`\n }\n return result\n }\n}\n"]}

View file

@ -0,0 +1,31 @@
import * as http from "http";
import type { AwsCredentials } from "./awsCredentials";
export interface S3PutObjectParams {
bucket: string;
key: string;
file: string;
region: string;
endpoint?: string;
forcePathStyle?: boolean;
contentType: string;
acl?: string;
storageClass?: string;
serverSideEncryption?: string;
credentials?: AwsCredentials;
}
/**
* Uploads a file to S3 (or S3-compatible storage) using a single PutObject request.
* Suitable for files up to 5 GB the S3 single-part upload limit.
* Returns the underlying ClientRequest so callers can abort mid-flight.
* Mirrors the behaviour of the `publish-s3` app-builder subcommand.
*/
export declare function startS3PutObject(params: S3PutObjectParams): {
req: http.ClientRequest;
done: Promise<void>;
};
/**
* Returns the MIME content-type for an S3 upload key, using explicit overrides
* for formats that mime databases commonly misidentify. Mirrors the Go binary's
* getContentType() function in pkg/publisher/s3.go.
*/
export declare function getS3ContentType(file: string): string;

View file

@ -0,0 +1,117 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.startS3PutObject = startS3PutObject;
exports.getS3ContentType = getS3ContentType;
const aws4_1 = require("aws4");
const fs = require("fs");
const http = require("http");
const https = require("https");
const mime = require("mime");
const path = require("path");
/**
* Uploads a file to S3 (or S3-compatible storage) using a single PutObject request.
* Suitable for files up to 5 GB the S3 single-part upload limit.
* Returns the underlying ClientRequest so callers can abort mid-flight.
* Mirrors the behaviour of the `publish-s3` app-builder subcommand.
*/
function startS3PutObject(params) {
const stat = fs.statSync(params.file);
const region = params.region;
let hostname;
let rawPath;
let isHttp = false;
if (params.endpoint != null) {
const u = new URL(params.endpoint);
isHttp = u.protocol === "http:";
hostname = u.port ? `${u.hostname}:${u.port}` : u.hostname;
// path-style for custom endpoints (handles buckets whose names contain dots)
rawPath = `/${params.bucket}/${params.key}`;
}
else if (params.forcePathStyle) {
hostname = `s3.${region}.amazonaws.com`;
rawPath = `/${params.bucket}/${params.key}`;
}
else {
hostname = `${params.bucket}.s3.${region}.amazonaws.com`;
rawPath = `/${params.key}`;
}
// URL-encode each path segment individually so forward-slashes in keys are preserved
const urlPath = "/" + rawPath.slice(1).split("/").map(encodeURIComponent).join("/");
const headers = {
"Content-Type": params.contentType,
"Content-Length": String(stat.size),
// Declare the payload as unsigned so aws4 signs over this literal string
// rather than defaulting to SHA256("") — which would not match the streamed body.
"x-amz-content-sha256": "UNSIGNED-PAYLOAD",
};
if (params.acl != null) {
headers["x-amz-acl"] = params.acl;
}
if (params.storageClass != null) {
headers["x-amz-storage-class"] = params.storageClass;
}
if (params.serverSideEncryption != null) {
headers["x-amz-server-side-encryption"] = params.serverSideEncryption;
}
const signed = (0, aws4_1.sign)({
service: "s3",
region,
method: "PUT",
host: hostname,
path: urlPath,
headers,
}, params.credentials);
const transport = isHttp ? http : https;
let resolvePromise;
let rejectPromise;
const done = new Promise((res, rej) => {
resolvePromise = res;
rejectPromise = rej;
});
const req = transport.request({
hostname: hostname.split(":")[0],
port: hostname.includes(":") ? Number(hostname.split(":")[1]) : undefined,
path: urlPath,
method: "PUT",
headers: signed.headers,
}, res => {
if (res.statusCode === 200) {
res.resume();
res.on("end", resolvePromise);
}
else {
let body = "";
let bodySize = 0;
const MAX_ERROR_BODY = 65536;
res.on("data", (chunk) => {
bodySize += chunk.length;
if (bodySize <= MAX_ERROR_BODY) {
body += chunk;
}
});
res.on("end", () => rejectPromise(new Error(`S3 PutObject failed (HTTP ${res.statusCode}): ${body.slice(0, 512)}`)));
}
});
req.on("error", rejectPromise);
const fileStream = fs.createReadStream(params.file);
fileStream.on("error", rejectPromise);
req.on("close", () => fileStream.destroy());
fileStream.pipe(req);
return { req, done };
}
/**
* Returns the MIME content-type for an S3 upload key, using explicit overrides
* for formats that mime databases commonly misidentify. Mirrors the Go binary's
* getContentType() function in pkg/publisher/s3.go.
*/
function getS3ContentType(file) {
var _a, _b;
const ext = path.extname(file).toLowerCase();
const overrides = {
".appimage": "application/vnd.appimage",
".blockmap": "application/gzip",
".snap": "application/vnd.snap",
};
return (_b = (_a = overrides[ext]) !== null && _a !== void 0 ? _a : mime.getType(file)) !== null && _b !== void 0 ? _b : "application/octet-stream";
}
//# sourceMappingURL=s3UploadHelper.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,11 @@
import { SpacesOptions } from "builder-util-runtime";
import { PublishContext } from "../";
import { BaseS3Publisher, S3UploadConfig } from "./baseS3Publisher";
export declare class SpacesPublisher extends BaseS3Publisher {
private readonly info;
readonly providerName = "spaces";
constructor(context: PublishContext, info: SpacesOptions);
static checkAndResolveOptions(options: SpacesOptions, channelFromAppVersion: string | null, _errorIfCannot: boolean): Promise<void>;
protected getBucketName(): string;
getS3UploadConfig(): S3UploadConfig;
}

View file

@ -0,0 +1,45 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SpacesPublisher = void 0;
const builder_util_1 = require("builder-util");
const baseS3Publisher_1 = require("./baseS3Publisher");
class SpacesPublisher extends baseS3Publisher_1.BaseS3Publisher {
constructor(context, info) {
super(context, info);
this.info = info;
this.providerName = "spaces";
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
static checkAndResolveOptions(options, channelFromAppVersion, _errorIfCannot) {
if (options.name == null) {
throw new builder_util_1.InvalidConfigurationError(`Please specify "name" for "spaces" publish provider (see https://www.electron.build/publish#spacesoptions)`);
}
if (options.region == null) {
throw new builder_util_1.InvalidConfigurationError(`Please specify "region" for "spaces" publish provider (see https://www.electron.build/publish#spacesoptions)`);
}
if (options.channel == null && channelFromAppVersion != null) {
options.channel = channelFromAppVersion;
}
return Promise.resolve();
}
getBucketName() {
return this.info.name;
}
getS3UploadConfig() {
const accessKey = process.env.DO_KEY_ID;
const secretKey = process.env.DO_SECRET_KEY;
if ((0, builder_util_1.isEmptyOrSpaces)(accessKey)) {
throw new builder_util_1.InvalidConfigurationError("Please set env DO_KEY_ID (see https://www.electron.build/publish#spacesoptions)");
}
if ((0, builder_util_1.isEmptyOrSpaces)(secretKey)) {
throw new builder_util_1.InvalidConfigurationError("Please set env DO_SECRET_KEY (see https://www.electron.build/publish#spacesoptions)");
}
return {
region: this.info.region,
endpoint: `https://${this.info.region}.digitaloceanspaces.com`,
credentials: { accessKeyId: accessKey, secretAccessKey: secretKey },
};
}
}
exports.SpacesPublisher = SpacesPublisher;
//# sourceMappingURL=spacesPublisher.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"spacesPublisher.js","sourceRoot":"","sources":["../../src/s3/spacesPublisher.ts"],"names":[],"mappings":";;;AAAA,+CAAyE;AAGzE,uDAAmE;AAEnE,MAAa,eAAgB,SAAQ,iCAAe;IAGlD,YACE,OAAuB,EACN,IAAmB;QAEpC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;QAFH,SAAI,GAAJ,IAAI,CAAe;QAJ7B,iBAAY,GAAG,QAAQ,CAAA;IAOhC,CAAC;IAED,6DAA6D;IAC7D,MAAM,CAAC,sBAAsB,CAAC,OAAsB,EAAE,qBAAoC,EAAE,cAAuB;QACjH,IAAI,OAAO,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;YACzB,MAAM,IAAI,wCAAyB,CAAC,4GAA4G,CAAC,CAAA;QACnJ,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;YAC3B,MAAM,IAAI,wCAAyB,CAAC,8GAA8G,CAAC,CAAA;QACrJ,CAAC;QAED,IAAI,OAAO,CAAC,OAAO,IAAI,IAAI,IAAI,qBAAqB,IAAI,IAAI,EAAE,CAAC;YAC7D,OAAO,CAAC,OAAO,GAAG,qBAAqB,CAAA;QACzC,CAAC;QACD,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;IAC1B,CAAC;IAES,aAAa;QACrB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAA;IACvB,CAAC;IAEM,iBAAiB;QACtB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAA;QACvC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAA;QAC3C,IAAI,IAAA,8BAAe,EAAC,SAAS,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,wCAAyB,CAAC,iFAAiF,CAAC,CAAA;QACxH,CAAC;QACD,IAAI,IAAA,8BAAe,EAAC,SAAS,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,wCAAyB,CAAC,qFAAqF,CAAC,CAAA;QAC5H,CAAC;QACD,OAAO;YACL,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;YACxB,QAAQ,EAAE,WAAW,IAAI,CAAC,IAAI,CAAC,MAAM,yBAAyB;YAC9D,WAAW,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,EAAE;SACpE,CAAA;IACH,CAAC;CACF;AA5CD,0CA4CC","sourcesContent":["import { InvalidConfigurationError, isEmptyOrSpaces } from \"builder-util\"\nimport { SpacesOptions } from \"builder-util-runtime\"\nimport { PublishContext } from \"../\"\nimport { BaseS3Publisher, S3UploadConfig } from \"./baseS3Publisher\"\n\nexport class SpacesPublisher extends BaseS3Publisher {\n readonly providerName = \"spaces\"\n\n constructor(\n context: PublishContext,\n private readonly info: SpacesOptions\n ) {\n super(context, info)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n static checkAndResolveOptions(options: SpacesOptions, channelFromAppVersion: string | null, _errorIfCannot: boolean) {\n if (options.name == null) {\n throw new InvalidConfigurationError(`Please specify \"name\" for \"spaces\" publish provider (see https://www.electron.build/publish#spacesoptions)`)\n }\n if (options.region == null) {\n throw new InvalidConfigurationError(`Please specify \"region\" for \"spaces\" publish provider (see https://www.electron.build/publish#spacesoptions)`)\n }\n\n if (options.channel == null && channelFromAppVersion != null) {\n options.channel = channelFromAppVersion\n }\n return Promise.resolve()\n }\n\n protected getBucketName(): string {\n return this.info.name\n }\n\n public getS3UploadConfig(): S3UploadConfig {\n const accessKey = process.env.DO_KEY_ID\n const secretKey = process.env.DO_SECRET_KEY\n if (isEmptyOrSpaces(accessKey)) {\n throw new InvalidConfigurationError(\"Please set env DO_KEY_ID (see https://www.electron.build/publish#spacesoptions)\")\n }\n if (isEmptyOrSpaces(secretKey)) {\n throw new InvalidConfigurationError(\"Please set env DO_SECRET_KEY (see https://www.electron.build/publish#spacesoptions)\")\n }\n return {\n region: this.info.region,\n endpoint: `https://${this.info.region}.digitaloceanspaces.com`,\n credentials: { accessKeyId: accessKey, secretAccessKey: secretKey },\n }\n }\n}\n"]}