@buildbase/sdk 0.0.47 → 0.0.49
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/AGENTS.md +119 -0
- package/CHANGELOG.md +42 -0
- package/README.md +198 -0
- package/dist/css/styles.css +1 -1
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +403 -4
- package/dist/index.mjs +1 -1
- package/dist/react/index.cjs +36 -0
- package/dist/react/index.d.ts +123 -35
- package/dist/react/index.mjs +5 -5
- package/package.json +11 -9
- package/dist/index.js +0 -1
- package/dist/react/index.js +0 -36
- /package/dist/data/{index.js → index.cjs} +0 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});let e=!0;function t(t,...r){e&&function(){try{const e="undefined"!=typeof globalThis?globalThis:null;return"development"===e?.process?.env?.NODE_ENV}catch{return!1}}()&&console.error(t,...r)}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 s(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 r={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}: ${r})`)}(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 n extends Error{constructor(e,t,r,s){super(e),this.code=t,this.context=r,this.originalError=s,this.name="SDKError","undefined"!=typeof Error&&"captureStackTrace"in Error&&Error.captureStackTrace(this,n)}}const o=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,r={}){if(function(e){return e instanceof Error&&("AbortError"===e.name||"ERR_CANCELED"===e.code)}(e))return;const s=e instanceof Error?e:new n("string"==typeof e?e:"An unknown error occurred","UNKNOWN_ERROR",r),o=s instanceof n?s:new n(s.message,"SDK_ERROR",r,s);if(this.config.enableConsoleLogging&&t(`[SDK Error] ${r.component||"Unknown"}:`,{message:o.message,code:o.code,context:o.context,originalError:o.originalError,stack:o.stack}),this.config.onError)try{this.config.onError(o,r)}catch(e){!function(e,...t){console.error(e,...t)}("[SDK Error Handler] Error in custom error callback:",e)}this.config.showUserNotifications&&this.notifyUser(o,r)}notifyUser(e,t){"undefined"!=typeof window&&window.dispatchEvent&&window.dispatchEvent(new CustomEvent("sdk-error",{detail:{error:e,context:t}}))}wrapAsync(e,t){return(...r)=>e(...r).catch(e=>{throw this.handleError(e,t),e})}wrapSync(e,t){return(...r)=>{try{return e(...r)}catch(e){throw this.handleError(e,t),e}}}};function i(e,t={}){o.handleError(e,t)}function a(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}}function c(e){if("undefined"!=typeof window)try{localStorage.removeItem(e)}catch(t){i(t,{component:"storage",action:"removeStorageItem",metadata:{key:e}})}}function u(e,t){try{!function(e,t){if("undefined"!=typeof window)try{localStorage.setItem(e,t)}catch(t){i(t,{component:"storage",action:"setStorageItem",metadata:{key:e}})}}(e,JSON.stringify(t))}catch(t){i(t,{component:"storage",action:"setStorageJSON",metadata:{key:e}})}}const l="saas-session-id";function d(){return function(){if("undefined"==typeof window)return null;try{return a(l)}catch(e){return i(e,{component:"auth-utils",action:"getSessionId",metadata:{key:l}}),null}}()}const p=new WeakSet,h="SDK is not ready (missing serverUrl, version, or orgId)";class f{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._onUnauthorized=e.onUnauthorized,this._fetch=e.fetch??globalThis.fetch}ensureReady(){if(!this.serverUrl?.trim()||!this.version)throw new Error(h);if(this.requireOrgId&&!this.orgId?.trim())throw new Error(h)}get baseUrl(){return this.ensureReady(),`${this.serverUrl}/api/${this.version}/${this.basePath}`}getAuthHeaders(){return this._sessionId?{"x-session-id":this._sessionId}:function(){const e=d(),t={};return e&&(t["x-session-id"]=e),t}()}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}reportError(e,t){p.has(e)||(p.add(e),this._onError?.(e,t))}async executeFetch(e,t){return this.executeFetchUrl(this.url(e),t,e)}async executeFetchUrl(e,t,r){const s=(t.method??"GET").toUpperCase(),n=r??e,o=this.buildHeaders(t),i={...t,headers:o};let a;if(this._timeout>0){const e=new AbortController;a=setTimeout(()=>e.abort(),this._timeout),i.signal=t.signal?AbortSignal.any([t.signal,e.signal]):e.signal}const c=async t=>{try{const r=this._fetch.bind(globalThis),n=await r(e,i);if(this._debug&&console.log(`[BuildBase] ${s} ${e} → ${n.status}`),401===n.status&&this._onUnauthorized&&this._onUnauthorized(),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)),c(t+1)}return n}catch(e){if(e instanceof Error&&"AbortError"===e.name){if(void 0!==a){const e=new Error(`Request timeout after ${this._timeout}ms: ${s} ${n}`);throw this.reportError(e,{method:s,path:n}),e}throw e}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)),c(t+1)}throw e instanceof Error&&this.reportError(e,{method:s,path:n}),e}};try{return await c(0)}finally{void 0!==a&&clearTimeout(a)}}async fetchJson(e,t={},r="Request failed"){this.ensureReady();try{const n=await this.executeFetch(e,t);return await s(n,r)}catch(r){throw r instanceof Error&&this.reportError(r,{method:(t.method??"GET").toUpperCase(),path:e}),r}}async fetchResponse(e,t={}){return this.ensureReady(),this.executeFetch(e,t)}async fetchAbsoluteUrl(e,t={}){return this.ensureReady(),this.executeFetchUrl(e,t)}async throwResponseError(e,t){let r=t;try{r=(await e.json()).message||r}catch{r=`${t} (${e.status}: ${e.statusText})`}throw new Error(r)}async unwrapResponse(e,t){const r=await e.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||t);return r.data||r}return r}}class g extends f{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 extends f{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 f{constructor(e){super({...e,requireOrgId:!0})}async getSettings(e){return this.fetchJson(`${this.orgId}/settings`,{signal:e},"Failed to fetch settings")}}class m extends f{constructor(e){super(e)}async getAttributes(e){const t=await this.fetchResponse("users/attributes",{signal:e});t.ok||await this.throwResponseError(t,"Failed to fetch user attributes");const r=await this.unwrapResponse(t,"Failed to fetch user attributes");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});t.ok||await this.throwResponseError(t,"Failed to fetch user features");const r=await this.unwrapResponse(t,"Failed to fetch user features");return"object"==typeof r&&null!==r?r:{}}}class k extends f{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,r){return this.fetchJson(`workspaces/${e}/users/${t}`,{method:"PATCH",body:JSON.stringify(r)},"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,r){return this.fetchJson(`workspaces/${e}/features`,{method:"PATCH",body:JSON.stringify({features:{[t]:r}})},"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 getPasskeys(){const e=await this.fetchJson("passkeys",{},"Failed to fetch passkeys");return e?.passkeys??[]}async renamePasskey(e,t){await this.fetchJson(`passkeys/${e}`,{method:"PATCH",body:JSON.stringify({name:t})},"Failed to rename passkey")}async deletePasskey(e){await this.fetchJson(`passkeys/${e}`,{method:"DELETE"},"Failed to remove passkey")}async getCurrentSubscription(e){const t=await this.fetchResponse(`workspaces/${e}/subscription`);return t.ok||await this.throwResponseError(t,"Failed to fetch subscription"),this.unwrapResponse(t,"Failed to fetch subscription")}async getPlanGroup(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/plan-group`);return t.ok||await this.throwResponseError(t,"Failed to fetch plan group"),this.unwrapResponse(t,"Failed to fetch plan group")}async getPlanGroupByVersion(e,t){const r=await this.fetchResponse(`workspaces/${e}/subscription/plan-group?groupVersionId=${encodeURIComponent(t)}`);return r.ok||await this.throwResponseError(r,"Failed to fetch plan group version"),this.unwrapResponse(r,"Failed to fetch plan group version")}async getPlanGroupVersions(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/plan-group/versions`);return t.ok||await this.throwResponseError(t,"Failed to fetch plan group versions"),this.unwrapResponse(t,"Failed to fetch plan group versions")}async getPublicPlans(e){if(!this.orgId)throw new Error("orgId is required for getPublicPlans");const t=await this.fetchResponse(`${this.orgId}/plans/${encodeURIComponent(e)}`);return t.ok||await this.throwResponseError(t,"Failed to fetch plans"),this.unwrapResponse(t,"Failed to fetch plans")}async getPublicCreditPackages(){if(!this.orgId)throw new Error("orgId is required for getPublicCreditPackages");const e=await this.fetchResponse(`${this.orgId}/credit-packages`);return e.ok||await this.throwResponseError(e,"Failed to fetch credit packages"),this.unwrapResponse(e,"Failed to fetch credit packages")}async getPlanGroupVersion(e){const t=await this.fetchResponse(`plan-group-versions/${e}`);return t.ok||await this.throwResponseError(t,"Failed to fetch plan group version"),this.unwrapResponse(t,"Failed to fetch plan group version")}async createCheckoutSession(e,t){const r=await this.fetchResponse(`workspaces/${e}/subscription/checkout`,{method:"POST",body:JSON.stringify(t)});return r.ok||await this.throwResponseError(r,"Failed to create checkout session"),this.unwrapResponse(r,"Failed to create checkout session")}async selectFreePlan(e,t){const r=await this.fetchResponse(`workspaces/${e}/subscription/select-free-plan`,{method:"POST",body:JSON.stringify({planVersionId:t})});return r.ok||await this.throwResponseError(r,"Failed to select free plan"),r.json()}async updateSubscription(e,t){const r=await this.fetchResponse(`workspaces/${e}/subscription`,{method:"PATCH",body:JSON.stringify(t)});return r.ok||await this.throwResponseError(r,"Failed to update subscription"),this.unwrapResponse(r,"Failed to update subscription")}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,r){const s=new URLSearchParams;s.append("limit",t.toString()),r&&s.append("starting_after",r);const n=await this.fetchResponse(`workspaces/${e}/subscription/invoices?${s.toString()}`);return n.ok||await this.throwResponseError(n,"Failed to fetch invoices"),this.unwrapResponse(n,"Failed to fetch invoices")}async getInvoice(e,t){const r=await this.fetchResponse(`workspaces/${e}/subscription/invoices/${t}`);return r.ok||await this.throwResponseError(r,"Failed to fetch invoice"),this.unwrapResponse(r,"Failed to fetch invoice")}async cancelSubscriptionAtPeriodEnd(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/cancel-at-period-end`,{method:"POST"});return t.ok||await this.throwResponseError(t,"Failed to cancel subscription"),this.unwrapResponse(t,"Failed to cancel subscription")}async resumeSubscription(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/resume`,{method:"POST"});return t.ok||await this.throwResponseError(t,"Failed to resume subscription"),this.unwrapResponse(t,"Failed to resume subscription")}async recordUsage(e,t){const r=await this.fetchResponse(`workspaces/${e}/subscription/usage`,{method:"POST",body:JSON.stringify(t)});return r.ok||await this.throwResponseError(r,"Failed to record usage"),this.unwrapResponse(r,"Failed to record usage")}async recordUsageBatch(e,t){const r=await this.fetchResponse(`workspaces/${e}/subscription/usage/batch`,{method:"POST",body:JSON.stringify(t)});return r.ok||await this.throwResponseError(r,"Failed to record batch usage"),this.unwrapResponse(r,"Failed to record batch usage")}async getQuotaUsageStatus(e,t){const r=await this.fetchResponse(`workspaces/${e}/subscription/usage/status?quotaSlug=${encodeURIComponent(t)}`);return r.ok||await this.throwResponseError(r,"Failed to fetch quota usage status"),this.unwrapResponse(r,"Failed to fetch quota usage status")}async getAllQuotaUsage(e){const t=await this.fetchResponse(`workspaces/${e}/subscription/usage/all`);return t.ok||await this.throwResponseError(t,"Failed to fetch all quota usage"),this.unwrapResponse(t,"Failed to fetch all quota usage")}async getUsageLogs(e,t){const r=new URLSearchParams;t?.quotaSlug&&r.append("quotaSlug",t.quotaSlug),t?.from&&r.append("from",t.from),t?.to&&r.append("to",t.to),t?.source&&r.append("source",t.source),t?.page&&r.append("page",t.page.toString()),t?.limit&&r.append("limit",t.limit.toString());const s=r.toString(),n=`workspaces/${e}/subscription/usage/logs${s?`?${s}`:""}`,o=await this.fetchResponse(n);return o.ok||await this.throwResponseError(o,"Failed to fetch usage logs"),this.unwrapResponse(o,"Failed to fetch usage logs")}async sendNotification(e,t,r,s){const n={event:t};return r&&(n.userId=r),s&&(n.data=s),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??{}}async getCreditBalance(e){const t=await this.fetchResponse(`workspaces/${e}/credits`);return t.ok||await this.throwResponseError(t,"Failed to fetch credit balance"),this.unwrapResponse(t,"Failed to fetch credit balance")}async consumeCredits(e,t){const r=await this.fetchResponse(`workspaces/${e}/credits/consume`,{method:"POST",body:JSON.stringify(t)});if(!r.ok){if(402===r.status){const e=await r.json().catch(()=>({})),t=new Error(e.message||"Insufficient credits");throw t.available=e.available,t.requested=e.requested,t.code="INSUFFICIENT_CREDITS",t}await this.throwResponseError(r,"Failed to consume credits")}return this.unwrapResponse(r,"Failed to consume credits")}async purchaseCredits(e,t){const r=await this.fetchResponse(`workspaces/${e}/credits/purchase`,{method:"POST",body:JSON.stringify(t)});return r.ok||await this.throwResponseError(r,"Failed to create credit purchase checkout"),this.unwrapResponse(r,"Failed to create credit purchase checkout")}async getCreditPackages(e){const t=await this.fetchResponse(`workspaces/${e}/credits/packages`);t.ok||await this.throwResponseError(t,"Failed to fetch credit packages");const r=await this.unwrapResponse(t,"Failed to fetch credit packages");return r.docs??r}async getCreditTransactions(e,t){const r=new URLSearchParams;t?.type&&r.append("type",t.type),t?.page&&r.append("page",t.page.toString()),t?.limit&&r.append("limit",t.limit.toString());const s=r.toString(),n=`workspaces/${e}/credits/transactions${s?`?${s}`:""}`,o=await this.fetchResponse(n);return o.ok||await this.throwResponseError(o,"Failed to fetch credit transactions"),this.unwrapResponse(o,"Failed to fetch credit transactions")}async getCreditBuckets(e,t){const r=new URLSearchParams;t?.status&&r.append("status",t.status),t?.source&&r.append("source",t.source),t?.page&&r.append("page",t.page.toString()),t?.limit&&r.append("limit",t.limit.toString());const s=r.toString(),n=`workspaces/${e}/credits/buckets${s?`?${s}`:""}`,o=await this.fetchResponse(n);return o.ok||await this.throwResponseError(o,"Failed to fetch credit buckets"),this.unwrapResponse(o,"Failed to fetch credit buckets")}async getExpiringCredits(e,t){const r=t?`?days=${t}`:"",s=await this.fetchResponse(`workspaces/${e}/credits/expiring${r}`);return s.ok||await this.throwResponseError(s,"Failed to fetch expiring credits"),this.unwrapResponse(s,"Failed to fetch expiring credits")}}exports.ApiVersion=void 0,(exports.ApiVersion||(exports.ApiVersion={})).V1="v1";const b={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 S{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(b.UserCreated,{user:e})}async emitUserUpdated(e,t){await this.emit(b.UserUpdated,{user:e,previousUser:t})}async emitWorkspaceChanged(e,t){await this.emit(b.WorkspaceChanged,{workspace:e,previousWorkspace:t})}async emitWorkspaceUpdated(e){await this.emit(b.WorkspaceUpdated,{workspace:e})}async emitWorkspaceUserAdded(e,t,r){await this.emit(b.WorkspaceUserAdded,{userId:e,workspace:t,role:r})}async emitWorkspaceUserRemoved(e,t,r){await this.emit(b.WorkspaceUserRemoved,{userId:e,workspace:t,role:r})}async emitWorkspaceUserRoleChanged(e,t,r,s){await this.emit(b.WorkspaceUserRoleChanged,{userId:e,workspace:t,previousRole:r,newRole:s})}async emitWorkspaceCreated(e){await this.emit(b.WorkspaceCreated,{workspace:e})}async emitWorkspaceDeleted(e){await this.emit(b.WorkspaceDeleted,{workspace:e})}}const v=new S;function E(){const e=new Set;return{subscribe:t=>(e.add(t),()=>{e.delete(t)}),invalidate(){e.forEach(e=>e())},reset(){e.clear()}}}const R=E().invalidate,x=E().invalidate,$=E().invalidate,P="bb",U={Checkout:"checkout",Billing:"billing",SelectPlan:"selectPlan",CreditPurchase:"creditPurchase",OpenCreditStore:"openCreditStore",Invite:"invite"},C={Success:"success",Cancel:"cancel",Error:"error"},I={Subscription:"subscription",Credits:"credits",Usage:"usage",Users:"users",Profile:"profile",General:"general",Features:"features",Notifications:"notifications",Permissions:"permissions",Danger:"danger"};function _(e,t){let r;try{const e=t||("undefined"!=typeof window?window.location.href:"https://localhost");r=new URL(e),r.search=""}catch{r=new URL("https://localhost")}return r.searchParams.set(P,function(e){return Object.entries(e).filter(([,e])=>null!=e&&""!==e).map(([e,t])=>`${encodeURIComponent(e)}:${encodeURIComponent(t)}`).join(",")}(e)),r.toString()}function A(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 F="saas-auth-intent";function O(e){return"object"==typeof e&&null!==e&&"string"==typeof e.returnUrl&&"number"==typeof e.createdAt}const W={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:"฿"},T={usd:"🇺🇸",eur:"🇪🇺",gbp:"🇬🇧",jpy:"🇯🇵",cad:"🇨🇦",aud:"🇦🇺",chf:"🇨🇭",cny:"🇨🇳",hkd:"🇭🇰",sgd:"🇸🇬",inr:"🇮🇳",mxn:"🇲🇽",brl:"🇧🇷",nzd:"🇳🇿",sek:"🇸🇪",nok:"🇳🇴",dkk:"🇩🇰",pln:"🇵🇱",thb:"🇹🇭"};function N(e){if(!e||!e.trim())return"";const t=e.trim().toLowerCase();return W[t]??t.toUpperCase()}const B=["usd","eur","gbp","jpy","cad","aud","chf","cny","hkd","sgd","inr","mxn","brl","nzd","sek","nok","dkk","pln","thb"],J=B.map(e=>({value:e,label:`${e.toUpperCase()} (${N(e)})`}));function L(e,t){return N(t)+(e/100).toFixed(2)}const M={unit:"unit",units:"units",included:"Included",afterThat:"after that",afterIncluded:"After included"};const q={included:"included",then:"then"};const D={Monthly:"monthly",Yearly:"yearly",Quarterly:"quarterly"};function V(e,t){const r=e.pricingVariants;if(!r?.length)return null;const s=t.toLowerCase();return r.find(e=>e.currency?.toLowerCase()===s)??null}function K(e,t,r){const s=V(e,t);if(!s?.basePricing)return null;const n=s.basePricing[r];return null!=n?n:null}function j(e,t,r,s){const n=V(e,t),o=n?.quotaOverages?.[r];if(o)return o[s]}function z(e,t){const r=V(e,t);return r?.seatPricing?.enabled?r.seatPricing:null}function G(e,t,r){const s=z(e,t);return s?.perSeat?s.perSeat[r]??null:null}function H(e,t){return Math.max(0,e-(t||0))}function Q(e,t,r,s){const n=z(e,t);if(!n)return null;return H(s,n.includedSeats)*(G(e,t,r)??0)}const Y={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"},Z=Object.values(Y),X={admin:Z.filter(e=>e!==Y.WORKSPACE_DELETE),member:[Y.WORKSPACE_SETTINGS_VIEW,Y.WORKSPACE_MEMBERS_VIEW,Y.WORKSPACE_FEATURES_VIEW,Y.WORKSPACE_BILLING_VIEW,Y.WORKSPACE_USAGE_VIEW],viewer:[Y.WORKSPACE_SETTINGS_VIEW,Y.WORKSPACE_MEMBERS_VIEW]};function ee(e){const t=new Set;for(const r of Object.values(e))for(const e of r)t.add(e);return Array.from(t)}function te(e){const{userId:t,workspace:r,settings:s,appPermissions:n}=e;if(!r||!t)return new Set;if(function(e,t){if(!t)return!1;const r=(s=e.createdBy)?"string"==typeof s?s:"object"==typeof s&&"_id"in s&&"string"==typeof s._id?s._id:null:null;var s;return null!==r&&r===t}(r,t)){const e=new Set(Z);if(n)for(const t of ee(n))e.add(t);if(r.permissions)for(const t of ee(r.permissions))e.add(t);if(s?.workspace?.permissions)for(const t of ee(s.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 r=e.users.find(e=>"string"==typeof e?e===t:"object"==typeof e&&null!==e&&"_id"in e&&e._id===t);return r&&"object"==typeof r&&"role"in r&&"string"==typeof r.role?r.role:null}(r,t);if(!o)return new Set;const i=r.permissions,a=s?.workspace?.permissions,c=e=>e.filter(e=>e.startsWith("workspace:")),u=e=>e.filter(e=>!e.startsWith("workspace:")),l=i?.[o]?c(i[o]):[],d=a?.[o]?c(a[o]):[],p=X[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=X[s?.workspace?.defaultRole??"member"]??X.member??[]}const f=new Set(h),g=i?.[o]?u(i[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,r){if(!r?.workspace)return;const{canInviteMembers:s}=r.workspace;(!1===s||"admin-only"===s&&"admin"!==t)&&e.delete(Y.WORKSPACE_MEMBERS_INVITE)}(f,o,s),f}function re(e,t){const r=te(t);return Array.isArray(e)?e.every(e=>r.has(e)):r.has(e)}var se;function ne(e){const{body:t,signature:r,timestamp:s,secret:n,maxAgeSeconds:o=300}=e;if(!(r&&s&&n&&t))return!1;const i="sha256=";if(!r.startsWith(i))return!1;const a=r.slice(7);if(o>0){const e=parseInt(s,10);if(isNaN(e))return!1;if(Math.abs(Math.floor(Date.now()/1e3)-e)>o)return!1}try{const e=require("crypto"),r=e.createHmac("sha256",n).update(`${s}.${t}`).digest("hex"),o=Buffer.from(a,"hex"),i=Buffer.from(r,"hex");return o.length===i.length&&e.timingSafeEqual(o,i)}catch{return!1}}exports.AuthStatus=void 0,(se=exports.AuthStatus||(exports.AuthStatus={})).loading="loading",se.redirecting="redirecting",se.authenticated="authenticated",se.unauthenticated="unauthenticated",se.authenticating="authenticating";const oe=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),ie=(e,t)=>e>>>t|e<<32-t;function ae(e){let t=1779033703,r=3144134277,s=1013904242,n=2773480762,o=1359893119,i=2600822924,a=528734635,c=1541459225;const u=e.length,l=u+1,d=l+(56-l%64+64)%64+8,p=new Uint8Array(d);p.set(e,0),p[u]=128;const h=8*u,f=Math.floor(h/4294967296),g=h>>>0;p[d-8]=f>>>24&255,p[d-7]=f>>>16&255,p[d-6]=f>>>8&255,p[d-5]=255&f,p[d-4]=g>>>24&255,p[d-3]=g>>>16&255,p[d-2]=g>>>8&255,p[d-1]=255&g;const w=new Uint32Array(64);for(let e=0;e<d;e+=64){for(let t=0;t<16;t++){const r=e+4*t;w[t]=p[r]<<24|p[r+1]<<16|p[r+2]<<8|p[r+3]}for(let e=16;e<64;e++){const t=ie(w[e-15],7)^ie(w[e-15],18)^w[e-15]>>>3,r=ie(w[e-2],17)^ie(w[e-2],19)^w[e-2]>>>10;w[e]=w[e-16]+t+w[e-7]+r>>>0}let u=t,l=r,d=s,h=n,f=o,g=i,y=a,m=c;for(let e=0;e<64;e++){const t=m+(ie(f,6)^ie(f,11)^ie(f,25))+(f&g^~f&y)+oe[e]+w[e]>>>0,r=u&l^u&d^l&d;m=y,y=g,g=f,f=h+t>>>0,h=d,d=l,l=u,u=t+((ie(u,2)^ie(u,13)^ie(u,22))+r>>>0)>>>0}t=t+u>>>0,r=r+l>>>0,s=s+d>>>0,n=n+h>>>0,o=o+f>>>0,i=i+g>>>0,a=a+y>>>0,c=c+m>>>0}const y=new Uint8Array(32),m=[t,r,s,n,o,i,a,c];for(let e=0;e<8;e++)y[4*e]=m[e]>>>24&255,y[4*e+1]=m[e]>>>16&255,y[4*e+2]=m[e]>>>8&255,y[4*e+3]=255&m[e];return y}function ce(e){return(new TextEncoder).encode(e)}function ue(e,t){const r=new Uint8Array(e.length+t.length);return r.set(e,0),r.set(t,e.length),r}const le=300,de="/.well-known/oauth-protected-resource",pe="/.well-known/agent-skills",he="application/json",fe="text/plain; charset=utf-8";function ge(e){return e.replace(/\/+$/,"")}function we(e){return`public, max-age=${e}, s-maxage=${e}`}function ye(e){return"sha256:"+function(e){let t="";for(let r=0;r<e.length;r++)t+=e[r].toString(16).padStart(2,"0");return t}(ae(ce(e)))}const me=new Map;async function ke(e){const t=e.cacheTtlSeconds??le,r=`${ge(e.serverUrl)}::${e.orgId}`,s=me.get(r);if(s&&s.expiresAt>Date.now())return s.value;const n=e.fetch??fetch,o=`${ge(e.serverUrl)}/api/v1/public/${e.orgId}/agent-readiness`;let i={enabled:!1};try{const e=await n(o,{headers:{Accept:he}});if(e.ok){const t=await e.json();t&&"object"==typeof t&&(i=t)}}catch{}return me.set(r,{value:i,expiresAt:Date.now()+1e3*t}),i}function be(e,t){const r=ge(e.siteUrl),s={llms_txt:"/llms.txt",sitemap:"/sitemap.xml",robots:"/robots.txt",oauth_protected_resource:de};t.authorizationServer?.metadataUrl&&(s.oauth_authorization_server=t.authorizationServer.metadataUrl),e.skills?.length&&(s.agent_skills=`${pe}/index.json`);return $e({schema_version:"1.0",name:e.site.name,...e.site.description?{description:e.site.description}:{},url:r,...e.site.documentationUrl?{documentation_url:e.site.documentationUrl}:{},provider:e.site.provider??{name:e.site.name,url:r},capabilities:s,...e.site.contactEmail?{contact:{email:e.site.contactEmail}}:{}},e)}function Se(e,t,r){const s=r.protectedResources??[];if(!s.length)return null;const n=e.replace(/\/+$/,"")||de,o=s.find(e=>function(e){let t="/";try{t=new URL(e).pathname}catch{t=e.startsWith("/")?e:`/${e}`}const r="/"===t?"":t.replace(/\/+$/,"");return de+r}(e.resource)===n);return o?$e(o.metadata,t):n===de&&1===s.length?$e(s[0].metadata,t):null}function ve(e){const t=e.skills??[];if(!t.length)return null;const r=ge(e.siteUrl);return $e({$schema:"https://schemas.agentskills.io/discovery/0.2.0/schema.json",skills:t.map(e=>({name:e.name,type:e.type??"skill-md",description:e.description,url:`${r}${Ee(e)}`,digest:ye(e.content)}))},e)}function Ee(e){return e.path??`${pe}/${e.name}/SKILL.md`}function Re(e,t){const r=(t.skills??[]).find(t=>Ee(t)===e);return r?{status:200,contentType:"text/markdown; charset=utf-8",body:r.content,cacheControl:we(t.cacheTtlSeconds??le)}:null}function xe(e){if(!e.security)return null;const t=(Array.isArray(e.security.contact)?e.security.contact:[e.security.contact]).map(e=>`Contact: ${e}`);return e.security.expires&&t.push(`Expires: ${e.security.expires}`),e.security.policy&&t.push(`Policy: ${e.security.policy}`),{status:200,contentType:fe,body:t.join("\n")+"\n",cacheControl:we(e.cacheTtlSeconds??le)}}function $e(e,t){return{status:200,contentType:he,body:JSON.stringify(e,null,2),cacheControl:we(t.cacheTtlSeconds??le)}}class Pe extends Error{constructor(e,t){super(t),this.name="AppBridgeError",this.code=e}}function Ue(e){const t=e.replace(/-/g,"+").replace(/_/g,"/"),r=t.length%4==0?"":"=".repeat(4-t.length%4),s=atob(t+r),n=new Uint8Array(s.length);for(let e=0;e<s.length;e++)n[e]=s.charCodeAt(e);return n}function Ce(e){return JSON.parse((new TextDecoder).decode(Ue(e)))}function Ie(e,t,r=60){if(!e||!t)throw new Pe("invalid_token","Missing token or client secret");const s=e.split(".");if(3!==s.length)throw new Pe("invalid_token","Malformed JWT");const[n,o,i]=s,a=function(e,t){let r=e;r.length>64&&(r=ae(r));const s=new Uint8Array(64),n=new Uint8Array(64);for(let e=0;e<64;e++){const t=e<r.length?r[e]:0;s[e]=54^t,n[e]=92^t}const o=ae(ue(s,t));return ae(ue(n,o))}(ce(t),ce(`${n}.${o}`));let c,u,l;try{c=Ue(i)}catch{throw new Pe("invalid_signature","Unreadable JWT signature")}if(!function(e,t){if(e.length!==t.length)return!1;let r=0;for(let s=0;s<e.length;s++)r|=e[s]^t[s];return 0===r}(a,c))throw new Pe("invalid_signature","JWT signature verification failed");try{u=Ce(n),l=Ce(o)}catch{throw new Pe("invalid_token","Unreadable JWT segments")}if("HS256"!==u.alg)throw new Pe("invalid_algorithm",`Unexpected JWT alg: ${String(u.alg)}`);const d=Math.floor(Date.now()/1e3);if("number"==typeof l.exp&&d>l.exp+r)throw new Pe("token_expired","JWT has expired");if("number"==typeof l.nbf&&d+r<l.nbf)throw new Pe("token_not_yet_valid","JWT is not yet valid");return l}function _e(e){if(!e)return null;const t=/^Bearer\s+(.+)$/i.exec(e.trim());return t?t[1].trim():null}function Ae(e){const t=_e(e.authorization);if(!t)throw new Pe("invalid_token","Missing Bearer token");return Ie(t,e.clientSecret,e.clockToleranceSec)}function Fe(e){const t=_e(e.authorization);if(!t)throw new Pe("invalid_token","Missing Bearer token");return Ie(t,e.clientSecret,e.clockToleranceSec)}function Oe(e){return{success:!0,token:e.token,message:e.message??"ok",..."number"==typeof e.expiresIn?{expiresIn:e.expiresIn}:{}}}function We(e){return{success:!1,token:"",message:e}}function Te(e){const{serverUrl:t,orgId:r,version:s="v1",getSessionId:n,timeout:o,maxRetries:i,debug:a,headers:c,onError:u,fetch:l}=e;if(!t)throw new Error("BuildBase: serverUrl is required");if(!r)throw new Error("BuildBase: orgId is required");const d={...void 0!==o&&{timeout:o},...void 0!==i&&{maxRetries:i},...void 0!==a&&{debug:a},...c&&{headers:c},...u&&{onError:u},...l&&{fetch:l}},p=e=>{const n={serverUrl:t,version:s,orgId:r,sessionId:e,...d};return{workspace:new k(n),user:new m(n),settings:new y(n),push:new w(n)}},h=new k({serverUrl:t,version:s,orgId:r,...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,r)=>(await e()).workspace.updateWorkspace(t,r),delete:async t=>(await e()).workspace.deleteWorkspace(t)},users:{list:async t=>(await e()).workspace.getWorkspaceUsers(t),invite:async(t,r,s)=>(await e()).workspace.addUser(t,{email:r,role:s}),remove:async(t,r)=>(await e()).workspace.removeUser(t,r),updateRole:async(t,r,s)=>(await e()).workspace.updateUser(t,r,{role:s}),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,r)=>(await e()).workspace.createCheckoutSession(t,r),update:async(t,r)=>(await e()).workspace.updateSubscription(t,r),cancel:async t=>(await e()).workspace.cancelSubscriptionAtPeriodEnd(t),resume:async t=>(await e()).workspace.resumeSubscription(t),getBillingPortalUrl:async(t,r)=>(await e()).workspace.createBillingPortalSession(t,r)},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,r,s)=>(await e()).workspace.listInvoices(t,r,s),get:async(t,r)=>(await e()).workspace.getInvoice(t,r)},usage:{record:async(t,r)=>(await e()).workspace.recordUsage(t,r),recordBatch:async(t,r)=>(await e()).workspace.recordUsageBatch(t,r),getQuota:async(t,r)=>(await e()).workspace.getQuotaUsageStatus(t,r),getAll:async t=>(await e()).workspace.getAllQuotaUsage(t),getLogs:async(t,r)=>(await e()).workspace.getUsageLogs(t,r)},settings:{get:async()=>(await e()).settings.getSettings()},features:{list:async()=>(await e()).workspace.getFeatures(),update:async(t,r,s)=>(await e()).workspace.updateFeature(t,r,s)},notification:{send:async(t,r,s,n)=>(await e()).workspace.sendNotification(t,r,s,n)},credits:{getBalance:async t=>(await e()).workspace.getCreditBalance(t),consume:async(t,r)=>(await e()).workspace.consumeCredits(t,r),purchase:async(t,r)=>(await e()).workspace.purchaseCredits(t,r),getPackages:async t=>(await e()).workspace.getCreditPackages(t),getTransactions:async(t,r)=>(await e()).workspace.getCreditTransactions(t,r),getBuckets:async(t,r)=>(await e()).workspace.getCreditBuckets(t,r),getExpiring:async(t,r)=>(await e()).workspace.getExpiringCredits(t,r),getPublicPackages:()=>h.getPublicCreditPackages()},permissions:{check:async(t,r,s)=>{const n=await e(),[o,i,a]=await Promise.all([n.workspace.getWorkspace(t),n.settings.getSettings(),n.workspace.getWorkspaceUsers(t)]),c=a.find(e=>("string"==typeof e.user?e.user:e.user._id)===r);return re(s,{userId:r,workspaceRole:c?.role??null,workspace:o,settings:i})},resolve:async(t,r)=>{const s=await e(),[n,o,i]=await Promise.all([s.workspace.getWorkspace(t),s.settings.getSettings(),s.workspace.getWorkspaceUsers(t)]),a=i.find(e=>("string"==typeof e.user?e.user:e.user._id)===r);return te({userId:r,workspaceRole:a?.role??null,workspace:n,settings:o})}}}),g=f(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 f(async()=>t)},client:{forSession:p},...g}}exports.AppBridgeError=Pe,exports.AuthApi=class extends f{constructor(e){super(e)}async requestAuth(e){const t=`${this.serverUrl}/api/${this.version}/auth/request`,r=await this.fetchAbsoluteUrl(t,{method:"POST",body:JSON.stringify(e)});return r.ok||await this.throwResponseError(r,"Failed to initiate authentication"),r.json()}async getProfile(e,t){return this.fetchJson("profile",{headers:{"x-session-id":e},signal:t},"Failed to fetch user profile")}},exports.BBAction=U,exports.BBScreen=I,exports.BBStatus=C,exports.BB_PARAM=P,exports.BaseApi=f,exports.BetaForm=class{constructor(e){this.api=new g(e),this.orgId=e.orgId}async fetchConfig(){return this.api.fetchConfig()}async submitBetaUser(e){const t=e?.context??{},r=t?.country??("undefined"!=typeof navigator&&navigator.language?navigator.language.split("-")[1]:void 0),s=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:r,language:s,timezone:n,currency:o}})}},exports.BillingIntervals=D,exports.BuildBase=Te,exports.CURRENCY_DISPLAY=W,exports.CURRENCY_FLAG=T,exports.CreditBucketSource={PlanGrant:"plan_grant",CreditPackPurchase:"credit_pack_purchase",AdminGrant:"admin_grant",Refund:"refund"},exports.CreditBucketStatus={Pending:"pending",Active:"active",Expired:"expired",Consumed:"consumed"},exports.CreditTransactionType={PlanGrant:"plan_grant",PackPurchased:"pack_purchased",Consumed:"consumed",Expired:"expired",AdminGrant:"admin_grant",AdminRevoke:"admin_revoke",Refund:"refund"},exports.DEFAULT_ROLE_PERMISSIONS=X,exports.DunningState={None:"none",Notified:"notified",Warning:"warning",Final:"final",Suspended:"suspended"},exports.EventEmitter=S,exports.InvoiceStatuses={Draft:"draft",Open:"open",Paid:"paid",Uncollectible:"uncollectible",Void:"void"},exports.PLAN_CURRENCY_CODES=B,exports.PLAN_CURRENCY_OPTIONS=J,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 const payload = event.data.json();\n const title = payload.title || 'Notification';\n const 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 const 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 (let i = 0; i < clientList.length; i++) {\n const 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=Y,exports.PushApi=w,exports.SDKEvent=b,exports.SettingsApi=y,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=m,exports.WorkspaceApi=k,exports.appTokenFailure=We,exports.appTokenSuccess=Oe,exports.bearerChallenge=function(e){const t=[`Bearer resource_metadata="${e.resourceMetadataUrl}"`];return e.error&&t.push(`error="${e.error}"`),e.errorDescription&&t.push(`error_description="${e.errorDescription}"`),{status:401,headers:{"WWW-Authenticate":t.join(", "),"Content-Type":"application/json"},body:JSON.stringify({error:e.error??"invalid_token"})}},exports.buildAgentCard=be,exports.buildAgentSkillsIndex=ve,exports.buildLlmsTxt=function(e,t){return t.llmsTxt?{status:200,contentType:fe,body:t.llmsTxt,cacheControl:we(e.cacheTtlSeconds??le)}:null},exports.buildProtectedResourceMetadata=Se,exports.buildSecurityTxt=xe,exports.buildSkillMd=Re,exports.calculateBillableSeats=H,exports.calculateSeatOverageCents=Q,exports.calculateTotalSubscriptionCents=function(e,t,r,s){const n=K(e,t,r);return null===n?null:void 0===s?n:n+(Q(e,t,r,s)??0)},exports.cleanBBParams=function(){if("undefined"!=typeof window)try{const e=new URL(window.location.href);e.searchParams.has(P)&&(e.searchParams.delete(P),window.history.replaceState({},"",e.toString()))}catch{}},exports.clearAgentReadinessCache=function(){me.clear()},exports.clearAuthIntent=function(){c(F)},exports.consumeAuthIntent=function(){const e=function(e,t){const r=a(e);if(!r)return null;try{const s=JSON.parse(r);return t&&!t(s)?(i(new Error("Storage data failed validation"),{component:"storage",action:"getStorageJSON",metadata:{key:e}}),c(e),null):s}catch(t){return i(t,{component:"storage",action:"getStorageJSON",metadata:{key:e}}),c(e),null}}(F,O);return c(F),e?Date.now()-e.createdAt>6e5?null:A(e.returnUrl):null},exports.createBBUrl=_,exports.createCheckoutRedirectUrls=function(e,t){const r=t||("undefined"!=typeof window?window.location.href:void 0);return{successUrl:_({action:U.Checkout,status:C.Success,ws:e,screen:I.Subscription},r),cancelUrl:_({action:U.Checkout,status:C.Cancel,ws:e,screen:I.Subscription},r)}},exports.createCreditPurchaseRedirectUrls=function(e,t){const r=t||("undefined"!=typeof window?window.location.href:void 0);return{successUrl:_({action:U.CreditPurchase,status:C.Success,ws:e,screen:I.Credits},r),cancelUrl:_({action:U.CreditPurchase,status:C.Cancel,ws:e,screen:I.Credits},r)}},exports.default=Te,exports.eventEmitter=v,exports.extractBearerToken=_e,exports.fetchAgentReadiness=ke,exports.formatCents=L,exports.formatOverageRate=function(e,t,r,s){if(null==e||e<0)return null;const n={...M,...s},o=null!=t&&t>=1?t:1,i=N(r),a=(e/100).toFixed(2);return 1===o?`${i}${a}/${n.unit}`:`${i}${a}/${o.toLocaleString()} ${n.units}`},exports.formatOverageRateWithLabel=function(e,t,r,s,n,o){if(null==e||e<0)return null;const i={...M,...o},a=null!=t&&t>=1?t:1,c=N(s),u=(e/100).toFixed(2);if(r){const e=n??(r.endsWith("s")?r:`${r}s`);return a>=2?`${c}${u}/${a.toLocaleString()} ${e}`:`${c}${u}/${r}`}return 1===a?`${c}${u}/${i.unit}`:`${c}${u}/${a.toLocaleString()} ${i.units}`},exports.formatQuotaIncludedOverage=function(e,t,r,s,n,o,i,a){const c={...M,...i};if(!1===a)return null!=e?`${c.included}: ${e.toLocaleString()} (${c.hardLimit??"hard limit"})`:c.hardLimit??"Hard limit";const u=o??(r.endsWith("s")?r:`${r}s`),l=null!=n&&n>=2?`${n.toLocaleString()} ${u}`:r;return null!=e&&null!=t?`${c.included}: ${e.toLocaleString()}, ${c.afterThat} ${L(t,s)}/${l}`:null!=e?`${c.included}: ${e.toLocaleString()}`:null!=t?`${c.afterIncluded}: ${L(t,s)}/${l}`:"—"},exports.formatQuotaWithPrice=function(e,t,r={}){const{overageInCents:s=!0,currency:n}=r,o=r.labels??q,i=r.currencySymbol??N(n??"");if(null==e)return"—";const{included:a,overage:c}=e,u=`${a} ${o.included}`;if(!1===e.allowOverage)return`${u} (hard limit)`;if(null==c)return u;const l=s?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} ${i}${d}${p}`},exports.getAvailableCurrenciesFromPlans=function(e){const t=new Set;for(const r of e)r.pricingVariants?.forEach(e=>{e.currency&&t.add(e.currency.toLowerCase())});return Array.from(t).sort()},exports.getBasePriceCents=K,exports.getBillingIntervalAndCurrencyFromPriceId=function(e,t){if(!e)return null;for(const r of t){const t=r.pricingVariants;if(t?.length)for(const r of t){const t=r.stripePrices;if(t){if(t.monthlyPriceId===e||t.monthly===e)return{interval:"monthly",currency:r.currency};if(t.yearlyPriceId===e||t.yearly===e)return{interval:"yearly",currency:r.currency};if(t.quarterlyPriceId===e)return{interval:"quarterly",currency:r.currency}}}}return null},exports.getCurrencyFlag=function(e){return e&&e.trim()?T[e.trim().toLowerCase()]??"":""},exports.getCurrencySymbol=N,exports.getDisplayCurrency=function(e,t){const r=V(e,t);return r?r.currency:e.plan?.currency??""},exports.getPerSeatPriceCents=G,exports.getPricingVariant=V,exports.getQuotaDisplayValue=function(e,t){if(null==e)return null;const r=e[t??"monthly"];return r?{included:r.included,...void 0!==r.overage&&{overage:r.overage},...void 0!==r.unitSize&&{unitSize:r.unitSize},allowOverage:!1!==e.allowOverage}:null},exports.getQuotaDisplayWithVariant=function(e,t,r,s){const n=e.quotas?.[r];if(null==n)return null;const o=n[s];if(!o)return null;const i=j(e,t,r,s);return{included:o.included,...void 0!==o.unitSize&&{unitSize:o.unitSize},...void 0!==i&&{overage:i},allowOverage:!1!==n.allowOverage}},exports.getQuotaOverageCents=j,exports.getQuotaUnitLabelFromName=function(e,t="unit"){const r=(e||"").trim().toLowerCase();if(!r)return t;const s=r.split(/\s+/)[0]??r;return new Set(["series","species","status","analysis","basis","bus","campus","corpus","axis"]).has(s)?s:s.endsWith("ies")&&s.length>3?s.slice(0,-3)+"y":s.endsWith("ses")||s.endsWith("xes")||s.endsWith("zes")||s.endsWith("ches")||s.endsWith("shes")?s.slice(0,-2):s.endsWith("s")&&!s.endsWith("ss")&&s.length>1?s.slice(0,-1):s||t},exports.getSeatPricing=z,exports.getStripePriceIdForInterval=function(e,t,r){const s=V(e,t);if(!s?.stripePrices)return null;const n=r===D.Monthly?"monthlyPriceId":r===D.Yearly?"yearlyPriceId":"quarterlyPriceId",o=r===D.Monthly?"monthly":r===D.Yearly?"yearly":void 0;return s.stripePrices[n]??(o?s.stripePrices[o]:void 0)??null},exports.handleAppRevokeRequest=async function(e){let t;try{t=Fe(e)}catch(e){return{status:401,body:{success:!1,message:e instanceof Pe?e.code:"invalid_token"}}}return await e.onRevoke(t),{status:200,body:{success:!0}}},exports.handleAppTokenRequest=async function(e){let t;try{t=Ae(e)}catch(e){return{status:401,body:We(e instanceof Pe?e.code:"invalid_token")}}return{status:200,body:Oe(await e.mintToken(t))}},exports.hasPermission=re,exports.invalidateCreditBalance=R,exports.invalidateQuotaUsage=x,exports.invalidateSubscription=$,exports.parseWebhookEvent=function(e){if(!ne(e))return null;try{return JSON.parse(e.body)}catch{return null}},exports.readBBParams=function(){if("undefined"==typeof window)return null;try{const e=new URLSearchParams(window.location.search).get(P);if(!e)return null;const t=function(e){const t={};if(!e)return t;const r=e.split(",");for(const e of r){const r=e.indexOf(":");if(-1===r)continue;const s=decodeURIComponent(e.slice(0,r)),n=decodeURIComponent(e.slice(r+1));s&&(t[s]=n)}return t}(e);return Object.keys(t).length>0?t:null}catch{return null}},exports.resolveMaxUsers=function(e){const{planVersion:t,currency:r="usd",settingsMaxUsers:s}=e;if(t){const e=z(t,r);if(e)return{maxUsers:e.maxSeats??0,source:"seat_pricing",includedSeats:e.includedSeats??0,hasSeatPricing:!0}}return null!=s&&s>0?{maxUsers:s,source:"settings",includedSeats:0,hasSeatPricing:!1}:{maxUsers:0,source:"none",includedSeats:0,hasSeatPricing:!1}},exports.resolvePermissions=te,exports.resolveWellKnown=async function(e,t){const r=e.replace(/\/+$/,"")||e;if("/.well-known/agent.json"===r){return be(t,await ke(t))}if("/.well-known/security.txt"===r)return xe(t);if(r===`${pe}/index.json`)return ve(t);if(r.startsWith(`${pe}/`)&&r.endsWith("SKILL.md"))return Re(r,t);if("/.well-known/oauth-authorization-server"===r){const e=await ke(t),r=e.authorizationServer?.metadataUrl;return r?$e({...e.authorizationServer?.issuer?{issuer:e.authorizationServer.issuer}:{},oauth_authorization_server_metadata:r},t):null}if(r.startsWith(de)){return Se(r,t,await ke(t))}return null},exports.safeRedirect=function(e,t="/"){const r=A(e);window.location.href=r||t},exports.saveAuthIntent=function(e){A(e)&&u(F,{returnUrl:e,createdAt:Date.now()})},exports.sha256Digest=ye,exports.validateInvite=function(e){const{memberCount:t,maxUsersConfig:r,hasSubscription:s=!0,requireSubscription:n=!1}=e;if(n&&!s)return{canInvite:!1,blockReason:"no_subscription",blockMessageKey:"users.subscriptionRequired",blockMessageValues:{}};const{maxUsers:o,source:i}=r;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"}[i]??"seat_limit_reached",blockMessageKey:{seat_pricing:"users.seatLimitMessage",settings:"users.settingsLimitMessage"}[i]??"users.memberLimitMessage",blockMessageValues:{maxUsers:o}}}return{canInvite:!0,blockReason:null,blockMessageKey:null,blockMessageValues:null}},exports.validateRedirectUrl=A,exports.verifyAppRevokeRequest=Fe,exports.verifyAppTokenRequest=Ae,exports.verifyClientJwt=Ie,exports.verifyWebhookSignature=ne;
|
package/dist/index.d.ts
CHANGED
|
@@ -23,6 +23,19 @@ interface IUser extends IDocument {
|
|
|
23
23
|
currency?: string;
|
|
24
24
|
attributes?: Record<string, string | number | boolean>;
|
|
25
25
|
}
|
|
26
|
+
/** A registered passkey (WebAuthn credential) — no key material exposed. */
|
|
27
|
+
interface IPasskeySummary {
|
|
28
|
+
id: string;
|
|
29
|
+
name: string;
|
|
30
|
+
deviceType?: string;
|
|
31
|
+
backedUp?: boolean;
|
|
32
|
+
lastUsedAt?: string;
|
|
33
|
+
createdAt?: string;
|
|
34
|
+
/** Auth domain the credential is bound to */
|
|
35
|
+
rpId?: string;
|
|
36
|
+
/** False when the org's auth domain changed and this credential can no longer be used to sign in */
|
|
37
|
+
active?: boolean;
|
|
38
|
+
}
|
|
26
39
|
interface IAsset extends IDocument {
|
|
27
40
|
_id: string;
|
|
28
41
|
createdAt: string;
|
|
@@ -1099,8 +1112,12 @@ declare abstract class BaseApi {
|
|
|
1099
1112
|
protected url(path: string): string;
|
|
1100
1113
|
/** Merge auth + custom + per-request headers. */
|
|
1101
1114
|
private buildHeaders;
|
|
1115
|
+
/** Fire the onError callback exactly once per error, regardless of call path. */
|
|
1116
|
+
private reportError;
|
|
1102
1117
|
/** Execute fetch with timeout, retries, debug logging, and error callback. */
|
|
1103
1118
|
private executeFetch;
|
|
1119
|
+
/** Internal: execute fetch against a resolved URL with timeout, retries, debug logging, and error callback. */
|
|
1120
|
+
private executeFetchUrl;
|
|
1104
1121
|
/**
|
|
1105
1122
|
* Execute request and parse JSON with handleApiResponse (throws on !response.ok).
|
|
1106
1123
|
* Use for standard JSON APIs.
|
|
@@ -1111,6 +1128,12 @@ declare abstract class BaseApi {
|
|
|
1111
1128
|
* Caller is responsible for checking response.ok and parsing body.
|
|
1112
1129
|
*/
|
|
1113
1130
|
protected fetchResponse(path: string, init?: RequestInit): Promise<Response>;
|
|
1131
|
+
/**
|
|
1132
|
+
* Execute request against an absolute URL (bypasses baseUrl).
|
|
1133
|
+
* Useful for endpoints outside the default basePath (e.g. /auth vs /public).
|
|
1134
|
+
* Gets the same timeout, retry, header-merge, and error-callback handling as fetchResponse.
|
|
1135
|
+
*/
|
|
1136
|
+
protected fetchAbsoluteUrl(absoluteUrl: string, init?: RequestInit): Promise<Response>;
|
|
1114
1137
|
/**
|
|
1115
1138
|
* Throw an error from a failed response.
|
|
1116
1139
|
* Tries to parse JSON error body; falls back to status-based message.
|
|
@@ -1135,6 +1158,7 @@ interface AuthRequestParams {
|
|
|
1135
1158
|
success: string;
|
|
1136
1159
|
error: string;
|
|
1137
1160
|
};
|
|
1161
|
+
state?: string;
|
|
1138
1162
|
}
|
|
1139
1163
|
interface AuthRequestResponse {
|
|
1140
1164
|
success: boolean;
|
|
@@ -1149,8 +1173,8 @@ declare class AuthApi extends BaseApi {
|
|
|
1149
1173
|
});
|
|
1150
1174
|
/**
|
|
1151
1175
|
* Initiate OAuth sign-in flow. Returns redirect URL to the auth provider.
|
|
1152
|
-
*
|
|
1153
|
-
* so we
|
|
1176
|
+
* Auth endpoints sit at /api/v1/auth/ (outside the /public basePath),
|
|
1177
|
+
* so we use fetchAbsoluteUrl to get timeout, retry, and error handling via BaseApi.
|
|
1154
1178
|
*/
|
|
1155
1179
|
requestAuth(params: AuthRequestParams): Promise<AuthRequestResponse>;
|
|
1156
1180
|
/** Fetch user profile with the given session ID (used after OAuth redirect or from storage). */
|
|
@@ -1369,6 +1393,9 @@ declare class WorkspaceApi extends BaseApi {
|
|
|
1369
1393
|
getWorkspace(workspaceId: string): Promise<IWorkspace>;
|
|
1370
1394
|
getProfile(): Promise<IUser>;
|
|
1371
1395
|
updateUserProfile(config: Partial<IUser>): Promise<IUser>;
|
|
1396
|
+
getPasskeys(): Promise<IPasskeySummary[]>;
|
|
1397
|
+
renamePasskey(passkeyId: string, name: string): Promise<void>;
|
|
1398
|
+
deletePasskey(passkeyId: string): Promise<void>;
|
|
1372
1399
|
/**
|
|
1373
1400
|
* Get current subscription for a workspace
|
|
1374
1401
|
* Returns subscription details including plan, plan version, and group information
|
|
@@ -2260,6 +2287,378 @@ declare function parseWebhookEvent(options: {
|
|
|
2260
2287
|
data: Record<string, any>;
|
|
2261
2288
|
} | null;
|
|
2262
2289
|
|
|
2290
|
+
/**
|
|
2291
|
+
* Agent-readiness discovery toolkit (server-side, framework-agnostic).
|
|
2292
|
+
*
|
|
2293
|
+
* Makes a consuming app "agent ready" (see https://isitagentready.com) by
|
|
2294
|
+
* serving the standard machine-readable discovery documents an AI agent looks
|
|
2295
|
+
* for — with the BuildBase server as the source of truth.
|
|
2296
|
+
*
|
|
2297
|
+
* The heavy lifting already lives on the platform: an org admin configures
|
|
2298
|
+
* agent readiness once (protected resources, scopes, llms.txt) and the server
|
|
2299
|
+
* publishes the OAuth2 authorization-server metadata (RFC 8414) and the
|
|
2300
|
+
* per-resource protected-resource metadata (RFC 9728). This module lets an app
|
|
2301
|
+
* re-serve those documents from its own origin — where agents actually look —
|
|
2302
|
+
* plus generate the static discovery documents (Agent Card, Agent Skills,
|
|
2303
|
+
* security.txt) from local config. The result: an org admin adds full agent
|
|
2304
|
+
* support to their app in a couple of lines, and never hand-writes a
|
|
2305
|
+
* `.well-known` route.
|
|
2306
|
+
*
|
|
2307
|
+
* Zero React and no framework types — every function returns plain data. The
|
|
2308
|
+
* only runtime dependency is `fetch`; SHA-256 (for Agent Skills digests) is a
|
|
2309
|
+
* dependency-free pure-JS implementation, so there is no Web Crypto / Node
|
|
2310
|
+
* `crypto` requirement and output is identical on every runtime (browser, edge,
|
|
2311
|
+
* Node 18+). Wire the returned documents into your router yourself (Next.js,
|
|
2312
|
+
* Hono, Express, …).
|
|
2313
|
+
*
|
|
2314
|
+
* @example Next.js App Router — the entire integration:
|
|
2315
|
+
* ```ts
|
|
2316
|
+
* // lib/agent-ready.ts
|
|
2317
|
+
* import type { AgentReadyConfig } from "@buildbase/sdk";
|
|
2318
|
+
* export const agentConfig: AgentReadyConfig = {
|
|
2319
|
+
* serverUrl: process.env.BUILDBASE_URL!,
|
|
2320
|
+
* orgId: process.env.BUILDBASE_ORG_ID!,
|
|
2321
|
+
* siteUrl: "https://imejis.io",
|
|
2322
|
+
* site: { name: "Imejis", description: "Generate images from templates via API." },
|
|
2323
|
+
* };
|
|
2324
|
+
*
|
|
2325
|
+
* // app/.well-known/[...path]/route.ts
|
|
2326
|
+
* import { resolveWellKnown } from "@buildbase/sdk";
|
|
2327
|
+
* import { agentConfig } from "@/lib/agent-ready";
|
|
2328
|
+
* export async function GET(req: Request) {
|
|
2329
|
+
* const doc = await resolveWellKnown(new URL(req.url).pathname, agentConfig);
|
|
2330
|
+
* if (!doc) return new Response('{"error":"not_found"}', { status: 404 });
|
|
2331
|
+
* return new Response(doc.body, {
|
|
2332
|
+
* status: doc.status,
|
|
2333
|
+
* headers: { "Content-Type": doc.contentType, "Cache-Control": doc.cacheControl },
|
|
2334
|
+
* });
|
|
2335
|
+
* }
|
|
2336
|
+
*
|
|
2337
|
+
* // app/llms.txt/route.ts
|
|
2338
|
+
* import { buildLlmsTxt, fetchAgentReadiness } from "@buildbase/sdk";
|
|
2339
|
+
* import { agentConfig } from "@/lib/agent-ready";
|
|
2340
|
+
* export async function GET() {
|
|
2341
|
+
* const doc = buildLlmsTxt(agentConfig, await fetchAgentReadiness(agentConfig));
|
|
2342
|
+
* if (!doc) return new Response("Not found", { status: 404 });
|
|
2343
|
+
* return new Response(doc.body, { headers: { "Content-Type": doc.contentType } });
|
|
2344
|
+
* }
|
|
2345
|
+
* ```
|
|
2346
|
+
*/
|
|
2347
|
+
/**
|
|
2348
|
+
* The agent-readiness bundle the BuildBase server publishes for an org at
|
|
2349
|
+
* `GET /api/v1/public/:orgId/agent-readiness`. This is the single source of
|
|
2350
|
+
* truth an org admin edits; everything org-specific below is derived from it.
|
|
2351
|
+
*/
|
|
2352
|
+
interface AgentReadinessBundle {
|
|
2353
|
+
/** False when the org has not enabled agent readiness — everything else absent. */
|
|
2354
|
+
enabled: boolean;
|
|
2355
|
+
/** Pointer to the org's RFC 8414 authorization-server metadata. */
|
|
2356
|
+
authorizationServer?: {
|
|
2357
|
+
issuer: string;
|
|
2358
|
+
metadataUrl: string;
|
|
2359
|
+
};
|
|
2360
|
+
/**
|
|
2361
|
+
* RFC 9728 protected-resource metadata objects, ready to serve. Each `metadata`
|
|
2362
|
+
* is a complete document; `resource` is the canonical resource URI it describes.
|
|
2363
|
+
*/
|
|
2364
|
+
protectedResources?: Array<{
|
|
2365
|
+
resource: string;
|
|
2366
|
+
metadata: Record<string, unknown>;
|
|
2367
|
+
}>;
|
|
2368
|
+
/** Org-authored llms.txt content, or null when unset. */
|
|
2369
|
+
llmsTxt?: string | null;
|
|
2370
|
+
}
|
|
2371
|
+
/** An Agent Skill (Agent Skills Discovery RFC v0.2.0) published by this app. */
|
|
2372
|
+
interface AgentSkill {
|
|
2373
|
+
/** Stable slug, e.g. `imejis-api`. */
|
|
2374
|
+
name: string;
|
|
2375
|
+
/** One-line human/agent-readable summary. */
|
|
2376
|
+
description: string;
|
|
2377
|
+
/** Full markdown content of the SKILL.md served for this skill. */
|
|
2378
|
+
content: string;
|
|
2379
|
+
/**
|
|
2380
|
+
* Path the SKILL.md is served from. Defaults to
|
|
2381
|
+
* `/.well-known/agent-skills/<name>/SKILL.md`.
|
|
2382
|
+
*/
|
|
2383
|
+
path?: string;
|
|
2384
|
+
/** Skill artifact kind. Defaults to `skill-md`. */
|
|
2385
|
+
type?: 'skill-md' | 'archive';
|
|
2386
|
+
}
|
|
2387
|
+
/** Configuration for the agent-readiness discovery layer. */
|
|
2388
|
+
interface AgentReadyConfig {
|
|
2389
|
+
/** BuildBase server base URL, e.g. `https://api.buildbase.app` (no trailing slash needed). */
|
|
2390
|
+
serverUrl: string;
|
|
2391
|
+
/** The org id (24-hex) whose agent-readiness config to serve. */
|
|
2392
|
+
orgId: string;
|
|
2393
|
+
/**
|
|
2394
|
+
* This app's public origin, e.g. `https://imejis.io`. Used to build absolute
|
|
2395
|
+
* URLs in the Agent Card and to match RFC 9728 resource paths.
|
|
2396
|
+
*/
|
|
2397
|
+
siteUrl: string;
|
|
2398
|
+
/** Static metadata for the Agent Card (`/.well-known/agent.json`). */
|
|
2399
|
+
site: {
|
|
2400
|
+
name: string;
|
|
2401
|
+
description?: string;
|
|
2402
|
+
/** Absolute URL to human/agent documentation. */
|
|
2403
|
+
documentationUrl?: string;
|
|
2404
|
+
/** Support/contact email surfaced on the Agent Card. */
|
|
2405
|
+
contactEmail?: string;
|
|
2406
|
+
/** Provider block; defaults to `{ name: site.name, url: siteUrl }`. */
|
|
2407
|
+
provider?: {
|
|
2408
|
+
name: string;
|
|
2409
|
+
url: string;
|
|
2410
|
+
};
|
|
2411
|
+
};
|
|
2412
|
+
/** Agent Skills to publish. Omit to skip the Agent Skills documents. */
|
|
2413
|
+
skills?: AgentSkill[];
|
|
2414
|
+
/** security.txt fields (RFC 9116). Omit to skip serving security.txt. */
|
|
2415
|
+
security?: {
|
|
2416
|
+
/** Contact URI(s) — email (`mailto:`) or URL. */
|
|
2417
|
+
contact: string | string[];
|
|
2418
|
+
/** ISO-8601 expiry; strongly recommended by RFC 9116. */
|
|
2419
|
+
expires?: string;
|
|
2420
|
+
/** Security policy URL. */
|
|
2421
|
+
policy?: string;
|
|
2422
|
+
};
|
|
2423
|
+
/** TTL (seconds) for cached platform fetches. Default 300 (5 min). */
|
|
2424
|
+
cacheTtlSeconds?: number;
|
|
2425
|
+
/** Injectable fetch, mainly for testing. Defaults to the global `fetch`. */
|
|
2426
|
+
fetch?: typeof fetch;
|
|
2427
|
+
}
|
|
2428
|
+
/** A rendered discovery document ready to become an HTTP response. */
|
|
2429
|
+
interface DiscoveryDocument {
|
|
2430
|
+
status: number;
|
|
2431
|
+
contentType: string;
|
|
2432
|
+
body: string;
|
|
2433
|
+
cacheControl: string;
|
|
2434
|
+
}
|
|
2435
|
+
/**
|
|
2436
|
+
* SHA-256 of `content` as `sha256:<hex>`, via the shared pure-JS hash (no Web
|
|
2437
|
+
* Crypto / Node `crypto`), so output is identical on every runtime.
|
|
2438
|
+
*/
|
|
2439
|
+
declare function sha256Digest(content: string): string;
|
|
2440
|
+
/**
|
|
2441
|
+
* Fetch (and cache) an org's agent-readiness bundle from the BuildBase server.
|
|
2442
|
+
*
|
|
2443
|
+
* Fail-soft: any network/HTTP/parse error resolves to `{ enabled: false }` so a
|
|
2444
|
+
* discovery route never 500s and never leaks the platform being down — agents
|
|
2445
|
+
* simply see the app as not (yet) agent-ready.
|
|
2446
|
+
*/
|
|
2447
|
+
declare function fetchAgentReadiness(config: AgentReadyConfig): Promise<AgentReadinessBundle>;
|
|
2448
|
+
/** Clear the in-memory agent-readiness cache (mainly for tests). */
|
|
2449
|
+
declare function clearAgentReadinessCache(): void;
|
|
2450
|
+
/**
|
|
2451
|
+
* The Agent Card served at `/.well-known/agent.json`. A stable, machine-readable
|
|
2452
|
+
* entry point advertising who this app is and where agents can discover more.
|
|
2453
|
+
*/
|
|
2454
|
+
declare function buildAgentCard(config: AgentReadyConfig, bundle: AgentReadinessBundle): DiscoveryDocument;
|
|
2455
|
+
/**
|
|
2456
|
+
* Resolve the RFC 9728 protected-resource metadata for a request path, or null
|
|
2457
|
+
* if no configured resource maps to it.
|
|
2458
|
+
*/
|
|
2459
|
+
declare function buildProtectedResourceMetadata(requestPath: string, config: AgentReadyConfig, bundle: AgentReadinessBundle): DiscoveryDocument | null;
|
|
2460
|
+
/** Agent Skills discovery index (Agent Skills Discovery RFC v0.2.0). */
|
|
2461
|
+
declare function buildAgentSkillsIndex(config: AgentReadyConfig): DiscoveryDocument | null;
|
|
2462
|
+
/** Serve a single skill's SKILL.md by request path, or null if none matches. */
|
|
2463
|
+
declare function buildSkillMd(requestPath: string, config: AgentReadyConfig): DiscoveryDocument | null;
|
|
2464
|
+
/** security.txt (RFC 9116), or null when not configured. */
|
|
2465
|
+
declare function buildSecurityTxt(config: AgentReadyConfig): DiscoveryDocument | null;
|
|
2466
|
+
/** The org-authored llms.txt, or null when the org hasn't set one. */
|
|
2467
|
+
declare function buildLlmsTxt(config: AgentReadyConfig, bundle: AgentReadinessBundle): DiscoveryDocument | null;
|
|
2468
|
+
/**
|
|
2469
|
+
* Resolve any `.well-known` request path to its discovery document, or null if
|
|
2470
|
+
* this app serves nothing there (caller should 404).
|
|
2471
|
+
*
|
|
2472
|
+
* Handles: agent.json, oauth-protected-resource (+ per-resource paths),
|
|
2473
|
+
* oauth-authorization-server (pointer), agent-skills index + SKILL.md,
|
|
2474
|
+
* security.txt.
|
|
2475
|
+
*/
|
|
2476
|
+
declare function resolveWellKnown(requestPath: string, config: AgentReadyConfig): Promise<DiscoveryDocument | null>;
|
|
2477
|
+
|
|
2478
|
+
/**
|
|
2479
|
+
* OAuth2 app-bridge toolkit (server-side).
|
|
2480
|
+
*
|
|
2481
|
+
* BuildBase runs the OAuth2 authorization flow (login, consent, code, PKCE,
|
|
2482
|
+
* refresh rotation) but it never mints the access token itself — on the token
|
|
2483
|
+
* grant it calls the org's own backend to mint the token the agent will carry.
|
|
2484
|
+
* Concretely, the platform makes signed webhook-style calls to two endpoints an
|
|
2485
|
+
* OAuth2 client registers:
|
|
2486
|
+
*
|
|
2487
|
+
* • applicationTokenUrl — mint an access token for a user (required)
|
|
2488
|
+
* • applicationRevokeUrl — invalidate a user's token on revocation (optional)
|
|
2489
|
+
*
|
|
2490
|
+
* Both requests carry an `Authorization: Bearer <JWT>` where the JWT is HS256,
|
|
2491
|
+
* signed with the client's secret (so possession of the secret authenticates
|
|
2492
|
+
* the platform). This module verifies those requests and shapes the responses,
|
|
2493
|
+
* so an implementor writes only the part that is theirs: minting/invalidating a
|
|
2494
|
+
* token in their own format.
|
|
2495
|
+
*
|
|
2496
|
+
* HMAC verification uses the SDK's dependency-free pure-JS HMAC-SHA256 (no Web
|
|
2497
|
+
* Crypto, no Node `crypto`, no `require`), so it behaves identically whether the
|
|
2498
|
+
* bundle is loaded as ESM or CJS, under a bundler or on bare Node.
|
|
2499
|
+
*
|
|
2500
|
+
* @example applicationTokenUrl handler (Next.js Pages Router):
|
|
2501
|
+
* ```ts
|
|
2502
|
+
* import { handleAppTokenRequest } from "@buildbase/sdk";
|
|
2503
|
+
* export default async function handler(req, res) {
|
|
2504
|
+
* const { status, body } = await handleAppTokenRequest({
|
|
2505
|
+
* authorization: req.headers.authorization,
|
|
2506
|
+
* clientSecret: process.env.BUILDBASE_CLIENT_SECRET!,
|
|
2507
|
+
* mintToken: (user) => ({
|
|
2508
|
+
* token: signMyAccessToken(user, { aud: user.resource }), // your token, your format
|
|
2509
|
+
* expiresIn: 3600,
|
|
2510
|
+
* }),
|
|
2511
|
+
* });
|
|
2512
|
+
* res.status(status).json(body);
|
|
2513
|
+
* }
|
|
2514
|
+
* ```
|
|
2515
|
+
*/
|
|
2516
|
+
/** Thrown when an incoming platform request fails verification. */
|
|
2517
|
+
declare class AppBridgeError extends Error {
|
|
2518
|
+
/** Machine-readable reason, e.g. `invalid_signature`, `token_expired`. */
|
|
2519
|
+
readonly code: string;
|
|
2520
|
+
constructor(code: string, message: string);
|
|
2521
|
+
}
|
|
2522
|
+
/**
|
|
2523
|
+
* The user + grant context BuildBase sends to `applicationTokenUrl`. The app
|
|
2524
|
+
* mints a token for this user; `resource` is the RFC 8707 audience(s) the token
|
|
2525
|
+
* should be bound to (stamp them as `aud`), and `scope` is what the user granted.
|
|
2526
|
+
* Unknown claims are preserved for forward-compatibility.
|
|
2527
|
+
*/
|
|
2528
|
+
interface AppTokenRequestClaims {
|
|
2529
|
+
/** The user's id in the org. */
|
|
2530
|
+
id: string;
|
|
2531
|
+
email: string;
|
|
2532
|
+
name?: string;
|
|
2533
|
+
role?: string;
|
|
2534
|
+
emailVerified?: boolean;
|
|
2535
|
+
image?: string;
|
|
2536
|
+
blocked?: boolean;
|
|
2537
|
+
blockedReason?: string;
|
|
2538
|
+
blockedAt?: string;
|
|
2539
|
+
/** Which grant triggered this mint. */
|
|
2540
|
+
grantType?: 'authorization_code' | 'refresh_token';
|
|
2541
|
+
/** Scopes granted at authorization time. */
|
|
2542
|
+
scope?: string[];
|
|
2543
|
+
/** RFC 8707 resource indicator(s) — bind the minted token's `aud` to these. */
|
|
2544
|
+
resource?: string[];
|
|
2545
|
+
/** The OAuth2 client's display title. */
|
|
2546
|
+
clientTitle?: string;
|
|
2547
|
+
[claim: string]: unknown;
|
|
2548
|
+
}
|
|
2549
|
+
/** The payload BuildBase sends to `applicationRevokeUrl`. */
|
|
2550
|
+
interface AppRevokeRequestClaims {
|
|
2551
|
+
userId: string;
|
|
2552
|
+
clientId: string;
|
|
2553
|
+
reason: string;
|
|
2554
|
+
[claim: string]: unknown;
|
|
2555
|
+
}
|
|
2556
|
+
/**
|
|
2557
|
+
* Verify a BuildBase-issued HS256 JWT (signed with the client secret) and return
|
|
2558
|
+
* its payload. Checks the signature (timing-safe), the algorithm, and `exp`/`nbf`.
|
|
2559
|
+
* Throws {@link AppBridgeError} on any failure.
|
|
2560
|
+
*/
|
|
2561
|
+
declare function verifyClientJwt(token: string, clientSecret: string, clockToleranceSec?: number): Record<string, any>;
|
|
2562
|
+
/** Extract the token from an `Authorization: Bearer <token>` header. */
|
|
2563
|
+
declare function extractBearerToken(authorization: string | null | undefined): string | null;
|
|
2564
|
+
interface VerifyOptions {
|
|
2565
|
+
/** The `Authorization` header value from the incoming request. */
|
|
2566
|
+
authorization: string | null | undefined;
|
|
2567
|
+
/** Your OAuth2 client's secret (the signing key). */
|
|
2568
|
+
clientSecret: string;
|
|
2569
|
+
/** Allowed clock skew in seconds for exp/nbf. Default 60. */
|
|
2570
|
+
clockToleranceSec?: number;
|
|
2571
|
+
}
|
|
2572
|
+
/** Verify an `applicationTokenUrl` request and return the user + grant context. */
|
|
2573
|
+
declare function verifyAppTokenRequest(options: VerifyOptions): AppTokenRequestClaims;
|
|
2574
|
+
/** Verify an `applicationRevokeUrl` request and return the revocation context. */
|
|
2575
|
+
declare function verifyAppRevokeRequest(options: VerifyOptions): AppRevokeRequestClaims;
|
|
2576
|
+
/** What your `mintToken` returns: an access token and, ideally, its lifetime. */
|
|
2577
|
+
interface AppTokenResult {
|
|
2578
|
+
/** The access token your app minted (its own format). */
|
|
2579
|
+
token: string;
|
|
2580
|
+
/** Token lifetime in seconds; the platform surfaces it as `expires_in`. */
|
|
2581
|
+
expiresIn?: number;
|
|
2582
|
+
/** Optional human-readable message. */
|
|
2583
|
+
message?: string;
|
|
2584
|
+
}
|
|
2585
|
+
/**
|
|
2586
|
+
* The exact body shape the platform expects from `applicationTokenUrl`
|
|
2587
|
+
* (`{ success, token, message }`, plus optional `expiresIn`; no other keys).
|
|
2588
|
+
*/
|
|
2589
|
+
interface AppTokenResponseBody {
|
|
2590
|
+
success: boolean;
|
|
2591
|
+
token: string;
|
|
2592
|
+
message: string;
|
|
2593
|
+
expiresIn?: number;
|
|
2594
|
+
}
|
|
2595
|
+
/** Build a success body for `applicationTokenUrl`. */
|
|
2596
|
+
declare function appTokenSuccess(result: AppTokenResult): AppTokenResponseBody;
|
|
2597
|
+
/** Build a failure body for `applicationTokenUrl`. */
|
|
2598
|
+
declare function appTokenFailure(message: string): AppTokenResponseBody;
|
|
2599
|
+
/** The `{ status, body }` a framework-agnostic handler returns. */
|
|
2600
|
+
interface HandlerResult<T> {
|
|
2601
|
+
status: number;
|
|
2602
|
+
body: T;
|
|
2603
|
+
}
|
|
2604
|
+
/**
|
|
2605
|
+
* Verify an `applicationTokenUrl` request, mint via your callback, and return
|
|
2606
|
+
* the exact response the platform expects. Returns 401 with a failure body when
|
|
2607
|
+
* verification fails; errors thrown by `mintToken` propagate to you.
|
|
2608
|
+
*
|
|
2609
|
+
* @example
|
|
2610
|
+
* ```ts
|
|
2611
|
+
* const { status, body } = await handleAppTokenRequest({
|
|
2612
|
+
* authorization: req.headers.authorization,
|
|
2613
|
+
* clientSecret: process.env.BUILDBASE_CLIENT_SECRET!,
|
|
2614
|
+
* mintToken: (user) => ({ token: signMyJwt(user, { aud: user.resource }), expiresIn: 3600 }),
|
|
2615
|
+
* });
|
|
2616
|
+
* res.status(status).json(body);
|
|
2617
|
+
* ```
|
|
2618
|
+
*/
|
|
2619
|
+
declare function handleAppTokenRequest(options: {
|
|
2620
|
+
authorization: string | null | undefined;
|
|
2621
|
+
clientSecret: string;
|
|
2622
|
+
mintToken: (claims: AppTokenRequestClaims) => AppTokenResult | Promise<AppTokenResult>;
|
|
2623
|
+
clockToleranceSec?: number;
|
|
2624
|
+
}): Promise<HandlerResult<AppTokenResponseBody>>;
|
|
2625
|
+
/**
|
|
2626
|
+
* Verify an `applicationRevokeUrl` request and run your invalidation callback.
|
|
2627
|
+
* Returns 401 on verification failure; errors thrown by `onRevoke` propagate.
|
|
2628
|
+
*/
|
|
2629
|
+
declare function handleAppRevokeRequest(options: {
|
|
2630
|
+
authorization: string | null | undefined;
|
|
2631
|
+
clientSecret: string;
|
|
2632
|
+
onRevoke: (claims: AppRevokeRequestClaims) => void | Promise<void>;
|
|
2633
|
+
clockToleranceSec?: number;
|
|
2634
|
+
}): Promise<HandlerResult<{
|
|
2635
|
+
success: boolean;
|
|
2636
|
+
message?: string;
|
|
2637
|
+
}>>;
|
|
2638
|
+
/**
|
|
2639
|
+
* Build the 401 an agent should receive when it calls your protected API without
|
|
2640
|
+
* a valid token. The `WWW-Authenticate: Bearer resource_metadata=...` header
|
|
2641
|
+
* points the agent at your `/.well-known/oauth-protected-resource` document,
|
|
2642
|
+
* bootstrapping the OAuth discovery flow (RFC 9728 §5.1, RFC 6750 §3).
|
|
2643
|
+
*
|
|
2644
|
+
* @example
|
|
2645
|
+
* ```ts
|
|
2646
|
+
* if (!isValid(token)) {
|
|
2647
|
+
* const c = bearerChallenge({ resourceMetadataUrl: "https://imejis.io/.well-known/oauth-protected-resource" });
|
|
2648
|
+
* res.writeHead(c.status, c.headers).end(c.body);
|
|
2649
|
+
* }
|
|
2650
|
+
* ```
|
|
2651
|
+
*/
|
|
2652
|
+
declare function bearerChallenge(options: {
|
|
2653
|
+
resourceMetadataUrl: string;
|
|
2654
|
+
error?: 'invalid_token' | 'insufficient_scope' | string;
|
|
2655
|
+
errorDescription?: string;
|
|
2656
|
+
}): {
|
|
2657
|
+
status: number;
|
|
2658
|
+
headers: Record<string, string>;
|
|
2659
|
+
body: string;
|
|
2660
|
+
};
|
|
2661
|
+
|
|
2263
2662
|
interface BuildBaseConfig {
|
|
2264
2663
|
/** Base URL of the BuildBase API server */
|
|
2265
2664
|
serverUrl: string;
|
|
@@ -2544,5 +2943,5 @@ interface BuildBaseResult extends ScopedActions {
|
|
|
2544
2943
|
}
|
|
2545
2944
|
declare function BuildBase(config: BuildBaseConfig): BuildBaseResult;
|
|
2546
2945
|
|
|
2547
|
-
export { ApiVersion, AuthApi, AuthStatus, BBAction, BBScreen, BBStatus, BB_PARAM, BaseApi, BetaForm, BillingIntervals, BuildBase, CURRENCY_DISPLAY, CURRENCY_FLAG, CreditBucketSource, CreditBucketStatus, CreditTransactionType, DEFAULT_ROLE_PERMISSIONS, DunningState, EventEmitter, InvoiceStatuses, PLAN_CURRENCY_CODES, PLAN_CURRENCY_OPTIONS, PUSH_SERVICE_WORKER_SCRIPT, Permission, PushApi, SDKEvent, SettingsApi, SubscriptionItemType, SubscriptionStatus, UserApi, WorkspaceApi, calculateBillableSeats, calculateSeatOverageCents, calculateTotalSubscriptionCents, cleanBBParams, clearAuthIntent, consumeAuthIntent, createBBUrl, createCheckoutRedirectUrls, createCreditPurchaseRedirectUrls, BuildBase as default, eventEmitter, formatCents, formatOverageRate, formatOverageRateWithLabel, formatQuotaIncludedOverage, formatQuotaWithPrice, getAvailableCurrenciesFromPlans, getBasePriceCents, getBillingIntervalAndCurrencyFromPriceId, getCurrencyFlag, getCurrencySymbol, getDisplayCurrency, getPerSeatPriceCents, getPricingVariant, getQuotaDisplayValue, getQuotaDisplayWithVariant, getQuotaOverageCents, getQuotaUnitLabelFromName, getSeatPricing, getStripePriceIdForInterval, hasPermission, invalidateCreditBalance, invalidateQuotaUsage, invalidateSubscription, parseWebhookEvent, readBBParams, resolveMaxUsers, resolvePermissions, safeRedirect, saveAuthIntent, validateInvite, validateRedirectUrl, verifyWebhookSignature };
|
|
2548
|
-
export type { BBActionType, BBScreenType, BBStatusType, BetaFormData, BetaFormResponse, BillingInterval, BuildBaseConfig, BuildBaseResult, BuildBaseSession, CheckoutResult, CreditActions, CreditBucketSourceType, CreditBucketStatusType, CreditTransactionTypeValue, DunningStateType, EventData, EventType, FeatureActions, FormatQuotaWithPriceOptions, GetCheckoutStripeParams, IAllQuotaUsageResponse, IBaseApiConfig, IBasePricing, IBetaConfig, ICheckoutSessionRequest, ICheckoutSessionResponse, ICheckoutStripeOptions, IConsumeCreditsRequest, IConsumeCreditsResponse, ICreditBalance, ICreditBucket, ICreditBucketsQuery, ICreditBucketsResponse, ICreditPackage, ICreditPackagePricingVariant, ICreditPurchaseRequest, ICreditPurchaseResponse, ICreditTransaction, ICreditTransactionsQuery, ICreditTransactionsResponse, IEventCallbacks, IExpiringCreditsResponse, IInvoice, IInvoiceListResponse, IInvoiceResponse, IOsConfig, IOsState, IPlan, IPlanGroup, IPlanGroupInfo, IPlanGroupLatestVersion, IPlanGroupResponse, IPlanGroupVersion, IPlanGroupVersionWithPlans, IPlanGroupVersionsResponse, IPlanVersion, IPlanVersionSummary, IPlanVersionWithPlan, IPricingVariant, IPublicCreditPackage, IPublicCreditPackagesResponse, IPublicPlanItem, IPublicPlanItemCategory, IPublicPlanVersion, IPublicPlansResponse, IQuotaByInterval, IQuotaIntervalValue, IQuotaOveragePriceIdsByInterval, IQuotaOveragesByInterval, IQuotaUsageStatus, IQuotaUsageStatusResponse, IRecordUsageRequest, IRecordUsageResponse, IStripePricesByInterval, ISubscription, ISubscriptionItem, ISubscriptionResponse, ISubscriptionUpdateRequest, ISubscriptionUpdateResponse, IUsageLogEntry, IUsageLogsQuery, IUsageLogsResponse, InviteBlockReason, InviteValidation, InvoiceActions, InvoiceStatus, InvoiceStatusType, MaxUsersConfig, NotificationData, NotificationEvent, NotificationResult, OnWorkspaceChangeParams, PermissionActions, PermissionContext, PermissionKey, PlanActions, PlanVersionWithPricingVariants, QuotaDisplayValue, QuotaDisplayWithOverage, RolePermissionMap, ScopedActions, SettingsActions, SubscriptionActions, SubscriptionItemTypeValue, SubscriptionStatusType, UsageActions, UserActions, UserCreatedEventData, UserUpdatedEventData, WorkspaceActions, WorkspaceChangedEventData, WorkspaceCreatedEventData, WorkspaceDeletedEventData, WorkspaceUpdatedEventData, WorkspaceUserAddedEventData, WorkspaceUserRemovedEventData, WorkspaceUserRoleChangedEventData };
|
|
2946
|
+
export { ApiVersion, AppBridgeError, AuthApi, AuthStatus, BBAction, BBScreen, BBStatus, BB_PARAM, BaseApi, BetaForm, BillingIntervals, BuildBase, CURRENCY_DISPLAY, CURRENCY_FLAG, CreditBucketSource, CreditBucketStatus, CreditTransactionType, DEFAULT_ROLE_PERMISSIONS, DunningState, EventEmitter, InvoiceStatuses, PLAN_CURRENCY_CODES, PLAN_CURRENCY_OPTIONS, PUSH_SERVICE_WORKER_SCRIPT, Permission, PushApi, SDKEvent, SettingsApi, SubscriptionItemType, SubscriptionStatus, UserApi, WorkspaceApi, appTokenFailure, appTokenSuccess, bearerChallenge, buildAgentCard, buildAgentSkillsIndex, buildLlmsTxt, buildProtectedResourceMetadata, buildSecurityTxt, buildSkillMd, calculateBillableSeats, calculateSeatOverageCents, calculateTotalSubscriptionCents, cleanBBParams, clearAgentReadinessCache, clearAuthIntent, consumeAuthIntent, createBBUrl, createCheckoutRedirectUrls, createCreditPurchaseRedirectUrls, BuildBase as default, eventEmitter, extractBearerToken, fetchAgentReadiness, formatCents, formatOverageRate, formatOverageRateWithLabel, formatQuotaIncludedOverage, formatQuotaWithPrice, getAvailableCurrenciesFromPlans, getBasePriceCents, getBillingIntervalAndCurrencyFromPriceId, getCurrencyFlag, getCurrencySymbol, getDisplayCurrency, getPerSeatPriceCents, getPricingVariant, getQuotaDisplayValue, getQuotaDisplayWithVariant, getQuotaOverageCents, getQuotaUnitLabelFromName, getSeatPricing, getStripePriceIdForInterval, handleAppRevokeRequest, handleAppTokenRequest, hasPermission, invalidateCreditBalance, invalidateQuotaUsage, invalidateSubscription, parseWebhookEvent, readBBParams, resolveMaxUsers, resolvePermissions, resolveWellKnown, safeRedirect, saveAuthIntent, sha256Digest, validateInvite, validateRedirectUrl, verifyAppRevokeRequest, verifyAppTokenRequest, verifyClientJwt, verifyWebhookSignature };
|
|
2947
|
+
export type { AgentReadinessBundle, AgentReadyConfig, AgentSkill, AppRevokeRequestClaims, AppTokenRequestClaims, AppTokenResponseBody, AppTokenResult, BBActionType, BBScreenType, BBStatusType, BetaFormData, BetaFormResponse, BillingInterval, BuildBaseConfig, BuildBaseResult, BuildBaseSession, CheckoutResult, CreditActions, CreditBucketSourceType, CreditBucketStatusType, CreditTransactionTypeValue, DiscoveryDocument, DunningStateType, EventData, EventType, FeatureActions, FormatQuotaWithPriceOptions, GetCheckoutStripeParams, HandlerResult, IAllQuotaUsageResponse, IBaseApiConfig, IBasePricing, IBetaConfig, ICheckoutSessionRequest, ICheckoutSessionResponse, ICheckoutStripeOptions, IConsumeCreditsRequest, IConsumeCreditsResponse, ICreditBalance, ICreditBucket, ICreditBucketsQuery, ICreditBucketsResponse, ICreditPackage, ICreditPackagePricingVariant, ICreditPurchaseRequest, ICreditPurchaseResponse, ICreditTransaction, ICreditTransactionsQuery, ICreditTransactionsResponse, IEventCallbacks, IExpiringCreditsResponse, IInvoice, IInvoiceListResponse, IInvoiceResponse, IOsConfig, IOsState, IPlan, IPlanGroup, IPlanGroupInfo, IPlanGroupLatestVersion, IPlanGroupResponse, IPlanGroupVersion, IPlanGroupVersionWithPlans, IPlanGroupVersionsResponse, IPlanVersion, IPlanVersionSummary, IPlanVersionWithPlan, IPricingVariant, IPublicCreditPackage, IPublicCreditPackagesResponse, IPublicPlanItem, IPublicPlanItemCategory, IPublicPlanVersion, IPublicPlansResponse, IQuotaByInterval, IQuotaIntervalValue, IQuotaOveragePriceIdsByInterval, IQuotaOveragesByInterval, IQuotaUsageStatus, IQuotaUsageStatusResponse, IRecordUsageRequest, IRecordUsageResponse, IStripePricesByInterval, ISubscription, ISubscriptionItem, ISubscriptionResponse, ISubscriptionUpdateRequest, ISubscriptionUpdateResponse, IUsageLogEntry, IUsageLogsQuery, IUsageLogsResponse, InviteBlockReason, InviteValidation, InvoiceActions, InvoiceStatus, InvoiceStatusType, MaxUsersConfig, NotificationData, NotificationEvent, NotificationResult, OnWorkspaceChangeParams, PermissionActions, PermissionContext, PermissionKey, PlanActions, PlanVersionWithPricingVariants, QuotaDisplayValue, QuotaDisplayWithOverage, RolePermissionMap, ScopedActions, SettingsActions, SubscriptionActions, SubscriptionItemTypeValue, SubscriptionStatusType, UsageActions, UserActions, UserCreatedEventData, UserUpdatedEventData, WorkspaceActions, WorkspaceChangedEventData, WorkspaceCreatedEventData, WorkspaceDeletedEventData, WorkspaceUpdatedEventData, WorkspaceUserAddedEventData, WorkspaceUserRemovedEventData, WorkspaceUserRoleChangedEventData };
|