vite-plugin-deploy-oss 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -48,6 +48,7 @@ export default {
48
48
 
49
49
  ## 说明
50
50
 
51
+ - 当前版本仅支持 ESM(`import`),不再提供 CommonJS(`require`)入口。
51
52
  - `open` 默认 `true`,建议通过环境变量控制开关(例如 `DEPLOY_OSS=1` 时再上传)。
52
53
  - `fancy` 默认 `true`,TTY 终端下会显示实时动效进度(速度、预计剩余、并发、当前文件)。
53
54
  - `failOnError` 默认 `true`,上传有失败会抛错,适合 CI 场景保证发布质量。
package/dist/index.js CHANGED
@@ -1,47 +1,13 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
1
  // src/index.ts
31
- var index_exports = {};
32
- __export(index_exports, {
33
- default: () => vitePluginDeployOss
34
- });
35
- module.exports = __toCommonJS(index_exports);
36
- var import_ali_oss = __toESM(require("ali-oss"));
37
- var import_chalk = __toESM(require("chalk"));
38
- var import_delete_empty = __toESM(require("delete-empty"));
39
- var import_glob = require("glob");
40
- var import_promises = require("fs/promises");
41
- var import_node_path = require("path");
42
- var import_ora = __toESM(require("ora"));
43
- var import_vite = require("vite");
44
- var normalizeObjectKey = (targetDir, relativeFilePath) => (0, import_vite.normalizePath)(`${targetDir}/${relativeFilePath}`).replace(/\/{2,}/g, "/").replace(/^\/+/, "");
2
+ import oss from "ali-oss";
3
+ import chalk from "chalk";
4
+ import deleteEmpty from "delete-empty";
5
+ import { globSync } from "glob";
6
+ import { stat, unlink } from "fs/promises";
7
+ import { resolve } from "path";
8
+ import ora from "ora";
9
+ import { normalizePath } from "vite";
10
+ var normalizeObjectKey = (targetDir, relativeFilePath) => normalizePath(`${targetDir}/${relativeFilePath}`).replace(/\/{2,}/g, "/").replace(/^\/+/, "");
45
11
  var formatBytes = (bytes) => {
46
12
  if (!Number.isFinite(bytes) || bytes <= 0) return "0 B";
47
13
  const units = ["B", "KB", "MB", "GB", "TB"];
@@ -73,12 +39,12 @@ var buildCapsuleBar = (ratio, width = 30) => {
73
39
  const safeRatio = Math.max(0, Math.min(1, ratio));
74
40
  if (width <= 0) return "";
75
41
  if (safeRatio >= 1) {
76
- return import_chalk.default.green("\u2588".repeat(width));
42
+ return chalk.green("\u2588".repeat(width));
77
43
  }
78
44
  const pointerIndex = Math.min(width - 1, Math.floor(width * safeRatio));
79
- const done = pointerIndex > 0 ? import_chalk.default.green("\u2588".repeat(pointerIndex)) : "";
80
- const pointer = import_chalk.default.cyanBright("\u25B8");
81
- const pending = pointerIndex < width - 1 ? import_chalk.default.gray("\u2591".repeat(width - pointerIndex - 1)) : "";
45
+ const done = pointerIndex > 0 ? chalk.green("\u2588".repeat(pointerIndex)) : "";
46
+ const pointer = chalk.cyanBright("\u25B8");
47
+ const pending = pointerIndex < width - 1 ? chalk.gray("\u2591".repeat(width - pointerIndex - 1)) : "";
82
48
  return `${done}${pointer}${pending}`;
83
49
  };
84
50
  function vitePluginDeployOss(option) {
@@ -105,7 +71,7 @@ function vitePluginDeployOss(option) {
105
71
  } = option || {};
106
72
  let buildFailed = false;
107
73
  let upload = false;
108
- let outDir = (0, import_vite.normalizePath)((0, import_node_path.resolve)("dist"));
74
+ let outDir = normalizePath(resolve("dist"));
109
75
  let resolvedConfig = null;
110
76
  const useInteractiveOutput = fancy && Boolean(process.stdout?.isTTY) && Boolean(process.stderr?.isTTY) && !process.env.CI;
111
77
  const clearScreen = () => {
@@ -147,9 +113,9 @@ function vitePluginDeployOss(option) {
147
113
  if (result.res.status === 200) {
148
114
  if (autoDelete) {
149
115
  try {
150
- await (0, import_promises.unlink)(task.filePath);
116
+ await unlink(task.filePath);
151
117
  } catch (error) {
152
- console.warn(`${import_chalk.default.yellow("\u26A0")} \u5220\u9664\u672C\u5730\u6587\u4EF6\u5931\u8D25: ${task.filePath}`);
118
+ console.warn(`${chalk.yellow("\u26A0")} \u5220\u9664\u672C\u5730\u6587\u4EF6\u5931\u8D25: ${task.filePath}`);
153
119
  }
154
120
  }
155
121
  return { success: true, file: task.filePath, name: task.name, size: task.size, retries: attempt - 1 };
@@ -160,7 +126,7 @@ function vitePluginDeployOss(option) {
160
126
  if (attempt === maxRetries) {
161
127
  if (!silentLogs) {
162
128
  console.log(
163
- `${import_chalk.default.red("\u2717")} ${task.filePath} => ${error instanceof Error ? error.message : String(error)}`
129
+ `${chalk.red("\u2717")} ${task.filePath} => ${error instanceof Error ? error.message : String(error)}`
164
130
  );
165
131
  }
166
132
  return {
@@ -173,7 +139,7 @@ function vitePluginDeployOss(option) {
173
139
  };
174
140
  } else {
175
141
  if (!silentLogs) {
176
- console.log(`${import_chalk.default.yellow("\u26A0")} ${task.filePath} \u4E0A\u4F20\u5931\u8D25\uFF0C\u6B63\u5728\u91CD\u8BD5 (${attempt}/${maxRetries})...`);
142
+ console.log(`${chalk.yellow("\u26A0")} ${task.filePath} \u4E0A\u4F20\u5931\u8D25\uFF0C\u6B63\u5728\u91CD\u8BD5 (${attempt}/${maxRetries})...`);
177
143
  }
178
144
  await new Promise((resolve2) => setTimeout(resolve2, 1e3 * attempt));
179
145
  }
@@ -198,10 +164,10 @@ function vitePluginDeployOss(option) {
198
164
  let retries = 0;
199
165
  const taskCandidates = await Promise.all(
200
166
  files.map(async (relativeFilePath) => {
201
- const filePath = (0, import_vite.normalizePath)((0, import_node_path.resolve)(outDir, relativeFilePath));
167
+ const filePath = normalizePath(resolve(outDir, relativeFilePath));
202
168
  const name = normalizeObjectKey(uploadDir, relativeFilePath);
203
169
  try {
204
- const fileStats = await (0, import_promises.stat)(filePath);
170
+ const fileStats = await stat(filePath);
205
171
  return { task: { filePath, name, size: fileStats.size } };
206
172
  } catch (error) {
207
173
  return { task: null, error, filePath, name };
@@ -229,7 +195,7 @@ function vitePluginDeployOss(option) {
229
195
  const activeFiles = /* @__PURE__ */ new Set();
230
196
  const safeWindowSize = Math.max(1, Math.min(windowSize, tasks.length || 1));
231
197
  const silentLogs = Boolean(useInteractiveOutput);
232
- const spinner = useInteractiveOutput ? (0, import_ora.default)({ text: "\u51C6\u5907\u4E0A\u4F20...", spinner: "dots12" }).start() : null;
198
+ const spinner = useInteractiveOutput ? ora({ text: "\u51C6\u5907\u4E0A\u4F20...", spinner: "dots12" }).start() : null;
233
199
  const reportEvery = Math.max(1, Math.ceil(totalFiles / 10));
234
200
  let lastReportedCompleted = -1;
235
201
  const updateProgress = () => {
@@ -244,7 +210,7 @@ function vitePluginDeployOss(option) {
244
210
  if (completed === lastReportedCompleted) return;
245
211
  if (completed === totalFiles || completed % reportEvery === 0) {
246
212
  console.log(
247
- `${import_chalk.default.gray("\u8FDB\u5EA6:")} ${completed}/${totalFiles} (${percentage}%) | ${import_chalk.default.gray("\u6570\u636E:")} ${formatBytes(uploadedBytes)}/${formatBytes(totalBytes)} | ${import_chalk.default.gray("\u901F\u5EA6:")} ${formatBytes(speed)}/s`
213
+ `${chalk.gray("\u8FDB\u5EA6:")} ${completed}/${totalFiles} (${percentage}%) | ${chalk.gray("\u6570\u636E:")} ${formatBytes(uploadedBytes)}/${formatBytes(totalBytes)} | ${chalk.gray("\u901F\u5EA6:")} ${formatBytes(speed)}/s`
248
214
  );
249
215
  lastReportedCompleted = completed;
250
216
  }
@@ -252,10 +218,10 @@ function vitePluginDeployOss(option) {
252
218
  }
253
219
  const bar = buildCapsuleBar(progressRatio);
254
220
  const warnLine = retries > 0 || failed > 0 ? `
255
- ${import_chalk.default.yellow("\u91CD\u8BD5")}: ${retries} ${import_chalk.default.yellow("\u5931\u8D25")}: ${failed}` : "";
221
+ ${chalk.yellow("\u91CD\u8BD5")}: ${retries} ${chalk.yellow("\u5931\u8D25")}: ${failed}` : "";
256
222
  spinner.text = [
257
- `${import_chalk.default.cyan("\u6B63\u5728\u4E0A\u4F20:")} ${import_chalk.default.white(currentFile)}`,
258
- `${bar} ${import_chalk.default.bold(`${percentage}%`)} ${import_chalk.default.gray(`(${completed}/${totalFiles})`)} ${import_chalk.default.gray("|")} ${import_chalk.default.blue(formatBytes(uploadedBytes))}/${import_chalk.default.blue(formatBytes(totalBytes))} ${import_chalk.default.gray("|")} ${import_chalk.default.magenta(`${formatBytes(speed)}/s`)} ${import_chalk.default.gray("|")} \u9884\u8BA1 ${import_chalk.default.yellow(formatDuration(etaSeconds))}`
223
+ `${chalk.cyan("\u6B63\u5728\u4E0A\u4F20:")} ${chalk.white(currentFile)}`,
224
+ `${bar} ${chalk.bold(`${percentage}%`)} ${chalk.gray(`(${completed}/${totalFiles})`)} ${chalk.gray("|")} ${chalk.blue(formatBytes(uploadedBytes))}/${chalk.blue(formatBytes(totalBytes))} ${chalk.gray("|")} ${chalk.magenta(`${formatBytes(speed)}/s`)} ${chalk.gray("|")} \u9884\u8BA1 ${chalk.yellow(formatDuration(etaSeconds))}`
259
225
  ].join("\n");
260
226
  spinner.text += warnLine;
261
227
  };
@@ -292,11 +258,11 @@ ${import_chalk.default.yellow("\u91CD\u8BD5")}: ${retries} ${import_chalk.defau
292
258
  const successCount = results.filter((item) => item.success).length;
293
259
  const speed = elapsedSeconds > 0 ? uploadedBytes / elapsedSeconds : 0;
294
260
  spinner.succeed(
295
- `${import_chalk.default.green("\u4E0A\u4F20\u6210\u529F")} ${successCount} \u4E2A\u6587\u4EF6\u3002
296
- ${buildCapsuleBar(1)} 100% (${totalFiles}/${totalFiles}) ${import_chalk.default.gray("|")} \u901F\u5EA6 ${import_chalk.default.magenta(`${formatBytes(speed)}/s`)} ${import_chalk.default.gray("|")} \u8017\u65F6 ${import_chalk.default.yellow(formatDuration(elapsedSeconds))}`
261
+ `${chalk.green("\u4E0A\u4F20\u6210\u529F")} ${successCount} \u4E2A\u6587\u4EF6\u3002
262
+ ${buildCapsuleBar(1)} 100% (${totalFiles}/${totalFiles}) ${chalk.gray("|")} \u901F\u5EA6 ${chalk.magenta(`${formatBytes(speed)}/s`)} ${chalk.gray("|")} \u8017\u65F6 ${chalk.yellow(formatDuration(elapsedSeconds))}`
297
263
  );
298
264
  } else {
299
- console.log(`${import_chalk.default.green("\u2714")} \u6240\u6709\u6587\u4EF6\u4E0A\u4F20\u5B8C\u6210 (${totalFiles}/${totalFiles})`);
265
+ console.log(`${chalk.green("\u2714")} \u6240\u6709\u6587\u4EF6\u4E0A\u4F20\u5B8C\u6210 (${totalFiles}/${totalFiles})`);
300
266
  }
301
267
  return results;
302
268
  };
@@ -312,7 +278,7 @@ ${buildCapsuleBar(1)} 100% (${totalFiles}/${totalFiles}) ${import_chalk.default.
312
278
  clearScreen();
313
279
  const validationErrors = validateOptions();
314
280
  if (validationErrors.length > 0) {
315
- console.log(`${import_chalk.default.red("\u2717 \u914D\u7F6E\u9519\u8BEF:")}
281
+ console.log(`${chalk.red("\u2717 \u914D\u7F6E\u9519\u8BEF:")}
316
282
  ${validationErrors.map((err) => ` - ${err}`).join("\n")}`);
317
283
  return;
318
284
  }
@@ -322,7 +288,7 @@ ${validationErrors.map((err) => ` - ${err}`).join("\n")}`);
322
288
  },
323
289
  configResolved(config) {
324
290
  resolvedConfig = config;
325
- outDir = (0, import_vite.normalizePath)((0, import_node_path.resolve)(config.root, config.build.outDir));
291
+ outDir = normalizePath(resolve(config.root, config.build.outDir));
326
292
  },
327
293
  closeBundle: {
328
294
  sequential: true,
@@ -330,26 +296,26 @@ ${validationErrors.map((err) => ` - ${err}`).join("\n")}`);
330
296
  async handler() {
331
297
  if (!open || !upload || buildFailed || !resolvedConfig) return;
332
298
  const startTime = Date.now();
333
- const client = new import_ali_oss.default({ region, accessKeyId, accessKeySecret, secure, bucket, ...props });
334
- const files = (0, import_glob.globSync)("**/*", {
299
+ const client = new oss({ region, accessKeyId, accessKeySecret, secure, bucket, ...props });
300
+ const files = globSync("**/*", {
335
301
  cwd: outDir,
336
302
  nodir: true,
337
303
  ignore: Array.isArray(skip) ? skip : [skip]
338
- }).map((file) => (0, import_vite.normalizePath)(file));
304
+ }).map((file) => normalizePath(file));
339
305
  if (files.length === 0) {
340
- console.log(`${import_chalk.default.yellow("\u26A0 \u6CA1\u6709\u627E\u5230\u9700\u8981\u4E0A\u4F20\u7684\u6587\u4EF6")}`);
306
+ console.log(`${chalk.yellow("\u26A0 \u6CA1\u6709\u627E\u5230\u9700\u8981\u4E0A\u4F20\u7684\u6587\u4EF6")}`);
341
307
  return;
342
308
  }
343
309
  clearScreen();
344
- console.log(import_chalk.default.cyan(`
310
+ console.log(chalk.cyan(`
345
311
  \u{1F680} OSS \u90E8\u7F72\u5F00\u59CB
346
312
  `));
347
- console.log(`${import_chalk.default.gray("Bucket:")} ${import_chalk.default.green(bucket)}`);
348
- console.log(`${import_chalk.default.gray("Region:")} ${import_chalk.default.green(region)}`);
349
- console.log(`${import_chalk.default.gray("Source:")} ${import_chalk.default.yellow(outDir)}`);
350
- console.log(`${import_chalk.default.gray("Target:")} ${import_chalk.default.yellow(uploadDir)}`);
351
- if (alias) console.log(`${import_chalk.default.gray("Alias:")} ${import_chalk.default.green(alias)}`);
352
- console.log(`${import_chalk.default.gray("Files:")} ${import_chalk.default.blue(files.length)}
313
+ console.log(`${chalk.gray("Bucket:")} ${chalk.green(bucket)}`);
314
+ console.log(`${chalk.gray("Region:")} ${chalk.green(region)}`);
315
+ console.log(`${chalk.gray("Source:")} ${chalk.yellow(outDir)}`);
316
+ console.log(`${chalk.gray("Target:")} ${chalk.yellow(uploadDir)}`);
317
+ if (alias) console.log(`${chalk.gray("Alias:")} ${chalk.green(alias)}`);
318
+ console.log(`${chalk.gray("Files:")} ${chalk.blue(files.length)}
353
319
  `);
354
320
  try {
355
321
  const results = await uploadFilesInBatches(client, files, concurrency);
@@ -361,48 +327,48 @@ ${validationErrors.map((err) => ` - ${err}`).join("\n")}`);
361
327
  const retryCount = results.reduce((sum, result) => sum + result.retries, 0);
362
328
  const avgSpeed = durationSeconds > 0 ? uploadedBytes / durationSeconds : 0;
363
329
  clearScreen();
364
- console.log("\n" + import_chalk.default.gray("\u2500".repeat(40)) + "\n");
330
+ console.log("\n" + chalk.gray("\u2500".repeat(40)) + "\n");
365
331
  if (failedCount === 0) {
366
- console.log(`${import_chalk.default.green("\u{1F389} \u90E8\u7F72\u6210\u529F!")}`);
332
+ console.log(`${chalk.green("\u{1F389} \u90E8\u7F72\u6210\u529F!")}`);
367
333
  } else {
368
- console.log(`${import_chalk.default.yellow("\u26A0 \u90E8\u7F72\u5B8C\u6210\u4F46\u5B58\u5728\u9519\u8BEF")}`);
334
+ console.log(`${chalk.yellow("\u26A0 \u90E8\u7F72\u5B8C\u6210\u4F46\u5B58\u5728\u9519\u8BEF")}`);
369
335
  }
370
336
  console.log(`
371
- ${import_chalk.default.gray("\u7EDF\u8BA1:")}`);
372
- console.log(` ${import_chalk.default.green("\u2714")} \u6210\u529F: ${import_chalk.default.bold(successCount)}`);
337
+ ${chalk.gray("\u7EDF\u8BA1:")}`);
338
+ console.log(` ${chalk.green("\u2714")} \u6210\u529F: ${chalk.bold(successCount)}`);
373
339
  if (failedCount > 0) {
374
- console.log(` ${import_chalk.default.red("\u2717")} \u5931\u8D25: ${import_chalk.default.bold(failedCount)}`);
340
+ console.log(` ${chalk.red("\u2717")} \u5931\u8D25: ${chalk.bold(failedCount)}`);
375
341
  }
376
- console.log(` ${import_chalk.default.cyan("\u21C4")} \u91CD\u8BD5: ${import_chalk.default.bold(retryCount)}`);
377
- console.log(` ${import_chalk.default.blue("\u{1F4E6}")} \u6570\u636E: ${import_chalk.default.bold(formatBytes(uploadedBytes))}`);
378
- console.log(` ${import_chalk.default.magenta("\u26A1")} \u5E73\u5747\u901F\u5EA6: ${import_chalk.default.bold(`${formatBytes(avgSpeed)}/s`)}`);
379
- console.log(` ${import_chalk.default.blue("\u23F1")} \u8017\u65F6: ${import_chalk.default.bold(duration)}s`);
342
+ console.log(` ${chalk.cyan("\u21C4")} \u91CD\u8BD5: ${chalk.bold(retryCount)}`);
343
+ console.log(` ${chalk.blue("\u{1F4E6}")} \u6570\u636E: ${chalk.bold(formatBytes(uploadedBytes))}`);
344
+ console.log(` ${chalk.magenta("\u26A1")} \u5E73\u5747\u901F\u5EA6: ${chalk.bold(`${formatBytes(avgSpeed)}/s`)}`);
345
+ console.log(` ${chalk.blue("\u23F1")} \u8017\u65F6: ${chalk.bold(duration)}s`);
380
346
  console.log("");
381
347
  if (failedCount > 0) {
382
348
  const failedItems = results.filter((result) => !result.success);
383
349
  const previewCount = Math.min(5, failedItems.length);
384
- console.log(import_chalk.default.red("\u5931\u8D25\u660E\u7EC6:"));
350
+ console.log(chalk.red("\u5931\u8D25\u660E\u7EC6:"));
385
351
  for (let i = 0; i < previewCount; i++) {
386
352
  const item = failedItems[i];
387
353
  const reason = item.error?.message || "unknown error";
388
- console.log(` ${import_chalk.default.red("\u2022")} ${item.name} => ${reason}`);
354
+ console.log(` ${chalk.red("\u2022")} ${item.name} => ${reason}`);
389
355
  }
390
356
  if (failedItems.length > previewCount) {
391
- console.log(import_chalk.default.gray(` ... \u8FD8\u6709 ${failedItems.length - previewCount} \u4E2A\u5931\u8D25\u6587\u4EF6`));
357
+ console.log(chalk.gray(` ... \u8FD8\u6709 ${failedItems.length - previewCount} \u4E2A\u5931\u8D25\u6587\u4EF6`));
392
358
  }
393
359
  console.log("");
394
360
  }
395
361
  try {
396
- await (0, import_delete_empty.default)((0, import_node_path.resolve)(outDir));
362
+ await deleteEmpty(resolve(outDir));
397
363
  } catch (error) {
398
- console.warn(`${import_chalk.default.yellow("\u26A0 \u6E05\u7406\u7A7A\u76EE\u5F55\u5931\u8D25:")} ${error}`);
364
+ console.warn(`${chalk.yellow("\u26A0 \u6E05\u7406\u7A7A\u76EE\u5F55\u5931\u8D25:")} ${error}`);
399
365
  }
400
366
  if (failedCount > 0 && failOnError) {
401
367
  throw new Error(`Failed to upload ${failedCount} of ${results.length} files`);
402
368
  }
403
369
  } catch (error) {
404
370
  console.log(`
405
- ${import_chalk.default.red("\u274C \u4E0A\u4F20\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:")} ${error}
371
+ ${chalk.red("\u274C \u4E0A\u4F20\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:")} ${error}
406
372
  `);
407
373
  if (failOnError) {
408
374
  throw error instanceof Error ? error : new Error(String(error));
@@ -412,3 +378,6 @@ ${import_chalk.default.red("\u274C \u4E0A\u4F20\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9
412
378
  }
413
379
  };
414
380
  }
381
+ export {
382
+ vitePluginDeployOss as default
383
+ };
package/package.json CHANGED
@@ -1,10 +1,9 @@
1
1
  {
2
2
  "name": "vite-plugin-deploy-oss",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "main": "./dist/index.js",
5
- "module": "./dist/index.mjs",
6
5
  "types": "./dist/index.d.ts",
7
- "type": "commonjs",
6
+ "type": "module",
8
7
  "homepage": "https://github.com/yulin96/vite-plugin-deploy-oss",
9
8
  "repository": {
10
9
  "type": "git",
@@ -15,14 +14,8 @@
15
14
  },
16
15
  "exports": {
17
16
  ".": {
18
- "import": {
19
- "types": "./dist/index.d.mts",
20
- "default": "./dist/index.mjs"
21
- },
22
- "require": {
23
- "types": "./dist/index.d.ts",
24
- "default": "./dist/index.js"
25
- }
17
+ "types": "./dist/index.d.ts",
18
+ "default": "./dist/index.js"
26
19
  }
27
20
  },
28
21
  "keywords": [
package/dist/index.d.mts DELETED
@@ -1,26 +0,0 @@
1
- import oss from 'ali-oss';
2
- import { Plugin } from 'vite';
3
-
4
- interface vitePluginDeployOssOption extends Omit<oss.Options, 'accessKeyId' | 'accessKeySecret' | 'bucket' | 'region'> {
5
- configBase?: string;
6
- accessKeyId: string;
7
- accessKeySecret: string;
8
- region: string;
9
- secure?: boolean;
10
- bucket: string;
11
- overwrite?: boolean;
12
- uploadDir: string;
13
- alias?: string;
14
- autoDelete?: boolean;
15
- skip?: string | string[];
16
- open?: boolean;
17
- fancy?: boolean;
18
- noCache?: boolean;
19
- failOnError?: boolean;
20
- concurrency?: number;
21
- retryTimes?: number;
22
- multipartThreshold?: number;
23
- }
24
- declare function vitePluginDeployOss(option: vitePluginDeployOssOption): Plugin;
25
-
26
- export { vitePluginDeployOss as default, type vitePluginDeployOssOption };
package/dist/index.mjs DELETED
@@ -1,383 +0,0 @@
1
- // src/index.ts
2
- import oss from "ali-oss";
3
- import chalk from "chalk";
4
- import deleteEmpty from "delete-empty";
5
- import { globSync } from "glob";
6
- import { stat, unlink } from "fs/promises";
7
- import { resolve } from "path";
8
- import ora from "ora";
9
- import { normalizePath } from "vite";
10
- var normalizeObjectKey = (targetDir, relativeFilePath) => normalizePath(`${targetDir}/${relativeFilePath}`).replace(/\/{2,}/g, "/").replace(/^\/+/, "");
11
- var formatBytes = (bytes) => {
12
- if (!Number.isFinite(bytes) || bytes <= 0) return "0 B";
13
- const units = ["B", "KB", "MB", "GB", "TB"];
14
- let value = bytes;
15
- let unitIndex = 0;
16
- while (value >= 1024 && unitIndex < units.length - 1) {
17
- value /= 1024;
18
- unitIndex++;
19
- }
20
- const digits = value >= 100 || unitIndex === 0 ? 0 : 1;
21
- return `${value.toFixed(digits)} ${units[unitIndex]}`;
22
- };
23
- var formatDuration = (seconds) => {
24
- if (!Number.isFinite(seconds) || seconds < 0) return "--";
25
- const rounded = Math.round(seconds);
26
- const mins = Math.floor(rounded / 60);
27
- const secs = rounded % 60;
28
- if (mins === 0) return `${secs}s`;
29
- return `${mins}m${String(secs).padStart(2, "0")}s`;
30
- };
31
- var trimMiddle = (text, maxLength) => {
32
- if (text.length <= maxLength) return text;
33
- if (maxLength <= 10) return text.slice(0, maxLength);
34
- const leftLength = Math.floor((maxLength - 3) / 2);
35
- const rightLength = maxLength - 3 - leftLength;
36
- return `${text.slice(0, leftLength)}...${text.slice(-rightLength)}`;
37
- };
38
- var buildCapsuleBar = (ratio, width = 30) => {
39
- const safeRatio = Math.max(0, Math.min(1, ratio));
40
- if (width <= 0) return "";
41
- if (safeRatio >= 1) {
42
- return chalk.green("\u2588".repeat(width));
43
- }
44
- const pointerIndex = Math.min(width - 1, Math.floor(width * safeRatio));
45
- const done = pointerIndex > 0 ? chalk.green("\u2588".repeat(pointerIndex)) : "";
46
- const pointer = chalk.cyanBright("\u25B8");
47
- const pending = pointerIndex < width - 1 ? chalk.gray("\u2591".repeat(width - pointerIndex - 1)) : "";
48
- return `${done}${pointer}${pending}`;
49
- };
50
- function vitePluginDeployOss(option) {
51
- const {
52
- accessKeyId,
53
- accessKeySecret,
54
- region,
55
- bucket,
56
- configBase,
57
- skip = "**/index.html",
58
- uploadDir,
59
- overwrite = true,
60
- secure = true,
61
- autoDelete = false,
62
- alias,
63
- open = true,
64
- fancy = true,
65
- noCache = false,
66
- failOnError = true,
67
- concurrency = 5,
68
- retryTimes = 3,
69
- multipartThreshold = 10 * 1024 * 1024,
70
- ...props
71
- } = option || {};
72
- let buildFailed = false;
73
- let upload = false;
74
- let outDir = normalizePath(resolve("dist"));
75
- let resolvedConfig = null;
76
- const useInteractiveOutput = fancy && Boolean(process.stdout?.isTTY) && Boolean(process.stderr?.isTTY) && !process.env.CI;
77
- const clearScreen = () => {
78
- if (!useInteractiveOutput) return;
79
- process.stdout.write("\x1B[2J\x1B[0f");
80
- };
81
- const validateOptions = () => {
82
- const errors = [];
83
- if (!accessKeyId) errors.push("accessKeyId is required");
84
- if (!accessKeySecret) errors.push("accessKeySecret is required");
85
- if (!bucket) errors.push("bucket is required");
86
- if (!region) errors.push("region is required");
87
- if (!uploadDir) errors.push("uploadDir is required");
88
- if (!Number.isInteger(retryTimes) || retryTimes < 1) errors.push("retryTimes must be >= 1");
89
- if (!Number.isInteger(concurrency) || concurrency < 1) errors.push("concurrency must be >= 1");
90
- if (!Number.isFinite(multipartThreshold) || multipartThreshold <= 0)
91
- errors.push("multipartThreshold must be > 0");
92
- return errors;
93
- };
94
- const uploadFileWithRetry = async (client, task, silentLogs, maxRetries = retryTimes) => {
95
- const shouldUseMultipart = task.size >= multipartThreshold;
96
- const headers = {
97
- "x-oss-storage-class": "Standard",
98
- "x-oss-object-acl": "default",
99
- "Cache-Control": noCache ? "no-cache" : "public, max-age=86400, immutable",
100
- "x-oss-forbid-overwrite": overwrite ? "false" : "true"
101
- };
102
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
103
- try {
104
- const result = shouldUseMultipart ? await client.multipartUpload(task.name, task.filePath, {
105
- timeout: 6e5,
106
- partSize: 1024 * 1024,
107
- parallel: Math.max(1, Math.min(concurrency, 4)),
108
- headers
109
- }) : await client.put(task.name, task.filePath, {
110
- timeout: 6e5,
111
- headers
112
- });
113
- if (result.res.status === 200) {
114
- if (autoDelete) {
115
- try {
116
- await unlink(task.filePath);
117
- } catch (error) {
118
- console.warn(`${chalk.yellow("\u26A0")} \u5220\u9664\u672C\u5730\u6587\u4EF6\u5931\u8D25: ${task.filePath}`);
119
- }
120
- }
121
- return { success: true, file: task.filePath, name: task.name, size: task.size, retries: attempt - 1 };
122
- } else {
123
- throw new Error(`Upload failed with status: ${result.res.status}`);
124
- }
125
- } catch (error) {
126
- if (attempt === maxRetries) {
127
- if (!silentLogs) {
128
- console.log(
129
- `${chalk.red("\u2717")} ${task.filePath} => ${error instanceof Error ? error.message : String(error)}`
130
- );
131
- }
132
- return {
133
- success: false,
134
- file: task.filePath,
135
- name: task.name,
136
- size: task.size,
137
- retries: attempt - 1,
138
- error
139
- };
140
- } else {
141
- if (!silentLogs) {
142
- console.log(`${chalk.yellow("\u26A0")} ${task.filePath} \u4E0A\u4F20\u5931\u8D25\uFF0C\u6B63\u5728\u91CD\u8BD5 (${attempt}/${maxRetries})...`);
143
- }
144
- await new Promise((resolve2) => setTimeout(resolve2, 1e3 * attempt));
145
- }
146
- }
147
- }
148
- return {
149
- success: false,
150
- file: task.filePath,
151
- name: task.name,
152
- size: task.size,
153
- retries: maxRetries,
154
- error: new Error("Max retries exceeded")
155
- };
156
- };
157
- const uploadFilesInBatches = async (client, files, windowSize = concurrency) => {
158
- const results = [];
159
- const totalFiles = files.length;
160
- const tasks = [];
161
- let completed = 0;
162
- let failed = 0;
163
- let uploadedBytes = 0;
164
- let retries = 0;
165
- const taskCandidates = await Promise.all(
166
- files.map(async (relativeFilePath) => {
167
- const filePath = normalizePath(resolve(outDir, relativeFilePath));
168
- const name = normalizeObjectKey(uploadDir, relativeFilePath);
169
- try {
170
- const fileStats = await stat(filePath);
171
- return { task: { filePath, name, size: fileStats.size } };
172
- } catch (error) {
173
- return { task: null, error, filePath, name };
174
- }
175
- })
176
- );
177
- for (const candidate of taskCandidates) {
178
- if (candidate.task) {
179
- tasks.push(candidate.task);
180
- } else {
181
- failed++;
182
- completed++;
183
- results.push({
184
- success: false,
185
- file: candidate.filePath,
186
- name: candidate.name,
187
- size: 0,
188
- retries: 0,
189
- error: candidate.error
190
- });
191
- }
192
- }
193
- const totalBytes = tasks.reduce((sum, task) => sum + task.size, 0);
194
- const startAt = Date.now();
195
- const activeFiles = /* @__PURE__ */ new Set();
196
- const safeWindowSize = Math.max(1, Math.min(windowSize, tasks.length || 1));
197
- const silentLogs = Boolean(useInteractiveOutput);
198
- const spinner = useInteractiveOutput ? ora({ text: "\u51C6\u5907\u4E0A\u4F20...", spinner: "dots12" }).start() : null;
199
- const reportEvery = Math.max(1, Math.ceil(totalFiles / 10));
200
- let lastReportedCompleted = -1;
201
- const updateProgress = () => {
202
- const progressRatio = totalFiles > 0 ? completed / totalFiles : 1;
203
- const percentage = Math.round(progressRatio * 100);
204
- const elapsedSeconds = (Date.now() - startAt) / 1e3;
205
- const speed = elapsedSeconds > 0 ? uploadedBytes / elapsedSeconds : 0;
206
- const etaSeconds = speed > 0 ? Math.max(0, (totalBytes - uploadedBytes) / speed) : 0;
207
- const activeList = Array.from(activeFiles);
208
- const currentFile = activeList.length > 0 ? trimMiddle(activeList[activeList.length - 1], 86) : "-";
209
- if (!spinner) {
210
- if (completed === lastReportedCompleted) return;
211
- if (completed === totalFiles || completed % reportEvery === 0) {
212
- console.log(
213
- `${chalk.gray("\u8FDB\u5EA6:")} ${completed}/${totalFiles} (${percentage}%) | ${chalk.gray("\u6570\u636E:")} ${formatBytes(uploadedBytes)}/${formatBytes(totalBytes)} | ${chalk.gray("\u901F\u5EA6:")} ${formatBytes(speed)}/s`
214
- );
215
- lastReportedCompleted = completed;
216
- }
217
- return;
218
- }
219
- const bar = buildCapsuleBar(progressRatio);
220
- const warnLine = retries > 0 || failed > 0 ? `
221
- ${chalk.yellow("\u91CD\u8BD5")}: ${retries} ${chalk.yellow("\u5931\u8D25")}: ${failed}` : "";
222
- spinner.text = [
223
- `${chalk.cyan("\u6B63\u5728\u4E0A\u4F20:")} ${chalk.white(currentFile)}`,
224
- `${bar} ${chalk.bold(`${percentage}%`)} ${chalk.gray(`(${completed}/${totalFiles})`)} ${chalk.gray("|")} ${chalk.blue(formatBytes(uploadedBytes))}/${chalk.blue(formatBytes(totalBytes))} ${chalk.gray("|")} ${chalk.magenta(`${formatBytes(speed)}/s`)} ${chalk.gray("|")} \u9884\u8BA1 ${chalk.yellow(formatDuration(etaSeconds))}`
225
- ].join("\n");
226
- spinner.text += warnLine;
227
- };
228
- const refreshTimer = spinner ? setInterval(updateProgress, 120) : null;
229
- let currentIndex = 0;
230
- const worker = async () => {
231
- while (true) {
232
- const index = currentIndex++;
233
- if (index >= tasks.length) return;
234
- const task = tasks[index];
235
- activeFiles.add(task.name);
236
- updateProgress();
237
- const result = await uploadFileWithRetry(client, task, silentLogs);
238
- completed++;
239
- retries += result.retries;
240
- if (result.success) {
241
- uploadedBytes += result.size;
242
- } else {
243
- failed++;
244
- }
245
- results.push(result);
246
- activeFiles.delete(task.name);
247
- updateProgress();
248
- }
249
- };
250
- updateProgress();
251
- try {
252
- await Promise.all(Array.from({ length: safeWindowSize }, () => worker()));
253
- } finally {
254
- if (refreshTimer) clearInterval(refreshTimer);
255
- }
256
- if (spinner) {
257
- const elapsedSeconds = (Date.now() - startAt) / 1e3;
258
- const successCount = results.filter((item) => item.success).length;
259
- const speed = elapsedSeconds > 0 ? uploadedBytes / elapsedSeconds : 0;
260
- spinner.succeed(
261
- `${chalk.green("\u4E0A\u4F20\u6210\u529F")} ${successCount} \u4E2A\u6587\u4EF6\u3002
262
- ${buildCapsuleBar(1)} 100% (${totalFiles}/${totalFiles}) ${chalk.gray("|")} \u901F\u5EA6 ${chalk.magenta(`${formatBytes(speed)}/s`)} ${chalk.gray("|")} \u8017\u65F6 ${chalk.yellow(formatDuration(elapsedSeconds))}`
263
- );
264
- } else {
265
- console.log(`${chalk.green("\u2714")} \u6240\u6709\u6587\u4EF6\u4E0A\u4F20\u5B8C\u6210 (${totalFiles}/${totalFiles})`);
266
- }
267
- return results;
268
- };
269
- return {
270
- name: "vite-plugin-deploy-oss",
271
- apply: "build",
272
- enforce: "post",
273
- buildEnd(error) {
274
- if (error) buildFailed = true;
275
- },
276
- config(config) {
277
- if (!open || buildFailed) return;
278
- clearScreen();
279
- const validationErrors = validateOptions();
280
- if (validationErrors.length > 0) {
281
- console.log(`${chalk.red("\u2717 \u914D\u7F6E\u9519\u8BEF:")}
282
- ${validationErrors.map((err) => ` - ${err}`).join("\n")}`);
283
- return;
284
- }
285
- upload = true;
286
- config.base = configBase || config.base;
287
- return config;
288
- },
289
- configResolved(config) {
290
- resolvedConfig = config;
291
- outDir = normalizePath(resolve(config.root, config.build.outDir));
292
- },
293
- closeBundle: {
294
- sequential: true,
295
- order: "post",
296
- async handler() {
297
- if (!open || !upload || buildFailed || !resolvedConfig) return;
298
- const startTime = Date.now();
299
- const client = new oss({ region, accessKeyId, accessKeySecret, secure, bucket, ...props });
300
- const files = globSync("**/*", {
301
- cwd: outDir,
302
- nodir: true,
303
- ignore: Array.isArray(skip) ? skip : [skip]
304
- }).map((file) => normalizePath(file));
305
- if (files.length === 0) {
306
- console.log(`${chalk.yellow("\u26A0 \u6CA1\u6709\u627E\u5230\u9700\u8981\u4E0A\u4F20\u7684\u6587\u4EF6")}`);
307
- return;
308
- }
309
- clearScreen();
310
- console.log(chalk.cyan(`
311
- \u{1F680} OSS \u90E8\u7F72\u5F00\u59CB
312
- `));
313
- console.log(`${chalk.gray("Bucket:")} ${chalk.green(bucket)}`);
314
- console.log(`${chalk.gray("Region:")} ${chalk.green(region)}`);
315
- console.log(`${chalk.gray("Source:")} ${chalk.yellow(outDir)}`);
316
- console.log(`${chalk.gray("Target:")} ${chalk.yellow(uploadDir)}`);
317
- if (alias) console.log(`${chalk.gray("Alias:")} ${chalk.green(alias)}`);
318
- console.log(`${chalk.gray("Files:")} ${chalk.blue(files.length)}
319
- `);
320
- try {
321
- const results = await uploadFilesInBatches(client, files, concurrency);
322
- const successCount = results.filter((r) => r.success).length;
323
- const failedCount = results.length - successCount;
324
- const durationSeconds = (Date.now() - startTime) / 1e3;
325
- const duration = durationSeconds.toFixed(2);
326
- const uploadedBytes = results.reduce((sum, result) => result.success ? sum + result.size : sum, 0);
327
- const retryCount = results.reduce((sum, result) => sum + result.retries, 0);
328
- const avgSpeed = durationSeconds > 0 ? uploadedBytes / durationSeconds : 0;
329
- clearScreen();
330
- console.log("\n" + chalk.gray("\u2500".repeat(40)) + "\n");
331
- if (failedCount === 0) {
332
- console.log(`${chalk.green("\u{1F389} \u90E8\u7F72\u6210\u529F!")}`);
333
- } else {
334
- console.log(`${chalk.yellow("\u26A0 \u90E8\u7F72\u5B8C\u6210\u4F46\u5B58\u5728\u9519\u8BEF")}`);
335
- }
336
- console.log(`
337
- ${chalk.gray("\u7EDF\u8BA1:")}`);
338
- console.log(` ${chalk.green("\u2714")} \u6210\u529F: ${chalk.bold(successCount)}`);
339
- if (failedCount > 0) {
340
- console.log(` ${chalk.red("\u2717")} \u5931\u8D25: ${chalk.bold(failedCount)}`);
341
- }
342
- console.log(` ${chalk.cyan("\u21C4")} \u91CD\u8BD5: ${chalk.bold(retryCount)}`);
343
- console.log(` ${chalk.blue("\u{1F4E6}")} \u6570\u636E: ${chalk.bold(formatBytes(uploadedBytes))}`);
344
- console.log(` ${chalk.magenta("\u26A1")} \u5E73\u5747\u901F\u5EA6: ${chalk.bold(`${formatBytes(avgSpeed)}/s`)}`);
345
- console.log(` ${chalk.blue("\u23F1")} \u8017\u65F6: ${chalk.bold(duration)}s`);
346
- console.log("");
347
- if (failedCount > 0) {
348
- const failedItems = results.filter((result) => !result.success);
349
- const previewCount = Math.min(5, failedItems.length);
350
- console.log(chalk.red("\u5931\u8D25\u660E\u7EC6:"));
351
- for (let i = 0; i < previewCount; i++) {
352
- const item = failedItems[i];
353
- const reason = item.error?.message || "unknown error";
354
- console.log(` ${chalk.red("\u2022")} ${item.name} => ${reason}`);
355
- }
356
- if (failedItems.length > previewCount) {
357
- console.log(chalk.gray(` ... \u8FD8\u6709 ${failedItems.length - previewCount} \u4E2A\u5931\u8D25\u6587\u4EF6`));
358
- }
359
- console.log("");
360
- }
361
- try {
362
- await deleteEmpty(resolve(outDir));
363
- } catch (error) {
364
- console.warn(`${chalk.yellow("\u26A0 \u6E05\u7406\u7A7A\u76EE\u5F55\u5931\u8D25:")} ${error}`);
365
- }
366
- if (failedCount > 0 && failOnError) {
367
- throw new Error(`Failed to upload ${failedCount} of ${results.length} files`);
368
- }
369
- } catch (error) {
370
- console.log(`
371
- ${chalk.red("\u274C \u4E0A\u4F20\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:")} ${error}
372
- `);
373
- if (failOnError) {
374
- throw error instanceof Error ? error : new Error(String(error));
375
- }
376
- }
377
- }
378
- }
379
- };
380
- }
381
- export {
382
- vitePluginDeployOss as default
383
- };