@gylautorun/dev-proxy-cookie 1.0.0-beta.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/LICENSE +21 -0
- package/README.md +743 -0
- package/dist/index.d.mts +264 -0
- package/dist/index.d.ts +264 -0
- package/dist/index.js +847 -0
- package/dist/index.min.js +4 -0
- package/dist/index.min.mjs +4 -0
- package/dist/index.mjs +801 -0
- package/package.json +83 -0
- package/src/index.ts +2 -0
- package/src/proxy/apply-dev-cookie-header.ts +14 -0
- package/src/proxy/core.ts +429 -0
- package/src/proxy/index.ts +5 -0
- package/src/proxy/vite-adapter.ts +98 -0
- package/src/proxy/vite-cookie-plugin.ts +94 -0
- package/src/proxy/vite-plugin.ts +66 -0
- package/src/proxy/vue-proxy-config.ts +192 -0
- package/src/utils/cookie-reader.ts +54 -0
- package/src/utils/cookie-watcher.ts +91 -0
- package/src/utils/env-detector.ts +155 -0
- package/src/utils/index.ts +3 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,801 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
// src/proxy/core.ts
|
|
9
|
+
import * as http from "http";
|
|
10
|
+
import * as fs2 from "fs";
|
|
11
|
+
import * as path3 from "path";
|
|
12
|
+
import httpProxy from "http-proxy";
|
|
13
|
+
|
|
14
|
+
// src/utils/cookie-reader.ts
|
|
15
|
+
import * as fs from "fs";
|
|
16
|
+
import * as path from "path";
|
|
17
|
+
var CookieReader = class {
|
|
18
|
+
constructor(options) {
|
|
19
|
+
this.options = {
|
|
20
|
+
encoding: "utf-8",
|
|
21
|
+
...options
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
readCookie() {
|
|
25
|
+
try {
|
|
26
|
+
const filePath = path.resolve(this.options.cookieFile);
|
|
27
|
+
if (fs.existsSync(filePath)) {
|
|
28
|
+
const content = fs.readFileSync(filePath, this.options.encoding || "utf-8");
|
|
29
|
+
const lines = content.split("\n");
|
|
30
|
+
const cookieLines = lines.map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
|
|
31
|
+
return cookieLines.join("; ");
|
|
32
|
+
}
|
|
33
|
+
return "";
|
|
34
|
+
} catch {
|
|
35
|
+
return "";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
ensureCookieFile() {
|
|
39
|
+
const filePath = path.resolve(this.options.cookieFile);
|
|
40
|
+
const dir = path.dirname(filePath);
|
|
41
|
+
if (!fs.existsSync(dir)) {
|
|
42
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
43
|
+
}
|
|
44
|
+
if (!fs.existsSync(filePath)) {
|
|
45
|
+
fs.writeFileSync(filePath, "");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
function createCookieGetter(cookieFile) {
|
|
50
|
+
const reader = new CookieReader({ cookieFile });
|
|
51
|
+
return () => reader.readCookie();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// src/utils/cookie-watcher.ts
|
|
55
|
+
import * as path2 from "path";
|
|
56
|
+
import chokidar from "chokidar";
|
|
57
|
+
var CookieWatcher = class {
|
|
58
|
+
constructor(options) {
|
|
59
|
+
this.watcher = null;
|
|
60
|
+
this.lastContent = "";
|
|
61
|
+
this.handleChange = () => {
|
|
62
|
+
const newContent = this.cookieReader.readCookie();
|
|
63
|
+
if (newContent !== this.lastContent) {
|
|
64
|
+
this.lastContent = newContent;
|
|
65
|
+
this.options.onCookieChange(newContent);
|
|
66
|
+
console.log(`[CookieWatcher] Cookie updated from file: ${this.options.cookieFile}`);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
this.options = {
|
|
70
|
+
autoCreateFile: true,
|
|
71
|
+
...options
|
|
72
|
+
};
|
|
73
|
+
this.cookieReader = new CookieReader({ cookieFile: options.cookieFile });
|
|
74
|
+
}
|
|
75
|
+
start() {
|
|
76
|
+
if (this.options.autoCreateFile) {
|
|
77
|
+
this.cookieReader.ensureCookieFile();
|
|
78
|
+
}
|
|
79
|
+
const watchPath = path2.resolve(this.options.cookieFile);
|
|
80
|
+
this.lastContent = this.cookieReader.readCookie();
|
|
81
|
+
console.log(`[CookieWatcher] Started watching: ${watchPath}`);
|
|
82
|
+
try {
|
|
83
|
+
this.watcher = chokidar.watch(watchPath, {
|
|
84
|
+
persistent: true,
|
|
85
|
+
ignoreInitial: true,
|
|
86
|
+
awaitWriteFinish: {
|
|
87
|
+
stabilityThreshold: 100,
|
|
88
|
+
pollInterval: 50
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
this.watcher.on("change", this.handleChange);
|
|
92
|
+
this.watcher.on("add", this.handleChange);
|
|
93
|
+
this.watcher.on("error", (error) => {
|
|
94
|
+
this.options.onError?.(error);
|
|
95
|
+
});
|
|
96
|
+
} catch (error) {
|
|
97
|
+
this.options.onError?.(error);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
stop() {
|
|
101
|
+
if (this.watcher) {
|
|
102
|
+
this.watcher.close();
|
|
103
|
+
this.watcher = null;
|
|
104
|
+
console.log(`[CookieWatcher] Stopped watching: ${this.options.cookieFile}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
getCurrentCookie() {
|
|
108
|
+
return this.lastContent;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
function watchCookieFile(cookieFile, onCookieChange, onError) {
|
|
112
|
+
const watcher = new CookieWatcher({
|
|
113
|
+
cookieFile,
|
|
114
|
+
onCookieChange,
|
|
115
|
+
onError
|
|
116
|
+
});
|
|
117
|
+
watcher.start();
|
|
118
|
+
return watcher;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/utils/env-detector.ts
|
|
122
|
+
function isProductionValue(value) {
|
|
123
|
+
const productionValues = [
|
|
124
|
+
"production",
|
|
125
|
+
// 生产环境
|
|
126
|
+
"prod",
|
|
127
|
+
// 生产环境
|
|
128
|
+
"prd",
|
|
129
|
+
// 生产环境
|
|
130
|
+
"release",
|
|
131
|
+
// 发布环境
|
|
132
|
+
"staging",
|
|
133
|
+
// 预发布环境
|
|
134
|
+
"uat"
|
|
135
|
+
// 预发布环境
|
|
136
|
+
];
|
|
137
|
+
return productionValues.includes(value.toLowerCase().trim());
|
|
138
|
+
}
|
|
139
|
+
function detectProductionEnvironment(customEnvs = [], debug = false, loggerPrefix = "[env-detector]") {
|
|
140
|
+
const env = process.env;
|
|
141
|
+
if (customEnvs.length > 0) {
|
|
142
|
+
for (const envName of customEnvs) {
|
|
143
|
+
const envValue = env[envName];
|
|
144
|
+
if (envValue && isProductionValue(envValue)) {
|
|
145
|
+
if (debug) {
|
|
146
|
+
console.log(`${loggerPrefix} Detected production via custom env: ${envName}=${envValue}`);
|
|
147
|
+
}
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const commonEnvNames = [
|
|
153
|
+
"NODE_ENV",
|
|
154
|
+
"BUILD_MODE",
|
|
155
|
+
"VUE_APP_ENV",
|
|
156
|
+
"VITE_NODE_ENV",
|
|
157
|
+
"WEBPACK_MODE",
|
|
158
|
+
"CI_ENV",
|
|
159
|
+
"APP_ENV",
|
|
160
|
+
"ENV",
|
|
161
|
+
"DEPLOY_ENV",
|
|
162
|
+
"RUN_MODE"
|
|
163
|
+
];
|
|
164
|
+
for (const envName of commonEnvNames) {
|
|
165
|
+
const envValue = env[envName];
|
|
166
|
+
if (envValue && isProductionValue(envValue)) {
|
|
167
|
+
if (debug) {
|
|
168
|
+
console.log(`${loggerPrefix} Detected production via env: ${envName}=${envValue}`);
|
|
169
|
+
}
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (env.CI === "true" || env.CI === "1" || env.CI === "yes") {
|
|
174
|
+
if (debug) {
|
|
175
|
+
console.log(`${loggerPrefix} Detected production via CI env`);
|
|
176
|
+
}
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
if (env.npm_lifecycle_event) {
|
|
180
|
+
const lifecycleEvent = env.npm_lifecycle_event.toLowerCase();
|
|
181
|
+
if (lifecycleEvent.includes("build") || lifecycleEvent.includes("prod") || lifecycleEvent.includes("prd") || lifecycleEvent.includes("release")) {
|
|
182
|
+
if (debug) {
|
|
183
|
+
console.log(`${loggerPrefix} Detected production via lifecycle event: ${env.npm_lifecycle_event}`);
|
|
184
|
+
}
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const processArgs = process.argv.join("").toLowerCase();
|
|
189
|
+
if (processArgs.includes("build") || processArgs.includes("production") || processArgs.includes("--mode=production") || processArgs.includes("--prod") || processArgs.includes("--release")) {
|
|
190
|
+
if (debug) {
|
|
191
|
+
console.log(`${loggerPrefix} Detected production via process arguments`);
|
|
192
|
+
}
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
function shouldEnableWatch(watch, customEnvs = [], debug = false, loggerPrefix = "[env-detector]") {
|
|
198
|
+
if (typeof watch === "boolean") {
|
|
199
|
+
if (debug && !watch) {
|
|
200
|
+
console.log(`${loggerPrefix} Watch disabled by user setting`);
|
|
201
|
+
}
|
|
202
|
+
return watch;
|
|
203
|
+
}
|
|
204
|
+
const isProduction = detectProductionEnvironment(customEnvs, debug, loggerPrefix);
|
|
205
|
+
if (isProduction) {
|
|
206
|
+
if (debug) {
|
|
207
|
+
console.log(`${loggerPrefix} Auto-detected production mode - disabling watch`);
|
|
208
|
+
}
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
if (debug) {
|
|
212
|
+
console.log(`${loggerPrefix} Auto-detected development mode - enabling watch`);
|
|
213
|
+
}
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// src/proxy/apply-dev-cookie-header.ts
|
|
218
|
+
function applyDevCookieHeader(proxyReq, cookie) {
|
|
219
|
+
if (!cookie) return;
|
|
220
|
+
proxyReq.removeHeader("cookie");
|
|
221
|
+
proxyReq.removeHeader("Cookie");
|
|
222
|
+
proxyReq.setHeader("Cookie", cookie);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// src/proxy/core.ts
|
|
226
|
+
var AutoProxyCookie = class {
|
|
227
|
+
constructor(options) {
|
|
228
|
+
this.currentCookie = "";
|
|
229
|
+
this.server = null;
|
|
230
|
+
this.proxyServer = null;
|
|
231
|
+
this.watcher = null;
|
|
232
|
+
this.handleCookieChange = (newCookie) => {
|
|
233
|
+
if (newCookie !== this.currentCookie) {
|
|
234
|
+
this.currentCookie = newCookie;
|
|
235
|
+
this.log("info", "[AutoProxyCookie] Cookie updated:", newCookie ? "(has cookie)" : "(empty)");
|
|
236
|
+
if (this.options.autoRestart && this.options.restartMarkerFile) {
|
|
237
|
+
const markerPath = path3.resolve(this.options.restartMarkerFile);
|
|
238
|
+
fs2.writeFileSync(markerPath, JSON.stringify({
|
|
239
|
+
timestamp: Date.now(),
|
|
240
|
+
cookie: newCookie
|
|
241
|
+
}, null, 2));
|
|
242
|
+
this.log("info", "[AutoProxyCookie] Restart marker written to:", markerPath);
|
|
243
|
+
this.log("info", "[AutoProxyCookie] Please restart the dev server for changes to take effect");
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
this.handleOnProxyReq = (proxyReq, req, res, _options) => {
|
|
248
|
+
if (this.currentCookie) {
|
|
249
|
+
applyDevCookieHeader(proxyReq, this.currentCookie);
|
|
250
|
+
}
|
|
251
|
+
this.log("debug", "[AutoProxyCookie] Proxy Request:", req.method, req.url);
|
|
252
|
+
if (this.options.hooks.onProxyReq) {
|
|
253
|
+
try {
|
|
254
|
+
this.options.hooks.onProxyReq(proxyReq, req, res);
|
|
255
|
+
} catch (err) {
|
|
256
|
+
this.log("error", "[AutoProxyCookie] onProxyReq hook error:", err.message);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
this.handleOnProxyRes = (proxyRes, req, res) => {
|
|
261
|
+
const allowedHeaders = [
|
|
262
|
+
"Content-Type",
|
|
263
|
+
"Content-Length",
|
|
264
|
+
"Authorization",
|
|
265
|
+
"Set-Cookie",
|
|
266
|
+
"X-Requested-With",
|
|
267
|
+
"Access-Control-Allow-Origin",
|
|
268
|
+
"Access-Control-Allow-Credentials"
|
|
269
|
+
];
|
|
270
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
271
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
|
|
272
|
+
res.setHeader("Access-Control-Allow-Headers", allowedHeaders.join(","));
|
|
273
|
+
res.setHeader("Access-Control-Allow-Credentials", "true");
|
|
274
|
+
this.log("debug", "[AutoProxyCookie] Proxy Response:", req.url, proxyRes.statusCode);
|
|
275
|
+
if (this.options.hooks.onProxyRes) {
|
|
276
|
+
try {
|
|
277
|
+
this.options.hooks.onProxyRes(proxyRes, req, res);
|
|
278
|
+
} catch (err) {
|
|
279
|
+
this.log("error", "[AutoProxyCookie] onProxyRes hook error:", err.message);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
this.handleOnError = (err, req, res) => {
|
|
284
|
+
this.log("error", "[AutoProxyCookie] Proxy Error:", err.message);
|
|
285
|
+
this.log("error", "[AutoProxyCookie] URL:", req.url);
|
|
286
|
+
if (res instanceof http.ServerResponse && !res.headersSent) {
|
|
287
|
+
res.writeHead(503, { "Content-Type": "application/json; charset=utf-8" });
|
|
288
|
+
res.end(JSON.stringify({
|
|
289
|
+
success: false,
|
|
290
|
+
message: "\u670D\u52A1\u6682\u4E0D\u53EF\u7528\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",
|
|
291
|
+
error: err.message
|
|
292
|
+
}));
|
|
293
|
+
}
|
|
294
|
+
if (this.options.hooks.onError) {
|
|
295
|
+
try {
|
|
296
|
+
this.options.hooks.onError(err, req, res);
|
|
297
|
+
} catch (hookErr) {
|
|
298
|
+
this.log("error", "[AutoProxyCookie] onError hook error:", hookErr.message);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
this.handleOnWsError = (err, req, socket) => {
|
|
303
|
+
this.log("error", "[AutoProxyCookie] WebSocket Proxy Error:", err.message);
|
|
304
|
+
this.log("error", "[AutoProxyCookie] WebSocket URL:", req.url);
|
|
305
|
+
if (socket) {
|
|
306
|
+
socket.close();
|
|
307
|
+
}
|
|
308
|
+
if (this.options.hooks.onWsError) {
|
|
309
|
+
try {
|
|
310
|
+
this.options.hooks.onWsError(err, req, socket);
|
|
311
|
+
} catch (hookErr) {
|
|
312
|
+
this.log("error", "[AutoProxyCookie] onWsError hook error:", hookErr.message);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
const defaultHooks = {
|
|
317
|
+
onProxyReq: () => {
|
|
318
|
+
},
|
|
319
|
+
onProxyRes: () => {
|
|
320
|
+
},
|
|
321
|
+
onError: () => {
|
|
322
|
+
},
|
|
323
|
+
onWsError: () => {
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
const mergedOptions = {
|
|
327
|
+
...options,
|
|
328
|
+
hooks: {
|
|
329
|
+
...defaultHooks,
|
|
330
|
+
...options.hooks || {}
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
this.options = {
|
|
334
|
+
debug: false,
|
|
335
|
+
autoRestart: false,
|
|
336
|
+
restartMarkerFile: ".cookie-restart-marker",
|
|
337
|
+
proxyMap: {},
|
|
338
|
+
ignorePaths: [],
|
|
339
|
+
ws: true,
|
|
340
|
+
changeOrigin: true,
|
|
341
|
+
secure: false,
|
|
342
|
+
followRedirects: true,
|
|
343
|
+
autoRewrite: false,
|
|
344
|
+
protocolRewrite: void 0,
|
|
345
|
+
logLevel: "info",
|
|
346
|
+
cookieDomainRewrite: "*",
|
|
347
|
+
cookiePathRewrite: false,
|
|
348
|
+
headers: {},
|
|
349
|
+
...mergedOptions
|
|
350
|
+
};
|
|
351
|
+
this.cookieReader = new CookieReader({ cookieFile: options.cookieFile });
|
|
352
|
+
}
|
|
353
|
+
getProxyUrl(req) {
|
|
354
|
+
const pathname = req.url?.split("?")[0] || "/";
|
|
355
|
+
const proxyMap = this.options.proxyMap || {};
|
|
356
|
+
for (const [prefix, target] of Object.entries(proxyMap)) {
|
|
357
|
+
if (pathname.startsWith(prefix)) {
|
|
358
|
+
return target;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return this.options.target;
|
|
362
|
+
}
|
|
363
|
+
isIgnoredPath(pathname) {
|
|
364
|
+
const ignorePaths = this.options.ignorePaths || [];
|
|
365
|
+
return ignorePaths.some(
|
|
366
|
+
(ignored) => pathname.startsWith(ignored)
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
log(level, ...args) {
|
|
370
|
+
const levels = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
371
|
+
const currentLevel = levels[this.options.logLevel || "info"];
|
|
372
|
+
const msgLevel = levels[level];
|
|
373
|
+
if (msgLevel >= currentLevel) {
|
|
374
|
+
if (level === "error") {
|
|
375
|
+
console.error(...args);
|
|
376
|
+
} else if (level === "warn") {
|
|
377
|
+
console.warn(...args);
|
|
378
|
+
} else {
|
|
379
|
+
console.log(...args);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
createProxyOptions(target) {
|
|
384
|
+
const {
|
|
385
|
+
ws,
|
|
386
|
+
changeOrigin,
|
|
387
|
+
secure,
|
|
388
|
+
followRedirects,
|
|
389
|
+
autoRewrite,
|
|
390
|
+
protocolRewrite,
|
|
391
|
+
cookieDomainRewrite,
|
|
392
|
+
cookiePathRewrite,
|
|
393
|
+
headers
|
|
394
|
+
} = this.options;
|
|
395
|
+
return {
|
|
396
|
+
target,
|
|
397
|
+
ws,
|
|
398
|
+
changeOrigin,
|
|
399
|
+
secure,
|
|
400
|
+
followRedirects,
|
|
401
|
+
autoRewrite,
|
|
402
|
+
protocolRewrite,
|
|
403
|
+
cookieDomainRewrite,
|
|
404
|
+
cookiePathRewrite,
|
|
405
|
+
headers: {
|
|
406
|
+
...headers
|
|
407
|
+
},
|
|
408
|
+
ignorePath: false
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
async setup(server) {
|
|
412
|
+
this.server = server;
|
|
413
|
+
this.currentCookie = this.cookieReader.readCookie();
|
|
414
|
+
try {
|
|
415
|
+
const baseOptions = {
|
|
416
|
+
target: this.options.target,
|
|
417
|
+
changeOrigin: this.options.changeOrigin,
|
|
418
|
+
secure: this.options.secure,
|
|
419
|
+
followRedirects: this.options.followRedirects,
|
|
420
|
+
autoRewrite: this.options.autoRewrite,
|
|
421
|
+
protocolRewrite: this.options.protocolRewrite,
|
|
422
|
+
cookieDomainRewrite: this.options.cookieDomainRewrite,
|
|
423
|
+
cookiePathRewrite: this.options.cookiePathRewrite,
|
|
424
|
+
ws: this.options.ws
|
|
425
|
+
};
|
|
426
|
+
this.proxyServer = httpProxy.createProxyServer(baseOptions);
|
|
427
|
+
this.proxyServer.on("proxyReq", this.handleOnProxyReq);
|
|
428
|
+
this.proxyServer.on("proxyRes", this.handleOnProxyRes);
|
|
429
|
+
this.proxyServer.on("error", this.handleOnError);
|
|
430
|
+
if (this.options.ws) {
|
|
431
|
+
this.proxyServer.on("wsError", this.handleOnWsError);
|
|
432
|
+
}
|
|
433
|
+
this.log("info", "[AutoProxyCookie] Proxy server created with WebSocket support");
|
|
434
|
+
} catch (err) {
|
|
435
|
+
this.log("warn", "[AutoProxyCookie] http-proxy create failed, using basic mode:", err.message);
|
|
436
|
+
}
|
|
437
|
+
server.middlewares.use((req, res, next) => {
|
|
438
|
+
const pathname = new URL(req.url || "/", "http://localhost").pathname;
|
|
439
|
+
if (this.isIgnoredPath(pathname)) {
|
|
440
|
+
next();
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
this.currentCookie = this.cookieReader.readCookie();
|
|
444
|
+
if (this.proxyServer) {
|
|
445
|
+
const target = this.getProxyUrl(req);
|
|
446
|
+
if (this.options.debug || this.options.logLevel === "debug") {
|
|
447
|
+
this.log("info", `[AutoProxyCookie] ${pathname} -> ${target}`);
|
|
448
|
+
}
|
|
449
|
+
const proxyOptions = this.createProxyOptions(target);
|
|
450
|
+
try {
|
|
451
|
+
this.proxyServer.web(req, res, proxyOptions);
|
|
452
|
+
} catch (err) {
|
|
453
|
+
this.log("error", "[AutoProxyCookie] Proxy web error:", err.message);
|
|
454
|
+
next(err);
|
|
455
|
+
}
|
|
456
|
+
} else {
|
|
457
|
+
next();
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
if (this.options.ws && this.server.httpServer && this.proxyServer) {
|
|
461
|
+
this.server.httpServer.on("upgrade", (req, socket, head) => {
|
|
462
|
+
const pathname = new URL(req.url || "/", "http://localhost").pathname;
|
|
463
|
+
if (this.isIgnoredPath(pathname)) {
|
|
464
|
+
socket.destroy();
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
const target = this.getProxyUrl(req);
|
|
468
|
+
this.proxyServer?.ws(req, socket, head, {
|
|
469
|
+
target,
|
|
470
|
+
ws: true,
|
|
471
|
+
changeOrigin: this.options.changeOrigin,
|
|
472
|
+
secure: this.options.secure
|
|
473
|
+
});
|
|
474
|
+
});
|
|
475
|
+
this.log("info", "[AutoProxyCookie] WebSocket upgrade handler registered");
|
|
476
|
+
}
|
|
477
|
+
this.startFileWatch();
|
|
478
|
+
this.log("info", "[AutoProxyCookie] Auto-proxy middleware enabled");
|
|
479
|
+
this.log("info", "[AutoProxyCookie] Target:", this.options.target);
|
|
480
|
+
this.log("info", "[AutoProxyCookie] Cookie file:", this.options.cookieFile);
|
|
481
|
+
if (this.options.autoRestart) {
|
|
482
|
+
this.log("info", "[AutoProxyCookie] Auto-restart enabled");
|
|
483
|
+
}
|
|
484
|
+
if (this.options.ws) {
|
|
485
|
+
this.log("info", "[AutoProxyCookie] WebSocket support enabled");
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
startFileWatch() {
|
|
489
|
+
let shouldWatch;
|
|
490
|
+
if (this.options.isDev !== void 0) {
|
|
491
|
+
shouldWatch = this.options.isDev;
|
|
492
|
+
if (this.options.debug) {
|
|
493
|
+
console.log(`[AutoProxyCookie] isDev=${this.options.isDev}, ${shouldWatch ? "enabling" : "disabling"} watch`);
|
|
494
|
+
}
|
|
495
|
+
} else {
|
|
496
|
+
shouldWatch = true;
|
|
497
|
+
if (this.options.debug) {
|
|
498
|
+
console.log("[AutoProxyCookie] Default behavior: enabling watch (dev mode)");
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
if (shouldWatch) {
|
|
502
|
+
this.watcher = watchCookieFile(
|
|
503
|
+
this.options.cookieFile,
|
|
504
|
+
this.handleCookieChange,
|
|
505
|
+
(error) => {
|
|
506
|
+
this.log("error", "[AutoProxyCookie] File watch error:", error.message);
|
|
507
|
+
}
|
|
508
|
+
);
|
|
509
|
+
} else if (this.options.debug) {
|
|
510
|
+
console.log("[AutoProxyCookie] File watch disabled");
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
stop() {
|
|
514
|
+
if (this.watcher) {
|
|
515
|
+
this.watcher.stop();
|
|
516
|
+
this.watcher = null;
|
|
517
|
+
}
|
|
518
|
+
if (this.proxyServer) {
|
|
519
|
+
this.proxyServer.close();
|
|
520
|
+
this.proxyServer = null;
|
|
521
|
+
}
|
|
522
|
+
this.log("info", "[AutoProxyCookie] Stopped");
|
|
523
|
+
}
|
|
524
|
+
getCurrentCookie() {
|
|
525
|
+
return this.currentCookie;
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
function createAutoProxyCookie(options) {
|
|
529
|
+
return new AutoProxyCookie(options);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// src/proxy/vite-plugin.ts
|
|
533
|
+
function viteAutoProxyCookie(options) {
|
|
534
|
+
const {
|
|
535
|
+
name = "vite-auto-proxy-cookie",
|
|
536
|
+
isDev,
|
|
537
|
+
...autoProxyOptions
|
|
538
|
+
} = options;
|
|
539
|
+
let autoProxy = null;
|
|
540
|
+
return {
|
|
541
|
+
name,
|
|
542
|
+
apply: "serve",
|
|
543
|
+
async configureServer(server) {
|
|
544
|
+
autoProxy = createAutoProxyCookie({
|
|
545
|
+
...autoProxyOptions,
|
|
546
|
+
debug: options.debug ?? false,
|
|
547
|
+
autoRestart: options.autoRestart ?? true,
|
|
548
|
+
isDev
|
|
549
|
+
});
|
|
550
|
+
try {
|
|
551
|
+
await autoProxy.setup(server);
|
|
552
|
+
} catch (error) {
|
|
553
|
+
console.error("[vite-auto-proxy-cookie] Failed to setup proxy:", error);
|
|
554
|
+
if (options.debug) {
|
|
555
|
+
console.log("[vite-auto-proxy-cookie] Falling back to middleware mode");
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
},
|
|
559
|
+
closeBundle() {
|
|
560
|
+
autoProxy?.stop();
|
|
561
|
+
}
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// src/proxy/vite-cookie-plugin.ts
|
|
566
|
+
function viteDevProxyCookie(options) {
|
|
567
|
+
const { cookieFile, debug = false, onCookieChange, watch = "auto", isDev } = options;
|
|
568
|
+
let watcher = null;
|
|
569
|
+
let currentCookie = "";
|
|
570
|
+
const cookieReader = new CookieReader({ cookieFile });
|
|
571
|
+
return {
|
|
572
|
+
name: "vite-dev-proxy-cookie",
|
|
573
|
+
apply: "serve",
|
|
574
|
+
configureServer(server) {
|
|
575
|
+
currentCookie = cookieReader.readCookie();
|
|
576
|
+
if (debug) {
|
|
577
|
+
console.log("[vite-dev-proxy-cookie] Initial cookie loaded");
|
|
578
|
+
}
|
|
579
|
+
const middlewares = server.middlewares || server._middlewares || server.app;
|
|
580
|
+
if (middlewares && typeof middlewares.use === "function") {
|
|
581
|
+
middlewares.use((req, _res, next) => {
|
|
582
|
+
if (currentCookie && req.url?.startsWith("/")) {
|
|
583
|
+
req.headers = req.headers || {};
|
|
584
|
+
req.headers["cookie"] = currentCookie;
|
|
585
|
+
}
|
|
586
|
+
next();
|
|
587
|
+
});
|
|
588
|
+
} else {
|
|
589
|
+
console.warn("[vite-dev-proxy-cookie] Could not access middleware stack, cookie injection disabled");
|
|
590
|
+
}
|
|
591
|
+
let shouldWatch;
|
|
592
|
+
if (isDev !== void 0) {
|
|
593
|
+
shouldWatch = isDev;
|
|
594
|
+
if (debug) {
|
|
595
|
+
console.log(`[vite-dev-proxy-cookie] isDev=${isDev}, ${shouldWatch ? "enabling" : "disabling"} watch`);
|
|
596
|
+
}
|
|
597
|
+
} else {
|
|
598
|
+
shouldWatch = shouldEnableWatch(watch, [], debug, "[vite-dev-proxy-cookie]");
|
|
599
|
+
}
|
|
600
|
+
if (shouldWatch) {
|
|
601
|
+
watcher = watchCookieFile(
|
|
602
|
+
cookieFile,
|
|
603
|
+
(newCookie) => {
|
|
604
|
+
currentCookie = newCookie;
|
|
605
|
+
onCookieChange?.(newCookie);
|
|
606
|
+
console.log("[vite-dev-proxy-cookie] Cookie changed, please restart server for full effect");
|
|
607
|
+
},
|
|
608
|
+
(error) => {
|
|
609
|
+
console.error("[vite-dev-proxy-cookie] Watch error:", error.message);
|
|
610
|
+
}
|
|
611
|
+
);
|
|
612
|
+
} else if (debug) {
|
|
613
|
+
console.log("[vite-dev-proxy-cookie] File watch disabled");
|
|
614
|
+
}
|
|
615
|
+
},
|
|
616
|
+
closeBundle() {
|
|
617
|
+
watcher?.stop();
|
|
618
|
+
}
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// src/proxy/vue-proxy-config.ts
|
|
623
|
+
import * as path4 from "path";
|
|
624
|
+
function createVueProxyConfig(target, options = {}) {
|
|
625
|
+
const {
|
|
626
|
+
getCookie,
|
|
627
|
+
debug = false,
|
|
628
|
+
headers = {},
|
|
629
|
+
ws = false,
|
|
630
|
+
changeOrigin = true,
|
|
631
|
+
secure = false,
|
|
632
|
+
onError: customOnError
|
|
633
|
+
} = options;
|
|
634
|
+
const config = {
|
|
635
|
+
ws,
|
|
636
|
+
target,
|
|
637
|
+
changeOrigin,
|
|
638
|
+
secure,
|
|
639
|
+
headers,
|
|
640
|
+
onProxyReq: (proxyReq, req) => {
|
|
641
|
+
const cookie = getCookie ? getCookie() : "";
|
|
642
|
+
if (cookie) {
|
|
643
|
+
applyDevCookieHeader(proxyReq, cookie);
|
|
644
|
+
}
|
|
645
|
+
if (debug) {
|
|
646
|
+
const reqPath = req.url || "/";
|
|
647
|
+
console.log("[Proxy Request]", reqPath, req.method, cookie ? "(with cookie)" : "(no cookie)");
|
|
648
|
+
}
|
|
649
|
+
},
|
|
650
|
+
onError: customOnError || ((err) => {
|
|
651
|
+
console.error("\n[Proxy Error]", err.message);
|
|
652
|
+
})
|
|
653
|
+
};
|
|
654
|
+
return config;
|
|
655
|
+
}
|
|
656
|
+
function createFileCookieGetter(cookieFile, options = {}) {
|
|
657
|
+
const {
|
|
658
|
+
watch = "auto",
|
|
659
|
+
debug = false,
|
|
660
|
+
productionEnvs = [],
|
|
661
|
+
isDev
|
|
662
|
+
} = options;
|
|
663
|
+
const reader = new CookieReader({ cookieFile: path4.resolve(cookieFile) });
|
|
664
|
+
let shouldWatch;
|
|
665
|
+
if (isDev !== void 0) {
|
|
666
|
+
shouldWatch = isDev;
|
|
667
|
+
if (debug) {
|
|
668
|
+
console.log(`[CookieFile] isDev=${isDev}, ${shouldWatch ? "enabling" : "disabling"} watch`);
|
|
669
|
+
}
|
|
670
|
+
} else {
|
|
671
|
+
shouldWatch = shouldEnableWatch(watch, productionEnvs, debug, "[CookieFile]");
|
|
672
|
+
}
|
|
673
|
+
if (shouldWatch) {
|
|
674
|
+
watchCookieFile(
|
|
675
|
+
path4.resolve(cookieFile),
|
|
676
|
+
(newCookie) => {
|
|
677
|
+
if (debug) {
|
|
678
|
+
console.log("[CookieFile] Updated:", newCookie ? "(has cookie)" : "(empty)");
|
|
679
|
+
}
|
|
680
|
+
},
|
|
681
|
+
(error) => {
|
|
682
|
+
console.error("[CookieFile] Watch error:", error.message);
|
|
683
|
+
}
|
|
684
|
+
);
|
|
685
|
+
} else if (debug) {
|
|
686
|
+
console.log("[CookieFile] File watch disabled");
|
|
687
|
+
}
|
|
688
|
+
return () => reader.readCookie();
|
|
689
|
+
}
|
|
690
|
+
function createAutoProxyConfig(options) {
|
|
691
|
+
const { target, ignorePaths = [], includePaths = [], additionalProxies = {}, getCookie, debug, headers } = options;
|
|
692
|
+
const result = {};
|
|
693
|
+
if (includePaths.length > 0) {
|
|
694
|
+
for (const proxyPath of includePaths) {
|
|
695
|
+
result[proxyPath] = createVueProxyConfig(target, { getCookie, debug, headers });
|
|
696
|
+
}
|
|
697
|
+
} else {
|
|
698
|
+
const defaultProxy = {
|
|
699
|
+
ws: false,
|
|
700
|
+
target,
|
|
701
|
+
changeOrigin: true,
|
|
702
|
+
secure: false,
|
|
703
|
+
headers,
|
|
704
|
+
onProxyReq: (proxyReq, req) => {
|
|
705
|
+
const reqPath = req.url || "/";
|
|
706
|
+
if (ignorePaths.some((p) => reqPath.startsWith(p))) {
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
const cookie = getCookie ? getCookie() : "";
|
|
710
|
+
if (cookie) {
|
|
711
|
+
applyDevCookieHeader(proxyReq, cookie);
|
|
712
|
+
}
|
|
713
|
+
if (debug) {
|
|
714
|
+
console.log("[Proxy Request]", reqPath, req.method, cookie ? "(with cookie)" : "(no cookie)");
|
|
715
|
+
}
|
|
716
|
+
},
|
|
717
|
+
onError: (err) => {
|
|
718
|
+
console.error("\n[Proxy Error]", err.message);
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
result["/"] = defaultProxy;
|
|
722
|
+
}
|
|
723
|
+
for (const [proxyPath, proxyTarget] of Object.entries(additionalProxies)) {
|
|
724
|
+
result[proxyPath] = createVueProxyConfig(proxyTarget, { getCookie, debug, headers });
|
|
725
|
+
}
|
|
726
|
+
return result;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
// src/proxy/vite-adapter.ts
|
|
730
|
+
var viteVersion = "";
|
|
731
|
+
var majorVersion = null;
|
|
732
|
+
function detectViteVersion() {
|
|
733
|
+
if (majorVersion !== null) {
|
|
734
|
+
return majorVersion;
|
|
735
|
+
}
|
|
736
|
+
try {
|
|
737
|
+
const pkg = __require("vite/package.json");
|
|
738
|
+
viteVersion = pkg.version;
|
|
739
|
+
majorVersion = parseInt(viteVersion.split(".")[0], 10);
|
|
740
|
+
} catch {
|
|
741
|
+
majorVersion = 5;
|
|
742
|
+
}
|
|
743
|
+
return majorVersion;
|
|
744
|
+
}
|
|
745
|
+
function createDevProxyCookie(options) {
|
|
746
|
+
const {
|
|
747
|
+
mode = "auto",
|
|
748
|
+
watch = "auto",
|
|
749
|
+
isDev,
|
|
750
|
+
...restOptions
|
|
751
|
+
} = options;
|
|
752
|
+
const version = detectViteVersion();
|
|
753
|
+
if (options.debug) {
|
|
754
|
+
console.log(`[dev-proxy-cookie] Detected Vite ${version}.x`);
|
|
755
|
+
}
|
|
756
|
+
if (mode === "cookie" || mode === "auto" && !options.target) {
|
|
757
|
+
return viteDevProxyCookie({
|
|
758
|
+
cookieFile: options.cookieFile,
|
|
759
|
+
debug: options.debug,
|
|
760
|
+
onCookieChange: options.onCookieChange,
|
|
761
|
+
watch,
|
|
762
|
+
isDev
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
const pluginOptions = {
|
|
766
|
+
cookieFile: options.cookieFile,
|
|
767
|
+
target: options.target,
|
|
768
|
+
debug: options.debug,
|
|
769
|
+
autoRestart: options.autoRestart ?? true,
|
|
770
|
+
restartMarkerFile: options.restartMarkerFile,
|
|
771
|
+
proxyMap: options.proxyMap,
|
|
772
|
+
ignorePaths: options.ignorePaths
|
|
773
|
+
};
|
|
774
|
+
return viteAutoProxyCookie(pluginOptions);
|
|
775
|
+
}
|
|
776
|
+
function getViteVersion() {
|
|
777
|
+
detectViteVersion();
|
|
778
|
+
return viteVersion;
|
|
779
|
+
}
|
|
780
|
+
function getViteMajorVersion() {
|
|
781
|
+
return detectViteVersion();
|
|
782
|
+
}
|
|
783
|
+
export {
|
|
784
|
+
AutoProxyCookie,
|
|
785
|
+
CookieReader,
|
|
786
|
+
CookieWatcher,
|
|
787
|
+
createAutoProxyConfig,
|
|
788
|
+
createAutoProxyCookie,
|
|
789
|
+
createCookieGetter,
|
|
790
|
+
createDevProxyCookie,
|
|
791
|
+
createFileCookieGetter,
|
|
792
|
+
createVueProxyConfig,
|
|
793
|
+
detectProductionEnvironment,
|
|
794
|
+
getViteMajorVersion,
|
|
795
|
+
getViteVersion,
|
|
796
|
+
isProductionValue,
|
|
797
|
+
shouldEnableWatch,
|
|
798
|
+
viteAutoProxyCookie,
|
|
799
|
+
viteDevProxyCookie,
|
|
800
|
+
watchCookieFile
|
|
801
|
+
};
|