klaim 1.11.7 → 1.11.8
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/deno.json +1 -1
- package/dist/klaim.cjs +1 -1
- package/dist/klaim.es.js +282 -290
- package/dist/klaim.umd.js +1 -1
- package/package.json +4 -4
package/deno.json
CHANGED
package/dist/klaim.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var O=Object.defineProperty;var G=(n,t,e)=>t in n?O(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var o=(n,t,e)=>G(n,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function k(n){return n.replace(/([-_][a-z])/gi,t=>t.toUpperCase().replace("-","").replace("_","")).replace(/(^\w)/,t=>t.toLowerCase())}function M(n){return n.trim().replace(/^\/|\/$/g,"")}const j={limit:5,duration:10},A=new Map;function U(n,t){const e=Date.now(),a=t.duration*1e3;let r=A.get(n);r||(r={timestamps:[]},A.set(n,r));const i=r.timestamps.filter(s=>e-s<a);return i.length>=t.limit?!1:(i.push(e),r.timestamps=i,!0)}function I(n,t){const e=A.get(n);if(!e||e.timestamps.length<t.limit)return 0;const a=Date.now(),r=t.duration*1e3,l=[...e.timestamps].sort((u,p)=>u-p)[0]+r-a;return Math.max(0,l)}const b={duration:5,message:"Request timed out"};async function H(n,t){const{duration:e,message:a}=t;return Promise.race([n,new Promise((r,i)=>{const s=setTimeout(()=>{clearTimeout(s),i(new Error(a))},e*1e3)})])}const q={page:1,pageParam:"page",limit:10,limitParam:"limit"};class F{constructor(t,e,a,r={}){o(this,"type");o(this,"name");o(this,"url");o(this,"headers");o(this,"parent");o(this,"method");o(this,"arguments",new Set);o(this,"schema");o(this,"pagination");o(this,"callbacks",{before:null,after:null,call:null});o(this,"cache",!1);o(this,"retry",!1);o(this,"rate",!1);o(this,"timeout",!1);o(this,"withCache",(t=20)=>(this.cache=t,this));o(this,"withRetry",(t=2)=>(this.retry=t,this));o(this,"withRate",(t={})=>(this.rate={...j,...t},this));o(this,"withTimeout",(t=b.duration,e=b.message)=>(this.timeout={duration:t,message:e},this));this.type=t,this.name=k(e),this.name!==e&&console.warn(`Name "${e}" has been camelCased to "${this.name}"`),this.url=M(a),this.headers=r||{}}before(t){return this.callbacks.before=t,this}after(t){return this.callbacks.after=t,this}onCall(t){return this.callbacks.call=t,this}withPagination(t={}){return this.pagination={...q,...t},this}}const g=class g{constructor(){o(this,"cache");this.cache=new Map}static get i(){return g._instance||(g._instance=new g),g._instance}set(t,e,a=0){const r=Date.now()+a;this.cache.set(t,{data:e,expiry:r})}has(t){const e=this.cache.get(t);return e?Date.now()>e.expiry?(this.cache.delete(t),!1):!0:!1}get(t){return this.has(t)?this.cache.get(t).data:null}};o(g,"_instance");let y=g;function W(n){let a=2166136261;for(let i=0;i<n.length;i++)a^=n.charCodeAt(i),a*=16777619;let r=(a>>>0).toString(16).padStart(8,"0");for(;r.length<32;)a^=r.charCodeAt(r.length%r.length),a*=16777619,r+=(a>>>0).toString(16).padStart(8,"0");return r.substring(0,32)}async function J(n,t,e){const a=`${n.toString()}${JSON.stringify(t)}`,r=W(a);if(y.i.has(r))return y.i.get(r);const s=await(await fetch(n,t)).json();return y.i.set(r,s,e),s}class S{static subscribe(t,e){this._callbacks.set(t,e)}static run(t){const e=this._callbacks.get(t);e&&e()}}o(S,"_callbacks",new Map);const _={};function V(n,t){return async(...e)=>{if(t.pagination){const[i=0,s={},l={}]=e;return x(n,t,i,s,l)}const[a={},r={}]=e;return x(n,t,void 0,a,r)}}async function x(n,t,e,a={},r={}){const i=n.split(".");let s;for(let P=0;P<i.length;P++){const $=i[P];if(s=c.i.getApi($),s)break}if(!t||!s||t.type!=="route"||s.type!=="api")throw new Error(`Invalid path: ${n}.${t.name}`);let l=Q(`${s.url}/${t.url}`,t,a);if(t.pagination&&typeof e<"u"){const{pageParam:P="page",limit:$=10,limitParam:K="limit"}=t.pagination,T=new URLSearchParams;T.append(P,String(e)),T.append(K,String($));const L=l.includes("?")?"&":"?";l=`${l}${L}${T.toString()}`}let u={};r&&t.method!=="GET"&&(u.body=JSON.stringify(r)),u.headers={"Content-Type":"application/json",...s.headers,...t.headers},u.method=t.method;const{beforeRoute:p,beforeApi:C,beforeUrl:E,beforeConfig:h}=X({route:t,api:s,url:l,config:u});l=E,u=h,c.updateElement(C),c.updateElement(p);let m=await B(s,t,l,u);t.schema&&"validate"in t.schema&&(m=await t.schema.validate(m));const{afterRoute:d,afterApi:w,afterData:D}=Y({route:t,api:s,response:m,data:m});return c.updateElement(w),c.updateElement(d),S.run(`${s.name}.${t.name}`),D}async function z(n,t,e,a){return n?await J(t,e,a.cache):await(await fetch(t,e)).json()}async function B(n,t,e,a){var C,E;const r=n.cache||t.cache,i=t.retry||n.retry||0,s=t.timeout||n.timeout;if(t.rate){const h=`${n.name}.${t.name}`;if(!U(h,t.rate)){const d=I(h,t.rate),w=Math.ceil(d/1e3);throw new Error(`Rate limit exceeded for ${h}. Try again in ${w} seconds.`)}}else if(n.rate){const h=`${n.name}`;if(!U(h,n.rate)){const d=I(h,n.rate),w=Math.ceil(d/1e3);throw new Error(`Rate limit exceeded for ${n.name} API. Try again in ${w} seconds.`)}}let l,u=!1,p=0;for(;p<=i&&!u;)try{(C=t.callbacks)!=null&&C.call?t.callbacks.call({}):(E=n.callbacks)!=null&&E.call&&n.callbacks.call({});const h=z(!!r,e,a,n);l=s?await H(h,s):await h,u=!0}catch(h){if(p++,p>i)throw h.message||(h.message=`Failed to fetch ${e} after ${i} attempts`),h}return l}function Q(n,t,e){let a=n;return t.arguments.forEach(r=>{if(e[r]===void 0)throw new Error(`Argument ${r} is missing`);a=a.replace(`[${r}]`,e[r])}),a}function X({route:n,api:t,url:e,config:a}){var i,s;const r=(s=(i=n.callbacks).before)==null?void 0:s.call(i,{route:n,api:t,url:e,config:a});return{beforeRoute:(r==null?void 0:r.route)||n,beforeApi:(r==null?void 0:r.api)||t,beforeUrl:(r==null?void 0:r.url)||e,beforeConfig:(r==null?void 0:r.config)||a}}function Y({route:n,api:t,response:e,data:a}){var i,s;const r=(s=(i=n.callbacks).after)==null?void 0:s.call(i,{route:n,api:t,response:e,data:a});return{afterRoute:(r==null?void 0:r.route)||n,afterApi:(r==null?void 0:r.api)||t,afterResponse:(r==null?void 0:r.response)||e,afterData:(r==null?void 0:r.data)||a}}const f=class f{constructor(){o(this,"_elements",new Map);o(this,"_currentParent",null)}static get i(){return f._instance||(f._instance=new f),f._instance}registerElement(t){const e=this._currentParent;e&&(t.parent=this.getFullPath(e));const a=this.getElementKey(t);if(this._elements.set(a,t),t.type==="api"||t.type==="group"){let r=_;if(e){const i=this.getFullPath(e).split(".");for(const s of i)r[s]||(r[s]={}),r=r[s]}r[t.name]||(r[t.name]={})}}getCurrentParent(){return this._currentParent}setCurrentParent(t){const e=this._elements.get(t);if(!e||e.type!=="api"&&e.type!=="group")throw new Error(`Element ${t} not found or not a valid parent type`);this._currentParent=e}clearCurrentParent(){this._currentParent=null}registerRoute(t){if(!this._currentParent)throw new Error("No current parent set, use Route only inside Api or Group create callback");t.parent=this.getFullPath(this._currentParent);const e=this.getElementKey(t);this._elements.set(e,t),this.addToKlaimRoute(t)}addToKlaimRoute(t){if(!t.parent)return;let e=_;const a=t.parent.split(".");for(const r of a)e[r]||(e[r]={}),e=e[r];e[t.name]=V(t.parent,t)}getElementKey(t){return t?t.parent?`${t.parent}.${t.name}`:t.name:""}getFullPath(t){if(!t)return"";if(!t.parent)return t.name;const e=[t.name];let a=t;for(;a.parent;){const r=this._elements.get(a.parent);if(!r)break;e.unshift(r.name),a=r}return e.join(".")}getRoute(t,e){return this._elements.get(`${t}.${e}`)}getChildren(t){const e=[];return this._elements.forEach(a=>{a.parent===t&&e.push(a)}),e}static updateElement(t){return f.i._elements.get(f.i.getElementKey(t))||t}getApi(t){const e=this._elements.get(t);if(!e){for(const[a,r]of this._elements.entries())if(r.type==="api"&&a.endsWith(`.${t}`))return r;return}return e.type==="api"?e:this.findApi(e)}findApi(t){if(!t||!t.parent)return;const e=t.parent.split(".");for(let a=e.length;a>=0;a--){const r=e.slice(0,a).join("."),i=this._elements.get(r);if((i==null?void 0:i.type)==="api")return i}}};o(f,"_instance");let c=f;class R extends F{static create(t,e,a,r={}){const i=k(t);i!==t&&console.warn(`API name "${t}" has been camelCased to "${i}"`);const s=new R(i,e,r),l=c.i.getCurrentParent();c.i.registerElement(s);const u=l?c.i.getFullPath(l):"",p=u?`${u}.${i}`:i;return c.i.setCurrentParent(p),a(),l?c.i.setCurrentParent(c.i.getFullPath(l)):c.i.clearCurrentParent(),s}constructor(t,e,a={}){super("api",t,e,a)}}class v extends F{static create(t,e){const a=k(t),r=c.i.getCurrentParent(),i=r?c.i.getFullPath(r):"",s=i?`${i}.${a}`:a,l=new v(a,"");a!==t&&console.warn(`Group name "${t}" has been camelCased to "${a}"`),c.i.registerElement(l);const u=c.i.getCurrentParent();return c.i.setCurrentParent(s),e(),u?c.i.setCurrentParent(c.i.getFullPath(u)):c.i.clearCurrentParent(),l}constructor(t,e,a={}){super("group",t,e,a)}withCache(t=20){return super.withCache(t),c.i.getChildren(c.i.getFullPath(this)).forEach(e=>{e.cache||(e.cache=t)}),this}withRetry(t=2){return super.withRetry(t),c.i.getChildren(c.i.getFullPath(this)).forEach(e=>{e.retry||(e.retry=t)}),this}withTimeout(t=b.duration,e=b.message){return super.withTimeout(t,e),c.i.getChildren(c.i.getFullPath(this)).forEach(a=>{a.timeout||(a.timeout={duration:t,message:e})}),this}before(t){return super.before(t),c.i.getChildren(c.i.getFullPath(this)).forEach(e=>{e.callbacks.before||(e.callbacks.before=t)}),this}after(t){return super.after(t),c.i.getChildren(c.i.getFullPath(this)).forEach(e=>{e.callbacks.after||(e.callbacks.after=t)}),this}onCall(t){return super.onCall(t),c.i.getChildren(c.i.getFullPath(this)).forEach(e=>{e.callbacks.call||(e.callbacks.call=t)}),this}}class N extends F{constructor(t,e,a={},r="GET"){super("route",t,e,a),this.method=r,this.detectArguments()}static createRoute(t,e,a={},r){const i=new N(t,e,a,r);return c.i.registerRoute(i),i}static get(t,e,a={}){return this.createRoute(t,e,a,"GET")}static post(t,e,a={}){return this.createRoute(t,e,a,"POST")}static put(t,e,a={}){return this.createRoute(t,e,a,"PUT")}static delete(t,e,a={}){return this.createRoute(t,e,a,"DELETE")}static patch(t,e,a={}){return this.createRoute(t,e,a,"PATCH")}static options(t,e,a={}){return this.createRoute(t,e,a,"OPTIONS")}detectArguments(){const t=this.url.match(/\[([^\]]+)]/g);t&&t.forEach(e=>{const a=e.replace("[","").replace("]","");this.arguments.add(a)})}validate(t){return this.schema=t,this}}exports.Api=R;exports.Group=v;exports.Hook=S;exports.Klaim=_;exports.Registry=c;exports.Route=N;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function C(n){return n.replace(/([-_][a-z])/gi,t=>t.toUpperCase().replace("-","").replace("_","")).replace(/(^\w)/,t=>t.toLowerCase())}function D(n){return n.trim().replace(/^\/|\/$/g,"")}const K={limit:5,duration:10},b=new Map;function _(n,t){const e=Date.now(),r=t.duration*1e3;let a=b.get(n);a||(a={timestamps:[]},b.set(n,a));const i=a.timestamps.filter(c=>e-c<r);return i.length>=t.limit?!1:(i.push(e),a.timestamps=i,!0)}function k(n,t){const e=b.get(n);if(!e||e.timestamps.length<t.limit)return 0;const r=Date.now(),a=t.duration*1e3,o=[...e.timestamps].sort((l,h)=>l-h)[0]+a-r;return Math.max(0,o)}const d={duration:5,message:"Request timed out"};async function L(n,t){const{duration:e,message:r}=t;return Promise.race([n,new Promise((a,i)=>{const c=setTimeout(()=>{clearTimeout(c),i(new Error(r))},e*1e3)})])}const O={page:1,pageParam:"page",limit:10,limitParam:"limit"};class ${type;name;url;headers;parent;method;arguments=new Set;schema;pagination;callbacks={before:null,after:null,call:null};cache=!1;retry=!1;rate=!1;timeout=!1;constructor(t,e,r,a={}){this.type=t,this.name=C(e),this.name!==e&&console.warn(`Name "${e}" has been camelCased to "${this.name}"`),this.url=D(r),this.headers=a||{}}before(t){return this.callbacks.before=t,this}after(t){return this.callbacks.after=t,this}onCall(t){return this.callbacks.call=t,this}withCache=(t=20)=>(this.cache=t,this);withRetry=(t=2)=>(this.retry=t,this);withPagination(t={}){return this.pagination={...O,...t},this}withRate=(t={})=>(this.rate={...K,...t},this);withTimeout=(t=d.duration,e=d.message)=>(this.timeout={duration:t,message:e},this)}class p{static _instance;cache;constructor(){this.cache=new Map}static get i(){return p._instance||(p._instance=new p),p._instance}set(t,e,r=0){const a=Date.now()+r;this.cache.set(t,{data:e,expiry:a})}has(t){const e=this.cache.get(t);return e?Date.now()>e.expiry?(this.cache.delete(t),!1):!0:!1}get(t){return this.has(t)?this.cache.get(t).data:null}}function G(n){let r=2166136261;for(let i=0;i<n.length;i++)r^=n.charCodeAt(i),r*=16777619;let a=(r>>>0).toString(16).padStart(8,"0");for(;a.length<32;)r^=a.charCodeAt(a.length%a.length),r*=16777619,a+=(r>>>0).toString(16).padStart(8,"0");return a.substring(0,32)}async function M(n,t,e){const r=`${n.toString()}${JSON.stringify(t)}`,a=G(r);if(p.i.has(a))return p.i.get(a);const c=await(await fetch(n,t)).json();return p.i.set(a,c,e),c}class S{static _callbacks=new Map;static subscribe(t,e){this._callbacks.set(t,e)}static run(t){const e=this._callbacks.get(t);e&&e()}}const E={};function H(n,t){return async(...e)=>{if(t.pagination){const[i=0,c={},o={}]=e;return F(n,t,i,c,o)}const[r={},a={}]=e;return F(n,t,void 0,r,a)}}async function F(n,t,e,r={},a={}){const i=n.split(".");let c;for(let g=0;g<i.length;g++){const P=i[g];if(c=s.i.getApi(P),c)break}if(!t||!c||t.type!=="route"||c.type!=="api")throw new Error(`Invalid path: ${n}.${t.name}`);let o=W(`${c.url}/${t.url}`,t,r);if(t.pagination&&typeof e<"u"){const{pageParam:g="page",limit:P=10,limitParam:I="limit"}=t.pagination,y=new URLSearchParams;y.append(g,String(e)),y.append(I,String(P));const x=o.includes("?")?"&":"?";o=`${o}${x}${y.toString()}`}let l={};a&&t.method!=="GET"&&(l.body=JSON.stringify(a)),l.headers={"Content-Type":"application/json",...c.headers,...t.headers},l.method=t.method;const{beforeRoute:h,beforeApi:u,beforeUrl:w,beforeConfig:m}=J({route:t,api:c,url:o,config:l});o=w,l=m,s.updateElement(u),s.updateElement(h);let f=await q(c,t,o,l);t.schema&&"validate"in t.schema&&(f=await t.schema.validate(f));const{afterRoute:v,afterApi:N,afterData:U}=V({route:t,api:c,response:f,data:f});return s.updateElement(N),s.updateElement(v),S.run(`${c.name}.${t.name}`),U}async function j(n,t,e,r){return n?await M(t,e,r.cache):await(await fetch(t,e)).json()}async function q(n,t,e,r){const a=n.cache||t.cache,i=t.retry||n.retry||0,c=t.timeout||n.timeout;if(t.rate){const u=`${n.name}.${t.name}`;if(!_(u,t.rate)){const m=k(u,t.rate),f=Math.ceil(m/1e3);throw new Error(`Rate limit exceeded for ${u}. Try again in ${f} seconds.`)}}else if(n.rate){const u=`${n.name}`;if(!_(u,n.rate)){const m=k(u,n.rate),f=Math.ceil(m/1e3);throw new Error(`Rate limit exceeded for ${n.name} API. Try again in ${f} seconds.`)}}let o,l=!1,h=0;for(;h<=i&&!l;)try{t.callbacks?.call?t.callbacks.call({}):n.callbacks?.call&&n.callbacks.call({});const u=j(!!a,e,r,n);o=c?await L(u,c):await u,l=!0}catch(u){if(h++,h>i)throw u.message||(u.message=`Failed to fetch ${e} after ${i} attempts`),u}return o}function W(n,t,e){let r=n;return t.arguments.forEach(a=>{if(e[a]===void 0)throw new Error(`Argument ${a} is missing`);r=r.replace(`[${a}]`,e[a])}),r}function J({route:n,api:t,url:e,config:r}){const a=n.callbacks.before?.({route:n,api:t,url:e,config:r});return{beforeRoute:a?.route||n,beforeApi:a?.api||t,beforeUrl:a?.url||e,beforeConfig:a?.config||r}}function V({route:n,api:t,response:e,data:r}){const a=n.callbacks.after?.({route:n,api:t,response:e,data:r});return{afterRoute:a?.route||n,afterApi:a?.api||t,afterResponse:a?.response||e,afterData:a?.data||r}}class s{static _instance;_elements=new Map;_currentParent=null;constructor(){}static get i(){return s._instance||(s._instance=new s),s._instance}registerElement(t){const e=this._currentParent;e&&(t.parent=this.getFullPath(e));const r=this.getElementKey(t);if(this._elements.set(r,t),t.type==="api"||t.type==="group"){let a=E;if(e){const i=this.getFullPath(e).split(".");for(const c of i)a[c]||(a[c]={}),a=a[c]}a[t.name]||(a[t.name]={})}}getCurrentParent(){return this._currentParent}setCurrentParent(t){const e=this._elements.get(t);if(!e||e.type!=="api"&&e.type!=="group")throw new Error(`Element ${t} not found or not a valid parent type`);this._currentParent=e}clearCurrentParent(){this._currentParent=null}registerRoute(t){if(!this._currentParent)throw new Error("No current parent set, use Route only inside Api or Group create callback");t.parent=this.getFullPath(this._currentParent);const e=this.getElementKey(t);this._elements.set(e,t),this.addToKlaimRoute(t)}addToKlaimRoute(t){if(!t.parent)return;let e=E;const r=t.parent.split(".");for(const a of r)e[a]||(e[a]={}),e=e[a];e[t.name]=H(t.parent,t)}getElementKey(t){return t?t.parent?`${t.parent}.${t.name}`:t.name:""}getFullPath(t){if(!t)return"";if(!t.parent)return t.name;const e=[t.name];let r=t;for(;r.parent;){const a=this._elements.get(r.parent);if(!a)break;e.unshift(a.name),r=a}return e.join(".")}getRoute(t,e){return this._elements.get(`${t}.${e}`)}getChildren(t){const e=[];return this._elements.forEach(r=>{r.parent===t&&e.push(r)}),e}static updateElement(t){return s.i._elements.get(s.i.getElementKey(t))||t}getApi(t){const e=this._elements.get(t);if(!e){for(const[r,a]of this._elements.entries())if(a.type==="api"&&r.endsWith(`.${t}`))return a;return}return e.type==="api"?e:this.findApi(e)}findApi(t){if(!t||!t.parent)return;const e=t.parent.split(".");for(let r=e.length;r>=0;r--){const a=e.slice(0,r).join("."),i=this._elements.get(a);if(i?.type==="api")return i}}}class T extends ${static create(t,e,r,a={}){const i=C(t);i!==t&&console.warn(`API name "${t}" has been camelCased to "${i}"`);const c=new T(i,e,a),o=s.i.getCurrentParent();s.i.registerElement(c);const l=o?s.i.getFullPath(o):"",h=l?`${l}.${i}`:i;return s.i.setCurrentParent(h),r(),o?s.i.setCurrentParent(s.i.getFullPath(o)):s.i.clearCurrentParent(),c}constructor(t,e,r={}){super("api",t,e,r)}}class R extends ${static create(t,e){const r=C(t),a=s.i.getCurrentParent(),i=a?s.i.getFullPath(a):"",c=i?`${i}.${r}`:r,o=new R(r,"");r!==t&&console.warn(`Group name "${t}" has been camelCased to "${r}"`),s.i.registerElement(o);const l=s.i.getCurrentParent();return s.i.setCurrentParent(c),e(),l?s.i.setCurrentParent(s.i.getFullPath(l)):s.i.clearCurrentParent(),o}constructor(t,e,r={}){super("group",t,e,r)}withCache(t=20){return super.withCache(t),s.i.getChildren(s.i.getFullPath(this)).forEach(e=>{e.cache||(e.cache=t)}),this}withRetry(t=2){return super.withRetry(t),s.i.getChildren(s.i.getFullPath(this)).forEach(e=>{e.retry||(e.retry=t)}),this}withTimeout(t=d.duration,e=d.message){return super.withTimeout(t,e),s.i.getChildren(s.i.getFullPath(this)).forEach(r=>{r.timeout||(r.timeout={duration:t,message:e})}),this}before(t){return super.before(t),s.i.getChildren(s.i.getFullPath(this)).forEach(e=>{e.callbacks.before||(e.callbacks.before=t)}),this}after(t){return super.after(t),s.i.getChildren(s.i.getFullPath(this)).forEach(e=>{e.callbacks.after||(e.callbacks.after=t)}),this}onCall(t){return super.onCall(t),s.i.getChildren(s.i.getFullPath(this)).forEach(e=>{e.callbacks.call||(e.callbacks.call=t)}),this}}class A extends ${constructor(t,e,r={},a="GET"){super("route",t,e,r),this.method=a,this.detectArguments()}static createRoute(t,e,r={},a){const i=new A(t,e,r,a);return s.i.registerRoute(i),i}static get(t,e,r={}){return this.createRoute(t,e,r,"GET")}static post(t,e,r={}){return this.createRoute(t,e,r,"POST")}static put(t,e,r={}){return this.createRoute(t,e,r,"PUT")}static delete(t,e,r={}){return this.createRoute(t,e,r,"DELETE")}static patch(t,e,r={}){return this.createRoute(t,e,r,"PATCH")}static options(t,e,r={}){return this.createRoute(t,e,r,"OPTIONS")}detectArguments(){const t=this.url.match(/\[([^\]]+)]/g);t&&t.forEach(e=>{const r=e.replace("[","").replace("]","");this.arguments.add(r)})}validate(t){return this.schema=t,this}}exports.Api=T;exports.Group=R;exports.Hook=S;exports.Klaim=E;exports.Registry=s;exports.Route=A;
|
package/dist/klaim.es.js
CHANGED
|
@@ -1,53 +1,68 @@
|
|
|
1
|
-
|
|
2
|
-
var G = (n, t, e) => t in n ? O(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
|
|
3
|
-
var o = (n, t, e) => G(n, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
-
function _(n) {
|
|
1
|
+
function E(n) {
|
|
5
2
|
return n.replace(/([-_][a-z])/gi, (t) => t.toUpperCase().replace("-", "").replace("_", "")).replace(/(^\w)/, (t) => t.toLowerCase());
|
|
6
3
|
}
|
|
7
|
-
function
|
|
4
|
+
function I(n) {
|
|
8
5
|
return n.trim().replace(/^\/|\/$/g, "");
|
|
9
6
|
}
|
|
10
|
-
const
|
|
7
|
+
const D = {
|
|
11
8
|
limit: 5,
|
|
12
9
|
duration: 10
|
|
13
10
|
// seconds
|
|
14
|
-
},
|
|
15
|
-
function
|
|
16
|
-
const e = Date.now(),
|
|
17
|
-
let
|
|
18
|
-
|
|
19
|
-
const i =
|
|
20
|
-
return i.length >= t.limit ? !1 : (i.push(e),
|
|
11
|
+
}, b = /* @__PURE__ */ new Map();
|
|
12
|
+
function $(n, t) {
|
|
13
|
+
const e = Date.now(), r = t.duration * 1e3;
|
|
14
|
+
let a = b.get(n);
|
|
15
|
+
a || (a = { timestamps: [] }, b.set(n, a));
|
|
16
|
+
const i = a.timestamps.filter((c) => e - c < r);
|
|
17
|
+
return i.length >= t.limit ? !1 : (i.push(e), a.timestamps = i, !0);
|
|
21
18
|
}
|
|
22
|
-
function
|
|
23
|
-
const e =
|
|
19
|
+
function T(n, t) {
|
|
20
|
+
const e = b.get(n);
|
|
24
21
|
if (!e || e.timestamps.length < t.limit)
|
|
25
22
|
return 0;
|
|
26
|
-
const
|
|
27
|
-
return Math.max(0,
|
|
23
|
+
const r = Date.now(), a = t.duration * 1e3, o = [...e.timestamps].sort((l, h) => l - h)[0] + a - r;
|
|
24
|
+
return Math.max(0, o);
|
|
28
25
|
}
|
|
29
|
-
const
|
|
26
|
+
const d = {
|
|
30
27
|
duration: 5,
|
|
31
28
|
message: "Request timed out"
|
|
32
29
|
};
|
|
33
|
-
async function
|
|
34
|
-
const { duration: e, message:
|
|
30
|
+
async function L(n, t) {
|
|
31
|
+
const { duration: e, message: r } = t;
|
|
35
32
|
return Promise.race([
|
|
36
33
|
n,
|
|
37
|
-
new Promise((
|
|
38
|
-
const
|
|
39
|
-
clearTimeout(
|
|
34
|
+
new Promise((a, i) => {
|
|
35
|
+
const c = setTimeout(() => {
|
|
36
|
+
clearTimeout(c), i(new Error(r));
|
|
40
37
|
}, e * 1e3);
|
|
41
38
|
})
|
|
42
39
|
]);
|
|
43
40
|
}
|
|
44
|
-
const
|
|
41
|
+
const K = {
|
|
45
42
|
page: 1,
|
|
46
43
|
pageParam: "page",
|
|
47
44
|
limit: 10,
|
|
48
45
|
limitParam: "limit"
|
|
49
46
|
};
|
|
50
|
-
class
|
|
47
|
+
class C {
|
|
48
|
+
type;
|
|
49
|
+
name;
|
|
50
|
+
url;
|
|
51
|
+
headers;
|
|
52
|
+
parent;
|
|
53
|
+
method;
|
|
54
|
+
arguments = /* @__PURE__ */ new Set();
|
|
55
|
+
schema;
|
|
56
|
+
pagination;
|
|
57
|
+
callbacks = {
|
|
58
|
+
before: null,
|
|
59
|
+
after: null,
|
|
60
|
+
call: null
|
|
61
|
+
};
|
|
62
|
+
cache = !1;
|
|
63
|
+
retry = !1;
|
|
64
|
+
rate = !1;
|
|
65
|
+
timeout = !1;
|
|
51
66
|
/**
|
|
52
67
|
* Creates a new element with the specified properties
|
|
53
68
|
*
|
|
@@ -56,62 +71,8 @@ class k {
|
|
|
56
71
|
* @param {string} url - Base URL or path segment
|
|
57
72
|
* @param {IHeaders} [headers] - HTTP headers for the element
|
|
58
73
|
*/
|
|
59
|
-
constructor(t, e,
|
|
60
|
-
|
|
61
|
-
o(this, "name");
|
|
62
|
-
o(this, "url");
|
|
63
|
-
o(this, "headers");
|
|
64
|
-
o(this, "parent");
|
|
65
|
-
o(this, "method");
|
|
66
|
-
o(this, "arguments", /* @__PURE__ */ new Set());
|
|
67
|
-
o(this, "schema");
|
|
68
|
-
o(this, "pagination");
|
|
69
|
-
o(this, "callbacks", {
|
|
70
|
-
before: null,
|
|
71
|
-
after: null,
|
|
72
|
-
call: null
|
|
73
|
-
});
|
|
74
|
-
o(this, "cache", !1);
|
|
75
|
-
o(this, "retry", !1);
|
|
76
|
-
o(this, "rate", !1);
|
|
77
|
-
o(this, "timeout", !1);
|
|
78
|
-
/**
|
|
79
|
-
* Enables response caching for this element
|
|
80
|
-
*
|
|
81
|
-
* @param {number} [duration] - Cache duration in seconds
|
|
82
|
-
* @returns {this} The element instance for chaining
|
|
83
|
-
*/
|
|
84
|
-
o(this, "withCache", (t = 20) => (this.cache = t, this));
|
|
85
|
-
/**
|
|
86
|
-
* Enables request retries for this element
|
|
87
|
-
*
|
|
88
|
-
* @param {number} [maxRetries] - Maximum number of retry attempts
|
|
89
|
-
* @returns {this} The element instance for chaining
|
|
90
|
-
*/
|
|
91
|
-
o(this, "withRetry", (t = 2) => (this.retry = t, this));
|
|
92
|
-
/**
|
|
93
|
-
* Enables rate limiting for this element
|
|
94
|
-
*
|
|
95
|
-
* @param {Partial<IRateLimitConfig>} [config] - Rate limiting configuration options
|
|
96
|
-
* @returns {this} The element instance for chaining
|
|
97
|
-
* @example
|
|
98
|
-
* ```typescript
|
|
99
|
-
* Route.get("getUser", "/users/[id]").withRate({ limit: 5, duration: 10 });
|
|
100
|
-
* ```
|
|
101
|
-
*/
|
|
102
|
-
o(this, "withRate", (t = {}) => (this.rate = {
|
|
103
|
-
...j,
|
|
104
|
-
...t
|
|
105
|
-
}, this));
|
|
106
|
-
/**
|
|
107
|
-
* Enables request timeout for this element
|
|
108
|
-
*
|
|
109
|
-
* @param {number} [duration] - Timeout duration in seconds
|
|
110
|
-
* @param {string} [message] - Custom error message
|
|
111
|
-
* @returns {this} The element instance for chaining
|
|
112
|
-
*/
|
|
113
|
-
o(this, "withTimeout", (t = $.duration, e = $.message) => (this.timeout = { duration: t, message: e }, this));
|
|
114
|
-
this.type = t, this.name = _(e), this.name !== e && console.warn(`Name "${e}" has been camelCased to "${this.name}"`), this.url = M(a), this.headers = r || {};
|
|
74
|
+
constructor(t, e, r, a = {}) {
|
|
75
|
+
this.type = t, this.name = E(e), this.name !== e && console.warn(`Name "${e}" has been camelCased to "${this.name}"`), this.url = I(r), this.headers = a || {};
|
|
115
76
|
}
|
|
116
77
|
/**
|
|
117
78
|
* Adds a before-request middleware callback
|
|
@@ -140,6 +101,20 @@ class k {
|
|
|
140
101
|
onCall(t) {
|
|
141
102
|
return this.callbacks.call = t, this;
|
|
142
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Enables response caching for this element
|
|
106
|
+
*
|
|
107
|
+
* @param {number} [duration] - Cache duration in seconds
|
|
108
|
+
* @returns {this} The element instance for chaining
|
|
109
|
+
*/
|
|
110
|
+
withCache = (t = 20) => (this.cache = t, this);
|
|
111
|
+
/**
|
|
112
|
+
* Enables request retries for this element
|
|
113
|
+
*
|
|
114
|
+
* @param {number} [maxRetries] - Maximum number of retry attempts
|
|
115
|
+
* @returns {this} The element instance for chaining
|
|
116
|
+
*/
|
|
117
|
+
withRetry = (t = 2) => (this.retry = t, this);
|
|
143
118
|
/**
|
|
144
119
|
* Configures pagination settings for this element
|
|
145
120
|
*
|
|
@@ -157,12 +132,47 @@ class k {
|
|
|
157
132
|
*/
|
|
158
133
|
withPagination(t = {}) {
|
|
159
134
|
return this.pagination = {
|
|
160
|
-
...
|
|
135
|
+
...K,
|
|
161
136
|
...t
|
|
162
137
|
}, this;
|
|
163
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* Enables rate limiting for this element
|
|
141
|
+
*
|
|
142
|
+
* @param {Partial<IRateLimitConfig>} [config] - Rate limiting configuration options
|
|
143
|
+
* @returns {this} The element instance for chaining
|
|
144
|
+
* @example
|
|
145
|
+
* ```typescript
|
|
146
|
+
* Route.get("getUser", "/users/[id]").withRate({ limit: 5, duration: 10 });
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
withRate = (t = {}) => (this.rate = {
|
|
150
|
+
...D,
|
|
151
|
+
...t
|
|
152
|
+
}, this);
|
|
153
|
+
/**
|
|
154
|
+
* Enables request timeout for this element
|
|
155
|
+
*
|
|
156
|
+
* @param {number} [duration] - Timeout duration in seconds
|
|
157
|
+
* @param {string} [message] - Custom error message
|
|
158
|
+
* @returns {this} The element instance for chaining
|
|
159
|
+
*/
|
|
160
|
+
withTimeout = (t = d.duration, e = d.message) => (this.timeout = { duration: t, message: e }, this);
|
|
164
161
|
}
|
|
165
|
-
|
|
162
|
+
class p {
|
|
163
|
+
/**
|
|
164
|
+
* The singleton instance of the Cache class.
|
|
165
|
+
*
|
|
166
|
+
* @private
|
|
167
|
+
*/
|
|
168
|
+
static _instance;
|
|
169
|
+
/**
|
|
170
|
+
* Internal storage for cached items.
|
|
171
|
+
* Maps keys to objects containing the data and expiration timestamp.
|
|
172
|
+
*
|
|
173
|
+
* @private
|
|
174
|
+
*/
|
|
175
|
+
cache;
|
|
166
176
|
/**
|
|
167
177
|
* Private constructor to enforce singleton pattern.
|
|
168
178
|
* Initializes an empty cache storage.
|
|
@@ -170,13 +180,6 @@ const g = class g {
|
|
|
170
180
|
* @private
|
|
171
181
|
*/
|
|
172
182
|
constructor() {
|
|
173
|
-
/**
|
|
174
|
-
* Internal storage for cached items.
|
|
175
|
-
* Maps keys to objects containing the data and expiration timestamp.
|
|
176
|
-
*
|
|
177
|
-
* @private
|
|
178
|
-
*/
|
|
179
|
-
o(this, "cache");
|
|
180
183
|
this.cache = /* @__PURE__ */ new Map();
|
|
181
184
|
}
|
|
182
185
|
/**
|
|
@@ -190,7 +193,7 @@ const g = class g {
|
|
|
190
193
|
* ```
|
|
191
194
|
*/
|
|
192
195
|
static get i() {
|
|
193
|
-
return
|
|
196
|
+
return p._instance || (p._instance = new p()), p._instance;
|
|
194
197
|
}
|
|
195
198
|
/**
|
|
196
199
|
* Stores a value in the cache with an optional time-to-live duration.
|
|
@@ -207,9 +210,9 @@ const g = class g {
|
|
|
207
210
|
* Cache.i.set("appConfig", configData);
|
|
208
211
|
* ```
|
|
209
212
|
*/
|
|
210
|
-
set(t, e,
|
|
211
|
-
const
|
|
212
|
-
this.cache.set(t, { data: e, expiry:
|
|
213
|
+
set(t, e, r = 0) {
|
|
214
|
+
const a = Date.now() + r;
|
|
215
|
+
this.cache.set(t, { data: e, expiry: a });
|
|
213
216
|
}
|
|
214
217
|
/**
|
|
215
218
|
* Checks if the cache contains a valid (non-expired) entry for the given key.
|
|
@@ -247,31 +250,31 @@ const g = class g {
|
|
|
247
250
|
get(t) {
|
|
248
251
|
return this.has(t) ? this.cache.get(t).data : null;
|
|
249
252
|
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
*
|
|
254
|
-
* @private
|
|
255
|
-
*/
|
|
256
|
-
o(g, "_instance");
|
|
257
|
-
let y = g;
|
|
258
|
-
function W(n) {
|
|
259
|
-
let a = 2166136261;
|
|
253
|
+
}
|
|
254
|
+
function O(n) {
|
|
255
|
+
let r = 2166136261;
|
|
260
256
|
for (let i = 0; i < n.length; i++)
|
|
261
|
-
|
|
262
|
-
let
|
|
263
|
-
for (;
|
|
264
|
-
|
|
265
|
-
return
|
|
257
|
+
r ^= n.charCodeAt(i), r *= 16777619;
|
|
258
|
+
let a = (r >>> 0).toString(16).padStart(8, "0");
|
|
259
|
+
for (; a.length < 32; )
|
|
260
|
+
r ^= a.charCodeAt(a.length % a.length), r *= 16777619, a += (r >>> 0).toString(16).padStart(8, "0");
|
|
261
|
+
return a.substring(0, 32);
|
|
266
262
|
}
|
|
267
|
-
async function
|
|
268
|
-
const
|
|
269
|
-
if (
|
|
270
|
-
return
|
|
271
|
-
const
|
|
272
|
-
return
|
|
263
|
+
async function G(n, t, e) {
|
|
264
|
+
const r = `${n.toString()}${JSON.stringify(t)}`, a = O(r);
|
|
265
|
+
if (p.i.has(a))
|
|
266
|
+
return p.i.get(a);
|
|
267
|
+
const c = await (await fetch(n, t)).json();
|
|
268
|
+
return p.i.set(a, c, e), c;
|
|
273
269
|
}
|
|
274
|
-
class
|
|
270
|
+
class M {
|
|
271
|
+
/**
|
|
272
|
+
* Internal storage for hook callbacks.
|
|
273
|
+
* Maps route names to their corresponding callback functions.
|
|
274
|
+
*
|
|
275
|
+
* @private
|
|
276
|
+
*/
|
|
277
|
+
static _callbacks = /* @__PURE__ */ new Map();
|
|
275
278
|
/**
|
|
276
279
|
* Registers a callback function for a specific route.
|
|
277
280
|
* If a callback already exists for the route, it will be replaced.
|
|
@@ -307,142 +310,133 @@ class v {
|
|
|
307
310
|
e && e();
|
|
308
311
|
}
|
|
309
312
|
}
|
|
310
|
-
/**
|
|
311
|
-
* Internal storage for hook callbacks.
|
|
312
|
-
* Maps route names to their corresponding callback functions.
|
|
313
|
-
*
|
|
314
|
-
* @private
|
|
315
|
-
*/
|
|
316
|
-
o(v, "_callbacks", /* @__PURE__ */ new Map());
|
|
317
313
|
const R = {};
|
|
318
|
-
function
|
|
314
|
+
function H(n, t) {
|
|
319
315
|
return async (...e) => {
|
|
320
316
|
if (t.pagination) {
|
|
321
317
|
const [
|
|
322
318
|
i = 0,
|
|
323
|
-
|
|
324
|
-
|
|
319
|
+
c = {},
|
|
320
|
+
o = {}
|
|
325
321
|
] = e;
|
|
326
|
-
return
|
|
322
|
+
return A(n, t, i, c, o);
|
|
327
323
|
}
|
|
328
|
-
const [
|
|
329
|
-
return
|
|
324
|
+
const [r = {}, a = {}] = e;
|
|
325
|
+
return A(n, t, void 0, r, a);
|
|
330
326
|
};
|
|
331
327
|
}
|
|
332
|
-
async function
|
|
328
|
+
async function A(n, t, e, r = {}, a = {}) {
|
|
333
329
|
const i = n.split(".");
|
|
334
|
-
let
|
|
335
|
-
for (let
|
|
336
|
-
const
|
|
337
|
-
if (
|
|
330
|
+
let c;
|
|
331
|
+
for (let g = 0; g < i.length; g++) {
|
|
332
|
+
const P = i[g];
|
|
333
|
+
if (c = s.i.getApi(P), c) break;
|
|
338
334
|
}
|
|
339
|
-
if (!t || !
|
|
335
|
+
if (!t || !c || t.type !== "route" || c.type !== "api")
|
|
340
336
|
throw new Error(`Invalid path: ${n}.${t.name}`);
|
|
341
|
-
let
|
|
337
|
+
let o = W(`${c.url}/${t.url}`, t, r);
|
|
342
338
|
if (t.pagination && typeof e < "u") {
|
|
343
|
-
const { pageParam:
|
|
344
|
-
|
|
345
|
-
const
|
|
346
|
-
|
|
339
|
+
const { pageParam: g = "page", limit: P = 10, limitParam: U = "limit" } = t.pagination, y = new URLSearchParams();
|
|
340
|
+
y.append(g, String(e)), y.append(U, String(P));
|
|
341
|
+
const x = o.includes("?") ? "&" : "?";
|
|
342
|
+
o = `${o}${x}${y.toString()}`;
|
|
347
343
|
}
|
|
348
|
-
let
|
|
349
|
-
|
|
344
|
+
let l = {};
|
|
345
|
+
a && t.method !== "GET" && (l.body = JSON.stringify(a)), l.headers = {
|
|
350
346
|
"Content-Type": "application/json",
|
|
351
|
-
...
|
|
347
|
+
...c.headers,
|
|
352
348
|
...t.headers
|
|
353
|
-
},
|
|
349
|
+
}, l.method = t.method;
|
|
354
350
|
const {
|
|
355
|
-
beforeRoute:
|
|
356
|
-
beforeApi:
|
|
357
|
-
beforeUrl:
|
|
358
|
-
beforeConfig:
|
|
359
|
-
} =
|
|
360
|
-
|
|
361
|
-
let
|
|
362
|
-
t.schema && "validate" in t.schema && (
|
|
351
|
+
beforeRoute: h,
|
|
352
|
+
beforeApi: u,
|
|
353
|
+
beforeUrl: w,
|
|
354
|
+
beforeConfig: m
|
|
355
|
+
} = J({ route: t, api: c, url: o, config: l });
|
|
356
|
+
o = w, l = m, s.updateElement(u), s.updateElement(h);
|
|
357
|
+
let f = await q(c, t, o, l);
|
|
358
|
+
t.schema && "validate" in t.schema && (f = await t.schema.validate(f));
|
|
363
359
|
const {
|
|
364
|
-
afterRoute:
|
|
365
|
-
afterApi:
|
|
366
|
-
afterData:
|
|
367
|
-
} =
|
|
368
|
-
return
|
|
360
|
+
afterRoute: S,
|
|
361
|
+
afterApi: N,
|
|
362
|
+
afterData: v
|
|
363
|
+
} = V({ route: t, api: c, response: f, data: f });
|
|
364
|
+
return s.updateElement(N), s.updateElement(S), M.run(`${c.name}.${t.name}`), v;
|
|
369
365
|
}
|
|
370
|
-
async function
|
|
371
|
-
return n ? await
|
|
366
|
+
async function j(n, t, e, r) {
|
|
367
|
+
return n ? await G(t, e, r.cache) : await (await fetch(t, e)).json();
|
|
372
368
|
}
|
|
373
|
-
async function
|
|
374
|
-
|
|
375
|
-
const r = n.cache || t.cache, i = t.retry || n.retry || 0, s = t.timeout || n.timeout;
|
|
369
|
+
async function q(n, t, e, r) {
|
|
370
|
+
const a = n.cache || t.cache, i = t.retry || n.retry || 0, c = t.timeout || n.timeout;
|
|
376
371
|
if (t.rate) {
|
|
377
|
-
const
|
|
378
|
-
if (
|
|
379
|
-
const
|
|
380
|
-
throw new Error(`Rate limit exceeded for ${
|
|
372
|
+
const u = `${n.name}.${t.name}`;
|
|
373
|
+
if (!$(u, t.rate)) {
|
|
374
|
+
const m = T(u, t.rate), f = Math.ceil(m / 1e3);
|
|
375
|
+
throw new Error(`Rate limit exceeded for ${u}. Try again in ${f} seconds.`);
|
|
381
376
|
}
|
|
382
377
|
} else if (n.rate) {
|
|
383
|
-
const
|
|
384
|
-
if (
|
|
385
|
-
const
|
|
386
|
-
throw new Error(`Rate limit exceeded for ${n.name} API. Try again in ${
|
|
378
|
+
const u = `${n.name}`;
|
|
379
|
+
if (!$(u, n.rate)) {
|
|
380
|
+
const m = T(u, n.rate), f = Math.ceil(m / 1e3);
|
|
381
|
+
throw new Error(`Rate limit exceeded for ${n.name} API. Try again in ${f} seconds.`);
|
|
387
382
|
}
|
|
388
383
|
}
|
|
389
|
-
let
|
|
390
|
-
for (;
|
|
384
|
+
let o, l = !1, h = 0;
|
|
385
|
+
for (; h <= i && !l; )
|
|
391
386
|
try {
|
|
392
|
-
|
|
393
|
-
const
|
|
394
|
-
|
|
395
|
-
} catch (
|
|
396
|
-
if (
|
|
397
|
-
throw
|
|
387
|
+
t.callbacks?.call ? t.callbacks.call({}) : n.callbacks?.call && n.callbacks.call({});
|
|
388
|
+
const u = j(!!a, e, r, n);
|
|
389
|
+
o = c ? await L(u, c) : await u, l = !0;
|
|
390
|
+
} catch (u) {
|
|
391
|
+
if (h++, h > i)
|
|
392
|
+
throw u.message || (u.message = `Failed to fetch ${e} after ${i} attempts`), u;
|
|
398
393
|
}
|
|
399
|
-
return
|
|
394
|
+
return o;
|
|
400
395
|
}
|
|
401
|
-
function
|
|
402
|
-
let
|
|
403
|
-
return t.arguments.forEach((
|
|
404
|
-
if (e[
|
|
405
|
-
throw new Error(`Argument ${
|
|
406
|
-
|
|
407
|
-
}),
|
|
396
|
+
function W(n, t, e) {
|
|
397
|
+
let r = n;
|
|
398
|
+
return t.arguments.forEach((a) => {
|
|
399
|
+
if (e[a] === void 0)
|
|
400
|
+
throw new Error(`Argument ${a} is missing`);
|
|
401
|
+
r = r.replace(`[${a}]`, e[a]);
|
|
402
|
+
}), r;
|
|
408
403
|
}
|
|
409
|
-
function
|
|
410
|
-
|
|
411
|
-
const r = (s = (i = n.callbacks).before) == null ? void 0 : s.call(i, { route: n, api: t, url: e, config: a });
|
|
404
|
+
function J({ route: n, api: t, url: e, config: r }) {
|
|
405
|
+
const a = n.callbacks.before?.({ route: n, api: t, url: e, config: r });
|
|
412
406
|
return {
|
|
413
|
-
beforeRoute:
|
|
414
|
-
beforeApi:
|
|
415
|
-
beforeUrl:
|
|
416
|
-
beforeConfig:
|
|
407
|
+
beforeRoute: a?.route || n,
|
|
408
|
+
beforeApi: a?.api || t,
|
|
409
|
+
beforeUrl: a?.url || e,
|
|
410
|
+
beforeConfig: a?.config || r
|
|
417
411
|
};
|
|
418
412
|
}
|
|
419
|
-
function
|
|
420
|
-
|
|
421
|
-
const r = (s = (i = n.callbacks).after) == null ? void 0 : s.call(i, { route: n, api: t, response: e, data: a });
|
|
413
|
+
function V({ route: n, api: t, response: e, data: r }) {
|
|
414
|
+
const a = n.callbacks.after?.({ route: n, api: t, response: e, data: r });
|
|
422
415
|
return {
|
|
423
|
-
afterRoute:
|
|
424
|
-
afterApi:
|
|
425
|
-
afterResponse:
|
|
426
|
-
afterData:
|
|
416
|
+
afterRoute: a?.route || n,
|
|
417
|
+
afterApi: a?.api || t,
|
|
418
|
+
afterResponse: a?.response || e,
|
|
419
|
+
afterData: a?.data || r
|
|
427
420
|
};
|
|
428
421
|
}
|
|
429
|
-
|
|
422
|
+
class s {
|
|
423
|
+
static _instance;
|
|
424
|
+
/**
|
|
425
|
+
* Map storing all registered elements with their full paths as keys
|
|
426
|
+
*
|
|
427
|
+
* @private
|
|
428
|
+
*/
|
|
429
|
+
_elements = /* @__PURE__ */ new Map();
|
|
430
|
+
/**
|
|
431
|
+
* Reference to the current parent element during registration
|
|
432
|
+
*
|
|
433
|
+
* @private
|
|
434
|
+
*/
|
|
435
|
+
_currentParent = null;
|
|
430
436
|
/**
|
|
431
437
|
*
|
|
432
438
|
*/
|
|
433
439
|
constructor() {
|
|
434
|
-
/**
|
|
435
|
-
* Map storing all registered elements with their full paths as keys
|
|
436
|
-
*
|
|
437
|
-
* @private
|
|
438
|
-
*/
|
|
439
|
-
o(this, "_elements", /* @__PURE__ */ new Map());
|
|
440
|
-
/**
|
|
441
|
-
* Reference to the current parent element during registration
|
|
442
|
-
*
|
|
443
|
-
* @private
|
|
444
|
-
*/
|
|
445
|
-
o(this, "_currentParent", null);
|
|
446
440
|
}
|
|
447
441
|
/**
|
|
448
442
|
* Gets the singleton instance of the Registry
|
|
@@ -450,7 +444,7 @@ const f = class f {
|
|
|
450
444
|
* @returns The singleton Registry instance
|
|
451
445
|
*/
|
|
452
446
|
static get i() {
|
|
453
|
-
return
|
|
447
|
+
return s._instance || (s._instance = new s()), s._instance;
|
|
454
448
|
}
|
|
455
449
|
/**
|
|
456
450
|
* Registers a new element in the registry and updates the Klaim object structure
|
|
@@ -465,15 +459,15 @@ const f = class f {
|
|
|
465
459
|
registerElement(t) {
|
|
466
460
|
const e = this._currentParent;
|
|
467
461
|
e && (t.parent = this.getFullPath(e));
|
|
468
|
-
const
|
|
469
|
-
if (this._elements.set(
|
|
470
|
-
let
|
|
462
|
+
const r = this.getElementKey(t);
|
|
463
|
+
if (this._elements.set(r, t), t.type === "api" || t.type === "group") {
|
|
464
|
+
let a = R;
|
|
471
465
|
if (e) {
|
|
472
466
|
const i = this.getFullPath(e).split(".");
|
|
473
|
-
for (const
|
|
474
|
-
|
|
467
|
+
for (const c of i)
|
|
468
|
+
a[c] || (a[c] = {}), a = a[c];
|
|
475
469
|
}
|
|
476
|
-
|
|
470
|
+
a[t.name] || (a[t.name] = {});
|
|
477
471
|
}
|
|
478
472
|
}
|
|
479
473
|
/**
|
|
@@ -524,10 +518,10 @@ const f = class f {
|
|
|
524
518
|
addToKlaimRoute(t) {
|
|
525
519
|
if (!t.parent) return;
|
|
526
520
|
let e = R;
|
|
527
|
-
const
|
|
528
|
-
for (const
|
|
529
|
-
e[
|
|
530
|
-
e[t.name] =
|
|
521
|
+
const r = t.parent.split(".");
|
|
522
|
+
for (const a of r)
|
|
523
|
+
e[a] || (e[a] = {}), e = e[a];
|
|
524
|
+
e[t.name] = H(t.parent, t);
|
|
531
525
|
}
|
|
532
526
|
/**
|
|
533
527
|
* Generates a unique key for an element based on its path
|
|
@@ -548,11 +542,11 @@ const f = class f {
|
|
|
548
542
|
if (!t) return "";
|
|
549
543
|
if (!t.parent) return t.name;
|
|
550
544
|
const e = [t.name];
|
|
551
|
-
let
|
|
552
|
-
for (;
|
|
553
|
-
const
|
|
554
|
-
if (!
|
|
555
|
-
e.unshift(
|
|
545
|
+
let r = t;
|
|
546
|
+
for (; r.parent; ) {
|
|
547
|
+
const a = this._elements.get(r.parent);
|
|
548
|
+
if (!a) break;
|
|
549
|
+
e.unshift(a.name), r = a;
|
|
556
550
|
}
|
|
557
551
|
return e.join(".");
|
|
558
552
|
}
|
|
@@ -574,8 +568,8 @@ const f = class f {
|
|
|
574
568
|
*/
|
|
575
569
|
getChildren(t) {
|
|
576
570
|
const e = [];
|
|
577
|
-
return this._elements.forEach((
|
|
578
|
-
|
|
571
|
+
return this._elements.forEach((r) => {
|
|
572
|
+
r.parent === t && e.push(r);
|
|
579
573
|
}), e;
|
|
580
574
|
}
|
|
581
575
|
/**
|
|
@@ -585,7 +579,7 @@ const f = class f {
|
|
|
585
579
|
* @returns The updated element
|
|
586
580
|
*/
|
|
587
581
|
static updateElement(t) {
|
|
588
|
-
return
|
|
582
|
+
return s.i._elements.get(s.i.getElementKey(t)) || t;
|
|
589
583
|
}
|
|
590
584
|
/**
|
|
591
585
|
* Retrieves an API element by name, searching through the entire registry if necessary
|
|
@@ -596,9 +590,9 @@ const f = class f {
|
|
|
596
590
|
getApi(t) {
|
|
597
591
|
const e = this._elements.get(t);
|
|
598
592
|
if (!e) {
|
|
599
|
-
for (const [
|
|
600
|
-
if (
|
|
601
|
-
return
|
|
593
|
+
for (const [r, a] of this._elements.entries())
|
|
594
|
+
if (a.type === "api" && r.endsWith(`.${t}`))
|
|
595
|
+
return a;
|
|
602
596
|
return;
|
|
603
597
|
}
|
|
604
598
|
return e.type === "api" ? e : this.findApi(e);
|
|
@@ -613,15 +607,13 @@ const f = class f {
|
|
|
613
607
|
findApi(t) {
|
|
614
608
|
if (!t || !t.parent) return;
|
|
615
609
|
const e = t.parent.split(".");
|
|
616
|
-
for (let
|
|
617
|
-
const
|
|
618
|
-
if (
|
|
610
|
+
for (let r = e.length; r >= 0; r--) {
|
|
611
|
+
const a = e.slice(0, r).join("."), i = this._elements.get(a);
|
|
612
|
+
if (i?.type === "api") return i;
|
|
619
613
|
}
|
|
620
614
|
}
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
let c = f;
|
|
624
|
-
class U extends k {
|
|
615
|
+
}
|
|
616
|
+
class _ extends C {
|
|
625
617
|
/**
|
|
626
618
|
* Creates and registers a new API instance with the given configuration
|
|
627
619
|
*
|
|
@@ -640,13 +632,13 @@ class U extends k {
|
|
|
640
632
|
* });
|
|
641
633
|
* ```
|
|
642
634
|
*/
|
|
643
|
-
static create(t, e,
|
|
644
|
-
const i =
|
|
635
|
+
static create(t, e, r, a = {}) {
|
|
636
|
+
const i = E(t);
|
|
645
637
|
i !== t && console.warn(`API name "${t}" has been camelCased to "${i}"`);
|
|
646
|
-
const
|
|
647
|
-
|
|
648
|
-
const
|
|
649
|
-
return
|
|
638
|
+
const c = new _(i, e, a), o = s.i.getCurrentParent();
|
|
639
|
+
s.i.registerElement(c);
|
|
640
|
+
const l = o ? s.i.getFullPath(o) : "", h = l ? `${l}.${i}` : i;
|
|
641
|
+
return s.i.setCurrentParent(h), r(), o ? s.i.setCurrentParent(s.i.getFullPath(o)) : s.i.clearCurrentParent(), c;
|
|
650
642
|
}
|
|
651
643
|
/**
|
|
652
644
|
* Creates a new API instance
|
|
@@ -657,11 +649,11 @@ class U extends k {
|
|
|
657
649
|
* @param headers - Optional default headers for all routes
|
|
658
650
|
* @private
|
|
659
651
|
*/
|
|
660
|
-
constructor(t, e,
|
|
661
|
-
super("api", t, e,
|
|
652
|
+
constructor(t, e, r = {}) {
|
|
653
|
+
super("api", t, e, r);
|
|
662
654
|
}
|
|
663
655
|
}
|
|
664
|
-
class
|
|
656
|
+
class k extends C {
|
|
665
657
|
/**
|
|
666
658
|
* Creates a new group and registers it in the Registry.
|
|
667
659
|
* Supports nested groups and inheritable configurations.
|
|
@@ -687,10 +679,10 @@ class x extends k {
|
|
|
687
679
|
* ```
|
|
688
680
|
*/
|
|
689
681
|
static create(t, e) {
|
|
690
|
-
const
|
|
691
|
-
|
|
692
|
-
const
|
|
693
|
-
return
|
|
682
|
+
const r = E(t), a = s.i.getCurrentParent(), i = a ? s.i.getFullPath(a) : "", c = i ? `${i}.${r}` : r, o = new k(r, "");
|
|
683
|
+
r !== t && console.warn(`Group name "${t}" has been camelCased to "${r}"`), s.i.registerElement(o);
|
|
684
|
+
const l = s.i.getCurrentParent();
|
|
685
|
+
return s.i.setCurrentParent(c), e(), l ? s.i.setCurrentParent(s.i.getFullPath(l)) : s.i.clearCurrentParent(), o;
|
|
694
686
|
}
|
|
695
687
|
/**
|
|
696
688
|
* Creates a new Group instance.
|
|
@@ -701,8 +693,8 @@ class x extends k {
|
|
|
701
693
|
* @param headers - Optional headers shared by all routes in the group
|
|
702
694
|
* @private
|
|
703
695
|
*/
|
|
704
|
-
constructor(t, e,
|
|
705
|
-
super("group", t, e,
|
|
696
|
+
constructor(t, e, r = {}) {
|
|
697
|
+
super("group", t, e, r);
|
|
706
698
|
}
|
|
707
699
|
/**
|
|
708
700
|
* Enables caching for the group and all its children (routes and APIs).
|
|
@@ -720,7 +712,7 @@ class x extends k {
|
|
|
720
712
|
* ```
|
|
721
713
|
*/
|
|
722
714
|
withCache(t = 20) {
|
|
723
|
-
return super.withCache(t),
|
|
715
|
+
return super.withCache(t), s.i.getChildren(s.i.getFullPath(this)).forEach((e) => {
|
|
724
716
|
e.cache || (e.cache = t);
|
|
725
717
|
}), this;
|
|
726
718
|
}
|
|
@@ -740,7 +732,7 @@ class x extends k {
|
|
|
740
732
|
* ```
|
|
741
733
|
*/
|
|
742
734
|
withRetry(t = 2) {
|
|
743
|
-
return super.withRetry(t),
|
|
735
|
+
return super.withRetry(t), s.i.getChildren(s.i.getFullPath(this)).forEach((e) => {
|
|
744
736
|
e.retry || (e.retry = t);
|
|
745
737
|
}), this;
|
|
746
738
|
}
|
|
@@ -752,9 +744,9 @@ class x extends k {
|
|
|
752
744
|
* @param message - Error message if the timeout is reached
|
|
753
745
|
* @returns The current instance for chaining
|
|
754
746
|
*/
|
|
755
|
-
withTimeout(t =
|
|
756
|
-
return super.withTimeout(t, e),
|
|
757
|
-
|
|
747
|
+
withTimeout(t = d.duration, e = d.message) {
|
|
748
|
+
return super.withTimeout(t, e), s.i.getChildren(s.i.getFullPath(this)).forEach((r) => {
|
|
749
|
+
r.timeout || (r.timeout = { duration: t, message: e });
|
|
758
750
|
}), this;
|
|
759
751
|
}
|
|
760
752
|
/**
|
|
@@ -775,7 +767,7 @@ class x extends k {
|
|
|
775
767
|
* ```
|
|
776
768
|
*/
|
|
777
769
|
before(t) {
|
|
778
|
-
return super.before(t),
|
|
770
|
+
return super.before(t), s.i.getChildren(s.i.getFullPath(this)).forEach((e) => {
|
|
779
771
|
e.callbacks.before || (e.callbacks.before = t);
|
|
780
772
|
}), this;
|
|
781
773
|
}
|
|
@@ -797,7 +789,7 @@ class x extends k {
|
|
|
797
789
|
* ```
|
|
798
790
|
*/
|
|
799
791
|
after(t) {
|
|
800
|
-
return super.after(t),
|
|
792
|
+
return super.after(t), s.i.getChildren(s.i.getFullPath(this)).forEach((e) => {
|
|
801
793
|
e.callbacks.after || (e.callbacks.after = t);
|
|
802
794
|
}), this;
|
|
803
795
|
}
|
|
@@ -819,12 +811,12 @@ class x extends k {
|
|
|
819
811
|
* ```
|
|
820
812
|
*/
|
|
821
813
|
onCall(t) {
|
|
822
|
-
return super.onCall(t),
|
|
814
|
+
return super.onCall(t), s.i.getChildren(s.i.getFullPath(this)).forEach((e) => {
|
|
823
815
|
e.callbacks.call || (e.callbacks.call = t);
|
|
824
816
|
}), this;
|
|
825
817
|
}
|
|
826
818
|
}
|
|
827
|
-
class
|
|
819
|
+
class F extends C {
|
|
828
820
|
/**
|
|
829
821
|
* Creates a new Route instance.
|
|
830
822
|
*
|
|
@@ -833,8 +825,8 @@ class I extends k {
|
|
|
833
825
|
* @param headers - Optional HTTP headers specific to this route
|
|
834
826
|
* @param method - HTTP method for this route
|
|
835
827
|
*/
|
|
836
|
-
constructor(t, e,
|
|
837
|
-
super("route", t, e,
|
|
828
|
+
constructor(t, e, r = {}, a = "GET") {
|
|
829
|
+
super("route", t, e, r), this.method = a, this.detectArguments();
|
|
838
830
|
}
|
|
839
831
|
/**
|
|
840
832
|
* Internal helper to create and register a new route.
|
|
@@ -846,9 +838,9 @@ class I extends k {
|
|
|
846
838
|
* @returns The created route element
|
|
847
839
|
* @private
|
|
848
840
|
*/
|
|
849
|
-
static createRoute(t, e,
|
|
850
|
-
const i = new
|
|
851
|
-
return
|
|
841
|
+
static createRoute(t, e, r = {}, a) {
|
|
842
|
+
const i = new F(t, e, r, a);
|
|
843
|
+
return s.i.registerRoute(i), i;
|
|
852
844
|
}
|
|
853
845
|
/**
|
|
854
846
|
* Creates a GET route.
|
|
@@ -863,11 +855,11 @@ class I extends k {
|
|
|
863
855
|
* Route.get("getUser", "/users/[id]");
|
|
864
856
|
* ```
|
|
865
857
|
*/
|
|
866
|
-
static get(t, e,
|
|
858
|
+
static get(t, e, r = {}) {
|
|
867
859
|
return this.createRoute(
|
|
868
860
|
t,
|
|
869
861
|
e,
|
|
870
|
-
|
|
862
|
+
r,
|
|
871
863
|
"GET"
|
|
872
864
|
/* GET */
|
|
873
865
|
);
|
|
@@ -884,11 +876,11 @@ class I extends k {
|
|
|
884
876
|
* Route.post("createUser", "/users");
|
|
885
877
|
* ```
|
|
886
878
|
*/
|
|
887
|
-
static post(t, e,
|
|
879
|
+
static post(t, e, r = {}) {
|
|
888
880
|
return this.createRoute(
|
|
889
881
|
t,
|
|
890
882
|
e,
|
|
891
|
-
|
|
883
|
+
r,
|
|
892
884
|
"POST"
|
|
893
885
|
/* POST */
|
|
894
886
|
);
|
|
@@ -905,11 +897,11 @@ class I extends k {
|
|
|
905
897
|
* Route.put("updateUser", "/users/[id]");
|
|
906
898
|
* ```
|
|
907
899
|
*/
|
|
908
|
-
static put(t, e,
|
|
900
|
+
static put(t, e, r = {}) {
|
|
909
901
|
return this.createRoute(
|
|
910
902
|
t,
|
|
911
903
|
e,
|
|
912
|
-
|
|
904
|
+
r,
|
|
913
905
|
"PUT"
|
|
914
906
|
/* PUT */
|
|
915
907
|
);
|
|
@@ -926,11 +918,11 @@ class I extends k {
|
|
|
926
918
|
* Route.delete("deleteUser", "/users/[id]");
|
|
927
919
|
* ```
|
|
928
920
|
*/
|
|
929
|
-
static delete(t, e,
|
|
921
|
+
static delete(t, e, r = {}) {
|
|
930
922
|
return this.createRoute(
|
|
931
923
|
t,
|
|
932
924
|
e,
|
|
933
|
-
|
|
925
|
+
r,
|
|
934
926
|
"DELETE"
|
|
935
927
|
/* DELETE */
|
|
936
928
|
);
|
|
@@ -947,11 +939,11 @@ class I extends k {
|
|
|
947
939
|
* Route.patch("updateUserStatus", "/users/[id]/status");
|
|
948
940
|
* ```
|
|
949
941
|
*/
|
|
950
|
-
static patch(t, e,
|
|
942
|
+
static patch(t, e, r = {}) {
|
|
951
943
|
return this.createRoute(
|
|
952
944
|
t,
|
|
953
945
|
e,
|
|
954
|
-
|
|
946
|
+
r,
|
|
955
947
|
"PATCH"
|
|
956
948
|
/* PATCH */
|
|
957
949
|
);
|
|
@@ -968,11 +960,11 @@ class I extends k {
|
|
|
968
960
|
* Route.options("userOptions", "/users");
|
|
969
961
|
* ```
|
|
970
962
|
*/
|
|
971
|
-
static options(t, e,
|
|
963
|
+
static options(t, e, r = {}) {
|
|
972
964
|
return this.createRoute(
|
|
973
965
|
t,
|
|
974
966
|
e,
|
|
975
|
-
|
|
967
|
+
r,
|
|
976
968
|
"OPTIONS"
|
|
977
969
|
/* OPTIONS */
|
|
978
970
|
);
|
|
@@ -987,8 +979,8 @@ class I extends k {
|
|
|
987
979
|
detectArguments() {
|
|
988
980
|
const t = this.url.match(/\[([^\]]+)]/g);
|
|
989
981
|
t && t.forEach((e) => {
|
|
990
|
-
const
|
|
991
|
-
this.arguments.add(
|
|
982
|
+
const r = e.replace("[", "").replace("]", "");
|
|
983
|
+
this.arguments.add(r);
|
|
992
984
|
});
|
|
993
985
|
}
|
|
994
986
|
/**
|
|
@@ -1007,10 +999,10 @@ class I extends k {
|
|
|
1007
999
|
}
|
|
1008
1000
|
}
|
|
1009
1001
|
export {
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1002
|
+
_ as Api,
|
|
1003
|
+
k as Group,
|
|
1004
|
+
M as Hook,
|
|
1013
1005
|
R as Klaim,
|
|
1014
|
-
|
|
1015
|
-
|
|
1006
|
+
s as Registry,
|
|
1007
|
+
F as Route
|
|
1016
1008
|
};
|
package/dist/klaim.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(u,p){typeof exports=="object"&&typeof module<"u"?p(exports):typeof define=="function"&&define.amd?define(["exports"],p):(u=typeof globalThis<"u"?globalThis:u||self,p(u.klaim={}))})(this,function(u){"use strict";var Y=Object.defineProperty;var Z=(u,p,w)=>p in u?Y(u,p,{enumerable:!0,configurable:!0,writable:!0,value:w}):u[p]=w;var o=(u,p,w)=>Z(u,typeof p!="symbol"?p+"":p,w);function p(n){return n.replace(/([-_][a-z])/gi,t=>t.toUpperCase().replace("-","").replace("_","")).replace(/(^\w)/,t=>t.toLowerCase())}function w(n){return n.trim().replace(/^\/|\/$/g,"")}const O={limit:5,duration:10},k=new Map;function D(n,t){const e=Date.now(),a=t.duration*1e3;let r=k.get(n);r||(r={timestamps:[]},k.set(n,r));const i=r.timestamps.filter(s=>e-s<a);return i.length>=t.limit?!1:(i.push(e),r.timestamps=i,!0)}function K(n,t){const e=k.get(n);if(!e||e.timestamps.length<t.limit)return 0;const a=Date.now(),r=t.duration*1e3,l=[...e.timestamps].sort((h,g)=>h-g)[0]+r-a;return Math.max(0,l)}const $={duration:5,message:"Request timed out"};async function G(n,t){const{duration:e,message:a}=t;return Promise.race([n,new Promise((r,i)=>{const s=setTimeout(()=>{clearTimeout(s),i(new Error(a))},e*1e3)})])}const M={page:1,pageParam:"page",limit:10,limitParam:"limit"};class _{constructor(t,e,a,r={}){o(this,"type");o(this,"name");o(this,"url");o(this,"headers");o(this,"parent");o(this,"method");o(this,"arguments",new Set);o(this,"schema");o(this,"pagination");o(this,"callbacks",{before:null,after:null,call:null});o(this,"cache",!1);o(this,"retry",!1);o(this,"rate",!1);o(this,"timeout",!1);o(this,"withCache",(t=20)=>(this.cache=t,this));o(this,"withRetry",(t=2)=>(this.retry=t,this));o(this,"withRate",(t={})=>(this.rate={...O,...t},this));o(this,"withTimeout",(t=$.duration,e=$.message)=>(this.timeout={duration:t,message:e},this));this.type=t,this.name=p(e),this.name!==e&&console.warn(`Name "${e}" has been camelCased to "${this.name}"`),this.url=w(a),this.headers=r||{}}before(t){return this.callbacks.before=t,this}after(t){return this.callbacks.after=t,this}onCall(t){return this.callbacks.call=t,this}withPagination(t={}){return this.pagination={...M,...t},this}}const d=class d{constructor(){o(this,"cache");this.cache=new Map}static get i(){return d._instance||(d._instance=new d),d._instance}set(t,e,a=0){const r=Date.now()+a;this.cache.set(t,{data:e,expiry:r})}has(t){const e=this.cache.get(t);return e?Date.now()>e.expiry?(this.cache.delete(t),!1):!0:!1}get(t){return this.has(t)?this.cache.get(t).data:null}};o(d,"_instance");let y=d;function x(n){let a=2166136261;for(let i=0;i<n.length;i++)a^=n.charCodeAt(i),a*=16777619;let r=(a>>>0).toString(16).padStart(8,"0");for(;r.length<32;)a^=r.charCodeAt(r.length%r.length),a*=16777619,r+=(a>>>0).toString(16).padStart(8,"0");return r.substring(0,32)}async function j(n,t,e){const a=`${n.toString()}${JSON.stringify(t)}`,r=x(a);if(y.i.has(r))return y.i.get(r);const s=await(await fetch(n,t)).json();return y.i.set(r,s,e),s}class F{static subscribe(t,e){this._callbacks.set(t,e)}static run(t){const e=this._callbacks.get(t);e&&e()}}o(F,"_callbacks",new Map);const S={};function H(n,t){return async(...e)=>{if(t.pagination){const[i=0,s={},l={}]=e;return L(n,t,i,s,l)}const[a={},r={}]=e;return L(n,t,void 0,a,r)}}async function L(n,t,e,a={},r={}){const i=n.split(".");let s;for(let b=0;b<i.length;b++){const U=i[b];if(s=c.i.getApi(U),s)break}if(!t||!s||t.type!=="route"||s.type!=="api")throw new Error(`Invalid path: ${n}.${t.name}`);let l=J(`${s.url}/${t.url}`,t,a);if(t.pagination&&typeof e<"u"){const{pageParam:b="page",limit:U=10,limitParam:Q="limit"}=t.pagination,I=new URLSearchParams;I.append(b,String(e)),I.append(Q,String(U));const X=l.includes("?")?"&":"?";l=`${l}${X}${I.toString()}`}let h={};r&&t.method!=="GET"&&(h.body=JSON.stringify(r)),h.headers={"Content-Type":"application/json",...s.headers,...t.headers},h.method=t.method;const{beforeRoute:g,beforeApi:T,beforeUrl:A,beforeConfig:f}=V({route:t,api:s,url:l,config:h});l=A,h=f,c.updateElement(T),c.updateElement(g);let P=await W(s,t,l,h);t.schema&&"validate"in t.schema&&(P=await t.schema.validate(P));const{afterRoute:C,afterApi:E,afterData:B}=z({route:t,api:s,response:P,data:P});return c.updateElement(E),c.updateElement(C),F.run(`${s.name}.${t.name}`),B}async function q(n,t,e,a){return n?await j(t,e,a.cache):await(await fetch(t,e)).json()}async function W(n,t,e,a){var T,A;const r=n.cache||t.cache,i=t.retry||n.retry||0,s=t.timeout||n.timeout;if(t.rate){const f=`${n.name}.${t.name}`;if(!D(f,t.rate)){const C=K(f,t.rate),E=Math.ceil(C/1e3);throw new Error(`Rate limit exceeded for ${f}. Try again in ${E} seconds.`)}}else if(n.rate){const f=`${n.name}`;if(!D(f,n.rate)){const C=K(f,n.rate),E=Math.ceil(C/1e3);throw new Error(`Rate limit exceeded for ${n.name} API. Try again in ${E} seconds.`)}}let l,h=!1,g=0;for(;g<=i&&!h;)try{(T=t.callbacks)!=null&&T.call?t.callbacks.call({}):(A=n.callbacks)!=null&&A.call&&n.callbacks.call({});const f=q(!!r,e,a,n);l=s?await G(f,s):await f,h=!0}catch(f){if(g++,g>i)throw f.message||(f.message=`Failed to fetch ${e} after ${i} attempts`),f}return l}function J(n,t,e){let a=n;return t.arguments.forEach(r=>{if(e[r]===void 0)throw new Error(`Argument ${r} is missing`);a=a.replace(`[${r}]`,e[r])}),a}function V({route:n,api:t,url:e,config:a}){var i,s;const r=(s=(i=n.callbacks).before)==null?void 0:s.call(i,{route:n,api:t,url:e,config:a});return{beforeRoute:(r==null?void 0:r.route)||n,beforeApi:(r==null?void 0:r.api)||t,beforeUrl:(r==null?void 0:r.url)||e,beforeConfig:(r==null?void 0:r.config)||a}}function z({route:n,api:t,response:e,data:a}){var i,s;const r=(s=(i=n.callbacks).after)==null?void 0:s.call(i,{route:n,api:t,response:e,data:a});return{afterRoute:(r==null?void 0:r.route)||n,afterApi:(r==null?void 0:r.api)||t,afterResponse:(r==null?void 0:r.response)||e,afterData:(r==null?void 0:r.data)||a}}const m=class m{constructor(){o(this,"_elements",new Map);o(this,"_currentParent",null)}static get i(){return m._instance||(m._instance=new m),m._instance}registerElement(t){const e=this._currentParent;e&&(t.parent=this.getFullPath(e));const a=this.getElementKey(t);if(this._elements.set(a,t),t.type==="api"||t.type==="group"){let r=S;if(e){const i=this.getFullPath(e).split(".");for(const s of i)r[s]||(r[s]={}),r=r[s]}r[t.name]||(r[t.name]={})}}getCurrentParent(){return this._currentParent}setCurrentParent(t){const e=this._elements.get(t);if(!e||e.type!=="api"&&e.type!=="group")throw new Error(`Element ${t} not found or not a valid parent type`);this._currentParent=e}clearCurrentParent(){this._currentParent=null}registerRoute(t){if(!this._currentParent)throw new Error("No current parent set, use Route only inside Api or Group create callback");t.parent=this.getFullPath(this._currentParent);const e=this.getElementKey(t);this._elements.set(e,t),this.addToKlaimRoute(t)}addToKlaimRoute(t){if(!t.parent)return;let e=S;const a=t.parent.split(".");for(const r of a)e[r]||(e[r]={}),e=e[r];e[t.name]=H(t.parent,t)}getElementKey(t){return t?t.parent?`${t.parent}.${t.name}`:t.name:""}getFullPath(t){if(!t)return"";if(!t.parent)return t.name;const e=[t.name];let a=t;for(;a.parent;){const r=this._elements.get(a.parent);if(!r)break;e.unshift(r.name),a=r}return e.join(".")}getRoute(t,e){return this._elements.get(`${t}.${e}`)}getChildren(t){const e=[];return this._elements.forEach(a=>{a.parent===t&&e.push(a)}),e}static updateElement(t){return m.i._elements.get(m.i.getElementKey(t))||t}getApi(t){const e=this._elements.get(t);if(!e){for(const[a,r]of this._elements.entries())if(r.type==="api"&&a.endsWith(`.${t}`))return r;return}return e.type==="api"?e:this.findApi(e)}findApi(t){if(!t||!t.parent)return;const e=t.parent.split(".");for(let a=e.length;a>=0;a--){const r=e.slice(0,a).join("."),i=this._elements.get(r);if((i==null?void 0:i.type)==="api")return i}}};o(m,"_instance");let c=m;class R extends _{static create(t,e,a,r={}){const i=p(t);i!==t&&console.warn(`API name "${t}" has been camelCased to "${i}"`);const s=new R(i,e,r),l=c.i.getCurrentParent();c.i.registerElement(s);const h=l?c.i.getFullPath(l):"",g=h?`${h}.${i}`:i;return c.i.setCurrentParent(g),a(),l?c.i.setCurrentParent(c.i.getFullPath(l)):c.i.clearCurrentParent(),s}constructor(t,e,a={}){super("api",t,e,a)}}class v extends _{static create(t,e){const a=p(t),r=c.i.getCurrentParent(),i=r?c.i.getFullPath(r):"",s=i?`${i}.${a}`:a,l=new v(a,"");a!==t&&console.warn(`Group name "${t}" has been camelCased to "${a}"`),c.i.registerElement(l);const h=c.i.getCurrentParent();return c.i.setCurrentParent(s),e(),h?c.i.setCurrentParent(c.i.getFullPath(h)):c.i.clearCurrentParent(),l}constructor(t,e,a={}){super("group",t,e,a)}withCache(t=20){return super.withCache(t),c.i.getChildren(c.i.getFullPath(this)).forEach(e=>{e.cache||(e.cache=t)}),this}withRetry(t=2){return super.withRetry(t),c.i.getChildren(c.i.getFullPath(this)).forEach(e=>{e.retry||(e.retry=t)}),this}withTimeout(t=$.duration,e=$.message){return super.withTimeout(t,e),c.i.getChildren(c.i.getFullPath(this)).forEach(a=>{a.timeout||(a.timeout={duration:t,message:e})}),this}before(t){return super.before(t),c.i.getChildren(c.i.getFullPath(this)).forEach(e=>{e.callbacks.before||(e.callbacks.before=t)}),this}after(t){return super.after(t),c.i.getChildren(c.i.getFullPath(this)).forEach(e=>{e.callbacks.after||(e.callbacks.after=t)}),this}onCall(t){return super.onCall(t),c.i.getChildren(c.i.getFullPath(this)).forEach(e=>{e.callbacks.call||(e.callbacks.call=t)}),this}}class N extends _{constructor(t,e,a={},r="GET"){super("route",t,e,a),this.method=r,this.detectArguments()}static createRoute(t,e,a={},r){const i=new N(t,e,a,r);return c.i.registerRoute(i),i}static get(t,e,a={}){return this.createRoute(t,e,a,"GET")}static post(t,e,a={}){return this.createRoute(t,e,a,"POST")}static put(t,e,a={}){return this.createRoute(t,e,a,"PUT")}static delete(t,e,a={}){return this.createRoute(t,e,a,"DELETE")}static patch(t,e,a={}){return this.createRoute(t,e,a,"PATCH")}static options(t,e,a={}){return this.createRoute(t,e,a,"OPTIONS")}detectArguments(){const t=this.url.match(/\[([^\]]+)]/g);t&&t.forEach(e=>{const a=e.replace("[","").replace("]","");this.arguments.add(a)})}validate(t){return this.schema=t,this}}u.Api=R,u.Group=v,u.Hook=F,u.Klaim=S,u.Registry=c,u.Route=N,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(h,g){typeof exports=="object"&&typeof module<"u"?g(exports):typeof define=="function"&&define.amd?define(["exports"],g):(h=typeof globalThis<"u"?globalThis:h||self,g(h.klaim={}))})(this,function(h){"use strict";function g(n){return n.replace(/([-_][a-z])/gi,t=>t.toUpperCase().replace("-","").replace("_","")).replace(/(^\w)/,t=>t.toLowerCase())}function N(n){return n.trim().replace(/^\/|\/$/g,"")}const U={limit:5,duration:10},y=new Map;function k(n,t){const e=Date.now(),r=t.duration*1e3;let a=y.get(n);a||(a={timestamps:[]},y.set(n,a));const s=a.timestamps.filter(c=>e-c<r);return s.length>=t.limit?!1:(s.push(e),a.timestamps=s,!0)}function F(n,t){const e=y.get(n);if(!e||e.timestamps.length<t.limit)return 0;const r=Date.now(),a=t.duration*1e3,o=[...e.timestamps].sort((l,f)=>l-f)[0]+a-r;return Math.max(0,o)}const P={duration:5,message:"Request timed out"};async function I(n,t){const{duration:e,message:r}=t;return Promise.race([n,new Promise((a,s)=>{const c=setTimeout(()=>{clearTimeout(c),s(new Error(r))},e*1e3)})])}const D={page:1,pageParam:"page",limit:10,limitParam:"limit"};class b{type;name;url;headers;parent;method;arguments=new Set;schema;pagination;callbacks={before:null,after:null,call:null};cache=!1;retry=!1;rate=!1;timeout=!1;constructor(t,e,r,a={}){this.type=t,this.name=g(e),this.name!==e&&console.warn(`Name "${e}" has been camelCased to "${this.name}"`),this.url=N(r),this.headers=a||{}}before(t){return this.callbacks.before=t,this}after(t){return this.callbacks.after=t,this}onCall(t){return this.callbacks.call=t,this}withCache=(t=20)=>(this.cache=t,this);withRetry=(t=2)=>(this.retry=t,this);withPagination(t={}){return this.pagination={...D,...t},this}withRate=(t={})=>(this.rate={...U,...t},this);withTimeout=(t=P.duration,e=P.message)=>(this.timeout={duration:t,message:e},this)}class p{static _instance;cache;constructor(){this.cache=new Map}static get i(){return p._instance||(p._instance=new p),p._instance}set(t,e,r=0){const a=Date.now()+r;this.cache.set(t,{data:e,expiry:a})}has(t){const e=this.cache.get(t);return e?Date.now()>e.expiry?(this.cache.delete(t),!1):!0:!1}get(t){return this.has(t)?this.cache.get(t).data:null}}function K(n){let r=2166136261;for(let s=0;s<n.length;s++)r^=n.charCodeAt(s),r*=16777619;let a=(r>>>0).toString(16).padStart(8,"0");for(;a.length<32;)r^=a.charCodeAt(a.length%a.length),r*=16777619,a+=(r>>>0).toString(16).padStart(8,"0");return a.substring(0,32)}async function L(n,t,e){const r=`${n.toString()}${JSON.stringify(t)}`,a=K(r);if(p.i.has(a))return p.i.get(a);const c=await(await fetch(n,t)).json();return p.i.set(a,c,e),c}class S{static _callbacks=new Map;static subscribe(t,e){this._callbacks.set(t,e)}static run(t){const e=this._callbacks.get(t);e&&e()}}const E={};function O(n,t){return async(...e)=>{if(t.pagination){const[s=0,c={},o={}]=e;return v(n,t,s,c,o)}const[r={},a={}]=e;return v(n,t,void 0,r,a)}}async function v(n,t,e,r={},a={}){const s=n.split(".");let c;for(let w=0;w<s.length;w++){const A=s[w];if(c=i.i.getApi(A),c)break}if(!t||!c||t.type!=="route"||c.type!=="api")throw new Error(`Invalid path: ${n}.${t.name}`);let o=x(`${c.url}/${t.url}`,t,r);if(t.pagination&&typeof e<"u"){const{pageParam:w="page",limit:A=10,limitParam:V="limit"}=t.pagination,_=new URLSearchParams;_.append(w,String(e)),_.append(V,String(A));const z=o.includes("?")?"&":"?";o=`${o}${z}${_.toString()}`}let l={};a&&t.method!=="GET"&&(l.body=JSON.stringify(a)),l.headers={"Content-Type":"application/json",...c.headers,...t.headers},l.method=t.method;const{beforeRoute:f,beforeApi:u,beforeUrl:R,beforeConfig:d}=j({route:t,api:c,url:o,config:l});o=R,l=d,i.updateElement(u),i.updateElement(f);let m=await M(c,t,o,l);t.schema&&"validate"in t.schema&&(m=await t.schema.validate(m));const{afterRoute:q,afterApi:W,afterData:J}=H({route:t,api:c,response:m,data:m});return i.updateElement(W),i.updateElement(q),S.run(`${c.name}.${t.name}`),J}async function G(n,t,e,r){return n?await L(t,e,r.cache):await(await fetch(t,e)).json()}async function M(n,t,e,r){const a=n.cache||t.cache,s=t.retry||n.retry||0,c=t.timeout||n.timeout;if(t.rate){const u=`${n.name}.${t.name}`;if(!k(u,t.rate)){const d=F(u,t.rate),m=Math.ceil(d/1e3);throw new Error(`Rate limit exceeded for ${u}. Try again in ${m} seconds.`)}}else if(n.rate){const u=`${n.name}`;if(!k(u,n.rate)){const d=F(u,n.rate),m=Math.ceil(d/1e3);throw new Error(`Rate limit exceeded for ${n.name} API. Try again in ${m} seconds.`)}}let o,l=!1,f=0;for(;f<=s&&!l;)try{t.callbacks?.call?t.callbacks.call({}):n.callbacks?.call&&n.callbacks.call({});const u=G(!!a,e,r,n);o=c?await I(u,c):await u,l=!0}catch(u){if(f++,f>s)throw u.message||(u.message=`Failed to fetch ${e} after ${s} attempts`),u}return o}function x(n,t,e){let r=n;return t.arguments.forEach(a=>{if(e[a]===void 0)throw new Error(`Argument ${a} is missing`);r=r.replace(`[${a}]`,e[a])}),r}function j({route:n,api:t,url:e,config:r}){const a=n.callbacks.before?.({route:n,api:t,url:e,config:r});return{beforeRoute:a?.route||n,beforeApi:a?.api||t,beforeUrl:a?.url||e,beforeConfig:a?.config||r}}function H({route:n,api:t,response:e,data:r}){const a=n.callbacks.after?.({route:n,api:t,response:e,data:r});return{afterRoute:a?.route||n,afterApi:a?.api||t,afterResponse:a?.response||e,afterData:a?.data||r}}class i{static _instance;_elements=new Map;_currentParent=null;constructor(){}static get i(){return i._instance||(i._instance=new i),i._instance}registerElement(t){const e=this._currentParent;e&&(t.parent=this.getFullPath(e));const r=this.getElementKey(t);if(this._elements.set(r,t),t.type==="api"||t.type==="group"){let a=E;if(e){const s=this.getFullPath(e).split(".");for(const c of s)a[c]||(a[c]={}),a=a[c]}a[t.name]||(a[t.name]={})}}getCurrentParent(){return this._currentParent}setCurrentParent(t){const e=this._elements.get(t);if(!e||e.type!=="api"&&e.type!=="group")throw new Error(`Element ${t} not found or not a valid parent type`);this._currentParent=e}clearCurrentParent(){this._currentParent=null}registerRoute(t){if(!this._currentParent)throw new Error("No current parent set, use Route only inside Api or Group create callback");t.parent=this.getFullPath(this._currentParent);const e=this.getElementKey(t);this._elements.set(e,t),this.addToKlaimRoute(t)}addToKlaimRoute(t){if(!t.parent)return;let e=E;const r=t.parent.split(".");for(const a of r)e[a]||(e[a]={}),e=e[a];e[t.name]=O(t.parent,t)}getElementKey(t){return t?t.parent?`${t.parent}.${t.name}`:t.name:""}getFullPath(t){if(!t)return"";if(!t.parent)return t.name;const e=[t.name];let r=t;for(;r.parent;){const a=this._elements.get(r.parent);if(!a)break;e.unshift(a.name),r=a}return e.join(".")}getRoute(t,e){return this._elements.get(`${t}.${e}`)}getChildren(t){const e=[];return this._elements.forEach(r=>{r.parent===t&&e.push(r)}),e}static updateElement(t){return i.i._elements.get(i.i.getElementKey(t))||t}getApi(t){const e=this._elements.get(t);if(!e){for(const[r,a]of this._elements.entries())if(a.type==="api"&&r.endsWith(`.${t}`))return a;return}return e.type==="api"?e:this.findApi(e)}findApi(t){if(!t||!t.parent)return;const e=t.parent.split(".");for(let r=e.length;r>=0;r--){const a=e.slice(0,r).join("."),s=this._elements.get(a);if(s?.type==="api")return s}}}class C extends b{static create(t,e,r,a={}){const s=g(t);s!==t&&console.warn(`API name "${t}" has been camelCased to "${s}"`);const c=new C(s,e,a),o=i.i.getCurrentParent();i.i.registerElement(c);const l=o?i.i.getFullPath(o):"",f=l?`${l}.${s}`:s;return i.i.setCurrentParent(f),r(),o?i.i.setCurrentParent(i.i.getFullPath(o)):i.i.clearCurrentParent(),c}constructor(t,e,r={}){super("api",t,e,r)}}class $ extends b{static create(t,e){const r=g(t),a=i.i.getCurrentParent(),s=a?i.i.getFullPath(a):"",c=s?`${s}.${r}`:r,o=new $(r,"");r!==t&&console.warn(`Group name "${t}" has been camelCased to "${r}"`),i.i.registerElement(o);const l=i.i.getCurrentParent();return i.i.setCurrentParent(c),e(),l?i.i.setCurrentParent(i.i.getFullPath(l)):i.i.clearCurrentParent(),o}constructor(t,e,r={}){super("group",t,e,r)}withCache(t=20){return super.withCache(t),i.i.getChildren(i.i.getFullPath(this)).forEach(e=>{e.cache||(e.cache=t)}),this}withRetry(t=2){return super.withRetry(t),i.i.getChildren(i.i.getFullPath(this)).forEach(e=>{e.retry||(e.retry=t)}),this}withTimeout(t=P.duration,e=P.message){return super.withTimeout(t,e),i.i.getChildren(i.i.getFullPath(this)).forEach(r=>{r.timeout||(r.timeout={duration:t,message:e})}),this}before(t){return super.before(t),i.i.getChildren(i.i.getFullPath(this)).forEach(e=>{e.callbacks.before||(e.callbacks.before=t)}),this}after(t){return super.after(t),i.i.getChildren(i.i.getFullPath(this)).forEach(e=>{e.callbacks.after||(e.callbacks.after=t)}),this}onCall(t){return super.onCall(t),i.i.getChildren(i.i.getFullPath(this)).forEach(e=>{e.callbacks.call||(e.callbacks.call=t)}),this}}class T extends b{constructor(t,e,r={},a="GET"){super("route",t,e,r),this.method=a,this.detectArguments()}static createRoute(t,e,r={},a){const s=new T(t,e,r,a);return i.i.registerRoute(s),s}static get(t,e,r={}){return this.createRoute(t,e,r,"GET")}static post(t,e,r={}){return this.createRoute(t,e,r,"POST")}static put(t,e,r={}){return this.createRoute(t,e,r,"PUT")}static delete(t,e,r={}){return this.createRoute(t,e,r,"DELETE")}static patch(t,e,r={}){return this.createRoute(t,e,r,"PATCH")}static options(t,e,r={}){return this.createRoute(t,e,r,"OPTIONS")}detectArguments(){const t=this.url.match(/\[([^\]]+)]/g);t&&t.forEach(e=>{const r=e.replace("[","").replace("]","");this.arguments.add(r)})}validate(t){return this.schema=t,this}}h.Api=C,h.Group=$,h.Hook=S,h.Klaim=E,h.Registry=i,h.Route=T,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "klaim",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.8",
|
|
4
4
|
"author": "antharuu",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -13,18 +13,18 @@
|
|
|
13
13
|
"@stylistic/eslint-plugin": "5.0.0",
|
|
14
14
|
"@types/bun": "^1.2.17",
|
|
15
15
|
"@types/eslint__js": "9.14.0",
|
|
16
|
-
"@types/node": "^24.0.
|
|
16
|
+
"@types/node": "^24.0.4",
|
|
17
17
|
"@vitest/coverage-v8": "^3.2.4",
|
|
18
18
|
"@vitest/ui": "^3.2.4",
|
|
19
19
|
"dotenv-cli": "^8.0.0",
|
|
20
20
|
"eslint": "9.29.0",
|
|
21
|
-
"eslint-plugin-jsdoc": "51.2.
|
|
21
|
+
"eslint-plugin-jsdoc": "51.2.3",
|
|
22
22
|
"eslint-plugin-simple-import-sort": "12.1.1",
|
|
23
23
|
"jsdom": "^26.1.0",
|
|
24
24
|
"release-it": "^19.0.3",
|
|
25
25
|
"typescript": "5.8",
|
|
26
26
|
"typescript-eslint": "8.35",
|
|
27
|
-
"vite": "^
|
|
27
|
+
"vite": "^7.0.0",
|
|
28
28
|
"vitest": "^3.2.4",
|
|
29
29
|
"yup": "^1.6.1"
|
|
30
30
|
},
|