-
Notifications
You must be signed in to change notification settings - Fork 43
Expand file tree
/
Copy pathvite.config.ts
More file actions
182 lines (174 loc) · 7.23 KB
/
Copy pathvite.config.ts
File metadata and controls
182 lines (174 loc) · 7.23 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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
import { defineConfig, loadEnv } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
import { nodePolyfills } from 'vite-plugin-node-polyfills'
import fs from 'fs';
import path from 'path';
// https://vite.dev/config/
export default defineConfig(({ mode }) => {
// Load env file based on `mode` (development, production, etc.)
const env = loadEnv(mode, process.cwd(), '');
// SSL certificate path from .env (optional - leave empty to disable HTTPS)
const sslCertPath = env.SSL_CERT_PATH || '';
// Check if SSL certificates exist (only if path is configured)
const sslEnabled = sslCertPath &&
fs.existsSync(path.join(sslCertPath, 'fullchain.pem')) &&
fs.existsSync(path.join(sslCertPath, 'privkey.pem'));
// HMR host from .env (optional - for remote development)
const hmrHost = env.HMR_HOST || '';
// Paths served by the dev proxy (see server.proxy below). These MUST bypass
// the SPA HTML fallback — a proxied URL without a "." (e.g.
// /coingecko/simple/price?ids=bitcoin) would otherwise be rewritten to
// index.html and never reach the proxy (the SDK then gets HTML, not JSON).
const proxyPaths = ['/rpc', '/dev-rpc', '/coingecko', '/wallet-api', '/local-agg', '/sgw'];
// wallet-api backend + LOCAL dev-stack aggregator (docker-compose.dev.yml
// in the wallet-api repo). Neither serves CORS headers, so the browser app
// reaches them through this same-origin proxy in dev/preview (set
// VITE_WALLET_API_URL=/wallet-api etc.); production deployments must solve
// CORS/edge routing on the backend side.
const localStackProxy = {
'/wallet-api': {
target: env.WALLET_API_PROXY_TARGET || 'http://127.0.0.1:3000',
changeOrigin: true,
ws: true, // the SDK's wake socket (/v1/ws) rides the same base URL
rewrite: (p: string) => p.replace(/^\/wallet-api/, ''),
},
'/local-agg': {
target: env.AGGREGATOR_PROXY_TARGET || 'http://127.0.0.1:3001',
changeOrigin: true,
rewrite: (p: string) => p.replace(/^\/local-agg/, ''),
},
};
// Subscription gateway (SGW): /api/paymento/* (the Paymento store endpoints)
// sends no CORS headers, so the wallet reaches it through this same-origin
// proxy in dev/preview (set VITE_SUBSCRIPTION_API_URL=/sgw, the default).
// Target is the aggregator-subscription repo's local docker-compose stack.
const sgwProxy = {
'/sgw': {
target: env.SGW_PROXY_TARGET || 'http://127.0.0.1:8080',
changeOrigin: true,
rewrite: (p: string) => p.replace(/^\/sgw/, ''),
},
};
return {
plugins: [
react(),
tailwindcss(),
nodePolyfills({
protocolImports: true,
globals: {
Buffer: 'build',
},
}),
{
name: 'html-from-src',
configureServer(server) {
// SPA fallback: rewrite HTML requests to src/index.html
// This runs before Vite's built-in middleware so it handles
// both "/" and deep routes like "/home", "/agents/dm", etc.
server.middlewares.use((req, _res, next) => {
const url = req.url || '';
// Classify by the PATH ONLY — stripping the query first. Otherwise a
// route whose query value contains a dot (e.g.
// /agents/custom?url=boxy-run.fly.dev) is misread as a static asset
// by the `.` check below and never falls back to index.html (404).
const pathname = url.split('?')[0];
const isProxied = proxyPaths.some((p) => pathname.startsWith(p));
const isAsset = pathname.startsWith('/src/') || pathname.startsWith('/node_modules/') || pathname.startsWith('/@') || pathname.includes('.');
if (!isProxied && !isAsset) {
req.url = '/src/index.html';
}
next();
});
},
closeBundle() {
// Move index.html from dist/src/ to dist/ after build
const srcHtml = path.resolve(__dirname, 'dist/src/index.html');
const destHtml = path.resolve(__dirname, 'dist/index.html');
if (fs.existsSync(srcHtml)) {
fs.renameSync(srcHtml, destHtml);
fs.rmdirSync(path.resolve(__dirname, 'dist/src'));
}
},
},
],
base: env.BASE_PATH || '/',
server: {
// Allow Vite to serve files from the parent directory (needed for
// local file: references like "@unicitylabs/sphere-sdk": "file:../sphere-sdk")
fs: {
allow: ['.', '..'],
},
// Enable HTTPS if certificates are available
https: sslEnabled ? {
key: fs.readFileSync(path.join(sslCertPath, 'privkey.pem')),
cert: fs.readFileSync(path.join(sslCertPath, 'fullchain.pem')),
} : undefined,
// Allow external connections
host: '0.0.0.0',
// Configure HMR WebSocket - use env var for custom host, or auto-detect
hmr: hmrHost ? {
host: hmrHost,
protocol: sslEnabled ? 'wss' : 'ws',
} : true,
proxy: {
'/rpc': {
target: 'https://goggregator-test.unicity.network',
changeOrigin: true,
secure: false,
rewrite: (path) => path.replace(/^\/rpc/, ''),
},
'/dev-rpc': {
target: 'https://dev-aggregator.dyndns.org',
changeOrigin: true,
secure: false,
rewrite: (path) => path.replace(/^\/dev-rpc/, ''),
},
'/coingecko': {
target: 'https://api.coingecko.com/api/v3',
changeOrigin: true,
secure: true,
rewrite: (path) => path.replace(/^\/coingecko/, ''),
},
...localStackProxy,
...sgwProxy,
}
},
// `vite preview` (used by the Playwright smoke) needs the same
// same-origin route to the local stack as the dev server.
preview: {
proxy: { ...localStackProxy, ...sgwProxy },
},
// Ensure polyfill shims resolve correctly for symlinked file: dependencies
resolve: {
alias: {
'vite-plugin-node-polyfills/shims/buffer': path.resolve(__dirname, 'node_modules/vite-plugin-node-polyfills/shims/buffer'),
'vite-plugin-node-polyfills/shims/process': path.resolve(__dirname, 'node_modules/vite-plugin-node-polyfills/shims/process'),
'vite-plugin-node-polyfills/shims/global': path.resolve(__dirname, 'node_modules/vite-plugin-node-polyfills/shims/global'),
},
// Dedupe peer deps so file:-linked sphere-ui doesn't pull a second copy of React etc.
// through its devDependencies, which would break hooks across the module boundary.
dedupe: ['react', 'react-dom', 'framer-motion', '@dnd-kit/core', '@dnd-kit/sortable', '@dnd-kit/utilities'],
},
build: {
rollupOptions: {
input: path.resolve(__dirname, 'src/index.html'),
},
},
// Pre-bundle heavy CJS dependencies to speed up dev server cold start
optimizeDeps: {
include: [
'elliptic',
'crypto-js',
'framer-motion',
'react',
'react-dom',
'react-router-dom',
'@tanstack/react-query',
],
// Force re-bundling on dev start so the file:-linked sphere-ui is freshly resolved
// against the deduped peer deps (otherwise Vite caches stale pre-bundles).
force: true,
}
};
});