@resolid/dev 0.2.0 → 0.3.0

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.
@@ -0,0 +1,86 @@
1
+ import { RouterContextProvider, ServerBuild, UNSAFE_DataWithResponseInit } from "react-router";
2
+ import { Context, Env, Hono, MiddlewareHandler } from "hono";
3
+ import { Http2Bindings, HttpBindings } from "@hono/node-server";
4
+ import { Context as Context$1 } from "@netlify/types";
5
+ import { HonoOptions } from "hono/hono-base";
6
+ import { BlankEnv } from "hono/types";
7
+ import { IncomingMessage, ServerResponse } from "http";
8
+ import { Http2ServerRequest, Http2ServerResponse } from "http2";
9
+ import { AddressInfo } from "node:net";
10
+
11
+ //#region src/http/middlewares/request-id.d.ts
12
+ declare function getRequestId(context: Readonly<RouterContextProvider> | Context): string;
13
+ //#endregion
14
+ //#region src/http/middlewares/request-origin.d.ts
15
+ declare function getRequestOrigin(context: Readonly<RouterContextProvider> | Context): string | undefined;
16
+ type RequestOriginVariables = {
17
+ requestOrigin: string | undefined;
18
+ };
19
+ declare module "hono" {
20
+ interface ContextVariableMap extends RequestOriginVariables {}
21
+ }
22
+ //#endregion
23
+ //#region src/http/middlewares/client-ip.d.ts
24
+ declare function getClientIp(context: Readonly<RouterContextProvider> | Context): string;
25
+ type ClientIpVariables = {
26
+ clientIp: string;
27
+ };
28
+ declare module "hono" {
29
+ interface ContextVariableMap extends ClientIpVariables {}
30
+ }
31
+ //#endregion
32
+ //#region src/http/utils/response.d.ts
33
+ declare function httpProblem<E>(errors: E): UNSAFE_DataWithResponseInit<{
34
+ errors: E;
35
+ }>;
36
+ declare function httpNotFound(message?: string): never;
37
+ declare function httpRedirect(url: string, cookie?: string | null, status?: number): never;
38
+ //#endregion
39
+ //#region src/http/utils/server.d.ts
40
+ interface NodeEnv {
41
+ Bindings: HttpBindings | Http2Bindings;
42
+ }
43
+ interface HonoServerBaseOptions<E extends Env = BlankEnv> {
44
+ configure?: <E extends Env = BlankEnv>(app: Hono<E>) => Promise<void> | void;
45
+ honoOptions?: HonoOptions<E>;
46
+ onShutdown?: () => Promise<void> | void;
47
+ getLoadContext?: (context: Context<E>, options: {
48
+ build: ServerBuild;
49
+ mode?: string;
50
+ }) => Promise<RouterContextProvider> | RouterContextProvider;
51
+ }
52
+ //#endregion
53
+ //#region src/http/platforms/netlify.d.ts
54
+ interface NetlifyEnv {
55
+ Bindings: {
56
+ context: Context$1;
57
+ };
58
+ }
59
+ type HonoNetlifyServerOptions = HonoServerBaseOptions<NetlifyEnv>;
60
+ type HonoNetlifyServer = (req: Request, context: Context$1) => Response | Promise<Response>;
61
+ declare function createHonoNetlifyServer(options?: HonoNetlifyServerOptions): Promise<HonoNetlifyServer>;
62
+ //#endregion
63
+ //#region src/http/platforms/vercel.d.ts
64
+ type HonoVercelServerOptions = HonoServerBaseOptions<NodeEnv>;
65
+ type HonoVercelServer = (incoming: IncomingMessage | Http2ServerRequest, outgoing: ServerResponse | Http2ServerResponse) => Promise<void>;
66
+ declare const createHonoVercelServer: (options?: HonoVercelServerOptions) => Promise<HonoVercelServer>;
67
+ //#endregion
68
+ //#region src/http/utils/request.d.ts
69
+ interface GetClientIpOptions {
70
+ proxy: boolean;
71
+ proxyCount?: number;
72
+ ipHeaders?: string;
73
+ }
74
+ //#endregion
75
+ //#region src/http/platforms/node.d.ts
76
+ type HonoNodeServerOptions = HonoServerBaseOptions<NodeEnv> & {
77
+ port?: number;
78
+ defaultLogger?: boolean;
79
+ listeningListener?: (info: AddressInfo) => void;
80
+ getClientIpOptions?: GetClientIpOptions;
81
+ };
82
+ type HonoNodeServer = Hono<NodeEnv>;
83
+ declare function createHonoNodeServer(options?: HonoNodeServerOptions): Promise<HonoNodeServer>;
84
+ declare function cacheControl(seconds: number, immutable?: boolean): MiddlewareHandler;
85
+ //#endregion
86
+ export { HonoNetlifyServer, HonoNetlifyServerOptions, HonoNodeServer, HonoNodeServerOptions, HonoVercelServer, HonoVercelServerOptions, cacheControl, createHonoNetlifyServer, createHonoNodeServer, createHonoVercelServer, getClientIp, getRequestId, getRequestOrigin, httpNotFound, httpProblem, httpRedirect };
package/dist/http.mjs ADDED
@@ -0,0 +1 @@
1
+ import{RouterContextProvider as e,createContext as t,createRequestHandler as n,data as r}from"react-router";import{handle as i}from"hono/netlify";import a,{env as o}from"node:process";import{Hono as s}from"hono";import{requestId as c}from"hono/request-id";import{handle as l}from"@hono/node-server/vercel";import{serve as u}from"@hono/node-server";import{serveStatic as d}from"@hono/node-server/serve-static";import{logger as f}from"hono/logger";import{randomBytes as p}from"node:crypto";import{networkInterfaces as m}from"node:os";const h=t();function g(t){return t instanceof e?t.get(h):t.get(`requestId`)}const _=t();function v(t){return t instanceof e?t.get(_):t.get(`requestOrigin`)}function y(e){return async(t,n)=>{t.set(`requestOrigin`,e(t)),await n()}}const b=t();function x(t){return t instanceof e?t.get(b):t.get(`clientIp`)}function S(e){return async(t,n)=>{t.set(`clientIp`,e(t)),await n()}}function C(e){return r({errors:e},422)}function w(e=`页面未找到`){throw new Response(e,{status:404})}function T(e,t=null,n=302){let r=new Headers;throw r.set(`Location`,e),t&&r.set(`Set-Cookie`,t),new Response(null,{status:n,headers:r})}async function E(t,r){let i=new s(r.honoOptions),o=await import(`virtual:react-router/server-build`);i.use(`*`,S(r.getClientIp),c({generator:r.getRequestId}),y(r.getRequestOrigin)),r.configure&&await r.configure(i),i.use(`*`,async i=>(async i=>{let a=r.getLoadContext?.(i,{build:o,mode:t}),s=(a instanceof Promise?await a:a)??new e;return s.set(b,i.get(`clientIp`)),s.set(h,i.get(`requestId`)),s.set(_,i.get(`requestOrigin`)),n(o,t)(i.req.raw,s)})(i));async function l(){r.onShutdown?.(),a.removeListener(`SIGINT`,l),a.removeListener(`SIGTERM`,l),a.exit(0)}return a.on(`SIGINT`,l),a.on(`SIGTERM`,l),i}async function D(e={}){return i(await E(o.NODE_ENV==`test`?`development`:o.NODE_ENV,{...e,getClientIp:e=>e.env.context.ip,getRequestId:e=>e.env.context.requestId,getRequestOrigin:e=>e.env.context.site.url}))}const O=async(e={})=>l(await E(o.NODE_ENV==`test`?`development`:o.NODE_ENV,{...e,getClientIp:e=>e.req.raw.headers.get(`x-real-ip`)??``,getRequestId:e=>e.req.raw.headers.get(`x-vercel-id`)??``,getRequestOrigin:()=>`https://${o.VERCEL_PROJECT_PRODUCTION_URL}`}));function k(e,t,n){let{proxy:r=!1,proxyCount:i=0,ipHeaders:a=`x-forwarded-for`}=n||{},o=e.headers.get(a),s=r&&o?o.split(/\s*,\s*/):[];return i>0&&(s=s.slice(-i)),s[0]||t.remoteAddress||``}function A(e,t,n=!1){return`${t.encrypted?`https`:(n?e.headers.get(`x-forwarded-proto`):null)?.split(/\s*,\s*/)[0]??`http`}://${(n?e.headers.get(`x-forwarded-host`):null)?.split(/\s*,\s*/)[0]??e.headers.get(`host`)}`}async function j(e={}){let t=o.NODE_ENV==`test`?`development`:o.NODE_ENV,n=t==`production`,r={port:Number(o.PORT)||3e3,listeningListener:e=>{console.log(`🚀 Server started on port ${e.port}`);let t=Object.values(m()).flat().find(e=>String(e?.family).includes(`4`)&&!e?.internal)?.address,n=o.SERVE_PATH?o.SERVE_PATH:``;console.log(`[resolid] http://localhost:${e.port}${n}${t&&` (http://${t}:${e.port})`}`)},...e,defaultLogger:e.defaultLogger??!n},i=null,a=await E(t,{configure:async e=>{if(n){let t=`${import.meta.env.RESOLID_BUILD_DIR}/client`;e.use(`/${import.meta.env.RESOLID_ASSETS_DIR}/*`,M(3600*24*365,!0),d({root:t})),e.use(`*`,M(3600),d({root:t}))}else e.use(`*`,M(3600),d({root:`./public`}));r.defaultLogger&&e.use(`*`,f()),await r.configure?.(e)},honoOptions:r.honoOptions,getLoadContext:r.getLoadContext,onShutdown:async()=>{i?.close(),r.onShutdown?.()},getClientIp:e=>k(e.req.raw,e.env.incoming.socket,r.getClientIpOptions),getRequestId:()=>p(16).toString(`hex`),getRequestOrigin:e=>A(e.req.raw,e.env.incoming.socket,r.getClientIpOptions?.proxy)});return n&&(i=u({...a,port:r.port},r.listeningListener)),a}function M(e,t=!1){return async(n,r)=>{if(!n.req.path.match(/\.[a-zA-Z0-9]+$/)||n.req.path.endsWith(`.data`))return r();await r(),n.res.ok&&n.header(`Cache-Control`,`public, max-age=${e}${t?`, immutable`:``}`)}}export{M as cacheControl,D as createHonoNetlifyServer,j as createHonoNodeServer,O as createHonoVercelServer,x as getClientIp,g as getRequestId,v as getRequestOrigin,w as httpNotFound,C as httpProblem,T as httpRedirect};
@@ -1,7 +1,10 @@
1
- import { n as ServerPlatform, t as NodeVersion } from "./index-BMC9vh2X.mjs";
2
- import { Simplify } from "@resolid/utils";
3
1
  import { Config } from "@react-router/dev/config";
2
+ import { Simplify } from "@resolid/utils";
4
3
 
4
+ //#region src/types/index.d.ts
5
+ type NodeVersion = 22 | 24;
6
+ type ServerPlatform = "vercel" | "netlify" | "node";
7
+ //#endregion
5
8
  //#region src/config/index.d.ts
6
9
  interface VitePluginOptions {
7
10
  platform: ServerPlatform;
package/dist/index.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as defineDevConfig, i as VitePluginOptions, n as DevConfigOptions, r as ReactRouterConfig, t as DevConfig } from "./index-BMs3Y706.mjs";
1
+ import { a as defineDevConfig, i as VitePluginOptions, n as DevConfigOptions, r as ReactRouterConfig, t as DevConfig } from "./index-CyAg_-Yx.mjs";
2
2
  export { DevConfig, DevConfigOptions, ReactRouterConfig, VitePluginOptions, defineDevConfig };
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
- import{cp as e,mkdir as t,readFile as n,readdir as r,realpath as i,rm as a,stat as o,symlink as s,writeFile as c}from"node:fs/promises";import{basename as l,dirname as u,join as d,relative as f}from"node:path";import p from"fast-glob";import{existsSync as m}from"node:fs";import{build as h}from"rolldown";import{esmExternalRequirePlugin as g}from"rolldown/plugins";import{searchForWorkspaceRoot as _}from"vite";var v=`@resolid/dev`,y=`0.2.0`;async function b({includeFiles:t=[],nodeVersion:r=22,buildManifest:i,reactRouterConfig:o,viteConfig:s,buildStart:c,buildBundleEnd:l}){let m=s.root,_=s.build.assetsDir??`assets`,v=JSON.parse(await n(d(m,`package.json`),`utf8`)),y=x(v.dependencies??{},s.ssr.external),b=d(o.buildDirectory,`server`),C=i?.serverBundles??{site:{id:`site`,file:f(m,d(b,o.serverBuildFile))}},w=t?.length>0?await p(t,{cwd:m}):[],T=await c();await Promise.all(Object.entries(C).map(async([,t])=>{let n=t.id,i=d(m,t.file),o=u(i);await S(d(o,`package.json`),v,y,r),console.log(`Bundle file for ${n}...`);let s=d(o,`server.mjs`);await h({input:i,output:{file:s,codeSplitting:!1,minify:`dce-only`,comments:{legal:!1}},platform:`node`,transform:{define:{"process.env.NODE_ENV":JSON.stringify(`production`),"import.meta.env.NODE_ENV":JSON.stringify(`production`)},target:`node${r}`},external:[`vite`,...Object.keys(y)],plugins:[g({external:[`vite`,...Object.keys(y)],skipDuplicateCheck:!0})]}),await a(d(o,_),{force:!0,recursive:!0}),await a(i,{force:!0}),await Promise.all(w.map(t=>e(t,d(b,t),{recursive:!0}))),await l?.(T,o,n,s,y)}))}function x(e,t){let n=Array.isArray(t)?t.filter(e=>![`react-router`,`react-router-dom`,`@react-router/architect`,`@react-router/cloudflare`,`@react-router/dev`,`@react-router/express`,`@react-router/node`,`@react-router/serve`].includes(e)):t;return Object.keys(e).filter(e=>n===void 0?!1:n===!0?!0:n.includes(e)).reduce((t,n)=>(t[n]=e[n]??``,t),{})}async function S(e,t,n,r){let i={name:t.name,type:t.type,version:t.version,scripts:{postinstall:t.scripts?.postinstall??``},dependencies:n,engines:{node:`${r}.x`}};await c(e,JSON.stringify(i,null,2),`utf8`)}async function C(e,n=!1){let r=d(...e);return n&&await a(r,{recursive:!0,force:!0}),await t(r,{recursive:!0}),r}function w(e){if(e?.routeIdToServerBundleId){let t=Object.values(e.routes).filter(e=>e.id!=`root`).map(t=>{let n=[...T(e.routes,t.parentId),t.path].join(`/`);return{id:t.id,path:`/${n}`}}),n={};for(let[r,i]of Object.entries(e?.routeIdToServerBundleId)){n[i]||(n[i]=[]);for(let e of t)e.id==r&&n[i].push(e.path)}let r={};for(let[e,t]of Object.entries(n)){t.sort((e,t)=>e.length<t.length?-1:1);for(let n of t)!r[n]&&!Object.keys(r).find(t=>r[t].bundleId==e&&n.startsWith(r[t].path))&&(r[n]={path:n,bundleId:e})}let i=Object.values(r).map(e=>({path:e.path.endsWith(`/`)?e.path.slice(0,-1):e.path,bundleId:e.bundleId}));return i.sort((e,t)=>e.path.length>t.path.length?-1:1),i}return[{path:``,bundleId:`site`}]}function T(e,t){if(t==null)return[];let n=[],r=t=>{let i=e[t];i.parentId&&r(i.parentId),i.path&&n.push(i.path)};return r(t),n}async function E(n,a,c){let p=_(n),{nodeFileTrace:h}=await import(`@vercel/nft`),g=await h([n],{base:p,cache:c}),v=Array.from(g.fileList).map(e=>d(p,e)),y=u(v[0]);for(let e of v.slice(1))for(;!e.startsWith(y);)y=u(y);return await Promise.all(v.map(async c=>{let p=d(a,f(y,c)),h=await i(c),g=h!==c,_=(await o(c)).isDirectory();if(await t(u(p),{recursive:!0}),c==n){let t=u(n),i=u(p);await Promise.all((await r(t)).filter(e=>e!==l(n)).map(n=>e(d(t,n),d(i,n),{recursive:!0})))}g?m(p)||await s(f(u(p),d(a,f(y,h))),p,_?`dir`:`file`):_||await e(c,p)})),f(y,n)}const D=e=>{let{nodeVersion:t}=e;return{name:`@resolid/react-router-hono-netlify-preset`,reactRouterConfig:()=>({buildEnd:async({buildManifest:n,reactRouterConfig:r,viteConfig:i})=>{await b({includeFiles:e.includeFiles,nodeVersion:t,buildManifest:n,reactRouterConfig:r,viteConfig:i,buildStart:async()=>{let e=await C([i.root,`.netlify`,`v1`],!0);return await O(i.build.assetsDir??`assets`,d(e,`config.json`)),{netlifyRoot:e,netlifyFunctionDir:await C([e,`functions`]),serverRoutes:w(n),nftCache:{}}},buildBundleEnd:async(e,n,r,i)=>{console.log(`Coping Netlify function files for ${r}...`);let a=await E(i,await C([e.netlifyFunctionDir,r],!0),e.nftCache),o=e.serverRoutes.find(e=>e.bundleId==r)?.path,s=o?[o,`${o}/*`]:`/*`;await c(d(e.netlifyFunctionDir,`${r}.mjs`),`export { default } from "./${d(r,a)}";
1
+ import{cp as e,mkdir as t,readFile as n,readdir as r,realpath as i,rm as a,stat as o,symlink as s,writeFile as c}from"node:fs/promises";import{basename as l,dirname as u,join as d,relative as f}from"node:path";import p from"fast-glob";import{existsSync as m}from"node:fs";import{build as h}from"rolldown";import{esmExternalRequirePlugin as g}from"rolldown/plugins";import{searchForWorkspaceRoot as _}from"vite";var v=`@resolid/dev`,y=`0.3.0`;async function b({includeFiles:t=[],nodeVersion:r=22,buildManifest:i,reactRouterConfig:o,viteConfig:s,buildStart:c,buildBundleEnd:l}){let m=s.root,_=s.build.assetsDir??`assets`,v=JSON.parse(await n(d(m,`package.json`),`utf8`)),y=x(v.dependencies??{},s.ssr.external),b=d(o.buildDirectory,`server`),C=i?.serverBundles??{site:{id:`site`,file:f(m,d(b,o.serverBuildFile))}},w=t?.length>0?await p(t,{cwd:m}):[],T=await c();await Promise.all(Object.entries(C).map(async([,t])=>{let n=t.id,i=d(m,t.file),o=u(i);await S(d(o,`package.json`),v,y,r),console.log(`Bundle file for ${n}...`);let s=d(o,`server.mjs`);await h({input:i,output:{file:s,codeSplitting:!1,minify:`dce-only`,comments:{legal:!1}},platform:`node`,transform:{define:{"process.env.NODE_ENV":JSON.stringify(`production`),"import.meta.env.NODE_ENV":JSON.stringify(`production`)},target:`node${r}`},external:[`vite`,...Object.keys(y)],plugins:[g({external:[`vite`,...Object.keys(y)],skipDuplicateCheck:!0})]}),await a(d(o,_),{force:!0,recursive:!0}),await a(i,{force:!0}),await Promise.all(w.map(t=>e(t,d(b,t),{recursive:!0}))),await l?.(T,o,n,s,y)}))}function x(e,t){let n=Array.isArray(t)?t.filter(e=>![`react-router`,`react-router-dom`,`@react-router/architect`,`@react-router/cloudflare`,`@react-router/dev`,`@react-router/express`,`@react-router/node`,`@react-router/serve`].includes(e)):t;return Object.keys(e).filter(e=>n===void 0?!1:n===!0?!0:n.includes(e)).reduce((t,n)=>(t[n]=e[n]??``,t),{})}async function S(e,t,n,r){let i={name:t.name,type:t.type,version:t.version,scripts:{postinstall:t.scripts?.postinstall??``},dependencies:n,engines:{node:`${r}.x`}};await c(e,JSON.stringify(i,null,2),`utf8`)}async function C(e,n=!1){let r=d(...e);return n&&await a(r,{recursive:!0,force:!0}),await t(r,{recursive:!0}),r}function w(e){if(e?.routeIdToServerBundleId){let t=Object.values(e.routes).filter(e=>e.id!=`root`).map(t=>{let n=[...T(e.routes,t.parentId),t.path].join(`/`);return{id:t.id,path:`/${n}`}}),n={};for(let[r,i]of Object.entries(e?.routeIdToServerBundleId)){n[i]||(n[i]=[]);for(let e of t)e.id==r&&n[i].push(e.path)}let r={};for(let[e,t]of Object.entries(n)){t.sort((e,t)=>e.length<t.length?-1:1);for(let n of t)!r[n]&&!Object.keys(r).find(t=>r[t].bundleId==e&&n.startsWith(r[t].path))&&(r[n]={path:n,bundleId:e})}let i=Object.values(r).map(e=>({path:e.path.endsWith(`/`)?e.path.slice(0,-1):e.path,bundleId:e.bundleId}));return i.sort((e,t)=>e.path.length>t.path.length?-1:1),i}return[{path:``,bundleId:`site`}]}function T(e,t){if(t==null)return[];let n=[],r=t=>{let i=e[t];i.parentId&&r(i.parentId),i.path&&n.push(i.path)};return r(t),n}async function E(n,a,c){let p=_(n),{nodeFileTrace:h}=await import(`@vercel/nft`),g=await h([n],{base:p,cache:c}),v=Array.from(g.fileList).map(e=>d(p,e)),y=u(v[0]);for(let e of v.slice(1))for(;!e.startsWith(y);)y=u(y);return await Promise.all(v.map(async c=>{let p=d(a,f(y,c)),h=await i(c),g=h!==c,_=(await o(c)).isDirectory();if(await t(u(p),{recursive:!0}),c==n){let t=u(n),i=u(p);await Promise.all((await r(t)).filter(e=>e!==l(n)).map(n=>e(d(t,n),d(i,n),{recursive:!0})))}g?m(p)||await s(f(u(p),d(a,f(y,h))),p,_?`dir`:`file`):_||await e(c,p)})),f(y,n)}const D=({nodeVersion:e,includeFiles:t})=>({name:`@resolid/react-router-hono-netlify-preset`,reactRouterConfig:()=>({buildEnd:async({buildManifest:n,reactRouterConfig:r,viteConfig:i})=>{await b({includeFiles:t,nodeVersion:e,buildManifest:n,reactRouterConfig:r,viteConfig:i,buildStart:async()=>{let e=await C([i.root,`.netlify`,`v1`],!0);return await O(i.build.assetsDir??`assets`,d(e,`config.json`)),{netlifyRoot:e,netlifyFunctionDir:await C([e,`functions`]),serverRoutes:w(n),nftCache:{}}},buildBundleEnd:async(t,n,r,i)=>{console.log(`Coping Netlify function files for ${r}...`);let a=await E(i,await C([t.netlifyFunctionDir,r],!0),t.nftCache),o=t.serverRoutes.find(e=>e.bundleId==r)?.path,s=o?[o,`${o}/*`]:`/*`;await c(d(t.netlifyFunctionDir,`${r}.mjs`),`export { default } from "./${d(r,a)}";
2
2
 
3
3
  export const config = {
4
4
  path: ${Array.isArray(s)?JSON.stringify(s):`"${s}"`},
5
5
  displayName: "${r} server",
6
6
  generator: "${v}@${y}",
7
7
  preferStatic: true,
8
- nodeVersion: ${t}
8
+ nodeVersion: ${e}
9
9
  };
10
- `,`utf8`)}})}})}},O=async(e,t)=>{console.log(`Writing Netlify config file...`);let n={headers:[]};n.headers.push({for:`^/${e}/.*`,values:{"Cache-Control":`public, max-age=31536000, immutable`}}),await c(t,JSON.stringify(n,null,2),`utf8`)},k=e=>{let{nodeVersion:t}=e;return{name:`@resolid/react-router-hono-node-preset`,reactRouterConfig:()=>({buildEnd:async({buildManifest:n,reactRouterConfig:r,viteConfig:i})=>{await b({includeFiles:e.includeFiles,nodeVersion:t,buildManifest:n,reactRouterConfig:r,viteConfig:i,buildStart:async()=>{console.log(`Bundle Node Server for production...`)}})}})}},A=e=>{let{nodeVersion:t}=e;return{name:`@resolid/react-router-hono-vercel-preset`,reactRouterConfig:()=>({buildEnd:async({buildManifest:n,reactRouterConfig:r,viteConfig:i})=>{await b({includeFiles:e.includeFiles,nodeVersion:t,buildManifest:n,reactRouterConfig:r,viteConfig:i,buildStart:async()=>{let e=await C([i.root,`.vercel`,`output`],!0);return await j(d(r.buildDirectory,`client`),e),await M(i.build.assetsDir??`assets`,n,d(e,`config.json`)),{vercelOutput:e,nftCache:{}}},buildBundleEnd:async(e,n,r,i)=>{console.log(`Coping Vercel function files for ${r}...`);let a=await C([e.vercelOutput,`functions`,`_${r}.func`],!0),o=await E(i,a,e.nftCache);await c(d(a,`.vc-config.json`),JSON.stringify({handler:o,runtime:`nodejs${t}.x`,launcherType:`Nodejs`,supportsResponseStreaming:!0},null,2),`utf8`)}})}})}},j=async(t,n)=>{console.log(`Copying assets...`);let r=await C([n,`static`]);await e(t,r,{recursive:!0,force:!0}),await a(d(r,`.vite`),{recursive:!0,force:!0})},M=async(e,t,n)=>{console.log(`Writing Vercel config file...`);let r={version:3,routes:[],framework:{slug:`vite`}};r.routes.push({src:`^/${e}/.*`,headers:{"Cache-Control":`public, max-age=31536000, immutable`},continue:!0}),r.routes.push({handle:`filesystem`});let i=w(t);for(let e of i)e.path.length>0?r.routes.push({src:`^${e.path}(?:/.*)?$`,dest:`_${e.bundleId}`}):r.routes.push({src:`^/.*$`,dest:`_${e.bundleId}`});await c(n,JSON.stringify(r,null,2),`utf8`)},N=({platform:e=`node`,nodeVersion:t=22,entryFile:n=`server.ts`,appDirectory:r=`src`,includeFiles:i=[],reactRouterConfig:a={},devExclude:o})=>{let s=(e==`netlify`?D:e==`vercel`?A:k)({nodeVersion:t,includeFiles:i}),{future:c,presets:l,...u}=a;return{vitePluginOptions:{platform:e,nodeVersion:t,entryFile:n,devExclude:o},reactRouterConfig:{...u,appDirectory:r,ssr:!0,serverModuleFormat:`esm`,presets:l?[...l,s]:[s],future:{v8_middleware:!0,v8_splitRouteModules:!0,v8_viteEnvironmentApi:!0,...c}}}};export{N as defineDevConfig};
10
+ `,`utf8`)}})}})}),O=async(e,t)=>{console.log(`Writing Netlify config file...`);let n={headers:[]};n.headers.push({for:`^/${e}/.*`,values:{"Cache-Control":`public, max-age=31536000, immutable`}}),await c(t,JSON.stringify(n,null,2),`utf8`)},k=({nodeVersion:e,includeFiles:t})=>({name:`@resolid/react-router-hono-node-preset`,reactRouterConfig:()=>({buildEnd:async({buildManifest:n,reactRouterConfig:r,viteConfig:i})=>{await b({includeFiles:t,nodeVersion:e,buildManifest:n,reactRouterConfig:r,viteConfig:i,buildStart:async()=>{console.log(`Bundle Node Server for production...`)}})}})}),A=({nodeVersion:e,includeFiles:t})=>({name:`@resolid/react-router-hono-vercel-preset`,reactRouterConfig:()=>({buildEnd:async({buildManifest:n,reactRouterConfig:r,viteConfig:i})=>{await b({includeFiles:t,nodeVersion:e,buildManifest:n,reactRouterConfig:r,viteConfig:i,buildStart:async()=>{let e=await C([i.root,`.vercel`,`output`],!0);return await j(d(r.buildDirectory,`client`),e),await M(i.build.assetsDir??`assets`,n,d(e,`config.json`)),{vercelOutput:e,nftCache:{}}},buildBundleEnd:async(t,n,r,i)=>{console.log(`Coping Vercel function files for ${r}...`);let a=await C([t.vercelOutput,`functions`,`_${r}.func`],!0),o=await E(i,a,t.nftCache);await c(d(a,`.vc-config.json`),JSON.stringify({handler:o,runtime:`nodejs${e}.x`,launcherType:`Nodejs`,supportsResponseStreaming:!0},null,2),`utf8`)}})}})}),j=async(t,n)=>{console.log(`Copying assets...`);let r=await C([n,`static`]);await e(t,r,{recursive:!0,force:!0}),await a(d(r,`.vite`),{recursive:!0,force:!0})},M=async(e,t,n)=>{console.log(`Writing Vercel config file...`);let r={version:3,routes:[],framework:{slug:`vite`}};r.routes.push({src:`^/${e}/.*`,headers:{"Cache-Control":`public, max-age=31536000, immutable`},continue:!0}),r.routes.push({handle:`filesystem`});let i=w(t);for(let e of i)e.path.length>0?r.routes.push({src:`^${e.path}(?:/.*)?$`,dest:`_${e.bundleId}`}):r.routes.push({src:`^/.*$`,dest:`_${e.bundleId}`});await c(n,JSON.stringify(r,null,2),`utf8`)},N=({platform:e=`node`,nodeVersion:t=22,entryFile:n=`server.ts`,appDirectory:r=`src`,includeFiles:i=[],reactRouterConfig:a={},devExclude:o})=>{let s=(e==`netlify`?D:e==`vercel`?A:k)({nodeVersion:t,includeFiles:i}),{future:c,presets:l,...u}=a;return{vitePluginOptions:{platform:e,nodeVersion:t,entryFile:n,devExclude:o},reactRouterConfig:{...u,appDirectory:r,ssr:!0,serverModuleFormat:`esm`,presets:l?[...l,s]:[s],future:{...c,v8_middleware:!0,v8_splitRouteModules:!0,v8_viteEnvironmentApi:!0}}}};export{N as defineDevConfig};
package/dist/routes.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import{readdir as e}from"node:fs/promises";import{extname as t,join as n,relative as r,resolve as i,win32 as a}from"node:path";import{getAppDirectory as o,index as s,layout as c,route as l}from"@react-router/dev/routes";import{makeRe as u}from"minimatch";function d(e){let t=o();return{route:(n,a,...o)=>l(n,r(t,i(e,a)),...o),index:(n,...a)=>s(r(t,i(e,n)),...a),layout:(n,...a)=>c(r(t,i(e,n)),...a)}}async function f(t,i,a=t){for(let o of await e(t,{withFileTypes:!0,encoding:`utf8`})){let e=n(t,o.name);o.isDirectory()?await f(e,i,a):o.isFile()&&i(r(a,e))}}function p(e,t=`root`){let n={};for(let t in e){let r=e[t];n[t]={id:r.id,file:r.file,path:r.path,index:r.index,caseSensitive:r.caseSensitive}}let r=[];for(let i in n){let a=n[i],{parentId:o}=e[a.id];if(o===t)r.push(a);else{let e=o&&n[o];e&&(e.children=e.children||[],e.children.push(a))}}return r}function m(e,r){let i={},a=new Map,o=new Map;for(let i of r){let r=y(n(e,i)),s=r.slice(0,-t(r).length),c=s.slice(-7)==`_layout`?s.slice(0,-8):s,l=a.get(c);if(l){let e=o.get(c)??[l];e.push(r),o.set(c,e);continue}a.set(c,r)}let s=new v,c=Array.from(a).sort(([e],[t])=>t.length-e.length);for(let[t,n]of c){let[r,a]=h(t.slice(e.length+1)),o=t.slice(-6)==`_index`;i[t]={file:n,id:t,path:g(r,a,o)},o&&(i[t].index=!0);let c=s.findAndRemove(t,e=>[`.`,`/`].includes(e.slice(t.length).charAt(0)));if(s.add(t),c.length>0)for(let e of c)i[e].parentId=t}let l=new Map;for(let[e]of c){let t=i[e];if(!t.parentId)continue;let n=l.get(t.parentId)||[];n.push(t),l.set(t.parentId,n)}let u=new Map,d=new Map;for(let[t]of c){let n=i[t],r=n.path||``,a=n.parentId?i[n.parentId]:null,o=n.path;a?.path&&o&&(o=o.slice(a.path.length).replace(/^\//,``).replace(/\/$/,``)),n.parentId||=`root`,n.path=o||void 0;let s=n.id.replace(RegExp(`^${e}/`),``).split(/[./]/).pop();if(s&&s[0]==`_`&&s!==`_index`)continue;let c=r+(n.index?`?index`:``),l=u.get(c);if(u.set(c,n),l&&(r||n.index)){let e=d.get(r);e||=[l],e.push(n),d.set(r,e)}}if(o.size>0)for(let[e,t]of o.entries()){let[n,...r]=t,i=r.map(e=>`⭕ ${e}`).join(`
1
+ import{readdir as e}from"node:fs/promises";import{extname as t,join as n,relative as r,resolve as i,win32 as a}from"node:path";import{getAppDirectory as o,index as s,layout as c,route as l}from"@react-router/dev/routes";import{makeRe as u}from"minimatch";function d(e){let t=o();return{route:(n,a,...o)=>l(n,r(t,i(e,a)),...o),index:(n,...a)=>s(r(t,i(e,n)),...a),layout:(n,...a)=>c(r(t,i(e,n)),...a)}}async function f(t,i,a=t){for(let o of await e(t,{withFileTypes:!0,encoding:`utf8`})){let e=n(t,o.name);o.isDirectory()?await f(e,i,a):o.isFile()&&i(r(a,e))}}function p(e,t=`root`){let n={};for(let[t,r]of Object.entries(e))n[t]={id:r.id,file:r.file,path:r.path,index:r.index,caseSensitive:r.caseSensitive};let r=[];for(let[,i]of Object.entries(n)){let{parentId:a}=e[i.id];if(a===t)r.push(i);else{let e=a&&n[a];e&&(e.children=e.children||[],e.children.push(i))}}return r}function m(e,r){let i={},a=new Map,o=new Map;for(let i of r){let r=y(n(e,i)),s=r.slice(0,-t(r).length),c=s.slice(-7)==`_layout`?s.slice(0,-8):s,l=a.get(c);if(l){let e=o.get(c)??[l];e.push(r),o.set(c,e);continue}a.set(c,r)}let s=new v,c=Array.from(a).sort(([e],[t])=>t.length-e.length);for(let[t,n]of c){let[r,a]=h(t.slice(e.length+1)),o=t.slice(-6)==`_index`;i[t]={file:n,id:t,path:g(r,a,o)},o&&(i[t].index=!0);let c=s.findAndRemove(t,e=>[`.`,`/`].includes(e.slice(t.length).charAt(0)));if(s.add(t),c.length>0)for(let e of c)i[e].parentId=t}let l=new Map;for(let[e]of c){let t=i[e];if(!t.parentId)continue;let n=l.get(t.parentId)||[];n.push(t),l.set(t.parentId,n)}let u=new Map,d=new Map;for(let[t]of c){let n=i[t],r=n.path||``,a=n.parentId?i[n.parentId]:null,o=n.path;a?.path&&o&&(o=o.slice(a.path.length).replace(/^\//,``).replace(/\/$/,``)),n.parentId||=`root`,n.path=o||void 0;let s=n.id.replace(RegExp(`^${e}/`),``).split(/[./]/).pop();if(s&&s[0]==`_`&&s!==`_index`)continue;let c=r+(n.index?`?index`:``),l=u.get(c);if(u.set(c,n),l&&(r||n.index)){let e=d.get(r);e||=[l],e.push(n),d.set(r,e)}}if(o.size>0)for(let[e,t]of o.entries()){let[n,...r]=t,i=r.map(e=>`⭕ ${e}`).join(`
2
2
  `);console.error(`!Route ID 冲突: "${e}"\n\n下列路由都定义了相同的路由 ID,但只有第一个会生效\n\n🟢 ${n}\n${i}\n`)}if(d.size>0)for(let[e,t]of d.entries()){for(let e=1;e<t.length;e++)delete i[t[e].id];let[n,...r]=t.map(e=>e.file),a=e[0]==`/`?e:`/${e}`,o=r.map(e=>`⭕ ${e}`).join(`
3
3
  `);console.error(`! Route 路径冲突: "${a}"\n\n下列路由都定义了相同的 URL,但只有第一个会生效\n\n🟢 ${n}\n${o}\n`)}return i}function h(e){let t=[],n=[],r=0,i=``,a=``,o=`NORMAL`,s=(e,r)=>{if(e){if(r.includes(`*`)||r.includes(`:`)||r.includes(`?`))throw Error("路由文件或目录中不能存在 `*` `:` `?` 特殊字符");t.push(e),n.push(r)}};for(;r<e.length;){let t=e[r];switch(r++,o){case`NORMAL`:if(t&&[`.`,`/`].includes(t)){s(i,a),i=``,a=``,o=`NORMAL`;break}if(t===`[`){o=`ESCAPE`,a+=t;break}if(t===`(`){o=`OPTIONAL`,a+=t;break}if(!i&&t==`$`){r===e.length?(i+=`*`,a+=t):(i+=`:`,a+=t);break}i+=t,a+=t;break;case`ESCAPE`:if(t===`]`){o=`NORMAL`,a+=t;break}i+=t,a+=t;break;case`OPTIONAL`:if(t===`)`){i+=`?`,a+=t,o=`NORMAL`;break}if(t===`[`){o=`OPTIONAL_ESCAPE`,a+=t;break}if(!i&&t===`$`){r===e.length?(i+=`*`,a+=t):(i+=`:`,a+=t);break}i+=t,a+=t;break;case`OPTIONAL_ESCAPE`:if(t===`]`){o=`OPTIONAL`,a+=t;break}i+=t,a+=t;break}}return s(i,a),[t,n]}function g(e,t,n){let r=[],i=n?e.slice(0,-1):e;for(let e=0;e<i.length;e++){let n=t[e],a=i[e];a.startsWith(`_`)&&n.startsWith(`_`)||(a.endsWith(`_`)&&n.endsWith(`_`)&&(a=a.slice(0,-1)),r.push(a))}return r.length?r.join(`/`):void 0}const _=Symbol(`PrefixLookupTrieEndSymbol`);var v=class{root={[_]:!1};add(e){if(!e)throw Error(`Cannot add empty string to PrefixLookupTrie`);let t=this.root;for(let n of e)t[n]||(t[n]={[_]:!1}),t=t[n];t[_]=!0}findAndRemove(e,t){let n=this.root;for(let t of e){if(!n[t])return[];n=n[t]}return this.#e([],n,e,t)}#e(e,t,n,r){for(let i of Object.keys(t))this.#e(e,t[i],n+i,r);return t[_]&&r(n)&&(t[_]=!1,e.push(n)),e}};function y(e){return e.split(a.sep).join(`/`)}const b=[`.js`,`.jsx`,`.ts`,`.tsx`,`.md`,`.mdx`];async function x(e={}){let{routesDirectory:r=`routes`,ignoredRouteFiles:i=[]}=e,a=o(),s=i.map(e=>u(e)).filter(e=>!!e),c=[];return await f(n(a,r),e=>{s.some(t=>t.test(e))||b.includes(t(e))&&c.push(e)}),p(m(r,c))}export{x as flexRoutes,d as relativeFactory};
package/dist/vite.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { i as VitePluginOptions } from "./index-BMs3Y706.mjs";
1
+ import { i as VitePluginOptions } from "./index-CyAg_-Yx.mjs";
2
2
  import { Plugin } from "vite";
3
3
 
4
4
  //#region src/vite/index.d.ts
package/dist/vite.mjs CHANGED
@@ -1 +1 @@
1
- import{join as e,relative as t}from"node:path";import{existsSync as n,statSync as r}from"node:fs";import{normalizePath as i}from"vite";import{makeRe as a}from"minimatch";import{getRequestListener as o}from"@hono/node-server";import{reactRouter as s}from"@react-router/dev/vite";function c(n,r){if(!(`__reactRouterPluginContext`in n))return;let{reactRouterConfig:i,rootDirectory:a,buildManifest:o,environmentBuildContext:s}=n.__reactRouterPluginContext,c=t(a,i.appDirectory);return{entryFile:e(c,r.entryFile),appDir:c,buildDir:t(a,i.buildDirectory),assetsDir:n.build?.assetsDir||`assets`,ssrBuild:s?.name===`ssr`,future:i.future,buildManifest:o}}function l(e,t){let n=i(e),[r]=n.split(`/`),o=[RegExp(`^(?=\\/${n}\\/)((?!.*\\.data(\\?|$)).*\\..*(\\?.*)?$)`),RegExp(`^(?=\\/${n}\\/.*\\/\\..*\\/.*)`)];if(n!=r&&(o.push(RegExp(`^(?=\\/${r}\\/)((?!.*\\.data(\\?|$)).*\\..*(\\?.*)?$)`)),o.push(RegExp(`^(?=\\/${r}\\/.*\\/\\..*\\/.*)`))),t)for(let e of t)if(e instanceof RegExp)o.push(e);else try{o.push(a(e))}catch{}return o}function u(e,t){if(e.includes(`/node_modules/`)||e.startsWith(`/@`)||e.includes(`?import`))return!0;for(let n of t)if(n.test(e))return!0;return!1}function d(t){let i=``,a;return{name:`@resolid/vite-dev-plugin`,enforce:`post`,config(e){if(a=c(e,t),!a)return;let n={define:{"import.meta.env.RESOLID_PLATFORM":JSON.stringify(t.platform),"import.meta.env.RESOLID_BUILD_DIR":JSON.stringify(a.buildDir),"import.meta.env.RESOLID_ASSETS_DIR":JSON.stringify(a.assetsDir)},ssr:{noExternal:[`@resolid/dev`]}};if(!a.future?.v8_viteEnvironmentApi&&!a.ssrBuild)return n;let r={build:{target:`node${t.nodeVersion}`,rollupOptions:{input:a.entryFile}}};return a.future?.v8_viteEnvironmentApi?{...n,environments:{ssr:r}}:{...n,...r}},configResolved(e){if(i=e.publicDir,a?.buildManifest?.serverBundles)for(let t of Object.keys(a.buildManifest.serverBundles))e.environments[`ssrBundle_${t}`]&&(e.environments[`ssrBundle_${t}`].build.rollupOptions.input=a.entryFile)},async configureServer(s){if(!a)return;let c=l(a.appDir,t?.devExclude);s.middlewares.use(await(async t=>async(s,l,d)=>{if(s.url){let t=e(i,s.url);try{if(n(t)&&r(t).isFile())return d()}catch{}}if(s.url&&u(s.url,c))return d();let f=a.entryFile,p=a.future?.v8_viteEnvironmentApi?(await t.environments.ssr.runner.import(f)).default:(await t.ssrLoadModule(f)).default;if(!p)return d(Error(`Failed to find default export from ${f}`));await o(async e=>{let t=await p.fetch(e,{incoming:s,outgoing:l});if(!(t instanceof Response))throw t;return t},{overrideGlobalObjects:!1,errorHandler:e=>{let n;e instanceof Error?(n=e,t.ssrFixStacktrace(n)):n=typeof e==`string`?Error(`The response is not an instance of "Response", but: ${e}`):Error(`Unknown error: ${e}`),d(n)}})(s,l)})(s))},handleHotUpdate({server:e,modules:t}){if(t.some(e=>e._ssrModule))return e.hot.send({type:`full-reload`}),[]}}}function f(e){return[d(e),...s()]}export{f as resolidVite};
1
+ import{join as e,relative as t}from"node:path";import{existsSync as n,statSync as r}from"node:fs";import{normalizePath as i}from"vite";import{getRequestListener as a}from"@hono/node-server";import{makeRe as o}from"minimatch";import{reactRouter as s}from"@react-router/dev/vite";function c(n,r){if(!(`__reactRouterPluginContext`in n))return;let{reactRouterConfig:i,rootDirectory:a,buildManifest:o,environmentBuildContext:s}=n.__reactRouterPluginContext,c=t(a,i.appDirectory);return{entryFile:e(c,r.entryFile),appDir:c,buildDir:t(a,i.buildDirectory),assetsDir:n.build?.assetsDir||`assets`,ssrBuild:s?.name===`ssr`,future:i.future,buildManifest:o}}function l(e,t){let n=i(e),[r]=n.split(`/`),a=[RegExp(`^(?=\\/${n}\\/)((?!.*\\.data(\\?|$)).*\\..*(\\?.*)?$)`),RegExp(`^(?=\\/${n}\\/.*\\/\\..*\\/.*)`)];if(n!=r&&(a.push(RegExp(`^(?=\\/${r}\\/)((?!.*\\.data(\\?|$)).*\\..*(\\?.*)?$)`)),a.push(RegExp(`^(?=\\/${r}\\/.*\\/\\..*\\/.*)`))),t)for(let e of t)if(e instanceof RegExp)a.push(e);else try{a.push(o(e))}catch{}return a}function u(e,t){if(e.includes(`/node_modules/`)||e.startsWith(`/@`)||e.includes(`?import`))return!0;for(let n of t)if(n.test(e))return!0;return!1}function d(t){let i=``,o;return{name:`@resolid/vite-dev-plugin`,enforce:`post`,config(e){if(o=c(e,t),!o)return;let n={define:{"import.meta.env.RESOLID_PLATFORM":JSON.stringify(t.platform),"import.meta.env.RESOLID_BUILD_DIR":JSON.stringify(o.buildDir),"import.meta.env.RESOLID_ASSETS_DIR":JSON.stringify(o.assetsDir)},ssr:{noExternal:[`@resolid/dev`]}};if(!o.future?.v8_viteEnvironmentApi&&!o.ssrBuild)return n;let r={build:{target:`node${t.nodeVersion}`,rollupOptions:{input:o.entryFile}}};return o.future?.v8_viteEnvironmentApi?{...n,environments:{ssr:r}}:{...n,...r}},configResolved(e){if(i=e.publicDir,o?.buildManifest?.serverBundles)for(let t of Object.keys(o.buildManifest.serverBundles))e.environments[`ssrBundle_${t}`]&&(e.environments[`ssrBundle_${t}`].build.rollupOptions.input=o.entryFile)},async configureServer(s){if(!o)return;let c=l(o.appDir,t?.devExclude);s.middlewares.use(await(async t=>async(s,l,d)=>{if(s.url){let t=e(i,s.url);try{if(n(t)&&r(t).isFile())return d()}catch{}}if(s.url&&u(s.url,c))return d();let f=o.entryFile,p=o.future?.v8_viteEnvironmentApi?(await t.environments.ssr.runner.import(f)).default:(await t.ssrLoadModule(f)).default;if(!p)return d(Error(`Failed to find default export from ${f}`));await a(async e=>{let t=await p.fetch(e,{incoming:s,outgoing:l});if(!(t instanceof Response))throw t;return t},{overrideGlobalObjects:!1,errorHandler:e=>{let n;e instanceof Error?(n=e,t.ssrFixStacktrace(n)):n=typeof e==`string`?Error(`The response is not an instance of "Response", but: ${e}`):Error(`Unknown error: ${e}`),d(n)}})(s,l)})(s))},handleHotUpdate({server:e,modules:t}){if(t.some(e=>e._ssrModule))return e.hot.send({type:`full-reload`}),[]}}}function f(e){return[d(e),...s()]}export{f as resolidVite};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@resolid/dev",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "private": false,
5
5
  "description": "Development utils for Resolid applications",
6
6
  "keywords": [
@@ -37,21 +37,17 @@
37
37
  "./env": {
38
38
  "types": "./env.d.ts"
39
39
  },
40
- "./routes": {
41
- "types": "./dist/routes.d.mts",
42
- "import": "./dist/routes.mjs"
40
+ "./http.server": {
41
+ "types": "./dist/http.d.mts",
42
+ "import": "./dist/http.mjs"
43
43
  },
44
44
  "./router": {
45
45
  "types": "./dist/router.d.mts",
46
46
  "import": "./dist/router.mjs"
47
47
  },
48
- "./router.server": {
49
- "types": "./dist/router.server.d.mts",
50
- "import": "./dist/router.server.mjs"
51
- },
52
- "./server": {
53
- "types": "./dist/server.d.mts",
54
- "import": "./dist/server.mjs"
48
+ "./routes": {
49
+ "types": "./dist/routes.d.mts",
50
+ "import": "./dist/routes.mjs"
55
51
  },
56
52
  "./vite": {
57
53
  "types": "./dist/vite.d.mts",
@@ -1,5 +0,0 @@
1
- //#region src/types/index.d.ts
2
- type NodeVersion = 22 | 24;
3
- type ServerPlatform = "vercel" | "netlify" | "node";
4
- //#endregion
5
- export { ServerPlatform as n, NodeVersion as t };
@@ -1,49 +0,0 @@
1
- import { MiddlewareFunction, RouterContextProvider, UNSAFE_DataWithResponseInit } from "react-router";
2
- import { Socket } from "node:net";
3
-
4
- //#region src/router/middlewares/request-id.server.d.ts
5
- interface CreateRequestIdMiddlewareOptions {
6
- /**
7
- * The name of the header to read the requestId from.
8
- *
9
- * @default "X-Request-Id"
10
- */
11
- header?: string;
12
- /**
13
- * The length of the requestId.
14
- *
15
- * @default 255
16
- */
17
- limitLength?: number;
18
- /**
19
- * A function to generate a requestId.
20
- *
21
- * @default () => random()
22
- */
23
- generator?: () => string;
24
- }
25
- declare function createRequestIdMiddleware({
26
- header,
27
- generator,
28
- limitLength
29
- }?: CreateRequestIdMiddlewareOptions): [MiddlewareFunction<Response>, (context: Readonly<RouterContextProvider>) => string];
30
- //#endregion
31
- //#region src/router/utils/http.exceptions.d.ts
32
- declare function httpProblem<E>(errors: E): UNSAFE_DataWithResponseInit<{
33
- errors: E;
34
- }>;
35
- declare function httpNotFound(message?: string): never;
36
- declare function httpRedirect(url: string, cookie?: string | null, status?: number): never;
37
- //#endregion
38
- //#region src/router/utils/http.server.d.ts
39
- interface GetClientIpOptions {
40
- proxy: boolean;
41
- proxyCount?: number;
42
- ipHeaders?: string;
43
- }
44
- declare function getClientIp(req: Request, socket: Socket, options?: GetClientIpOptions): string;
45
- declare function getRequestProtocol(req: Request, socket: Socket, proxy?: boolean): string;
46
- declare function getRequestHost(req: Request, proxy?: boolean): string | null;
47
- declare function getRequestOrigin(req: Request, socket: Socket, proxy?: boolean): string;
48
- //#endregion
49
- export { createRequestIdMiddleware, getClientIp, getRequestHost, getRequestOrigin, getRequestProtocol, httpNotFound, httpProblem, httpRedirect };
@@ -1 +0,0 @@
1
- import{random as e}from"@resolid/utils";import{createContext as t,data as n}from"react-router";function r({header:n=`X-Request-Id`,generator:r=()=>e(),limitLength:i=255}={}){let a=t();return[({request:e,context:t})=>{let o=e.headers.get(n);(!o||o.length>i||/[^\w-]/.test(o))&&(o=r()),t.set(a,o)},e=>e.get(a)]}function i(e){return n({errors:e},422)}function a(e=`页面未找到`){throw new Response(e,{status:404})}function o(e,t=null,n=302){let r=new Headers;throw r.set(`Location`,e),t&&r.set(`Set-Cookie`,t),new Response(null,{status:n,headers:r})}function s(e,t,n){let{proxy:r=!1,proxyCount:i=0,ipHeaders:a=`x-forwarded-for`}=n||{},o=e.headers.get(a),s=r&&o?o.split(/\s*,\s*/):[];return i>0&&(s=s.slice(-i)),s[0]||t.remoteAddress||``}function c(e,t,n=!1){if(t.encrypted)return`https`;if(!n)return`http`;let r=e.headers.get(`x-forwarded-proto`);return r?r.split(/\s*,\s*/,1)[0]:`http`}function l(e,t=!1){let n=t&&e.headers.get(`x-forwarded-host`);return n?n.split(/\s*,\s*/,1)[0]:e.headers.get(`host`)}function u(e,t,n=!1){return`${c(e,t,n)}://${l(e,n)}`}export{r as createRequestIdMiddleware,s as getClientIp,l as getRequestHost,u as getRequestOrigin,c as getRequestProtocol,a as httpNotFound,i as httpProblem,o as httpRedirect};
package/dist/server.d.mts DELETED
@@ -1,54 +0,0 @@
1
- import { n as ServerPlatform } from "./index-BMC9vh2X.mjs";
2
- import { AppLoadContext, RouterContextProvider, ServerBuild, UNSAFE_MiddlewareEnabled } from "react-router";
3
- import { Context, Context as HonoContext, Env, Hono, Hono as Hono$1, MiddlewareHandler } from "hono";
4
- import { Http2Bindings, HttpBindings } from "@hono/node-server";
5
- import { AddressInfo } from "node:net";
6
- import { IncomingMessage, ServerResponse } from "http";
7
- import { Http2ServerRequest, Http2ServerResponse } from "http2";
8
- import { HonoOptions } from "hono/hono-base";
9
- import { BlankEnv } from "hono/types";
10
- import { Context as NetlifyContext } from "@netlify/types";
11
-
12
- //#region src/server/utils.d.ts
13
- interface NodeEnv {
14
- Bindings: HttpBindings | Http2Bindings;
15
- }
16
- type ReactRouterAppLoadContext = UNSAFE_MiddlewareEnabled extends true ? RouterContextProvider : AppLoadContext;
17
- interface HonoServerOptions<E extends Env = BlankEnv> {
18
- configure?: <E extends Env = BlankEnv>(app: Hono$1<E>) => Promise<void> | void;
19
- getLoadContext?: (c: Context<E>, options: {
20
- build: ServerBuild;
21
- mode?: string;
22
- }) => Promise<ReactRouterAppLoadContext> | ReactRouterAppLoadContext;
23
- onShutdown?: () => Promise<void> | void;
24
- honoOptions?: HonoOptions<E>;
25
- }
26
- //#endregion
27
- //#region src/server/platforms/netlify.d.ts
28
- interface NetlifyEnv {
29
- Bindings: {
30
- context: NetlifyContext;
31
- };
32
- }
33
- type HonoNetlifyServerOptions = HonoServerOptions<NetlifyEnv>;
34
- //#endregion
35
- //#region src/server/platforms/node.d.ts
36
- type HonoNodeServerOptions = HonoServerOptions<NodeEnv> & {
37
- port?: number;
38
- defaultLogger?: boolean;
39
- listeningListener?: (info: AddressInfo) => void;
40
- };
41
- declare function cache(seconds: number, immutable?: boolean): MiddlewareHandler;
42
- //#endregion
43
- //#region src/server/platforms/vercel.d.ts
44
- type HonoVercelServerOptions = HonoServerOptions<NodeEnv>;
45
- //#endregion
46
- //#region src/server/index.d.ts
47
- type PlatformConfig<T> = (config: T | undefined) => T | undefined;
48
- declare const cacheControl: typeof cache;
49
- declare const nodeConfig: PlatformConfig<HonoNodeServerOptions>;
50
- declare const netlifyConfig: PlatformConfig<HonoNetlifyServerOptions>;
51
- declare const vercelConfig: PlatformConfig<HonoVercelServerOptions>;
52
- declare const createServer: (factory: (platform: ServerPlatform) => HonoNodeServerOptions | HonoNetlifyServerOptions | HonoVercelServerOptions | undefined) => Promise<((req: Request, context: NetlifyContext) => Response | Promise<Response>) | ((incoming: IncomingMessage | Http2ServerRequest, outgoing: ServerResponse | Http2ServerResponse) => Promise<void>) | Hono<NodeEnv>>;
53
- //#endregion
54
- export { type Hono, type HonoContext, type NetlifyContext, type NodeEnv, type ServerPlatform, cacheControl, createServer, netlifyConfig, nodeConfig, vercelConfig };
package/dist/server.mjs DELETED
@@ -1 +0,0 @@
1
- import{createRequestHandler as e}from"react-router";import{handle as t}from"hono/netlify";import n,{env as r}from"node:process";import{Hono as i}from"hono";import{serve as a}from"@hono/node-server";import{serveStatic as o}from"@hono/node-server/serve-static";import{logger as s}from"hono/logger";import{networkInterfaces as c}from"node:os";import{handle as l}from"@hono/node-server/vercel";async function u(t,r={}){let a=new i(r.honoOptions);r.configure&&await r.configure(a),a.use(`*`,async n=>{let i=await import(`virtual:react-router/server-build`);return(async n=>{let a=e(i,t),o=r.getLoadContext?.(n,{build:i,mode:t});return a(n.req.raw,o instanceof Promise?await o:o)})(n)});async function o(){r.onShutdown?.(),n.removeListener(`SIGINT`,o),n.removeListener(`SIGTERM`,o),n.exit(0)}return n.on(`SIGINT`,o),n.on(`SIGTERM`,o),a}async function d(e={}){return t(await u(r.NODE_ENV==`test`?`development`:r.NODE_ENV,e))}function f(e,t=!1){return async(n,r)=>{if(!n.req.path.match(/\.[a-zA-Z0-9]+$/)||n.req.path.endsWith(`.data`))return r();await r(),n.res.ok&&n.res.headers.set(`Cache-Control`,`public, max-age=${e}${t?`, immutable`:``}`)}}async function p(e={}){let t=r.NODE_ENV==`test`?`development`:r.NODE_ENV,n=t==`production`,i={port:Number(r.PORT)||3e3,listeningListener:e=>{console.log(`🚀 Server started on port ${e.port}`);let t=Object.values(c()).flat().find(e=>String(e?.family).includes(`4`)&&!e?.internal)?.address,n=r.SERVE_PATH?r.SERVE_PATH:``;console.log(`[resolid-server] http://localhost:${e.port}${n}${t&&` (http://${t}:${e.port})`}`)},...e,defaultLogger:e.defaultLogger??!n},l=null,d=await u(t,{configure:async e=>{if(n){let t=`${import.meta.env.RESOLID_BUILD_DIR}/client`;e.use(`/${import.meta.env.RESOLID_ASSETS_DIR}/*`,f(3600*24*365,!0),o({root:t})),e.use(`*`,f(3600),o({root:t}))}else e.use(`*`,f(3600),o({root:`./public`}));i.defaultLogger&&e.use(`*`,s()),await i.configure?.(e)},getLoadContext:i.getLoadContext,honoOptions:i.honoOptions,onShutdown:async()=>{l?.close(),i.onShutdown?.()}});return n&&(l=a({...d,port:i.port},i.listeningListener)),d}const m=async(e={})=>l(await u(r.NODE_ENV==`test`?`development`:r.NODE_ENV,e)),h=f,g=e=>e,_=e=>e,v=e=>e,y=async e=>{switch(import.meta.env.RESOLID_PLATFORM){case`netlify`:return await d(e(`netlify`));case`vercel`:return await m(e(`vercel`));default:return await p(e(`node`))}};export{h as cacheControl,y as createServer,_ as netlifyConfig,g as nodeConfig,v as vercelConfig};