-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvite.config.ts
More file actions
123 lines (113 loc) · 3.25 KB
/
vite.config.ts
File metadata and controls
123 lines (113 loc) · 3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import tailwindcss from '@tailwindcss/vite';
import { defineConfig } from 'vitest/config';
import { sveltekit } from '@sveltejs/kit/vite';
import type { Plugin } from 'vite';
import type { IncomingMessage, ServerResponse } from 'node:http';
const PROXY_PATH = '/__rpc_proxy__';
function readRequestBody(req: IncomingMessage): Promise<Buffer> {
return new Promise((resolve, reject) => {
const chunks: Buffer[] = [];
req.on('data', (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
req.on('end', () => resolve(Buffer.concat(chunks)));
req.on('error', reject);
});
}
function createRpcProxyMiddleware() {
return async (req: IncomingMessage, res: ServerResponse, next: () => void) => {
if (!req.url || !req.url.startsWith(PROXY_PATH)) {
next();
return;
}
const parsedUrl = new URL(req.url, 'http://localhost');
const target = parsedUrl.searchParams.get('target');
if (!target || (!target.startsWith('http://') && !target.startsWith('https://'))) {
res.statusCode = 400;
res.end('invalid rpc target');
return;
}
try {
const body = await readRequestBody(req);
const headers = new Headers();
for (const [key, value] of Object.entries(req.headers)) {
if (
value === undefined ||
key === 'host' ||
key === 'content-length' ||
key === 'accept-encoding'
) {
continue;
}
if (Array.isArray(value)) {
for (const v of value) headers.append(key, v);
} else {
headers.set(key, value);
}
}
const upstream = await fetch(target, {
method: req.method ?? 'POST',
headers,
body:
req.method === 'GET' || req.method === 'HEAD' || body.byteLength === 0
? undefined
: new Uint8Array(body)
});
res.statusCode = upstream.status;
const responseBody = Buffer.from(await upstream.arrayBuffer());
upstream.headers.forEach((value, key) => {
if (key === 'transfer-encoding' || key === 'content-encoding' || key === 'content-length') {
return;
}
res.setHeader(key, value);
});
res.setHeader('content-length', responseBody.byteLength.toString());
res.end(responseBody);
} catch (error) {
res.statusCode = 502;
res.end(error instanceof Error ? error.message : 'proxy failed');
}
};
}
function devRpcProxyPlugin(): Plugin {
const middleware = createRpcProxyMiddleware();
return {
name: 'dev-rpc-proxy',
configureServer(server) {
server.middlewares.use(middleware);
},
configurePreviewServer(server) {
server.middlewares.use(middleware);
}
};
}
export default defineConfig({
plugins: [tailwindcss(), devRpcProxyPlugin(), sveltekit()],
test: {
expect: { requireAssertions: true },
projects: [
{
extends: './vite.config.ts',
test: {
name: 'client',
environment: 'browser',
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }]
},
include: ['src/**/*.svelte.{test,spec}.{js,ts}'],
exclude: ['src/lib/server/**'],
setupFiles: ['./vitest-setup-client.ts']
}
},
{
extends: './vite.config.ts',
test: {
name: 'server',
environment: 'node',
include: ['src/**/*.{test,spec}.{js,ts}', 'tests/**/*.{test,spec}.{js,ts}'],
exclude: ['src/**/*.svelte.{test,spec}.{js,ts}']
}
}
]
}
});