@tourmind-frontend/monitor-plugin-vite 1.2.0 → 1.6.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/dist/index.cjs +26 -5
- package/dist/index.d.ts +2 -2
- package/dist/index.js +26 -5
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -33,6 +33,7 @@ __export(src_exports, {
|
|
|
33
33
|
default: () => uploadSourceMapPlugin
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(src_exports);
|
|
36
|
+
var import_zlib = require("zlib");
|
|
36
37
|
var import_axios = __toESM(require("axios"), 1);
|
|
37
38
|
var import_form_data = __toESM(require("form-data"), 1);
|
|
38
39
|
var LOG_PREFIX = "[frontend-monitor]";
|
|
@@ -43,6 +44,11 @@ function defaultLogger(level, msg, extra) {
|
|
|
43
44
|
else if (level === "warn") console.warn(line, tail);
|
|
44
45
|
else console.error(line, tail);
|
|
45
46
|
}
|
|
47
|
+
function formatSize(bytes) {
|
|
48
|
+
if (bytes >= 1024 * 1024) return `${(bytes / 1024 / 1024).toFixed(1)}MB`;
|
|
49
|
+
if (bytes >= 1024) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
50
|
+
return `${bytes}B`;
|
|
51
|
+
}
|
|
46
52
|
function extractSourceMaps(bundle) {
|
|
47
53
|
const result = [];
|
|
48
54
|
for (const fileName of Object.keys(bundle)) {
|
|
@@ -60,10 +66,16 @@ function extractSourceMaps(bundle) {
|
|
|
60
66
|
}
|
|
61
67
|
async function uploadFiles({ url, query, files }) {
|
|
62
68
|
const form = new import_form_data.default();
|
|
69
|
+
let rawBytes = 0;
|
|
70
|
+
let gzipBytes = 0;
|
|
63
71
|
for (const [filename, content] of files) {
|
|
64
|
-
|
|
72
|
+
const raw = Buffer.from(content, "utf-8");
|
|
73
|
+
const gz = (0, import_zlib.gzipSync)(raw);
|
|
74
|
+
rawBytes += raw.byteLength;
|
|
75
|
+
gzipBytes += gz.byteLength;
|
|
76
|
+
form.append("file", gz, { filename });
|
|
65
77
|
}
|
|
66
|
-
const qs = new URLSearchParams(query).toString();
|
|
78
|
+
const qs = new URLSearchParams({ ...query, encoding: "gzip" }).toString();
|
|
67
79
|
const fullUrl = `${url}${url.includes("?") ? "&" : "?"}${qs}`;
|
|
68
80
|
await (0, import_axios.default)({
|
|
69
81
|
method: "POST",
|
|
@@ -73,11 +85,15 @@ async function uploadFiles({ url, query, files }) {
|
|
|
73
85
|
maxBodyLength: Infinity,
|
|
74
86
|
maxContentLength: Infinity
|
|
75
87
|
});
|
|
88
|
+
return { rawBytes, gzipBytes };
|
|
76
89
|
}
|
|
77
90
|
function uploadSourceMapPlugin(options) {
|
|
78
91
|
var _a;
|
|
79
92
|
if (!options.url) throw new Error(`${LOG_PREFIX} "url" is required`);
|
|
80
|
-
if (!options.
|
|
93
|
+
if (!options.authToken) throw new Error(`${LOG_PREFIX} "authToken" is required`);
|
|
94
|
+
if (!options.authToken.startsWith("fm_at_")) {
|
|
95
|
+
throw new Error(`${LOG_PREFIX} "authToken" must start with "fm_at_"; do not use the client key here`);
|
|
96
|
+
}
|
|
81
97
|
if (!options.commit) throw new Error(`${LOG_PREFIX} "commit" is required`);
|
|
82
98
|
const log = (_a = options.logger) != null ? _a : defaultLogger;
|
|
83
99
|
const uploadUrl = `${options.url.replace(/\/+$/, "")}/api/upload`;
|
|
@@ -102,11 +118,16 @@ function uploadSourceMapPlugin(options) {
|
|
|
102
118
|
const commit = (_a2 = options.commit) != null ? _a2 : "";
|
|
103
119
|
const timestamp = (_b = options.timestamp) != null ? _b : Date.now();
|
|
104
120
|
const query = {
|
|
105
|
-
token: options.
|
|
121
|
+
token: options.authToken,
|
|
106
122
|
timestamp: String(timestamp)
|
|
107
123
|
};
|
|
108
124
|
if (commit) query.commit = commit;
|
|
109
|
-
uploadPromise = uploadFiles({ url: uploadUrl, query, files }).then(
|
|
125
|
+
uploadPromise = uploadFiles({ url: uploadUrl, query, files }).then(
|
|
126
|
+
({ rawBytes, gzipBytes }) => log(
|
|
127
|
+
"info",
|
|
128
|
+
`uploaded ${files.length} sourcemap file(s) (commit=${commit || "-"}, ${formatSize(rawBytes)} -> ${formatSize(gzipBytes)} gzipped)`
|
|
129
|
+
)
|
|
130
|
+
).catch((err) => log("error", "upload failed", err instanceof Error ? err.message : err));
|
|
110
131
|
},
|
|
111
132
|
async closeBundle() {
|
|
112
133
|
if (uploadPromise) await uploadPromise;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { Plugin } from "vite";
|
|
|
2
2
|
export interface UploadSourceMapOptions {
|
|
3
3
|
/** monitor 服务的 base URL,例如 `https://monitor.example.com`。内部拼接 `/api/upload`。 */
|
|
4
4
|
url: string;
|
|
5
|
-
/** monitor 项目 token
|
|
6
|
-
|
|
5
|
+
/** monitor 项目 auth token(前缀 `fm_at_`),仅供 CI / 构建机使用,从 web 控制台「项目」页获取。 */
|
|
6
|
+
authToken: string;
|
|
7
7
|
/** Commit hash,由调用方自行解析(如 `git rev-parse HEAD`)。 */
|
|
8
8
|
commit: string;
|
|
9
9
|
/** 构建时间戳(毫秒),未设置时取上传时刻的 `Date.now()`。 */
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// extensions/plugin-vite/src/index.ts
|
|
2
|
+
import { gzipSync } from "zlib";
|
|
2
3
|
import axios from "axios";
|
|
3
4
|
import FormData from "form-data";
|
|
4
5
|
var LOG_PREFIX = "[frontend-monitor]";
|
|
@@ -9,6 +10,11 @@ function defaultLogger(level, msg, extra) {
|
|
|
9
10
|
else if (level === "warn") console.warn(line, tail);
|
|
10
11
|
else console.error(line, tail);
|
|
11
12
|
}
|
|
13
|
+
function formatSize(bytes) {
|
|
14
|
+
if (bytes >= 1024 * 1024) return `${(bytes / 1024 / 1024).toFixed(1)}MB`;
|
|
15
|
+
if (bytes >= 1024) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
16
|
+
return `${bytes}B`;
|
|
17
|
+
}
|
|
12
18
|
function extractSourceMaps(bundle) {
|
|
13
19
|
const result = [];
|
|
14
20
|
for (const fileName of Object.keys(bundle)) {
|
|
@@ -26,10 +32,16 @@ function extractSourceMaps(bundle) {
|
|
|
26
32
|
}
|
|
27
33
|
async function uploadFiles({ url, query, files }) {
|
|
28
34
|
const form = new FormData();
|
|
35
|
+
let rawBytes = 0;
|
|
36
|
+
let gzipBytes = 0;
|
|
29
37
|
for (const [filename, content] of files) {
|
|
30
|
-
|
|
38
|
+
const raw = Buffer.from(content, "utf-8");
|
|
39
|
+
const gz = gzipSync(raw);
|
|
40
|
+
rawBytes += raw.byteLength;
|
|
41
|
+
gzipBytes += gz.byteLength;
|
|
42
|
+
form.append("file", gz, { filename });
|
|
31
43
|
}
|
|
32
|
-
const qs = new URLSearchParams(query).toString();
|
|
44
|
+
const qs = new URLSearchParams({ ...query, encoding: "gzip" }).toString();
|
|
33
45
|
const fullUrl = `${url}${url.includes("?") ? "&" : "?"}${qs}`;
|
|
34
46
|
await axios({
|
|
35
47
|
method: "POST",
|
|
@@ -39,11 +51,15 @@ async function uploadFiles({ url, query, files }) {
|
|
|
39
51
|
maxBodyLength: Infinity,
|
|
40
52
|
maxContentLength: Infinity
|
|
41
53
|
});
|
|
54
|
+
return { rawBytes, gzipBytes };
|
|
42
55
|
}
|
|
43
56
|
function uploadSourceMapPlugin(options) {
|
|
44
57
|
var _a;
|
|
45
58
|
if (!options.url) throw new Error(`${LOG_PREFIX} "url" is required`);
|
|
46
|
-
if (!options.
|
|
59
|
+
if (!options.authToken) throw new Error(`${LOG_PREFIX} "authToken" is required`);
|
|
60
|
+
if (!options.authToken.startsWith("fm_at_")) {
|
|
61
|
+
throw new Error(`${LOG_PREFIX} "authToken" must start with "fm_at_"; do not use the client key here`);
|
|
62
|
+
}
|
|
47
63
|
if (!options.commit) throw new Error(`${LOG_PREFIX} "commit" is required`);
|
|
48
64
|
const log = (_a = options.logger) != null ? _a : defaultLogger;
|
|
49
65
|
const uploadUrl = `${options.url.replace(/\/+$/, "")}/api/upload`;
|
|
@@ -68,11 +84,16 @@ function uploadSourceMapPlugin(options) {
|
|
|
68
84
|
const commit = (_a2 = options.commit) != null ? _a2 : "";
|
|
69
85
|
const timestamp = (_b = options.timestamp) != null ? _b : Date.now();
|
|
70
86
|
const query = {
|
|
71
|
-
token: options.
|
|
87
|
+
token: options.authToken,
|
|
72
88
|
timestamp: String(timestamp)
|
|
73
89
|
};
|
|
74
90
|
if (commit) query.commit = commit;
|
|
75
|
-
uploadPromise = uploadFiles({ url: uploadUrl, query, files }).then(
|
|
91
|
+
uploadPromise = uploadFiles({ url: uploadUrl, query, files }).then(
|
|
92
|
+
({ rawBytes, gzipBytes }) => log(
|
|
93
|
+
"info",
|
|
94
|
+
`uploaded ${files.length} sourcemap file(s) (commit=${commit || "-"}, ${formatSize(rawBytes)} -> ${formatSize(gzipBytes)} gzipped)`
|
|
95
|
+
)
|
|
96
|
+
).catch((err) => log("error", "upload failed", err instanceof Error ? err.message : err));
|
|
76
97
|
},
|
|
77
98
|
async closeBundle() {
|
|
78
99
|
if (uploadPromise) await uploadPromise;
|