picgo-plugin-s3
Version:
picgo amazon s3 uploader
295 lines (294 loc) • 9.54 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OutputURLGenerator = exports.FileNameGenerator = void 0;
exports.extractInfo = extractInfo;
exports.getProxyAgent = getProxyAgent;
const crypto_1 = __importDefault(require("crypto"));
const path_1 = __importDefault(require("path"));
const file_type_1 = require("file-type");
const mime_1 = __importDefault(require("mime"));
const hpagent_1 = require("hpagent");
class Generateor {
constructor() {
this.date = new Date();
}
year() {
return this.date.getFullYear().toString();
}
month() {
return (this.date.getMonth() + 1).toString().padStart(2, '0');
}
day() {
return this.date.getDate().toString().padStart(2, '0');
}
hour() {
return this.date.getHours().toString().padStart(2, '0');
}
minute() {
return this.date.getMinutes().toString().padStart(2, '0');
}
second() {
return this.date.getSeconds().toString().padStart(2, '0');
}
millisecond() {
return this.date.getMilliseconds().toString().padStart(3, '0');
}
timestamp() {
return Math.floor(this.date.getTime() / 1000).toString();
}
timestampMS() {
return this.date.getTime().toString();
}
format(s) {
if (!s) {
return '';
}
const formatters = {
year: () => this.year(),
month: () => this.month(),
day: () => this.day(),
hour: () => this.hour(),
minute: () => this.minute(),
second: () => this.second(),
millisecond: () => this.millisecond(),
timestamp: () => this.timestamp(),
timestampMS: () => this.timestampMS(),
};
return Object.entries(formatters).reduce((result, [key, formatter]) => result.replace(new RegExp(`{${key}}`, 'g'), formatter()), s);
}
}
class FileNameGenerator extends Generateor {
constructor(info) {
super();
this.info = info;
}
fullName() {
return this.info.fileName || "";
}
fileName() {
var _a;
if (!((_a = this.info) === null || _a === void 0 ? void 0 : _a.fileName)) {
return '';
}
const ext = this.info.extname || '';
return this.info.fileName.replace(new RegExp(`${ext}$`), '');
}
extName() {
var _a, _b;
return ((_b = (_a = this.info) === null || _a === void 0 ? void 0 : _a.extname) === null || _b === void 0 ? void 0 : _b.replace('.', '')) || '';
}
md5() {
return crypto_1.default.createHash("md5").update(this.imgBuffer()).digest("hex");
}
md5B64() {
return crypto_1.default
.createHash("md5")
.update(this.imgBuffer())
.digest("base64")
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=+$/, "");
}
md5B64Short() {
return crypto_1.default
.createHash("md5")
.update(this.imgBuffer())
.digest("base64")
.replace(/\+/g, "-")
.replace(/\//g, "_")
.slice(0, 7);
}
sha1() {
return crypto_1.default.createHash("sha1").update(this.imgBuffer()).digest("hex");
}
sha256() {
return crypto_1.default.createHash("sha256").update(this.imgBuffer()).digest("hex");
}
imgBuffer() {
return this.info.base64Image ? this.info.base64Image : (this.info.buffer || "");
}
format(s) {
if (!s) {
return this.fullName();
}
const formatters = {
fullName: () => this.fullName(),
fileName: () => this.fileName(),
extName: () => this.extName(),
md5: () => this.md5(),
md5B64: () => this.md5B64(),
md5B64Short: () => this.md5B64Short(),
sha1: () => this.sha1(),
sha256: () => this.sha256(),
};
return Object.entries(formatters).reduce((result, [key, formatter]) => result.replace(new RegExp(`{${key}}`, 'g'), formatter()), super.format(s));
}
}
exports.FileNameGenerator = FileNameGenerator;
class OutputURLGenerator extends Generateor {
constructor(config, info) {
super();
this._config = config;
this._info = info;
// parse the url from storage
const url = info.url || info.imgUrl || '';
try {
const u = new URL(url);
this._protocol = u.protocol;
this._host = u.hostname;
this._port = u.port;
this._path = u.pathname;
this._query = u.search;
this._hash = u.hash;
}
catch (e) {
console.error(`Failed to parse URL: ${url}`, e);
}
}
protocol() {
if (this._protocol) {
return this._protocol.replace(/(:)$/, '');
}
return "https";
}
host() {
return this._host;
}
port() {
return this._port;
}
path() {
return this._path.replace(/^(\/)/, '');
}
fileName() {
if (this._info.fileName) {
return this._info.fileName;
}
return path_1.default.basename(this.path());
}
extName() {
if (this._info.extname) {
return this._info.extname.replace(/^./, '');
}
return path_1.default.extname(this.path()).replace(/^./, '');
}
dir() {
return path_1.default.dirname(this.path());
}
originalURL() {
let url = this._info.url;
if (!url) {
url = this._info.imgUrl;
}
return url;
}
query() {
return this._query;
}
hash() {
return this._hash;
}
bucket() {
return this._config.bucketName;
}
legacyFormat() {
let url = this.originalURL();
let uploadPath = this._info.uploadPath || this.path();
if (this._config.urlPrefix) {
let urlPrefix = this._config.urlPrefix.replace(/\/?$/, "");
if (this._config.pathStyleAccess && !this._config.disableBucketPrefixToURL) {
urlPrefix += "/" + this._config.bucketName;
}
url = `${urlPrefix}/${uploadPath}`;
}
url = `${url}${this._config.urlSuffix || ''}`;
return url;
}
format() {
if (!this._config.outputURLPattern) {
return this.legacyFormat();
}
const formatters = {
protocol: () => this.protocol(),
host: () => this.host(),
port: () => this.port(),
dir: () => this.dir(),
fileName: () => this.fileName(),
path: () => this.path(),
extName: () => this.extName(),
query: () => this.query(),
hash: () => this.hash(),
bucket: () => this.bucket(),
};
return Object.entries(formatters).reduce((result, [key, formatter]) => {
const simplePattern = new RegExp(`{${key}}`, "g");
const advancedPattern = new RegExp(`{${key}:/(.*?)/(\\w)?,['"](.*)['"]}`, "g");
if (advancedPattern.test(result)) {
result = result.replace(advancedPattern, (match, p1, p2, p3) => {
const r = formatter();
return p2 ? r.replace(new RegExp(p1, p2), p3) : r;
});
}
else {
result = result.replace(simplePattern, formatter());
}
return result;
}, super.format(this._config.outputURLPattern));
}
}
exports.OutputURLGenerator = OutputURLGenerator;
async function extractInfo(info) {
var _a;
const result = {};
if (info.base64Image) {
const body = info.base64Image.replace(/^data:[/\w]+;base64,/, "");
result.contentType = (_a = info.base64Image.match(/[^:]\w+\/[\w-+\d.]+(?=;|,)/)) === null || _a === void 0 ? void 0 : _a[0];
result.body = Buffer.from(body, "base64");
result.contentEncoding = "base64";
}
else {
if (info.extname) {
result.contentType = mime_1.default.getType(info.extname);
}
result.body = info.buffer;
}
// fallback to detect from buffer
if (!result.contentType) {
const fileType = await (0, file_type_1.fromBuffer)(result.body);
result.contentType = fileType === null || fileType === void 0 ? void 0 : fileType.mime;
}
return result;
}
function formatHttpProxyURL(url = "") {
if (!url)
return "";
if (!/^https?:\/\//.test(url)) {
const [host, port] = url.split(":");
return `http://${host.replace("127.0.0.1", "localhost")}:${port}`;
}
try {
const { protocol, hostname, port } = new URL(url);
return `${protocol}//${hostname.replace("127.0.0.1", "localhost")}:${port}`;
}
catch (e) {
return "";
}
}
function getProxyAgent(proxy, sslEnabled, rejectUnauthorized) {
const formatedProxy = formatHttpProxyURL(proxy);
if (!formatedProxy) {
return undefined;
}
const Agent = sslEnabled ? hpagent_1.HttpsProxyAgent : hpagent_1.HttpProxyAgent;
const options = {
keepAlive: true,
keepAliveMsecs: 1000,
scheduling: "lifo",
rejectUnauthorized,
proxy: formatedProxy,
};
return new Agent(options);
}