@bouygues-telecom/staticjs 1.0.0 → 1.0.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/_build/helpers/cachePages.d.ts +8 -0
- package/_build/helpers/cachePages.js +46 -0
- package/_build/helpers/createPage.d.ts +2 -1
- package/_build/helpers/createPage.js +9 -2
- package/_build/helpers/renderPageRuntime.js +16 -4
- package/_build/helpers/styleDiscovery.d.ts +13 -0
- package/_build/helpers/styleDiscovery.js +61 -0
- package/_build/scripts/build-css.d.ts +5 -0
- package/_build/scripts/build-css.js +79 -0
- package/_build/scripts/build-html.js +10 -4
- package/_build/scripts/cli.js +9 -2
- package/_build/scripts/create-static-app.js +26 -26
- package/_build/server/config/index.d.ts +3 -0
- package/_build/server/config/index.js +108 -1
- package/_build/server/config/vite.config.js +18 -1
- package/_build/server/index.d.ts +1 -1
- package/_build/server/index.js +8 -3
- package/_build/server/middleware/hotReload.js +30 -22
- package/_build/server/middleware/runtime.d.ts +4 -0
- package/_build/server/middleware/runtime.js +126 -1
- package/_build/server/middleware/security.d.ts +2 -2
- package/_build/server/middleware/security.js +52 -8
- package/_build/server/routes/api.d.ts +6 -1
- package/_build/server/routes/api.js +52 -1
- package/_build/server/scripts/revalidate.js +82 -9
- package/_build/server/static/hot-reload-client.js +362 -0
- package/_build/server/utils/vite.js +23 -2
- package/package.json +9 -2
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side WebSocket hot reload script
|
|
3
|
+
* Handles WebSocket connection and different reload strategies
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
(function() {
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
// Only run in development mode
|
|
10
|
+
if (typeof window === 'undefined') {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Only run in development mode - check for development indicators
|
|
15
|
+
if (window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1') {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function HotReloadClient() {
|
|
20
|
+
this.ws = null;
|
|
21
|
+
this.reconnectAttempts = 0;
|
|
22
|
+
this.maxReconnectAttempts = 10;
|
|
23
|
+
this.reconnectDelay = 1000; // Start with 1 second
|
|
24
|
+
this.maxReconnectDelay = 30000; // Max 30 seconds
|
|
25
|
+
this.isConnected = false;
|
|
26
|
+
this.isReconnecting = false;
|
|
27
|
+
this.statusEl = null;
|
|
28
|
+
|
|
29
|
+
this.init();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
HotReloadClient.prototype.init = function() {
|
|
33
|
+
this.createStatusIndicator();
|
|
34
|
+
this.connect();
|
|
35
|
+
this.setupVisibilityHandler();
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
HotReloadClient.prototype.createStatusIndicator = function() {
|
|
39
|
+
// Create a small status indicator
|
|
40
|
+
this.statusEl = document.createElement('div');
|
|
41
|
+
this.statusEl.id = 'hot-reload-status';
|
|
42
|
+
this.statusEl.style.cssText =
|
|
43
|
+
'position: fixed;' +
|
|
44
|
+
'top: 10px;' +
|
|
45
|
+
'right: 10px;' +
|
|
46
|
+
'width: 12px;' +
|
|
47
|
+
'height: 12px;' +
|
|
48
|
+
'border-radius: 50%;' +
|
|
49
|
+
'background: #ff6b6b;' +
|
|
50
|
+
'z-index: 10000;' +
|
|
51
|
+
'transition: all 0.3s ease;' +
|
|
52
|
+
'box-shadow: 0 2px 4px rgba(0,0,0,0.2);' +
|
|
53
|
+
'opacity: 0.8;';
|
|
54
|
+
this.statusEl.title = 'Hot Reload: Disconnected';
|
|
55
|
+
document.body.appendChild(this.statusEl);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
HotReloadClient.prototype.updateStatus = function(connected, message) {
|
|
59
|
+
message = message || '';
|
|
60
|
+
if (!this.statusEl) return;
|
|
61
|
+
|
|
62
|
+
this.isConnected = connected;
|
|
63
|
+
this.statusEl.style.background = connected ? '#51cf66' : '#ff6b6b';
|
|
64
|
+
this.statusEl.title = 'Hot Reload: ' + (connected ? 'Connected' : 'Disconnected') + (message ? ' - ' + message : '');
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
HotReloadClient.prototype.connect = function() {
|
|
68
|
+
var self = this;
|
|
69
|
+
|
|
70
|
+
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
var protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
76
|
+
var wsUrl = protocol + '//' + window.location.host + '/ws';
|
|
77
|
+
|
|
78
|
+
console.log('[HotReload] Connecting to WebSocket:', wsUrl);
|
|
79
|
+
this.ws = new WebSocket(wsUrl);
|
|
80
|
+
|
|
81
|
+
this.ws.onopen = function() {
|
|
82
|
+
console.log('[HotReload] WebSocket connected');
|
|
83
|
+
self.updateStatus(true);
|
|
84
|
+
self.reconnectAttempts = 0;
|
|
85
|
+
self.reconnectDelay = 1000;
|
|
86
|
+
self.isReconnecting = false;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
this.ws.onmessage = function(event) {
|
|
90
|
+
self.handleMessage(event);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
this.ws.onclose = function(event) {
|
|
94
|
+
console.log('[HotReload] WebSocket disconnected:', event.code, event.reason);
|
|
95
|
+
self.updateStatus(false, 'Disconnected');
|
|
96
|
+
self.scheduleReconnect();
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
this.ws.onerror = function(error) {
|
|
100
|
+
console.error('[HotReload] WebSocket error:', error);
|
|
101
|
+
self.updateStatus(false, 'Error');
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.error('[HotReload] Failed to create WebSocket connection:', error);
|
|
106
|
+
this.updateStatus(false, 'Failed to connect');
|
|
107
|
+
this.scheduleReconnect();
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
HotReloadClient.prototype.handleMessage = function(event) {
|
|
112
|
+
try {
|
|
113
|
+
var message = JSON.parse(event.data);
|
|
114
|
+
|
|
115
|
+
switch (message.type) {
|
|
116
|
+
case 'connected':
|
|
117
|
+
console.log('[HotReload]', message.message);
|
|
118
|
+
break;
|
|
119
|
+
|
|
120
|
+
case 'reload':
|
|
121
|
+
this.handleReload(message);
|
|
122
|
+
break;
|
|
123
|
+
|
|
124
|
+
default:
|
|
125
|
+
console.log('[HotReload] Unknown message type:', message.type);
|
|
126
|
+
}
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.error('[HotReload] Error parsing WebSocket message:', error);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
HotReloadClient.prototype.handleReload = function(message) {
|
|
133
|
+
var reloadType = message.reloadType;
|
|
134
|
+
var data = message.data;
|
|
135
|
+
|
|
136
|
+
console.log('[HotReload] Received ' + reloadType + ' reload request:', data);
|
|
137
|
+
|
|
138
|
+
// Show reload notification
|
|
139
|
+
this.showReloadNotification(reloadType, data);
|
|
140
|
+
|
|
141
|
+
// Execute reload strategy
|
|
142
|
+
switch (reloadType) {
|
|
143
|
+
case 'style':
|
|
144
|
+
this.reloadStyles();
|
|
145
|
+
break;
|
|
146
|
+
|
|
147
|
+
case 'asset':
|
|
148
|
+
this.reloadAssets();
|
|
149
|
+
break;
|
|
150
|
+
|
|
151
|
+
case 'page':
|
|
152
|
+
this.reloadPage();
|
|
153
|
+
break;
|
|
154
|
+
|
|
155
|
+
case 'full':
|
|
156
|
+
this.fullReload();
|
|
157
|
+
break;
|
|
158
|
+
|
|
159
|
+
default:
|
|
160
|
+
this.reloadPage();
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
HotReloadClient.prototype.showReloadNotification = function(type, data) {
|
|
165
|
+
// Create temporary notification
|
|
166
|
+
var notification = document.createElement('div');
|
|
167
|
+
notification.style.cssText =
|
|
168
|
+
'position: fixed;' +
|
|
169
|
+
'top: 50px;' +
|
|
170
|
+
'right: 10px;' +
|
|
171
|
+
'background: #4c6ef5;' +
|
|
172
|
+
'color: white;' +
|
|
173
|
+
'padding: 8px 12px;' +
|
|
174
|
+
'border-radius: 4px;' +
|
|
175
|
+
'font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;' +
|
|
176
|
+
'font-size: 12px;' +
|
|
177
|
+
'z-index: 10001;' +
|
|
178
|
+
'box-shadow: 0 2px 8px rgba(0,0,0,0.2);' +
|
|
179
|
+
'opacity: 0;' +
|
|
180
|
+
'transition: opacity 0.3s ease;';
|
|
181
|
+
|
|
182
|
+
var fileName = data.file ? data.file.split('/').pop() : 'file';
|
|
183
|
+
notification.textContent = 'Reloading ' + type + ': ' + fileName;
|
|
184
|
+
|
|
185
|
+
document.body.appendChild(notification);
|
|
186
|
+
|
|
187
|
+
// Animate in
|
|
188
|
+
setTimeout(function() {
|
|
189
|
+
notification.style.opacity = '1';
|
|
190
|
+
}, 10);
|
|
191
|
+
|
|
192
|
+
// Remove after delay
|
|
193
|
+
setTimeout(function() {
|
|
194
|
+
notification.style.opacity = '0';
|
|
195
|
+
setTimeout(function() {
|
|
196
|
+
if (notification.parentNode) {
|
|
197
|
+
notification.parentNode.removeChild(notification);
|
|
198
|
+
}
|
|
199
|
+
}, 300);
|
|
200
|
+
}, 2000);
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
HotReloadClient.prototype.reloadStyles = function() {
|
|
204
|
+
// Reload all CSS links
|
|
205
|
+
var links = document.querySelectorAll('link[rel="stylesheet"]');
|
|
206
|
+
for (var i = 0; i < links.length; i++) {
|
|
207
|
+
var link = links[i];
|
|
208
|
+
var href = link.href;
|
|
209
|
+
var url = new URL(href);
|
|
210
|
+
url.searchParams.set('t', Date.now().toString());
|
|
211
|
+
link.href = url.toString();
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Reload style tags (for CSS-in-JS)
|
|
215
|
+
var styles = document.querySelectorAll('style[data-vite-dev-id]');
|
|
216
|
+
for (var j = 0; j < styles.length; j++) {
|
|
217
|
+
var style = styles[j];
|
|
218
|
+
// Trigger re-evaluation by Vite
|
|
219
|
+
var event = new CustomEvent('vite:invalidate', {
|
|
220
|
+
detail: { path: style.getAttribute('data-vite-dev-id') }
|
|
221
|
+
});
|
|
222
|
+
window.dispatchEvent(event);
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
HotReloadClient.prototype.reloadAssets = function() {
|
|
227
|
+
// Reload images and other assets
|
|
228
|
+
var images = document.querySelectorAll('img');
|
|
229
|
+
for (var i = 0; i < images.length; i++) {
|
|
230
|
+
var img = images[i];
|
|
231
|
+
var src = img.src;
|
|
232
|
+
if (src && !src.startsWith('data:')) {
|
|
233
|
+
var url = new URL(src);
|
|
234
|
+
url.searchParams.set('t', Date.now().toString());
|
|
235
|
+
img.src = url.toString();
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
HotReloadClient.prototype.reloadPage = function() {
|
|
241
|
+
console.log('[HotReload] Reloading page...');
|
|
242
|
+
|
|
243
|
+
// Before reloading, try to preserve scroll position and form data
|
|
244
|
+
var scrollPosition = {
|
|
245
|
+
x: window.scrollX || window.pageXOffset,
|
|
246
|
+
y: window.scrollY || window.pageYOffset
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
// Store scroll position in sessionStorage for restoration after reload
|
|
250
|
+
try {
|
|
251
|
+
sessionStorage.setItem('hotReloadScrollPosition', JSON.stringify(scrollPosition));
|
|
252
|
+
} catch (e) {
|
|
253
|
+
// Ignore storage errors
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Perform the reload
|
|
257
|
+
window.location.reload();
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
HotReloadClient.prototype.fullReload = function() {
|
|
261
|
+
console.log('[HotReload] Performing full reload...');
|
|
262
|
+
// Clear cache and reload
|
|
263
|
+
if ('caches' in window) {
|
|
264
|
+
caches.keys().then(function(names) {
|
|
265
|
+
for (var i = 0; i < names.length; i++) {
|
|
266
|
+
caches.delete(names[i]);
|
|
267
|
+
}
|
|
268
|
+
window.location.reload();
|
|
269
|
+
});
|
|
270
|
+
} else {
|
|
271
|
+
window.location.reload();
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
HotReloadClient.prototype.scheduleReconnect = function() {
|
|
276
|
+
var self = this;
|
|
277
|
+
|
|
278
|
+
if (this.isReconnecting || this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
279
|
+
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
280
|
+
console.log('[HotReload] Max reconnection attempts reached');
|
|
281
|
+
this.updateStatus(false, 'Max retries reached');
|
|
282
|
+
}
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
this.isReconnecting = true;
|
|
287
|
+
this.reconnectAttempts++;
|
|
288
|
+
|
|
289
|
+
console.log('[HotReload] Scheduling reconnection attempt ' + this.reconnectAttempts + ' in ' + this.reconnectDelay + 'ms');
|
|
290
|
+
this.updateStatus(false, 'Reconnecting... (' + this.reconnectAttempts + '/' + this.maxReconnectAttempts + ')');
|
|
291
|
+
|
|
292
|
+
setTimeout(function() {
|
|
293
|
+
self.connect();
|
|
294
|
+
}, this.reconnectDelay);
|
|
295
|
+
|
|
296
|
+
// Exponential backoff with jitter
|
|
297
|
+
this.reconnectDelay = Math.min(
|
|
298
|
+
this.reconnectDelay * 1.5 + Math.random() * 1000,
|
|
299
|
+
this.maxReconnectDelay
|
|
300
|
+
);
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
HotReloadClient.prototype.setupVisibilityHandler = function() {
|
|
304
|
+
var self = this;
|
|
305
|
+
|
|
306
|
+
// Reconnect when page becomes visible (handles browser sleep/wake)
|
|
307
|
+
document.addEventListener('visibilitychange', function() {
|
|
308
|
+
if (!document.hidden && !self.isConnected && !self.isReconnecting) {
|
|
309
|
+
console.log('[HotReload] Page became visible, attempting to reconnect...');
|
|
310
|
+
self.reconnectAttempts = 0;
|
|
311
|
+
self.reconnectDelay = 1000;
|
|
312
|
+
self.connect();
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
HotReloadClient.prototype.disconnect = function() {
|
|
318
|
+
if (this.ws) {
|
|
319
|
+
this.ws.close();
|
|
320
|
+
this.ws = null;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (this.statusEl && this.statusEl.parentNode) {
|
|
324
|
+
this.statusEl.parentNode.removeChild(this.statusEl);
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
// Restore scroll position after hot reload
|
|
329
|
+
function restoreScrollPosition() {
|
|
330
|
+
try {
|
|
331
|
+
var stored = sessionStorage.getItem('hotReloadScrollPosition');
|
|
332
|
+
if (stored) {
|
|
333
|
+
var position = JSON.parse(stored);
|
|
334
|
+
window.scrollTo(position.x, position.y);
|
|
335
|
+
sessionStorage.removeItem('hotReloadScrollPosition');
|
|
336
|
+
}
|
|
337
|
+
} catch (e) {
|
|
338
|
+
// Ignore restoration errors
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Initialize hot reload client when DOM is ready
|
|
343
|
+
if (document.readyState === 'loading') {
|
|
344
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
345
|
+
window.hotReloadClient = new HotReloadClient();
|
|
346
|
+
// Restore scroll position after a short delay to ensure page is fully loaded
|
|
347
|
+
setTimeout(restoreScrollPosition, 100);
|
|
348
|
+
});
|
|
349
|
+
} else {
|
|
350
|
+
window.hotReloadClient = new HotReloadClient();
|
|
351
|
+
// Restore scroll position after a short delay to ensure page is fully loaded
|
|
352
|
+
setTimeout(restoreScrollPosition, 100);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Cleanup on page unload
|
|
356
|
+
window.addEventListener('beforeunload', function() {
|
|
357
|
+
if (window.hotReloadClient) {
|
|
358
|
+
window.hotReloadClient.disconnect();
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
})();
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { createServer as createViteServer } from "vite";
|
|
6
6
|
import { isDevelopment } from "../config/index.js";
|
|
7
|
-
import { registerJavaScriptMiddleware } from "../middleware/runtime.js";
|
|
7
|
+
import { registerJavaScriptMiddleware, registerCSSMiddleware } from "../middleware/runtime.js";
|
|
8
|
+
import path from "path";
|
|
9
|
+
import { fileURLToPath } from "url";
|
|
8
10
|
let viteServer = null;
|
|
9
11
|
/**
|
|
10
12
|
* Initialize Vite server for development mode
|
|
@@ -18,6 +20,10 @@ export const initializeViteServer = async (app) => {
|
|
|
18
20
|
}
|
|
19
21
|
try {
|
|
20
22
|
// Initializing Vite server
|
|
23
|
+
// Get the absolute path to the vite config file within the package
|
|
24
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
25
|
+
const __dirname = path.dirname(__filename);
|
|
26
|
+
const configPath = path.resolve(__dirname, '../config/vite.config.js');
|
|
21
27
|
// Create Vite server for development mode JS compilation
|
|
22
28
|
viteServer = await createViteServer({
|
|
23
29
|
server: {
|
|
@@ -27,16 +33,31 @@ export const initializeViteServer = async (app) => {
|
|
|
27
33
|
}
|
|
28
34
|
},
|
|
29
35
|
appType: 'custom',
|
|
30
|
-
configFile:
|
|
36
|
+
configFile: configPath
|
|
31
37
|
});
|
|
32
38
|
// Vite server initialized
|
|
33
39
|
// Add Vite's middleware to handle dependency requests
|
|
34
40
|
app.use(viteServer.middlewares);
|
|
35
41
|
// Register JavaScript serving middleware after Vite server is ready
|
|
36
42
|
registerJavaScriptMiddleware(app, viteServer);
|
|
43
|
+
// Register CSS serving middleware after Vite server is ready
|
|
44
|
+
registerCSSMiddleware(app, viteServer);
|
|
37
45
|
}
|
|
38
46
|
catch (error) {
|
|
39
47
|
console.error('❌ Failed to initialize Vite server:', error);
|
|
48
|
+
// Check for common Node.js version compatibility issues
|
|
49
|
+
if (error instanceof TypeError && error.message.includes('crypto.hash is not a function')) {
|
|
50
|
+
console.error('');
|
|
51
|
+
console.error('🔧 This error is likely due to a Node.js version compatibility issue.');
|
|
52
|
+
console.error(' The crypto.hash() method requires Node.js 15.0.0 or higher.');
|
|
53
|
+
console.error(' Current Node.js version:', process.version);
|
|
54
|
+
console.error('');
|
|
55
|
+
console.error('💡 Solutions:');
|
|
56
|
+
console.error(' 1. Update Node.js to version 18+ (recommended)');
|
|
57
|
+
console.error(' 2. Use a compatible Vite version (5.x instead of 6.x)');
|
|
58
|
+
console.error(' 3. Check your package.json engines field');
|
|
59
|
+
console.error('');
|
|
60
|
+
}
|
|
40
61
|
}
|
|
41
62
|
}
|
|
42
63
|
return viteServer;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bouygues-telecom/staticjs",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./_build/server/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"generate-test-multiapps": "./_build/scripts/generate-test-multiapps.js"
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
|
-
"build": "rm -rf _build && tsc && chmod +x _build/scripts/*.js",
|
|
24
|
+
"build": "rm -rf _build && tsc && chmod +x _build/scripts/*.js && cp -r server/static _build/server/",
|
|
25
25
|
"dev": "npm run build && cd ../templates/react && npm run dev"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
@@ -38,8 +38,15 @@
|
|
|
38
38
|
"path": "^0.12.7",
|
|
39
39
|
"readline": "^1.3.0",
|
|
40
40
|
"rimraf": "^6.0.1",
|
|
41
|
+
"sass": "^1.77.0",
|
|
41
42
|
"ws": "^8.18.0"
|
|
42
43
|
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"vite": "^5.0.0 || ^6.0.0"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18.0.0"
|
|
49
|
+
},
|
|
43
50
|
"volta": {
|
|
44
51
|
"node": "24.1.0"
|
|
45
52
|
},
|