@lengkapp/edge 0.0.29 → 0.0.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @lengkapp/edge v0.0.29
2
+ * @lengkapp/edge v0.0.30
3
3
  * MIT License
4
4
  *
5
5
  * LengkApp Edge License
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @lengkapp/edge v0.0.29
2
+ * @lengkapp/edge v0.0.30
3
3
  * MIT License
4
4
  *
5
5
  * LengkApp Edge License
@@ -51,17 +51,29 @@ export function jsx(
51
51
  ...children: any[]
52
52
  ): JSXNode;
53
53
 
54
- export function renderToString(node: any): string;
54
+ /**
55
+ * Renders a JSX tree to an HTML string. Async because components may be
56
+ * `async`. Accepts `null`/boolean children, Promises, and arrays.
57
+ *
58
+ * The optional `ctx` is normally supplied by `Context.html`/`Context.page`;
59
+ * user code never needs to pass it.
60
+ */
61
+ export function renderToString(node: any, ctx?: Context): Promise<string>;
55
62
 
56
63
  /* ------------------------------------------------------------------ *
57
- * Ambient context (sync-scoped) *
58
- * ------------------------------------------------------------------ *
59
- * Returns the Context of the request currently being rendered. *
60
- * Valid ONLY during the synchronous render pass initiated by *
61
- * `ctx.html()` / `ctx.page()`. Throws if called outside of a *
62
- * render (e.g. from top-level module code, a scheduled handler, *
63
- * or async code that outlives the render). *
64
+ * Ambient context *
64
65
  * ------------------------------------------------------------------ */
66
+
67
+ /**
68
+ * Returns the Context of the request whose render is currently executing.
69
+ *
70
+ * MUST be called synchronously at the top of a component — before any
71
+ * `await`. After an `await`, use the captured local reference; the
72
+ * ambient slot is no longer guaranteed to belong to your request.
73
+ *
74
+ * Throws if called outside an active render (module top-level, scheduled
75
+ * handler, `waitUntil` callback, or after an `await`).
76
+ */
65
77
  export function useCtx(): Context;
66
78
 
67
79
  /* ------------------------------------------------------------------ *
@@ -123,16 +135,21 @@ export class Context {
123
135
 
124
136
  text(data: string, status?: number, headers?: Record<string, string>): Response;
125
137
  json(data: any, status?: number, headers?: Record<string, string>): Response;
138
+
139
+ /** Async — JSX trees may contain async components. */
126
140
  html(
127
141
  data: string | JSXNode | JSXNode[] | null | undefined,
128
142
  status?: number,
129
143
  headers?: Record<string, string>
130
- ): Response;
144
+ ): Promise<Response>;
145
+
146
+ /** Async — JSX trees may contain async components. */
131
147
  page(
132
148
  data: string | JSXNode | JSXNode[] | null | undefined,
133
149
  status?: number,
134
150
  headers?: Record<string, string>
135
- ): Response;
151
+ ): Promise<Response>;
152
+
136
153
  redirect(location: string, status?: number): Response;
137
154
  }
138
155
 
@@ -149,11 +166,8 @@ export type ScheduledHandler = (
149
166
  ) => void | Promise<void>;
150
167
 
151
168
  export interface SecurityOptions {
152
- /** Emit structured security logs. Default: true */
153
169
  logSecurityEvents?: boolean;
154
- /** Extra response headers applied to every route. */
155
170
  extraHeaders?: Record<string, string> | null;
156
- /** Trusted proxy list (reserved). */
157
171
  trustedProxies?: string[] | null;
158
172
  }
159
173
 
@@ -193,12 +207,13 @@ export class Edge {
193
207
  executionCtx: ExecutionContext
194
208
  ): Promise<Response>;
195
209
  }
210
+
196
211
  /* ---------------- JSX typing for this runtime ---------------- */
197
212
 
198
213
  declare global {
199
214
  namespace JSX {
200
215
  type Element = any;
201
- type ElementType = string | symbol | ((props: any) => JSXNode);
216
+ type ElementType = string | symbol | ((props: any) => JSXNode | Promise<JSXNode>);
202
217
  interface IntrinsicElements { [elemName: string]: any; }
203
218
  interface ElementChildrenAttribute { children: {}; }
204
219
  }
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @lengkapp/edge v0.0.29
2
+ * @lengkapp/edge v0.0.30
3
3
  * MIT License
4
4
  *
5
5
  * LengkApp Edge License
@@ -30,4 +30,4 @@
30
30
  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31
31
  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32
32
  */
33
- var t=Object.defineProperty,e=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,r=(e,n)=>{for(var o in n)t(e,o,{get:n[o],enumerable:!0})},i=(r,i,s,c)=>{if(i&&"object"==typeof i||"function"==typeof i)for(let l of n(i))o.call(r,l)||l===s||t(r,l,{get:()=>i[l],enumerable:!(c=e(i,l))||c.enumerable});return r},s=e=>i(t({},"__esModule",{value:!0}),e),c={};function l(t){const e=[],n=t.length;let o=1;for(let r=1;r<=n;r++)r!==n&&47!==t.charCodeAt(r)||(r>o&&e.push(t.slice(o,r)),o=r+1);return e}function a(t){const e=t.length;return e>1&&47===t.charCodeAt(e-1)?t.slice(0,-1):t}r(c,{Context:()=>_,Edge:()=>Edge,Fragment:()=>Fragment,jsx:()=>jsx,renderToString:()=>renderToString,useCtx:()=>P}),module.exports=s(c);var u=new Set(["__proto__","constructor","prototype"]);function f(t){return"string"==typeof t&&!u.has(t)}function h(t){const e=t.length;let n=0;for(;n<e;){const e=t.charCodeAt(n);if(38===e||60===e||62===e||34===e||39===e)break;n++}if(n===e)return t;let o=t.slice(0,n),r=n;for(;n<e;n++){const e=t.charCodeAt(n);let i;if(38===e)i="&amp;";else if(60===e)i="&lt;";else if(62===e)i="&gt;";else if(34===e)i="&quot;";else{if(39!==e)continue;i="&#039;"}n>r&&(o+=t.slice(r,n)),o+=i,r=n+1}return r<e&&(o+=t.slice(r)),o}function p(t){return t>=65&&t<=90||t>=97&&t<=122}function d(t){return t>=48&&t<=57}function y(t){const e=t.length;if(0===e||!p(t.charCodeAt(0)))return!1;for(let n=1;n<e;n++){const e=t.charCodeAt(n);if(!p(e)&&!d(e)&&45!==e)return!1}return!0}function g(t){const e=t.length;if(0===e)return!1;const n=t.charCodeAt(0);if(!p(n)&&95!==n&&58!==n)return!1;for(let n=1;n<e;n++){const e=t.charCodeAt(n);if(!p(e)&&!d(e)&&95!==e&&58!==e&&46!==e&&45!==e)return!1}return!0}function m(t){const e=t.charCodeAt(0),n=t.charCodeAt(1);return!(111!==e&&79!==e||110!==n&&78!==n)}var Fragment=Symbol("Fragment");function jsx(t,e,...n){return{type:t,props:e||{},children:n,__isJSX:!0}}var w=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),C=new Set(["allowfullscreen","async","autofocus","autoplay","checked","controls","default","defer","disabled","formnovalidate","hidden","inert","ismap","itemscope","loop","multiple","muted","nomodule","novalidate","open","playsinline","readonly","required","reversed","selected"]),T=new Set(["animation-iteration-count","border-image-outset","border-image-slice","border-image-width","box-flex","box-flex-group","box-ordinal-group","column-count","columns","flex","flex-grow","flex-positive","flex-shrink","flex-negative","flex-order","grid-row","grid-row-end","grid-row-span","grid-row-start","grid-column","grid-column-end","grid-column-span","grid-column-start","font-weight","line-clamp","line-height","opacity","order","orphans","tab-size","widows","z-index","zoom","fill-opacity","flood-opacity","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-miterlimit","stroke-opacity","stroke-width"]),b=new Map,O=2e3;function x(t){const e=b.get(t);if(void 0!==e)return e;const n=t.replace(/([A-Z])/g,"-$1").toLowerCase().replace(/^-/,"");return b.size>=O&&b.clear(),b.set(t,n),n}function v(t){if(!t||"object"!=typeof t)return"";let e="";for(const n in t){if(!Object.prototype.hasOwnProperty.call(t,n))continue;const o=x(n);let r=t[n];"number"!=typeof r||T.has(o)||(r+="px"),e&&(e+=";"),e+=o+":"+r}return e}var S=new Set(["href","src","xlink:href","action","formaction"]);function renderToString(t){if(null==t||"boolean"==typeof t)return"";const e=typeof t;if("string"===e)return h(t);if("number"===e)return h(String(t));if(Array.isArray(t)){let e="";for(let n=0;n<t.length;n++)e+=renderToString(t[n]);return e}if(!t.__isJSX)return h(String(t));const{type:n,props:o,children:r}=t;if(n===Fragment){let t="";for(let e=0;e<r.length;e++)t+=renderToString(r[e]);return t}if("symbol"==typeof n)return"";if("function"==typeof n)return renderToString(n({...o,children:r}));if("string"!=typeof n||!y(n))return"";const i=w.has(n);let s="";for(const t in o){if(!Object.prototype.hasOwnProperty.call(o,t))continue;if("children"===t||"key"===t||"ref"===t)continue;const e=o[t];if(null==e||!1===e)continue;if("dangerouslySetInnerHTML"===t)continue;let n=t;if("className"===t||"class"===t?n="class":"htmlFor"!==t&&"for"!==t||(n="for"),f(n)&&!m(n)&&g(n)){if(S.has(n)){const t=String(e).replace(/[\u0000-\u0020]/g,"").toLowerCase();if(t.startsWith("javascript:")||t.startsWith("vbscript:")||t.startsWith("data:text/html"))continue}if(C.has(n))!0===e&&(s+=" "+n);else if(!0!==e){if("style"===n&&"object"==typeof e){const t=v(e);t&&(s+=' style="'+h(t)+'"');continue}s+=" "+n+'="'+h(String(e))+'"'}else s+=" "+n+'="true"'}}let c="";const l=o.dangerouslySetInnerHTML;if(l&&null!=l.__html)c=l.__html;else for(let t=0;t<r.length;t++)c+=renderToString(r[t]);return i?"<"+n+s+"/>":"<"+n+s+">"+c+"</"+n+">"}var A=Object.freeze([["X-Content-Type-Options","nosniff"],["X-Frame-Options","DENY"],["Referrer-Policy","strict-origin-when-cross-origin"],["Permissions-Policy","geolocation=(), microphone=(), camera=()"]]),E=Object.freeze(Object.create(null)),j=[];function P(){const t=j[j.length-1];if(!t)throw new Error("useCtx() called outside of an active render. It is only valid inside a component invoked by ctx.html()/ctx.page().");return t}function k(t,e){j.push(t);try{return e()}finally{j.pop()}}var _=class{constructor(t,e,n,o={},r=null){this.req=t,this.env=e,this.executionCtx=n,this.params=o,this.status=200,this.headers=new Headers(A),this.t=null,this.url=r||new URL(t.url)}o(){if(null!==this.t)return this.t;const t=this.req.headers.get("Cookie");if(!t)return this.t=E,E;const e=Object.create(null);let n=0;const o=t.length;for(;n<o;){let r=t.indexOf(";",n);-1===r&&(r=o);let i=n,s=r;for(;i<s&&32===t.charCodeAt(i);)i++;for(;s>i&&32===t.charCodeAt(s-1);)s--;if(s>i){const n=t.indexOf("=",i);if(n>i&&n<s)try{const o=decodeURIComponent(t.slice(i,n));f(o)&&(e[o]=decodeURIComponent(t.slice(n+1,s)))}catch{}}n=r+1}return this.t=e,e}getCookie(t){const e=this.o()[t];return void 0===e?null:e}get query(){return this.url.searchParams}setCookie(t,e,n={}){if("string"!=typeof t||!f(t)||/[\r\n;=]/.test(t))return;let o=encodeURIComponent(t)+"="+encodeURIComponent(e);n.path&&(o+="; Path="+n.path),n.domain&&(o+="; Domain="+n.domain),void 0!==n.maxAge&&(o+="; Max-Age="+n.maxAge),n.expires&&(o+="; Expires="+n.expires.toUTCString()),n.secure&&(o+="; Secure"),n.httpOnly&&(o+="; HttpOnly"),n.sameSite&&(o+="; SameSite="+n.sameSite),this.headers.append("Set-Cookie",o)}deleteCookie(t,e={}){this.setCookie(t,"",{...e,maxAge:0,expires:new Date(0)})}i(t){if(!t)return this.headers;const e=Object.keys(t);if(0===e.length)return this.headers;const n=new Headers(this.headers);for(let o=0;o<e.length;o++)n.set(e[o],t[e[o]]);return n}text(t,e=this.status,n={}){const o=this.i(n);return o.has("Content-Type")||o.set("Content-Type","text/plain; charset=utf-8"),new Response(t,{status:e,headers:o})}json(t,e=this.status,n={}){const o=this.i(n);return o.has("Content-Type")||o.set("Content-Type","application/json; charset=utf-8"),new Response(JSON.stringify(t),{status:e,headers:o})}html(t,e=this.status,n={}){const o=this.i(n);o.has("Content-Type")||o.set("Content-Type","text/html; charset=utf-8");const r="string"==typeof t?t:t&&t.__isJSX||Array.isArray(t)?k(this,()=>renderToString(t)):null==t?"":String(t);return new Response(r,{status:e,headers:o})}page(t,e=this.status,n={}){const o=this.i(n);o.has("Content-Type")||o.set("Content-Type","text/html; charset=utf-8");let r="string"==typeof t?t:t&&t.__isJSX||Array.isArray(t)?k(this,()=>renderToString(t)):null==t?"":String(t);return/^\s*<!doctype\s/i.test(r)||(r="<!DOCTYPE html>"+r),new Response(r,{status:e,headers:o})}redirect(t,e=302){const n=new Headers(this.headers);return n.set("Location",String(t)),n.delete("Content-Type"),new Response(null,{status:e,headers:n})}},H=class{constructor(){this.children=null,this.paramChild=null,this.handler=null}},R=class{constructor(){this.root=new H}add(t,e,n){let o=this.root;const r=[];for(let e=0;e<t.length;e++){const n=t[e];if(58===n.charCodeAt(0)){const t=n.slice(1);r.push(f(t)?t:"_p"+e),o.paramChild||(o.paramChild=new H),o=o.paramChild}else{o.children||(o.children=new Map);let t=o.children.get(n);t||(t=new H,o.children.set(n,t)),o=t}}o.handler={handler:e,options:n,paramNames:r}}match(t){const e=[],n=this.l(this.root,t,0,e);if(!n)return null;const{handler:o,options:r,paramNames:i}=n,s=Object.create(null);for(let t=0;t<i.length;t++)s[i[t]]=e[t];return{handler:o,options:r,params:s}}l(t,e,n,o){if(n===e.length)return t.handler;const r=e[n],i=t.children;if(i){const t=i.get(r);if(t){const r=this.l(t,e,n+1,o);if(r)return r}}const s=t.paramChild;if(s){o.push(r);const t=this.l(s,e,n+1,o);if(t)return t;o.pop()}return null}},D=["GET","POST","PUT","DELETE","PATCH","OPTIONS","HEAD"],I=["text/","application/json","application/xml","application/javascript","application/xhtml","application/ld+json","application/manifest+json","image/svg"];function L(t){if(!t)return!0;const e=t.toLowerCase();for(let t=0;t<I.length;t++)if(e.startsWith(I[t]))return!0;return!1}var N=new Map,U=0;function M(t,e,n){const o=t+"|"+(e||"")+"|"+(n||""),r=Date.now(),i=N.get(o);if(i&&r-i<6e4)return!1;if(N.set(o,r),r-U>3e4){U=r;for(const[t,e]of N)r-e>6e4&&N.delete(t)}return!0}var Edge=class{constructor(){this.staticRoutes=new Map;for(let t=0;t<D.length;t++)this.staticRoutes.set(D[t],new Map);this.dynamicTries={};for(let t=0;t<D.length;t++)this.dynamicTries[D[t]]=new R;this.defaults={cors:{origin:"*",methods:"GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD"}},this.scheduledHandler=null,this.security={logSecurityEvents:!0,extraHeaders:null,trustedProxies:null}}u(t,e,n,o){if("boolean"==typeof n?n={}:"function"==typeof n&&(o=n,n={}),"function"!=typeof o)throw new Error("Handler for "+t+" "+e+" must be a function");const r={...this.defaults,...n||{}};-1===e.indexOf(":")?this.staticRoutes.get(t).set(a(e),{handler:o,options:r}):this.dynamicTries[t].add(l(e),o,r)}get(t,e,n){this.u("GET",t,e,n)}post(t,e,n){this.u("POST",t,e,n)}put(t,e,n){this.u("PUT",t,e,n)}delete(t,e,n){this.u("DELETE",t,e,n)}patch(t,e,n){this.u("PATCH",t,e,n)}options(t,e,n){this.u("OPTIONS",t,e,n)}head(t,e,n){this.u("HEAD",t,e,n)}scheduled(t){this.scheduledHandler=t}h(t,e,n){if(this.security.logSecurityEvents)try{const o=t.req.headers.get("CF-Connecting-IP")||"",r=t.url?t.url.pathname:"";if(!M(e,o,r))return;console.log(JSON.stringify({ts:(new Date).toISOString(),kind:"security",event:e,detail:"string"==typeof n?n:void 0,ip:o||void 0,method:t.req.method,path:r,ua:t.req.headers.get("User-Agent")||void 0}))}catch{}}p(t,e){if(!e)return;const n="object"==typeof e?e:this.defaults.cors,o=t.req.headers.get("Origin"),r=n.origin;"*"===r?t.headers.set("Access-Control-Allow-Origin","*"):Array.isArray(r)?o&&-1!==r.indexOf(o)&&(t.headers.set("Access-Control-Allow-Origin",o),t.headers.set("Vary","Origin"),t.headers.set("Access-Control-Allow-Credentials","true")):"string"==typeof r&&o===r&&(t.headers.set("Access-Control-Allow-Origin",o),t.headers.set("Vary","Origin"),t.headers.set("Access-Control-Allow-Credentials","true")),t.headers.set("Access-Control-Allow-Methods",n.methods||"GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD"),t.headers.set("Access-Control-Allow-Headers",n.headers||"Content-Type, Authorization, X-CSRF-Token"),t.headers.set("Access-Control-Max-Age","86400")}m(t,e){e&&console.log(t.req.method+" "+t.req.url+" - "+t.status)}C(t,e){if(!L(e.headers.get("Content-Type")))return e;const n=e.headers.get("Content-Length");if(null!==n&&+n<1024)return e;const o=t.headers.get("Accept-Encoding")||"";let r=null;if(-1!==o.indexOf("gzip")?r="gzip":-1!==o.indexOf("deflate")&&(r="deflate"),!r||!e.body)return e;const i=e.body.pipeThrough(new CompressionStream(r)),s=new Headers(e.headers);return s.set("Content-Encoding",r),s.set("Vary","Accept-Encoding"),s.delete("Content-Length"),new Response(i,{status:e.status,statusText:e.statusText,headers:s})}async T(t,e){return!e||"function"!=typeof e||!!await e(t)}async O(t){return await caches.default.match(t)||null}async v(t,e,n){if(!n)return;const o=!0===n?{}:n,r=o.ttl??3600,i=o.staleWhileRevalidate??0,s=new Headers(e.headers);s.set("Cache-Control","max-age="+r+(i>0?", stale-while-revalidate="+i:"")),s.delete("Set-Cookie"),await caches.default.put(t,new Response(e.body,{status:e.status,statusText:e.statusText,headers:s}))}async fetch(t,e,n){const o=new URL(t.url),r=a(o.pathname),i=t.method,s=this.staticRoutes.get(i);if(s){const i=s.get(r);if(i)return this.S(i.handler,i.options,t,e,n,Object.create(null),o)}const c=this.dynamicTries[i];if(c){const i=c.match(l(r));if(i)return this.S(i.handler,i.options,t,e,n,i.params,o)}return new Response("Not Found",{status:404})}async S(t,e,n,o,r,i,s){const c=new _(n,o,r,i,s),l=this.security.extraHeaders;if(l)for(const t in l)Object.prototype.hasOwnProperty.call(l,t)&&c.headers.set(t,l[t]);let a,u=!1;try{u=await this.T(c,e.validate)}catch(t){this.h(c,"validation_error",t&&t.message),u=!1}if(!u)return c.text("Validation failed",400);if(e.cache&&"GET"===n.method){const t=await this.O(n);if(t)return this.p(c,e.cors),this.m(c,e.log),t}this.p(c,e.cors);try{const e=await t(c);a=e instanceof Response?e:e&&e.__isJSX?c.html(e):c.text("OK")}catch(t){this.h(c,"handler_error",t&&t.message),a=c.text("Internal Server Error",500)}return e.cache&&"GET"===n.method&&200===a.status&&c.executionCtx.waitUntil(this.v(n,a.clone(),e.cache)),e.compress&&(a=this.C(n,a)),this.m(c,e.log),a}};
33
+ var t=Object.defineProperty,e=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,r=(e,n)=>{for(var o in n)t(e,o,{get:n[o],enumerable:!0})},i=(r,i,s,c)=>{if(i&&"object"==typeof i||"function"==typeof i)for(let a of n(i))o.call(r,a)||a===s||t(r,a,{get:()=>i[a],enumerable:!(c=e(i,a))||c.enumerable});return r},s=e=>i(t({},"__esModule",{value:!0}),e),c={};function a(t){const e=[],n=t.length;let o=1;for(let r=1;r<=n;r++)r!==n&&47!==t.charCodeAt(r)||(r>o&&e.push(t.slice(o,r)),o=r+1);return e}function l(t){const e=t.length;return e>1&&47===t.charCodeAt(e-1)?t.slice(0,-1):t}r(c,{Context:()=>_,Edge:()=>Edge,Fragment:()=>Fragment,jsx:()=>jsx,renderToString:()=>renderToString,useCtx:()=>E}),module.exports=s(c);var u=new Set(["__proto__","constructor","prototype"]);function f(t){return"string"==typeof t&&!u.has(t)}function h(t){const e=t.length;let n=0;for(;n<e;){const e=t.charCodeAt(n);if(38===e||60===e||62===e||34===e||39===e)break;n++}if(n===e)return t;let o=t.slice(0,n),r=n;for(;n<e;n++){const e=t.charCodeAt(n);let i;if(38===e)i="&amp;";else if(60===e)i="&lt;";else if(62===e)i="&gt;";else if(34===e)i="&quot;";else{if(39!==e)continue;i="&#039;"}n>r&&(o+=t.slice(r,n)),o+=i,r=n+1}return r<e&&(o+=t.slice(r)),o}function p(t){return t>=65&&t<=90||t>=97&&t<=122}function d(t){return t>=48&&t<=57}function y(t){const e=t.length;if(0===e||!p(t.charCodeAt(0)))return!1;for(let n=1;n<e;n++){const e=t.charCodeAt(n);if(!p(e)&&!d(e)&&45!==e)return!1}return!0}function g(t){const e=t.length;if(0===e)return!1;const n=t.charCodeAt(0);if(!p(n)&&95!==n&&58!==n)return!1;for(let n=1;n<e;n++){const e=t.charCodeAt(n);if(!p(e)&&!d(e)&&95!==e&&58!==e&&46!==e&&45!==e)return!1}return!0}function w(t){const e=t.charCodeAt(0),n=t.charCodeAt(1);return!(111!==e&&79!==e||110!==n&&78!==n)}var Fragment=Symbol("Fragment");function jsx(t,e,...n){return{type:t,props:e||{},children:n,__isJSX:!0}}var m=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),C=new Set(["allowfullscreen","async","autofocus","autoplay","checked","controls","default","defer","disabled","formnovalidate","hidden","inert","ismap","itemscope","loop","multiple","muted","nomodule","novalidate","open","playsinline","readonly","required","reversed","selected"]),b=new Set(["animation-iteration-count","border-image-outset","border-image-slice","border-image-width","box-flex","box-flex-group","box-ordinal-group","column-count","columns","flex","flex-grow","flex-positive","flex-shrink","flex-negative","flex-order","grid-row","grid-row-end","grid-row-span","grid-row-start","grid-column","grid-column-end","grid-column-span","grid-column-start","font-weight","line-clamp","line-height","opacity","order","orphans","tab-size","widows","z-index","zoom","fill-opacity","flood-opacity","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-miterlimit","stroke-opacity","stroke-width"]),T=new Map,O=2e3;function x(t){const e=T.get(t);if(void 0!==e)return e;const n=t.replace(/([A-Z])/g,"-$1").toLowerCase().replace(/^-/,"");return T.size>=O&&T.clear(),T.set(t,n),n}function S(t){if(!t||"object"!=typeof t)return"";let e="";for(const n in t){if(!Object.prototype.hasOwnProperty.call(t,n))continue;const o=x(n);let r=t[n];"number"!=typeof r||b.has(o)||(r+="px"),e&&(e+=";"),e+=o+":"+r}return e}var A=new Set(["href","src","xlink:href","action","formaction"]),v=[];function E(){const t=v[v.length-1];if(!t)throw new Error("useCtx() must be called synchronously at the top of a component (before any await). It is not available after an await, nor outside a render.");return t}async function renderToString(t,e){if(void 0===e&&(e=v[v.length-1]),null==t||"boolean"==typeof t)return"";const n=typeof t;if("string"===n)return h(t);if("number"===n)return h(String(t));if("object"===n&&"function"==typeof t.then)return renderToString(await t,e);if(Array.isArray(t)){let n="";for(let o=0;o<t.length;o++)n+=await renderToString(t[o],e);return n}if(!t.__isJSX)return h(String(t));const{type:o,props:r,children:i}=t;if(o===Fragment){let t="";for(let n=0;n<i.length;n++)t+=await renderToString(i[n],e);return t}if("symbol"==typeof o)return"";if("function"==typeof o){let t;if(e){v.push(e);try{t=o({...r,children:i})}finally{v.pop()}}else t=o({...r,children:i});return renderToString(await t,e)}if("string"!=typeof o||!y(o))return"";const s=m.has(o);let c="";for(const t in r){if(!Object.prototype.hasOwnProperty.call(r,t))continue;if("children"===t||"key"===t||"ref"===t)continue;const e=r[t];if(null==e||!1===e)continue;if("dangerouslySetInnerHTML"===t)continue;let n=t;if("className"===t||"class"===t?n="class":"htmlFor"!==t&&"for"!==t||(n="for"),f(n)&&!w(n)&&g(n)){if(A.has(n)){const t=String(e).replace(/[\u0000-\u0020]/g,"").toLowerCase();if(t.startsWith("javascript:")||t.startsWith("vbscript:")||t.startsWith("data:text/html"))continue}if(C.has(n))!0===e&&(c+=" "+n);else if(!0!==e){if("style"===n&&"object"==typeof e){const t=S(e);t&&(c+=' style="'+h(t)+'"');continue}c+=" "+n+'="'+h(String(e))+'"'}else c+=" "+n+'="true"'}}let a="";const l=r.dangerouslySetInnerHTML;if(l&&null!=l.__html)a=l.__html;else for(let t=0;t<i.length;t++)a+=await renderToString(i[t],e);return s?"<"+o+c+"/>":"<"+o+c+">"+a+"</"+o+">"}var j=Object.freeze([["X-Content-Type-Options","nosniff"],["X-Frame-Options","DENY"],["Referrer-Policy","strict-origin-when-cross-origin"],["Permissions-Policy","geolocation=(), microphone=(), camera=()"]]),P=Object.freeze(Object.create(null)),_=class{constructor(t,e,n,o={},r=null){this.req=t,this.env=e,this.executionCtx=n,this.params=o,this.status=200,this.headers=new Headers(j),this.t=null,this.url=r||new URL(t.url)}o(){if(null!==this.t)return this.t;const t=this.req.headers.get("Cookie");if(!t)return this.t=P,P;const e=Object.create(null);let n=0;const o=t.length;for(;n<o;){let r=t.indexOf(";",n);-1===r&&(r=o);let i=n,s=r;for(;i<s&&32===t.charCodeAt(i);)i++;for(;s>i&&32===t.charCodeAt(s-1);)s--;if(s>i){const n=t.indexOf("=",i);if(n>i&&n<s)try{const o=decodeURIComponent(t.slice(i,n));f(o)&&(e[o]=decodeURIComponent(t.slice(n+1,s)))}catch{}}n=r+1}return this.t=e,e}getCookie(t){const e=this.o()[t];return void 0===e?null:e}get query(){return this.url.searchParams}setCookie(t,e,n={}){if("string"!=typeof t||!f(t)||/[\r\n;=]/.test(t))return;let o=encodeURIComponent(t)+"="+encodeURIComponent(e);n.path&&(o+="; Path="+n.path),n.domain&&(o+="; Domain="+n.domain),void 0!==n.maxAge&&(o+="; Max-Age="+n.maxAge),n.expires&&(o+="; Expires="+n.expires.toUTCString()),n.secure&&(o+="; Secure"),n.httpOnly&&(o+="; HttpOnly"),n.sameSite&&(o+="; SameSite="+n.sameSite),this.headers.append("Set-Cookie",o)}deleteCookie(t,e={}){this.setCookie(t,"",{...e,maxAge:0,expires:new Date(0)})}i(t){if(!t)return this.headers;const e=Object.keys(t);if(0===e.length)return this.headers;const n=new Headers(this.headers);for(let o=0;o<e.length;o++)n.set(e[o],t[e[o]]);return n}text(t,e=this.status,n={}){const o=this.i(n);return o.has("Content-Type")||o.set("Content-Type","text/plain; charset=utf-8"),new Response(t,{status:e,headers:o})}json(t,e=this.status,n={}){const o=this.i(n);return o.has("Content-Type")||o.set("Content-Type","application/json; charset=utf-8"),new Response(JSON.stringify(t),{status:e,headers:o})}async html(t,e=this.status,n={}){const o=this.i(n);let r;return o.has("Content-Type")||o.set("Content-Type","text/html; charset=utf-8"),r="string"==typeof t?t:t&&t.__isJSX||Array.isArray(t)?await renderToString(t,this):null==t?"":String(t),new Response(r,{status:e,headers:o})}async page(t,e=this.status,n={}){const o=this.i(n);let r;return o.has("Content-Type")||o.set("Content-Type","text/html; charset=utf-8"),r="string"==typeof t?t:t&&t.__isJSX||Array.isArray(t)?await renderToString(t,this):null==t?"":String(t),/^\s*<!doctype\s/i.test(r)||(r="<!DOCTYPE html>"+r),new Response(r,{status:e,headers:o})}redirect(t,e=302){const n=new Headers(this.headers);return n.set("Location",String(t)),n.delete("Content-Type"),new Response(null,{status:e,headers:n})}},k=class{constructor(){this.children=null,this.paramChild=null,this.handler=null}},H=class{constructor(){this.root=new k}add(t,e,n){let o=this.root;const r=[];for(let e=0;e<t.length;e++){const n=t[e];if(58===n.charCodeAt(0)){const t=n.slice(1);r.push(f(t)?t:"_p"+e),o.paramChild||(o.paramChild=new k),o=o.paramChild}else{o.children||(o.children=new Map);let t=o.children.get(n);t||(t=new k,o.children.set(n,t)),o=t}}o.handler={handler:e,options:n,paramNames:r}}match(t){const e=[],n=this.l(this.root,t,0,e);if(!n)return null;const{handler:o,options:r,paramNames:i}=n,s=Object.create(null);for(let t=0;t<i.length;t++)s[i[t]]=e[t];return{handler:o,options:r,params:s}}l(t,e,n,o){if(n===e.length)return t.handler;const r=e[n],i=t.children;if(i){const t=i.get(r);if(t){const r=this.l(t,e,n+1,o);if(r)return r}}const s=t.paramChild;if(s){o.push(r);const t=this.l(s,e,n+1,o);if(t)return t;o.pop()}return null}},R=["GET","POST","PUT","DELETE","PATCH","OPTIONS","HEAD"],D=["text/","application/json","application/xml","application/javascript","application/xhtml","application/ld+json","application/manifest+json","image/svg"];function I(t){if(!t)return!0;const e=t.toLowerCase();for(let t=0;t<D.length;t++)if(e.startsWith(D[t]))return!0;return!1}var L=new Map,N=0;function U(t,e,n){const o=t+"|"+(e||"")+"|"+(n||""),r=Date.now(),i=L.get(o);if(i&&r-i<6e4)return!1;if(L.set(o,r),r-N>3e4){N=r;for(const[t,e]of L)r-e>6e4&&L.delete(t)}return!0}var Edge=class{constructor(){this.staticRoutes=new Map;for(let t=0;t<R.length;t++)this.staticRoutes.set(R[t],new Map);this.dynamicTries={};for(let t=0;t<R.length;t++)this.dynamicTries[R[t]]=new H;this.defaults={cors:{origin:"*",methods:"GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD"}},this.scheduledHandler=null,this.security={logSecurityEvents:!0,extraHeaders:null,trustedProxies:null}}u(t,e,n,o){if("boolean"==typeof n?n={}:"function"==typeof n&&(o=n,n={}),"function"!=typeof o)throw new Error("Handler for "+t+" "+e+" must be a function");const r={...this.defaults,...n||{}};-1===e.indexOf(":")?this.staticRoutes.get(t).set(l(e),{handler:o,options:r}):this.dynamicTries[t].add(a(e),o,r)}get(t,e,n){this.u("GET",t,e,n)}post(t,e,n){this.u("POST",t,e,n)}put(t,e,n){this.u("PUT",t,e,n)}delete(t,e,n){this.u("DELETE",t,e,n)}patch(t,e,n){this.u("PATCH",t,e,n)}options(t,e,n){this.u("OPTIONS",t,e,n)}head(t,e,n){this.u("HEAD",t,e,n)}scheduled(t){this.scheduledHandler=t}h(t,e,n){if(this.security.logSecurityEvents)try{const o=t.req.headers.get("CF-Connecting-IP")||"",r=t.url?t.url.pathname:"";if(!U(e,o,r))return;console.log(JSON.stringify({ts:(new Date).toISOString(),kind:"security",event:e,detail:"string"==typeof n?n:void 0,ip:o||void 0,method:t.req.method,path:r,ua:t.req.headers.get("User-Agent")||void 0}))}catch{}}p(t,e){if(!e)return;const n="object"==typeof e?e:this.defaults.cors,o=t.req.headers.get("Origin"),r=n.origin;"*"===r?t.headers.set("Access-Control-Allow-Origin","*"):Array.isArray(r)?o&&-1!==r.indexOf(o)&&(t.headers.set("Access-Control-Allow-Origin",o),t.headers.set("Vary","Origin"),t.headers.set("Access-Control-Allow-Credentials","true")):"string"==typeof r&&o===r&&(t.headers.set("Access-Control-Allow-Origin",o),t.headers.set("Vary","Origin"),t.headers.set("Access-Control-Allow-Credentials","true")),t.headers.set("Access-Control-Allow-Methods",n.methods||"GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD"),t.headers.set("Access-Control-Allow-Headers",n.headers||"Content-Type, Authorization, X-CSRF-Token"),t.headers.set("Access-Control-Max-Age","86400")}m(t,e){e&&console.log(t.req.method+" "+t.req.url+" - "+t.status)}C(t,e){if(!I(e.headers.get("Content-Type")))return e;const n=e.headers.get("Content-Length");if(null!==n&&+n<1024)return e;const o=t.headers.get("Accept-Encoding")||"";let r=null;if(-1!==o.indexOf("gzip")?r="gzip":-1!==o.indexOf("deflate")&&(r="deflate"),!r||!e.body)return e;const i=e.body.pipeThrough(new CompressionStream(r)),s=new Headers(e.headers);return s.set("Content-Encoding",r),s.set("Vary","Accept-Encoding"),s.delete("Content-Length"),new Response(i,{status:e.status,statusText:e.statusText,headers:s})}async T(t,e){return!e||"function"!=typeof e||!!await e(t)}async O(t){return await caches.default.match(t)||null}async S(t,e,n){if(!n)return;const o=!0===n?{}:n,r=o.ttl??3600,i=o.staleWhileRevalidate??0,s=new Headers(e.headers);s.set("Cache-Control","max-age="+r+(i>0?", stale-while-revalidate="+i:"")),s.delete("Set-Cookie"),await caches.default.put(t,new Response(e.body,{status:e.status,statusText:e.statusText,headers:s}))}async fetch(t,e,n){const o=new URL(t.url),r=l(o.pathname),i=t.method,s=this.staticRoutes.get(i);if(s){const i=s.get(r);if(i)return this.A(i.handler,i.options,t,e,n,Object.create(null),o)}const c=this.dynamicTries[i];if(c){const i=c.match(a(r));if(i)return this.A(i.handler,i.options,t,e,n,i.params,o)}return new Response("Not Found",{status:404})}async A(t,e,n,o,r,i,s){const c=new _(n,o,r,i,s),a=this.security.extraHeaders;if(a)for(const t in a)Object.prototype.hasOwnProperty.call(a,t)&&c.headers.set(t,a[t]);let l,u=!1;try{u=await this.T(c,e.validate)}catch(t){this.h(c,"validation_error",t&&t.message),u=!1}if(!u)return c.text("Validation failed",400);if(e.cache&&"GET"===n.method){const t=await this.O(n);if(t)return this.p(c,e.cors),this.m(c,e.log),t}this.p(c,e.cors);try{const e=await t(c);l=e instanceof Response?e:e&&e.__isJSX?await c.html(e):c.text("OK")}catch(t){this.h(c,"handler_error",t&&t.message),l=c.text("Internal Server Error",500)}return e.cache&&"GET"===n.method&&200===l.status&&c.executionCtx.waitUntil(this.S(n,l.clone(),e.cache)),e.compress&&(l=this.C(n,l)),this.m(c,e.log),l}};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lengkapp/edge",
3
- "version": "0.0.29",
3
+ "version": "0.0.30",
4
4
  "description": "Edge framework used by Lengkapp",
5
5
  "main": "dist/edge-server.js",
6
6
  "types": "dist/edge-server.d.ts",