@buildbase/sdk 0.0.35 → 0.0.37

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/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});let e=!0;function t(t,...s){e&&function(){try{const e="undefined"!=typeof globalThis?globalThis:null;return"development"===e?.process?.env?.NODE_ENV}catch{return!1}}()&&console.error(t,...s)}async function s(e,t){try{const s=await e.json();return s?.message||s?.error||t}catch{return t}}async function r(e){const t=await e.text();if(!t)throw new Error("Empty response body");try{return JSON.parse(t)}catch(e){throw new Error(`Invalid JSON response: ${t.substring(0,100)}${t.length>100?"...":""}`)}}async function n(e,t="Request failed"){if(!e.ok){let s=t;try{const t=await r(e);s=t.message||t.error||s}catch{s=function(e,t){const s={400:"Bad Request",401:"Unauthorized - Please check your session",403:"Forbidden - You do not have permission",404:"Resource not found",500:"Internal server error",502:"Bad Gateway",503:"Service unavailable"}[e.status]||e.statusText||t;return new Error(`${t} (${e.status}: ${s})`)}(e,t).message}throw new Error(s)}try{return await r(e)}catch(e){if(e instanceof Error&&e.message.includes("Invalid JSON"))throw e;throw new Error("Failed to parse response as JSON")}}class o extends Error{constructor(e,t,s,r){super(e),this.code=t,this.context=s,this.originalError=r,this.name="SDKError","undefined"!=typeof Error&&"captureStackTrace"in Error&&Error.captureStackTrace(this,o)}}const a=new class{constructor(){this.config={enableConsoleLogging:!0,showUserNotifications:!1}}configure(t){this.config={...this.config,...t},void 0!==t.enableConsoleLogging&&function(t){void 0!==t.enableLogging&&(e=t.enableLogging)}({enableLogging:t.enableConsoleLogging})}handleError(e,s={}){if(function(e){return e instanceof Error&&("AbortError"===e.name||"ERR_CANCELED"===e.code)}(e))return;const r=e instanceof Error?e:new o("string"==typeof e?e:"An unknown error occurred","UNKNOWN_ERROR",s),n=r instanceof o?r:new o(r.message,"SDK_ERROR",s,r);if(this.config.enableConsoleLogging&&t(`[SDK Error] ${s.component||"Unknown"}:`,{message:n.message,code:n.code,context:n.context,originalError:n.originalError,stack:n.stack}),this.config.onError)try{this.config.onError(n,s)}catch(e){!function(e,...t){console.error(e,...t)}("[SDK Error Handler] Error in custom error callback:",e)}this.config.showUserNotifications&&this.notifyUser(n,s)}notifyUser(e,t){"undefined"!=typeof window&&window.dispatchEvent&&window.dispatchEvent(new CustomEvent("sdk-error",{detail:{error:e,context:t}}))}wrapAsync(e,t){return(...s)=>e(...s).catch(e=>{throw this.handleError(e,t),e})}wrapSync(e,t){return(...s)=>{try{return e(...s)}catch(e){throw this.handleError(e,t),e}}}};function i(e,t={}){a.handleError(e,t)}const c="saas-session-id";function u(){if("undefined"==typeof window)return null;try{return function(e){if("undefined"==typeof window)return null;try{return localStorage.getItem(e)}catch(t){return i(t,{component:"storage",action:"getStorageItem",metadata:{key:e}}),null}}(c)}catch(e){return i(e,{component:"auth-utils",action:"getSessionId",metadata:{key:c}}),null}}function l(){const e=u(),t={};return e&&(t["x-session-id"]=e),t}const d="SDK is not ready (missing serverUrl, version, or orgId)";class p{constructor(e){this.serverUrl=e.serverUrl,this.version=e.version,this.orgId=e.orgId,this.requireOrgId=e.requireOrgId??!1,this.basePath=e.basePath??"public",this._sessionId=e.sessionId,this._timeout=e.timeout??3e4,this._maxRetries=e.maxRetries??0,this._debug=e.debug??!1,this._customHeaders=e.headers??{},this._onError=e.onError,this._fetch=e.fetch??globalThis.fetch}ensureReady(){if(!this.serverUrl?.trim()||!this.version)throw new Error(d);if(this.requireOrgId&&!this.orgId?.trim())throw new Error(d)}get baseUrl(){return this.ensureReady(),`${this.serverUrl}/api/${this.version}/${this.basePath}`}getAuthHeaders(){return this._sessionId?{"x-session-id":this._sessionId}:l()}url(e){const t=e.startsWith("/")?e.slice(1):e;return`${this.baseUrl.endsWith("/")?this.baseUrl.slice(0,-1):this.baseUrl}/${t}`}buildHeaders(e){const t={...this._customHeaders,...this.getAuthHeaders()};return e.headers&&Object.assign(t,e.headers),null==e.body||t["Content-Type"]||(t["Content-Type"]="application/json"),t}async executeFetch(e,t){const s=this.url(e),r=(t.method??"GET").toUpperCase(),n=this.buildHeaders(t),o={...t,headers:n};let a;if(this._timeout>0){const e=new AbortController;a=setTimeout(()=>e.abort(),this._timeout),o.signal=t.signal?AbortSignal.any([t.signal,e.signal]):e.signal}const i=async t=>{try{const e=this._fetch.bind(globalThis),n=await e(s,o);if(this._debug&&console.log(`[BuildBase] ${r} ${s} → ${n.status}`),n.status>=500&&t<this._maxRetries){const e=Math.min(1e3*Math.pow(2,t),1e4);return this._debug&&console.log(`[BuildBase] Retrying in ${e}ms (attempt ${t+1}/${this._maxRetries})`),await new Promise(t=>setTimeout(t,e)),i(t+1)}return n}catch(s){if(s instanceof Error&&"AbortError"===s.name){if(void 0!==a){const t=new Error(`Request timeout after ${this._timeout}ms: ${r} ${e}`);throw this._onError?.(t,{method:r,path:e}),t}throw s}if(t<this._maxRetries){const e=Math.min(1e3*Math.pow(2,t),1e4);return this._debug&&console.log(`[BuildBase] Network error, retrying in ${e}ms (attempt ${t+1}/${this._maxRetries})`),await new Promise(t=>setTimeout(t,e)),i(t+1)}throw s instanceof Error&&this._onError?.(s,{method:r,path:e}),s}};try{return await i(0)}finally{void 0!==a&&clearTimeout(a)}}async fetchJson(e,t={},s="Request failed"){this.ensureReady();try{const r=await this.executeFetch(e,t);return await n(r,s)}catch(s){throw s instanceof Error&&this._onError?.(s,{method:(t.method??"GET").toUpperCase(),path:e}),s}}async fetchResponse(e,t={}){return this.ensureReady(),this.executeFetch(e,t)}}class h extends p{constructor(e){super({...e,basePath:"beta",requireOrgId:!0})}getAuthHeaders(){return{}}async fetchConfig(){return this.fetchJson(`config?orgId=${encodeURIComponent(this.orgId)}`,{},"Failed to fetch beta form configuration")}async submitBetaUser(e){return this.fetchJson("submit",{method:"POST",body:JSON.stringify(e)},"Failed to submit beta user request")}}class f extends p{constructor(e){super({...e,requireOrgId:!0})}async getVapidPublicKey(){return this.fetchJson("push/vapid-public-key")}async subscribe(e,t){await this.fetchJson("push/subscribe",{method:"POST",body:JSON.stringify({endpoint:e.endpoint,keys:e.keys,userAgent:t})})}async unsubscribe(e){await this.fetchJson("push/unsubscribe",{method:"DELETE",body:JSON.stringify({endpoint:e})})}}class g extends p{constructor(e){super({...e,requireOrgId:!0})}async getSettings(e){return this.fetchJson(`${this.orgId}/settings`,{signal:e},"Failed to fetch settings")}}class w extends p{constructor(e){super(e)}async getAttributes(e){const t=await this.fetchResponse("users/attributes",{signal:e});if(!t.ok)throw new Error(await s(t,"Failed to fetch user attributes"));const r=await t.json();return r&&"object"==typeof r&&!Array.isArray(r)?r:{}}async updateAttributes(e){return this.fetchJson("users/attributes",{method:"PATCH",body:JSON.stringify({attributes:e})},"Failed to update user attributes")}async updateAttribute(e,t){return this.fetchJson(`users/attributes/${e}`,{method:"PATCH",body:JSON.stringify({value:t})},"Failed to update user attribute")}async getFeatures(e){const t=await this.fetchResponse("users/features",{signal:e});if(!t.ok)throw new Error(await s(t,"Failed to fetch user features"));const r=await t.json();return"object"==typeof r&&null!==r?r:{}}}class y extends p{constructor(e){super({...e,requireOrgId:!0})}async getWorkspaces(){return this.fetchJson("workspaces",{},"Failed to fetch workspaces")}async createWorkspace(e){return this.fetchJson("workspaces",{method:"POST",body:JSON.stringify(e)},"Failed to create workspace")}async updateWorkspace(e,t){return this.fetchJson(`workspaces/${e}`,{method:"PUT",body:JSON.stringify(t)},"Failed to update workspace")}async deleteWorkspace(e){return this.fetchJson(`workspaces/${e}`,{method:"DELETE"},"Failed to delete workspace")}async getWorkspaceUsers(e){return this.fetchJson(`workspaces/${e}/users`,{},"Failed to fetch workspace users")}async addUser(e,t){return this.fetchJson(`workspaces/${e}/users/add`,{method:"POST",body:JSON.stringify(t)},"Failed to invite member")}async removeUser(e,t){return this.fetchJson(`workspaces/${e}/users/${t}`,{method:"DELETE"},"Failed to remove user")}async updateUser(e,t,s){return this.fetchJson(`workspaces/${e}/users/${t}`,{method:"PATCH",body:JSON.stringify(s)},"Failed to update user")}async updateSettings(e){return this.fetchJson("workspaces/settings",{method:"PATCH",body:JSON.stringify(e)},"Failed to update workspace settings")}async updateWorkspacePermissions(e,t){return this.fetchJson(`workspaces/${e}/permissions`,{method:"PATCH",body:JSON.stringify({permissions:t})},"Failed to update workspace permissions")}async getFeatures(){return this.fetchJson("workspaces/features",{},"Failed to fetch features")}async updateFeature(e,t,s){return this.fetchJson(`workspaces/${e}/features`,{method:"PATCH",body:JSON.stringify({features:{[t]:s}})},"Failed to update feature")}async getWorkspace(e){return this.fetchJson(`workspaces/${e}`,{},"Failed to fetch workspace")}async getProfile(){return this.fetchJson("profile",{},"Failed to fetch profile")}async updateUserProfile(e){return this.fetchJson("profile",{method:"PATCH",body:JSON.stringify(e)},"Failed to update user profile")}async getCurrentSubscription(e){const t=await this.fetchResponse(`workspaces/${e}/subscription`);if(!t.ok){let e="Failed to fetch subscription";try{e=(await t.json()).message||e}catch{e=404===t.status?"Workspace not found or no subscription available":401===t.status?"Unauthorized - Please check your session":`Failed to fetch subscription (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch subscription");return s.data||s}return s}async getPlanGroup(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/plan-group`);if(!t.ok){let e="Failed to fetch plan group";try{e=(await t.json()).message||e}catch{e=404===t.status?"No plan group found for this workspace":401===t.status?"Unauthorized - Please check your session":`Failed to fetch plan group (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch plan group");return s.data||s}return s}async getPlanGroupByVersion(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/plan-group?groupVersionId=${encodeURIComponent(t)}`);if(!s.ok){let e="Failed to fetch plan group version";try{e=(await s.json()).message||e}catch{e=404===s.status?"Plan group version not found":401===s.status?"Unauthorized - Please check your session":`Failed to fetch plan group version (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to fetch plan group version");return r.data||r}return r}async getPlanGroupVersions(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/plan-group/versions`);if(!t.ok){let e="Failed to fetch plan group versions";try{e=(await t.json()).message||e}catch{e=404===t.status?"No plan group versions found":401===t.status?"Unauthorized - Please check your session":`Failed to fetch plan group versions (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch plan group versions");return s.data||s}return s}async getPublicPlans(e){if(!this.orgId)throw new Error("orgId is required for getPublicPlans");const t=await this.fetchResponse(`${this.orgId}/plans/${encodeURIComponent(e)}`);if(!t.ok){let s="Failed to fetch plans";try{s=(await t.json()).message||s}catch{s=404===t.status?`Plans "${e}" not found`:`Failed to fetch plans (${t.status}: ${t.statusText})`}throw new Error(s)}const s=await t.json();if(void 0!==s.success&&!s.success)throw new Error(s.message||"Failed to fetch plans");return s.data??s}async getPlanGroupVersion(e){const t=await this.fetchResponse(`plan-group-versions/${e}`);if(!t.ok){let e="Failed to fetch plan group version";try{e=(await t.json()).message||e}catch{e=404===t.status?"Plan group version not found":401===t.status?"Unauthorized - Please check your session":`Failed to fetch plan group version (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch plan group version");return s.data||s}return s}async createCheckoutSession(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/checkout`,{method:"POST",body:JSON.stringify(t)});if(!s.ok){let e="Failed to create checkout session";try{e=(await s.json()).message||e}catch{e=`Failed to create checkout session (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to create checkout session");return r.data||r}return r}async updateSubscription(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription`,{method:"PATCH",body:JSON.stringify(t)});if(!s.ok){let e="Failed to update subscription";try{e=(await s.json()).message||e}catch{e=`Failed to update subscription (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to update subscription");return r.data?.checkoutUrl||r.checkoutUrl,r.data||r}return r.checkoutUrl,r}async createBillingPortalSession(e,t){return this.fetchJson(`workspaces/${e}/subscription/billing-portal`,{method:"POST",body:JSON.stringify(t?{returnUrl:t}:{})})}async listInvoices(e,t=10,s){const r=new URLSearchParams;r.append("limit",t.toString()),s&&r.append("starting_after",s);const n=await this.fetchResponse(`workspaces/${e}/subscription/invoices?${r.toString()}`,{});if(!n.ok){let e="Failed to fetch invoices";try{e=(await n.json()).message||e}catch{e=404===n.status?"Workspace not found or no invoices available":401===n.status?"Unauthorized - Please check your session":`Failed to fetch invoices (${n.status}: ${n.statusText})`}throw new Error(e)}const o=await n.json();if(void 0!==o.success){if(!o.success)throw new Error(o.message||"Failed to fetch invoices");return o}return o}async getInvoice(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/invoices/${t}`,{});if(!s.ok){let e="Failed to fetch invoice";try{e=(await s.json()).message||e}catch{e=404===s.status?"Invoice not found":401===s.status?"Unauthorized - Please check your session":`Failed to fetch invoice (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to fetch invoice");return r}return r}async cancelSubscriptionAtPeriodEnd(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/cancel-at-period-end`,{method:"POST"});if(!t.ok){let e="Failed to cancel subscription";try{e=(await t.json()).message||e}catch{e=404===t.status?"Subscription not found":401===t.status?"Unauthorized - Please check your session":`Failed to cancel subscription (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to cancel subscription");return s.data||s}return s}async resumeSubscription(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/resume`,{method:"POST"});if(!t.ok){let e="Failed to resume subscription";try{e=(await t.json()).message||e}catch{e=404===t.status?"Subscription not found":401===t.status?"Unauthorized - Please check your session":`Failed to resume subscription (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to resume subscription");return s.data||s}return s}async recordUsage(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/usage`,{method:"POST",body:JSON.stringify(t)});if(!s.ok){let e="Failed to record usage";try{e=(await s.json()).message||e}catch{e=`Failed to record usage (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to record usage");return r.data||r}return r}async recordUsageBatch(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/usage/batch`,{method:"POST",body:JSON.stringify(t)});if(!s.ok){let e="Failed to record batch usage";try{e=(await s.json()).message||e}catch{e=`Failed to record batch usage (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();return r.data||r}async getQuotaUsageStatus(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/usage/status?quotaSlug=${encodeURIComponent(t)}`);if(!s.ok){let e="Failed to fetch quota usage status";try{e=(await s.json()).message||e}catch{e=404===s.status?"Workspace not found or no subscription available":401===s.status?"Unauthorized - Please check your session":`Failed to fetch quota usage status (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to fetch quota usage status");return r.data||r}return r}async getAllQuotaUsage(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/usage/all`);if(!t.ok){let e="Failed to fetch all quota usage";try{e=(await t.json()).message||e}catch{e=404===t.status?"Workspace not found or no subscription available":401===t.status?"Unauthorized - Please check your session":`Failed to fetch all quota usage (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch all quota usage");return s.data||s}return s}async getUsageLogs(e,t){const s=new URLSearchParams;t?.quotaSlug&&s.append("quotaSlug",t.quotaSlug),t?.from&&s.append("from",t.from),t?.to&&s.append("to",t.to),t?.source&&s.append("source",t.source),t?.page&&s.append("page",t.page.toString()),t?.limit&&s.append("limit",t.limit.toString());const r=s.toString(),n=`workspaces/${e}/subscription/usage/logs${r?`?${r}`:""}`,o=await this.fetchResponse(n);if(!o.ok){let e="Failed to fetch usage logs";try{e=(await o.json()).message||e}catch{e=404===o.status?"Workspace not found":401===o.status?"Unauthorized - Please check your session":`Failed to fetch usage logs (${o.status}: ${o.statusText})`}throw new Error(e)}const a=await o.json();if(void 0!==a.success){if(!a.success)throw new Error(a.message||"Failed to fetch usage logs");return a.data||a}return a}async sendNotification(e,t,s,r){const n={event:t};return s&&(n.userId=s),r&&(n.data=r),this.fetchJson(`workspaces/${e}/notifications/send`,{method:"POST",body:JSON.stringify(n)},"Failed to send notification")}async getNotificationEvents(e){return this.fetchJson(`workspaces/${e}/notification-events`,{},"Failed to fetch notification events")}async getNotificationPreferences(e){return(await this.fetchJson(`workspaces/${e}/notification-preferences`,{},"Failed to fetch notification preferences")).notificationPreferences??{}}async updateNotificationPreferences(e,t){return(await this.fetchJson(`workspaces/${e}/notification-preferences`,{method:"PATCH",body:JSON.stringify({notificationPreferences:t})},"Failed to update notification preferences")).notificationPreferences??{}}}exports.ApiVersion=void 0,(exports.ApiVersion||(exports.ApiVersion={})).V1="v1";const m={UserCreated:"user:created",UserUpdated:"user:updated",WorkspaceChanged:"workspace:changed",WorkspaceUpdated:"workspace:updated",WorkspaceUserAdded:"workspace:user-added",WorkspaceUserRemoved:"workspace:user-removed",WorkspaceUserRoleChanged:"workspace:user-role-changed",WorkspaceCreated:"workspace:created",WorkspaceDeleted:"workspace:deleted"};class k{constructor(){this.callbacks=null}setCallbacks(e){this.callbacks=e}getCallbacks(){return this.callbacks}async emit(e,t){if(this.callbacks?.handleEvent)try{await this.callbacks.handleEvent(e,t)}catch(t){i(t,{component:"EventEmitter",action:"emit",metadata:{eventType:e}})}}async emitUserCreated(e){await this.emit(m.UserCreated,{user:e})}async emitUserUpdated(e,t){await this.emit(m.UserUpdated,{user:e,previousUser:t})}async emitWorkspaceChanged(e,t){await this.emit(m.WorkspaceChanged,{workspace:e,previousWorkspace:t})}async emitWorkspaceUpdated(e){await this.emit(m.WorkspaceUpdated,{workspace:e})}async emitWorkspaceUserAdded(e,t,s){await this.emit(m.WorkspaceUserAdded,{userId:e,workspace:t,role:s})}async emitWorkspaceUserRemoved(e,t,s){await this.emit(m.WorkspaceUserRemoved,{userId:e,workspace:t,role:s})}async emitWorkspaceUserRoleChanged(e,t,s,r){await this.emit(m.WorkspaceUserRoleChanged,{userId:e,workspace:t,previousRole:s,newRole:r})}async emitWorkspaceCreated(e){await this.emit(m.WorkspaceCreated,{workspace:e})}async emitWorkspaceDeleted(e){await this.emit(m.WorkspaceDeleted,{workspace:e})}}const b=new k,S=new Set;const v=new Set;const E="bb";function $(e,t){let s;try{const e=t||("undefined"!=typeof window?window.location.href:"https://localhost");s=new URL(e),s.search=""}catch{s=new URL("https://localhost")}return s.searchParams.set(E,function(e){return Object.entries(e).filter(([,e])=>null!=e&&""!==e).map(([e,t])=>`${encodeURIComponent(e)}:${encodeURIComponent(t)}`).join(",")}(e)),s.toString()}function P(e){if(!e||"string"!=typeof e)return null;try{const t=new URL(e);return"https:"===t.protocol?e:"http:"!==t.protocol||"localhost"!==t.hostname&&"127.0.0.1"!==t.hostname&&"::1"!==t.hostname?null:e}catch{return null}}const U={usd:"$",eur:"€",gbp:"£",jpy:"¥",cad:"CA$",aud:"A$",chf:"CHF",cny:"¥",hkd:"HK$",sgd:"S$",inr:"₹",mxn:"MX$",brl:"R$",nzd:"NZ$",sek:"kr",nok:"kr",dkk:"kr",pln:"zł",thb:"฿"},R={usd:"🇺🇸",eur:"🇪🇺",gbp:"🇬🇧",jpy:"🇯🇵",cad:"🇨🇦",aud:"🇦🇺",chf:"🇨🇭",cny:"🇨🇳",hkd:"🇭🇰",sgd:"🇸🇬",inr:"🇮🇳",mxn:"🇲🇽",brl:"🇧🇷",nzd:"🇳🇿",sek:"🇸🇪",nok:"🇳🇴",dkk:"🇩🇰",pln:"🇵🇱",thb:"🇹🇭"};function x(e){if(!e||!e.trim())return"";const t=e.trim().toLowerCase();return U[t]??t.toUpperCase()}const I=["usd","eur","gbp","jpy","cad","aud","chf","cny","hkd","sgd","inr","mxn","brl","nzd","sek","nok","dkk","pln","thb"],F=I.map(e=>({value:e,label:`${e.toUpperCase()} (${x(e)})`}));function C(e,t){return x(t)+(e/100).toFixed(2)}const _={unit:"unit",units:"units",included:"Included",afterThat:"after that",afterIncluded:"After included"};const W={included:"included",then:"then"};const A={Monthly:"monthly",Yearly:"yearly",Quarterly:"quarterly"};function O(e,t){const s=e.pricingVariants;if(!s?.length)return null;const r=t.toLowerCase();return s.find(e=>e.currency?.toLowerCase()===r)??null}function T(e,t,s){const r=O(e,t);if(!r?.basePricing)return null;const n=r.basePricing[s];return null!=n?n:null}function N(e,t,s,r){const n=O(e,t),o=n?.quotaOverages?.[s];if(o)return o[r]}function L(e,t){const s=O(e,t);return s?.seatPricing?.enabled?s.seatPricing:null}function j(e,t,s){const r=L(e,t);return r?.perSeat?r.perSeat[s]??null:null}function B(e,t){return Math.max(0,e-(t||0))}function J(e,t,s,r){const n=L(e,t);if(!n)return null;return B(r,n.includedSeats)*(j(e,t,s)??0)}const M={WORKSPACE_SETTINGS_VIEW:"workspace:settings:view",WORKSPACE_SETTINGS_EDIT:"workspace:settings:edit",WORKSPACE_DELETE:"workspace:delete",WORKSPACE_MEMBERS_VIEW:"workspace:members:view",WORKSPACE_MEMBERS_INVITE:"workspace:members:invite",WORKSPACE_MEMBERS_REMOVE:"workspace:members:remove",WORKSPACE_MEMBERS_ROLE_CHANGE:"workspace:members:role-change",WORKSPACE_FEATURES_VIEW:"workspace:features:view",WORKSPACE_FEATURES_EDIT:"workspace:features:edit",WORKSPACE_BILLING_VIEW:"workspace:billing:view",WORKSPACE_BILLING_MANAGE:"workspace:billing:manage",WORKSPACE_USAGE_VIEW:"workspace:usage:view"},V=Object.values(M),q={admin:V.filter(e=>e!==M.WORKSPACE_DELETE),member:[M.WORKSPACE_SETTINGS_VIEW,M.WORKSPACE_MEMBERS_VIEW,M.WORKSPACE_FEATURES_VIEW,M.WORKSPACE_BILLING_VIEW,M.WORKSPACE_USAGE_VIEW],viewer:[M.WORKSPACE_SETTINGS_VIEW,M.WORKSPACE_MEMBERS_VIEW]};function K(e){const t=new Set;for(const s of Object.values(e))for(const e of s)t.add(e);return Array.from(t)}function D(e){const{userId:t,workspace:s,settings:r,appPermissions:n}=e;if(!s||!t)return new Set;if(function(e,t){if(!t)return!1;const s=(r=e.createdBy)?"string"==typeof r?r:"object"==typeof r&&"_id"in r&&"string"==typeof r._id?r._id:null:null;var r;return null!==s&&s===t}(s,t)){const e=new Set(V);if(n)for(const t of K(n))e.add(t);if(s.permissions)for(const t of K(s.permissions))e.add(t);if(r?.workspace?.permissions)for(const t of K(r.workspace.permissions))e.add(t);return e}const o=e.workspaceRole??function(e,t){if(!t||!e.users||!Array.isArray(e.users))return null;const s=e.users.find(e=>"string"==typeof e?e===t:"object"==typeof e&&null!==e&&"_id"in e&&e._id===t);return s&&"object"==typeof s&&"role"in s&&"string"==typeof s.role?s.role:null}(s,t);if(!o)return new Set;const a=s.permissions,i=r?.workspace?.permissions,c=e=>e.filter(e=>e.startsWith("workspace:")),u=e=>e.filter(e=>!e.startsWith("workspace:")),l=a?.[o]?c(a[o]):[],d=i?.[o]?c(i[o]):[],p=q[o]??[];let h;if(l.length>0)h=l;else if(d.length>0)h=d;else if(p.length>0)h=p;else{h=q[r?.workspace?.defaultRole??"member"]??q.member??[]}const f=new Set(h),g=a?.[o]?u(a[o]):[],w=n?.[o]?u(n[o]):[],y=g.length>0?g:w;for(const e of y)f.add(e);return function(e,t,s){if(!s?.workspace)return;const{canInviteMembers:r}=s.workspace;(!1===r||"admin-only"===r&&"admin"!==t)&&e.delete(M.WORKSPACE_MEMBERS_INVITE)}(f,o,r),f}function z(e,t){const s=D(t);return Array.isArray(e)?e.every(e=>s.has(e)):s.has(e)}var G;function H(e){const{serverUrl:t,orgId:s,version:r="v1",getSessionId:n,timeout:o,maxRetries:a,debug:i,headers:c,onError:u,fetch:l}=e;if(!t)throw new Error("BuildBase: serverUrl is required");if(!s)throw new Error("BuildBase: orgId is required");const d={...void 0!==o&&{timeout:o},...void 0!==a&&{maxRetries:a},...void 0!==i&&{debug:i},...c&&{headers:c},...u&&{onError:u},...l&&{fetch:l}},p=e=>{const n={serverUrl:t,version:r,orgId:s,sessionId:e,...d};return{workspace:new y(n),user:new w(n),settings:new g(n),push:new f(n)}},h=new y({serverUrl:t,version:r,orgId:s,...d}),m=e=>({workspace:{list:async()=>(await e()).workspace.getWorkspaces(),get:async t=>(await e()).workspace.getWorkspace(t),create:async t=>(await e()).workspace.createWorkspace(t),update:async(t,s)=>(await e()).workspace.updateWorkspace(t,s),delete:async t=>(await e()).workspace.deleteWorkspace(t)},users:{list:async t=>(await e()).workspace.getWorkspaceUsers(t),invite:async(t,s,r)=>(await e()).workspace.addUser(t,{email:s,role:r}),remove:async(t,s)=>(await e()).workspace.removeUser(t,s),updateRole:async(t,s,r)=>(await e()).workspace.updateUser(t,s,{role:r}),getProfile:async()=>(await e()).workspace.getProfile(),updateProfile:async t=>(await e()).workspace.updateUserProfile(t)},subscription:{get:async t=>(await e()).workspace.getCurrentSubscription(t),checkout:async(t,s)=>(await e()).workspace.createCheckoutSession(t,s),update:async(t,s)=>(await e()).workspace.updateSubscription(t,s),cancel:async t=>(await e()).workspace.cancelSubscriptionAtPeriodEnd(t),resume:async t=>(await e()).workspace.resumeSubscription(t),getBillingPortalUrl:async(t,s)=>(await e()).workspace.createBillingPortalSession(t,s)},plans:{getGroup:async t=>(await e()).workspace.getPlanGroup(t),getVersions:async t=>(await e()).workspace.getPlanGroupVersions(t),getPublic:e=>h.getPublicPlans(e),getVersion:e=>h.getPlanGroupVersion(e)},invoices:{list:async(t,s,r)=>(await e()).workspace.listInvoices(t,s,r),get:async(t,s)=>(await e()).workspace.getInvoice(t,s)},usage:{record:async(t,s)=>(await e()).workspace.recordUsage(t,s),recordBatch:async(t,s)=>(await e()).workspace.recordUsageBatch(t,s),getQuota:async(t,s)=>(await e()).workspace.getQuotaUsageStatus(t,s),getAll:async t=>(await e()).workspace.getAllQuotaUsage(t),getLogs:async(t,s)=>(await e()).workspace.getUsageLogs(t,s)},settings:{get:async()=>(await e()).settings.getSettings()},features:{list:async()=>(await e()).workspace.getFeatures(),update:async(t,s,r)=>(await e()).workspace.updateFeature(t,s,r)},notification:{send:async(t,s,r,n)=>(await e()).workspace.sendNotification(t,s,r,n)},permissions:{check:async(t,s,r)=>{const n=await e(),[o,a,i]=await Promise.all([n.workspace.getWorkspace(t),n.settings.getSettings(),n.workspace.getWorkspaceUsers(t)]),c=i.find(e=>("string"==typeof e.user?e.user:e.user._id)===s);return z(r,{userId:s,workspaceRole:c?.role??null,workspace:o,settings:a})},resolve:async(t,s)=>{const r=await e(),[n,o,a]=await Promise.all([r.workspace.getWorkspace(t),r.settings.getSettings(),r.workspace.getWorkspaceUsers(t)]),i=a.find(e=>("string"==typeof e.user?e.user:e.user._id)===s);return D({userId:s,workspaceRole:i?.role??null,workspace:n,settings:o})}}}),k=m(async()=>p(await(async()=>{if(!n)throw new Error("BuildBase: getSessionId callback is required for authenticated calls. Pass it in BuildBase({ getSessionId: ... }) or use withSession(id) / client.forSession(id).");const e=await n();if(!e)throw new Error("BuildBase: Not authenticated (getSessionId returned null)");return e})()));return{auth:async()=>{if(!n)return null;const e=await n();return e?{sessionId:e}:null},withSession:e=>{const t=p(e);return m(async()=>t)},client:{forSession:p},...k}}exports.AuthStatus=void 0,(G=exports.AuthStatus||(exports.AuthStatus={})).loading="loading",G.redirecting="redirecting",G.authenticated="authenticated",G.unauthenticated="unauthenticated",G.authenticating="authenticating",exports.AuthApi=class extends p{constructor(e){super(e)}async requestAuth(e){const t=`${this.serverUrl}/api/${this.version}/auth/request`,s=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!s.ok){let e="Failed to initiate authentication";try{e=(await s.json()).message||e}catch{e=`Failed to initiate authentication (${s.status}: ${s.statusText})`}throw new Error(e)}return s.json()}async getProfile(e,t){return this.fetchJson("profile",{headers:{"x-session-id":e},signal:t},"Failed to fetch user profile")}},exports.BB_PARAM=E,exports.BaseApi=p,exports.BetaForm=class{constructor(e){this.api=new h(e),this.orgId=e.orgId}async fetchConfig(){return this.api.fetchConfig()}async submitBetaUser(e){const t=e?.context??{},s=t?.country??("undefined"!=typeof navigator&&navigator.language?navigator.language.split("-")[1]:void 0),r=t?.language??("undefined"!=typeof navigator&&navigator.language?navigator.language.split("-")[0]:void 0),n=t?.timezone??("undefined"!=typeof Intl&&Intl.DateTimeFormat?Intl.DateTimeFormat().resolvedOptions().timeZone:void 0),o=t?.currency??("undefined"!=typeof Intl&&Intl.NumberFormat&&Intl.NumberFormat().resolvedOptions().currency?Intl.NumberFormat().resolvedOptions().currency:void 0);return this.api.submitBetaUser({orgId:this.orgId,formData:{...e,country:s,language:r,timezone:n,currency:o}})}},exports.BillingIntervals=A,exports.BuildBase=H,exports.CURRENCY_DISPLAY=U,exports.CURRENCY_FLAG=R,exports.DEFAULT_ROLE_PERMISSIONS=q,exports.DunningState={None:"none",Notified:"notified",Warning:"warning",Final:"final",Suspended:"suspended"},exports.EventEmitter=k,exports.InvoiceStatuses={Draft:"draft",Open:"open",Paid:"paid",Uncollectible:"uncollectible",Void:"void"},exports.PLAN_CURRENCY_CODES=I,exports.PLAN_CURRENCY_OPTIONS=F,exports.PUSH_SERVICE_WORKER_SCRIPT="\n// BuildBase Push Notification Service Worker\n// Place this file in your app's public directory (e.g. public/push-sw.js)\n\nself.addEventListener('push', function(event) {\n if (!event.data) return;\n\n try {\n var payload = event.data.json();\n var title = payload.title || 'Notification';\n var options = {\n body: payload.body || '',\n icon: payload.icon || undefined,\n badge: payload.icon || undefined,\n data: { url: payload.url, ...(payload.data || {}) },\n tag: 'buildbase-push-' + Date.now(),\n };\n\n event.waitUntil(\n self.registration.showNotification(title, options)\n );\n } catch (e) {\n console.error('[PushSW] Failed to show notification:', e);\n }\n});\n\nself.addEventListener('notificationclick', function(event) {\n event.notification.close();\n\n var url = event.notification.data && event.notification.data.url;\n if (url) {\n event.waitUntil(\n clients.matchAll({ type: 'window', includeUncontrolled: true }).then(function(clientList) {\n for (var i = 0; i < clientList.length; i++) {\n var client = clientList[i];\n if (client.url === url && 'focus' in client) {\n return client.focus();\n }\n }\n if (clients.openWindow) {\n return clients.openWindow(url);\n }\n })\n );\n }\n});\n",exports.Permission=M,exports.PushApi=f,exports.SDKEvent=m,exports.SettingsApi=g,exports.SubscriptionItemType={Feature:"feature",Limit:"limit",Quota:"quota"},exports.SubscriptionStatus={Active:"active",Trialing:"trialing",Canceled:"canceled",PastDue:"past_due",Paused:"paused",Incomplete:"incomplete",Unpaid:"unpaid"},exports.UserApi=w,exports.WorkspaceApi=y,exports.calculateBillableSeats=B,exports.calculateSeatOverageCents=J,exports.calculateTotalSubscriptionCents=function(e,t,s,r){const n=T(e,t,s);return null===n?null:void 0===r?n:n+(J(e,t,s,r)??0)},exports.cleanBBParams=function(){if("undefined"!=typeof window)try{const e=new URL(window.location.href);e.searchParams.has(E)&&(e.searchParams.delete(E),window.history.replaceState({},"",e.toString()))}catch{}},exports.createBBUrl=$,exports.createCheckoutRedirectUrls=function(e,t){const s=t||("undefined"!=typeof window?window.location.href:void 0);return{successUrl:$({action:"checkout",status:"success",ws:e,screen:"subscription"},s),cancelUrl:$({action:"checkout",status:"cancel",ws:e,screen:"subscription"},s)}},exports.default=H,exports.eventEmitter=b,exports.formatCents=C,exports.formatOverageRate=function(e,t,s,r){if(null==e||e<0)return null;const n={..._,...r},o=null!=t&&t>=1?t:1,a=x(s),i=(e/100).toFixed(2);return 1===o?`${a}${i}/${n.unit}`:`${a}${i}/${o.toLocaleString()} ${n.units}`},exports.formatOverageRateWithLabel=function(e,t,s,r,n,o){if(null==e||e<0)return null;const a={..._,...o},i=null!=t&&t>=1?t:1,c=x(r),u=(e/100).toFixed(2);if(s){const e=n??(s.endsWith("s")?s:`${s}s`);return i>=2?`${c}${u}/${i.toLocaleString()} ${e}`:`${c}${u}/${s}`}return 1===i?`${c}${u}/${a.unit}`:`${c}${u}/${i.toLocaleString()} ${a.units}`},exports.formatQuotaIncludedOverage=function(e,t,s,r,n,o,a){const i={..._,...a},c=o??(s.endsWith("s")?s:`${s}s`),u=null!=n&&n>=2?`${n.toLocaleString()} ${c}`:s;return null!=e&&null!=t?`${i.included}: ${e.toLocaleString()}, ${i.afterThat} ${C(t,r)}/${u}`:null!=e?`${i.included}: ${e.toLocaleString()}`:null!=t?`${i.afterIncluded}: ${C(t,r)}/${u}`:"—"},exports.formatQuotaWithPrice=function(e,t,s={}){const{overageInCents:r=!0,currency:n}=s,o=s.labels??W,a=s.currencySymbol??x(n??"");if(null==e)return"—";const{included:i,overage:c}=e,u=`${i} ${o.included}`;if(null==c)return u;const l=r?c/100:c,d="number"==typeof l&&Number.isFinite(l)?l.toFixed(2):String(c),p=t&&"unitSize"in e&&null!=e.unitSize&&e.unitSize>0?` / ${e.unitSize.toLocaleString()} ${t}`:t?` / ${t}`:"";return`${u}, ${o.then} ${a}${d}${p}`},exports.getAvailableCurrenciesFromPlans=function(e){const t=new Set;for(const s of e)s.pricingVariants?.forEach(e=>{e.currency&&t.add(e.currency.toLowerCase())});return Array.from(t).sort()},exports.getBasePriceCents=T,exports.getBillingIntervalAndCurrencyFromPriceId=function(e,t){if(!e)return null;for(const s of t){const t=s.pricingVariants;if(t?.length)for(const s of t){const t=s.stripePrices;if(t){if(t.monthlyPriceId===e||t.monthly===e)return{interval:"monthly",currency:s.currency};if(t.yearlyPriceId===e||t.yearly===e)return{interval:"yearly",currency:s.currency};if(t.quarterlyPriceId===e)return{interval:"quarterly",currency:s.currency}}}}return null},exports.getCurrencyFlag=function(e){return e&&e.trim()?R[e.trim().toLowerCase()]??"":""},exports.getCurrencySymbol=x,exports.getDisplayCurrency=function(e,t){const s=O(e,t);return s?s.currency:e.plan?.currency??""},exports.getPerSeatPriceCents=j,exports.getPricingVariant=O,exports.getQuotaDisplayValue=function(e,t){if(null==e)return null;const s=e[t??"monthly"];return s?{included:s.included,...void 0!==s.overage&&{overage:s.overage},...void 0!==s.unitSize&&{unitSize:s.unitSize}}:null},exports.getQuotaDisplayWithVariant=function(e,t,s,r){const n=e.quotas?.[s];if(null==n)return null;const o=n[r];if(!o)return null;const a=N(e,t,s,r);return{included:o.included,...void 0!==o.unitSize&&{unitSize:o.unitSize},...void 0!==a&&{overage:a}}},exports.getQuotaOverageCents=N,exports.getQuotaUnitLabelFromName=function(e,t="unit"){const s=(e||"").trim().toLowerCase();if(!s)return t;const r=s.split(/\s+/)[0]??s;return new Set(["series","species","status","analysis","basis","bus","campus","corpus","axis"]).has(r)?r:r.endsWith("ies")&&r.length>3?r.slice(0,-3)+"y":r.endsWith("ses")||r.endsWith("xes")||r.endsWith("zes")||r.endsWith("ches")||r.endsWith("shes")?r.slice(0,-2):r.endsWith("s")&&!r.endsWith("ss")&&r.length>1?r.slice(0,-1):r||t},exports.getSeatPricing=L,exports.getStripePriceIdForInterval=function(e,t,s){const r=O(e,t);if(!r?.stripePrices)return null;const n=s===A.Monthly?"monthlyPriceId":s===A.Yearly?"yearlyPriceId":"quarterlyPriceId",o=s===A.Monthly?"monthly":s===A.Yearly?"yearly":void 0;return r.stripePrices[n]??(o?r.stripePrices[o]:void 0)??null},exports.hasPermission=z,exports.invalidateQuotaUsage=function(){v.forEach(e=>e())},exports.invalidateSubscription=function(){S.forEach(e=>e())},exports.readBBParams=function(){if("undefined"==typeof window)return null;try{const e=new URLSearchParams(window.location.search).get(E);if(!e)return null;const t=function(e){const t={};if(!e)return t;const s=e.split(",");for(const e of s){const s=e.indexOf(":");if(-1===s)continue;const r=decodeURIComponent(e.slice(0,s)),n=decodeURIComponent(e.slice(s+1));r&&(t[r]=n)}return t}(e);return Object.keys(t).length>0?t:null}catch{return null}},exports.resolveMaxUsers=function(e){const{planVersion:t,currency:s="usd",settingsMaxUsers:r}=e;if(t){const e=L(t,s);if(e)return{maxUsers:e.maxSeats??0,source:"seat_pricing",includedSeats:e.includedSeats??0,hasSeatPricing:!0}}return null!=r&&r>0?{maxUsers:r,source:"settings",includedSeats:0,hasSeatPricing:!1}:{maxUsers:0,source:"none",includedSeats:0,hasSeatPricing:!1}},exports.resolvePermissions=D,exports.safeRedirect=function(e,t="/"){const s=P(e);window.location.href=s||t},exports.validateInvite=function(e){const{memberCount:t,maxUsersConfig:s,hasSubscription:r=!0,requireSubscription:n=!1}=e;if(n&&!r)return{canInvite:!1,blockReason:"no_subscription",blockMessageKey:"users.subscriptionRequired",blockMessageValues:{}};const{maxUsers:o,source:a}=s;if(o<=0)return{canInvite:!0,blockReason:null,blockMessageKey:null,blockMessageValues:null};if(t>=o){return{canInvite:!1,blockReason:{seat_pricing:"seat_limit_reached",settings:"settings_user_limit_reached"}[a]??"seat_limit_reached",blockMessageKey:{seat_pricing:"users.seatLimitMessage",settings:"users.settingsLimitMessage"}[a]??"users.memberLimitMessage",blockMessageValues:{maxUsers:o}}}return{canInvite:!0,blockReason:null,blockMessageKey:null,blockMessageValues:null}},exports.validateRedirectUrl=P;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});let e=!0;function t(t,...s){e&&function(){try{const e="undefined"!=typeof globalThis?globalThis:null;return"development"===e?.process?.env?.NODE_ENV}catch{return!1}}()&&console.error(t,...s)}async function s(e,t){try{const s=await e.json();return s?.message||s?.error||t}catch{return t}}async function r(e){const t=await e.text();if(!t)throw new Error("Empty response body");try{return JSON.parse(t)}catch(e){throw new Error(`Invalid JSON response: ${t.substring(0,100)}${t.length>100?"...":""}`)}}async function n(e,t="Request failed"){if(!e.ok){let s=t;try{const t=await r(e);s=t.message||t.error||s}catch{s=function(e,t){const s={400:"Bad Request",401:"Unauthorized - Please check your session",403:"Forbidden - You do not have permission",404:"Resource not found",500:"Internal server error",502:"Bad Gateway",503:"Service unavailable"}[e.status]||e.statusText||t;return new Error(`${t} (${e.status}: ${s})`)}(e,t).message}throw new Error(s)}try{return await r(e)}catch(e){if(e instanceof Error&&e.message.includes("Invalid JSON"))throw e;throw new Error("Failed to parse response as JSON")}}class o extends Error{constructor(e,t,s,r){super(e),this.code=t,this.context=s,this.originalError=r,this.name="SDKError","undefined"!=typeof Error&&"captureStackTrace"in Error&&Error.captureStackTrace(this,o)}}const a=new class{constructor(){this.config={enableConsoleLogging:!0,showUserNotifications:!1}}configure(t){this.config={...this.config,...t},void 0!==t.enableConsoleLogging&&function(t){void 0!==t.enableLogging&&(e=t.enableLogging)}({enableLogging:t.enableConsoleLogging})}handleError(e,s={}){if(function(e){return e instanceof Error&&("AbortError"===e.name||"ERR_CANCELED"===e.code)}(e))return;const r=e instanceof Error?e:new o("string"==typeof e?e:"An unknown error occurred","UNKNOWN_ERROR",s),n=r instanceof o?r:new o(r.message,"SDK_ERROR",s,r);if(this.config.enableConsoleLogging&&t(`[SDK Error] ${s.component||"Unknown"}:`,{message:n.message,code:n.code,context:n.context,originalError:n.originalError,stack:n.stack}),this.config.onError)try{this.config.onError(n,s)}catch(e){!function(e,...t){console.error(e,...t)}("[SDK Error Handler] Error in custom error callback:",e)}this.config.showUserNotifications&&this.notifyUser(n,s)}notifyUser(e,t){"undefined"!=typeof window&&window.dispatchEvent&&window.dispatchEvent(new CustomEvent("sdk-error",{detail:{error:e,context:t}}))}wrapAsync(e,t){return(...s)=>e(...s).catch(e=>{throw this.handleError(e,t),e})}wrapSync(e,t){return(...s)=>{try{return e(...s)}catch(e){throw this.handleError(e,t),e}}}};function i(e,t={}){a.handleError(e,t)}const c="saas-session-id";function u(){if("undefined"==typeof window)return null;try{return function(e){if("undefined"==typeof window)return null;try{return localStorage.getItem(e)}catch(t){return i(t,{component:"storage",action:"getStorageItem",metadata:{key:e}}),null}}(c)}catch(e){return i(e,{component:"auth-utils",action:"getSessionId",metadata:{key:c}}),null}}function l(){const e=u(),t={};return e&&(t["x-session-id"]=e),t}const d="SDK is not ready (missing serverUrl, version, or orgId)";class p{constructor(e){this.serverUrl=e.serverUrl,this.version=e.version,this.orgId=e.orgId,this.requireOrgId=e.requireOrgId??!1,this.basePath=e.basePath??"public",this._sessionId=e.sessionId,this._timeout=e.timeout??3e4,this._maxRetries=e.maxRetries??0,this._debug=e.debug??!1,this._customHeaders=e.headers??{},this._onError=e.onError,this._fetch=e.fetch??globalThis.fetch}ensureReady(){if(!this.serverUrl?.trim()||!this.version)throw new Error(d);if(this.requireOrgId&&!this.orgId?.trim())throw new Error(d)}get baseUrl(){return this.ensureReady(),`${this.serverUrl}/api/${this.version}/${this.basePath}`}getAuthHeaders(){return this._sessionId?{"x-session-id":this._sessionId}:l()}url(e){const t=e.startsWith("/")?e.slice(1):e;return`${this.baseUrl.endsWith("/")?this.baseUrl.slice(0,-1):this.baseUrl}/${t}`}buildHeaders(e){const t={...this._customHeaders,...this.getAuthHeaders()};return e.headers&&Object.assign(t,e.headers),null==e.body||t["Content-Type"]||(t["Content-Type"]="application/json"),t}async executeFetch(e,t){const s=this.url(e),r=(t.method??"GET").toUpperCase(),n=this.buildHeaders(t),o={...t,headers:n};let a;if(this._timeout>0){const e=new AbortController;a=setTimeout(()=>e.abort(),this._timeout),o.signal=t.signal?AbortSignal.any([t.signal,e.signal]):e.signal}const i=async t=>{try{const e=this._fetch.bind(globalThis),n=await e(s,o);if(this._debug&&console.log(`[BuildBase] ${r} ${s} → ${n.status}`),n.status>=500&&t<this._maxRetries){const e=Math.min(1e3*Math.pow(2,t),1e4);return this._debug&&console.log(`[BuildBase] Retrying in ${e}ms (attempt ${t+1}/${this._maxRetries})`),await new Promise(t=>setTimeout(t,e)),i(t+1)}return n}catch(s){if(s instanceof Error&&"AbortError"===s.name){if(void 0!==a){const t=new Error(`Request timeout after ${this._timeout}ms: ${r} ${e}`);throw this._onError?.(t,{method:r,path:e}),t}throw s}if(t<this._maxRetries){const e=Math.min(1e3*Math.pow(2,t),1e4);return this._debug&&console.log(`[BuildBase] Network error, retrying in ${e}ms (attempt ${t+1}/${this._maxRetries})`),await new Promise(t=>setTimeout(t,e)),i(t+1)}throw s instanceof Error&&this._onError?.(s,{method:r,path:e}),s}};try{return await i(0)}finally{void 0!==a&&clearTimeout(a)}}async fetchJson(e,t={},s="Request failed"){this.ensureReady();try{const r=await this.executeFetch(e,t);return await n(r,s)}catch(s){throw s instanceof Error&&this._onError?.(s,{method:(t.method??"GET").toUpperCase(),path:e}),s}}async fetchResponse(e,t={}){return this.ensureReady(),this.executeFetch(e,t)}}class h extends p{constructor(e){super({...e,basePath:"beta",requireOrgId:!0})}getAuthHeaders(){return{}}async fetchConfig(){return this.fetchJson(`config?orgId=${encodeURIComponent(this.orgId)}`,{},"Failed to fetch beta form configuration")}async submitBetaUser(e){return this.fetchJson("submit",{method:"POST",body:JSON.stringify(e)},"Failed to submit beta user request")}}class f extends p{constructor(e){super({...e,requireOrgId:!0})}async getVapidPublicKey(){return this.fetchJson("push/vapid-public-key")}async subscribe(e,t){await this.fetchJson("push/subscribe",{method:"POST",body:JSON.stringify({endpoint:e.endpoint,keys:e.keys,userAgent:t})})}async unsubscribe(e){await this.fetchJson("push/unsubscribe",{method:"DELETE",body:JSON.stringify({endpoint:e})})}}class g extends p{constructor(e){super({...e,requireOrgId:!0})}async getSettings(e){return this.fetchJson(`${this.orgId}/settings`,{signal:e},"Failed to fetch settings")}}class w extends p{constructor(e){super(e)}async getAttributes(e){const t=await this.fetchResponse("users/attributes",{signal:e});if(!t.ok)throw new Error(await s(t,"Failed to fetch user attributes"));const r=await t.json();return r&&"object"==typeof r&&!Array.isArray(r)?r:{}}async updateAttributes(e){return this.fetchJson("users/attributes",{method:"PATCH",body:JSON.stringify({attributes:e})},"Failed to update user attributes")}async updateAttribute(e,t){return this.fetchJson(`users/attributes/${e}`,{method:"PATCH",body:JSON.stringify({value:t})},"Failed to update user attribute")}async getFeatures(e){const t=await this.fetchResponse("users/features",{signal:e});if(!t.ok)throw new Error(await s(t,"Failed to fetch user features"));const r=await t.json();return"object"==typeof r&&null!==r?r:{}}}class y extends p{constructor(e){super({...e,requireOrgId:!0})}async getWorkspaces(){return this.fetchJson("workspaces",{},"Failed to fetch workspaces")}async createWorkspace(e){return this.fetchJson("workspaces",{method:"POST",body:JSON.stringify(e)},"Failed to create workspace")}async updateWorkspace(e,t){return this.fetchJson(`workspaces/${e}`,{method:"PUT",body:JSON.stringify(t)},"Failed to update workspace")}async deleteWorkspace(e){return this.fetchJson(`workspaces/${e}`,{method:"DELETE"},"Failed to delete workspace")}async getWorkspaceUsers(e){return this.fetchJson(`workspaces/${e}/users`,{},"Failed to fetch workspace users")}async addUser(e,t){return this.fetchJson(`workspaces/${e}/users/add`,{method:"POST",body:JSON.stringify(t)},"Failed to invite member")}async removeUser(e,t){return this.fetchJson(`workspaces/${e}/users/${t}`,{method:"DELETE"},"Failed to remove user")}async updateUser(e,t,s){return this.fetchJson(`workspaces/${e}/users/${t}`,{method:"PATCH",body:JSON.stringify(s)},"Failed to update user")}async updateSettings(e){return this.fetchJson("workspaces/settings",{method:"PATCH",body:JSON.stringify(e)},"Failed to update workspace settings")}async updateWorkspacePermissions(e,t){return this.fetchJson(`workspaces/${e}/permissions`,{method:"PATCH",body:JSON.stringify({permissions:t})},"Failed to update workspace permissions")}async getFeatures(){return this.fetchJson("workspaces/features",{},"Failed to fetch features")}async updateFeature(e,t,s){return this.fetchJson(`workspaces/${e}/features`,{method:"PATCH",body:JSON.stringify({features:{[t]:s}})},"Failed to update feature")}async getWorkspace(e){return this.fetchJson(`workspaces/${e}`,{},"Failed to fetch workspace")}async getProfile(){return this.fetchJson("profile",{},"Failed to fetch profile")}async updateUserProfile(e){return this.fetchJson("profile",{method:"PATCH",body:JSON.stringify(e)},"Failed to update user profile")}async getCurrentSubscription(e){const t=await this.fetchResponse(`workspaces/${e}/subscription`);if(!t.ok){let e="Failed to fetch subscription";try{e=(await t.json()).message||e}catch{e=404===t.status?"Workspace not found or no subscription available":401===t.status?"Unauthorized - Please check your session":`Failed to fetch subscription (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch subscription");return s.data||s}return s}async getPlanGroup(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/plan-group`);if(!t.ok){let e="Failed to fetch plan group";try{e=(await t.json()).message||e}catch{e=404===t.status?"No plan group found for this workspace":401===t.status?"Unauthorized - Please check your session":`Failed to fetch plan group (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch plan group");return s.data||s}return s}async getPlanGroupByVersion(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/plan-group?groupVersionId=${encodeURIComponent(t)}`);if(!s.ok){let e="Failed to fetch plan group version";try{e=(await s.json()).message||e}catch{e=404===s.status?"Plan group version not found":401===s.status?"Unauthorized - Please check your session":`Failed to fetch plan group version (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to fetch plan group version");return r.data||r}return r}async getPlanGroupVersions(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/plan-group/versions`);if(!t.ok){let e="Failed to fetch plan group versions";try{e=(await t.json()).message||e}catch{e=404===t.status?"No plan group versions found":401===t.status?"Unauthorized - Please check your session":`Failed to fetch plan group versions (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch plan group versions");return s.data||s}return s}async getPublicPlans(e){if(!this.orgId)throw new Error("orgId is required for getPublicPlans");const t=await this.fetchResponse(`${this.orgId}/plans/${encodeURIComponent(e)}`);if(!t.ok){let s="Failed to fetch plans";try{s=(await t.json()).message||s}catch{s=404===t.status?`Plans "${e}" not found`:`Failed to fetch plans (${t.status}: ${t.statusText})`}throw new Error(s)}const s=await t.json();if(void 0!==s.success&&!s.success)throw new Error(s.message||"Failed to fetch plans");return s.data??s}async getPlanGroupVersion(e){const t=await this.fetchResponse(`plan-group-versions/${e}`);if(!t.ok){let e="Failed to fetch plan group version";try{e=(await t.json()).message||e}catch{e=404===t.status?"Plan group version not found":401===t.status?"Unauthorized - Please check your session":`Failed to fetch plan group version (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch plan group version");return s.data||s}return s}async createCheckoutSession(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/checkout`,{method:"POST",body:JSON.stringify(t)});if(!s.ok){let e="Failed to create checkout session";try{e=(await s.json()).message||e}catch{e=`Failed to create checkout session (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to create checkout session");return r.data||r}return r}async selectFreePlan(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/select-free-plan`,{method:"POST",body:JSON.stringify({planVersionId:t})});if(!s.ok){let e="Failed to select free plan";try{e=(await s.json()).message||e}catch{e=`Failed to select free plan (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();return r.data||r}async updateSubscription(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription`,{method:"PATCH",body:JSON.stringify(t)});if(!s.ok){let e="Failed to update subscription";try{e=(await s.json()).message||e}catch{e=`Failed to update subscription (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to update subscription");return r.data?.checkoutUrl||r.checkoutUrl,r.data||r}return r.checkoutUrl,r}async createBillingPortalSession(e,t){return this.fetchJson(`workspaces/${e}/subscription/billing-portal`,{method:"POST",body:JSON.stringify(t?{returnUrl:t}:{})})}async listInvoices(e,t=10,s){const r=new URLSearchParams;r.append("limit",t.toString()),s&&r.append("starting_after",s);const n=await this.fetchResponse(`workspaces/${e}/subscription/invoices?${r.toString()}`,{});if(!n.ok){let e="Failed to fetch invoices";try{e=(await n.json()).message||e}catch{e=404===n.status?"Workspace not found or no invoices available":401===n.status?"Unauthorized - Please check your session":`Failed to fetch invoices (${n.status}: ${n.statusText})`}throw new Error(e)}const o=await n.json();if(void 0!==o.success){if(!o.success)throw new Error(o.message||"Failed to fetch invoices");return o}return o}async getInvoice(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/invoices/${t}`,{});if(!s.ok){let e="Failed to fetch invoice";try{e=(await s.json()).message||e}catch{e=404===s.status?"Invoice not found":401===s.status?"Unauthorized - Please check your session":`Failed to fetch invoice (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to fetch invoice");return r}return r}async cancelSubscriptionAtPeriodEnd(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/cancel-at-period-end`,{method:"POST"});if(!t.ok){let e="Failed to cancel subscription";try{e=(await t.json()).message||e}catch{e=404===t.status?"Subscription not found":401===t.status?"Unauthorized - Please check your session":`Failed to cancel subscription (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to cancel subscription");return s.data||s}return s}async resumeSubscription(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/resume`,{method:"POST"});if(!t.ok){let e="Failed to resume subscription";try{e=(await t.json()).message||e}catch{e=404===t.status?"Subscription not found":401===t.status?"Unauthorized - Please check your session":`Failed to resume subscription (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to resume subscription");return s.data||s}return s}async recordUsage(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/usage`,{method:"POST",body:JSON.stringify(t)});if(!s.ok){let e="Failed to record usage";try{e=(await s.json()).message||e}catch{e=`Failed to record usage (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to record usage");return r.data||r}return r}async recordUsageBatch(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/usage/batch`,{method:"POST",body:JSON.stringify(t)});if(!s.ok){let e="Failed to record batch usage";try{e=(await s.json()).message||e}catch{e=`Failed to record batch usage (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();return r.data||r}async getQuotaUsageStatus(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/usage/status?quotaSlug=${encodeURIComponent(t)}`);if(!s.ok){let e="Failed to fetch quota usage status";try{e=(await s.json()).message||e}catch{e=404===s.status?"Workspace not found or no subscription available":401===s.status?"Unauthorized - Please check your session":`Failed to fetch quota usage status (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to fetch quota usage status");return r.data||r}return r}async getAllQuotaUsage(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/usage/all`);if(!t.ok){let e="Failed to fetch all quota usage";try{e=(await t.json()).message||e}catch{e=404===t.status?"Workspace not found or no subscription available":401===t.status?"Unauthorized - Please check your session":`Failed to fetch all quota usage (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch all quota usage");return s.data||s}return s}async getUsageLogs(e,t){const s=new URLSearchParams;t?.quotaSlug&&s.append("quotaSlug",t.quotaSlug),t?.from&&s.append("from",t.from),t?.to&&s.append("to",t.to),t?.source&&s.append("source",t.source),t?.page&&s.append("page",t.page.toString()),t?.limit&&s.append("limit",t.limit.toString());const r=s.toString(),n=`workspaces/${e}/subscription/usage/logs${r?`?${r}`:""}`,o=await this.fetchResponse(n);if(!o.ok){let e="Failed to fetch usage logs";try{e=(await o.json()).message||e}catch{e=404===o.status?"Workspace not found":401===o.status?"Unauthorized - Please check your session":`Failed to fetch usage logs (${o.status}: ${o.statusText})`}throw new Error(e)}const a=await o.json();if(void 0!==a.success){if(!a.success)throw new Error(a.message||"Failed to fetch usage logs");return a.data||a}return a}async sendNotification(e,t,s,r){const n={event:t};return s&&(n.userId=s),r&&(n.data=r),this.fetchJson(`workspaces/${e}/notifications/send`,{method:"POST",body:JSON.stringify(n)},"Failed to send notification")}async getNotificationEvents(e){return this.fetchJson(`workspaces/${e}/notification-events`,{},"Failed to fetch notification events")}async getNotificationPreferences(e){return(await this.fetchJson(`workspaces/${e}/notification-preferences`,{},"Failed to fetch notification preferences")).notificationPreferences??{}}async updateNotificationPreferences(e,t){return(await this.fetchJson(`workspaces/${e}/notification-preferences`,{method:"PATCH",body:JSON.stringify({notificationPreferences:t})},"Failed to update notification preferences")).notificationPreferences??{}}}exports.ApiVersion=void 0,(exports.ApiVersion||(exports.ApiVersion={})).V1="v1";const m={UserCreated:"user:created",UserUpdated:"user:updated",WorkspaceChanged:"workspace:changed",WorkspaceUpdated:"workspace:updated",WorkspaceUserAdded:"workspace:user-added",WorkspaceUserRemoved:"workspace:user-removed",WorkspaceUserRoleChanged:"workspace:user-role-changed",WorkspaceCreated:"workspace:created",WorkspaceDeleted:"workspace:deleted"};class k{constructor(){this.callbacks=null}setCallbacks(e){this.callbacks=e}getCallbacks(){return this.callbacks}async emit(e,t){if(this.callbacks?.handleEvent)try{await this.callbacks.handleEvent(e,t)}catch(t){i(t,{component:"EventEmitter",action:"emit",metadata:{eventType:e}})}}async emitUserCreated(e){await this.emit(m.UserCreated,{user:e})}async emitUserUpdated(e,t){await this.emit(m.UserUpdated,{user:e,previousUser:t})}async emitWorkspaceChanged(e,t){await this.emit(m.WorkspaceChanged,{workspace:e,previousWorkspace:t})}async emitWorkspaceUpdated(e){await this.emit(m.WorkspaceUpdated,{workspace:e})}async emitWorkspaceUserAdded(e,t,s){await this.emit(m.WorkspaceUserAdded,{userId:e,workspace:t,role:s})}async emitWorkspaceUserRemoved(e,t,s){await this.emit(m.WorkspaceUserRemoved,{userId:e,workspace:t,role:s})}async emitWorkspaceUserRoleChanged(e,t,s,r){await this.emit(m.WorkspaceUserRoleChanged,{userId:e,workspace:t,previousRole:s,newRole:r})}async emitWorkspaceCreated(e){await this.emit(m.WorkspaceCreated,{workspace:e})}async emitWorkspaceDeleted(e){await this.emit(m.WorkspaceDeleted,{workspace:e})}}const b=new k,v=new Set;const S=new Set;const E="bb";function $(e,t){let s;try{const e=t||("undefined"!=typeof window?window.location.href:"https://localhost");s=new URL(e),s.search=""}catch{s=new URL("https://localhost")}return s.searchParams.set(E,function(e){return Object.entries(e).filter(([,e])=>null!=e&&""!==e).map(([e,t])=>`${encodeURIComponent(e)}:${encodeURIComponent(t)}`).join(",")}(e)),s.toString()}function P(e){if(!e||"string"!=typeof e)return null;try{const t=new URL(e);return"https:"===t.protocol?e:"http:"!==t.protocol||"localhost"!==t.hostname&&"127.0.0.1"!==t.hostname&&"::1"!==t.hostname?null:e}catch{return null}}const U={usd:"$",eur:"€",gbp:"£",jpy:"¥",cad:"CA$",aud:"A$",chf:"CHF",cny:"¥",hkd:"HK$",sgd:"S$",inr:"₹",mxn:"MX$",brl:"R$",nzd:"NZ$",sek:"kr",nok:"kr",dkk:"kr",pln:"zł",thb:"฿"},R={usd:"🇺🇸",eur:"🇪🇺",gbp:"🇬🇧",jpy:"🇯🇵",cad:"🇨🇦",aud:"🇦🇺",chf:"🇨🇭",cny:"🇨🇳",hkd:"🇭🇰",sgd:"🇸🇬",inr:"🇮🇳",mxn:"🇲🇽",brl:"🇧🇷",nzd:"🇳🇿",sek:"🇸🇪",nok:"🇳🇴",dkk:"🇩🇰",pln:"🇵🇱",thb:"🇹🇭"};function x(e){if(!e||!e.trim())return"";const t=e.trim().toLowerCase();return U[t]??t.toUpperCase()}const I=["usd","eur","gbp","jpy","cad","aud","chf","cny","hkd","sgd","inr","mxn","brl","nzd","sek","nok","dkk","pln","thb"],F=I.map(e=>({value:e,label:`${e.toUpperCase()} (${x(e)})`}));function C(e,t){return x(t)+(e/100).toFixed(2)}const _={unit:"unit",units:"units",included:"Included",afterThat:"after that",afterIncluded:"After included"};const W={included:"included",then:"then"};const O={Monthly:"monthly",Yearly:"yearly",Quarterly:"quarterly"};function A(e,t){const s=e.pricingVariants;if(!s?.length)return null;const r=t.toLowerCase();return s.find(e=>e.currency?.toLowerCase()===r)??null}function T(e,t,s){const r=A(e,t);if(!r?.basePricing)return null;const n=r.basePricing[s];return null!=n?n:null}function N(e,t,s,r){const n=A(e,t),o=n?.quotaOverages?.[s];if(o)return o[r]}function L(e,t){const s=A(e,t);return s?.seatPricing?.enabled?s.seatPricing:null}function j(e,t,s){const r=L(e,t);return r?.perSeat?r.perSeat[s]??null:null}function B(e,t){return Math.max(0,e-(t||0))}function J(e,t,s,r){const n=L(e,t);if(!n)return null;return B(r,n.includedSeats)*(j(e,t,s)??0)}const V={WORKSPACE_SETTINGS_VIEW:"workspace:settings:view",WORKSPACE_SETTINGS_EDIT:"workspace:settings:edit",WORKSPACE_DELETE:"workspace:delete",WORKSPACE_MEMBERS_VIEW:"workspace:members:view",WORKSPACE_MEMBERS_INVITE:"workspace:members:invite",WORKSPACE_MEMBERS_REMOVE:"workspace:members:remove",WORKSPACE_MEMBERS_ROLE_CHANGE:"workspace:members:role-change",WORKSPACE_FEATURES_VIEW:"workspace:features:view",WORKSPACE_FEATURES_EDIT:"workspace:features:edit",WORKSPACE_BILLING_VIEW:"workspace:billing:view",WORKSPACE_BILLING_MANAGE:"workspace:billing:manage",WORKSPACE_USAGE_VIEW:"workspace:usage:view"},M=Object.values(V),q={admin:M.filter(e=>e!==V.WORKSPACE_DELETE),member:[V.WORKSPACE_SETTINGS_VIEW,V.WORKSPACE_MEMBERS_VIEW,V.WORKSPACE_FEATURES_VIEW,V.WORKSPACE_BILLING_VIEW,V.WORKSPACE_USAGE_VIEW],viewer:[V.WORKSPACE_SETTINGS_VIEW,V.WORKSPACE_MEMBERS_VIEW]};function K(e){const t=new Set;for(const s of Object.values(e))for(const e of s)t.add(e);return Array.from(t)}function D(e){const{userId:t,workspace:s,settings:r,appPermissions:n}=e;if(!s||!t)return new Set;if(function(e,t){if(!t)return!1;const s=(r=e.createdBy)?"string"==typeof r?r:"object"==typeof r&&"_id"in r&&"string"==typeof r._id?r._id:null:null;var r;return null!==s&&s===t}(s,t)){const e=new Set(M);if(n)for(const t of K(n))e.add(t);if(s.permissions)for(const t of K(s.permissions))e.add(t);if(r?.workspace?.permissions)for(const t of K(r.workspace.permissions))e.add(t);return e}const o=e.workspaceRole??function(e,t){if(!t||!e.users||!Array.isArray(e.users))return null;const s=e.users.find(e=>"string"==typeof e?e===t:"object"==typeof e&&null!==e&&"_id"in e&&e._id===t);return s&&"object"==typeof s&&"role"in s&&"string"==typeof s.role?s.role:null}(s,t);if(!o)return new Set;const a=s.permissions,i=r?.workspace?.permissions,c=e=>e.filter(e=>e.startsWith("workspace:")),u=e=>e.filter(e=>!e.startsWith("workspace:")),l=a?.[o]?c(a[o]):[],d=i?.[o]?c(i[o]):[],p=q[o]??[];let h;if(l.length>0)h=l;else if(d.length>0)h=d;else if(p.length>0)h=p;else{h=q[r?.workspace?.defaultRole??"member"]??q.member??[]}const f=new Set(h),g=a?.[o]?u(a[o]):[],w=n?.[o]?u(n[o]):[],y=g.length>0?g:w;for(const e of y)f.add(e);return function(e,t,s){if(!s?.workspace)return;const{canInviteMembers:r}=s.workspace;(!1===r||"admin-only"===r&&"admin"!==t)&&e.delete(V.WORKSPACE_MEMBERS_INVITE)}(f,o,r),f}function z(e,t){const s=D(t);return Array.isArray(e)?e.every(e=>s.has(e)):s.has(e)}var G;function H(e){const{serverUrl:t,orgId:s,version:r="v1",getSessionId:n,timeout:o,maxRetries:a,debug:i,headers:c,onError:u,fetch:l}=e;if(!t)throw new Error("BuildBase: serverUrl is required");if(!s)throw new Error("BuildBase: orgId is required");const d={...void 0!==o&&{timeout:o},...void 0!==a&&{maxRetries:a},...void 0!==i&&{debug:i},...c&&{headers:c},...u&&{onError:u},...l&&{fetch:l}},p=e=>{const n={serverUrl:t,version:r,orgId:s,sessionId:e,...d};return{workspace:new y(n),user:new w(n),settings:new g(n),push:new f(n)}},h=new y({serverUrl:t,version:r,orgId:s,...d}),m=e=>({workspace:{list:async()=>(await e()).workspace.getWorkspaces(),get:async t=>(await e()).workspace.getWorkspace(t),create:async t=>(await e()).workspace.createWorkspace(t),update:async(t,s)=>(await e()).workspace.updateWorkspace(t,s),delete:async t=>(await e()).workspace.deleteWorkspace(t)},users:{list:async t=>(await e()).workspace.getWorkspaceUsers(t),invite:async(t,s,r)=>(await e()).workspace.addUser(t,{email:s,role:r}),remove:async(t,s)=>(await e()).workspace.removeUser(t,s),updateRole:async(t,s,r)=>(await e()).workspace.updateUser(t,s,{role:r}),getProfile:async()=>(await e()).workspace.getProfile(),updateProfile:async t=>(await e()).workspace.updateUserProfile(t)},subscription:{get:async t=>(await e()).workspace.getCurrentSubscription(t),checkout:async(t,s)=>(await e()).workspace.createCheckoutSession(t,s),update:async(t,s)=>(await e()).workspace.updateSubscription(t,s),cancel:async t=>(await e()).workspace.cancelSubscriptionAtPeriodEnd(t),resume:async t=>(await e()).workspace.resumeSubscription(t),getBillingPortalUrl:async(t,s)=>(await e()).workspace.createBillingPortalSession(t,s)},plans:{getGroup:async t=>(await e()).workspace.getPlanGroup(t),getVersions:async t=>(await e()).workspace.getPlanGroupVersions(t),getPublic:e=>h.getPublicPlans(e),getVersion:e=>h.getPlanGroupVersion(e)},invoices:{list:async(t,s,r)=>(await e()).workspace.listInvoices(t,s,r),get:async(t,s)=>(await e()).workspace.getInvoice(t,s)},usage:{record:async(t,s)=>(await e()).workspace.recordUsage(t,s),recordBatch:async(t,s)=>(await e()).workspace.recordUsageBatch(t,s),getQuota:async(t,s)=>(await e()).workspace.getQuotaUsageStatus(t,s),getAll:async t=>(await e()).workspace.getAllQuotaUsage(t),getLogs:async(t,s)=>(await e()).workspace.getUsageLogs(t,s)},settings:{get:async()=>(await e()).settings.getSettings()},features:{list:async()=>(await e()).workspace.getFeatures(),update:async(t,s,r)=>(await e()).workspace.updateFeature(t,s,r)},notification:{send:async(t,s,r,n)=>(await e()).workspace.sendNotification(t,s,r,n)},permissions:{check:async(t,s,r)=>{const n=await e(),[o,a,i]=await Promise.all([n.workspace.getWorkspace(t),n.settings.getSettings(),n.workspace.getWorkspaceUsers(t)]),c=i.find(e=>("string"==typeof e.user?e.user:e.user._id)===s);return z(r,{userId:s,workspaceRole:c?.role??null,workspace:o,settings:a})},resolve:async(t,s)=>{const r=await e(),[n,o,a]=await Promise.all([r.workspace.getWorkspace(t),r.settings.getSettings(),r.workspace.getWorkspaceUsers(t)]),i=a.find(e=>("string"==typeof e.user?e.user:e.user._id)===s);return D({userId:s,workspaceRole:i?.role??null,workspace:n,settings:o})}}}),k=m(async()=>p(await(async()=>{if(!n)throw new Error("BuildBase: getSessionId callback is required for authenticated calls. Pass it in BuildBase({ getSessionId: ... }) or use withSession(id) / client.forSession(id).");const e=await n();if(!e)throw new Error("BuildBase: Not authenticated (getSessionId returned null)");return e})()));return{auth:async()=>{if(!n)return null;const e=await n();return e?{sessionId:e}:null},withSession:e=>{const t=p(e);return m(async()=>t)},client:{forSession:p},...k}}exports.AuthStatus=void 0,(G=exports.AuthStatus||(exports.AuthStatus={})).loading="loading",G.redirecting="redirecting",G.authenticated="authenticated",G.unauthenticated="unauthenticated",G.authenticating="authenticating",exports.AuthApi=class extends p{constructor(e){super(e)}async requestAuth(e){const t=`${this.serverUrl}/api/${this.version}/auth/request`,s=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!s.ok){let e="Failed to initiate authentication";try{e=(await s.json()).message||e}catch{e=`Failed to initiate authentication (${s.status}: ${s.statusText})`}throw new Error(e)}return s.json()}async getProfile(e,t){return this.fetchJson("profile",{headers:{"x-session-id":e},signal:t},"Failed to fetch user profile")}},exports.BB_PARAM=E,exports.BaseApi=p,exports.BetaForm=class{constructor(e){this.api=new h(e),this.orgId=e.orgId}async fetchConfig(){return this.api.fetchConfig()}async submitBetaUser(e){const t=e?.context??{},s=t?.country??("undefined"!=typeof navigator&&navigator.language?navigator.language.split("-")[1]:void 0),r=t?.language??("undefined"!=typeof navigator&&navigator.language?navigator.language.split("-")[0]:void 0),n=t?.timezone??("undefined"!=typeof Intl&&Intl.DateTimeFormat?Intl.DateTimeFormat().resolvedOptions().timeZone:void 0),o=t?.currency??("undefined"!=typeof Intl&&Intl.NumberFormat&&Intl.NumberFormat().resolvedOptions().currency?Intl.NumberFormat().resolvedOptions().currency:void 0);return this.api.submitBetaUser({orgId:this.orgId,formData:{...e,country:s,language:r,timezone:n,currency:o}})}},exports.BillingIntervals=O,exports.BuildBase=H,exports.CURRENCY_DISPLAY=U,exports.CURRENCY_FLAG=R,exports.DEFAULT_ROLE_PERMISSIONS=q,exports.DunningState={None:"none",Notified:"notified",Warning:"warning",Final:"final",Suspended:"suspended"},exports.EventEmitter=k,exports.InvoiceStatuses={Draft:"draft",Open:"open",Paid:"paid",Uncollectible:"uncollectible",Void:"void"},exports.PLAN_CURRENCY_CODES=I,exports.PLAN_CURRENCY_OPTIONS=F,exports.PUSH_SERVICE_WORKER_SCRIPT="\n// BuildBase Push Notification Service Worker\n// Place this file in your app's public directory (e.g. public/push-sw.js)\n\nself.addEventListener('push', function(event) {\n if (!event.data) return;\n\n try {\n var payload = event.data.json();\n var title = payload.title || 'Notification';\n var options = {\n body: payload.body || '',\n icon: payload.icon || undefined,\n badge: payload.icon || undefined,\n data: { url: payload.url, ...(payload.data || {}) },\n tag: 'buildbase-push-' + Date.now(),\n };\n\n event.waitUntil(\n self.registration.showNotification(title, options)\n );\n } catch (e) {\n console.error('[PushSW] Failed to show notification:', e);\n }\n});\n\nself.addEventListener('notificationclick', function(event) {\n event.notification.close();\n\n var url = event.notification.data && event.notification.data.url;\n if (url) {\n event.waitUntil(\n clients.matchAll({ type: 'window', includeUncontrolled: true }).then(function(clientList) {\n for (var i = 0; i < clientList.length; i++) {\n var client = clientList[i];\n if (client.url === url && 'focus' in client) {\n return client.focus();\n }\n }\n if (clients.openWindow) {\n return clients.openWindow(url);\n }\n })\n );\n }\n});\n",exports.Permission=V,exports.PushApi=f,exports.SDKEvent=m,exports.SettingsApi=g,exports.SubscriptionItemType={Feature:"feature",Limit:"limit",Quota:"quota"},exports.SubscriptionStatus={Active:"active",Trialing:"trialing",Canceled:"canceled",PastDue:"past_due",Paused:"paused",Incomplete:"incomplete",Unpaid:"unpaid"},exports.UserApi=w,exports.WorkspaceApi=y,exports.calculateBillableSeats=B,exports.calculateSeatOverageCents=J,exports.calculateTotalSubscriptionCents=function(e,t,s,r){const n=T(e,t,s);return null===n?null:void 0===r?n:n+(J(e,t,s,r)??0)},exports.cleanBBParams=function(){if("undefined"!=typeof window)try{const e=new URL(window.location.href);e.searchParams.has(E)&&(e.searchParams.delete(E),window.history.replaceState({},"",e.toString()))}catch{}},exports.createBBUrl=$,exports.createCheckoutRedirectUrls=function(e,t){const s=t||("undefined"!=typeof window?window.location.href:void 0);return{successUrl:$({action:"checkout",status:"success",ws:e,screen:"subscription"},s),cancelUrl:$({action:"checkout",status:"cancel",ws:e,screen:"subscription"},s)}},exports.default=H,exports.eventEmitter=b,exports.formatCents=C,exports.formatOverageRate=function(e,t,s,r){if(null==e||e<0)return null;const n={..._,...r},o=null!=t&&t>=1?t:1,a=x(s),i=(e/100).toFixed(2);return 1===o?`${a}${i}/${n.unit}`:`${a}${i}/${o.toLocaleString()} ${n.units}`},exports.formatOverageRateWithLabel=function(e,t,s,r,n,o){if(null==e||e<0)return null;const a={..._,...o},i=null!=t&&t>=1?t:1,c=x(r),u=(e/100).toFixed(2);if(s){const e=n??(s.endsWith("s")?s:`${s}s`);return i>=2?`${c}${u}/${i.toLocaleString()} ${e}`:`${c}${u}/${s}`}return 1===i?`${c}${u}/${a.unit}`:`${c}${u}/${i.toLocaleString()} ${a.units}`},exports.formatQuotaIncludedOverage=function(e,t,s,r,n,o,a,i){const c={..._,...a};if(!1===i)return null!=e?`${c.included}: ${e.toLocaleString()} (${c.hardLimit??"hard limit"})`:c.hardLimit??"Hard limit";const u=o??(s.endsWith("s")?s:`${s}s`),l=null!=n&&n>=2?`${n.toLocaleString()} ${u}`:s;return null!=e&&null!=t?`${c.included}: ${e.toLocaleString()}, ${c.afterThat} ${C(t,r)}/${l}`:null!=e?`${c.included}: ${e.toLocaleString()}`:null!=t?`${c.afterIncluded}: ${C(t,r)}/${l}`:"—"},exports.formatQuotaWithPrice=function(e,t,s={}){const{overageInCents:r=!0,currency:n}=s,o=s.labels??W,a=s.currencySymbol??x(n??"");if(null==e)return"—";const{included:i,overage:c}=e,u=`${i} ${o.included}`;if(!1===e.allowOverage)return`${u} (hard limit)`;if(null==c)return u;const l=r?c/100:c,d="number"==typeof l&&Number.isFinite(l)?l.toFixed(2):String(c),p=t&&"unitSize"in e&&null!=e.unitSize&&e.unitSize>0?` / ${e.unitSize.toLocaleString()} ${t}`:t?` / ${t}`:"";return`${u}, ${o.then} ${a}${d}${p}`},exports.getAvailableCurrenciesFromPlans=function(e){const t=new Set;for(const s of e)s.pricingVariants?.forEach(e=>{e.currency&&t.add(e.currency.toLowerCase())});return Array.from(t).sort()},exports.getBasePriceCents=T,exports.getBillingIntervalAndCurrencyFromPriceId=function(e,t){if(!e)return null;for(const s of t){const t=s.pricingVariants;if(t?.length)for(const s of t){const t=s.stripePrices;if(t){if(t.monthlyPriceId===e||t.monthly===e)return{interval:"monthly",currency:s.currency};if(t.yearlyPriceId===e||t.yearly===e)return{interval:"yearly",currency:s.currency};if(t.quarterlyPriceId===e)return{interval:"quarterly",currency:s.currency}}}}return null},exports.getCurrencyFlag=function(e){return e&&e.trim()?R[e.trim().toLowerCase()]??"":""},exports.getCurrencySymbol=x,exports.getDisplayCurrency=function(e,t){const s=A(e,t);return s?s.currency:e.plan?.currency??""},exports.getPerSeatPriceCents=j,exports.getPricingVariant=A,exports.getQuotaDisplayValue=function(e,t){if(null==e)return null;const s=e[t??"monthly"];return s?{included:s.included,...void 0!==s.overage&&{overage:s.overage},...void 0!==s.unitSize&&{unitSize:s.unitSize},allowOverage:!1!==e.allowOverage}:null},exports.getQuotaDisplayWithVariant=function(e,t,s,r){const n=e.quotas?.[s];if(null==n)return null;const o=n[r];if(!o)return null;const a=N(e,t,s,r);return{included:o.included,...void 0!==o.unitSize&&{unitSize:o.unitSize},...void 0!==a&&{overage:a},allowOverage:!1!==n.allowOverage}},exports.getQuotaOverageCents=N,exports.getQuotaUnitLabelFromName=function(e,t="unit"){const s=(e||"").trim().toLowerCase();if(!s)return t;const r=s.split(/\s+/)[0]??s;return new Set(["series","species","status","analysis","basis","bus","campus","corpus","axis"]).has(r)?r:r.endsWith("ies")&&r.length>3?r.slice(0,-3)+"y":r.endsWith("ses")||r.endsWith("xes")||r.endsWith("zes")||r.endsWith("ches")||r.endsWith("shes")?r.slice(0,-2):r.endsWith("s")&&!r.endsWith("ss")&&r.length>1?r.slice(0,-1):r||t},exports.getSeatPricing=L,exports.getStripePriceIdForInterval=function(e,t,s){const r=A(e,t);if(!r?.stripePrices)return null;const n=s===O.Monthly?"monthlyPriceId":s===O.Yearly?"yearlyPriceId":"quarterlyPriceId",o=s===O.Monthly?"monthly":s===O.Yearly?"yearly":void 0;return r.stripePrices[n]??(o?r.stripePrices[o]:void 0)??null},exports.hasPermission=z,exports.invalidateQuotaUsage=function(){S.forEach(e=>e())},exports.invalidateSubscription=function(){v.forEach(e=>e())},exports.readBBParams=function(){if("undefined"==typeof window)return null;try{const e=new URLSearchParams(window.location.search).get(E);if(!e)return null;const t=function(e){const t={};if(!e)return t;const s=e.split(",");for(const e of s){const s=e.indexOf(":");if(-1===s)continue;const r=decodeURIComponent(e.slice(0,s)),n=decodeURIComponent(e.slice(s+1));r&&(t[r]=n)}return t}(e);return Object.keys(t).length>0?t:null}catch{return null}},exports.resolveMaxUsers=function(e){const{planVersion:t,currency:s="usd",settingsMaxUsers:r}=e;if(t){const e=L(t,s);if(e)return{maxUsers:e.maxSeats??0,source:"seat_pricing",includedSeats:e.includedSeats??0,hasSeatPricing:!0}}return null!=r&&r>0?{maxUsers:r,source:"settings",includedSeats:0,hasSeatPricing:!1}:{maxUsers:0,source:"none",includedSeats:0,hasSeatPricing:!1}},exports.resolvePermissions=D,exports.safeRedirect=function(e,t="/"){const s=P(e);window.location.href=s||t},exports.validateInvite=function(e){const{memberCount:t,maxUsersConfig:s,hasSubscription:r=!0,requireSubscription:n=!1}=e;if(n&&!r)return{canInvite:!1,blockReason:"no_subscription",blockMessageKey:"users.subscriptionRequired",blockMessageValues:{}};const{maxUsers:o,source:a}=s;if(o<=0)return{canInvite:!0,blockReason:null,blockMessageKey:null,blockMessageValues:null};if(t>=o){return{canInvite:!1,blockReason:{seat_pricing:"seat_limit_reached",settings:"settings_user_limit_reached"}[a]??"seat_limit_reached",blockMessageKey:{seat_pricing:"users.seatLimitMessage",settings:"users.settingsLimitMessage"}[a]??"users.memberLimitMessage",blockMessageValues:{maxUsers:o}}}return{canInvite:!0,blockReason:null,blockMessageKey:null,blockMessageValues:null}},exports.validateRedirectUrl=P;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- let e=!0;function t(t,...s){e&&function(){try{const e="undefined"!=typeof globalThis?globalThis:null;return"development"===e?.process?.env?.NODE_ENV}catch{return!1}}()&&console.error(t,...s)}async function s(e,t){try{const s=await e.json();return s?.message||s?.error||t}catch{return t}}async function r(e){const t=await e.text();if(!t)throw new Error("Empty response body");try{return JSON.parse(t)}catch(e){throw new Error(`Invalid JSON response: ${t.substring(0,100)}${t.length>100?"...":""}`)}}async function n(e,t="Request failed"){if(!e.ok){let s=t;try{const t=await r(e);s=t.message||t.error||s}catch{s=function(e,t){const s={400:"Bad Request",401:"Unauthorized - Please check your session",403:"Forbidden - You do not have permission",404:"Resource not found",500:"Internal server error",502:"Bad Gateway",503:"Service unavailable"}[e.status]||e.statusText||t;return new Error(`${t} (${e.status}: ${s})`)}(e,t).message}throw new Error(s)}try{return await r(e)}catch(e){if(e instanceof Error&&e.message.includes("Invalid JSON"))throw e;throw new Error("Failed to parse response as JSON")}}class o extends Error{constructor(e,t,s,r){super(e),this.code=t,this.context=s,this.originalError=r,this.name="SDKError","undefined"!=typeof Error&&"captureStackTrace"in Error&&Error.captureStackTrace(this,o)}}const a=new class{constructor(){this.config={enableConsoleLogging:!0,showUserNotifications:!1}}configure(t){this.config={...this.config,...t},void 0!==t.enableConsoleLogging&&function(t){void 0!==t.enableLogging&&(e=t.enableLogging)}({enableLogging:t.enableConsoleLogging})}handleError(e,s={}){if(function(e){return e instanceof Error&&("AbortError"===e.name||"ERR_CANCELED"===e.code)}(e))return;const r=e instanceof Error?e:new o("string"==typeof e?e:"An unknown error occurred","UNKNOWN_ERROR",s),n=r instanceof o?r:new o(r.message,"SDK_ERROR",s,r);if(this.config.enableConsoleLogging&&t(`[SDK Error] ${s.component||"Unknown"}:`,{message:n.message,code:n.code,context:n.context,originalError:n.originalError,stack:n.stack}),this.config.onError)try{this.config.onError(n,s)}catch(e){!function(e,...t){console.error(e,...t)}("[SDK Error Handler] Error in custom error callback:",e)}this.config.showUserNotifications&&this.notifyUser(n,s)}notifyUser(e,t){"undefined"!=typeof window&&window.dispatchEvent&&window.dispatchEvent(new CustomEvent("sdk-error",{detail:{error:e,context:t}}))}wrapAsync(e,t){return(...s)=>e(...s).catch(e=>{throw this.handleError(e,t),e})}wrapSync(e,t){return(...s)=>{try{return e(...s)}catch(e){throw this.handleError(e,t),e}}}};function i(e,t={}){a.handleError(e,t)}const c="saas-session-id";function u(){if("undefined"==typeof window)return null;try{return function(e){if("undefined"==typeof window)return null;try{return localStorage.getItem(e)}catch(t){return i(t,{component:"storage",action:"getStorageItem",metadata:{key:e}}),null}}(c)}catch(e){return i(e,{component:"auth-utils",action:"getSessionId",metadata:{key:c}}),null}}function l(){const e=u(),t={};return e&&(t["x-session-id"]=e),t}const d="SDK is not ready (missing serverUrl, version, or orgId)";class h{constructor(e){this.serverUrl=e.serverUrl,this.version=e.version,this.orgId=e.orgId,this.requireOrgId=e.requireOrgId??!1,this.basePath=e.basePath??"public",this._sessionId=e.sessionId,this._timeout=e.timeout??3e4,this._maxRetries=e.maxRetries??0,this._debug=e.debug??!1,this._customHeaders=e.headers??{},this._onError=e.onError,this._fetch=e.fetch??globalThis.fetch}ensureReady(){if(!this.serverUrl?.trim()||!this.version)throw new Error(d);if(this.requireOrgId&&!this.orgId?.trim())throw new Error(d)}get baseUrl(){return this.ensureReady(),`${this.serverUrl}/api/${this.version}/${this.basePath}`}getAuthHeaders(){return this._sessionId?{"x-session-id":this._sessionId}:l()}url(e){const t=e.startsWith("/")?e.slice(1):e;return`${this.baseUrl.endsWith("/")?this.baseUrl.slice(0,-1):this.baseUrl}/${t}`}buildHeaders(e){const t={...this._customHeaders,...this.getAuthHeaders()};return e.headers&&Object.assign(t,e.headers),null==e.body||t["Content-Type"]||(t["Content-Type"]="application/json"),t}async executeFetch(e,t){const s=this.url(e),r=(t.method??"GET").toUpperCase(),n=this.buildHeaders(t),o={...t,headers:n};let a;if(this._timeout>0){const e=new AbortController;a=setTimeout(()=>e.abort(),this._timeout),o.signal=t.signal?AbortSignal.any([t.signal,e.signal]):e.signal}const i=async t=>{try{const e=this._fetch.bind(globalThis),n=await e(s,o);if(this._debug&&console.log(`[BuildBase] ${r} ${s} → ${n.status}`),n.status>=500&&t<this._maxRetries){const e=Math.min(1e3*Math.pow(2,t),1e4);return this._debug&&console.log(`[BuildBase] Retrying in ${e}ms (attempt ${t+1}/${this._maxRetries})`),await new Promise(t=>setTimeout(t,e)),i(t+1)}return n}catch(s){if(s instanceof Error&&"AbortError"===s.name){if(void 0!==a){const t=new Error(`Request timeout after ${this._timeout}ms: ${r} ${e}`);throw this._onError?.(t,{method:r,path:e}),t}throw s}if(t<this._maxRetries){const e=Math.min(1e3*Math.pow(2,t),1e4);return this._debug&&console.log(`[BuildBase] Network error, retrying in ${e}ms (attempt ${t+1}/${this._maxRetries})`),await new Promise(t=>setTimeout(t,e)),i(t+1)}throw s instanceof Error&&this._onError?.(s,{method:r,path:e}),s}};try{return await i(0)}finally{void 0!==a&&clearTimeout(a)}}async fetchJson(e,t={},s="Request failed"){this.ensureReady();try{const r=await this.executeFetch(e,t);return await n(r,s)}catch(s){throw s instanceof Error&&this._onError?.(s,{method:(t.method??"GET").toUpperCase(),path:e}),s}}async fetchResponse(e,t={}){return this.ensureReady(),this.executeFetch(e,t)}}class p extends h{constructor(e){super(e)}async requestAuth(e){const t=`${this.serverUrl}/api/${this.version}/auth/request`,s=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!s.ok){let e="Failed to initiate authentication";try{e=(await s.json()).message||e}catch{e=`Failed to initiate authentication (${s.status}: ${s.statusText})`}throw new Error(e)}return s.json()}async getProfile(e,t){return this.fetchJson("profile",{headers:{"x-session-id":e},signal:t},"Failed to fetch user profile")}}class f extends h{constructor(e){super({...e,basePath:"beta",requireOrgId:!0})}getAuthHeaders(){return{}}async fetchConfig(){return this.fetchJson(`config?orgId=${encodeURIComponent(this.orgId)}`,{},"Failed to fetch beta form configuration")}async submitBetaUser(e){return this.fetchJson("submit",{method:"POST",body:JSON.stringify(e)},"Failed to submit beta user request")}}class g{constructor(e){this.api=new f(e),this.orgId=e.orgId}async fetchConfig(){return this.api.fetchConfig()}async submitBetaUser(e){const t=e?.context??{},s=t?.country??("undefined"!=typeof navigator&&navigator.language?navigator.language.split("-")[1]:void 0),r=t?.language??("undefined"!=typeof navigator&&navigator.language?navigator.language.split("-")[0]:void 0),n=t?.timezone??("undefined"!=typeof Intl&&Intl.DateTimeFormat?Intl.DateTimeFormat().resolvedOptions().timeZone:void 0),o=t?.currency??("undefined"!=typeof Intl&&Intl.NumberFormat&&Intl.NumberFormat().resolvedOptions().currency?Intl.NumberFormat().resolvedOptions().currency:void 0);return this.api.submitBetaUser({orgId:this.orgId,formData:{...e,country:s,language:r,timezone:n,currency:o}})}}class w extends h{constructor(e){super({...e,requireOrgId:!0})}async getVapidPublicKey(){return this.fetchJson("push/vapid-public-key")}async subscribe(e,t){await this.fetchJson("push/subscribe",{method:"POST",body:JSON.stringify({endpoint:e.endpoint,keys:e.keys,userAgent:t})})}async unsubscribe(e){await this.fetchJson("push/unsubscribe",{method:"DELETE",body:JSON.stringify({endpoint:e})})}}class y extends h{constructor(e){super({...e,requireOrgId:!0})}async getSettings(e){return this.fetchJson(`${this.orgId}/settings`,{signal:e},"Failed to fetch settings")}}class m extends h{constructor(e){super(e)}async getAttributes(e){const t=await this.fetchResponse("users/attributes",{signal:e});if(!t.ok)throw new Error(await s(t,"Failed to fetch user attributes"));const r=await t.json();return r&&"object"==typeof r&&!Array.isArray(r)?r:{}}async updateAttributes(e){return this.fetchJson("users/attributes",{method:"PATCH",body:JSON.stringify({attributes:e})},"Failed to update user attributes")}async updateAttribute(e,t){return this.fetchJson(`users/attributes/${e}`,{method:"PATCH",body:JSON.stringify({value:t})},"Failed to update user attribute")}async getFeatures(e){const t=await this.fetchResponse("users/features",{signal:e});if(!t.ok)throw new Error(await s(t,"Failed to fetch user features"));const r=await t.json();return"object"==typeof r&&null!==r?r:{}}}class k extends h{constructor(e){super({...e,requireOrgId:!0})}async getWorkspaces(){return this.fetchJson("workspaces",{},"Failed to fetch workspaces")}async createWorkspace(e){return this.fetchJson("workspaces",{method:"POST",body:JSON.stringify(e)},"Failed to create workspace")}async updateWorkspace(e,t){return this.fetchJson(`workspaces/${e}`,{method:"PUT",body:JSON.stringify(t)},"Failed to update workspace")}async deleteWorkspace(e){return this.fetchJson(`workspaces/${e}`,{method:"DELETE"},"Failed to delete workspace")}async getWorkspaceUsers(e){return this.fetchJson(`workspaces/${e}/users`,{},"Failed to fetch workspace users")}async addUser(e,t){return this.fetchJson(`workspaces/${e}/users/add`,{method:"POST",body:JSON.stringify(t)},"Failed to invite member")}async removeUser(e,t){return this.fetchJson(`workspaces/${e}/users/${t}`,{method:"DELETE"},"Failed to remove user")}async updateUser(e,t,s){return this.fetchJson(`workspaces/${e}/users/${t}`,{method:"PATCH",body:JSON.stringify(s)},"Failed to update user")}async updateSettings(e){return this.fetchJson("workspaces/settings",{method:"PATCH",body:JSON.stringify(e)},"Failed to update workspace settings")}async updateWorkspacePermissions(e,t){return this.fetchJson(`workspaces/${e}/permissions`,{method:"PATCH",body:JSON.stringify({permissions:t})},"Failed to update workspace permissions")}async getFeatures(){return this.fetchJson("workspaces/features",{},"Failed to fetch features")}async updateFeature(e,t,s){return this.fetchJson(`workspaces/${e}/features`,{method:"PATCH",body:JSON.stringify({features:{[t]:s}})},"Failed to update feature")}async getWorkspace(e){return this.fetchJson(`workspaces/${e}`,{},"Failed to fetch workspace")}async getProfile(){return this.fetchJson("profile",{},"Failed to fetch profile")}async updateUserProfile(e){return this.fetchJson("profile",{method:"PATCH",body:JSON.stringify(e)},"Failed to update user profile")}async getCurrentSubscription(e){const t=await this.fetchResponse(`workspaces/${e}/subscription`);if(!t.ok){let e="Failed to fetch subscription";try{e=(await t.json()).message||e}catch{e=404===t.status?"Workspace not found or no subscription available":401===t.status?"Unauthorized - Please check your session":`Failed to fetch subscription (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch subscription");return s.data||s}return s}async getPlanGroup(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/plan-group`);if(!t.ok){let e="Failed to fetch plan group";try{e=(await t.json()).message||e}catch{e=404===t.status?"No plan group found for this workspace":401===t.status?"Unauthorized - Please check your session":`Failed to fetch plan group (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch plan group");return s.data||s}return s}async getPlanGroupByVersion(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/plan-group?groupVersionId=${encodeURIComponent(t)}`);if(!s.ok){let e="Failed to fetch plan group version";try{e=(await s.json()).message||e}catch{e=404===s.status?"Plan group version not found":401===s.status?"Unauthorized - Please check your session":`Failed to fetch plan group version (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to fetch plan group version");return r.data||r}return r}async getPlanGroupVersions(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/plan-group/versions`);if(!t.ok){let e="Failed to fetch plan group versions";try{e=(await t.json()).message||e}catch{e=404===t.status?"No plan group versions found":401===t.status?"Unauthorized - Please check your session":`Failed to fetch plan group versions (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch plan group versions");return s.data||s}return s}async getPublicPlans(e){if(!this.orgId)throw new Error("orgId is required for getPublicPlans");const t=await this.fetchResponse(`${this.orgId}/plans/${encodeURIComponent(e)}`);if(!t.ok){let s="Failed to fetch plans";try{s=(await t.json()).message||s}catch{s=404===t.status?`Plans "${e}" not found`:`Failed to fetch plans (${t.status}: ${t.statusText})`}throw new Error(s)}const s=await t.json();if(void 0!==s.success&&!s.success)throw new Error(s.message||"Failed to fetch plans");return s.data??s}async getPlanGroupVersion(e){const t=await this.fetchResponse(`plan-group-versions/${e}`);if(!t.ok){let e="Failed to fetch plan group version";try{e=(await t.json()).message||e}catch{e=404===t.status?"Plan group version not found":401===t.status?"Unauthorized - Please check your session":`Failed to fetch plan group version (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch plan group version");return s.data||s}return s}async createCheckoutSession(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/checkout`,{method:"POST",body:JSON.stringify(t)});if(!s.ok){let e="Failed to create checkout session";try{e=(await s.json()).message||e}catch{e=`Failed to create checkout session (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to create checkout session");return r.data||r}return r}async updateSubscription(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription`,{method:"PATCH",body:JSON.stringify(t)});if(!s.ok){let e="Failed to update subscription";try{e=(await s.json()).message||e}catch{e=`Failed to update subscription (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to update subscription");return r.data?.checkoutUrl||r.checkoutUrl,r.data||r}return r.checkoutUrl,r}async createBillingPortalSession(e,t){return this.fetchJson(`workspaces/${e}/subscription/billing-portal`,{method:"POST",body:JSON.stringify(t?{returnUrl:t}:{})})}async listInvoices(e,t=10,s){const r=new URLSearchParams;r.append("limit",t.toString()),s&&r.append("starting_after",s);const n=await this.fetchResponse(`workspaces/${e}/subscription/invoices?${r.toString()}`,{});if(!n.ok){let e="Failed to fetch invoices";try{e=(await n.json()).message||e}catch{e=404===n.status?"Workspace not found or no invoices available":401===n.status?"Unauthorized - Please check your session":`Failed to fetch invoices (${n.status}: ${n.statusText})`}throw new Error(e)}const o=await n.json();if(void 0!==o.success){if(!o.success)throw new Error(o.message||"Failed to fetch invoices");return o}return o}async getInvoice(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/invoices/${t}`,{});if(!s.ok){let e="Failed to fetch invoice";try{e=(await s.json()).message||e}catch{e=404===s.status?"Invoice not found":401===s.status?"Unauthorized - Please check your session":`Failed to fetch invoice (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to fetch invoice");return r}return r}async cancelSubscriptionAtPeriodEnd(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/cancel-at-period-end`,{method:"POST"});if(!t.ok){let e="Failed to cancel subscription";try{e=(await t.json()).message||e}catch{e=404===t.status?"Subscription not found":401===t.status?"Unauthorized - Please check your session":`Failed to cancel subscription (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to cancel subscription");return s.data||s}return s}async resumeSubscription(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/resume`,{method:"POST"});if(!t.ok){let e="Failed to resume subscription";try{e=(await t.json()).message||e}catch{e=404===t.status?"Subscription not found":401===t.status?"Unauthorized - Please check your session":`Failed to resume subscription (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to resume subscription");return s.data||s}return s}async recordUsage(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/usage`,{method:"POST",body:JSON.stringify(t)});if(!s.ok){let e="Failed to record usage";try{e=(await s.json()).message||e}catch{e=`Failed to record usage (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to record usage");return r.data||r}return r}async recordUsageBatch(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/usage/batch`,{method:"POST",body:JSON.stringify(t)});if(!s.ok){let e="Failed to record batch usage";try{e=(await s.json()).message||e}catch{e=`Failed to record batch usage (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();return r.data||r}async getQuotaUsageStatus(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/usage/status?quotaSlug=${encodeURIComponent(t)}`);if(!s.ok){let e="Failed to fetch quota usage status";try{e=(await s.json()).message||e}catch{e=404===s.status?"Workspace not found or no subscription available":401===s.status?"Unauthorized - Please check your session":`Failed to fetch quota usage status (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to fetch quota usage status");return r.data||r}return r}async getAllQuotaUsage(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/usage/all`);if(!t.ok){let e="Failed to fetch all quota usage";try{e=(await t.json()).message||e}catch{e=404===t.status?"Workspace not found or no subscription available":401===t.status?"Unauthorized - Please check your session":`Failed to fetch all quota usage (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch all quota usage");return s.data||s}return s}async getUsageLogs(e,t){const s=new URLSearchParams;t?.quotaSlug&&s.append("quotaSlug",t.quotaSlug),t?.from&&s.append("from",t.from),t?.to&&s.append("to",t.to),t?.source&&s.append("source",t.source),t?.page&&s.append("page",t.page.toString()),t?.limit&&s.append("limit",t.limit.toString());const r=s.toString(),n=`workspaces/${e}/subscription/usage/logs${r?`?${r}`:""}`,o=await this.fetchResponse(n);if(!o.ok){let e="Failed to fetch usage logs";try{e=(await o.json()).message||e}catch{e=404===o.status?"Workspace not found":401===o.status?"Unauthorized - Please check your session":`Failed to fetch usage logs (${o.status}: ${o.statusText})`}throw new Error(e)}const a=await o.json();if(void 0!==a.success){if(!a.success)throw new Error(a.message||"Failed to fetch usage logs");return a.data||a}return a}async sendNotification(e,t,s,r){const n={event:t};return s&&(n.userId=s),r&&(n.data=r),this.fetchJson(`workspaces/${e}/notifications/send`,{method:"POST",body:JSON.stringify(n)},"Failed to send notification")}async getNotificationEvents(e){return this.fetchJson(`workspaces/${e}/notification-events`,{},"Failed to fetch notification events")}async getNotificationPreferences(e){return(await this.fetchJson(`workspaces/${e}/notification-preferences`,{},"Failed to fetch notification preferences")).notificationPreferences??{}}async updateNotificationPreferences(e,t){return(await this.fetchJson(`workspaces/${e}/notification-preferences`,{method:"PATCH",body:JSON.stringify({notificationPreferences:t})},"Failed to update notification preferences")).notificationPreferences??{}}}var b;!function(e){e.V1="v1"}(b||(b={}));const E={UserCreated:"user:created",UserUpdated:"user:updated",WorkspaceChanged:"workspace:changed",WorkspaceUpdated:"workspace:updated",WorkspaceUserAdded:"workspace:user-added",WorkspaceUserRemoved:"workspace:user-removed",WorkspaceUserRoleChanged:"workspace:user-role-changed",WorkspaceCreated:"workspace:created",WorkspaceDeleted:"workspace:deleted"};class v{constructor(){this.callbacks=null}setCallbacks(e){this.callbacks=e}getCallbacks(){return this.callbacks}async emit(e,t){if(this.callbacks?.handleEvent)try{await this.callbacks.handleEvent(e,t)}catch(t){i(t,{component:"EventEmitter",action:"emit",metadata:{eventType:e}})}}async emitUserCreated(e){await this.emit(E.UserCreated,{user:e})}async emitUserUpdated(e,t){await this.emit(E.UserUpdated,{user:e,previousUser:t})}async emitWorkspaceChanged(e,t){await this.emit(E.WorkspaceChanged,{workspace:e,previousWorkspace:t})}async emitWorkspaceUpdated(e){await this.emit(E.WorkspaceUpdated,{workspace:e})}async emitWorkspaceUserAdded(e,t,s){await this.emit(E.WorkspaceUserAdded,{userId:e,workspace:t,role:s})}async emitWorkspaceUserRemoved(e,t,s){await this.emit(E.WorkspaceUserRemoved,{userId:e,workspace:t,role:s})}async emitWorkspaceUserRoleChanged(e,t,s,r){await this.emit(E.WorkspaceUserRoleChanged,{userId:e,workspace:t,previousRole:s,newRole:r})}async emitWorkspaceCreated(e){await this.emit(E.WorkspaceCreated,{workspace:e})}async emitWorkspaceDeleted(e){await this.emit(E.WorkspaceDeleted,{workspace:e})}}const S=new v,$=new Set;function P(){$.forEach(e=>e())}const U=new Set;function I(){U.forEach(e=>e())}const R="bb";function F(e,t){let s;try{const e=t||("undefined"!=typeof window?window.location.href:"https://localhost");s=new URL(e),s.search=""}catch{s=new URL("https://localhost")}return s.searchParams.set(R,function(e){return Object.entries(e).filter(([,e])=>null!=e&&""!==e).map(([e,t])=>`${encodeURIComponent(e)}:${encodeURIComponent(t)}`).join(",")}(e)),s.toString()}function W(e,t){const s=t||("undefined"!=typeof window?window.location.href:void 0);return{successUrl:F({action:"checkout",status:"success",ws:e,screen:"subscription"},s),cancelUrl:F({action:"checkout",status:"cancel",ws:e,screen:"subscription"},s)}}function _(){if("undefined"==typeof window)return null;try{const e=new URLSearchParams(window.location.search).get(R);if(!e)return null;const t=function(e){const t={};if(!e)return t;const s=e.split(",");for(const e of s){const s=e.indexOf(":");if(-1===s)continue;const r=decodeURIComponent(e.slice(0,s)),n=decodeURIComponent(e.slice(s+1));r&&(t[r]=n)}return t}(e);return Object.keys(t).length>0?t:null}catch{return null}}function C(){if("undefined"!=typeof window)try{const e=new URL(window.location.href);e.searchParams.has(R)&&(e.searchParams.delete(R),window.history.replaceState({},"",e.toString()))}catch{}}function O(e){if(!e||"string"!=typeof e)return null;try{const t=new URL(e);return"https:"===t.protocol?e:"http:"!==t.protocol||"localhost"!==t.hostname&&"127.0.0.1"!==t.hostname&&"::1"!==t.hostname?null:e}catch{return null}}function T(e,t="/"){const s=O(e);window.location.href=s||t}const A={usd:"$",eur:"€",gbp:"£",jpy:"¥",cad:"CA$",aud:"A$",chf:"CHF",cny:"¥",hkd:"HK$",sgd:"S$",inr:"₹",mxn:"MX$",brl:"R$",nzd:"NZ$",sek:"kr",nok:"kr",dkk:"kr",pln:"zł",thb:"฿"},x={usd:"🇺🇸",eur:"🇪🇺",gbp:"🇬🇧",jpy:"🇯🇵",cad:"🇨🇦",aud:"🇦🇺",chf:"🇨🇭",cny:"🇨🇳",hkd:"🇭🇰",sgd:"🇸🇬",inr:"🇮🇳",mxn:"🇲🇽",brl:"🇧🇷",nzd:"🇳🇿",sek:"🇸🇪",nok:"🇳🇴",dkk:"🇩🇰",pln:"🇵🇱",thb:"🇹🇭"};function N(e){return e&&e.trim()?x[e.trim().toLowerCase()]??"":""}function j(e){if(!e||!e.trim())return"";const t=e.trim().toLowerCase();return A[t]??t.toUpperCase()}const J=["usd","eur","gbp","jpy","cad","aud","chf","cny","hkd","sgd","inr","mxn","brl","nzd","sek","nok","dkk","pln","thb"],L=J.map(e=>({value:e,label:`${e.toUpperCase()} (${j(e)})`}));function B(e,t){return j(t)+(e/100).toFixed(2)}const M={unit:"unit",units:"units",included:"Included",afterThat:"after that",afterIncluded:"After included"};function q(e,t,s,r){if(null==e||e<0)return null;const n={...M,...r},o=null!=t&&t>=1?t:1,a=j(s),i=(e/100).toFixed(2);return 1===o?`${a}${i}/${n.unit}`:`${a}${i}/${o.toLocaleString()} ${n.units}`}function V(e,t,s,r,n,o){if(null==e||e<0)return null;const a={...M,...o},i=null!=t&&t>=1?t:1,c=j(r),u=(e/100).toFixed(2);if(s){const e=n??(s.endsWith("s")?s:`${s}s`);return i>=2?`${c}${u}/${i.toLocaleString()} ${e}`:`${c}${u}/${s}`}return 1===i?`${c}${u}/${a.unit}`:`${c}${u}/${i.toLocaleString()} ${a.units}`}function K(e,t="unit"){const s=(e||"").trim().toLowerCase();if(!s)return t;const r=s.split(/\s+/)[0]??s;return new Set(["series","species","status","analysis","basis","bus","campus","corpus","axis"]).has(r)?r:r.endsWith("ies")&&r.length>3?r.slice(0,-3)+"y":r.endsWith("ses")||r.endsWith("xes")||r.endsWith("zes")||r.endsWith("ches")||r.endsWith("shes")?r.slice(0,-2):r.endsWith("s")&&!r.endsWith("ss")&&r.length>1?r.slice(0,-1):r||t}function z(e,t,s,r,n,o,a){const i={...M,...a},c=o??(s.endsWith("s")?s:`${s}s`),u=null!=n&&n>=2?`${n.toLocaleString()} ${c}`:s;return null!=e&&null!=t?`${i.included}: ${e.toLocaleString()}, ${i.afterThat} ${B(t,r)}/${u}`:null!=e?`${i.included}: ${e.toLocaleString()}`:null!=t?`${i.afterIncluded}: ${B(t,r)}/${u}`:"—"}function D(e,t){if(null==e)return null;const s=e[t??"monthly"];return s?{included:s.included,...void 0!==s.overage&&{overage:s.overage},...void 0!==s.unitSize&&{unitSize:s.unitSize}}:null}const G={included:"included",then:"then"};function H(e,t,s={}){const{overageInCents:r=!0,currency:n}=s,o=s.labels??G,a=s.currencySymbol??j(n??"");if(null==e)return"—";const{included:i,overage:c}=e,u=`${i} ${o.included}`;if(null==c)return u;const l=r?c/100:c,d="number"==typeof l&&Number.isFinite(l)?l.toFixed(2):String(c),h=t&&"unitSize"in e&&null!=e.unitSize&&e.unitSize>0?` / ${e.unitSize.toLocaleString()} ${t}`:t?` / ${t}`:"";return`${u}, ${o.then} ${a}${d}${h}`}const Q={Monthly:"monthly",Yearly:"yearly",Quarterly:"quarterly"},Y={Active:"active",Trialing:"trialing",Canceled:"canceled",PastDue:"past_due",Paused:"paused",Incomplete:"incomplete",Unpaid:"unpaid"},Z={Draft:"draft",Open:"open",Paid:"paid",Uncollectible:"uncollectible",Void:"void"},X={Feature:"feature",Limit:"limit",Quota:"quota"},ee={None:"none",Notified:"notified",Warning:"warning",Final:"final",Suspended:"suspended"};function te(e,t){const s=e.pricingVariants;if(!s?.length)return null;const r=t.toLowerCase();return s.find(e=>e.currency?.toLowerCase()===r)??null}function se(e,t,s){const r=te(e,t);if(!r?.basePricing)return null;const n=r.basePricing[s];return null!=n?n:null}function re(e,t,s){const r=te(e,t);if(!r?.stripePrices)return null;const n=s===Q.Monthly?"monthlyPriceId":s===Q.Yearly?"yearlyPriceId":"quarterlyPriceId",o=s===Q.Monthly?"monthly":s===Q.Yearly?"yearly":void 0;return r.stripePrices[n]??(o?r.stripePrices[o]:void 0)??null}function ne(e,t,s,r){const n=te(e,t),o=n?.quotaOverages?.[s];if(o)return o[r]}function oe(e,t){const s=te(e,t);return s?s.currency:e.plan?.currency??""}function ae(e){const t=new Set;for(const s of e)s.pricingVariants?.forEach(e=>{e.currency&&t.add(e.currency.toLowerCase())});return Array.from(t).sort()}function ie(e,t,s,r){const n=e.quotas?.[s];if(null==n)return null;const o=n[r];if(!o)return null;const a=ne(e,t,s,r);return{included:o.included,...void 0!==o.unitSize&&{unitSize:o.unitSize},...void 0!==a&&{overage:a}}}function ce(e,t){if(!e)return null;for(const s of t){const t=s.pricingVariants;if(t?.length)for(const s of t){const t=s.stripePrices;if(t){if(t.monthlyPriceId===e||t.monthly===e)return{interval:"monthly",currency:s.currency};if(t.yearlyPriceId===e||t.yearly===e)return{interval:"yearly",currency:s.currency};if(t.quarterlyPriceId===e)return{interval:"quarterly",currency:s.currency}}}}return null}function ue(e,t){const s=te(e,t);return s?.seatPricing?.enabled?s.seatPricing:null}function le(e,t,s){const r=ue(e,t);return r?.perSeat?r.perSeat[s]??null:null}function de(e,t){return Math.max(0,e-(t||0))}function he(e,t,s,r){const n=ue(e,t);if(!n)return null;return de(r,n.includedSeats)*(le(e,t,s)??0)}function pe(e,t,s,r){const n=se(e,t,s);if(null===n)return null;if(void 0===r)return n;return n+(he(e,t,s,r)??0)}function fe(e){const{planVersion:t,currency:s="usd",settingsMaxUsers:r}=e;if(t){const e=ue(t,s);if(e)return{maxUsers:e.maxSeats??0,source:"seat_pricing",includedSeats:e.includedSeats??0,hasSeatPricing:!0}}return null!=r&&r>0?{maxUsers:r,source:"settings",includedSeats:0,hasSeatPricing:!1}:{maxUsers:0,source:"none",includedSeats:0,hasSeatPricing:!1}}function ge(e){const{memberCount:t,maxUsersConfig:s,hasSubscription:r=!0,requireSubscription:n=!1}=e;if(n&&!r)return{canInvite:!1,blockReason:"no_subscription",blockMessageKey:"users.subscriptionRequired",blockMessageValues:{}};const{maxUsers:o,source:a}=s;if(o<=0)return{canInvite:!0,blockReason:null,blockMessageKey:null,blockMessageValues:null};if(t>=o){return{canInvite:!1,blockReason:{seat_pricing:"seat_limit_reached",settings:"settings_user_limit_reached"}[a]??"seat_limit_reached",blockMessageKey:{seat_pricing:"users.seatLimitMessage",settings:"users.settingsLimitMessage"}[a]??"users.memberLimitMessage",blockMessageValues:{maxUsers:o}}}return{canInvite:!0,blockReason:null,blockMessageKey:null,blockMessageValues:null}}const we={WORKSPACE_SETTINGS_VIEW:"workspace:settings:view",WORKSPACE_SETTINGS_EDIT:"workspace:settings:edit",WORKSPACE_DELETE:"workspace:delete",WORKSPACE_MEMBERS_VIEW:"workspace:members:view",WORKSPACE_MEMBERS_INVITE:"workspace:members:invite",WORKSPACE_MEMBERS_REMOVE:"workspace:members:remove",WORKSPACE_MEMBERS_ROLE_CHANGE:"workspace:members:role-change",WORKSPACE_FEATURES_VIEW:"workspace:features:view",WORKSPACE_FEATURES_EDIT:"workspace:features:edit",WORKSPACE_BILLING_VIEW:"workspace:billing:view",WORKSPACE_BILLING_MANAGE:"workspace:billing:manage",WORKSPACE_USAGE_VIEW:"workspace:usage:view"},ye=Object.values(we),me={admin:ye.filter(e=>e!==we.WORKSPACE_DELETE),member:[we.WORKSPACE_SETTINGS_VIEW,we.WORKSPACE_MEMBERS_VIEW,we.WORKSPACE_FEATURES_VIEW,we.WORKSPACE_BILLING_VIEW,we.WORKSPACE_USAGE_VIEW],viewer:[we.WORKSPACE_SETTINGS_VIEW,we.WORKSPACE_MEMBERS_VIEW]};function ke(e){const t=new Set;for(const s of Object.values(e))for(const e of s)t.add(e);return Array.from(t)}function be(e){const{userId:t,workspace:s,settings:r,appPermissions:n}=e;if(!s||!t)return new Set;if(function(e,t){if(!t)return!1;const s=(r=e.createdBy)?"string"==typeof r?r:"object"==typeof r&&"_id"in r&&"string"==typeof r._id?r._id:null:null;var r;return null!==s&&s===t}(s,t)){const e=new Set(ye);if(n)for(const t of ke(n))e.add(t);if(s.permissions)for(const t of ke(s.permissions))e.add(t);if(r?.workspace?.permissions)for(const t of ke(r.workspace.permissions))e.add(t);return e}const o=e.workspaceRole??function(e,t){if(!t||!e.users||!Array.isArray(e.users))return null;const s=e.users.find(e=>"string"==typeof e?e===t:"object"==typeof e&&null!==e&&"_id"in e&&e._id===t);return s&&"object"==typeof s&&"role"in s&&"string"==typeof s.role?s.role:null}(s,t);if(!o)return new Set;const a=s.permissions,i=r?.workspace?.permissions,c=e=>e.filter(e=>e.startsWith("workspace:")),u=e=>e.filter(e=>!e.startsWith("workspace:")),l=a?.[o]?c(a[o]):[],d=i?.[o]?c(i[o]):[],h=me[o]??[];let p;if(l.length>0)p=l;else if(d.length>0)p=d;else if(h.length>0)p=h;else{p=me[r?.workspace?.defaultRole??"member"]??me.member??[]}const f=new Set(p),g=a?.[o]?u(a[o]):[],w=n?.[o]?u(n[o]):[],y=g.length>0?g:w;for(const e of y)f.add(e);return function(e,t,s){if(!s?.workspace)return;const{canInviteMembers:r}=s.workspace;(!1===r||"admin-only"===r&&"admin"!==t)&&e.delete(we.WORKSPACE_MEMBERS_INVITE)}(f,o,r),f}function Ee(e,t){const s=be(t);return Array.isArray(e)?e.every(e=>s.has(e)):s.has(e)}const ve="\n// BuildBase Push Notification Service Worker\n// Place this file in your app's public directory (e.g. public/push-sw.js)\n\nself.addEventListener('push', function(event) {\n if (!event.data) return;\n\n try {\n var payload = event.data.json();\n var title = payload.title || 'Notification';\n var options = {\n body: payload.body || '',\n icon: payload.icon || undefined,\n badge: payload.icon || undefined,\n data: { url: payload.url, ...(payload.data || {}) },\n tag: 'buildbase-push-' + Date.now(),\n };\n\n event.waitUntil(\n self.registration.showNotification(title, options)\n );\n } catch (e) {\n console.error('[PushSW] Failed to show notification:', e);\n }\n});\n\nself.addEventListener('notificationclick', function(event) {\n event.notification.close();\n\n var url = event.notification.data && event.notification.data.url;\n if (url) {\n event.waitUntil(\n clients.matchAll({ type: 'window', includeUncontrolled: true }).then(function(clientList) {\n for (var i = 0; i < clientList.length; i++) {\n var client = clientList[i];\n if (client.url === url && 'focus' in client) {\n return client.focus();\n }\n }\n if (clients.openWindow) {\n return clients.openWindow(url);\n }\n })\n );\n }\n});\n";var Se;function $e(e){const{serverUrl:t,orgId:s,version:r="v1",getSessionId:n,timeout:o,maxRetries:a,debug:i,headers:c,onError:u,fetch:l}=e;if(!t)throw new Error("BuildBase: serverUrl is required");if(!s)throw new Error("BuildBase: orgId is required");const d={...void 0!==o&&{timeout:o},...void 0!==a&&{maxRetries:a},...void 0!==i&&{debug:i},...c&&{headers:c},...u&&{onError:u},...l&&{fetch:l}},h=e=>{const n={serverUrl:t,version:r,orgId:s,sessionId:e,...d};return{workspace:new k(n),user:new m(n),settings:new y(n),push:new w(n)}},p=new k({serverUrl:t,version:r,orgId:s,...d}),f=e=>({workspace:{list:async()=>(await e()).workspace.getWorkspaces(),get:async t=>(await e()).workspace.getWorkspace(t),create:async t=>(await e()).workspace.createWorkspace(t),update:async(t,s)=>(await e()).workspace.updateWorkspace(t,s),delete:async t=>(await e()).workspace.deleteWorkspace(t)},users:{list:async t=>(await e()).workspace.getWorkspaceUsers(t),invite:async(t,s,r)=>(await e()).workspace.addUser(t,{email:s,role:r}),remove:async(t,s)=>(await e()).workspace.removeUser(t,s),updateRole:async(t,s,r)=>(await e()).workspace.updateUser(t,s,{role:r}),getProfile:async()=>(await e()).workspace.getProfile(),updateProfile:async t=>(await e()).workspace.updateUserProfile(t)},subscription:{get:async t=>(await e()).workspace.getCurrentSubscription(t),checkout:async(t,s)=>(await e()).workspace.createCheckoutSession(t,s),update:async(t,s)=>(await e()).workspace.updateSubscription(t,s),cancel:async t=>(await e()).workspace.cancelSubscriptionAtPeriodEnd(t),resume:async t=>(await e()).workspace.resumeSubscription(t),getBillingPortalUrl:async(t,s)=>(await e()).workspace.createBillingPortalSession(t,s)},plans:{getGroup:async t=>(await e()).workspace.getPlanGroup(t),getVersions:async t=>(await e()).workspace.getPlanGroupVersions(t),getPublic:e=>p.getPublicPlans(e),getVersion:e=>p.getPlanGroupVersion(e)},invoices:{list:async(t,s,r)=>(await e()).workspace.listInvoices(t,s,r),get:async(t,s)=>(await e()).workspace.getInvoice(t,s)},usage:{record:async(t,s)=>(await e()).workspace.recordUsage(t,s),recordBatch:async(t,s)=>(await e()).workspace.recordUsageBatch(t,s),getQuota:async(t,s)=>(await e()).workspace.getQuotaUsageStatus(t,s),getAll:async t=>(await e()).workspace.getAllQuotaUsage(t),getLogs:async(t,s)=>(await e()).workspace.getUsageLogs(t,s)},settings:{get:async()=>(await e()).settings.getSettings()},features:{list:async()=>(await e()).workspace.getFeatures(),update:async(t,s,r)=>(await e()).workspace.updateFeature(t,s,r)},notification:{send:async(t,s,r,n)=>(await e()).workspace.sendNotification(t,s,r,n)},permissions:{check:async(t,s,r)=>{const n=await e(),[o,a,i]=await Promise.all([n.workspace.getWorkspace(t),n.settings.getSettings(),n.workspace.getWorkspaceUsers(t)]),c=i.find(e=>("string"==typeof e.user?e.user:e.user._id)===s);return Ee(r,{userId:s,workspaceRole:c?.role??null,workspace:o,settings:a})},resolve:async(t,s)=>{const r=await e(),[n,o,a]=await Promise.all([r.workspace.getWorkspace(t),r.settings.getSettings(),r.workspace.getWorkspaceUsers(t)]),i=a.find(e=>("string"==typeof e.user?e.user:e.user._id)===s);return be({userId:s,workspaceRole:i?.role??null,workspace:n,settings:o})}}}),g=f(async()=>h(await(async()=>{if(!n)throw new Error("BuildBase: getSessionId callback is required for authenticated calls. Pass it in BuildBase({ getSessionId: ... }) or use withSession(id) / client.forSession(id).");const e=await n();if(!e)throw new Error("BuildBase: Not authenticated (getSessionId returned null)");return e})()));return{auth:async()=>{if(!n)return null;const e=await n();return e?{sessionId:e}:null},withSession:e=>{const t=h(e);return f(async()=>t)},client:{forSession:h},...g}}!function(e){e.loading="loading",e.redirecting="redirecting",e.authenticated="authenticated",e.unauthenticated="unauthenticated",e.authenticating="authenticating"}(Se||(Se={}));export{b as ApiVersion,p as AuthApi,Se as AuthStatus,R as BB_PARAM,h as BaseApi,g as BetaForm,Q as BillingIntervals,$e as BuildBase,A as CURRENCY_DISPLAY,x as CURRENCY_FLAG,me as DEFAULT_ROLE_PERMISSIONS,ee as DunningState,v as EventEmitter,Z as InvoiceStatuses,J as PLAN_CURRENCY_CODES,L as PLAN_CURRENCY_OPTIONS,ve as PUSH_SERVICE_WORKER_SCRIPT,we as Permission,w as PushApi,E as SDKEvent,y as SettingsApi,X as SubscriptionItemType,Y as SubscriptionStatus,m as UserApi,k as WorkspaceApi,de as calculateBillableSeats,he as calculateSeatOverageCents,pe as calculateTotalSubscriptionCents,C as cleanBBParams,F as createBBUrl,W as createCheckoutRedirectUrls,$e as default,S as eventEmitter,B as formatCents,q as formatOverageRate,V as formatOverageRateWithLabel,z as formatQuotaIncludedOverage,H as formatQuotaWithPrice,ae as getAvailableCurrenciesFromPlans,se as getBasePriceCents,ce as getBillingIntervalAndCurrencyFromPriceId,N as getCurrencyFlag,j as getCurrencySymbol,oe as getDisplayCurrency,le as getPerSeatPriceCents,te as getPricingVariant,D as getQuotaDisplayValue,ie as getQuotaDisplayWithVariant,ne as getQuotaOverageCents,K as getQuotaUnitLabelFromName,ue as getSeatPricing,re as getStripePriceIdForInterval,Ee as hasPermission,I as invalidateQuotaUsage,P as invalidateSubscription,_ as readBBParams,fe as resolveMaxUsers,be as resolvePermissions,T as safeRedirect,ge as validateInvite,O as validateRedirectUrl};
1
+ let e=!0;function t(t,...s){e&&function(){try{const e="undefined"!=typeof globalThis?globalThis:null;return"development"===e?.process?.env?.NODE_ENV}catch{return!1}}()&&console.error(t,...s)}async function s(e,t){try{const s=await e.json();return s?.message||s?.error||t}catch{return t}}async function r(e){const t=await e.text();if(!t)throw new Error("Empty response body");try{return JSON.parse(t)}catch(e){throw new Error(`Invalid JSON response: ${t.substring(0,100)}${t.length>100?"...":""}`)}}async function n(e,t="Request failed"){if(!e.ok){let s=t;try{const t=await r(e);s=t.message||t.error||s}catch{s=function(e,t){const s={400:"Bad Request",401:"Unauthorized - Please check your session",403:"Forbidden - You do not have permission",404:"Resource not found",500:"Internal server error",502:"Bad Gateway",503:"Service unavailable"}[e.status]||e.statusText||t;return new Error(`${t} (${e.status}: ${s})`)}(e,t).message}throw new Error(s)}try{return await r(e)}catch(e){if(e instanceof Error&&e.message.includes("Invalid JSON"))throw e;throw new Error("Failed to parse response as JSON")}}class o extends Error{constructor(e,t,s,r){super(e),this.code=t,this.context=s,this.originalError=r,this.name="SDKError","undefined"!=typeof Error&&"captureStackTrace"in Error&&Error.captureStackTrace(this,o)}}const a=new class{constructor(){this.config={enableConsoleLogging:!0,showUserNotifications:!1}}configure(t){this.config={...this.config,...t},void 0!==t.enableConsoleLogging&&function(t){void 0!==t.enableLogging&&(e=t.enableLogging)}({enableLogging:t.enableConsoleLogging})}handleError(e,s={}){if(function(e){return e instanceof Error&&("AbortError"===e.name||"ERR_CANCELED"===e.code)}(e))return;const r=e instanceof Error?e:new o("string"==typeof e?e:"An unknown error occurred","UNKNOWN_ERROR",s),n=r instanceof o?r:new o(r.message,"SDK_ERROR",s,r);if(this.config.enableConsoleLogging&&t(`[SDK Error] ${s.component||"Unknown"}:`,{message:n.message,code:n.code,context:n.context,originalError:n.originalError,stack:n.stack}),this.config.onError)try{this.config.onError(n,s)}catch(e){!function(e,...t){console.error(e,...t)}("[SDK Error Handler] Error in custom error callback:",e)}this.config.showUserNotifications&&this.notifyUser(n,s)}notifyUser(e,t){"undefined"!=typeof window&&window.dispatchEvent&&window.dispatchEvent(new CustomEvent("sdk-error",{detail:{error:e,context:t}}))}wrapAsync(e,t){return(...s)=>e(...s).catch(e=>{throw this.handleError(e,t),e})}wrapSync(e,t){return(...s)=>{try{return e(...s)}catch(e){throw this.handleError(e,t),e}}}};function i(e,t={}){a.handleError(e,t)}const c="saas-session-id";function u(){if("undefined"==typeof window)return null;try{return function(e){if("undefined"==typeof window)return null;try{return localStorage.getItem(e)}catch(t){return i(t,{component:"storage",action:"getStorageItem",metadata:{key:e}}),null}}(c)}catch(e){return i(e,{component:"auth-utils",action:"getSessionId",metadata:{key:c}}),null}}function l(){const e=u(),t={};return e&&(t["x-session-id"]=e),t}const d="SDK is not ready (missing serverUrl, version, or orgId)";class h{constructor(e){this.serverUrl=e.serverUrl,this.version=e.version,this.orgId=e.orgId,this.requireOrgId=e.requireOrgId??!1,this.basePath=e.basePath??"public",this._sessionId=e.sessionId,this._timeout=e.timeout??3e4,this._maxRetries=e.maxRetries??0,this._debug=e.debug??!1,this._customHeaders=e.headers??{},this._onError=e.onError,this._fetch=e.fetch??globalThis.fetch}ensureReady(){if(!this.serverUrl?.trim()||!this.version)throw new Error(d);if(this.requireOrgId&&!this.orgId?.trim())throw new Error(d)}get baseUrl(){return this.ensureReady(),`${this.serverUrl}/api/${this.version}/${this.basePath}`}getAuthHeaders(){return this._sessionId?{"x-session-id":this._sessionId}:l()}url(e){const t=e.startsWith("/")?e.slice(1):e;return`${this.baseUrl.endsWith("/")?this.baseUrl.slice(0,-1):this.baseUrl}/${t}`}buildHeaders(e){const t={...this._customHeaders,...this.getAuthHeaders()};return e.headers&&Object.assign(t,e.headers),null==e.body||t["Content-Type"]||(t["Content-Type"]="application/json"),t}async executeFetch(e,t){const s=this.url(e),r=(t.method??"GET").toUpperCase(),n=this.buildHeaders(t),o={...t,headers:n};let a;if(this._timeout>0){const e=new AbortController;a=setTimeout(()=>e.abort(),this._timeout),o.signal=t.signal?AbortSignal.any([t.signal,e.signal]):e.signal}const i=async t=>{try{const e=this._fetch.bind(globalThis),n=await e(s,o);if(this._debug&&console.log(`[BuildBase] ${r} ${s} → ${n.status}`),n.status>=500&&t<this._maxRetries){const e=Math.min(1e3*Math.pow(2,t),1e4);return this._debug&&console.log(`[BuildBase] Retrying in ${e}ms (attempt ${t+1}/${this._maxRetries})`),await new Promise(t=>setTimeout(t,e)),i(t+1)}return n}catch(s){if(s instanceof Error&&"AbortError"===s.name){if(void 0!==a){const t=new Error(`Request timeout after ${this._timeout}ms: ${r} ${e}`);throw this._onError?.(t,{method:r,path:e}),t}throw s}if(t<this._maxRetries){const e=Math.min(1e3*Math.pow(2,t),1e4);return this._debug&&console.log(`[BuildBase] Network error, retrying in ${e}ms (attempt ${t+1}/${this._maxRetries})`),await new Promise(t=>setTimeout(t,e)),i(t+1)}throw s instanceof Error&&this._onError?.(s,{method:r,path:e}),s}};try{return await i(0)}finally{void 0!==a&&clearTimeout(a)}}async fetchJson(e,t={},s="Request failed"){this.ensureReady();try{const r=await this.executeFetch(e,t);return await n(r,s)}catch(s){throw s instanceof Error&&this._onError?.(s,{method:(t.method??"GET").toUpperCase(),path:e}),s}}async fetchResponse(e,t={}){return this.ensureReady(),this.executeFetch(e,t)}}class p extends h{constructor(e){super(e)}async requestAuth(e){const t=`${this.serverUrl}/api/${this.version}/auth/request`,s=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!s.ok){let e="Failed to initiate authentication";try{e=(await s.json()).message||e}catch{e=`Failed to initiate authentication (${s.status}: ${s.statusText})`}throw new Error(e)}return s.json()}async getProfile(e,t){return this.fetchJson("profile",{headers:{"x-session-id":e},signal:t},"Failed to fetch user profile")}}class f extends h{constructor(e){super({...e,basePath:"beta",requireOrgId:!0})}getAuthHeaders(){return{}}async fetchConfig(){return this.fetchJson(`config?orgId=${encodeURIComponent(this.orgId)}`,{},"Failed to fetch beta form configuration")}async submitBetaUser(e){return this.fetchJson("submit",{method:"POST",body:JSON.stringify(e)},"Failed to submit beta user request")}}class w{constructor(e){this.api=new f(e),this.orgId=e.orgId}async fetchConfig(){return this.api.fetchConfig()}async submitBetaUser(e){const t=e?.context??{},s=t?.country??("undefined"!=typeof navigator&&navigator.language?navigator.language.split("-")[1]:void 0),r=t?.language??("undefined"!=typeof navigator&&navigator.language?navigator.language.split("-")[0]:void 0),n=t?.timezone??("undefined"!=typeof Intl&&Intl.DateTimeFormat?Intl.DateTimeFormat().resolvedOptions().timeZone:void 0),o=t?.currency??("undefined"!=typeof Intl&&Intl.NumberFormat&&Intl.NumberFormat().resolvedOptions().currency?Intl.NumberFormat().resolvedOptions().currency:void 0);return this.api.submitBetaUser({orgId:this.orgId,formData:{...e,country:s,language:r,timezone:n,currency:o}})}}class g extends h{constructor(e){super({...e,requireOrgId:!0})}async getVapidPublicKey(){return this.fetchJson("push/vapid-public-key")}async subscribe(e,t){await this.fetchJson("push/subscribe",{method:"POST",body:JSON.stringify({endpoint:e.endpoint,keys:e.keys,userAgent:t})})}async unsubscribe(e){await this.fetchJson("push/unsubscribe",{method:"DELETE",body:JSON.stringify({endpoint:e})})}}class y extends h{constructor(e){super({...e,requireOrgId:!0})}async getSettings(e){return this.fetchJson(`${this.orgId}/settings`,{signal:e},"Failed to fetch settings")}}class m extends h{constructor(e){super(e)}async getAttributes(e){const t=await this.fetchResponse("users/attributes",{signal:e});if(!t.ok)throw new Error(await s(t,"Failed to fetch user attributes"));const r=await t.json();return r&&"object"==typeof r&&!Array.isArray(r)?r:{}}async updateAttributes(e){return this.fetchJson("users/attributes",{method:"PATCH",body:JSON.stringify({attributes:e})},"Failed to update user attributes")}async updateAttribute(e,t){return this.fetchJson(`users/attributes/${e}`,{method:"PATCH",body:JSON.stringify({value:t})},"Failed to update user attribute")}async getFeatures(e){const t=await this.fetchResponse("users/features",{signal:e});if(!t.ok)throw new Error(await s(t,"Failed to fetch user features"));const r=await t.json();return"object"==typeof r&&null!==r?r:{}}}class k extends h{constructor(e){super({...e,requireOrgId:!0})}async getWorkspaces(){return this.fetchJson("workspaces",{},"Failed to fetch workspaces")}async createWorkspace(e){return this.fetchJson("workspaces",{method:"POST",body:JSON.stringify(e)},"Failed to create workspace")}async updateWorkspace(e,t){return this.fetchJson(`workspaces/${e}`,{method:"PUT",body:JSON.stringify(t)},"Failed to update workspace")}async deleteWorkspace(e){return this.fetchJson(`workspaces/${e}`,{method:"DELETE"},"Failed to delete workspace")}async getWorkspaceUsers(e){return this.fetchJson(`workspaces/${e}/users`,{},"Failed to fetch workspace users")}async addUser(e,t){return this.fetchJson(`workspaces/${e}/users/add`,{method:"POST",body:JSON.stringify(t)},"Failed to invite member")}async removeUser(e,t){return this.fetchJson(`workspaces/${e}/users/${t}`,{method:"DELETE"},"Failed to remove user")}async updateUser(e,t,s){return this.fetchJson(`workspaces/${e}/users/${t}`,{method:"PATCH",body:JSON.stringify(s)},"Failed to update user")}async updateSettings(e){return this.fetchJson("workspaces/settings",{method:"PATCH",body:JSON.stringify(e)},"Failed to update workspace settings")}async updateWorkspacePermissions(e,t){return this.fetchJson(`workspaces/${e}/permissions`,{method:"PATCH",body:JSON.stringify({permissions:t})},"Failed to update workspace permissions")}async getFeatures(){return this.fetchJson("workspaces/features",{},"Failed to fetch features")}async updateFeature(e,t,s){return this.fetchJson(`workspaces/${e}/features`,{method:"PATCH",body:JSON.stringify({features:{[t]:s}})},"Failed to update feature")}async getWorkspace(e){return this.fetchJson(`workspaces/${e}`,{},"Failed to fetch workspace")}async getProfile(){return this.fetchJson("profile",{},"Failed to fetch profile")}async updateUserProfile(e){return this.fetchJson("profile",{method:"PATCH",body:JSON.stringify(e)},"Failed to update user profile")}async getCurrentSubscription(e){const t=await this.fetchResponse(`workspaces/${e}/subscription`);if(!t.ok){let e="Failed to fetch subscription";try{e=(await t.json()).message||e}catch{e=404===t.status?"Workspace not found or no subscription available":401===t.status?"Unauthorized - Please check your session":`Failed to fetch subscription (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch subscription");return s.data||s}return s}async getPlanGroup(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/plan-group`);if(!t.ok){let e="Failed to fetch plan group";try{e=(await t.json()).message||e}catch{e=404===t.status?"No plan group found for this workspace":401===t.status?"Unauthorized - Please check your session":`Failed to fetch plan group (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch plan group");return s.data||s}return s}async getPlanGroupByVersion(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/plan-group?groupVersionId=${encodeURIComponent(t)}`);if(!s.ok){let e="Failed to fetch plan group version";try{e=(await s.json()).message||e}catch{e=404===s.status?"Plan group version not found":401===s.status?"Unauthorized - Please check your session":`Failed to fetch plan group version (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to fetch plan group version");return r.data||r}return r}async getPlanGroupVersions(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/plan-group/versions`);if(!t.ok){let e="Failed to fetch plan group versions";try{e=(await t.json()).message||e}catch{e=404===t.status?"No plan group versions found":401===t.status?"Unauthorized - Please check your session":`Failed to fetch plan group versions (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch plan group versions");return s.data||s}return s}async getPublicPlans(e){if(!this.orgId)throw new Error("orgId is required for getPublicPlans");const t=await this.fetchResponse(`${this.orgId}/plans/${encodeURIComponent(e)}`);if(!t.ok){let s="Failed to fetch plans";try{s=(await t.json()).message||s}catch{s=404===t.status?`Plans "${e}" not found`:`Failed to fetch plans (${t.status}: ${t.statusText})`}throw new Error(s)}const s=await t.json();if(void 0!==s.success&&!s.success)throw new Error(s.message||"Failed to fetch plans");return s.data??s}async getPlanGroupVersion(e){const t=await this.fetchResponse(`plan-group-versions/${e}`);if(!t.ok){let e="Failed to fetch plan group version";try{e=(await t.json()).message||e}catch{e=404===t.status?"Plan group version not found":401===t.status?"Unauthorized - Please check your session":`Failed to fetch plan group version (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch plan group version");return s.data||s}return s}async createCheckoutSession(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/checkout`,{method:"POST",body:JSON.stringify(t)});if(!s.ok){let e="Failed to create checkout session";try{e=(await s.json()).message||e}catch{e=`Failed to create checkout session (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to create checkout session");return r.data||r}return r}async selectFreePlan(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/select-free-plan`,{method:"POST",body:JSON.stringify({planVersionId:t})});if(!s.ok){let e="Failed to select free plan";try{e=(await s.json()).message||e}catch{e=`Failed to select free plan (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();return r.data||r}async updateSubscription(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription`,{method:"PATCH",body:JSON.stringify(t)});if(!s.ok){let e="Failed to update subscription";try{e=(await s.json()).message||e}catch{e=`Failed to update subscription (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to update subscription");return r.data?.checkoutUrl||r.checkoutUrl,r.data||r}return r.checkoutUrl,r}async createBillingPortalSession(e,t){return this.fetchJson(`workspaces/${e}/subscription/billing-portal`,{method:"POST",body:JSON.stringify(t?{returnUrl:t}:{})})}async listInvoices(e,t=10,s){const r=new URLSearchParams;r.append("limit",t.toString()),s&&r.append("starting_after",s);const n=await this.fetchResponse(`workspaces/${e}/subscription/invoices?${r.toString()}`,{});if(!n.ok){let e="Failed to fetch invoices";try{e=(await n.json()).message||e}catch{e=404===n.status?"Workspace not found or no invoices available":401===n.status?"Unauthorized - Please check your session":`Failed to fetch invoices (${n.status}: ${n.statusText})`}throw new Error(e)}const o=await n.json();if(void 0!==o.success){if(!o.success)throw new Error(o.message||"Failed to fetch invoices");return o}return o}async getInvoice(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/invoices/${t}`,{});if(!s.ok){let e="Failed to fetch invoice";try{e=(await s.json()).message||e}catch{e=404===s.status?"Invoice not found":401===s.status?"Unauthorized - Please check your session":`Failed to fetch invoice (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to fetch invoice");return r}return r}async cancelSubscriptionAtPeriodEnd(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/cancel-at-period-end`,{method:"POST"});if(!t.ok){let e="Failed to cancel subscription";try{e=(await t.json()).message||e}catch{e=404===t.status?"Subscription not found":401===t.status?"Unauthorized - Please check your session":`Failed to cancel subscription (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to cancel subscription");return s.data||s}return s}async resumeSubscription(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/resume`,{method:"POST"});if(!t.ok){let e="Failed to resume subscription";try{e=(await t.json()).message||e}catch{e=404===t.status?"Subscription not found":401===t.status?"Unauthorized - Please check your session":`Failed to resume subscription (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to resume subscription");return s.data||s}return s}async recordUsage(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/usage`,{method:"POST",body:JSON.stringify(t)});if(!s.ok){let e="Failed to record usage";try{e=(await s.json()).message||e}catch{e=`Failed to record usage (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to record usage");return r.data||r}return r}async recordUsageBatch(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/usage/batch`,{method:"POST",body:JSON.stringify(t)});if(!s.ok){let e="Failed to record batch usage";try{e=(await s.json()).message||e}catch{e=`Failed to record batch usage (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();return r.data||r}async getQuotaUsageStatus(e,t){const s=await this.fetchResponse(`workspaces/${e}/subscription/usage/status?quotaSlug=${encodeURIComponent(t)}`);if(!s.ok){let e="Failed to fetch quota usage status";try{e=(await s.json()).message||e}catch{e=404===s.status?"Workspace not found or no subscription available":401===s.status?"Unauthorized - Please check your session":`Failed to fetch quota usage status (${s.status}: ${s.statusText})`}throw new Error(e)}const r=await s.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||"Failed to fetch quota usage status");return r.data||r}return r}async getAllQuotaUsage(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/usage/all`);if(!t.ok){let e="Failed to fetch all quota usage";try{e=(await t.json()).message||e}catch{e=404===t.status?"Workspace not found or no subscription available":401===t.status?"Unauthorized - Please check your session":`Failed to fetch all quota usage (${t.status}: ${t.statusText})`}throw new Error(e)}const s=await t.json();if(void 0!==s.success){if(!s.success)throw new Error(s.message||"Failed to fetch all quota usage");return s.data||s}return s}async getUsageLogs(e,t){const s=new URLSearchParams;t?.quotaSlug&&s.append("quotaSlug",t.quotaSlug),t?.from&&s.append("from",t.from),t?.to&&s.append("to",t.to),t?.source&&s.append("source",t.source),t?.page&&s.append("page",t.page.toString()),t?.limit&&s.append("limit",t.limit.toString());const r=s.toString(),n=`workspaces/${e}/subscription/usage/logs${r?`?${r}`:""}`,o=await this.fetchResponse(n);if(!o.ok){let e="Failed to fetch usage logs";try{e=(await o.json()).message||e}catch{e=404===o.status?"Workspace not found":401===o.status?"Unauthorized - Please check your session":`Failed to fetch usage logs (${o.status}: ${o.statusText})`}throw new Error(e)}const a=await o.json();if(void 0!==a.success){if(!a.success)throw new Error(a.message||"Failed to fetch usage logs");return a.data||a}return a}async sendNotification(e,t,s,r){const n={event:t};return s&&(n.userId=s),r&&(n.data=r),this.fetchJson(`workspaces/${e}/notifications/send`,{method:"POST",body:JSON.stringify(n)},"Failed to send notification")}async getNotificationEvents(e){return this.fetchJson(`workspaces/${e}/notification-events`,{},"Failed to fetch notification events")}async getNotificationPreferences(e){return(await this.fetchJson(`workspaces/${e}/notification-preferences`,{},"Failed to fetch notification preferences")).notificationPreferences??{}}async updateNotificationPreferences(e,t){return(await this.fetchJson(`workspaces/${e}/notification-preferences`,{method:"PATCH",body:JSON.stringify({notificationPreferences:t})},"Failed to update notification preferences")).notificationPreferences??{}}}var b;!function(e){e.V1="v1"}(b||(b={}));const E={UserCreated:"user:created",UserUpdated:"user:updated",WorkspaceChanged:"workspace:changed",WorkspaceUpdated:"workspace:updated",WorkspaceUserAdded:"workspace:user-added",WorkspaceUserRemoved:"workspace:user-removed",WorkspaceUserRoleChanged:"workspace:user-role-changed",WorkspaceCreated:"workspace:created",WorkspaceDeleted:"workspace:deleted"};class v{constructor(){this.callbacks=null}setCallbacks(e){this.callbacks=e}getCallbacks(){return this.callbacks}async emit(e,t){if(this.callbacks?.handleEvent)try{await this.callbacks.handleEvent(e,t)}catch(t){i(t,{component:"EventEmitter",action:"emit",metadata:{eventType:e}})}}async emitUserCreated(e){await this.emit(E.UserCreated,{user:e})}async emitUserUpdated(e,t){await this.emit(E.UserUpdated,{user:e,previousUser:t})}async emitWorkspaceChanged(e,t){await this.emit(E.WorkspaceChanged,{workspace:e,previousWorkspace:t})}async emitWorkspaceUpdated(e){await this.emit(E.WorkspaceUpdated,{workspace:e})}async emitWorkspaceUserAdded(e,t,s){await this.emit(E.WorkspaceUserAdded,{userId:e,workspace:t,role:s})}async emitWorkspaceUserRemoved(e,t,s){await this.emit(E.WorkspaceUserRemoved,{userId:e,workspace:t,role:s})}async emitWorkspaceUserRoleChanged(e,t,s,r){await this.emit(E.WorkspaceUserRoleChanged,{userId:e,workspace:t,previousRole:s,newRole:r})}async emitWorkspaceCreated(e){await this.emit(E.WorkspaceCreated,{workspace:e})}async emitWorkspaceDeleted(e){await this.emit(E.WorkspaceDeleted,{workspace:e})}}const S=new v,$=new Set;function P(){$.forEach(e=>e())}const U=new Set;function I(){U.forEach(e=>e())}const R="bb";function F(e,t){let s;try{const e=t||("undefined"!=typeof window?window.location.href:"https://localhost");s=new URL(e),s.search=""}catch{s=new URL("https://localhost")}return s.searchParams.set(R,function(e){return Object.entries(e).filter(([,e])=>null!=e&&""!==e).map(([e,t])=>`${encodeURIComponent(e)}:${encodeURIComponent(t)}`).join(",")}(e)),s.toString()}function W(e,t){const s=t||("undefined"!=typeof window?window.location.href:void 0);return{successUrl:F({action:"checkout",status:"success",ws:e,screen:"subscription"},s),cancelUrl:F({action:"checkout",status:"cancel",ws:e,screen:"subscription"},s)}}function O(){if("undefined"==typeof window)return null;try{const e=new URLSearchParams(window.location.search).get(R);if(!e)return null;const t=function(e){const t={};if(!e)return t;const s=e.split(",");for(const e of s){const s=e.indexOf(":");if(-1===s)continue;const r=decodeURIComponent(e.slice(0,s)),n=decodeURIComponent(e.slice(s+1));r&&(t[r]=n)}return t}(e);return Object.keys(t).length>0?t:null}catch{return null}}function _(){if("undefined"!=typeof window)try{const e=new URL(window.location.href);e.searchParams.has(R)&&(e.searchParams.delete(R),window.history.replaceState({},"",e.toString()))}catch{}}function C(e){if(!e||"string"!=typeof e)return null;try{const t=new URL(e);return"https:"===t.protocol?e:"http:"!==t.protocol||"localhost"!==t.hostname&&"127.0.0.1"!==t.hostname&&"::1"!==t.hostname?null:e}catch{return null}}function T(e,t="/"){const s=C(e);window.location.href=s||t}const A={usd:"$",eur:"€",gbp:"£",jpy:"¥",cad:"CA$",aud:"A$",chf:"CHF",cny:"¥",hkd:"HK$",sgd:"S$",inr:"₹",mxn:"MX$",brl:"R$",nzd:"NZ$",sek:"kr",nok:"kr",dkk:"kr",pln:"zł",thb:"฿"},x={usd:"🇺🇸",eur:"🇪🇺",gbp:"🇬🇧",jpy:"🇯🇵",cad:"🇨🇦",aud:"🇦🇺",chf:"🇨🇭",cny:"🇨🇳",hkd:"🇭🇰",sgd:"🇸🇬",inr:"🇮🇳",mxn:"🇲🇽",brl:"🇧🇷",nzd:"🇳🇿",sek:"🇸🇪",nok:"🇳🇴",dkk:"🇩🇰",pln:"🇵🇱",thb:"🇹🇭"};function N(e){return e&&e.trim()?x[e.trim().toLowerCase()]??"":""}function j(e){if(!e||!e.trim())return"";const t=e.trim().toLowerCase();return A[t]??t.toUpperCase()}const J=["usd","eur","gbp","jpy","cad","aud","chf","cny","hkd","sgd","inr","mxn","brl","nzd","sek","nok","dkk","pln","thb"],L=J.map(e=>({value:e,label:`${e.toUpperCase()} (${j(e)})`}));function B(e,t){return j(t)+(e/100).toFixed(2)}const M={unit:"unit",units:"units",included:"Included",afterThat:"after that",afterIncluded:"After included"};function q(e,t,s,r){if(null==e||e<0)return null;const n={...M,...r},o=null!=t&&t>=1?t:1,a=j(s),i=(e/100).toFixed(2);return 1===o?`${a}${i}/${n.unit}`:`${a}${i}/${o.toLocaleString()} ${n.units}`}function V(e,t,s,r,n,o){if(null==e||e<0)return null;const a={...M,...o},i=null!=t&&t>=1?t:1,c=j(r),u=(e/100).toFixed(2);if(s){const e=n??(s.endsWith("s")?s:`${s}s`);return i>=2?`${c}${u}/${i.toLocaleString()} ${e}`:`${c}${u}/${s}`}return 1===i?`${c}${u}/${a.unit}`:`${c}${u}/${i.toLocaleString()} ${a.units}`}function K(e,t="unit"){const s=(e||"").trim().toLowerCase();if(!s)return t;const r=s.split(/\s+/)[0]??s;return new Set(["series","species","status","analysis","basis","bus","campus","corpus","axis"]).has(r)?r:r.endsWith("ies")&&r.length>3?r.slice(0,-3)+"y":r.endsWith("ses")||r.endsWith("xes")||r.endsWith("zes")||r.endsWith("ches")||r.endsWith("shes")?r.slice(0,-2):r.endsWith("s")&&!r.endsWith("ss")&&r.length>1?r.slice(0,-1):r||t}function z(e,t,s,r,n,o,a,i){const c={...M,...a};if(!1===i)return null!=e?`${c.included}: ${e.toLocaleString()} (${c.hardLimit??"hard limit"})`:c.hardLimit??"Hard limit";const u=o??(s.endsWith("s")?s:`${s}s`),l=null!=n&&n>=2?`${n.toLocaleString()} ${u}`:s;return null!=e&&null!=t?`${c.included}: ${e.toLocaleString()}, ${c.afterThat} ${B(t,r)}/${l}`:null!=e?`${c.included}: ${e.toLocaleString()}`:null!=t?`${c.afterIncluded}: ${B(t,r)}/${l}`:"—"}function D(e,t){if(null==e)return null;const s=e[t??"monthly"];return s?{included:s.included,...void 0!==s.overage&&{overage:s.overage},...void 0!==s.unitSize&&{unitSize:s.unitSize},allowOverage:!1!==e.allowOverage}:null}const G={included:"included",then:"then"};function H(e,t,s={}){const{overageInCents:r=!0,currency:n}=s,o=s.labels??G,a=s.currencySymbol??j(n??"");if(null==e)return"—";const{included:i,overage:c}=e,u=`${i} ${o.included}`;if(!1===e.allowOverage)return`${u} (hard limit)`;if(null==c)return u;const l=r?c/100:c,d="number"==typeof l&&Number.isFinite(l)?l.toFixed(2):String(c),h=t&&"unitSize"in e&&null!=e.unitSize&&e.unitSize>0?` / ${e.unitSize.toLocaleString()} ${t}`:t?` / ${t}`:"";return`${u}, ${o.then} ${a}${d}${h}`}const Q={Monthly:"monthly",Yearly:"yearly",Quarterly:"quarterly"},Y={Active:"active",Trialing:"trialing",Canceled:"canceled",PastDue:"past_due",Paused:"paused",Incomplete:"incomplete",Unpaid:"unpaid"},Z={Draft:"draft",Open:"open",Paid:"paid",Uncollectible:"uncollectible",Void:"void"},X={Feature:"feature",Limit:"limit",Quota:"quota"},ee={None:"none",Notified:"notified",Warning:"warning",Final:"final",Suspended:"suspended"};function te(e,t){const s=e.pricingVariants;if(!s?.length)return null;const r=t.toLowerCase();return s.find(e=>e.currency?.toLowerCase()===r)??null}function se(e,t,s){const r=te(e,t);if(!r?.basePricing)return null;const n=r.basePricing[s];return null!=n?n:null}function re(e,t,s){const r=te(e,t);if(!r?.stripePrices)return null;const n=s===Q.Monthly?"monthlyPriceId":s===Q.Yearly?"yearlyPriceId":"quarterlyPriceId",o=s===Q.Monthly?"monthly":s===Q.Yearly?"yearly":void 0;return r.stripePrices[n]??(o?r.stripePrices[o]:void 0)??null}function ne(e,t,s,r){const n=te(e,t),o=n?.quotaOverages?.[s];if(o)return o[r]}function oe(e,t){const s=te(e,t);return s?s.currency:e.plan?.currency??""}function ae(e){const t=new Set;for(const s of e)s.pricingVariants?.forEach(e=>{e.currency&&t.add(e.currency.toLowerCase())});return Array.from(t).sort()}function ie(e,t,s,r){const n=e.quotas?.[s];if(null==n)return null;const o=n[r];if(!o)return null;const a=ne(e,t,s,r);return{included:o.included,...void 0!==o.unitSize&&{unitSize:o.unitSize},...void 0!==a&&{overage:a},allowOverage:!1!==n.allowOverage}}function ce(e,t){if(!e)return null;for(const s of t){const t=s.pricingVariants;if(t?.length)for(const s of t){const t=s.stripePrices;if(t){if(t.monthlyPriceId===e||t.monthly===e)return{interval:"monthly",currency:s.currency};if(t.yearlyPriceId===e||t.yearly===e)return{interval:"yearly",currency:s.currency};if(t.quarterlyPriceId===e)return{interval:"quarterly",currency:s.currency}}}}return null}function ue(e,t){const s=te(e,t);return s?.seatPricing?.enabled?s.seatPricing:null}function le(e,t,s){const r=ue(e,t);return r?.perSeat?r.perSeat[s]??null:null}function de(e,t){return Math.max(0,e-(t||0))}function he(e,t,s,r){const n=ue(e,t);if(!n)return null;return de(r,n.includedSeats)*(le(e,t,s)??0)}function pe(e,t,s,r){const n=se(e,t,s);if(null===n)return null;if(void 0===r)return n;return n+(he(e,t,s,r)??0)}function fe(e){const{planVersion:t,currency:s="usd",settingsMaxUsers:r}=e;if(t){const e=ue(t,s);if(e)return{maxUsers:e.maxSeats??0,source:"seat_pricing",includedSeats:e.includedSeats??0,hasSeatPricing:!0}}return null!=r&&r>0?{maxUsers:r,source:"settings",includedSeats:0,hasSeatPricing:!1}:{maxUsers:0,source:"none",includedSeats:0,hasSeatPricing:!1}}function we(e){const{memberCount:t,maxUsersConfig:s,hasSubscription:r=!0,requireSubscription:n=!1}=e;if(n&&!r)return{canInvite:!1,blockReason:"no_subscription",blockMessageKey:"users.subscriptionRequired",blockMessageValues:{}};const{maxUsers:o,source:a}=s;if(o<=0)return{canInvite:!0,blockReason:null,blockMessageKey:null,blockMessageValues:null};if(t>=o){return{canInvite:!1,blockReason:{seat_pricing:"seat_limit_reached",settings:"settings_user_limit_reached"}[a]??"seat_limit_reached",blockMessageKey:{seat_pricing:"users.seatLimitMessage",settings:"users.settingsLimitMessage"}[a]??"users.memberLimitMessage",blockMessageValues:{maxUsers:o}}}return{canInvite:!0,blockReason:null,blockMessageKey:null,blockMessageValues:null}}const ge={WORKSPACE_SETTINGS_VIEW:"workspace:settings:view",WORKSPACE_SETTINGS_EDIT:"workspace:settings:edit",WORKSPACE_DELETE:"workspace:delete",WORKSPACE_MEMBERS_VIEW:"workspace:members:view",WORKSPACE_MEMBERS_INVITE:"workspace:members:invite",WORKSPACE_MEMBERS_REMOVE:"workspace:members:remove",WORKSPACE_MEMBERS_ROLE_CHANGE:"workspace:members:role-change",WORKSPACE_FEATURES_VIEW:"workspace:features:view",WORKSPACE_FEATURES_EDIT:"workspace:features:edit",WORKSPACE_BILLING_VIEW:"workspace:billing:view",WORKSPACE_BILLING_MANAGE:"workspace:billing:manage",WORKSPACE_USAGE_VIEW:"workspace:usage:view"},ye=Object.values(ge),me={admin:ye.filter(e=>e!==ge.WORKSPACE_DELETE),member:[ge.WORKSPACE_SETTINGS_VIEW,ge.WORKSPACE_MEMBERS_VIEW,ge.WORKSPACE_FEATURES_VIEW,ge.WORKSPACE_BILLING_VIEW,ge.WORKSPACE_USAGE_VIEW],viewer:[ge.WORKSPACE_SETTINGS_VIEW,ge.WORKSPACE_MEMBERS_VIEW]};function ke(e){const t=new Set;for(const s of Object.values(e))for(const e of s)t.add(e);return Array.from(t)}function be(e){const{userId:t,workspace:s,settings:r,appPermissions:n}=e;if(!s||!t)return new Set;if(function(e,t){if(!t)return!1;const s=(r=e.createdBy)?"string"==typeof r?r:"object"==typeof r&&"_id"in r&&"string"==typeof r._id?r._id:null:null;var r;return null!==s&&s===t}(s,t)){const e=new Set(ye);if(n)for(const t of ke(n))e.add(t);if(s.permissions)for(const t of ke(s.permissions))e.add(t);if(r?.workspace?.permissions)for(const t of ke(r.workspace.permissions))e.add(t);return e}const o=e.workspaceRole??function(e,t){if(!t||!e.users||!Array.isArray(e.users))return null;const s=e.users.find(e=>"string"==typeof e?e===t:"object"==typeof e&&null!==e&&"_id"in e&&e._id===t);return s&&"object"==typeof s&&"role"in s&&"string"==typeof s.role?s.role:null}(s,t);if(!o)return new Set;const a=s.permissions,i=r?.workspace?.permissions,c=e=>e.filter(e=>e.startsWith("workspace:")),u=e=>e.filter(e=>!e.startsWith("workspace:")),l=a?.[o]?c(a[o]):[],d=i?.[o]?c(i[o]):[],h=me[o]??[];let p;if(l.length>0)p=l;else if(d.length>0)p=d;else if(h.length>0)p=h;else{p=me[r?.workspace?.defaultRole??"member"]??me.member??[]}const f=new Set(p),w=a?.[o]?u(a[o]):[],g=n?.[o]?u(n[o]):[],y=w.length>0?w:g;for(const e of y)f.add(e);return function(e,t,s){if(!s?.workspace)return;const{canInviteMembers:r}=s.workspace;(!1===r||"admin-only"===r&&"admin"!==t)&&e.delete(ge.WORKSPACE_MEMBERS_INVITE)}(f,o,r),f}function Ee(e,t){const s=be(t);return Array.isArray(e)?e.every(e=>s.has(e)):s.has(e)}const ve="\n// BuildBase Push Notification Service Worker\n// Place this file in your app's public directory (e.g. public/push-sw.js)\n\nself.addEventListener('push', function(event) {\n if (!event.data) return;\n\n try {\n var payload = event.data.json();\n var title = payload.title || 'Notification';\n var options = {\n body: payload.body || '',\n icon: payload.icon || undefined,\n badge: payload.icon || undefined,\n data: { url: payload.url, ...(payload.data || {}) },\n tag: 'buildbase-push-' + Date.now(),\n };\n\n event.waitUntil(\n self.registration.showNotification(title, options)\n );\n } catch (e) {\n console.error('[PushSW] Failed to show notification:', e);\n }\n});\n\nself.addEventListener('notificationclick', function(event) {\n event.notification.close();\n\n var url = event.notification.data && event.notification.data.url;\n if (url) {\n event.waitUntil(\n clients.matchAll({ type: 'window', includeUncontrolled: true }).then(function(clientList) {\n for (var i = 0; i < clientList.length; i++) {\n var client = clientList[i];\n if (client.url === url && 'focus' in client) {\n return client.focus();\n }\n }\n if (clients.openWindow) {\n return clients.openWindow(url);\n }\n })\n );\n }\n});\n";var Se;function $e(e){const{serverUrl:t,orgId:s,version:r="v1",getSessionId:n,timeout:o,maxRetries:a,debug:i,headers:c,onError:u,fetch:l}=e;if(!t)throw new Error("BuildBase: serverUrl is required");if(!s)throw new Error("BuildBase: orgId is required");const d={...void 0!==o&&{timeout:o},...void 0!==a&&{maxRetries:a},...void 0!==i&&{debug:i},...c&&{headers:c},...u&&{onError:u},...l&&{fetch:l}},h=e=>{const n={serverUrl:t,version:r,orgId:s,sessionId:e,...d};return{workspace:new k(n),user:new m(n),settings:new y(n),push:new g(n)}},p=new k({serverUrl:t,version:r,orgId:s,...d}),f=e=>({workspace:{list:async()=>(await e()).workspace.getWorkspaces(),get:async t=>(await e()).workspace.getWorkspace(t),create:async t=>(await e()).workspace.createWorkspace(t),update:async(t,s)=>(await e()).workspace.updateWorkspace(t,s),delete:async t=>(await e()).workspace.deleteWorkspace(t)},users:{list:async t=>(await e()).workspace.getWorkspaceUsers(t),invite:async(t,s,r)=>(await e()).workspace.addUser(t,{email:s,role:r}),remove:async(t,s)=>(await e()).workspace.removeUser(t,s),updateRole:async(t,s,r)=>(await e()).workspace.updateUser(t,s,{role:r}),getProfile:async()=>(await e()).workspace.getProfile(),updateProfile:async t=>(await e()).workspace.updateUserProfile(t)},subscription:{get:async t=>(await e()).workspace.getCurrentSubscription(t),checkout:async(t,s)=>(await e()).workspace.createCheckoutSession(t,s),update:async(t,s)=>(await e()).workspace.updateSubscription(t,s),cancel:async t=>(await e()).workspace.cancelSubscriptionAtPeriodEnd(t),resume:async t=>(await e()).workspace.resumeSubscription(t),getBillingPortalUrl:async(t,s)=>(await e()).workspace.createBillingPortalSession(t,s)},plans:{getGroup:async t=>(await e()).workspace.getPlanGroup(t),getVersions:async t=>(await e()).workspace.getPlanGroupVersions(t),getPublic:e=>p.getPublicPlans(e),getVersion:e=>p.getPlanGroupVersion(e)},invoices:{list:async(t,s,r)=>(await e()).workspace.listInvoices(t,s,r),get:async(t,s)=>(await e()).workspace.getInvoice(t,s)},usage:{record:async(t,s)=>(await e()).workspace.recordUsage(t,s),recordBatch:async(t,s)=>(await e()).workspace.recordUsageBatch(t,s),getQuota:async(t,s)=>(await e()).workspace.getQuotaUsageStatus(t,s),getAll:async t=>(await e()).workspace.getAllQuotaUsage(t),getLogs:async(t,s)=>(await e()).workspace.getUsageLogs(t,s)},settings:{get:async()=>(await e()).settings.getSettings()},features:{list:async()=>(await e()).workspace.getFeatures(),update:async(t,s,r)=>(await e()).workspace.updateFeature(t,s,r)},notification:{send:async(t,s,r,n)=>(await e()).workspace.sendNotification(t,s,r,n)},permissions:{check:async(t,s,r)=>{const n=await e(),[o,a,i]=await Promise.all([n.workspace.getWorkspace(t),n.settings.getSettings(),n.workspace.getWorkspaceUsers(t)]),c=i.find(e=>("string"==typeof e.user?e.user:e.user._id)===s);return Ee(r,{userId:s,workspaceRole:c?.role??null,workspace:o,settings:a})},resolve:async(t,s)=>{const r=await e(),[n,o,a]=await Promise.all([r.workspace.getWorkspace(t),r.settings.getSettings(),r.workspace.getWorkspaceUsers(t)]),i=a.find(e=>("string"==typeof e.user?e.user:e.user._id)===s);return be({userId:s,workspaceRole:i?.role??null,workspace:n,settings:o})}}}),w=f(async()=>h(await(async()=>{if(!n)throw new Error("BuildBase: getSessionId callback is required for authenticated calls. Pass it in BuildBase({ getSessionId: ... }) or use withSession(id) / client.forSession(id).");const e=await n();if(!e)throw new Error("BuildBase: Not authenticated (getSessionId returned null)");return e})()));return{auth:async()=>{if(!n)return null;const e=await n();return e?{sessionId:e}:null},withSession:e=>{const t=h(e);return f(async()=>t)},client:{forSession:h},...w}}!function(e){e.loading="loading",e.redirecting="redirecting",e.authenticated="authenticated",e.unauthenticated="unauthenticated",e.authenticating="authenticating"}(Se||(Se={}));export{b as ApiVersion,p as AuthApi,Se as AuthStatus,R as BB_PARAM,h as BaseApi,w as BetaForm,Q as BillingIntervals,$e as BuildBase,A as CURRENCY_DISPLAY,x as CURRENCY_FLAG,me as DEFAULT_ROLE_PERMISSIONS,ee as DunningState,v as EventEmitter,Z as InvoiceStatuses,J as PLAN_CURRENCY_CODES,L as PLAN_CURRENCY_OPTIONS,ve as PUSH_SERVICE_WORKER_SCRIPT,ge as Permission,g as PushApi,E as SDKEvent,y as SettingsApi,X as SubscriptionItemType,Y as SubscriptionStatus,m as UserApi,k as WorkspaceApi,de as calculateBillableSeats,he as calculateSeatOverageCents,pe as calculateTotalSubscriptionCents,_ as cleanBBParams,F as createBBUrl,W as createCheckoutRedirectUrls,$e as default,S as eventEmitter,B as formatCents,q as formatOverageRate,V as formatOverageRateWithLabel,z as formatQuotaIncludedOverage,H as formatQuotaWithPrice,ae as getAvailableCurrenciesFromPlans,se as getBasePriceCents,ce as getBillingIntervalAndCurrencyFromPriceId,N as getCurrencyFlag,j as getCurrencySymbol,oe as getDisplayCurrency,le as getPerSeatPriceCents,te as getPricingVariant,D as getQuotaDisplayValue,ie as getQuotaDisplayWithVariant,ne as getQuotaOverageCents,K as getQuotaUnitLabelFromName,ue as getSeatPricing,re as getStripePriceIdForInterval,Ee as hasPermission,I as invalidateQuotaUsage,P as invalidateSubscription,O as readBBParams,fe as resolveMaxUsers,be as resolvePermissions,T as safeRedirect,we as validateInvite,C as validateRedirectUrl};
@@ -143,6 +143,8 @@ interface IQuotaIntervalValue {
143
143
  }
144
144
  /** Quota defined per billing interval (new plan-group/versions schema) */
145
145
  interface IQuotaByInterval {
146
+ /** Whether over-usage beyond included is allowed (billed as overage). When false, usage is hard-capped at included amount. Default true. */
147
+ allowOverage?: boolean;
146
148
  monthly?: IQuotaIntervalValue;
147
149
  yearly?: IQuotaIntervalValue;
148
150
  quarterly?: IQuotaIntervalValue;
@@ -209,6 +211,12 @@ interface IPlanVersion {
209
211
  /** Multi-currency pricing. Each variant has currency, basePricing, stripePrices, quotaOverages. */
210
212
  pricingVariants?: IPricingVariant[];
211
213
  subscriptionItems?: ISubscriptionItem[];
214
+ /** Trial configuration. When enabled, users can start a free trial of this plan. */
215
+ trial?: {
216
+ enabled: boolean;
217
+ durationDays: number;
218
+ requireCard: boolean;
219
+ };
212
220
  isCurrent?: boolean;
213
221
  isLegacy?: boolean;
214
222
  archived?: boolean;
@@ -229,6 +237,8 @@ interface IPlan {
229
237
  description?: string;
230
238
  /** Stripe currency code (e.g. 'usd', 'inr', 'eur'). Used for pricing display. */
231
239
  currency?: string;
240
+ /** Freemium plan: $0 base pricing, no seat billing, no trial. */
241
+ isFreemium?: boolean;
232
242
  latestVersion?: IPlanVersionSummary;
233
243
  archived?: boolean;
234
244
  deleted?: boolean;
@@ -493,6 +503,8 @@ interface IQuotaUsageStatus {
493
503
  available: number;
494
504
  overage: number;
495
505
  hasOverage: boolean;
506
+ /** Whether over-usage is allowed (billed as overage). When false, usage is hard-capped. Default true. */
507
+ allowOverage?: boolean;
496
508
  }
497
509
  /** Response from GET .../workspaces/:id/subscription/usage/status?quotaSlug=X */
498
510
  interface IQuotaUsageStatusResponse extends IQuotaUsageStatus {
@@ -561,11 +573,8 @@ interface IWorkspace {
561
573
  billingCurrency?: string | null;
562
574
  /** Per-workspace permission overrides. Takes priority over org-level settings.permissions. */
563
575
  permissions?: Record<string, string[]>;
564
- /** Workspace onboarding config. Set on creation based on org settings. SDK shows trial CTA. */
565
- pendingOnboarding?: {
566
- mode: 'trial';
567
- planVersionId: string;
568
- } | null;
576
+ /** Set when workspace first uses a trial. Blocks trial from being used again on the same workspace. */
577
+ trialUsedAt?: string | null;
569
578
  }
570
579
  interface IWorkspaceFeature {
571
580
  _id: string;
@@ -984,8 +993,38 @@ interface NotificationData {
984
993
  title?: string;
985
994
  /** Primary message — used in email body and as push notification body. */
986
995
  message?: string;
996
+ /** Custom icon URL for the push notification. Falls back to the org icon. */
997
+ icon?: string;
998
+ /** Large image URL displayed in the push notification body. */
999
+ image?: string;
1000
+ /** Small monochrome icon for the status bar (Android/ChromeOS). */
1001
+ badge?: string;
987
1002
  /** URL to open when the user clicks the push notification. Also available as {{url}} in email template. */
988
1003
  url?: string;
1004
+ /** Tag to group/replace notifications. New notification with same tag replaces the previous one instead of stacking. */
1005
+ tag?: string;
1006
+ /** Action buttons displayed on the notification (max 2). */
1007
+ actions?: Array<{
1008
+ action: string;
1009
+ title: string;
1010
+ icon?: string;
1011
+ }>;
1012
+ /** Show notification without sound or vibration. */
1013
+ silent?: boolean;
1014
+ /** Keep notification visible until user interacts (no auto-dismiss). Useful for critical alerts. */
1015
+ requireInteraction?: boolean;
1016
+ /** Vibrate/sound again when replacing a notification with the same tag. Only works with `tag`. */
1017
+ renotify?: boolean;
1018
+ /** Custom timestamp (ms since epoch) displayed on the notification. */
1019
+ timestamp?: number;
1020
+ /** Text direction for title/body. */
1021
+ dir?: 'ltr' | 'rtl' | 'auto';
1022
+ /** Time-to-live in seconds. Push service discards the message if not delivered within this time. Default: 86400 (24h). */
1023
+ ttl?: number;
1024
+ /** Delivery urgency hint. Affects battery/delivery priority on mobile. */
1025
+ urgency?: 'very-low' | 'low' | 'normal' | 'high';
1026
+ /** ISO 8601 date string. Delays delivery until the specified time. */
1027
+ scheduledAt?: string;
989
1028
  /**
990
1029
  * Which channels to send on. Overrides the event's default channel config.
991
1030
  * Omit to use the event's configured channels.
@@ -1124,6 +1163,10 @@ declare class WorkspaceApi extends BaseApi {
1124
1163
  * @returns Checkout session response with checkoutUrl to redirect user
1125
1164
  */
1126
1165
  createCheckoutSession(workspaceId: string, request: ICheckoutSessionRequest): Promise<CheckoutResult>;
1166
+ selectFreePlan(workspaceId: string, planVersionId: string): Promise<{
1167
+ success: boolean;
1168
+ message: string;
1169
+ }>;
1127
1170
  /**
1128
1171
  * Update subscription (upgrade/downgrade)
1129
1172
  * Only allows plan changes within the same plan group
@@ -1476,6 +1519,8 @@ interface OverageLabels {
1476
1519
  afterThat: string;
1477
1520
  /** "After included:" prefix when no included count */
1478
1521
  afterIncluded: string;
1522
+ /** "Hard limit" label for quotas where over-usage is not allowed */
1523
+ hardLimit?: string;
1479
1524
  }
1480
1525
  /**
1481
1526
  * Format overage rate for display. When unitSize > 1: "$1.00/1,000 units"; else "$1.00/unit".
@@ -1498,12 +1543,13 @@ declare function getQuotaUnitLabelFromName(nameOrSlug: string, fallback?: string
1498
1543
  * Format quota "included + overage" for display.
1499
1544
  * Pass `labels` and `pluralUnitLabel` for i18n support.
1500
1545
  */
1501
- declare function formatQuotaIncludedOverage(included: number | undefined, overageCents: number | undefined, unitLabel: string, currency: string, unitSize?: number, pluralUnitLabel?: string, labels?: Partial<OverageLabels>): string;
1546
+ declare function formatQuotaIncludedOverage(included: number | undefined, overageCents: number | undefined, unitLabel: string, currency: string, unitSize?: number, pluralUnitLabel?: string, labels?: Partial<OverageLabels>, allowOverage?: boolean): string;
1502
1547
 
1503
1548
  type QuotaDisplayValue = {
1504
1549
  included: number;
1505
1550
  overage?: number;
1506
1551
  unitSize?: number;
1552
+ allowOverage?: boolean;
1507
1553
  } | null;
1508
1554
  /**
1509
1555
  * Normalize a per-interval quota value to a display shape for the given billing interval.
@@ -1583,6 +1629,7 @@ type QuotaDisplayWithOverage = {
1583
1629
  included: number;
1584
1630
  overage?: number;
1585
1631
  unitSize?: number;
1632
+ allowOverage?: boolean;
1586
1633
  } | null;
1587
1634
  /**
1588
1635
  * Get quota display value for a slug/interval, merging plan version quotas (included, unitSize)
@@ -1833,7 +1880,15 @@ interface SDKMessages {
1833
1880
  cancelSuccess: string;
1834
1881
  cancelNotCharged: string;
1835
1882
  cancelResumeAnytime: string;
1883
+ cancelTrialTitle: string;
1884
+ cancelTrialConfirm: string;
1885
+ cancelTrialAccess: string;
1886
+ cancelTrialNoCharge: string;
1887
+ cancelTrialResume: string;
1888
+ cancelTrialKeep: string;
1889
+ cancelTrialButton: string;
1836
1890
  resumeTitle: string;
1891
+ resumeTrial: string;
1837
1892
  resumeConfirm: string;
1838
1893
  resumeKeep: string;
1839
1894
  resumeButton: string;
@@ -1843,6 +1898,7 @@ interface SDKMessages {
1843
1898
  openingPortal: string;
1844
1899
  viewAllPlans: string;
1845
1900
  scheduledCancellation: string;
1901
+ scheduledTrialCancellation: string;
1846
1902
  paymentPastDue: string;
1847
1903
  paymentPastDueDescription: string;
1848
1904
  subscriptionPaused: string;
@@ -1921,6 +1977,7 @@ interface SDKMessages {
1921
1977
  dunningSuspendedDescription: string;
1922
1978
  dunningRecoveryDescription: string;
1923
1979
  cancelEndDescription: string;
1980
+ trialEndDescription: string;
1924
1981
  cancelEndFallback: string;
1925
1982
  resumeChargeDate: string;
1926
1983
  resumeChargeFallback: string;
@@ -1933,6 +1990,8 @@ interface SDKMessages {
1933
1990
  startTrialDescription: string;
1934
1991
  noSubscriptionDescription: string;
1935
1992
  startFreeTrial: string;
1993
+ startTrialDays: string;
1994
+ trialBadge: string;
1936
1995
  };
1937
1996
  users: {
1938
1997
  title: string;
@@ -2157,6 +2216,7 @@ interface SDKMessages {
2157
2216
  quota: {
2158
2217
  includedOnly: string;
2159
2218
  includedWithOverage: string;
2219
+ includedHardLimit: string;
2160
2220
  unitFallback: string;
2161
2221
  };
2162
2222
  pricing: {
@@ -2320,7 +2380,7 @@ declare function useTranslation(): {
2320
2380
  t: (key: TranslationKey, values?: TranslationValues) => string;
2321
2381
  locale: SDKLocale;
2322
2382
  formattingLocale: string;
2323
- dir: "rtl" | "ltr";
2383
+ dir: "ltr" | "rtl";
2324
2384
  fmtNum: (n: number) => string;
2325
2385
  fmtCents: (cents: number, currency: string) => string;
2326
2386
  messages: SDKMessages;