buildx-sdk 1.8.17 → 1.8.19

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
@@ -7,6 +7,7 @@ Official JavaScript/TypeScript SDK for Buildx APIs.
7
7
  ## Contents
8
8
  - [Install](#install)
9
9
  - [Quick Start](#quick-start)
10
+ - [Testing](#testing)
10
11
  - [SDK Boundary](#sdk-boundary)
11
12
  - [How Scoping Works](#how-scoping-works)
12
13
  - [Configuration](#configuration)
@@ -19,6 +20,7 @@ Official JavaScript/TypeScript SDK for Buildx APIs.
19
20
  - [Flows](#flows)
20
21
  - [Templates](#templates)
21
22
  - [Functions](#functions)
23
+ - [Crypto](#crypto)
22
24
  - [Buildx Objects](#buildx-objects)
23
25
  - [API Keys](#api-keys)
24
26
  - [Production Notes](#production-notes)
@@ -60,6 +62,13 @@ const orders = await collections.query("orders", {
60
62
  });
61
63
  ```
62
64
 
65
+ ## Testing
66
+
67
+ `buildx-sdk` uses `vitest` as the package test runner.
68
+
69
+ - Run once: `yarn test`
70
+ - Watch mode: `yarn test:watch`
71
+
63
72
  ## SDK Boundary
64
73
 
65
74
  `buildx-sdk` is the **public/client SDK** for Buildx APIs.
@@ -117,6 +126,7 @@ type ErrorResponse = {
117
126
  error: string;
118
127
  message: string;
119
128
  statusCode: number;
129
+ code?: string;
120
130
  success: false;
121
131
  };
122
132
  ```
@@ -131,6 +141,12 @@ function isError<T>(value: T | ErrorResponse): value is ErrorResponse {
131
141
  }
132
142
  ```
133
143
 
144
+ Auth error code policy used by SDK auto-refresh:
145
+
146
+ - `E02006` (`TOKEN_EXPIRED`): SDK may try refresh-token flow
147
+ - `E02005` (`UNAUTHORIZED`): SDK fail-fast (no refresh) and caller should re-authenticate
148
+ - `403/forbidden` is not treated as session-expired by default
149
+
134
150
  ## Authentication
135
151
 
136
152
  ### Login / Signup / Current User
@@ -160,6 +176,37 @@ auth.clearTokens();
160
176
  await auth.refreshToken();
161
177
  ```
162
178
 
179
+ ### Device Trust (Optional)
180
+
181
+ SDK รองรับ device trust สำหรับ auth endpoints โดยไม่บังคับการใช้งาน:
182
+
183
+ - ถ้าไม่ตั้งค่า `clientId`/`clientProof`:
184
+ - auth flow เดิมยังทำงานได้ (เหมาะกับ policy `device_trust = none`)
185
+ - ถ้าตั้งค่า `clientId`/`clientProof`:
186
+ - SDK จะส่ง `x-client-id` / `x-client-proof` เฉพาะ auth endpoints
187
+ - SDK จะส่ง `client_id` / `client_proof` ใน payload auth ที่เกี่ยวข้อง
188
+ - SDK จะไม่รอ `device_token` แล้ว และจะอัปเดต `clientProof` จาก `refresh_token` (fallback เป็น `access_token`) อัตโนมัติ
189
+
190
+ ตัวอย่าง:
191
+
192
+ ```ts
193
+ const auth = buildx.auth();
194
+ auth.setClientId("device-123");
195
+ auth.setClientProof("existing-device-proof-token");
196
+
197
+ const loginResult = await auth.login({
198
+ username: "user@example.com",
199
+ password: "secret",
200
+ });
201
+
202
+ if (!("success" in loginResult) && (loginResult as any).requires_device_otp) {
203
+ const verify = await auth.verifyDeviceTrustOtp({
204
+ challenge_token: (loginResult as any).challenge_token,
205
+ otp: "123456",
206
+ });
207
+ }
208
+ ```
209
+
163
210
  ### OTP Login (Project-Scoped Only)
164
211
 
165
212
  ```ts
@@ -442,11 +489,18 @@ const storage = buildx.storage();
442
489
 
443
490
  await storage.upload(file, "invoices/2026");
444
491
  await storage.uploadToCollection(file, "orders", "attachments");
492
+ // upload response includes checksum metadata when available:
493
+ // { checksum: { algorithm: "sha256", value: "<hex>" } }
445
494
 
446
495
  await storage.list("invoices/");
447
496
  await storage.getSize("invoices/");
448
497
 
449
498
  await storage.delete("invoices/2026/a.pdf");
499
+
500
+ await storage.getPrivateAccessUrl({
501
+ path: "invoices/2026/a.pdf",
502
+ expiresInSec: 900,
503
+ });
450
504
  ```
451
505
 
452
506
  ## Projects
@@ -470,6 +524,17 @@ await projects.backup("project-id");
470
524
  await projects.restore("project-id", backupFile);
471
525
  ```
472
526
 
527
+ ## Crypto
528
+
529
+ ```ts
530
+ const crypto = buildx.crypto();
531
+
532
+ await crypto.hashPayloadWithTsa("{\"event\":\"approve\"}", {
533
+ certReq: true,
534
+ requestTimeoutMs: 8000,
535
+ });
536
+ ```
537
+
473
538
  ## Flows
474
539
 
475
540
  ```ts
package/dist/Buildx.d.ts CHANGED
@@ -9,6 +9,7 @@ import { Functions } from "./services/Functions";
9
9
  import { BuildxObjects } from "./services/BuildxObjects";
10
10
  import { ApiKeys } from "./services/ApiKeys";
11
11
  import { Onboarding } from "./services/Onboarding";
12
+ import { Crypto } from "./services/Crypto";
12
13
  /**
13
14
  * Main Buildx SDK class
14
15
  *
@@ -40,6 +41,7 @@ export declare class Buildx {
40
41
  private _buildxObjects;
41
42
  private _apiKeys;
42
43
  private _onboarding;
44
+ private _crypto;
43
45
  private _baseService;
44
46
  constructor(config: BuildxConfig);
45
47
  /**
@@ -100,5 +102,10 @@ export declare class Buildx {
100
102
  * Handles pre-project onboarding flow (OTP -> complete -> bootstrap access)
101
103
  */
102
104
  onboarding(): Onboarding;
105
+ /**
106
+ * Crypto service
107
+ * Handles project-scoped cryptographic utilities (for example TSA hashing)
108
+ */
109
+ crypto(): Crypto;
103
110
  }
104
111
  export default Buildx;
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("axios");class t{constructor(e){this.baseService=e}setAccessToken(e){this.baseService.setAccessToken(e)}getAccessToken(){return this.baseService.getAccessToken()}setRefreshToken(e){this.baseService.setRefreshToken(e)}getRefreshToken(){return this.baseService.getRefreshToken()}clearTokens(){this.baseService.clearTokens()}isAuthenticated(){return this.baseService.isAuthenticated()}storeTokens(e){if(!e||"object"!=typeof e)return;const t=e.token||e.access_token||null,s=e.refresh_token||e.refreshToken||null;t&&this.baseService.setAccessToken(t),s&&this.baseService.setRefreshToken(s)}isErrorResponse(e){return e&&"object"==typeof e&&"success"in e&&!1===e.success}hasProjectScope(){const e=this.baseService.config.projectId;return!!e&&"default"!==e}buildAuthUrl(e,t){const s=this.baseService.config.projectId,i=e.startsWith("/auth")?e:`/auth${e.startsWith("/")?e:`/${e}`}`;if(s&&"default"!==s)return`/${s}${i}`;if(t?.requireProjectScope)throw new Error("Project ID is required for this auth endpoint");return i}async login(e){const t=this.buildAuthUrl("/auth/login"),s=await this.baseService.post(t,e);return this.isErrorResponse(s)||this.storeTokens(s),s}async loginWithGoogle(e){const t=this.buildAuthUrl("/auth/google"),s=await this.baseService.post(t,e);return this.isErrorResponse(s)||this.storeTokens(s),s}async signup(e){const t=this.buildAuthUrl("/auth/signup"),s=await this.baseService.post(t,e);return this.isErrorResponse(s)||this.storeTokens(s),s}async requestEotp(e){const t=this.buildAuthUrl("/auth/eotp/auth/request",{requireProjectScope:!0});return await this.baseService.post(t,e)}async requestEotpAuth(e){return this.requestEotp(e)}async requestOtpLogin(e){return this.requestEotp(e)}async verifyEotp(e){const t=this.buildAuthUrl("/auth/eotp/auth/verify",{requireProjectScope:!0}),s=await this.baseService.post(t,e);return this.isErrorResponse(s)||this.storeTokens(s),s}async verifyEotpAuth(e){return this.verifyEotp(e)}async verifyOtpLogin(e){return this.verifyEotp(e)}async requestPublicOnboardingOtp(e){return await this.baseService.post("/public/onboarding/otp/request",e)}async verifyPublicOnboardingOtp(e){return await this.baseService.post("/public/onboarding/otp/verify",e)}async completePublicOnboarding(e,t){const s=await this.baseService.post("/public/onboarding/complete",e,{headers:{"Idempotency-Key":t}});if(this.isErrorResponse(s))return s;const i=s?.data?.access_token,r=s?.data?.refresh_token;return i&&this.baseService.setAccessToken(i),r&&this.baseService.setRefreshToken(r),s}async getPublicOnboardingRequest(e){return await this.baseService.get(`/public/onboarding/request/${encodeURIComponent(e)}`)}async getCurrentUser(){const e=this.buildAuthUrl("/auth/me");return await this.baseService.get(e)}async refreshToken(){const e=this.buildAuthUrl("/auth/token"),t=await this.baseService.post(e,{});return this.isErrorResponse(t)||t&&"object"==typeof t&&"token"in t&&t.token&&this.storeTokens(t),t}async updatePassword(e){const t=this.buildAuthUrl("/auth/password/update");return await this.baseService.post(t,{password:e})}async changePassword(e){const t=this.buildAuthUrl("/auth/password/update");if("string"==typeof e)return await this.baseService.post(t,{password:e});const s=e.password??e.newPassword??e.new_password,i={...e};return s&&(i.password=s),e.currentPassword&&!i.current_password&&(i.current_password=e.currentPassword),e.newPassword&&!i.new_password&&(i.new_password=e.newPassword),await this.baseService.post(t,i)}async adminUpdatePassword(e,t){const s=this.buildAuthUrl("/auth/password/update");return await this.baseService.post(s,{user_id:e,password:t})}async requestPasswordReset(e){const t=this.buildAuthUrl("/auth/password/reset/request");return await this.baseService.post(t,e)}async resetPassword(e){const t=this.buildAuthUrl("/auth/password/reset");return await this.baseService.post(t,e)}async updatePushToken(e){const t=this.hasProjectScope()?`/${this.baseService.config.projectId}/users/push-tokens`:"/users/push-tokens";return await this.baseService.post(t,{token:e})}async listUsers(e){const t=e?`/${e}/auth/users`:"/auth/users";return await this.baseService.get(t)}async lookupUsers(e){const t=e?`/${e}/auth/users/lookup`:"/auth/users/lookup";return await this.baseService.get(t)}async getUser(e,t){const s=t?`/${t}/auth/user/${e}`:`/auth/user/${e}`;return await this.baseService.get(s)}async deleteUser(e){const t=this.buildAuthUrl(`/auth/user/${e}/delete`);return await this.baseService.post(t,{})}}class s{constructor(e){this.baseService=e}async list(){return await this.baseService.get("/projects")}async get(e){return await this.baseService.get(`/project/${e}`)}async create(e){return await this.baseService.post("/projects",e)}async update(e,t){return await this.baseService.patch(`/project/${e}`,t)}async updateMetadata(e,t){return await this.baseService.patch(`/project/${e}/metadata`,t)}async validateLocale(e){return await this.baseService.post("/project/locale/validate",e)}async deleteById(e){return await this.baseService.delete(`/project/${e}`)}async backup(e){const t=await this.baseService.axiosInstance.get(`/project/${e}/backup`,{responseType:"blob",headers:await this.baseService.getHeaders()});if("undefined"!=typeof window){const s=window.URL.createObjectURL(t.data),i=document.createElement("a");i.href=s,i.setAttribute("download",`backup_${e}.buildx`),document.body.appendChild(i),i.click(),document.body.removeChild(i),window.URL.revokeObjectURL(s)}return{success:!0,message:"Backup downloaded successfully"}}async restore(e,t){const s=new FormData;s.append("new_project_id",e),s.append("backup_file",t);const i={...await this.baseService.getHeaders(),"Content-Type":"multipart/form-data"};return await this.baseService.post("/project/import",s,{headers:i})}}class i{constructor(e,t,s){this.baseService=e,this.collectionId=t,this.wsFactory=s,this.socket=null,this.connectPromise=null,this.requestCounter=0,this.pending=new Map}async query(e,t,s=3e4){if(await this.ensureConnected(),!this.socket)throw new Error("WebSocket connection is unavailable");const i=`${Date.now()}_${++this.requestCounter}`,r=new Promise((e,t)=>{const r=setTimeout(()=>{this.pending.delete(i),t(new Error("WebSocket pagination timeout"))},s);this.pending.set(i,{resolve:e,reject:t,timeout:r})});return this.socket.send(JSON.stringify({id:i,action:e,payload:t})),r}close(){if(this.socket){try{this.socket.close()}catch(e){}this.socket=null,this.connectPromise=null;for(const[,e]of this.pending.entries())clearTimeout(e.timeout),e.reject(new Error("WebSocket closed"));this.pending.clear()}}async ensureConnected(){if(!this.socket||!this.isSocketOpen(this.socket))return this.connectPromise||(this.connectPromise=new Promise((e,t)=>{const s=globalThis.WebSocket;this.wsFactory||s?this.baseService.ensureValidAccessToken().then(()=>{const i=this.buildSocketUrl(),r=this.wsFactory?this.wsFactory(i):new s(i);this.socket=r;let n=!1;const a=()=>{n||(n=!0,e())},o=e=>{n||(n=!0,t(e)),this.close()},c=()=>{n||(n=!0,t(new Error("WebSocket closed before connection is ready"))),this.close()},l=e=>{let t;try{t=JSON.parse(e?.data||"{}")}catch(e){return}const s=t?.id;if(!s)return;const i=this.pending.get(s);i&&(clearTimeout(i.timeout),this.pending.delete(s),t.ok&&t.result?i.resolve(t.result):i.reject(new Error(t.error||"WebSocket pagination query failed")))};r.addEventListener?(r.addEventListener("open",a),r.addEventListener("error",o),r.addEventListener("close",c),r.addEventListener("message",l)):(r.onopen=a,r.onerror=o,r.onclose=c,r.onmessage=l)}).catch(e=>{t(e)}):t(new Error("WebSocket is not available in this runtime"))}).finally(()=>{this.connectPromise=null})),this.connectPromise}isSocketOpen(e){const t=globalThis.WebSocket?.OPEN??1;return e.readyState===t}buildSocketUrl(){const e=this.baseService.config.apiEndpoint.replace(/\/$/,"").replace(/^http:/i,"ws:").replace(/^https:/i,"wss:"),t=this.baseService.buildProjectUrl(`/${this.collectionId}/data/pagination/ws`),s=new URLSearchParams,i=this.baseService.config.apiKey;i&&s.set("api_key",i);const r=this.baseService.getAccessToken();r&&s.set("token",r);const n=s.toString();return`${e}${t}${n?`?${n}`:""}`}}class r{constructor(e){this.collectionWsClient=null,this.collectionWsCollectionId=null,this.collectionWsDisabledUntil=0,this.baseService=e}async list(e=!1,t=!1){const s=this.baseService.buildProjectUrl("/collections"),i={};e&&(i.with_stats=!0);const r=this.baseService.buildQueryString(i),n=r?`${s}${r}`:s,a=await this.baseService.get(n);return Array.isArray(a)&&!t?a.filter(e=>e.collection_id&&!e.collection_id.startsWith("buildx_")):a}async getSchema(e,t=1){const s=this.baseService.buildProjectUrl(`/collection/${e}`),i={};t>1&&(i.depth=t);const r=this.baseService.buildQueryString(i),n=r?`${s}${r}`:s;return await this.baseService.get(n)}async set(e){const t=this.baseService.buildProjectUrl("/collections");return await this.baseService.post(t,e)}async deleteCollection(e){const t=this.baseService.buildProjectUrl(`/collections/${e}`);return await this.baseService.delete(t)}async query(e,t){const s=this.baseService.buildProjectUrl(`/${e}`),i=t?.noPopulate??(!!t?.relations&&t.relations.length>0),r=this.buildQueryParams({...t,options:i?{...t?.options||{},noPopulate:!0}:t?.options}),n=this.baseService.buildQueryString(r),a=n?`${s}${n}`:s,o=await this.baseService.get(a);if(!Array.isArray(o))return o;if(!t?.relations||0===t.relations.length)return o;const c="http"!==(t?.paginationTransport||"auto");return await this.hydrateRelations(o,t.relations,t.relationSelect,{preferWs:c,wsFactory:t.wsFactory})}async queryRaw(e,t){const s={...t,options:{...t?.options||{},noPopulate:!0}};if("http"!==(s.paginationTransport||"http")&&Date.now()>=this.collectionWsDisabledUntil)try{return await this.queryRawViaWs(e,s)}catch(e){console.warn("[buildx-sdk] WS raw query failed, fallback to HTTP",e?.message||e),this.collectionWsDisabledUntil=Date.now()+3e4,this.resetCollectionWsClient()}const i=this.baseService.buildProjectUrl(`/${e}/raw`),r=this.buildQueryParams(s),n=this.baseService.buildQueryString(r),a=n?`${i}${n}`:i;return await this.baseService.get(a)}async queryWithPagination(e,t){const s=t?.noPopulate??(!!t?.relations&&t.relations.length>0),i={...t,options:s?{...t?.options||{},noPopulate:!0}:t?.options},r=i.paginationTransport||"auto";let n;if("http"!==r&&Date.now()>=this.collectionWsDisabledUntil)try{n=await this.queryWithPaginationViaWs(e,i)}catch(t){console.warn("[buildx-sdk] WS pagination failed, fallback to HTTP",t?.message||t),this.collectionWsDisabledUntil=Date.now()+3e4,this.resetCollectionWsClient(),n=await this.queryWithPaginationViaHttp(e,i)}else n=await this.queryWithPaginationViaHttp(e,i);if(!n||!1===n.success)return n;if(!i?.relations||0===i.relations.length)return n;const a="http"!==r,o=await this.hydrateRelations(n.data||[],i.relations,i.relationSelect,{preferWs:a,wsFactory:i.wsFactory});return Array.isArray(o)?{...n,data:o}:o}async queryWithPaginationViaHttp(e,t){const s=this.baseService.buildProjectUrl(`/${e}/data/pagination`),i=this.buildQueryParams(t),r=this.baseService.buildQueryString(i),n=r?`${s}${r}`:s,a=await this.baseService.get(n);return a&&!1!==a.success?{...a,meta:{...a.meta||{},transport:"http"}}:a}async queryWithPaginationViaWs(e,t){const s=this.buildQueryParams(t),i=this.getOrCreateCollectionWsClient(e,t?.wsFactory),r=await i.query("queryWithPagination",s);return r&&!1!==r.success?{...r,meta:{...r.meta||{},transport:"ws"}}:r}async queryRawViaWs(e,t){const s=this.buildQueryParams(t),i=this.getOrCreateCollectionWsClient(e,t?.wsFactory),r=await i.query("queryRaw",s);return r&&!1!==r.success?Array.isArray(r)?r:[]:r}getOrCreateCollectionWsClient(e,t){return this.collectionWsClient&&this.collectionWsCollectionId===e||(this.resetCollectionWsClient(),this.collectionWsClient=new i(this.baseService,e,t),this.collectionWsCollectionId=e),this.collectionWsClient}resetCollectionWsClient(){this.collectionWsClient&&this.collectionWsClient.close(),this.collectionWsClient=null,this.collectionWsCollectionId=null}subscribeRealtime(e,t,s){const i=globalThis.WebSocket,r=s?.wsFactory;if(!r&&!i)throw new Error("WebSocket is not available in this runtime. Provide wsFactory in options.");const n=!1!==s?.reconnect,a="number"==typeof s?.reconnectDelayMs&&s.reconnectDelayMs>=0?s.reconnectDelayMs:5e3;let o=null,c=!1,l=!1,u=null,h=!1,p=null;const d=()=>{l||c||(c=!0,t.onConnected?.())},b=()=>{u&&(clearTimeout(u),u=null)},y=async()=>{const t=this.baseService.config.apiEndpoint.replace(/\/$/,"").replace(/^http:/i,"ws:").replace(/^https:/i,"wss:"),i=this.baseService.buildProjectUrl(`/${e}/realtime/ws`),r=new URLSearchParams,n=s?.apiKey||this.baseService.config.apiKey;n&&r.set("api_key",n);const a=s?.token||await this.baseService.ensureValidAccessToken();a&&r.set("token",a);const o=r.toString();return`${t}${i}${o?`?${o}`:""}`},f=e=>{l||h||(h=!0,t.onError?.(e),l||!n||u||(u=setTimeout(()=>{u=null,l||(c=!1,p&&p())},a)))},w=()=>{h=!1,d()},g=e=>(e=>{if(!l)try{const s=e?.data;if(null==s)return;let i;if("string"==typeof s){const e=s.trim();if(!e)return;i=JSON.parse(e)}else{if("object"!=typeof s)return;i=s}if(!i||"object"!=typeof i||Array.isArray(i))return;if("ping"===i.type)return;if("connected"===i.type)return void d();const r={...i,timestamp:"number"==typeof i.timestamp?i.timestamp:Date.now()};t.onEvent?.(r)}catch(e){t.onError?.(e)}})(e),S=e=>{if(l)return;f(e instanceof Error?e:new Error(e?.message||e?.type||"Realtime WebSocket error"))},v=e=>{if(l)return;const t=e?.code,s=e?.reason,i=new Error(`Realtime WebSocket closed${t?` (code ${t})`:""}${s?`: ${s}`:""}`);f(i)};return p=async()=>{b();const e=await y(),t=r?r(e):new i(e);o=t,t.addEventListener?(t.addEventListener("open",w),t.addEventListener("message",g),t.addEventListener("error",S),t.addEventListener("close",v)):(t.onopen=w,t.onmessage=g,t.onerror=S,t.onclose=v)},p().catch(e=>{f(e instanceof Error?e:new Error(String(e||"Realtime connection failed")))}),{close:()=>{l=!0,b(),o?.close()}}}async lookup(e,t){const s=this.baseService.buildProjectUrl(`/${e}`),i={};t&&(t.filter&&(i.filter=t.filter),t.jsonFilter&&(i.jsonFilter=t.jsonFilter),t.projection&&(i.projection=t.projection),t.options&&(i.options=t.options));const r=this.baseService.buildQueryString(i),n=r?`${s}${r}`:s,a=await this.baseService.get(n);return Array.isArray(a)?a.map(e=>({value:e._id,label:e._display||e.label||e.title||e.name||e.username||e.description||""})):a}buildQueryParams(e){const t={};if(!e)return t;const s=e.q||e.searchQuery;return s&&(t.q=s),e.quick_filter_fields&&(t.quick_filter_fields=e.quick_filter_fields),e.filter&&(t.filter=e.filter),e.jsonFilter&&(t.jsonFilter=e.jsonFilter),e.select&&(t.select=Array.isArray(e.select)?e.select.join(","):e.select),e.projection&&(t.projection=e.projection),e.options&&(t.options=e.options),e.sort&&(t.sort=e.sort),"number"==typeof e.limit&&(t.limit=e.limit),"number"==typeof e.skip&&e.skip>0&&(t.skip=e.skip),t}async hydrateRelations(e,t,s,i){const n=e.map(e=>({...e})),a=s||"_id,_display,name,title,username",o=t.reduce((e,t)=>(e[t.collectionId]||(e[t.collectionId]=[]),e[t.collectionId].push(t),e),{}),c=new Map;for(const[e,t]of Object.entries(o)){const s=new Set;for(const e of n)for(const i of t){const t=e[i.field];if(t)if(Array.isArray(t))for(const e of t){const t=this.extractReferenceId(e);t&&s.add(t)}else{const e=this.extractReferenceId(t);e&&s.add(e)}}const o=Array.from(s).filter(t=>!c.has(`${e}:${t}`));if(o.length>0){const t=r.RELATION_QUERY_CHUNK_SIZE;for(let s=0;s<o.length;s+=t){const r=o.slice(s,s+t),n=await this.queryRaw(e,{filter:{_id:{$in:r}},select:a,paginationTransport:i?.preferWs?"auto":"http",wsFactory:i?.wsFactory});if(!Array.isArray(n))return n;for(const t of n)t?._id&&c.set(`${e}:${t._id}`,t)}}for(const s of n)for(const i of t){const t=s[i.field];if(t)if(Array.isArray(t))s[i.field]=t.map(t=>{const s=this.extractReferenceId(t);return s&&c.get(`${e}:${s}`)||t});else{const r=this.extractReferenceId(t);if(!r)continue;s[i.field]=c.get(`${e}:${r}`)||t}}}return n}extractReferenceId(e){if(null==e)return null;if("string"==typeof e||"number"==typeof e){const t=String(e).trim();return t.length>0?t:null}if("object"==typeof e&&void 0!==e._id&&null!==e._id){const t=String(e._id).trim();return t.length>0?t:null}return null}async getDocument(e,t,s){const i=this.baseService.buildProjectUrl(`/${e}/${t}`),r={};s&&s.length>0&&(r.populate=s.join(","));const n=this.baseService.buildQueryString(r),a=n?`${i}${n}`:i;return await this.baseService.get(a)}async createDocument(e,t){const s=this.baseService.buildProjectUrl(`/${e}`);return await this.baseService.post(s,t)}async updateDocument(e,t,s){const i=this.baseService.buildProjectUrl(`/${e}/${t}`);return await this.baseService.patch(i,s)}async updateDocumentWithOptions(e,t,s,i){const r=this.baseService.buildProjectUrl(`/${e}/${t}`),n=i?.updateOnly?`${r}?mode=updateOnly`:r;return await this.baseService.patch(n,s)}async getDocumentRevisions(e,t){const s=this.baseService.buildProjectUrl(`/${e}/${t}/revisions`);return await this.baseService.get(s)}async deleteDocument(e,t){const s=this.baseService.buildProjectUrl(`/${e}/${t}`);return await this.baseService.delete(s)}async deleteByFilter(e,t){const s=this.baseService.buildProjectUrl(`/${e}/delete`);return await this.baseService.post(s,{filter:t})}async import(e,t,s){const i=new FormData;i.append("mapping",JSON.stringify(s)),i.append("file",t);const r=this.baseService.buildProjectUrl(`/${e}/import`),n={...await this.baseService.getHeaders(),"Content-Type":"multipart/form-data"};return await this.baseService.post(r,i,{headers:n})}async getDataTypes(){const e=this.baseService.buildProjectUrl("/collections/types");return await this.baseService.get(e)}async validate(e){const t=this.baseService.buildProjectUrl(`/${e}/validate`);return await this.baseService.post(t,null)}async migrate(e){const t=this.baseService.buildProjectUrl(`/${e}/migrate`);return await this.baseService.post(t,null)}}r.RELATION_QUERY_CHUNK_SIZE=200;class n{constructor(e){this.baseService=e}async upload(e,t){const s=new FormData;t&&""!==t&&s.append("prefix",t),s.append("file",e),s.append("filename",e.name||"file");const i=this.baseService.buildProjectUrl("/storage/upload"),r={...await this.baseService.getHeaders(),"Content-Type":"multipart/form-data; charset=utf-8"};return await this.baseService.post(i,s,{headers:r})}async uploadToCollection(e,t,s){const i=new FormData;s&&""!==s&&i.append("prefix",s),i.append("file",e),i.append("filename",e.name||"file"),i.append("collection_id",t);const r=this.baseService.buildProjectUrl("/storage/upload"),n={...await this.baseService.getHeaders(),"Content-Type":"multipart/form-data; charset=utf-8"};return await this.baseService.post(r,i,{headers:n})}async list(e){const t=this.baseService.buildProjectUrl(`/storage?path=${encodeURIComponent(e)}`);return await this.baseService.get(t)}async getSize(e){const t=this.baseService.buildProjectUrl(`/storage/size?path=${encodeURIComponent(e)}`);return await this.baseService.get(t)}async delete(e){const t=this.baseService.buildProjectUrl(`/storage?path=${encodeURIComponent(e)}`);return await this.baseService.delete(t)}}class a{constructor(e){this.baseService=e}async getTypes(){return await this.baseService.get("/flows/types")}async run(e,t=null,s="root",i={}){const r=this.baseService.buildProjectUrl(`/flows/${e}/run`);return await this.baseService.post(r,{session_id:t,state:s,args:i})}async getGptFlowSuggestions(e){const t=this.baseService.buildProjectUrl("/ai/gpt/flow/node");return await this.baseService.post(t,{instruction:e})}async getGptCollectionSuggestions(e){const t=this.baseService.buildProjectUrl("/ai/gpt/collections");return await this.baseService.post(t,{instruction:e})}async getGptLifecycleSuggestions(e){const t=this.baseService.buildProjectUrl("/ai/gpt/lifecycle");return await this.baseService.post(t,{instruction:e})}}class o{constructor(e){this.baseService=e}async preview(e,t){const s=this.baseService.buildProjectUrl("/templates/preview");return await this.baseService.post(s,{template:e,data:t})}async render(e,t){const s=this.baseService.buildProjectUrl(`/templates/${e}/render`);return await this.baseService.post(s,t)}async renderPDF(e,t){const s=this.baseService.buildProjectUrl(`/templates/${e}/pdf`),i={...await this.baseService.getHeaders(),responseType:"blob"},r=await this.baseService.axiosInstance.post(s,t,{headers:i});if("undefined"!=typeof window){const e=window.URL.createObjectURL(r.data),t=document.createElement("a");t.href=e,t.setAttribute("download","document.pdf"),document.body.appendChild(t),t.click(),document.body.removeChild(t),window.URL.revokeObjectURL(e)}return{success:!0,message:"PDF downloaded successfully"}}}class c{constructor(e){this.baseService=e}async list(){const e=this.baseService.buildProjectUrl("/functions");return await this.baseService.get(e)}async getByName(e){const t=this.baseService.buildProjectUrl(`/functions/${e}`);return await this.baseService.get(t)}async update(e,t){const s=this.baseService.buildProjectUrl(`/functions/${e}`);return await this.baseService.post(s,t)}async getLogs(e){const t=this.baseService.buildProjectUrl(`/functions/${e}/logs`);return await this.baseService.get(t)}async invoke(e,t,s){const i=new URLSearchParams;null!=s?.revision&&i.set("revision",String(s.revision)),s?.alias&&i.set("alias",s.alias);const r=i.toString(),n=this.baseService.buildProjectUrl(`/functions/run/${e}${r?`?${r}`:""}`);return await this.baseService.post(n,t)}async listRevisions(e){const t=this.baseService.buildProjectUrl(`/functions/${e}/revisions`);return await this.baseService.get(t)}async publishRevision(e,t,s="live"){const i=this.baseService.buildProjectUrl(`/functions/${e}/revisions/${t}/publish`);return await this.baseService.post(i,{alias:s})}async setAlias(e,t,s){const i=this.baseService.buildProjectUrl(`/functions/${e}/aliases/${t}`);return await this.baseService.put(i,{revision:s})}}class l{constructor(e){this.baseService=e}async getCollection(e){const t=this.baseService.buildProjectUrl(`/buildx/collection/${e}`);return await this.baseService.get(t)}async getDocument(e,t){const s=this.baseService.buildProjectUrl(`/buildx/${e}/${t}`),i=await this.baseService.get(s);return"object"==typeof i&&null!==i&&(i._display=i._display||i.label||i.title||i.name||i.username||i.description||""),i}async query(e,t){const s=this.baseService.buildProjectUrl(`/buildx/${e}`),i={};t&&(t.filter&&(i.filter=t.filter),t.jsonFilter&&(i.jsonFilter=t.jsonFilter),t.select&&(i.select=Array.isArray(t.select)?t.select.join(","):t.select),t.projection&&(i.projection=t.projection),t.options&&(i.options=t.options),t.sort&&(i.sort=t.sort),t.limit&&(i.limit=t.limit));const r=this.baseService.buildQueryString(i),n=r?`${s}${r}`:s,a=await this.baseService.get(n);return Array.isArray(a)&&a.forEach(e=>{e._display=e._display||e.label||e.title||e.name||e.username||e.description||""}),a}async create(e,t){const s=this.baseService.buildProjectUrl(`/buildx/${e}`);return await this.baseService.post(s,t)}async update(e,t,s){const i=this.baseService.buildProjectUrl(`/buildx/${e}/${t}`);return await this.baseService.patch(i,s)}async deleteObject(e,t){const s=this.baseService.buildProjectUrl(`/buildx/${e}/${t}`);return await this.baseService.delete(s)}}class u{constructor(e){this.baseService=e}async list(e){const t=e?`/${e}/auth/api-keys`:"/auth/api-keys";return await this.baseService.get(t)}async get(e,t){const s=t?`/${t}/auth/api-key/${e}`:`/auth/api-key/${e}`;return await this.baseService.get(s)}async getSecret(e,t){const s=t?`/${t}/auth/api-key/${e}/secret`:`/auth/api-key/${e}/secret`;return await this.baseService.get(s)}}class h{constructor(e){this.baseService=e}isErrorResponse(e){return e&&"object"==typeof e&&"success"in e&&!1===e.success}async requestOtp(e){return await this.baseService.post("/public/onboarding/otp/request",e)}async verifyOtp(e){return await this.baseService.post("/public/onboarding/otp/verify",e)}async complete(e,t){const s=await this.baseService.post("/public/onboarding/complete",e,{headers:{"Idempotency-Key":t}});if(this.isErrorResponse(s))return s;const i=s?.data?.access_token,r=s?.data?.refresh_token;return i&&this.baseService.setAccessToken(i),r&&this.baseService.setRefreshToken(r),s}async getRequest(e){return await this.baseService.get(`/public/onboarding/request/${encodeURIComponent(e)}`)}}const p="default";let d={};class b{static getInstance(e,t,s,i){t||(t="default");const r=(s||"https://api.buildx.ai").replace(/\/$/,""),n=`${r}|${e}|${t}|${i||""}`;if(d[n]){const t=d[n];t.config.apiEndpoint===r&&t.config.apiKey===e||t.updateConfig({...t.config,apiEndpoint:r,apiKey:e})}else d[n]=new b({apiEndpoint:r,projectId:t,apiKey:e,organizationId:i});return d[n]}constructor(t){this._accessToken=null,this._refreshToken=null,this.refreshPromise=null,this.config=t,this.axiosInstance=e.create({baseURL:t.apiEndpoint,timeout:3e4}),this.axiosInstance.interceptors.request.use(e=>(e.headers["X-API-Key"]=this.config.apiKey,e),e=>Promise.reject(e)),this.axiosInstance.interceptors.response.use(e=>e,e=>this.handleError(e))}updateConfig(e){this.config=e,this.axiosInstance.defaults.baseURL=e.apiEndpoint}setAccessToken(e){this._accessToken=e,this.emitTokenChange()}getAccessToken(){return this._accessToken}setRefreshToken(e){this._refreshToken=e,this.emitTokenChange()}getRefreshToken(){return this._refreshToken}clearTokens(){this._accessToken=null,this._refreshToken=null,this.emitTokenChange()}emitTokenChange(){if("function"==typeof this.config.onTokenChange)try{this.config.onTokenChange({accessToken:this._accessToken,refreshToken:this._refreshToken})}catch{}}decodeJwtPayload(e){try{const[,t]=e.split(".");if(!t)return null;const s=t.replace(/-/g,"+").replace(/_/g,"/"),i=s.padEnd(4*Math.ceil(s.length/4),"="),r=globalThis.Buffer,n="function"==typeof atob?atob(i):r.from(i,"base64").toString("utf8");return JSON.parse(n)}catch(e){return null}}isTokenExpiredOrNearExpiry(e,t=3e4){const s=this.decodeJwtPayload(e),i=Number(s?.exp||0);return!!i&&Date.now()>=1e3*i-t}isAuthenticated(){return null!==this._accessToken}async getHeaders(e=!1){const t=e?this._refreshToken:this._accessToken,s={"Content-Type":"application/json","X-API-Key":this.config.apiKey};return t&&(s.Authorization=`Bearer ${t}`),s}getPublicHeaders(){return{"Content-Type":"application/json","X-API-Key":this.config.apiKey}}async get(e,t){return await this.executeWithAutoRefresh(e,async()=>{const s=await this.getHeaders(),i=await this.axiosInstance.get(e,{...t,headers:{...s,...t?.headers}});return this.unwrapResponse(i)})}async post(e,t,s){return await this.executeWithAutoRefresh(e,async()=>{const i=await this.getHeaders(),r=await this.axiosInstance.post(e,t,{...s,headers:{...i,...s?.headers}});return this.unwrapResponse(r)})}async put(e,t,s){return await this.executeWithAutoRefresh(e,async()=>{const i=await this.getHeaders(),r=await this.axiosInstance.put(e,t,{...s,headers:{...i,...s?.headers}});return this.unwrapResponse(r)})}async patch(e,t,s){return await this.executeWithAutoRefresh(e,async()=>{const i=await this.getHeaders(),r=await this.axiosInstance.patch(e,t,{...s,headers:{...i,...s?.headers}});return this.unwrapResponse(r)})}async delete(e,t){return await this.executeWithAutoRefresh(e,async()=>{const s=await this.getHeaders(),i=await this.axiosInstance.delete(e,{...t,headers:{...s,...t?.headers}});return this.unwrapResponse(i)})}isErrorPayload(e){return!!e&&"object"==typeof e&&!1===e.success}shouldAttemptRefresh(e,t){if(!this._refreshToken)return!1;if(e.includes("/auth/login")||e.includes("/auth/token"))return!1;const s=Number(t.statusCode||t.status||0),i=String(t.code||"").toLowerCase(),r=String(t.message||t.description||t.error||"").toLowerCase();return 401===s||403===s||"e07007"===i||i.includes("invalid_token")||r.includes("jwt expired")||r.includes("invalid token")||r.includes("unauthorized")||r.includes("forbidden")}getRefreshUrl(){const e=this.config.projectId;return e&&e!==p?`/${e}/auth/token`:"/auth/token"}async refreshAccessToken(){return this.refreshPromise||(this.refreshPromise=(async()=>{if(!this._refreshToken)return!1;try{const e=await this.axiosInstance.post(this.getRefreshUrl(),{},{headers:{"Content-Type":"application/json","X-API-Key":this.config.apiKey,Authorization:`Bearer ${this._refreshToken}`}}),t=this.unwrapResponse(e),s=t?.token||t?.access_token,i=t?.refresh_token||t?.refreshToken||this._refreshToken;return s?(this.setAccessToken(s),this.setRefreshToken(i),!0):(this.clearTokens(),!1)}catch{return this.clearTokens(),!1}finally{this.refreshPromise=null}})()),this.refreshPromise}async executeWithAutoRefresh(e,t){const s=await t();if(!this.isErrorPayload(s))return s;if(!this.shouldAttemptRefresh(e,s))return s;return await this.refreshAccessToken()?await t():{...s,message:"Session expired and refresh failed. Please login again."}}unwrapResponse(e){return e&&"object"==typeof e&&"data"in e?e.data:e}handleError(e){if(e.response){const{status:t,data:s}=e.response;return s&&"object"==typeof s?{error:s.error||"RequestError",message:s.message||s.description||"Something went wrong",statusCode:t,success:!1}:{error:"RequestError",message:`Request failed with status ${t}`,statusCode:t,success:!1}}return"Network Error"===e.message?{error:"NetworkError",message:"Network connection failed",statusCode:500,success:!1}:{error:"RequestError",message:e.message||"Unknown error occurred",statusCode:500,success:!1}}async ensureValidAccessToken(){if(this._accessToken&&!this.isTokenExpiredOrNearExpiry(this._accessToken))return this._accessToken;if(!this._refreshToken)return this._accessToken;return await this.refreshAccessToken()?this._accessToken:null}buildProjectUrl(e=""){const t=this.config.projectId;if(!t||t===p)throw new Error("Project ID is required");return`/project/${t}${e}`}buildOrgUrl(e=""){const t=this.config.organizationId||this.config.projectId;if(!t)throw new Error("Organization ID is required");return`/${t}${e}`}buildQueryString(e){const t=new URLSearchParams;Object.entries(e).forEach(([e,s])=>{null!=s&&("object"==typeof s?t.append(e,JSON.stringify(s)):t.append(e,String(s)))});const s=t.toString();return s?`?${s}`:""}}class y{constructor(e){this.config={apiEndpoint:e.apiEndpoint.replace(/\/$/,""),apiKey:e.apiKey,projectId:e.projectId,organizationId:e.organizationId,onTokenChange:e.onTokenChange},this._baseService=b.getInstance(this.config.apiKey,this.config.projectId,this.config.apiEndpoint,this.config.organizationId),this._baseService.updateConfig(this.config),this._auth=new t(this._baseService),this._projects=new s(this._baseService),this._collections=new r(this._baseService),this._storage=new n(this._baseService),this._flows=new a(this._baseService),this._templates=new o(this._baseService),this._functions=new c(this._baseService),this._buildxObjects=new l(this._baseService),this._apiKeys=new u(this._baseService),this._onboarding=new h(this._baseService)}getConfig(){return{...this.config}}updateConfig(e){this.config={...this.config,...e},this._baseService.updateConfig(this.config)}auth(){return this._auth}projects(){return this._projects}collections(){return this._collections}storage(){return this._storage}flows(){return this._flows}templates(){return this._templates}functions(){return this._functions}buildxObjects(){return this._buildxObjects}apiKeys(){return this._apiKeys}onboarding(){return this._onboarding}}exports.ApiKeys=u,exports.Auth=t,exports.Buildx=y,exports.BuildxObjects=l,exports.Collections=r,exports.Flows=a,exports.Functions=c,exports.Onboarding=h,exports.Projects=s,exports.Storage=n,exports.Templates=o,exports.default=y;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("axios");class t{constructor(e){this.baseService=e}setAccessToken(e){this.baseService.setAccessToken(e)}getAccessToken(){return this.baseService.getAccessToken()}setRefreshToken(e){this.baseService.setRefreshToken(e)}getRefreshToken(){return this.baseService.getRefreshToken()}setClientId(e){this.baseService.setClientId(e)}getClientId(){return this.baseService.getClientId()}setClientProof(e){this.baseService.setClientProof(e)}getClientProof(){return this.baseService.getClientProof()}clearTokens(){this.baseService.clearTokens()}isAuthenticated(){return this.baseService.isAuthenticated()}storeTokens(e){if(!e||"object"!=typeof e)return;const t=e.token||e.access_token||null,s=e.refresh_token||e.refreshToken||null;t&&this.baseService.setAccessToken(t),s?(this.baseService.setRefreshToken(s),this.baseService.setClientProof(s)):t&&this.baseService.setClientProof(t)}isErrorResponse(e){return e&&"object"==typeof e&&"success"in e&&!1===e.success}hasProjectScope(){const e=this.baseService.config.projectId;return!!e&&"default"!==e}getAuthClientContext(){const e=this.baseService.getClientId(),t=this.baseService.getClientProof(),s={};return e&&(s.client_id=e),t&&(s.client_proof=t),s}getAuthClientHeaders(){const e=this.baseService.getClientId(),t=this.baseService.getClientProof(),s={};return e&&(s["x-client-id"]=e),t&&(s["x-client-proof"]=t),s}buildAuthUrl(e,t){const s=this.baseService.config.projectId,i=e.startsWith("/auth")?e:`/auth${e.startsWith("/")?e:`/${e}`}`;if(s&&"default"!==s)return`/${s}${i}`;if(t?.requireProjectScope)throw new Error("Project ID is required for this auth endpoint");return i}async login(e){const t=this.buildAuthUrl("/auth/login"),s=await this.baseService.post(t,{...e,...this.getAuthClientContext()},{headers:this.getAuthClientHeaders()});return this.isErrorResponse(s)||this.storeTokens(s),s}async loginWithGoogle(e){const t=this.buildAuthUrl("/auth/google"),s=await this.baseService.post(t,{...e,...this.getAuthClientContext()},{headers:this.getAuthClientHeaders()});return this.isErrorResponse(s)||this.storeTokens(s),s}async signup(e){const t=this.buildAuthUrl("/auth/signup"),s=await this.baseService.post(t,{...e,...this.getAuthClientContext()},{headers:this.getAuthClientHeaders()});return this.isErrorResponse(s)||this.storeTokens(s),s}async requestEotp(e){const t=this.buildAuthUrl("/auth/eotp/auth/request",{requireProjectScope:!0});return await this.baseService.post(t,e)}async requestEotpAuth(e){return this.requestEotp(e)}async requestOtpLogin(e){return this.requestEotp(e)}async verifyEotp(e){const t=this.buildAuthUrl("/auth/eotp/auth/verify",{requireProjectScope:!0}),s=await this.baseService.post(t,{...e,...this.getAuthClientContext()},{headers:this.getAuthClientHeaders()});return this.isErrorResponse(s)||this.storeTokens(s),s}async verifyEotpAuth(e){return this.verifyEotp(e)}async verifyOtpLogin(e){return this.verifyEotp(e)}async requestPublicOnboardingOtp(e){return await this.baseService.post("/public/onboarding/otp/request",e)}async verifyPublicOnboardingOtp(e){return await this.baseService.post("/public/onboarding/otp/verify",e)}async completePublicOnboarding(e,t){const s=await this.baseService.post("/public/onboarding/complete",e,{headers:{"Idempotency-Key":t}});if(this.isErrorResponse(s))return s;const i=s?.data?.access_token,r=s?.data?.refresh_token;return i&&this.baseService.setAccessToken(i),r&&this.baseService.setRefreshToken(r),s}async getPublicOnboardingRequest(e){return await this.baseService.get(`/public/onboarding/request/${encodeURIComponent(e)}`)}async getCurrentUser(){const e=this.buildAuthUrl("/auth/me");return await this.baseService.get(e)}async refreshToken(){const e=this.buildAuthUrl("/auth/token"),t=await this.baseService.post(e,{},{headers:this.getAuthClientHeaders()});return this.isErrorResponse(t)||t&&"object"==typeof t&&"token"in t&&t.token&&this.storeTokens(t),t}async verifyDeviceTrustOtp(e){const t=this.buildAuthUrl("/auth/device-trust/verify"),s=await this.baseService.post(t,e,{headers:this.getAuthClientHeaders()});return this.isErrorResponse(s)||this.storeTokens(s),s}async updatePassword(e){const t=this.buildAuthUrl("/auth/password/update");return await this.baseService.post(t,{password:e})}async changePassword(e){const t=this.buildAuthUrl("/auth/password/update");if("string"==typeof e)return await this.baseService.post(t,{password:e});const s=e.password??e.newPassword??e.new_password,i={...e};return s&&(i.password=s),e.currentPassword&&!i.current_password&&(i.current_password=e.currentPassword),e.newPassword&&!i.new_password&&(i.new_password=e.newPassword),await this.baseService.post(t,i)}async adminUpdatePassword(e,t){const s=this.buildAuthUrl("/auth/password/update");return await this.baseService.post(s,{user_id:e,password:t})}async requestPasswordReset(e){const t=this.buildAuthUrl("/auth/password/reset/request");return await this.baseService.post(t,e)}async resetPassword(e){const t=this.buildAuthUrl("/auth/password/reset");return await this.baseService.post(t,e)}async updatePushToken(e){const t=this.hasProjectScope()?`/${this.baseService.config.projectId}/users/push-tokens`:"/users/push-tokens";return await this.baseService.post(t,{token:e})}async listUsers(e){const t=e?`/${e}/auth/users`:"/auth/users";return await this.baseService.get(t)}async lookupUsers(e){const t=e?`/${e}/auth/users/lookup`:"/auth/users/lookup";return await this.baseService.get(t)}async getUser(e,t){const s=t?`/${t}/auth/user/${e}`:`/auth/user/${e}`;return await this.baseService.get(s)}async deleteUser(e){const t=this.buildAuthUrl(`/auth/user/${e}/delete`);return await this.baseService.post(t,{})}}class s{constructor(e){this.baseService=e}async list(){return await this.baseService.get("/projects")}async get(e){return await this.baseService.get(`/project/${e}`)}async create(e){return await this.baseService.post("/projects",e)}async update(e,t){return await this.baseService.patch(`/project/${e}`,t)}async updateMetadata(e,t){return await this.baseService.patch(`/project/${e}/metadata`,t)}async validateLocale(e){return await this.baseService.post("/project/locale/validate",e)}async deleteById(e){return await this.baseService.delete(`/project/${e}`)}async backup(e){const t=await this.baseService.axiosInstance.get(`/project/${e}/backup`,{responseType:"blob",headers:await this.baseService.getHeaders()});if("undefined"!=typeof window){const s=window.URL.createObjectURL(t.data),i=document.createElement("a");i.href=s,i.setAttribute("download",`backup_${e}.buildx`),document.body.appendChild(i),i.click(),document.body.removeChild(i),window.URL.revokeObjectURL(s)}return{success:!0,message:"Backup downloaded successfully"}}async restore(e,t){const s=new FormData;s.append("new_project_id",e),s.append("backup_file",t);const i={...await this.baseService.getHeaders(),"Content-Type":"multipart/form-data"};return await this.baseService.post("/project/import",s,{headers:i})}}class i{constructor(e,t,s){this.baseService=e,this.collectionId=t,this.wsFactory=s,this.socket=null,this.connectPromise=null,this.requestCounter=0,this.pending=new Map}async query(e,t,s=3e4){if(await this.ensureConnected(),!this.socket)throw new Error("WebSocket connection is unavailable");const i=`${Date.now()}_${++this.requestCounter}`,r=new Promise((e,t)=>{const r=setTimeout(()=>{this.pending.delete(i),t(new Error("WebSocket pagination timeout"))},s);this.pending.set(i,{resolve:e,reject:t,timeout:r})});return this.socket.send(JSON.stringify({id:i,action:e,payload:t})),r}close(){if(this.socket){try{this.socket.close()}catch(e){}this.socket=null,this.connectPromise=null;for(const[,e]of this.pending.entries())clearTimeout(e.timeout),e.reject(new Error("WebSocket closed"));this.pending.clear()}}async ensureConnected(){if(!this.socket||!this.isSocketOpen(this.socket))return this.connectPromise||(this.connectPromise=new Promise((e,t)=>{const s=globalThis.WebSocket;this.wsFactory||s?this.baseService.ensureValidAccessToken().then(()=>{const i=this.buildSocketUrl(),r=this.wsFactory?this.wsFactory(i):new s(i);this.socket=r;let n=!1;const a=()=>{n||(n=!0,e())},o=e=>{n||(n=!0,t(e)),this.close()},c=()=>{n||(n=!0,t(new Error("WebSocket closed before connection is ready"))),this.close()},l=e=>{let t;try{t=JSON.parse(e?.data||"{}")}catch(e){return}const s=t?.id;if(!s)return;const i=this.pending.get(s);i&&(clearTimeout(i.timeout),this.pending.delete(s),t.ok&&t.result?i.resolve(t.result):i.reject(new Error(t.error||"WebSocket pagination query failed")))};r.addEventListener?(r.addEventListener("open",a),r.addEventListener("error",o),r.addEventListener("close",c),r.addEventListener("message",l)):(r.onopen=a,r.onerror=o,r.onclose=c,r.onmessage=l)}).catch(e=>{t(e)}):t(new Error("WebSocket is not available in this runtime"))}).finally(()=>{this.connectPromise=null})),this.connectPromise}isSocketOpen(e){const t=globalThis.WebSocket?.OPEN??1;return e.readyState===t}buildSocketUrl(){const e=this.baseService.config.apiEndpoint.replace(/\/$/,"").replace(/^http:/i,"ws:").replace(/^https:/i,"wss:"),t=this.baseService.buildProjectUrl(`/${this.collectionId}/data/pagination/ws`),s=new URLSearchParams,i=this.baseService.config.apiKey;i&&s.set("api_key",i);const r=this.baseService.getAccessToken();r&&s.set("token",r);const n=s.toString();return`${e}${t}${n?`?${n}`:""}`}}class r{constructor(e){this.collectionWsClient=null,this.collectionWsCollectionId=null,this.collectionWsDisabledUntil=0,this.baseService=e}async list(e=!1,t=!1){const s=this.baseService.buildProjectUrl("/collections"),i={};e&&(i.with_stats=!0);const r=this.baseService.buildQueryString(i),n=r?`${s}${r}`:s,a=await this.baseService.get(n);return Array.isArray(a)&&!t?a.filter(e=>e.collection_id&&!e.collection_id.startsWith("buildx_")):a}async getSchema(e,t=1){const s=this.baseService.buildProjectUrl(`/collection/${e}`),i={};t>1&&(i.depth=t);const r=this.baseService.buildQueryString(i),n=r?`${s}${r}`:s;return await this.baseService.get(n)}async set(e){const t=this.baseService.buildProjectUrl("/collections");return await this.baseService.post(t,e)}async deleteCollection(e){const t=this.baseService.buildProjectUrl(`/collections/${e}`);return await this.baseService.delete(t)}async query(e,t){const s=this.baseService.buildProjectUrl(`/${e}`),i=t?.noPopulate??(!!t?.relations&&t.relations.length>0),r=this.buildQueryParams({...t,options:i?{...t?.options||{},noPopulate:!0}:t?.options}),n=this.baseService.buildQueryString(r),a=n?`${s}${n}`:s,o=await this.baseService.get(a);if(!Array.isArray(o))return o;if(!t?.relations||0===t.relations.length)return o;const c="http"!==(t?.paginationTransport||"auto");return await this.hydrateRelations(o,t.relations,t.relationSelect,{preferWs:c,wsFactory:t.wsFactory})}async queryRaw(e,t){const s={...t,options:{...t?.options||{},noPopulate:!0}};if("http"!==(s.paginationTransport||"http")&&Date.now()>=this.collectionWsDisabledUntil)try{return await this.queryRawViaWs(e,s)}catch(e){console.warn("[buildx-sdk] WS raw query failed, fallback to HTTP",e?.message||e),this.collectionWsDisabledUntil=Date.now()+3e4,this.resetCollectionWsClient()}const i=this.baseService.buildProjectUrl(`/${e}/raw`),r=this.buildQueryParams(s),n=this.baseService.buildQueryString(r),a=n?`${i}${n}`:i;return await this.baseService.get(a)}async queryWithPagination(e,t){const s=t?.noPopulate??(!!t?.relations&&t.relations.length>0),i={...t,options:s?{...t?.options||{},noPopulate:!0}:t?.options},r=i.paginationTransport||"auto";let n;if("http"!==r&&Date.now()>=this.collectionWsDisabledUntil)try{n=await this.queryWithPaginationViaWs(e,i)}catch(t){console.warn("[buildx-sdk] WS pagination failed, fallback to HTTP",t?.message||t),this.collectionWsDisabledUntil=Date.now()+3e4,this.resetCollectionWsClient(),n=await this.queryWithPaginationViaHttp(e,i)}else n=await this.queryWithPaginationViaHttp(e,i);if(!n||!1===n.success)return n;if(!i?.relations||0===i.relations.length)return n;const a="http"!==r,o=await this.hydrateRelations(n.data||[],i.relations,i.relationSelect,{preferWs:a,wsFactory:i.wsFactory});return Array.isArray(o)?{...n,data:o}:o}async queryWithPaginationViaHttp(e,t){const s=this.baseService.buildProjectUrl(`/${e}/data/pagination`),i=this.buildQueryParams(t),r=this.baseService.buildQueryString(i),n=r?`${s}${r}`:s,a=await this.baseService.get(n);return a&&!1!==a.success?{...a,meta:{...a.meta||{},transport:"http"}}:a}async queryWithPaginationViaWs(e,t){const s=this.buildQueryParams(t),i=this.getOrCreateCollectionWsClient(e,t?.wsFactory),r=await i.query("queryWithPagination",s);return r&&!1!==r.success?{...r,meta:{...r.meta||{},transport:"ws"}}:r}async queryRawViaWs(e,t){const s=this.buildQueryParams(t),i=this.getOrCreateCollectionWsClient(e,t?.wsFactory),r=await i.query("queryRaw",s);return r&&!1!==r.success?Array.isArray(r)?r:[]:r}getOrCreateCollectionWsClient(e,t){return this.collectionWsClient&&this.collectionWsCollectionId===e||(this.resetCollectionWsClient(),this.collectionWsClient=new i(this.baseService,e,t),this.collectionWsCollectionId=e),this.collectionWsClient}resetCollectionWsClient(){this.collectionWsClient&&this.collectionWsClient.close(),this.collectionWsClient=null,this.collectionWsCollectionId=null}subscribeRealtime(e,t,s){const i=globalThis.WebSocket,r=s?.wsFactory;if(!r&&!i)throw new Error("WebSocket is not available in this runtime. Provide wsFactory in options.");const n=!1!==s?.reconnect,a="number"==typeof s?.reconnectDelayMs&&s.reconnectDelayMs>=0?s.reconnectDelayMs:5e3;let o=null,c=!1,l=!1,u=null,h=!1,d=null;const p=()=>{l||c||(c=!0,t.onConnected?.())},b=()=>{u&&(clearTimeout(u),u=null)},y=async()=>{const t=this.baseService.config.apiEndpoint.replace(/\/$/,"").replace(/^http:/i,"ws:").replace(/^https:/i,"wss:"),i=this.baseService.buildProjectUrl(`/${e}/realtime/ws`),r=new URLSearchParams,n=s?.apiKey||this.baseService.config.apiKey;n&&r.set("api_key",n);const a=s?.token||await this.baseService.ensureValidAccessToken();a&&r.set("token",a);const o=r.toString();return`${t}${i}${o?`?${o}`:""}`},f=e=>{l||h||(h=!0,t.onError?.(e),l||!n||u||(u=setTimeout(()=>{u=null,l||(c=!1,d&&d())},a)))},g=()=>{h=!1,p()},w=e=>(e=>{if(!l)try{const s=e?.data;if(null==s)return;let i;if("string"==typeof s){const e=s.trim();if(!e)return;i=JSON.parse(e)}else{if("object"!=typeof s)return;i=s}if(!i||"object"!=typeof i||Array.isArray(i))return;if("ping"===i.type)return;if("connected"===i.type)return void p();const r={...i,timestamp:"number"==typeof i.timestamp?i.timestamp:Date.now()};t.onEvent?.(r)}catch(e){t.onError?.(e)}})(e),S=e=>{if(l)return;f(e instanceof Error?e:new Error(e?.message||e?.type||"Realtime WebSocket error"))},v=e=>{if(l)return;const t=e?.code,s=e?.reason,i=new Error(`Realtime WebSocket closed${t?` (code ${t})`:""}${s?`: ${s}`:""}`);f(i)};return d=async()=>{b();const e=await y(),t=r?r(e):new i(e);o=t,t.addEventListener?(t.addEventListener("open",g),t.addEventListener("message",w),t.addEventListener("error",S),t.addEventListener("close",v)):(t.onopen=g,t.onmessage=w,t.onerror=S,t.onclose=v)},d().catch(e=>{f(e instanceof Error?e:new Error(String(e||"Realtime connection failed")))}),{close:()=>{l=!0,b(),o?.close()}}}async lookup(e,t){const s=this.baseService.buildProjectUrl(`/${e}`),i={};t&&(t.filter&&(i.filter=t.filter),t.jsonFilter&&(i.jsonFilter=t.jsonFilter),t.projection&&(i.projection=t.projection),t.options&&(i.options=t.options));const r=this.baseService.buildQueryString(i),n=r?`${s}${r}`:s,a=await this.baseService.get(n);return Array.isArray(a)?a.map(e=>({value:e._id,label:e._display||e.label||e.title||e.name||e.username||e.description||""})):a}buildQueryParams(e){const t={};if(!e)return t;const s=e.q||e.searchQuery;return s&&(t.q=s),e.quick_filter_fields&&(t.quick_filter_fields=e.quick_filter_fields),e.filter&&(t.filter=e.filter),e.jsonFilter&&(t.jsonFilter=e.jsonFilter),e.select&&(t.select=Array.isArray(e.select)?e.select.join(","):e.select),e.projection&&(t.projection=e.projection),e.options&&(t.options=e.options),e.sort&&(t.sort=e.sort),"number"==typeof e.limit&&(t.limit=e.limit),"number"==typeof e.skip&&e.skip>0&&(t.skip=e.skip),t}async hydrateRelations(e,t,s,i){const n=e.map(e=>({...e})),a=s||"_id,_display,name,title,username",o=t.reduce((e,t)=>(e[t.collectionId]||(e[t.collectionId]=[]),e[t.collectionId].push(t),e),{}),c=new Map;for(const[e,t]of Object.entries(o)){const s=new Set;for(const e of n)for(const i of t){const t=e[i.field];if(t)if(Array.isArray(t))for(const e of t){const t=this.extractReferenceId(e);t&&s.add(t)}else{const e=this.extractReferenceId(t);e&&s.add(e)}}const o=Array.from(s).filter(t=>!c.has(`${e}:${t}`));if(o.length>0){const t=r.RELATION_QUERY_CHUNK_SIZE;for(let s=0;s<o.length;s+=t){const r=o.slice(s,s+t),n=await this.queryRaw(e,{filter:{_id:{$in:r}},select:a,paginationTransport:i?.preferWs?"auto":"http",wsFactory:i?.wsFactory});if(!Array.isArray(n))return n;for(const t of n)t?._id&&c.set(`${e}:${t._id}`,t)}}for(const s of n)for(const i of t){const t=s[i.field];if(t)if(Array.isArray(t))s[i.field]=t.map(t=>{const s=this.extractReferenceId(t);return s&&c.get(`${e}:${s}`)||t});else{const r=this.extractReferenceId(t);if(!r)continue;s[i.field]=c.get(`${e}:${r}`)||t}}}return n}extractReferenceId(e){if(null==e)return null;if("string"==typeof e||"number"==typeof e){const t=String(e).trim();return t.length>0?t:null}if("object"==typeof e&&void 0!==e._id&&null!==e._id){const t=String(e._id).trim();return t.length>0?t:null}return null}async getDocument(e,t,s){const i=this.baseService.buildProjectUrl(`/${e}/${t}`),r={};s&&s.length>0&&(r.populate=s.join(","));const n=this.baseService.buildQueryString(r),a=n?`${i}${n}`:i;return await this.baseService.get(a)}async createDocument(e,t){const s=this.baseService.buildProjectUrl(`/${e}`);return await this.baseService.post(s,t)}async updateDocument(e,t,s){const i=this.baseService.buildProjectUrl(`/${e}/${t}`);return await this.baseService.patch(i,s)}async updateDocumentWithOptions(e,t,s,i){const r=this.baseService.buildProjectUrl(`/${e}/${t}`),n=i?.updateOnly?`${r}?mode=updateOnly`:r;return await this.baseService.patch(n,s)}async getDocumentRevisions(e,t){const s=this.baseService.buildProjectUrl(`/${e}/${t}/revisions`);return await this.baseService.get(s)}async deleteDocument(e,t){const s=this.baseService.buildProjectUrl(`/${e}/${t}`);return await this.baseService.delete(s)}async deleteByFilter(e,t){const s=this.baseService.buildProjectUrl(`/${e}/delete`);return await this.baseService.post(s,{filter:t})}async import(e,t,s){const i=new FormData;i.append("mapping",JSON.stringify(s)),i.append("file",t);const r=this.baseService.buildProjectUrl(`/${e}/import`),n={...await this.baseService.getHeaders(),"Content-Type":"multipart/form-data"};return await this.baseService.post(r,i,{headers:n})}async getDataTypes(){const e=this.baseService.buildProjectUrl("/collections/types");return await this.baseService.get(e)}async validate(e){const t=this.baseService.buildProjectUrl(`/${e}/validate`);return await this.baseService.post(t,null)}async migrate(e){const t=this.baseService.buildProjectUrl(`/${e}/migrate`);return await this.baseService.post(t,null)}}r.RELATION_QUERY_CHUNK_SIZE=200;class n{constructor(e){this.baseService=e}async upload(e,t){const s=new FormData;t&&""!==t&&s.append("prefix",t),s.append("file",e),s.append("filename",e.name||"file");const i=this.baseService.buildProjectUrl("/storage/upload"),r={...await this.baseService.getHeaders(),"Content-Type":"multipart/form-data; charset=utf-8"};return await this.baseService.post(i,s,{headers:r})}async uploadToCollection(e,t,s){const i=new FormData;s&&""!==s&&i.append("prefix",s),i.append("file",e),i.append("filename",e.name||"file"),i.append("collection_id",t);const r=this.baseService.buildProjectUrl("/storage/upload"),n={...await this.baseService.getHeaders(),"Content-Type":"multipart/form-data; charset=utf-8"};return await this.baseService.post(r,i,{headers:n})}async list(e){const t=this.baseService.buildProjectUrl(`/storage?path=${encodeURIComponent(e)}`);return await this.baseService.get(t)}async getSize(e){const t=this.baseService.buildProjectUrl(`/storage/size?path=${encodeURIComponent(e)}`);return await this.baseService.get(t)}async delete(e){const t=this.baseService.buildProjectUrl(`/storage?path=${encodeURIComponent(e)}`);return await this.baseService.delete(t)}async getPrivateAccessUrl(e){const t=this.baseService.buildProjectUrl("/storage/private/access-url");return await this.baseService.post(t,e)}}class a{constructor(e){this.baseService=e}async getTypes(){return await this.baseService.get("/flows/types")}async run(e,t=null,s="root",i={}){const r=this.baseService.buildProjectUrl(`/flows/${e}/run`);return await this.baseService.post(r,{session_id:t,state:s,args:i})}async getGptFlowSuggestions(e){const t=this.baseService.buildProjectUrl("/ai/gpt/flow/node");return await this.baseService.post(t,{instruction:e})}async getGptCollectionSuggestions(e){const t=this.baseService.buildProjectUrl("/ai/gpt/collections");return await this.baseService.post(t,{instruction:e})}async getGptLifecycleSuggestions(e){const t=this.baseService.buildProjectUrl("/ai/gpt/lifecycle");return await this.baseService.post(t,{instruction:e})}}class o{constructor(e){this.baseService=e}async preview(e,t){const s=this.baseService.buildProjectUrl("/templates/preview");return await this.baseService.post(s,{template:e,data:t})}async render(e,t){const s=this.baseService.buildProjectUrl(`/templates/${e}/render`);return await this.baseService.post(s,t)}async renderPDF(e,t){const s=this.baseService.buildProjectUrl(`/templates/${e}/pdf`),i={...await this.baseService.getHeaders(),responseType:"blob"},r=await this.baseService.axiosInstance.post(s,t,{headers:i});if("undefined"!=typeof window){const e=window.URL.createObjectURL(r.data),t=document.createElement("a");t.href=e,t.setAttribute("download","document.pdf"),document.body.appendChild(t),t.click(),document.body.removeChild(t),window.URL.revokeObjectURL(e)}return{success:!0,message:"PDF downloaded successfully"}}}class c{constructor(e){this.baseService=e}async list(){const e=this.baseService.buildProjectUrl("/functions");return await this.baseService.get(e)}async getByName(e){const t=this.baseService.buildProjectUrl(`/functions/${e}`);return await this.baseService.get(t)}async update(e,t){const s=this.baseService.buildProjectUrl(`/functions/${e}`);return await this.baseService.post(s,t)}async getLogs(e){const t=this.baseService.buildProjectUrl(`/functions/${e}/logs`);return await this.baseService.get(t)}async invoke(e,t,s){const i=new URLSearchParams;null!=s?.revision&&i.set("revision",String(s.revision)),s?.alias&&i.set("alias",s.alias);const r=i.toString(),n=this.baseService.buildProjectUrl(`/functions/run/${e}${r?`?${r}`:""}`);return await this.baseService.post(n,t)}async listRevisions(e){const t=this.baseService.buildProjectUrl(`/functions/${e}/revisions`);return await this.baseService.get(t)}async publishRevision(e,t,s="live"){const i=this.baseService.buildProjectUrl(`/functions/${e}/revisions/${t}/publish`);return await this.baseService.post(i,{alias:s})}async setAlias(e,t,s){const i=this.baseService.buildProjectUrl(`/functions/${e}/aliases/${t}`);return await this.baseService.put(i,{revision:s})}}class l{constructor(e){this.baseService=e}async getCollection(e){const t=this.baseService.buildProjectUrl(`/buildx/collection/${e}`);return await this.baseService.get(t)}async getDocument(e,t){const s=this.baseService.buildProjectUrl(`/buildx/${e}/${t}`),i=await this.baseService.get(s);return"object"==typeof i&&null!==i&&(i._display=i._display||i.label||i.title||i.name||i.username||i.description||""),i}async query(e,t){const s=this.baseService.buildProjectUrl(`/buildx/${e}`),i={};t&&(t.filter&&(i.filter=t.filter),t.jsonFilter&&(i.jsonFilter=t.jsonFilter),t.select&&(i.select=Array.isArray(t.select)?t.select.join(","):t.select),t.projection&&(i.projection=t.projection),t.options&&(i.options=t.options),t.sort&&(i.sort=t.sort),t.limit&&(i.limit=t.limit));const r=this.baseService.buildQueryString(i),n=r?`${s}${r}`:s,a=await this.baseService.get(n);return Array.isArray(a)&&a.forEach(e=>{e._display=e._display||e.label||e.title||e.name||e.username||e.description||""}),a}async create(e,t){const s=this.baseService.buildProjectUrl(`/buildx/${e}`);return await this.baseService.post(s,t)}async update(e,t,s){const i=this.baseService.buildProjectUrl(`/buildx/${e}/${t}`);return await this.baseService.patch(i,s)}async deleteObject(e,t){const s=this.baseService.buildProjectUrl(`/buildx/${e}/${t}`);return await this.baseService.delete(s)}}class u{constructor(e){this.baseService=e}async list(e){const t=e?`/${e}/auth/api-keys`:"/auth/api-keys";return await this.baseService.get(t)}async get(e,t){const s=t?`/${t}/auth/api-key/${e}`:`/auth/api-key/${e}`;return await this.baseService.get(s)}async getSecret(e,t){const s=t?`/${t}/auth/api-key/${e}/secret`:`/auth/api-key/${e}/secret`;return await this.baseService.get(s)}}class h{constructor(e){this.baseService=e}isErrorResponse(e){return e&&"object"==typeof e&&"success"in e&&!1===e.success}async checkProjectIdAvailability(e){const t=new URLSearchParams({product_key:e.product_key,project_id:e.project_id});return await this.baseService.get(`/public/onboarding/project-id/availability?${t.toString()}`)}async requestOtp(e){return await this.baseService.post("/public/onboarding/otp/request",e)}async verifyOtp(e){return await this.baseService.post("/public/onboarding/otp/verify",e)}async complete(e,t){const s=await this.baseService.post("/public/onboarding/complete",e,{headers:{"Idempotency-Key":t}});if(this.isErrorResponse(s))return s;const i=s?.data?.access_token,r=s?.data?.refresh_token;return i&&this.baseService.setAccessToken(i),r&&this.baseService.setRefreshToken(r),s}async getRequest(e){return await this.baseService.get(`/public/onboarding/request/${encodeURIComponent(e)}`)}}class d{constructor(e){this.baseService=e}async hashPayloadWithTsa(e,t={}){const s=this.baseService.buildProjectUrl("/crypto/tsa/hash");return await this.baseService.post(s,{payload:e,...t})}}const p={UNAUTHORIZED:{code:"E02005"},TOKEN_EXPIRED:{code:"E02006"}},b=p.UNAUTHORIZED,y=p.TOKEN_EXPIRED,f=e=>String(e?.response?.data?.code||e?.code||"").trim().toUpperCase(),g=e=>{if(f(e)===y.code)return!0;const t=(e=>String(e?.response?.data?.message||e?.response?.data?.description||e?.response?.data?.error||e?.inner?.message||e?.message||e?.description||e?.error||"").toLowerCase())(e);return!!t&&(t.includes("jwt expired")||t.includes("token expired")||t.includes("expired token")||t.includes("session expired"))},w="default";let S={};class v{static getInstance(e,t,s,i){t||(t="default");const r=(s||"https://api.buildx.ai").replace(/\/$/,""),n=`${r}|${e}|${t}|${i||""}`;if(S[n]){const t=S[n];t.config.apiEndpoint===r&&t.config.apiKey===e||t.updateConfig({...t.config,apiEndpoint:r,apiKey:e})}else S[n]=new v({apiEndpoint:r,projectId:t,apiKey:e,organizationId:i});return S[n]}constructor(t){this._accessToken=null,this._refreshToken=null,this._clientId=null,this._clientProof=null,this.refreshPromise=null,this.config=t,this._clientId=t.clientId??null,this._clientProof=t.clientProof??null,this.axiosInstance=e.create({baseURL:t.apiEndpoint,timeout:3e4}),this.axiosInstance.interceptors.request.use(e=>(e.headers["X-API-Key"]=this.config.apiKey,e),e=>Promise.reject(e)),this.axiosInstance.interceptors.response.use(e=>e,e=>this.handleError(e))}updateConfig(e){this.config=e,this._clientId=e.clientId??this._clientId,this._clientProof=e.clientProof??this._clientProof,this.axiosInstance.defaults.baseURL=e.apiEndpoint}setAccessToken(e){this._accessToken=e,this.emitTokenChange()}getAccessToken(){return this._accessToken}setRefreshToken(e){this._refreshToken=e,this.emitTokenChange()}getRefreshToken(){return this._refreshToken}setClientId(e){this._clientId=e}getClientId(){return this._clientId}setClientProof(e){this._clientProof=e}getClientProof(){return this._clientProof}clearTokens(){this._accessToken=null,this._refreshToken=null,this.emitTokenChange()}emitTokenChange(){if("function"==typeof this.config.onTokenChange)try{this.config.onTokenChange({accessToken:this._accessToken,refreshToken:this._refreshToken})}catch{}}decodeJwtPayload(e){try{const[,t]=e.split(".");if(!t)return null;const s=t.replace(/-/g,"+").replace(/_/g,"/"),i=s.padEnd(4*Math.ceil(s.length/4),"="),r=globalThis.Buffer,n="function"==typeof atob?atob(i):r.from(i,"base64").toString("utf8");return JSON.parse(n)}catch(e){return null}}isTokenExpiredOrNearExpiry(e,t=3e4){const s=this.decodeJwtPayload(e),i=Number(s?.exp||0);return!!i&&Date.now()>=1e3*i-t}isAuthenticated(){return null!==this._accessToken}async getHeaders(e=!1){const t=e?this._refreshToken:this._accessToken,s={"Content-Type":"application/json","X-API-Key":this.config.apiKey};return t&&(s.Authorization=`Bearer ${t}`),s}getPublicHeaders(){return{"Content-Type":"application/json","X-API-Key":this.config.apiKey}}async get(e,t){return await this.executeWithAutoRefresh(e,async()=>{const s=await this.getHeaders(),i=await this.axiosInstance.get(e,{...t,headers:{...s,...t?.headers}});return this.unwrapResponse(i)})}async post(e,t,s){return await this.executeWithAutoRefresh(e,async()=>{const i=await this.getHeaders(),r=await this.axiosInstance.post(e,t,{...s,headers:{...i,...s?.headers}});return this.unwrapResponse(r)})}async put(e,t,s){return await this.executeWithAutoRefresh(e,async()=>{const i=await this.getHeaders(),r=await this.axiosInstance.put(e,t,{...s,headers:{...i,...s?.headers}});return this.unwrapResponse(r)})}async patch(e,t,s){return await this.executeWithAutoRefresh(e,async()=>{const i=await this.getHeaders(),r=await this.axiosInstance.patch(e,t,{...s,headers:{...i,...s?.headers}});return this.unwrapResponse(r)})}async delete(e,t){return await this.executeWithAutoRefresh(e,async()=>{const s=await this.getHeaders(),i=await this.axiosInstance.delete(e,{...t,headers:{...s,...t?.headers}});return this.unwrapResponse(i)})}isErrorPayload(e){return!!e&&"object"==typeof e&&!1===e.success}shouldAttemptRefresh(e,t){if(!this._refreshToken)return!1;if(e.includes("/auth/login")||e.includes("/auth/token"))return!1;const s=Number(t.statusCode||t.status||0),i=String(t.code||"").toUpperCase(),r=String(t.message||t.description||t.error||"").toLowerCase();return 401===s&&(i!==b.code&&(i===y.code||g({code:i,message:r})))}getRefreshUrl(){const e=this.config.projectId;return e&&e!==w?`/${e}/auth/token`:"/auth/token"}async refreshAccessToken(){return this.refreshPromise||(this.refreshPromise=(async()=>{if(!this._refreshToken)return!1;try{const e=await this.axiosInstance.post(this.getRefreshUrl(),{},{headers:{"Content-Type":"application/json","X-API-Key":this.config.apiKey,Authorization:`Bearer ${this._refreshToken}`}}),t=this.unwrapResponse(e),s=t?.token||t?.access_token,i=t?.refresh_token||t?.refreshToken||this._refreshToken;return s?(this.setAccessToken(s),this.setRefreshToken(i),!0):(this.clearTokens(),!1)}catch{return this.clearTokens(),!1}finally{this.refreshPromise=null}})()),this.refreshPromise}async executeWithAutoRefresh(e,t){const s=await t();if(!this.isErrorPayload(s))return s;if(!this.shouldAttemptRefresh(e,s))return s;return await this.refreshAccessToken()?await t():{...s,message:"Session expired and refresh failed. Please login again."}}unwrapResponse(e){return e&&"object"==typeof e&&"data"in e?e.data:e}handleError(e){if(e.response){const{status:t,data:s}=e.response;return s&&"object"==typeof s?{error:s.error||"RequestError",message:s.message||s.description||"Something went wrong",statusCode:t,code:s.code,success:!1}:{error:"RequestError",message:`Request failed with status ${t}`,statusCode:t,success:!1}}return"Network Error"===e.message?{error:"NetworkError",message:"Network connection failed",statusCode:500,success:!1}:{error:"RequestError",message:e.message||"Unknown error occurred",statusCode:500,success:!1}}async ensureValidAccessToken(){if(this._accessToken&&!this.isTokenExpiredOrNearExpiry(this._accessToken))return this._accessToken;if(!this._refreshToken)return this._accessToken;return await this.refreshAccessToken()?this._accessToken:null}buildProjectUrl(e=""){const t=this.config.projectId;if(!t||t===w)throw new Error("Project ID is required");return`/project/${t}${e}`}buildOrgUrl(e=""){const t=this.config.organizationId||this.config.projectId;if(!t)throw new Error("Organization ID is required");return`/${t}${e}`}buildQueryString(e){const t=new URLSearchParams;Object.entries(e).forEach(([e,s])=>{null!=s&&("object"==typeof s?t.append(e,JSON.stringify(s)):t.append(e,String(s)))});const s=t.toString();return s?`?${s}`:""}}class m{constructor(e){this.config={apiEndpoint:e.apiEndpoint.replace(/\/$/,""),apiKey:e.apiKey,projectId:e.projectId,organizationId:e.organizationId,onTokenChange:e.onTokenChange},this._baseService=v.getInstance(this.config.apiKey,this.config.projectId,this.config.apiEndpoint,this.config.organizationId),this._baseService.updateConfig(this.config),this._auth=new t(this._baseService),this._projects=new s(this._baseService),this._collections=new r(this._baseService),this._storage=new n(this._baseService),this._flows=new a(this._baseService),this._templates=new o(this._baseService),this._functions=new c(this._baseService),this._buildxObjects=new l(this._baseService),this._apiKeys=new u(this._baseService),this._onboarding=new h(this._baseService),this._crypto=new d(this._baseService)}getConfig(){return{...this.config}}updateConfig(e){this.config={...this.config,...e},this._baseService.updateConfig(this.config)}auth(){return this._auth}projects(){return this._projects}collections(){return this._collections}storage(){return this._storage}flows(){return this._flows}templates(){return this._templates}functions(){return this._functions}buildxObjects(){return this._buildxObjects}apiKeys(){return this._apiKeys}onboarding(){return this._onboarding}crypto(){return this._crypto}}exports.ApiKeys=u,exports.Auth=t,exports.Buildx=m,exports.BuildxObjects=l,exports.Collections=r,exports.Crypto=d,exports.Flows=a,exports.Functions=c,exports.Onboarding=h,exports.Projects=s,exports.Storage=n,exports.Templates=o,exports.default=m;
2
2
  //# sourceMappingURL=index.cjs.map