@resolid/dev 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022-present, Resolid Tech
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # Development utils for Resolid applications
2
+
3
+ ![GitHub License](https://img.shields.io/github/license/resolid/framework)
4
+ ![NPM Version](https://img.shields.io/npm/v/%40resolid/dev)
5
+
6
+ <b>[Documentation](https://www.resolid.tech/docs/dev)</b> | [Framework Bundle](https://github.com/resolid/framework)
7
+
8
+ ## Installation
9
+
10
+ ```shell
11
+ pnpm add @resolid/dev
12
+ # or
13
+ npm install @resolid/dev
14
+ # or
15
+ yarn add @resolid/dev
16
+ # or
17
+ bun add @resolid/dev
18
+ ```
19
+
20
+ ## License
21
+
22
+ MIT License (MIT). Please see [LICENSE](./LICENSE) for more information.
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ import { spawn } from "node:child_process";
3
+ import { dirname, resolve } from "node:path";
4
+ import { argv, exit } from "node:process";
5
+ import { fileURLToPath } from "node:url";
6
+
7
+ const binPath = resolve(
8
+ dirname(fileURLToPath(import.meta.url)),
9
+ "../node_modules/.bin/react-router",
10
+ );
11
+
12
+ const child = spawn(binPath, argv.slice(2), { stdio: "inherit" });
13
+
14
+ child.on("exit", (code) => {
15
+ exit(code ?? 0);
16
+ });
@@ -0,0 +1,5 @@
1
+ //#region src/types/index.d.ts
2
+ type NodeVersion = 22 | 24;
3
+ type Platform = "vercel" | "netlify" | "node";
4
+ //#endregion
5
+ export { Platform as n, NodeVersion as t };
@@ -0,0 +1,33 @@
1
+ import { n as Platform, t as NodeVersion } from "./index-Bl4eSdJb.mjs";
2
+ import { Config } from "@react-router/dev/config";
3
+
4
+ //#region src/config/index.d.ts
5
+ interface VitePluginOptions {
6
+ platform: Platform;
7
+ nodeVersion: NodeVersion;
8
+ entryFile: string;
9
+ devExclude?: (string | RegExp)[];
10
+ }
11
+ type ReactRouterConfig = Omit<Config, "appDirectory" | "ssr" | "serverModuleFormat" | "future"> & {
12
+ future?: Omit<Config["future"], "v8_middleware" | "v8_splitRouteModules" | "v8_viteEnvironmentApi">;
13
+ };
14
+ type DevConfigOptions = Partial<VitePluginOptions> & {
15
+ appDirectory?: string;
16
+ includeFiles?: string[];
17
+ reactRouterConfig?: ReactRouterConfig;
18
+ };
19
+ interface DevConfig {
20
+ vitePluginOptions: VitePluginOptions;
21
+ reactRouterConfig: Config;
22
+ }
23
+ declare const defineDevConfig: ({
24
+ platform,
25
+ nodeVersion,
26
+ entryFile,
27
+ appDirectory,
28
+ includeFiles,
29
+ reactRouterConfig,
30
+ devExclude
31
+ }: DevConfigOptions) => DevConfig;
32
+ //#endregion
33
+ export { defineDevConfig as a, VitePluginOptions as i, DevConfigOptions as n, ReactRouterConfig as r, DevConfig as t };
@@ -0,0 +1,2 @@
1
+ import { a as defineDevConfig, i as VitePluginOptions, n as DevConfigOptions, r as ReactRouterConfig, t as DevConfig } from "./index-BxG71-IE.mjs";
2
+ export { DevConfig, DevConfigOptions, ReactRouterConfig, VitePluginOptions, defineDevConfig };
package/dist/index.mjs ADDED
@@ -0,0 +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.1.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,legalComments:`none`},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)}";
2
+
3
+ export const config = {
4
+ path: ${Array.isArray(s)?JSON.stringify(s):`"${s}"`},
5
+ displayName: "${r} server",
6
+ generator: "${v}@${y}",
7
+ preferStatic: true,
8
+ nodeVersion: ${t}
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};
@@ -0,0 +1,6 @@
1
+ import { MetaArgs, MetaDescriptor } from "react-router";
2
+
3
+ //#region src/router/utils/merge-meta.d.ts
4
+ declare function mergeMeta(metaFn: (arg: MetaArgs) => MetaDescriptor[], titleJoin?: string): (arg: MetaArgs) => MetaDescriptor[];
5
+ //#endregion
6
+ export { mergeMeta };
@@ -0,0 +1 @@
1
+ function e(e,t=` - `){return n=>{let r=e(n),i=n.matches.reduceRight((e,t)=>{if(t)for(let n of t.meta)e.findIndex(e=>`name`in e&&`name`in n?e.name===n.name:`property`in e&&`property`in n?e.property===n.property:`title`in e&&`title`in n?e.title===n.title:!1)==-1&&e.push(n);return e},r),a=[],o=[];for(let e of i)`title`in e?typeof e.title==`string`&&e.title.length>0&&a.push(...e.title.split(t)):o.push(e);return o.unshift({title:[...new Set(a)].join(t)}),o}}export{e as mergeMeta};
@@ -0,0 +1,49 @@
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 };
@@ -0,0 +1 @@
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};
@@ -0,0 +1,10 @@
1
+ import { RouteConfig, RouteConfigEntry, index, layout, prefix, route } from "@react-router/dev/routes";
2
+
3
+ //#region src/routes/index.d.ts
4
+ declare function relativeFactory(directory: string): {
5
+ route: typeof route;
6
+ index: typeof index;
7
+ layout: typeof layout;
8
+ };
9
+ //#endregion
10
+ export { type RouteConfig, type RouteConfigEntry, index, layout, prefix, relativeFactory, route };
@@ -0,0 +1 @@
1
+ import{relative as e,resolve as t}from"node:path";import{getAppDirectory as n,index as r,layout as i,prefix as a,route as o}from"@react-router/dev/routes";function s(a){let s=n();return{route:(n,r,...i)=>o(n,e(s,t(a,r)),...i),index:(n,...i)=>r(e(s,t(a,n)),...i),layout:(n,...r)=>i(e(s,t(a,n)),...r)}}export{r as index,i as layout,a as prefix,s as relativeFactory,o as route};
@@ -0,0 +1,54 @@
1
+ import { n as Platform } from "./index-Bl4eSdJb.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: Platform) => 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, cacheControl, createServer, netlifyConfig, nodeConfig, vercelConfig };
@@ -0,0 +1 @@
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};
@@ -0,0 +1,7 @@
1
+ import { i as VitePluginOptions } from "./index-BxG71-IE.mjs";
2
+ import { Plugin } from "vite";
3
+
4
+ //#region src/vite/index.d.ts
5
+ declare function resolidVite(options: VitePluginOptions): Plugin[];
6
+ //#endregion
7
+ export { resolidVite };
package/dist/vite.mjs ADDED
@@ -0,0 +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{getRequestListener as a}from"@hono/node-server";import{reactRouter as o}from"@react-router/dev/vite";import{makeRe as s}from"minimatch";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(s(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),...o()]}export{f as resolidVite};
package/package.json ADDED
@@ -0,0 +1,93 @@
1
+ {
2
+ "name": "@resolid/dev",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "description": "Development utils for Resolid applications",
6
+ "keywords": [
7
+ "netlify",
8
+ "nodejs",
9
+ "react-router",
10
+ "resolid",
11
+ "vercel",
12
+ "vite"
13
+ ],
14
+ "homepage": "https://www.resolid.tech",
15
+ "license": "MIT",
16
+ "author": {
17
+ "name": "Huijie Wei",
18
+ "email": "hello@resolid.tech"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/resolid/framework.git",
23
+ "directory": "packages/dev"
24
+ },
25
+ "bin": {
26
+ "react-router": "cli/react-router.js"
27
+ },
28
+ "files": [
29
+ "cli",
30
+ "dist"
31
+ ],
32
+ "type": "module",
33
+ "sideEffects": false,
34
+ "types": "./dist/index.d.mts",
35
+ "exports": {
36
+ ".": {
37
+ "types": "./dist/index.d.mts",
38
+ "import": "./dist/index.mjs"
39
+ },
40
+ "./routes": {
41
+ "types": "./dist/routes.d.mts",
42
+ "import": "./dist/routes.mjs"
43
+ },
44
+ "./router": {
45
+ "types": "./dist/router.d.mts",
46
+ "import": "./dist/router.mjs"
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"
55
+ },
56
+ "./vite": {
57
+ "types": "./dist/vite.d.mts",
58
+ "import": "./dist/vite.mjs"
59
+ }
60
+ },
61
+ "publishConfig": {
62
+ "access": "public",
63
+ "provenance": true
64
+ },
65
+ "scripts": {
66
+ "build": "tsdown",
67
+ "lint": "oxlint",
68
+ "typecheck": "tsc --noEmit"
69
+ },
70
+ "dependencies": {
71
+ "@hono/node-server": "^1.19.9",
72
+ "@react-router/dev": "^7.13.1",
73
+ "@resolid/utils": "^1.2.7",
74
+ "@vercel/nft": "^1.3.2",
75
+ "fast-glob": "^3.3.3",
76
+ "hono": "^4.12.3",
77
+ "minimatch": "^10.2.4",
78
+ "rolldown": "latest"
79
+ },
80
+ "devDependencies": {
81
+ "tsdown": "^0.20.3"
82
+ },
83
+ "peerDependencies": {
84
+ "@netlify/types": "^2.3.0",
85
+ "@react-router/node": "^7.13.1",
86
+ "isbot": "^5.1.35",
87
+ "react-router": "^7.13.1",
88
+ "vite": "^7.3.1"
89
+ },
90
+ "engines": {
91
+ "node": "^22.13.0 || >=24"
92
+ }
93
+ }