klaim 1.7.0-alpha.2 → 1.7.0

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
@@ -8,9 +8,13 @@
8
8
  - [Basic API Configuration](#basic-api-configuration)
9
9
  - [Route Definition](#route-definition)
10
10
  - [Request Handling](#request-handling)
11
+ - [Groups](#groups)
12
+ - [API Groups](#api-groups)
13
+ - [Route Groups](#route-groups)
14
+ - [Nested Groups](#nested-groups)
15
+ - [Group Configuration](#group-configuration)
11
16
  - [Middleware Usage](#middleware-usage)
12
17
  - [Hook Subscription](#hook-subscription)
13
- - [Group Usage](#group-usage)
14
18
  - [Caching Requests](#caching-requests)
15
19
  - [Retry Mechanism](#retry-mechanism)
16
20
  - [Response Validation](#response-validation)
@@ -21,12 +25,13 @@
21
25
  ## 🚀 Features
22
26
 
23
27
  - **Efficient API Management**: Easily manage multiple APIs with streamlined integration and interaction capabilities.
28
+ - **API Grouping**: Organize related APIs into logical groups with shared settings and configuration.
29
+ - **Route Grouping**: Organize related routes into logical groups with inherited settings.
24
30
  - **Request Recording**: Seamlessly track requests for debugging and monitoring.
25
31
  - **User Experience Optimization**: Focused on performance and usability for a smooth user experience.
26
32
  - **Lightweight**: Minimal footprint for fast load times and minimal performance impact.
27
33
  - **Middleware Support**: Easily add middleware to modify requests and responses (`before` and `after`).
28
34
  - **Hook System**: Subscribe to hooks to monitor and react to specific events.
29
- - **Group Organization**: Organize related routes into logical groups with inherited settings.
30
35
  - **Caching**: Enable caching on requests to reduce network load and improve performance.
31
36
  - **Retry Mechanism**: Automatically retry failed requests to enhance reliability.
32
37
  - **TypeScript Support**: Fully typed for enhanced code quality and developer experience.
@@ -76,19 +81,147 @@ Api.create("hello", "https://jsonplaceholder.typicode.com/", () => {
76
81
 
77
82
  ### Route Definition
78
83
 
79
- Define various routes within the API callback:
84
+ Routes represent endpoints in your API and can be defined with different HTTP methods. Routes can include parameters and custom configurations:
80
85
 
81
86
  ```typescript
82
- Api.create("hello", "https://jsonplaceholder.typicode.com/", () => {
83
- // Get a list of todos
84
- Route.get<Todo[]>("listTodos", "todos");
87
+ Api.create("api", "https://api.example.com", () => {
88
+ // Basic GET route
89
+ Route.get("listUsers", "/users");
90
+
91
+ // GET route with URL parameter
92
+ Route.get("getUser", "/users/[id]");
93
+
94
+ // POST route with custom headers and body
95
+ Route.post("createUser", "/users", {
96
+ "Content-Type": "application/json"
97
+ }, { userId: 1, name: "John Doe" });
98
+
99
+ // PUT route with parameter
100
+ Route.put("updateUser", "/users/[id]");
101
+
102
+ // DELETE route
103
+ Route.delete("deleteUser", "/users/[id]");
104
+
105
+ // PATCH route
106
+ Route.patch("updateUserStatus", "/users/[id]/status");
107
+
108
+ // OPTIONS route
109
+ Route.options("userOptions", "/users");
110
+ });
111
+ ```
85
112
 
86
- // Get a specific todo by id
87
- Route.get<Todo>("getTodo", "todos/[id]");
113
+ ### Groups
88
114
 
89
- // Add a new todo
90
- Route.post<Todo>("addTodo", "todos");
115
+ Klaim provides powerful grouping capabilities for both APIs and routes. Groups can be used to organize related elements, share configuration, and maintain a clean structure in your application.
116
+
117
+ #### API Groups
118
+
119
+ Organize multiple APIs that serve related purposes:
120
+
121
+ ```typescript
122
+ import {Group, Api, Route} from 'klaim';
123
+
124
+ // Create a group for user-related services
125
+ Group.create("userServices", () => {
126
+ // Authentication API
127
+ Api.create("auth", "https://auth.example.com", () => {
128
+ Route.post("login", "/login");
129
+ Route.post("register", "/register");
130
+ });
131
+
132
+ // User Management API
133
+ Api.create("users", "https://users.example.com", () => {
134
+ Route.get("list", "/users");
135
+ Route.get("getOne", "/users/[id]");
136
+ });
137
+ }).withRetry(3); // Apply retry mechanism to all APIs in the group
138
+
139
+ // Access grouped APIs
140
+ await Klaim.userServices.auth.login({}, { username: "user", password: "pass" });
141
+ await Klaim.userServices.users.list();
142
+ ```
143
+
144
+ #### Route Groups
145
+
146
+ Organize routes within an API into logical groups:
147
+
148
+ ```typescript
149
+ Api.create("hello", "https://api.example.com/", () => {
150
+ // Group user-related routes
151
+ Group.create("users", () => {
152
+ Route.get<User[]>("list", "/users");
153
+ Route.get<User>("getOne", "/users/[id]");
154
+ Route.post<User>("create", "/users");
155
+ }).withCache(60); // Cache all user routes for 60 seconds
156
+
157
+ // Group product-related routes
158
+ Group.create("products", () => {
159
+ Route.get("list", "/products");
160
+ Route.get("getOne", "/products/[id]");
161
+ });
91
162
  });
163
+
164
+ // Use grouped routes
165
+ const users = await Klaim.hello.users.list();
166
+ const product = await Klaim.hello.products.getOne({ id: 1 });
167
+ ```
168
+
169
+ #### Nested Groups
170
+
171
+ Create complex hierarchies with nested groups:
172
+
173
+ ```typescript
174
+ Group.create("services", () => {
175
+ // Internal services group
176
+ Group.create("internal", () => {
177
+ Api.create("logs", "https://logs.internal.example.com", () => {
178
+ Route.post("write", "/logs");
179
+ });
180
+
181
+ Api.create("metrics", "https://metrics.internal.example.com", () => {
182
+ Route.post("track", "/metrics");
183
+ });
184
+ }).withRetry(5); // More retries for internal services
185
+
186
+ // External services group
187
+ Group.create("external", () => {
188
+ Api.create("weather", "https://api.weather.com", () => {
189
+ Route.get("forecast", "/forecast/[city]");
190
+ });
191
+
192
+ Api.create("geocoding", "https://api.geocoding.com", () => {
193
+ Route.get("search", "/search/[query]");
194
+ });
195
+ }).withCache(300); // Cache external services longer
196
+ });
197
+
198
+ // Access nested groups
199
+ await Klaim.services.internal.logs.write({}, { message: "Log entry" });
200
+ await Klaim.services.external.weather.forecast({ city: "Paris" });
201
+ ```
202
+
203
+ #### Group Configuration
204
+
205
+ Groups can share configuration among all their members:
206
+
207
+ ```typescript
208
+ Group.create("apis", () => {
209
+ Api.create("service1", "https://api1.example.com", () => {
210
+ Route.get("test", "/test");
211
+ });
212
+
213
+ Api.create("service2", "https://api2.example.com", () => {
214
+ Route.get("test", "/test");
215
+ });
216
+ })
217
+ .withCache(60) // Enable caching for all APIs
218
+ .withRetry(3) // Enable retries for all APIs
219
+ .before(({ config }) => { // Add authentication for all APIs
220
+ config.headers.Authorization = `Bearer ${getToken()}`;
221
+ })
222
+ .after(({ data }) => { // Process all responses
223
+ logResponse(data);
224
+ });
92
225
  ```
93
226
 
94
227
  ### Request Handling
@@ -143,32 +276,6 @@ Hook.subscribe("hello.getFirstTodo", ({url}) => {
143
276
  });
144
277
  ```
145
278
 
146
- ### Group Usage
147
-
148
- Use groups to organize related routes and share common settings:
149
-
150
- ```typescript
151
- import {Api, Group, Route} from 'klaim';
152
-
153
- Api.create("hello", "https://jsonplaceholder.typicode.com/", () => {
154
- // Create a group for user-related routes
155
- Group.create("users", () => {
156
- Route.get("list", "/users");
157
- Route.get("getOne", "/users/[id]");
158
-
159
- // Nested group for user posts
160
- Group.create("posts", () => {
161
- Route.get("list", "/users/[userId]/posts");
162
- }).withCache(); // Cache enabled for all routes in this group
163
- });
164
- });
165
-
166
- // Use the grouped routes
167
- const users = await Klaim.hello.users.list();
168
- const user = await Klaim.hello.users.getOne({id: 1});
169
- const userPosts = await Klaim.hello.users.posts.list({userId: 1});
170
- ```
171
-
172
279
  ### Caching Requests
173
280
 
174
281
  Enable caching on requests to reduce network load and improve performance. By default, the cache duration is 20 seconds,
package/deno.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antharuu/klaim",
3
- "version": "1.6.34",
3
+ "version": "1.7.0",
4
4
  "description": "Klaim is a lightweight TypeScript library designed to manage APIs and record requests, optimized for an optimal user experience.",
5
5
  "repository": {
6
6
  "type": "git",
package/dist/klaim.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var F=Object.defineProperty;var S=(s,t,e)=>t in s?F(s,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[t]=e;var o=(s,t,e)=>S(s,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function y(s){return s.replace(/([-_][a-z])/gi,t=>t.toUpperCase().replace("-","").replace("_","")).replace(/(^\w)/,t=>t.toLowerCase())}function v(s){return s.trim().replace(/^\/|\/$/g,"")}class P{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,"callbacks",{before:null,after:null,call:null});o(this,"cache",!1);o(this,"retry",!1);this.type=t,this.name=y(e),this.name!==e&&console.warn(`Name "${e}" has been camelCased to "${this.name}"`),this.url=v(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}withCache(t=20){return this.cache=t,this}withRetry(t=2){return this.retry=t,this}}const f=class f{constructor(){o(this,"cache");this.cache=new Map}static get i(){return f._instance||(f._instance=new f),f._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(f,"_instance");let g=f;function T(s){let a=2166136261;for(let n=0;n<s.length;n++)a^=s.charCodeAt(n),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 K(s,t,e){const a=`${s.toString()}${JSON.stringify(t)}`,r=T(a);if(g.i.has(r))return g.i.get(r);const c=await(await fetch(s,t)).json();return g.i.set(r,c,e),c}class C{static subscribe(t,e){this._callbacks.set(t,e)}static run(t){const e=this._callbacks.get(t);e&&e()}}o(C,"_callbacks",new Map);const m={};async function R(s,t,e={},a={}){const r=i.i.getApi(s.split(".")[0]);if(!t||!r||t.type!=="route"||r.type!=="api")throw new Error(`Invalid path: ${s}.${t.name}`);let n=j(`${r.url}/${t.url}`,t,e),c={};a&&t.method!=="GET"&&(c.body=JSON.stringify(a)),c.headers={"Content-Type":"application/json",...r.headers,...t.headers},c.method=t.method;const{beforeRoute:u,beforeApi:h,beforeUrl:d,beforeConfig:w}=x({route:t,api:r,url:n,config:c});n=d,c=w,i.updateElement(h),i.updateElement(u);let p=await O(r,t,n,c);t.schema&&"validate"in t.schema&&(p=await t.schema.validate(p));const{afterRoute:k,afterApi:A,afterData:_}=D({route:t,api:r,response:p,data:p});return i.updateElement(A),i.updateElement(k),C.run(`${r.name}.${t.name}`),_}async function N(s,t,e,a){return s?await K(t,e,a.cache):await(await fetch(t,e)).json()}async function O(s,t,e,a){var d,w;const r=s.cache||t.cache,n=t.retry||s.retry||0;let c,u=!1,h=0;for(;h<=n&&!u;)try{(d=t.callbacks)!=null&&d.call?t.callbacks.call({}):(w=s.callbacks)!=null&&w.call&&s.callbacks.call({}),c=await N(!!r,e,a,s),u=!0}catch(p){if(h++,h>n)throw p.message=`Failed to fetch ${e} after ${n} attempts`,p}return c}function j(s,t,e){let a=s;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:s,api:t,url:e,config:a}){var n,c;const r=(c=(n=s.callbacks).before)==null?void 0:c.call(n,{route:s,api:t,url:e,config:a});return{beforeRoute:(r==null?void 0:r.route)||s,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 D({route:s,api:t,response:e,data:a}){var n,c;const r=(c=(n=s.callbacks).after)==null?void 0:c.call(n,{route:s,api:t,response:e,data:a});return{afterRoute:(r==null?void 0:r.route)||s,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 l=class l{constructor(){o(this,"_elements",new Map);o(this,"_currentParent",null)}static get i(){return l._instance||(l._instance=new l),l._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=m;e&&(r=this.getOrCreateKlaimBranch(e)),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");const e=this.getFullPath(this._currentParent);if(!this._elements.has(e))throw new Error(`Parent element ${e} not found`);t.parent=e;const a=this.getElementKey(t);this._elements.set(a,t),this.addToKlaimRoute(t)}getOrCreateKlaimBranch(t){let e=m;const r=this.getFullPath(t).split(".");for(const n of r)e[n]||(e[n]={}),e=e[n];return e}addToKlaimRoute(t){if(!t.parent)return;const e=t.parent.split(".");let a=m;for(const r of e)a[r]||(a[r]={}),a=a[r];a[t.name]=function(n={},c={}){return R(t.parent,t,n,c)}}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 l.i._elements.get(l.i.getElementKey(t))||t}getApi(t){const e=this._elements.get(t);if(e)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("."),n=this._elements.get(r);if((n==null?void 0:n.type)==="api")return n}}};o(l,"_instance");let i=l;class b extends P{static create(t,e,a,r={}){const n=y(t);n!==t&&console.warn(`API name "${t}" has been camelCased to "${n}"`);const c=new b(n,e,r);return i.i.registerElement(c),i.i.setCurrentParent(n),a(),i.i.clearCurrentParent(),c}constructor(t,e,a={}){super("api",t,e,a)}}class E extends P{static create(t,e){const a=y(t),r=i.i.getCurrentParent(),n=r?i.i.getFullPath(r):"",c=n?`${n}.${a}`:a,u=new E(a,"");a!==t&&console.warn(`Group name "${t}" has been camelCased to "${a}"`),i.i.registerElement(u);const h=i.i.getCurrentParent();return i.i.setCurrentParent(c),e(),h?i.i.setCurrentParent(i.i.getFullPath(h)):i.i.clearCurrentParent(),u}constructor(t,e,a={}){super("group",t,e,a)}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}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 $ extends P{constructor(t,e,a={},r="GET"){super("route",t,e,a),this.method=r,this.detectArguments()}static createRoute(t,e,a={},r){const n=new $(t,e,a,r);return i.i.registerRoute(n),n}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=b;exports.Group=E;exports.Hook=C;exports.Klaim=m;exports.Registry=i;exports.Route=$;
1
+ "use strict";var T=Object.defineProperty;var R=(s,t,e)=>t in s?T(s,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[t]=e;var o=(s,t,e)=>R(s,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function b(s){return s.replace(/([-_][a-z])/gi,t=>t.toUpperCase().replace("-","").replace("_","")).replace(/(^\w)/,t=>t.toLowerCase())}function K(s){return s.trim().replace(/^\/|\/$/g,"")}class C{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,"callbacks",{before:null,after:null,call:null});o(this,"cache",!1);o(this,"retry",!1);this.type=t,this.name=b(e),this.name!==e&&console.warn(`Name "${e}" has been camelCased to "${this.name}"`),this.url=K(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}withCache(t=20){return this.cache=t,this}withRetry(t=2){return this.retry=t,this}}const p=class p{constructor(){o(this,"cache");this.cache=new Map}static get i(){return p._instance||(p._instance=new p),p._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(p,"_instance");let g=p;function N(s){let a=2166136261;for(let n=0;n<s.length;n++)a^=s.charCodeAt(n),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(s,t,e){const a=`${s.toString()}${JSON.stringify(t)}`,r=N(a);if(g.i.has(r))return g.i.get(r);const c=await(await fetch(s,t)).json();return g.i.set(r,c,e),c}class E{static subscribe(t,e){this._callbacks.set(t,e)}static run(t){const e=this._callbacks.get(t);e&&e()}}o(E,"_callbacks",new Map);const m={};async function x(s,t,e={},a={}){const r=s.split(".");let n;for(let y=0;y<r.length;y++){const v=r[y];if(n=i.i.getApi(v),n)break}if(!t||!n||t.type!=="route"||n.type!=="api")throw new Error(`Invalid path: ${s}.${t.name}`);let c=O(`${n.url}/${t.url}`,t,e),l={};a&&t.method!=="GET"&&(l.body=JSON.stringify(a)),l.headers={"Content-Type":"application/json",...n.headers,...t.headers},l.method=t.method;const{beforeRoute:h,beforeApi:f,beforeUrl:d,beforeConfig:P}=U({route:t,api:n,url:c,config:l});c=d,l=P,i.updateElement(f),i.updateElement(h);let w=await G(n,t,c,l);t.schema&&"validate"in t.schema&&(w=await t.schema.validate(w));const{afterRoute:_,afterApi:F,afterData:S}=H({route:t,api:n,response:w,data:w});return i.updateElement(F),i.updateElement(_),E.run(`${n.name}.${t.name}`),S}async function D(s,t,e,a){return s?await j(t,e,a.cache):await(await fetch(t,e)).json()}async function G(s,t,e,a){var f,d;const r=s.cache||t.cache,n=t.retry||s.retry||0;let c,l=!1,h=0;for(;h<=n&&!l;)try{(f=t.callbacks)!=null&&f.call?t.callbacks.call({}):(d=s.callbacks)!=null&&d.call&&s.callbacks.call({}),c=await D(!!r,e,a,s),l=!0}catch(P){if(h++,h>n)throw P.message=`Failed to fetch ${e} after ${n} attempts`,P}return c}function O(s,t,e){let a=s;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 U({route:s,api:t,url:e,config:a}){var n,c;const r=(c=(n=s.callbacks).before)==null?void 0:c.call(n,{route:s,api:t,url:e,config:a});return{beforeRoute:(r==null?void 0:r.route)||s,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 H({route:s,api:t,response:e,data:a}){var n,c;const r=(c=(n=s.callbacks).after)==null?void 0:c.call(n,{route:s,api:t,response:e,data:a});return{afterRoute:(r==null?void 0:r.route)||s,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 u=class u{constructor(){o(this,"_elements",new Map);o(this,"_currentParent",null)}static get i(){return u._instance||(u._instance=new u),u._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=m;if(e){const n=this.getFullPath(e).split(".");for(const c of n)r[c]||(r[c]={}),r=r[c]}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=m;const a=t.parent.split(".");for(const r of a)e[r]||(e[r]={}),e=e[r];e[t.name]=function(r={},n={}){return x(t.parent,t,r,n)}}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 u.i._elements.get(u.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("."),n=this._elements.get(r);if((n==null?void 0:n.type)==="api")return n}}};o(u,"_instance");let i=u;class $ extends C{static create(t,e,a,r={}){const n=b(t);n!==t&&console.warn(`API name "${t}" has been camelCased to "${n}"`);const c=new $(n,e,r),l=i.i.getCurrentParent();i.i.registerElement(c);const h=l?i.i.getFullPath(l):"",f=h?`${h}.${n}`:n;return i.i.setCurrentParent(f),a(),l?i.i.setCurrentParent(i.i.getFullPath(l)):i.i.clearCurrentParent(),c}constructor(t,e,a={}){super("api",t,e,a)}}class k extends C{static create(t,e){const a=b(t),r=i.i.getCurrentParent(),n=r?i.i.getFullPath(r):"",c=n?`${n}.${a}`:a,l=new k(a,"");a!==t&&console.warn(`Group name "${t}" has been camelCased to "${a}"`),i.i.registerElement(l);const h=i.i.getCurrentParent();return i.i.setCurrentParent(c),e(),h?i.i.setCurrentParent(i.i.getFullPath(h)):i.i.clearCurrentParent(),l}constructor(t,e,a={}){super("group",t,e,a)}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}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 A extends C{constructor(t,e,a={},r="GET"){super("route",t,e,a),this.method=r,this.detectArguments()}static createRoute(t,e,a={},r){const n=new A(t,e,a,r);return i.i.registerRoute(n),n}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=$;exports.Group=k;exports.Hook=E;exports.Klaim=m;exports.Registry=i;exports.Route=A;