@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/package.json ADDED
@@ -0,0 +1,83 @@
1
+ {
2
+ "name": "@gylautorun/dev-proxy-cookie",
3
+ "version": "1.0.0-beta.1",
4
+ "description": "开发环境代理Cookie注入工具,支持文件监听自动重载和自动代理",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "src",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean",
16
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
17
+ "test": "jest",
18
+ "test:coverage": "jest --coverage",
19
+ "lint": "tsc --noEmit",
20
+ "bump": "node scripts/bump-version.js",
21
+ "bump:major": "node scripts/bump-version.js --major",
22
+ "bump:minor": "node scripts/bump-version.js --minor",
23
+ "bump:patch": "node scripts/bump-version.js --patch",
24
+ "bump:beta": "node scripts/bump-version.js --beta",
25
+ "bump:alpha": "node scripts/bump-version.js --alpha",
26
+ "bump:major-beta": "node scripts/bump-version.js --major-beta",
27
+ "bump:minor-beta": "node scripts/bump-version.js --minor-beta",
28
+ "bump:major-alpha": "node scripts/bump-version.js --major-alpha",
29
+ "bump:minor-alpha": "node scripts/bump-version.js --minor-alpha",
30
+ "publish:major": "npm run bump:major && npm publish",
31
+ "publish:minor": "npm run bump:minor && npm publish",
32
+ "publish:patch": "npm run bump:patch && npm publish",
33
+ "publish:beta": "npm run bump:beta && npm publish --tag beta",
34
+ "publish:alpha": "npm run bump:alpha && npm publish --tag alpha",
35
+ "prepublishOnly": "npm run lint && npm run test && npm run build"
36
+ },
37
+ "keywords": [
38
+ "dev",
39
+ "proxy",
40
+ "cookie",
41
+ "vite",
42
+ "vue",
43
+ "webpack",
44
+ "auto-proxy",
45
+ "hot-reload",
46
+ "cookie-injection"
47
+ ],
48
+ "author": "gyl",
49
+ "license": "MIT",
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "git@github.com:gylautorun/dev-proxy-cookie.git"
53
+ },
54
+ "bugs": {
55
+ "url": "https://github.com/gylautorun/dev-proxy-cookie/issues"
56
+ },
57
+ "homepage": "https://github.com/gylautorun/dev-proxy-cookie/blob/main/README.md",
58
+ "dependencies": {
59
+ "chokidar": "^3.5.3",
60
+ "http-proxy": "^1.18.1"
61
+ },
62
+ "peerDependencies": {
63
+ "vite": ">=4.0.0"
64
+ },
65
+ "peerDependenciesMeta": {
66
+ "vite": {
67
+ "optional": true
68
+ }
69
+ },
70
+ "devDependencies": {
71
+ "@types/http-proxy": "^1.17.14",
72
+ "@types/jest": "^30.0.0",
73
+ "@types/node": "^18.19.0",
74
+ "jest": "^30.4.2",
75
+ "ts-jest": "^29.4.9",
76
+ "tsup": "^8.0.0",
77
+ "typescript": "^5.3.0",
78
+ "vite": "^4.5.0"
79
+ },
80
+ "engines": {
81
+ "node": ">=16.0.0"
82
+ }
83
+ }
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './proxy';
2
+ export * from './utils';
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Replace outbound Cookie with the dev file cookie.
3
+ * Browsers send `Cookie` when `withCredentials` is true; merging with file cookie often yields duplicate
4
+ * names (e.g. two JSESSIONID) and many servers honor the first value — the stale browser session.
5
+ */
6
+ export function applyDevCookieHeader(
7
+ proxyReq: { removeHeader(name: string): void; setHeader(name: string, value: string): void },
8
+ cookie: string
9
+ ): void {
10
+ if (!cookie) return;
11
+ proxyReq.removeHeader('cookie');
12
+ proxyReq.removeHeader('Cookie');
13
+ proxyReq.setHeader('Cookie', cookie);
14
+ }
@@ -0,0 +1,429 @@
1
+ import * as http from 'http';
2
+ import * as net from 'net';
3
+ import * as fs from 'fs';
4
+ import * as path from 'path';
5
+ import type { IncomingMessage, ServerResponse } from 'http';
6
+ import type { ViteDevServer } from 'vite';
7
+ import httpProxy from 'http-proxy';
8
+ import { CookieReader, CookieWatcher, watchCookieFile } from '../utils';
9
+ import { applyDevCookieHeader } from './apply-dev-cookie-header';
10
+
11
+ export type ErrorCallback = (err: Error, req: IncomingMessage, res: ServerResponse | net.Socket) => void;
12
+
13
+ interface ProxyServer {
14
+ web(req: IncomingMessage, res: ServerResponse, options?: ServerOptions): void;
15
+ ws(req: IncomingMessage, socket: net.Socket, head: Buffer, options?: ServerOptions): void;
16
+ on(event: 'proxyReq', listener: (proxyReq: any, req: IncomingMessage, res: ServerResponse, options: ServerOptions) => void): void;
17
+ on(event: 'proxyRes', listener: (proxyRes: IncomingMessage, req: IncomingMessage, res: ServerResponse) => void): void;
18
+ on(event: 'error', listener: (err: Error, req: IncomingMessage, res: ServerResponse | net.Socket) => void): void;
19
+ on(event: 'wsError', listener: (err: Error, req: IncomingMessage, socket: net.Socket) => void): void;
20
+ close(): void;
21
+ }
22
+
23
+ interface ServerOptions {
24
+ target: string;
25
+ ws?: boolean;
26
+ changeOrigin?: boolean;
27
+ secure?: boolean;
28
+ followRedirects?: boolean;
29
+ autoRewrite?: boolean;
30
+ protocolRewrite?: string;
31
+ cookieDomainRewrite?: false | string | { [oldDomain: string]: string };
32
+ cookiePathRewrite?: false | string | { [oldPath: string]: string };
33
+ headers?: { [header: string]: string };
34
+ ignorePath?: boolean;
35
+ }
36
+
37
+ export interface ProxyHooks {
38
+ onProxyReq?: (proxyReq: any, req: IncomingMessage, res: ServerResponse) => void;
39
+ onProxyRes?: (proxyRes: any, req: IncomingMessage, res: ServerResponse) => void;
40
+ onError?: ErrorCallback;
41
+ onWsError?: (err: Error, req: IncomingMessage, socket: net.Socket) => void;
42
+ }
43
+
44
+ export interface AutoProxyCookieOptions {
45
+ cookieFile: string;
46
+ target: string;
47
+ debug?: boolean;
48
+ autoRestart?: boolean;
49
+ restartMarkerFile?: string;
50
+ proxyMap?: Record<string, string>;
51
+ ignorePaths?: string[];
52
+ ws?: boolean;
53
+ changeOrigin?: boolean;
54
+ secure?: boolean;
55
+ followRedirects?: boolean;
56
+ autoRewrite?: boolean;
57
+ protocolRewrite?: string;
58
+ logLevel?: 'debug' | 'info' | 'warn' | 'error';
59
+ cookieDomainRewrite?: false | string | { [oldDomain: string]: string };
60
+ cookiePathRewrite?: false | string | { [oldPath: string]: string };
61
+ headers?: { [header: string]: string };
62
+ hooks?: ProxyHooks;
63
+ /**
64
+ * 是否为开发环境(优先级最高)
65
+ * 设置此参数后,将直接决定是否启用文件监听:
66
+ * - true: 启用监听(开发模式)
67
+ * - false: 禁用监听(生产模式)
68
+ *
69
+ * 使用示例: isDev: process.env.NODE_ENV === 'development'
70
+ */
71
+ isDev?: boolean;
72
+ }
73
+
74
+ export class AutoProxyCookie {
75
+ private options: AutoProxyCookieOptions & { hooks: Required<ProxyHooks> };
76
+ private currentCookie: string = '';
77
+ private server: ViteDevServer | null = null;
78
+ private proxyServer: ProxyServer | null = null;
79
+ private watcher: CookieWatcher | null = null;
80
+ private cookieReader: CookieReader;
81
+
82
+ constructor(options: AutoProxyCookieOptions) {
83
+ const defaultHooks: Required<ProxyHooks> = {
84
+ onProxyReq: () => {},
85
+ onProxyRes: () => {},
86
+ onError: () => {},
87
+ onWsError: () => {},
88
+ };
89
+
90
+ const mergedOptions = {
91
+ ...options,
92
+ hooks: {
93
+ ...defaultHooks,
94
+ ...(options.hooks || {}),
95
+ },
96
+ };
97
+
98
+ this.options = {
99
+ debug: false,
100
+ autoRestart: false,
101
+ restartMarkerFile: '.cookie-restart-marker',
102
+ proxyMap: {},
103
+ ignorePaths: [],
104
+ ws: true,
105
+ changeOrigin: true,
106
+ secure: false,
107
+ followRedirects: true,
108
+ autoRewrite: false,
109
+ protocolRewrite: undefined,
110
+ logLevel: 'info',
111
+ cookieDomainRewrite: '*',
112
+ cookiePathRewrite: false,
113
+ headers: {},
114
+ ...mergedOptions,
115
+ };
116
+ this.cookieReader = new CookieReader({ cookieFile: options.cookieFile });
117
+ }
118
+
119
+ private handleCookieChange = (newCookie: string): void => {
120
+ if (newCookie !== this.currentCookie) {
121
+ this.currentCookie = newCookie;
122
+ this.log('info', '[AutoProxyCookie] Cookie updated:', newCookie ? '(has cookie)' : '(empty)');
123
+
124
+ if (this.options.autoRestart && this.options.restartMarkerFile) {
125
+ const markerPath = path.resolve(this.options.restartMarkerFile);
126
+ fs.writeFileSync(markerPath, JSON.stringify({
127
+ timestamp: Date.now(),
128
+ cookie: newCookie,
129
+ }, null, 2));
130
+ this.log('info', '[AutoProxyCookie] Restart marker written to:', markerPath);
131
+ this.log('info', '[AutoProxyCookie] Please restart the dev server for changes to take effect');
132
+ }
133
+ }
134
+ };
135
+
136
+ private getProxyUrl(req: IncomingMessage): string {
137
+ const pathname = req.url?.split('?')[0] || '/';
138
+ const proxyMap = this.options.proxyMap || {};
139
+
140
+ for (const [prefix, target] of Object.entries(proxyMap)) {
141
+ if (pathname.startsWith(prefix)) {
142
+ return target;
143
+ }
144
+ }
145
+
146
+ return this.options.target;
147
+ }
148
+
149
+ private isIgnoredPath(pathname: string): boolean {
150
+ const ignorePaths = this.options.ignorePaths || [];
151
+ return ignorePaths.some(ignored =>
152
+ pathname.startsWith(ignored)
153
+ );
154
+ }
155
+
156
+ private log(level: 'debug' | 'info' | 'warn' | 'error', ...args: any[]): void {
157
+ const levels: Record<string, number> = { debug: 0, info: 1, warn: 2, error: 3 };
158
+ const currentLevel = levels[this.options.logLevel || 'info'];
159
+ const msgLevel = levels[level];
160
+
161
+ if (msgLevel >= currentLevel) {
162
+ if (level === 'error') {
163
+ console.error(...args);
164
+ } else if (level === 'warn') {
165
+ console.warn(...args);
166
+ } else {
167
+ console.log(...args);
168
+ }
169
+ }
170
+ }
171
+
172
+ private createProxyOptions(target: string): ServerOptions {
173
+ const {
174
+ ws,
175
+ changeOrigin,
176
+ secure,
177
+ followRedirects,
178
+ autoRewrite,
179
+ protocolRewrite,
180
+ cookieDomainRewrite,
181
+ cookiePathRewrite,
182
+ headers,
183
+ } = this.options;
184
+
185
+ return {
186
+ target,
187
+ ws,
188
+ changeOrigin,
189
+ secure,
190
+ followRedirects,
191
+ autoRewrite,
192
+ protocolRewrite,
193
+ cookieDomainRewrite,
194
+ cookiePathRewrite,
195
+ headers: {
196
+ ...headers,
197
+ },
198
+ ignorePath: false,
199
+ };
200
+ }
201
+
202
+ private handleOnProxyReq = (proxyReq: any, req: IncomingMessage, res: ServerResponse, _options: ServerOptions): void => {
203
+ if (this.currentCookie) {
204
+ applyDevCookieHeader(proxyReq, this.currentCookie);
205
+ }
206
+
207
+ this.log('debug', '[AutoProxyCookie] Proxy Request:', req.method, req.url);
208
+
209
+ if (this.options.hooks.onProxyReq) {
210
+ try {
211
+ this.options.hooks.onProxyReq(proxyReq, req, res);
212
+ } catch (err) {
213
+ this.log('error', '[AutoProxyCookie] onProxyReq hook error:', (err as Error).message);
214
+ }
215
+ }
216
+ };
217
+
218
+ private handleOnProxyRes = (proxyRes: any, req: IncomingMessage, res: ServerResponse): void => {
219
+ const allowedHeaders = [
220
+ 'Content-Type',
221
+ 'Content-Length',
222
+ 'Authorization',
223
+ 'Set-Cookie',
224
+ 'X-Requested-With',
225
+ 'Access-Control-Allow-Origin',
226
+ 'Access-Control-Allow-Credentials',
227
+ ];
228
+
229
+ res.setHeader('Access-Control-Allow-Origin', '*');
230
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
231
+ res.setHeader('Access-Control-Allow-Headers', allowedHeaders.join(','));
232
+ res.setHeader('Access-Control-Allow-Credentials', 'true');
233
+
234
+ this.log('debug', '[AutoProxyCookie] Proxy Response:', req.url, proxyRes.statusCode);
235
+
236
+ if (this.options.hooks.onProxyRes) {
237
+ try {
238
+ this.options.hooks.onProxyRes(proxyRes, req, res);
239
+ } catch (err) {
240
+ this.log('error', '[AutoProxyCookie] onProxyRes hook error:', (err as Error).message);
241
+ }
242
+ }
243
+ };
244
+
245
+ private handleOnError = (err: Error, req: IncomingMessage, res: ServerResponse | net.Socket): void => {
246
+ this.log('error', '[AutoProxyCookie] Proxy Error:', err.message);
247
+ this.log('error', '[AutoProxyCookie] URL:', req.url);
248
+
249
+ if (res instanceof http.ServerResponse && !res.headersSent) {
250
+ res.writeHead(503, { 'Content-Type': 'application/json; charset=utf-8' });
251
+ res.end(JSON.stringify({
252
+ success: false,
253
+ message: '服务暂不可用,请稍后重试',
254
+ error: err.message,
255
+ }));
256
+ }
257
+
258
+ if (this.options.hooks.onError) {
259
+ try {
260
+ this.options.hooks.onError(err, req, res);
261
+ } catch (hookErr) {
262
+ this.log('error', '[AutoProxyCookie] onError hook error:', (hookErr as Error).message);
263
+ }
264
+ }
265
+ };
266
+
267
+ private handleOnWsError = (err: Error, req: IncomingMessage, socket: any): void => {
268
+ this.log('error', '[AutoProxyCookie] WebSocket Proxy Error:', err.message);
269
+ this.log('error', '[AutoProxyCookie] WebSocket URL:', req.url);
270
+
271
+ if (socket) {
272
+ socket.close();
273
+ }
274
+
275
+ if (this.options.hooks.onWsError) {
276
+ try {
277
+ this.options.hooks.onWsError(err, req, socket);
278
+ } catch (hookErr) {
279
+ this.log('error', '[AutoProxyCookie] onWsError hook error:', (hookErr as Error).message);
280
+ }
281
+ }
282
+ };
283
+
284
+ async setup(server: ViteDevServer): Promise<void> {
285
+ this.server = server;
286
+ this.currentCookie = this.cookieReader.readCookie();
287
+
288
+ try {
289
+ const baseOptions: ServerOptions = {
290
+ target: this.options.target,
291
+ changeOrigin: this.options.changeOrigin,
292
+ secure: this.options.secure,
293
+ followRedirects: this.options.followRedirects,
294
+ autoRewrite: this.options.autoRewrite,
295
+ protocolRewrite: this.options.protocolRewrite,
296
+ cookieDomainRewrite: this.options.cookieDomainRewrite,
297
+ cookiePathRewrite: this.options.cookiePathRewrite,
298
+ ws: this.options.ws,
299
+ };
300
+
301
+ this.proxyServer = httpProxy.createProxyServer(baseOptions) as unknown as ProxyServer;
302
+
303
+ this.proxyServer.on('proxyReq', this.handleOnProxyReq);
304
+ this.proxyServer.on('proxyRes', this.handleOnProxyRes);
305
+ this.proxyServer.on('error', this.handleOnError);
306
+ if (this.options.ws) {
307
+ (this.proxyServer as any).on('wsError', this.handleOnWsError);
308
+ }
309
+
310
+ this.log('info', '[AutoProxyCookie] Proxy server created with WebSocket support');
311
+ } catch (err) {
312
+ this.log('warn', '[AutoProxyCookie] http-proxy create failed, using basic mode:', (err as Error).message);
313
+ }
314
+
315
+ server.middlewares.use((req: any, res: any, next: any) => {
316
+ const pathname = new URL(req.url || '/', 'http://localhost').pathname;
317
+
318
+ if (this.isIgnoredPath(pathname)) {
319
+ next();
320
+ return;
321
+ }
322
+
323
+ this.currentCookie = this.cookieReader.readCookie();
324
+
325
+ if (this.proxyServer) {
326
+ const target = this.getProxyUrl(req);
327
+ if (this.options.debug || this.options.logLevel === 'debug') {
328
+ this.log('info', `[AutoProxyCookie] ${pathname} -> ${target}`);
329
+ }
330
+
331
+ const proxyOptions = this.createProxyOptions(target);
332
+
333
+ try {
334
+ this.proxyServer.web(req, res, proxyOptions);
335
+ } catch (err: any) {
336
+ this.log('error', '[AutoProxyCookie] Proxy web error:', err.message);
337
+ next(err);
338
+ }
339
+ } else {
340
+ next();
341
+ }
342
+ });
343
+
344
+ if (this.options.ws && this.server.httpServer && this.proxyServer) {
345
+ this.server.httpServer.on('upgrade', (req: IncomingMessage, socket: any, head: Buffer) => {
346
+ const pathname = new URL(req.url || '/', 'http://localhost').pathname;
347
+
348
+ if (this.isIgnoredPath(pathname)) {
349
+ socket.destroy();
350
+ return;
351
+ }
352
+
353
+ const target = this.getProxyUrl(req);
354
+
355
+ this.proxyServer?.ws(req, socket, head, {
356
+ target,
357
+ ws: true,
358
+ changeOrigin: this.options.changeOrigin,
359
+ secure: this.options.secure,
360
+ });
361
+ });
362
+
363
+ this.log('info', '[AutoProxyCookie] WebSocket upgrade handler registered');
364
+ }
365
+
366
+ this.startFileWatch();
367
+
368
+ this.log('info', '[AutoProxyCookie] Auto-proxy middleware enabled');
369
+ this.log('info', '[AutoProxyCookie] Target:', this.options.target);
370
+ this.log('info', '[AutoProxyCookie] Cookie file:', this.options.cookieFile);
371
+ if (this.options.autoRestart) {
372
+ this.log('info', '[AutoProxyCookie] Auto-restart enabled');
373
+ }
374
+ if (this.options.ws) {
375
+ this.log('info', '[AutoProxyCookie] WebSocket support enabled');
376
+ }
377
+ }
378
+
379
+ private startFileWatch(): void {
380
+ // 判断是否应该启用监听
381
+ // isDev 参数优先级最高
382
+ let shouldWatch: boolean;
383
+
384
+ if (this.options.isDev !== undefined) {
385
+ shouldWatch = this.options.isDev;
386
+ if (this.options.debug) {
387
+ console.log(`[AutoProxyCookie] isDev=${this.options.isDev}, ${shouldWatch ? 'enabling' : 'disabling'} watch`);
388
+ }
389
+ } else {
390
+ // 默认启用监听(因为 AutoProxyCookie 主要用于开发环境)
391
+ shouldWatch = true;
392
+ if (this.options.debug) {
393
+ console.log('[AutoProxyCookie] Default behavior: enabling watch (dev mode)');
394
+ }
395
+ }
396
+
397
+ if (shouldWatch) {
398
+ this.watcher = watchCookieFile(
399
+ this.options.cookieFile,
400
+ this.handleCookieChange,
401
+ (error) => {
402
+ this.log('error', '[AutoProxyCookie] File watch error:', error.message);
403
+ }
404
+ );
405
+ } else if (this.options.debug) {
406
+ console.log('[AutoProxyCookie] File watch disabled');
407
+ }
408
+ }
409
+
410
+ stop(): void {
411
+ if (this.watcher) {
412
+ this.watcher.stop();
413
+ this.watcher = null;
414
+ }
415
+ if (this.proxyServer) {
416
+ this.proxyServer.close();
417
+ this.proxyServer = null;
418
+ }
419
+ this.log('info', '[AutoProxyCookie] Stopped');
420
+ }
421
+
422
+ getCurrentCookie(): string {
423
+ return this.currentCookie;
424
+ }
425
+ }
426
+
427
+ export function createAutoProxyCookie(options: AutoProxyCookieOptions): AutoProxyCookie {
428
+ return new AutoProxyCookie(options);
429
+ }
@@ -0,0 +1,5 @@
1
+ export * from './core';
2
+ export * from './vite-plugin';
3
+ export * from './vite-cookie-plugin';
4
+ export * from './vue-proxy-config';
5
+ export * from './vite-adapter';
@@ -0,0 +1,98 @@
1
+ import type { Plugin } from 'vite';
2
+ import { viteAutoProxyCookie, type ViteAutoProxyCookiePluginOptions } from './vite-plugin';
3
+ import { viteDevProxyCookie, type ViteDevProxyCookieOptions } from './vite-cookie-plugin';
4
+
5
+ let viteVersion: string = '';
6
+ let majorVersion: number | null = null;
7
+
8
+ function detectViteVersion(): number {
9
+ if (majorVersion !== null) {
10
+ return majorVersion;
11
+ }
12
+
13
+ try {
14
+ const pkg = require('vite/package.json');
15
+ viteVersion = pkg.version;
16
+ majorVersion = parseInt(viteVersion.split('.')[0], 10);
17
+ } catch {
18
+ majorVersion = 5;
19
+ }
20
+
21
+ return majorVersion;
22
+ }
23
+
24
+ export interface UnifiedProxyCookieOptions {
25
+ cookieFile: string;
26
+ target?: string;
27
+ debug?: boolean;
28
+ autoRestart?: boolean;
29
+ restartMarkerFile?: string;
30
+ proxyMap?: Record<string, string>;
31
+ ignorePaths?: string[];
32
+ includePaths?: string[];
33
+ onCookieChange?: (cookie: string) => void;
34
+ mode?: 'auto' | 'proxy' | 'cookie';
35
+ /**
36
+ * 是否监听文件变化
37
+ * - true: 始终监听
38
+ * - false: 从不监听
39
+ * - 'auto': 根据环境自动判断(默认)
40
+ * @default 'auto'
41
+ */
42
+ watch?: boolean | 'auto';
43
+ /**
44
+ * 是否为开发环境(优先级最高)
45
+ * 设置此参数后,将直接决定是否启用文件监听:
46
+ * - true: 启用监听(开发模式)
47
+ * - false: 禁用监听(生产模式)
48
+ *
49
+ * 使用示例: isDev: process.env.NODE_ENV === 'development'
50
+ */
51
+ isDev?: boolean;
52
+ }
53
+
54
+ export function createDevProxyCookie(options: UnifiedProxyCookieOptions): Plugin {
55
+ const {
56
+ mode = 'auto',
57
+ watch = 'auto',
58
+ isDev,
59
+ ...restOptions
60
+ } = options;
61
+
62
+ const version = detectViteVersion();
63
+
64
+ if (options.debug) {
65
+ console.log(`[dev-proxy-cookie] Detected Vite ${version}.x`);
66
+ }
67
+
68
+ if (mode === 'cookie' || (mode === 'auto' && !options.target)) {
69
+ return viteDevProxyCookie({
70
+ cookieFile: options.cookieFile,
71
+ debug: options.debug,
72
+ onCookieChange: options.onCookieChange,
73
+ watch,
74
+ isDev,
75
+ });
76
+ }
77
+
78
+ const pluginOptions: ViteAutoProxyCookiePluginOptions = {
79
+ cookieFile: options.cookieFile,
80
+ target: options.target!,
81
+ debug: options.debug,
82
+ autoRestart: options.autoRestart ?? true,
83
+ restartMarkerFile: options.restartMarkerFile,
84
+ proxyMap: options.proxyMap,
85
+ ignorePaths: options.ignorePaths,
86
+ };
87
+
88
+ return viteAutoProxyCookie(pluginOptions);
89
+ }
90
+
91
+ export function getViteVersion(): string | null {
92
+ detectViteVersion();
93
+ return viteVersion;
94
+ }
95
+
96
+ export function getViteMajorVersion(): number {
97
+ return detectViteVersion();
98
+ }