@devlusoft/devix 0.5.4 → 0.5.5

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.
@@ -1,2 +1,2 @@
1
- import{createContext as m}from"react";var u=globalThis;u.__devix_RouterContext__??=m(null);var w=u.__devix_RouterContext__;u.__devix_PageMetaContext__??=m(null);u.__devix_RouteDataContext__??=m(null);var P=u.__devix_PageMetaContext__,x=u.__devix_RouteDataContext__;import{Fragment as v,jsx as g}from"react/jsx-runtime";function M(t,e){let o=[];t.title&&o.push({tag:"title",children:t.title}),t.description&&o.push({tag:"meta",name:"description",content:t.description}),t.keywords?.length&&o.push({tag:"meta",name:"keywords",content:t.keywords.join(", ")});let r=t.og?.title??t.title;r&&o.push({tag:"meta",property:"og:title",content:r});let a=t.og?.description??t.description;a&&o.push({tag:"meta",property:"og:description",content:a}),t.og?.image&&o.push({tag:"meta",property:"og:image",content:t.og.image}),t.og?.type&&o.push({tag:"meta",property:"og:type",content:t.og.type}),t.og?.url&&o.push({tag:"meta",property:"og:url",content:t.og.url});let c=t.twitter?.title??t.title;c&&o.push({tag:"meta",name:"twitter:title",content:c});let l=t.twitter?.description??t.description;if(l&&o.push({tag:"meta",name:"twitter:description",content:l}),t.twitter?.card&&o.push({tag:"meta",name:"twitter:card",content:t.twitter.card}),t.twitter?.image&&o.push({tag:"meta",name:"twitter:image",content:t.twitter.image}),t.twitter?.creator&&o.push({tag:"meta",name:"twitter:creator",content:t.twitter.creator}),t.canonical&&o.push({tag:"link",rel:"canonical",href:t.canonical}),t.robots&&o.push({tag:"meta",name:"robots",content:t.robots}),t.alternates)for(let[n,i]of Object.entries(t.alternates))o.push({tag:"link",rel:"alternate",href:i,hrefLang:n});if(t.icons){let n=Array.isArray(t.icons)?t.icons:[t.icons];for(let i of n){let s=typeof i=="string"?{href:i}:i;o.push({tag:"link",rel:s.rel??"icon",href:s.href,...s.type&&{type:s.type},...s.sizes&&{sizes:s.sizes}})}}if(e){let n=[];e.width!==void 0&&n.push(`width=${e.width}`),e.initialScale!==void 0&&n.push(`initial-scale=${e.initialScale}`),e.maximumScale!==void 0&&n.push(`maximum-scale=${e.maximumScale}`),e.userScalable!==void 0&&n.push(`user-scalable=${e.userScalable?"yes":"no"}`),n.length&&o.push({tag:"meta",name:"viewport",content:n.join(", ")}),e.themeColor&&o.push({tag:"meta",name:"theme-color",content:e.themeColor})}return o}function _({metadata:t,viewport:e}){return typeof window>"u"||!t?null:g(v,{children:D(t,e)})}function D(t,e){let o=M(t,e);return g(v,{children:o.map((r,a)=>r.tag==="title"?g("title",{children:r.children},a):r.tag==="link"?g("link",{rel:r.rel,href:r.href,hrefLang:r.hrefLang,type:r.type,sizes:r.sizes},a):g("meta",{name:r.name,property:r.property,content:r.content},a))})}import{Component as V}from"react";import{jsx as R}from"react/jsx-runtime";var h=class extends V{state={error:null};static getDerivedStateFromError(e){return e instanceof y?{error:{statusCode:e.statusCode,message:e.message}}:{error:{statusCode:500,message:e instanceof Error?e.message:"Unknown error"}}}render(){return this.state.error&&this.props.ErrorPage?R(this.props.ErrorPage,{...this.state.error}):this.state.error?R("h1",{children:this.state.error.statusCode}):this.props.children}},y=class extends Error{statusCode;code;data;constructor(e,o,r){super(o),this.name="DevixError",this.statusCode=e,this.code=r?.code,this.data=r?.data}};import{jsx as p,jsxs as E}from"react/jsx-runtime";var S=(t,e)=>Promise.resolve(),T=()=>Promise.resolve(),b=t=>{};function K({pathname:t,params:e,loaderData:o,layoutsData:r,guardData:a,Page:c,layouts:l,metadata:n,viewport:i,clientEntry:s}){let d=p(x,{value:{loaderData:o,params:e},children:p(c,{data:o,params:e,url:t})});for(let f=l.length-1;f>=0;f--){let k=l[f],C=r[f];d=p(x,{value:{loaderData:C,params:e},children:p(k,{data:C,params:e,children:d})})}return E(P,{value:{metadata:n,viewport:i,clientEntry:s},children:[p(_,{metadata:n,viewport:i}),p(w,{value:{pathname:t,params:e,loaderData:o,layoutsData:r,guardData:a,Page:c,layouts:l,metadata:n,viewport:i,isNavigating:!1,navigate:S,revalidate:T,prefetchRoute:b},children:p(h,{children:d},t)})]})}export{K as ServerApp};
1
+ import{createContext as m}from"react";var u=globalThis;u.__devix_RouterContext__??=m(null);var w=u.__devix_RouterContext__;u.__devix_PageMetaContext__??=m(null);u.__devix_RouteDataContext__??=m(null);var P=u.__devix_PageMetaContext__,x=u.__devix_RouteDataContext__;import{Fragment as R,jsx as g}from"react/jsx-runtime";function M(t,e){let o=[];t.title&&o.push({tag:"title",children:t.title}),t.description&&o.push({tag:"meta",name:"description",content:t.description}),t.keywords?.length&&o.push({tag:"meta",name:"keywords",content:t.keywords.join(", ")});let r=t.og?.title??t.title;r&&o.push({tag:"meta",property:"og:title",content:r});let a=t.og?.description??t.description;a&&o.push({tag:"meta",property:"og:description",content:a}),t.og?.image&&o.push({tag:"meta",property:"og:image",content:t.og.image}),t.og?.type&&o.push({tag:"meta",property:"og:type",content:t.og.type}),t.og?.url&&o.push({tag:"meta",property:"og:url",content:t.og.url});let c=t.twitter?.title??t.title;c&&o.push({tag:"meta",name:"twitter:title",content:c});let l=t.twitter?.description??t.description;if(l&&o.push({tag:"meta",name:"twitter:description",content:l}),t.twitter?.card&&o.push({tag:"meta",name:"twitter:card",content:t.twitter.card}),t.twitter?.image&&o.push({tag:"meta",name:"twitter:image",content:t.twitter.image}),t.twitter?.creator&&o.push({tag:"meta",name:"twitter:creator",content:t.twitter.creator}),t.canonical&&o.push({tag:"link",rel:"canonical",href:t.canonical}),t.robots&&o.push({tag:"meta",name:"robots",content:t.robots}),t.alternates)for(let[n,i]of Object.entries(t.alternates))o.push({tag:"link",rel:"alternate",href:i,hrefLang:n});if(t.icons){let n=Array.isArray(t.icons)?t.icons:[t.icons];for(let i of n){let s=typeof i=="string"?{href:i}:i;o.push({tag:"link",rel:s.rel??"icon",href:s.href,...s.type&&{type:s.type},...s.sizes&&{sizes:s.sizes}})}}if(e){let n=[];e.width!==void 0&&n.push(`width=${e.width}`),e.initialScale!==void 0&&n.push(`initial-scale=${e.initialScale}`),e.maximumScale!==void 0&&n.push(`maximum-scale=${e.maximumScale}`),e.userScalable!==void 0&&n.push(`user-scalable=${e.userScalable?"yes":"no"}`),n.length&&o.push({tag:"meta",name:"viewport",content:n.join(", ")}),e.themeColor&&o.push({tag:"meta",name:"theme-color",content:e.themeColor})}return o}function _({metadata:t,viewport:e}){return typeof window>"u"||!t?null:g(R,{children:V(t,e)})}function V(t,e){let o=M(t,e);return g(R,{children:o.map((r,a)=>r.tag==="title"?g("title",{children:r.children},a):r.tag==="link"?g("link",{rel:r.rel,href:r.href,hrefLang:r.hrefLang,type:r.type,sizes:r.sizes},a):g("meta",{name:r.name,property:r.property,content:r.content},a))})}import{Component as b}from"react";import{jsx as k}from"react/jsx-runtime";var h=class extends b{state={error:null};static getDerivedStateFromError(e){return e instanceof y?{error:{statusCode:e.statusCode,message:e.message}}:{error:{statusCode:500,message:e instanceof Error?e.message:"Unknown error"}}}render(){return this.state.error&&this.props.ErrorPage?k(this.props.ErrorPage,{...this.state.error}):this.state.error?k("h1",{children:this.state.error.statusCode}):this.props.children}},v=Symbol.for("@devlusoft/devix.DevixError"),y=class extends Error{static[Symbol.hasInstance](e){return e!==null&&typeof e=="object"&&e[v]===!0}statusCode;code;data;constructor(e,o,r){super(o),this.name="DevixError",this.statusCode=e,this.code=r?.code,this.data=r?.data,this[v]=!0}};import{jsx as p,jsxs as N}from"react/jsx-runtime";var S=(t,e)=>Promise.resolve(),E=()=>Promise.resolve(),T=t=>{};function K({pathname:t,params:e,loaderData:o,layoutsData:r,guardData:a,Page:c,layouts:l,metadata:n,viewport:i,clientEntry:s}){let d=p(x,{value:{loaderData:o,params:e},children:p(c,{data:o,params:e,url:t})});for(let f=l.length-1;f>=0;f--){let D=l[f],C=r[f];d=p(x,{value:{loaderData:C,params:e},children:p(D,{data:C,params:e,children:d})})}return N(P,{value:{metadata:n,viewport:i,clientEntry:s},children:[p(_,{metadata:n,viewport:i}),p(w,{value:{pathname:t,params:e,loaderData:o,layoutsData:r,guardData:a,Page:c,layouts:l,metadata:n,viewport:i,isNavigating:!1,navigate:S,revalidate:E,prefetchRoute:T},children:p(h,{children:d},t)})]})}export{K as ServerApp};
2
2
  //# sourceMappingURL=server-app.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/runtime/context.tsx", "../../src/runtime/head.tsx", "../../src/runtime/error-boundary.tsx", "../../src/runtime/server-app.tsx"],
4
- "sourcesContent": ["import {createContext, Context, ComponentType} from \"react\";\nimport {Metadata, Viewport} from \"../types\";\nimport {LayoutProps, PageProps} from \"../server/types\";\n\nexport interface NavigateOptions {\n replace?: boolean\n viewTransition?: boolean\n}\n\nexport interface RouterContextValue {\n pathname: string\n params: Record<string, string>\n loaderData: unknown\n layoutsData: unknown[]\n guardData: unknown\n Page: ComponentType<PageProps>\n layouts: ComponentType<LayoutProps>[]\n metadata: Metadata | null\n viewport?: Viewport\n navigate: (to: string, options?: NavigateOptions) => Promise<void>\n revalidate: () => Promise<void>\n prefetchRoute: (href: string) => void\n isNavigating: boolean\n}\n\nexport interface PageMetaContextValue {\n metadata: Metadata | null\n viewport?: Viewport\n clientEntry?: string\n}\n\nexport interface RouteDataContextValue {\n loaderData: unknown\n params: Record<string, string>\n}\n\nconst g = globalThis as any\n\ng.__devix_RouterContext__ ??= createContext<RouterContextValue | null>(null)\nexport const RouterContext: Context<RouterContextValue | null> = g.__devix_RouterContext__\n\ng.__devix_PageMetaContext__ ??= createContext<PageMetaContextValue | null>(null)\ng.__devix_RouteDataContext__ ??= createContext<RouteDataContextValue | null>(null)\n\nexport const PageMetaContext: Context<PageMetaContextValue | null> = g.__devix_PageMetaContext__\nexport const RouteDataContext: Context<RouteDataContextValue | null> = g.__devix_RouteDataContext__\n\n", "import { Metadata, MetadataIcon, Viewport } from \"../types\";\nimport { ReactNode } from \"react\";\n\ntype MetaTag =\n | { tag: 'title'; children: string }\n | { tag: 'meta'; name?: string; property?: string; content: string }\n | { tag: 'link'; rel: string; href: string; hrefLang?: string; type?: string; sizes?: string }\n\nfunction collectTags(metadata: Metadata, viewport?: Viewport): MetaTag[] {\n const tags: MetaTag[] = []\n\n if (metadata.title)\n tags.push({ tag: 'title', children: metadata.title })\n if (metadata.description)\n tags.push({ tag: 'meta', name: 'description', content: metadata.description })\n if (metadata.keywords?.length)\n tags.push({ tag: 'meta', name: 'keywords', content: metadata.keywords.join(', ') })\n\n const ogTitle = metadata.og?.title ?? metadata.title\n if (ogTitle) tags.push({ tag: 'meta', property: 'og:title', content: ogTitle })\n const ogDesc = metadata.og?.description ?? metadata.description\n if (ogDesc) tags.push({ tag: 'meta', property: 'og:description', content: ogDesc })\n if (metadata.og?.image) tags.push({ tag: 'meta', property: 'og:image', content: metadata.og.image })\n if (metadata.og?.type) tags.push({ tag: 'meta', property: 'og:type', content: metadata.og.type })\n if (metadata.og?.url) tags.push({ tag: 'meta', property: 'og:url', content: metadata.og.url })\n\n const twTitle = metadata.twitter?.title ?? metadata.title\n if (twTitle) tags.push({ tag: 'meta', name: 'twitter:title', content: twTitle })\n const twDesc = metadata.twitter?.description ?? metadata.description\n if (twDesc) tags.push({ tag: 'meta', name: 'twitter:description', content: twDesc })\n if (metadata.twitter?.card) tags.push({\n tag: 'meta', name: 'twitter:card', content:\n metadata.twitter.card\n })\n if (metadata.twitter?.image) tags.push({\n tag: 'meta', name: 'twitter:image', content:\n metadata.twitter.image\n })\n if (metadata.twitter?.creator) tags.push({\n tag: 'meta', name: 'twitter:creator', content:\n metadata.twitter.creator\n })\n\n if (metadata.canonical) tags.push({ tag: 'link', rel: 'canonical', href: metadata.canonical })\n if (metadata.robots) tags.push({ tag: 'meta', name: 'robots', content: metadata.robots })\n if (metadata.alternates) {\n for (const [lang, href] of Object.entries(metadata.alternates))\n tags.push({ tag: 'link', rel: 'alternate', href, hrefLang: lang })\n }\n\n if (metadata.icons) {\n const raw = Array.isArray(metadata.icons) ? metadata.icons : [metadata.icons]\n for (const icon of raw) {\n const resolved: MetadataIcon = typeof icon === 'string' ? { href: icon } : icon\n tags.push({\n tag: 'link',\n rel: resolved.rel ?? 'icon',\n href: resolved.href,\n ...(resolved.type && { type: resolved.type }),\n ...(resolved.sizes && { sizes: resolved.sizes }),\n })\n }\n }\n\n if (viewport) {\n const parts: string[] = []\n if (viewport.width !== undefined) parts.push(`width=${viewport.width}`)\n if (viewport.initialScale !== undefined) parts.push(`initial-scale=${viewport.initialScale}`)\n if (viewport.maximumScale !== undefined) parts.push(`maximum-scale=${viewport.maximumScale}`)\n if (viewport.userScalable !== undefined) parts.push(`user-scalable=${viewport.userScalable ? 'yes' :\n 'no'}`)\n if (parts.length) tags.push({ tag: 'meta', name: 'viewport', content: parts.join(', ') })\n if (viewport.themeColor) tags.push({\n tag: 'meta', name: 'theme-color', content: viewport.themeColor\n })\n }\n\n return tags\n}\n\nexport function HeadSlot({ metadata, viewport }: { metadata: Metadata | null, viewport?: Viewport }) {\n if (typeof window === 'undefined' || !metadata) return null\n return <>{buildHeadNodes(metadata, viewport)}</>\n}\n\nexport function buildHeadNodes(metadata: Metadata, viewport?: Viewport): ReactNode {\n const tags = collectTags(metadata, viewport)\n\n return <>\n {tags.map((t, i) => {\n if (t.tag === 'title') return <title key={i}>{t.children}</title>\n if (t.tag === 'link') return <link key={i} rel={t.rel} href={t.href} hrefLang={t.hrefLang} type={t.type} sizes={t.sizes} />\n return <meta key={i} name={t.name} property={t.property} content={t.content} />\n })}\n </>\n}", "import {Component, ComponentType, ReactNode} from \"react\";\nimport {ErrorProps} from \"../server/types\";\n\ninterface Props {\n ErrorPage?: ComponentType<ErrorProps>\n children: ReactNode\n}\n\ninterface State {\n error: ErrorProps | null\n}\n\nexport class DevixErrorBoundary extends Component<Props, State> {\n state: State = { error: null }\n\n static getDerivedStateFromError(err: unknown): State {\n if (err instanceof DevixError) {\n return {\n error: {statusCode: err.statusCode, message: err.message}\n }\n }\n return {\n error: {statusCode: 500, message: err instanceof Error ? err.message : 'Unknown error'}\n }\n }\n\n render() {\n if (this.state.error && this.props.ErrorPage) {\n return <this.props.ErrorPage {...this.state.error} />\n }\n if (this.state.error) {\n return <h1>{this.state.error.statusCode}</h1>\n }\n return this.props.children\n }\n}\n\nexport interface DevixErrorOptions {\n code?: string\n data?: unknown\n}\n\nexport class DevixError extends Error {\n statusCode: number\n code?: string\n data?: unknown\n constructor(statusCode: number, message: string, options?: DevixErrorOptions) {\n super(message)\n this.name = 'DevixError'\n this.statusCode = statusCode\n this.code = options?.code\n this.data = options?.data\n }\n}\n", "import {ComponentType, ReactNode} from 'react'\nimport {RouterContext, PageMetaContext, RouteDataContext, NavigateOptions} from './context'\nimport {HeadSlot} from './head'\nimport {DevixErrorBoundary} from './error-boundary'\nimport {LayoutProps, PageProps} from '../server/types'\nimport {Metadata, Viewport} from '../types'\n\nconst noopNavigate = (_to: string, _opts?: NavigateOptions) => Promise.resolve()\nconst noopRevalidate = () => Promise.resolve()\nconst noopPrefetch = (_href: string) => {}\n\nexport interface ServerAppProps {\n pathname: string\n params: Record<string, string>\n loaderData: unknown\n layoutsData: unknown[]\n guardData: unknown\n Page: ComponentType<PageProps>\n layouts: ComponentType<LayoutProps>[]\n metadata: Metadata | null\n viewport?: Viewport\n clientEntry: string\n}\n\nexport function ServerApp({\n pathname, params, loaderData, layoutsData, guardData,\n Page, layouts, metadata, viewport, clientEntry,\n}: ServerAppProps) {\n let tree: ReactNode = (\n <RouteDataContext value={{loaderData, params}}>\n <Page data={loaderData as any} params={params} url={pathname}/>\n </RouteDataContext>\n )\n\n for (let i = layouts.length - 1; i >= 0; i--) {\n const Layout = layouts[i]\n const layoutData = layoutsData[i]\n tree = (\n <RouteDataContext value={{loaderData: layoutData, params}}>\n <Layout data={layoutData as any} params={params}>{tree}</Layout>\n </RouteDataContext>\n )\n }\n\n return (\n <PageMetaContext value={{metadata, viewport, clientEntry}}>\n <HeadSlot metadata={metadata} viewport={viewport}/>\n <RouterContext value={{\n pathname,\n params,\n loaderData,\n layoutsData,\n guardData,\n Page,\n layouts,\n metadata,\n viewport,\n isNavigating: false,\n navigate: noopNavigate,\n revalidate: noopRevalidate,\n prefetchRoute: noopPrefetch,\n }}>\n <DevixErrorBoundary key={pathname}>\n {tree}\n </DevixErrorBoundary>\n </RouterContext>\n </PageMetaContext>\n )\n}\n"],
5
- "mappings": "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",
6
- "names": ["createContext", "g", "RouterContext", "PageMetaContext", "RouteDataContext", "Fragment", "jsx", "collectTags", "metadata", "viewport", "tags", "ogTitle", "ogDesc", "twTitle", "twDesc", "lang", "href", "raw", "icon", "resolved", "parts", "HeadSlot", "buildHeadNodes", "t", "i", "Component", "jsx", "DevixErrorBoundary", "err", "DevixError", "statusCode", "message", "options", "jsx", "jsxs", "noopNavigate", "_to", "_opts", "noopRevalidate", "noopPrefetch", "_href", "ServerApp", "pathname", "params", "loaderData", "layoutsData", "guardData", "Page", "layouts", "metadata", "viewport", "clientEntry", "tree", "RouteDataContext", "i", "Layout", "layoutData", "PageMetaContext", "HeadSlot", "RouterContext", "DevixErrorBoundary"]
4
+ "sourcesContent": ["import {createContext, Context, ComponentType} from \"react\";\nimport {Metadata, Viewport} from \"../types\";\nimport {LayoutProps, PageProps} from \"../server/types\";\n\nexport interface NavigateOptions {\n replace?: boolean\n viewTransition?: boolean\n}\n\nexport interface RouterContextValue {\n pathname: string\n params: Record<string, string>\n loaderData: unknown\n layoutsData: unknown[]\n guardData: unknown\n Page: ComponentType<PageProps>\n layouts: ComponentType<LayoutProps>[]\n metadata: Metadata | null\n viewport?: Viewport\n navigate: (to: string, options?: NavigateOptions) => Promise<void>\n revalidate: () => Promise<void>\n prefetchRoute: (href: string) => void\n isNavigating: boolean\n}\n\nexport interface PageMetaContextValue {\n metadata: Metadata | null\n viewport?: Viewport\n clientEntry?: string\n}\n\nexport interface RouteDataContextValue {\n loaderData: unknown\n params: Record<string, string>\n}\n\nconst g = globalThis as any\n\ng.__devix_RouterContext__ ??= createContext<RouterContextValue | null>(null)\nexport const RouterContext: Context<RouterContextValue | null> = g.__devix_RouterContext__\n\ng.__devix_PageMetaContext__ ??= createContext<PageMetaContextValue | null>(null)\ng.__devix_RouteDataContext__ ??= createContext<RouteDataContextValue | null>(null)\n\nexport const PageMetaContext: Context<PageMetaContextValue | null> = g.__devix_PageMetaContext__\nexport const RouteDataContext: Context<RouteDataContextValue | null> = g.__devix_RouteDataContext__\n\n", "import { Metadata, MetadataIcon, Viewport } from \"../types\";\nimport { ReactNode } from \"react\";\n\ntype MetaTag =\n | { tag: 'title'; children: string }\n | { tag: 'meta'; name?: string; property?: string; content: string }\n | { tag: 'link'; rel: string; href: string; hrefLang?: string; type?: string; sizes?: string }\n\nfunction collectTags(metadata: Metadata, viewport?: Viewport): MetaTag[] {\n const tags: MetaTag[] = []\n\n if (metadata.title)\n tags.push({ tag: 'title', children: metadata.title })\n if (metadata.description)\n tags.push({ tag: 'meta', name: 'description', content: metadata.description })\n if (metadata.keywords?.length)\n tags.push({ tag: 'meta', name: 'keywords', content: metadata.keywords.join(', ') })\n\n const ogTitle = metadata.og?.title ?? metadata.title\n if (ogTitle) tags.push({ tag: 'meta', property: 'og:title', content: ogTitle })\n const ogDesc = metadata.og?.description ?? metadata.description\n if (ogDesc) tags.push({ tag: 'meta', property: 'og:description', content: ogDesc })\n if (metadata.og?.image) tags.push({ tag: 'meta', property: 'og:image', content: metadata.og.image })\n if (metadata.og?.type) tags.push({ tag: 'meta', property: 'og:type', content: metadata.og.type })\n if (metadata.og?.url) tags.push({ tag: 'meta', property: 'og:url', content: metadata.og.url })\n\n const twTitle = metadata.twitter?.title ?? metadata.title\n if (twTitle) tags.push({ tag: 'meta', name: 'twitter:title', content: twTitle })\n const twDesc = metadata.twitter?.description ?? metadata.description\n if (twDesc) tags.push({ tag: 'meta', name: 'twitter:description', content: twDesc })\n if (metadata.twitter?.card) tags.push({\n tag: 'meta', name: 'twitter:card', content:\n metadata.twitter.card\n })\n if (metadata.twitter?.image) tags.push({\n tag: 'meta', name: 'twitter:image', content:\n metadata.twitter.image\n })\n if (metadata.twitter?.creator) tags.push({\n tag: 'meta', name: 'twitter:creator', content:\n metadata.twitter.creator\n })\n\n if (metadata.canonical) tags.push({ tag: 'link', rel: 'canonical', href: metadata.canonical })\n if (metadata.robots) tags.push({ tag: 'meta', name: 'robots', content: metadata.robots })\n if (metadata.alternates) {\n for (const [lang, href] of Object.entries(metadata.alternates))\n tags.push({ tag: 'link', rel: 'alternate', href, hrefLang: lang })\n }\n\n if (metadata.icons) {\n const raw = Array.isArray(metadata.icons) ? metadata.icons : [metadata.icons]\n for (const icon of raw) {\n const resolved: MetadataIcon = typeof icon === 'string' ? { href: icon } : icon\n tags.push({\n tag: 'link',\n rel: resolved.rel ?? 'icon',\n href: resolved.href,\n ...(resolved.type && { type: resolved.type }),\n ...(resolved.sizes && { sizes: resolved.sizes }),\n })\n }\n }\n\n if (viewport) {\n const parts: string[] = []\n if (viewport.width !== undefined) parts.push(`width=${viewport.width}`)\n if (viewport.initialScale !== undefined) parts.push(`initial-scale=${viewport.initialScale}`)\n if (viewport.maximumScale !== undefined) parts.push(`maximum-scale=${viewport.maximumScale}`)\n if (viewport.userScalable !== undefined) parts.push(`user-scalable=${viewport.userScalable ? 'yes' :\n 'no'}`)\n if (parts.length) tags.push({ tag: 'meta', name: 'viewport', content: parts.join(', ') })\n if (viewport.themeColor) tags.push({\n tag: 'meta', name: 'theme-color', content: viewport.themeColor\n })\n }\n\n return tags\n}\n\nexport function HeadSlot({ metadata, viewport }: { metadata: Metadata | null, viewport?: Viewport }) {\n if (typeof window === 'undefined' || !metadata) return null\n return <>{buildHeadNodes(metadata, viewport)}</>\n}\n\nexport function buildHeadNodes(metadata: Metadata, viewport?: Viewport): ReactNode {\n const tags = collectTags(metadata, viewport)\n\n return <>\n {tags.map((t, i) => {\n if (t.tag === 'title') return <title key={i}>{t.children}</title>\n if (t.tag === 'link') return <link key={i} rel={t.rel} href={t.href} hrefLang={t.hrefLang} type={t.type} sizes={t.sizes} />\n return <meta key={i} name={t.name} property={t.property} content={t.content} />\n })}\n </>\n}", "import {Component, ComponentType, ReactNode} from \"react\";\nimport {ErrorProps} from \"../server/types\";\n\ninterface Props {\n ErrorPage?: ComponentType<ErrorProps>\n children: ReactNode\n}\n\ninterface State {\n error: ErrorProps | null\n}\n\nexport class DevixErrorBoundary extends Component<Props, State> {\n state: State = { error: null }\n\n static getDerivedStateFromError(err: unknown): State {\n if (err instanceof DevixError) {\n return {\n error: {statusCode: err.statusCode, message: err.message}\n }\n }\n return {\n error: {statusCode: 500, message: err instanceof Error ? err.message : 'Unknown error'}\n }\n }\n\n render() {\n if (this.state.error && this.props.ErrorPage) {\n return <this.props.ErrorPage {...this.state.error} />\n }\n if (this.state.error) {\n return <h1>{this.state.error.statusCode}</h1>\n }\n return this.props.children\n }\n}\n\nexport interface DevixErrorOptions {\n code?: string\n data?: unknown\n}\n\nconst DEVIX_ERROR_BRAND = Symbol.for('@devlusoft/devix.DevixError')\n\nexport class DevixError extends Error {\n /**\n * Custom `instanceof` que matchea por brand cross-bundle. Ver nota en\n * `FetchError` para el detalle del dual package hazard.\n */\n static [Symbol.hasInstance](value: unknown): boolean {\n return value !== null && typeof value === 'object' && (value as any)[DEVIX_ERROR_BRAND] === true\n }\n\n statusCode: number\n code?: string\n data?: unknown\n constructor(statusCode: number, message: string, options?: DevixErrorOptions) {\n super(message)\n this.name = 'DevixError'\n this.statusCode = statusCode\n this.code = options?.code\n this.data = options?.data\n ;(this as any)[DEVIX_ERROR_BRAND] = true\n }\n}\n", "import {ComponentType, ReactNode} from 'react'\nimport {RouterContext, PageMetaContext, RouteDataContext, NavigateOptions} from './context'\nimport {HeadSlot} from './head'\nimport {DevixErrorBoundary} from './error-boundary'\nimport {LayoutProps, PageProps} from '../server/types'\nimport {Metadata, Viewport} from '../types'\n\nconst noopNavigate = (_to: string, _opts?: NavigateOptions) => Promise.resolve()\nconst noopRevalidate = () => Promise.resolve()\nconst noopPrefetch = (_href: string) => {}\n\nexport interface ServerAppProps {\n pathname: string\n params: Record<string, string>\n loaderData: unknown\n layoutsData: unknown[]\n guardData: unknown\n Page: ComponentType<PageProps>\n layouts: ComponentType<LayoutProps>[]\n metadata: Metadata | null\n viewport?: Viewport\n clientEntry: string\n}\n\nexport function ServerApp({\n pathname, params, loaderData, layoutsData, guardData,\n Page, layouts, metadata, viewport, clientEntry,\n}: ServerAppProps) {\n let tree: ReactNode = (\n <RouteDataContext value={{loaderData, params}}>\n <Page data={loaderData as any} params={params} url={pathname}/>\n </RouteDataContext>\n )\n\n for (let i = layouts.length - 1; i >= 0; i--) {\n const Layout = layouts[i]\n const layoutData = layoutsData[i]\n tree = (\n <RouteDataContext value={{loaderData: layoutData, params}}>\n <Layout data={layoutData as any} params={params}>{tree}</Layout>\n </RouteDataContext>\n )\n }\n\n return (\n <PageMetaContext value={{metadata, viewport, clientEntry}}>\n <HeadSlot metadata={metadata} viewport={viewport}/>\n <RouterContext value={{\n pathname,\n params,\n loaderData,\n layoutsData,\n guardData,\n Page,\n layouts,\n metadata,\n viewport,\n isNavigating: false,\n navigate: noopNavigate,\n revalidate: noopRevalidate,\n prefetchRoute: noopPrefetch,\n }}>\n <DevixErrorBoundary key={pathname}>\n {tree}\n </DevixErrorBoundary>\n </RouterContext>\n </PageMetaContext>\n )\n}\n"],
5
+ "mappings": "AAAA,OAAQ,iBAAAA,MAA4C,QAoCpD,IAAMC,EAAI,WAEVA,EAAE,0BAA4BD,EAAyC,IAAI,EACpE,IAAME,EAAoDD,EAAE,wBAEnEA,EAAE,4BAA8BD,EAA2C,IAAI,EAC/EC,EAAE,6BAA+BD,EAA4C,IAAI,EAE1E,IAAMG,EAAwDF,EAAE,0BAC1DG,EAA0DH,EAAE,2BCqC9D,mBAAAI,EAAA,OAAAC,MAAA,oBA1EX,SAASC,EAAYC,EAAoBC,EAAgC,CACrE,IAAMC,EAAkB,CAAC,EAErBF,EAAS,OACTE,EAAK,KAAK,CAAE,IAAK,QAAS,SAAUF,EAAS,KAAM,CAAC,EACpDA,EAAS,aACTE,EAAK,KAAK,CAAE,IAAK,OAAQ,KAAM,cAAe,QAASF,EAAS,WAAY,CAAC,EAC7EA,EAAS,UAAU,QACnBE,EAAK,KAAK,CAAE,IAAK,OAAQ,KAAM,WAAY,QAASF,EAAS,SAAS,KAAK,IAAI,CAAE,CAAC,EAEtF,IAAMG,EAAUH,EAAS,IAAI,OAASA,EAAS,MAC3CG,GAASD,EAAK,KAAK,CAAE,IAAK,OAAQ,SAAU,WAAY,QAASC,CAAQ,CAAC,EAC9E,IAAMC,EAASJ,EAAS,IAAI,aAAeA,EAAS,YAChDI,GAAQF,EAAK,KAAK,CAAE,IAAK,OAAQ,SAAU,iBAAkB,QAASE,CAAO,CAAC,EAC9EJ,EAAS,IAAI,OAAOE,EAAK,KAAK,CAAE,IAAK,OAAQ,SAAU,WAAY,QAASF,EAAS,GAAG,KAAM,CAAC,EAC/FA,EAAS,IAAI,MAAME,EAAK,KAAK,CAAE,IAAK,OAAQ,SAAU,UAAW,QAASF,EAAS,GAAG,IAAK,CAAC,EAC5FA,EAAS,IAAI,KAAKE,EAAK,KAAK,CAAE,IAAK,OAAQ,SAAU,SAAU,QAASF,EAAS,GAAG,GAAI,CAAC,EAE7F,IAAMK,EAAUL,EAAS,SAAS,OAASA,EAAS,MAChDK,GAASH,EAAK,KAAK,CAAE,IAAK,OAAQ,KAAM,gBAAiB,QAASG,CAAQ,CAAC,EAC/E,IAAMC,EAASN,EAAS,SAAS,aAAeA,EAAS,YAiBzD,GAhBIM,GAAQJ,EAAK,KAAK,CAAE,IAAK,OAAQ,KAAM,sBAAuB,QAASI,CAAO,CAAC,EAC/EN,EAAS,SAAS,MAAME,EAAK,KAAK,CAClC,IAAK,OAAQ,KAAM,eAAgB,QAC/BF,EAAS,QAAQ,IACzB,CAAC,EACGA,EAAS,SAAS,OAAOE,EAAK,KAAK,CACnC,IAAK,OAAQ,KAAM,gBAAiB,QAChCF,EAAS,QAAQ,KACzB,CAAC,EACGA,EAAS,SAAS,SAASE,EAAK,KAAK,CACrC,IAAK,OAAQ,KAAM,kBAAmB,QAClCF,EAAS,QAAQ,OACzB,CAAC,EAEGA,EAAS,WAAWE,EAAK,KAAK,CAAE,IAAK,OAAQ,IAAK,YAAa,KAAMF,EAAS,SAAU,CAAC,EACzFA,EAAS,QAAQE,EAAK,KAAK,CAAE,IAAK,OAAQ,KAAM,SAAU,QAASF,EAAS,MAAO,CAAC,EACpFA,EAAS,WACT,OAAW,CAACO,EAAMC,CAAI,IAAK,OAAO,QAAQR,EAAS,UAAU,EACzDE,EAAK,KAAK,CAAE,IAAK,OAAQ,IAAK,YAAa,KAAAM,EAAM,SAAUD,CAAK,CAAC,EAGzE,GAAIP,EAAS,MAAO,CAChB,IAAMS,EAAM,MAAM,QAAQT,EAAS,KAAK,EAAIA,EAAS,MAAQ,CAACA,EAAS,KAAK,EAC5E,QAAWU,KAAQD,EAAK,CACpB,IAAME,EAAyB,OAAOD,GAAS,SAAW,CAAE,KAAMA,CAAK,EAAIA,EAC3ER,EAAK,KAAK,CACN,IAAK,OACL,IAAKS,EAAS,KAAO,OACrB,KAAMA,EAAS,KACf,GAAIA,EAAS,MAAQ,CAAE,KAAMA,EAAS,IAAK,EAC3C,GAAIA,EAAS,OAAS,CAAE,MAAOA,EAAS,KAAM,CAClD,CAAC,CACL,CACJ,CAEA,GAAIV,EAAU,CACV,IAAMW,EAAkB,CAAC,EACrBX,EAAS,QAAU,QAAWW,EAAM,KAAK,SAASX,EAAS,KAAK,EAAE,EAClEA,EAAS,eAAiB,QAAWW,EAAM,KAAK,iBAAiBX,EAAS,YAAY,EAAE,EACxFA,EAAS,eAAiB,QAAWW,EAAM,KAAK,iBAAiBX,EAAS,YAAY,EAAE,EACxFA,EAAS,eAAiB,QAAWW,EAAM,KAAK,iBAAiBX,EAAS,aAAe,MACzF,IAAI,EAAE,EACNW,EAAM,QAAQV,EAAK,KAAK,CAAE,IAAK,OAAQ,KAAM,WAAY,QAASU,EAAM,KAAK,IAAI,CAAE,CAAC,EACpFX,EAAS,YAAYC,EAAK,KAAK,CAC/B,IAAK,OAAQ,KAAM,cAAe,QAASD,EAAS,UACxD,CAAC,CACL,CAEA,OAAOC,CACX,CAEO,SAASW,EAAS,CAAE,SAAAb,EAAU,SAAAC,CAAS,EAAuD,CACjG,OAAI,OAAO,OAAW,KAAe,CAACD,EAAiB,KAChDF,EAAAD,EAAA,CAAG,SAAAiB,EAAed,EAAUC,CAAQ,EAAE,CACjD,CAEO,SAASa,EAAed,EAAoBC,EAAgC,CAC/E,IAAMC,EAAOH,EAAYC,EAAUC,CAAQ,EAE3C,OAAOH,EAAAD,EAAA,CACF,SAAAK,EAAK,IAAI,CAACa,EAAGC,IACND,EAAE,MAAQ,QAAgBjB,EAAC,SAAe,SAAAiB,EAAE,UAANC,CAAe,EACrDD,EAAE,MAAQ,OAAejB,EAAC,QAAa,IAAKiB,EAAE,IAAK,KAAMA,EAAE,KAAM,SAAUA,EAAE,SAAU,KAAMA,EAAE,KAAM,MAAOA,EAAE,OAA1EC,CAAiF,EAClHlB,EAAC,QAAa,KAAMiB,EAAE,KAAM,SAAUA,EAAE,SAAU,QAASA,EAAE,SAAlDC,CAA2D,CAChF,EACL,CACJ,CC/FA,OAAQ,aAAAC,MAA0C,QA4B/B,cAAAC,MAAA,oBAhBZ,IAAMC,EAAN,cAAiCF,CAAwB,CAC5D,MAAe,CAAE,MAAO,IAAK,EAE7B,OAAO,yBAAyBG,EAAqB,CACjD,OAAIA,aAAeC,EACR,CACH,MAAO,CAAC,WAAYD,EAAI,WAAY,QAASA,EAAI,OAAO,CAC5D,EAEI,CACJ,MAAO,CAAC,WAAY,IAAK,QAASA,aAAe,MAAQA,EAAI,QAAU,eAAe,CAC1F,CACJ,CAEA,QAAS,CACL,OAAI,KAAK,MAAM,OAAS,KAAK,MAAM,UACxBF,EAAC,KAAK,MAAM,UAAX,CAAsB,GAAG,KAAK,MAAM,MAAO,EAEnD,KAAK,MAAM,MACJA,EAAC,MAAI,cAAK,MAAM,MAAM,WAAW,EAErC,KAAK,MAAM,QACtB,CACJ,EAOMI,EAAoB,OAAO,IAAI,6BAA6B,EAErDD,EAAN,cAAyB,KAAM,CAKlC,OAAQ,OAAO,WAAW,EAAEE,EAAyB,CACjD,OAAOA,IAAU,MAAQ,OAAOA,GAAU,UAAaA,EAAcD,CAAiB,IAAM,EAChG,CAEA,WACA,KACA,KACA,YAAYE,EAAoBC,EAAiBC,EAA6B,CAC1E,MAAMD,CAAO,EACb,KAAK,KAAO,aACZ,KAAK,WAAaD,EAClB,KAAK,KAAOE,GAAS,KACrB,KAAK,KAAOA,GAAS,KACnB,KAAaJ,CAAiB,EAAI,EACxC,CACJ,EClCY,cAAAK,EAeJ,QAAAC,MAfI,oBAvBZ,IAAMC,EAAe,CAACC,EAAaC,IAA4B,QAAQ,QAAQ,EACzEC,EAAiB,IAAM,QAAQ,QAAQ,EACvCC,EAAgBC,GAAkB,CAAC,EAelC,SAASC,EAAU,CACtB,SAAAC,EAAU,OAAAC,EAAQ,WAAAC,EAAY,YAAAC,EAAa,UAAAC,EAC3C,KAAAC,EAAM,QAAAC,EAAS,SAAAC,EAAU,SAAAC,EAAU,YAAAC,CACvC,EAAmB,CACf,IAAIC,EACAnB,EAACoB,EAAA,CAAiB,MAAO,CAAC,WAAAT,EAAY,OAAAD,CAAM,EACxC,SAAAV,EAACc,EAAA,CAAK,KAAMH,EAAmB,OAAQD,EAAQ,IAAKD,EAAS,EACjE,EAGJ,QAASY,EAAIN,EAAQ,OAAS,EAAGM,GAAK,EAAGA,IAAK,CAC1C,IAAMC,EAASP,EAAQM,CAAC,EAClBE,EAAaX,EAAYS,CAAC,EAChCF,EACInB,EAACoB,EAAA,CAAiB,MAAO,CAAC,WAAYG,EAAY,OAAAb,CAAM,EACpD,SAAAV,EAACsB,EAAA,CAAO,KAAMC,EAAmB,OAAQb,EAAS,SAAAS,EAAK,EAC3D,CAER,CAEA,OACIlB,EAACuB,EAAA,CAAgB,MAAO,CAAC,SAAAR,EAAU,SAAAC,EAAU,YAAAC,CAAW,EACpD,UAAAlB,EAACyB,EAAA,CAAS,SAAUT,EAAU,SAAUC,EAAS,EACjDjB,EAAC0B,EAAA,CAAc,MAAO,CAClB,SAAAjB,EACA,OAAAC,EACA,WAAAC,EACA,YAAAC,EACA,UAAAC,EACA,KAAAC,EACA,QAAAC,EACA,SAAAC,EACA,SAAAC,EACA,aAAc,GACd,SAAUf,EACV,WAAYG,EACZ,cAAeC,CACnB,EACI,SAAAN,EAAC2B,EAAA,CACI,SAAAR,GADoBV,CAEzB,EACJ,GACJ,CAER",
6
+ "names": ["createContext", "g", "RouterContext", "PageMetaContext", "RouteDataContext", "Fragment", "jsx", "collectTags", "metadata", "viewport", "tags", "ogTitle", "ogDesc", "twTitle", "twDesc", "lang", "href", "raw", "icon", "resolved", "parts", "HeadSlot", "buildHeadNodes", "t", "i", "Component", "jsx", "DevixErrorBoundary", "err", "DevixError", "DEVIX_ERROR_BRAND", "value", "statusCode", "message", "options", "jsx", "jsxs", "noopNavigate", "_to", "_opts", "noopRevalidate", "noopPrefetch", "_href", "ServerApp", "pathname", "params", "loaderData", "layoutsData", "guardData", "Page", "layouts", "metadata", "viewport", "clientEntry", "tree", "RouteDataContext", "i", "Layout", "layoutData", "PageMetaContext", "HeadSlot", "RouterContext", "DevixErrorBoundary"]
7
7
  }
@@ -1,2 +1,2 @@
1
- function h(n){if(n&&typeof n=="object"&&"message"in n){let e=n.message;if(typeof e=="string"&&e.length>0)return e}return null}var p=class extends Error{constructor(t,s,u,r){super(h(r)??`HTTP ${t}: ${s}`);this.status=t;this.statusText=s;this.response=u;this.body=r;this.name="FetchError"}get code(){if(this.body&&typeof this.body=="object"&&"code"in this.body){let t=this.body.code;return typeof t=="string"?t:void 0}}};var g="/_devix/server";async function i(n,e,t,s,u){let r=new Headers(u?.headers),c;s!=null&&(s instanceof FormData||s instanceof Blob||s instanceof ArrayBuffer?c=s:(c=JSON.stringify(s),r.has("Content-Type")||r.set("Content-Type","application/json")));let l=`${g}/${n}${t}`,o=await fetch(l,{method:e,headers:r,body:c,signal:u?.signal}),a=o.status===204||o.headers.get("Content-Length")==="0";if(!o.ok){let f=o.headers.get("Content-Type")??"",d;if(!a&&f.includes("application/json"))try{d=await o.json()}catch{}throw new p(o.status,o.statusText,o,d)}return a?null:(o.headers.get("Content-Type")??"").includes("application/json")?await o.json():await o.text()}function T(n){return{get:(e,t)=>i(n,"GET",e,void 0,t),post:(e,t,s)=>i(n,"POST",e,t,s),put:(e,t,s)=>i(n,"PUT",e,t,s),patch:(e,t,s)=>i(n,"PATCH",e,t,s),delete:(e,t)=>i(n,"DELETE",e,void 0,t)}}var R=new Proxy({},{get(n,e){if(typeof e=="string")return n[e]||(n[e]=T(e)),n[e]}});export{R as $server};
1
+ function T(t){if(t&&typeof t=="object"&&"message"in t){let n=t.message;if(typeof n=="string"&&n.length>0)return n}return null}var l=Symbol.for("@devlusoft/devix.FetchError"),p=class extends Error{constructor(e,s,c,r){super(T(r)??`HTTP ${e}: ${s}`);this.status=e;this.statusText=s;this.response=c;this.body=r;this.name="FetchError",this[l]=!0}static[Symbol.hasInstance](e){return e!==null&&typeof e=="object"&&e[l]===!0}get code(){if(this.body&&typeof this.body=="object"&&"code"in this.body){let e=this.body.code;return typeof e=="string"?e:void 0}}};var g="/_devix/server";async function i(t,n,e,s,c){let r=new Headers(c?.headers),u;s!=null&&(s instanceof FormData||s instanceof Blob||s instanceof ArrayBuffer?u=s:(u=JSON.stringify(s),r.has("Content-Type")||r.set("Content-Type","application/json")));let f=`${g}/${t}${e}`,o=await fetch(f,{method:n,headers:r,body:u,signal:c?.signal}),a=o.status===204||o.headers.get("Content-Length")==="0";if(!o.ok){let h=o.headers.get("Content-Type")??"",d;if(!a&&h.includes("application/json"))try{d=await o.json()}catch{}throw new p(o.status,o.statusText,o,d)}return a?null:(o.headers.get("Content-Type")??"").includes("application/json")?await o.json():await o.text()}function y(t){return{get:(n,e)=>i(t,"GET",n,void 0,e),post:(n,e,s)=>i(t,"POST",n,e,s),put:(n,e,s)=>i(t,"PUT",n,e,s),patch:(n,e,s)=>i(t,"PATCH",n,e,s),delete:(n,e)=>i(t,"DELETE",n,void 0,e)}}var E=new Proxy({},{get(t,n){if(typeof n=="string")return t[n]||(t[n]=y(n)),t[n]}});export{E as $server};
2
2
  //# sourceMappingURL=server-client.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/runtime/fetch.ts", "../../src/runtime/server-client.ts"],
4
- "sourcesContent": ["export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'\n\nfunction extractMessage(body: unknown): string | null {\n if (body && typeof body === 'object' && 'message' in body) {\n const m = (body as {message: unknown}).message\n if (typeof m === 'string' && m.length > 0) return m\n }\n return null\n}\n\nexport class FetchError<E = unknown> extends Error {\n constructor(\n public readonly status: number,\n public readonly statusText: string,\n public readonly response: Response,\n public readonly body?: E,\n ) {\n super(extractMessage(body) ?? `HTTP ${status}: ${statusText}`)\n this.name = 'FetchError'\n }\n\n get code(): string | undefined {\n if (this.body && typeof this.body === 'object' && 'code' in this.body) {\n const c = (this.body as {code: unknown}).code\n return typeof c === 'string' ? c : undefined\n }\n return undefined\n }\n}\n", "import {FetchError, type HttpMethod} from './fetch'\n\nexport interface ServerFetchOptions {\n headers?: HeadersInit\n signal?: AbortSignal\n}\n\nconst PROXY_PREFIX = '/_devix/server'\n\nasync function proxyFetch<TResponse>(\n namespace: string,\n method: HttpMethod,\n path: string,\n body: unknown,\n options?: ServerFetchOptions,\n): Promise<TResponse> {\n const headers = new Headers(options?.headers)\n let sendBody: BodyInit | undefined\n if (body !== undefined && body !== null) {\n if (body instanceof FormData || body instanceof Blob || body instanceof ArrayBuffer) {\n sendBody = body\n } else {\n sendBody = JSON.stringify(body)\n if (!headers.has('Content-Type')) headers.set('Content-Type', 'application/json')\n }\n }\n\n const url = `${PROXY_PREFIX}/${namespace}${path}`\n const response = await fetch(url, {method, headers, body: sendBody, signal: options?.signal})\n\n const isEmptyBody = response.status === 204 || response.headers.get('Content-Length') === '0'\n\n if (!response.ok) {\n const ct = response.headers.get('Content-Type') ?? ''\n let errorBody: unknown\n if (!isEmptyBody && ct.includes('application/json')) {\n try { errorBody = await response.json() } catch { /* body vac\u00EDo o inv\u00E1lido */ }\n }\n throw new FetchError(response.status, response.statusText, response, errorBody)\n }\n\n if (isEmptyBody) return null as TResponse\n\n const ct = response.headers.get('Content-Type') ?? ''\n if (ct.includes('application/json')) return await response.json() as TResponse\n return await response.text() as unknown as TResponse\n}\n\n/**\n * Cliente para llamar a un backend remoto configurado en `devix.config.ts`.\n *\n * El tipo de respuesta se declara en cada call site con un generic:\n *\n * ```ts\n * const me = await $server.api.get<User>('/v1/me')\n * const post = await $server.api.post<Post>('/v1/posts', { title: 'Hola' })\n * ```\n *\n * Si no pasas el generic, el retorno es `unknown`. devix no puede inferir tipos del\n * backend remoto (vive fuera del repo) \u2014 el cast en el call site ES el contrato.\n */\nexport interface BackendClient {\n get<TResponse = unknown>(path: string, options?: ServerFetchOptions): Promise<TResponse>\n post<TResponse = unknown>(path: string, body?: unknown, options?: ServerFetchOptions): Promise<TResponse>\n put<TResponse = unknown>(path: string, body?: unknown, options?: ServerFetchOptions): Promise<TResponse>\n patch<TResponse = unknown>(path: string, body?: unknown, options?: ServerFetchOptions): Promise<TResponse>\n delete<TResponse = unknown>(path: string, options?: ServerFetchOptions): Promise<TResponse>\n}\n\nfunction makeBackendClient(namespace: string): BackendClient {\n return {\n get: (path, options) => proxyFetch(namespace, 'GET', path, undefined, options),\n post: (path, body, options) => proxyFetch(namespace, 'POST', path, body, options),\n put: (path, body, options) => proxyFetch(namespace, 'PUT', path, body, options),\n patch: (path, body, options) => proxyFetch(namespace, 'PATCH', path, body, options),\n delete: (path, options) => proxyFetch(namespace, 'DELETE', path, undefined, options),\n }\n}\n\n/**\n * Cliente para llamar a backends remotos configurados en `devix.config.ts`.\n *\n * En cliente: las requests pasan por el proxy interno `/_devix/server/<namespace>/...`\n * donde devix aplica `prepare` (auth pass-through, tracing, etc.) y reenv\u00EDa al backend.\n *\n * En server (loaders/handlers): NO uses este import \u2014 usa `ctx.$server` que recibe\n * el request del usuario para que `prepare` pueda leer cookies.\n *\n * ```ts\n * const me = await $server.api.get<User>('/v1/me')\n * const post = await $server.api.post<Post>('/v1/posts', { title: 'Hola' })\n * ```\n */\nexport const $server: Record<string, BackendClient> = new Proxy({} as Record<string, BackendClient>, {\n get(target, namespace: string) {\n if (typeof namespace !== 'string') return undefined\n if (!target[namespace]) target[namespace] = makeBackendClient(namespace)\n return target[namespace]\n },\n})\n"],
5
- "mappings": "AAEA,SAASA,EAAeC,EAA8B,CAClD,GAAIA,GAAQ,OAAOA,GAAS,UAAY,YAAaA,EAAM,CACvD,IAAMC,EAAKD,EAA4B,QACvC,GAAI,OAAOC,GAAM,UAAYA,EAAE,OAAS,EAAG,OAAOA,CACtD,CACA,OAAO,IACX,CAEO,IAAMC,EAAN,cAAsC,KAAM,CAC/C,YACoBC,EACAC,EACAC,EACAL,EAClB,CACE,MAAMD,EAAeC,CAAI,GAAK,QAAQG,CAAM,KAAKC,CAAU,EAAE,EAL7C,YAAAD,EACA,gBAAAC,EACA,cAAAC,EACA,UAAAL,EAGhB,KAAK,KAAO,YAChB,CAEA,IAAI,MAA2B,CAC3B,GAAI,KAAK,MAAQ,OAAO,KAAK,MAAS,UAAY,SAAU,KAAK,KAAM,CACnE,IAAMM,EAAK,KAAK,KAAyB,KACzC,OAAO,OAAOA,GAAM,SAAWA,EAAI,MACvC,CAEJ,CACJ,ECrBA,IAAMC,EAAe,iBAErB,eAAeC,EACXC,EACAC,EACAC,EACAC,EACAC,EACkB,CAClB,IAAMC,EAAU,IAAI,QAAQD,GAAS,OAAO,EACxCE,EACsBH,GAAS,OAC3BA,aAAgB,UAAYA,aAAgB,MAAQA,aAAgB,YACpEG,EAAWH,GAEXG,EAAW,KAAK,UAAUH,CAAI,EACzBE,EAAQ,IAAI,cAAc,GAAGA,EAAQ,IAAI,eAAgB,kBAAkB,IAIxF,IAAME,EAAM,GAAGT,CAAY,IAAIE,CAAS,GAAGE,CAAI,GACzCM,EAAW,MAAM,MAAMD,EAAK,CAAC,OAAAN,EAAQ,QAAAI,EAAS,KAAMC,EAAU,OAAQF,GAAS,MAAM,CAAC,EAEtFK,EAAcD,EAAS,SAAW,KAAOA,EAAS,QAAQ,IAAI,gBAAgB,IAAM,IAE1F,GAAI,CAACA,EAAS,GAAI,CACd,IAAME,EAAKF,EAAS,QAAQ,IAAI,cAAc,GAAK,GAC/CG,EACJ,GAAI,CAACF,GAAeC,EAAG,SAAS,kBAAkB,EAC9C,GAAI,CAAEC,EAAY,MAAMH,EAAS,KAAK,CAAE,MAAQ,CAA8B,CAElF,MAAM,IAAII,EAAWJ,EAAS,OAAQA,EAAS,WAAYA,EAAUG,CAAS,CAClF,CAEA,OAAIF,EAAoB,MAEbD,EAAS,QAAQ,IAAI,cAAc,GAAK,IAC5C,SAAS,kBAAkB,EAAU,MAAMA,EAAS,KAAK,EACzD,MAAMA,EAAS,KAAK,CAC/B,CAuBA,SAASK,EAAkBb,EAAkC,CACzD,MAAO,CACH,IAAK,CAACE,EAAME,IAAYL,EAAWC,EAAW,MAAOE,EAAM,OAAWE,CAAO,EAC7E,KAAM,CAACF,EAAMC,EAAMC,IAAYL,EAAWC,EAAW,OAAQE,EAAMC,EAAMC,CAAO,EAChF,IAAK,CAACF,EAAMC,EAAMC,IAAYL,EAAWC,EAAW,MAAOE,EAAMC,EAAMC,CAAO,EAC9E,MAAO,CAACF,EAAMC,EAAMC,IAAYL,EAAWC,EAAW,QAASE,EAAMC,EAAMC,CAAO,EAClF,OAAQ,CAACF,EAAME,IAAYL,EAAWC,EAAW,SAAUE,EAAM,OAAWE,CAAO,CACvF,CACJ,CAgBO,IAAMU,EAAyC,IAAI,MAAM,CAAC,EAAoC,CACjG,IAAIC,EAAQf,EAAmB,CAC3B,GAAI,OAAOA,GAAc,SACzB,OAAKe,EAAOf,CAAS,IAAGe,EAAOf,CAAS,EAAIa,EAAkBb,CAAS,GAChEe,EAAOf,CAAS,CAC3B,CACJ,CAAC",
6
- "names": ["extractMessage", "body", "m", "FetchError", "status", "statusText", "response", "c", "PROXY_PREFIX", "proxyFetch", "namespace", "method", "path", "body", "options", "headers", "sendBody", "url", "response", "isEmptyBody", "ct", "errorBody", "FetchError", "makeBackendClient", "$server", "target"]
4
+ "sourcesContent": ["export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'\n\nfunction extractMessage(body: unknown): string | null {\n if (body && typeof body === 'object' && 'message' in body) {\n const m = (body as {message: unknown}).message\n if (typeof m === 'string' && m.length > 0) return m\n }\n return null\n}\n\nconst FETCH_ERROR_BRAND = Symbol.for('@devlusoft/devix.FetchError')\n\nexport class FetchError<E = unknown> extends Error {\n static [Symbol.hasInstance](value: unknown): boolean {\n return value !== null && typeof value === 'object' && (value as any)[FETCH_ERROR_BRAND] === true\n }\n\n constructor(\n public readonly status: number,\n public readonly statusText: string,\n public readonly response: Response,\n public readonly body?: E,\n ) {\n super(extractMessage(body) ?? `HTTP ${status}: ${statusText}`)\n this.name = 'FetchError'\n ;(this as any)[FETCH_ERROR_BRAND] = true\n }\n\n get code(): string | undefined {\n if (this.body && typeof this.body === 'object' && 'code' in this.body) {\n const c = (this.body as {code: unknown}).code\n return typeof c === 'string' ? c : undefined\n }\n return undefined\n }\n}\n", "import {FetchError, type HttpMethod} from './fetch'\n\nexport interface ServerFetchOptions {\n headers?: HeadersInit\n signal?: AbortSignal\n}\n\nconst PROXY_PREFIX = '/_devix/server'\n\nasync function proxyFetch<TResponse>(\n namespace: string,\n method: HttpMethod,\n path: string,\n body: unknown,\n options?: ServerFetchOptions,\n): Promise<TResponse> {\n const headers = new Headers(options?.headers)\n let sendBody: BodyInit | undefined\n if (body !== undefined && body !== null) {\n if (body instanceof FormData || body instanceof Blob || body instanceof ArrayBuffer) {\n sendBody = body\n } else {\n sendBody = JSON.stringify(body)\n if (!headers.has('Content-Type')) headers.set('Content-Type', 'application/json')\n }\n }\n\n const url = `${PROXY_PREFIX}/${namespace}${path}`\n const response = await fetch(url, {method, headers, body: sendBody, signal: options?.signal})\n\n const isEmptyBody = response.status === 204 || response.headers.get('Content-Length') === '0'\n\n if (!response.ok) {\n const ct = response.headers.get('Content-Type') ?? ''\n let errorBody: unknown\n if (!isEmptyBody && ct.includes('application/json')) {\n try { errorBody = await response.json() } catch { /* body vac\u00EDo o inv\u00E1lido */ }\n }\n throw new FetchError(response.status, response.statusText, response, errorBody)\n }\n\n if (isEmptyBody) return null as TResponse\n\n const ct = response.headers.get('Content-Type') ?? ''\n if (ct.includes('application/json')) return await response.json() as TResponse\n return await response.text() as unknown as TResponse\n}\n\n/**\n * Cliente para llamar a un backend remoto configurado en `devix.config.ts`.\n *\n * El tipo de respuesta se declara en cada call site con un generic:\n *\n * ```ts\n * const me = await $server.api.get<User>('/v1/me')\n * const post = await $server.api.post<Post>('/v1/posts', { title: 'Hola' })\n * ```\n *\n * Si no pasas el generic, el retorno es `unknown`. devix no puede inferir tipos del\n * backend remoto (vive fuera del repo) \u2014 el cast en el call site ES el contrato.\n */\nexport interface BackendClient {\n get<TResponse = unknown>(path: string, options?: ServerFetchOptions): Promise<TResponse>\n post<TResponse = unknown>(path: string, body?: unknown, options?: ServerFetchOptions): Promise<TResponse>\n put<TResponse = unknown>(path: string, body?: unknown, options?: ServerFetchOptions): Promise<TResponse>\n patch<TResponse = unknown>(path: string, body?: unknown, options?: ServerFetchOptions): Promise<TResponse>\n delete<TResponse = unknown>(path: string, options?: ServerFetchOptions): Promise<TResponse>\n}\n\nfunction makeBackendClient(namespace: string): BackendClient {\n return {\n get: (path, options) => proxyFetch(namespace, 'GET', path, undefined, options),\n post: (path, body, options) => proxyFetch(namespace, 'POST', path, body, options),\n put: (path, body, options) => proxyFetch(namespace, 'PUT', path, body, options),\n patch: (path, body, options) => proxyFetch(namespace, 'PATCH', path, body, options),\n delete: (path, options) => proxyFetch(namespace, 'DELETE', path, undefined, options),\n }\n}\n\n/**\n * Cliente para llamar a backends remotos configurados en `devix.config.ts`.\n *\n * En cliente: las requests pasan por el proxy interno `/_devix/server/<namespace>/...`\n * donde devix aplica `prepare` (auth pass-through, tracing, etc.) y reenv\u00EDa al backend.\n *\n * En server (loaders/handlers): NO uses este import \u2014 usa `ctx.$server` que recibe\n * el request del usuario para que `prepare` pueda leer cookies.\n *\n * ```ts\n * const me = await $server.api.get<User>('/v1/me')\n * const post = await $server.api.post<Post>('/v1/posts', { title: 'Hola' })\n * ```\n */\nexport const $server: Record<string, BackendClient> = new Proxy({} as Record<string, BackendClient>, {\n get(target, namespace: string) {\n if (typeof namespace !== 'string') return undefined\n if (!target[namespace]) target[namespace] = makeBackendClient(namespace)\n return target[namespace]\n },\n})\n"],
5
+ "mappings": "AAEA,SAASA,EAAeC,EAA8B,CAClD,GAAIA,GAAQ,OAAOA,GAAS,UAAY,YAAaA,EAAM,CACvD,IAAMC,EAAKD,EAA4B,QACvC,GAAI,OAAOC,GAAM,UAAYA,EAAE,OAAS,EAAG,OAAOA,CACtD,CACA,OAAO,IACX,CAEA,IAAMC,EAAoB,OAAO,IAAI,6BAA6B,EAErDC,EAAN,cAAsC,KAAM,CAK/C,YACoBC,EACAC,EACAC,EACAN,EAClB,CACE,MAAMD,EAAeC,CAAI,GAAK,QAAQI,CAAM,KAAKC,CAAU,EAAE,EAL7C,YAAAD,EACA,gBAAAC,EACA,cAAAC,EACA,UAAAN,EAGhB,KAAK,KAAO,aACV,KAAaE,CAAiB,EAAI,EACxC,CAbA,OAAQ,OAAO,WAAW,EAAEK,EAAyB,CACjD,OAAOA,IAAU,MAAQ,OAAOA,GAAU,UAAaA,EAAcL,CAAiB,IAAM,EAChG,CAaA,IAAI,MAA2B,CAC3B,GAAI,KAAK,MAAQ,OAAO,KAAK,MAAS,UAAY,SAAU,KAAK,KAAM,CACnE,IAAMM,EAAK,KAAK,KAAyB,KACzC,OAAO,OAAOA,GAAM,SAAWA,EAAI,MACvC,CAEJ,CACJ,EC5BA,IAAMC,EAAe,iBAErB,eAAeC,EACXC,EACAC,EACAC,EACAC,EACAC,EACkB,CAClB,IAAMC,EAAU,IAAI,QAAQD,GAAS,OAAO,EACxCE,EACsBH,GAAS,OAC3BA,aAAgB,UAAYA,aAAgB,MAAQA,aAAgB,YACpEG,EAAWH,GAEXG,EAAW,KAAK,UAAUH,CAAI,EACzBE,EAAQ,IAAI,cAAc,GAAGA,EAAQ,IAAI,eAAgB,kBAAkB,IAIxF,IAAME,EAAM,GAAGT,CAAY,IAAIE,CAAS,GAAGE,CAAI,GACzCM,EAAW,MAAM,MAAMD,EAAK,CAAC,OAAAN,EAAQ,QAAAI,EAAS,KAAMC,EAAU,OAAQF,GAAS,MAAM,CAAC,EAEtFK,EAAcD,EAAS,SAAW,KAAOA,EAAS,QAAQ,IAAI,gBAAgB,IAAM,IAE1F,GAAI,CAACA,EAAS,GAAI,CACd,IAAME,EAAKF,EAAS,QAAQ,IAAI,cAAc,GAAK,GAC/CG,EACJ,GAAI,CAACF,GAAeC,EAAG,SAAS,kBAAkB,EAC9C,GAAI,CAAEC,EAAY,MAAMH,EAAS,KAAK,CAAE,MAAQ,CAA8B,CAElF,MAAM,IAAII,EAAWJ,EAAS,OAAQA,EAAS,WAAYA,EAAUG,CAAS,CAClF,CAEA,OAAIF,EAAoB,MAEbD,EAAS,QAAQ,IAAI,cAAc,GAAK,IAC5C,SAAS,kBAAkB,EAAU,MAAMA,EAAS,KAAK,EACzD,MAAMA,EAAS,KAAK,CAC/B,CAuBA,SAASK,EAAkBb,EAAkC,CACzD,MAAO,CACH,IAAK,CAACE,EAAME,IAAYL,EAAWC,EAAW,MAAOE,EAAM,OAAWE,CAAO,EAC7E,KAAM,CAACF,EAAMC,EAAMC,IAAYL,EAAWC,EAAW,OAAQE,EAAMC,EAAMC,CAAO,EAChF,IAAK,CAACF,EAAMC,EAAMC,IAAYL,EAAWC,EAAW,MAAOE,EAAMC,EAAMC,CAAO,EAC9E,MAAO,CAACF,EAAMC,EAAMC,IAAYL,EAAWC,EAAW,QAASE,EAAMC,EAAMC,CAAO,EAClF,OAAQ,CAACF,EAAME,IAAYL,EAAWC,EAAW,SAAUE,EAAM,OAAWE,CAAO,CACvF,CACJ,CAgBO,IAAMU,EAAyC,IAAI,MAAM,CAAC,EAAoC,CACjG,IAAIC,EAAQf,EAAmB,CAC3B,GAAI,OAAOA,GAAc,SACzB,OAAKe,EAAOf,CAAS,IAAGe,EAAOf,CAAS,EAAIa,EAAkBb,CAAS,GAChEe,EAAOf,CAAS,CAC3B,CACJ,CAAC",
6
+ "names": ["extractMessage", "body", "m", "FETCH_ERROR_BRAND", "FetchError", "status", "statusText", "response", "value", "c", "PROXY_PREFIX", "proxyFetch", "namespace", "method", "path", "body", "options", "headers", "sendBody", "url", "response", "isEmptyBody", "ct", "errorBody", "FetchError", "makeBackendClient", "$server", "target"]
7
7
  }
@@ -1,2 +1,2 @@
1
- function B(e){return e.replace(/\.(tsx|ts|jsx|js)$/,"").replace(/\(.*?\)\//g,"").replace(/^index$|\/index$/,"").replace(/\[([^\]]+)]/g,":$1")||"/"}function F(e,t){let n=e.slice(t.length+1).replace(/\\/g,"/"),o=B(n);return o==="/"?"/api":`/api/${o}`.replace("/api//","/api/")}function v(e){return e.slice(0,e.lastIndexOf("/"))}function b(e,t,n){let o=[],r=[];for(let s of t)r.push({dir:v(s),key:s});for(let s of e){let a=F(s,n),c=[...a.matchAll(/:([^/]+)/g)].map(l=>l[1]),d=a.replace(/:[^/]+/g,"([^/]+)").replace(/\//g,"\\/");o.push({path:a,key:s,params:c,regex:new RegExp(`^${d}$`)})}return o.sort((s,a)=>{let c=(s.path.match(/:/g)||[]).length,d=(a.path.match(/:/g)||[]).length;return c!==d?c-d:a.path.length-s.path.length}),{routes:o,middlewares:r}}function D(e,t){let n=v(e);return t.filter(o=>n.startsWith(o.dir)).sort((o,r)=>o.dir.split("/").length-r.dir.split("/").length)}function _(e,t){for(let n of t){let o=e.match(n.regex);if(o){let r={};return n.params.forEach((s,a)=>{r[s]=decodeURIComponent(o[a+1])}),{route:n,params:r}}}return null}var x=class{params;request;url;$server;_state=new Map;constructor(t,n,o,r={}){this.params=t,this.request=n,this.url=o,this.$server=r}set(t,n){this._state.set(t,n)}get(t){return this._state.get(t)}};import{Component as oe}from"react";import{jsx as de}from"react/jsx-runtime";var w=class extends Error{statusCode;code;data;constructor(t,n,o){super(n),this.name="DevixError",this.statusCode=t,this.code=o?.code,this.data=o?.data}};var j="__devix_handler__";import{AsyncLocalStorage as q}from"node:async_hooks";var T=Symbol.for("@devlusoft/devix.handlerStore"),C=globalThis;C[T]||(C[T]=new q);var G=C[T];function M(e,t){return G.run(e,t)}var N=Symbol.for("devix.loaderError");function $(e,t,n){return{[N]:!0,statusCode:e,message:t,code:n?.code,data:n?.data}}function L(e){return typeof e=="object"&&e!==null&&N in e}function E(e){let t={statusCode:e.statusCode,message:e.message};return e.code!==void 0&&(t.code=e.code),e.data!==void 0&&(t.data=e.data),t}function J(e){if(e&&typeof e=="object"&&"message"in e){let t=e.message;if(typeof t=="string"&&t.length>0)return t}return null}var y=class extends Error{constructor(n,o,r,s){super(J(s)??`HTTP ${n}: ${o}`);this.status=n;this.statusText=o;this.response=r;this.body=s;this.name="FetchError"}get code(){if(this.body&&typeof this.body=="object"&&"code"in this.body){let n=this.body.code;return typeof n=="string"?n:void 0}}};function V(e,t){return K(t).test(e)}function S(e,t){if(!t||t.length===0)return!1;for(let n of t)if(V(e,n))return!0;return!1}function K(e){let t="",n=0;for(;n<e.length;){let o=e[n];if(o==="*"&&e[n+1]==="*")t+=".*",n+=2;else if(o==="*")t+="[^/]*",n+=1;else if(o===":"){for(n+=1;n<e.length&&/[a-zA-Z0-9_]/.test(e[n]);)n+=1;t+="[^/]+"}else".+?^$()|[]{}\\".includes(o)?(t+="\\"+o,n+=1):(t+=o,n+=1)}return new RegExp(`^${t}$`)}function O(e,t){if(!t)return new Proxy({},{get(o,r){throw new Error(`[devix] ctx.$server.${String(r)} called but no 'server' config is defined in devix.config.ts`)}});let n=new Map;return new Proxy({},{get(o,r){if(typeof r!="string")return;let s=t[r];if(!s)throw new Error(`[devix] ctx.$server.${r} \u2014 namespace "${r}" not configured in devix.config.ts`);let a=n.get(r);return a||(a=W(r,s,e),n.set(r,a)),a}})}function W(e,t,n){async function o(r,s,a,c){if(!S(s,t.allowedPaths))throw new y(403,"Path not allowed",new Response(null,{status:403}),{statusCode:403,message:"Path not allowed",code:"PATH_NOT_ALLOWED"});if(S(s,t.deniedPaths))throw new y(403,"Path denied",new Response(null,{status:403}),{statusCode:403,message:"Path denied",code:"PATH_DENIED"});let d=new URL(s,t.url),l=new Headers(c?.headers);if(t.prepare){let R={request:n,headers:l,url:d},u=await t.prepare(R);if(u instanceof Response)throw new y(u.status,u.statusText,u,await z(u))}let m;a!=null&&r!=="GET"&&r!=="HEAD"&&(a instanceof FormData||a instanceof Blob||a instanceof ArrayBuffer?m=a:(m=JSON.stringify(a),l.has("Content-Type")||l.set("Content-Type","application/json")));let i=await fetch(d,{method:r,headers:l,body:m,signal:c?.signal}),f=i.status===204||i.headers.get("Content-Length")==="0";if(!i.ok){let R=i.headers.get("Content-Type")??"",u;if(!f&&R.includes("application/json"))try{u=await i.json()}catch{}throw new y(i.status,i.statusText,i,u)}return f?null:(i.headers.get("Content-Type")??"").includes("application/json")?await i.json():await i.text()}return{get:((r,s)=>o("GET",r,void 0,s)),post:((r,s,a)=>o("POST",r,s,a)),put:((r,s,a)=>o("PUT",r,s,a)),patch:((r,s,a)=>o("PATCH",r,s,a)),delete:((r,s)=>o("DELETE",r,void 0,s))}}async function z(e){if((e.headers.get("Content-Type")??"").includes("application/json"))try{return await e.json()}catch{return}}var k=null,I=null;function Y(e){return typeof e=="object"&&e!==null&&j in e}async function Z(e){let t=e.headers.get("Content-Type")??"";return t.includes("application/json")?e.json():t.includes("multipart/form-data")||t.includes("application/x-www-form-urlencoded")?e.formData():e.text()}function A(e,t){return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":"application/json"}})}function Q(e){return e instanceof Response?e:L(e)?A(E(e),e.statusCode):e==null?new Response(null,{status:204}):new Response(JSON.stringify(e),{headers:{"Content-Type":"application/json"}})}async function He(e,t,n,o){try{let{pathname:r}=new URL(e,"http://localhost"),s=Object.keys(n.routes).sort().join("\0")+"|"+Object.keys(n.middlewares).sort().join("\0");(!k||I!==s)&&(k=b(Object.keys(n.routes),Object.keys(n.middlewares),n.apiDir),I=s);let{routes:a,middlewares:c}=k,d=_(r,a);if(!d)return new Response("Not Found",{status:404});let{route:l,params:m}=d,i=O(t,o),f=new x(m,t,new URL(e,"http://localhost"),i),H=await M({request:t,ctx:f},async()=>{let R=D(l.key,c);for(let h of R){let g=await n.middlewares[h.key]();if(g.middleware){let P=await g.middleware(f);if(P instanceof Response)return P}}let u=await n.routes[l.key](),U=t.method.toUpperCase(),p=u[U];if(!p)return new Response("Method Not Allowed",{status:405});if(Y(p)){if(p.fn.length===0)return p.fn();let h=await Z(t);if(p.schema){let g=await p.schema["~standard"].validate(h);return g.issues?$(400,"Validation failed",{code:"VALIDATION_ERROR",data:{issues:g.issues}}):p.fn(g.value,f)}return p.fn(h,f)}return p(f)});return Q(H)}catch(r){return r instanceof w?A(E(r),r.statusCode):(console.error("[devix] api error:",r),A({statusCode:500,message:"Internal Server Error"},500))}}export{He as handleApiRequest};
1
+ function B(e){return e.replace(/\.(tsx|ts|jsx|js)$/,"").replace(/\(.*?\)\//g,"").replace(/^index$|\/index$/,"").replace(/\[([^\]]+)]/g,":$1")||"/"}function V(e,t){let n=e.slice(t.length+1).replace(/\\/g,"/"),o=B(n);return o==="/"?"/api":`/api/${o}`.replace("/api//","/api/")}function P(e){return e.slice(0,e.lastIndexOf("/"))}function v(e,t,n){let o=[],r=[];for(let s of t)r.push({dir:P(s),key:s});for(let s of e){let a=V(s,n),c=[...a.matchAll(/:([^/]+)/g)].map(l=>l[1]),d=a.replace(/:[^/]+/g,"([^/]+)").replace(/\//g,"\\/");o.push({path:a,key:s,params:c,regex:new RegExp(`^${d}$`)})}return o.sort((s,a)=>{let c=(s.path.match(/:/g)||[]).length,d=(a.path.match(/:/g)||[]).length;return c!==d?c-d:a.path.length-s.path.length}),{routes:o,middlewares:r}}function D(e,t){let n=P(e);return t.filter(o=>n.startsWith(o.dir)).sort((o,r)=>o.dir.split("/").length-r.dir.split("/").length)}function _(e,t){for(let n of t){let o=e.match(n.regex);if(o){let r={};return n.params.forEach((s,a)=>{r[s]=decodeURIComponent(o[a+1])}),{route:n,params:r}}}return null}var x=class{params;request;url;$server;_state=new Map;constructor(t,n,o,r={}){this.params=t,this.request=n,this.url=o,this.$server=r}set(t,n){this._state.set(t,n)}get(t){return this._state.get(t)}};import{Component as ae}from"react";import{jsx as ce}from"react/jsx-runtime";var j=Symbol.for("@devlusoft/devix.DevixError"),w=class extends Error{static[Symbol.hasInstance](t){return t!==null&&typeof t=="object"&&t[j]===!0}statusCode;code;data;constructor(t,n,o){super(n),this.name="DevixError",this.statusCode=t,this.code=o?.code,this.data=o?.data,this[j]=!0}};var N="__devix_handler__";import{AsyncLocalStorage as G}from"node:async_hooks";var T=Symbol.for("@devlusoft/devix.handlerStore"),E=globalThis;E[T]||(E[T]=new G);var J=E[T];function M(e,t){return J.run(e,t)}var O=Symbol.for("devix.loaderError");function $(e,t,n){return{[O]:!0,statusCode:e,message:t,code:n?.code,data:n?.data}}function L(e){return typeof e=="object"&&e!==null&&O in e}function C(e){let t={statusCode:e.statusCode,message:e.message};return e.code!==void 0&&(t.code=e.code),e.data!==void 0&&(t.data=e.data),t}function K(e){if(e&&typeof e=="object"&&"message"in e){let t=e.message;if(typeof t=="string"&&t.length>0)return t}return null}var I=Symbol.for("@devlusoft/devix.FetchError"),y=class extends Error{constructor(n,o,r,s){super(K(s)??`HTTP ${n}: ${o}`);this.status=n;this.statusText=o;this.response=r;this.body=s;this.name="FetchError",this[I]=!0}static[Symbol.hasInstance](n){return n!==null&&typeof n=="object"&&n[I]===!0}get code(){if(this.body&&typeof this.body=="object"&&"code"in this.body){let n=this.body.code;return typeof n=="string"?n:void 0}}};function W(e,t){return z(t).test(e)}function S(e,t){if(!t||t.length===0)return!1;for(let n of t)if(W(e,n))return!0;return!1}function z(e){let t="",n=0;for(;n<e.length;){let o=e[n];if(o==="*"&&e[n+1]==="*")t+=".*",n+=2;else if(o==="*")t+="[^/]*",n+=1;else if(o===":"){for(n+=1;n<e.length&&/[a-zA-Z0-9_]/.test(e[n]);)n+=1;t+="[^/]+"}else".+?^$()|[]{}\\".includes(o)?(t+="\\"+o,n+=1):(t+=o,n+=1)}return new RegExp(`^${t}$`)}function F(e,t){if(!t)return new Proxy({},{get(o,r){throw new Error(`[devix] ctx.$server.${String(r)} called but no 'server' config is defined in devix.config.ts`)}});let n=new Map;return new Proxy({},{get(o,r){if(typeof r!="string")return;let s=t[r];if(!s)throw new Error(`[devix] ctx.$server.${r} \u2014 namespace "${r}" not configured in devix.config.ts`);let a=n.get(r);return a||(a=X(r,s,e),n.set(r,a)),a}})}function X(e,t,n){async function o(r,s,a,c){if(!S(s,t.allowedPaths))throw new y(403,"Path not allowed",new Response(null,{status:403}),{statusCode:403,message:"Path not allowed",code:"PATH_NOT_ALLOWED"});if(S(s,t.deniedPaths))throw new y(403,"Path denied",new Response(null,{status:403}),{statusCode:403,message:"Path denied",code:"PATH_DENIED"});let d=new URL(s,t.url),l=new Headers(c?.headers);if(t.prepare){let m={request:n,headers:l,url:d},u=await t.prepare(m);if(u instanceof Response)throw new y(u.status,u.statusText,u,await Y(u))}let R;a!=null&&r!=="GET"&&r!=="HEAD"&&(a instanceof FormData||a instanceof Blob||a instanceof ArrayBuffer?R=a:(R=JSON.stringify(a),l.has("Content-Type")||l.set("Content-Type","application/json")));let i=await fetch(d,{method:r,headers:l,body:R,signal:c?.signal}),f=i.status===204||i.headers.get("Content-Length")==="0";if(!i.ok){let m=i.headers.get("Content-Type")??"",u;if(!f&&m.includes("application/json"))try{u=await i.json()}catch{}throw new y(i.status,i.statusText,i,u)}return f?null:(i.headers.get("Content-Type")??"").includes("application/json")?await i.json():await i.text()}return{get:((r,s)=>o("GET",r,void 0,s)),post:((r,s,a)=>o("POST",r,s,a)),put:((r,s,a)=>o("PUT",r,s,a)),patch:((r,s,a)=>o("PATCH",r,s,a)),delete:((r,s)=>o("DELETE",r,void 0,s))}}async function Y(e){if((e.headers.get("Content-Type")??"").includes("application/json"))try{return await e.json()}catch{return}}var k=null,U=null;function Z(e){return typeof e=="object"&&e!==null&&N in e}async function Q(e){let t=e.headers.get("Content-Type")??"";return t.includes("application/json")?e.json():t.includes("multipart/form-data")||t.includes("application/x-www-form-urlencoded")?e.formData():e.text()}function A(e,t){return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":"application/json"}})}function ee(e){return e instanceof Response?e:L(e)?A(C(e),e.statusCode):e==null?new Response(null,{status:204}):new Response(JSON.stringify(e),{headers:{"Content-Type":"application/json"}})}async function Be(e,t,n,o){try{let{pathname:r}=new URL(e,"http://localhost"),s=Object.keys(n.routes).sort().join("\0")+"|"+Object.keys(n.middlewares).sort().join("\0");(!k||U!==s)&&(k=v(Object.keys(n.routes),Object.keys(n.middlewares),n.apiDir),U=s);let{routes:a,middlewares:c}=k,d=_(r,a);if(!d)return new Response("Not Found",{status:404});let{route:l,params:R}=d,i=F(t,o),f=new x(R,t,new URL(e,"http://localhost"),i),H=await M({request:t,ctx:f},async()=>{let m=D(l.key,c);for(let h of m){let g=await n.middlewares[h.key]();if(g.middleware){let b=await g.middleware(f);if(b instanceof Response)return b}}let u=await n.routes[l.key](),q=t.method.toUpperCase(),p=u[q];if(!p)return new Response("Method Not Allowed",{status:405});if(Z(p)){if(p.fn.length===0)return p.fn();let h=await Q(t);if(p.schema){let g=await p.schema["~standard"].validate(h);return g.issues?$(400,"Validation failed",{code:"VALIDATION_ERROR",data:{issues:g.issues}}):p.fn(g.value,f)}return p.fn(h,f)}return p(f)});return ee(H)}catch(r){return r instanceof w?A(C(r),r.statusCode):(console.error("[devix] api error:",r),A({statusCode:500,message:"Internal Server Error"},500))}}export{Be as handleApiRequest};
2
2
  //# sourceMappingURL=api.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/patterns.ts", "../../src/server/api-router.ts", "../../src/runtime/api-context.ts", "../../src/runtime/error-boundary.tsx", "../../src/runtime/create-handler.ts", "../../src/server/handler-store.ts", "../../src/utils/response.ts", "../../src/runtime/fetch.ts", "../../src/utils/glob.ts", "../../src/server/server-bound.ts", "../../src/server/api.ts"],
4
- "sourcesContent": ["export function routePattern(rel: string): string {\n return rel\n .replace(/\\.(tsx|ts|jsx|js)$/, '')\n .replace(/\\(.*?\\)\\//g, '')\n .replace(/^index$|\\/index$/, '')\n .replace(/\\[([^\\]]+)]/g, ':$1')\n || '/'\n}", "import {routePattern} from \"../utils/patterns\";\n\nexport interface ApiRoute {\n path: string\n key: string\n params: string[]\n regex: RegExp\n}\n\nexport interface ApiMiddleware {\n dir: string\n key: string\n}\n\nexport interface ApiResult {\n routes: ApiRoute[]\n middlewares: ApiMiddleware[]\n}\n\nexport function keyToRoutePattern(key: string, apiDir: string): string {\n const rel = key.slice(apiDir.length + 1).replace(/\\\\/g, '/')\n const pattern = routePattern(rel)\n return pattern === '/' ? '/api' : `/api/${pattern}`.replace('/api//', '/api/')\n}\n\nfunction keyToDir(key: string): string {\n return key.slice(0, key.lastIndexOf('/'))\n}\n\nexport function buildRoutes(routeKeys: string[], middlewareKeys: string[], apiDir: string): ApiResult {\n const routes: ApiRoute[] = []\n const middlewares: ApiMiddleware[] = []\n\n for (const key of middlewareKeys) {\n middlewares.push({dir: keyToDir(key), key})\n }\n\n for (const key of routeKeys) {\n const pattern = keyToRoutePattern(key, apiDir)\n const params = [...pattern.matchAll(/:([^/]+)/g)].map(m => m[1])\n const regexStr = pattern\n .replace(/:[^/]+/g, '([^/]+)')\n .replace(/\\//g, '\\\\/')\n routes.push({path: pattern, key, params, regex: new RegExp(`^${regexStr}$`)})\n }\n routes.sort((a, b) => {\n const aScore = (a.path.match(/:/g) || []).length\n const bScore = (b.path.match(/:/g) || []).length\n if (aScore !== bScore) return aScore - bScore\n return b.path.length - a.path.length\n })\n\n return {routes, middlewares}\n}\n\nexport function collectMiddlewareChain(routeKey: string, middlewares: ApiMiddleware[]): ApiMiddleware[] {\n const routeDir = keyToDir(routeKey)\n\n return middlewares\n .filter(mw => routeDir.startsWith(mw.dir))\n .sort((a, b) => a.dir.split('/').length - b.dir.split('/').length)\n}\n\nexport function matchRoute(\n pathname: string,\n routes: ApiRoute[]\n): { route: ApiRoute; params: Record<string, string> } | null {\n for (const route of routes) {\n const match = pathname.match(route.regex)\n if (match) {\n const params: Record<string, string> = {}\n route.params.forEach((name, i) => {\n params[name] = decodeURIComponent(match[i + 1])\n })\n return {route, params}\n }\n }\n return null\n}\n", "import type {DevixHandler} from './create-handler'\nimport type {RouteError} from '../utils/response'\nimport type {BackendClient} from './server-client'\n\nexport class RouteContext {\n readonly params: Record<string, string>\n readonly request: Request\n readonly url: URL\n readonly $server: Record<string, BackendClient>\n private _state = new Map<string, unknown>()\n\n constructor(\n params: Record<string, string>,\n request: Request,\n url: URL,\n $server: Record<string, BackendClient> = {},\n ) {\n this.params = params\n this.request = request\n this.url = url\n this.$server = $server\n }\n\n set<T>(key: string, value: T): void {\n this._state.set(key, value)\n }\n\n get<T>(key: string): T | undefined {\n return this._state.get(key) as T\n }\n}\n\nexport type RouteResult = Response | RouteError | Record<string, unknown> | unknown[] | null | void\n\nexport type RouteHandler = (ctx: RouteContext) => Promise<RouteResult> | RouteResult\n\nexport interface MiddlewareModule {\n middleware: (ctx: RouteContext) => Promise<Response | null> | Response | null\n}\n\ntype AnyHandler = RouteHandler | DevixHandler<any, any>\n\nexport interface RouteModule {\n GET?: AnyHandler\n POST?: AnyHandler\n PUT?: AnyHandler\n PATCH?: AnyHandler\n DELETE?: AnyHandler\n HEAD?: AnyHandler\n OPTIONS?: AnyHandler\n}\n", "import {Component, ComponentType, ReactNode} from \"react\";\nimport {ErrorProps} from \"../server/types\";\n\ninterface Props {\n ErrorPage?: ComponentType<ErrorProps>\n children: ReactNode\n}\n\ninterface State {\n error: ErrorProps | null\n}\n\nexport class DevixErrorBoundary extends Component<Props, State> {\n state: State = { error: null }\n\n static getDerivedStateFromError(err: unknown): State {\n if (err instanceof DevixError) {\n return {\n error: {statusCode: err.statusCode, message: err.message}\n }\n }\n return {\n error: {statusCode: 500, message: err instanceof Error ? err.message : 'Unknown error'}\n }\n }\n\n render() {\n if (this.state.error && this.props.ErrorPage) {\n return <this.props.ErrorPage {...this.state.error} />\n }\n if (this.state.error) {\n return <h1>{this.state.error.statusCode}</h1>\n }\n return this.props.children\n }\n}\n\nexport interface DevixErrorOptions {\n code?: string\n data?: unknown\n}\n\nexport class DevixError extends Error {\n statusCode: number\n code?: string\n data?: unknown\n constructor(statusCode: number, message: string, options?: DevixErrorOptions) {\n super(message)\n this.name = 'DevixError'\n this.statusCode = statusCode\n this.code = options?.code\n this.data = options?.data\n }\n}\n", "import type {RouteContext} from './api-context'\nimport type {StandardSchemaV1} from '../utils/standard-schema'\n\nexport const HANDLER_BRAND = '__devix_handler__' as const\n\nexport interface DevixHandler<TBody = undefined, TReturn = unknown> {\n readonly [HANDLER_BRAND]: true\n readonly fn: (...args: any[]) => any\n readonly schema?: StandardSchemaV1\n readonly __body: TBody\n readonly __return: TReturn\n}\n\n/**\n * Crea un handler API tipado.\n *\n * El primer argumento (si lo declaras) es el body parseado autom\u00E1ticamente:\n * - `application/json` \u2192 objeto JS\n * - `multipart/form-data` o `application/x-www-form-urlencoded` \u2192 FormData\n * - cualquier otro \u2192 string\n *\n * El segundo argumento es `ctx: RouteContext` con `request`, `url`, `params`,\n * y los helpers `get`/`set` para state heredado de middleware.\n *\n * ```ts\n * // sin body\n * export const GET = createHandler(async () => ({ ok: true }))\n *\n * // con body tipado\n * export const POST = createHandler(async (body: Login) => ...)\n *\n * // con body y ctx\n * export const POST = createHandler(async (body: Login, ctx) => {\n * const user = ctx.get<User>('user')\n * const ua = ctx.request.headers.get('User-Agent')\n * })\n *\n * // solo ctx, sin body (ej. GET que necesita query params)\n * export const GET = createHandler(async (_body, ctx) => {\n * const filter = ctx.url.searchParams.get('filter')\n * })\n * ```\n */\ntype ExtractBody<TFn> =\n TFn extends () => any ? undefined :\n TFn extends (body: infer B, ...rest: any[]) => any ? B :\n undefined\n\ntype HandlerFn = ((body: any, ctx: RouteContext) => any) | (() => any)\n\nexport function createHandler<TFn extends HandlerFn>(\n fn: TFn,\n): DevixHandler<ExtractBody<TFn>, Awaited<ReturnType<TFn>>>\n\n/**\n * Overload con Standard Schema. devix valida el body autom\u00E1ticamente y, si\n * falla, devuelve `400` con shape `ErrorBody` y `code: 'VALIDATION_ERROR'`.\n * El body recibido por el handler est\u00E1 ya validado y tipado al output del schema.\n *\n * ```ts\n * import { z } from 'zod'\n *\n * const Input = z.object({ email: z.email(), password: z.string().min(8) })\n *\n * export const POST = createHandler(Input, async (body, ctx) => {\n * // body: z.infer<typeof Input>, ya validado\n * })\n * ```\n */\nexport function createHandler<TSchema extends StandardSchemaV1, TReturn>(\n schema: TSchema,\n fn: (body: StandardSchemaV1.InferOutput<TSchema>, ctx: RouteContext) => TReturn | Promise<TReturn>,\n): DevixHandler<StandardSchemaV1.InferInput<TSchema>, Awaited<TReturn>>\n\nexport function createHandler(\n schemaOrFn: StandardSchemaV1 | ((...args: any[]) => any),\n maybeFn?: (...args: any[]) => any,\n): DevixHandler<any, any> {\n if (maybeFn) {\n return {\n [HANDLER_BRAND]: true,\n fn: maybeFn,\n schema: schemaOrFn as StandardSchemaV1,\n } as unknown as DevixHandler<any, any>\n }\n return {\n [HANDLER_BRAND]: true,\n fn: schemaOrFn as (...args: any[]) => any,\n } as unknown as DevixHandler<any, any>\n}\n", "import {AsyncLocalStorage} from 'node:async_hooks'\nimport type {RouteContext} from '../runtime/api-context'\n\ninterface HandlerStore {\n request: Request\n ctx: RouteContext\n}\n\nconst ALS_KEY = Symbol.for('@devlusoft/devix.handlerStore')\nconst g = globalThis as Record<symbol, unknown>\nif (!g[ALS_KEY]) g[ALS_KEY] = new AsyncLocalStorage<HandlerStore>()\nconst storage = g[ALS_KEY] as AsyncLocalStorage<HandlerStore>\n\nexport function withHandlerStore<T>(store: HandlerStore, fn: () => T): T {\n return storage.run(store, fn)\n}\n\nfunction getStore(hookName: string): HandlerStore {\n const store = storage.getStore()\n if (!store) throw new Error(`[devix] ${hookName}() called outside of a request handler`)\n return store\n}\n\n/**\n * @deprecated Usa el `ctx` que recibe tu handler como segundo argumento:\n * `createHandler(async (body, ctx) => ctx.request)`. Ser\u00E1 eliminado en v0.6.\n */\nexport function useRequest(): Request {\n return getStore('useRequest').request\n}\n\n/**\n * @deprecated Usa el `ctx` que recibe tu handler como segundo argumento.\n * Ser\u00E1 eliminado en v0.6.\n */\nexport function useCtx(): RouteContext {\n return getStore('useCtx').ctx\n}\n\n/**\n * @deprecated Usa `ctx.params` desde el segundo argumento de tu handler.\n * Ser\u00E1 eliminado en v0.6.\n */\nexport function useParams(): Record<string, string> {\n return getStore('useParams').ctx.params\n}\n", "export type JsonResponse<T = unknown, S extends number = number> = Response & {\n readonly __body: T\n readonly __status: S\n}\n\nexport function json<const T>(data: T): JsonResponse<T, 200>\nexport function json<const T, const S extends number>(data: T, status: S): JsonResponse<T, S>\nexport function json<const T>(data: T, status: number = 200): JsonResponse<T, any> {\n return new Response(JSON.stringify(data), {\n status,\n headers: {'Content-Type': 'application/json'},\n }) as JsonResponse<T, any>\n}\n\nexport const text = (body: string, status = 200): Response =>\n new Response(body, {status, headers: {'Content-Type': 'text/plain; charset=utf-8'}})\n\nconst REDIRECT_BRAND = Symbol.for('devix.redirect')\n\nexport interface RedirectOptions {\n status?: number\n replace?: boolean\n}\n\nexport interface Redirect {\n readonly [REDIRECT_BRAND]: true\n readonly url: string\n readonly status: number\n readonly replace: boolean\n}\n\nexport function redirect(url: string, statusOrOptions?: number | RedirectOptions): Redirect {\n const status = typeof statusOrOptions === 'number' ? statusOrOptions : (statusOrOptions?.status ?? 302)\n const replace = typeof statusOrOptions === 'object' ? (statusOrOptions?.replace ?? false) : false\n return {[REDIRECT_BRAND]: true, url, status, replace} as Redirect\n}\n\nexport function isRedirect(value: unknown): value is Redirect {\n return typeof value === 'object' && value !== null && REDIRECT_BRAND in value\n}\n\nconst ERROR_BRAND = Symbol.for('devix.loaderError')\n\nexport interface RouteError {\n readonly [ERROR_BRAND]: true\n readonly statusCode: number\n readonly message: string\n readonly code?: string\n readonly data?: unknown\n}\n\nexport interface ErrorOptions {\n code?: string\n data?: unknown\n}\n\n/**\n * Crea un error tipado que funciona en loaders, guards y handlers API.\n *\n * En loaders/guards: ret\u00F3rnalo (no lo lances) y el sistema renderiza `error.tsx`.\n * En handlers API: ret\u00F3rnalo y el sistema serializa el shape `ErrorBody` como JSON\n * con el statusCode correcto.\n *\n * ```ts\n * return error(404, 'Post no encontrado', { code: 'POST_NOT_FOUND' })\n * ```\n */\nexport function error(statusCode: number, message: string, options?: ErrorOptions): RouteError {\n return {\n [ERROR_BRAND]: true,\n statusCode,\n message,\n code: options?.code,\n data: options?.data,\n } as RouteError\n}\n\nexport function isLoaderError(value: unknown): value is RouteError {\n return typeof value === 'object' && value !== null && ERROR_BRAND in value\n}\n\n/**\n * Shape p\u00FAblico del body de un error API. Todos los errores emitidos por `error()`\n * o `DevixError` se serializan a este shape. `FetchError.body` del cliente lo recibe.\n */\nexport interface ErrorBody {\n statusCode: number\n message: string\n code?: string\n data?: unknown\n}\n\nexport function errorToBody(err: { statusCode: number; message: string; code?: string; data?: unknown }): ErrorBody {\n const body: ErrorBody = { statusCode: err.statusCode, message: err.message }\n if (err.code !== undefined) body.code = err.code\n if (err.data !== undefined) body.data = err.data\n return body\n}\n", "export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'\n\nfunction extractMessage(body: unknown): string | null {\n if (body && typeof body === 'object' && 'message' in body) {\n const m = (body as {message: unknown}).message\n if (typeof m === 'string' && m.length > 0) return m\n }\n return null\n}\n\nexport class FetchError<E = unknown> extends Error {\n constructor(\n public readonly status: number,\n public readonly statusText: string,\n public readonly response: Response,\n public readonly body?: E,\n ) {\n super(extractMessage(body) ?? `HTTP ${status}: ${statusText}`)\n this.name = 'FetchError'\n }\n\n get code(): string | undefined {\n if (this.body && typeof this.body === 'object' && 'code' in this.body) {\n const c = (this.body as {code: unknown}).code\n return typeof c === 'string' ? c : undefined\n }\n return undefined\n }\n}\n", "/**\n * Match simple de path contra un glob estilo `'/v1/**'`, `'/v1/users/*'`, `'/v1/users/:id'`.\n *\n * Reglas:\n * - `**` matchea cualquier subpath (incluye `/`).\n * - `*` matchea un \u00FAnico segmento (sin `/`).\n * - `:param` matchea un \u00FAnico segmento.\n * - Cualquier otro caracter es literal.\n */\nexport function matchPathGlob(path: string, pattern: string): boolean {\n const regex = globToRegex(pattern)\n return regex.test(path)\n}\n\nexport function matchesAnyGlob(path: string, patterns: readonly string[] | undefined): boolean {\n if (!patterns || patterns.length === 0) return false\n for (const pattern of patterns) {\n if (matchPathGlob(path, pattern)) return true\n }\n return false\n}\n\nfunction globToRegex(pattern: string): RegExp {\n let regex = ''\n let i = 0\n while (i < pattern.length) {\n const c = pattern[i]\n if (c === '*' && pattern[i + 1] === '*') {\n regex += '.*'\n i += 2\n } else if (c === '*') {\n regex += '[^/]*'\n i += 1\n } else if (c === ':') {\n i += 1\n while (i < pattern.length && /[a-zA-Z0-9_]/.test(pattern[i])) i += 1\n regex += '[^/]+'\n } else if ('.+?^$()|[]{}\\\\'.includes(c)) {\n regex += '\\\\' + c\n i += 1\n } else {\n regex += c\n i += 1\n }\n }\n return new RegExp(`^${regex}$`)\n}\n", "import {FetchError, type HttpMethod} from '../runtime/fetch'\nimport {matchesAnyGlob} from '../utils/glob'\nimport type {ServerBackendConfig, PrepareContext} from '../config'\nimport type {BackendClient} from '../runtime/server-client'\n\n/**\n * Construye un `$server` server-side bound al request del usuario.\n *\n * Diferencias clave vs el `$server` cliente:\n * - Hace fetch directo a `backend.url + path` (sin pasar por el proxy interno).\n * - Aplica `prepare` con el `Request` del loader/handler para que pueda leer cookies.\n * - Aplica allowlist/denylist por simetr\u00EDa con el proxy cliente.\n */\nexport function makeBoundServer(\n request: Request,\n config: Record<string, ServerBackendConfig> | undefined,\n): Record<string, BackendClient> {\n if (!config) return new Proxy({} as any, {\n get(_t, namespace: string) {\n throw new Error(`[devix] ctx.$server.${String(namespace)} called but no 'server' config is defined in devix.config.ts`)\n },\n })\n\n const cache = new Map<string, BackendClient>()\n return new Proxy({} as any, {\n get(_t, namespace: string) {\n if (typeof namespace !== 'string') return undefined\n const backend = config[namespace]\n if (!backend) {\n throw new Error(`[devix] ctx.$server.${namespace} \u2014 namespace \"${namespace}\" not configured in devix.config.ts`)\n }\n let client = cache.get(namespace)\n if (!client) {\n client = makeBackendClientBound(namespace, backend, request)\n cache.set(namespace, client)\n }\n return client\n },\n })\n}\n\nfunction makeBackendClientBound(\n _namespace: string,\n backend: ServerBackendConfig,\n userRequest: Request,\n): BackendClient {\n async function call<TResult>(method: HttpMethod, path: string, body?: unknown, options?: {headers?: HeadersInit; signal?: AbortSignal}): Promise<TResult> {\n if (!matchesAnyGlob(path, backend.allowedPaths)) {\n throw new FetchError(403, 'Path not allowed', new Response(null, {status: 403}), {\n statusCode: 403, message: 'Path not allowed', code: 'PATH_NOT_ALLOWED',\n })\n }\n if (matchesAnyGlob(path, backend.deniedPaths)) {\n throw new FetchError(403, 'Path denied', new Response(null, {status: 403}), {\n statusCode: 403, message: 'Path denied', code: 'PATH_DENIED',\n })\n }\n\n const targetUrl = new URL(path, backend.url)\n const headers = new Headers(options?.headers)\n if (backend.prepare) {\n const ctx: PrepareContext = {request: userRequest, headers, url: targetUrl}\n const result = await backend.prepare(ctx)\n if (result instanceof Response) {\n throw new FetchError(\n result.status,\n result.statusText,\n result,\n await readErrorBody(result),\n )\n }\n }\n\n let sendBody: BodyInit | undefined\n if (body !== undefined && body !== null && method !== 'GET' && method !== 'HEAD') {\n if (body instanceof FormData || body instanceof Blob || body instanceof ArrayBuffer) {\n sendBody = body\n } else {\n sendBody = JSON.stringify(body)\n if (!headers.has('Content-Type')) headers.set('Content-Type', 'application/json')\n }\n }\n\n const response = await fetch(targetUrl, {method, headers, body: sendBody, signal: options?.signal})\n const isEmpty = response.status === 204 || response.headers.get('Content-Length') === '0'\n\n if (!response.ok) {\n const ct = response.headers.get('Content-Type') ?? ''\n let errorBody: unknown\n if (!isEmpty && ct.includes('application/json')) {\n try { errorBody = await response.json() } catch { /* body inv\u00E1lido */ }\n }\n throw new FetchError(response.status, response.statusText, response, errorBody)\n }\n\n if (isEmpty) return null as TResult\n\n const ct = response.headers.get('Content-Type') ?? ''\n if (ct.includes('application/json')) return await response.json() as TResult\n return await response.text() as unknown as TResult\n }\n\n return {\n get: ((path: string, options?: any) => call('GET', path, undefined, options)) as BackendClient['get'],\n post: ((path: string, body?: any, options?: any) => call('POST', path, body, options)) as BackendClient['post'],\n put: ((path: string, body?: any, options?: any) => call('PUT', path, body, options)) as BackendClient['put'],\n patch: ((path: string, body?: any, options?: any) => call('PATCH', path, body, options)) as BackendClient['patch'],\n delete: ((path: string, options?: any) => call('DELETE', path, undefined, options)) as BackendClient['delete'],\n }\n}\n\nasync function readErrorBody(res: Response): Promise<unknown> {\n const ct = res.headers.get('Content-Type') ?? ''\n if (ct.includes('application/json')) {\n try { return await res.json() } catch { return undefined }\n }\n return undefined\n}\n", "import {buildRoutes, matchRoute, collectMiddlewareChain, ApiResult} from './api-router'\nimport {RouteContext} from '../runtime/api-context'\nimport type {RouteModule, MiddlewareModule, RouteResult} from '../runtime/api-context'\nimport type {ApiGlob} from './types'\nimport {DevixError} from '../runtime/error-boundary'\nimport {HANDLER_BRAND, type DevixHandler} from '../runtime/create-handler'\nimport {withHandlerStore} from './handler-store'\nimport {error, errorToBody, isLoaderError} from '../utils/response'\nimport type {ServerBackendConfig} from '../config'\nimport {makeBoundServer} from './server-bound'\n\nlet apiCache: ApiResult | null = null\nlet apiCacheKey: string | null = null\n\nfunction isDevixHandler(h: unknown): h is DevixHandler<any, any> {\n return typeof h === 'object' && h !== null && HANDLER_BRAND in h\n}\n\nasync function parseBody(request: Request): Promise<unknown> {\n const ct = request.headers.get('Content-Type') ?? ''\n if (ct.includes('application/json')) return request.json()\n if (ct.includes('multipart/form-data') || ct.includes('application/x-www-form-urlencoded')) {\n return request.formData()\n }\n return request.text()\n}\n\nfunction jsonResponse(body: unknown, status: number): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: {'Content-Type': 'application/json'},\n })\n}\n\nfunction resultToResponse(result: RouteResult): Response {\n if (result instanceof Response) return result\n if (isLoaderError(result)) return jsonResponse(errorToBody(result), result.statusCode)\n if (result == null) return new Response(null, {status: 204})\n return new Response(JSON.stringify(result), {\n headers: {'Content-Type': 'application/json'},\n })\n}\n\nexport async function handleApiRequest(\n url: string,\n request: Request,\n glob: ApiGlob,\n serverConfig?: Record<string, ServerBackendConfig>,\n): Promise<Response> {\n try {\n const {pathname} = new URL(url, 'http://localhost')\n const cacheKey = Object.keys(glob.routes).sort().join('\\0') + '|' + Object.keys(glob.middlewares).sort().join('\\0')\n if (!apiCache || apiCacheKey !== cacheKey) {\n apiCache = buildRoutes(\n Object.keys(glob.routes),\n Object.keys(glob.middlewares),\n glob.apiDir,\n )\n apiCacheKey = cacheKey\n }\n const {routes, middlewares} = apiCache\n const matched = matchRoute(pathname, routes)\n\n if (!matched) return new Response('Not Found', {status: 404})\n\n const {route, params} = matched\n const $server = makeBoundServer(request, serverConfig)\n const ctx = new RouteContext(params, request, new URL(url, 'http://localhost'), $server)\n\n const result = await withHandlerStore({request, ctx}, async () => {\n const middlewareChain = collectMiddlewareChain(route.key, middlewares)\n for (const mw of middlewareChain) {\n const mod = await glob.middlewares[mw.key]() as MiddlewareModule\n if (mod.middleware) {\n const mwResult = await mod.middleware(ctx)\n if (mwResult instanceof Response) return mwResult\n }\n }\n\n const mod = await glob.routes[route.key]() as RouteModule\n const method = request.method.toUpperCase() as keyof RouteModule\n const handler = mod[method]\n\n if (!handler) return new Response('Method Not Allowed', {status: 405})\n\n if (isDevixHandler(handler)) {\n if (handler.fn.length === 0) {\n return handler.fn() as Promise<RouteResult>\n }\n const rawBody = await parseBody(request)\n if (handler.schema) {\n const result = await handler.schema['~standard'].validate(rawBody)\n if (result.issues) {\n return error(400, 'Validation failed', {\n code: 'VALIDATION_ERROR',\n data: {issues: result.issues},\n })\n }\n return handler.fn(result.value, ctx) as Promise<RouteResult>\n }\n return handler.fn(rawBody, ctx) as Promise<RouteResult>\n }\n\n return handler(ctx)\n })\n\n return resultToResponse(result)\n } catch (err) {\n if (err instanceof DevixError) {\n return jsonResponse(errorToBody(err), err.statusCode)\n }\n console.error('[devix] api error:', err)\n return jsonResponse({statusCode: 500, message: 'Internal Server Error'}, 500)\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["routePattern", "rel", "keyToRoutePattern", "key", "apiDir", "rel", "pattern", "routePattern", "keyToDir", "buildRoutes", "routeKeys", "middlewareKeys", "routes", "middlewares", "params", "m", "regexStr", "a", "b", "aScore", "bScore", "collectMiddlewareChain", "routeKey", "routeDir", "mw", "matchRoute", "pathname", "route", "match", "name", "i", "RouteContext", "params", "request", "url", "$server", "key", "value", "Component", "jsx", "DevixError", "statusCode", "message", "options", "HANDLER_BRAND", "AsyncLocalStorage", "ALS_KEY", "g", "storage", "withHandlerStore", "store", "fn", "ERROR_BRAND", "error", "statusCode", "message", "options", "isLoaderError", "value", "errorToBody", "err", "body", "extractMessage", "body", "m", "FetchError", "status", "statusText", "response", "c", "matchPathGlob", "path", "pattern", "globToRegex", "matchesAnyGlob", "patterns", "regex", "i", "c", "makeBoundServer", "request", "config", "_t", "namespace", "cache", "backend", "client", "makeBackendClientBound", "_namespace", "userRequest", "call", "method", "path", "body", "options", "matchesAnyGlob", "FetchError", "targetUrl", "headers", "ctx", "result", "readErrorBody", "sendBody", "response", "isEmpty", "ct", "errorBody", "res", "apiCache", "apiCacheKey", "isDevixHandler", "h", "HANDLER_BRAND", "parseBody", "request", "ct", "jsonResponse", "body", "status", "resultToResponse", "result", "isLoaderError", "errorToBody", "handleApiRequest", "url", "glob", "serverConfig", "pathname", "cacheKey", "buildRoutes", "routes", "middlewares", "matched", "matchRoute", "route", "params", "$server", "makeBoundServer", "ctx", "RouteContext", "withHandlerStore", "middlewareChain", "collectMiddlewareChain", "mw", "mod", "mwResult", "method", "handler", "rawBody", "error", "err", "DevixError"]
4
+ "sourcesContent": ["export function routePattern(rel: string): string {\n return rel\n .replace(/\\.(tsx|ts|jsx|js)$/, '')\n .replace(/\\(.*?\\)\\//g, '')\n .replace(/^index$|\\/index$/, '')\n .replace(/\\[([^\\]]+)]/g, ':$1')\n || '/'\n}", "import {routePattern} from \"../utils/patterns\";\n\nexport interface ApiRoute {\n path: string\n key: string\n params: string[]\n regex: RegExp\n}\n\nexport interface ApiMiddleware {\n dir: string\n key: string\n}\n\nexport interface ApiResult {\n routes: ApiRoute[]\n middlewares: ApiMiddleware[]\n}\n\nexport function keyToRoutePattern(key: string, apiDir: string): string {\n const rel = key.slice(apiDir.length + 1).replace(/\\\\/g, '/')\n const pattern = routePattern(rel)\n return pattern === '/' ? '/api' : `/api/${pattern}`.replace('/api//', '/api/')\n}\n\nfunction keyToDir(key: string): string {\n return key.slice(0, key.lastIndexOf('/'))\n}\n\nexport function buildRoutes(routeKeys: string[], middlewareKeys: string[], apiDir: string): ApiResult {\n const routes: ApiRoute[] = []\n const middlewares: ApiMiddleware[] = []\n\n for (const key of middlewareKeys) {\n middlewares.push({dir: keyToDir(key), key})\n }\n\n for (const key of routeKeys) {\n const pattern = keyToRoutePattern(key, apiDir)\n const params = [...pattern.matchAll(/:([^/]+)/g)].map(m => m[1])\n const regexStr = pattern\n .replace(/:[^/]+/g, '([^/]+)')\n .replace(/\\//g, '\\\\/')\n routes.push({path: pattern, key, params, regex: new RegExp(`^${regexStr}$`)})\n }\n routes.sort((a, b) => {\n const aScore = (a.path.match(/:/g) || []).length\n const bScore = (b.path.match(/:/g) || []).length\n if (aScore !== bScore) return aScore - bScore\n return b.path.length - a.path.length\n })\n\n return {routes, middlewares}\n}\n\nexport function collectMiddlewareChain(routeKey: string, middlewares: ApiMiddleware[]): ApiMiddleware[] {\n const routeDir = keyToDir(routeKey)\n\n return middlewares\n .filter(mw => routeDir.startsWith(mw.dir))\n .sort((a, b) => a.dir.split('/').length - b.dir.split('/').length)\n}\n\nexport function matchRoute(\n pathname: string,\n routes: ApiRoute[]\n): { route: ApiRoute; params: Record<string, string> } | null {\n for (const route of routes) {\n const match = pathname.match(route.regex)\n if (match) {\n const params: Record<string, string> = {}\n route.params.forEach((name, i) => {\n params[name] = decodeURIComponent(match[i + 1])\n })\n return {route, params}\n }\n }\n return null\n}\n", "import type {DevixHandler} from './create-handler'\nimport type {RouteError} from '../utils/response'\nimport type {BackendClient} from './server-client'\n\nexport class RouteContext {\n readonly params: Record<string, string>\n readonly request: Request\n readonly url: URL\n readonly $server: Record<string, BackendClient>\n private _state = new Map<string, unknown>()\n\n constructor(\n params: Record<string, string>,\n request: Request,\n url: URL,\n $server: Record<string, BackendClient> = {},\n ) {\n this.params = params\n this.request = request\n this.url = url\n this.$server = $server\n }\n\n set<T>(key: string, value: T): void {\n this._state.set(key, value)\n }\n\n get<T>(key: string): T | undefined {\n return this._state.get(key) as T\n }\n}\n\nexport type RouteResult = Response | RouteError | Record<string, unknown> | unknown[] | null | void\n\nexport type RouteHandler = (ctx: RouteContext) => Promise<RouteResult> | RouteResult\n\nexport interface MiddlewareModule {\n middleware: (ctx: RouteContext) => Promise<Response | null> | Response | null\n}\n\ntype AnyHandler = RouteHandler | DevixHandler<any, any>\n\nexport interface RouteModule {\n GET?: AnyHandler\n POST?: AnyHandler\n PUT?: AnyHandler\n PATCH?: AnyHandler\n DELETE?: AnyHandler\n HEAD?: AnyHandler\n OPTIONS?: AnyHandler\n}\n", "import {Component, ComponentType, ReactNode} from \"react\";\nimport {ErrorProps} from \"../server/types\";\n\ninterface Props {\n ErrorPage?: ComponentType<ErrorProps>\n children: ReactNode\n}\n\ninterface State {\n error: ErrorProps | null\n}\n\nexport class DevixErrorBoundary extends Component<Props, State> {\n state: State = { error: null }\n\n static getDerivedStateFromError(err: unknown): State {\n if (err instanceof DevixError) {\n return {\n error: {statusCode: err.statusCode, message: err.message}\n }\n }\n return {\n error: {statusCode: 500, message: err instanceof Error ? err.message : 'Unknown error'}\n }\n }\n\n render() {\n if (this.state.error && this.props.ErrorPage) {\n return <this.props.ErrorPage {...this.state.error} />\n }\n if (this.state.error) {\n return <h1>{this.state.error.statusCode}</h1>\n }\n return this.props.children\n }\n}\n\nexport interface DevixErrorOptions {\n code?: string\n data?: unknown\n}\n\nconst DEVIX_ERROR_BRAND = Symbol.for('@devlusoft/devix.DevixError')\n\nexport class DevixError extends Error {\n /**\n * Custom `instanceof` que matchea por brand cross-bundle. Ver nota en\n * `FetchError` para el detalle del dual package hazard.\n */\n static [Symbol.hasInstance](value: unknown): boolean {\n return value !== null && typeof value === 'object' && (value as any)[DEVIX_ERROR_BRAND] === true\n }\n\n statusCode: number\n code?: string\n data?: unknown\n constructor(statusCode: number, message: string, options?: DevixErrorOptions) {\n super(message)\n this.name = 'DevixError'\n this.statusCode = statusCode\n this.code = options?.code\n this.data = options?.data\n ;(this as any)[DEVIX_ERROR_BRAND] = true\n }\n}\n", "import type {RouteContext} from './api-context'\nimport type {StandardSchemaV1} from '../utils/standard-schema'\n\nexport const HANDLER_BRAND = '__devix_handler__' as const\n\nexport interface DevixHandler<TBody = undefined, TReturn = unknown> {\n readonly [HANDLER_BRAND]: true\n readonly fn: (...args: any[]) => any\n readonly schema?: StandardSchemaV1\n readonly __body: TBody\n readonly __return: TReturn\n}\n\n/**\n * Crea un handler API tipado.\n *\n * El primer argumento (si lo declaras) es el body parseado autom\u00E1ticamente:\n * - `application/json` \u2192 objeto JS\n * - `multipart/form-data` o `application/x-www-form-urlencoded` \u2192 FormData\n * - cualquier otro \u2192 string\n *\n * El segundo argumento es `ctx: RouteContext` con `request`, `url`, `params`,\n * y los helpers `get`/`set` para state heredado de middleware.\n *\n * ```ts\n * // sin body\n * export const GET = createHandler(async () => ({ ok: true }))\n *\n * // con body tipado\n * export const POST = createHandler(async (body: Login) => ...)\n *\n * // con body y ctx\n * export const POST = createHandler(async (body: Login, ctx) => {\n * const user = ctx.get<User>('user')\n * const ua = ctx.request.headers.get('User-Agent')\n * })\n *\n * // solo ctx, sin body (ej. GET que necesita query params)\n * export const GET = createHandler(async (_body, ctx) => {\n * const filter = ctx.url.searchParams.get('filter')\n * })\n * ```\n */\ntype ExtractBody<TFn> =\n TFn extends () => any ? undefined :\n TFn extends (body: infer B, ...rest: any[]) => any ? B :\n undefined\n\ntype HandlerFn = ((body: any, ctx: RouteContext) => any) | (() => any)\n\nexport function createHandler<TFn extends HandlerFn>(\n fn: TFn,\n): DevixHandler<ExtractBody<TFn>, Awaited<ReturnType<TFn>>>\n\n/**\n * Overload con Standard Schema. devix valida el body autom\u00E1ticamente y, si\n * falla, devuelve `400` con shape `ErrorBody` y `code: 'VALIDATION_ERROR'`.\n * El body recibido por el handler est\u00E1 ya validado y tipado al output del schema.\n *\n * ```ts\n * import { z } from 'zod'\n *\n * const Input = z.object({ email: z.email(), password: z.string().min(8) })\n *\n * export const POST = createHandler(Input, async (body, ctx) => {\n * // body: z.infer<typeof Input>, ya validado\n * })\n * ```\n */\nexport function createHandler<TSchema extends StandardSchemaV1, TReturn>(\n schema: TSchema,\n fn: (body: StandardSchemaV1.InferOutput<TSchema>, ctx: RouteContext) => TReturn | Promise<TReturn>,\n): DevixHandler<StandardSchemaV1.InferInput<TSchema>, Awaited<TReturn>>\n\nexport function createHandler(\n schemaOrFn: StandardSchemaV1 | ((...args: any[]) => any),\n maybeFn?: (...args: any[]) => any,\n): DevixHandler<any, any> {\n if (maybeFn) {\n return {\n [HANDLER_BRAND]: true,\n fn: maybeFn,\n schema: schemaOrFn as StandardSchemaV1,\n } as unknown as DevixHandler<any, any>\n }\n return {\n [HANDLER_BRAND]: true,\n fn: schemaOrFn as (...args: any[]) => any,\n } as unknown as DevixHandler<any, any>\n}\n", "import {AsyncLocalStorage} from 'node:async_hooks'\nimport type {RouteContext} from '../runtime/api-context'\n\ninterface HandlerStore {\n request: Request\n ctx: RouteContext\n}\n\nconst ALS_KEY = Symbol.for('@devlusoft/devix.handlerStore')\nconst g = globalThis as Record<symbol, unknown>\nif (!g[ALS_KEY]) g[ALS_KEY] = new AsyncLocalStorage<HandlerStore>()\nconst storage = g[ALS_KEY] as AsyncLocalStorage<HandlerStore>\n\nexport function withHandlerStore<T>(store: HandlerStore, fn: () => T): T {\n return storage.run(store, fn)\n}\n\nfunction getStore(hookName: string): HandlerStore {\n const store = storage.getStore()\n if (!store) throw new Error(`[devix] ${hookName}() called outside of a request handler`)\n return store\n}\n\n/**\n * @deprecated Usa el `ctx` que recibe tu handler como segundo argumento:\n * `createHandler(async (body, ctx) => ctx.request)`. Ser\u00E1 eliminado en v0.6.\n */\nexport function useRequest(): Request {\n return getStore('useRequest').request\n}\n\n/**\n * @deprecated Usa el `ctx` que recibe tu handler como segundo argumento.\n * Ser\u00E1 eliminado en v0.6.\n */\nexport function useCtx(): RouteContext {\n return getStore('useCtx').ctx\n}\n\n/**\n * @deprecated Usa `ctx.params` desde el segundo argumento de tu handler.\n * Ser\u00E1 eliminado en v0.6.\n */\nexport function useParams(): Record<string, string> {\n return getStore('useParams').ctx.params\n}\n", "export type JsonResponse<T = unknown, S extends number = number> = Response & {\n readonly __body: T\n readonly __status: S\n}\n\nexport function json<const T>(data: T): JsonResponse<T, 200>\nexport function json<const T, const S extends number>(data: T, status: S): JsonResponse<T, S>\nexport function json<const T>(data: T, status: number = 200): JsonResponse<T, any> {\n return new Response(JSON.stringify(data), {\n status,\n headers: {'Content-Type': 'application/json'},\n }) as JsonResponse<T, any>\n}\n\nexport const text = (body: string, status = 200): Response =>\n new Response(body, {status, headers: {'Content-Type': 'text/plain; charset=utf-8'}})\n\nconst REDIRECT_BRAND = Symbol.for('devix.redirect')\n\nexport interface RedirectOptions {\n status?: number\n replace?: boolean\n}\n\nexport interface Redirect {\n readonly [REDIRECT_BRAND]: true\n readonly url: string\n readonly status: number\n readonly replace: boolean\n}\n\nexport function redirect(url: string, statusOrOptions?: number | RedirectOptions): Redirect {\n const status = typeof statusOrOptions === 'number' ? statusOrOptions : (statusOrOptions?.status ?? 302)\n const replace = typeof statusOrOptions === 'object' ? (statusOrOptions?.replace ?? false) : false\n return {[REDIRECT_BRAND]: true, url, status, replace} as Redirect\n}\n\nexport function isRedirect(value: unknown): value is Redirect {\n return typeof value === 'object' && value !== null && REDIRECT_BRAND in value\n}\n\nconst ERROR_BRAND = Symbol.for('devix.loaderError')\n\nexport interface RouteError {\n readonly [ERROR_BRAND]: true\n readonly statusCode: number\n readonly message: string\n readonly code?: string\n readonly data?: unknown\n}\n\nexport interface ErrorOptions {\n code?: string\n data?: unknown\n}\n\n/**\n * Crea un error tipado que funciona en loaders, guards y handlers API.\n *\n * En loaders/guards: ret\u00F3rnalo (no lo lances) y el sistema renderiza `error.tsx`.\n * En handlers API: ret\u00F3rnalo y el sistema serializa el shape `ErrorBody` como JSON\n * con el statusCode correcto.\n *\n * ```ts\n * return error(404, 'Post no encontrado', { code: 'POST_NOT_FOUND' })\n * ```\n */\nexport function error(statusCode: number, message: string, options?: ErrorOptions): RouteError {\n return {\n [ERROR_BRAND]: true,\n statusCode,\n message,\n code: options?.code,\n data: options?.data,\n } as RouteError\n}\n\nexport function isLoaderError(value: unknown): value is RouteError {\n return typeof value === 'object' && value !== null && ERROR_BRAND in value\n}\n\n/**\n * Shape p\u00FAblico del body de un error API. Todos los errores emitidos por `error()`\n * o `DevixError` se serializan a este shape. `FetchError.body` del cliente lo recibe.\n */\nexport interface ErrorBody {\n statusCode: number\n message: string\n code?: string\n data?: unknown\n}\n\nexport function errorToBody(err: { statusCode: number; message: string; code?: string; data?: unknown }): ErrorBody {\n const body: ErrorBody = { statusCode: err.statusCode, message: err.message }\n if (err.code !== undefined) body.code = err.code\n if (err.data !== undefined) body.data = err.data\n return body\n}\n", "export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'\n\nfunction extractMessage(body: unknown): string | null {\n if (body && typeof body === 'object' && 'message' in body) {\n const m = (body as {message: unknown}).message\n if (typeof m === 'string' && m.length > 0) return m\n }\n return null\n}\n\nconst FETCH_ERROR_BRAND = Symbol.for('@devlusoft/devix.FetchError')\n\nexport class FetchError<E = unknown> extends Error {\n static [Symbol.hasInstance](value: unknown): boolean {\n return value !== null && typeof value === 'object' && (value as any)[FETCH_ERROR_BRAND] === true\n }\n\n constructor(\n public readonly status: number,\n public readonly statusText: string,\n public readonly response: Response,\n public readonly body?: E,\n ) {\n super(extractMessage(body) ?? `HTTP ${status}: ${statusText}`)\n this.name = 'FetchError'\n ;(this as any)[FETCH_ERROR_BRAND] = true\n }\n\n get code(): string | undefined {\n if (this.body && typeof this.body === 'object' && 'code' in this.body) {\n const c = (this.body as {code: unknown}).code\n return typeof c === 'string' ? c : undefined\n }\n return undefined\n }\n}\n", "/**\n * Match simple de path contra un glob estilo `'/v1/**'`, `'/v1/users/*'`, `'/v1/users/:id'`.\n *\n * Reglas:\n * - `**` matchea cualquier subpath (incluye `/`).\n * - `*` matchea un \u00FAnico segmento (sin `/`).\n * - `:param` matchea un \u00FAnico segmento.\n * - Cualquier otro caracter es literal.\n */\nexport function matchPathGlob(path: string, pattern: string): boolean {\n const regex = globToRegex(pattern)\n return regex.test(path)\n}\n\nexport function matchesAnyGlob(path: string, patterns: readonly string[] | undefined): boolean {\n if (!patterns || patterns.length === 0) return false\n for (const pattern of patterns) {\n if (matchPathGlob(path, pattern)) return true\n }\n return false\n}\n\nfunction globToRegex(pattern: string): RegExp {\n let regex = ''\n let i = 0\n while (i < pattern.length) {\n const c = pattern[i]\n if (c === '*' && pattern[i + 1] === '*') {\n regex += '.*'\n i += 2\n } else if (c === '*') {\n regex += '[^/]*'\n i += 1\n } else if (c === ':') {\n i += 1\n while (i < pattern.length && /[a-zA-Z0-9_]/.test(pattern[i])) i += 1\n regex += '[^/]+'\n } else if ('.+?^$()|[]{}\\\\'.includes(c)) {\n regex += '\\\\' + c\n i += 1\n } else {\n regex += c\n i += 1\n }\n }\n return new RegExp(`^${regex}$`)\n}\n", "import {FetchError, type HttpMethod} from '../runtime/fetch'\nimport {matchesAnyGlob} from '../utils/glob'\nimport type {ServerBackendConfig, PrepareContext} from '../config'\nimport type {BackendClient} from '../runtime/server-client'\n\n/**\n * Construye un `$server` server-side bound al request del usuario.\n *\n * Diferencias clave vs el `$server` cliente:\n * - Hace fetch directo a `backend.url + path` (sin pasar por el proxy interno).\n * - Aplica `prepare` con el `Request` del loader/handler para que pueda leer cookies.\n * - Aplica allowlist/denylist por simetr\u00EDa con el proxy cliente.\n */\nexport function makeBoundServer(\n request: Request,\n config: Record<string, ServerBackendConfig> | undefined,\n): Record<string, BackendClient> {\n if (!config) return new Proxy({} as any, {\n get(_t, namespace: string) {\n throw new Error(`[devix] ctx.$server.${String(namespace)} called but no 'server' config is defined in devix.config.ts`)\n },\n })\n\n const cache = new Map<string, BackendClient>()\n return new Proxy({} as any, {\n get(_t, namespace: string) {\n if (typeof namespace !== 'string') return undefined\n const backend = config[namespace]\n if (!backend) {\n throw new Error(`[devix] ctx.$server.${namespace} \u2014 namespace \"${namespace}\" not configured in devix.config.ts`)\n }\n let client = cache.get(namespace)\n if (!client) {\n client = makeBackendClientBound(namespace, backend, request)\n cache.set(namespace, client)\n }\n return client\n },\n })\n}\n\nfunction makeBackendClientBound(\n _namespace: string,\n backend: ServerBackendConfig,\n userRequest: Request,\n): BackendClient {\n async function call<TResult>(method: HttpMethod, path: string, body?: unknown, options?: {headers?: HeadersInit; signal?: AbortSignal}): Promise<TResult> {\n if (!matchesAnyGlob(path, backend.allowedPaths)) {\n throw new FetchError(403, 'Path not allowed', new Response(null, {status: 403}), {\n statusCode: 403, message: 'Path not allowed', code: 'PATH_NOT_ALLOWED',\n })\n }\n if (matchesAnyGlob(path, backend.deniedPaths)) {\n throw new FetchError(403, 'Path denied', new Response(null, {status: 403}), {\n statusCode: 403, message: 'Path denied', code: 'PATH_DENIED',\n })\n }\n\n const targetUrl = new URL(path, backend.url)\n const headers = new Headers(options?.headers)\n if (backend.prepare) {\n const ctx: PrepareContext = {request: userRequest, headers, url: targetUrl}\n const result = await backend.prepare(ctx)\n if (result instanceof Response) {\n throw new FetchError(\n result.status,\n result.statusText,\n result,\n await readErrorBody(result),\n )\n }\n }\n\n let sendBody: BodyInit | undefined\n if (body !== undefined && body !== null && method !== 'GET' && method !== 'HEAD') {\n if (body instanceof FormData || body instanceof Blob || body instanceof ArrayBuffer) {\n sendBody = body\n } else {\n sendBody = JSON.stringify(body)\n if (!headers.has('Content-Type')) headers.set('Content-Type', 'application/json')\n }\n }\n\n const response = await fetch(targetUrl, {method, headers, body: sendBody, signal: options?.signal})\n const isEmpty = response.status === 204 || response.headers.get('Content-Length') === '0'\n\n if (!response.ok) {\n const ct = response.headers.get('Content-Type') ?? ''\n let errorBody: unknown\n if (!isEmpty && ct.includes('application/json')) {\n try { errorBody = await response.json() } catch { /* body inv\u00E1lido */ }\n }\n throw new FetchError(response.status, response.statusText, response, errorBody)\n }\n\n if (isEmpty) return null as TResult\n\n const ct = response.headers.get('Content-Type') ?? ''\n if (ct.includes('application/json')) return await response.json() as TResult\n return await response.text() as unknown as TResult\n }\n\n return {\n get: ((path: string, options?: any) => call('GET', path, undefined, options)) as BackendClient['get'],\n post: ((path: string, body?: any, options?: any) => call('POST', path, body, options)) as BackendClient['post'],\n put: ((path: string, body?: any, options?: any) => call('PUT', path, body, options)) as BackendClient['put'],\n patch: ((path: string, body?: any, options?: any) => call('PATCH', path, body, options)) as BackendClient['patch'],\n delete: ((path: string, options?: any) => call('DELETE', path, undefined, options)) as BackendClient['delete'],\n }\n}\n\nasync function readErrorBody(res: Response): Promise<unknown> {\n const ct = res.headers.get('Content-Type') ?? ''\n if (ct.includes('application/json')) {\n try { return await res.json() } catch { return undefined }\n }\n return undefined\n}\n", "import {buildRoutes, matchRoute, collectMiddlewareChain, ApiResult} from './api-router'\nimport {RouteContext} from '../runtime/api-context'\nimport type {RouteModule, MiddlewareModule, RouteResult} from '../runtime/api-context'\nimport type {ApiGlob} from './types'\nimport {DevixError} from '../runtime/error-boundary'\nimport {HANDLER_BRAND, type DevixHandler} from '../runtime/create-handler'\nimport {withHandlerStore} from './handler-store'\nimport {error, errorToBody, isLoaderError} from '../utils/response'\nimport type {ServerBackendConfig} from '../config'\nimport {makeBoundServer} from './server-bound'\n\nlet apiCache: ApiResult | null = null\nlet apiCacheKey: string | null = null\n\nfunction isDevixHandler(h: unknown): h is DevixHandler<any, any> {\n return typeof h === 'object' && h !== null && HANDLER_BRAND in h\n}\n\nasync function parseBody(request: Request): Promise<unknown> {\n const ct = request.headers.get('Content-Type') ?? ''\n if (ct.includes('application/json')) return request.json()\n if (ct.includes('multipart/form-data') || ct.includes('application/x-www-form-urlencoded')) {\n return request.formData()\n }\n return request.text()\n}\n\nfunction jsonResponse(body: unknown, status: number): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: {'Content-Type': 'application/json'},\n })\n}\n\nfunction resultToResponse(result: RouteResult): Response {\n if (result instanceof Response) return result\n if (isLoaderError(result)) return jsonResponse(errorToBody(result), result.statusCode)\n if (result == null) return new Response(null, {status: 204})\n return new Response(JSON.stringify(result), {\n headers: {'Content-Type': 'application/json'},\n })\n}\n\nexport async function handleApiRequest(\n url: string,\n request: Request,\n glob: ApiGlob,\n serverConfig?: Record<string, ServerBackendConfig>,\n): Promise<Response> {\n try {\n const {pathname} = new URL(url, 'http://localhost')\n const cacheKey = Object.keys(glob.routes).sort().join('\\0') + '|' + Object.keys(glob.middlewares).sort().join('\\0')\n if (!apiCache || apiCacheKey !== cacheKey) {\n apiCache = buildRoutes(\n Object.keys(glob.routes),\n Object.keys(glob.middlewares),\n glob.apiDir,\n )\n apiCacheKey = cacheKey\n }\n const {routes, middlewares} = apiCache\n const matched = matchRoute(pathname, routes)\n\n if (!matched) return new Response('Not Found', {status: 404})\n\n const {route, params} = matched\n const $server = makeBoundServer(request, serverConfig)\n const ctx = new RouteContext(params, request, new URL(url, 'http://localhost'), $server)\n\n const result = await withHandlerStore({request, ctx}, async () => {\n const middlewareChain = collectMiddlewareChain(route.key, middlewares)\n for (const mw of middlewareChain) {\n const mod = await glob.middlewares[mw.key]() as MiddlewareModule\n if (mod.middleware) {\n const mwResult = await mod.middleware(ctx)\n if (mwResult instanceof Response) return mwResult\n }\n }\n\n const mod = await glob.routes[route.key]() as RouteModule\n const method = request.method.toUpperCase() as keyof RouteModule\n const handler = mod[method]\n\n if (!handler) return new Response('Method Not Allowed', {status: 405})\n\n if (isDevixHandler(handler)) {\n if (handler.fn.length === 0) {\n return handler.fn() as Promise<RouteResult>\n }\n const rawBody = await parseBody(request)\n if (handler.schema) {\n const result = await handler.schema['~standard'].validate(rawBody)\n if (result.issues) {\n return error(400, 'Validation failed', {\n code: 'VALIDATION_ERROR',\n data: {issues: result.issues},\n })\n }\n return handler.fn(result.value, ctx) as Promise<RouteResult>\n }\n return handler.fn(rawBody, ctx) as Promise<RouteResult>\n }\n\n return handler(ctx)\n })\n\n return resultToResponse(result)\n } catch (err) {\n if (err instanceof DevixError) {\n return jsonResponse(errorToBody(err), err.statusCode)\n }\n console.error('[devix] api error:', err)\n return jsonResponse({statusCode: 500, message: 'Internal Server Error'}, 500)\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["routePattern", "rel", "keyToRoutePattern", "key", "apiDir", "rel", "pattern", "routePattern", "keyToDir", "buildRoutes", "routeKeys", "middlewareKeys", "routes", "middlewares", "params", "m", "regexStr", "a", "b", "aScore", "bScore", "collectMiddlewareChain", "routeKey", "routeDir", "mw", "matchRoute", "pathname", "route", "match", "name", "i", "RouteContext", "params", "request", "url", "$server", "key", "value", "Component", "jsx", "DEVIX_ERROR_BRAND", "DevixError", "value", "statusCode", "message", "options", "HANDLER_BRAND", "AsyncLocalStorage", "ALS_KEY", "g", "storage", "withHandlerStore", "store", "fn", "ERROR_BRAND", "error", "statusCode", "message", "options", "isLoaderError", "value", "errorToBody", "err", "body", "extractMessage", "body", "m", "FETCH_ERROR_BRAND", "FetchError", "status", "statusText", "response", "value", "c", "matchPathGlob", "path", "pattern", "globToRegex", "matchesAnyGlob", "patterns", "regex", "i", "c", "makeBoundServer", "request", "config", "_t", "namespace", "cache", "backend", "client", "makeBackendClientBound", "_namespace", "userRequest", "call", "method", "path", "body", "options", "matchesAnyGlob", "FetchError", "targetUrl", "headers", "ctx", "result", "readErrorBody", "sendBody", "response", "isEmpty", "ct", "errorBody", "res", "apiCache", "apiCacheKey", "isDevixHandler", "h", "HANDLER_BRAND", "parseBody", "request", "ct", "jsonResponse", "body", "status", "resultToResponse", "result", "isLoaderError", "errorToBody", "handleApiRequest", "url", "glob", "serverConfig", "pathname", "cacheKey", "buildRoutes", "routes", "middlewares", "matched", "matchRoute", "route", "params", "$server", "makeBoundServer", "ctx", "RouteContext", "withHandlerStore", "middlewareChain", "collectMiddlewareChain", "mw", "mod", "mwResult", "method", "handler", "rawBody", "error", "err", "DevixError"]
7
7
  }
@@ -1,2 +1,2 @@
1
- import{createElement as Te}from"react";import{renderToString as ve,renderToStaticMarkup as Ee}from"react-dom/server";import{Fragment as Y,jsx as k}from"react/jsx-runtime";function ue(e,t){let r=[];e.title&&r.push({tag:"title",children:e.title}),e.description&&r.push({tag:"meta",name:"description",content:e.description}),e.keywords?.length&&r.push({tag:"meta",name:"keywords",content:e.keywords.join(", ")});let n=e.og?.title??e.title;n&&r.push({tag:"meta",property:"og:title",content:n});let o=e.og?.description??e.description;o&&r.push({tag:"meta",property:"og:description",content:o}),e.og?.image&&r.push({tag:"meta",property:"og:image",content:e.og.image}),e.og?.type&&r.push({tag:"meta",property:"og:type",content:e.og.type}),e.og?.url&&r.push({tag:"meta",property:"og:url",content:e.og.url});let a=e.twitter?.title??e.title;a&&r.push({tag:"meta",name:"twitter:title",content:a});let s=e.twitter?.description??e.description;if(s&&r.push({tag:"meta",name:"twitter:description",content:s}),e.twitter?.card&&r.push({tag:"meta",name:"twitter:card",content:e.twitter.card}),e.twitter?.image&&r.push({tag:"meta",name:"twitter:image",content:e.twitter.image}),e.twitter?.creator&&r.push({tag:"meta",name:"twitter:creator",content:e.twitter.creator}),e.canonical&&r.push({tag:"link",rel:"canonical",href:e.canonical}),e.robots&&r.push({tag:"meta",name:"robots",content:e.robots}),e.alternates)for(let[i,c]of Object.entries(e.alternates))r.push({tag:"link",rel:"alternate",href:c,hrefLang:i});if(e.icons){let i=Array.isArray(e.icons)?e.icons:[e.icons];for(let c of i){let u=typeof c=="string"?{href:c}:c;r.push({tag:"link",rel:u.rel??"icon",href:u.href,...u.type&&{type:u.type},...u.sizes&&{sizes:u.sizes}})}}if(t){let i=[];t.width!==void 0&&i.push(`width=${t.width}`),t.initialScale!==void 0&&i.push(`initial-scale=${t.initialScale}`),t.maximumScale!==void 0&&i.push(`maximum-scale=${t.maximumScale}`),t.userScalable!==void 0&&i.push(`user-scalable=${t.userScalable?"yes":"no"}`),i.length&&r.push({tag:"meta",name:"viewport",content:i.join(", ")}),t.themeColor&&r.push({tag:"meta",name:"theme-color",content:t.themeColor})}return r}function W({metadata:e,viewport:t}){return typeof window>"u"||!e?null:k(Y,{children:V(e,t)})}function V(e,t){let r=ue(e,t);return k(Y,{children:r.map((n,o)=>n.tag==="title"?k("title",{children:n.children},o):n.tag==="link"?k("link",{rel:n.rel,href:n.href,hrefLang:n.hrefLang,type:n.type,sizes:n.sizes},o):k("meta",{name:n.name,property:n.property,content:n.content},o))})}import{createContext as j}from"react";var v=globalThis;v.__devix_RouterContext__??=j(null);var q=v.__devix_RouterContext__;v.__devix_PageMetaContext__??=j(null);v.__devix_RouteDataContext__??=j(null);var X=v.__devix_PageMetaContext__,N=v.__devix_RouteDataContext__;import{Component as de}from"react";import{jsx as K}from"react/jsx-runtime";var B=class extends de{state={error:null};static getDerivedStateFromError(t){return t instanceof H?{error:{statusCode:t.statusCode,message:t.message}}:{error:{statusCode:500,message:t instanceof Error?t.message:"Unknown error"}}}render(){return this.state.error&&this.props.ErrorPage?K(this.props.ErrorPage,{...this.state.error}):this.state.error?K("h1",{children:this.state.error.statusCode}):this.props.children}},H=class extends Error{statusCode;code;data;constructor(t,r,n){super(r),this.name="DevixError",this.statusCode=t,this.code=n?.code,this.data=n?.data}};import{jsx as C,jsxs as me}from"react/jsx-runtime";var pe=(e,t)=>Promise.resolve(),ge=()=>Promise.resolve(),fe=e=>{};function Z({pathname:e,params:t,loaderData:r,layoutsData:n,guardData:o,Page:a,layouts:s,metadata:i,viewport:c,clientEntry:u}){let p=C(N,{value:{loaderData:r,params:t},children:C(a,{data:r,params:t,url:e})});for(let d=s.length-1;d>=0;d--){let g=s[d],w=n[d];p=C(N,{value:{loaderData:w,params:t},children:C(g,{data:w,params:t,children:p})})}return me(X,{value:{metadata:i,viewport:c,clientEntry:u},children:[C(W,{metadata:i,viewport:c}),C(q,{value:{pathname:e,params:t,loaderData:r,layoutsData:n,guardData:o,Page:a,layouts:s,metadata:i,viewport:c,isNavigating:!1,navigate:pe,revalidate:ge,prefetchRoute:fe},children:C(B,{children:p},e)})]})}function Q(e){return e.replace(/\.(tsx|ts|jsx|js)$/,"").replace(/\(.*?\)\//g,"").replace(/^index$|\/index$/,"").replace(/\[([^\]]+)]/g,":$1")||"/"}function ye(e,t){let r=e.slice(t.length+1).replace(/\\/g,"/"),n=Q(r);return n==="/"?"/":`/${n}`}function ee(e){return e.slice(0,e.lastIndexOf("/"))}function I(e,t,r){let n=[],o=[];for(let a of t)o.push({dir:ee(a),key:a});for(let a of e){let s=ye(a,r),i=[...s.matchAll(/:([^/]+)/g)].map(u=>u[1]),c=s.replace(/:[^/]+/g,"([^/]+)").replace(/\//g,"\\/");n.push({path:s,key:a,params:i,regex:new RegExp(`^${c}$`)})}return n.sort((a,s)=>{let i=a.path.split("/").filter(Boolean),c=s.path.split("/").filter(Boolean),u=Math.max(i.length,c.length);for(let p=0;p<u;p++){let d=p<i.length?i[p].startsWith(":")?1:2:0,g=p<c.length?c[p].startsWith(":")?1:2:0;if(d!==g)return g-d}return s.path.length-a.path.length}),{pages:n,layouts:o}}function te(e,t){let r=ee(e);return t.filter(n=>r.startsWith(n.dir)).sort((n,o)=>n.dir.split("/").length-o.dir.split("/").length)}function re(e,t){for(let r of t){let n=e.match(r.regex);if(n){let o={};return r.params.forEach((a,s)=>{o[a]=decodeURIComponent(n[s+1])}),{page:r,params:o}}}return null}async function U(e,t){let r=e.generateMetadata?await e.generateMetadata(t):e.metadata??{},n=e.generateViewport?await e.generateViewport(t):e.viewport;return{metadata:r,viewport:n}}function ne(...e){let t={};for(let r of e){if(!r)continue;let{og:n,twitter:o,...a}=r;Object.assign(t,a),n&&(t.og={...t.og,...n}),o&&(t.twitter={...t.twitter,...o})}return t}function P(e){return JSON.stringify(e).replace(/<\/script>/gi,"<\\/script>")}function oe(e){return e.replace(/"/g,"&quot;")}function G(e,t){let r;return Promise.race([e.finally(()=>clearTimeout(r)),new Promise((n,o)=>{r=setTimeout(()=>o(new Error(`timed out after ${t}ms`)),t)})])}var he=Symbol.for("devix.redirect");function O(e){return typeof e=="object"&&e!==null&&he in e}var we=Symbol.for("devix.loaderError");function D(e){return typeof e=="object"&&e!==null&&we in e}function ae(e){let t={statusCode:e.statusCode,message:e.message};return e.code!==void 0&&(t.code=e.code),e.data!==void 0&&(t.data=e.data),t}function xe(e){if(e&&typeof e=="object"&&"message"in e){let t=e.message;if(typeof t=="string"&&t.length>0)return t}return null}var T=class extends Error{constructor(r,n,o,a){super(xe(a)??`HTTP ${r}: ${n}`);this.status=r;this.statusText=n;this.response=o;this.body=a;this.name="FetchError"}get code(){if(this.body&&typeof this.body=="object"&&"code"in this.body){let r=this.body.code;return typeof r=="string"?r:void 0}}};function Re(e,t){return _e(t).test(e)}function J(e,t){if(!t||t.length===0)return!1;for(let r of t)if(Re(e,r))return!0;return!1}function _e(e){let t="",r=0;for(;r<e.length;){let n=e[r];if(n==="*"&&e[r+1]==="*")t+=".*",r+=2;else if(n==="*")t+="[^/]*",r+=1;else if(n===":"){for(r+=1;r<e.length&&/[a-zA-Z0-9_]/.test(e[r]);)r+=1;t+="[^/]+"}else".+?^$()|[]{}\\".includes(n)?(t+="\\"+n,r+=1):(t+=n,r+=1)}return new RegExp(`^${t}$`)}function se(e,t){if(!t)return new Proxy({},{get(n,o){throw new Error(`[devix] ctx.$server.${String(o)} called but no 'server' config is defined in devix.config.ts`)}});let r=new Map;return new Proxy({},{get(n,o){if(typeof o!="string")return;let a=t[o];if(!a)throw new Error(`[devix] ctx.$server.${o} \u2014 namespace "${o}" not configured in devix.config.ts`);let s=r.get(o);return s||(s=Pe(o,a,e),r.set(o,s)),s}})}function Pe(e,t,r){async function n(o,a,s,i){if(!J(a,t.allowedPaths))throw new T(403,"Path not allowed",new Response(null,{status:403}),{statusCode:403,message:"Path not allowed",code:"PATH_NOT_ALLOWED"});if(J(a,t.deniedPaths))throw new T(403,"Path denied",new Response(null,{status:403}),{statusCode:403,message:"Path denied",code:"PATH_DENIED"});let c=new URL(a,t.url),u=new Headers(i?.headers);if(t.prepare){let y={request:r,headers:u,url:c},m=await t.prepare(y);if(m instanceof Response)throw new T(m.status,m.statusText,m,await Ce(m))}let p;s!=null&&o!=="GET"&&o!=="HEAD"&&(s instanceof FormData||s instanceof Blob||s instanceof ArrayBuffer?p=s:(p=JSON.stringify(s),u.has("Content-Type")||u.set("Content-Type","application/json")));let d=await fetch(c,{method:o,headers:u,body:p,signal:i?.signal}),g=d.status===204||d.headers.get("Content-Length")==="0";if(!d.ok){let y=d.headers.get("Content-Type")??"",m;if(!g&&y.includes("application/json"))try{m=await d.json()}catch{}throw new T(d.status,d.statusText,d,m)}return g?null:(d.headers.get("Content-Type")??"").includes("application/json")?await d.json():await d.text()}return{get:((o,a)=>n("GET",o,void 0,a)),post:((o,a,s)=>n("POST",o,a,s)),put:((o,a,s)=>n("PUT",o,a,s)),patch:((o,a,s)=>n("PATCH",o,a,s)),delete:((o,a)=>n("DELETE",o,void 0,a))}}async function Ce(e){if((e.headers.get("Content-Type")??"").includes("application/json"))try{return await e.json()}catch{return}}var ke={width:"device-width",initialScale:1},z=null,ie=null,De="/@id/virtual:devix/entry-client";function ce(e){return typeof e=="string"?{url:e,status:302,replace:!1}:O(e)?{url:e.url,status:e.status,replace:e.replace}:null}async function le(e,t,r,n,o){let a=Object.keys(r.pages).sort().join("\0")+"|"+Object.keys(r.layouts).sort().join("\0");(!z||ie!==a)&&(z=I(Object.keys(r.pages),Object.keys(r.layouts),r.pagesDir),ie=a);let{pages:s,layouts:i}=z,c=re(e,s);if(!c)return null;let{page:u,params:p}=c,d=te(u.key,i),[g,...w]=await Promise.all([r.pages[u.key](),...d.map(l=>r.layouts[l.key]())]),y,m=se(t,o);for(let l of w)if(l.guard){let h=await l.guard({params:p,request:t,guardData:y,$server:m}),$=ce(h);if($!==null)return{redirect:$.url,redirectStatus:$.status,redirectReplace:$.replace};if(D(h))return{loaderError:h};h!=null&&(y=h)}if(g.guard){let l=await g.guard({params:p,request:t,guardData:y,$server:m}),h=ce(l);if(h!==null)return{redirect:h.url,redirectStatus:h.status,redirectReplace:h.replace};if(D(l))return{loaderError:l};l!=null&&(y=l)}let x={params:p,request:t,guardData:y,$server:m},R=g.loader?await G(Promise.resolve(g.loader(x)),n):null;if(O(R))return{redirect:R.url,redirectStatus:R.status,redirectReplace:R.replace};if(D(R))return{loaderError:R};let S=R,b=await G(Promise.all(w.map(l=>l.loader?l.loader(x):null)),n);for(let l of b){if(O(l))return{redirect:l.url,redirectStatus:l.status,redirectReplace:l.replace};if(D(l))return{loaderError:l}}let E=b,M=await U(g,{...x,loaderData:S}),A=await Promise.all(w.map((l,h)=>U(l,{...x,loaderData:E[h]}))),F=ne(...A.map(l=>l.metadata),M.metadata),f=M.viewport??A.findLast(l=>l.viewport)?.viewport??ke,_=w[0],L=_?.generateLang?await _.generateLang({...x,loaderData:E[0]}):_?.lang??"en";return{pageMod:g,layoutMods:w,params:p,loaderData:S,layoutsData:E,guardData:y,metadata:F,viewport:f,lang:L}}async function mt(e,t,r,n){let{pathname:o}=new URL(e,"http://localhost"),a;try{let g=n?.loaderTimeout??1e4;a=await le(o,t,r,g,n?.server)}catch(g){return console.error("[devix] render error:",g),{error:!0,loaderData:null,params:{},layouts:[],metadata:null,viewport:void 0}}if(!a)return{loaderData:null,params:{},layouts:[],metadata:null,viewport:void 0};if("redirect"in a)return{redirect:a.redirect,redirectStatus:a.redirectStatus,redirectReplace:a.redirectReplace};if("loaderError"in a)return{loaderError:a.loaderError};let{loaderData:s,params:i,layoutsData:c,guardData:u,metadata:p,viewport:d}=a;return{loaderData:s,params:i,layouts:c.map(g=>({loaderData:g})),guardData:u,metadata:p,viewport:d}}async function yt(e,t,r,n){let o=n?.manifest?`/${Object.values(n.manifest).find(f=>f.isEntry)?.file}`:De,s=(n?.manifest?Object.values(n.manifest).find(f=>f.isEntry)?.css??[]:[]).map(f=>`<link rel="stylesheet" href="/${f}">`).join(""),{pathname:i}=new URL(e,"http://localhost"),c;try{let f=n?.loaderTimeout??1e4;c=await le(i,t,r,f,n?.server)}catch(f){return console.error("[devix] render error:",f),{html:`<html lang="en"><head><meta charset="utf-8">${s}</head><body><script>window.__DEVIX__=null;window.__LOADER_DATA__=null;window.__LAYOUTS_DATA__=[];</script><script type="module" src="${o}"></script><div id="devix-root"></div></body></html>`,statusCode:500,headers:{}}}if(!c){let f=`<script>window.__DEVIX__=${P({metadata:null,viewport:void 0,clientEntry:o})};window.__LOADER_DATA__=null;window.__LAYOUTS_DATA__=[];</script>`,_=`<script type="module" src="${o}"></script>`;return{html:`<html lang="en"><head><meta charset="utf-8">${s}${f}</head><body><div id="devix-root"></div>${_}</body></html>`,statusCode:404,headers:{}}}if("redirect"in c)return{html:"",statusCode:c.redirectStatus,headers:{Location:c.redirect}};if("loaderError"in c){let f=ae(c.loaderError),_=`<script>window.__DEVIX__=${P({metadata:null,viewport:void 0,clientEntry:o})};window.__LOADER_DATA__=null;window.__LAYOUTS_DATA__=[];window.__LOADER_ERROR__=${P(f)};</script>`,L=`<script type="module" src="${o}"></script>`;return{html:`<html lang="en"><head><meta charset="utf-8">${s}${_}</head><body><div id="devix-root"></div>${L}</body></html>`,statusCode:f.statusCode,headers:{}}}let{pageMod:u,layoutMods:p,params:d,loaderData:g,layoutsData:w,guardData:y,metadata:m,viewport:x,lang:R}=c,S=ve(Te(Z,{pathname:i,params:d,loaderData:g,layoutsData:w,guardData:y,Page:u.default,layouts:p.map(f=>f.default),metadata:m??null,viewport:x,clientEntry:o})),b=m?Ee(V(m,x)):"",E=`<script>window.__DEVIX__=${P({metadata:m,viewport:x,clientEntry:o})};window.__LOADER_DATA__=${P(g??null)};window.__LAYOUTS_DATA__=${P(w)};window.__GUARD_DATA__=${P(y??null)};</script>`,M=`<script type="module" src="${o}"></script>`,A=u.headers??{};return{html:`<html lang="${oe(R)}"><head><meta charset="utf-8">${b}${s}${E}</head><body><div id="devix-root">${S}</div>${M}</body></html>`,statusCode:200,headers:A}}async function ht(e){let{pages:t}=I(Object.keys(e.pages),Object.keys(e.layouts),e.pagesDir),r=[];for(let n of t)if(n.params.length===0)r.push(n.path);else{let o=await e.pages[n.key]();if(!o.generateStaticParams)continue;let a=await o.generateStaticParams();for(let s of a){let i=n.path;for(let[c,u]of Object.entries(s))i=i.replace(`:${c}`,encodeURIComponent(u));r.push(i)}}return r}export{ht as getStaticRoutes,yt as render,mt as runLoader};
1
+ import{createElement as Ee}from"react";import{renderToString as De,renderToStaticMarkup as ke}from"react-dom/server";import{Fragment as X,jsx as D}from"react/jsx-runtime";function pe(e,t){let r=[];e.title&&r.push({tag:"title",children:e.title}),e.description&&r.push({tag:"meta",name:"description",content:e.description}),e.keywords?.length&&r.push({tag:"meta",name:"keywords",content:e.keywords.join(", ")});let n=e.og?.title??e.title;n&&r.push({tag:"meta",property:"og:title",content:n});let o=e.og?.description??e.description;o&&r.push({tag:"meta",property:"og:description",content:o}),e.og?.image&&r.push({tag:"meta",property:"og:image",content:e.og.image}),e.og?.type&&r.push({tag:"meta",property:"og:type",content:e.og.type}),e.og?.url&&r.push({tag:"meta",property:"og:url",content:e.og.url});let a=e.twitter?.title??e.title;a&&r.push({tag:"meta",name:"twitter:title",content:a});let s=e.twitter?.description??e.description;if(s&&r.push({tag:"meta",name:"twitter:description",content:s}),e.twitter?.card&&r.push({tag:"meta",name:"twitter:card",content:e.twitter.card}),e.twitter?.image&&r.push({tag:"meta",name:"twitter:image",content:e.twitter.image}),e.twitter?.creator&&r.push({tag:"meta",name:"twitter:creator",content:e.twitter.creator}),e.canonical&&r.push({tag:"link",rel:"canonical",href:e.canonical}),e.robots&&r.push({tag:"meta",name:"robots",content:e.robots}),e.alternates)for(let[i,c]of Object.entries(e.alternates))r.push({tag:"link",rel:"alternate",href:c,hrefLang:i});if(e.icons){let i=Array.isArray(e.icons)?e.icons:[e.icons];for(let c of i){let u=typeof c=="string"?{href:c}:c;r.push({tag:"link",rel:u.rel??"icon",href:u.href,...u.type&&{type:u.type},...u.sizes&&{sizes:u.sizes}})}}if(t){let i=[];t.width!==void 0&&i.push(`width=${t.width}`),t.initialScale!==void 0&&i.push(`initial-scale=${t.initialScale}`),t.maximumScale!==void 0&&i.push(`maximum-scale=${t.maximumScale}`),t.userScalable!==void 0&&i.push(`user-scalable=${t.userScalable?"yes":"no"}`),i.length&&r.push({tag:"meta",name:"viewport",content:i.join(", ")}),t.themeColor&&r.push({tag:"meta",name:"theme-color",content:t.themeColor})}return r}function W({metadata:e,viewport:t}){return typeof window>"u"||!e?null:D(X,{children:j(e,t)})}function j(e,t){let r=pe(e,t);return D(X,{children:r.map((n,o)=>n.tag==="title"?D("title",{children:n.children},o):n.tag==="link"?D("link",{rel:n.rel,href:n.href,hrefLang:n.hrefLang,type:n.type,sizes:n.sizes},o):D("meta",{name:n.name,property:n.property,content:n.content},o))})}import{createContext as V}from"react";var v=globalThis;v.__devix_RouterContext__??=V(null);var Y=v.__devix_RouterContext__;v.__devix_PageMetaContext__??=V(null);v.__devix_RouteDataContext__??=V(null);var q=v.__devix_PageMetaContext__,N=v.__devix_RouteDataContext__;import{Component as ge}from"react";import{jsx as Z}from"react/jsx-runtime";var B=class extends ge{state={error:null};static getDerivedStateFromError(t){return t instanceof I?{error:{statusCode:t.statusCode,message:t.message}}:{error:{statusCode:500,message:t instanceof Error?t.message:"Unknown error"}}}render(){return this.state.error&&this.props.ErrorPage?Z(this.props.ErrorPage,{...this.state.error}):this.state.error?Z("h1",{children:this.state.error.statusCode}):this.props.children}},K=Symbol.for("@devlusoft/devix.DevixError"),I=class extends Error{static[Symbol.hasInstance](t){return t!==null&&typeof t=="object"&&t[K]===!0}statusCode;code;data;constructor(t,r,n){super(r),this.name="DevixError",this.statusCode=t,this.code=n?.code,this.data=n?.data,this[K]=!0}};import{jsx as C,jsxs as he}from"react/jsx-runtime";var fe=(e,t)=>Promise.resolve(),me=()=>Promise.resolve(),ye=e=>{};function Q({pathname:e,params:t,loaderData:r,layoutsData:n,guardData:o,Page:a,layouts:s,metadata:i,viewport:c,clientEntry:u}){let p=C(N,{value:{loaderData:r,params:t},children:C(a,{data:r,params:t,url:e})});for(let d=s.length-1;d>=0;d--){let g=s[d],w=n[d];p=C(N,{value:{loaderData:w,params:t},children:C(g,{data:w,params:t,children:p})})}return he(q,{value:{metadata:i,viewport:c,clientEntry:u},children:[C(W,{metadata:i,viewport:c}),C(Y,{value:{pathname:e,params:t,loaderData:r,layoutsData:n,guardData:o,Page:a,layouts:s,metadata:i,viewport:c,isNavigating:!1,navigate:fe,revalidate:me,prefetchRoute:ye},children:C(B,{children:p},e)})]})}function ee(e){return e.replace(/\.(tsx|ts|jsx|js)$/,"").replace(/\(.*?\)\//g,"").replace(/^index$|\/index$/,"").replace(/\[([^\]]+)]/g,":$1")||"/"}function we(e,t){let r=e.slice(t.length+1).replace(/\\/g,"/"),n=ee(r);return n==="/"?"/":`/${n}`}function te(e){return e.slice(0,e.lastIndexOf("/"))}function H(e,t,r){let n=[],o=[];for(let a of t)o.push({dir:te(a),key:a});for(let a of e){let s=we(a,r),i=[...s.matchAll(/:([^/]+)/g)].map(u=>u[1]),c=s.replace(/:[^/]+/g,"([^/]+)").replace(/\//g,"\\/");n.push({path:s,key:a,params:i,regex:new RegExp(`^${c}$`)})}return n.sort((a,s)=>{let i=a.path.split("/").filter(Boolean),c=s.path.split("/").filter(Boolean),u=Math.max(i.length,c.length);for(let p=0;p<u;p++){let d=p<i.length?i[p].startsWith(":")?1:2:0,g=p<c.length?c[p].startsWith(":")?1:2:0;if(d!==g)return g-d}return s.path.length-a.path.length}),{pages:n,layouts:o}}function re(e,t){let r=te(e);return t.filter(n=>r.startsWith(n.dir)).sort((n,o)=>n.dir.split("/").length-o.dir.split("/").length)}function ne(e,t){for(let r of t){let n=e.match(r.regex);if(n){let o={};return r.params.forEach((a,s)=>{o[a]=decodeURIComponent(n[s+1])}),{page:r,params:o}}}return null}async function U(e,t){let r=e.generateMetadata?await e.generateMetadata(t):e.metadata??{},n=e.generateViewport?await e.generateViewport(t):e.viewport;return{metadata:r,viewport:n}}function oe(...e){let t={};for(let r of e){if(!r)continue;let{og:n,twitter:o,...a}=r;Object.assign(t,a),n&&(t.og={...t.og,...n}),o&&(t.twitter={...t.twitter,...o})}return t}function P(e){return JSON.stringify(e).replace(/<\/script>/gi,"<\\/script>")}function ae(e){return e.replace(/"/g,"&quot;")}function G(e,t){let r;return Promise.race([e.finally(()=>clearTimeout(r)),new Promise((n,o)=>{r=setTimeout(()=>o(new Error(`timed out after ${t}ms`)),t)})])}var xe=Symbol.for("devix.redirect");function O(e){return typeof e=="object"&&e!==null&&xe in e}var Re=Symbol.for("devix.loaderError");function k(e){return typeof e=="object"&&e!==null&&Re in e}function se(e){let t={statusCode:e.statusCode,message:e.message};return e.code!==void 0&&(t.code=e.code),e.data!==void 0&&(t.data=e.data),t}function _e(e){if(e&&typeof e=="object"&&"message"in e){let t=e.message;if(typeof t=="string"&&t.length>0)return t}return null}var ie=Symbol.for("@devlusoft/devix.FetchError"),T=class extends Error{constructor(r,n,o,a){super(_e(a)??`HTTP ${r}: ${n}`);this.status=r;this.statusText=n;this.response=o;this.body=a;this.name="FetchError",this[ie]=!0}static[Symbol.hasInstance](r){return r!==null&&typeof r=="object"&&r[ie]===!0}get code(){if(this.body&&typeof this.body=="object"&&"code"in this.body){let r=this.body.code;return typeof r=="string"?r:void 0}}};function Pe(e,t){return Ce(t).test(e)}function J(e,t){if(!t||t.length===0)return!1;for(let r of t)if(Pe(e,r))return!0;return!1}function Ce(e){let t="",r=0;for(;r<e.length;){let n=e[r];if(n==="*"&&e[r+1]==="*")t+=".*",r+=2;else if(n==="*")t+="[^/]*",r+=1;else if(n===":"){for(r+=1;r<e.length&&/[a-zA-Z0-9_]/.test(e[r]);)r+=1;t+="[^/]+"}else".+?^$()|[]{}\\".includes(n)?(t+="\\"+n,r+=1):(t+=n,r+=1)}return new RegExp(`^${t}$`)}function ce(e,t){if(!t)return new Proxy({},{get(n,o){throw new Error(`[devix] ctx.$server.${String(o)} called but no 'server' config is defined in devix.config.ts`)}});let r=new Map;return new Proxy({},{get(n,o){if(typeof o!="string")return;let a=t[o];if(!a)throw new Error(`[devix] ctx.$server.${o} \u2014 namespace "${o}" not configured in devix.config.ts`);let s=r.get(o);return s||(s=Te(o,a,e),r.set(o,s)),s}})}function Te(e,t,r){async function n(o,a,s,i){if(!J(a,t.allowedPaths))throw new T(403,"Path not allowed",new Response(null,{status:403}),{statusCode:403,message:"Path not allowed",code:"PATH_NOT_ALLOWED"});if(J(a,t.deniedPaths))throw new T(403,"Path denied",new Response(null,{status:403}),{statusCode:403,message:"Path denied",code:"PATH_DENIED"});let c=new URL(a,t.url),u=new Headers(i?.headers);if(t.prepare){let y={request:r,headers:u,url:c},m=await t.prepare(y);if(m instanceof Response)throw new T(m.status,m.statusText,m,await ve(m))}let p;s!=null&&o!=="GET"&&o!=="HEAD"&&(s instanceof FormData||s instanceof Blob||s instanceof ArrayBuffer?p=s:(p=JSON.stringify(s),u.has("Content-Type")||u.set("Content-Type","application/json")));let d=await fetch(c,{method:o,headers:u,body:p,signal:i?.signal}),g=d.status===204||d.headers.get("Content-Length")==="0";if(!d.ok){let y=d.headers.get("Content-Type")??"",m;if(!g&&y.includes("application/json"))try{m=await d.json()}catch{}throw new T(d.status,d.statusText,d,m)}return g?null:(d.headers.get("Content-Type")??"").includes("application/json")?await d.json():await d.text()}return{get:((o,a)=>n("GET",o,void 0,a)),post:((o,a,s)=>n("POST",o,a,s)),put:((o,a,s)=>n("PUT",o,a,s)),patch:((o,a,s)=>n("PATCH",o,a,s)),delete:((o,a)=>n("DELETE",o,void 0,a))}}async function ve(e){if((e.headers.get("Content-Type")??"").includes("application/json"))try{return await e.json()}catch{return}}var be={width:"device-width",initialScale:1},F=null,le=null,Se="/@id/virtual:devix/entry-client";function ue(e){return typeof e=="string"?{url:e,status:302,replace:!1}:O(e)?{url:e.url,status:e.status,replace:e.replace}:null}async function de(e,t,r,n,o){let a=Object.keys(r.pages).sort().join("\0")+"|"+Object.keys(r.layouts).sort().join("\0");(!F||le!==a)&&(F=H(Object.keys(r.pages),Object.keys(r.layouts),r.pagesDir),le=a);let{pages:s,layouts:i}=F,c=ne(e,s);if(!c)return null;let{page:u,params:p}=c,d=re(u.key,i),[g,...w]=await Promise.all([r.pages[u.key](),...d.map(l=>r.layouts[l.key]())]),y,m=ce(t,o);for(let l of w)if(l.guard){let h=await l.guard({params:p,request:t,guardData:y,$server:m}),$=ue(h);if($!==null)return{redirect:$.url,redirectStatus:$.status,redirectReplace:$.replace};if(k(h))return{loaderError:h};h!=null&&(y=h)}if(g.guard){let l=await g.guard({params:p,request:t,guardData:y,$server:m}),h=ue(l);if(h!==null)return{redirect:h.url,redirectStatus:h.status,redirectReplace:h.replace};if(k(l))return{loaderError:l};l!=null&&(y=l)}let x={params:p,request:t,guardData:y,$server:m},R=g.loader?await G(Promise.resolve(g.loader(x)),n):null;if(O(R))return{redirect:R.url,redirectStatus:R.status,redirectReplace:R.replace};if(k(R))return{loaderError:R};let b=R,S=await G(Promise.all(w.map(l=>l.loader?l.loader(x):null)),n);for(let l of S){if(O(l))return{redirect:l.url,redirectStatus:l.status,redirectReplace:l.replace};if(k(l))return{loaderError:l}}let E=S,M=await U(g,{...x,loaderData:b}),A=await Promise.all(w.map((l,h)=>U(l,{...x,loaderData:E[h]}))),z=oe(...A.map(l=>l.metadata),M.metadata),f=M.viewport??A.findLast(l=>l.viewport)?.viewport??be,_=w[0],L=_?.generateLang?await _.generateLang({...x,loaderData:E[0]}):_?.lang??"en";return{pageMod:g,layoutMods:w,params:p,loaderData:b,layoutsData:E,guardData:y,metadata:z,viewport:f,lang:L}}async function ht(e,t,r,n){let{pathname:o}=new URL(e,"http://localhost"),a;try{let g=n?.loaderTimeout??1e4;a=await de(o,t,r,g,n?.server)}catch(g){return console.error("[devix] render error:",g),{error:!0,loaderData:null,params:{},layouts:[],metadata:null,viewport:void 0}}if(!a)return{loaderData:null,params:{},layouts:[],metadata:null,viewport:void 0};if("redirect"in a)return{redirect:a.redirect,redirectStatus:a.redirectStatus,redirectReplace:a.redirectReplace};if("loaderError"in a)return{loaderError:a.loaderError};let{loaderData:s,params:i,layoutsData:c,guardData:u,metadata:p,viewport:d}=a;return{loaderData:s,params:i,layouts:c.map(g=>({loaderData:g})),guardData:u,metadata:p,viewport:d}}async function wt(e,t,r,n){let o=n?.manifest?`/${Object.values(n.manifest).find(f=>f.isEntry)?.file}`:Se,s=(n?.manifest?Object.values(n.manifest).find(f=>f.isEntry)?.css??[]:[]).map(f=>`<link rel="stylesheet" href="/${f}">`).join(""),{pathname:i}=new URL(e,"http://localhost"),c;try{let f=n?.loaderTimeout??1e4;c=await de(i,t,r,f,n?.server)}catch(f){return console.error("[devix] render error:",f),{html:`<html lang="en"><head><meta charset="utf-8">${s}</head><body><script>window.__DEVIX__=null;window.__LOADER_DATA__=null;window.__LAYOUTS_DATA__=[];</script><script type="module" src="${o}"></script><div id="devix-root"></div></body></html>`,statusCode:500,headers:{}}}if(!c){let f=`<script>window.__DEVIX__=${P({metadata:null,viewport:void 0,clientEntry:o})};window.__LOADER_DATA__=null;window.__LAYOUTS_DATA__=[];</script>`,_=`<script type="module" src="${o}"></script>`;return{html:`<html lang="en"><head><meta charset="utf-8">${s}${f}</head><body><div id="devix-root"></div>${_}</body></html>`,statusCode:404,headers:{}}}if("redirect"in c)return{html:"",statusCode:c.redirectStatus,headers:{Location:c.redirect}};if("loaderError"in c){let f=se(c.loaderError),_=`<script>window.__DEVIX__=${P({metadata:null,viewport:void 0,clientEntry:o})};window.__LOADER_DATA__=null;window.__LAYOUTS_DATA__=[];window.__LOADER_ERROR__=${P(f)};</script>`,L=`<script type="module" src="${o}"></script>`;return{html:`<html lang="en"><head><meta charset="utf-8">${s}${_}</head><body><div id="devix-root"></div>${L}</body></html>`,statusCode:f.statusCode,headers:{}}}let{pageMod:u,layoutMods:p,params:d,loaderData:g,layoutsData:w,guardData:y,metadata:m,viewport:x,lang:R}=c,b=De(Ee(Q,{pathname:i,params:d,loaderData:g,layoutsData:w,guardData:y,Page:u.default,layouts:p.map(f=>f.default),metadata:m??null,viewport:x,clientEntry:o})),S=m?ke(j(m,x)):"",E=`<script>window.__DEVIX__=${P({metadata:m,viewport:x,clientEntry:o})};window.__LOADER_DATA__=${P(g??null)};window.__LAYOUTS_DATA__=${P(w)};window.__GUARD_DATA__=${P(y??null)};</script>`,M=`<script type="module" src="${o}"></script>`,A=u.headers??{};return{html:`<html lang="${ae(R)}"><head><meta charset="utf-8">${S}${s}${E}</head><body><div id="devix-root">${b}</div>${M}</body></html>`,statusCode:200,headers:A}}async function xt(e){let{pages:t}=H(Object.keys(e.pages),Object.keys(e.layouts),e.pagesDir),r=[];for(let n of t)if(n.params.length===0)r.push(n.path);else{let o=await e.pages[n.key]();if(!o.generateStaticParams)continue;let a=await o.generateStaticParams();for(let s of a){let i=n.path;for(let[c,u]of Object.entries(s))i=i.replace(`:${c}`,encodeURIComponent(u));r.push(i)}}return r}export{xt as getStaticRoutes,wt as render,ht as runLoader};
2
2
  //# sourceMappingURL=render.js.map