@voltx/server 0.4.4 → 0.4.6
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/dist/index.cjs +93 -9
- package/dist/index.d.cts +23 -2
- package/dist/index.d.ts +23 -2
- package/dist/index.js +92 -9
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -41,6 +41,7 @@ __export(index_exports, {
|
|
|
41
41
|
registerSSR: () => registerSSR,
|
|
42
42
|
registerStaticFiles: () => registerStaticFiles,
|
|
43
43
|
scanAndRegisterRoutes: () => scanAndRegisterRoutes,
|
|
44
|
+
voltxAPI: () => voltxAPI,
|
|
44
45
|
voltxRouter: () => voltxRouter
|
|
45
46
|
});
|
|
46
47
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -313,26 +314,26 @@ function createViteDevConfig(options = {}) {
|
|
|
313
314
|
// src/vite-plugin.ts
|
|
314
315
|
function voltxRouter(options = {}) {
|
|
315
316
|
const pagesDir = options.pagesDir ?? "src/pages";
|
|
316
|
-
const
|
|
317
|
-
const
|
|
317
|
+
const PUBLIC_ID = "voltx/router";
|
|
318
|
+
const LEGACY_ID = "virtual:voltx-routes";
|
|
319
|
+
const RESOLVED_ID = "\0voltx/router";
|
|
318
320
|
return {
|
|
319
321
|
name: "voltx-router",
|
|
320
322
|
enforce: "pre",
|
|
321
323
|
config() {
|
|
322
324
|
return {
|
|
323
325
|
ssr: {
|
|
324
|
-
// react-router ships CJS — force Vite to bundle its .mjs for SSR
|
|
325
326
|
noExternal: ["react-router"]
|
|
326
327
|
}
|
|
327
328
|
};
|
|
328
329
|
},
|
|
329
330
|
resolveId(id) {
|
|
330
|
-
if (id ===
|
|
331
|
-
return
|
|
331
|
+
if (id === PUBLIC_ID || id === LEGACY_ID) {
|
|
332
|
+
return RESOLVED_ID;
|
|
332
333
|
}
|
|
333
334
|
},
|
|
334
335
|
load(id) {
|
|
335
|
-
if (id ===
|
|
336
|
+
if (id === RESOLVED_ID) {
|
|
336
337
|
return `
|
|
337
338
|
import { createElement } from "react";
|
|
338
339
|
import { Routes, Route } from "react-router";
|
|
@@ -374,13 +375,95 @@ export function VoltxRoutes() {
|
|
|
374
375
|
}
|
|
375
376
|
|
|
376
377
|
export { routes };
|
|
378
|
+
|
|
379
|
+
// Navigation primitives \u2014 single import source
|
|
380
|
+
export { Link, NavLink, useNavigate, useParams, useLocation, useSearchParams } from "react-router";
|
|
377
381
|
`;
|
|
378
382
|
}
|
|
379
383
|
},
|
|
380
|
-
// HMR: when a file in src/pages/ is added/removed, invalidate the virtual module
|
|
381
384
|
handleHotUpdate({ file, server }) {
|
|
382
385
|
if (file.includes(pagesDir.replace(/\//g, "/"))) {
|
|
383
|
-
const mod = server.moduleGraph.getModuleById(
|
|
386
|
+
const mod = server.moduleGraph.getModuleById(RESOLVED_ID);
|
|
387
|
+
if (mod) {
|
|
388
|
+
server.moduleGraph.invalidateModule(mod);
|
|
389
|
+
server.ws.send({ type: "full-reload" });
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// src/vite-api-plugin.ts
|
|
397
|
+
function voltxAPI(options = {}) {
|
|
398
|
+
const apiDir = options.apiDir ?? "api";
|
|
399
|
+
const PUBLIC_ID = "voltx/api";
|
|
400
|
+
const RESOLVED_ID = "\0voltx/api";
|
|
401
|
+
return {
|
|
402
|
+
name: "voltx-api",
|
|
403
|
+
enforce: "pre",
|
|
404
|
+
resolveId(id) {
|
|
405
|
+
if (id === PUBLIC_ID) {
|
|
406
|
+
return RESOLVED_ID;
|
|
407
|
+
}
|
|
408
|
+
},
|
|
409
|
+
load(id) {
|
|
410
|
+
if (id === RESOLVED_ID) {
|
|
411
|
+
return `
|
|
412
|
+
const modules = import.meta.glob("/${apiDir}/**/*.ts", { eager: true });
|
|
413
|
+
|
|
414
|
+
const HTTP_METHODS = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"];
|
|
415
|
+
|
|
416
|
+
function fileToRoute(filePath) {
|
|
417
|
+
let route = filePath
|
|
418
|
+
.replace("/${apiDir}", "/${apiDir}")
|
|
419
|
+
.replace(/\\.ts$/, "")
|
|
420
|
+
.replace(/\\/index$/, "");
|
|
421
|
+
|
|
422
|
+
// Convert [param] -> :param
|
|
423
|
+
route = route.replace(/\\[([^\\]\\.]+)\\]/g, ":$1");
|
|
424
|
+
// Convert [...slug] -> *
|
|
425
|
+
route = route.replace(/\\[\\.\\.\\.([^\\]]+)\\]/g, "*");
|
|
426
|
+
|
|
427
|
+
if (!route || route === "/${apiDir}") route = "/${apiDir}";
|
|
428
|
+
return route;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
export function registerRoutes(app) {
|
|
432
|
+
const registered = [];
|
|
433
|
+
|
|
434
|
+
// Sort: static routes first, dynamic (:param) second, catch-all (*) last
|
|
435
|
+
const entries = Object.entries(modules).sort(([a], [b]) => {
|
|
436
|
+
const ra = fileToRoute(a);
|
|
437
|
+
const rb = fileToRoute(b);
|
|
438
|
+
const sa = ra.includes("*") ? 2 : ra.includes(":") ? 1 : 0;
|
|
439
|
+
const sb = rb.includes("*") ? 2 : rb.includes(":") ? 1 : 0;
|
|
440
|
+
if (sa !== sb) return sa - sb;
|
|
441
|
+
return ra.localeCompare(rb);
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
for (const [filePath, mod] of entries) {
|
|
445
|
+
const route = fileToRoute(filePath);
|
|
446
|
+
|
|
447
|
+
for (const method of HTTP_METHODS) {
|
|
448
|
+
const handler = mod[method];
|
|
449
|
+
if (typeof handler === "function") {
|
|
450
|
+
app.on(method, route, handler);
|
|
451
|
+
registered.push({ method, path: route });
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
return registered;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
export { modules as apiModules };
|
|
460
|
+
`;
|
|
461
|
+
}
|
|
462
|
+
},
|
|
463
|
+
// HMR: when a file in api/ is added/removed, invalidate the virtual module
|
|
464
|
+
handleHotUpdate({ file, server }) {
|
|
465
|
+
if (file.includes(`/${apiDir}/`) || file.endsWith(`/${apiDir}`)) {
|
|
466
|
+
const mod = server.moduleGraph.getModuleById(RESOLVED_ID);
|
|
384
467
|
if (mod) {
|
|
385
468
|
server.moduleGraph.invalidateModule(mod);
|
|
386
469
|
server.ws.send({ type: "full-reload" });
|
|
@@ -530,7 +613,7 @@ ${cssLinks}
|
|
|
530
613
|
}
|
|
531
614
|
|
|
532
615
|
// src/index.ts
|
|
533
|
-
var VERSION = "0.4.
|
|
616
|
+
var VERSION = "0.4.6";
|
|
534
617
|
// Annotate the CommonJS export names for ESM import in node:
|
|
535
618
|
0 && (module.exports = {
|
|
536
619
|
Hono,
|
|
@@ -544,5 +627,6 @@ var VERSION = "0.4.4";
|
|
|
544
627
|
registerSSR,
|
|
545
628
|
registerStaticFiles,
|
|
546
629
|
scanAndRegisterRoutes,
|
|
630
|
+
voltxAPI,
|
|
547
631
|
voltxRouter
|
|
548
632
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -187,6 +187,9 @@ interface VoltxRouterOptions {
|
|
|
187
187
|
* Scans `src/pages/` and generates a virtual module that maps
|
|
188
188
|
* file paths to routes — just like Next.js.
|
|
189
189
|
*
|
|
190
|
+
* Usage:
|
|
191
|
+
* import { Link, VoltxRoutes, useNavigate } from "voltx/router";
|
|
192
|
+
*
|
|
190
193
|
* Convention:
|
|
191
194
|
* src/pages/index.tsx → /
|
|
192
195
|
* src/pages/about.tsx → /about
|
|
@@ -195,6 +198,24 @@ interface VoltxRouterOptions {
|
|
|
195
198
|
*/
|
|
196
199
|
declare function voltxRouter(options?: VoltxRouterOptions): Plugin;
|
|
197
200
|
|
|
201
|
+
interface VoltxAPIOptions {
|
|
202
|
+
/** Directory to scan for API route files (default: "api") */
|
|
203
|
+
apiDir?: string;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* VoltX file-based API routing plugin for Vite.
|
|
207
|
+
*
|
|
208
|
+
* Usage in server.ts:
|
|
209
|
+
* import { registerRoutes } from "voltx/api";
|
|
210
|
+
* registerRoutes(app);
|
|
211
|
+
*
|
|
212
|
+
* Convention:
|
|
213
|
+
* api/index.ts → /api
|
|
214
|
+
* api/users.ts → /api/users
|
|
215
|
+
* api/users/[id].ts → /api/users/:id
|
|
216
|
+
*/
|
|
217
|
+
declare function voltxAPI(options?: VoltxAPIOptions): Plugin;
|
|
218
|
+
|
|
198
219
|
interface SSROptions {
|
|
199
220
|
/** Path to entry-server module (default: src/entry-server.tsx) */
|
|
200
221
|
entryServer?: string;
|
|
@@ -242,6 +263,6 @@ interface ViteDevServer {
|
|
|
242
263
|
*/
|
|
243
264
|
declare function registerSSR(app: Hono, vite: ViteDevServer | null, options?: SSROptions): void;
|
|
244
265
|
|
|
245
|
-
declare const VERSION = "0.4.
|
|
266
|
+
declare const VERSION = "0.4.6";
|
|
246
267
|
|
|
247
|
-
export { type CorsConfig, type HttpMethod, type MiddlewareHandler, type RouteEntry, type RouteHandler, type RouteModule, type SSROptions, type ServerConfig, type ServerInfo, VERSION, type ViteDevOptions, type VoltxRouterOptions, type VoltxServer, createCorsMiddleware, createErrorHandler, createLoggerMiddleware, createServer, createViteDevConfig, filePathToUrlPath, registerSSR, registerStaticFiles, scanAndRegisterRoutes, voltxRouter };
|
|
268
|
+
export { type CorsConfig, type HttpMethod, type MiddlewareHandler, type RouteEntry, type RouteHandler, type RouteModule, type SSROptions, type ServerConfig, type ServerInfo, VERSION, type ViteDevOptions, type VoltxAPIOptions, type VoltxRouterOptions, type VoltxServer, createCorsMiddleware, createErrorHandler, createLoggerMiddleware, createServer, createViteDevConfig, filePathToUrlPath, registerSSR, registerStaticFiles, scanAndRegisterRoutes, voltxAPI, voltxRouter };
|
package/dist/index.d.ts
CHANGED
|
@@ -187,6 +187,9 @@ interface VoltxRouterOptions {
|
|
|
187
187
|
* Scans `src/pages/` and generates a virtual module that maps
|
|
188
188
|
* file paths to routes — just like Next.js.
|
|
189
189
|
*
|
|
190
|
+
* Usage:
|
|
191
|
+
* import { Link, VoltxRoutes, useNavigate } from "voltx/router";
|
|
192
|
+
*
|
|
190
193
|
* Convention:
|
|
191
194
|
* src/pages/index.tsx → /
|
|
192
195
|
* src/pages/about.tsx → /about
|
|
@@ -195,6 +198,24 @@ interface VoltxRouterOptions {
|
|
|
195
198
|
*/
|
|
196
199
|
declare function voltxRouter(options?: VoltxRouterOptions): Plugin;
|
|
197
200
|
|
|
201
|
+
interface VoltxAPIOptions {
|
|
202
|
+
/** Directory to scan for API route files (default: "api") */
|
|
203
|
+
apiDir?: string;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* VoltX file-based API routing plugin for Vite.
|
|
207
|
+
*
|
|
208
|
+
* Usage in server.ts:
|
|
209
|
+
* import { registerRoutes } from "voltx/api";
|
|
210
|
+
* registerRoutes(app);
|
|
211
|
+
*
|
|
212
|
+
* Convention:
|
|
213
|
+
* api/index.ts → /api
|
|
214
|
+
* api/users.ts → /api/users
|
|
215
|
+
* api/users/[id].ts → /api/users/:id
|
|
216
|
+
*/
|
|
217
|
+
declare function voltxAPI(options?: VoltxAPIOptions): Plugin;
|
|
218
|
+
|
|
198
219
|
interface SSROptions {
|
|
199
220
|
/** Path to entry-server module (default: src/entry-server.tsx) */
|
|
200
221
|
entryServer?: string;
|
|
@@ -242,6 +263,6 @@ interface ViteDevServer {
|
|
|
242
263
|
*/
|
|
243
264
|
declare function registerSSR(app: Hono, vite: ViteDevServer | null, options?: SSROptions): void;
|
|
244
265
|
|
|
245
|
-
declare const VERSION = "0.4.
|
|
266
|
+
declare const VERSION = "0.4.6";
|
|
246
267
|
|
|
247
|
-
export { type CorsConfig, type HttpMethod, type MiddlewareHandler, type RouteEntry, type RouteHandler, type RouteModule, type SSROptions, type ServerConfig, type ServerInfo, VERSION, type ViteDevOptions, type VoltxRouterOptions, type VoltxServer, createCorsMiddleware, createErrorHandler, createLoggerMiddleware, createServer, createViteDevConfig, filePathToUrlPath, registerSSR, registerStaticFiles, scanAndRegisterRoutes, voltxRouter };
|
|
268
|
+
export { type CorsConfig, type HttpMethod, type MiddlewareHandler, type RouteEntry, type RouteHandler, type RouteModule, type SSROptions, type ServerConfig, type ServerInfo, VERSION, type ViteDevOptions, type VoltxAPIOptions, type VoltxRouterOptions, type VoltxServer, createCorsMiddleware, createErrorHandler, createLoggerMiddleware, createServer, createViteDevConfig, filePathToUrlPath, registerSSR, registerStaticFiles, scanAndRegisterRoutes, voltxAPI, voltxRouter };
|
package/dist/index.js
CHANGED
|
@@ -266,26 +266,26 @@ function createViteDevConfig(options = {}) {
|
|
|
266
266
|
// src/vite-plugin.ts
|
|
267
267
|
function voltxRouter(options = {}) {
|
|
268
268
|
const pagesDir = options.pagesDir ?? "src/pages";
|
|
269
|
-
const
|
|
270
|
-
const
|
|
269
|
+
const PUBLIC_ID = "voltx/router";
|
|
270
|
+
const LEGACY_ID = "virtual:voltx-routes";
|
|
271
|
+
const RESOLVED_ID = "\0voltx/router";
|
|
271
272
|
return {
|
|
272
273
|
name: "voltx-router",
|
|
273
274
|
enforce: "pre",
|
|
274
275
|
config() {
|
|
275
276
|
return {
|
|
276
277
|
ssr: {
|
|
277
|
-
// react-router ships CJS — force Vite to bundle its .mjs for SSR
|
|
278
278
|
noExternal: ["react-router"]
|
|
279
279
|
}
|
|
280
280
|
};
|
|
281
281
|
},
|
|
282
282
|
resolveId(id) {
|
|
283
|
-
if (id ===
|
|
284
|
-
return
|
|
283
|
+
if (id === PUBLIC_ID || id === LEGACY_ID) {
|
|
284
|
+
return RESOLVED_ID;
|
|
285
285
|
}
|
|
286
286
|
},
|
|
287
287
|
load(id) {
|
|
288
|
-
if (id ===
|
|
288
|
+
if (id === RESOLVED_ID) {
|
|
289
289
|
return `
|
|
290
290
|
import { createElement } from "react";
|
|
291
291
|
import { Routes, Route } from "react-router";
|
|
@@ -327,13 +327,95 @@ export function VoltxRoutes() {
|
|
|
327
327
|
}
|
|
328
328
|
|
|
329
329
|
export { routes };
|
|
330
|
+
|
|
331
|
+
// Navigation primitives \u2014 single import source
|
|
332
|
+
export { Link, NavLink, useNavigate, useParams, useLocation, useSearchParams } from "react-router";
|
|
330
333
|
`;
|
|
331
334
|
}
|
|
332
335
|
},
|
|
333
|
-
// HMR: when a file in src/pages/ is added/removed, invalidate the virtual module
|
|
334
336
|
handleHotUpdate({ file, server }) {
|
|
335
337
|
if (file.includes(pagesDir.replace(/\//g, "/"))) {
|
|
336
|
-
const mod = server.moduleGraph.getModuleById(
|
|
338
|
+
const mod = server.moduleGraph.getModuleById(RESOLVED_ID);
|
|
339
|
+
if (mod) {
|
|
340
|
+
server.moduleGraph.invalidateModule(mod);
|
|
341
|
+
server.ws.send({ type: "full-reload" });
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// src/vite-api-plugin.ts
|
|
349
|
+
function voltxAPI(options = {}) {
|
|
350
|
+
const apiDir = options.apiDir ?? "api";
|
|
351
|
+
const PUBLIC_ID = "voltx/api";
|
|
352
|
+
const RESOLVED_ID = "\0voltx/api";
|
|
353
|
+
return {
|
|
354
|
+
name: "voltx-api",
|
|
355
|
+
enforce: "pre",
|
|
356
|
+
resolveId(id) {
|
|
357
|
+
if (id === PUBLIC_ID) {
|
|
358
|
+
return RESOLVED_ID;
|
|
359
|
+
}
|
|
360
|
+
},
|
|
361
|
+
load(id) {
|
|
362
|
+
if (id === RESOLVED_ID) {
|
|
363
|
+
return `
|
|
364
|
+
const modules = import.meta.glob("/${apiDir}/**/*.ts", { eager: true });
|
|
365
|
+
|
|
366
|
+
const HTTP_METHODS = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"];
|
|
367
|
+
|
|
368
|
+
function fileToRoute(filePath) {
|
|
369
|
+
let route = filePath
|
|
370
|
+
.replace("/${apiDir}", "/${apiDir}")
|
|
371
|
+
.replace(/\\.ts$/, "")
|
|
372
|
+
.replace(/\\/index$/, "");
|
|
373
|
+
|
|
374
|
+
// Convert [param] -> :param
|
|
375
|
+
route = route.replace(/\\[([^\\]\\.]+)\\]/g, ":$1");
|
|
376
|
+
// Convert [...slug] -> *
|
|
377
|
+
route = route.replace(/\\[\\.\\.\\.([^\\]]+)\\]/g, "*");
|
|
378
|
+
|
|
379
|
+
if (!route || route === "/${apiDir}") route = "/${apiDir}";
|
|
380
|
+
return route;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export function registerRoutes(app) {
|
|
384
|
+
const registered = [];
|
|
385
|
+
|
|
386
|
+
// Sort: static routes first, dynamic (:param) second, catch-all (*) last
|
|
387
|
+
const entries = Object.entries(modules).sort(([a], [b]) => {
|
|
388
|
+
const ra = fileToRoute(a);
|
|
389
|
+
const rb = fileToRoute(b);
|
|
390
|
+
const sa = ra.includes("*") ? 2 : ra.includes(":") ? 1 : 0;
|
|
391
|
+
const sb = rb.includes("*") ? 2 : rb.includes(":") ? 1 : 0;
|
|
392
|
+
if (sa !== sb) return sa - sb;
|
|
393
|
+
return ra.localeCompare(rb);
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
for (const [filePath, mod] of entries) {
|
|
397
|
+
const route = fileToRoute(filePath);
|
|
398
|
+
|
|
399
|
+
for (const method of HTTP_METHODS) {
|
|
400
|
+
const handler = mod[method];
|
|
401
|
+
if (typeof handler === "function") {
|
|
402
|
+
app.on(method, route, handler);
|
|
403
|
+
registered.push({ method, path: route });
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
return registered;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
export { modules as apiModules };
|
|
412
|
+
`;
|
|
413
|
+
}
|
|
414
|
+
},
|
|
415
|
+
// HMR: when a file in api/ is added/removed, invalidate the virtual module
|
|
416
|
+
handleHotUpdate({ file, server }) {
|
|
417
|
+
if (file.includes(`/${apiDir}/`) || file.endsWith(`/${apiDir}`)) {
|
|
418
|
+
const mod = server.moduleGraph.getModuleById(RESOLVED_ID);
|
|
337
419
|
if (mod) {
|
|
338
420
|
server.moduleGraph.invalidateModule(mod);
|
|
339
421
|
server.ws.send({ type: "full-reload" });
|
|
@@ -483,7 +565,7 @@ ${cssLinks}
|
|
|
483
565
|
}
|
|
484
566
|
|
|
485
567
|
// src/index.ts
|
|
486
|
-
var VERSION = "0.4.
|
|
568
|
+
var VERSION = "0.4.6";
|
|
487
569
|
export {
|
|
488
570
|
Hono2 as Hono,
|
|
489
571
|
VERSION,
|
|
@@ -496,5 +578,6 @@ export {
|
|
|
496
578
|
registerSSR,
|
|
497
579
|
registerStaticFiles,
|
|
498
580
|
scanAndRegisterRoutes,
|
|
581
|
+
voltxAPI,
|
|
499
582
|
voltxRouter
|
|
500
583
|
};
|
package/package.json
CHANGED