@lengkapp/edge 0.0.45 → 0.0.47

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.45
2
+ * @lengkapp/edge v0.0.47
3
3
  * MIT License
4
4
  *
5
5
  * LengkApp Edge License
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @lengkapp/edge v0.0.45
2
+ * @lengkapp/edge v0.0.47
3
3
  * MIT License
4
4
  *
5
5
  * LengkApp Edge License
@@ -169,6 +169,29 @@ export type ScheduledHandler = (
169
169
  ctx: ExecutionContext
170
170
  ) => void | Promise<void>;
171
171
 
172
+ /**
173
+ * Invoked when no route matches the incoming request.
174
+ *
175
+ * Receives a full Context (same shape as a route handler) so it can
176
+ * set `c.status` and return a Response, or a JSX tree (which is
177
+ * coerced to an HTML response at that status).
178
+ */
179
+ export type NotFoundHandler = (ctx: Context) => any | Promise<any>;
180
+
181
+ /**
182
+ * Invoked when a route handler (or the not-found handler) throws.
183
+ *
184
+ * The thrown value is `unknown` because nothing enforces that handlers
185
+ * throw `Error` specifically. Returning a Response uses it verbatim;
186
+ * returning JSX renders it as a 500 HTML response. Errors thrown by
187
+ * the error handler itself are swallowed and replaced with a
188
+ * plain-text 500.
189
+ */
190
+ export type ErrorHandler = (
191
+ ctx: Context,
192
+ err: unknown
193
+ ) => any | Promise<any>;
194
+
172
195
  export interface SecurityOptions {
173
196
  logSecurityEvents?: boolean;
174
197
  extraHeaders?: Record<string, string> | null;
@@ -188,6 +211,14 @@ export class Edge {
188
211
  scheduledHandler: ScheduledHandler | null;
189
212
  security: SecurityOptions;
190
213
 
214
+ /* ---- Fallback handlers ------------------------------------------ *
215
+ * Exposed as public fields to mirror the runtime shape; normally *
216
+ * set via `.notFound()` / `.onError()` rather than assigned *
217
+ * directly. */
218
+ notFoundHandler: NotFoundHandler | null;
219
+ errorHandler: ErrorHandler | null;
220
+
221
+ /* ---- Route registration ----------------------------------------- */
191
222
  get(path: string, options: RouteOptions | boolean, handler: RouteHandler): void;
192
223
  get(path: string, handler: RouteHandler): void;
193
224
  post(path: string, options: RouteOptions | boolean, handler: RouteHandler): void;
@@ -203,8 +234,33 @@ export class Edge {
203
234
  head(path: string, options: RouteOptions | boolean, handler: RouteHandler): void;
204
235
  head(path: string, handler: RouteHandler): void;
205
236
 
237
+ /* ---- Scheduled handler ------------------------------------------ */
206
238
  scheduled(handler: ScheduledHandler): void;
207
239
 
240
+ /* ---- Fallback registration -------------------------------------- */
241
+
242
+ /**
243
+ * Register a handler invoked when no route matches the incoming
244
+ * request. The handler runs with a full Context (headers, cookies,
245
+ * `c.page`, `c.html`) but with empty route options — no CORS,
246
+ * compression, or caching. Its own errors flow into `onError`.
247
+ *
248
+ * `OPTIONS` requests are short-circuited to a 204 (with base security
249
+ * headers, no body) before this handler runs, so preflights never
250
+ * render an HTML error page.
251
+ */
252
+ notFound(handler: NotFoundHandler): void;
253
+
254
+ /**
255
+ * Register a handler invoked when a route handler (including the
256
+ * not-found handler) throws. Returning a Response uses it verbatim;
257
+ * returning JSX renders it as a 500 HTML response. Errors thrown by
258
+ * the error handler itself are swallowed and replaced with a
259
+ * plain-text 500.
260
+ */
261
+ onError(handler: ErrorHandler): void;
262
+
263
+ /* ---- Entry point ------------------------------------------------ */
208
264
  fetch(
209
265
  request: Request,
210
266
  env: Record<string, any>,
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @lengkapp/edge v0.0.45
2
+ * @lengkapp/edge v0.0.47
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 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:()=>P,Edge:()=>Edge,Fragment:()=>Fragment,jsx:()=>jsx,renderToString:()=>renderToString,useCtx:()=>useCtx}),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 useCtx(){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 E=Object.freeze([["X-Content-Type-Options","nosniff"],["X-Frame-Options","DENY"],["Referrer-Policy","strict-origin-when-cross-origin"],["Permissions-Policy","geolocation=(), microphone=(), camera=()"]]),j=Object.freeze(Object.create(null)),P=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(E),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=j,j;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})}},_=class{constructor(){this.children=null,this.paramChild=null,this.handler=null}},k=class{constructor(){this.root=new _}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 _),o=o.paramChild}else{o.children||(o.children=new Map);let t=o.children.get(n);t||(t=new _,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}},H=["GET","POST","PUT","DELETE","PATCH","OPTIONS","HEAD"],R=["text/","application/json","application/xml","application/javascript","application/xhtml","application/ld+json","application/manifest+json","image/svg"];function D(t){if(!t)return!0;const e=t.toLowerCase();for(let t=0;t<R.length;t++)if(e.startsWith(R[t]))return!0;return!1}var I=new Map,L=0;function N(t,e,n){const o=t+"|"+(e||"")+"|"+(n||""),r=Date.now(),i=I.get(o);if(i&&r-i<6e4)return!1;if(I.set(o,r),r-L>3e4){L=r;for(const[t,e]of I)r-e>6e4&&I.delete(t)}return!0}var Edge=class{constructor(){this.staticRoutes=new Map;for(let t=0;t<H.length;t++)this.staticRoutes.set(H[t],new Map);this.dynamicTries={};for(let t=0;t<H.length;t++)this.dynamicTries[H[t]]=new k;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(!N(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(!D(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 P(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}};
33
+ var t=Object.defineProperty,e=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,r=Object.prototype.hasOwnProperty,o=(e,n)=>{for(var r in n)t(e,r,{get:n[r],enumerable:!0})},i=(o,i,s,c)=>{if(i&&"object"==typeof i||"function"==typeof i)for(let a of n(i))r.call(o,a)||a===s||t(o,a,{get:()=>i[a],enumerable:!(c=e(i,a))||c.enumerable});return o},s=e=>i(t({},"__esModule",{value:!0}),e),c={};function a(t){const e=[],n=t.length;let r=1;for(let o=1;o<=n;o++)o!==n&&47!==t.charCodeAt(o)||(o>r&&e.push(t.slice(r,o)),r=o+1);return e}function l(t){const e=t.length;return e>1&&47===t.charCodeAt(e-1)?t.slice(0,-1):t}o(c,{Context:()=>k,Edge:()=>Edge,Fragment:()=>Fragment,jsx:()=>jsx,renderToString:()=>renderToString,useCtx:()=>useCtx}),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 r=t.slice(0,n),o=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>o&&(r+=t.slice(o,n)),r+=i,o=n+1}return o<e&&(r+=t.slice(o)),r}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 w(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 g(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,S=2e3;function O(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>=S&&T.clear(),T.set(t,n),n}function E(t){if(!t||"object"!=typeof t)return"";let e="";for(const n in t){if(!Object.prototype.hasOwnProperty.call(t,n))continue;const r=O(n);let o=t[n];"number"!=typeof o||b.has(r)||(o+="px"),e&&(e+=";"),e+=r+":"+o}return e}var x=new Set(["href","src","xlink:href","action","formaction"]),v=[];function useCtx(){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 r=0;r<t.length;r++)n+=await renderToString(t[r],e);return n}if(!t.__isJSX)return h(String(t));const{type:r,props:o,children:i}=t;if(r===Fragment){let t="";for(let n=0;n<i.length;n++)t+=await renderToString(i[n],e);return t}if("symbol"==typeof r)return"";if("function"==typeof r){let t;if(e){v.push(e);try{t=r({...o,children:i})}finally{v.pop()}}else t=r({...o,children:i});return renderToString(await t,e)}if("string"!=typeof r||!y(r))return"";const s=m.has(r);let c="";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)&&!g(n)&&w(n)){if(x.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=E(e);t&&(c+=' style="'+h(t)+'"');continue}c+=" "+n+'="'+h(String(e))+'"'}else c+=" "+n+'="true"'}}let a="";const l=o.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?"<"+r+c+"/>":"<"+r+c+">"+a+"</"+r+">"}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=()"]]),j=Object.freeze(Object.create(null)),k=class{constructor(t,e,n,r={},o=null){this.req=t,this.env=e,this.executionCtx=n,this.params=r,this.status=200,this.headers=new Headers(A),this.t=null,this.url=o||new URL(t.url)}o(){if(null!==this.t)return this.t;const t=this.req.headers.get("Cookie");if(!t)return this.t=j,j;const e=Object.create(null);let n=0;const r=t.length;for(;n<r;){let o=t.indexOf(";",n);-1===o&&(o=r);let i=n,s=o;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 r=decodeURIComponent(t.slice(i,n));f(r)&&(e[r]=decodeURIComponent(t.slice(n+1,s)))}catch{}}n=o+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 r=encodeURIComponent(t)+"="+encodeURIComponent(e);n.path&&(r+="; Path="+n.path),n.domain&&(r+="; Domain="+n.domain),void 0!==n.maxAge&&(r+="; Max-Age="+n.maxAge),n.expires&&(r+="; Expires="+n.expires.toUTCString()),n.secure&&(r+="; Secure"),n.httpOnly&&(r+="; HttpOnly"),n.sameSite&&(r+="; SameSite="+n.sameSite),this.headers.append("Set-Cookie",r)}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 r=0;r<e.length;r++)n.set(e[r],t[e[r]]);return n}text(t,e=this.status,n={}){const r=this.i(n);return r.has("Content-Type")||r.set("Content-Type","text/plain; charset=utf-8"),new Response(t,{status:e,headers:r})}json(t,e=this.status,n={}){const r=this.i(n);return r.has("Content-Type")||r.set("Content-Type","application/json; charset=utf-8"),new Response(JSON.stringify(t),{status:e,headers:r})}async html(t,e=this.status,n={}){const r=this.i(n);let o;return r.has("Content-Type")||r.set("Content-Type","text/html; charset=utf-8"),o="string"==typeof t?t:t&&t.__isJSX||Array.isArray(t)?await renderToString(t,this):null==t?"":String(t),new Response(o,{status:e,headers:r})}async page(t,e=this.status,n={}){const r=this.i(n);let o;return r.has("Content-Type")||r.set("Content-Type","text/html; charset=utf-8"),o="string"==typeof t?t:t&&t.__isJSX||Array.isArray(t)?await renderToString(t,this):null==t?"":String(t),/^\s*<!doctype\s/i.test(o)||(o="<!DOCTYPE html>"+o),new Response(o,{status:e,headers:r})}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})}},_=class{constructor(){this.children=null,this.paramChild=null,this.handler=null}},P=class{constructor(){this.root=new _}add(t,e,n){let r=this.root;const o=[];for(let e=0;e<t.length;e++){const n=t[e];if(58===n.charCodeAt(0)){const t=n.slice(1);o.push(f(t)?t:"_p"+e),r.paramChild||(r.paramChild=new _),r=r.paramChild}else{r.children||(r.children=new Map);let t=r.children.get(n);t||(t=new _,r.children.set(n,t)),r=t}}r.handler={handler:e,options:n,paramNames:o}}match(t){const e=[],n=this.l(this.root,t,0,e);if(!n)return null;const{handler:r,options:o,paramNames:i}=n,s=Object.create(null);for(let t=0;t<i.length;t++)s[i[t]]=e[t];return{handler:r,options:o,params:s}}l(t,e,n,r){if(n===e.length)return t.handler;const o=e[n],i=t.children;if(i){const t=i.get(o);if(t){const o=this.l(t,e,n+1,r);if(o)return o}}const s=t.paramChild;if(s){r.push(o);const t=this.l(s,e,n+1,r);if(t)return t;r.pop()}return null}},R=["GET","POST","PUT","DELETE","PATCH","OPTIONS","HEAD"],H=["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<H.length;t++)if(e.startsWith(H[t]))return!0;return!1}var D=new Map,N=0;function L(t,e,n){const r=t+"|"+(e||"")+"|"+(n||""),o=Date.now(),i=D.get(r);if(i&&o-i<6e4)return!1;if(D.set(r,o),o-N>3e4){N=o;for(const[t,e]of D)o-e>6e4&&D.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 P;this.defaults={cors:{origin:"*",methods:"GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD"}},this.scheduledHandler=null,this.security={logSecurityEvents:!0,extraHeaders:null,trustedProxies:null},this.notFoundHandler=null,this.errorHandler=null}u(t,e,n,r){if("boolean"==typeof n?n={}:"function"==typeof n&&(r=n,n={}),"function"!=typeof r)throw new Error("Handler for "+t+" "+e+" must be a function");const o={...this.defaults,...n||{}};-1===e.indexOf(":")?this.staticRoutes.get(t).set(l(e),{handler:r,options:o}):this.dynamicTries[t].add(a(e),r,o)}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}notFound(t){if("function"!=typeof t)throw new Error("notFound(handler) requires a function");this.notFoundHandler=t}onError(t){if("function"!=typeof t)throw new Error("onError(handler) requires a function");this.errorHandler=t}h(t,e){const n=new Headers(e.headers);t.headers.forEach((t,e)=>{"set-cookie"!==e.toLowerCase()&&(n.has(e)||n.set(e,t))});const r="function"==typeof t.headers.getSetCookie?t.headers.getSetCookie():t.headers.get("Set-Cookie")?[t.headers.get("Set-Cookie")]:[];if(r.length){const t="function"==typeof n.getSetCookie?n.getSetCookie():n.get("Set-Cookie")?[n.get("Set-Cookie")]:[],e=new Set(t);for(let t=0;t<r.length;t++){const o=r[t];e.has(o)||(n.append("Set-Cookie",o),e.add(o))}}const o=204===e.status||304===e.status?null:e.body;return new Response(o,{status:e.status,statusText:e.statusText,headers:n})}p(t,e,n){if(this.security.logSecurityEvents)try{const r=t.req.headers.get("CF-Connecting-IP")||"",o=t.url?t.url.pathname:"";if(!L(e,r,o))return;console.log(JSON.stringify({ts:(new Date).toISOString(),kind:"security",event:e,detail:"string"==typeof n?n:void 0,ip:r||void 0,method:t.req.method,path:o,ua:t.req.headers.get("User-Agent")||void 0}))}catch{}}m(t,e){if(!e)return;const n="object"==typeof e?e:this.defaults.cors,r=t.req.headers.get("Origin"),o=n.origin;"*"===o?t.headers.set("Access-Control-Allow-Origin","*"):Array.isArray(o)?r&&-1!==o.indexOf(r)&&(t.headers.set("Access-Control-Allow-Origin",r),t.headers.set("Vary","Origin"),t.headers.set("Access-Control-Allow-Credentials","true")):"string"==typeof o&&r===o&&(t.headers.set("Access-Control-Allow-Origin",r),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")}C(t,e){e&&console.log(t.req.method+" "+t.req.url+" - "+t.status)}T(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 r=t.headers.get("Accept-Encoding")||"";let o=null;if(-1!==r.indexOf("gzip")?o="gzip":-1!==r.indexOf("deflate")&&(o="deflate"),!o||!e.body)return e;const i=e.body.pipeThrough(new CompressionStream(o)),s=new Headers(e.headers);return s.set("Content-Encoding",o),s.set("Vary","Accept-Encoding"),s.delete("Content-Length"),new Response(i,{status:e.status,statusText:e.statusText,headers:s})}async S(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 r=!0===n?{}:n,o=r.ttl??3600,i=r.staleWhileRevalidate??0,s=new Headers(e.headers);s.set("Cache-Control","max-age="+o+(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 r=new URL(t.url),o=l(r.pathname),i=t.method,s=this.staticRoutes.get(i);if(s){const i=s.get(o);if(i)return this.A(i.handler,i.options,t,e,n,Object.create(null),r)}const c=this.dynamicTries[i];if(c){const i=c.match(a(o));if(i)return this.A(i.handler,i.options,t,e,n,i.params,r)}if("OPTIONS"===i){const o=new k(t,e,n,Object.create(null),r);return this.h(o,new Response(null,{status:204}))}if(this.notFoundHandler)return this.A(this.notFoundHandler,{},t,e,n,Object.create(null),r);const u=new k(t,e,n,Object.create(null),r);return this.h(u,new Response("Not Found",{status:404}))}async j(t,e){const n=this.errorHandler;if(!n)return t.text("Internal Server Error",500);try{const r=await n(t,e);return r instanceof Response?this.h(t,r):r&&r.__isJSX||Array.isArray(r)?t.html(r,500):t.text("Internal Server Error",500)}catch(e){return this.p(t,"error_handler_failure",e&&e.message),t.text("Internal Server Error",500)}}async A(t,e,n,r,o,i,s){const c=new k(n,r,o,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.S(c,e.validate)}catch(t){this.p(c,"validation_error",t&&t.message),u=!1}if(!u)return this.h(c,c.text("Validation failed",400));if(e.cache&&"GET"===n.method){const t=await this.O(n);if(t)return this.m(c,e.cors),this.C(c,e.log),this.h(c,t)}this.m(c,e.cors);try{const e=await t(c);l=e instanceof Response?this.h(c,e):e&&e.__isJSX?await c.html(e):c.text("OK")}catch(t){this.p(c,"handler_error",t&&t.message),l=await this.j(c,t)}return e.cache&&"GET"===n.method&&200===l.status&&c.executionCtx.waitUntil(this.v(n,l.clone(),e.cache)),e.compress&&(l=this.T(n,l)),this.C(c,e.log),l}};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lengkapp/edge",
3
- "version": "0.0.45",
3
+ "version": "0.0.47",
4
4
  "description": "Edge framework used by Lengkapp",
5
5
  "main": "dist/edge-server.js",
6
6
  "types": "dist/edge-server.d.ts",