what-server 0.13.2 → 0.13.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.min.js +2 -2
- package/dist/node.min.js +4 -4
- package/package.json +3 -3
- package/src/adapter/core.js +10 -1
- package/src/index.js +14 -0
package/dist/index.min.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{h as tt,_isAriaAttr as ue,_beginComponentSSR as et,_endComponentSSR as nt,_mapArrayToArray as rt,getServerContext as Tt,runWithServerContext as S,beginHeadCollection as de,endHeadCollection as ot}from"what-core";var $t=new RegExp("[<>&\\u2028\\u2029]","g"),Pt={60:"\\u003c",62:"\\u003e",38:"\\u0026",8232:"\\u2028",8233:"\\u2029"};function J(t){return JSON.stringify(t).replace($t,e=>Pt[e.charCodeAt(0)])}import{mount as ke,hydrate as Ce,signal as Oe,batch as $e,getServerContext as xt}from"what-core";var vt=new Map;function It(t){let e=t||xt();return e&&e.islandStores instanceof Map?e.islandStores:null}function ht(t){let e=typeof document<"u"?vt:It(t),n={};for(let[r,s]of e||[])n[r]=s._getSnapshot();return n}import{signal as _,batch as Y}from"what-core";var D=Symbol.for("what.revalidationHandler"),yt=!(typeof process<"u");function V(t){globalThis[D]=t}function Nt(){return globalThis[D]??null}async function W(t,e){let n=globalThis[D];if(n&&n.revalidatePath)return n.revalidatePath(t,e);yt&&console.warn(`[what] revalidatePath('${t}') had no effect: no cache engine is bound. Create a what-isr engine and bind it in your adapter (setRevalidationHandler).`)}async function z(t,e){let n=globalThis[D];if(n&&n.revalidateTag)return n.revalidateTag(t,e);yt&&console.warn(`[what] revalidateTag('${t}') had no effect: no cache engine is bound.`)}var G=new Map;function Dt(){if(typeof document<"u"){let t=document.querySelector('meta[name="what-csrf-token"]');if(t)return t.getAttribute("content");let e=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);if(e)return decodeURIComponent(e[1])}return null}function X(){if(typeof crypto<"u"&&crypto.randomUUID)return crypto.randomUUID();if(typeof crypto<"u"&&crypto.getRandomValues){let t=new Uint8Array(16);return crypto.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}throw Object.assign(new Error("[what] No secure random source available for CSRF token generation"),{code:"ERR_NO_SECURE_RANDOM"})}function mt(t,e){if(!t||!e||t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r++)n|=t.charCodeAt(r)^e.charCodeAt(r);return n===0}function K(t){return`<meta name="what-csrf-token" content="${String(t).replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}">`}var Ht=0,Lt=!1;function jt(){return!Lt&&typeof process<"u",`a_${typeof crypto<"u"&&crypto.getRandomValues?Array.from(crypto.getRandomValues(new Uint8Array(6)),e=>e.toString(16).padStart(2,"0")).join(""):`c${(++Ht).toString(36)}_${Date.now().toString(36)}`}`}function Mt(t,e={}){let n=e.id||jt(),{onError:r,onSuccess:s,revalidate:a}=e;typeof window>"u"&&G.set(n,{fn:t,options:e});async function o(...i){if(typeof window>"u")return t(...i);let c=e.timeout||3e4,u=new AbortController,d=setTimeout(()=>u.abort(),c);try{let f=Dt(),l={"Content-Type":"application/json","X-What-Action":n};f&&(l["X-CSRF-Token"]=f);let p=await fetch("/__what_action",{method:"POST",headers:l,credentials:"same-origin",signal:u.signal,body:JSON.stringify({args:i})});if(!p.ok){let w=await p.json().catch(()=>({message:"Action failed"}));throw Object.assign(new Error(w.message||"Action failed"),{code:"ERR_ACTION_FAILED"})}let h=await p.json();if(s&&s(h),a)for(let w of a)St(w);return h}catch(f){if(f.name==="AbortError"){let l=new Error(`Action "${n}" timed out after ${c}ms`);throw l.code="TIMEOUT",r&&r(l),l}throw r&&r(f),f}finally{clearTimeout(d)}}return o._actionId=n,o._isAction=!0,o}function gt(t,e={}){let{onSuccess:n,onError:r,resetOnSuccess:s=!0}=e;return async a=>{let o,i;a instanceof Event?(a.preventDefault(),i=a.target,o=new FormData(i)):o=a;let c={},u=!1;for(let[d,f]of o.entries())typeof File<"u"&&f instanceof File&&(u=!0),c[d]?Array.isArray(c[d])?c[d].push(f):c[d]=[c[d],f]:c[d]=f;try{let d=u?await t(c,o):await t(c);return n&&n(d,i),s&&i&&i.reset(),d}catch(d){throw r&&r(d,i),d}}}function wt(t){let e=_(!1),n=_(null),r=_(null);async function s(...a){e.set(!0),n.set(null);try{let o=await t(...a);return r.set(o),o}catch(o){throw n.set(o),o}finally{e.set(!1)}}return{trigger:s,isPending:()=>e(),error:()=>n(),data:()=>r(),reset:()=>{n.set(null),r.set(null)}}}function Ft(t,e={}){let{resetOnSuccess:n=!0}=e,r={current:null},s=wt(gt(t,{resetOnSuccess:n}));function a(o){o.preventDefault();let i=new FormData(o.target);return r.current=o.target,s.trigger(i)}return{...s,handleSubmit:a,formRef:r}}function Ut(t,e){let n=_(t),r=_([]),s=_(t);function a(u){let d=e(n.peek(),u);Y(()=>{r.set([...r.peek(),u]),n.set(d)})}function o(u,d){Y(()=>{if(r.set(r.peek().filter(f=>f!==u)),d!==void 0){s.set(d);let f=d;for(let l of r.peek())f=e(f,l);n.set(f)}})}function i(u,d){Y(()=>{let f=r.peek().filter(h=>h!==u);r.set(f);let l=d!==void 0?d:s.peek();s.set(l);let p=l;for(let h of f)p=e(p,h);n.set(p)})}async function c(u,d){a(u);try{let f=await d();return o(u,f),f}catch(f){throw i(u),f}}return{value:()=>n(),isPending:()=>r().length>0,addOptimistic:a,resolve:o,rollback:i,withOptimistic:c,set:u=>{n.set(u),s.set(u)}}}var v=new Map;function Bt(t,e){return v.has(t)||v.set(t,new Set),v.get(t).add(e),()=>{v.get(t)?.delete(e)}}function St(t){let e=v.get(t);if(e)for(let n of e)try{n()}catch(r){console.error("[what] Revalidation error:",r)}}function H(t,e,n,r={}){let{csrfToken:s,skipCsrf:a=!1}=r;if(!a){if(!s)return Promise.resolve({status:500,body:{message:"[what] CSRF token not configured. Pass { csrfToken: sessionToken } to handleActionRequest, or { skipCsrf: true } to explicitly opt out."}});let i=t?.headers?.["x-csrf-token"]||t?.headers?.["X-CSRF-Token"];if(!mt(i,s))return Promise.resolve({status:403,body:{message:"Invalid CSRF token"}})}let o=G.get(e);return o?Array.isArray(n)?o.fn(...n).then(async i=>{let c=o.options||{};if(Array.isArray(c.revalidate))for(let u of c.revalidate)await W(u);if(Array.isArray(c.revalidateTags))for(let u of c.revalidateTags)await z(u);return{status:200,body:i}}).catch(i=>(console.error(`[what] Action "${e}" error:`,i),{status:500,body:{message:"Action failed"}})):Promise.resolve({status:400,body:{message:"Invalid action arguments"}}):Promise.resolve({status:404,body:{message:"Action not found"}})}function Jt(){return[...G.keys()]}function Vt(t,e={}){let{onSuccess:n,onError:r,onSettled:s}=e,a={isPending:_(!1),error:_(null),data:_(null)};async function o(...i){a.isPending.set(!0),a.error.set(null);try{let c=await t(...i);return a.data.set(c),n&&n(c,...i),c}catch(c){throw a.error.set(c),r&&r(c,...i),c}finally{a.isPending.set(!1),s&&s(a.data.peek(),a.error.peek(),...i)}}return{mutate:o,isPending:()=>a.isPending(),error:()=>a.error(),data:()=>a.data(),reset:()=>{a.error.set(null),a.data.set(null)}}}import{h as L}from"what-core";var bt="/__what_action";function Wt(t){if(typeof t=="string")return t;if(typeof t=="function"){let e=t._actionId;if(e)return e;throw Object.assign(new Error("[what] <Form action={fn}>: that function is not a server action. Wrap it with action() from what-server, or pass the action id as a string."),{code:"ERR_FORM_ACTION_NOT_REGISTERED"})}throw Object.assign(new Error("[what] <Form> requires an `action` prop: a server action or its id."),{code:"ERR_FORM_ACTION_MISSING"})}function zt(){if(typeof document>"u")return null;let t=document.querySelector('meta[name="what-csrf-token"]');if(t)return t.getAttribute("content");let e=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);return e?decodeURIComponent(e[1]):null}function Yt({action:t,csrfToken:e,redirect:n,method:r="post",enhance:s=!0,children:a,...o}){let i=Wt(t),c=e!==void 0?e:zt();c==null&&typeof process<"u";let u=[L("input",{type:"hidden",name:"_action",value:i}),L("input",{type:"hidden",name:"what-csrf-token",value:c||""})];n&&u.push(L("input",{type:"hidden",name:"_redirect",value:n}));let d={...o,method:r,action:o.action||bt,"data-action":i};s&&(d["data-enhance"]="");let f=a==null?[]:Array.isArray(a)?a:[a];return L("form",d,...u,...f)}var Gt="/__what_action",Rt=1024*1024;function Xt(t){if(!t)return{};if(typeof t.forEach=="function"&&typeof t.get=="function"){let n={};return t.forEach((r,s)=>{n[s.toLowerCase()]=r}),n}let e={};for(let n in t)e[n.toLowerCase()]=t[n];return e}function j(t,e){return{status:t,headers:{"content-type":"application/json"},body:JSON.stringify(e)}}function Z(t,e){return{status:t,headers:{"content-type":"text/html; charset=utf-8"},body:`<!DOCTYPE html><html><body><h1>${t}</h1><p>${String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}</p></body></html>`}}function _t(t){if(typeof t!="string"||!t.startsWith("/")||/^[/\\]{2}/.test(t)||t.includes("\\"))return null;try{let e=new URL(t,"http://localhost");return e.origin!=="http://localhost"?null:e.pathname+e.search}catch{return null}}function Kt(t,e){let n=_t(t&&t._redirect);if(n)return n;let r=e.referer||e.referrer;if(r)try{let s=new URL(r,"http://localhost"),a=_t(s.pathname+s.search);if(a)return a}catch{}return"/"}var Zt=new Set(["_action","data-action","_csrf","what-csrf-token","_redirect"]);function I(t={}){let{getCsrfToken:e,skipCsrf:n=!1}=t;return async function(s){if((s.method||"POST").toUpperCase()!=="POST")return j(405,{message:"Method Not Allowed"});let o=Xt(s.headers),i=o["x-what-action"],c=o["content-type"]||"",u=!i&&c.includes("application/x-www-form-urlencoded"),d=n?void 0:e?await e(s):void 0;if(u){let h=s.body||{},w=h._action||h["data-action"]||s.query&&s.query.action;if(!w)return Z(400,'Missing action name (add a hidden "_action" field or ?action= query param)');let b={...o},k=h._csrf??h["what-csrf-token"];if(k&&!b["x-csrf-token"]&&(b["x-csrf-token"]=String(k)),!n&&e&&!d)return Z(403,"Missing CSRF token");let C={};for(let[O,U]of Object.entries(h))Zt.has(O)||(C[O]=U);let T=await H({headers:b},w,[C],{csrfToken:d,skipCsrf:n});return T.status===200?{status:303,headers:{location:Kt(h,o)},body:""}:Z(T.status,T.body&&T.body.message||"Action failed")}if(!i)return j(400,{message:"Missing X-What-Action header"});if(!n&&e&&!d)return j(403,{message:"Missing CSRF token"});let l=(s.body||{}).args,p=await H({headers:o},i,l,{csrfToken:d,skipCsrf:n});return j(p.status,p.body)}}function Qt(t={}){let e=t.basePath||Gt,n=I(t);return async function(s,a,o){let[i,c]=(s.url||"").split("?");if(i!==e||(s.method||"").toUpperCase()!=="POST")return o?o():void 0;let u;try{let l=await qt(s);u=M(l,s.headers["content-type"]||"")}catch(l){a.writeHead(l.code==="BODY_TOO_LARGE"?413:400,{"content-type":"application/json"}),a.end(JSON.stringify({message:l.code==="BODY_TOO_LARGE"?"Payload too large":"Invalid request body"}));return}let d=Object.fromEntries(new URLSearchParams(c||"")),f=await n({method:s.method,headers:s.headers,body:u,query:d});a.writeHead(f.status,f.headers),a.end(f.body)}}function M(t,e){if((e||"").includes("application/x-www-form-urlencoded")){let n={};for(let[r,s]of new URLSearchParams(String(t)))n[r]===void 0?n[r]=s:Array.isArray(n[r])?n[r].push(s):n[r]=[n[r],s];return n}return t==null||t===""?{}:JSON.parse(String(t))}async function F(t,e=Rt){let n=Number(t.headers.get("content-length"));if(Number.isFinite(n)&&n>e)return{tooLarge:!0};let r=t.body;if(!r||typeof r.getReader!="function"){let i=await t.text();return Buffer.byteLength(i,"utf8")>e?{tooLarge:!0}:{raw:i}}let s=r.getReader(),a=[],o=0;for(;;){let{done:i,value:c}=await s.read();if(i)break;if(c){if(o+=c.byteLength,o>e){try{await s.cancel()}catch{}return{tooLarge:!0}}a.push(c)}}return{raw:Buffer.concat(a.map(i=>Buffer.from(i))).toString("utf8")}}function qt(t){return new Promise((e,n)=>{let r=0,s=[];t.on("data",a=>{if(r+=a.length,r>Rt){let o=new Error("Body too large");o.code="BODY_TOO_LARGE",n(o),t.destroy?.();return}s.push(a)}),t.on("end",()=>{if(s.length===0)return e("");e(Buffer.concat(s).toString("utf8"))}),t.on("error",n)})}function te(t={}){let e=I(t);return async function(n){let r={};try{let o=await F(n);if(o.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});r=M(o.raw,n.headers.get("content-type")||"")}catch{r={}}let s={};try{s=Object.fromEntries(new URL(n.url,"http://localhost").searchParams)}catch{}let a=await e({method:n.method,headers:n.headers,body:r,query:s});return new Response(a.body,{status:a.status,headers:a.headers})}}import{matchRoute as ee,parseQuery as ne}from"what-router/match";var re="/__what_action",oe="/__what_revalidate",Q="what-csrf";function N(t){let e={};return t&&typeof t.forEach=="function"&&t.forEach((n,r)=>{e[r.toLowerCase()]=n}),e}function At(t,e){if(!t)return null;let n=String(t).match(new RegExp(`(?:^|;\\s*)${e}=([^;]+)`));return n?decodeURIComponent(n[1]):null}async function ae(t){try{let e=await F(t);return e.tooLarge?{tooLarge:!0}:M(e.raw,t.headers.get("content-type")||"")}catch{return{}}}async function se(t){let e;try{e=await F(t)}catch{return{json:{}}}if(e.tooLarge)return{tooLarge:!0};try{return{json:JSON.parse(e.raw??"")}}catch{return{json:{}}}}function ie(t){return async function(n){let{route:r,params:s,query:a,request:o,csrfToken:i}=n,c={default:r.component,loader:r.loader},u=i?{params:s,query:a,request:o,csrfToken:i}:{params:s,query:a,request:o},d=i?{...t,csrfToken:i}:t;return{html:await Et(c,u,d),status:200,tags:n.config&&n.config.tags||[],path:n.path}}}function q(t={}){let{routes:e=[],cache:n,render:r,revalidateWebhook:s,document:a={},notFound:o,basePath:i="",csrf:c=!0}=t,u=c!==!1&&!t.actionHandler,d=t.actionHandler||I(u?{getCsrfToken:l=>At(l.headers&&l.headers.cookie,Q)}:{skipCsrf:!0}),f=r||ie(a);return n&&(n.revalidatePath||n.revalidateTag)&&V({revalidatePath:n.revalidatePath,revalidateTag:n.revalidateTag}),async function(p){let h=new URL(p.url,"http://localhost"),w=h.pathname;if(i&&w.startsWith(i)&&(w=w.slice(i.length)||"/"),p.method==="POST"&&w===re){let m=await ae(p);if(m&&m.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let A=await d({method:"POST",headers:N(p.headers),body:m,query:Object.fromEntries(h.searchParams)});return new Response(A.body,{status:A.status,headers:A.headers})}let b=null,k=null;if(u&&(b=At(N(p.headers).cookie,Q),!b)){b=X();let A=N(p.headers)["x-forwarded-proto"]==="https"||h.protocol==="https:"||!0;k=`${Q}=${encodeURIComponent(b)}; Path=/; SameSite=Lax`+(A?"; Secure":"")}let C=m=>(k&&(m["set-cookie"]=k),m);if(p.method==="POST"&&w===oe&&s){let m=await se(p);if(m.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let A=await s({headers:N(p.headers),body:m.json});return new Response(JSON.stringify(A.body),{status:A.status,headers:{"content-type":"application/json"}})}let T=ee(w,e);if(!T){let m=o?o():"<!DOCTYPE html><html><body><h1>404 \u2014 Not Found</h1></body></html>";return new Response(m,{status:404,headers:C({"content-type":"text/html; charset=utf-8"})})}let{route:O,params:U}=T,B=O.page||{mode:O.mode||"client"},x={path:w,query:ne(h.search),config:B,route:O,params:U,request:p};if(n&&B.mode!=="server"){x.varyHeaders=N(p.headers);let m=await n.handle(x,()=>f(x));return new Response(m.html,{status:m.status||200,headers:C({"content-type":"text/html; charset=utf-8",...m.headers||{}})})}b&&(x.csrfToken=b);let lt=await f(x),pt=C({"content-type":"text/html; charset=utf-8"});return B.mode==="server"&&(pt["Cache-Control"]="private, no-store"),new Response(lt.html,{status:lt.status||200,headers:pt})}}function ce(t={}){let e=q(t);return{async fetch(n,r,s){return r&&(n.__env=r),s&&(n.__ctx=s),e(n)}}}function E(t){return{head:de(),loaderData:t,resources:new Map,islandStores:new Map,resourceCounter:0,boundaryCounter:0,suspended:[]}}var kt=0;function fe(){kt=0}function le(){return"h"+kt++}function pe(t){if(!Tt()){let e=E(void 0);return S(e,()=>pe(t))}return fe(),R(t)}var Ct=new Set(["__errorBoundary","__suspense"]),at=new Set(["__portal"]);function st(t){let e=t.children;return!e||e.length===0?{...t.props}:{...t.props,children:e}}function it(t,e){let n=t.props&&t.props.fallback;if(typeof n!="function")return n;let r=t.props&&t.props.reset||(()=>{});try{return n({error:e,reset:r})}catch(s){return P&&console.warn(`[what-server] <ErrorBoundary> fallback threw during SSR: ${s.message}`),null}}function R(t){if(t==null||t===!1||t===!0)return"";if(typeof t=="string"||typeof t=="number")return g(String(t));if(typeof t=="function"&&t._signal)return`<!--$-->${R(t())}<!--/$-->`;if(typeof t=="function"&&t._mapArray)try{return`<!--$-->${R(rt(t))}<!--/$-->`}catch{return typeof process<"u","<!--$--><!--/$-->"}if(typeof t=="function")try{return`<!--$-->${R(t())}<!--/$-->`}catch{return typeof process<"u","<!--$--><!--/$-->"}if(Array.isArray(t))return`<!--[]-->${t.map(R).join("")}<!--/[]-->`;if(at.has(t.tag))return"";if(Ct.has(t.tag))try{return(t.children||[]).map(R).join("")}catch(c){let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return R(it(t,u?null:c))}if(typeof t.tag=="function"){let c=le(),u=et(t.tag),d;try{d=R(t.tag(st(t)))}finally{nt(u)}return he(d,c)}let{tag:e,props:n,children:r}=t;ut(e);let s=dt(n||{}),a=`<${e}${s}>`;if(ft.has(e))return a;let o=ct(n),i=o!=null?String(o):r.map(R).join("");return`${a}${i}</${e}>`}function he(t,e){let n=t.match(/^((?:<!--.*?-->)*)<([a-zA-Z][a-zA-Z0-9-]*)/);if(n){let r=n[1],s=n[2],a=r.length+1+s.length,o=t.indexOf(">",a),i=t.slice(a,o===-1?void 0:o);return/[\s"']data-hk\s*=/.test(i)||/^\s*data-hk\s*=/.test(i)?t:t.slice(0,a)+` data-hk="${e}"`+t.slice(a)}return t}function y(t){if(!Tt()){let c=E(void 0);return S(c,()=>y(t))}if(t==null||t===!1||t===!0)return"";if(typeof t=="string"||typeof t=="number")return g(String(t));if(typeof t=="function"&&t._signal)return y(t());if(typeof t=="function"&&t._mapArray)try{return y(rt(t))}catch{return typeof process<"u",""}if(typeof t=="function")try{return y(t())}catch{return typeof process<"u",""}if(Array.isArray(t))return t.map(y).join("");if(at.has(t.tag))return"";if(Ct.has(t.tag))try{return(t.children||[]).map(y).join("")}catch(c){let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return y(it(t,u?null:c))}if(typeof t.tag=="function"){let c=et(t.tag);try{return y(t.tag(st(t)))}finally{nt(c)}}let{tag:e,props:n,children:r}=t;ut(e);let s=dt(n||{}),a=`<${e}${s}>`;if(ft.has(e))return a;let o=ct(n),i=o!=null?String(o):r.map(y).join("");return`${a}${i}</${e}>`}function Ze(t){let e=E(void 0);return{body:S(e,()=>y(t)),head:ot(e.head)}}async function Qe(t,e={}){let n=t.default||t,r=typeof t.loader=="function"?await t.loader(e):void 0,s=E(r),a=e.params||{};return{body:S(s,()=>y(tt(n,{...a,loaderData:r}))),head:ot(s.head),loaderData:r}}var Ot=12;async function ye(t,e){e||(e=E(void 0));let n="";for(let s=0;s<Ot;s++){n=S(e,()=>y(t));let a=[...e.resources.values()].filter(o=>o.status==="pending").map(o=>o.promise);if(a.length===0)break;await Promise.all(a)}let r={};for(let[s,a]of e.resources)a.status==="ready"&&(r[s]=a.value);return{body:n,head:ot(e.head),loaderData:e.loaderData,resources:r,ctx:e}}async function Et(t,e={},n={}){let r=t.default||t,s=typeof t.loader=="function"?await t.loader(e):void 0,a=E(s),o=e.params||{},{body:i,head:c,resources:u}=await ye(tt(r,{...o,loaderData:s}),a),d={loaderData:s??null,resources:u,islandStores:ht(a)};return me({body:i,head:c,payload:d,options:n})}function me({body:t,head:e,payload:n,options:r={}}){let s=r.lang||"en",a=`<script id="__what_data" type="application/json">${J(n)}<\/script>`,o=r.clientEntry?`<script type="module" src="${g(r.clientEntry)}"><\/script>`:"",c=(r.csrfToken?K(r.csrfToken):"")+(r.head||""),u=r.bodyClass?` class="${g(r.bodyClass)}"`:"";return`<!DOCTYPE html><html lang="${g(s)}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">${e||""}${c}</head><body${u}>${t}${a}${o}</body></html>`}async function*$(t,e){if(e===void 0&&(e=E(void 0)),t==null||t===!1||t===!0)return;if(typeof t=="string"||typeof t=="number"){yield g(String(t));return}if(typeof t=="function"&&t._signal){let o=S(e,()=>t());yield*$(o,e);return}if(typeof t=="function"&&t._mapArray){let o=null;try{o=S(e,()=>rt(t))}catch{typeof process<"u"}o&&(yield*$(o,e));return}if(typeof t=="function"){try{let o=S(e,()=>t());yield*$(o,e)}catch{typeof process<"u"}return}if(Array.isArray(t)){for(let o of t)yield*$(o,e);return}if(at.has(t.tag))return;if(t.tag==="__errorBoundary"){let o;try{o=S(e,()=>(t.children||[]).map(y).join(""))}catch(i){if(i&&typeof i.then=="function")throw i;o=S(e,()=>y(it(t,i)))}yield o;return}if(t.tag==="__suspense"){let o=null;for(let i=0;i<Ot&&o===null;i++){let c=null;try{o=S(e,()=>(t.children||[]).map(y).join(""))}catch(u){if(u&&typeof u.then=="function")c=u;else throw u}if(o===null){let u=[...e.resources.values()].filter(d=>d.status==="pending").map(d=>d.promise);await Promise.all([c,...u].filter(Boolean))}}o===null&&(o=S(e,()=>y(t.props&&t.props.fallback))),yield o;return}if(typeof t.tag=="function"){let o=et(t.tag);try{let i=S(e,()=>t.tag(st(t))),c=i instanceof Promise?await i:i;yield*$(c,e)}catch(i){typeof process<"u",yield P?`<!-- SSR Error: ${g(i.message||"Component error")} -->`:"<!-- SSR Error -->"}finally{nt(o)}return}let{tag:n,props:r,children:s}=t;ut(n);let a=dt(r||{});if(yield`<${n}${a}>`,!ft.has(n)){let o=ct(r);if(o!=null)yield String(o);else for(let i of s)yield*$(i,e);yield`</${n}>`}}function qe(t){return{mode:"static",...t}}function tn(t,e={}){let n=E(e),r=S(n,()=>y(tt(t.component,e))),s=t.islands||[];return ge({title:t.title||"",meta:t.meta||{},body:r,islands:s,scripts:t.mode==="static"?[]:t.scripts||[],styles:t.styles||[],mode:t.mode})}function ge({title:t,meta:e,body:n,islands:r,scripts:s,styles:a,mode:o}){let i=Object.entries(e).map(([l,p])=>`<meta name="${g(l)}" content="${g(p)}">`).join(`
|
|
1
|
+
import{h as et,_isAriaAttr as ue,_beginComponentSSR as nt,_endComponentSSR as rt,_mapArrayToArray as ot,getServerContext as Tt,runWithServerContext as S,beginHeadCollection as de,endHeadCollection as at}from"what-core";var $t=new RegExp("[<>&\\u2028\\u2029]","g"),Pt={60:"\\u003c",62:"\\u003e",38:"\\u0026",8232:"\\u2028",8233:"\\u2029"};function V(t){return JSON.stringify(t).replace($t,e=>Pt[e.charCodeAt(0)])}import{mount as ke,hydrate as Ce,signal as Oe,batch as $e,getServerContext as vt}from"what-core";var xt=new Map;function It(t){let e=t||vt();return e&&e.islandStores instanceof Map?e.islandStores:null}function ht(t){let e=typeof document<"u"?xt:It(t),n={};for(let[r,s]of e||[])n[r]=s._getSnapshot();return n}import{signal as _,batch as G}from"what-core";var D=Symbol.for("what.revalidationHandler"),yt=!(typeof process<"u");function W(t){globalThis[D]=t}function Nt(){return globalThis[D]??null}async function z(t,e){let n=globalThis[D];if(n&&n.revalidatePath)return n.revalidatePath(t,e);yt&&console.warn(`[what] revalidatePath('${t}') had no effect: no cache engine is bound. Create a what-isr engine and bind it in your adapter (setRevalidationHandler).`)}async function Y(t,e){let n=globalThis[D];if(n&&n.revalidateTag)return n.revalidateTag(t,e);yt&&console.warn(`[what] revalidateTag('${t}') had no effect: no cache engine is bound.`)}var X=new Map;function Dt(){if(typeof document<"u"){let t=document.querySelector('meta[name="what-csrf-token"]');if(t)return t.getAttribute("content");let e=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);if(e)return decodeURIComponent(e[1])}return null}function K(){if(typeof crypto<"u"&&crypto.randomUUID)return crypto.randomUUID();if(typeof crypto<"u"&&crypto.getRandomValues){let t=new Uint8Array(16);return crypto.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}throw Object.assign(new Error("[what] No secure random source available for CSRF token generation"),{code:"ERR_NO_SECURE_RANDOM"})}function mt(t,e){if(!t||!e||t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r++)n|=t.charCodeAt(r)^e.charCodeAt(r);return n===0}function Z(t){return`<meta name="what-csrf-token" content="${String(t).replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}">`}var Ht=0,Lt=!1;function jt(){return!Lt&&typeof process<"u",`a_${typeof crypto<"u"&&crypto.getRandomValues?Array.from(crypto.getRandomValues(new Uint8Array(6)),e=>e.toString(16).padStart(2,"0")).join(""):`c${(++Ht).toString(36)}_${Date.now().toString(36)}`}`}function Mt(t,e={}){let n=e.id||jt(),{onError:r,onSuccess:s,revalidate:a}=e;typeof window>"u"&&X.set(n,{fn:t,options:e});async function o(...i){if(typeof window>"u")return t(...i);let c=e.timeout||3e4,u=new AbortController,d=setTimeout(()=>u.abort(),c);try{let f=Dt(),l={"Content-Type":"application/json","X-What-Action":n};f&&(l["X-CSRF-Token"]=f);let p=await fetch("/__what_action",{method:"POST",headers:l,credentials:"same-origin",signal:u.signal,body:JSON.stringify({args:i})});if(!p.ok){let w=await p.json().catch(()=>({message:"Action failed"}));throw Object.assign(new Error(w.message||"Action failed"),{code:"ERR_ACTION_FAILED"})}let h=await p.json();if(s&&s(h),a)for(let w of a)St(w);return h}catch(f){if(f.name==="AbortError"){let l=new Error(`Action "${n}" timed out after ${c}ms`);throw l.code="TIMEOUT",r&&r(l),l}throw r&&r(f),f}finally{clearTimeout(d)}}return o._actionId=n,o._isAction=!0,o}function gt(t,e={}){let{onSuccess:n,onError:r,resetOnSuccess:s=!0}=e;return async a=>{let o,i;a instanceof Event?(a.preventDefault(),i=a.target,o=new FormData(i)):o=a;let c={},u=!1;for(let[d,f]of o.entries())typeof File<"u"&&f instanceof File&&(u=!0),c[d]?Array.isArray(c[d])?c[d].push(f):c[d]=[c[d],f]:c[d]=f;try{let d=u?await t(c,o):await t(c);return n&&n(d,i),s&&i&&i.reset(),d}catch(d){throw r&&r(d,i),d}}}function wt(t){let e=_(!1),n=_(null),r=_(null);async function s(...a){e.set(!0),n.set(null);try{let o=await t(...a);return r.set(o),o}catch(o){throw n.set(o),o}finally{e.set(!1)}}return{trigger:s,isPending:()=>e(),error:()=>n(),data:()=>r(),reset:()=>{n.set(null),r.set(null)}}}function Ft(t,e={}){let{resetOnSuccess:n=!0}=e,r={current:null},s=wt(gt(t,{resetOnSuccess:n}));function a(o){o.preventDefault();let i=new FormData(o.target);return r.current=o.target,s.trigger(i)}return{...s,handleSubmit:a,formRef:r}}function Ut(t,e){let n=_(t),r=_([]),s=_(t);function a(u){let d=e(n.peek(),u);G(()=>{r.set([...r.peek(),u]),n.set(d)})}function o(u,d){G(()=>{if(r.set(r.peek().filter(f=>f!==u)),d!==void 0){s.set(d);let f=d;for(let l of r.peek())f=e(f,l);n.set(f)}})}function i(u,d){G(()=>{let f=r.peek().filter(h=>h!==u);r.set(f);let l=d!==void 0?d:s.peek();s.set(l);let p=l;for(let h of f)p=e(p,h);n.set(p)})}async function c(u,d){a(u);try{let f=await d();return o(u,f),f}catch(f){throw i(u),f}}return{value:()=>n(),isPending:()=>r().length>0,addOptimistic:a,resolve:o,rollback:i,withOptimistic:c,set:u=>{n.set(u),s.set(u)}}}var x=new Map;function Bt(t,e){return x.has(t)||x.set(t,new Set),x.get(t).add(e),()=>{x.get(t)?.delete(e)}}function St(t){let e=x.get(t);if(e)for(let n of e)try{n()}catch(r){console.error("[what] Revalidation error:",r)}}function H(t,e,n,r={}){let{csrfToken:s,skipCsrf:a=!1}=r;if(!a){if(!s)return Promise.resolve({status:500,body:{message:"[what] CSRF token not configured. Pass { csrfToken: sessionToken } to handleActionRequest, or { skipCsrf: true } to explicitly opt out."}});let i=t?.headers?.["x-csrf-token"]||t?.headers?.["X-CSRF-Token"];if(!mt(i,s))return Promise.resolve({status:403,body:{message:"Invalid CSRF token"}})}let o=X.get(e);return o?Array.isArray(n)?o.fn(...n).then(async i=>{let c=o.options||{};if(Array.isArray(c.revalidate))for(let u of c.revalidate)await z(u);if(Array.isArray(c.revalidateTags))for(let u of c.revalidateTags)await Y(u);return{status:200,body:i}}).catch(i=>(console.error(`[what] Action "${e}" error:`,i),{status:500,body:{message:"Action failed"}})):Promise.resolve({status:400,body:{message:"Invalid action arguments"}}):Promise.resolve({status:404,body:{message:"Action not found"}})}function Jt(){return[...X.keys()]}function Vt(t,e={}){let{onSuccess:n,onError:r,onSettled:s}=e,a={isPending:_(!1),error:_(null),data:_(null)};async function o(...i){a.isPending.set(!0),a.error.set(null);try{let c=await t(...i);return a.data.set(c),n&&n(c,...i),c}catch(c){throw a.error.set(c),r&&r(c,...i),c}finally{a.isPending.set(!1),s&&s(a.data.peek(),a.error.peek(),...i)}}return{mutate:o,isPending:()=>a.isPending(),error:()=>a.error(),data:()=>a.data(),reset:()=>{a.error.set(null),a.data.set(null)}}}import{h as L}from"what-core";var bt="/__what_action";function Wt(t){if(typeof t=="string")return t;if(typeof t=="function"){let e=t._actionId;if(e)return e;throw Object.assign(new Error("[what] <Form action={fn}>: that function is not a server action. Wrap it with action() from what-server, or pass the action id as a string."),{code:"ERR_FORM_ACTION_NOT_REGISTERED"})}throw Object.assign(new Error("[what] <Form> requires an `action` prop: a server action or its id."),{code:"ERR_FORM_ACTION_MISSING"})}function zt(){if(typeof document>"u")return null;let t=document.querySelector('meta[name="what-csrf-token"]');if(t)return t.getAttribute("content");let e=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);return e?decodeURIComponent(e[1]):null}function Yt({action:t,csrfToken:e,redirect:n,method:r="post",enhance:s=!0,children:a,...o}){let i=Wt(t),c=e!==void 0?e:zt();c==null&&typeof process<"u";let u=[L("input",{type:"hidden",name:"_action",value:i}),L("input",{type:"hidden",name:"what-csrf-token",value:c||""})];n&&u.push(L("input",{type:"hidden",name:"_redirect",value:n}));let d={...o,method:r,action:o.action||bt,"data-action":i};s&&(d["data-enhance"]="");let f=a==null?[]:Array.isArray(a)?a:[a];return L("form",d,...u,...f)}var Gt="/__what_action",At=1024*1024;function Xt(t){if(!t)return{};if(typeof t.forEach=="function"&&typeof t.get=="function"){let n={};return t.forEach((r,s)=>{n[s.toLowerCase()]=r}),n}let e={};for(let n in t)e[n.toLowerCase()]=t[n];return e}function j(t,e){return{status:t,headers:{"content-type":"application/json"},body:JSON.stringify(e)}}function Q(t,e){return{status:t,headers:{"content-type":"text/html; charset=utf-8"},body:`<!DOCTYPE html><html><body><h1>${t}</h1><p>${String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}</p></body></html>`}}function _t(t){if(typeof t!="string"||!t.startsWith("/")||/^[/\\]{2}/.test(t)||t.includes("\\"))return null;try{let e=new URL(t,"http://localhost");return e.origin!=="http://localhost"?null:e.pathname+e.search}catch{return null}}function Kt(t,e){let n=_t(t&&t._redirect);if(n)return n;let r=e.referer||e.referrer;if(r)try{let s=new URL(r,"http://localhost"),a=_t(s.pathname+s.search);if(a)return a}catch{}return"/"}var Zt=new Set(["_action","data-action","_csrf","what-csrf-token","_redirect"]);function I(t={}){let{getCsrfToken:e,skipCsrf:n=!1}=t;return async function(s){if((s.method||"POST").toUpperCase()!=="POST")return j(405,{message:"Method Not Allowed"});let o=Xt(s.headers),i=o["x-what-action"],c=o["content-type"]||"",u=!i&&c.includes("application/x-www-form-urlencoded"),d=n?void 0:e?await e(s):void 0;if(u){let h=s.body||{},w=h._action||h["data-action"]||s.query&&s.query.action;if(!w)return Q(400,'Missing action name (add a hidden "_action" field or ?action= query param)');let b={...o},k=h._csrf??h["what-csrf-token"];if(k&&!b["x-csrf-token"]&&(b["x-csrf-token"]=String(k)),!n&&e&&!d)return Q(403,"Missing CSRF token");let C={};for(let[O,U]of Object.entries(h))Zt.has(O)||(C[O]=U);let T=await H({headers:b},w,[C],{csrfToken:d,skipCsrf:n});return T.status===200?{status:303,headers:{location:Kt(h,o)},body:""}:Q(T.status,T.body&&T.body.message||"Action failed")}if(!i)return j(400,{message:"Missing X-What-Action header"});if(!n&&e&&!d)return j(403,{message:"Missing CSRF token"});let l=(s.body||{}).args,p=await H({headers:o},i,l,{csrfToken:d,skipCsrf:n});return j(p.status,p.body)}}function Qt(t={}){let e=t.basePath||Gt,n=I(t);return async function(s,a,o){let[i,c]=(s.url||"").split("?");if(i!==e||(s.method||"").toUpperCase()!=="POST")return o?o():void 0;let u;try{let l=await qt(s);u=M(l,s.headers["content-type"]||"")}catch(l){a.writeHead(l.code==="BODY_TOO_LARGE"?413:400,{"content-type":"application/json"}),a.end(JSON.stringify({message:l.code==="BODY_TOO_LARGE"?"Payload too large":"Invalid request body"}));return}let d=Object.fromEntries(new URLSearchParams(c||"")),f=await n({method:s.method,headers:s.headers,body:u,query:d});a.writeHead(f.status,f.headers),a.end(f.body)}}function M(t,e){if((e||"").includes("application/x-www-form-urlencoded")){let n={};for(let[r,s]of new URLSearchParams(String(t)))n[r]===void 0?n[r]=s:Array.isArray(n[r])?n[r].push(s):n[r]=[n[r],s];return n}return t==null||t===""?{}:JSON.parse(String(t))}async function F(t,e=At){let n=Number(t.headers.get("content-length"));if(Number.isFinite(n)&&n>e)return{tooLarge:!0};let r=t.body;if(!r||typeof r.getReader!="function"){let i=await t.text();return Buffer.byteLength(i,"utf8")>e?{tooLarge:!0}:{raw:i}}let s=r.getReader(),a=[],o=0;for(;;){let{done:i,value:c}=await s.read();if(i)break;if(c){if(o+=c.byteLength,o>e){try{await s.cancel()}catch{}return{tooLarge:!0}}a.push(c)}}return{raw:Buffer.concat(a.map(i=>Buffer.from(i))).toString("utf8")}}function qt(t){return new Promise((e,n)=>{let r=0,s=[];t.on("data",a=>{if(r+=a.length,r>At){let o=new Error("Body too large");o.code="BODY_TOO_LARGE",n(o),t.destroy?.();return}s.push(a)}),t.on("end",()=>{if(s.length===0)return e("");e(Buffer.concat(s).toString("utf8"))}),t.on("error",n)})}function te(t={}){let e=I(t);return async function(n){let r={};try{let o=await F(n);if(o.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});r=M(o.raw,n.headers.get("content-type")||"")}catch{r={}}let s={};try{s=Object.fromEntries(new URL(n.url,"http://localhost").searchParams)}catch{}let a=await e({method:n.method,headers:n.headers,body:r,query:s});return new Response(a.body,{status:a.status,headers:a.headers})}}import{matchRoute as ee,parseQuery as ne}from"what-router/match";var re="/__what_action",oe="/__what_revalidate",q="what-csrf";function N(t){let e={};return t&&typeof t.forEach=="function"&&t.forEach((n,r)=>{e[r.toLowerCase()]=n}),e}function Rt(t,e){if(!t)return null;let n=String(t).match(new RegExp(`(?:^|;\\s*)${e}=([^;]+)`));return n?decodeURIComponent(n[1]):null}async function ae(t){try{let e=await F(t);return e.tooLarge?{tooLarge:!0}:M(e.raw,t.headers.get("content-type")||"")}catch{return{}}}async function se(t){let e;try{e=await F(t)}catch{return{json:{}}}if(e.tooLarge)return{tooLarge:!0};try{return{json:JSON.parse(e.raw??"")}}catch{return{json:{}}}}function ie(t){return async function(n){let{route:r,params:s,query:a,request:o,csrfToken:i}=n,c={default:r.component,loader:r.loader},u=i?{params:s,query:a,request:o,csrfToken:i}:{params:s,query:a,request:o},d=i?{...t,csrfToken:i}:t;return{html:await Et(c,u,d),status:200,tags:n.config&&n.config.tags||[],path:n.path}}}function tt(t={}){let{routes:e=[],cache:n,render:r,revalidateWebhook:s,document:a={},notFound:o,basePath:i="",csrf:c=!0}=t,u=c!==!1&&!t.actionHandler,d=t.actionHandler||I(u?{getCsrfToken:l=>Rt(l.headers&&l.headers.cookie,q)}:{skipCsrf:!0}),f=r||ie(a);return n&&(n.revalidatePath||n.revalidateTag)&&W({revalidatePath:n.revalidatePath,revalidateTag:n.revalidateTag}),async function(p){let h=new URL(p.url,"http://localhost"),w=h.pathname;if(i&&w.startsWith(i)&&(w=w.slice(i.length)||"/"),p.method==="POST"&&w===re){let m=await ae(p);if(m&&m.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let R=await d({method:"POST",headers:N(p.headers),body:m,query:Object.fromEntries(h.searchParams)});return new Response(R.body,{status:R.status,headers:R.headers})}let b=null,k=null;if(u&&(b=Rt(N(p.headers).cookie,q),!b)){b=K();let R=N(p.headers)["x-forwarded-proto"]==="https"||h.protocol==="https:"||!0;k=`${q}=${encodeURIComponent(b)}; Path=/; SameSite=Lax`+(R?"; Secure":"")}let C=m=>(k&&(m["set-cookie"]=k),m);if(p.method==="POST"&&w===oe&&s){let m=await se(p);if(m.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let R=await s({headers:N(p.headers),body:m.json});return new Response(JSON.stringify(R.body),{status:R.status,headers:{"content-type":"application/json"}})}let T=ee(w,e);if(!T){let m=o?o():"<!DOCTYPE html><html><body><h1>404 \u2014 Not Found</h1></body></html>";return new Response(m,{status:404,headers:C({"content-type":"text/html; charset=utf-8"})})}let{route:O,params:U}=T,B=O.page||{mode:O.mode||"client"},v={path:w,query:ne(h.search),config:B,route:O,params:U,request:p};if(n&&B.mode!=="server"){v.varyHeaders=N(p.headers);let m=await n.handle(v,()=>f(v));return new Response(m.html,{status:m.status||200,headers:C({"content-type":"text/html; charset=utf-8",...m.headers||{}})})}b&&(v.csrfToken=b);let J=await f(v),pt=C({"content-type":"text/html; charset=utf-8",...J.headers||{}});return B.mode==="server"&&(pt["Cache-Control"]="private, no-store"),new Response(J.html,{status:J.status||200,headers:pt})}}function ce(t={}){let e=tt(t);return{async fetch(n,r,s){return r&&(n.__env=r),s&&(n.__ctx=s),e(n)}}}function E(t){return{head:de(),loaderData:t,resources:new Map,islandStores:new Map,resourceCounter:0,boundaryCounter:0,suspended:[]}}var kt=0;function fe(){kt=0}function le(){return"h"+kt++}function pe(t){if(!Tt()){let e=E(void 0);return S(e,()=>pe(t))}return fe(),A(t)}var Ct=new Set(["__errorBoundary","__suspense"]),st=new Set(["__portal"]);function it(t){let e=t.children;return!e||e.length===0?{...t.props}:{...t.props,children:e}}function ct(t,e){let n=t.props&&t.props.fallback;if(typeof n!="function")return n;let r=t.props&&t.props.reset||(()=>{});try{return n({error:e,reset:r})}catch(s){return P&&console.warn(`[what-server] <ErrorBoundary> fallback threw during SSR: ${s.message}`),null}}function A(t){if(t==null||t===!1||t===!0)return"";if(typeof t=="string"||typeof t=="number")return g(String(t));if(typeof t=="function"&&t._signal)return`<!--$-->${A(t())}<!--/$-->`;if(typeof t=="function"&&t._mapArray)try{return`<!--$-->${A(ot(t))}<!--/$-->`}catch{return typeof process<"u","<!--$--><!--/$-->"}if(typeof t=="function")try{return`<!--$-->${A(t())}<!--/$-->`}catch{return typeof process<"u","<!--$--><!--/$-->"}if(Array.isArray(t))return`<!--[]-->${t.map(A).join("")}<!--/[]-->`;if(st.has(t.tag))return"";if(Ct.has(t.tag))try{return(t.children||[]).map(A).join("")}catch(c){let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return A(ct(t,u?null:c))}if(typeof t.tag=="function"){let c=le(),u=nt(t.tag),d;try{d=A(t.tag(it(t)))}finally{rt(u)}return he(d,c)}let{tag:e,props:n,children:r}=t;dt(e);let s=ft(n||{}),a=`<${e}${s}>`;if(lt.has(e))return a;let o=ut(n),i=o!=null?String(o):r.map(A).join("");return`${a}${i}</${e}>`}function he(t,e){let n=t.match(/^((?:<!--.*?-->)*)<([a-zA-Z][a-zA-Z0-9-]*)/);if(n){let r=n[1],s=n[2],a=r.length+1+s.length,o=t.indexOf(">",a),i=t.slice(a,o===-1?void 0:o);return/[\s"']data-hk\s*=/.test(i)||/^\s*data-hk\s*=/.test(i)?t:t.slice(0,a)+` data-hk="${e}"`+t.slice(a)}return t}function y(t){if(!Tt()){let c=E(void 0);return S(c,()=>y(t))}if(t==null||t===!1||t===!0)return"";if(typeof t=="string"||typeof t=="number")return g(String(t));if(typeof t=="function"&&t._signal)return y(t());if(typeof t=="function"&&t._mapArray)try{return y(ot(t))}catch{return typeof process<"u",""}if(typeof t=="function")try{return y(t())}catch{return typeof process<"u",""}if(Array.isArray(t))return t.map(y).join("");if(st.has(t.tag))return"";if(Ct.has(t.tag))try{return(t.children||[]).map(y).join("")}catch(c){let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return y(ct(t,u?null:c))}if(typeof t.tag=="function"){let c=nt(t.tag);try{return y(t.tag(it(t)))}finally{rt(c)}}let{tag:e,props:n,children:r}=t;dt(e);let s=ft(n||{}),a=`<${e}${s}>`;if(lt.has(e))return a;let o=ut(n),i=o!=null?String(o):r.map(y).join("");return`${a}${i}</${e}>`}function Ze(t){let e=E(void 0);return{body:S(e,()=>y(t)),head:at(e.head)}}async function Qe(t,e={}){let n=t.default||t,r=typeof t.loader=="function"?await t.loader(e):void 0,s=E(r),a=e.params||{};return{body:S(s,()=>y(et(n,{...a,loaderData:r}))),head:at(s.head),loaderData:r}}var Ot=12;async function ye(t,e){e||(e=E(void 0));let n="",r=e.resourceCounter;for(let a=0;a<Ot;a++){e.resourceCounter=r,n=S(e,()=>y(t));let o=[...e.resources.values()].filter(i=>i.status==="pending").map(i=>i.promise);if(o.length===0)break;await Promise.all(o)}let s={};for(let[a,o]of e.resources)o.status==="ready"&&(s[a]=o.value);return{body:n,head:at(e.head),loaderData:e.loaderData,resources:s,ctx:e}}async function Et(t,e={},n={}){let r=t.default||t,s=typeof t.loader=="function"?await t.loader(e):void 0,a=E(s),o=e.params||{},{body:i,head:c,resources:u}=await ye(et(r,{...o,loaderData:s}),a),d={loaderData:s??null,resources:u,islandStores:ht(a)};return me({body:i,head:c,payload:d,options:n})}function me({body:t,head:e,payload:n,options:r={}}){let s=r.lang||"en",a=`<script id="__what_data" type="application/json">${V(n)}<\/script>`,o=r.clientEntry?`<script type="module" src="${g(r.clientEntry)}"><\/script>`:"",c=(r.csrfToken?Z(r.csrfToken):"")+(r.head||""),u=r.bodyClass?` class="${g(r.bodyClass)}"`:"";return`<!DOCTYPE html><html lang="${g(s)}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">${e||""}${c}</head><body${u}>${t}${a}${o}</body></html>`}async function*$(t,e){if(e===void 0&&(e=E(void 0)),t==null||t===!1||t===!0)return;if(typeof t=="string"||typeof t=="number"){yield g(String(t));return}if(typeof t=="function"&&t._signal){let o=S(e,()=>t());yield*$(o,e);return}if(typeof t=="function"&&t._mapArray){let o=null;try{o=S(e,()=>ot(t))}catch{typeof process<"u"}o&&(yield*$(o,e));return}if(typeof t=="function"){try{let o=S(e,()=>t());yield*$(o,e)}catch{typeof process<"u"}return}if(Array.isArray(t)){for(let o of t)yield*$(o,e);return}if(st.has(t.tag))return;if(t.tag==="__errorBoundary"){let o;try{o=S(e,()=>(t.children||[]).map(y).join(""))}catch(i){if(i&&typeof i.then=="function")throw i;o=S(e,()=>y(ct(t,i)))}yield o;return}if(t.tag==="__suspense"){let o=null,i=e.resourceCounter;for(let c=0;c<Ot&&o===null;c++){e.resourceCounter=i;let u=null;try{o=S(e,()=>(t.children||[]).map(y).join(""))}catch(d){if(d&&typeof d.then=="function")u=d;else throw d}if(o===null){let d=[...e.resources.values()].filter(f=>f.status==="pending").map(f=>f.promise);await Promise.all([u,...d].filter(Boolean))}}o===null&&(o=S(e,()=>y(t.props&&t.props.fallback))),yield o;return}if(typeof t.tag=="function"){let o=nt(t.tag);try{let i=S(e,()=>t.tag(it(t))),c=i instanceof Promise?await i:i;yield*$(c,e)}catch(i){typeof process<"u",yield P?`<!-- SSR Error: ${g(i.message||"Component error")} -->`:"<!-- SSR Error -->"}finally{rt(o)}return}let{tag:n,props:r,children:s}=t;dt(n);let a=ft(r||{});if(yield`<${n}${a}>`,!lt.has(n)){let o=ut(r);if(o!=null)yield String(o);else for(let i of s)yield*$(i,e);yield`</${n}>`}}function qe(t){return{mode:"static",...t}}function tn(t,e={}){let n=E(e),r=S(n,()=>y(et(t.component,e))),s=t.islands||[];return ge({title:t.title||"",meta:t.meta||{},body:r,islands:s,scripts:t.mode==="static"?[]:t.scripts||[],styles:t.styles||[],mode:t.mode})}function ge({title:t,meta:e,body:n,islands:r,scripts:s,styles:a,mode:o}){let i=Object.entries(e).map(([l,p])=>`<meta name="${g(l)}" content="${g(p)}">`).join(`
|
|
2
2
|
`),c=a.map(l=>`<link rel="stylesheet" href="${g(l)}">`).join(`
|
|
3
3
|
`),u=r.length>0?`
|
|
4
4
|
<script type="module">
|
|
@@ -21,4 +21,4 @@ import{h as tt,_isAriaAttr as ue,_beginComponentSSR as et,_endComponentSSR as nt
|
|
|
21
21
|
${d}
|
|
22
22
|
${f}
|
|
23
23
|
</body>
|
|
24
|
-
</html>`}function en(t){return t._server=!0,t}var P=!(typeof process<"u");function
|
|
24
|
+
</html>`}function en(t){return t._server=!0,t}var P=!(typeof process<"u");function ut(t){return t?t.dangerouslySetInnerHTML?t.dangerouslySetInnerHTML.__html??null:t.innerHTML&&typeof t.innerHTML=="object"&&"__html"in t.innerHTML?t.innerHTML.__html??null:(t.innerHTML!=null&&typeof t.innerHTML=="string"&&P&&console.warn("[what-server] innerHTML received a raw string. This is a security risk (XSS). Use innerHTML={{ __html: trustedString }} or dangerouslySetInnerHTML={{ __html: trustedString }} instead."),null):null}var we=/^[a-zA-Z_:][a-zA-Z0-9:._-]*$/,Se=/^[a-zA-Z_][a-zA-Z0-9._:-]*$/;function dt(t){if(typeof t!="string"||!Se.test(t))throw Object.assign(new Error(`[what-server] Invalid tag name in SSR: ${JSON.stringify(t)}`),{code:"ERR_INVALID_SSR_TAG"})}function ft(t){let e="";for(let[n,r]of Object.entries(t)){if(n==="key"||n==="ref"||n==="children"||n==="dangerouslySetInnerHTML"||n==="innerHTML")continue;let s=n.toLowerCase();if(s.startsWith("on")&&n.length>2)continue;let a=r;if(typeof a=="function"){try{a=a()}catch(o){P&&console.warn(`[what-server] Skipping attribute ${JSON.stringify(n)}: its value threw during SSR: ${o.message}`);continue}if(typeof a=="function")continue}if(a===!1&&ue(n)){e+=` ${n}="false"`;continue}if(!(a===!1||a==null)){if(!we.test(n)){P&&console.warn(`[what-server] Skipping invalid attribute name in SSR: ${JSON.stringify(n)}`);continue}if(Ae.has(s)){P&&console.warn(`[what-server] Skipping unsafe attribute in SSR: ${JSON.stringify(n)}`);continue}if(n==="className"||n==="class")e+=` class="${g(String(a))}"`;else if(n==="style"&&typeof a=="object"){let o=Object.entries(a).map(([i,c])=>`${Re(i)}:${c}`).join(";");e+=` style="${g(o)}"`}else if(a===!0)n.startsWith("aria-")||n==="role"?e+=` ${n}="true"`:e+=` ${n}`;else{if(be(n,a))continue;e+=` ${n}="${g(String(a))}"`}}}return e}function be(t,e){let n=t.toLowerCase();if(!_e.has(n))return!1;let r=String(e).trim().replace(/[\u0000-\u001f\u007f\s]+/g,"").toLowerCase();return r.startsWith("javascript:")||r.startsWith("vbscript:")||r.startsWith("data:")}var _e=new Set(["href","src","action","formaction","data","ping","xlink:href"]),Ae=new Set(["srcdoc"]);function g(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function Re(t){return t.startsWith("--")?t:t.replace(/([A-Z])/g,"-$1").toLowerCase()}var lt=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);export{bt as ACTION_ENDPOINT,Yt as Form,Mt as action,I as createActionHandler,ce as createCloudflareHandler,tt as createRequestHandler,Z as csrfMetaTag,qe as definePage,te as fetchActionHandler,gt as formAction,K as generateCsrfToken,tn as generateStaticPage,Jt as getRegisteredActions,Nt as getRevalidationHandler,H as handleActionRequest,St as invalidatePath,Qt as nodeActionMiddleware,Bt as onRevalidate,Et as renderDocument,Qe as renderPage,pe as renderToHydratableString,$ as renderToStream,y as renderToString,ye as renderToStringAsync,Ze as renderToStringWithHead,z as revalidatePath,Y as revalidateTag,V as serializeState,en as server,W as setRevalidationHandler,wt as useAction,Ft as useFormAction,Vt as useMutation,Ut as useOptimistic,mt as validateCsrfToken};
|
package/dist/node.min.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{AsyncLocalStorage as Je}from"node:async_hooks";import{__installServerContextStorage as We}from"what-core";import{h as rt,_isAriaAttr as ge,_beginComponentSSR as ot,_endComponentSSR as at,_mapArrayToArray as st,getServerContext as Ct,runWithServerContext as S,beginHeadCollection as we,endHeadCollection as it}from"what-core";var Dt=new RegExp("[<>&\\u2028\\u2029]","g"),Lt={60:"\\u003c",62:"\\u003e",38:"\\u0026",8232:"\\u2028",8233:"\\u2029"};function N(t){return JSON.stringify(t).replace(Dt,e=>Lt[e.charCodeAt(0)])}import{mount as Ye,hydrate as Xe,signal as Ke,batch as Ze,getServerContext as Mt}from"what-core";var Ft=new Map;function Ut(t){let e=t||Mt();return e&&e.islandStores instanceof Map?e.islandStores:null}function St(t){let e=typeof document<"u"?Ft:Ut(t),n={};for(let[r,s]of e||[])n[r]=s._getSnapshot();return n}import{signal as _,batch as Z}from"what-core";var L=Symbol.for("what.revalidationHandler"),bt=!(typeof process<"u");function Y(t){globalThis[L]=t}function Bt(){return globalThis[L]??null}async function X(t,e){let n=globalThis[L];if(n&&n.revalidatePath)return n.revalidatePath(t,e);bt&&console.warn(`[what] revalidatePath('${t}') had no effect: no cache engine is bound. Create a what-isr engine and bind it in your adapter (setRevalidationHandler).`)}async function K(t,e){let n=globalThis[L];if(n&&n.revalidateTag)return n.revalidateTag(t,e);bt&&console.warn(`[what] revalidateTag('${t}') had no effect: no cache engine is bound.`)}var Q=new Map;function Vt(){if(typeof document<"u"){let t=document.querySelector('meta[name="what-csrf-token"]');if(t)return t.getAttribute("content");let e=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);if(e)return decodeURIComponent(e[1])}return null}function q(){if(typeof crypto<"u"&&crypto.randomUUID)return crypto.randomUUID();if(typeof crypto<"u"&&crypto.getRandomValues){let t=new Uint8Array(16);return crypto.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}throw Object.assign(new Error("[what] No secure random source available for CSRF token generation"),{code:"ERR_NO_SECURE_RANDOM"})}function _t(t,e){if(!t||!e||t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r++)n|=t.charCodeAt(r)^e.charCodeAt(r);return n===0}function tt(t){return`<meta name="what-csrf-token" content="${String(t).replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}">`}var Jt=0,Wt=!1;function zt(){return!Wt&&typeof process<"u",`a_${typeof crypto<"u"&&crypto.getRandomValues?Array.from(crypto.getRandomValues(new Uint8Array(6)),e=>e.toString(16).padStart(2,"0")).join(""):`c${(++Jt).toString(36)}_${Date.now().toString(36)}`}`}function Gt(t,e={}){let n=e.id||zt(),{onError:r,onSuccess:s,revalidate:o}=e;typeof window>"u"&&Q.set(n,{fn:t,options:e});async function a(...i){if(typeof window>"u")return t(...i);let c=e.timeout||3e4,u=new AbortController,d=setTimeout(()=>u.abort(),c);try{let f=Vt(),l={"Content-Type":"application/json","X-What-Action":n};f&&(l["X-CSRF-Token"]=f);let p=await fetch("/__what_action",{method:"POST",headers:l,credentials:"same-origin",signal:u.signal,body:JSON.stringify({args:i})});if(!p.ok){let y=await p.json().catch(()=>({message:"Action failed"}));throw Object.assign(new Error(y.message||"Action failed"),{code:"ERR_ACTION_FAILED"})}let h=await p.json();if(s&&s(h),o)for(let y of o)At(y);return h}catch(f){if(f.name==="AbortError"){let l=new Error(`Action "${n}" timed out after ${c}ms`);throw l.code="TIMEOUT",r&&r(l),l}throw r&&r(f),f}finally{clearTimeout(d)}}return a._actionId=n,a._isAction=!0,a}function Rt(t,e={}){let{onSuccess:n,onError:r,resetOnSuccess:s=!0}=e;return async o=>{let a,i;o instanceof Event?(o.preventDefault(),i=o.target,a=new FormData(i)):a=o;let c={},u=!1;for(let[d,f]of a.entries())typeof File<"u"&&f instanceof File&&(u=!0),c[d]?Array.isArray(c[d])?c[d].push(f):c[d]=[c[d],f]:c[d]=f;try{let d=u?await t(c,a):await t(c);return n&&n(d,i),s&&i&&i.reset(),d}catch(d){throw r&&r(d,i),d}}}function Et(t){let e=_(!1),n=_(null),r=_(null);async function s(...o){e.set(!0),n.set(null);try{let a=await t(...o);return r.set(a),a}catch(a){throw n.set(a),a}finally{e.set(!1)}}return{trigger:s,isPending:()=>e(),error:()=>n(),data:()=>r(),reset:()=>{n.set(null),r.set(null)}}}function Yt(t,e={}){let{resetOnSuccess:n=!0}=e,r={current:null},s=Et(Rt(t,{resetOnSuccess:n}));function o(a){a.preventDefault();let i=new FormData(a.target);return r.current=a.target,s.trigger(i)}return{...s,handleSubmit:o,formRef:r}}function Xt(t,e){let n=_(t),r=_([]),s=_(t);function o(u){let d=e(n.peek(),u);Z(()=>{r.set([...r.peek(),u]),n.set(d)})}function a(u,d){Z(()=>{if(r.set(r.peek().filter(f=>f!==u)),d!==void 0){s.set(d);let f=d;for(let l of r.peek())f=e(f,l);n.set(f)}})}function i(u,d){Z(()=>{let f=r.peek().filter(h=>h!==u);r.set(f);let l=d!==void 0?d:s.peek();s.set(l);let p=l;for(let h of f)p=e(p,h);n.set(p)})}async function c(u,d){o(u);try{let f=await d();return a(u,f),f}catch(f){throw i(u),f}}return{value:()=>n(),isPending:()=>r().length>0,addOptimistic:o,resolve:a,rollback:i,withOptimistic:c,set:u=>{n.set(u),s.set(u)}}}var I=new Map;function Kt(t,e){return I.has(t)||I.set(t,new Set),I.get(t).add(e),()=>{I.get(t)?.delete(e)}}function At(t){let e=I.get(t);if(e)for(let n of e)try{n()}catch(r){console.error("[what] Revalidation error:",r)}}function M(t,e,n,r={}){let{csrfToken:s,skipCsrf:o=!1}=r;if(!o){if(!s)return Promise.resolve({status:500,body:{message:"[what] CSRF token not configured. Pass { csrfToken: sessionToken } to handleActionRequest, or { skipCsrf: true } to explicitly opt out."}});let i=t?.headers?.["x-csrf-token"]||t?.headers?.["X-CSRF-Token"];if(!_t(i,s))return Promise.resolve({status:403,body:{message:"Invalid CSRF token"}})}let a=Q.get(e);return a?Array.isArray(n)?a.fn(...n).then(async i=>{let c=a.options||{};if(Array.isArray(c.revalidate))for(let u of c.revalidate)await X(u);if(Array.isArray(c.revalidateTags))for(let u of c.revalidateTags)await K(u);return{status:200,body:i}}).catch(i=>(console.error(`[what] Action "${e}" error:`,i),{status:500,body:{message:"Action failed"}})):Promise.resolve({status:400,body:{message:"Invalid action arguments"}}):Promise.resolve({status:404,body:{message:"Action not found"}})}function Zt(){return[...Q.keys()]}function Qt(t,e={}){let{onSuccess:n,onError:r,onSettled:s}=e,o={isPending:_(!1),error:_(null),data:_(null)};async function a(...i){o.isPending.set(!0),o.error.set(null);try{let c=await t(...i);return o.data.set(c),n&&n(c,...i),c}catch(c){throw o.error.set(c),r&&r(c,...i),c}finally{o.isPending.set(!1),s&&s(o.data.peek(),o.error.peek(),...i)}}return{mutate:a,isPending:()=>o.isPending(),error:()=>o.error(),data:()=>o.data(),reset:()=>{o.error.set(null),o.data.set(null)}}}import{h as F}from"what-core";var Tt="/__what_action";function qt(t){if(typeof t=="string")return t;if(typeof t=="function"){let e=t._actionId;if(e)return e;throw Object.assign(new Error("[what] <Form action={fn}>: that function is not a server action. Wrap it with action() from what-server, or pass the action id as a string."),{code:"ERR_FORM_ACTION_NOT_REGISTERED"})}throw Object.assign(new Error("[what] <Form> requires an `action` prop: a server action or its id."),{code:"ERR_FORM_ACTION_MISSING"})}function te(){if(typeof document>"u")return null;let t=document.querySelector('meta[name="what-csrf-token"]');if(t)return t.getAttribute("content");let e=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);return e?decodeURIComponent(e[1]):null}function ee({action:t,csrfToken:e,redirect:n,method:r="post",enhance:s=!0,children:o,...a}){let i=qt(t),c=e!==void 0?e:te();c==null&&typeof process<"u";let u=[F("input",{type:"hidden",name:"_action",value:i}),F("input",{type:"hidden",name:"what-csrf-token",value:c||""})];n&&u.push(F("input",{type:"hidden",name:"_redirect",value:n}));let d={...a,method:r,action:a.action||Tt,"data-action":i};s&&(d["data-enhance"]="");let f=o==null?[]:Array.isArray(o)?o:[o];return F("form",d,...u,...f)}var ne="/__what_action",j=1024*1024;function re(t){if(!t)return{};if(typeof t.forEach=="function"&&typeof t.get=="function"){let n={};return t.forEach((r,s)=>{n[s.toLowerCase()]=r}),n}let e={};for(let n in t)e[n.toLowerCase()]=t[n];return e}function U(t,e){return{status:t,headers:{"content-type":"application/json"},body:JSON.stringify(e)}}function et(t,e){return{status:t,headers:{"content-type":"text/html; charset=utf-8"},body:`<!DOCTYPE html><html><body><h1>${t}</h1><p>${String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}</p></body></html>`}}function kt(t){if(typeof t!="string"||!t.startsWith("/")||/^[/\\]{2}/.test(t)||t.includes("\\"))return null;try{let e=new URL(t,"http://localhost");return e.origin!=="http://localhost"?null:e.pathname+e.search}catch{return null}}function oe(t,e){let n=kt(t&&t._redirect);if(n)return n;let r=e.referer||e.referrer;if(r)try{let s=new URL(r,"http://localhost"),o=kt(s.pathname+s.search);if(o)return o}catch{}return"/"}var ae=new Set(["_action","data-action","_csrf","what-csrf-token","_redirect"]);function H(t={}){let{getCsrfToken:e,skipCsrf:n=!1}=t;return async function(s){if((s.method||"POST").toUpperCase()!=="POST")return U(405,{message:"Method Not Allowed"});let a=re(s.headers),i=a["x-what-action"],c=a["content-type"]||"",u=!i&&c.includes("application/x-www-form-urlencoded"),d=n?void 0:e?await e(s):void 0;if(u){let h=s.body||{},y=h._action||h["data-action"]||s.query&&s.query.action;if(!y)return et(400,'Missing action name (add a hidden "_action" field or ?action= query param)');let b={...a},O=h._csrf??h["what-csrf-token"];if(O&&!b["x-csrf-token"]&&(b["x-csrf-token"]=String(O)),!n&&e&&!d)return et(403,"Missing CSRF token");let C={};for(let[v,z]of Object.entries(h))ae.has(v)||(C[v]=z);let k=await M({headers:b},y,[C],{csrfToken:d,skipCsrf:n});return k.status===200?{status:303,headers:{location:oe(h,a)},body:""}:et(k.status,k.body&&k.body.message||"Action failed")}if(!i)return U(400,{message:"Missing X-What-Action header"});if(!n&&e&&!d)return U(403,{message:"Missing CSRF token"});let l=(s.body||{}).args,p=await M({headers:a},i,l,{csrfToken:d,skipCsrf:n});return U(p.status,p.body)}}function se(t={}){let e=t.basePath||ne,n=H(t);return async function(s,o,a){let[i,c]=(s.url||"").split("?");if(i!==e||(s.method||"").toUpperCase()!=="POST")return a?a():void 0;let u;try{let l=await ie(s);u=B(l,s.headers["content-type"]||"")}catch(l){o.writeHead(l.code==="BODY_TOO_LARGE"?413:400,{"content-type":"application/json"}),o.end(JSON.stringify({message:l.code==="BODY_TOO_LARGE"?"Payload too large":"Invalid request body"}));return}let d=Object.fromEntries(new URLSearchParams(c||"")),f=await n({method:s.method,headers:s.headers,body:u,query:d});o.writeHead(f.status,f.headers),o.end(f.body)}}function B(t,e){if((e||"").includes("application/x-www-form-urlencoded")){let n={};for(let[r,s]of new URLSearchParams(String(t)))n[r]===void 0?n[r]=s:Array.isArray(n[r])?n[r].push(s):n[r]=[n[r],s];return n}return t==null||t===""?{}:JSON.parse(String(t))}async function V(t,e=j){let n=Number(t.headers.get("content-length"));if(Number.isFinite(n)&&n>e)return{tooLarge:!0};let r=t.body;if(!r||typeof r.getReader!="function"){let i=await t.text();return Buffer.byteLength(i,"utf8")>e?{tooLarge:!0}:{raw:i}}let s=r.getReader(),o=[],a=0;for(;;){let{done:i,value:c}=await s.read();if(i)break;if(c){if(a+=c.byteLength,a>e){try{await s.cancel()}catch{}return{tooLarge:!0}}o.push(c)}}return{raw:Buffer.concat(o.map(i=>Buffer.from(i))).toString("utf8")}}function ie(t){return new Promise((e,n)=>{let r=0,s=[];t.on("data",o=>{if(r+=o.length,r>j){let a=new Error("Body too large");a.code="BODY_TOO_LARGE",n(a),t.destroy?.();return}s.push(o)}),t.on("end",()=>{if(s.length===0)return e("");e(Buffer.concat(s).toString("utf8"))}),t.on("error",n)})}function ce(t={}){let e=H(t);return async function(n){let r={};try{let a=await V(n);if(a.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});r=B(a.raw,n.headers.get("content-type")||"")}catch{r={}}let s={};try{s=Object.fromEntries(new URL(n.url,"http://localhost").searchParams)}catch{}let o=await e({method:n.method,headers:n.headers,body:r,query:s});return new Response(o.body,{status:o.status,headers:o.headers})}}import{matchRoute as ue,parseQuery as de}from"what-router/match";var fe="/__what_action",le="/__what_revalidate",nt="what-csrf";function D(t){let e={};return t&&typeof t.forEach=="function"&&t.forEach((n,r)=>{e[r.toLowerCase()]=n}),e}function Ot(t,e){if(!t)return null;let n=String(t).match(new RegExp(`(?:^|;\\s*)${e}=([^;]+)`));return n?decodeURIComponent(n[1]):null}async function pe(t){try{let e=await V(t);return e.tooLarge?{tooLarge:!0}:B(e.raw,t.headers.get("content-type")||"")}catch{return{}}}async function he(t){let e;try{e=await V(t)}catch{return{json:{}}}if(e.tooLarge)return{tooLarge:!0};try{return{json:JSON.parse(e.raw??"")}}catch{return{json:{}}}}function ye(t){return async function(n){let{route:r,params:s,query:o,request:a,csrfToken:i}=n,c={default:r.component,loader:r.loader},u=i?{params:s,query:o,request:a,csrfToken:i}:{params:s,query:o,request:a},d=i?{...t,csrfToken:i}:t;return{html:await J(c,u,d),status:200,tags:n.config&&n.config.tags||[],path:n.path}}}function A(t={}){let{routes:e=[],cache:n,render:r,revalidateWebhook:s,document:o={},notFound:a,basePath:i="",csrf:c=!0}=t,u=c!==!1&&!t.actionHandler,d=t.actionHandler||H(u?{getCsrfToken:l=>Ot(l.headers&&l.headers.cookie,nt)}:{skipCsrf:!0}),f=r||ye(o);return n&&(n.revalidatePath||n.revalidateTag)&&Y({revalidatePath:n.revalidatePath,revalidateTag:n.revalidateTag}),async function(p){let h=new URL(p.url,"http://localhost"),y=h.pathname;if(i&&y.startsWith(i)&&(y=y.slice(i.length)||"/"),p.method==="POST"&&y===fe){let g=await pe(p);if(g&&g.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let E=await d({method:"POST",headers:D(p.headers),body:g,query:Object.fromEntries(h.searchParams)});return new Response(E.body,{status:E.status,headers:E.headers})}let b=null,O=null;if(u&&(b=Ot(D(p.headers).cookie,nt),!b)){b=q();let E=D(p.headers)["x-forwarded-proto"]==="https"||h.protocol==="https:"||!0;O=`${nt}=${encodeURIComponent(b)}; Path=/; SameSite=Lax`+(E?"; Secure":"")}let C=g=>(O&&(g["set-cookie"]=O),g);if(p.method==="POST"&&y===le&&s){let g=await he(p);if(g.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let E=await s({headers:D(p.headers),body:g.json});return new Response(JSON.stringify(E.body),{status:E.status,headers:{"content-type":"application/json"}})}let k=ue(y,e);if(!k){let g=a?a():"<!DOCTYPE html><html><body><h1>404 \u2014 Not Found</h1></body></html>";return new Response(g,{status:404,headers:C({"content-type":"text/html; charset=utf-8"})})}let{route:v,params:z}=k,G=v.page||{mode:v.mode||"client"},P={path:y,query:de(h.search),config:G,route:v,params:z,request:p};if(n&&G.mode!=="server"){P.varyHeaders=D(p.headers);let g=await n.handle(P,()=>f(P));return new Response(g.html,{status:g.status||200,headers:C({"content-type":"text/html; charset=utf-8",...g.headers||{}})})}b&&(P.csrfToken=b);let gt=await f(P),wt=C({"content-type":"text/html; charset=utf-8"});return G.mode==="server"&&(wt["Cache-Control"]="private, no-store"),new Response(gt.html,{status:gt.status||200,headers:wt})}}function me(t={}){let e=A(t);return{async fetch(n,r,s){return r&&(n.__env=r),s&&(n.__ctx=s),e(n)}}}function T(t){return{head:we(),loaderData:t,resources:new Map,islandStores:new Map,resourceCounter:0,boundaryCounter:0,suspended:[]}}var vt=0;function Se(){vt=0}function be(){return"h"+vt++}function _e(t){if(!Ct()){let e=T(void 0);return S(e,()=>_e(t))}return Se(),R(t)}var xt=new Set(["__errorBoundary","__suspense"]),ct=new Set(["__portal"]);function ut(t){let e=t.children;return!e||e.length===0?{...t.props}:{...t.props,children:e}}function dt(t,e){let n=t.props&&t.props.fallback;if(typeof n!="function")return n;let r=t.props&&t.props.reset||(()=>{});try{return n({error:e,reset:r})}catch(s){return $&&console.warn(`[what-server] <ErrorBoundary> fallback threw during SSR: ${s.message}`),null}}function R(t){if(t==null||t===!1||t===!0)return"";if(typeof t=="string"||typeof t=="number")return w(String(t));if(typeof t=="function"&&t._signal)return`<!--$-->${R(t())}<!--/$-->`;if(typeof t=="function"&&t._mapArray)try{return`<!--$-->${R(st(t))}<!--/$-->`}catch{return typeof process<"u","<!--$--><!--/$-->"}if(typeof t=="function")try{return`<!--$-->${R(t())}<!--/$-->`}catch{return typeof process<"u","<!--$--><!--/$-->"}if(Array.isArray(t))return`<!--[]-->${t.map(R).join("")}<!--/[]-->`;if(ct.has(t.tag))return"";if(xt.has(t.tag))try{return(t.children||[]).map(R).join("")}catch(c){let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return R(dt(t,u?null:c))}if(typeof t.tag=="function"){let c=be(),u=ot(t.tag),d;try{d=R(t.tag(ut(t)))}finally{at(u)}return Re(d,c)}let{tag:e,props:n,children:r}=t;lt(e);let s=pt(n||{}),o=`<${e}${s}>`;if(ht.has(e))return o;let a=ft(n),i=a!=null?String(a):r.map(R).join("");return`${o}${i}</${e}>`}function Re(t,e){let n=t.match(/^((?:<!--.*?-->)*)<([a-zA-Z][a-zA-Z0-9-]*)/);if(n){let r=n[1],s=n[2],o=r.length+1+s.length,a=t.indexOf(">",o),i=t.slice(o,a===-1?void 0:a);return/[\s"']data-hk\s*=/.test(i)||/^\s*data-hk\s*=/.test(i)?t:t.slice(0,o)+` data-hk="${e}"`+t.slice(o)}return t}function m(t){if(!Ct()){let c=T(void 0);return S(c,()=>m(t))}if(t==null||t===!1||t===!0)return"";if(typeof t=="string"||typeof t=="number")return w(String(t));if(typeof t=="function"&&t._signal)return m(t());if(typeof t=="function"&&t._mapArray)try{return m(st(t))}catch{return typeof process<"u",""}if(typeof t=="function")try{return m(t())}catch{return typeof process<"u",""}if(Array.isArray(t))return t.map(m).join("");if(ct.has(t.tag))return"";if(xt.has(t.tag))try{return(t.children||[]).map(m).join("")}catch(c){let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return m(dt(t,u?null:c))}if(typeof t.tag=="function"){let c=ot(t.tag);try{return m(t.tag(ut(t)))}finally{at(c)}}let{tag:e,props:n,children:r}=t;lt(e);let s=pt(n||{}),o=`<${e}${s}>`;if(ht.has(e))return o;let a=ft(n),i=a!=null?String(a):r.map(m).join("");return`${o}${i}</${e}>`}function bn(t){let e=T(void 0);return{body:S(e,()=>m(t)),head:it(e.head)}}async function _n(t,e={}){let n=t.default||t,r=typeof t.loader=="function"?await t.loader(e):void 0,s=T(r),o=e.params||{};return{body:S(s,()=>m(rt(n,{...o,loaderData:r}))),head:it(s.head),loaderData:r}}var $t=12;async function Ee(t,e){e||(e=T(void 0));let n="";for(let s=0;s<$t;s++){n=S(e,()=>m(t));let o=[...e.resources.values()].filter(a=>a.status==="pending").map(a=>a.promise);if(o.length===0)break;await Promise.all(o)}let r={};for(let[s,o]of e.resources)o.status==="ready"&&(r[s]=o.value);return{body:n,head:it(e.head),loaderData:e.loaderData,resources:r,ctx:e}}async function J(t,e={},n={}){let r=t.default||t,s=typeof t.loader=="function"?await t.loader(e):void 0,o=T(s),a=e.params||{},{body:i,head:c,resources:u}=await Ee(rt(r,{...a,loaderData:s}),o),d={loaderData:s??null,resources:u,islandStores:St(o)};return Ae({body:i,head:c,payload:d,options:n})}function Ae({body:t,head:e,payload:n,options:r={}}){let s=r.lang||"en",o=`<script id="__what_data" type="application/json">${N(n)}<\/script>`,a=r.clientEntry?`<script type="module" src="${w(r.clientEntry)}"><\/script>`:"",c=(r.csrfToken?tt(r.csrfToken):"")+(r.head||""),u=r.bodyClass?` class="${w(r.bodyClass)}"`:"";return`<!DOCTYPE html><html lang="${w(s)}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">${e||""}${c}</head><body${u}>${t}${o}${a}</body></html>`}async function*x(t,e){if(e===void 0&&(e=T(void 0)),t==null||t===!1||t===!0)return;if(typeof t=="string"||typeof t=="number"){yield w(String(t));return}if(typeof t=="function"&&t._signal){let a=S(e,()=>t());yield*x(a,e);return}if(typeof t=="function"&&t._mapArray){let a=null;try{a=S(e,()=>st(t))}catch{typeof process<"u"}a&&(yield*x(a,e));return}if(typeof t=="function"){try{let a=S(e,()=>t());yield*x(a,e)}catch{typeof process<"u"}return}if(Array.isArray(t)){for(let a of t)yield*x(a,e);return}if(ct.has(t.tag))return;if(t.tag==="__errorBoundary"){let a;try{a=S(e,()=>(t.children||[]).map(m).join(""))}catch(i){if(i&&typeof i.then=="function")throw i;a=S(e,()=>m(dt(t,i)))}yield a;return}if(t.tag==="__suspense"){let a=null;for(let i=0;i<$t&&a===null;i++){let c=null;try{a=S(e,()=>(t.children||[]).map(m).join(""))}catch(u){if(u&&typeof u.then=="function")c=u;else throw u}if(a===null){let u=[...e.resources.values()].filter(d=>d.status==="pending").map(d=>d.promise);await Promise.all([c,...u].filter(Boolean))}}a===null&&(a=S(e,()=>m(t.props&&t.props.fallback))),yield a;return}if(typeof t.tag=="function"){let a=ot(t.tag);try{let i=S(e,()=>t.tag(ut(t))),c=i instanceof Promise?await i:i;yield*x(c,e)}catch(i){typeof process<"u",yield $?`<!-- SSR Error: ${w(i.message||"Component error")} -->`:"<!-- SSR Error -->"}finally{at(a)}return}let{tag:n,props:r,children:s}=t;lt(n);let o=pt(r||{});if(yield`<${n}${o}>`,!ht.has(n)){let a=ft(r);if(a!=null)yield String(a);else for(let i of s)yield*x(i,e);yield`</${n}>`}}function Rn(t){return{mode:"static",...t}}function En(t,e={}){let n=T(e),r=S(n,()=>m(rt(t.component,e))),s=t.islands||[];return Te({title:t.title||"",meta:t.meta||{},body:r,islands:s,scripts:t.mode==="static"?[]:t.scripts||[],styles:t.styles||[],mode:t.mode})}function Te({title:t,meta:e,body:n,islands:r,scripts:s,styles:o,mode:a}){let i=Object.entries(e).map(([l,p])=>`<meta name="${w(l)}" content="${w(p)}">`).join(`
|
|
1
|
+
import{AsyncLocalStorage as Je}from"node:async_hooks";import{__installServerContextStorage as We}from"what-core";import{h as ot,_isAriaAttr as ge,_beginComponentSSR as at,_endComponentSSR as st,_mapArrayToArray as it,getServerContext as Ct,runWithServerContext as S,beginHeadCollection as we,endHeadCollection as ct}from"what-core";var Dt=new RegExp("[<>&\\u2028\\u2029]","g"),Lt={60:"\\u003c",62:"\\u003e",38:"\\u0026",8232:"\\u2028",8233:"\\u2029"};function N(t){return JSON.stringify(t).replace(Dt,e=>Lt[e.charCodeAt(0)])}import{mount as Ye,hydrate as Xe,signal as Ke,batch as Ze,getServerContext as Mt}from"what-core";var Ft=new Map;function Ut(t){let e=t||Mt();return e&&e.islandStores instanceof Map?e.islandStores:null}function St(t){let e=typeof document<"u"?Ft:Ut(t),r={};for(let[n,s]of e||[])r[n]=s._getSnapshot();return r}import{signal as _,batch as Q}from"what-core";var L=Symbol.for("what.revalidationHandler"),bt=!(typeof process<"u");function X(t){globalThis[L]=t}function Bt(){return globalThis[L]??null}async function K(t,e){let r=globalThis[L];if(r&&r.revalidatePath)return r.revalidatePath(t,e);bt&&console.warn(`[what] revalidatePath('${t}') had no effect: no cache engine is bound. Create a what-isr engine and bind it in your adapter (setRevalidationHandler).`)}async function Z(t,e){let r=globalThis[L];if(r&&r.revalidateTag)return r.revalidateTag(t,e);bt&&console.warn(`[what] revalidateTag('${t}') had no effect: no cache engine is bound.`)}var q=new Map;function Vt(){if(typeof document<"u"){let t=document.querySelector('meta[name="what-csrf-token"]');if(t)return t.getAttribute("content");let e=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);if(e)return decodeURIComponent(e[1])}return null}function tt(){if(typeof crypto<"u"&&crypto.randomUUID)return crypto.randomUUID();if(typeof crypto<"u"&&crypto.getRandomValues){let t=new Uint8Array(16);return crypto.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}throw Object.assign(new Error("[what] No secure random source available for CSRF token generation"),{code:"ERR_NO_SECURE_RANDOM"})}function _t(t,e){if(!t||!e||t.length!==e.length)return!1;let r=0;for(let n=0;n<t.length;n++)r|=t.charCodeAt(n)^e.charCodeAt(n);return r===0}function et(t){return`<meta name="what-csrf-token" content="${String(t).replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}">`}var Jt=0,Wt=!1;function zt(){return!Wt&&typeof process<"u",`a_${typeof crypto<"u"&&crypto.getRandomValues?Array.from(crypto.getRandomValues(new Uint8Array(6)),e=>e.toString(16).padStart(2,"0")).join(""):`c${(++Jt).toString(36)}_${Date.now().toString(36)}`}`}function Gt(t,e={}){let r=e.id||zt(),{onError:n,onSuccess:s,revalidate:o}=e;typeof window>"u"&&q.set(r,{fn:t,options:e});async function a(...i){if(typeof window>"u")return t(...i);let c=e.timeout||3e4,u=new AbortController,d=setTimeout(()=>u.abort(),c);try{let f=Vt(),l={"Content-Type":"application/json","X-What-Action":r};f&&(l["X-CSRF-Token"]=f);let p=await fetch("/__what_action",{method:"POST",headers:l,credentials:"same-origin",signal:u.signal,body:JSON.stringify({args:i})});if(!p.ok){let y=await p.json().catch(()=>({message:"Action failed"}));throw Object.assign(new Error(y.message||"Action failed"),{code:"ERR_ACTION_FAILED"})}let h=await p.json();if(s&&s(h),o)for(let y of o)At(y);return h}catch(f){if(f.name==="AbortError"){let l=new Error(`Action "${r}" timed out after ${c}ms`);throw l.code="TIMEOUT",n&&n(l),l}throw n&&n(f),f}finally{clearTimeout(d)}}return a._actionId=r,a._isAction=!0,a}function Rt(t,e={}){let{onSuccess:r,onError:n,resetOnSuccess:s=!0}=e;return async o=>{let a,i;o instanceof Event?(o.preventDefault(),i=o.target,a=new FormData(i)):a=o;let c={},u=!1;for(let[d,f]of a.entries())typeof File<"u"&&f instanceof File&&(u=!0),c[d]?Array.isArray(c[d])?c[d].push(f):c[d]=[c[d],f]:c[d]=f;try{let d=u?await t(c,a):await t(c);return r&&r(d,i),s&&i&&i.reset(),d}catch(d){throw n&&n(d,i),d}}}function Et(t){let e=_(!1),r=_(null),n=_(null);async function s(...o){e.set(!0),r.set(null);try{let a=await t(...o);return n.set(a),a}catch(a){throw r.set(a),a}finally{e.set(!1)}}return{trigger:s,isPending:()=>e(),error:()=>r(),data:()=>n(),reset:()=>{r.set(null),n.set(null)}}}function Yt(t,e={}){let{resetOnSuccess:r=!0}=e,n={current:null},s=Et(Rt(t,{resetOnSuccess:r}));function o(a){a.preventDefault();let i=new FormData(a.target);return n.current=a.target,s.trigger(i)}return{...s,handleSubmit:o,formRef:n}}function Xt(t,e){let r=_(t),n=_([]),s=_(t);function o(u){let d=e(r.peek(),u);Q(()=>{n.set([...n.peek(),u]),r.set(d)})}function a(u,d){Q(()=>{if(n.set(n.peek().filter(f=>f!==u)),d!==void 0){s.set(d);let f=d;for(let l of n.peek())f=e(f,l);r.set(f)}})}function i(u,d){Q(()=>{let f=n.peek().filter(h=>h!==u);n.set(f);let l=d!==void 0?d:s.peek();s.set(l);let p=l;for(let h of f)p=e(p,h);r.set(p)})}async function c(u,d){o(u);try{let f=await d();return a(u,f),f}catch(f){throw i(u),f}}return{value:()=>r(),isPending:()=>n().length>0,addOptimistic:o,resolve:a,rollback:i,withOptimistic:c,set:u=>{r.set(u),s.set(u)}}}var I=new Map;function Kt(t,e){return I.has(t)||I.set(t,new Set),I.get(t).add(e),()=>{I.get(t)?.delete(e)}}function At(t){let e=I.get(t);if(e)for(let r of e)try{r()}catch(n){console.error("[what] Revalidation error:",n)}}function M(t,e,r,n={}){let{csrfToken:s,skipCsrf:o=!1}=n;if(!o){if(!s)return Promise.resolve({status:500,body:{message:"[what] CSRF token not configured. Pass { csrfToken: sessionToken } to handleActionRequest, or { skipCsrf: true } to explicitly opt out."}});let i=t?.headers?.["x-csrf-token"]||t?.headers?.["X-CSRF-Token"];if(!_t(i,s))return Promise.resolve({status:403,body:{message:"Invalid CSRF token"}})}let a=q.get(e);return a?Array.isArray(r)?a.fn(...r).then(async i=>{let c=a.options||{};if(Array.isArray(c.revalidate))for(let u of c.revalidate)await K(u);if(Array.isArray(c.revalidateTags))for(let u of c.revalidateTags)await Z(u);return{status:200,body:i}}).catch(i=>(console.error(`[what] Action "${e}" error:`,i),{status:500,body:{message:"Action failed"}})):Promise.resolve({status:400,body:{message:"Invalid action arguments"}}):Promise.resolve({status:404,body:{message:"Action not found"}})}function Zt(){return[...q.keys()]}function Qt(t,e={}){let{onSuccess:r,onError:n,onSettled:s}=e,o={isPending:_(!1),error:_(null),data:_(null)};async function a(...i){o.isPending.set(!0),o.error.set(null);try{let c=await t(...i);return o.data.set(c),r&&r(c,...i),c}catch(c){throw o.error.set(c),n&&n(c,...i),c}finally{o.isPending.set(!1),s&&s(o.data.peek(),o.error.peek(),...i)}}return{mutate:a,isPending:()=>o.isPending(),error:()=>o.error(),data:()=>o.data(),reset:()=>{o.error.set(null),o.data.set(null)}}}import{h as F}from"what-core";var Tt="/__what_action";function qt(t){if(typeof t=="string")return t;if(typeof t=="function"){let e=t._actionId;if(e)return e;throw Object.assign(new Error("[what] <Form action={fn}>: that function is not a server action. Wrap it with action() from what-server, or pass the action id as a string."),{code:"ERR_FORM_ACTION_NOT_REGISTERED"})}throw Object.assign(new Error("[what] <Form> requires an `action` prop: a server action or its id."),{code:"ERR_FORM_ACTION_MISSING"})}function te(){if(typeof document>"u")return null;let t=document.querySelector('meta[name="what-csrf-token"]');if(t)return t.getAttribute("content");let e=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);return e?decodeURIComponent(e[1]):null}function ee({action:t,csrfToken:e,redirect:r,method:n="post",enhance:s=!0,children:o,...a}){let i=qt(t),c=e!==void 0?e:te();c==null&&typeof process<"u";let u=[F("input",{type:"hidden",name:"_action",value:i}),F("input",{type:"hidden",name:"what-csrf-token",value:c||""})];r&&u.push(F("input",{type:"hidden",name:"_redirect",value:r}));let d={...a,method:n,action:a.action||Tt,"data-action":i};s&&(d["data-enhance"]="");let f=o==null?[]:Array.isArray(o)?o:[o];return F("form",d,...u,...f)}var re="/__what_action",j=1024*1024;function ne(t){if(!t)return{};if(typeof t.forEach=="function"&&typeof t.get=="function"){let r={};return t.forEach((n,s)=>{r[s.toLowerCase()]=n}),r}let e={};for(let r in t)e[r.toLowerCase()]=t[r];return e}function U(t,e){return{status:t,headers:{"content-type":"application/json"},body:JSON.stringify(e)}}function rt(t,e){return{status:t,headers:{"content-type":"text/html; charset=utf-8"},body:`<!DOCTYPE html><html><body><h1>${t}</h1><p>${String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}</p></body></html>`}}function kt(t){if(typeof t!="string"||!t.startsWith("/")||/^[/\\]{2}/.test(t)||t.includes("\\"))return null;try{let e=new URL(t,"http://localhost");return e.origin!=="http://localhost"?null:e.pathname+e.search}catch{return null}}function oe(t,e){let r=kt(t&&t._redirect);if(r)return r;let n=e.referer||e.referrer;if(n)try{let s=new URL(n,"http://localhost"),o=kt(s.pathname+s.search);if(o)return o}catch{}return"/"}var ae=new Set(["_action","data-action","_csrf","what-csrf-token","_redirect"]);function H(t={}){let{getCsrfToken:e,skipCsrf:r=!1}=t;return async function(s){if((s.method||"POST").toUpperCase()!=="POST")return U(405,{message:"Method Not Allowed"});let a=ne(s.headers),i=a["x-what-action"],c=a["content-type"]||"",u=!i&&c.includes("application/x-www-form-urlencoded"),d=r?void 0:e?await e(s):void 0;if(u){let h=s.body||{},y=h._action||h["data-action"]||s.query&&s.query.action;if(!y)return rt(400,'Missing action name (add a hidden "_action" field or ?action= query param)');let b={...a},O=h._csrf??h["what-csrf-token"];if(O&&!b["x-csrf-token"]&&(b["x-csrf-token"]=String(O)),!r&&e&&!d)return rt(403,"Missing CSRF token");let C={};for(let[v,z]of Object.entries(h))ae.has(v)||(C[v]=z);let k=await M({headers:b},y,[C],{csrfToken:d,skipCsrf:r});return k.status===200?{status:303,headers:{location:oe(h,a)},body:""}:rt(k.status,k.body&&k.body.message||"Action failed")}if(!i)return U(400,{message:"Missing X-What-Action header"});if(!r&&e&&!d)return U(403,{message:"Missing CSRF token"});let l=(s.body||{}).args,p=await M({headers:a},i,l,{csrfToken:d,skipCsrf:r});return U(p.status,p.body)}}function se(t={}){let e=t.basePath||re,r=H(t);return async function(s,o,a){let[i,c]=(s.url||"").split("?");if(i!==e||(s.method||"").toUpperCase()!=="POST")return a?a():void 0;let u;try{let l=await ie(s);u=B(l,s.headers["content-type"]||"")}catch(l){o.writeHead(l.code==="BODY_TOO_LARGE"?413:400,{"content-type":"application/json"}),o.end(JSON.stringify({message:l.code==="BODY_TOO_LARGE"?"Payload too large":"Invalid request body"}));return}let d=Object.fromEntries(new URLSearchParams(c||"")),f=await r({method:s.method,headers:s.headers,body:u,query:d});o.writeHead(f.status,f.headers),o.end(f.body)}}function B(t,e){if((e||"").includes("application/x-www-form-urlencoded")){let r={};for(let[n,s]of new URLSearchParams(String(t)))r[n]===void 0?r[n]=s:Array.isArray(r[n])?r[n].push(s):r[n]=[r[n],s];return r}return t==null||t===""?{}:JSON.parse(String(t))}async function V(t,e=j){let r=Number(t.headers.get("content-length"));if(Number.isFinite(r)&&r>e)return{tooLarge:!0};let n=t.body;if(!n||typeof n.getReader!="function"){let i=await t.text();return Buffer.byteLength(i,"utf8")>e?{tooLarge:!0}:{raw:i}}let s=n.getReader(),o=[],a=0;for(;;){let{done:i,value:c}=await s.read();if(i)break;if(c){if(a+=c.byteLength,a>e){try{await s.cancel()}catch{}return{tooLarge:!0}}o.push(c)}}return{raw:Buffer.concat(o.map(i=>Buffer.from(i))).toString("utf8")}}function ie(t){return new Promise((e,r)=>{let n=0,s=[];t.on("data",o=>{if(n+=o.length,n>j){let a=new Error("Body too large");a.code="BODY_TOO_LARGE",r(a),t.destroy?.();return}s.push(o)}),t.on("end",()=>{if(s.length===0)return e("");e(Buffer.concat(s).toString("utf8"))}),t.on("error",r)})}function ce(t={}){let e=H(t);return async function(r){let n={};try{let a=await V(r);if(a.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});n=B(a.raw,r.headers.get("content-type")||"")}catch{n={}}let s={};try{s=Object.fromEntries(new URL(r.url,"http://localhost").searchParams)}catch{}let o=await e({method:r.method,headers:r.headers,body:n,query:s});return new Response(o.body,{status:o.status,headers:o.headers})}}import{matchRoute as ue,parseQuery as de}from"what-router/match";var fe="/__what_action",le="/__what_revalidate",nt="what-csrf";function D(t){let e={};return t&&typeof t.forEach=="function"&&t.forEach((r,n)=>{e[n.toLowerCase()]=r}),e}function Ot(t,e){if(!t)return null;let r=String(t).match(new RegExp(`(?:^|;\\s*)${e}=([^;]+)`));return r?decodeURIComponent(r[1]):null}async function pe(t){try{let e=await V(t);return e.tooLarge?{tooLarge:!0}:B(e.raw,t.headers.get("content-type")||"")}catch{return{}}}async function he(t){let e;try{e=await V(t)}catch{return{json:{}}}if(e.tooLarge)return{tooLarge:!0};try{return{json:JSON.parse(e.raw??"")}}catch{return{json:{}}}}function ye(t){return async function(r){let{route:n,params:s,query:o,request:a,csrfToken:i}=r,c={default:n.component,loader:n.loader},u=i?{params:s,query:o,request:a,csrfToken:i}:{params:s,query:o,request:a},d=i?{...t,csrfToken:i}:t;return{html:await J(c,u,d),status:200,tags:r.config&&r.config.tags||[],path:r.path}}}function A(t={}){let{routes:e=[],cache:r,render:n,revalidateWebhook:s,document:o={},notFound:a,basePath:i="",csrf:c=!0}=t,u=c!==!1&&!t.actionHandler,d=t.actionHandler||H(u?{getCsrfToken:l=>Ot(l.headers&&l.headers.cookie,nt)}:{skipCsrf:!0}),f=n||ye(o);return r&&(r.revalidatePath||r.revalidateTag)&&X({revalidatePath:r.revalidatePath,revalidateTag:r.revalidateTag}),async function(p){let h=new URL(p.url,"http://localhost"),y=h.pathname;if(i&&y.startsWith(i)&&(y=y.slice(i.length)||"/"),p.method==="POST"&&y===fe){let g=await pe(p);if(g&&g.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let E=await d({method:"POST",headers:D(p.headers),body:g,query:Object.fromEntries(h.searchParams)});return new Response(E.body,{status:E.status,headers:E.headers})}let b=null,O=null;if(u&&(b=Ot(D(p.headers).cookie,nt),!b)){b=tt();let E=D(p.headers)["x-forwarded-proto"]==="https"||h.protocol==="https:"||!0;O=`${nt}=${encodeURIComponent(b)}; Path=/; SameSite=Lax`+(E?"; Secure":"")}let C=g=>(O&&(g["set-cookie"]=O),g);if(p.method==="POST"&&y===le&&s){let g=await he(p);if(g.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let E=await s({headers:D(p.headers),body:g.json});return new Response(JSON.stringify(E.body),{status:E.status,headers:{"content-type":"application/json"}})}let k=ue(y,e);if(!k){let g=a?a():"<!DOCTYPE html><html><body><h1>404 \u2014 Not Found</h1></body></html>";return new Response(g,{status:404,headers:C({"content-type":"text/html; charset=utf-8"})})}let{route:v,params:z}=k,G=v.page||{mode:v.mode||"client"},P={path:y,query:de(h.search),config:G,route:v,params:z,request:p};if(r&&G.mode!=="server"){P.varyHeaders=D(p.headers);let g=await r.handle(P,()=>f(P));return new Response(g.html,{status:g.status||200,headers:C({"content-type":"text/html; charset=utf-8",...g.headers||{}})})}b&&(P.csrfToken=b);let Y=await f(P),wt=C({"content-type":"text/html; charset=utf-8",...Y.headers||{}});return G.mode==="server"&&(wt["Cache-Control"]="private, no-store"),new Response(Y.html,{status:Y.status||200,headers:wt})}}function me(t={}){let e=A(t);return{async fetch(r,n,s){return n&&(r.__env=n),s&&(r.__ctx=s),e(r)}}}function T(t){return{head:we(),loaderData:t,resources:new Map,islandStores:new Map,resourceCounter:0,boundaryCounter:0,suspended:[]}}var vt=0;function Se(){vt=0}function be(){return"h"+vt++}function _e(t){if(!Ct()){let e=T(void 0);return S(e,()=>_e(t))}return Se(),R(t)}var xt=new Set(["__errorBoundary","__suspense"]),ut=new Set(["__portal"]);function dt(t){let e=t.children;return!e||e.length===0?{...t.props}:{...t.props,children:e}}function ft(t,e){let r=t.props&&t.props.fallback;if(typeof r!="function")return r;let n=t.props&&t.props.reset||(()=>{});try{return r({error:e,reset:n})}catch(s){return $&&console.warn(`[what-server] <ErrorBoundary> fallback threw during SSR: ${s.message}`),null}}function R(t){if(t==null||t===!1||t===!0)return"";if(typeof t=="string"||typeof t=="number")return w(String(t));if(typeof t=="function"&&t._signal)return`<!--$-->${R(t())}<!--/$-->`;if(typeof t=="function"&&t._mapArray)try{return`<!--$-->${R(it(t))}<!--/$-->`}catch{return typeof process<"u","<!--$--><!--/$-->"}if(typeof t=="function")try{return`<!--$-->${R(t())}<!--/$-->`}catch{return typeof process<"u","<!--$--><!--/$-->"}if(Array.isArray(t))return`<!--[]-->${t.map(R).join("")}<!--/[]-->`;if(ut.has(t.tag))return"";if(xt.has(t.tag))try{return(t.children||[]).map(R).join("")}catch(c){let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return R(ft(t,u?null:c))}if(typeof t.tag=="function"){let c=be(),u=at(t.tag),d;try{d=R(t.tag(dt(t)))}finally{st(u)}return Re(d,c)}let{tag:e,props:r,children:n}=t;pt(e);let s=ht(r||{}),o=`<${e}${s}>`;if(yt.has(e))return o;let a=lt(r),i=a!=null?String(a):n.map(R).join("");return`${o}${i}</${e}>`}function Re(t,e){let r=t.match(/^((?:<!--.*?-->)*)<([a-zA-Z][a-zA-Z0-9-]*)/);if(r){let n=r[1],s=r[2],o=n.length+1+s.length,a=t.indexOf(">",o),i=t.slice(o,a===-1?void 0:a);return/[\s"']data-hk\s*=/.test(i)||/^\s*data-hk\s*=/.test(i)?t:t.slice(0,o)+` data-hk="${e}"`+t.slice(o)}return t}function m(t){if(!Ct()){let c=T(void 0);return S(c,()=>m(t))}if(t==null||t===!1||t===!0)return"";if(typeof t=="string"||typeof t=="number")return w(String(t));if(typeof t=="function"&&t._signal)return m(t());if(typeof t=="function"&&t._mapArray)try{return m(it(t))}catch{return typeof process<"u",""}if(typeof t=="function")try{return m(t())}catch{return typeof process<"u",""}if(Array.isArray(t))return t.map(m).join("");if(ut.has(t.tag))return"";if(xt.has(t.tag))try{return(t.children||[]).map(m).join("")}catch(c){let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return m(ft(t,u?null:c))}if(typeof t.tag=="function"){let c=at(t.tag);try{return m(t.tag(dt(t)))}finally{st(c)}}let{tag:e,props:r,children:n}=t;pt(e);let s=ht(r||{}),o=`<${e}${s}>`;if(yt.has(e))return o;let a=lt(r),i=a!=null?String(a):n.map(m).join("");return`${o}${i}</${e}>`}function Sr(t){let e=T(void 0);return{body:S(e,()=>m(t)),head:ct(e.head)}}async function br(t,e={}){let r=t.default||t,n=typeof t.loader=="function"?await t.loader(e):void 0,s=T(n),o=e.params||{};return{body:S(s,()=>m(ot(r,{...o,loaderData:n}))),head:ct(s.head),loaderData:n}}var $t=12;async function Ee(t,e){e||(e=T(void 0));let r="",n=e.resourceCounter;for(let o=0;o<$t;o++){e.resourceCounter=n,r=S(e,()=>m(t));let a=[...e.resources.values()].filter(i=>i.status==="pending").map(i=>i.promise);if(a.length===0)break;await Promise.all(a)}let s={};for(let[o,a]of e.resources)a.status==="ready"&&(s[o]=a.value);return{body:r,head:ct(e.head),loaderData:e.loaderData,resources:s,ctx:e}}async function J(t,e={},r={}){let n=t.default||t,s=typeof t.loader=="function"?await t.loader(e):void 0,o=T(s),a=e.params||{},{body:i,head:c,resources:u}=await Ee(ot(n,{...a,loaderData:s}),o),d={loaderData:s??null,resources:u,islandStores:St(o)};return Ae({body:i,head:c,payload:d,options:r})}function Ae({body:t,head:e,payload:r,options:n={}}){let s=n.lang||"en",o=`<script id="__what_data" type="application/json">${N(r)}<\/script>`,a=n.clientEntry?`<script type="module" src="${w(n.clientEntry)}"><\/script>`:"",c=(n.csrfToken?et(n.csrfToken):"")+(n.head||""),u=n.bodyClass?` class="${w(n.bodyClass)}"`:"";return`<!DOCTYPE html><html lang="${w(s)}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">${e||""}${c}</head><body${u}>${t}${o}${a}</body></html>`}async function*x(t,e){if(e===void 0&&(e=T(void 0)),t==null||t===!1||t===!0)return;if(typeof t=="string"||typeof t=="number"){yield w(String(t));return}if(typeof t=="function"&&t._signal){let a=S(e,()=>t());yield*x(a,e);return}if(typeof t=="function"&&t._mapArray){let a=null;try{a=S(e,()=>it(t))}catch{typeof process<"u"}a&&(yield*x(a,e));return}if(typeof t=="function"){try{let a=S(e,()=>t());yield*x(a,e)}catch{typeof process<"u"}return}if(Array.isArray(t)){for(let a of t)yield*x(a,e);return}if(ut.has(t.tag))return;if(t.tag==="__errorBoundary"){let a;try{a=S(e,()=>(t.children||[]).map(m).join(""))}catch(i){if(i&&typeof i.then=="function")throw i;a=S(e,()=>m(ft(t,i)))}yield a;return}if(t.tag==="__suspense"){let a=null,i=e.resourceCounter;for(let c=0;c<$t&&a===null;c++){e.resourceCounter=i;let u=null;try{a=S(e,()=>(t.children||[]).map(m).join(""))}catch(d){if(d&&typeof d.then=="function")u=d;else throw d}if(a===null){let d=[...e.resources.values()].filter(f=>f.status==="pending").map(f=>f.promise);await Promise.all([u,...d].filter(Boolean))}}a===null&&(a=S(e,()=>m(t.props&&t.props.fallback))),yield a;return}if(typeof t.tag=="function"){let a=at(t.tag);try{let i=S(e,()=>t.tag(dt(t))),c=i instanceof Promise?await i:i;yield*x(c,e)}catch(i){typeof process<"u",yield $?`<!-- SSR Error: ${w(i.message||"Component error")} -->`:"<!-- SSR Error -->"}finally{st(a)}return}let{tag:r,props:n,children:s}=t;pt(r);let o=ht(n||{});if(yield`<${r}${o}>`,!yt.has(r)){let a=lt(n);if(a!=null)yield String(a);else for(let i of s)yield*x(i,e);yield`</${r}>`}}function _r(t){return{mode:"static",...t}}function Rr(t,e={}){let r=T(e),n=S(r,()=>m(ot(t.component,e))),s=t.islands||[];return Te({title:t.title||"",meta:t.meta||{},body:n,islands:s,scripts:t.mode==="static"?[]:t.scripts||[],styles:t.styles||[],mode:t.mode})}function Te({title:t,meta:e,body:r,islands:n,scripts:s,styles:o,mode:a}){let i=Object.entries(e).map(([l,p])=>`<meta name="${w(l)}" content="${w(p)}">`).join(`
|
|
2
2
|
`),c=o.map(l=>`<link rel="stylesheet" href="${w(l)}">`).join(`
|
|
3
|
-
`),u=
|
|
3
|
+
`),u=n.length>0?`
|
|
4
4
|
<script type="module">
|
|
5
5
|
import { hydrateIslands } from '/@what/islands.js';
|
|
6
6
|
hydrateIslands();
|
|
@@ -16,9 +16,9 @@ import{AsyncLocalStorage as Je}from"node:async_hooks";import{__installServerCont
|
|
|
16
16
|
${c}
|
|
17
17
|
</head>
|
|
18
18
|
<body>
|
|
19
|
-
<div id="app">${
|
|
19
|
+
<div id="app">${r}</div>
|
|
20
20
|
${u}
|
|
21
21
|
${d}
|
|
22
22
|
${f}
|
|
23
23
|
</body>
|
|
24
|
-
</html>`}function
|
|
24
|
+
</html>`}function Er(t){return t._server=!0,t}var $=!(typeof process<"u");function lt(t){return t?t.dangerouslySetInnerHTML?t.dangerouslySetInnerHTML.__html??null:t.innerHTML&&typeof t.innerHTML=="object"&&"__html"in t.innerHTML?t.innerHTML.__html??null:(t.innerHTML!=null&&typeof t.innerHTML=="string"&&$&&console.warn("[what-server] innerHTML received a raw string. This is a security risk (XSS). Use innerHTML={{ __html: trustedString }} or dangerouslySetInnerHTML={{ __html: trustedString }} instead."),null):null}var ke=/^[a-zA-Z_:][a-zA-Z0-9:._-]*$/,Oe=/^[a-zA-Z_][a-zA-Z0-9._:-]*$/;function pt(t){if(typeof t!="string"||!Oe.test(t))throw Object.assign(new Error(`[what-server] Invalid tag name in SSR: ${JSON.stringify(t)}`),{code:"ERR_INVALID_SSR_TAG"})}function ht(t){let e="";for(let[r,n]of Object.entries(t)){if(r==="key"||r==="ref"||r==="children"||r==="dangerouslySetInnerHTML"||r==="innerHTML")continue;let s=r.toLowerCase();if(s.startsWith("on")&&r.length>2)continue;let o=n;if(typeof o=="function"){try{o=o()}catch(a){$&&console.warn(`[what-server] Skipping attribute ${JSON.stringify(r)}: its value threw during SSR: ${a.message}`);continue}if(typeof o=="function")continue}if(o===!1&&ge(r)){e+=` ${r}="false"`;continue}if(!(o===!1||o==null)){if(!ke.test(r)){$&&console.warn(`[what-server] Skipping invalid attribute name in SSR: ${JSON.stringify(r)}`);continue}if(xe.has(s)){$&&console.warn(`[what-server] Skipping unsafe attribute in SSR: ${JSON.stringify(r)}`);continue}if(r==="className"||r==="class")e+=` class="${w(String(o))}"`;else if(r==="style"&&typeof o=="object"){let a=Object.entries(o).map(([i,c])=>`${$e(i)}:${c}`).join(";");e+=` style="${w(a)}"`}else if(o===!0)r.startsWith("aria-")||r==="role"?e+=` ${r}="true"`:e+=` ${r}`;else{if(Ce(r,o))continue;e+=` ${r}="${w(String(o))}"`}}}return e}function Ce(t,e){let r=t.toLowerCase();if(!ve.has(r))return!1;let n=String(e).trim().replace(/[\u0000-\u001f\u007f\s]+/g,"").toLowerCase();return n.startsWith("javascript:")||n.startsWith("vbscript:")||n.startsWith("data:")}var ve=new Set(["href","src","action","formaction","data","ping","xlink:href"]),xe=new Set(["srcdoc"]);function w(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function $e(t){return t.startsWith("--")?t:t.replace(/([A-Z])/g,"-$1").toLowerCase()}var yt=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);import Pe from"node:http";var mt=Symbol("what.bodyTooLarge"),Pt=()=>new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});async function Nt(t){let r=`http://${t.headers.host||"localhost"}${t.url}`,n=new Headers;for(let[o,a]of Object.entries(t.headers))a!=null&&n.set(o,Array.isArray(a)?a.join(", "):String(a));let s;if(t.method!=="GET"&&t.method!=="HEAD"){let o=Number(t.headers["content-length"]),a=Number.isFinite(o)&&o>j,i=[],c=0;for await(let u of t)if(!a){if(c+=u.length,c>j){a=!0,i.length=0;continue}i.push(u)}if(a)return mt;i.length&&(s=Buffer.concat(i))}return new Request(r,{method:t.method,headers:n,body:s})}async function W(t,e){t.statusCode=e.status,e.headers.forEach((n,s)=>t.setHeader(s,n));let r=await e.text();t.end(r)}function It(t){return async function(r,n){try{let s=await Nt(r);if(s===mt)return await W(n,Pt());let o=await t(s);await W(n,o)}catch(s){n.headersSent||n.writeHead(500,{"content-type":"text/html; charset=utf-8"}),n.end("<!DOCTYPE html><html><body><h1>500 \u2014 Server Error</h1></body></html>"),console.error("[what-server] request error:",s)}}}function Ne(t={}){let e=A(t);return async function(n,s,o){let a=await Nt(n);if(a===mt)return await W(s,Pt());let i=await e(a);if(i.status===404&&typeof o=="function")return o();await W(s,i)}}function Ie(t={}){let e=A(t),r=Pe.createServer(It(e)),{scheduler:n}=t;if(n){n.start();let s=()=>{try{n.stop()}catch{}r.close()};process.once("SIGTERM",s),process.once("SIGINT",s)}return r}import{mkdir as je,writeFile as jt}from"node:fs/promises";import{join as gt,resolve as Ht,sep as He}from"node:path";import{matchRoute as De}from"what-router/match";function Le(t){return t.includes(":")||t.includes("*")||t.includes("[")}function Me(t,e){return t.replace(/\[\.\.\.(\w+)\]/g,(r,n)=>e[n]??"").replace(/\[(\w+)\]/g,(r,n)=>e[n]??"").replace(/[:*](\w+)/g,(r,n)=>e[n]??"")}function Fe(t,e){let r=Ht(t),n=Ht(gt(t,e==="/"?"":e));if(n!==r&&!n.startsWith(r+He))throw Object.assign(new Error(`[what-server] Refusing to write outside outDir: ${e}`),{code:"ERR_STATIC_WRITE_ESCAPE"});return n}async function Ue({routes:t=[],outDir:e,render:r,documentOptions:n={}}={}){let s=[];for(let o of t){let a=o.page&&o.page.mode||o.mode;if(a!=="static"&&a!=="hybrid")continue;let i={default:o.component,loader:o.loader},c=[o.path];if(Le(o.path)){if(typeof o.getStaticPaths!="function")continue;c=((await o.getStaticPaths()).paths||[]).map(d=>Me(o.path,d.params||{}))}for(let u of c){let d=Fe(e,u),f=De(u,[o]),p={params:f?f.params:{},query:{}},h=r?await r(i,p):await J(i,p,n);if(await je(d,{recursive:!0}),await jt(gt(d,"index.html"),h),typeof o.loader=="function"){let y=await o.loader(p);await jt(gt(d,"__what_data.json"),N({loaderData:y}))}s.push(u)}}return{pages:s}}function Be(t={}){return A(t)}async function Ve({outDir:t=".vercel/output",functionName:e="render",runtime:r="nodejs22.x",files:n=null,handler:s="index.mjs",staticDir:o=null}={}){let{mkdir:a,writeFile:i,cp:c}=await import("node:fs/promises"),{join:u,dirname:d}=await import("node:path");await a(t,{recursive:!0});let f={version:3,routes:[{handle:"filesystem"},{src:"/.*",dest:`/${e}`}]};await i(u(t,"config.json"),JSON.stringify(f,null,2)),o&&await c(o,u(t,"static"),{recursive:!0});let l=null;if(n&&typeof n=="object"){l=u(t,"functions",`${e}.func`),await a(l,{recursive:!0});let p={runtime:r,handler:s,launcherType:"Nodejs",shouldAddHelpers:!1,supportsResponseStreaming:!0};await i(u(l,".vc-config.json"),JSON.stringify(p,null,2));for(let[h,y]of Object.entries(n)){let b=u(l,h);await a(d(b),{recursive:!0}),await i(b,y)}s in n||console.warn(`[what-server] buildVercelOutput: files does not include the handler entry "${s}" \u2014 the deploy will 500 until your build emits it.`)}return{config:f,outDir:t,functionDir:l}}We(new Je);export{Tt as ACTION_ENDPOINT,ee as Form,Gt as action,Ve as buildVercelOutput,H as createActionHandler,me as createCloudflareHandler,A as createRequestHandler,Ie as createServer,Be as createVercelHandler,et as csrfMetaTag,_r as definePage,Ue as exportStatic,ce as fetchActionHandler,Rt as formAction,tt as generateCsrfToken,Rr as generateStaticPage,Zt as getRegisteredActions,Bt as getRevalidationHandler,M as handleActionRequest,At as invalidatePath,se as nodeActionMiddleware,Kt as onRevalidate,J as renderDocument,br as renderPage,_e as renderToHydratableString,x as renderToStream,m as renderToString,Ee as renderToStringAsync,Sr as renderToStringWithHead,K as revalidatePath,Z as revalidateTag,N as serializeState,Er as server,X as setRevalidationHandler,It as toNodeListener,Et as useAction,Yt as useFormAction,Qt as useMutation,Xt as useOptimistic,_t as validateCsrfToken,Ne as whatMiddleware};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "what-server",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.4",
|
|
4
4
|
"description": "What Framework - SSR, islands architecture, static generation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"author": "ZVN DEV (https://zvndev.com)",
|
|
52
52
|
"license": "MIT",
|
|
53
53
|
"peerDependencies": {
|
|
54
|
-
"what-core": "^0.13.
|
|
55
|
-
"what-router": "^0.13.
|
|
54
|
+
"what-core": "^0.13.4",
|
|
55
|
+
"what-router": "^0.13.4"
|
|
56
56
|
},
|
|
57
57
|
"peerDependenciesMeta": {
|
|
58
58
|
"what-router": {
|
package/src/adapter/core.js
CHANGED
|
@@ -229,7 +229,16 @@ export function createRequestHandler(options = {}) {
|
|
|
229
229
|
// safe to embed the CSRF token as a <meta> tag for forms/fetch clients.
|
|
230
230
|
if (csrfToken) routeMatch.csrfToken = csrfToken;
|
|
231
231
|
const out = await renderRoute(routeMatch);
|
|
232
|
-
|
|
232
|
+
// `out.headers` is honoured here exactly as it is on the cache path above.
|
|
233
|
+
// It used to be dropped on this branch only, so a custom `render` could set
|
|
234
|
+
// response headers for a cached route and not for an uncached one — which
|
|
235
|
+
// meant a render returning a 302 produced a redirect with no Location, an
|
|
236
|
+
// empty page with nothing to say why. Spread before the CSRF cookie so a
|
|
237
|
+
// render cannot drop it.
|
|
238
|
+
const headers = withCsrfCookie({
|
|
239
|
+
'content-type': 'text/html; charset=utf-8',
|
|
240
|
+
...(out.headers || {}),
|
|
241
|
+
});
|
|
233
242
|
if (config.mode === 'server') headers['Cache-Control'] = 'private, no-store';
|
|
234
243
|
return new Response(out.html, { status: out.status || 200, headers });
|
|
235
244
|
};
|
package/src/index.js
CHANGED
|
@@ -406,7 +406,15 @@ const MAX_RESOLVE_PASSES = 12;
|
|
|
406
406
|
export async function renderToStringAsync(vnode, ctx) {
|
|
407
407
|
if (!ctx) ctx = createRenderContext(undefined);
|
|
408
408
|
let body = '';
|
|
409
|
+
// Every pass re-renders the same tree, so every pass must hand out the same
|
|
410
|
+
// resource keys. createResource names a keyless resource `__r${counter++}`
|
|
411
|
+
// off the render context; without restoring the counter, pass 1 asks for
|
|
412
|
+
// `__r1` where pass 0 stored `__r0`, finds nothing cached, and starts the
|
|
413
|
+
// fetch again. The loop then burns all twelve passes, pays for twelve
|
|
414
|
+
// sequential fetches, and returns the Suspense fallback as final HTML.
|
|
415
|
+
const counterAtStart = ctx.resourceCounter;
|
|
409
416
|
for (let pass = 0; pass < MAX_RESOLVE_PASSES; pass++) {
|
|
417
|
+
ctx.resourceCounter = counterAtStart;
|
|
410
418
|
body = runWithServerContext(ctx, () => renderToString(vnode));
|
|
411
419
|
const pending = [...ctx.resources.values()]
|
|
412
420
|
.filter((r) => r.status === 'pending')
|
|
@@ -546,7 +554,13 @@ export async function* renderToStream(vnode, ctx) {
|
|
|
546
554
|
// enhancement.) The synchronous render runs inside the threaded ctx.
|
|
547
555
|
if (vnode.tag === '__suspense') {
|
|
548
556
|
let html = null;
|
|
557
|
+
// Restored, not zeroed: the counter is context-wide and earlier siblings
|
|
558
|
+
// have already taken keys from it. Resetting to zero would re-issue those
|
|
559
|
+
// keys inside this boundary and render a sibling's data here. See the note
|
|
560
|
+
// in renderToStringAsync for what the missing restore cost.
|
|
561
|
+
const counterAtStart = ctx.resourceCounter;
|
|
549
562
|
for (let attempt = 0; attempt < MAX_RESOLVE_PASSES && html === null; attempt++) {
|
|
563
|
+
ctx.resourceCounter = counterAtStart;
|
|
550
564
|
let suspended = null;
|
|
551
565
|
try {
|
|
552
566
|
html = runWithServerContext(ctx, () => (vnode.children || []).map(renderToString).join(''));
|