UNPKG

@shencom/oss-upload

Version:
897 lines (883 loc) 30.4 kB
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