unplugin-version-injector 2.2.0 → 2.3.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 +119 -15
- package/README.zh-CN.md +120 -15
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +68 -29
- package/dist/index.mjs +68 -29
- package/dist/rolldown.d.mts +1 -1
- package/dist/rolldown.d.ts +1 -1
- package/dist/rolldown.js +68 -29
- package/dist/rolldown.mjs +68 -29
- package/dist/rollup.d.mts +1 -1
- package/dist/rollup.d.ts +1 -1
- package/dist/rollup.js +68 -29
- package/dist/rollup.mjs +68 -29
- package/dist/rspack.d.mts +1 -1
- package/dist/rspack.d.ts +1 -1
- package/dist/rspack.js +68 -29
- package/dist/rspack.mjs +68 -29
- package/dist/{types-Cc-nzIS0.d.mts → types-CLRw9rBI.d.mts} +5 -0
- package/dist/{types-Cc-nzIS0.d.ts → types-CLRw9rBI.d.ts} +5 -0
- package/dist/vite.d.mts +1 -1
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +68 -29
- package/dist/vite.mjs +68 -29
- package/dist/webpack.d.mts +1 -1
- package/dist/webpack.d.ts +1 -1
- package/dist/webpack.js +68 -29
- package/dist/webpack.mjs +68 -29
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -93,18 +93,27 @@ function toScriptString(value) {
|
|
|
93
93
|
var INJECTED_MARK = 'data-injected="unplugin-version-injector"';
|
|
94
94
|
var HEADERS_INJECTED_MARK = 'data-injected="unplugin-version-injector-headers"';
|
|
95
95
|
var HEADER_NAME_RE = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
96
|
+
var DEFAULT_VERSION_HEADER = "X-Client-Version";
|
|
97
|
+
var DEFAULT_BUILD_TIME_HEADER = "X-Client-Build-Time";
|
|
96
98
|
function normalizeRequestHeaders(opt) {
|
|
97
|
-
var _a, _b, _c;
|
|
98
99
|
if (!opt) return null;
|
|
99
100
|
const o = typeof opt === "object" ? opt : {};
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
101
|
+
const pickHeaderName = (value, fallback) => {
|
|
102
|
+
if (value == null) return fallback;
|
|
103
|
+
if (HEADER_NAME_RE.test(value)) return value;
|
|
104
|
+
console.warn(
|
|
105
|
+
`[VersionInjector] invalid request header name "${value}", falling back to "${fallback}"`
|
|
106
|
+
);
|
|
107
|
+
return fallback;
|
|
108
|
+
};
|
|
109
|
+
const include = (Array.isArray(o.include) ? o.include : []).filter(
|
|
110
|
+
(p) => typeof p === "string" || p instanceof RegExp
|
|
111
|
+
);
|
|
112
|
+
return {
|
|
113
|
+
versionHeaderName: pickHeaderName(o.versionHeaderName, DEFAULT_VERSION_HEADER),
|
|
114
|
+
buildTimeHeaderName: pickHeaderName(o.buildTimeHeaderName, DEFAULT_BUILD_TIME_HEADER),
|
|
115
|
+
include
|
|
116
|
+
};
|
|
108
117
|
}
|
|
109
118
|
function sanitizeHeaderValue(value) {
|
|
110
119
|
return value.replace(/[^\t\x20-\x7E]/g, "").trim();
|
|
@@ -115,6 +124,7 @@ function serializeInclude(patterns) {
|
|
|
115
124
|
);
|
|
116
125
|
return `[${items.join(", ")}]`;
|
|
117
126
|
}
|
|
127
|
+
var HEAD_OPEN_RE = /<head(\s[^>]*)?>/i;
|
|
118
128
|
function createVersionInjector(options = {}) {
|
|
119
129
|
const pkg = options.version && options.name ? { version: options.version, name: options.name } : getPackageVersion();
|
|
120
130
|
const version = options.version || pkg.version;
|
|
@@ -122,25 +132,34 @@ function createVersionInjector(options = {}) {
|
|
|
122
132
|
const formatDateOpt = options.formatDate;
|
|
123
133
|
const formatDate2 = typeof formatDateOpt === "string" ? (date) => formatDate(date, formatDateOpt) : formatDateOpt != null ? formatDateOpt : defaultFormatDate;
|
|
124
134
|
const headersConfig = normalizeRequestHeaders(options.requestHeaders);
|
|
135
|
+
let cachedBuildTime = null;
|
|
136
|
+
const getBuildTime = () => {
|
|
137
|
+
if (cachedBuildTime === null) cachedBuildTime = formatDate2(/* @__PURE__ */ new Date());
|
|
138
|
+
return cachedBuildTime;
|
|
139
|
+
};
|
|
140
|
+
const nonceAttr = options.nonce ? ` nonce="${escapeHtml(options.nonce)}"` : "";
|
|
125
141
|
const metaTag = `<meta name="version" content="${escapeHtml(version)}">
|
|
126
142
|
<meta name="project" content="${escapeHtml(name)}">
|
|
127
143
|
`;
|
|
128
144
|
const buildLogScript = (buildTime) => `
|
|
129
|
-
<script ${INJECTED_MARK}>
|
|
145
|
+
<script${nonceAttr} ${INJECTED_MARK}>
|
|
130
146
|
(function () {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
147
|
+
try {
|
|
148
|
+
var isDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
149
|
+
var bg = isDark ? '#ffffff' : '#1e1e1e';
|
|
150
|
+
var base = 'background: ' + bg + '; border-radius: 4px; padding: 4px; font-size: 12px;';
|
|
151
|
+
console.log('%c' + ${toScriptString(` ${name}@${version} `)}, base + ' color: #00c853;');
|
|
152
|
+
console.log('%c' + ${toScriptString(` Build Time: ${buildTime} `)}, base + ' color: #ffab00;');
|
|
153
|
+
} catch (e) {}
|
|
136
154
|
})();
|
|
137
155
|
</script>`;
|
|
138
156
|
const buildHeaderScript = (buildTime, cfg) => {
|
|
139
157
|
const versionValue = sanitizeHeaderValue(`${name}/${version}`);
|
|
140
158
|
const buildValue = sanitizeHeaderValue(buildTime);
|
|
141
159
|
return `
|
|
142
|
-
<script ${HEADERS_INJECTED_MARK}>
|
|
160
|
+
<script${nonceAttr} ${HEADERS_INJECTED_MARK}>
|
|
143
161
|
(function () {
|
|
162
|
+
try {
|
|
144
163
|
if (window.__UVI_HEADERS_PATCHED__) return;
|
|
145
164
|
window.__UVI_HEADERS_PATCHED__ = true;
|
|
146
165
|
var VERSION_HEADER = ${toScriptString(cfg.versionHeaderName)};
|
|
@@ -164,13 +183,21 @@ function createVersionInjector(options = {}) {
|
|
|
164
183
|
}
|
|
165
184
|
}
|
|
166
185
|
|
|
186
|
+
function matchesPrefix(href, p) {
|
|
187
|
+
if (href.indexOf(p) !== 0) return false;
|
|
188
|
+
// \u524D\u7F00\u672C\u8EAB\u4EE5 / \u7ED3\u5C3E\uFF0C\u6216\u524D\u7F00\u540E\u7D27\u8DDF\u8FB9\u754C\u5B57\u7B26\uFF0C\u907F\u514D 'https://api.x.com' \u547D\u4E2D 'https://api.x.com.evil.com'
|
|
189
|
+
if (p.charAt(p.length - 1) === '/') return true;
|
|
190
|
+
var next = href.charAt(p.length);
|
|
191
|
+
return next === '' || next === '/' || next === '?' || next === '#';
|
|
192
|
+
}
|
|
193
|
+
|
|
167
194
|
function shouldInject(url) {
|
|
168
195
|
var u = resolveUrl(url == null ? '' : String(url));
|
|
169
196
|
if (!u || (u.protocol !== 'http:' && u.protocol !== 'https:')) return false;
|
|
170
197
|
if (u.protocol === location.protocol && u.host === location.host) return true;
|
|
171
198
|
for (var i = 0; i < INCLUDE.length; i++) {
|
|
172
199
|
var p = INCLUDE[i];
|
|
173
|
-
if (typeof p === 'string' ? u.href
|
|
200
|
+
if (typeof p === 'string' ? matchesPrefix(u.href, p) : p.test(u.href)) return true;
|
|
174
201
|
}
|
|
175
202
|
return false;
|
|
176
203
|
}
|
|
@@ -219,29 +246,37 @@ function createVersionInjector(options = {}) {
|
|
|
219
246
|
};
|
|
220
247
|
}
|
|
221
248
|
}
|
|
249
|
+
} catch (e) {}
|
|
222
250
|
})();
|
|
223
251
|
</script>`;
|
|
224
252
|
};
|
|
225
253
|
const processHtml = function processHtml2(html) {
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
254
|
+
const original = html;
|
|
255
|
+
try {
|
|
256
|
+
const buildTime = getBuildTime();
|
|
257
|
+
if (!html.includes('<meta name="version"')) {
|
|
258
|
+
html = html.replace(HEAD_OPEN_RE, (match) => `${match}
|
|
229
259
|
${metaTag}`);
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
260
|
+
}
|
|
261
|
+
if (headersConfig && !html.includes(HEADERS_INJECTED_MARK)) {
|
|
262
|
+
const headerScript = buildHeaderScript(buildTime, headersConfig);
|
|
263
|
+
html = html.replace(HEAD_OPEN_RE, (match) => `${match}
|
|
234
264
|
${headerScript}
|
|
235
265
|
`);
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
266
|
+
}
|
|
267
|
+
if (options.log !== false && !html.includes(INJECTED_MARK)) {
|
|
268
|
+
const logScript = buildLogScript(buildTime);
|
|
269
|
+
html = html.replace(/<\/body>/i, () => ` ${logScript}
|
|
240
270
|
</body>`);
|
|
271
|
+
}
|
|
272
|
+
return html;
|
|
273
|
+
} catch (err) {
|
|
274
|
+
console.warn("[VersionInjector] injection failed, returning original HTML unchanged:", err);
|
|
275
|
+
return original;
|
|
241
276
|
}
|
|
242
|
-
return html;
|
|
243
277
|
};
|
|
244
278
|
processHtml.resetBuildTime = () => {
|
|
279
|
+
cachedBuildTime = null;
|
|
245
280
|
};
|
|
246
281
|
return processHtml;
|
|
247
282
|
}
|
|
@@ -296,6 +331,10 @@ var unpluginFactory = (options = {}) => {
|
|
|
296
331
|
const inject = createVersionInjector(options);
|
|
297
332
|
return {
|
|
298
333
|
name: PLUGIN_NAME,
|
|
334
|
+
// 每轮(重)构建开始时重置构建时间缓存:watch 重建刷新时间,同一次构建里 MPA 各页保持一致
|
|
335
|
+
buildStart() {
|
|
336
|
+
inject.resetBuildTime();
|
|
337
|
+
},
|
|
299
338
|
vite: {
|
|
300
339
|
transformIndexHtml(html) {
|
|
301
340
|
return inject(html);
|
package/dist/rolldown.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as unplugin from 'unplugin';
|
|
2
|
-
import { V as VersionInjectorOptions } from './types-
|
|
2
|
+
import { V as VersionInjectorOptions } from './types-CLRw9rBI.mjs';
|
|
3
3
|
|
|
4
4
|
declare const _default: (options?: VersionInjectorOptions | undefined) => unplugin.RolldownPlugin<any> | unplugin.RolldownPlugin<any>[];
|
|
5
5
|
|
package/dist/rolldown.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as unplugin from 'unplugin';
|
|
2
|
-
import { V as VersionInjectorOptions } from './types-
|
|
2
|
+
import { V as VersionInjectorOptions } from './types-CLRw9rBI.js';
|
|
3
3
|
|
|
4
4
|
declare const _default: (options?: VersionInjectorOptions | undefined) => unplugin.RolldownPlugin<any> | unplugin.RolldownPlugin<any>[];
|
|
5
5
|
|
package/dist/rolldown.js
CHANGED
|
@@ -100,18 +100,27 @@ function toScriptString(value) {
|
|
|
100
100
|
var INJECTED_MARK = 'data-injected="unplugin-version-injector"';
|
|
101
101
|
var HEADERS_INJECTED_MARK = 'data-injected="unplugin-version-injector-headers"';
|
|
102
102
|
var HEADER_NAME_RE = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
103
|
+
var DEFAULT_VERSION_HEADER = "X-Client-Version";
|
|
104
|
+
var DEFAULT_BUILD_TIME_HEADER = "X-Client-Build-Time";
|
|
103
105
|
function normalizeRequestHeaders(opt) {
|
|
104
|
-
var _a, _b, _c;
|
|
105
106
|
if (!opt) return null;
|
|
106
107
|
const o = typeof opt === "object" ? opt : {};
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
108
|
+
const pickHeaderName = (value, fallback) => {
|
|
109
|
+
if (value == null) return fallback;
|
|
110
|
+
if (HEADER_NAME_RE.test(value)) return value;
|
|
111
|
+
console.warn(
|
|
112
|
+
`[VersionInjector] invalid request header name "${value}", falling back to "${fallback}"`
|
|
113
|
+
);
|
|
114
|
+
return fallback;
|
|
115
|
+
};
|
|
116
|
+
const include = (Array.isArray(o.include) ? o.include : []).filter(
|
|
117
|
+
(p) => typeof p === "string" || p instanceof RegExp
|
|
118
|
+
);
|
|
119
|
+
return {
|
|
120
|
+
versionHeaderName: pickHeaderName(o.versionHeaderName, DEFAULT_VERSION_HEADER),
|
|
121
|
+
buildTimeHeaderName: pickHeaderName(o.buildTimeHeaderName, DEFAULT_BUILD_TIME_HEADER),
|
|
122
|
+
include
|
|
123
|
+
};
|
|
115
124
|
}
|
|
116
125
|
function sanitizeHeaderValue(value) {
|
|
117
126
|
return value.replace(/[^\t\x20-\x7E]/g, "").trim();
|
|
@@ -122,6 +131,7 @@ function serializeInclude(patterns) {
|
|
|
122
131
|
);
|
|
123
132
|
return `[${items.join(", ")}]`;
|
|
124
133
|
}
|
|
134
|
+
var HEAD_OPEN_RE = /<head(\s[^>]*)?>/i;
|
|
125
135
|
function createVersionInjector(options = {}) {
|
|
126
136
|
const pkg = options.version && options.name ? { version: options.version, name: options.name } : getPackageVersion();
|
|
127
137
|
const version = options.version || pkg.version;
|
|
@@ -129,25 +139,34 @@ function createVersionInjector(options = {}) {
|
|
|
129
139
|
const formatDateOpt = options.formatDate;
|
|
130
140
|
const formatDate2 = typeof formatDateOpt === "string" ? (date) => formatDate(date, formatDateOpt) : formatDateOpt != null ? formatDateOpt : defaultFormatDate;
|
|
131
141
|
const headersConfig = normalizeRequestHeaders(options.requestHeaders);
|
|
142
|
+
let cachedBuildTime = null;
|
|
143
|
+
const getBuildTime = () => {
|
|
144
|
+
if (cachedBuildTime === null) cachedBuildTime = formatDate2(/* @__PURE__ */ new Date());
|
|
145
|
+
return cachedBuildTime;
|
|
146
|
+
};
|
|
147
|
+
const nonceAttr = options.nonce ? ` nonce="${escapeHtml(options.nonce)}"` : "";
|
|
132
148
|
const metaTag = `<meta name="version" content="${escapeHtml(version)}">
|
|
133
149
|
<meta name="project" content="${escapeHtml(name)}">
|
|
134
150
|
`;
|
|
135
151
|
const buildLogScript = (buildTime) => `
|
|
136
|
-
<script ${INJECTED_MARK}>
|
|
152
|
+
<script${nonceAttr} ${INJECTED_MARK}>
|
|
137
153
|
(function () {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
154
|
+
try {
|
|
155
|
+
var isDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
156
|
+
var bg = isDark ? '#ffffff' : '#1e1e1e';
|
|
157
|
+
var base = 'background: ' + bg + '; border-radius: 4px; padding: 4px; font-size: 12px;';
|
|
158
|
+
console.log('%c' + ${toScriptString(` ${name}@${version} `)}, base + ' color: #00c853;');
|
|
159
|
+
console.log('%c' + ${toScriptString(` Build Time: ${buildTime} `)}, base + ' color: #ffab00;');
|
|
160
|
+
} catch (e) {}
|
|
143
161
|
})();
|
|
144
162
|
</script>`;
|
|
145
163
|
const buildHeaderScript = (buildTime, cfg) => {
|
|
146
164
|
const versionValue = sanitizeHeaderValue(`${name}/${version}`);
|
|
147
165
|
const buildValue = sanitizeHeaderValue(buildTime);
|
|
148
166
|
return `
|
|
149
|
-
<script ${HEADERS_INJECTED_MARK}>
|
|
167
|
+
<script${nonceAttr} ${HEADERS_INJECTED_MARK}>
|
|
150
168
|
(function () {
|
|
169
|
+
try {
|
|
151
170
|
if (window.__UVI_HEADERS_PATCHED__) return;
|
|
152
171
|
window.__UVI_HEADERS_PATCHED__ = true;
|
|
153
172
|
var VERSION_HEADER = ${toScriptString(cfg.versionHeaderName)};
|
|
@@ -171,13 +190,21 @@ function createVersionInjector(options = {}) {
|
|
|
171
190
|
}
|
|
172
191
|
}
|
|
173
192
|
|
|
193
|
+
function matchesPrefix(href, p) {
|
|
194
|
+
if (href.indexOf(p) !== 0) return false;
|
|
195
|
+
// \u524D\u7F00\u672C\u8EAB\u4EE5 / \u7ED3\u5C3E\uFF0C\u6216\u524D\u7F00\u540E\u7D27\u8DDF\u8FB9\u754C\u5B57\u7B26\uFF0C\u907F\u514D 'https://api.x.com' \u547D\u4E2D 'https://api.x.com.evil.com'
|
|
196
|
+
if (p.charAt(p.length - 1) === '/') return true;
|
|
197
|
+
var next = href.charAt(p.length);
|
|
198
|
+
return next === '' || next === '/' || next === '?' || next === '#';
|
|
199
|
+
}
|
|
200
|
+
|
|
174
201
|
function shouldInject(url) {
|
|
175
202
|
var u = resolveUrl(url == null ? '' : String(url));
|
|
176
203
|
if (!u || (u.protocol !== 'http:' && u.protocol !== 'https:')) return false;
|
|
177
204
|
if (u.protocol === location.protocol && u.host === location.host) return true;
|
|
178
205
|
for (var i = 0; i < INCLUDE.length; i++) {
|
|
179
206
|
var p = INCLUDE[i];
|
|
180
|
-
if (typeof p === 'string' ? u.href
|
|
207
|
+
if (typeof p === 'string' ? matchesPrefix(u.href, p) : p.test(u.href)) return true;
|
|
181
208
|
}
|
|
182
209
|
return false;
|
|
183
210
|
}
|
|
@@ -226,29 +253,37 @@ function createVersionInjector(options = {}) {
|
|
|
226
253
|
};
|
|
227
254
|
}
|
|
228
255
|
}
|
|
256
|
+
} catch (e) {}
|
|
229
257
|
})();
|
|
230
258
|
</script>`;
|
|
231
259
|
};
|
|
232
260
|
const processHtml = function processHtml2(html) {
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
|
|
261
|
+
const original = html;
|
|
262
|
+
try {
|
|
263
|
+
const buildTime = getBuildTime();
|
|
264
|
+
if (!html.includes('<meta name="version"')) {
|
|
265
|
+
html = html.replace(HEAD_OPEN_RE, (match) => `${match}
|
|
236
266
|
${metaTag}`);
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
267
|
+
}
|
|
268
|
+
if (headersConfig && !html.includes(HEADERS_INJECTED_MARK)) {
|
|
269
|
+
const headerScript = buildHeaderScript(buildTime, headersConfig);
|
|
270
|
+
html = html.replace(HEAD_OPEN_RE, (match) => `${match}
|
|
241
271
|
${headerScript}
|
|
242
272
|
`);
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
273
|
+
}
|
|
274
|
+
if (options.log !== false && !html.includes(INJECTED_MARK)) {
|
|
275
|
+
const logScript = buildLogScript(buildTime);
|
|
276
|
+
html = html.replace(/<\/body>/i, () => ` ${logScript}
|
|
247
277
|
</body>`);
|
|
278
|
+
}
|
|
279
|
+
return html;
|
|
280
|
+
} catch (err) {
|
|
281
|
+
console.warn("[VersionInjector] injection failed, returning original HTML unchanged:", err);
|
|
282
|
+
return original;
|
|
248
283
|
}
|
|
249
|
-
return html;
|
|
250
284
|
};
|
|
251
285
|
processHtml.resetBuildTime = () => {
|
|
286
|
+
cachedBuildTime = null;
|
|
252
287
|
};
|
|
253
288
|
return processHtml;
|
|
254
289
|
}
|
|
@@ -303,6 +338,10 @@ var unpluginFactory = (options = {}) => {
|
|
|
303
338
|
const inject = createVersionInjector(options);
|
|
304
339
|
return {
|
|
305
340
|
name: PLUGIN_NAME,
|
|
341
|
+
// 每轮(重)构建开始时重置构建时间缓存:watch 重建刷新时间,同一次构建里 MPA 各页保持一致
|
|
342
|
+
buildStart() {
|
|
343
|
+
inject.resetBuildTime();
|
|
344
|
+
},
|
|
306
345
|
vite: {
|
|
307
346
|
transformIndexHtml(html) {
|
|
308
347
|
return inject(html);
|
package/dist/rolldown.mjs
CHANGED
|
@@ -93,18 +93,27 @@ function toScriptString(value) {
|
|
|
93
93
|
var INJECTED_MARK = 'data-injected="unplugin-version-injector"';
|
|
94
94
|
var HEADERS_INJECTED_MARK = 'data-injected="unplugin-version-injector-headers"';
|
|
95
95
|
var HEADER_NAME_RE = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
96
|
+
var DEFAULT_VERSION_HEADER = "X-Client-Version";
|
|
97
|
+
var DEFAULT_BUILD_TIME_HEADER = "X-Client-Build-Time";
|
|
96
98
|
function normalizeRequestHeaders(opt) {
|
|
97
|
-
var _a, _b, _c;
|
|
98
99
|
if (!opt) return null;
|
|
99
100
|
const o = typeof opt === "object" ? opt : {};
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
101
|
+
const pickHeaderName = (value, fallback) => {
|
|
102
|
+
if (value == null) return fallback;
|
|
103
|
+
if (HEADER_NAME_RE.test(value)) return value;
|
|
104
|
+
console.warn(
|
|
105
|
+
`[VersionInjector] invalid request header name "${value}", falling back to "${fallback}"`
|
|
106
|
+
);
|
|
107
|
+
return fallback;
|
|
108
|
+
};
|
|
109
|
+
const include = (Array.isArray(o.include) ? o.include : []).filter(
|
|
110
|
+
(p) => typeof p === "string" || p instanceof RegExp
|
|
111
|
+
);
|
|
112
|
+
return {
|
|
113
|
+
versionHeaderName: pickHeaderName(o.versionHeaderName, DEFAULT_VERSION_HEADER),
|
|
114
|
+
buildTimeHeaderName: pickHeaderName(o.buildTimeHeaderName, DEFAULT_BUILD_TIME_HEADER),
|
|
115
|
+
include
|
|
116
|
+
};
|
|
108
117
|
}
|
|
109
118
|
function sanitizeHeaderValue(value) {
|
|
110
119
|
return value.replace(/[^\t\x20-\x7E]/g, "").trim();
|
|
@@ -115,6 +124,7 @@ function serializeInclude(patterns) {
|
|
|
115
124
|
);
|
|
116
125
|
return `[${items.join(", ")}]`;
|
|
117
126
|
}
|
|
127
|
+
var HEAD_OPEN_RE = /<head(\s[^>]*)?>/i;
|
|
118
128
|
function createVersionInjector(options = {}) {
|
|
119
129
|
const pkg = options.version && options.name ? { version: options.version, name: options.name } : getPackageVersion();
|
|
120
130
|
const version = options.version || pkg.version;
|
|
@@ -122,25 +132,34 @@ function createVersionInjector(options = {}) {
|
|
|
122
132
|
const formatDateOpt = options.formatDate;
|
|
123
133
|
const formatDate2 = typeof formatDateOpt === "string" ? (date) => formatDate(date, formatDateOpt) : formatDateOpt != null ? formatDateOpt : defaultFormatDate;
|
|
124
134
|
const headersConfig = normalizeRequestHeaders(options.requestHeaders);
|
|
135
|
+
let cachedBuildTime = null;
|
|
136
|
+
const getBuildTime = () => {
|
|
137
|
+
if (cachedBuildTime === null) cachedBuildTime = formatDate2(/* @__PURE__ */ new Date());
|
|
138
|
+
return cachedBuildTime;
|
|
139
|
+
};
|
|
140
|
+
const nonceAttr = options.nonce ? ` nonce="${escapeHtml(options.nonce)}"` : "";
|
|
125
141
|
const metaTag = `<meta name="version" content="${escapeHtml(version)}">
|
|
126
142
|
<meta name="project" content="${escapeHtml(name)}">
|
|
127
143
|
`;
|
|
128
144
|
const buildLogScript = (buildTime) => `
|
|
129
|
-
<script ${INJECTED_MARK}>
|
|
145
|
+
<script${nonceAttr} ${INJECTED_MARK}>
|
|
130
146
|
(function () {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
147
|
+
try {
|
|
148
|
+
var isDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
149
|
+
var bg = isDark ? '#ffffff' : '#1e1e1e';
|
|
150
|
+
var base = 'background: ' + bg + '; border-radius: 4px; padding: 4px; font-size: 12px;';
|
|
151
|
+
console.log('%c' + ${toScriptString(` ${name}@${version} `)}, base + ' color: #00c853;');
|
|
152
|
+
console.log('%c' + ${toScriptString(` Build Time: ${buildTime} `)}, base + ' color: #ffab00;');
|
|
153
|
+
} catch (e) {}
|
|
136
154
|
})();
|
|
137
155
|
</script>`;
|
|
138
156
|
const buildHeaderScript = (buildTime, cfg) => {
|
|
139
157
|
const versionValue = sanitizeHeaderValue(`${name}/${version}`);
|
|
140
158
|
const buildValue = sanitizeHeaderValue(buildTime);
|
|
141
159
|
return `
|
|
142
|
-
<script ${HEADERS_INJECTED_MARK}>
|
|
160
|
+
<script${nonceAttr} ${HEADERS_INJECTED_MARK}>
|
|
143
161
|
(function () {
|
|
162
|
+
try {
|
|
144
163
|
if (window.__UVI_HEADERS_PATCHED__) return;
|
|
145
164
|
window.__UVI_HEADERS_PATCHED__ = true;
|
|
146
165
|
var VERSION_HEADER = ${toScriptString(cfg.versionHeaderName)};
|
|
@@ -164,13 +183,21 @@ function createVersionInjector(options = {}) {
|
|
|
164
183
|
}
|
|
165
184
|
}
|
|
166
185
|
|
|
186
|
+
function matchesPrefix(href, p) {
|
|
187
|
+
if (href.indexOf(p) !== 0) return false;
|
|
188
|
+
// \u524D\u7F00\u672C\u8EAB\u4EE5 / \u7ED3\u5C3E\uFF0C\u6216\u524D\u7F00\u540E\u7D27\u8DDF\u8FB9\u754C\u5B57\u7B26\uFF0C\u907F\u514D 'https://api.x.com' \u547D\u4E2D 'https://api.x.com.evil.com'
|
|
189
|
+
if (p.charAt(p.length - 1) === '/') return true;
|
|
190
|
+
var next = href.charAt(p.length);
|
|
191
|
+
return next === '' || next === '/' || next === '?' || next === '#';
|
|
192
|
+
}
|
|
193
|
+
|
|
167
194
|
function shouldInject(url) {
|
|
168
195
|
var u = resolveUrl(url == null ? '' : String(url));
|
|
169
196
|
if (!u || (u.protocol !== 'http:' && u.protocol !== 'https:')) return false;
|
|
170
197
|
if (u.protocol === location.protocol && u.host === location.host) return true;
|
|
171
198
|
for (var i = 0; i < INCLUDE.length; i++) {
|
|
172
199
|
var p = INCLUDE[i];
|
|
173
|
-
if (typeof p === 'string' ? u.href
|
|
200
|
+
if (typeof p === 'string' ? matchesPrefix(u.href, p) : p.test(u.href)) return true;
|
|
174
201
|
}
|
|
175
202
|
return false;
|
|
176
203
|
}
|
|
@@ -219,29 +246,37 @@ function createVersionInjector(options = {}) {
|
|
|
219
246
|
};
|
|
220
247
|
}
|
|
221
248
|
}
|
|
249
|
+
} catch (e) {}
|
|
222
250
|
})();
|
|
223
251
|
</script>`;
|
|
224
252
|
};
|
|
225
253
|
const processHtml = function processHtml2(html) {
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
254
|
+
const original = html;
|
|
255
|
+
try {
|
|
256
|
+
const buildTime = getBuildTime();
|
|
257
|
+
if (!html.includes('<meta name="version"')) {
|
|
258
|
+
html = html.replace(HEAD_OPEN_RE, (match) => `${match}
|
|
229
259
|
${metaTag}`);
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
260
|
+
}
|
|
261
|
+
if (headersConfig && !html.includes(HEADERS_INJECTED_MARK)) {
|
|
262
|
+
const headerScript = buildHeaderScript(buildTime, headersConfig);
|
|
263
|
+
html = html.replace(HEAD_OPEN_RE, (match) => `${match}
|
|
234
264
|
${headerScript}
|
|
235
265
|
`);
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
266
|
+
}
|
|
267
|
+
if (options.log !== false && !html.includes(INJECTED_MARK)) {
|
|
268
|
+
const logScript = buildLogScript(buildTime);
|
|
269
|
+
html = html.replace(/<\/body>/i, () => ` ${logScript}
|
|
240
270
|
</body>`);
|
|
271
|
+
}
|
|
272
|
+
return html;
|
|
273
|
+
} catch (err) {
|
|
274
|
+
console.warn("[VersionInjector] injection failed, returning original HTML unchanged:", err);
|
|
275
|
+
return original;
|
|
241
276
|
}
|
|
242
|
-
return html;
|
|
243
277
|
};
|
|
244
278
|
processHtml.resetBuildTime = () => {
|
|
279
|
+
cachedBuildTime = null;
|
|
245
280
|
};
|
|
246
281
|
return processHtml;
|
|
247
282
|
}
|
|
@@ -296,6 +331,10 @@ var unpluginFactory = (options = {}) => {
|
|
|
296
331
|
const inject = createVersionInjector(options);
|
|
297
332
|
return {
|
|
298
333
|
name: PLUGIN_NAME,
|
|
334
|
+
// 每轮(重)构建开始时重置构建时间缓存:watch 重建刷新时间,同一次构建里 MPA 各页保持一致
|
|
335
|
+
buildStart() {
|
|
336
|
+
inject.resetBuildTime();
|
|
337
|
+
},
|
|
299
338
|
vite: {
|
|
300
339
|
transformIndexHtml(html) {
|
|
301
340
|
return inject(html);
|
package/dist/rollup.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as rollup from 'rollup';
|
|
2
|
-
import { V as VersionInjectorOptions } from './types-
|
|
2
|
+
import { V as VersionInjectorOptions } from './types-CLRw9rBI.mjs';
|
|
3
3
|
|
|
4
4
|
declare const _default: (options?: VersionInjectorOptions | undefined) => rollup.Plugin<any> | rollup.Plugin<any>[];
|
|
5
5
|
|
package/dist/rollup.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as rollup from 'rollup';
|
|
2
|
-
import { V as VersionInjectorOptions } from './types-
|
|
2
|
+
import { V as VersionInjectorOptions } from './types-CLRw9rBI.js';
|
|
3
3
|
|
|
4
4
|
declare const _default: (options?: VersionInjectorOptions | undefined) => rollup.Plugin<any> | rollup.Plugin<any>[];
|
|
5
5
|
|