vite-plugin-deploy-oss 3.2.1 → 3.3.1
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/.prettierignore +5 -0
- package/.prettierrc.json +12 -0
- package/README.md +11 -0
- package/dist/index.d.ts +32 -3
- package/dist/index.js +358 -164
- package/package.json +11 -3
package/.prettierignore
ADDED
package/.prettierrc.json
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/prettierrc",
|
|
3
|
+
"arrowParens": "always",
|
|
4
|
+
"bracketSameLine": false,
|
|
5
|
+
"jsxSingleQuote": true,
|
|
6
|
+
"printWidth": 120,
|
|
7
|
+
"quoteProps": "as-needed",
|
|
8
|
+
"semi": false,
|
|
9
|
+
"singleQuote": true,
|
|
10
|
+
"tabWidth": 2,
|
|
11
|
+
"endOfLine": "lf"
|
|
12
|
+
}
|
package/README.md
CHANGED
|
@@ -12,6 +12,14 @@
|
|
|
12
12
|
pnpm add vite-plugin-deploy-oss -D
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
## 调试模式
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pnpm run build:test:debug
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
这会进入带调试信息的上传模式,构建结束后额外输出每个关键步骤花了多久。
|
|
22
|
+
|
|
15
23
|
## 使用
|
|
16
24
|
|
|
17
25
|
```ts
|
|
@@ -26,6 +34,8 @@ export default {
|
|
|
26
34
|
vitePluginDeployOss({
|
|
27
35
|
// 建议按环境变量开关上传,避免本地/CI误上传
|
|
28
36
|
open: process.env.DEPLOY_OSS === '1',
|
|
37
|
+
// 输出调试耗时信息,方便排查慢在哪里
|
|
38
|
+
debug: process.env.DEPLOY_OSS_DEBUG === '1',
|
|
29
39
|
// 终端实时动效进度面板(默认 true)
|
|
30
40
|
fancy: true,
|
|
31
41
|
|
|
@@ -53,6 +63,7 @@ export default {
|
|
|
53
63
|
|
|
54
64
|
- 当前版本仅支持 ESM(`import`),不再提供 CommonJS(`require`)入口。
|
|
55
65
|
- `open` 默认 `true`,建议通过环境变量控制开关(例如 `DEPLOY_OSS=1` 时再上传)。
|
|
66
|
+
- `debug` 默认关闭。开启后会在结束时额外输出每个关键步骤花了多久,方便排查慢点和卡点。
|
|
56
67
|
- `fancy` 默认 `true`,TTY 终端下会显示实时动效进度(速度、预计剩余、并发、当前文件)。
|
|
57
68
|
- `failOnError` 默认 `true`,上传有失败会抛错,适合 CI 场景保证发布质量。
|
|
58
69
|
- `manifest` 默认关闭。开启后会在构建目录生成并上传 `oss-manifest.json`。
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import oss from 'ali-oss';
|
|
2
1
|
import { Plugin } from 'vite';
|
|
2
|
+
import oss from 'ali-oss';
|
|
3
3
|
|
|
4
4
|
interface ManifestOption {
|
|
5
5
|
fileName?: string;
|
|
6
6
|
}
|
|
7
|
+
type ManifestConfig = boolean | ManifestOption | undefined;
|
|
7
8
|
interface vitePluginDeployOssOption extends Omit<oss.Options, 'accessKeyId' | 'accessKeySecret' | 'bucket' | 'region'> {
|
|
8
9
|
configBase?: string;
|
|
9
10
|
accessKeyId: string;
|
|
@@ -17,14 +18,42 @@ interface vitePluginDeployOssOption extends Omit<oss.Options, 'accessKeyId' | 'a
|
|
|
17
18
|
autoDelete?: boolean;
|
|
18
19
|
skip?: string | string[];
|
|
19
20
|
open?: boolean;
|
|
21
|
+
debug?: boolean;
|
|
20
22
|
fancy?: boolean;
|
|
21
23
|
noCache?: boolean;
|
|
22
24
|
failOnError?: boolean;
|
|
23
25
|
concurrency?: number;
|
|
24
26
|
retryTimes?: number;
|
|
25
27
|
multipartThreshold?: number;
|
|
26
|
-
manifest?:
|
|
28
|
+
manifest?: ManifestConfig;
|
|
29
|
+
}
|
|
30
|
+
interface UploadResult {
|
|
31
|
+
success: boolean;
|
|
32
|
+
file: string;
|
|
33
|
+
relativeFilePath: string;
|
|
34
|
+
name: string;
|
|
35
|
+
size: number;
|
|
36
|
+
retries: number;
|
|
37
|
+
error?: Error;
|
|
38
|
+
}
|
|
39
|
+
interface UploadTask {
|
|
40
|
+
filePath: string;
|
|
41
|
+
relativeFilePath: string;
|
|
42
|
+
name: string;
|
|
43
|
+
size: number;
|
|
44
|
+
cacheControl?: string;
|
|
27
45
|
}
|
|
46
|
+
interface ManifestFileItem {
|
|
47
|
+
file: string;
|
|
48
|
+
key: string;
|
|
49
|
+
url: string;
|
|
50
|
+
md5: string;
|
|
51
|
+
}
|
|
52
|
+
interface ManifestPayload {
|
|
53
|
+
version: number;
|
|
54
|
+
files: ManifestFileItem[];
|
|
55
|
+
}
|
|
56
|
+
|
|
28
57
|
declare function vitePluginDeployOss(option: vitePluginDeployOssOption): Plugin;
|
|
29
58
|
|
|
30
|
-
export { vitePluginDeployOss as default, type vitePluginDeployOssOption };
|
|
59
|
+
export { type ManifestConfig, type ManifestFileItem, type ManifestOption, type ManifestPayload, type UploadResult, type UploadTask, vitePluginDeployOss as default, type vitePluginDeployOssOption };
|
package/dist/index.js
CHANGED
|
@@ -1,24 +1,27 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import oss from "ali-oss";
|
|
3
|
-
import
|
|
3
|
+
import chalk3 from "chalk";
|
|
4
|
+
import cliProgress from "cli-progress";
|
|
4
5
|
import { globSync } from "glob";
|
|
6
|
+
import { mkdir, stat, unlink, writeFile } from "fs/promises";
|
|
7
|
+
import { dirname, resolve as resolve2 } from "path";
|
|
8
|
+
import { normalizePath } from "vite";
|
|
9
|
+
|
|
10
|
+
// src/utils/file.ts
|
|
5
11
|
import { createHash } from "crypto";
|
|
6
12
|
import { createReadStream } from "fs";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
import { normalizePath } from "vite";
|
|
13
|
+
import { readdir, rm } from "fs/promises";
|
|
14
|
+
import { resolve } from "path";
|
|
15
|
+
var GARBAGE_FILE_REGEX = /(?:Thumbs\.db|\.DS_Store)$/i;
|
|
11
16
|
var getFileMd5 = (filePath) => {
|
|
12
|
-
return new Promise((
|
|
17
|
+
return new Promise((resolvePromise, reject) => {
|
|
13
18
|
const hash = createHash("md5");
|
|
14
19
|
const stream = createReadStream(filePath);
|
|
15
20
|
stream.on("error", (err) => reject(err));
|
|
16
21
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
17
|
-
stream.on("end", () =>
|
|
22
|
+
stream.on("end", () => resolvePromise(hash.digest("hex")));
|
|
18
23
|
});
|
|
19
24
|
};
|
|
20
|
-
var GARBAGE_FILE_REGEX = /(?:Thumbs\.db|\.DS_Store)$/i;
|
|
21
|
-
var DEFAULT_MANIFEST_FILE_NAME = "oss-manifest.json";
|
|
22
25
|
var removeEmptyDirectories = async (rootDir) => {
|
|
23
26
|
const deletedDirectories = [];
|
|
24
27
|
const visit = async (dirPath) => {
|
|
@@ -43,9 +46,53 @@ var removeEmptyDirectories = async (rootDir) => {
|
|
|
43
46
|
await visit(resolve(rootDir));
|
|
44
47
|
return deletedDirectories;
|
|
45
48
|
};
|
|
46
|
-
|
|
49
|
+
|
|
50
|
+
// src/utils/path.ts
|
|
51
|
+
var DEFAULT_MANIFEST_FILE_NAME = "oss-manifest.json";
|
|
52
|
+
var normalizeSlash = (value) => value.replace(/\\/g, "/").trim();
|
|
53
|
+
var normalizePathSegments = (...values) => values.filter((value) => Boolean(value)).flatMap((value) => normalizeSlash(value).split("/")).filter(Boolean).join("/");
|
|
54
|
+
var splitUrlLikeBase = (value) => {
|
|
55
|
+
const normalized = normalizeSlash(value);
|
|
56
|
+
const protocolMatch = normalized.match(/^([a-zA-Z][a-zA-Z\d+.-]*:\/\/[^/]+)(.*)$/);
|
|
57
|
+
if (protocolMatch) {
|
|
58
|
+
return {
|
|
59
|
+
prefix: protocolMatch[1],
|
|
60
|
+
path: protocolMatch[2] || ""
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
const protocolRelativeMatch = normalized.match(/^(\/\/[^/]+)(.*)$/);
|
|
64
|
+
if (protocolRelativeMatch) {
|
|
65
|
+
return {
|
|
66
|
+
prefix: protocolRelativeMatch[1],
|
|
67
|
+
path: protocolRelativeMatch[2] || ""
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (normalized.startsWith("/")) {
|
|
71
|
+
return {
|
|
72
|
+
prefix: "/",
|
|
73
|
+
path: normalized
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
prefix: "",
|
|
78
|
+
path: normalized
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
var normalizeUrlLikeBase = (base) => {
|
|
82
|
+
const { prefix, path } = splitUrlLikeBase(base);
|
|
83
|
+
const normalizedPath = normalizePathSegments(path);
|
|
84
|
+
if (!prefix) return normalizedPath;
|
|
85
|
+
if (!normalizedPath) return prefix;
|
|
86
|
+
if (prefix === "/") return `/${normalizedPath}`;
|
|
87
|
+
return `${prefix}/${normalizedPath}`;
|
|
88
|
+
};
|
|
89
|
+
var ensureTrailingSlash = (value) => {
|
|
90
|
+
if (!value || value.endsWith("/")) return value;
|
|
91
|
+
return `${value}/`;
|
|
92
|
+
};
|
|
93
|
+
var normalizeObjectKey = (targetDir, relativeFilePath) => normalizePathSegments(targetDir, relativeFilePath);
|
|
47
94
|
var normalizeManifestFileName = (fileName) => {
|
|
48
|
-
const normalized =
|
|
95
|
+
const normalized = normalizePathSegments(fileName || DEFAULT_MANIFEST_FILE_NAME);
|
|
49
96
|
return normalized || DEFAULT_MANIFEST_FILE_NAME;
|
|
50
97
|
};
|
|
51
98
|
var resolveManifestFileName = (manifest) => {
|
|
@@ -53,46 +100,16 @@ var resolveManifestFileName = (manifest) => {
|
|
|
53
100
|
if (manifest === true) return DEFAULT_MANIFEST_FILE_NAME;
|
|
54
101
|
return normalizeManifestFileName(manifest.fileName);
|
|
55
102
|
};
|
|
56
|
-
var
|
|
57
|
-
|
|
58
|
-
const protocolSeparatorIndex = normalized.indexOf("://");
|
|
59
|
-
if (protocolSeparatorIndex >= 0) {
|
|
60
|
-
const pathIndex = normalized.indexOf("/", protocolSeparatorIndex + 3);
|
|
61
|
-
if (pathIndex < 0) return normalized;
|
|
62
|
-
return `${normalized.slice(0, pathIndex)}${normalized.slice(pathIndex).replace(/\/{2,}/g, "/")}`;
|
|
63
|
-
}
|
|
64
|
-
if (normalized.startsWith("//")) {
|
|
65
|
-
const pathIndex = normalized.indexOf("/", 2);
|
|
66
|
-
if (pathIndex < 0) return normalized;
|
|
67
|
-
return `${normalized.slice(0, pathIndex)}${normalized.slice(pathIndex).replace(/\/{2,}/g, "/")}`;
|
|
68
|
-
}
|
|
69
|
-
return normalized.replace(/\/{2,}/g, "/");
|
|
70
|
-
};
|
|
71
|
-
var encodeUrlPath = (path) => encodeURI(path.replace(/^\/+/, ""));
|
|
72
|
-
var joinUrlPath = (base, path) => `${normalizeUrlBase(base).replace(/\/+$/, "")}/${encodeUrlPath(path)}`;
|
|
103
|
+
var encodeUrlPath = (path) => encodeURI(normalizePathSegments(path));
|
|
104
|
+
var joinUrlPath = (base, path) => `${normalizeUrlLikeBase(base).replace(/\/+$/, "")}/${encodeUrlPath(path)}`;
|
|
73
105
|
var resolveUploadedFileUrl = (relativeFilePath, objectKey, configBase, alias) => {
|
|
74
106
|
if (configBase) return joinUrlPath(configBase, relativeFilePath);
|
|
75
107
|
if (alias) return joinUrlPath(alias, objectKey);
|
|
76
108
|
return objectKey;
|
|
77
109
|
};
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
successfulResults.map(async (result) => {
|
|
82
|
-
const md5 = await getFileMd5(result.file);
|
|
83
|
-
return {
|
|
84
|
-
file: result.relativeFilePath,
|
|
85
|
-
key: result.name,
|
|
86
|
-
url: resolveUploadedFileUrl(result.relativeFilePath, result.name, configBase, alias),
|
|
87
|
-
md5
|
|
88
|
-
};
|
|
89
|
-
})
|
|
90
|
-
);
|
|
91
|
-
return {
|
|
92
|
-
version: Date.now(),
|
|
93
|
-
files
|
|
94
|
-
};
|
|
95
|
-
};
|
|
110
|
+
|
|
111
|
+
// src/utils/progress.ts
|
|
112
|
+
import chalk from "chalk";
|
|
96
113
|
var formatBytes = (bytes) => {
|
|
97
114
|
if (!Number.isFinite(bytes) || bytes <= 0) return "0 B";
|
|
98
115
|
const units = ["B", "KB", "MB", "GB", "TB"];
|
|
@@ -113,24 +130,110 @@ var formatDuration = (seconds) => {
|
|
|
113
130
|
if (mins === 0) return `${secs}s`;
|
|
114
131
|
return `${mins}m${String(secs).padStart(2, "0")}s`;
|
|
115
132
|
};
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
133
|
+
|
|
134
|
+
// src/utils/terminal.ts
|
|
135
|
+
import chalk2 from "chalk";
|
|
136
|
+
import cliTruncate from "cli-truncate";
|
|
137
|
+
import logSymbols from "log-symbols";
|
|
138
|
+
import stringWidth from "string-width";
|
|
139
|
+
var panelBorderColor = {
|
|
140
|
+
info: "cyan",
|
|
141
|
+
success: "green",
|
|
142
|
+
warning: "yellow",
|
|
143
|
+
danger: "red"
|
|
122
144
|
};
|
|
123
|
-
var
|
|
124
|
-
|
|
145
|
+
var getTerminalWidth = () => process.stdout?.columns || 100;
|
|
146
|
+
var getPanelInnerWidth = () => Math.max(46, Math.min(84, getTerminalWidth() - 4));
|
|
147
|
+
var padVisual = (text, width) => `${text}${" ".repeat(Math.max(0, width - stringWidth(text)))}`;
|
|
148
|
+
var fitVisual = (text, width) => {
|
|
125
149
|
if (width <= 0) return "";
|
|
126
|
-
|
|
127
|
-
|
|
150
|
+
return padVisual(cliTruncate(text, width, { position: "middle" }), width);
|
|
151
|
+
};
|
|
152
|
+
var truncateTerminalText = (text, reservedWidth = 26) => {
|
|
153
|
+
const maxWidth = Math.max(24, Math.min(88, getTerminalWidth() - reservedWidth));
|
|
154
|
+
return cliTruncate(text, maxWidth, { position: "middle" });
|
|
155
|
+
};
|
|
156
|
+
var renderPanel = (title, rows, tone = "info", footer) => {
|
|
157
|
+
const color = chalk2[panelBorderColor[tone]];
|
|
158
|
+
const innerWidth = getPanelInnerWidth();
|
|
159
|
+
const labelWidth = rows.length > 0 ? Math.max(...rows.map((row) => stringWidth(row.label))) : 0;
|
|
160
|
+
const contentLines = [chalk2.bold(cliTruncate(title, innerWidth, { position: "end" }))];
|
|
161
|
+
if (rows.length > 0) {
|
|
162
|
+
contentLines.push("");
|
|
163
|
+
for (const row of rows) {
|
|
164
|
+
const paddedLabel = padVisual(row.label, labelWidth);
|
|
165
|
+
const prefix = `${paddedLabel} `;
|
|
166
|
+
const availableValueWidth = Math.max(8, innerWidth - stringWidth(prefix));
|
|
167
|
+
contentLines.push(`${chalk2.gray(prefix)}${fitVisual(row.value, availableValueWidth)}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (footer) {
|
|
171
|
+
contentLines.push("");
|
|
172
|
+
contentLines.push(chalk2.gray(cliTruncate(footer, innerWidth, { position: "middle" })));
|
|
173
|
+
}
|
|
174
|
+
const top = color(`\u256D${"\u2500".repeat(innerWidth + 2)}\u256E`);
|
|
175
|
+
const bottom = color(`\u2570${"\u2500".repeat(innerWidth + 2)}\u256F`);
|
|
176
|
+
const body = contentLines.map((line) => `${color("\u2502")} ${fitVisual(line, innerWidth)} ${color("\u2502")}`).join("\n");
|
|
177
|
+
return `${top}
|
|
178
|
+
${body}
|
|
179
|
+
${bottom}`;
|
|
180
|
+
};
|
|
181
|
+
var renderInlineStats = (items) => items.filter(Boolean).join(chalk2.gray(" \xB7 "));
|
|
182
|
+
var getPanelDot = (tone = "success") => {
|
|
183
|
+
switch (tone) {
|
|
184
|
+
case "info":
|
|
185
|
+
return chalk2.green("\u25CF");
|
|
186
|
+
case "success":
|
|
187
|
+
return chalk2.green("\u25CF");
|
|
188
|
+
case "warning":
|
|
189
|
+
return chalk2.yellow("\u25CF");
|
|
190
|
+
case "danger":
|
|
191
|
+
return chalk2.red("\u25CF");
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
var getLogSymbol = (tone) => {
|
|
195
|
+
switch (tone) {
|
|
196
|
+
case "success":
|
|
197
|
+
return logSymbols.success;
|
|
198
|
+
case "warning":
|
|
199
|
+
return logSymbols.warning;
|
|
200
|
+
case "danger":
|
|
201
|
+
return logSymbols.error;
|
|
128
202
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
return `${
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
// src/index.ts
|
|
206
|
+
var formatTimingDuration = (durationMs) => {
|
|
207
|
+
if (durationMs < 1e3) return `${durationMs}ms`;
|
|
208
|
+
const seconds = durationMs / 1e3;
|
|
209
|
+
return `${seconds.toFixed(seconds >= 10 ? 1 : 2)}s`;
|
|
210
|
+
};
|
|
211
|
+
var renderDebugPanel = (entries) => {
|
|
212
|
+
const rows = entries.map((entry) => ({
|
|
213
|
+
label: `${entry.label}:`,
|
|
214
|
+
value: chalk3.cyan(
|
|
215
|
+
entry.detail ? `${formatTimingDuration(entry.durationMs)} \xB7 ${truncateTerminalText(entry.detail, 24)}` : formatTimingDuration(entry.durationMs)
|
|
216
|
+
)
|
|
217
|
+
}));
|
|
218
|
+
return renderPanel(`${getPanelDot("success")} \u8C03\u8BD5\u8017\u65F6`, rows, "info");
|
|
219
|
+
};
|
|
220
|
+
var createManifestPayload = async (results, configBase, alias) => {
|
|
221
|
+
const successfulResults = results.filter((result) => result.success);
|
|
222
|
+
const files = await Promise.all(
|
|
223
|
+
successfulResults.map(async (result) => {
|
|
224
|
+
const md5 = await getFileMd5(result.file);
|
|
225
|
+
return {
|
|
226
|
+
file: result.relativeFilePath,
|
|
227
|
+
key: result.name,
|
|
228
|
+
url: resolveUploadedFileUrl(result.relativeFilePath, result.name, configBase, alias),
|
|
229
|
+
md5
|
|
230
|
+
};
|
|
231
|
+
})
|
|
232
|
+
);
|
|
233
|
+
return {
|
|
234
|
+
version: Date.now(),
|
|
235
|
+
files
|
|
236
|
+
};
|
|
134
237
|
};
|
|
135
238
|
function vitePluginDeployOss(option) {
|
|
136
239
|
const {
|
|
@@ -146,6 +249,7 @@ function vitePluginDeployOss(option) {
|
|
|
146
249
|
autoDelete = false,
|
|
147
250
|
alias,
|
|
148
251
|
open = true,
|
|
252
|
+
debug = false,
|
|
149
253
|
fancy = true,
|
|
150
254
|
noCache = false,
|
|
151
255
|
failOnError = true,
|
|
@@ -155,12 +259,15 @@ function vitePluginDeployOss(option) {
|
|
|
155
259
|
manifest = false,
|
|
156
260
|
...props
|
|
157
261
|
} = option || {};
|
|
262
|
+
const normalizedUploadDir = normalizePathSegments(uploadDir);
|
|
263
|
+
const normalizedConfigBase = configBase ? ensureTrailingSlash(normalizeUrlLikeBase(configBase)) : void 0;
|
|
264
|
+
const normalizedAlias = alias ? normalizeUrlLikeBase(alias) : void 0;
|
|
158
265
|
let buildFailed = false;
|
|
159
266
|
let upload = false;
|
|
160
|
-
let outDir = normalizePath(
|
|
267
|
+
let outDir = normalizePath(resolve2("dist"));
|
|
161
268
|
let resolvedConfig = null;
|
|
162
269
|
const useInteractiveOutput = fancy && Boolean(process.stdout?.isTTY) && Boolean(process.stderr?.isTTY) && !process.env.CI;
|
|
163
|
-
const
|
|
270
|
+
const clearViewport = () => {
|
|
164
271
|
if (!useInteractiveOutput) return;
|
|
165
272
|
process.stdout.write("\x1B[2J\x1B[0f");
|
|
166
273
|
};
|
|
@@ -173,8 +280,7 @@ function vitePluginDeployOss(option) {
|
|
|
173
280
|
if (!uploadDir) errors.push("uploadDir is required");
|
|
174
281
|
if (!Number.isInteger(retryTimes) || retryTimes < 1) errors.push("retryTimes must be >= 1");
|
|
175
282
|
if (!Number.isInteger(concurrency) || concurrency < 1) errors.push("concurrency must be >= 1");
|
|
176
|
-
if (!Number.isFinite(multipartThreshold) || multipartThreshold <= 0)
|
|
177
|
-
errors.push("multipartThreshold must be > 0");
|
|
283
|
+
if (!Number.isFinite(multipartThreshold) || multipartThreshold <= 0) errors.push("multipartThreshold must be > 0");
|
|
178
284
|
return errors;
|
|
179
285
|
};
|
|
180
286
|
const uploadSingleTask = async (client, task) => uploadFileWithRetry(client, task, false);
|
|
@@ -202,7 +308,9 @@ function vitePluginDeployOss(option) {
|
|
|
202
308
|
try {
|
|
203
309
|
await unlink(task.filePath);
|
|
204
310
|
} catch (error) {
|
|
205
|
-
console.warn(
|
|
311
|
+
console.warn(
|
|
312
|
+
`${getLogSymbol("warning")} \u5220\u9664\u672C\u5730\u6587\u4EF6\u5931\u8D25: ${truncateTerminalText(task.relativeFilePath, 18)}`
|
|
313
|
+
);
|
|
206
314
|
}
|
|
207
315
|
}
|
|
208
316
|
return {
|
|
@@ -219,9 +327,8 @@ function vitePluginDeployOss(option) {
|
|
|
219
327
|
} catch (error) {
|
|
220
328
|
if (attempt === maxRetries) {
|
|
221
329
|
if (!silentLogs) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
);
|
|
330
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
331
|
+
console.log(`${getLogSymbol("danger")} ${truncateTerminalText(task.relativeFilePath, 18)} ${reason}`);
|
|
225
332
|
}
|
|
226
333
|
return {
|
|
227
334
|
success: false,
|
|
@@ -234,9 +341,11 @@ function vitePluginDeployOss(option) {
|
|
|
234
341
|
};
|
|
235
342
|
} else {
|
|
236
343
|
if (!silentLogs) {
|
|
237
|
-
console.log(
|
|
344
|
+
console.log(
|
|
345
|
+
`${getLogSymbol("warning")} ${truncateTerminalText(task.relativeFilePath, 18)} \u6B63\u5728\u91CD\u8BD5 (${attempt}/${maxRetries})`
|
|
346
|
+
);
|
|
238
347
|
}
|
|
239
|
-
await new Promise((
|
|
348
|
+
await new Promise((resolve3) => setTimeout(resolve3, 1e3 * attempt));
|
|
240
349
|
}
|
|
241
350
|
}
|
|
242
351
|
}
|
|
@@ -252,16 +361,18 @@ function vitePluginDeployOss(option) {
|
|
|
252
361
|
};
|
|
253
362
|
const uploadFilesInBatches = async (client, files, windowSize = concurrency) => {
|
|
254
363
|
const results = [];
|
|
364
|
+
const debugEntries = [];
|
|
255
365
|
const totalFiles = files.length;
|
|
256
366
|
const tasks = [];
|
|
257
367
|
let completed = 0;
|
|
258
368
|
let failed = 0;
|
|
259
369
|
let uploadedBytes = 0;
|
|
260
370
|
let retries = 0;
|
|
371
|
+
const taskPrepareStartedAt = Date.now();
|
|
261
372
|
const taskCandidates = await Promise.all(
|
|
262
373
|
files.map(async (relativeFilePath) => {
|
|
263
|
-
const filePath = normalizePath(
|
|
264
|
-
const name = normalizeObjectKey(
|
|
374
|
+
const filePath = normalizePath(resolve2(outDir, relativeFilePath));
|
|
375
|
+
const name = normalizeObjectKey(normalizedUploadDir, relativeFilePath);
|
|
265
376
|
try {
|
|
266
377
|
const fileStats = await stat(filePath);
|
|
267
378
|
return { task: { filePath, relativeFilePath, name, size: fileStats.size } };
|
|
@@ -270,6 +381,11 @@ function vitePluginDeployOss(option) {
|
|
|
270
381
|
}
|
|
271
382
|
})
|
|
272
383
|
);
|
|
384
|
+
debugEntries.push({
|
|
385
|
+
label: "\u751F\u6210\u4E0A\u4F20\u4EFB\u52A1",
|
|
386
|
+
durationMs: Date.now() - taskPrepareStartedAt,
|
|
387
|
+
detail: `${files.length} \u4E2A\u6587\u4EF6`
|
|
388
|
+
});
|
|
273
389
|
for (const candidate of taskCandidates) {
|
|
274
390
|
if (candidate.task) {
|
|
275
391
|
tasks.push(candidate.task);
|
|
@@ -289,47 +405,58 @@ function vitePluginDeployOss(option) {
|
|
|
289
405
|
}
|
|
290
406
|
const totalBytes = tasks.reduce((sum, task) => sum + task.size, 0);
|
|
291
407
|
const startAt = Date.now();
|
|
292
|
-
const activeFiles = /* @__PURE__ */ new Set();
|
|
293
408
|
const safeWindowSize = Math.max(1, Math.min(windowSize, tasks.length || 1));
|
|
294
409
|
const silentLogs = Boolean(useInteractiveOutput);
|
|
295
|
-
const
|
|
296
|
-
|
|
410
|
+
const progressBar = useInteractiveOutput ? new cliProgress.SingleBar({
|
|
411
|
+
hideCursor: true,
|
|
412
|
+
clearOnComplete: true,
|
|
413
|
+
stopOnComplete: true,
|
|
414
|
+
barsize: 18,
|
|
415
|
+
barCompleteChar: "\u2588",
|
|
416
|
+
barIncompleteChar: "\u2591",
|
|
417
|
+
format: `${chalk3.gray("\u4E0A\u4F20")} ${chalk3.bold("{percentage}%")} ${chalk3.cyan("{bar}")} ${chalk3.gray("\xB7")} ${chalk3.magenta("{speed}/s")} ${chalk3.gray("\xB7")} ${chalk3.gray("{elapsed}")}s`
|
|
418
|
+
}) : null;
|
|
419
|
+
const reportEvery = Math.max(1, Math.ceil(totalFiles / 6));
|
|
297
420
|
let lastReportedCompleted = -1;
|
|
421
|
+
if (progressBar) {
|
|
422
|
+
progressBar.start(totalFiles, 0, {
|
|
423
|
+
speed: formatBytes(0),
|
|
424
|
+
elapsed: "0"
|
|
425
|
+
});
|
|
426
|
+
}
|
|
298
427
|
const updateProgress = () => {
|
|
299
|
-
const progressRatio = totalFiles > 0 ? completed / totalFiles : 1;
|
|
300
|
-
const percentage = Math.round(progressRatio * 100);
|
|
301
428
|
const elapsedSeconds = (Date.now() - startAt) / 1e3;
|
|
302
429
|
const speed = elapsedSeconds > 0 ? uploadedBytes / elapsedSeconds : 0;
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
430
|
+
if (!progressBar) {
|
|
431
|
+
const progressRatio = totalFiles > 0 ? completed / totalFiles : 1;
|
|
432
|
+
const percentage = Math.round(progressRatio * 100);
|
|
433
|
+
if (completed === 0 && totalFiles > 0) return;
|
|
307
434
|
if (completed === lastReportedCompleted) return;
|
|
308
435
|
if (completed === totalFiles || completed % reportEvery === 0) {
|
|
309
436
|
console.log(
|
|
310
|
-
`${
|
|
437
|
+
`${chalk3.gray("\u4E0A\u4F20\u8FDB\u5EA6")} ${renderInlineStats([
|
|
438
|
+
chalk3.bold(`${completed}/${totalFiles}`),
|
|
439
|
+
`${percentage}%`,
|
|
440
|
+
`${formatBytes(uploadedBytes)}/${formatBytes(totalBytes)}`,
|
|
441
|
+
`${formatBytes(speed)}/s`
|
|
442
|
+
])}`
|
|
311
443
|
);
|
|
312
444
|
lastReportedCompleted = completed;
|
|
313
445
|
}
|
|
314
446
|
return;
|
|
315
447
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
`${chalk.cyan("\u6B63\u5728\u4E0A\u4F20:")} ${chalk.white(currentFile)}`,
|
|
321
|
-
`${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))}`
|
|
322
|
-
].join("\n");
|
|
323
|
-
spinner.text += warnLine;
|
|
448
|
+
progressBar.update(completed, {
|
|
449
|
+
speed: chalk3.magenta(formatBytes(speed)),
|
|
450
|
+
elapsed: formatDuration(elapsedSeconds).replace(/s$/, "")
|
|
451
|
+
});
|
|
324
452
|
};
|
|
325
|
-
const refreshTimer =
|
|
453
|
+
const refreshTimer = progressBar ? setInterval(updateProgress, 120) : null;
|
|
326
454
|
let currentIndex = 0;
|
|
327
455
|
const worker = async () => {
|
|
328
456
|
while (true) {
|
|
329
457
|
const index = currentIndex++;
|
|
330
458
|
if (index >= tasks.length) return;
|
|
331
459
|
const task = tasks[index];
|
|
332
|
-
activeFiles.add(task.name);
|
|
333
460
|
updateProgress();
|
|
334
461
|
const result = await uploadFileWithRetry(client, task, silentLogs);
|
|
335
462
|
completed++;
|
|
@@ -340,7 +467,6 @@ ${chalk.yellow("\u91CD\u8BD5")}: ${retries} ${chalk.yellow("\u5931\u8D25")}: ${
|
|
|
340
467
|
failed++;
|
|
341
468
|
}
|
|
342
469
|
results.push(result);
|
|
343
|
-
activeFiles.delete(task.name);
|
|
344
470
|
updateProgress();
|
|
345
471
|
}
|
|
346
472
|
};
|
|
@@ -350,18 +476,23 @@ ${chalk.yellow("\u91CD\u8BD5")}: ${retries} ${chalk.yellow("\u5931\u8D25")}: ${
|
|
|
350
476
|
} finally {
|
|
351
477
|
if (refreshTimer) clearInterval(refreshTimer);
|
|
352
478
|
}
|
|
353
|
-
if (
|
|
479
|
+
if (progressBar) {
|
|
354
480
|
const elapsedSeconds = (Date.now() - startAt) / 1e3;
|
|
355
|
-
const successCount = results.filter((item) => item.success).length;
|
|
356
481
|
const speed = elapsedSeconds > 0 ? uploadedBytes / elapsedSeconds : 0;
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
);
|
|
482
|
+
progressBar.update(totalFiles, {
|
|
483
|
+
speed: chalk3.magenta(formatBytes(speed)),
|
|
484
|
+
elapsed: formatDuration(elapsedSeconds).replace(/s$/, "")
|
|
485
|
+
});
|
|
486
|
+
progressBar.stop();
|
|
361
487
|
} else {
|
|
362
|
-
console.log(`${
|
|
488
|
+
console.log(`${getLogSymbol("success")} \u6240\u6709\u6587\u4EF6\u4E0A\u4F20\u5B8C\u6210 (${totalFiles}/${totalFiles})`);
|
|
363
489
|
}
|
|
364
|
-
|
|
490
|
+
debugEntries.push({
|
|
491
|
+
label: "\u4E0A\u4F20\u6587\u4EF6",
|
|
492
|
+
durationMs: Date.now() - startAt,
|
|
493
|
+
detail: `${tasks.length} \u4E2A\u6210\u529F\u5019\u9009 \xB7 \u5E76\u53D1 ${safeWindowSize}`
|
|
494
|
+
});
|
|
495
|
+
return { results, debugEntries };
|
|
365
496
|
};
|
|
366
497
|
return {
|
|
367
498
|
name: "vite-plugin-deploy-oss",
|
|
@@ -372,20 +503,19 @@ ${buildCapsuleBar(1)} 100% (${totalFiles}/${totalFiles}) ${chalk.gray("|")} \u90
|
|
|
372
503
|
},
|
|
373
504
|
config(config) {
|
|
374
505
|
if (!open || buildFailed) return;
|
|
375
|
-
clearScreen();
|
|
376
506
|
const validationErrors = validateOptions();
|
|
377
507
|
if (validationErrors.length > 0) {
|
|
378
|
-
console.log(`${
|
|
508
|
+
console.log(`${chalk3.red("\u2717 \u914D\u7F6E\u9519\u8BEF:")}
|
|
379
509
|
${validationErrors.map((err) => ` - ${err}`).join("\n")}`);
|
|
380
510
|
return;
|
|
381
511
|
}
|
|
382
512
|
upload = true;
|
|
383
|
-
config.base =
|
|
513
|
+
config.base = normalizedConfigBase || config.base;
|
|
384
514
|
return config;
|
|
385
515
|
},
|
|
386
516
|
configResolved(config) {
|
|
387
517
|
resolvedConfig = config;
|
|
388
|
-
outDir = normalizePath(
|
|
518
|
+
outDir = normalizePath(resolve2(config.root, config.build.outDir));
|
|
389
519
|
},
|
|
390
520
|
closeBundle: {
|
|
391
521
|
sequential: true,
|
|
@@ -393,80 +523,80 @@ ${validationErrors.map((err) => ` - ${err}`).join("\n")}`);
|
|
|
393
523
|
async handler() {
|
|
394
524
|
if (!open || !upload || buildFailed || !resolvedConfig) return;
|
|
395
525
|
const startTime = Date.now();
|
|
526
|
+
const debugEntries = [];
|
|
396
527
|
const client = new oss({ region, accessKeyId, accessKeySecret, secure, bucket, ...props });
|
|
397
528
|
const manifestFileName = resolveManifestFileName(manifest);
|
|
529
|
+
const collectFilesStartedAt = Date.now();
|
|
398
530
|
const files = globSync("**/*", {
|
|
399
531
|
cwd: outDir,
|
|
400
532
|
nodir: true,
|
|
401
533
|
ignore: Array.isArray(skip) ? skip : [skip]
|
|
402
534
|
}).map((file) => normalizePath(file)).filter((file) => file !== manifestFileName);
|
|
535
|
+
debugEntries.push({
|
|
536
|
+
label: "\u626B\u63CF\u672C\u5730\u6587\u4EF6",
|
|
537
|
+
durationMs: Date.now() - collectFilesStartedAt,
|
|
538
|
+
detail: `${files.length} \u4E2A\u6587\u4EF6`
|
|
539
|
+
});
|
|
403
540
|
if (files.length === 0) {
|
|
404
|
-
console.log(`${
|
|
541
|
+
console.log(`${getLogSymbol("warning")} \u6CA1\u6709\u627E\u5230\u9700\u8981\u4E0A\u4F20\u7684\u6587\u4EF6`);
|
|
405
542
|
return;
|
|
406
543
|
}
|
|
407
|
-
|
|
408
|
-
console.log(
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
`
|
|
544
|
+
clearViewport();
|
|
545
|
+
console.log(
|
|
546
|
+
renderPanel(
|
|
547
|
+
`${getPanelDot("success")} \u51C6\u5907\u90E8\u7F72`,
|
|
548
|
+
[
|
|
549
|
+
{ label: "\u4F4D\u7F6E:", value: chalk3.green(`${bucket} \xB7 ${region}`) },
|
|
550
|
+
{
|
|
551
|
+
label: "\u76EE\u6807:",
|
|
552
|
+
value: chalk3.yellow(
|
|
553
|
+
truncateTerminalText(
|
|
554
|
+
normalizedAlias ? `${normalizedUploadDir || "/"} \xB7 ${normalizedAlias}` : normalizedUploadDir || "/",
|
|
555
|
+
18
|
|
556
|
+
)
|
|
557
|
+
)
|
|
558
|
+
},
|
|
559
|
+
{
|
|
560
|
+
label: "\u6587\u4EF6:",
|
|
561
|
+
value: chalk3.blue(`${files.length} \u4E2A \xB7 ${truncateTerminalText(outDir, 30)}`)
|
|
562
|
+
}
|
|
563
|
+
],
|
|
564
|
+
"info"
|
|
565
|
+
)
|
|
566
|
+
);
|
|
418
567
|
try {
|
|
419
|
-
const
|
|
568
|
+
const uploadExecution = await uploadFilesInBatches(client, files, concurrency);
|
|
569
|
+
const { results, debugEntries: uploadDebugEntries } = uploadExecution;
|
|
570
|
+
if (debug) {
|
|
571
|
+
debugEntries.push(...uploadDebugEntries);
|
|
572
|
+
}
|
|
420
573
|
const successCount = results.filter((r) => r.success).length;
|
|
421
574
|
const failedCount = results.length - successCount;
|
|
422
575
|
const durationSeconds = (Date.now() - startTime) / 1e3;
|
|
423
|
-
const duration = durationSeconds.toFixed(2);
|
|
424
576
|
const uploadedBytes = results.reduce((sum, result) => result.success ? sum + result.size : sum, 0);
|
|
425
577
|
const retryCount = results.reduce((sum, result) => sum + result.retries, 0);
|
|
426
578
|
const avgSpeed = durationSeconds > 0 ? uploadedBytes / durationSeconds : 0;
|
|
427
|
-
|
|
428
|
-
console.log("\n" + chalk.gray("\u2500".repeat(40)) + "\n");
|
|
429
|
-
if (failedCount === 0) {
|
|
430
|
-
console.log(`${chalk.green("\u{1F389} \u90E8\u7F72\u6210\u529F!")}`);
|
|
431
|
-
} else {
|
|
432
|
-
console.log(`${chalk.yellow("\u26A0 \u90E8\u7F72\u5B8C\u6210\u4F46\u5B58\u5728\u9519\u8BEF")}`);
|
|
433
|
-
}
|
|
434
|
-
console.log(`
|
|
435
|
-
${chalk.gray("\u7EDF\u8BA1:")}`);
|
|
436
|
-
console.log(` ${chalk.green("\u2714")} \u6210\u529F: ${chalk.bold(successCount)}`);
|
|
437
|
-
if (failedCount > 0) {
|
|
438
|
-
console.log(` ${chalk.red("\u2717")} \u5931\u8D25: ${chalk.bold(failedCount)}`);
|
|
439
|
-
}
|
|
440
|
-
console.log(` ${chalk.cyan("\u21C4")} \u91CD\u8BD5: ${chalk.bold(retryCount)}`);
|
|
441
|
-
console.log(` ${chalk.blue("\u{1F4E6}")} \u6570\u636E: ${chalk.bold(formatBytes(uploadedBytes))}`);
|
|
442
|
-
console.log(` ${chalk.magenta("\u26A1")} \u5E73\u5747\u901F\u5EA6: ${chalk.bold(`${formatBytes(avgSpeed)}/s`)}`);
|
|
443
|
-
console.log(` ${chalk.blue("\u23F1")} \u8017\u65F6: ${chalk.bold(duration)}s`);
|
|
444
|
-
console.log("");
|
|
445
|
-
if (failedCount > 0) {
|
|
446
|
-
const failedItems = results.filter((result) => !result.success);
|
|
447
|
-
const previewCount = Math.min(5, failedItems.length);
|
|
448
|
-
console.log(chalk.red("\u5931\u8D25\u660E\u7EC6:"));
|
|
449
|
-
for (let i = 0; i < previewCount; i++) {
|
|
450
|
-
const item = failedItems[i];
|
|
451
|
-
const reason = item.error?.message || "unknown error";
|
|
452
|
-
console.log(` ${chalk.red("\u2022")} ${item.name} => ${reason}`);
|
|
453
|
-
}
|
|
454
|
-
if (failedItems.length > previewCount) {
|
|
455
|
-
console.log(chalk.gray(` ... \u8FD8\u6709 ${failedItems.length - previewCount} \u4E2A\u5931\u8D25\u6587\u4EF6`));
|
|
456
|
-
}
|
|
457
|
-
console.log("");
|
|
458
|
-
}
|
|
579
|
+
let manifestSummary = null;
|
|
459
580
|
if (manifestFileName) {
|
|
460
581
|
const manifestRelativeFilePath = manifestFileName;
|
|
461
|
-
const manifestFilePath = normalizePath(
|
|
462
|
-
const manifestObjectKey = normalizeObjectKey(
|
|
582
|
+
const manifestFilePath = normalizePath(resolve2(outDir, manifestRelativeFilePath));
|
|
583
|
+
const manifestObjectKey = normalizeObjectKey(normalizedUploadDir, manifestRelativeFilePath);
|
|
584
|
+
const manifestStartedAt = Date.now();
|
|
463
585
|
await mkdir(dirname(manifestFilePath), { recursive: true });
|
|
464
586
|
await writeFile(
|
|
465
587
|
manifestFilePath,
|
|
466
|
-
JSON.stringify(await createManifestPayload(results,
|
|
588
|
+
JSON.stringify(await createManifestPayload(results, normalizedConfigBase, normalizedAlias), null, 2),
|
|
467
589
|
"utf8"
|
|
468
590
|
);
|
|
591
|
+
if (debug) {
|
|
592
|
+
debugEntries.push({
|
|
593
|
+
label: "\u751F\u6210\u6E05\u5355\u6587\u4EF6",
|
|
594
|
+
durationMs: Date.now() - manifestStartedAt,
|
|
595
|
+
detail: manifestRelativeFilePath
|
|
596
|
+
});
|
|
597
|
+
}
|
|
469
598
|
const manifestStats = await stat(manifestFilePath);
|
|
599
|
+
const manifestUploadStartedAt = Date.now();
|
|
470
600
|
const manifestResult = await uploadSingleTask(client, {
|
|
471
601
|
filePath: manifestFilePath,
|
|
472
602
|
relativeFilePath: manifestRelativeFilePath,
|
|
@@ -477,30 +607,94 @@ ${chalk.gray("\u7EDF\u8BA1:")}`);
|
|
|
477
607
|
if (!manifestResult.success) {
|
|
478
608
|
throw manifestResult.error || new Error(`Failed to upload manifest: ${manifestRelativeFilePath}`);
|
|
479
609
|
}
|
|
610
|
+
if (debug) {
|
|
611
|
+
debugEntries.push({
|
|
612
|
+
label: "\u4E0A\u4F20\u6E05\u5355\u6587\u4EF6",
|
|
613
|
+
durationMs: Date.now() - manifestUploadStartedAt,
|
|
614
|
+
detail: manifestRelativeFilePath
|
|
615
|
+
});
|
|
616
|
+
}
|
|
480
617
|
const manifestUrl = resolveUploadedFileUrl(
|
|
481
618
|
manifestRelativeFilePath,
|
|
482
619
|
manifestObjectKey,
|
|
483
|
-
|
|
484
|
-
|
|
620
|
+
normalizedConfigBase,
|
|
621
|
+
normalizedAlias
|
|
485
622
|
);
|
|
486
|
-
|
|
487
|
-
console.log(` ${chalk.gray("File:")} ${chalk.yellow(manifestFilePath)}`);
|
|
488
|
-
console.log(` ${chalk.gray("Target:")} ${chalk.yellow(manifestObjectKey)}`);
|
|
489
|
-
console.log(` ${chalk.gray("URL:")} ${chalk.green(manifestUrl)}`);
|
|
490
|
-
console.log("");
|
|
623
|
+
manifestSummary = truncateTerminalText(manifestUrl || manifestObjectKey, 20);
|
|
491
624
|
}
|
|
492
625
|
try {
|
|
626
|
+
const cleanupStartedAt = Date.now();
|
|
493
627
|
await removeEmptyDirectories(outDir);
|
|
628
|
+
if (debug) {
|
|
629
|
+
debugEntries.push({
|
|
630
|
+
label: "\u6E05\u7406\u7A7A\u76EE\u5F55",
|
|
631
|
+
durationMs: Date.now() - cleanupStartedAt
|
|
632
|
+
});
|
|
633
|
+
}
|
|
494
634
|
} catch (error) {
|
|
495
|
-
console.warn(`${
|
|
635
|
+
console.warn(`${getLogSymbol("warning")} \u6E05\u7406\u7A7A\u76EE\u5F55\u5931\u8D25: ${error}`);
|
|
636
|
+
}
|
|
637
|
+
const resultRows = [
|
|
638
|
+
{
|
|
639
|
+
label: "\u7ED3\u679C:",
|
|
640
|
+
value: failedCount === 0 ? chalk3.green(`${successCount}/${results.length} \u5168\u90E8\u6210\u529F`) : chalk3.yellow(`\u6210\u529F ${successCount} \u4E2A\uFF0C\u5931\u8D25 ${failedCount} \u4E2A`)
|
|
641
|
+
},
|
|
642
|
+
{
|
|
643
|
+
label: "\u7EDF\u8BA1:",
|
|
644
|
+
value: renderInlineStats([
|
|
645
|
+
`${retryCount} \u6B21\u91CD\u8BD5`,
|
|
646
|
+
formatBytes(uploadedBytes),
|
|
647
|
+
`${formatBytes(avgSpeed)}/s`,
|
|
648
|
+
formatDuration(durationSeconds)
|
|
649
|
+
])
|
|
650
|
+
},
|
|
651
|
+
...manifestSummary ? [{ label: "\u6E05\u5355:", value: chalk3.cyan(manifestSummary) }] : []
|
|
652
|
+
];
|
|
653
|
+
if (failedCount > 0) {
|
|
654
|
+
const failedItems = results.filter((result) => !result.success).slice(0, 2);
|
|
655
|
+
resultRows.push(
|
|
656
|
+
...failedItems.map((item, index) => ({
|
|
657
|
+
label: `\u5931\u8D25 ${index + 1}`,
|
|
658
|
+
value: chalk3.red(
|
|
659
|
+
`${truncateTerminalText(item.name, 26)} \xB7 ${truncateTerminalText(item.error?.message || "unknown error", 22)}`
|
|
660
|
+
)
|
|
661
|
+
}))
|
|
662
|
+
);
|
|
663
|
+
if (failedCount > failedItems.length) {
|
|
664
|
+
resultRows.push({
|
|
665
|
+
label: "\u5176\u4F59",
|
|
666
|
+
value: chalk3.gray(`\u8FD8\u6709 ${failedCount - failedItems.length} \u4E2A\u5931\u8D25\u9879\u672A\u5C55\u5F00`)
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
console.log(
|
|
671
|
+
renderPanel(
|
|
672
|
+
failedCount === 0 ? `${getPanelDot("success")} \u90E8\u7F72\u5B8C\u6210` : `${getPanelDot("warning")} \u90E8\u7F72\u5B8C\u6210`,
|
|
673
|
+
resultRows,
|
|
674
|
+
failedCount === 0 ? "success" : "warning"
|
|
675
|
+
)
|
|
676
|
+
);
|
|
677
|
+
if (debug) {
|
|
678
|
+
debugEntries.push({
|
|
679
|
+
label: "\u603B\u8017\u65F6",
|
|
680
|
+
durationMs: Date.now() - startTime
|
|
681
|
+
});
|
|
682
|
+
console.log(renderDebugPanel(debugEntries));
|
|
496
683
|
}
|
|
497
684
|
if (failedCount > 0 && failOnError) {
|
|
498
685
|
throw new Error(`Failed to upload ${failedCount} of ${results.length} files`);
|
|
499
686
|
}
|
|
500
687
|
} catch (error) {
|
|
501
688
|
console.log(`
|
|
502
|
-
${
|
|
689
|
+
${getLogSymbol("danger")} \u4E0A\u4F20\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF: ${error}
|
|
503
690
|
`);
|
|
691
|
+
if (debug && debugEntries.length > 0) {
|
|
692
|
+
debugEntries.push({
|
|
693
|
+
label: "\u5931\u8D25\u524D\u8017\u65F6",
|
|
694
|
+
durationMs: Date.now() - startTime
|
|
695
|
+
});
|
|
696
|
+
console.log(renderDebugPanel(debugEntries));
|
|
697
|
+
}
|
|
504
698
|
if (failOnError) {
|
|
505
699
|
throw error instanceof Error ? error : new Error(String(error));
|
|
506
700
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-deploy-oss",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.1",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/ali-oss": "^6.23.3",
|
|
35
35
|
"@types/node": "^22.19.13",
|
|
36
|
+
"prettier": "3.8.1",
|
|
36
37
|
"tsup": "^8.5.1",
|
|
37
38
|
"typescript": "^5.9.3"
|
|
38
39
|
},
|
|
@@ -40,16 +41,23 @@
|
|
|
40
41
|
"vite": "^6.0.3 || ^7 || ^8"
|
|
41
42
|
},
|
|
42
43
|
"dependencies": {
|
|
44
|
+
"@types/cli-progress": "^3.11.6",
|
|
43
45
|
"ali-oss": "^6.23.0",
|
|
44
46
|
"chalk": "^5.6.2",
|
|
47
|
+
"cli-progress": "^3.12.0",
|
|
48
|
+
"cli-truncate": "^5.2.0",
|
|
45
49
|
"glob": "^13.0.6",
|
|
46
|
-
"
|
|
50
|
+
"log-symbols": "^7.0.1",
|
|
51
|
+
"string-width": "^8.2.0"
|
|
47
52
|
},
|
|
48
53
|
"scripts": {
|
|
49
54
|
"build": "tsup",
|
|
50
55
|
"typecheck": "tsc -p tsconfig.json",
|
|
51
56
|
"pack": "pnpm run build && pnpm pack",
|
|
57
|
+
"format": "prettier --write .",
|
|
58
|
+
"format:check": "prettier --check .",
|
|
52
59
|
"build:test": "cd playground && vite build",
|
|
53
|
-
"build:test:deploy": "cd playground && vite build --mode deploy"
|
|
60
|
+
"build:test:deploy": "cd playground && vite build --mode deploy",
|
|
61
|
+
"build:test:debug": "cd playground && vite build --mode deploy-debug"
|
|
54
62
|
}
|
|
55
63
|
}
|