@shencom/oss-upload
Version:
code upload to oss
897 lines (883 loc) • 30.4 kB
JavaScript
import { extname, basename, join, normalize } from 'path';
import log from '@shencom/npmlog';
import AliOSS from 'ali-oss';
import chalk from 'chalk';
import pLimit from 'p-limit';
import { execSync } from 'child_process';
import { statSync, existsSync, readFileSync } from 'fs';
import crypto from 'crypto';
import minimist from 'minimist';
import ora from 'ora';
import inquirer from 'inquirer';
import semver from 'semver';
import glob from 'glob';
import minimatch from 'minimatch';
import { homedir } from 'os';
import fs from 'fs-extra';
import dotenv from 'dotenv';
import boxen from 'boxen';
var version$1 = "2.7.1";
const _argv = minimist(process.argv);
const Mode = _argv._[2];
const Env = _argv.mode;
const isTst = Env === "tst";
const isUat = Env === "uat";
const isPro = Env === "production";
const isBuild = Mode === "build";
const isServe = Mode === "serve";
const isUpload = _argv.u;
const isDebug = _argv.debug;
const envName = `${isTst ? "\u6D4B\u8BD5" : isUat ? "UAT" : "\u6B63\u5F0F"}\u670D`;
const spinner = ora();
spinner.spinner = "clock";
function _branch() {
try {
return execSync("git symbolic-ref --short -q HEAD", { encoding: "utf8" }).replace("\n", "");
} catch (error) {
return "";
}
}
const branch = _branch();
function md5(val) {
const _md5 = crypto.createHash("md5");
const result = _md5.update(val).digest("hex");
return result.toLocaleUpperCase();
}
function getCliParam() {
const argvKey = Object.keys(_argv).filter((k) => k !== "_");
return argvKey.map((key) => `--${key} ${_argv[key]}`);
}
function confirm(message) {
return new Promise((resolve, reject) => {
inquirer.prompt({
type: "confirm",
name: "flag",
message: chalk.yellow(message),
default: true,
prefix: "\u26A0\uFE0F "
}).then((answers) => {
resolve(answers.flag);
}).catch(reject);
});
}
function verifyBuild() {
if (isUat && branch !== "uat") {
spinner.fail(chalk.red(" \u8BF7\u4F7F\u7528 uat \u5206\u652F\u6253\u5305UAT"));
return false;
}
if (isPro && branch !== "master") {
spinner.fail(chalk.red(" \u8BF7\u4F7F\u7528 master \u5206\u652F\u6253\u5305\u6B63\u5F0F\u670D"));
return false;
}
return true;
}
function isFile(filePath) {
try {
const isFile2 = statSync(filePath).isFile();
return isFile2;
} catch (error) {
return false;
}
}
function CheckEnvPath(envPath) {
if (!envPath)
return "";
const envPathExists = existsSync(envPath);
return envPathExists ? envPath : "";
}
function throwErr(prefix, message) {
log.error(prefix, message);
process.exit();
}
const versionReg = /\/(\d+(.\d+){0,3})\//;
const versionExec = (v) => versionReg.exec(v);
const versionSort = (v) => v.sort((a, b) => semver.compare(a, b, true));
const versionValid = (v) => semver.valid(semver.coerce(v || "", { loose: true }));
var utils = /*#__PURE__*/Object.freeze({
__proto__: null,
_argv: _argv,
Mode: Mode,
Env: Env,
isTst: isTst,
isUat: isUat,
isPro: isPro,
isBuild: isBuild,
isServe: isServe,
isUpload: isUpload,
isDebug: isDebug,
envName: envName,
spinner: spinner,
branch: branch,
md5: md5,
getCliParam: getCliParam,
confirm: confirm,
verifyBuild: verifyBuild,
isFile: isFile,
CheckEnvPath: CheckEnvPath,
throwErr: throwErr,
versionReg: versionReg,
versionExec: versionExec,
versionSort: versionSort,
versionValid: versionValid
});
var __defProp$2 = Object.defineProperty;
var __defProps$1 = Object.defineProperties;
var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols;
var __hasOwnProp$2 = Object.prototype.hasOwnProperty;
var __propIsEnum$2 = Object.prototype.propertyIsEnumerable;
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues$2 = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp$2.call(b, prop))
__defNormalProp$2(a, prop, b[prop]);
if (__getOwnPropSymbols$2)
for (var prop of __getOwnPropSymbols$2(b)) {
if (__propIsEnum$2.call(b, prop))
__defNormalProp$2(a, prop, b[prop]);
}
return a;
};
var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
function isOssPath(uploadPath, baseOssPath) {
if (uploadPath === baseOssPath)
return true;
const filePath = uploadPath.replace(baseOssPath, "");
return !!extname(filePath);
}
function fileStreamHandle(filePath) {
const isFiles = existsSync(filePath);
if (!isFiles)
return null;
const stream = readFileSync(filePath);
return { url: filePath, md5: md5(stream) };
}
function listIgnoreHandle(list = [], patterns = []) {
patterns.forEach((pattern) => {
list = minimatch.match(list, `!${pattern}`, {
matchBase: true
});
});
return list;
}
function getDirFilesPath(dirPath, ops) {
const files = glob.sync(`${dirPath}/**`, __spreadProps$1(__spreadValues$2({}, ops), { nodir: true }));
return files;
}
function filterOssName(objects) {
const names = objects.map((v) => {
const paths = v.name.split("/");
if (!paths[paths.length - 1])
return null;
return v.name;
}).filter(Boolean);
return names;
}
const PROJECT_ENV_PATH = `${process.cwd()}/.env.oss.local`;
const USER_HOME_SHENCOM = `${homedir()}/.shencom/oss_key`;
function ParseEnv(envPath) {
const path = CheckEnvPath(envPath);
if (!path) {
log.error("oss", "\u672A\u627E\u5230\u5BF9\u5E94\u7684\u79D8\u94A5\u914D\u7F6E\u6587\u4EF6\uFF0C\u8BF7\u5148\u914D\u7F6E\u79D8\u94A5");
TipLog();
process.exit();
}
const secret = dotenv.parse(fs.readFileSync(path));
return secret;
}
function TipLog() {
console.info(
boxen(
`1. \u53EF\u4EE5\u4F7F\u7528 ${chalk.magenta.bold("@shencom/cli")} \u521B\u5EFA\u79D8\u94A5${chalk.red.bold("(\u63A8\u8350)")}
${chalk.gray("\u5168\u5C40\u914D\u7F6E: ")}${chalk.gray.bold("$ npx @shencom/cli oss config")}
${chalk.gray("\u9879\u76EE\u914D\u7F6E: ")}${chalk.gray.bold("$ npx @shencom/cli oss config -p")}
2. \u5728\u5F53\u524D\u9879\u76EE\u6839\u76EE\u5F55\u521B\u5EFA ${chalk.blue.bold(".env.oss.local")} \u6587\u4EF6\uFF0C\u5E76\u914D\u7F6E\u5982\u4E0B\u5185\u5BB9:
${chalk.gray("accessKeySecret=xxx")}
${chalk.gray("accessKeyId=xxx")}
${chalk.red.bold("\u6CE8\u610F:")} \u8BF7\u52FF\u628A ${chalk.blue.bold(
".env.oss.local"
)} \u6587\u4EF6\u63D0\u4EA4\u5230\u4EE3\u7801\u4ED3\u5E93\u4E2D`,
{
padding: 1,
margin: 1,
title: "\u53EF\u4EE5\u4F7F\u7528\u4EE5\u4E0B\u4E24\u79CD\u65B9\u5F0F\u914D\u7F6E\u79D8\u94A5",
borderColor: "yellow",
borderStyle: "round"
}
)
);
}
function ParseAccessKeyEnv() {
const envPath = CheckEnvPath(PROJECT_ENV_PATH) || CheckEnvPath(USER_HOME_SHENCOM);
const { accessKeyId, accessKeySecret } = ParseEnv(envPath);
return { accessKeyId, accessKeySecret };
}
var __defProp$1 = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
var __knownSymbol = (name, symbol) => {
if (symbol = Symbol[name])
return symbol;
throw Error("Symbol." + name + " is not defined");
};
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues$1 = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp$1.call(b, prop))
__defNormalProp$1(a, prop, b[prop]);
if (__getOwnPropSymbols$1)
for (var prop of __getOwnPropSymbols$1(b)) {
if (__propIsEnum$1.call(b, prop))
__defNormalProp$1(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __publicField = (obj, key, value) => {
__defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")]) ? it.call(obj) : (obj = obj[__knownSymbol("iterator")](), it = {}, method = (key, fn) => (fn = obj[key]) && (it[key] = (arg) => new Promise((yes, no, done) => (arg = fn.call(obj, arg), done = arg.done, Promise.resolve(arg.value).then((value) => yes({ value, done }), no)))), method("next"), method("return"), it);
const TIME = 1e3 * 60 * 10;
if (_argv.debug) {
log.level = "verbose";
}
function debugLog(...args) {
const [message, ...arg] = args;
log.verbose("debug", message, ...arg);
return confirm("\u4EFB\u610F\u952E\u8FDB\u884C\u4E0B\u4E00\u6B65");
}
const handleLocalFileMD5 = (list) => {
const objects = list.map((v) => fileStreamHandle(v)).filter(Boolean);
return objects;
};
function handlePathSlash(path) {
return path.replace(/\/\//g, "/");
}
function handlePathSep(path) {
return path.replace(/\\/g, "/");
}
function handleOssBasePath(path) {
if (path === "")
return path;
if (path[0] === "/")
path = path.slice(1);
if (path.slice(-1) !== "/")
path += "/";
path = handlePathSep(path);
path = handlePathSlash(path);
return path;
}
function localPathToOssPath(list, ossPath, dirPath) {
const paths = Array.isArray(list) ? list : [list];
const objects = paths.map((v) => {
let str = ossPath + normalize(v).replace(dirPath, "");
str = handlePathSep(str);
str = handlePathSlash(str);
return str;
});
return Array.isArray(list) ? objects : objects[0];
}
function handleOssObjects(objects) {
const list = objects.map((v) => {
const paths = v.name.split("/");
if (!paths[paths.length - 1])
return null;
return { url: v.name, md5: v.etag && v.etag.toLocaleUpperCase().replace(/['"]/g, "") };
}).filter(Boolean);
return list;
}
function splitFile(list) {
const uploadFiles = [];
const deleteFiles = [];
list.forEach((item) => {
if (item.type === "upload") {
uploadFiles.push(item.url);
} else if (item.type === "delete") {
deleteFiles.push(item.url);
}
});
return { uploadFiles, deleteFiles };
}
function diffFileData(localList, ossList, options) {
const { dirPath, ossPath = "" } = options;
const map = /* @__PURE__ */ new Map();
for (let i = 0; i < localList.length; i++) {
const e = localList[i];
const path = e.url.replace(new RegExp(`${dirPath}/?`), "");
map.set(path, __spreadProps(__spreadValues$1({}, e), { type: "upload" }));
}
for (let i = 0; i < ossList.length; i++) {
const e = ossList[i];
const path = e.url.replace(ossPath, "");
const f = map.get(path);
if (f) {
if (f.md5 === e.md5)
map.delete(path);
} else {
map.set(path, __spreadProps(__spreadValues$1({}, e), { type: "delete" }));
}
}
return splitFile(map);
}
function handleIgnores(dirPath, ignores) {
ignores = ignores.map((v) => {
const e = join(v);
const val = e.replace(dirPath, "**/");
return join(val);
});
return ignores;
}
function handelOssRootFilesPath(root) {
const rootPaths = root.map((item) => {
const objects = filterOssName(item == null ? void 0 : item.objects);
const prefixes = item == null ? void 0 : item.prefixes;
return objects.concat(prefixes);
}).flat();
return rootPaths.filter(Boolean);
}
class OSSBase {
constructor(options) {
__publicField(this, "config", {});
__publicField(this, "CLIENT");
__publicField(this, "uploadIgnore", ["**/.DS_Store"]);
__publicField(this, "deleteIgnore", []);
const { timeout, bucket, debug } = options;
const { accessKeySecret, accessKeyId } = ParseAccessKeyEnv();
if (!(accessKeyId || accessKeySecret)) {
spinner.fail(chalk.red(`\u672A\u914D\u7F6Eoss\u79D8\u94A5`));
TipLog();
process.exit(1);
}
if (debug) {
log.level = "verbose";
}
options.ossPath = handleOssBasePath(options.ossPath);
this.config = options;
if (options.ossPath === void 0 || options.ossPath === null) {
spinner.fail("oss \u4E0A\u4F20\u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A");
process.exit(1);
}
this.CLIENT = new AliOSS({
region: "oss-cn-shenzhen",
accessKeyId,
accessKeySecret,
bucket: bucket || "scplugins",
timeout: timeout || TIME
});
this.setIgnore();
}
async setIgnore() {
const { ignore = [], uploadIgnore = [], deleteIgnore = [] } = this.config;
this.uploadIgnore.push(...ignore, ...uploadIgnore);
this.deleteIgnore.push(...ignore, ...deleteIgnore);
}
async _list(prefix = this.config.ossPath, options) {
try {
if (!this.CLIENT) {
spinner.fail(chalk.red("alioss \u521D\u59CB\u5316\u5931\u8D25"));
process.exit(1);
}
const list = [];
let continuationToken;
do {
const res = await this.CLIENT.listV2(
__spreadProps(__spreadValues$1({}, options), {
"continuation-token": continuationToken,
"max-keys": "1000",
prefix
}),
{ timeout: 1e3 * 60 }
);
const { objects = [], prefixes = [] } = res;
continuationToken = res.nextContinuationToken;
list.push({ objects, prefixes });
} while (continuationToken);
return list;
} catch (error) {
spinner.fail(chalk.red("\u83B7\u53D6 OSS \u5931\u8D25\uFF01"));
throw error;
}
}
/**
* 获取文件对象
*
* @protected
* @param {string} [refix=this.config.ossPath]
* @return {Promise<AliOSS.ObjectMeta[]>}
* @memberof OSSBase
*/
async _listObjects(refix = this.config.ossPath) {
const list = await this._list(refix);
return list.flatMap((v) => v.objects);
}
/**
* 获取目录
*
* @protected
* @param {string} [refix=this.config.ossPath]
* @return {Promise<string[]>}
* @memberof OSSBase
*/
async _listPrefixes(refix = this.config.ossPath) {
const list = await this._list(refix, { delimiter: "/" });
return list.flatMap((v) => v.prefixes);
}
async _head(path) {
if (!this.CLIENT) {
spinner.fail(chalk.red("alioss \u521D\u59CB\u5316\u5931\u8D25"));
process.exit(1);
}
try {
spinner.start(chalk.cyan(`\u{1F680} \u83B7\u53D6 ${basename(path)} MD5\u4E2D...`));
const head = await this.CLIENT.head(path);
spinner.stop();
const md5 = head.res.headers["content-md5"];
return md5;
} catch (error) {
spinner.fail(chalk.red(`\u83B7\u53D6 ${basename(path)}MD5 \u5931\u8D25\uFF01`));
return "";
}
}
_put(options) {
if (!this.CLIENT) {
spinner.fail(chalk.red("alioss \u521D\u59CB\u5316\u5931\u8D25"));
process.exit(1);
}
if (!options)
return Promise.resolve();
const { filePath, ossPath } = options;
if (!isFile(filePath)) {
spinner.fail(chalk.red(`${filePath} \u6587\u4EF6\u8DEF\u5F84\u4E0D\u5B58\u5728`));
process.exit(1);
}
if (!isOssPath(ossPath, this.config.ossPath)) {
spinner.fail(chalk.red(`${ossPath} oss\u8DEF\u5F84\u51FA\u9519`));
process.exit(1);
}
spinner.start(chalk.cyan(`\u4E0A\u4F20 ${basename(filePath)} \u6587\u4EF6\u4E2D...`));
const { uploadOptions } = this.config;
let ossOptions = {
headers: { disabledMD5: false }
};
if (typeof uploadOptions === "function") {
ossOptions = uploadOptions(filePath, ossOptions);
} else if (Object.prototype.toString.call(uploadOptions) === "[object Object]") {
ossOptions = Object.assign({}, ossOptions, uploadOptions);
}
log.verbose("debug", `\u4E0A\u4F20\u914D\u7F6E: ${JSON.stringify(ossOptions)}`);
return this.CLIENT.put(ossPath, filePath, ossOptions);
}
async _get(paths, options = {}) {
if (!this.CLIENT) {
spinner.fail(chalk.red("alioss \u521D\u59CB\u5316\u5931\u8D25"));
return Promise.reject(new Error("alioss \u521D\u59CB\u5316\u5931\u8D25"));
}
if (!paths) {
return Promise.reject(new Error("\u672A\u914D\u7F6E\u4E0B\u8F7D\u8DEF\u5F84 paths"));
}
const { ossPath, localPath } = paths;
try {
spinner.start(chalk.cyan(`\u{1F680} \u4E0B\u8F7D ${ossPath} \u4E2D...`));
const res = await this.CLIENT.get(ossPath, localPath, __spreadValues$1({
timeout: TIME
}, options));
spinner.stop();
return res;
} catch (error) {
spinner.fail(chalk.red(`\u4E0B\u8F7D ${ossPath} \u5931\u8D25\uFF01`));
return Promise.reject(error);
}
}
async _delete(paths) {
if (!this.CLIENT) {
spinner.fail(chalk.red("alioss \u521D\u59CB\u5316\u5931\u8D25"));
process.exit(1);
}
try {
spinner.start(chalk.green("\u{1F5D1} \u6B63\u5728\u5220\u9664\u591A\u4F59\u6587\u4EF6\u4E2D..."));
await this.CLIENT.deleteMulti(paths, { quiet: true });
spinner.succeed(chalk.green(`\u5220\u9664${paths.length}\u4E2A\u6587\u4EF6\u6210\u529F\uFF01`));
} catch (error) {
spinner.fail(chalk.red("\u5220\u9664\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u5220\u9664\uFF01"));
}
}
}
class OSS extends OSSBase {
constructor(ops) {
super(ops);
}
async list(ossPaths, returnType = "all", options) {
spinner.start("\u{1F680} \u83B7\u53D6 OSS \u6587\u4EF6\u4E2D...");
if (!Array.isArray(ossPaths))
ossPaths = [ossPaths];
const filesPath = [];
try {
for (var iter = __forAwait(ossPaths), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
const file = temp.value;
let objects = [];
if (returnType === "file") {
objects = await this._listObjects(file);
} else if (returnType === "dir") {
objects = await this._listPrefixes(file);
} else if (returnType === "all") {
objects = await this._list(file, options);
}
filesPath.push(...objects);
}
} catch (temp) {
error = [temp];
} finally {
try {
more && (temp = iter.return) && await temp.call(iter);
} finally {
if (error)
throw error[0];
}
}
log.verbose("debug", `OSS\u8DEF\u5F84: ${ossPaths}`);
spinner.succeed(chalk.green(`\u83B7\u53D6 OSS ${filesPath.length}\u4E2A\u6587\u4EF6\uFF01`));
return filesPath;
}
/**
* 批量获取oss文件的md5
*
* @param {string[]} ossFilePaths oss文件路径
* @returns {Promise<FileData[]>}
* @memberof OSS
*/
async head(ossFilePaths) {
const heads = [];
try {
for (var iter = __forAwait(ossFilePaths), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
const path = temp.value;
const md5 = await this._head(path);
heads.push({ url: path, md5 });
}
} catch (temp) {
error = [temp];
} finally {
try {
more && (temp = iter.return) && await temp.call(iter);
} finally {
if (error)
throw error[0];
}
}
spinner.succeed(chalk.green(`\u83B7\u53D6 OSS ${heads.length} \u4E2A\u6587\u4EF6\uFF01`));
return heads;
}
/**
* 删除oss文件
*
* @param {string[]} ossPaths oss文件路径
* @returns
* @memberof OSS
*/
async delete(ossPaths) {
if (!ossPaths.length)
return;
ossPaths.forEach((item) => {
spinner.info(chalk.cyan(`\u{1F5D1} \u5220\u9664 ${basename(item)} \u6587\u4EF6`));
});
await this._delete(ossPaths);
}
/**
* 上传文件
*
* @param {OssUploadItem[]} paths 上传路径对象
* @returns
* @memberof OSS
*/
async put(paths, options) {
if (!paths.length)
return;
const failUploadFiles = [];
const successUploadFiles = [];
if (!(options == null ? void 0 : options.isCloseConfirm)) {
const flag = await confirm("\u786E\u8BA4\u4E0A\u4F20\u5417?");
if (!flag)
process.exit();
}
try {
for (var iter = __forAwait(paths), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
const item = temp.value;
try {
const res = await this._put(item);
if (!res)
continue;
spinner.succeed(chalk.green(`${basename(res.url)} \u4E0A\u4F20\u6210\u529F`));
successUploadFiles.push(basename(res.url));
} catch (error2) {
spinner.fail(chalk.red(`${basename(item.filePath)} \u4E0A\u4F20\u5931\u8D25`));
failUploadFiles.push(basename(item.filePath));
throw error2;
}
}
} catch (temp) {
error = [temp];
} finally {
try {
more && (temp = iter.return) && await temp.call(iter);
} finally {
if (error)
throw error[0];
}
}
if (successUploadFiles.length) {
spinner.info(chalk.cyan(`\u{1F680} \u4E0A\u4F20\u6210\u529F${successUploadFiles.length}\u4E2A\u6587\u4EF6`));
}
if (failUploadFiles.length) {
spinner.fail(chalk.red(`\u4E0A\u4F20\u5931\u8D25${failUploadFiles.length}\u4E2A\u6587\u4EF6`));
}
}
/**
* 下载文件
*
* @param {OssDownloadItem[]} paths 下载路径对象
* @param {AliOSS.GetObjectOptions} options 下载参数
* @returns
* @memberof OSS
*/
download(paths, options) {
return new Promise((resolve) => {
const limit = pLimit(100);
const requests = paths.map((p) => limit(() => this._get(p, options)));
Promise.allSettled(requests).then((res) => {
const success = [];
const fail = [];
res.forEach((item) => {
if (item.status === "fulfilled") {
success.push(item.value);
} else {
fail.push(item.reason);
}
});
if (success.length) {
spinner.info(chalk.cyan(`\u{1F680} \u4E0B\u8F7D\u6210\u529F ${success.length} \u4E2A\u6587\u4EF6`));
}
if (fail.length) {
spinner.info(chalk.cyan(`\u274C \u4E0B\u8F7D\u5931\u8D25 ${fail.length} \u4E2A\u6587\u4EF6`));
}
resolve({ success, fail });
});
});
}
/**
* 代码上传
*
* @param {UploadOptions} ops 上传配置
* @memberof OSS
*/
async upload(ops) {
var _a, _b, _c, _d;
try {
ops.dirPath = join(ops.dirPath || "dist");
ops.debug = (_a = ops.debug) != null ? _a : _argv.debug;
ops.diff = (_c = (_b = ops.diff) != null ? _b : _argv.diff) != null ? _c : true;
ops.ossPath = (_d = ops.ossPath) != null ? _d : this.config.ossPath;
const { isClearVersion, version } = ops;
if (ops.debug)
log.level = "verbose";
this.setOssBasePath(ops.ossPath);
if (!CheckEnvPath(ops.dirPath)) {
throwErr("oss", "dirPath \u4E0D\u5B58\u5728");
}
if (ops.ossPath === void 0 || ops.ossPath === null) {
throwErr("oss", "ossPath \u4E3A\u7A7A");
}
if (isClearVersion && !version)
throwErr("oss", "isClearVersion \u4E3A true \u65F6\uFF0Cversion \u4E0D\u80FD\u4E3A\u7A7A");
const localFileData = await this._handleLocalPath(ops);
const ossFileData = await this._handleOssPath(ops.ossPath, ops);
const { uploadFiles, deleteFiles } = diffFileData(localFileData, ossFileData, ops);
if (!ops.isCloseConfirm) {
const flag = await confirm("\u786E\u8BA4\u4E0A\u4F20\u5417?");
if (!flag)
process.exit();
}
await this._handlePutFile(uploadFiles, ops);
await this._handleDeleteFile(deleteFiles, ops);
if (ops.isClearVersion)
await this._handleClearVersionDir(ops);
} catch (error) {
let message;
if (error instanceof Error) {
message = error.message;
} else {
message = "\u9519\u8BEF";
}
spinner.fail(message);
throw error;
}
}
/**
* 清除版本号文件夹
*
* @param {string[]} paths 文件路径
* @param {number} [limit] 保留版本号目录个数
* @return
* @memberof OSS
*/
async clearVersionDir(paths, opt) {
const { versionLimit, version } = opt;
const { ossPath } = this.config;
const limit = versionLimit != null ? versionLimit : 10;
if (!ossPath)
throwErr("oss", "ossPath \u4E3A\u7A7A");
let versions = paths.map((v) => {
const p = versionExec(v) || [];
return p[1];
}).filter((v) => versionValid(v)).filter((v) => v !== version);
versions = versionSort(versions);
if (_argv.debug)
await debugLog("\u7248\u672C\u53F7: ", `[${chalk.green(versions.join("\u3001"))}]`);
if (versions.length <= limit)
return;
const delDirs = versions.slice(0, versions.length - limit);
const delPath = delDirs.map((v) => handleOssBasePath(ossPath + v));
const flag = await confirm(`\u662F\u5426\u5220\u9664\u4E0B\u9762\u7248\u672C\u76EE\u5F55\uFF1F
${chalk.red(delPath.join("\n"))}
`);
if (!flag)
process.exit();
const delFiles = await this.list(delPath, "file");
if (!_argv.debug)
await this.delete(delFiles.map((v) => v.name));
}
setOssBasePath(path) {
this.config.ossPath = handleOssBasePath(path);
}
async _handleClearVersionDir(ops) {
const list = await this._listPrefixes(this.config.ossPath);
return this.clearVersionDir(list, ops);
}
async _handleOssPath(ossPath, ops) {
const { ossFileHook, ossPathHook, diff, debug, version, isClearVersion } = ops;
if (!diff)
return [];
let ossObjectMeta = [];
let paths = [];
if (isClearVersion && !version)
throwErr("oss", "isClearVersion \u4E3A true \u65F6\uFF0Cversion \u4E0D\u80FD\u4E3A\u7A7A");
if (version) {
const root = await this.list(ossPath, "all", { delimiter: "/" });
const rootPaths = handelOssRootFilesPath(root);
rootPaths.forEach((v) => {
const item = versionExec(v);
if (!item || version === item[1]) {
paths.push(v);
}
});
} else {
paths = Array.isArray(ossPath) ? ossPath : [ossPath];
}
if (typeof ossPathHook === "function") {
paths = ossPathHook(paths) || [];
}
ossObjectMeta = await this.list(paths, "file");
if (typeof ossFileHook === "function") {
ossObjectMeta = ossFileHook(ossObjectMeta) || [];
}
const ossFileData = handleOssObjects(ossObjectMeta);
if (debug)
await debugLog("oss\u6587\u4EF6\u4FE1\u606F: ", ossFileData);
return ossFileData;
}
async _handleLocalPath(ops) {
const { localFileHook: hook, dirPath, debug } = ops;
let localPath = getDirFilesPath(dirPath, {
ignore: this.uploadIgnore
});
if (typeof hook === "function") {
localPath = hook(localPath) || [];
}
localPath = localPath.filter(Boolean);
if (debug)
await debugLog("\u672C\u5730\u6587\u4EF6\u8DEF\u5F84: ", localPath);
spinner.succeed(chalk.green(`\u6210\u529F\u83B7\u53D6\u672C\u5730${localPath.length}\u4E2A\u6587\u4EF6\uFF01`));
const localFileData = handleLocalFileMD5(localPath);
if (debug)
await debugLog("\u672C\u5730\u6587\u4EF6\u6DFB\u52A0MD5: ", localFileData);
return localFileData;
}
async _handlePutFile(putFiles, ops) {
const { beforeUploadHook: hook, dirPath, debug } = ops;
const baseOssPath = this.config.ossPath;
let files = putFiles;
if (typeof hook === "function") {
files = hook(putFiles) || [];
}
if (debug)
await debugLog("\u4E0A\u4F20oss\u6587\u4EF6\u5217\u8868: ", files);
const ossPutFileObjects = files.map((item) => ({
ossPath: localPathToOssPath(item, baseOssPath, dirPath),
filePath: item
}));
if (debug)
await debugLog("\u4E0A\u4F20oss\u6587\u4EF6\u4FE1\u606F\u5217\u8868: ", ossPutFileObjects);
log.info("info", chalk.cyan(`\u26A0\uFE0F oss\u5730\u5740: ${baseOssPath}`));
const errorFiles = ossPutFileObjects.filter((item) => !item.ossPath.includes(baseOssPath));
if (errorFiles.length) {
debugLog(
"\u4E0A\u4F20\u8DEF\u5F84\u9519\u8BEF\u6587\u4EF6: ",
errorFiles.map((v) => v.ossPath)
);
process.exit(1);
}
if (!ossPutFileObjects.length)
return;
if (!debug)
await this.put(ossPutFileObjects, __spreadProps(__spreadValues$1({}, ops), { isCloseConfirm: false }));
}
async _handleDeleteFile(deleteFiles, ops) {
const { beforeDeleteHook: hook, dirPath, debug, isClearVersion, version } = ops;
let ossDeleteFileObjects = deleteFiles;
if (this.deleteIgnore.length) {
const patterns = handleIgnores(dirPath, this.deleteIgnore);
if (debug)
debugLog("\u5220\u9664\u8FC7\u6EE4\u89C4\u5219: ", patterns);
ossDeleteFileObjects = listIgnoreHandle(ossDeleteFileObjects, patterns);
}
if (typeof hook === "function") {
ossDeleteFileObjects = hook(ossDeleteFileObjects) || [];
}
if (version)
ossDeleteFileObjects = ossDeleteFileObjects.filter((v) => v.includes(`/${version}/`));
if (isClearVersion) {
const versionFiles = ossDeleteFileObjects.filter((v) => !versionExec(v));
ossDeleteFileObjects = ossDeleteFileObjects.concat(versionFiles);
}
ossDeleteFileObjects = [...new Set(ossDeleteFileObjects)];
if (debug)
await debugLog("\u5220\u9664oss\u6587\u4EF6\u5217\u8868: ", ossDeleteFileObjects);
if (!debug)
await this.delete(ossDeleteFileObjects);
}
}
var __defProp = Object.defineProperty;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
const version = version$1;
var index = __spreadValues({
OSS,
version
}, utils);
export { CheckEnvPath, Env, Mode, OSS, _argv, branch, confirm, index as default, envName, getCliParam, isBuild, isDebug, isFile, isPro, isServe, isTst, isUat, isUpload, md5, spinner, throwErr, verifyBuild, version, versionExec, versionReg, versionSort, versionValid };
//# sourceMappingURL=index.js.map