klaim 1.1.1 β†’ 1.2.1

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/README.md CHANGED
@@ -3,12 +3,19 @@
3
3
  Klaim is a lightweight TypeScript library designed to manage APIs and record requests, optimized for an optimal user
4
4
  experience.
5
5
 
6
+ ## Links
7
+
8
+ - [NPM](https://www.npmjs.com/package/klaim)
9
+ - [GitHub](https://github.com/antharuu/klaim)
10
+
6
11
  ## πŸš€ Features
7
12
 
8
13
  - **Efficient API Management**: Easily manage multiple APIs with streamlined integration and interaction capabilities.
9
14
  - **Request Recording**: Seamlessly track requests for debugging and monitoring.
10
15
  - **User Experience Optimization**: Focused on performance and usability for a smooth user experience.
11
16
  - **Lightweight**: Minimal footprint for fast load times and minimal performance impact.
17
+ - **Middleware Support**: Easily add middleware to modify requests and responses (`before` and `after`).
18
+ - **Hook System**: Subscribe to hooks to monitor and react to specific events.
12
19
  - **TypeScript Support**: Fully typed for enhanced code quality and developer experience.
13
20
 
14
21
  ## πŸ“₯ Installation
@@ -28,7 +35,7 @@ bun add klaim
28
35
  Here’s a basic example to get you started:
29
36
 
30
37
  ```typescript
31
- import {Api, Klaim, Registry, Route} from 'klaim';
38
+ import {Api, Klaim, Registry, Route, Hook} from 'klaim';
32
39
 
33
40
  // Your simple Todo type
34
41
  type Todo = {
@@ -71,6 +78,12 @@ const todo = await Klaim.hello.getTodo<Todo>({id: 1})
71
78
 
72
79
  // Make a request to the "addTodo" route
73
80
  const newTodo = await Klaim.hello.addTodo<Todo>({}, {title: "New Todo", completed: false, userId: 1})
81
+
82
+ // You can subscribe to hooks from everywhere
83
+ // Every time hello.getFirstTodo is called, the hook will be triggered
84
+ Hook.subscribe("hello.getFirstTodo", ({url}) => {
85
+ console.log(`Requesting ${url}`);
86
+ });
74
87
  ```
75
88
 
76
89
  ## 🀝 Contributing
package/dist/klaim.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var C=Object.defineProperty;var $=(a,t,e)=>t in a?C(a,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):a[t]=e;var s=(a,t,e)=>$(a,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function d(a){return a.trim().replace(/^\/|\/$/g,"")}function m(a){return a.replace(/([-_][a-z])/gi,t=>t.toUpperCase().replace("-","").replace("_","")).replace(/(^\w)/,t=>t.toLowerCase())}var A=(a=>(a.GET="GET",a.POST="POST",a.PUT="PUT",a.DELETE="DELETE",a.PATCH="PATCH",a.OPTIONS="OPTIONS",a))(A||{});class p{constructor(t,e,n,r="GET"){s(this,"api","undefined");s(this,"name");s(this,"url");s(this,"method");s(this,"headers");s(this,"arguments",new Set);s(this,"callbacks",{before:null,after:null});this.name=m(t),this.name!==t&&console.warn(`Route name "${t}" has been camelCased to "${this.name}"`),this.url=d(e),this.headers=n||{},this.method=r,this.detectArguments()}static createRoute(t,e,n,r){const i=new p(t,e,n,r);return o.i.registerRoute(i),i}static get(t,e,n={}){return this.createRoute(t,e,n,"GET")}static post(t,e,n){return this.createRoute(t,e,n,"POST")}static put(t,e,n){return this.createRoute(t,e,n,"PUT")}static delete(t,e,n){return this.createRoute(t,e,n,"DELETE")}static patch(t,e,n){return this.createRoute(t,e,n,"PATCH")}static options(t,e,n){return this.createRoute(t,e,n,"OPTIONS")}before(t){return this.callbacks.before=t,this}after(t){return this.callbacks.after=t,this}detectArguments(){const t=this.url.match(/\[([^\]]+)]/g);t&&t.forEach(e=>{const n=e.replace(/\[|]/g,"");this.arguments.add(n)})}}const l={};async function O(a,t,e={},n={}){let r=y(`${a.url}/${t.url}`,t,e),i={};n&&t.method!==A.GET&&(i.body=JSON.stringify(n)),i.headers={"Content-Type":"application/json",...a.headers,...t.headers},i.method=t.method;const{beforeRoute:u,beforeApi:g,beforeUrl:w,beforeConfig:T}=S({route:t,api:a,url:r,config:i});r=w,i=T,a=o.updateApi(g),t=o.updateRoute(u);const f=await fetch(r,i),{afterRoute:E,afterApi:P,afterData:b}=I({route:t,api:a,response:f,data:await f.json()});return o.updateApi(P),o.updateRoute(E),b}function y(a,t,e){let n=a;return t.arguments.forEach(r=>{if(e[r]===void 0)throw new Error(`Argument ${r} is missing`);n=n.replace(`[${r}]`,e[r])}),n}function S({route:a,api:t,url:e,config:n}){var i,u;const r=(u=(i=a.callbacks).before)==null?void 0:u.call(i,{route:a,api:t,url:e,config:n});return{beforeRoute:(r==null?void 0:r.route)||a,beforeApi:(r==null?void 0:r.api)||t,beforeUrl:(r==null?void 0:r.url)||e,beforeConfig:(r==null?void 0:r.config)||n}}function I({route:a,api:t,response:e,data:n}){var i,u;const r=(u=(i=a.callbacks).after)==null?void 0:u.call(i,{route:a,api:t,response:e,data:n});return{afterRoute:(r==null?void 0:r.route)||a,afterApi:(r==null?void 0:r.api)||t,afterResponse:(r==null?void 0:r.response)||e,afterData:(r==null?void 0:r.data)||n}}const c=class c{constructor(){s(this,"_apis",new Map);s(this,"_currentApi",null)}static get i(){return c._instance||(c._instance=new c),c._instance}registerApi(t){this._apis.set(t.name,t),l[t.name]={}}setCurrent(t){const e=this._apis.get(t);if(!e)throw new Error(`API ${t} not found`);this._currentApi=e}clearCurrent(){this._currentApi=null}registerRoute(t){if(!this._currentApi)throw new Error("No current API set, use Route only inside Api.create callback");t.api=this._currentApi.name,this._currentApi.routes.set(t.name,t),this.addToKlaimRoute(t.api,t)}getApi(t){return this._apis.get(t)}getRoute(t,e){const n=this._apis.get(t);if(!n)throw new Error(`API ${t} not found`);return n.routes.get(e)}static updateApi(t){return c.i._apis.has(t.name)||c.i.registerApi(t),c.i._apis.set(t.name,t),t}static updateRoute(t){const e=c.i._apis.get(t.api);if(!e)throw new Error(`API ${t.api} not found`);return e.routes.set(t.name,t),t}addToKlaimRoute(t,e){l[t][e.name]=async(n={},r={})=>{const i=c.i._apis.get(t);if(!i)throw new Error(`API ${e.api} not found`);return O(i,e,n,r)}}};s(c,"_instance");let o=c;class h{constructor(t,e,n){s(this,"name");s(this,"url");s(this,"headers");s(this,"routes",new Map);this.name=t,this.url=d(e),this.headers=n||{}}static create(t,e,n,r={}){const i=m(t);i!==t&&console.warn(`API name "${t}" has been camelCased to "${i}"`);const u=new h(i,e,r);return o.i.registerApi(u),o.i.setCurrent(i),n(),o.i.clearCurrent(),u}}exports.Api=h;exports.Klaim=l;exports.Registry=o;exports.Route=p;
1
+ "use strict";var $=Object.defineProperty;var k=(a,t,e)=>t in a?$(a,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):a[t]=e;var i=(a,t,e)=>k(a,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function d(a){return a.trim().replace(/^\/|\/$/g,"")}function A(a){return a.replace(/([-_][a-z])/gi,t=>t.toUpperCase().replace("-","").replace("_","")).replace(/(^\w)/,t=>t.toLowerCase())}class p{static subscribe(t,e){this._callbacks.set(t,e)}static run(t){const e=this._callbacks.get(t);e&&e()}}i(p,"_callbacks",new Map);var g=(a=>(a.GET="GET",a.POST="POST",a.PUT="PUT",a.DELETE="DELETE",a.PATCH="PATCH",a.OPTIONS="OPTIONS",a))(g||{});class h{constructor(t,e,n,r="GET"){i(this,"api","undefined");i(this,"name");i(this,"url");i(this,"method");i(this,"headers");i(this,"arguments",new Set);i(this,"callbacks",{before:null,after:null});this.name=A(t),this.name!==t&&console.warn(`Route name "${t}" has been camelCased to "${this.name}"`),this.url=d(e),this.headers=n||{},this.method=r,this.detectArguments()}static createRoute(t,e,n,r){const s=new h(t,e,n,r);return o.i.registerRoute(s),s}static get(t,e,n={}){return this.createRoute(t,e,n,"GET")}static post(t,e,n){return this.createRoute(t,e,n,"POST")}static put(t,e,n){return this.createRoute(t,e,n,"PUT")}static delete(t,e,n){return this.createRoute(t,e,n,"DELETE")}static patch(t,e,n){return this.createRoute(t,e,n,"PATCH")}static options(t,e,n){return this.createRoute(t,e,n,"OPTIONS")}before(t){return this.callbacks.before=t,this}after(t){return this.callbacks.after=t,this}detectArguments(){const t=this.url.match(/\[([^\]]+)]/g);t&&t.forEach(e=>{const n=e.replace(/\[|]/g,"");this.arguments.add(n)})}}const l={};async function O(a,t,e={},n={}){let r=_(`${a.url}/${t.url}`,t,e),s={};n&&t.method!==g.GET&&(s.body=JSON.stringify(n)),s.headers={"Content-Type":"application/json",...a.headers,...t.headers},s.method=t.method;const{beforeRoute:u,beforeApi:w,beforeUrl:T,beforeConfig:b}=y({route:t,api:a,url:r,config:s});r=T,s=b,a=o.updateApi(w),t=o.updateRoute(u);const m=await fetch(r,s),{afterRoute:E,afterApi:P,afterData:C}=S({route:t,api:a,response:m,data:await m.json()});return o.updateApi(P),o.updateRoute(E),p.run(`${a.name}.${t.name}`),C}function _(a,t,e){let n=a;return t.arguments.forEach(r=>{if(e[r]===void 0)throw new Error(`Argument ${r} is missing`);n=n.replace(`[${r}]`,e[r])}),n}function y({route:a,api:t,url:e,config:n}){var s,u;const r=(u=(s=a.callbacks).before)==null?void 0:u.call(s,{route:a,api:t,url:e,config:n});return{beforeRoute:(r==null?void 0:r.route)||a,beforeApi:(r==null?void 0:r.api)||t,beforeUrl:(r==null?void 0:r.url)||e,beforeConfig:(r==null?void 0:r.config)||n}}function S({route:a,api:t,response:e,data:n}){var s,u;const r=(u=(s=a.callbacks).after)==null?void 0:u.call(s,{route:a,api:t,response:e,data:n});return{afterRoute:(r==null?void 0:r.route)||a,afterApi:(r==null?void 0:r.api)||t,afterResponse:(r==null?void 0:r.response)||e,afterData:(r==null?void 0:r.data)||n}}const c=class c{constructor(){i(this,"_apis",new Map);i(this,"_currentApi",null)}static get i(){return c._instance||(c._instance=new c),c._instance}registerApi(t){this._apis.set(t.name,t),l[t.name]={}}setCurrent(t){const e=this._apis.get(t);if(!e)throw new Error(`API ${t} not found`);this._currentApi=e}clearCurrent(){this._currentApi=null}registerRoute(t){if(!this._currentApi)throw new Error("No current API set, use Route only inside Api.create callback");t.api=this._currentApi.name,this._currentApi.routes.set(t.name,t),this.addToKlaimRoute(t.api,t)}getApi(t){return this._apis.get(t)}getRoute(t,e){const n=this._apis.get(t);if(!n)throw new Error(`API ${t} not found`);return n.routes.get(e)}static updateApi(t){return c.i._apis.has(t.name)||c.i.registerApi(t),c.i._apis.set(t.name,t),t}static updateRoute(t){const e=c.i._apis.get(t.api);if(!e)throw new Error(`API ${t.api} not found`);return e.routes.set(t.name,t),t}addToKlaimRoute(t,e){l[t][e.name]=async(n={},r={})=>{const s=c.i._apis.get(t);if(!s)throw new Error(`API ${e.api} not found`);return O(s,e,n,r)}}};i(c,"_instance");let o=c;class f{constructor(t,e,n){i(this,"name");i(this,"url");i(this,"headers");i(this,"routes",new Map);this.name=t,this.url=d(e),this.headers=n||{}}static create(t,e,n,r={}){const s=A(t);s!==t&&console.warn(`API name "${t}" has been camelCased to "${s}"`);const u=new f(s,e,r);return o.i.registerApi(u),o.i.setCurrent(s),n(),o.i.clearCurrent(),u}}exports.Api=f;exports.Hook=p;exports.Klaim=l;exports.Registry=o;exports.Route=h;
package/dist/klaim.es.js CHANGED
@@ -1,12 +1,33 @@
1
- var b = Object.defineProperty;
2
- var $ = (a, t, e) => t in a ? b(a, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : a[t] = e;
3
- var s = (a, t, e) => $(a, typeof t != "symbol" ? t + "" : t, e);
1
+ var $ = Object.defineProperty;
2
+ var _ = (a, t, e) => t in a ? $(a, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : a[t] = e;
3
+ var i = (a, t, e) => _(a, typeof t != "symbol" ? t + "" : t, e);
4
4
  function h(a) {
5
5
  return a.trim().replace(/^\/|\/$/g, "");
6
6
  }
7
7
  function f(a) {
8
8
  return a.replace(/([-_][a-z])/gi, (t) => t.toUpperCase().replace("-", "").replace("_", "")).replace(/(^\w)/, (t) => t.toLowerCase());
9
9
  }
10
+ class m {
11
+ /**
12
+ * Subscribes to the hook
13
+ *
14
+ * @param routeName - The name of the route to subscribe to
15
+ * @param callback - The callback to subscribe
16
+ */
17
+ static subscribe(t, e) {
18
+ this._callbacks.set(t, e);
19
+ }
20
+ /**
21
+ * Runs the hook
22
+ *
23
+ * @param routeName - The name of the route to run
24
+ */
25
+ static run(t) {
26
+ const e = this._callbacks.get(t);
27
+ e && e();
28
+ }
29
+ }
30
+ i(m, "_callbacks", /* @__PURE__ */ new Map());
10
31
  var d = /* @__PURE__ */ ((a) => (a.GET = "GET", a.POST = "POST", a.PUT = "PUT", a.DELETE = "DELETE", a.PATCH = "PATCH", a.OPTIONS = "OPTIONS", a))(d || {});
11
32
  class A {
12
33
  /**
@@ -18,13 +39,13 @@ class A {
18
39
  * @param method - The HTTP method of the route
19
40
  */
20
41
  constructor(t, e, n, r = "GET") {
21
- s(this, "api", "undefined");
22
- s(this, "name");
23
- s(this, "url");
24
- s(this, "method");
25
- s(this, "headers");
26
- s(this, "arguments", /* @__PURE__ */ new Set());
27
- s(this, "callbacks", {
42
+ i(this, "api", "undefined");
43
+ i(this, "name");
44
+ i(this, "url");
45
+ i(this, "method");
46
+ i(this, "headers");
47
+ i(this, "arguments", /* @__PURE__ */ new Set());
48
+ i(this, "callbacks", {
28
49
  /**
29
50
  * Called before the request is sent
30
51
  */
@@ -46,8 +67,8 @@ class A {
46
67
  * @returns The new route
47
68
  */
48
69
  static createRoute(t, e, n, r) {
49
- const i = new A(t, e, n, r);
50
- return u.i.registerRoute(i), i;
70
+ const s = new A(t, e, n, r);
71
+ return u.i.registerRoute(s), s;
51
72
  }
52
73
  /**
53
74
  * Creates a new route with the GET method
@@ -181,28 +202,28 @@ class A {
181
202
  }
182
203
  }
183
204
  const p = {};
184
- async function O(a, t, e = {}, n = {}) {
185
- let r = I(`${a.url}/${t.url}`, t, e), i = {};
186
- n && t.method !== d.GET && (i.body = JSON.stringify(n)), i.headers = {
205
+ async function k(a, t, e = {}, n = {}) {
206
+ let r = O(`${a.url}/${t.url}`, t, e), s = {};
207
+ n && t.method !== d.GET && (s.body = JSON.stringify(n)), s.headers = {
187
208
  "Content-Type": "application/json",
188
209
  ...a.headers,
189
210
  ...t.headers
190
- }, i.method = t.method;
211
+ }, s.method = t.method;
191
212
  const {
192
213
  beforeRoute: o,
193
- beforeApi: w,
194
- beforeUrl: g,
195
- beforeConfig: T
196
- } = _({ route: t, api: a, url: r, config: i });
197
- r = g, i = T, a = u.updateApi(w), t = u.updateRoute(o);
198
- const l = await fetch(r, i), {
199
- afterRoute: E,
214
+ beforeApi: g,
215
+ beforeUrl: T,
216
+ beforeConfig: E
217
+ } = I({ route: t, api: a, url: r, config: s });
218
+ r = T, s = E, a = u.updateApi(g), t = u.updateRoute(o);
219
+ const l = await fetch(r, s), {
220
+ afterRoute: b,
200
221
  afterApi: P,
201
222
  afterData: C
202
223
  } = S({ route: t, api: a, response: l, data: await l.json() });
203
- return u.updateApi(P), u.updateRoute(E), C;
224
+ return u.updateApi(P), u.updateRoute(b), m.run(`${a.name}.${t.name}`), C;
204
225
  }
205
- function I(a, t, e) {
226
+ function O(a, t, e) {
206
227
  let n = a;
207
228
  return t.arguments.forEach((r) => {
208
229
  if (e[r] === void 0)
@@ -210,9 +231,9 @@ function I(a, t, e) {
210
231
  n = n.replace(`[${r}]`, e[r]);
211
232
  }), n;
212
233
  }
213
- function _({ route: a, api: t, url: e, config: n }) {
214
- var i, o;
215
- const r = (o = (i = a.callbacks).before) == null ? void 0 : o.call(i, { route: a, api: t, url: e, config: n });
234
+ function I({ route: a, api: t, url: e, config: n }) {
235
+ var s, o;
236
+ const r = (o = (s = a.callbacks).before) == null ? void 0 : o.call(s, { route: a, api: t, url: e, config: n });
216
237
  return {
217
238
  beforeRoute: (r == null ? void 0 : r.route) || a,
218
239
  beforeApi: (r == null ? void 0 : r.api) || t,
@@ -221,8 +242,8 @@ function _({ route: a, api: t, url: e, config: n }) {
221
242
  };
222
243
  }
223
244
  function S({ route: a, api: t, response: e, data: n }) {
224
- var i, o;
225
- const r = (o = (i = a.callbacks).after) == null ? void 0 : o.call(i, { route: a, api: t, response: e, data: n });
245
+ var s, o;
246
+ const r = (o = (s = a.callbacks).after) == null ? void 0 : o.call(s, { route: a, api: t, response: e, data: n });
226
247
  return {
227
248
  afterRoute: (r == null ? void 0 : r.route) || a,
228
249
  afterApi: (r == null ? void 0 : r.api) || t,
@@ -235,8 +256,8 @@ const c = class c {
235
256
  * Constructor
236
257
  */
237
258
  constructor() {
238
- s(this, "_apis", /* @__PURE__ */ new Map());
239
- s(this, "_currentApi", null);
259
+ i(this, "_apis", /* @__PURE__ */ new Map());
260
+ i(this, "_currentApi", null);
240
261
  }
241
262
  /**
242
263
  * Singleton instance
@@ -332,16 +353,16 @@ const c = class c {
332
353
  */
333
354
  addToKlaimRoute(t, e) {
334
355
  p[t][e.name] = async (n = {}, r = {}) => {
335
- const i = c.i._apis.get(t);
336
- if (!i)
356
+ const s = c.i._apis.get(t);
357
+ if (!s)
337
358
  throw new Error(`API ${e.api} not found`);
338
- return O(i, e, n, r);
359
+ return k(s, e, n, r);
339
360
  };
340
361
  }
341
362
  };
342
- s(c, "_instance");
363
+ i(c, "_instance");
343
364
  let u = c;
344
- class m {
365
+ class w {
345
366
  /**
346
367
  * Constructor
347
368
  *
@@ -350,10 +371,10 @@ class m {
350
371
  * @param headers - The headers to be sent with each request
351
372
  */
352
373
  constructor(t, e, n) {
353
- s(this, "name");
354
- s(this, "url");
355
- s(this, "headers");
356
- s(this, "routes", /* @__PURE__ */ new Map());
374
+ i(this, "name");
375
+ i(this, "url");
376
+ i(this, "headers");
377
+ i(this, "routes", /* @__PURE__ */ new Map());
357
378
  this.name = t, this.url = h(e), this.headers = n || {};
358
379
  }
359
380
  /**
@@ -366,14 +387,15 @@ class m {
366
387
  * @returns The new API
367
388
  */
368
389
  static create(t, e, n, r = {}) {
369
- const i = f(t);
370
- i !== t && console.warn(`API name "${t}" has been camelCased to "${i}"`);
371
- const o = new m(i, e, r);
372
- return u.i.registerApi(o), u.i.setCurrent(i), n(), u.i.clearCurrent(), o;
390
+ const s = f(t);
391
+ s !== t && console.warn(`API name "${t}" has been camelCased to "${s}"`);
392
+ const o = new w(s, e, r);
393
+ return u.i.registerApi(o), u.i.setCurrent(s), n(), u.i.clearCurrent(), o;
373
394
  }
374
395
  }
375
396
  export {
376
- m as Api,
397
+ w as Api,
398
+ m as Hook,
377
399
  p as Klaim,
378
400
  u as Registry,
379
401
  A as Route
package/dist/klaim.umd.js CHANGED
@@ -1 +1 @@
1
- (function(s,o){typeof exports=="object"&&typeof module<"u"?o(exports):typeof define=="function"&&define.amd?define(["exports"],o):(s=typeof globalThis<"u"?globalThis:s||self,o(s.klaim={}))})(this,function(s){"use strict";var I=Object.defineProperty;var _=(s,o,h)=>o in s?I(s,o,{enumerable:!0,configurable:!0,writable:!0,value:h}):s[o]=h;var c=(s,o,h)=>_(s,typeof o!="symbol"?o+"":o,h);function o(i){return i.trim().replace(/^\/|\/$/g,"")}function h(i){return i.replace(/([-_][a-z])/gi,t=>t.toUpperCase().replace("-","").replace("_","")).replace(/(^\w)/,t=>t.toLowerCase())}var A=(i=>(i.GET="GET",i.POST="POST",i.PUT="PUT",i.DELETE="DELETE",i.PATCH="PATCH",i.OPTIONS="OPTIONS",i))(A||{});class f{constructor(t,e,r,n="GET"){c(this,"api","undefined");c(this,"name");c(this,"url");c(this,"method");c(this,"headers");c(this,"arguments",new Set);c(this,"callbacks",{before:null,after:null});this.name=h(t),this.name!==t&&console.warn(`Route name "${t}" has been camelCased to "${this.name}"`),this.url=o(e),this.headers=r||{},this.method=n,this.detectArguments()}static createRoute(t,e,r,n){const a=new f(t,e,r,n);return l.i.registerRoute(a),a}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")}before(t){return this.callbacks.before=t,this}after(t){return this.callbacks.after=t,this}detectArguments(){const t=this.url.match(/\[([^\]]+)]/g);t&&t.forEach(e=>{const r=e.replace(/\[|]/g,"");this.arguments.add(r)})}}const d={};async function w(i,t,e={},r={}){let n=T(`${i.url}/${t.url}`,t,e),a={};r&&t.method!==A.GET&&(a.body=JSON.stringify(r)),a.headers={"Content-Type":"application/json",...i.headers,...t.headers},a.method=t.method;const{beforeRoute:p,beforeApi:b,beforeUrl:C,beforeConfig:$}=E({route:t,api:i,url:n,config:a});n=C,a=$,i=l.updateApi(b),t=l.updateRoute(p);const g=await fetch(n,a),{afterRoute:y,afterApi:O,afterData:S}=P({route:t,api:i,response:g,data:await g.json()});return l.updateApi(O),l.updateRoute(y),S}function T(i,t,e){let r=i;return t.arguments.forEach(n=>{if(e[n]===void 0)throw new Error(`Argument ${n} is missing`);r=r.replace(`[${n}]`,e[n])}),r}function E({route:i,api:t,url:e,config:r}){var a,p;const n=(p=(a=i.callbacks).before)==null?void 0:p.call(a,{route:i,api:t,url:e,config:r});return{beforeRoute:(n==null?void 0:n.route)||i,beforeApi:(n==null?void 0:n.api)||t,beforeUrl:(n==null?void 0:n.url)||e,beforeConfig:(n==null?void 0:n.config)||r}}function P({route:i,api:t,response:e,data:r}){var a,p;const n=(p=(a=i.callbacks).after)==null?void 0:p.call(a,{route:i,api:t,response:e,data:r});return{afterRoute:(n==null?void 0:n.route)||i,afterApi:(n==null?void 0:n.api)||t,afterResponse:(n==null?void 0:n.response)||e,afterData:(n==null?void 0:n.data)||r}}const u=class u{constructor(){c(this,"_apis",new Map);c(this,"_currentApi",null)}static get i(){return u._instance||(u._instance=new u),u._instance}registerApi(t){this._apis.set(t.name,t),d[t.name]={}}setCurrent(t){const e=this._apis.get(t);if(!e)throw new Error(`API ${t} not found`);this._currentApi=e}clearCurrent(){this._currentApi=null}registerRoute(t){if(!this._currentApi)throw new Error("No current API set, use Route only inside Api.create callback");t.api=this._currentApi.name,this._currentApi.routes.set(t.name,t),this.addToKlaimRoute(t.api,t)}getApi(t){return this._apis.get(t)}getRoute(t,e){const r=this._apis.get(t);if(!r)throw new Error(`API ${t} not found`);return r.routes.get(e)}static updateApi(t){return u.i._apis.has(t.name)||u.i.registerApi(t),u.i._apis.set(t.name,t),t}static updateRoute(t){const e=u.i._apis.get(t.api);if(!e)throw new Error(`API ${t.api} not found`);return e.routes.set(t.name,t),t}addToKlaimRoute(t,e){d[t][e.name]=async(r={},n={})=>{const a=u.i._apis.get(t);if(!a)throw new Error(`API ${e.api} not found`);return w(a,e,r,n)}}};c(u,"_instance");let l=u;class m{constructor(t,e,r){c(this,"name");c(this,"url");c(this,"headers");c(this,"routes",new Map);this.name=t,this.url=o(e),this.headers=r||{}}static create(t,e,r,n={}){const a=h(t);a!==t&&console.warn(`API name "${t}" has been camelCased to "${a}"`);const p=new m(a,e,n);return l.i.registerApi(p),l.i.setCurrent(a),r(),l.i.clearCurrent(),p}}s.Api=m,s.Klaim=d,s.Registry=l,s.Route=f,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"})});
1
+ (function(s,o){typeof exports=="object"&&typeof module<"u"?o(exports):typeof define=="function"&&define.amd?define(["exports"],o):(s=typeof globalThis<"u"?globalThis:s||self,o(s.klaim={}))})(this,function(s){"use strict";var S=Object.defineProperty;var I=(s,o,h)=>o in s?S(s,o,{enumerable:!0,configurable:!0,writable:!0,value:h}):s[o]=h;var c=(s,o,h)=>I(s,typeof o!="symbol"?o+"":o,h);function o(i){return i.trim().replace(/^\/|\/$/g,"")}function h(i){return i.replace(/([-_][a-z])/gi,t=>t.toUpperCase().replace("-","").replace("_","")).replace(/(^\w)/,t=>t.toLowerCase())}class f{static subscribe(t,e){this._callbacks.set(t,e)}static run(t){const e=this._callbacks.get(t);e&&e()}}c(f,"_callbacks",new Map);var g=(i=>(i.GET="GET",i.POST="POST",i.PUT="PUT",i.DELETE="DELETE",i.PATCH="PATCH",i.OPTIONS="OPTIONS",i))(g||{});class d{constructor(t,e,r,n="GET"){c(this,"api","undefined");c(this,"name");c(this,"url");c(this,"method");c(this,"headers");c(this,"arguments",new Set);c(this,"callbacks",{before:null,after:null});this.name=h(t),this.name!==t&&console.warn(`Route name "${t}" has been camelCased to "${this.name}"`),this.url=o(e),this.headers=r||{},this.method=n,this.detectArguments()}static createRoute(t,e,r,n){const a=new d(t,e,r,n);return l.i.registerRoute(a),a}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")}before(t){return this.callbacks.before=t,this}after(t){return this.callbacks.after=t,this}detectArguments(){const t=this.url.match(/\[([^\]]+)]/g);t&&t.forEach(e=>{const r=e.replace(/\[|]/g,"");this.arguments.add(r)})}}const m={};async function T(i,t,e={},r={}){let n=b(`${i.url}/${t.url}`,t,e),a={};r&&t.method!==g.GET&&(a.body=JSON.stringify(r)),a.headers={"Content-Type":"application/json",...i.headers,...t.headers},a.method=t.method;const{beforeRoute:p,beforeApi:C,beforeUrl:$,beforeConfig:k}=E({route:t,api:i,url:n,config:a});n=$,a=k,i=l.updateApi(C),t=l.updateRoute(p);const w=await fetch(n,a),{afterRoute:y,afterApi:O,afterData:_}=P({route:t,api:i,response:w,data:await w.json()});return l.updateApi(O),l.updateRoute(y),f.run(`${i.name}.${t.name}`),_}function b(i,t,e){let r=i;return t.arguments.forEach(n=>{if(e[n]===void 0)throw new Error(`Argument ${n} is missing`);r=r.replace(`[${n}]`,e[n])}),r}function E({route:i,api:t,url:e,config:r}){var a,p;const n=(p=(a=i.callbacks).before)==null?void 0:p.call(a,{route:i,api:t,url:e,config:r});return{beforeRoute:(n==null?void 0:n.route)||i,beforeApi:(n==null?void 0:n.api)||t,beforeUrl:(n==null?void 0:n.url)||e,beforeConfig:(n==null?void 0:n.config)||r}}function P({route:i,api:t,response:e,data:r}){var a,p;const n=(p=(a=i.callbacks).after)==null?void 0:p.call(a,{route:i,api:t,response:e,data:r});return{afterRoute:(n==null?void 0:n.route)||i,afterApi:(n==null?void 0:n.api)||t,afterResponse:(n==null?void 0:n.response)||e,afterData:(n==null?void 0:n.data)||r}}const u=class u{constructor(){c(this,"_apis",new Map);c(this,"_currentApi",null)}static get i(){return u._instance||(u._instance=new u),u._instance}registerApi(t){this._apis.set(t.name,t),m[t.name]={}}setCurrent(t){const e=this._apis.get(t);if(!e)throw new Error(`API ${t} not found`);this._currentApi=e}clearCurrent(){this._currentApi=null}registerRoute(t){if(!this._currentApi)throw new Error("No current API set, use Route only inside Api.create callback");t.api=this._currentApi.name,this._currentApi.routes.set(t.name,t),this.addToKlaimRoute(t.api,t)}getApi(t){return this._apis.get(t)}getRoute(t,e){const r=this._apis.get(t);if(!r)throw new Error(`API ${t} not found`);return r.routes.get(e)}static updateApi(t){return u.i._apis.has(t.name)||u.i.registerApi(t),u.i._apis.set(t.name,t),t}static updateRoute(t){const e=u.i._apis.get(t.api);if(!e)throw new Error(`API ${t.api} not found`);return e.routes.set(t.name,t),t}addToKlaimRoute(t,e){m[t][e.name]=async(r={},n={})=>{const a=u.i._apis.get(t);if(!a)throw new Error(`API ${e.api} not found`);return T(a,e,r,n)}}};c(u,"_instance");let l=u;class A{constructor(t,e,r){c(this,"name");c(this,"url");c(this,"headers");c(this,"routes",new Map);this.name=t,this.url=o(e),this.headers=r||{}}static create(t,e,r,n={}){const a=h(t);a!==t&&console.warn(`API name "${t}" has been camelCased to "${a}"`);const p=new A(a,e,n);return l.i.registerApi(p),l.i.setCurrent(a),r(),l.i.clearCurrent(),p}}s.Api=A,s.Hook=f,s.Klaim=m,s.Registry=l,s.Route=d,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "homepage": "https://github.com/antharuu/klaim#readme",
22
22
  "type": "module",
23
- "version": "1.1.1",
23
+ "version": "1.2.1",
24
24
  "main": "dist/klaim.cjs.js",
25
25
  "module": "dist/klaim.es.js",
26
26
  "types": "dist/index.d.ts",
@@ -0,0 +1,32 @@
1
+ type IHookCallback = () => any;
2
+
3
+ /**
4
+ * Represents hooks
5
+ */
6
+ export class Hook {
7
+ private static _callbacks: Map<string, IHookCallback> = new Map<string, IHookCallback>();
8
+
9
+ /**
10
+ * Subscribes to the hook
11
+ *
12
+ * @param routeName - The name of the route to subscribe to
13
+ * @param callback - The callback to subscribe
14
+ */
15
+ public static subscribe (routeName: string, callback: IHookCallback): void {
16
+ this._callbacks.set(routeName, callback);
17
+ }
18
+
19
+ /**
20
+ * Runs the hook
21
+ *
22
+ * @param routeName - The name of the route to run
23
+ */
24
+ public static run (routeName: string): void {
25
+ const callback = this._callbacks.get(routeName);
26
+ if (!callback) {
27
+ return;
28
+ }
29
+
30
+ callback();
31
+ }
32
+ }
package/src/core/Klaim.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Api } from "./Api";
2
+ import { Hook } from "./Hook";
2
3
  import { Registry } from "./Registry";
3
4
  import { ICallbackAfter, ICallbackBefore, Route, RouteMethod } from "./Route";
4
5
 
@@ -59,6 +60,8 @@ export async function callApi<T> (api: Api, route: Route, args: IArgs = {}, body
59
60
  Registry.updateApi(afterApi);
60
61
  Registry.updateRoute(afterRoute);
61
62
 
63
+ Hook.run(`${api.name}.${route.name}`);
64
+
62
65
  return afterData as T;
63
66
  }
64
67
 
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { Api } from "./core/Api";
2
+ export { Hook } from "./core/Hook";
2
3
  export { Klaim } from "./core/Klaim";
3
4
  export { Registry } from "./core/Registry";
4
5
  export { Route } from "./core/Route";