corsair 0.1.140 → 0.1.141
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/{browser-delivery-abNAhbHs.d.ts → browser-delivery-cP_cNQRX.d.ts} +1 -1
- package/dist/chunk-BRUFMVTV.js +1 -0
- package/dist/chunk-OFDCTRKH.js +66 -0
- package/dist/client/react/index.d.ts +1 -1
- package/dist/{connect-6OQOR7EK.js → connect-73AAKXSA.js} +1 -1
- package/dist/core.d.ts +4 -4
- package/dist/core.js +1 -1
- package/dist/hub.d.ts +34 -6
- package/dist/hub.js +1 -1
- package/dist/{index-Bl5hyiew.d.ts → index-CiuKIyhJ.d.ts} +1 -1
- package/dist/{index-WeGJYxdg.d.ts → index-t6AHe-A3.d.ts} +7 -1
- package/dist/{index-lld-eEKq.d.ts → index-xRPYZuqr.d.ts} +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.js +1 -1
- package/dist/{loop-VPXWWYUZ.js → loop-5OED2VBJ.js} +1 -1
- package/dist/oauth.d.ts +1 -1
- package/dist/oauth.js +1 -1
- package/dist/orm.js +1 -1
- package/dist/{setup-D4SNGLLD.js → setup-HIFGUGGU.js} +1 -1
- package/dist/{setup-introspect-5ED4PQJT.js → setup-introspect-MFXTQW6T.js} +1 -1
- package/dist/setup.d.ts +2 -2
- package/dist/setup.js +1 -1
- package/dist/{tenant-match-utils-C8YsN0zk.d.ts → tenant-match-utils-Dt8rnWmd.d.ts} +1 -1
- package/dist/tunnel.d.ts +4 -4
- package/dist/tunnel.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-CJYOCGYG.js +0 -66
- package/dist/chunk-LFFWCNRT.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as B,e as R,f as S,g as O}from"./chunk-XPXWKPFZ.js";var H=Symbol.for("corsair:internal"),A=class extends Error{constructor(t="Invalid corsair instance"){super(t),this.name="InvalidCorsairInstanceError"}};function D(e){return typeof e=="object"&&e!==null}function v(e){if(!D(e)||!Array.isArray(e.plugins)||typeof e.kek!="string"||typeof e.multiTenancy!="boolean")return!1;if(e.database===void 0)return!0;if(!D(e.database))return!1;let t=e.database.db;return typeof t=="object"&&t!==null&&typeof t.selectFrom=="function"}function N(e){if(!e||typeof e!="object")return;let r=Object.getOwnPropertyDescriptor(e,H)?.value;return v(r)?r:void 0}function G(e,t){let r=N(e);if(!r)throw t?.()??new A;return r}function W(e,t){return e.plugins.find(r=>r.id===t)}function X(e,t,r){let n=W(e,t);if(!n)throw r(`Plugin '${t}' not found`);return n}function Y(e){return"withTenant"in e&&typeof e.withTenant=="function"}function q(e,t){if(!e||typeof e!="object")return;let r=e[t];return typeof r=="function"?(...n)=>Reflect.apply(r,e,n):void 0}var P={oauth_2:{integration:["client_id","client_secret","redirect_url"],account:["access_token","refresh_token","expires_at","scope","webhook_signature"]},api_key:{integration:[],account:["api_key","webhook_signature"]},bot_token:{integration:[],account:["bot_token","webhook_signature"]},managed:{integration:[],account:["access_token","refresh_token","expires_at","scope","webhook_signature"]},managed_pricing:{integration:[],account:[]}};function j(e){return e==="oauth_2"||e==="api_key"||e==="bot_token"||e==="managed"||e==="managed_pricing"}function V(e){let t=e.options?.authType;return j(t)?t:void 0}function _e(e){return e==="managed_pricing"}function ee(e,t){let r=e.authConfig,n=P[t].account,i=r?.[t]?.account??[];return[...n,...i]}function Fe(e,t){let r=e.authConfig,n=P[t].integration,i=r?.[t]?.integration??[];return[...n,...i]}import{v7 as te}from"uuid";function x(){return te()}import{z as b}from"zod";import{sql as C}from"kysely";function I(e){return e.replace(/'/g,"''")}function K(e){let t=I(e);return C`data->>'${C.raw(t)}'`}function U(e){let t=I(e);return C`(data->>'${C.raw(t)}')::numeric`}function Z(e){let t=I(e);return C`(data->>'${C.raw(t)}')::boolean`}function $(e){let t=I(e);return C`(data->>'${C.raw(t)}')::timestamptz`}function ne(e){if(typeof e=="string")try{return JSON.parse(e)}catch{return e}return e}function M(e){let t=e;for(;t;){if(t instanceof b.ZodOptional||t instanceof b.ZodNullable){t=t._def.innerType;continue}if(t instanceof b.ZodDefault){t=t._def.innerType;continue}break}return t}function re(e){let t=M(e);if(t instanceof b.ZodString)return"string";if(t instanceof b.ZodNumber)return"number";if(t instanceof b.ZodBoolean)return"boolean";if(t instanceof b.ZodDate)return"date"}function ie(e){let t=M(e);if(!(t instanceof b.ZodObject))return{};let r=t.shape,n={};for(let[i,a]of Object.entries(r)){let u=re(a);u&&(n[i]=u)}return n}function oe(e,t,r){if(typeof r=="string")return e.where(t,"=",r);if(typeof r=="object"&&r!==null&&!Array.isArray(r)){let n=r;"equals"in n&&typeof n.equals=="string"&&(e=e.where(t,"=",n.equals)),"contains"in n&&typeof n.contains=="string"&&(e=e.where(t,"like",`%${n.contains}%`)),"startsWith"in n&&typeof n.startsWith=="string"&&(e=e.where(t,"like",`${n.startsWith}%`)),"endsWith"in n&&typeof n.endsWith=="string"&&(e=e.where(t,"like",`%${n.endsWith}`)),"in"in n&&Array.isArray(n.in)&&(e=e.where(t,"in",n.in))}return e}function se(e,t,r){if(typeof r=="number")return e.where(t,"=",r);if(typeof r=="object"&&r!==null&&!Array.isArray(r)){let n=r;typeof n.equals=="number"&&(e=e.where(t,"=",n.equals)),typeof n.gt=="number"&&(e=e.where(t,">",n.gt)),typeof n.gte=="number"&&(e=e.where(t,">=",n.gte)),typeof n.lt=="number"&&(e=e.where(t,"<",n.lt)),typeof n.lte=="number"&&(e=e.where(t,"<=",n.lte)),Array.isArray(n.in)&&(e=e.where(t,"in",n.in))}return e}function ae(e,t,r){if(typeof r=="boolean")return e.where(t,"=",r);if(typeof r=="object"&&r!==null&&!Array.isArray(r)){let n=r;typeof n.equals=="boolean"&&(e=e.where(t,"=",n.equals))}return e}function ue(e,t,r){if(r instanceof Date)return e.where(t,"=",r);if(typeof r=="object"&&r!==null&&!Array.isArray(r)){let n=r;if(n.equals instanceof Date&&(e=e.where(t,"=",n.equals)),n.before instanceof Date&&(e=e.where(t,"<",n.before)),n.after instanceof Date&&(e=e.where(t,">",n.after)),Array.isArray(n.between)&&n.between.length===2){let[i,a]=n.between;i instanceof Date&&(e=e.where(t,">=",i)),a instanceof Date&&(e=e.where(t,"<=",a))}}return e}function ce(e,t,r,n){return r==="number"?se(e,U(t),n):r==="boolean"?ae(e,Z(t),n):r==="date"?ue(e,$(t),n):oe(e,K(t),n)}function de(e,t,r){if(typeof r=="object"&&r!==null&&!Array.isArray(r)){let n=r;return"equals"in n&&(e=e.where(t,"=",n.equals)),"contains"in n&&typeof n.contains=="string"&&(e=e.where(t,"like",`%${n.contains}%`)),"startsWith"in n&&typeof n.startsWith=="string"&&(e=e.where(t,"like",`${n.startsWith}%`)),"endsWith"in n&&typeof n.endsWith=="string"&&(e=e.where(t,"like",`%${n.endsWith}`)),"in"in n&&Array.isArray(n.in)&&(e=e.where(t,"in",n.in)),e}return e.where(t,"=",r)}function le(e){return typeof e=="number"?e:typeof e=="bigint"?Number(e):Number.parseInt(String(e??0),10)}function T(e,t,r){return e.selectFrom("corsair_entities").selectAll().where("account_id","=",t).where("entity_type","=",r)}function Q(e,t,r,n,i){let a=ie(i);function u(o){let l=ne(o.data);return{...o,data:i.parse(l)}}return{findByEntityId:async o=>{let l=await t(),c=await T(e,l,r).where("entity_id","=",o).executeTakeFirst();return c?u(c):null},existsByEntityId:async o=>{let l=await t();return await T(e,l,r).select("id").where("entity_id","=",o).executeTakeFirst()!==void 0},findIdByEntityId:async o=>{let l=await t();return(await T(e,l,r).select("id").where("entity_id","=",o).executeTakeFirst())?.id??null},findById:async o=>{let l=await t(),c=await T(e,l,r).where("id","=",o).executeTakeFirst();return c?u(c):null},findManyByEntityIds:async o=>{if(o.length===0)return[];let l=await t();return(await T(e,l,r).where("entity_id","in",o).execute()).map(u)},list:async o=>{let l=await t(),c=T(e,l,r);return typeof o?.limit=="number"&&(c=c.limit(o.limit)),typeof o?.offset=="number"&&(c=c.offset(o.offset)),(await c.execute()).map(u)},search:async o=>{let l=await t(),c=T(e,l,r),d=new Set(["data","limit","offset"]);for(let[y,f]of Object.entries(o))d.has(y)||f===void 0||(c=de(c,y,f));if(o.data&&typeof o.data=="object")for(let[y,f]of Object.entries(o.data)){if(f===void 0)continue;let g=a[y]??"string";c=ce(c,y,g,f)}return typeof o.limit=="number"&&(c=c.limit(o.limit)),typeof o.offset=="number"&&(c=c.offset(o.offset)),(await c.execute()).map(u)},upsertByEntityId:async(o,l)=>{let c=await t(),d=i.parse(l),s=new Date,y=await T(e,c,r).select("id").where("entity_id","=",o).executeTakeFirst();if(y?.id){await e.updateTable("corsair_entities").set({version:n,data:d,updated_at:s}).where("id","=",y.id).execute();let _=await e.selectFrom("corsair_entities").selectAll().where("id","=",y.id).executeTakeFirst();return u(_)}let f=x();await e.insertInto("corsair_entities").values({id:f,created_at:s,updated_at:s,account_id:c,entity_id:o,entity_type:r,version:n,data:d}).execute();let g=await e.selectFrom("corsair_entities").selectAll().where("id","=",f).executeTakeFirst();return u(g)},deleteById:async o=>{let l=await t(),c=await e.deleteFrom("corsair_entities").where("account_id","=",l).where("entity_type","=",r).where("id","=",o).executeTakeFirst();return Number(c.numDeletedRows)>0},deleteByEntityId:async o=>{let l=await t(),c=await e.deleteFrom("corsair_entities").where("account_id","=",l).where("entity_type","=",r).where("entity_id","=",o).executeTakeFirst();return Number(c.numDeletedRows)>0},count:async()=>{let o=await t(),l=await e.selectFrom("corsair_entities").select(c=>c.fn.countAll().as("count")).where("account_id","=",o).where("entity_type","=",r).executeTakeFirst();return le(l?.count)}}}var ye={corsair_integrations:B,corsair_accounts:R,corsair_entities:S,corsair_events:O};function fe(e){return ye[e]}function z(e){if(typeof e=="string")try{return JSON.parse(e)}catch{return e}return e}function p(e){if(!e)throw new Error("Corsair database is not configured. Pass `database` to createCorsair(...) to enable ORM.")}function k(e){if(!e)return[];let t=[];for(let r in e){let n=r,i=e[n];if(i!==void 0)if(typeof i=="object"&&i!==null&&!Array.isArray(i)&&!(i instanceof Date)){let a=i;"in"in a&&Array.isArray(a.in)?t.push({field:n,operator:"in",value:a.in}):"like"in a&&typeof a.like=="string"&&t.push({field:n,operator:"like",value:a.like})}else t.push({field:n,value:i})}return t}function m(e,t){if(!t?.length)return e;let r=e;for(let n of t){let i=n.operator??"=";r=r.where(n.field,i,n.value)}return r}function pe(e){return typeof e=="number"?e:typeof e=="bigint"?Number(e):Number.parseInt(String(e??0),10)}function E(e,t){let r=fe(t),n=()=>(p(e),e),i=()=>n().db.selectFrom(t),a=()=>n().db.insertInto(t),u=()=>n().db.updateTable(t),o=()=>n().db.deleteFrom(t);function l(d){let s={};for(let[y,f]of Object.entries(d))s[y]=z(f);return r.parse(s)}function c(d){let s={};for(let[y,f]of Object.entries(d))s[y]=z(f);return r.parse(s)}return{findById:async d=>{p(e);let s=i().selectAll();s=m(s,[{field:"id",value:d}]);let y=await s.executeTakeFirst();return y?l(y):null},findOne:async d=>{p(e);let s=i().selectAll();s=m(s,k(d));let y=await s.executeTakeFirst();return y?l(y):null},findMany:async d=>{p(e);let s=i().selectAll();return s=m(s,k(d?.where)),typeof d?.limit=="number"&&(s=s.limit(d.limit)),typeof d?.offset=="number"&&(s=s.offset(d.offset)),(await s.execute()).map(f=>l(f))},create:async d=>{p(e);let s=new Date,y={id:d.id??x(),created_at:s,updated_at:s,...d},f=await a().values(y).returningAll().executeTakeFirst();return f?l(f):c(y)},update:async(d,s)=>{p(e);let y={...s,updated_at:new Date},f=u().set(y).returningAll();f=m(f,[{field:"id",value:d}]);let g=await f.executeTakeFirst();return g?l(g):null},updateMany:async(d,s)=>{p(e);let y={...s,updated_at:new Date},f=i().select("id");f=m(f,k(d));let g=await f.execute();for(let _ of g){let F=u().set(y);F=m(F,[{field:"id",value:_.id}]),await F.execute()}return g.length},delete:async d=>{p(e);let s=o();s=m(s,[{field:"id",value:d}]);let y=await s.executeTakeFirst();return Number(y?.numDeletedRows??0)>0},deleteMany:async d=>{p(e);let s=o();s=m(s,k(d));let y=await s.executeTakeFirst();return Number(y?.numDeletedRows??0)},count:async d=>{p(e);let s=i().select(f=>f.fn.countAll().as("count"));s=m(s,k(d));let y=await s.executeTakeFirst();return pe(y?.count)}}}function ge(e){let t=E(e,"corsair_integrations");return{...t,findByName:r=>t.findOne({name:r}),upsertByName:async(r,n)=>{let i=await t.findOne({name:r});return i?await t.update(i.id,n):t.create({...n,name:r})}}}function me(e){let t=E(e,"corsair_accounts");return{...t,findByTenantAndIntegration:async(r,n)=>{p(e);let i=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();return i?t.findOne({tenant_id:r,integration_id:i.id}):null},listByTenant:(r,n)=>t.findMany({where:{tenant_id:r},limit:n?.limit,offset:n?.offset}),upsertByTenantAndIntegration:async(r,n,i)=>{let a=await t.findOne({tenant_id:r,integration_id:n});return a?await t.update(a.id,i):t.create({...i,tenant_id:r,integration_id:n})}}}function we(e){let t=E(e,"corsair_entities");return{...t,findByEntityId:({accountId:r,entityType:n,entityId:i})=>t.findOne({account_id:r,entity_type:n,entity_id:i}),findManyByEntityIds:async({accountId:r,entityType:n,entityIds:i})=>i.length===0?[]:(p(e),await e.db.selectFrom("corsair_entities").selectAll().where("account_id","=",r).where("entity_type","=",n).where("entity_id","in",i).execute()),listByScope:({accountId:r,entityType:n,limit:i,offset:a})=>t.findMany({where:{account_id:r,entity_type:n},limit:i,offset:a}),searchByEntityId:async({accountId:r,entityType:n,query:i,limit:a,offset:u})=>{p(e);let o=e.db.selectFrom("corsair_entities").selectAll().where("account_id","=",r).where("entity_type","=",n).where("entity_id","like",`%${i}%`);return typeof a=="number"&&(o=o.limit(a)),typeof u=="number"&&(o=o.offset(u)),await o.execute()},upsertByEntityId:async({accountId:r,entityType:n,entityId:i,version:a,data:u})=>{let o=await t.findOne({account_id:r,entity_type:n,entity_id:i});return o?await t.update(o.id,{version:a,data:u}):t.create({account_id:r,entity_type:n,entity_id:i,version:a,data:u})},deleteByEntityId:async({accountId:r,entityType:n,entityId:i})=>{p(e);let a=await e.db.deleteFrom("corsair_entities").where("account_id","=",r).where("entity_type","=",n).where("entity_id","=",i).executeTakeFirst();return Number(a.numDeletedRows)>0}}}function he(e){let t=E(e,"corsair_events");return{...t,listByAccount:(r,n)=>t.findMany({where:{account_id:r},limit:n?.limit,offset:n?.offset}),listByStatus:(r,n)=>{let i={status:r};return n?.accountId&&(i.account_id=n.accountId),t.findMany({where:i,limit:n?.limit,offset:n?.offset})},listPending:r=>{let n={status:"pending"};return r?.accountId&&(n.account_id=r.accountId),t.findMany({where:n,limit:r?.limit??100})},updateStatus:(r,n)=>t.update(r,{status:n})}}function L(e){return{integrations:ge(e),accounts:me(e),entities:we(e),events:he(e)}}function Ce(e,t,r,n,i){let a=null;async function u(){if(a!==null)return a;p(e);let o=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",t.integrationName).executeTakeFirst();if(!o)throw new Error(`Integration "${t.integrationName}" not found. Make sure to create the integration first.`);let l=await e.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t.tenantId).where("integration_id","=",o.id).executeTakeFirst();if(!l)throw new Error(`Account not found for tenant "${t.tenantId}" and integration "${t.integrationName}". Make sure to create the account first.`);return a=l.id,a}return p(e),Q(e.db,u,r,n,i)}function J(e){let{database:t,integrationName:r,schema:n,tenantId:i}=e,a=L(t),u={tenantId:i,integrationName:r},o=null;async function l(){if(o!==null)return o;p(t);let d=await t.db.selectFrom("corsair_integrations").selectAll().where("name","=",r).executeTakeFirst();if(!d)throw new Error(`Integration "${r}" not found. Make sure to create the integration first.`);let s=await t.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",i).where("integration_id","=",d.id).executeTakeFirst();if(!s)throw new Error(`Account not found for tenant "${i}" and integration "${r}". Make sure to create the account first.`);return o=s.id,o}let c={};for(let[d,s]of Object.entries(n.entities))c[d]=Ce(t,u,d,n.version,s);return{...c,$orm:a,$integrationName:r,$tenantId:i,$getAccountId:l}}function qe(e,t){let r=L(e);return{$tenantId:t,$orm:r,listAccounts:n=>r.accounts.listByTenant(t,n),findAccountByIntegration:n=>r.accounts.findByTenantAndIntegration(t,n),listEntities:async n=>{p(e);let i=await e.db.selectFrom("corsair_accounts").select("id").where("tenant_id","=",t).execute();if(i.length===0)return[];let a=i.map(o=>o.id),u=e.db.selectFrom("corsair_entities").selectAll().where("account_id","in",a);return n?.entityType&&(u=u.where("entity_type","=",n.entityType)),typeof n?.limit=="number"&&(u=u.limit(n.limit)),typeof n?.offset=="number"&&(u=u.offset(n.offset)),await u.execute()},listEvents:async n=>{p(e);let i=await e.db.selectFrom("corsair_accounts").select("id").where("tenant_id","=",t).execute();if(i.length===0)return[];let a=i.map(o=>o.id),u=e.db.selectFrom("corsair_events").selectAll().where("account_id","in",a);return n?.status&&(u=u.where("status","=",n.status)),typeof n?.limit=="number"&&(u=u.limit(n.limit)),typeof n?.offset=="number"&&(u=u.offset(n.offset)),await u.execute()},forIntegration:n=>J({database:e,integrationName:n.integrationName,schema:n.schema,tenantId:t})}}function Ve(e,t){return{forTenant:r=>J({database:e,integrationName:t.integrationName,schema:t.schema,tenantId:r})}}export{A as a,D as b,N as c,G as d,X as e,Y as f,q as g,P as h,V as i,_e as j,ee as k,Fe as l,x as m,Q as n,ye as o,L as p,J as q,qe as r,Ve as s};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import{a as xe,b as ar,c as cr}from"./chunk-6IURNA4L.js";import{a as Vo,b as zn}from"./chunk-QAK6BJXE.js";import{a as Xo,b as Ie,c as ei,d as T,e as K,f as ni,g as ee,h as j,i as _,j as ti,k as Jn,l as ri,m as nn,n as sr,o as oi}from"./chunk-BRUFMVTV.js";import{b as Yo,c as Qo}from"./chunk-XPXWKPFZ.js";import{ZodBoolean as Od,ZodDate as Hd,ZodEnum as Bd,ZodNullable as Ud,ZodNumber as Fd,ZodObject as Ld,ZodOptional as Nd,ZodRecord as $d,ZodString as Wd,ZodType as jd}from"zod";var Vn=["ably","abstract","abuseipdb","abyssale","accrediblecertificates","activecampaign","activetrail","addresszen","aeroleads","affinda","agencyzoom","agentmail","agentql","agenty","agiled","agilitycms","ahrefs","aimlapi","airtable","aivoov","alchemy","algolia","allimagesai","alphavantage","altoviz","alttextai","amara","ambee","ambientweather","amcards","amplitude","anchorbrowser","anonyflow","anthropicadministrator","apaleo","api2pdf","apibible","apify","apilabz","apininjas","apipie","apisports","appointo","aryn","asana","ascora","ashby","asindataapi","asticaai","asyncinterview","attio","autom","ayrshare","backendless","bannerbear","bart","basecamp","baselinker","basin","beaconstac","beamer","beeminder","benchmarkemail","bestbuy","bettercontact","betterproposals","betterstack","bigdatacloud","bigmailer","bigml","bigpictureio","bitbucket","bitwarden","blazemeter","blocknative","bluesky","boldsign","boloforms","boltiot","bonsai","bookingmood","booqable","borneo","botbaba","botpress","botsonic","bouncer","box","boxhero","brandfetch","breathehr","brevo","brex","brightdata","browseai","browserless","browsertool","bubble","bugsnag","buildkite","bunnycdn","byteforms","cal","calendly","campaigncleaner","campayn","canny","canva","canvas","capsulecrm","carbone","castingwords","cdrplatform","certifier","chaser","chatbotkit","chatfai","chmeetings","cincopa","circleci","classmarker","clickhouse","clickmeeting","clientary","clockify","cloudcart","cloudflare","cloudflareapikey","cloudinary","cody","coinbase","collegefootballdata","confluence","connecteam","contentfulgraphql","contextsevenmcp","convoloai","cosmic","countdownapi","crowterminal","currentsapi","cursor","customerio","customgpt","dadataru","databricks","datadog","datarobot","deepseek","devinmcp","diffbot","digitalocean","discord","dockerhub","docupost","dodopayments","doppler","dovetail","dreamstudio","dripcel","dropbox","dropboxsign","dynapictures","emelia","epicgames","everhour","exa","exist","extractaai","facebook","faraday","figma","filevine","filloutforms","firecrawl","fireflies","flexisign","flutterwave","formbricks","gemini","giphy","github","gitlab","gladia","gmail","googleaddressvalidation","googleanalytics","googlebigquery","googlecalendar","googlecloudvision","googledocs","googledrive","googlemaps","googlemeet","googlesheets","grafana","griptape","groqcloud","habitica","hackernews","harvest","hashnode","here","heygen","hookdeck","htmltoimage","hubspot","huggingface","imagior","humanitix","imejisio","imgbb","insightoai","instagram","intercom","jigsawstack","jira","kaggle","kibana","leexi","linear","linkedin","loyverse","mailboxlayer","mailcheck","mailchimp","mailtrap","marketstack","merriamwebsterdict","monday","neon","nextdns","northflank","notion","ocrspace","ocrwebservice","ollama","onedrive","onepassword","openai","openrouter","openweathermap","oura","outlook","pagerduty","parseur","pdfco","pdfmonkey","perplexityai","phantombuster","pinecone","plain","posthog","postman","prisma","pushbullet","razorpay","reddit","reducto","replicate","removebg","replyio","resend","retailed","rootly","runpod","salesforce","sapsuccessfactors","scaleai","scrapegraphai","securitytrails","semanticscholar","sendgrid","sentry","serpapi","sharepoint","slack","snapchat","slackbot","sourcegraph","spoki","spotify","strava","streamtime","stripe","studiobyai21labs","supabase","supadata","synthflowai","tally","tavily","tavilymcp","teams","telegram","textrazor","ticktick","timecamp","timelink","tinyurl","tisane","todoist","toggl","tokenmetrics","tpscheck","trello","tripadvisor","twentyonerisk","twilio","twitter","twitterapiio","twochat","typeform","unione","uniswapapi","uploadcare","vapi","vercel","veriphone","vestaboard","waboxapp","wakatime","webflow","webscrapingai","webvizio","whatsapp","whoisfreaks","whautomate","winstonai","witai","wix","wiza","workday","workiom","worldnewsapi","xero","writer","xquik","youcom","youtube","zendesk","zenserp","zohobigin","zohoinventory","zohomail","zoom","zoominfo"],ii={ably:"Ably",abstract:"Abstract",abuseipdb:"AbuseIPDB",abyssale:"Abyssale",accrediblecertificates:"Accredible Certificates",activecampaign:"ActiveCampaign",activetrail:"Active Trail",addresszen:"Addresszen",aeroleads:"Aeroleads",affinda:"Affinda",agencyzoom:"AgencyZoom",agentmail:"AgentMail",agentql:"AgentQL",agenty:"Agenty",agiled:"Agiled",agilitycms:"Agility CMS",ahrefs:"Ahrefs",aimlapi:"AI/ML API",airtable:"Airtable",aivoov:"AiVOOV",alchemy:"Alchemy",algolia:"Algolia",allimagesai:"All Images AI",alphavantage:"Alpha Vantage",altoviz:"Altoviz",alttextai:"AltText.ai",amara:"Amara",ambee:"Ambee",ambientweather:"Ambient Weather",amcards:"AMcards",amplitude:"Amplitude",anchorbrowser:"Anchor Browser",anonyflow:"Anonyflow",anthropicadministrator:"Anthropic Administrator",apaleo:"Apaleo",api2pdf:"API2PDF",apibible:"API.Bible",apify:"Apify",apilabz:"API Labz",apininjas:"API Ninjas",apipie:"APIpie AI",apisports:"API-Sports",appointo:"Appointo",aryn:"Aryn",asana:"Asana",ascora:"Ascora",ashby:"Ashby",asindataapi:"ASIN Data API",asticaai:"Astica AI",asyncinterview:"Async Interview",attio:"Attio",autom:"Autom",ayrshare:"Ayrshare",backendless:"Backendless",bannerbear:"Bannerbear",bart:"BART",basecamp:"Basecamp",baselinker:"BaseLinker",basin:"Basin",beaconstac:"Beaconstac",beamer:"Beamer",beeminder:"Beeminder",benchmarkemail:"BenchmarkEmail",bestbuy:"Best Buy",bettercontact:"BetterContact",betterproposals:"Better Proposals",betterstack:"Better Stack",bigdatacloud:"BigDataCloud",bigmailer:"BigMailer",bigml:"BigML",bigpictureio:"BigPicture.io",bitbucket:"Bitbucket",bitwarden:"Bitwarden",blazemeter:"BlazeMeter",blocknative:"Blocknative",bluesky:"Bluesky",boldsign:"Boldsign",boloforms:"Boloforms",boltiot:"Bolt IoT",bonsai:"Bonsai",bookingmood:"Bookingmood",booqable:"Booqable",borneo:"Borneo",botbaba:"Botbaba",botpress:"Botpress",botsonic:"Botsonic",bouncer:"Bouncer",box:"Box",boxhero:"BoxHero",brandfetch:"Brandfetch",breathehr:"Breathe HR",brevo:"Brevo",brex:"Brex",brightdata:"Bright Data",browseai:"Browse AI",browserless:"Browserless",browsertool:"Browser Tool",bubble:"Bubble",bugsnag:"BugSnag",buildkite:"Buildkite",bunnycdn:"Bunnycdn",byteforms:"ByteForms",cal:"Cal",calendly:"Calendly",campaigncleaner:"Campaign Cleaner",campayn:"Campayn",canny:"Canny",canva:"Canva",canvas:"Canvas LMS",capsulecrm:"Capsule CRM",carbone:"Carbone",castingwords:"CastingWords",cdrplatform:"CDR Platform",certifier:"Certifier",chaser:"Chaser",chatbotkit:"ChatBotKit",chatfai:"ChatFAI",chmeetings:"ChMeetings",cincopa:"Cincopa",circleci:"CircleCI",classmarker:"ClassMarker",clickhouse:"Clickhouse",clickmeeting:"ClickMeeting",clientary:"Clientary",clockify:"Clockify",cloudcart:"CloudCart",cloudflare:"Cloudflare",cloudflareapikey:"Cloudflare API Key",cloudinary:"Cloudinary",cody:"Cody",coinbase:"Coinbase",collegefootballdata:"College Football Data",confluence:"Confluence",connecteam:"Connecteam",contentfulgraphql:"Contentful GraphQL",contextsevenmcp:"Context7",convoloai:"ConvoloAi",cosmic:"Cosmic",countdownapi:"Countdown API",crowterminal:"CrowTerminal",currentsapi:"CurrentsApi",cursor:"Cursor",customerio:"Customer.io",customgpt:"CustomGPT",dadataru:"Dadataru",databricks:"Databricks",datadog:"Datadog",datarobot:"DataRobot",deepseek:"DeepSeek",devinmcp:"Devin MCP",diffbot:"Diffbot",digitalocean:"DigitalOcean",discord:"Discord",dockerhub:"Docker Hub",docupost:"Docupost",dodopayments:"Dodo Payments",doppler:"Doppler",dovetail:"Dovetail",dreamstudio:"DreamStudio",dripcel:"Dripcel",dropbox:"Dropbox",dropboxsign:"Dropbox Sign",dynapictures:"Dynapictures",emelia:"Emelia",epicgames:"Epic Games",everhour:"Everhour",exa:"Exa",exist:"Exist",extractaai:"Extracta.ai",facebook:"Facebook",faraday:"Faraday",figma:"Figma",filevine:"Filevine",filloutforms:"FilloutForms",firecrawl:"Firecrawl",fireflies:"Fireflies",flexisign:"Flexisign",flutterwave:"Flutterwave",formbricks:"Formbricks",gemini:"Gemini",giphy:"Giphy",github:"GitHub",gitlab:"GitLab",gladia:"Gladia",gmail:"Gmail",googleaddressvalidation:"Google Address Validation",googleanalytics:"Google Analytics",googlebigquery:"Google BigQuery",googlecalendar:"Google Calendar",googlecloudvision:"Google Cloud Vision",googledocs:"Google Docs",googledrive:"Google Drive",googlemaps:"Google Maps",googlemeet:"Google Meet",googlesheets:"Google Sheets",grafana:"Grafana",griptape:"Griptape",groqcloud:"GroqCloud",habitica:"Habitica",hackernews:"Hacker News",harvest:"Harvest",hashnode:"Hashnode",here:"HERE",heygen:"HeyGen",hookdeck:"Hookdeck",htmltoimage:"HtmlToImage",hubspot:"HubSpot",huggingface:"Hugging Face",imagior:"Imagior",humanitix:"Humanitix",imejisio:"Imejis.io",imgbb:"ImgBB",insightoai:"Insighto.ai",instagram:"Instagram",intercom:"Intercom",jigsawstack:"JigsawStack",jira:"Jira",kaggle:"Kaggle",kibana:"Kibana",leexi:"Leexi",linear:"Linear",linkedin:"LinkedIn",loyverse:"Loyverse",mailboxlayer:"MailboxLayer",mailcheck:"Mailcheck",mailchimp:"Mailchimp",mailtrap:"Mailtrap",marketstack:"Marketstack",merriamwebsterdict:"Merriam-Webster Dictionary",monday:"Monday",neon:"Neon",nextdns:"NextDNS",northflank:"Northflank",notion:"Notion",ocrspace:"OCR.space",ocrwebservice:"OcrWebService",ollama:"Ollama",onedrive:"OneDrive",onepassword:"1Password",openai:"OpenAI",openrouter:"OpenRouter",openweathermap:"OpenWeatherMap",oura:"Oura",outlook:"Outlook",pagerduty:"PagerDuty",parseur:"Parseur",pdfco:"PDF.co",pdfmonkey:"PDFMonkey",perplexityai:"Perplexity AI",phantombuster:"PhantomBuster",pinecone:"Pinecone",plain:"Plain",posthog:"PostHog",postman:"Postman",prisma:"Prisma",pushbullet:"Pushbullet",razorpay:"Razorpay",reddit:"Reddit",reducto:"Reducto",replicate:"Replicate",removebg:"remove.bg",replyio:"Reply.io",resend:"Resend",retailed:"Retailed",rootly:"Rootly",runpod:"RunPod",salesforce:"Salesforce",sapsuccessfactors:"SAP SuccessFactors",scaleai:"Scale AI",scrapegraphai:"ScrapeGraphAI",securitytrails:"SecurityTrails",semanticscholar:"Semantic Scholar",sendgrid:"SendGrid",sentry:"Sentry",serpapi:"Serpapi",sharepoint:"SharePoint",slack:"Slack",snapchat:"Snapchat",slackbot:"Slackbot",sourcegraph:"Sourcegraph",spoki:"Spoki",spotify:"Spotify",strava:"Strava",streamtime:"Streamtime",stripe:"Stripe",studiobyai21labs:"StudioByAI21Labs",supabase:"Supabase",supadata:"Supadata",synthflowai:"Synthflow AI",tally:"Tally",tavily:"Tavily",tavilymcp:"Tavily MCP",teams:"Teams",telegram:"Telegram",textrazor:"TextRazor",ticktick:"TickTick",timecamp:"TimeCamp",timelink:"Timelink",tinyurl:"TinyURL",tisane:"Tisane",todoist:"Todoist",toggl:"Toggl",tokenmetrics:"Token Metrics",tpscheck:"TPSCheck",trello:"Trello",tripadvisor:"Tripadvisor",twentyonerisk:"TwentyOneRisk",twilio:"Twilio",twitter:"Twitter",twitterapiio:"Twitter API IO",twochat:"TwoChat",typeform:"Typeform",unione:"Unione",uniswapapi:"Uniswap",uploadcare:"Uploadcare",vapi:"Vapi",vercel:"Vercel",veriphone:"Veriphone",vestaboard:"Vestaboard",waboxapp:"Waboxapp",wakatime:"WakaTime",webflow:"Webflow",webscrapingai:"WebScraping.AI",webvizio:"Webvizio",whatsapp:"WhatsApp",whoisfreaks:"Whoisfreaks",whautomate:"Whautomate",winstonai:"Winston AI",witai:"WitAi",wix:"Wix",wiza:"Wiza",workday:"Workday",workiom:"Workiom",worldnewsapi:"World News API",xero:"Xero",writer:"Writer",xquik:"XQuik",youcom:"You.com",youtube:"YouTube",zendesk:"Zendesk",zenserp:"Zenserp",zohobigin:"Zoho Bigin",zohoinventory:"Zoho Inventory",zohomail:"Zoho Mail",zoom:"Zoom",zoominfo:"ZoomInfo"};function Se(e){let n=ii[e];return n||e.charAt(0).toUpperCase()+e.slice(1)}var ye=class extends Error{connectUrl;plugin;tenantId;reason;constructor(n){super(n.message??"Reconnect required"),Object.setPrototypeOf(this,new.target.prototype),this.name="ReconnectRequiredError",this.connectUrl=n.connectUrl,this.plugin=n.plugin,this.tenantId=n.tenantId,this.reason=n.reason}};function E(e){return typeof e=="string"&&e.length>0}function ec(e){return e==="ready"||e==="partial"||e==="not_started"||e==="missing_integration"}function nc(e){return e==="oauth_2"||e==="api_key"||e==="bot_token"||e==="managed"||e==="managed_pricing"}function Yn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty connect session");let n=e;if(!E(n.connectUrl)||!E(n.token)||!E(n.projectId))throw new Error("Hub API returned an incomplete connect session (expected connectUrl, token, and projectId)");let t={connectUrl:n.connectUrl,token:n.token,projectId:n.projectId,environmentId:E(n.environmentId)?n.environmentId:n.projectId};return E(n.expiresAt)&&(t.expiresAt=n.expiresAt),t}function Qn(e){if(!Array.isArray(e))throw new Error("Hub API returned an invalid connections response (expected array)");let n=[];for(let t of e){if(!t||typeof t!="object")continue;let r=t;if(!E(r.tenantId)||!E(r.plugin)||!ec(r.status)||!nc(r.authType)||typeof r.connected!="boolean"||typeof r.verified!="boolean")continue;let o=Array.isArray(r.missingFields)?r.missingFields.filter(i=>typeof i=="string"):[];n.push({tenantId:r.tenantId,plugin:r.plugin,status:r.status,authType:r.authType,connected:r.connected,verified:r.verified,missingFields:o,reportedAt:E(r.reportedAt)?r.reportedAt:new Date().toISOString()})}return n}function Xn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty permission session");let n=e;if(!E(n.approvalUrl)||!E(n.token)||!E(n.projectId)||!E(n.expiresAt))throw new Error("Hub API returned an incomplete permission session (expected approvalUrl, token, projectId, and expiresAt)");return{approvalUrl:n.approvalUrl,token:n.token,projectId:n.projectId,expiresAt:n.expiresAt}}function tn(e){if(!e||typeof e!="object")throw new Error("Hub token refresh returned an empty response");let n=e;if(E(n.access_token))return{access_token:n.access_token,refresh_token:E(n.refresh_token)?n.refresh_token:void 0,expires_in:(()=>{if(typeof n.expires_in=="number")return n.expires_in;if(typeof n.expires_in=="string"&&n.expires_in.trim().length>0){let t=Number(n.expires_in);return Number.isFinite(t)?t:void 0}})(),scope:E(n.scope)?n.scope:void 0};throw new Error(E(n.error)?E(n.error_description)?n.error_description:n.error:"Hub token refresh returned no access_token")}function tc(e){return Array.isArray(e)?e.filter(n=>typeof n=="string"):[]}function rc(e){if(!Array.isArray(e))return[];let n=[];for(let t of e){if(!t||typeof t!="object")continue;let r=t;E(r.name)&&n.push({name:r.name,level:r.level==="integration"||r.level==="account"?r.level:"account",required:r.required===!0,configured:r.configured===!0})}return n}function oc(e,n,t,r){return e==="ready"||e==="partial"||e==="not_started"||e==="missing_integration"?e:n?"ready":t.some(i=>i.level==="integration"&&i.required&&!i.configured)?"missing_integration":t.some(i=>i.level==="account"&&i.required&&i.configured)?"partial":(r.length>0,"not_started")}function si(e){if(!e||typeof e!="object")throw new Error("Connect status response was empty");let n=e;if(!E(n.tenantId)||!Array.isArray(n.plugins))throw new Error("Connect status response was incomplete (expected tenantId and plugins)");let t=[];for(let r of n.plugins){if(!r||typeof r!="object")continue;let o=r;if(!E(o.plugin)||typeof o.connected!="boolean")continue;let i=o.authKind==="oauth"||o.authKind==="api_key"||o.authKind==="bot_token"?o.authKind:"api_key",s=rc(o.fields),a=tc(o.missingRequiredFields),c=oc(o.status,o.connected,s,a);t.push({plugin:o.plugin,providerName:E(o.providerName)?o.providerName:o.plugin,authKind:i,status:c,connected:o.connected,fields:s,missingRequiredFields:a})}return{tenantId:n.tenantId,plugins:t}}function et(e){if(!e||typeof e!="object")return null;let n=e;return n.error??n.message??null}function ai(e){if(!e||typeof e!="object")return null;let n=e;if(n.errorType!=="reconnect_required")return null;let t=r=>typeof r=="string"&&r.length>0?r:null;return{message:t(n.error),connectUrl:t(n.connectUrl),plugin:t(n.plugin),tenantId:t(n.tenantId),reason:t(n.reason)}}function nt(e){return e.replace(/\/$/,"")}function ur(e){if(!e.projectApiKey.startsWith("ck_dev_"))return null;try{return xe()}catch{return null}}function ci(e){let n=ur(e);return n?{"x-corsair-delivery-url":n}:{}}function ui(e){let n=e.instanceKey?.trim();return n?{"x-corsair-instance-key":n}:{}}async function li(e){let n=e.headers.get("content-type")??"",t=await e.text();if(!t)return null;if(!n.includes("application/json")&&t.trimStart().startsWith("<"))throw new Error(`Hub API returned HTML instead of JSON (HTTP ${e.status}). Check HUB_API_URL and deploy the latest hub API.`);try{return JSON.parse(t)}catch{throw new Error(`Hub API returned invalid JSON (HTTP ${e.status})`)}}function ic(e,n,t){if(n===404&&t)return t;let r=et(e);return r||`Hub API returned HTTP ${n}`}function di(e,n,t){let r=ai(e);throw r?new ye({message:r.message??void 0,connectUrl:r.connectUrl,plugin:r.plugin,tenantId:r.tenantId,reason:r.reason??void 0}):new Error(ic(e,n,t))}async function x(e){let n=nt(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.hub.projectApiKey}`,...ci(e.hub),...ui(e.hub)},body:JSON.stringify(e.body)}),r=await li(t);return t.ok||di(r,t.status,e.notFoundMessage),e.parseResponse(r)}async function q(e){let n=nt(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"GET",headers:{authorization:`Bearer ${e.hub.projectApiKey}`,...ci(e.hub),...ui(e.hub)}}),r=await li(t);return t.ok||di(r,t.status,e.notFoundMessage),e.parseResponse(r)}function tt(e){return e&&typeof e=="object"?e:{}}function pi(e){let n=tt(e);return{chatId:n.threadId,message:n.message,workflowId:n.workflowId??null,action:n.action}}async function lr(e,n){return x({hub:e,path:"/threads",body:{tenantId:n.tenantId,message:n.message},parseResponse:t=>{let r=tt(t);return{chat:r.thread,reply:pi(r.reply)}}})}async function dr(e,n){return x({hub:e,path:`/threads/${encodeURIComponent(n.chatId)}/messages`,body:{tenantId:n.tenantId,message:n.message},notFoundMessage:`Chat "${n.chatId}" not found`,parseResponse:pi})}async function pr(e,n){return q({hub:e,path:`/threads?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=tt(t).threads;return Array.isArray(r)?r:[]}})}async function gr(e,n){return q({hub:e,path:`/threads/${encodeURIComponent(n.chatId)}/messages?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Chat "${n.chatId}" not found`,parseResponse:t=>{let r=tt(t).messages;return Array.isArray(r)?r:[]}})}import{randomUUID as pc}from"crypto";var sc="corsair:client-bridge";function fr(e){return new URL(e).origin}function rn(e){let n=JSON.stringify({type:sc,requestId:e.requestId,ok:e.ok,body:e.body??null,error:e.error??null}),t=JSON.stringify(fr(e.hubOrigin));return`<!DOCTYPE html><html><head><meta charset="utf-8"></head><body><script>
|
|
2
|
+
(function () {
|
|
3
|
+
var message = ${n};
|
|
4
|
+
var targetOrigin = ${t};
|
|
5
|
+
if (window.parent && window.parent !== window) {
|
|
6
|
+
window.parent.postMessage(message, targetOrigin);
|
|
7
|
+
}
|
|
8
|
+
})();
|
|
9
|
+
</script></body></html>`}var ac=new Set(["localhost","127.0.0.1","[::1]","::1"]);function yr(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:ac.has(n)}catch{return!1}}function Sn(e){return e==="development"?"browser":"server"}function gi(e){return Sn(e)==="browser"}function fi(e){return yr(e)?"Production delivery URL must be a public URL, not localhost":null}import{randomBytes as dc}from"crypto";var _e=60*1e3,We=300*1e3;import{createHmac as cc,randomBytes as uc,timingSafeEqual as lc}from"crypto";function me(){return uc(16).toString("base64url")}function _n(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required");return cc("sha256",t).update(e).digest("base64url")}function le(e,n){let t=n.trim();if(!t)return null;let r=e.split(".");if(r.length!==2)return null;let[o,i]=r;if(!o||!i)return null;let s=_n(o,t);try{if(!lc(Buffer.from(i,"utf8"),Buffer.from(s,"utf8")))return null}catch{return null}let a;try{a=JSON.parse(Buffer.from(o,"base64url").toString("utf8"))}catch{return null}return a.exp*1e3<Date.now()?null:a}function rt(e,n,t){let r=Math.floor(Date.now()/1e3),o={...e,iat:r,exp:t},i=Buffer.from(JSON.stringify(o)).toString("base64url"),s=_n(i,n);return`${i}.${s}`}function En(e,n,t){let r=Math.floor(Date.now()/1e3);return rt(e,n,r+Math.floor(t/1e3))}function je(e){return decodeURIComponent(e)}function mr(e){return encodeURIComponent(e).replace(/\./g,"%2E")}function yi(e){let n=e.trim();return n.length>0?n:null}function on(e,n){let t=new URL(e);return t.searchParams.set("d",n),t.toString()}function sn(e,n){if(!yi(n))throw new Error("Signing secret is required for browser delivery tokens");let t=Math.floor(Date.now()/1e3),r={...e,jti:e.jti??dc(16).toString("base64url"),iat:t,exp:t+Math.floor(_e/1e3)},o=Buffer.from(JSON.stringify(r)).toString("base64url"),i=_n(o,n);return`${o}.${i}`}function Ee(e,n){return yi(n)?le(e,n):null}function gc(e){let n=fr(e.hubOrigin),t={connectJti:e.requestId,projectId:e.projectId,hubSuccessUrl:e.hubOrigin,deliveryMode:e.deliveryMode,hubOrigin:n,requestId:e.requestId};switch(e.deliveryMode){case"connections.sync":return{...t,plugin:"connections.sync",tenantId:"*"};case"connect.create_link":return{...t,plugin:"connect.create_link",tenantId:e.tenantId,connectLinkPlugins:e.plugins}}}function hr(e){let n=sn(gc(e),e.signingSecret);return on(e.deliveryUrl,n)}function mi(e){if(Sn(e.environmentSlug)==="server")return{transport:"server"};if(!e.hubOrigin)throw new Error(`hubOrigin is required for development ${e.deliveryMode} delivery`);let t=pc(),r={...e,hubOrigin:e.hubOrigin,requestId:t};return{transport:"browser",requestId:t,deliveryUrl:hr(r)}}var Mn="https://auth.corsair.dev";var he=class extends Error{constructor(){super("Hub is not configured. Pass hub: { projectApiKey, signingSecret } to createCorsair()."),this.name="HubNotConfiguredError"}},Dn=class extends Error{constructor(){super("Hub credentials are missing. Pass hub: { projectApiKey, signingSecret } to createCorsair() with non-empty values, or omit `hub` entirely if you are not using Corsair Hub."),this.name="HubCredentialsMissingError"}};function br(e){let n=(e.apiUrl?.trim()||Mn).replace(/\/$/,""),t=e.projectApiKey?.trim()??"",r=e.signingSecret?.trim()??"",o=t.startsWith("ck_cloud_");if(!t||!r&&!o)throw new Dn;return{apiUrl:n,projectApiKey:t,signingSecret:r,instanceKey:e.instanceKey?.trim()||void 0,oauthCallbackUrl:e.oauthCallbackUrl?.trim().replace(/\/$/,""),redirectURL:e.redirectURL?.trim()||void 0,allowWorkflowExecution:e.allowWorkflowExecution??!1,tunnel:e.tunnel}}function ot(e){return br(e)}function fc(e){let n=e.projectApiKey.startsWith("ck_cloud_");return e.apiUrl.trim().length>0&&e.projectApiKey.trim().length>0&&(n||e.signingSecret.trim().length>0)}function U(e){let n=T(e).hub;if(!n||!fc(n))throw new he;return n}function hi(e){return e.replace(/\/$/,"")}function it(e){return e.oauthCallbackUrl?hi(e.oauthCallbackUrl.trim()):`${hi(e.apiUrl)}/oauth/callback`}function an(e){if(e.startsWith("ck_dev_"))return"development";if(e.startsWith("ck_prod_"))return"production";if(e.startsWith("ck_cloud_"))return"cloud";throw new Error("Hub API key must start with ck_dev_ (development), ck_prod_ (production), or ck_cloud_ (cloud)")}import{createCipheriv as bi,createDecipheriv as ki,randomBytes as st,scrypt as yc}from"crypto";import{promisify as mc}from"util";var wi=mc(yc),at="aes-256-gcm",Ci=12,ct=16,hc=16,qe=32;function be(){return st(qe).toString("base64")}async function ke(e,n){let t=st(hc),r=await wi(n,t,qe),o=st(Ci),i=bi(at,r,o,{authTagLength:ct}),s=Buffer.concat([i.update(e,"utf8"),i.final()]),a=i.getAuthTag();return[t.toString("base64"),o.toString("base64"),a.toString("base64"),s.toString("base64")].join(":")}async function ne(e,n){let[t,r,o,i]=e.split(":");if(!t||!r||!o||!i)throw new Error("Invalid encrypted DEK format");let s=Buffer.from(t,"base64"),a=Buffer.from(r,"base64"),c=Buffer.from(o,"base64"),l=Buffer.from(i,"base64"),u=await wi(n,s,qe),d=ki(at,u,a,{authTagLength:ct});return d.setAuthTag(c),Buffer.concat([d.update(l),d.final()]).toString("utf8")}function kr(e,n){let t=Buffer.from(n,"base64"),r=st(Ci),o=bi(at,t,r,{authTagLength:ct}),i=Buffer.concat([o.update(e,"utf8"),o.final()]),s=o.getAuthTag();return[r.toString("base64"),s.toString("base64"),i.toString("base64")].join(":")}function On(e,n){let[t,r,o]=e.split(":");if(!t||!r||!o)throw new Error("Invalid encrypted data format");let i=Buffer.from(n,"base64"),s=Buffer.from(t,"base64"),a=Buffer.from(r,"base64"),c=Buffer.from(o,"base64"),l=ki(at,i,s,{authTagLength:ct});return l.setAuthTag(a),Buffer.concat([l.update(c),l.final()]).toString("utf8")}function Me(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=kr(o,n);return t}function de(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=On(o,n);return t}function Hn(e,n,t){let r=de(e,n);return Me(r,t)}function vi(e,n,t){let r={};for(let o of t)r[`get_${o}`]=async()=>(await e())[o]??null,r[`set_${o}`]=async i=>{let s=[null,void 0,""].includes(i)?null:i;await n({[o]:s})};return r}var wr=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};function F(e){let{authType:n,integrationName:t,kek:r,database:o,extraIntegrationFields:i=[]}=e,s=[...j[n].integration,...i],a=null,c={kek:r,integrationName:t,getIntegration:async()=>{if(a)return a;let k=await o.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!k)throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`);return a={id:k.id,config:wr(k.config),dek:k.dek??null},a},updateIntegration:async k=>{let b=await c.getIntegration();await o.db.updateTable("corsair_integrations").set({...k.config!==void 0?{config:k.config}:{},...k.dek!==void 0?{dek:k.dek}:{},updated_at:new Date}).where("id","=",b.id).execute(),a=null}},l=null,u=async()=>{if(l)return l;let k=await c.getIntegration();if(!k.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return l=await ne(k.dek,r),l},d=async()=>{let k=await c.getIntegration(),b=await u(),v=k.config;return!v||Object.keys(v).length===0?{}:de(v,b)},p=Promise.resolve(),g=k=>{let b=p.then(()=>f(k));return p=b.catch(()=>{}),b},f=async k=>{let b=await u(),v;try{v=await d()}catch(M){console.error(`[corsair] Failed to decrypt config for integration "${t}", starting fresh:`,M),v={}}let P={...v};for(let[M,O]of Object.entries(k))O===null?delete P[M]:P[M]=O;let D=Me(P,b);await c.updateIntegration({config:D})};return{get_dek:u,issue_new_dek:async()=>{let k=await c.getIntegration(),b=be(),v={};if(k.dek){let D=await ne(k.dek,r),M=k.config;M&&Object.keys(M).length>0&&(v=Hn(M,D,b))}let P=await ke(b,r);return await c.updateIntegration({config:v,dek:P}),l=b,b},...vi(d,g,s)}}function B(e){let{authType:n,integrationName:t,tenantId:r,kek:o,database:i,extraAccountFields:s=[],ensureProvisioned:a}=e,c=[...j[n].account,...s],l=null,u=async()=>{if(l)return l;let w=!1;for(;;){let R=await i.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!R){if(!w&&a){w=!0,await a();continue}throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`)}return l={id:R.id,config:wr(R.config),dek:R.dek??null},l}},d={kek:o,integrationName:t,tenantId:r,getIntegration:u,getAccount:async()=>{let w=!1;for(;;){let R=await u(),A=await i.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",r).where("integration_id","=",R.id).executeTakeFirst();if(!A){if(!w&&a){w=!0,await a();continue}throw new Error(`Account not found for tenant "${r}" and integration "${t}". Make sure to create the account first.`)}return{id:A.id,config:wr(A.config),dek:A.dek??null}}},updateAccount:async w=>{let R=await d.getAccount();await i.db.updateTable("corsair_accounts").set({...w.config!==void 0?{config:w.config}:{},...w.dek!==void 0?{dek:w.dek}:{},updated_at:new Date}).where("id","=",R.id).execute()}},p=null,g=null,f=null,h=async()=>{let w=await d.getAccount();if(!w.dek)throw new Error(`No DEK found for account (tenant: "${r}", integration: "${t}"). Initialize the account first.`);return p&&g===w.dek||(p=await ne(w.dek,o),g=w.dek),p},k=async()=>{if(f)return f;let w=await d.getIntegration();if(!w.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return f=await ne(w.dek,o),f},b=async()=>{let w=await d.getAccount(),R=await h(),A=w.config;return!A||Object.keys(A).length===0?{}:de(A,R)},v=async()=>{let w=await d.getIntegration(),R=await k(),A=w.config;return!A||Object.keys(A).length===0?{}:de(A,R)},P=Promise.resolve(),D=w=>{let R=P.then(()=>M(w));return P=R.catch(()=>{}),R},M=async w=>{let R=await d.getAccount();if(!R.dek)throw new Error(`No DEK found for account (tenant: "${r}", integration: "${t}"). Initialize the account first.`);let A=await ne(R.dek,o),X;try{let L=R.config;X=!L||Object.keys(L).length===0?{}:de(L,A)}catch(L){console.error(`[corsair] Failed to decrypt config for account (tenant: "${r}", integration: "${t}"), starting fresh:`,L),X={}}let te={...X};for(let[L,Re]of Object.entries(w))Re===null?delete te[L]:te[L]=Re;let H=Me(te,A);await d.updateAccount({config:H})},O={get_dek:h,issue_new_dek:async()=>{let w=await d.getAccount(),R=be(),A={};if(w.dek){let te=await ne(w.dek,o),H=w.config;H&&Object.keys(H).length>0&&(A=Hn(H,te,R))}let X=await ke(R,o);return await d.updateAccount({config:A,dek:X}),p=R,g=X,R},...vi(b,D,c)};return n==="oauth_2"&&(O.get_integration_credentials=async()=>{let w=await v();return{...w,client_id:w.client_id||null,client_secret:w.client_secret||null,redirect_url:w.redirect_url??null}}),O}async function Ti(e,n,t){let r=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!r)throw new Error(`Integration "${n}" not found.`);let o=be(),i=await ke(o,t);return await e.db.updateTable("corsair_integrations").set({dek:i,updated_at:new Date}).where("id","=",r.id).execute(),o}async function Pi(e,n,t,r){let o=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!o)throw new Error(`Integration "${n}" not found.`);let i=await e.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",o.id).executeTakeFirst();if(!i)throw new Error(`Account not found for tenant "${t}" and integration "${n}".`);let s=be(),a=await ke(s,r);return await e.db.updateTable("corsair_accounts").set({dek:a,updated_at:new Date}).where("id","=",i.id).execute(),s}var bc=new Set(["webhook_signature","expires_at","scope","redirect_url","refresh_token"]);function De(e){return bc.has(e)}function kc(e,n){return De(n)?!1:e==="oauth_2"?n==="client_id"||n==="client_secret":!0}function wc(e){return!De(e)}function Cc(e){switch(e){case"oauth_2":case"managed":return["access_token"];case"api_key":return["api_key"];case"bot_token":return["bot_token"];case"managed_pricing":return[]}}function vc(e,n){return e!=="oauth_2"&&e!=="managed"?!1:n.some(t=>t.level==="account"&&t.name==="expires_at"&&t.configured)}function Tc(e,n){let t=i=>n.find(s=>s.level==="account"&&s.name===i);if(!Cc(e).every(i=>t(i)?.configured))return!1;let o=t("refresh_token");return o?.required?!!o.configured:!0}async function Ri(e,n){if(!e)return!1;let t=ee(e,`get_${n}`);if(!t)return!1;try{let r=await t();return typeof r=="string"&&r.length>0}catch{return!1}}function Pc(e,n){let r=e.authConfig?.[n]?.integration??[];return[...j[n].integration,...r]}function Rc(e,n){let r=e.authConfig?.[n]?.account??[];return[...j[n].account,...r]}function Ac(e,n,t){let r=t.filter(a=>a.required&&!a.configured).map(a=>a.name),o=t.filter(a=>a.level==="integration"&&a.required&&!a.configured).map(a=>a.name),i=t.filter(a=>a.level==="account"&&a.required&&a.configured),s;return o.length>0?s="missing_integration":r.length===0?s="ready":i.length>0?s="partial":s="not_started",{plugin:e,authType:n,status:s,connected:Tc(n,t),fields:t,missingRequiredFields:r}}async function Ke(e,n,t){let r=_(n);if(!r||!e.database||!e.kek)return null;let o=t.trim()||"default",i=n.authConfig,s=i?.[r]?.integration??[],a=i?.[r]?.account??[],c=F({authType:r,integrationName:n.id,kek:e.kek,database:e.database,extraIntegrationFields:s}),l=B({authType:r,integrationName:n.id,tenantId:o,kek:e.kek,database:e.database,extraAccountFields:a}),u=Pc(n,r),d=Rc(n,r),p=[];for(let g of u)p.push({name:g,level:"integration",required:kc(r,g),configured:await Ri(c,g)});for(let g of d)p.push({name:g,level:"account",required:wc(g),configured:await Ri(l,g)});if(vc(r,p)){let g=p.find(f=>f.level==="account"&&f.name==="refresh_token");g&&(g.required=!0)}return Ac(n.id,r,p)}async function Bn(e,n,t={}){let r=n.trim()||"default",o=t.pluginIds?.length?new Set(t.pluginIds):null,i=[];for(let s of e.plugins){if(o&&!o.has(s.id))continue;let a=await Ke(e,s,r);a&&i.push(a)}return i}function ut(e){return e.connected?"connected":e.status==="missing_integration"?"missing_credentials":"not_connected"}var Ai=Symbol.for("corsair:internal"),xi=new WeakMap,Ii=new WeakMap;function xc(e,n){let t=n.map(r=>r.id).sort().join("\0");return`${e}\0${t}`}function Ic(e){if(e.database){let t=xi.get(e.database);return t||(t=new Map,xi.set(e.database,t)),t}let n=Ii.get(e);return n||(n=new Map,Ii.set(e,n)),n}function Sc(e){return e.multiTenancy?{withTenant:()=>({}),[Ai]:e}:{[Ai]:e}}async function cn(e,n){if(!e.database)return;let t=n.trim()||"default",r=Ic(e),o=xc(t,e.plugins),i=r.get(o);if(i){await i;return}let s=(async()=>{let{setupCorsair:a}=await import("./setup-HIFGUGGU.js");await a(Sc(e),{tenantId:e.multiTenancy?t:void 0,silent:!0})})().finally(()=>{r.delete(o)});r.set(o,s),await s}import*as Un from"crypto";function Oe(e,n){return Buffer.from(JSON.stringify({plugin:e,tenantId:n,iat:Date.now()})).toString("base64url")}function Cr(e,{maxAgeMs:n}={}){try{let t=e.includes(".")?e.split(".")[0]:e,r=JSON.parse(Buffer.from(t,"base64url").toString("utf-8"));if(r!==null&&typeof r=="object"&&"plugin"in r&&"tenantId"in r&&typeof r.plugin=="string"&&typeof r.tenantId=="string"){let o=r;return n!==void 0&&typeof o.iat=="number"&&Date.now()-o.iat>n?null:o}return null}catch{return null}}function un(e,n){if(!n)throw new Error("OAuth state signing requires a configured kek. Pass kek to createCorsair().");let t=Un.createHmac("sha256",n).update(e).digest("base64url");return`${e}.${t}`}var vr=600*1e3;function lt(e,n){if(!n)return null;let t=e.lastIndexOf(".");if(t===-1)return null;let r=e.slice(0,t),o=e.slice(t+1),i=Un.createHmac("sha256",n).update(r).digest("base64url"),s=Buffer.from(o,"base64url"),a=Buffer.from(i,"base64url");return s.length!==a.length||!Un.timingSafeEqual(s,a)?null:Cr(r,{maxAgeMs:vr})}function Si(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType??"oauth_2",status:"ready",connected:!0,verified:!0,webhookLink:e.link}}function _i(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType,status:e.status,connected:e.connected,verified:e.verified,missingFields:e.missingFields,webhookLink:e.webhookLink,webhookSecret:e.webhookSecret}}async function ln(e,n){await x({hub:e,path:"/connections/report",body:Si(n),parseResponse:()=>({ok:!0})}).catch(()=>{})}function _c(e,n){try{let t=U(e);x({hub:t,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}catch(t){if(t instanceof he)return}}async function Ec(e){if(!e.hub||!e.database||!e.kek)return;let n={database:e.database,kek:e.kek,plugins:e.plugins};if(!_(e.plugin))return;let r=e.tenantId?.trim()||"default",o=await Ke(n,e.plugin,r);o&&Mi(e.hub,_i({tenantId:r,plugin:e.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:e.verified??o.connected,missingFields:o.missingRequiredFields}))}function Ei(e,n){_c(e,n)}function Mi(e,n){x({hub:e,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}function dn(e){Ec(e).catch(()=>{})}async function we(e,n){let t=T(e);if(!_(n.plugin))return;let o=await Ke(t,n.plugin,n.tenantId);o&&Ei(e,_i({tenantId:n.tenantId.trim()||"default",plugin:n.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:n.verified??o.connected,missingFields:o.missingRequiredFields,webhookLink:n.webhookLink,webhookSecret:n.webhookSecret}))}async function dt(e,n,t){for(let r of e){if(r.id!==n)continue;let o=r.oauthWebhookTenantLinkResolver;return o?o(t):null}return null}var Di=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};async function Mc(e){let n=await e.database.db.selectFrom("corsair_integrations").selectAll().where("name","=",e.pluginId).executeTakeFirst();if(!n)throw new Error(`Integration '${e.pluginId}' not found. Run setupCorsair before registering webhook tenant links.`);let t=await e.database.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",e.tenantId).where("integration_id","=",n.id).executeTakeFirst();if(!t)throw new Error(`Account not found for tenant '${e.tenantId}' and integration '${e.pluginId}'.`);return{integrationId:n.id,accountId:t.id}}async function Dc(e){let n=await e.database.db.selectFrom("corsair_accounts").selectAll().where("id","=",e.accountId).executeTakeFirst();if(!n?.dek)throw new Error(`Account '${e.accountId}' has no DEK.`);let t=await ne(n.dek,e.kek),r=Di(n.config),o={};Object.keys(r).length>0&&(o=de(r,t)),o[e.link.linkType]=e.link.externalId;let i=Me(o,t);await e.database.db.updateTable("corsair_accounts").set({config:i,updated_at:new Date}).where("id","=",n.id).execute()}async function pn(e){let{database:n,kek:t,pluginId:r,tenantId:o,link:i,authType:s,extraAccountFields:a=[]}=e,{accountId:c}=await Mc({database:n,pluginId:r,tenantId:o}),l=!1;if(s){let u=B({authType:s,integrationName:r,tenantId:o,kek:t,database:n,extraAccountFields:a}),d=`set_${i.linkType}`,p=u[d];typeof p=="function"&&(await p(i.externalId),l=!0)}l||await Dc({database:n,kek:t,accountId:c,link:i})}async function Tr(e){let{database:n,kek:t,pluginId:r,linkType:o,externalId:i}=e,s=await n.db.selectFrom("corsair_accounts as accounts").innerJoin("corsair_integrations as integrations","integrations.id","accounts.integration_id").selectAll("accounts").where("integrations.name","=",r).execute();for(let a of s)if(a.dek)try{let c=await ne(a.dek,t),u=Di(a.config)[o];if(!u)continue;if(On(u,c)===i)return a}catch{continue}return null}async function pt(e){return(await Tr(e))?.tenant_id??null}async function Oi(e){return pt({database:e.database,kek:e.kek,pluginId:e.pluginId,linkType:e.match.linkType,externalId:e.match.externalId})}import*as Hi from"querystring";function Ze(e){let{oauthConfig:n,clientId:t,redirectUri:r,state:o}=e,i={...n.authParams,client_id:t,redirect_uri:r,response_type:"code",scope:n.scopes.join(" "),state:o};return`${n.authUrl}?${Hi.stringify(i)}`}async function Bi(e,n){try{return await q({hub:e,path:`/webhooks/endpoint?plugin=${encodeURIComponent(n)}`,parseResponse:t=>t?.url??null})}catch{return null}}async function gn(e,n,t,r){if(!n.subscribe)return;let o=U(e),i=await Bi(o,n.id);if(!i)return;let s=await n.subscribe({keys:r},{webhookUrl:i});s&&await we(e,{plugin:n,tenantId:t,verified:!0,webhookLink:s.webhookLink,webhookSecret:s.webhookSecret})}var Z=class extends Error{code;constructor(n,t){super(t),this.name="OAuthCallbackError",this.code=n}};function Ui(e){let n=e.oauthConfig;if(!n)throw new Z("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function Oc(e,n,t,r){await e.db.transaction().execute(async o=>{let i=o.selectFrom("corsair_integrations").select(["id"]).where("name","=",n);e.isPg===!0&&(i=i.forUpdate());let s=await i.executeTakeFirst();if(!s)throw new Error(`Integration '${n}' not found. Run setupCorsair first.`);if(await o.selectFrom("corsair_accounts").select("id").where("tenant_id","=",t).where("integration_id","=",s.id).executeTakeFirst())return;let c=be(),l=await ke(c,r),u=new Date;await o.insertInto("corsair_accounts").values({id:nn(),created_at:u,updated_at:u,tenant_id:t,integration_id:s.id,config:{},dek:l}).execute()})}async function Pr(e,n,t){let{tenantId:r,redirectUri:o,hubConnect:i=!1}=t,s=T(e,()=>new Z("invalid_corsair_instance","Invalid corsair instance"));if(!s.database)throw new Error("No database configured on corsair instance");let a=K(s,n,p=>new Z("plugin_not_found",p)),c=Ui(a),u=await F({authType:"oauth_2",integrationName:n,kek:s.kek,database:s.database}).get_client_id();if(!u)throw new Error(`client_id not configured for '${n}'`);if(i){let p=new URL(Ze({oauthConfig:c,clientId:u,redirectUri:o,state:""}));return p.searchParams.delete("state"),{url:p.toString(),state:""}}let d=un(Oe(n,r),s.kek);return{url:Ze({oauthConfig:c,clientId:u,redirectUri:o,state:d}),state:d}}function Hc(e,n){return{...n??{},...e}}async function Fn(e,n){let{code:t,state:r,redirectUri:o}=n,i=T(e,()=>new Z("invalid_corsair_instance","Invalid corsair instance")),s,a;if(n.trusted){if(!n.plugin||!n.tenantId)throw new Z("invalid_state","trusted callback requires plugin and tenantId");s=n.plugin,a=n.tenantId}else{let h=lt(r,i.kek);if(!h)throw new Z("invalid_state","Invalid or tampered state parameter");s=h.plugin,a=h.tenantId}if(!i.database)throw new Z("no_database","No database configured on corsair instance");let c=K(i,s,h=>new Z("plugin_not_found",h)),l=Ui(c),u=F({authType:"oauth_2",integrationName:s,kek:i.kek,database:i.database}),d=await u.get_client_id(),p=await u.get_client_secret();if(!d||!p)throw new Z("credentials_not_configured",`Credentials not configured for '${s}'`);await Oc(i.database,s,a,i.kek);let g=await gt(t,d,p,l,o);if(!g.access_token)throw new Z("no_access_token",`No access_token returned from ${l.providerName}`);let f=B({authType:"oauth_2",integrationName:s,tenantId:a,kek:i.kek,database:i.database,extraAccountFields:[...c.authConfig?.oauth_2?.account??[]]});await f.set_access_token(g.access_token),g.refresh_token&&await f.set_refresh_token(g.refresh_token),g.expires_in&&await f.set_expires_at(String(Math.floor(Date.now()/1e3)+g.expires_in)),await we(e,{plugin:c,tenantId:a}).catch(()=>{});try{let h=Hc(g,n.callbackParams),k=await dt(i.plugins,s,h);if(k){try{let b=c.authConfig?.oauth_2?.account??[];await pn({database:i.database,kek:i.kek,pluginId:s,tenantId:a,link:k,authType:"oauth_2",extraAccountFields:b})}catch(b){console.warn(`[corsair:oauth] Failed to persist webhook tenant link for '${s}' tenant '${a}':`,b)}i.hub&&ln(i.hub,{plugin:s,tenantId:a,link:k,authType:"oauth_2"})}}catch(h){console.warn(`[corsair:oauth] Failed to resolve webhook tenant link for '${s}' tenant '${a}':`,h)}if(c.subscribe)try{await gn(e,c,a,f)}catch(h){console.warn(`[corsair:oauth] BYO subscribe failed for '${s}' tenant '${a}':`,h)}return{plugin:s,tenantId:a}}async function Bc(e){let{corsair:n,internal:t,rows:r}=e,o=e.subscribeAndReport??gn,i=[],s=[];if(!t.database)return{renewed:i,failed:s};for(let a of r){let c=t.plugins.find(u=>u.id===a.integrationName);if(!c?.subscribe)continue;let l=`${c.id}/${a.tenantId}`;try{let u=_(c)??"oauth_2",d=B({authType:u,integrationName:c.id,tenantId:a.tenantId,kek:t.kek,database:t.database,extraAccountFields:[...c.authConfig?.[u]?.account??[]]}),p=c.keyBuilder;if(p){let g=Object.create(d,{get_expires_at:{value:async()=>"0"}});await p({authType:u,keys:g,hub:t.hub},"endpoint")}await o(n,c,a.tenantId,d),i.push(l)}catch(u){console.warn(`[corsair:renewal] re-subscribe failed for '${l}':`,u),s.push(l)}}return{renewed:i,failed:s}}async function Fi(e){let n=T(e);if(!n.database)return{renewed:[],failed:[]};let t=await n.database.db.selectFrom("corsair_accounts as a").innerJoin("corsair_integrations as i","i.id","a.integration_id").select(["a.tenant_id as tenantId","i.name as integrationName"]).where("a.dek","is not",null).execute();return Bc({corsair:e,internal:n,rows:t.filter(r=>!!r.tenantId)})}function Uc(e,n={}){let t=!1,r=()=>{t||(t=!0,Fi(e).catch(i=>console.warn("[corsair:renewal] renewal pass failed:",i)).finally(()=>{t=!1}))};r();let o=setInterval(r,(n.intervalMinutes??45)*6e4);return o.unref?.(),()=>clearInterval(o)}async function Li(e){if(!T(e).database)throw new Error("A database must be configured to provision Corsair integrations");await ft(e,{silent:!0})}async function fn(e,n){let t=T(e);if(!t.database)throw new Error("A database must be configured to provision Corsair for connect");await cn(t,n)}var Fc=Symbol.for("corsair:internal"),Lc=new Set(["access_token","refresh_token","expires_at","scope"]);function Nc(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function $c(e,n){return e==="oauth_2"||e==="managed"?n.filter(t=>!De(t)&&!Lc.has(t)):n.filter(t=>!De(t))}function Ni(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function Wc(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function jc(e){return{[Fc]:Ni(e)}}async function yt(e,n,t={}){let r=it(e.hub),o=[],i=t.pluginIds?new Set(t.pluginIds):null,s=Ni(e),a=jc(e);for(let c of e.plugins){if(i&&!i.has(c.id))continue;let l=_(c);if(!l)continue;let u=Nc(l),d=t.providerNameOverrides?.[c.id]??Se(c.id),p=await Ke(s,c,n),g=Jn(c,l),f=$c(l,g),h={plugin:c.id,providerName:d,authKind:u,alreadyConfigured:p?.connected??!1};if(f.length>0&&(h.credentialFields=f),u==="oauth"){let b=t.oauthModeOverrides?.[c.id]??(l==="managed"?"managed":"byo");if(h.oauthMode=b,!t.skipOAuthUrlGeneration&&b!=="managed")try{let v=await Pr(a,c.id,{tenantId:n,redirectUri:r,hubConnect:!0});h.oauthUrl=v.url}catch(v){v instanceof Error&&/client_id not configured/i.test(v.message)||(h.setupError=v instanceof Error?v.message:`Could not prepare OAuth for ${c.id}`)}}o.push(h)}return o}async function mf(e,n,t={}){let r=T(e),o=r.hub;if(!o)throw new Error("Hub is not configured");return yt({plugins:r.plugins,database:r.database,kek:r.kek,hub:o},n,t)}async function $i(e,n){if(!e.database)throw new Error("A database must be configured to provision Corsair for connect");await cn(e.internalConfig??Wc(e),n)}async function Wi(e,n){await fn(e,n)}async function ji(e,n){let t=an(e.projectApiKey),r={tenantId:n.tenantId,plugins:n.plugins};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=xe({deliveryUrl:n.deliveryUrl})),x({hub:e,path:"/connect/sessions",notFoundMessage:"Hub REST API not found at /connect/sessions. Check HUB_API_URL and ensure the Hub API is deployed.",body:r,parseResponse:Yn})}async function qi(e,n){let t={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await $i(t,n.tenantId);let r=await yt(t,n.tenantId,{pluginIds:[n.plugin.id]});if(r.length===0)throw new Error(`Plugin '${n.plugin.id}' is not configured on this Corsair instance`);return ji(e,{tenantId:n.tenantId,plugins:r,deliveryUrl:n.deliveryUrl})}async function mt(e,n){let t=T(e),r=U(e),o={plugins:t.plugins,database:t.database,kek:t.kek,hub:r,multiTenancy:t.multiTenancy,internalConfig:t};await Wi(e,n.tenantId);let i=n.plugin?[n.plugin]:void 0,s=n.plugin&&n.oauthMode?{[n.plugin]:n.oauthMode}:void 0,a=n.plugin&&n.providerName?{[n.plugin]:n.providerName}:void 0,c=await yt(o,n.tenantId,{pluginIds:i,oauthModeOverrides:s,providerNameOverrides:a});if(c.length===0)throw new Error(n.plugin?`Plugin '${n.plugin}' is not configured on this Corsair instance`:"No plugins are configured on this Corsair instance");return ji(r,{tenantId:n.tenantId,plugins:c,deliveryUrl:n.deliveryUrl})}async function ht(e,n){let t=n.tenantId.trim();if(!t)throw new Error("tenantId is required");let r=n.plugins.map(s=>s.trim()).filter(Boolean);if(r.length===0)throw new Error("At least one plugin is required");let o=T(e);if(!o.hub)throw new Error("Hub is not configured on this Corsair instance");if(!o.database)throw new Error("Database not configured");let i=await qc(o.hub,{plugins:o.plugins,database:o.database,kek:o.kek,multiTenancy:o.multiTenancy},{tenantId:t,pluginIds:r});return{connectUrl:i.connectUrl,expiresAt:i.expiresAt}}async function qc(e,n,t){let{buildConnectPluginManifestFromContext:r,ensureConnectAccountRowsFromContext:o}=await import("./setup-introspect-MFXTQW6T.js"),{postHubConnectSession:i}=await import("./connect-73AAKXSA.js"),s={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await o(s,t.tenantId);let a=await r(s,t.tenantId,{pluginIds:t.pluginIds});if(a.length===0)throw new Error("No connectable plugins found for this tenant");let c=a.find(l=>l.setupError);if(c)throw new Error(c.setupError??`Could not prepare connect link for ${c.plugin}`);return i(e,{tenantId:t.tenantId,plugins:a})}function yn(e){return!!(e?.baseUrl?.trim()&&e?.redirectUri?.trim())}var oe=class extends Error{code;constructor(n,t){super(t),this.name="ConnectError",this.code=n}};function Kc(e){let n=e.oauthConfig;if(!n)throw new oe("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function Rr(e,n){let t=T(e,()=>new oe("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new oe("no_database","No database configured on corsair instance");let r=t.manual?.redirectUri;if(!r)throw new oe("no_redirect_uri","No redirectUri configured. Set manual.redirectUri in createCorsair().");let o=lt(n,t.kek);if(!o)throw new oe("invalid_state","Invalid or tampered state parameter");let{plugin:i,tenantId:s}=o,a=K(t,i,p=>new oe("plugin_not_found",p)),c=Kc(a),u=await F({authType:"oauth_2",integrationName:i,kek:t.kek,database:t.database}).get_client_id();if(!u)throw new oe("client_id_not_configured",`client_id not configured for '${i}'`);let d=Ze({oauthConfig:c,clientId:u,redirectUri:r,state:n});return{plugin:i,tenantId:s,providerName:c.providerName,oauthUrl:d,state:n}}import{AsyncLocalStorage as Gc}from"async_hooks";import{randomBytes as zc}from"crypto";import{v4 as Jc}from"uuid";async function bt(e,n){let t=an(e.projectApiKey),r={permissionId:n.permissionId,permissionToken:n.permissionToken,plugin:n.plugin,endpoint:n.endpoint,args:n.args,tenantId:n.tenantId,expiresAt:n.expiresAt};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=xe({deliveryUrl:n.deliveryUrl})),x({hub:e,path:"/permission/sessions",notFoundMessage:"Hub REST API not found at /permission/sessions. Check HUB_API_URL and ensure the Hub API is deployed.",body:r,parseResponse:Xn})}function kt(e){return`Approval required. Visit ${e} to approve or deny, then tell the agent to retry this action.`}var Ar="Permission approval required. Set manual.approvalBaseUrl (or use hub for hosted approval) so an approval URL can be generated. Optionally set manual.onApprovalRequired to customize the agent message.";function Ir(e){return e?e.approvalBaseUrl!==void 0||e.onApprovalRequired!==void 0:!1}function Ki(e,n){return`${e.replace(/\/+$/,"")}/${n}`}function xr(e){return kt(e)}async function Sr(e,n){if(Ir(e.manual)){let r=e.manual?.approvalBaseUrl?.trim();return r?Ki(r,n.token):null}let t=e.hub;if(!t)return null;try{return(await bt(t,{permissionId:n.id,permissionToken:n.token,plugin:n.plugin,endpoint:n.endpoint,args:Zc(n.args),tenantId:n.tenant_id,expiresAt:n.expires_at})).approvalUrl}catch(r){return console.warn(`[corsair/${n.plugin}] could not create an approval link for '${n.endpoint}': ${r instanceof Error?r.message:String(r)}`),null}}function Zc(e){try{return JSON.parse(e)}catch{return e}}async function wt(e,n){if(!(n.status==="pending"||n.status==="approved"))return{...n,approvalUrl:null};let r=await Sr(e,n);return{...n,approvalUrl:r}}async function _r(e){let{permissionsOptions:n,manual:t,hub:r,permissionId:o,permissionToken:i,plugin:s,endpoint:a,args:c,tenantId:l,expiresAt:u,operationPath:d}=e;if(n?.formatAsyncMessage)return n.formatAsyncMessage({token:i,id:o,plugin:s,endpoint:a,args:c});let g=await Sr({manual:t,hub:r},{id:o,token:i,plugin:s,endpoint:a,args:JSON.stringify(c),tenant_id:l,expires_at:u});return Ir(t)?g?t?.onApprovalRequired?t.onApprovalRequired({approvalUrl:g}):xr(g):Ar:r?g?xr(g):`Action '${d}' requires user approval before it can run. Could not create approval link. Check hub configuration and server logs.`:Ar}var He=class extends Error{reason;constructor(n,t="pending"){super(n),Object.setPrototypeOf(this,new.target.prototype),this.name="PermissionRequiredError",this.reason=t}};var Gi=new Gc,mn=class extends Error{endpointPath;riskLevel;constructor(n,t){super(`Action '${n}' is a '${t}' operation and is forbidden in readonly mode. Only read operations are permitted \u2014 rewrite the script to avoid write/destructive actions.`),this.name="ReadonlyForbiddenError",this.endpointPath=n,this.riskLevel=t}};function Er(e){return Gi.run(!0,e)}function zi(){return Gi.getStore()===!0}function Mr(e,n){if(zi()&&n!=="read")throw new mn(e,n)}var Vc={open:{read:"allow",write:"allow",destructive:"allow"},cautious:{read:"allow",write:"allow",destructive:"require_approval"},strict:{read:"allow",write:"require_approval",destructive:"deny"},readonly:{read:"allow",write:"deny",destructive:"deny"}};function Yc(e,n,t){return t!==void 0?t:Vc[n][e]}function Dr(e){let n=/(\d+)(d|h|m|s)/g,t=0,r;for(;(r=n.exec(e))!==null;){let o=parseInt(r[1],10);switch(r[2]){case"d":t+=o*864e5;break;case"h":t+=o*36e5;break;case"m":t+=o*6e4;break;case"s":t+=o*1e3;break}}return t>0?t:600*1e3}function Ji(e){return{async find_by_permission_id(n){if(e)return e.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst()},async find_by_token(n){if(e)return e.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst()},async set_executing(n){e&&await e.db.updateTable("corsair_permissions").set({status:"executing",updated_at:new Date}).where("id","=",n).execute()},async set_completed(n){e&&await e.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",n).execute()}}}async function Zi(e,n,t){let r=Date.now()+t;for(;Date.now()<r;){let o=await e.db.selectFrom("corsair_permissions").select(["id","status"]).where("id","=",n).executeTakeFirst();if(!o)return{result:"blocked",reason:"pending"};if(o.status==="approved")return{result:"allow",onComplete:async()=>{await e.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",n).execute()}};if(o.status==="denied")return{result:"blocked",reason:"denied"};if(o.status==="expired"||o.status==="failed")return{result:"blocked",reason:"timeout"};await new Promise(i=>setTimeout(i,500))}return{result:"blocked",reason:"timeout"}}async function Vi(e){let n=Yc(e.riskLevel,e.mode,e.override);if(n==="allow")return{result:"allow"};let t=e.meta?.irreversible?" (irreversible)":"",r=e.meta?.description?`${e.meta.description}${t}`:`${e.pluginId}.${e.endpointPath}${t}`;if(n==="deny"||!e.db)return console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 denied by permission mode '${e.mode}'.`,`
|
|
10
|
+
Action: ${r}`,`
|
|
11
|
+
To allow this, update the permission mode or add an override in your corsair config.`),{result:"blocked",reason:"policy"};let o=JSON.stringify(e.args),i=new Date().toISOString(),s=e.tenantId??"default",a=await e.db.db.selectFrom("corsair_permissions").selectAll().where("plugin","=",e.pluginId).where("endpoint","=",e.endpointPath).where("args","=",o).where("tenant_id","=",s).where("expires_at",">",i).where("status","in",["pending","approved","executing"]).orderBy("created_at","desc").limit(1).executeTakeFirst();if(a){if(a.status==="approved"){let f=e.db,h=a.id;return{result:"allow",onComplete:async()=>{await f.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",h).execute()}}}return a.status==="executing"?{result:"allow"}:(console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval already pending.`,`
|
|
12
|
+
Action: ${r}`,`
|
|
13
|
+
Permission ID: ${a.id}`,`
|
|
14
|
+
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Zi(e.db,a.id,e.timeoutMs??600*1e3):{result:"blocked",reason:"pending",id:a.id,token:a.token,expiresAt:a.expires_at})}let c=Jc(),l=zc(32).toString("hex"),u=e.timeoutMs??600*1e3,d=new Date(Date.now()+u).toISOString();return await e.db.db.insertInto("corsair_permissions").values({id:c,created_at:new Date,updated_at:new Date,token:l,plugin:e.pluginId,endpoint:e.endpointPath,args:o,tenant_id:s,status:"pending",expires_at:d}).execute(),console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval required.`,`
|
|
15
|
+
Action: ${r}`,`
|
|
16
|
+
Permission ID: ${c}`,`
|
|
17
|
+
Permission token: ${l}`,`
|
|
18
|
+
Expires at: ${d}`,`
|
|
19
|
+
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Zi(e.db,c,u):{result:"blocked",reason:"pending",id:c,token:l,expiresAt:d}}var C=class extends Error{status;code;extra;constructor(n,t,r,o={}){super(r??t),this.name="ManagementApiError",this.status=n,this.code=t,this.extra=o}};function I(e,n,t){return new Response(JSON.stringify(n),{status:e,headers:{"content-type":"application/json",...t}})}function pe(e){let n={error:e.code,message:e.message,...e.extra};return I(e.status,n)}function Be(e){return new C(404,"not_found",e)}function G(e,n={}){return new C(400,"bad_request",e,n)}function Or(e,n){return K(e,n,t=>Be(t))}async function Yi(e,n){let t=e.options?.authType;if(!t||!n.database||!n.kek)return{configured:!1,missingFields:[]};let r=F({authType:t,integrationName:e.id,kek:n.kek,database:n.database}),o=j[t].integration,i=r,s;try{s=await Promise.all(o.map(l=>i[`get_${l}`]()))}catch{s=o.map(()=>null)}let a=o.filter((l,u)=>s[u]==null),c;return t==="oauth_2"?c=!a.includes("client_id")&&!a.includes("client_secret"):c=a.length===0,{configured:c,missingFields:a}}async function Qi(e,n){let t=e.options?.authType??null,r=e.oauthConfig,{configured:o,missingFields:i}=await Yi(e,n);return{id:e.id,authType:t,configured:o,missingFields:i,oauth:r?{providerName:r.providerName,scopes:r.scopes,requiresRegisteredRedirect:!!r.requiresRegisteredRedirect}:null}}function Ct(){return{ok:!0}}async function hn(e){return Promise.all(e.plugins.map(n=>Qi(n,e)))}async function vt(e,n){let t=Or(e,n);return Qi(t,e)}async function Qc(e,n){return e.database?(await e.database.db.selectFrom("corsair_accounts as a").innerJoin("corsair_integrations as i","i.id","a.integration_id").select(["a.id as accountId","a.dek as dek","i.name as integrationName"]).where("a.tenant_id","=",n).execute()).map(r=>({integrationName:r.integrationName,hasCredentials:!!r.dek})):[]}async function Xi(e,n){let t=await Qc(e,n),r=t.filter(o=>o.hasCredentials).map(o=>o.integrationName);return{id:n,accounts:t,connectedPlugins:r}}async function bn(e){let n=new Map;if(n.set("default",{id:"default",accounts:[],connectedPlugins:[]}),e.database){let t=await e.database.db.selectFrom("corsair_accounts as a").innerJoin("corsair_integrations as i","i.id","a.integration_id").select(["a.tenant_id","a.dek as dek","i.name as integrationName"]).execute();for(let r of t){let o=r.tenant_id;if(!o)continue;let i=n.get(o);i||(i={id:o,accounts:[],connectedPlugins:[]},n.set(o,i));let s=!!r.dek;i.accounts.push({integrationName:r.integrationName,hasCredentials:s}),s&&i.connectedPlugins.push(r.integrationName)}}return[...n.values()]}async function Tt(e,n){if(!n)throw G("Tenant id must be a non-empty string");return Xi(e,n)}async function Pt(e,n){let t=n?.id?.trim();if(!t)throw G("Tenant id is required",{missingFields:["id"]});return Xi(e,t)}async function Rt(e,n){let t=n?.trim()||"default",r={},o=await Bn(e,t);for(let i of o)r[i.plugin]=ut(i);for(let i of e.plugins)i.id in r||(!i.options?.authType||!e.database||!e.kek?r[i.id]="missing_credentials":r[i.id]="not_connected");return r}async function At(e,n){let t=n?.plugin;if(typeof t!="string"||!t.trim())throw G("plugin is required",{missingFields:["plugin"]});let r=t.trim();Or(e,r);let o=n?.tenantId;if(o!=null&&typeof o!="string")throw G("tenantId must be a string");let i=o?.trim()||"default";if(!e.database)return{ok:!0,disconnected:!1};let s=e.database.db,a=await s.selectFrom("corsair_integrations").select(["id"]).where("name","=",r).executeTakeFirst();if(!a)return{ok:!0,disconnected:!1};let c=!1;return await s.transaction().execute(async l=>{e.database?.isPg===!0&&await l.selectFrom("corsair_integrations").select("id").where("name","=",r).forUpdate().execute();let u=l.selectFrom("corsair_accounts").select("id").where("tenant_id","=",i).where("integration_id","=",a.id);await l.deleteFrom("corsair_events").where("account_id","in",u).execute(),await l.deleteFrom("corsair_entities").where("account_id","in",u).execute(),c=((await l.deleteFrom("corsair_accounts").where("tenant_id","=",i).where("integration_id","=",a.id).executeTakeFirst()).numDeletedRows??0n)>0n}),{ok:!0,disconnected:c}}async function Hr(e,n){if(!e.database)throw Be(`Permission '${n}' not found`);let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst();if(!t)throw Be(`Permission '${n}' not found`);return wt(e,t)}function Xc(e){if(!e.oauthConfig)throw G(`Plugin '${e.id}' has no oauthConfig`)}function eu(e){if(!e.manual)throw new C(500,"connect_not_configured","createCorsair was not given manual config. Set { manual: { baseUrl, redirectUri } } to enable manual connect routes.");return e.manual}function Br(e){let n=eu(e);if(!n.baseUrl?.trim()||!n.redirectUri?.trim())throw new C(500,"connect_not_configured","Manual connect requires manual.baseUrl and manual.redirectUri. Use hub for hosted connect, or set both URLs for manual OAuth.");return n}function nu(e){let n=!!e.hub,t=yn(e.manual);if(!n&&!t)throw new C(500,"connect_not_configured","createCorsair was not given connect config. Set hub: { ... } for Hub mode, or manual: { baseUrl, redirectUri } for manual connect.")}function es(e){if(!e.database||!e.kek)throw new C(500,"database_not_configured","A database and kek are required to issue connect links.")}async function tu(e,n){let t=n?.plugin?.trim();if(!t)throw G("Plugin id is required",{missingFields:["plugin"]});let r=n.tenantId?.trim()||"default",o=Or(e,t);Xc(o);let i=Br(e);es(e);let s=await Yi(o,e);if(!s.configured)throw new C(400,"missing_credentials",`Plugin '${t}' is missing OAuth client credentials`,{missingFields:s.missingFields});let a=un(Oe(t,r),e.kek),c;try{c=new URL(i.baseUrl)}catch{throw new C(500,"connect_misconfigured","manual.baseUrl is not a valid URL. Set a full URL including protocol (e.g. https://app.example.com/connect).")}return c.searchParams.set("state",a),{connectUrl:c.toString(),expiresAt:new Date(Date.now()+vr).toISOString(),tenantId:r}}async function ru(e,n,t){es(n);let r=t.tenantId?.trim()||"default",o={tenantId:r,oauthMode:t.oauthMode},i=t.plugin?.trim();i&&(o.plugin=i);let s=t.providerName?.trim();s&&(o.providerName=s);let a=await mt(e,o);return{connectUrl:a.connectUrl,expiresAt:a.expiresAt,tenantId:r}}async function xt(e,n,t){return nu(n),n.hub?ru(e,n,t):tu(n,t)}async function It(e,n,t){if(n.hub&&!yn(n.manual))throw new C(400,"hub_mode","resolve is not used with hub config. Redirect users to connectUrl from createLink.");let r=t?.trim();if(!r)throw G("state is required",{missingFields:["state"]});Br(n);try{return await Rr(e,r)}catch(o){if(o instanceof oe)switch(o.code){case"invalid_state":throw G("Invalid or expired state");case"client_id_not_configured":throw new C(400,"missing_credentials","OAuth client_id is not configured for this plugin",{missingFields:["client_id"]});case"no_redirect_uri":break}throw new C(500,"resolve_failed","Could not resolve connect link. Check server logs for details.")}}async function St(e,n,t){if(n.hub&&!yn(n.manual))throw new C(400,"hub_mode","oauthCallback is not used with hub config. Hub delivers tokens to your deliveryUrl.");let r=t?.code?.trim(),o=t?.state?.trim(),i=[];if(r||i.push("code"),o||i.push("state"),i.length)throw G("Missing required fields",{missingFields:i});let s=Br(n),{processOAuthCallback:a}=await import("./oauth.js");try{return await a(e,{code:r,state:o,redirectUri:s.redirectUri,callbackParams:t.callbackParams})}catch(c){if(c instanceof Error&&c.name==="OAuthCallbackError")switch(c.code){case"invalid_state":throw G("Invalid or expired state");case"credentials_not_configured":throw new C(400,"missing_credentials","OAuth client credentials are not configured for this plugin",{missingFields:["client_id","client_secret"]})}throw new C(502,"oauth_callback_failed","OAuth callback did not complete. Check server logs for details.")}}async function Ur(e,n){if(!e.database)throw Be("Permission not found");let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst();if(!t)throw Be("Permission not found");return wt(e,t)}async function ns(e,n){return"id"in n?Hr(e,n.id):Ur(e,n.token)}import{createCipheriv as du,createDecipheriv as Cy,randomBytes as is,scryptSync as pu}from"crypto";import{createHmac as Fr,randomUUID as ou,timingSafeEqual as rs}from"crypto";function Lr(e){return e.run??null}function Nr(e){return e.probe??null}function os(e){if(e)return e.startsWith("sha256=")?e.slice(7):e}function _t(e){let n=JSON.stringify({type:e.type,payload:e.payload}),t=Math.floor(Date.now()/1e3).toString(),r=Fr("sha256",e.signingSecret.trim()).update(n).digest("hex");return{body:n,headers:{"content-type":"application/json","x-corsair-signature":`sha256=${r}`,"x-corsair-timestamp":t,"x-corsair-project":e.projectId,"x-corsair-nonce":ou()}}}function $r(e){let n=e.signingSecret.trim();if(!n)return!1;let t=os(e.signatureHeader);if(!t)return!1;let r=Number(e.timestampHeader);if(!Number.isFinite(r)||Math.abs(Date.now()-r*1e3)>We)return!1;let i=Fr("sha256",n).update(e.body).digest("hex");try{return rs(Buffer.from(i,"utf8"),Buffer.from(t,"utf8"))}catch{return!1}}function kn(e){let n=e.signingSecret.trim();if(!n)return{ok:!1,error:"Tunnel signing secret is required"};let t=os(e.signatureHeader);if(!t)return{ok:!1,error:"Invalid tunnel signature"};let r=Number(e.timestampHeader);if(!Number.isFinite(r))return{ok:!1,error:"Invalid or missing tunnel timestamp"};if(Math.abs(Date.now()-r*1e3)>We)return{ok:!1,error:"Tunnel request timestamp is outside the allowed window"};let i=Fr("sha256",n).update(e.body).digest("hex");try{if(!rs(Buffer.from(i,"utf8"),Buffer.from(t,"utf8")))return{ok:!1,error:"Invalid tunnel signature"}}catch{return{ok:!1,error:"Invalid tunnel signature"}}return{ok:!0}}function wn(e){if(!e)return{};try{return JSON.parse(e)}catch{return{}}}function Et(e){return e.httpOk&&(e.status===204||e.body.status==="ok"||e.body.ok===!0)}function Mt(e){let n=e.sync?.encrypted;return typeof n!="string"||!n.trim()?null:{encrypted:n.trim()}}function Ln(e){let n=e.connectUrl?.trim();return n?{connectUrl:n,expiresAt:e.expiresAt}:null}function Wr(e){return Ln(wn(e))}async function jr(e){let n=await Ht({deliveryUrl:e.deliveryUrl,projectId:e.projectId,signingSecret:e.signingSecret,type:"connect.create_link",payload:{tenantId:e.tenantId,plugins:e.plugins}}),t=wn(n.body),r=Et({httpOk:n.ok,status:n.status,body:t}),o=Ln(t);if(!r||!o)throw new Error(Ot({deliveryUrl:e.deliveryUrl,status:n.status,body:n.body,ack:t}));return o}function Dt(e){return Mt(wn(e))}function iu(e){let n=e;for(;n;){if(n instanceof Error){let t=n.code;if(typeof t=="string")return t;n=n.cause;continue}if(typeof n=="object"&&n!==null&&"code"in n){let t=n.code;if(typeof t=="string")return t}break}}function ts(e,n=200){let t=e.trim();return t.length<=n?t:`${t.slice(0,n)}\u2026`}var su="Verify hub.signingSecret in your app matches the signing secret shown in Hub project settings.",au="Check the delivery URL configured for this environment.";function cu(e){return`${e.ack.error?`${e.ack.error} (HTTP ${e.status} from ${e.deliveryUrl})`:`App rejected the signed delivery (HTTP ${e.status} from ${e.deliveryUrl})`}. ${su}`}function uu(e){return`${e.ack.error?`${e.ack.error} (HTTP 404 from ${e.deliveryUrl})`:`Delivery endpoint not found at ${e.deliveryUrl} (HTTP 404)`}. ${au}`}function Nn(e,n){let t=iu(n),r=n instanceof Error?n.message:"Delivery request failed",o;switch(t){case"ECONNREFUSED":o="connection refused \u2014 nothing accepted a TCP connection on that host and port";break;case"ENOTFOUND":o="host not found \u2014 DNS could not resolve the hostname";break;case"ETIMEDOUT":case"UND_ERR_CONNECT_TIMEOUT":o="connection timed out before the app responded";break;case"ECONNRESET":o="connection reset while talking to the app";break;case"CERT_HAS_EXPIRED":case"UNABLE_TO_VERIFY_LEAF_SIGNATURE":case"DEPTH_ZERO_SELF_SIGNED_CERT":o=`TLS certificate error (${t})`;break;default:o=r==="fetch failed"&&t?`${r} (${t})`:r}return[`Could not reach ${e}`,o].join(". ")}function Ot(e){if(e.status===0)return e.ack.error?e.ack.error:e.body.startsWith("Could not reach")?e.body:Nn(e.deliveryUrl,new Error(e.body||"Delivery request failed"));if(e.status===401||e.status===403)return cu(e);if(e.status===404)return uu(e);if(e.ack.error)return`${e.ack.error} (HTTP ${e.status} from ${e.deliveryUrl})`;if(e.status>=500){let t=e.body.trim();return t?`App failed while processing the delivery (HTTP ${e.status} from ${e.deliveryUrl}): ${ts(t)}`:`App failed while processing the delivery (HTTP ${e.status} from ${e.deliveryUrl})`}let n=e.body.trim();return n?`${ts(n)} (HTTP ${e.status} from ${e.deliveryUrl})`:`Delivery failed with HTTP ${e.status} from ${e.deliveryUrl}`}var lu=15e3;async function Ht(e){let{body:n,headers:t}=_t(e);try{let r=await fetch(e.deliveryUrl,{method:"POST",headers:t,body:n,signal:AbortSignal.timeout(lu)}),o=await r.text();return{ok:r.ok,status:r.status,body:o}}catch(r){return{ok:!1,status:0,body:Nn(e.deliveryUrl,r)}}}var gu="aes-256-gcm",fu=12,yu=16,mu=16,hu=32;function bu(e,n){return pu(e.trim(),n,hu)}function qr(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required to encrypt sync manifest");let r=is(mu),o=bu(t,r),i=is(fu),s=du(gu,o,i,{authTagLength:yu}),a=JSON.stringify(e),c=Buffer.concat([s.update(a,"utf8"),s.final()]),l=s.getAuthTag();return[r.toString("base64"),i.toString("base64"),l.toString("base64"),c.toString("base64")].join(":")}var ku=["invalid corsair instance","a database must be configured to sync connections from the app","a database must be configured on the corsair instance","signing secret is required to encrypt sync manifest"];function Kr(e){if(e instanceof Xo)return!1;if(!(e instanceof Error))return!0;let n=e.message.toLowerCase();return!ku.some(t=>n.includes(t))}function wu(e){if(!e)return[];let n=_(e);return n?(e.authConfig?.[n]?.integration??[]).filter(r=>!De(r)):[]}async function $n(e,n){let t=T(e);if(!t.database)throw new Error("A database must be configured to sync connections from the app");await ft(e,{silent:!0});let[r,o]=await Promise.all([bn(t),hn(t)]),i={tenants:r.map(s=>({id:s.id})),plugins:o.map(s=>{let a=wu(t.plugins.find(c=>c.id===s.id));return{id:s.id,authType:s.authType,configured:s.configured,missingFields:s.missingFields,...a.length>0?{integrationCredentialFields:a}:{}}}),syncedAt:new Date().toISOString()};return qr(i,n)}var ge=class extends Error{code;constructor(n,t){super(t),this.name="AuthCredentialsDeliveryError",this.code=n}};async function Bt(e,n){let t=T(e,()=>new ge("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new ge("no_database","Database not configured");let r=K(t,n.plugin,u=>new ge("plugin_not_found",u)),o=_(r);if(!o)throw new ge("invalid_credentials",`Plugin '${r.id}' has no authType configured`);if(o==="oauth_2"||o==="managed")throw new ge("invalid_credentials","OAuth plugins must be connected via sign-in, not credentials delivery");await fn(e,n.tenantId);let i=new Set(Jn(r,o)),a=r.authConfig?.[o]?.account??[],c=B({authType:o,integrationName:n.plugin,tenantId:n.tenantId,kek:t.kek,database:t.database,extraAccountFields:a}),l=0;for(let[u,d]of Object.entries(n.credentials)){if(!d.trim())continue;if(!i.has(u))throw new ge("invalid_credentials",`Unknown credential field '${u}' for plugin '${n.plugin}'`);let p=ee(c,`set_${u}`);if(!p)throw new ge("invalid_credentials",`Cannot set credential field '${u}' for plugin '${n.plugin}'`);await p(d.trim()),l+=1}if(l===0)throw new ge("invalid_credentials","Provide at least one credential field to save");return await we(e,{plugin:r,tenantId:n.tenantId}).catch(()=>{}),{plugin:n.plugin,tenantId:n.tenantId}}var fe=class extends Error{code;constructor(n,t){super(t),this.name="IntegrationCredentialsDeliveryError",this.code=n}};async function Zr(e,n){let t=T(e,()=>new fe("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new fe("no_database","Database not configured");let r=K(t,n.plugin,u=>new fe("plugin_not_found",u)),o=_(r);if(!o)throw new fe("invalid_credentials",`Plugin '${r.id}' has no authType configured`);await Li(e);let i=new Set(ri(r,o)),a=r.authConfig?.[o]?.integration??[],c=F({authType:o,integrationName:n.plugin,kek:t.kek,database:t.database,extraIntegrationFields:a}),l=0;for(let[u,d]of Object.entries(n.credentials)){if(!d.trim())continue;if(!i.has(u))throw new fe("invalid_credentials",`Unknown integration credential field '${u}' for plugin '${n.plugin}'`);let p=ee(c,`set_${u}`);if(!p)throw new fe("invalid_credentials",`Cannot set integration field '${u}' for plugin '${n.plugin}'`);await p(d.trim()),l+=1}if(l===0)throw new fe("invalid_credentials","Provide at least one integration credential field to save");return{plugin:n.plugin}}var Ut=new Map;function Cu(e){for(let[n,t]of Ut)t<=e&&Ut.delete(n)}function Ft(e,n){let t=e.trim();if(!t)return{ok:!1,error:"Delivery replay key is required"};if(!Number.isFinite(n)||n<=0)return{ok:!1,error:"Delivery replay TTL must be a positive number"};let r=Date.now();Cu(r);let o=Ut.get(t);return o!==void 0&&o>r?{ok:!1,error:"Delivery request already consumed"}:(Ut.set(t,r+n),{ok:!0})}var Ue=class extends Error{code;constructor(n,t){super(t),this.name="ManagedOAuthDeliveryError",this.code=n}};async function Cn(e,n){let{plugin:t,tenantId:r,accessToken:o,refreshToken:i,expiresIn:s,scope:a,authType:c="managed",providerData:l}=n;if(!o.trim())throw new Ue("no_access_token","Managed OAuth delivery missing access_token");let u=T(e,()=>new Ue("invalid_corsair_instance","Invalid corsair instance"));if(!u.database)throw new Ue("no_database","No database configured on corsair instance");let d=K(u,t,g=>new Ue("plugin_not_found",g));await fn(e,r);let p=B({authType:c,integrationName:t,tenantId:r,kek:u.kek,database:u.database});await p.set_access_token(o),i&&await p.set_refresh_token(i),s&&await p.set_expires_at(String(Math.floor(Date.now()/1e3)+s)),a&&await p.set_scope(a),await we(e,{plugin:d,tenantId:r}).catch(()=>{});try{let g=await dt(u.plugins,t,{access_token:o,refresh_token:i,scope:a,...l});if(g){try{let f=d.authConfig?.[c]?.account??[];await pn({database:u.database,kek:u.kek,pluginId:t,tenantId:r,link:g,authType:c,extraAccountFields:f})}catch(f){console.warn(`[corsair:managed-oauth] Failed to persist webhook tenant link for '${t}' tenant '${r}':`,f)}u.hub&&ln(u.hub,{plugin:t,tenantId:r,link:g,authType:c})}}catch(g){console.warn(`[corsair:managed-oauth] Failed to resolve webhook tenant link for '${t}' tenant '${r}':`,g)}return await gn(e,d,r,p).catch(g=>{console.warn(`[corsair:managed-oauth] subscribe failed for '${t}' tenant '${r}':`,g)}),{plugin:t,tenantId:r}}function vu(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function ss(e,n,t=[]){for(let[r,o]of Object.entries(e))if(vu(o)){if(o.match(n))return{webhook:o,path:[...t,r]}}else if(o&&typeof o=="object"){let i=ss(o,n,[...t,r]);if(i)return i}return null}function Tu(e){let n={};for(let[t,r]of Object.entries(e))n[t.toLowerCase()]=Array.isArray(r)?r[0]:r;return n}function Pu(e){let n=e["x-goog-resource-uri"],t=e["x-goog-channel-id"];if(!n||!t)return null;let r={resourceId:e["x-goog-resource-id"]||"",resourceState:e["x-goog-resource-state"]||"",resourceUri:n,channelId:t,channelExpiration:e["x-goog-channel-expiration"]||""};return n.includes("/drive/")&&(r.kind="drive#change"),{message:{data:Buffer.from(JSON.stringify(r)).toString("base64"),messageId:e["x-goog-message-number"]||""}}}async function as(e,n,t,r,o){let i=Tu(n),s=typeof t=="string"?JSON.parse(t):t;(!s||typeof s=="object"&&Object.keys(s).length===0)&&i["x-goog-resource-uri"]&&(s=Pu(i)||s);let c={headers:i,body:s,...r?{query:r}:{}},l=r?.tenantId||"default",u=e.withTenant?e.withTenant(l):e,d=o?.plugin,p=d?[d]:Vn;for(let g of p){let f=u[g];if(!f||!f.webhooks||!d&&f.pluginWebhookMatcher&&!f.pluginWebhookMatcher(c))continue;let h=ss(f.webhooks,c);if(!h)continue;let k=h.path.join("."),b={payload:s,headers:i,rawBody:typeof t=="string"?t:JSON.stringify(t),...r?{query:r}:{},...o?.hubVerified?{hubVerified:!0}:{}};try{let v=await h.webhook.handler(b),P=!!Object.keys(v.returnToSender||{})?.length;return{plugin:g,action:k,body:s,response:P?{...v?.returnToSender,success:!0}:{success:!0},...v.responseHeaders&&{responseHeaders:v.responseHeaders}}}catch(v){return console.error(`Error executing webhook handler for ${g}.${k}:`,v),{plugin:g,action:k,body:s,response:{success:!1,error:v instanceof Error?v.message:"Unknown error"}}}}return{plugin:null,action:null,body:null}}import{createHash as Ru}from"crypto";import*as Ge from"vm";var cs="__corsairFailedStep",Au=3e4,Gr=class{constructor(n,t){this.wakeAt=n;this.stepName=t}__corsairSleep=!0};function us(e){return typeof e=="object"&&e!==null&&e.__corsairSleep===!0}function ls(e,n){return`st_${Ru("sha256").update(`${n} ${e}`).digest("hex").slice(0,16)}`}function Lt(e){if(e instanceof Error)return e.message;if(e!==null&&typeof e=="object"&&"message"in e){let n=e.message;if(typeof n=="string")return n}return String(e)}var ds=new Set(["constructor","prototype","__proto__"]);function Ce(e,n){if(e===null)return null;let t=typeof e;return t==="function"?Iu(e,n):t==="object"?xu(e):e}function xu(e){return new Proxy(e,{get(n,t){if(!ds.has(t))return Ce(Reflect.get(n,t,n),n)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function Iu(e,n){return new Proxy(e,{apply:(t,r,o)=>Su(Reflect.apply(t,n,o)),construct(){throw new Error("Workflow code may not construct host objects")},get(t,r){if(!ds.has(r))return Ce(Reflect.get(t,r,t),t)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function Su(e){return e!==null&&typeof e=="object"&&typeof e.then=="function"?Promise.resolve(e).then(n=>Ce(n,void 0),n=>{throw Ce(n,void 0)}):Ce(e,void 0)}function _u(e){let n=Object.create(null),t=Ge.createContext(n,{name:"corsair-workflow",codeGeneration:{strings:!1,wasm:!1}}),o=Ge.runInContext("(s) => JSON.parse(s)",t,{filename:"corsair:sandbox:json"})(JSON.stringify(e.payload??null)),s=Ge.runInContext(`(function (hostRun, hostSleep) {
|
|
20
|
+
const step = function step(name, fn) { return hostRun(name, fn); };
|
|
21
|
+
step.sleep = function sleep(name, ms) { return hostSleep(name, ms); };
|
|
22
|
+
return step;
|
|
23
|
+
})`,t,{filename:"corsair:sandbox:step"})((p,g)=>e.step(p,g),(p,g)=>e.step.sleep(p,g)),c=Ge.runInContext(`(function (sink) {
|
|
24
|
+
const fwd = (level) => function () {
|
|
25
|
+
try { sink(level, Array.prototype.slice.call(arguments)); } catch (_e) {}
|
|
26
|
+
};
|
|
27
|
+
return { log: fwd('log'), info: fwd('info'), warn: fwd('warn'), error: fwd('error'), debug: fwd('debug') };
|
|
28
|
+
})`,t,{filename:"corsair:sandbox:console"})((p,g)=>{let f=console[p]??console.log;try{f(...g)}catch{}});n.__corsair=Ce(e.corsair,void 0),n.__payload=o,n.__step=s,n.__console=c;let l=Ge.runInContext(`(function () {
|
|
29
|
+
'use strict';
|
|
30
|
+
const module = { exports: {} };
|
|
31
|
+
const require = function (id) {
|
|
32
|
+
throw new Error('Workflow code may not import modules (attempted to require "' + id + '")');
|
|
33
|
+
};
|
|
34
|
+
(function (exports, module, require, console) {
|
|
35
|
+
${e.code}
|
|
36
|
+
})(module.exports, module, require, __console);
|
|
37
|
+
const main = module.exports.main;
|
|
38
|
+
if (typeof main !== 'function') {
|
|
39
|
+
throw new Error('Workflow code must export a \`main\` function');
|
|
40
|
+
}
|
|
41
|
+
return main(__corsair, __payload, __step);
|
|
42
|
+
})()`,t,{filename:"corsair:workflow",timeout:e.timeoutMs});l.catch(()=>{});let u,d=new Promise((p,g)=>{u=setTimeout(()=>g(new Error(`Workflow exceeded ${e.timeoutMs}ms time limit`)),e.timeoutMs)});return Promise.race([l,d]).finally(()=>clearTimeout(u))}async function zr(e){let n=e.memoizedSteps??{},t=[],r=0,o=null,i=(async(s,a)=>{if(o)throw o;let c=r++,l=ls(s,c);if(Object.hasOwn(n,l))return Ce(n[l].output,void 0);try{let u=await a();return t.push({stepId:l,name:s,seq:c,status:"completed",output:u}),u}catch(u){if(us(u))throw u;let d=Lt(u);t.push({stepId:l,name:s,seq:c,status:"failed",error:d});let p=new Error(d);throw p[cs]=s,p}});i.sleep=async(s,a)=>{if(o)throw o;let c=r++,l=ls(s,c);if(Object.hasOwn(n,l))return;t.push({stepId:l,name:s,seq:c,status:"completed",output:null});let u=Number.isFinite(a)?Math.max(0,a):0;throw o=new Gr(Date.now()+u,s),o};try{await _u({code:e.code,corsair:e.corsair,payload:e.payload,step:i,timeoutMs:e.timeoutMs??Au});let s=o;return s?{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()}:{status:"completed",steps:t}}catch(s){if(us(s))return{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()};let a=Lt(s),c=s!==null&&typeof s=="object"?s[cs]:void 0;return{status:"failed",steps:t,error:{message:a,...c?{failedStep:c}:{}}}}}import*as Nt from"vm";var ps=1e4;async function Jr(e){let n=Object.create(null),t=Nt.createContext(n,{name:"corsair-probe",codeGeneration:{strings:!1,wasm:!1}});n.corsair=Ce(e.corsair,void 0);let r=Mu(e.timeoutMs),o=`(async () => {
|
|
43
|
+
const __result = await (async () => {
|
|
44
|
+
${e.code}
|
|
45
|
+
})();
|
|
46
|
+
return JSON.stringify(__result) ?? 'null';
|
|
47
|
+
})()`;try{let i=await Er(()=>{let s=Nt.runInContext(o,t,{filename:"corsair:probe",timeout:r});s.catch(()=>{});let a,c=new Promise((l,u)=>{a=setTimeout(()=>u(new Error(`Probe exceeded ${r}ms time limit`)),r)});return Promise.race([s,c]).finally(()=>clearTimeout(a))});return{status:"ok",value:Eu(i)}}catch(i){return{status:"error",error:Lt(i)}}}function Eu(e){if(typeof e!="string")throw new Error(`Probe returned a non-string result (${typeof e})`);return JSON.parse(e)}function Mu(e){return typeof e!="number"||!Number.isFinite(e)||e<=0?ps:Math.min(e,ps)}function ze(e){return e.deliveryMode==="auth.credentials"}function Wn(e){return e.deliveryMode==="connections.sync"}function $t(e){return e.deliveryMode==="connect.create_link"}function jn(e){return e.deliveryMode==="permission.approve"||e.deliveryMode==="permission.deny"}function qn(e){return e.deliveryMode==="oauth.tokens"}function Wt(e){return e.deliveryMode==="oauth.callback"||e.deliveryMode===void 0&&!ze(e)&&!Wn(e)&&!$t(e)&&!jn(e)&&!qn(e)}function Du(e){return{status:"ok",connectLink:{connectUrl:e.connectUrl,expiresAt:e.expiresAt},webhookResponse:{status:200,body:{status:"ok",connectUrl:e.connectUrl,expiresAt:e.expiresAt}}}}async function Ou(e,n){try{return{status:"ok",webhookResponse:{status:200,body:{status:"ok",sync:{encrypted:await $n(e,n)}}}}}catch(t){return{status:"failed",retryable:Kr(t),error:t instanceof Error?t.message:"Connections sync delivery failed"}}}async function Hu(e,n){try{let t=await ht(e,n);return Du(t)}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Connect link delivery failed"}}}function Vr(e,n){if(e instanceof Headers)return e.get(n)??void 0;let t=e[n]??e[n.toLowerCase()];return Array.isArray(t)?t[0]:typeof t=="string"?t:void 0}async function Bu(e,n,t){let r=typeof t.tenantId=="string"?t.tenantId:typeof t.query?.tenantId=="string"?t.query.tenantId:void 0;return r||(!n.database||!t.plugin||!t.linkType||!t.externalId?void 0:await pt({database:n.database,kek:n.kek,pluginId:t.plugin,linkType:t.linkType,externalId:t.externalId})??void 0)}async function Uu(e,n,t,r){let o=await Bu(e,n,t),i={...t.query??{},...o?{tenantId:o}:{}},s=await as(e,t.headers,t.body,i,{plugin:t.plugin,hubVerified:r&&t.hubVerified===!0});if(!s.plugin)return{status:"failed",retryable:!1,error:"No matching webhook handler found"};if(s.response&&s.response.success===!1)return{status:"failed",retryable:!1,error:typeof s.response.error=="string"?s.response.error:"Webhook handler failed"};let a=s.response?.returnToSender,c=a&&typeof a=="object"&&typeof a.validationToken=="string"&&Object.keys(a).length===1?a.validationToken:a||(s.response?.data??s.response);return{status:"ok",webhookResponse:{status:s.response?.statusCode??200,body:c,headers:s.responseHeaders}}}async function Fu(e,n){return await Fn(e,{code:n.code,state:n.state,redirectUri:n.redirectUri,callbackParams:n.callbackParams,...n.plugin&&n.tenantId?{trusted:!0,plugin:n.plugin,tenantId:n.tenantId}:{}}),{status:"ok"}}async function Lu(e,n){return await Cn(e,{plugin:n.plugin,tenantId:n.tenantId,accessToken:n.accessToken,refreshToken:n.refreshToken,expiresIn:n.expiresIn,scope:n.scope,authType:n.authType,providerData:n.providerData}),{status:"ok"}}async function Qr(e,n,t){let r=await Yr(e,{token:n},t);if(r.status!=="ok")throw new Error(r.error??"Permission decision failed")}async function Yr(e,n,t){let r=T(e),o=n.token?.trim();if(!o)return{status:"failed",retryable:!1,error:"Permission token is required"};if(!r.database)return{status:"failed",retryable:!1,error:"Database not configured"};let i=new Date().toISOString(),s=await r.database.db.selectFrom("corsair_permissions").selectAll().where("token","=",o).executeTakeFirst();return s?s.status!=="pending"?{status:"ok"}:s.expires_at<i?(await r.database.db.updateTable("corsair_permissions").set({status:"expired",updated_at:new Date}).where("id","=",s.id).execute(),{status:"failed",retryable:!1,error:"Permission has expired"}):(await r.database.db.updateTable("corsair_permissions").set({status:t,updated_at:new Date}).where("id","=",s.id).execute(),{status:"ok"}):{status:"failed",retryable:!1,error:"Permission not found"}}async function Nu(e,n){try{return await Bt(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Credential delivery failed"}}}async function $u(e,n){try{return await Zr(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Integration credential delivery failed"}}}function gs(e,n){let t=e;return n&&typeof t?.withTenant=="function"?t.withTenant(n):e}async function Wu(e,n){try{let t=gs(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",run:await zr({corsair:t,code:n.code,payload:n.trigger?.payload??null,memoizedSteps:n.memoizedSteps})}}}}catch(t){return{status:"failed",retryable:!0,error:t instanceof Error?t.message:"Workflow run failed"}}}async function ju(e,n){try{let t=gs(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",probe:await Jr({corsair:t,code:n.code,timeoutMs:n.timeoutMs})}}}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Probe failed"}}}async function Kn(e,n,t={}){let r=T(e),o=Vr(n.headers,"x-corsair-signature"),i=Vr(n.headers,"x-corsair-timestamp"),s=Vr(n.headers,"x-corsair-nonce"),a=!1;if(t.signingSecret?.trim()){let l=kn({body:n.body,signatureHeader:o,timestampHeader:i,signingSecret:t.signingSecret});if(!l.ok)return{status:"failed",retryable:!1,error:l.error};if(!s?.trim())return{status:"failed",retryable:!1,error:"Missing tunnel nonce"};let u=Ft(`nonce:${s.trim()}`,We);if(!u.ok)return{status:"failed",retryable:!1,error:u.error};a=!0}else if(!t.allowUnsignedTunnel)return{status:"failed",retryable:!1,error:"Tunnel signing secret is required"};let c;try{c=JSON.parse(n.body)}catch{return{status:"failed",retryable:!1,error:"Invalid tunnel envelope JSON"}}if(c.type==="connect.status")return{status:"failed",retryable:!1,error:"connect.status is deprecated; use connections.sync signed delivery instead"};switch(c.type){case"webhook":return Uu(e,r,c.payload,a);case"oauth.callback":return Fu(e,c.payload);case"oauth.tokens":return Lu(e,c.payload);case"permission.approve":return Yr(e,c.payload,"approved");case"permission.deny":return Yr(e,c.payload,"denied");case"auth.credentials":return Nu(e,c.payload);case"integration.credentials":return $u(e,c.payload);case"connect.create_link":return Hu(e,c.payload);case"connections.sync":{let l=t.signingSecret?.trim();return l?Ou(e,l):{status:"failed",retryable:!1,error:"Tunnel signing secret is required for connections.sync"}}case"run":return t.allowWorkflowExecution?Wu(e,c.payload):{status:"failed",retryable:!1,error:"Workflow execution is not enabled (set allowWorkflowExecution: true)"};case"probe":return t.allowWorkflowExecution?ju(e,c.payload):{status:"failed",retryable:!1,error:"Workflow execution is not enabled (set allowWorkflowExecution: true)"};default:return{status:"failed",retryable:!1,error:`Unsupported tunnel type: ${String(c.type)}`}}}function qu(e){let n=e.webhookResponse;return e.status==="ok"?{status:n?.status??200,body:n?.body??{status:"ok"}}:{status:n?.status??502,body:n?.body??{status:"error",error:e.error??"delivery failed"}}}var Xr=3,Ku=250;function Zu(e){return e?.name==="AbortError"}async function Gu(e){try{return(await e.json())?.ok!==!1}catch{return!0}}async function zu(e,n,t,r,o){for(let i=1;i<=Xr;i++){try{let s=await n.fetch(`${e.apiUrl}/api/dev/ack`,{method:"POST",headers:{...t,"content-type":"application/json"},body:JSON.stringify(r),signal:o});if(s.ok)return await Gu(s)||console.warn(`[corsair] hub did not record delivery ${r.deliveryId} (already timed out); the run may be retried`),!0}catch(s){if(Zu(s))throw s}i<Xr&&await ys(Ku)}return console.warn(`[corsair] failed to acknowledge delivery ${r.deliveryId} after ${Xr} attempts; the run may be retried`),!1}async function Ju(e,n,t,r){let o={authorization:`Bearer ${n.projectApiKey}`},i=await t.fetch(`${n.apiUrl}/api/dev/pull`,{headers:o,signal:r});if(i.status===204)return"idle";if(!i.ok)return"error";let{deliveryId:s,body:a,headers:c}=await i.json(),l=await t.process(e,{headers:c,body:a},{signingSecret:n.signingSecret,allowWorkflowExecution:n.allowWorkflowExecution}),{status:u,body:d}=qu(l);return await zu(n,t,o,{deliveryId:s,status:u,body:d},r)?"handled":"error"}var fs=1e3,Vu=5e3,Yu=3e4;function ys(e){return new Promise(n=>setTimeout(n,e))}var jt=globalThis.__corsairConnectLoops??=new Map;function Qu(e,n={fetch,process:Kn}){let t;try{t=U(e)}catch{return{stop:()=>{}}}if(!t.projectApiKey.startsWith("ck_dev_"))return{stop:()=>{}};if(!t.allowWorkflowExecution)return console.warn("[corsair] workflow executions not enabled. Please set hub: { ..., allowWorkflowExecution: true }"),{stop:()=>{}};let r=t.projectApiKey;if(jt.has(r))return{stop:()=>{}};let o=Symbol("corsair-connect-loop");jt.set(r,o);let i=()=>{jt.get(r)===o&&jt.delete(r)},s=!1,a=null;return(async()=>{let l=fs,u=!1,d=async p=>{u||(console.warn("[corsair] connect loop error; retrying",p),u=!0),s||await ys(l),l=Math.min(l*2,Vu)};try{for(;!s;){a=new AbortController;let p=setTimeout(()=>a?.abort(),Yu);try{await Ju(e,t,n,a.signal)==="error"?await d("pull or ack failed"):(u=!1,l=fs)}catch(g){if(s)break;await d(g instanceof Error?g.message:g)}finally{clearTimeout(p)}}}finally{i()}})(),{stop:()=>{s=!0,a?.abort(),i()}}}function ms(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function Xu(e,n){return n&&!n.has(e.id)?!1:_(e)!==null}async function hs(e,n,t={}){let r=T(e),o=n.trim()||"default",i=t.pluginIds?.length?new Set(t.pluginIds):null,s=await Bn(r,o,{pluginIds:t.pluginIds}),a=new Map(s.map(l=>[l.plugin,l])),c=r.plugins.filter(l=>Xu(l,i)).map(l=>{let u=_(l),d=a.get(l.id);return d?{plugin:l.id,providerName:Se(l.id),authKind:ms(u),status:d.status,connected:d.connected,fields:d.fields.map(p=>({name:p.name,level:p.level,required:p.required,configured:p.configured})),missingRequiredFields:d.missingRequiredFields}:{plugin:l.id,providerName:Se(l.id),authKind:ms(u),status:"not_started",connected:!1,fields:[],missingRequiredFields:[]}});return{tenantId:o,plugins:c}}async function bs(e,n){let t=U(e);return q({hub:t,path:`/projects/${encodeURIComponent(n.projectId)}/connections`,notFoundMessage:"Hub REST API not found at /projects/:id/connections. Check HUB_API_URL and ensure the Hub API is deployed.",parseResponse:Qn})}function el(e){return typeof e=="string"&&e.length>0}function qt(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty managed pricing credentials payload");let n=e;if(!el(n.api_key))throw new Error("Hub API returned incomplete managed pricing credentials (expected api_key)");let t={api_key:n.api_key};return n.expires_in!==void 0&&typeof n.expires_in=="number"&&Number.isFinite(n.expires_in)&&n.expires_in>0&&(t.expires_in=n.expires_in),t}var ks=1024*1024,ws=3e4;function Je(e){return e!==void 0&&Number.isFinite(e)&&e>0?e:ks}function Ve(e){return e!==void 0&&Number.isFinite(e)&&e>=0?e:ws}function vn(e){return new C(413,"payload_too_large",`Request body exceeds the ${e}-byte limit`)}function nl(e){return new C(408,"request_timeout",`Request body stalled: no bytes received for ${e}ms`)}async function Kt(e,n){if(!(n>0))return e();let t;try{return await Promise.race([e(),new Promise((r,o)=>{t=setTimeout(()=>o(nl(n)),n)})])}finally{clearTimeout(t)}}async function Zt(e,n){if(e.body===null)return"";let t=e.body.getReader();try{let r=[],o=0;for(;;){let{done:a,value:c}=await Kt(()=>t.read(),n.bodyStallTimeoutMs);if(a)break;if(o+=c.byteLength,o>n.maxBodyBytes)throw vn(n.maxBodyBytes);r.push(c)}let i=new Uint8Array(o),s=0;for(let a of r)i.set(a,s),s+=a.byteLength;return new TextDecoder().decode(i)}catch(r){throw t.cancel().catch(()=>{}),r}}var eo=new Map;function Cs(e){let n;try{n=U(e)}catch{return}let t=ur(n);t&&eo.get(n.projectApiKey)!==t&&(eo.set(n.projectApiKey,t),x({hub:n,path:"/apps/announce",body:{deliveryUrl:t},parseResponse:()=>({ok:!0})}).catch(()=>{eo.delete(n.projectApiKey)}))}var tl=[".corsair.dev"];function rl(e){return e==="localhost"||e==="127.0.0.1"||e==="[::1]"||e==="::1"}function ol(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:rl(n)?!0:tl.some(r=>n===r.slice(1)||n.endsWith(r))}catch{return!1}}function vs(e){return!e||!ol(e)?null:{"Access-Control-Allow-Origin":e,"Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"content-type, x-corsair-signature, x-corsair-timestamp, x-corsair-project, x-corsair-nonce, access-control-request-private-network","Access-Control-Allow-Private-Network":"true","Access-Control-Max-Age":"0",Vary:"Origin"}}function Ts(e,n){if(!n)return e;let t=new Headers(e.headers);for(let[r,o]of Object.entries(n))t.set(r,o);return new Response(e.body,{status:e.status,statusText:e.statusText,headers:t})}function no(e,n){let t=new URL(e);return n.error?(t.searchParams.set("error",n.error),t.toString()):n.connectedPlugin?(t.searchParams.set("connected",n.connectedPlugin),t.toString()):(n.status!==void 0&&t.searchParams.set("status",Buffer.from(JSON.stringify(n.status)).toString("base64url")),t.toString())}async function to(e,n){let t=U(e),o=new URL(n).searchParams.get("d");if(!o)return{type:"json",status:200,body:{status:"ok",message:"Corsair tunnel endpoint is active",timestamp:new Date().toISOString()}};let i=Ee(o,t.signingSecret);if(!i)return{type:"json",status:400,body:{error:"Invalid or expired delivery token"}};let s=Ft(`browser:${i.jti}`,_e);if(!s.ok)return{type:"json",status:400,body:{error:s.error}};try{if(Wn(i)){if(!i.hubOrigin||!i.requestId)return{type:"json",status:400,body:{error:"Connections sync delivery requires hubOrigin and requestId for client bridge"}};let a=await $n(e,t.signingSecret);return{type:"text",status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:rn({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!0,body:{status:"ok",sync:{encrypted:a}}})}}if($t(i)){if(!i.hubOrigin||!i.requestId)return{type:"json",status:400,body:{error:"Connect link delivery requires hubOrigin and requestId for client bridge"}};let a=i.connectLinkPlugins?.filter(Boolean)??[];if(a.length===0)return{type:"json",status:400,body:{error:"Connect link delivery requires at least one plugin in connectLinkPlugins"}};let c=await ht(e,{tenantId:i.tenantId,plugins:a});return{type:"text",status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:rn({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!0,body:{status:"ok",connectUrl:c.connectUrl,expiresAt:c.expiresAt}})}}if(ze(i))return i.hubSuccessUrl?i.credentials?(await Bt(e,{plugin:i.plugin,tenantId:i.tenantId,credentials:i.credentials}),{type:"redirect",url:no(i.hubSuccessUrl,{connectedPlugin:i.plugin})}):{type:"redirect",url:no(i.hubSuccessUrl,{error:"Credential delivery missing credentials"})}:{type:"json",status:400,body:{error:"Credential delivery missing hubSuccessUrl"}};if(jn(i)){if(!i.permissionToken)return{type:"json",status:400,body:{error:"Permission delivery missing permission token"}};await Qr(e,i.permissionToken,i.deliveryMode==="permission.approve"?"approved":"denied")}else if(qn(i)){if(!i.accessToken)return{type:"json",status:400,body:{error:"Managed OAuth delivery missing access_token"}};await Cn(e,{plugin:i.plugin,tenantId:i.tenantId,accessToken:i.accessToken,refreshToken:i.refreshToken,expiresIn:i.expiresIn,scope:i.scope,authType:i.authType,providerData:i.providerData})}else{if(!Wt(i)||!i.code||!i.state||!i.redirectUri)return{type:"json",status:400,body:{error:"Invalid BYO OAuth delivery token"}};await Fn(e,{code:i.code,state:i.state,redirectUri:i.redirectUri,trusted:!0,plugin:i.plugin,tenantId:i.tenantId})}}catch(a){let c=a instanceof Error?a.message:"Hub delivery failed";return Wn(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:rn({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:c})}:$t(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:rn({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:c})}:ze(i)&&i.hubSuccessUrl?{type:"redirect",url:no(i.hubSuccessUrl,{error:c})}:ze(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:rn({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:c})}:{type:"json",status:400,body:{error:c}}}return{type:"redirect",url:i.hubSuccessUrl}}async function ro(e,n){let t=U(e),r=await Kn(e,n,{signingSecret:t.signingSecret,allowWorkflowExecution:t.allowWorkflowExecution});if(r.status!=="ok")return{type:"json",status:r.retryable===!1?400:502,body:{error:r.error??"Tunnel processing failed"}};let o=r.webhookResponse;if(!o)return{type:"json",status:200,body:{status:"ok"}};let i=o.status??200,s=o.headers;return o.body&&typeof o.body=="object"&&!(o.body instanceof ArrayBuffer)?{type:"json",status:i,body:o.body,headers:s}:{type:"text",status:i,body:typeof o.body=="string"?o.body:o.body?JSON.stringify(o.body):null,headers:s}}function oo(e){if(e.type==="redirect")return Response.redirect(e.url,302);let n=new Headers;for(let[t,r]of Object.entries(e.headers??{}))typeof r=="string"&&n.set(t,r);return e.type==="json"?Response.json(e.body,{status:e.status,headers:n}):new Response(e.body,{status:e.status,headers:n})}async function io(e,n){return n.method==="GET"?to(e,n.url):ro(e,{headers:n.headers,body:n.body??""})}async function so(e,n){try{let t=await io(e,n);return oo(t)}catch(t){if(t instanceof he)return Response.json({error:t.message},{status:503});throw t}}async function Ye(e,n,t){Cs(e);let r=n.method.toUpperCase(),o=vs(n.headers.get("origin"));if(r==="OPTIONS")return o?new Response(null,{status:204,headers:o}):Response.json({error:"Method not allowed"},{status:405});if(r!=="GET"&&r!=="POST")return Response.json({error:"Method not allowed"},{status:405});let i=await so(e,{method:r,url:n.url,headers:n.headers,body:r==="POST"?await Zt(n,{maxBodyBytes:Je(t?.maxBodyBytes),bodyStallTimeoutMs:Ve(t?.bodyStallTimeoutMs)}):void 0});return Ts(i,o)}var S=class extends Error{pluginId;authType;connectUrl;tenantId;constructor(n,t,r,o){super(r??`[auth-missing:${n}:${t}]`),Object.setPrototypeOf(this,new.target.prototype),this.name="AuthMissingError",this.pluginId=n,this.authType=t,this.connectUrl=o?.connectUrl??null,this.tenantId=o?.tenantId??null}};function Tn(e){if(e.forceRefresh||!e.accessToken)return!1;if(!e.expiresAt)return!0;let n=e.now??Math.floor(Date.now()/1e3);return Number(e.expiresAt)>n+300}async function Pn(e,n,t){let r=Math.floor(Date.now()/1e3),o=t?Number(t):Number.NaN,i=typeof n.expires_in=="number"?r+n.expires_in:Number.isFinite(o)&&o>r?o:r+3600;return await e.set_access_token(n.access_token),await e.set_expires_at(String(i)),n.refresh_token&&await e.set_refresh_token(n.refresh_token),n.scope&&await e.set_scope(n.scope),i}var Ps=new WeakMap;function Qe(e,n,t){let r=Ps.get(e);r||(r=new Map,Ps.set(e,r));let o=r.get(n);if(o!==void 0)return o;let i=t().finally(()=>{r.delete(n)});return r.set(n,i),i}var Rs=300;async function ao(e,n){let{keys:t,hub:r,plugin:o,tenantId:i}=e,s=n?.forceRefresh??!1,a=`managed:${o}:${i}`;return Qe(t,a,async()=>{let[c,l,u]=await Promise.all([t.get_access_token(),t.get_expires_at(),t.get_refresh_token()]);if(!c&&!u)throw new S(o,"managed");let d=Math.floor(Date.now()/1e3);if(!s&&c&&l&&Number(l)>d+Rs)return{accessToken:c,expiresAt:Number(l),refreshed:!1};if(!u&&c&&!s){let f=l?Number(l):null;if(f===null||f>d+Rs)return{accessToken:c,expiresAt:f??d+3600,refreshed:!1}}if(!u)throw new S(o,"managed");let p=await sl(r,o,i,u),g=await Pn(t,p,l);return{accessToken:p.access_token,expiresAt:g,refreshed:!0}})}function il(e){return e.includes("Managed OAuth connection not found")||e.includes("Managed OAuth connection has no tokens")}async function sl(e,n,t,r){try{return await x({hub:e,path:"/oauth/refresh",body:{plugin:n,tenantId:t,refresh_token:r},parseResponse:tn})}catch(o){let i=o instanceof Error?o.message:"";throw il(i)?new S(n,"managed"):o}}async function As(e,n){e._refreshAuth=async()=>(await ao(n,{forceRefresh:!0})).accessToken}var al="",cl=60,co=new WeakMap;function xs(e){let n=nt(e.apiUrl),t=e.instanceKey?.trim()??"";return[encodeURIComponent(n),encodeURIComponent(e.projectApiKey),encodeURIComponent(t)].join(al)}function ul(e,n,t,r){let i=`${xs(e)}:${n}:${t}`;return r?`${i}:${r}`:i}function ll(e,n){return co.get(e)?.get(n)}function dl(e,n,t){let r=co.get(e);r||(r=new Map,co.set(e,r)),r.set(n,t)}function pl(e,n){return e.expiresAt===null?!1:e.expiresAt>n+cl}function uo(e,n){if(!n)throw new S(e,"managed_pricing",`[auth-missing:${e}:managed_pricing]: Hub config is required. Pass hub: { ... } to createCorsair().`)}async function Is(e,n){uo(e.plugin,e.hub);let t=n?.forceRefresh??!1,r=ul(e.hub,e.plugin,e.tenantId,n?.operation),i=`managed_pricing:${t?"force":"routine"}:${r}`;return Qe(e.cache,i,async()=>{let s=Math.floor(Date.now()/1e3);if(!t){let l=ll(e.cache,r);if(l&&pl(l,s))return{apiKey:l.apiKey,expiresAt:l.expiresAt,fromCache:!0}}let a=await x({hub:e.hub,path:"/managed-pricing/credentials",body:{plugin:e.plugin,tenantId:e.tenantId,...n?.operation?{operation:n.operation}:{}},notFoundMessage:"Managed pricing is not configured for this project",parseResponse:qt}),c=a.expires_in!==void 0?s+a.expires_in:null;return dl(e.cache,r,{apiKey:a.api_key,expiresAt:c}),{apiKey:a.api_key,expiresAt:c,fromCache:!1}})}function Ss(){return{}}function _s(e){return{delivery:n=>Ye(e,n),deliveryOptions:n=>Ye(e,n)}}var Es=1200*1e3;function lo(){return me()}function po(){return Es}function go(e,n){return En(e,n,Es)}function fo(e,n){return le(e,n)}function yo(e){return je(e)}var Ms=600*1e3;function mo(){return me()}function ho(){return Ms}function bo(e,n){return En(e,n,Ms)}function ko(e,n){return le(e,n)}function wo(e){return mr(e)}function Co(e){return je(e)}function vo(){return me()}function To(e,n,t){return rt(e,n,Math.floor(t.getTime()/1e3))}function Po(e,n){return le(e,n)}function Ro(e){return je(e)}var Xe=class extends Error{constructor(){super(`Corsair KEK is missing. Pass \`kek\` to createCorsair() or set CORSAIR_KEK in your environment. Generate one with: openssl rand -base64 ${qe}`),this.name="CorsairKekMissingError"}};function Gt(e,n){let t=[];e||t.push("database"),n||t.push("kek");let r={};return new Proxy(r,{get(o,i){if(e&&!n)throw new Xe;let s=t.length>1;throw new Error(`corsair.keys.${String(i)}: Cannot access keys because ${t.join(" and ")} ${s?"are":"is"} not configured. Provide both 'database' and 'kek' in createCorsair() to enable key management.
|
|
48
|
+
|
|
49
|
+
To generate a KEK, run: openssl rand -base64 ${qe}`)}})}async function gl(e){let n=!1;for(;;){let t=await e.database.db.selectFrom("corsair_integrations").selectAll().where("name","=",e.integrationName).executeTakeFirst();if(!t){if(!n&&e.ensureProvisioned){n=!0,await e.ensureProvisioned();continue}throw new Error(`Integration "${e.integrationName}" not found. Make sure to create the integration first.`)}let r=await e.database.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",e.tenantId).where("integration_id","=",t.id).executeTakeFirst();if(!r){if(!n&&e.ensureProvisioned){n=!0,await e.ensureProvisioned();continue}throw new Error(`Account not found for tenant "${e.tenantId}" and integration "${e.integrationName}". Make sure to create the account first.`)}return{integrationId:t.id,accountId:r.id,integration:{id:t.id,config:t.config,dek:t.dek??null},account:{id:r.id,config:r.config,dek:r.dek??null}}}}async function Ds(e){let{integrationId:n,accountId:t}=await gl(e);return{integrationId:n,accountId:t}}function Os(e,n){let t=()=>{if(!e)throw new Error("corsair.chats requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e};return{create:r=>lr(t(),{tenantId:n,message:r}),list:()=>pr(t(),{tenantId:n}),get:r=>({message:o=>dr(t(),{chatId:r,tenantId:n,message:o}),listMessages:()=>gr(t(),{chatId:r,tenantId:n})})}}function Hs(e,n){return`[auth-missing:${e}] Authentication required. Direct the user to connect their account: ${n}`}async function fl(e){let n=e.hub;if(n&&e.database&&e.kek)try{let t=await qi(n,{tenantId:e.tenantId,plugin:e.plugin,database:e.database,kek:e.kek,plugins:e.plugins,multiTenancy:e.multiTenancy});return{message:e.manual?.onAuthMissing?e.manual.onAuthMissing({plugin:e.pluginId,connectUrl:t.connectUrl,state:t.token}):Hs(e.pluginId,t.connectUrl),connectUrl:t.connectUrl}}catch{return{message:`[auth-missing:${e.pluginId}:${e.authType}] Authentication required. Could not create connect link. Check hub configuration and server logs.`,connectUrl:null}}return{message:`[auth-missing:${e.pluginId}:${e.authType}]`,connectUrl:null}}function yl(e,n,t){let r=un(Oe(e,n.tenantId??t??"default"),n.kek),o=new URL(n.baseUrl);o.searchParams.set("state",r);let i=o.toString();return{message:n.onAuthMissing?n.onAuthMissing({plugin:e,connectUrl:i,state:r}):Hs(e,i),connectUrl:i}}async function ml(e){let n=e.tenantId??"default",t=e.error.pluginId;return e.error.authType==="managed_pricing"?{message:e.error.message,connectUrl:null}:e.manual&&yn(e.manual)&&e.manual.oauthConfig&&e.manual.kek&&e.error.authType==="oauth_2"?yl(t,{...e.manual,baseUrl:e.manual.baseUrl,kek:e.manual.kek},e.tenantId):e.hub&&e.plugin&&e.kek&&e.database&&e.plugins?fl({manual:e.manual,hub:e.hub,plugin:e.plugin,pluginId:t,tenantId:n,authType:e.error.authType,database:e.database,kek:e.kek,plugins:e.plugins,multiTenancy:e.multiTenancy}):{message:e.error.message,connectUrl:null}}async function Bs(e){let{message:n,connectUrl:t}=await ml(e);throw new S(e.error.pluginId,e.error.authType,n,{connectUrl:t,tenantId:e.tenantId??"default"})}var zt="connect.request",xo="connect.cleared",hl=600*1e3;async function Ao(e,n,t){let r=await e.db.selectFrom("corsair_integrations").select("id").where("name","=",t).executeTakeFirst();return r?(await e.db.selectFrom("corsair_accounts").select("id").where("tenant_id","=",n).where("integration_id","=",r.id).executeTakeFirst())?.id??null:null}async function bl(e,n){return(await e.db.selectFrom("corsair_accounts").select("id").where("tenant_id","=",n).execute()).map(r=>r.id)}async function kl(e,n,t){let r=await e.db.selectFrom("corsair_events").select("created_at").where("account_id","=",n).where("event_type","in",[zt,xo]).orderBy("created_at","desc").limit(1).executeTakeFirst();if(!r)return t;let o=r.created_at instanceof Date?r.created_at.getTime():Date.parse(String(r.created_at));return Math.max(t,o+1)}async function Us(e,n,t,r,o){let i=await kl(e,n,o),s=new Date(i);await e.db.insertInto("corsair_events").values({id:nn(),created_at:s,updated_at:s,account_id:n,event_type:t,payload:r}).execute()}async function wl(e,n,t=Date.now()){let r=await Ao(e,n.tenantId,n.plugin);r&&await Us(e,r,zt,{plugin:n.plugin,connectUrl:n.connectUrl},t)}function Cl(e){let n=e;if(typeof e=="string")try{n=JSON.parse(e)}catch{return null}return!n||typeof n!="object"||Array.isArray(n)?null:n}async function vl(e,n,t,r,o){let i=await e.db.selectFrom("corsair_events").select(["event_type","payload","created_at"]).where("account_id","=",n).where("event_type","in",[zt,xo]).orderBy("created_at","desc").limit(1).executeTakeFirst();if(!i||i.event_type!==zt)return null;let s=i.created_at instanceof Date?i.created_at.getTime():Date.parse(String(i.created_at));if(r-s>o)return null;let a=Cl(i.payload);if(!a)return null;let c=a.plugin,l=a.connectUrl;return typeof c!="string"||typeof l!="string"?null:{plugin:c,connectUrl:l,requestedAt:new Date(s).toISOString(),tenantId:t,requestedAtMs:s,accountId:n}}async function Io(e,n,t=Date.now(),r=hl){let o=await bl(e,n);if(o.length===0)return null;let i=(await Promise.all(o.map(l=>vl(e,l,n,t,r)))).filter(l=>l!==null);if(i.length===0)return null;i.sort((l,u)=>l.requestedAtMs-u.requestedAtMs||l.accountId.localeCompare(u.accountId));let{requestedAtMs:s,accountId:a,...c}=i[0];return c}async function Fs(e,n,t=Date.now(),r){let o;if(r)o=await Ao(e,n,r);else{let i=await Io(e,n,t);o=i?await Ao(e,n,i.plugin):null}o&&await Us(e,o,xo,{},t)}async function So(e,n){if(!(!e||!n.plugin||!n.connectUrl))try{await wl(e,{tenantId:n.tenantId??"default",plugin:n.plugin,connectUrl:n.connectUrl})}catch{}}var Tl=async(e,n)=>(console.error(`[corsair:${n.pluginId}:${n.operation}]`,{error:e.message,input:n.input}),{maxRetries:0});async function Ls(e,n,t,r,o){let i={pluginId:n,operation:t,input:r,originalError:e},s=Object.keys(o).find(l=>o[l]?.match(e,i));return await(o[s||"DEFAULT"]?.handler||Tl)(e,i)}function Pl(e){return typeof e=="function"}function _o({endpoints:e,hooks:n,ctx:t,tree:r,pluginId:o,errorHandlers:i,currentPath:s=[],keyBuilder:a,permissionsConfig:c,endpointMeta:l,database:u,permissionsOptions:d,tenantId:p,manualConfig:g,hubConfig:f,plugin:h,kek:k,allPlugins:b,multiTenancy:v}){for(let[P,D]of Object.entries(e)){let M=n?.[P];if(Pl(D)){let O=M,w=[...s,P].join("."),R=async(A={})=>{let X=l?.[w];Mr(w,X?.riskLevel??"write");let te;if(c){let N=X,{result:ce,reason:W,onComplete:In,token:Ae,id:$e,expiresAt:re}=await Vi({pluginId:o,endpointPath:w,args:A,mode:c.mode,override:c.overrides?.[w],riskLevel:N?.riskLevel??"write",meta:N,db:u,timeoutMs:d?Dr(d.timeout):void 0,tenantId:p,approvalMode:d?.mode});if(ce==="blocked"){let ue;W==="denied"?ue=`Action '${w}' was denied by the user. Await further instructions before proceeding.`:W==="policy"?ue=`Action '${w}' is blocked by the permission policy. Update the corsair config to allow it.`:W==="timeout"?ue=`Action '${w}' timed out waiting for approval.`:Ae&&$e?ue=await _r({permissionsOptions:d,manual:g,hub:f,permissionId:$e,permissionToken:Ae,plugin:o,endpoint:w,args:A,tenantId:p??"default",expiresAt:re??new Date(Date.now()+(d?Dr(d.timeout):600*1e3)).toISOString(),operationPath:w}):ue=`Action '${w}' requires user approval before it can run.`;let ir=W==="denied"||W==="policy"||W==="timeout"?W:"pending";throw new He(ue,ir)}te=In}let H=async(N,ce,W)=>{try{return await D(ce,W)}catch(In){if(In instanceof Error){let Ae=await Ls(In,o,w,typeof W=="object"&&W!==null?W:{args:W},i);if(N<(Ae.maxRetries||0)){let $e=N+1;console.log(`Retrying (${$e} / ${Ae.maxRetries})...`);let re;if(Ae.headersRetryAfterMs)re=Ae.headersRetryAfterMs;else switch(Ae.retryStrategy){case"exponential_backoff":re=Math.pow(2,$e-1)*1e3;break;case"exponential_backoff_jitter":let ue=Math.pow(2,$e-1)*1e3,ir=(Math.random()-.5)*1e3;re=Math.max(0,ue+ir);break;case"linear_1s":re=1e3;break;case"linear_2s":re=2e3;break;case"linear_3s":re=3e3;break;case"linear_4s":re=4e3;break;default:re=1e3;break}return await new Promise(ue=>setTimeout(ue,re)),await H($e,ce,W)}}throw In}},L;try{L=a?await a(t,"endpoint"):void 0}catch(N){if(N instanceof ye)throw h&&f&&dn({hub:f,database:u,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!1}),await So(u,{tenantId:N.tenantId??p,plugin:N.plugin,connectUrl:N.connectUrl}),N;if(N instanceof S){h&&f&&dn({hub:f,database:u,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!1});try{await Bs({error:N,manual:g,hub:f,plugin:h,tenantId:p,database:u,kek:k,plugins:b,multiTenancy:v})}catch(ce){throw ce instanceof S&&await So(u,{tenantId:ce.tenantId??p,plugin:ce.pluginId,connectUrl:ce.connectUrl}),ce}}throw N}if(!O?.before&&!O?.after){let N=await H(0,{...t,key:L},A);return await te?.(),h&&f&&dn({hub:f,database:u,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!0}),N}let Re={...t,key:L},Ne=O.before?await O.before(Re,A):{ctx:Re,args:A,continue:!0,passToAfter:void 0};if(Ne.continue===!1)return;let Jo=await H(0,Ne.ctx,Ne.args);return await O.after?.(Ne.ctx,Jo,Ne.passToAfter),await te?.(),h&&f&&dn({hub:f,database:u,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!0}),Jo};r[P]=R}else if(D&&typeof D=="object"){let O={};_o({endpoints:D,hooks:M,ctx:t,tree:O,pluginId:o,errorHandlers:i,currentPath:[...s,P],keyBuilder:a,permissionsConfig:c,endpointMeta:l,database:u,permissionsOptions:d,tenantId:p,manualConfig:g,hubConfig:f,plugin:h,kek:k,allPlugins:b,multiTenancy:v}),r[P]=O}}}function Rl(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function Eo({webhooks:e,hooks:n,ctx:t,webhooksTree:r,keyBuilder:o}){for(let[i,s]of Object.entries(e)){let a=n?.[i];if(Rl(s)){let c=a,l=async u=>{let d=(g,f)=>s.handler(g,f),p=o&&u?.hubVerified!==!0?await o(t,"webhook"):void 0;return!c?.before&&!c?.after?d({...t,key:p},u):(async()=>{let g={...t,key:p},f=c.before?await c.before(g,u):{ctx:g,args:u,continue:!0,passToAfter:void 0};if(f.continue===!1)return;let h=await d(f.ctx,f.args);return h?.success===!0&&await c.after?.(f.ctx,h,f.passToAfter),h})()};r[i]={match:s.match,handler:l}}else if(s&&typeof s=="object"){let c={};Eo({webhooks:s,hooks:a,ctx:t,webhooksTree:c,keyBuilder:o}),r[i]=c}}}function Ns(e){return e&&typeof e=="object"?e:{}}async function $s(e,n){return q({hub:e,path:`/workflows?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=Ns(t).workflows;return Array.isArray(r)?r:[]}})}async function Ws(e,n){return q({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>Ns(t).workflow})}async function js(e,n){await x({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/status?tenantId=${encodeURIComponent(n.tenantId)}`,body:{status:n.status},notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>t})}async function qs(e,n){await x({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/rename?tenantId=${encodeURIComponent(n.tenantId)}`,body:{name:n.name},notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>t})}async function Ks(e,n){return x({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/run?tenantId=${encodeURIComponent(n.tenantId)}`,body:{payload:n.payload,idempotencyKey:n.idempotencyKey},notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>t})}function Mo(e){return e&&typeof e=="object"?e:{}}async function Zs(e,n){return q({hub:e,path:`/runs?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=Mo(t).runs;return Array.isArray(r)?r:[]}})}async function Gs(e,n){return q({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/runs?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>{let r=Mo(t).runs;return Array.isArray(r)?r:[]}})}async function zs(e,n){return q({hub:e,path:`/runs/${encodeURIComponent(n.runId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Run "${n.runId}" not found`,parseResponse:t=>Mo(t).run})}async function Do(e,n,t){await x({hub:e,path:`/runs/${encodeURIComponent(t.runId)}/${n}?tenantId=${encodeURIComponent(t.tenantId)}`,body:{},notFoundMessage:`Run "${t.runId}" cannot be ${n==="cancel"?"canceled":`${n}d`} in its current state`,parseResponse:r=>r})}var Js=(e,n)=>Do(e,"approve",n),Vs=(e,n)=>Do(e,"deny",n),Ys=(e,n)=>Do(e,"cancel",n);function Qs(e,n){let t=()=>{if(!e)throw new Error("corsair.workflows.runs requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e};return{list:r=>r?.workflowId?Gs(t(),{workflowId:r.workflowId,tenantId:n}):Zs(t(),{tenantId:n}),get:r=>zs(t(),{runId:r,tenantId:n}),approve:r=>Js(t(),{runId:r,tenantId:n}),deny:r=>Vs(t(),{runId:r,tenantId:n}),cancel:r=>Ys(t(),{runId:r,tenantId:n})}}function Xs(e,n){let t=()=>{if(!e)throw new Error("corsair.workflows requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e},r=(o,i)=>js(t(),{workflowId:o,tenantId:n,status:i});return{list:()=>$s(t(),{tenantId:n}),get:o=>Ws(t(),{workflowId:o,tenantId:n}),run:(o,i)=>Ks(t(),{workflowId:o,tenantId:n,payload:i?.payload,idempotencyKey:i?.idempotencyKey}),runs:Qs(e,n),disable:o=>r(o,"inactive"),enable:o=>r(o,"active"),archive:o=>r(o,"archived"),unarchive:o=>r(o,"inactive"),rename:(o,i)=>qs(t(),{workflowId:o,tenantId:n,name:i})}}function Al(e,n,t,r){let o=null;return async()=>{if(o)return o;if(!e)throw new Error("Database not configured");let{accountId:i}=await Ds({database:e,integrationName:n,tenantId:t,ensureProvisioned:r});return o=i,o}}function xl(e,n,t,r,o){return e?sr(e.db,n,t,r,o):{findByEntityId:async()=>null,existsByEntityId:async()=>!1,findIdByEntityId:async()=>null,findById:async()=>null,findManyByEntityIds:async()=>[],list:async()=>[],search:async()=>[],upsertByEntityId:async()=>{throw new Error("Database not configured")},deleteById:async()=>!1,deleteByEntityId:async()=>!1,count:async()=>0}}function Oo(e,n){let{database:t,tenantId:r,kek:o,rootErrorHandlers:i,permissionsOptions:s,manualConfig:a,hubConfig:c,internalConfig:l}=n,u=r??"default",d=l&&t?()=>cn(l,u):void 0,p={},g={};for(let f of e)p[f.id]={},g[f.id]={};for(let f of e){let h=f.schema,k=Al(t,f.id,u,d);if(h?.entities){let H={};for(let[L,Re]of Object.entries(h.entities)){let Ne=t?sr(t.db,k,L,h.version,Re):xl(void 0,k,L,h.version,Re);H[L]=Ne}g[f.id].db=H,p[f.id].db=H}let b=f.options,v=f.authConfig,P;if(t&&o&&b?.authType){let H=v?.[b.authType]?.account??[];P=B({authType:b.authType,integrationName:f.id,tenantId:u,kek:o,database:t,extraAccountFields:H,ensureProvisioned:d}),p[f.id].keys=P}let D={database:t,db:g[f.id]?.db??{},$getAccountId:k,...f.options?{options:f.options}:{},...P?{keys:P,authType:b?.authType}:{},tenantId:u,...c?{hub:c}:{}},M=f.endpoints??{},O=f.hooks,w={...i,...f.errorHandlers},R={},A=f.options?.permissions;_o({endpoints:M,hooks:O,ctx:D,tree:R,pluginId:f.id,errorHandlers:w,currentPath:[],keyBuilder:f.keyBuilder,permissionsConfig:A,endpointMeta:f.endpointMeta,database:t,permissionsOptions:s,tenantId:r,manualConfig:a?{...a,oauthConfig:f.oauthConfig,kek:o,tenantId:u}:void 0,hubConfig:c,plugin:f,kek:o,allPlugins:e,multiTenancy:l?.multiTenancy}),Object.keys(R).length>0&&(p[f.id].api=R),D.endpoints=R;let X=f.webhooks??{},te=f.webhookHooks;if(Object.keys(X).length>0&&!ti(b?.authType)){let H={};Eo({webhooks:X,hooks:te,ctx:D,webhooksTree:H,keyBuilder:f.keyBuilder}),p[f.id].webhooks=H,f.pluginWebhookMatcher&&(p[f.id].pluginWebhookMatcher=f.pluginWebhookMatcher),f.pluginTenantWebhookMatcher&&(p[f.id].pluginTenantWebhookMatcher=f.pluginTenantWebhookMatcher)}}return p.chats=Os(c,u),p.workflows=Xs(c,u),p}function ea(e,n,t){let r={};for(let o of e){let i=o.options,s=o.authConfig;if(i?.authType){let a=s?.[i.authType]?.integration??[],c=F({authType:i.authType,integrationName:o.id,kek:t,database:n,extraIntegrationFields:a});r[o.id]=c}}return r}var Il=3e4;function Bo(e){let n=e.length;for(;n>0&&e[n-1]==="/";)n--;return e.slice(0,n)}function Sl(e){let n=0;for(;n<e.length&&e[n]==="/";)n++;return e.slice(n)}function _l(e,n){return`${Bo(e)}/${Sl(n)}`}function El(e,n){let t=n??{},{error:r,message:o,...i}=t;return typeof r!="string"?new C(e,"internal_error","Internal error"):new C(e,r,o,i)}var Ho=Symbol("cloudRequestTimeout");async function z(e,n,t,r){let o=e.fetch??globalThis.fetch,i=e.timeoutMs??Il,s=new AbortController,a,c=new Promise(p=>{a=setTimeout(()=>{s.abort(),p(Ho)},i)}),l;try{let p=o(_l(e.baseUrl,t),{method:n,headers:{authorization:`Bearer ${e.apiKey}`,"content-type":"application/json"},body:r===void 0?void 0:JSON.stringify(r),signal:s.signal}).catch(f=>{if(s.signal.aborted)return Ho;throw f}),g=await Promise.race([p,c]);if(g===Ho)throw new C(0,"internal_error","Cloud request timed out");l=g}finally{clearTimeout(a)}let u=await l.text(),d;try{d=u?JSON.parse(u):void 0}catch{d=void 0}if(!l.ok)throw El(l.status,d);if(d===void 0)throw new C(l.status,"internal_error","Invalid or empty response body from runtime");return d}var J={invoke:"/:tenant/:plugin/call/:op",instances:"/instances",connectLinks:"/connect/links",tenants:"/tenants",tenant:"/tenants/:id",connectionStatus:"/connection-status",disconnect:"/disconnect",permission:"/permissions/:id",permissionLookup:"/permissions/lookup-by-token"};var Ml=new Set(["db","keys","webhooks"]),Dl=new Set(["chats","workflows"]),na=new Set(["then","catch","finally"]);function ve(e){return typeof e=="function"?e():Promise.resolve(e)}function ta(e,n,t,r){let o=async(...i)=>{let s=await ve(e);return(await z(s,"POST",J.invoke.replace(":tenant",encodeURIComponent(n)).replace(":plugin",encodeURIComponent(t)).replace(":op",r.map(encodeURIComponent).join(".")),{args:i[0]})).data};return new Proxy(o,{get(i,s){if(!(typeof s!="string"||na.has(s)))return ta(e,n,t,[...r,s])}})}function Jt(e,n){let t=e?new Set(e.map(r=>r.id)):null;return new Proxy({},{get(r,o){if(!(typeof o!="string"||na.has(o))){if(Dl.has(o))throw new Error(`"${o}" is not available in cloud mode (deferred)`);if(t&&!t.has(o))throw new Error(`Unknown plugin "${o}"`);return new Proxy({},{get(i,s){if(s==="api")return ta(n.transport,n.tenantId,o,[]);if(typeof s=="string"&&Ml.has(s))throw new Error(`"${s}" is not available in cloud mode (deferred)`)}})}}})}function Vt(e){return{connect:{createLink:n=>{if(!n.plugin||!n.tenantId)throw new Error('connect.createLink requires both "plugin" and "tenantId" in cloud mode');return ve(e).then(t=>z(t,"POST",J.connectLinks,n))}},tenants:{create:n=>ve(e).then(t=>z(t,"POST",J.tenants,n)),list:()=>ve(e).then(n=>z(n,"GET",J.tenants)),get:n=>ve(e).then(t=>z(t,"GET",J.tenant.replace(":id",encodeURIComponent(n))))},connectionStatus:{get:n=>ve(e).then(t=>z(t,"GET",`${J.connectionStatus}?tenantId=${encodeURIComponent(n.tenantId)}`))},disconnect:n=>ve(e).then(t=>z(t,"POST",J.disconnect,n)),permissions:{get:n=>ve(e).then(t=>"id"in n?z(t,"GET",J.permission.replace(":id",encodeURIComponent(n.id))):z(t,"POST",J.permissionLookup,{token:n.token}))}}}var ra="default";function Te(e){throw new Error(`"${e}" is not available in cloud mode (deferred)`)}function Ol(e){let n=e?.baseUrl?.trim()||process.env.CORSAIR_CLOUD_URL?.trim();if(!n)throw new Error("Cloud mode (ck_cloud_ key) requires a base URL \u2014 set hub.baseUrl or CORSAIR_CLOUD_URL.");return zn(n),n}function oa(e){return!!(e?.baseUrl?.trim()||process.env.CORSAIR_CLOUD_URL?.trim())}function Hl(e,n){let t=Vt(e);return{ok:()=>Te("manage.ok"),tenants:t.tenants,plugins:{list:()=>Te("manage.plugins.list"),get:()=>Te("manage.plugins.get")},connectionStatus:{get:r=>{let o=r?.tenantId||void 0;if(!o&&n)throw new Error("connectionStatus.get requires a tenantId in multi-tenant mode");return t.connectionStatus.get({tenantId:o??ra})}},permissions:t.permissions,connect:{createLink:t.connect.createLink,resolve:()=>Te("manage.connect.resolve"),oauthCallback:()=>Te("manage.connect.oauthCallback")},disconnect:t.disconnect}}function Bl(e,n){let t=Hl(e,n.multiTenancy);if(n.multiTenancy)return{withTenant:s=>{if(!s)throw new Error("corsair.withTenant(tenantId): tenantId must be a non-empty string");return Jt(n.plugins,{transport:e,tenantId:s})},get keys(){return Te("keys")},get permissions(){return Te("permissions")},manage:t};let r=Jt(n.plugins,{transport:e,tenantId:ra}),o={manage:t,get keys(){return Te("keys")},get permissions(){return Te("permissions")}};return new Proxy(r,{get(s,a,c){return typeof a=="string"&&a in o?Reflect.get(o,a,c):Reflect.get(s,a,c)}})}function ia(e){return Bl({baseUrl:Ol(e.hub),apiKey:e.hub.projectApiKey},{multiTenancy:!!e.multiTenancy,plugins:e.plugins})}function Ul(e){let n=Bo(e),t="/api/corsair";return n.endsWith(t)?n.slice(0,-t.length):n}async function Fl(e){let n=await z({...e,baseUrl:Ul(e.baseUrl)},"GET",J.instances),t=new Map;for(let r of n.instances)zn(r.url,`Instance "${r.instanceKey}" URL`),t.set(r.instanceKey,r.url);return t}function Ll(e){let n=e.apiKey?.trim();if(!n)throw new Error("corsairCloud: apiKey is required");let t=e.url?.trim()||Vo(n);if(!t)throw new Error("corsairCloud: could not resolve a URL from apiKey \u2014 pass a ck_cloud_<slug>.<secret> key, or set `url` explicitly.");zn(t);let r={baseUrl:t,apiKey:n,fetch:e.fetch},o=null;function i(){return o||(o=Fl(r).catch(a=>{throw o=null,a})),o}let s=Vt(r);return{manage:{tenants:s.tenants,permissions:s.permissions},withInstance:a=>{let c=async()=>{let u=await i(),d=u.get(a);if(!d){let p=[...u.keys()].join(", ")||"(none)";throw new Error(`corsairCloud.withInstance("${a}"): no such instance \u2014 available: ${p}`)}return{...r,baseUrl:d}},l=Vt(c);return{withTenant(u){if(!u)throw new Error("corsair.withTenant(tenantId): tenantId must be a non-empty string");return Jt(void 0,{transport:c,tenantId:u})},connectionStatus:l.connectionStatus,connect:l.connect,disconnect:l.disconnect}}}}var Nl="createCorsair({ approval: ... }) is deprecated. Rename to permissions: { timeout, onTimeout, mode }.";function sa(e){let{permissions:n,approval:t}=e;if(n&&t)throw new Error("createCorsair was given both permissions and approval config. Use permissions only \u2014 approval is deprecated.");return t?(console.warn(`[corsair] ${Nl}`),t):n}var $l=e=>new C(404,"unknown_plugin",`Plugin '${e}' is not registered.`),Wl=(e,n)=>new C(404,"unknown_op",`Operation '${n}' not found on plugin '${e}'.`),Uo=()=>new C(403,"call_disabled","The /call route is disabled. Construct managementHandler with { unsafeAllowUnauthenticated: true } to enable it \u2014 only when your own backend fronts the handler."),jl=e=>new C(401,"not_connected",`Tenant is not connected for plugin '${e}'. Reconnect and retry.`),aa=e=>new C(403,"permission_denied",`The call was blocked (${e}).`,{reason:e}),ql=()=>new C(403,"approval_required","This action needs human approval before it can run. Approval is not resumable over HTTP in this version.",{reason:"pending"}),Kl=(e,n)=>new C(502,"provider_error","The provider returned an error.",{providerStatus:e,body:n});function Zl(e,n){if(e instanceof C)return e;if(e instanceof S)return jl(e.pluginId||n);if(e instanceof mn)return aa("readonly");if(e instanceof He)return e.reason==="pending"?ql():aa(e.reason);if(e instanceof Error&&e.name==="ApiError"){let t=e;return Kl(typeof t.status=="number"?t.status:502,t.body)}return console.error("[corsair] unhandled error in call operation",e),new C(500,"internal_error","Internal error")}var Gl=new WeakMap,ca=new WeakMap,zl=512;function ua(e,n){let t=e.get(n);return t||(t=new Map,e.set(n,t)),t}function Jl(e,n,t){if(n.size<=zl)return;let r=ca.get(e);for(let o of n.keys())if(o!==t&&(r?.get(o)??0)===0){n.delete(o);return}}function Vl(e,n,t){if(!n.multiTenancy)return{client:e};let r=typeof t=="string"?t.trim():"";if(!r)throw G("tenant is required for a multi-tenant runtime",{missingFields:["tenant"]});let o=ua(Gl,e),i=o.get(r);if(i)return o.delete(r),o.set(r,i),{client:i,tenantId:r};let s=e.withTenant(r);return o.set(r,s),Jl(e,o,r),{client:s,tenantId:r}}function Yl(e,n){let t=e;for(let r of n.split(".")){if(t==null||typeof t!="object"||!Object.prototype.hasOwnProperty.call(t,r))return null;t=t[r]}return typeof t=="function"?t:null}function la(e,n=[]){let t=[];for(let[r,o]of Object.entries(e??{}))typeof o=="function"?t.push([...n,r].join(".")):o&&typeof o=="object"&&t.push(...la(o,[...n,r]));return t}function da(e){let n={};for(let t of e.plugins)n[t.id]=la(t.endpoints??{});return n}async function pa(e,n,{plugin:t,op:r,tenant:o,args:i}){if(!n.plugins.some(d=>d.id===t))throw $l(t);let{client:s,tenantId:a}=Vl(e,n,o),c=s[t],l=Yl(c?.api,r);if(!l)throw Wl(t,r);let u=a?ua(ca,e):null;u&&a&&u.set(a,(u.get(a)??0)+1);try{return await l(i??{})}catch(d){throw Zl(d,t)}finally{if(u&&a){let d=(u.get(a)??1)-1;d<=0?u.delete(a):u.set(a,d)}}}function Rn(e,n){if(e===void 0)return n;if(e===null)throw new C(401,"unauthenticated","Could not determine the tenant for this request. Sign in and retry.");return e}function Yt(e){if(e!==void 0)throw new C(403,"forbidden","This route is disabled when resolveTenant is configured (end-user mode). Use a handler without resolveTenant, behind your own admin auth.")}var ga=[{method:"GET",pattern:"/ok",public:!0,handler:async()=>I(200,Ct())},{method:"GET",pattern:"/tenants",handler:async({internal:e,scopedTenant:n})=>(Yt(n),I(200,await bn(e)))},{method:"POST",pattern:"/tenants",handler:async({internal:e,body:n,scopedTenant:t})=>(Yt(t),I(201,await Pt(e,n)))},{method:"GET",pattern:"/tenants/:id",handler:async({internal:e,params:n,scopedTenant:t})=>(Yt(t),I(200,await Tt(e,n.id)))},{method:"GET",pattern:"/plugins",handler:async({internal:e})=>I(200,await hn(e))},{method:"GET",pattern:"/plugins/:id",handler:async({internal:e,params:n})=>I(200,await vt(e,n.id))},{method:"GET",pattern:"/connection-status",handler:async({internal:e,query:n,scopedTenant:t})=>I(200,await Rt(e,Rn(t,n.tenantId)))},{method:"GET",pattern:"/permissions/:id",handler:async({internal:e,params:n,scopedTenant:t})=>(Yt(t),I(200,await Hr(e,n.id)))},{method:"POST",pattern:"/permissions/lookup-by-token",public:!0,handler:async({internal:e,body:n})=>{let t=n?.token?.trim();return t?I(200,await Ur(e,t)):I(400,{error:"bad_request",message:"token is required",missingFields:["token"]})}},{method:"POST",pattern:"/connect/links",handler:async({corsair:e,internal:n,body:t,scopedTenant:r})=>{let o=t,i=Rn(r,o.tenantId);return I(200,await xt(e,n,{...o,tenantId:i}))}},{method:"GET",pattern:"/connect/resolve",public:!0,handler:async({corsair:e,internal:n,query:t})=>I(200,await It(e,n,t.state??""))},{method:"POST",pattern:"/connect/oauth/callback",public:!0,handler:async({corsair:e,internal:n,body:t})=>I(200,await St(e,n,t))},{method:"GET",pattern:"/connect/request",handler:async({internal:e,query:n,scopedTenant:t})=>{let r=Rn(t,n.tenantId)??"default",o=e.database?await Io(e.database,r):null;return I(200,{request:o},{"cache-control":"no-store"})}},{method:"POST",pattern:"/connect/request/clear",handler:async({internal:e,body:n,scopedTenant:t})=>{let r=n,o=Rn(t,r?.tenantId)??"default";return e.database&&await Fs(e.database,o,void 0,r?.plugin),I(200,{ok:!0})}},{method:"POST",pattern:"/disconnect",handler:async({internal:e,body:n,scopedTenant:t})=>{let r=n??{},o=Rn(t,r.tenantId);return I(200,await At(e,{...r,tenantId:o}))}},{method:"GET",pattern:"/call",handler:async({internal:e,allowCall:n})=>{if(!n)throw Uo();return I(200,{plugins:da(e)})}},{method:"POST",pattern:"/:tenant/:plugin/call/:op",handler:async({corsair:e,internal:n,params:t,body:r,scopedTenant:o,allowCall:i})=>{if(!i)throw Uo();let s=r??{},a=Rn(o,t.tenant),c=await pa(e,n,{plugin:t.plugin,op:t.op,tenant:a,args:s.args});return I(200,{data:c})}}];(()=>{let e=new Set;for(let n of ga){let t=`${n.method} ${n.pattern}`;if(e.has(t))throw new Error(`Duplicate management route registered: ${t}`);e.add(t)}})();function Ql(e,n){let t=e.split("/").filter(Boolean),r=n.split("/").filter(Boolean);if(t.length!==r.length)return null;let o={};for(let i=0;i<t.length;i++){let s=t[i],a=r[i];if(s.startsWith(":"))o[s.slice(1)]=decodeURIComponent(a);else if(s!==a)return null}return o}function Xl(e,n){if(!n)return e;let t=n.endsWith("/")?n.slice(0,-1):n;return e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length):e}async function ed(e,n){if(e.method==="GET"||e.method==="HEAD"||!(e.headers.get("content-type")??"").includes("application/json"))return;let r=await Zt(e,n).catch(o=>{throw o instanceof C?o:new C(400,"invalid_json","Request body is not valid JSON")});if(r)try{return JSON.parse(r)}catch{throw new C(400,"invalid_json","Request body is not valid JSON")}}var nd="/api/corsair";function $(e,n={}){let t=n.basePath??nd,r=Je(n.maxBodyBytes),o=Ve(n.bodyStallTimeoutMs),i={maxBodyBytes:r,bodyStallTimeoutMs:o},s=T(e,()=>new Error("managementHandler: invalid corsair instance (missing internal config)"));return async a=>{try{let c=a.headers.get("content-length");if(c!==null&&Number(c)>r)throw vn(r);let l=new URL(a.url),u=Xl(l.pathname,t),d=a.method.toUpperCase();if(d==="OPTIONS"||u==="/"||u==="")return await Ye(e,a,{maxBodyBytes:r,bodyStallTimeoutMs:o});if(d!=="GET"&&d!=="POST")return I(405,{error:"method_not_allowed",message:`Method ${d} not allowed`});let p=Object.fromEntries(l.searchParams);for(let g of ga){if(g.method!==d)continue;let f=Ql(g.pattern,u);if(!f)continue;if(!g.public&&n.authenticate&&!await n.authenticate(a))return I(401,{error:"unauthorized",message:"invalid or missing credentials"});let h=await ed(a,i),k=n.resolveTenant?await n.resolveTenant(a):void 0;return await g.handler({corsair:e,internal:s,req:a,params:f,query:p,body:h,scopedTenant:k,allowCall:(n.unsafeAllowUnauthenticated??!1)||!!n.authenticate})}throw Be(`No route for ${d} ${u}`)}catch(c){if(n.onError){let u=await n.onError(c,a);if(u)return u}if(c instanceof C)return pe(c);let l=c instanceof Error?c.message:"Internal server error";return I(500,{error:"internal_error",message:l})}}}function td(e,n){if(e.get)return e.get(n);let t=e.headers[n]??e.headers[n.toLowerCase()];return Array.isArray(t)?t[0]:t}function rd(e){if(Buffer.isBuffer(e))return e;if(e instanceof Uint8Array)return Buffer.from(e);if(typeof e=="string")return Buffer.from(e,"utf8");throw new TypeError(`corsair adapter: unsupported stream chunk type ${typeof e}`)}async function od(e,n,t){let r=[],o=0,i=e();try{let s=await Kt(()=>i.next(),t);for(;s.done!==!0;){let a=rd(s.value);if(o+=a.byteLength,o>n)throw vn(n);r.push(a),s=await Kt(()=>i.next(),t)}return Buffer.concat(r)}catch(s){try{Promise.resolve(i.return?.()).catch(()=>{})}catch{}throw s}}var fa=!1;function id(){fa||(fa=!0,console.warn("[corsair] A JSON body parser consumed this request before the corsair adapter.","Re-serializing the parsed object is lossy and will likely fail Hub signature",'verification ("Invalid tunnel signature"). Fix on the corsair route only:',"Express \u2192 mount express.raw({ type: 'application/json' }) before the handler,","or capture raw bytes via express.json({ verify: (req, _res, buf) => { req.rawBody = buf; } }).","Fastify \u2192 call registerCorsairRawBodyParser(app) before listen()."))}async function sd(e,n){let t=(e.method??"GET").toUpperCase();if(t==="GET"||t==="HEAD")return;let r=Je(n.maxBodyBytes),o=Ve(n.bodyStallTimeoutMs),i;if(typeof e.rawBody=="string")i=e.rawBody;else if(e.rawBody instanceof Uint8Array)i=e.rawBody;else if(e.body!==void 0&&e.body!==null)typeof e.body=="string"||e.body instanceof Uint8Array?i=e.body:(id(),i=JSON.stringify(e.body));else{let a=e[Symbol.asyncIterator];if(typeof a!="function")return;let c=await od(a.bind(e),r,o);c.length>0&&(i=c)}if(i===void 0)return;if((typeof i=="string"?Buffer.byteLength(i,"utf8"):i.byteLength)>r)throw vn(r);return typeof i=="string"?i:i}function V(e){e.resume?.()}async function Fe(e,n={}){let t=td(e,"host")??"localhost",r=e.protocol??"http",o=e.originalUrl??e.url??"/",i=`${r}://${t}${o}`,s=new Headers;for(let[l,u]of Object.entries(e.headers))if(u!=null&&!ad.has(l.toLowerCase()))if(Array.isArray(u))for(let d of u)s.append(l,d);else s.set(l,u);let a={method:(e.method??"GET").toUpperCase(),headers:s},c=await sd(e,n);return c!==void 0&&(a.body=c,s.has("content-type")||s.set("content-type","application/json")),new Request(i,a)}async function Y(e,n){typeof e.status=="function"?e.status(n.status):e.statusCode=n.status;let t=n.headers.getSetCookie();n.headers.forEach((o,i)=>{i!=="set-cookie"&&e.setHeader(i,o)}),t.length>0&&e.setHeader("set-cookie",t);let r=Buffer.from(await n.arrayBuffer());e.send?e.send(r):e.end?.(r)}var ad=new Set(["connection","keep-alive","proxy-authenticate","proxy-authorization","te","trailer","transfer-encoding","upgrade","content-length"]);function ya(e,n){let t=$(e,n);return async(r,o,i)=>{try{let s=await t(await Fe(r,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await Y(o,s)}catch(s){if(s instanceof C&&o.headersSent!==!0){await Y(o,pe(s)),V(r);return}V(r),i(s)}}}function cd(e,n){let t=e[n];return Array.isArray(t)?t[0]:t}function ud(e){let n=(e.method??"GET").toUpperCase();if(n==="GET"||n==="HEAD"||e.body!==void 0||e.rawBody!==void 0)return;let t=cd(e.headers,"content-type");if(!(!t||!t.includes("application/json"))&&!(e.raw.readableEnded!==!0&&e.raw.complete!==!0))throw new Error("corsair: Fastify consumed this JSON body before the corsair adapter could read it. Call registerCorsairRawBodyParser(app) before listen() so the original bytes reach the adapter verbatim (Hub signs deliveries over the exact bytes it sent).")}function ma(e){e.addContentTypeParser("application/json",{parseAs:"buffer"},(n,t,r)=>{n.rawBody=t;try{r(null,JSON.parse(t.toString("utf8")))}catch{r(Object.assign(new Error("Invalid JSON body"),{statusCode:400}))}})}function ha(e,n){let t=$(e,n);return async(r,o)=>{ud(r);let i={method:r.method??r.raw.method,url:r.url??r.raw.url,headers:r.headers,protocol:r.protocol,body:r.body,rawBody:r.rawBody,resume:r.raw.resume?.bind(r.raw),[Symbol.asyncIterator]:r.raw[Symbol.asyncIterator]?.bind(r.raw)};try{let s=await t(await Fe(i,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));o.hijack?.(),await Y(o.raw,s)}catch(s){if(s instanceof C&&o.raw.headersSent!==!0&&o.hijack){o.hijack(),await Y(o.raw,pe(s)),V(i);return}throw V(i),s}}}function ba(e,n){let t=$(e,n);return r=>t(r.req.raw)}function ka(e,n){let t=$(e,n);return{GET:t,POST:t,OPTIONS:t}}function wa(e,n){let t=$(e,n);return async(r,o)=>{try{let i=await t(await Fe(r,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await Y(o,i)}catch(i){if(o.headersSent===!0){console.error("[corsair] management response failed after headers were sent:",i),o.end?.(),V(r);return}if(i instanceof C){await Y(o,pe(i)),V(r);return}console.error("[corsair] management handler failed:",i),await Y(o,I(500,{error:"internal_error"})),V(r)}}}function Qt(e,n){let t=$(e,n);return r=>t(r.request)}function Ca(e,n){let t=Qt(e,n);return{GET:t,POST:t,OPTIONS:t}}function va(e,n){let t=Qt(e,n);return{loader:t,action:t}}function Ta(e,n){let t=Qt(e,n);return{GET:t,POST:t,OPTIONS:t}}function Pa(e,n){let t=Qt(e,n);return{GET:t,POST:t,OPTIONS:t}}function Ra(e,n){let t=$(e,n);return async r=>{let o={method:r.node.req.method,url:r.node.req.url,headers:r.node.req.headers,protocol:r.node.req.protocol,body:r._body,rawBody:r.node.req.rawBody??r._rawBody,resume:r.node.req.resume?.bind(r.node.req),[Symbol.asyncIterator]:r.node.req[Symbol.asyncIterator]?.bind(r.node.req)};try{let i=await t(await Fe(o,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await Y(r.node.res,i)}catch(i){if(i instanceof C&&r.node.res.headersSent!==!0){await Y(r.node.res,pe(i)),V(o);return}throw V(o),i}}}function Aa(e,n){return $(e,n)}function xa(e){let n={[Zn]:e};return{ok:Ct,tenants:{list:()=>bn(e),create:t=>Pt(e,t),get:t=>Tt(e,t)},plugins:{list:()=>hn(e),get:t=>vt(e,t)},connectionStatus:{get:t=>Rt(e,t?.tenantId)},permissions:{get:t=>ns(e,t)},connect:{createLink:t=>xt(n,e,t),resolve:t=>It(n,e,t),oauthCallback:t=>St(n,e,t)},disconnect:t=>At(e,t)}}async function Ia(e,n,t,r,o="pending"){if(!e)return null;try{let i=nn(),s=new Date;return await e.db.insertInto("corsair_events").values({id:i,created_at:s,updated_at:s,account_id:n,event_type:t,payload:r,status:o}).execute(),i}catch(i){return console.warn("Failed to log event:",i),null}}async function ld(e,n,t,r="pending"){try{let o=await e.$getAccountId();return Ia(e.database,o,n,t,r)}catch(o){return console.warn("Failed to log event:",o),null}}import*as _a from"https";import*as Xt from"querystring";var dd=["expires_in","refresh_token_expires_in"];function Sa(e){let n={...e};for(let t of dd){let r=e[t];if(typeof r=="string"){let o=Number(r);n[t]=Number.isFinite(o)?o:void 0}}return n}function pd(e){try{return Sa(JSON.parse(e))}catch{}if(!e.includes("="))return null;let n=Xt.parse(e);return!n.access_token&&!n.error?null:Sa({...n})}function gt(e,n,t,r,o){let i=new URL(r.tokenUrl),s=r.tokenAuthMethod==="basic";return new Promise((a,c)=>{let l={code:e.trim(),redirect_uri:o,grant_type:"authorization_code"};s||(l.client_id=n,l.client_secret=t);let u=Xt.stringify(l),d={"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json","Content-Length":Buffer.byteLength(u).toString()};s&&(d.Authorization=`Basic ${Buffer.from(`${n}:${t}`).toString("base64")}`);let p=_a.request({hostname:i.hostname,...i.port?{port:Number(i.port)}:{},path:i.pathname+i.search,method:"POST",headers:d},g=>{let f="";g.on("data",h=>{f+=h}),g.on("end",()=>{if(g.statusCode!==200){c(new Error(`Token exchange failed (${g.statusCode}): ${f}`));return}let h=pd(f);h?a(h):c(new Error(`Token endpoint returned non-JSON response: ${f}`))})});p.on("error",g=>c(new Error(`Request failed: ${g.message}`))),p.write(u),p.end()})}async function Ea(e,n){let{keys:t,hub:r,plugin:o,tenantId:i}=e,[s,a,c]=await Promise.all([t.get_access_token(),t.get_expires_at(),t.get_refresh_token()]);if(Tn({accessToken:s,expiresAt:a,forceRefresh:n?.forceRefresh}))return{accessToken:s,expiresAt:Number(a),refreshed:!1};if(!c)throw new S(o,"oauth_2");let l=await x({hub:r,path:"/oauth/refresh",body:{plugin:o,tenantId:i,refresh_token:c},parseResponse:tn}),u=await Pn(t,l,a);return{accessToken:l.access_token,expiresAt:u,refreshed:!0}}async function Ma(e){let{tokenUrl:n,refreshToken:t,clientSecret:r,clientId:o,tokenAuthMethod:i="body",bodyFormat:s="form",extraParams:a}=e,c={grant_type:"refresh_token",refresh_token:t,...a},l={Accept:"application/json"};i==="basic"?l.Authorization=`Basic ${Buffer.from(`${o??""}:${r}`).toString("base64")}`:i==="basic_secret_only"?l.Authorization=`Basic ${Buffer.from(`${r}:`).toString("base64")}`:(o&&(c.client_id=o),c.client_secret=r),s==="json"?l["Content-Type"]="application/json":l["Content-Type"]="application/x-www-form-urlencoded";let u=await fetch(n,{method:"POST",headers:l,body:s==="json"?JSON.stringify(c):new URLSearchParams(c)});if(!u.ok)throw new Error(`OAuth token refresh failed (${u.status}): ${await u.text()}`);let d=JSON.parse(await u.text());if(typeof d.access_token!="string"||d.access_token.length===0)throw new Error("OAuth token refresh returned no access_token");return{access_token:d.access_token,...typeof d.refresh_token=="string"&&d.refresh_token.length>0?{refresh_token:d.refresh_token}:{},...typeof d.expires_in=="number"?{expires_in:d.expires_in}:{},...typeof d.scope=="string"&&d.scope.length>0?{scope:d.scope}:{}}}async function Da(e,n){let t=await e.keys.get_integration_credentials(),r=`${n.plugin}:${e.tenantId}`;if(!t.client_secret){if(!e.hub)throw new S(n.plugin,"oauth_2");let l={keys:e.keys,hub:e.hub,plugin:n.plugin,tenantId:e.tenantId},u=g=>Qe(e.keys,r,async()=>(await Ea(l,{forceRefresh:g})).accessToken);e._refreshAuth=()=>u(!0);let[d,p]=await Promise.all([e.keys.get_access_token(),e.keys.get_expires_at()]);return Tn({accessToken:d,expiresAt:p})?d:u(!1)}let o=t.client_secret,i=t.client_id,s=l=>Qe(e.keys,r,async()=>{let[u,d,p]=await Promise.all([e.keys.get_access_token(),e.keys.get_expires_at(),e.keys.get_refresh_token()]);if(!l&&Tn({accessToken:u,expiresAt:d}))return u;if(!p)throw new S(n.plugin,"oauth_2");let g=await Ma({tokenUrl:n.tokenUrl,tokenAuthMethod:n.tokenAuthMethod,bodyFormat:n.bodyFormat,extraParams:n.extraParams,clientId:i,clientSecret:o,refreshToken:p});return await Pn(e.keys,g,d),g.access_token});e._refreshAuth=()=>s(!0);let[a,c]=await Promise.all([e.keys.get_access_token(),e.keys.get_expires_at()]);return Tn({accessToken:a,expiresAt:c})?a:s(!1)}var Oa=" ";function se(e){let n=e;return n._def??n.def??{}}function ae(e){let n=e.typeName;if(n)return n;let t=e.type;if(t)return`Zod${t.split("_").map(r=>r.charAt(0).toUpperCase()+r.slice(1)).join("")}`}function ie(e){return e.innerType??e.schema??e.out??e.in}function Ba(e,n){switch(n){case"ZodPipe":return e.in??e.innerType;case"ZodEffects":return e.schema??e.innerType;case"ZodTransform":return e.schema??e.innerType??e.in;default:return ie(e)}}function Ua(e){let n=e.type;return e.element??(typeof n=="string"?void 0:n)}function nr(e,n){let t=n.shape??e.shape;return typeof t=="function"?t():t}function An(e){return Array.isArray(e.options)?e.options:Array.isArray(e.values)?e.values:e.entries!==null&&typeof e.entries=="object"&&!Array.isArray(e.entries)?Object.values(e.entries):[]}function Fa(e,n){return e.description??n.description}function gd(e){let n=e;for(;n;){let t=se(n),r=Fa(n,t);if(r)return r;let o=ae(t);if(Wo(o)||o==="ZodPipe"||o==="ZodEffects"||o==="ZodTransform"){n=Ba(t,o);continue}break}}function Wo(e){return e==="ZodOptional"||e==="ZodNullable"||e==="ZodDefault"||e==="ZodCatch"}function Q(e){let n=se(e),t=ae(n);switch(t){case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"Date";case"ZodNull":return"null";case"ZodUnknown":case"ZodAny":return"any";case"ZodLiteral":return String(n.value??An(n)[0]??"unknown");case"ZodEnum":return An(n).map(r=>String(r)).join(" | ");case"ZodOptional":{let r=ie(n);return r?Q(r):"unknown"}case"ZodNullable":{let r=ie(n);return`${r?Q(r):"unknown"} | null`}case"ZodDefault":case"ZodCatch":{let r=ie(n);return r?Q(r):"unknown"}case"ZodArray":{let r=Ua(n);if(!r)return"unknown[]";let o=se(r),i=ae(o)==="ZodUnion",s=Q(r);return`${i?`(${s})`:s}[]`}case"ZodRecord":return"{}";case"ZodObject":{let r=nr(e,n),o=Object.entries(r);return o.length===0?"{}":`{ ${o.map(([s,a])=>{let c=ae(se(a));return`${c==="ZodOptional"||c==="ZodNullable"?s+"?":s}: ${Q(a)}`}).join(", ")} }`}case"ZodUnion":return An(n).map(r=>Q(r)).join(" | ");case"ZodIntersection":return`${Q(n.left)} & ${Q(n.right)}`;case"ZodPipe":case"ZodTransform":case"ZodEffects":{let r=Ba(n,t);return r?Q(r):"unknown"}default:return(t??"unknown").replace("Zod","").toLowerCase()}}function Pe(e){let n=se(e),t=ae(n),r=Fa(e,n);switch(t){case"ZodString":return{kind:"string",optional:!1,description:r};case"ZodNumber":return{kind:"number",optional:!1,description:r};case"ZodBoolean":return{kind:"boolean",optional:!1,description:r};case"ZodLiteral":{let o=n.value??An(n)[0],i=typeof o=="string"||typeof o=="number"||typeof o=="boolean"?o:String(o??"");return{kind:"literal",optional:!1,description:r,value:i}}case"ZodEnum":{let o=An(n).map(i=>String(i));return{kind:"string",optional:!1,description:r,enum:o}}case"ZodOptional":{let o=ie(n),i=o?Pe(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodNullable":{let o=ie(n),i=o?Pe(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodDefault":case"ZodCatch":{let o=ie(n);return o?{...Pe(o),description:r}:{kind:"unknown",optional:!1,description:r}}case"ZodArray":{let o=Ua(n);return{kind:"array",optional:!1,description:r,items:o?Pe(o):{kind:"unknown",optional:!1}}}case"ZodObject":{let o=nr(e,n),i={};for(let[s,a]of Object.entries(o))i[s]=Pe(a);return{kind:"object",optional:!1,description:r,fields:i}}case"ZodRecord":return{kind:"unknown",optional:!1,description:r};case"ZodUnion":{let o=An(n);for(let i of o){let s=se(i);if(ae(s)==="ZodObject")return{...Pe(i),description:r}}return{kind:"unknown",optional:!1,description:r}}case"ZodIntersection":case"ZodPipe":case"ZodTransform":case"ZodEffects":{let o=ie(n);return o?{...Pe(o),description:r}:{kind:"unknown",optional:!1,description:r}}default:return{kind:"unknown",optional:!1,description:r}}}function gv(e,n){let t=n.toLowerCase(),r=t.indexOf(".");if(r===-1)return null;let o=t.slice(0,r),i=t.slice(r+1),s=e.find(u=>u.id===o);if(!s)return null;let a=i;a.startsWith("api.")&&(a=a.slice(4));let c=Le(s.endpointMeta,a),l=Le(s.endpointSchemas,a);return!c&&!l?null:{input:l?.input?Pe(l.input):null,output:l?.output?Pe(l.output):null,description:c?.description}}var jo=["equals","contains","startsWith","endsWith","in"],fd=["equals","gt","gte","lt","lte","in"],yd=["equals"],md=["equals","before","after","between"];function La(e){let n=se(e);switch(ae(n)){case"ZodOptional":case"ZodNullable":case"ZodDefault":case"ZodCatch":{let r=ie(n);return r?La(r):null}case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"date";default:return null}}function qo(e){let n=se(e),t=ae(n);if(Wo(t)){let i=ie(n);return i?qo(i):{}}if(t!=="ZodObject")return{};let r=nr(e,n),o={};for(let[i,s]of Object.entries(r)){let a=La(s);a==="string"?o[i]={type:"string",operators:jo}:a==="number"?o[i]={type:"number",operators:fd}:a==="boolean"?o[i]={type:"boolean",operators:yd}:a==="date"&&(o[i]={type:"date",operators:md})}return o}function Na(e,n){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return[t,r]}function Lo(e,n,t){for(let[r,o]of Object.entries(e)){let i=[...n,r];typeof o=="function"?t.push(i.join(".")):o!==null&&typeof o=="object"&&Lo(o,i,t)}}function No(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function $o(e,n,t){for(let[r,o]of Object.entries(e)){let i=[...n,r];No(o)?t.push(i.join(".")):o!==null&&typeof o=="object"&&$o(o,i,t)}}function Ko(e,n){if(n.length===0)return null;let[t,...r]=n,o=Object.entries(e).find(([a])=>a.toLowerCase()===t);if(!o)return null;let[i,s]=o;if(r.length===0)return No(s)?[i]:null;if(s!==null&&typeof s=="object"&&!No(s)){let a=Ko(s,r);if(a!==null)return[i,...a]}return null}function $a(e,n){let t=[];t.push(`${e}({`),t.push(" webhookHooks: {");for(let i=0;i<n.length;i++){let s=" ".repeat(i+2);t.push(`${s}${n[i]}: {`)}let r=" ".repeat(n.length+2),o=r+" ";t.push(`${r}before(ctx, args) {`),t.push(`${o}return { ctx, args };`),t.push(`${r}},`),t.push(`${r}after(ctx, response) {`),t.push(`${r}},`);for(let i=n.length-1;i>=0;i--){let s=" ".repeat(i+2);t.push(`${s}},`)}return t.push(" },"),t.push("})"),t.join(`
|
|
50
|
+
`)}var hd=new Set(Vn);function en(e,n){let t=n?.type??"api",r=n?.plugin;if(r!==void 0){let i=e.find(a=>a.id===r);if(!i)return hd.has(r)?`This plugin (${r}) is not configured. Please add it to the Corsair instance to see its associated methods.`:en(e);if(t==="webhooks"){if(!i.webhooks)return[];let a=[];return $o(i.webhooks,[],a),a.map(c=>`${i.id}.webhooks.${c}`)}if(t==="db"){let a=i.schema?.entities;return a?Object.keys(a).map(c=>`${i.id}.db.${c}.search`):[]}if(!i.endpoints)return[];let s=[];return Lo(i.endpoints,[],s),s.map(a=>`${i.id}.api.${a}`)}let o={};if(t==="webhooks")for(let i of e){if(!i.webhooks)continue;let s=[];$o(i.webhooks,[],s),o[i.id]=s.map(a=>`${i.id}.webhooks.${a}`)}else if(t==="db")for(let i of e){let s=i.schema?.entities;s&&(o[i.id]=Object.keys(s).map(a=>`${i.id}.db.${a}.search`))}else for(let i of e){if(!i.endpoints)continue;let s=[];Lo(i.endpoints,[],s),o[i.id]=s.map(a=>`${i.id}.api.${a}`)}return o}function Le(e,n){if(e){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return r}}function bd(e,n){let t=e.toLowerCase(),r=n.toLowerCase();if(!t.startsWith(`${r}.`)){let i=t.slice(n.length+1),s=i.startsWith(".")?i.slice(1):i;return s.startsWith("api.")&&(s=s.slice(4)),{shortPath:s,lookupKey:s}}let o=e.slice(n.length+1);return o.toLowerCase().startsWith("api.")&&(o=o.slice(4)),{shortPath:o,lookupKey:o.toLowerCase()}}function Fo(e,n){return typeof e=="string"?e:Array.isArray(e)?`${n}:
|
|
51
|
+
${e.join(", ")}`:`${n}:
|
|
52
|
+
`+Object.entries(e).map(([t,r])=>` ${t}: ${r.join(", ")}`).join(`
|
|
53
|
+
`)}function fv(e,n){let t=n.toLowerCase(),r=t.indexOf(".");if(r!==-1){let o=t.slice(0,r),i=t.slice(r+1),s=e.find(a=>a.id===o);if(s){if(i.startsWith("db.")){let u=i.slice(3),d=u.lastIndexOf(".");if(d!==-1){let p=u.slice(0,d),g=u.slice(d+1),f=s.schema?.entities;if(g==="search"&&f){let h=Na(f,p);if(h){let[k,b]=h,v=qo(b),P=[`Search ${o} ${k} stored in the local database.`,"Pass limit and offset as numbers for pagination.","","filters {",` entity_id: string [${jo.join(", ")}]`];for(let[D,M]of Object.entries(v))P.push(` ${D}?: ${M.type} [${M.operators.join(", ")}]`);return P.push("}"),P.join(`
|
|
54
|
+
`)}}}return Fo(en(e,{type:"db"}),"Path not found. Available db operations")}if(i.startsWith("webhooks.")){let u=i.slice(9);if(s.webhooks){let d=Ko(s.webhooks,u.split("."));if(d!==null){let p=d.join("."),g=Le(s.webhookSchemas,p.toLowerCase()),f=g?.response?Q(g.response):null,h=[];return g?.description&&h.push(g.description),g?.payload&&h.push(`payload ${er(xn(g.payload))}`),f&&h.push(`response: ${f}`),h.push(`usage:
|
|
55
|
+
${$a(o,d)}`),h.join(`
|
|
56
|
+
|
|
57
|
+
`)}}return Fo(en(e,{type:"webhooks"}),"Path not found. Available webhooks")}let a=i;a.startsWith("api.")&&(a=a.slice(4));let c=Le(s.endpointMeta,a),l=Le(s.endpointSchemas,a);if(c||l){let u=[],d=[c?.riskLevel?`[${c.riskLevel}]`:"",c?.irreversible?"[irreversible]":""].filter(Boolean).join(" "),p=[c?.description,d].filter(Boolean).join(" ");return p&&u.push(p),l?.input&&u.push(`input ${er(xn(l.input))}`),l?.output&&u.push(`output ${er(xn(l.output))}`),u.join(`
|
|
58
|
+
|
|
59
|
+
`)}}}return Fo(en(e),"Path not found. Available operations")}function Ha(e){let n=e;for(;;){let t=se(n),r=ae(t);if(Wo(r)){let o=ie(t);if(!o)return n;n=o;continue}return n}}function xn(e){if(e===void 0)return{kind:"inline",type:"unknown"};let n=Ha(e),t=se(n);if(ae(t)==="ZodObject"){let o=nr(n,t),i=[];for(let[s,a]of Object.entries(o)){let c=se(a),l=ae(c),u=l==="ZodOptional"||l==="ZodNullable",d=Ha(a),p=gd(a);i.push({key:s,optional:u,type:Q(d),...p!==void 0?{description:p}:{}})}return{kind:"object",fields:i}}return{kind:"inline",type:Q(n)}}function er(e,n=0){if(e===void 0)return"{}";if(e.kind==="inline")return e.type;if(e.kind==="object"){if(e.fields.length===0)return"{}";let t=Oa.repeat(n+1),r=Oa.repeat(n);return`{
|
|
60
|
+
${e.fields.map(i=>{let s=i.optional?`${i.key}?`:i.key,a=i.description?` // ${i.description}`:"";return`${t}${s}: ${i.type}${a}`}).join(`
|
|
61
|
+
`)}
|
|
62
|
+
${r}}`}return"unknown"}function kd(e,n){let t=en(e,{plugin:n,type:"api"});if(typeof t=="string")return{ok:!1,error:t};if(!Array.isArray(t))return{ok:!1,error:"list_operations did not return a path array \u2014 pass a configured plugin id."};let r=e.find(u=>u.id===n);if(!r)return{ok:!1,error:`Plugin "${n}" is not configured on this instance.`};let o=[];for(let u of t){let{shortPath:d,lookupKey:p}=bd(u,n),g=Le(r.endpointMeta,p),f=Le(r.endpointSchemas,p);!g&&!f||o.push({path:u,shortPath:d,description:g?.description,riskLevel:g?.riskLevel,irreversible:g?.irreversible,input:xn(f?.input),output:xn(f?.output)})}o.sort((u,d)=>u.path.localeCompare(d.path));let i=[],s=en(e,{plugin:n,type:"webhooks"});if(Array.isArray(s)&&r.webhooks)for(let u of s){let p=u.toLowerCase().slice(n.length+1),g=p.startsWith(".")?p.slice(1):p;if(!g.startsWith("webhooks."))continue;let f=g.slice(9),h=Ko(r.webhooks,f.split("."));if(h===null)continue;let k=h.join("."),b=Le(r.webhookSchemas,k.toLowerCase()),v=b?.response?Q(b.response):void 0;i.push({path:u,description:b?.description,payload:xn(b?.payload),responseType:v,usageExample:$a(n,h)})}i.sort((u,d)=>u.path.localeCompare(d.path));let a=[],c=en(e,{plugin:n,type:"db"}),l=r.schema?.entities;if(Array.isArray(c)&&l)for(let u of c){let p=u.toLowerCase().slice(n.length+1),g=p.startsWith(".")?p.slice(1):p;if(!g.startsWith("db."))continue;let f=g.slice(3),h=f.lastIndexOf(".");if(h===-1)continue;let k=f.slice(0,h);if(f.slice(h+1)!=="search")continue;let v=Na(l,k);if(!v)continue;let[P,D]=v,M=qo(D),O=Object.entries(M).map(([w,R])=>({field:w,type:R.type,operators:R.operators}));a.push({path:u,entityName:P,filters:[{field:"entity_id",type:"string",operators:jo},...O]})}return a.sort((u,d)=>u.path.localeCompare(d.path)),{ok:!0,data:{pluginId:n,api:o,webhooks:i,db:a}}}import{randomUUID as Wa}from"crypto";async function wd(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r=Wa(),o=Wa(),i=await fetch(n.watchUrl,{method:"POST",signal:AbortSignal.timeout(2e4),headers:{authorization:`Bearer ${t}`,"content-type":"application/json"},body:JSON.stringify({id:r,type:"web_hook",address:n.webhookUrl,token:o,...n.body})});if(!i.ok)throw new Error(`Google channel watch failed (${i.status}): ${await i.text()}`);return{webhookLink:{linkType:"channel_id",externalId:r},webhookSecret:o}}import{randomUUID as Cd}from"crypto";var tr="https://graph.microsoft.com/v1.0",Zo=2e4,vd=60;async function Td(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r={authorization:`Bearer ${t}`};try{let c=await fetch(`${tr}/subscriptions`,{headers:r,signal:AbortSignal.timeout(Zo)});if(c.ok){let{value:l}=await c.json(),u=(l??[]).filter(d=>d.notificationUrl===n.webhookUrl);await Promise.all(u.map(d=>fetch(`${tr}/subscriptions/${d.id}`,{method:"DELETE",headers:r,signal:AbortSignal.timeout(Zo)}).catch(()=>{})))}}catch{}let o=Cd(),i=new Date(Date.now()+vd*6e4).toISOString(),s=await fetch(`${tr}/subscriptions`,{method:"POST",headers:{...r,"content-type":"application/json"},signal:AbortSignal.timeout(Zo),body:JSON.stringify({changeType:n.changeType,notificationUrl:n.webhookUrl,resource:n.resource,expirationDateTime:i,clientState:o})});if(!s.ok)throw new Error(`MS Graph subscribe failed (${s.status}): ${await s.text()}`);let a=await s.json();return a.id?(await e.keys.set_webhook_signature(o),{webhookLink:{linkType:"subscription_id",externalId:a.id},webhookSecret:o}):null}function ja(e,n){for(let[t,r]of Object.entries(e))if(r?.pluginWebhookMatcher&&r.pluginWebhookMatcher(n))return t;return null}function Pd(e,n){let t=ja(e,n);if(!t)return null;let r=e[t];if(!r?.pluginTenantWebhookMatcher)return null;let o=r.pluginTenantWebhookMatcher(n);return o?{plugin:t,tenantMatch:o}:null}function Rd(e){let n={};for(let t of e)!t.pluginWebhookMatcher&&!t.pluginTenantWebhookMatcher||(n[t.id]={pluginWebhookMatcher:t.pluginWebhookMatcher,pluginTenantWebhookMatcher:t.pluginTenantWebhookMatcher});return n}function qa(e,n){let t=n.toLowerCase(),r=e[t]??e[n];return Array.isArray(r)?r[0]:typeof r=="string"?r:void 0}function Ka(e){if(typeof e=="string"){let n=e.trim();return n.length>0?n:void 0}if(typeof e=="number"&&Number.isFinite(e))return String(e)}function Gn(e){return!e||typeof e!="object"||Array.isArray(e)?null:e}function Ad(e){return Gn(e.body)}function Za(e,n){let t=e.query;if(!t)return;let r=t[n]??t[n.toLowerCase()];return rr(Array.isArray(r)?r:[r])}function Ga(e){let n=e.headers??{},t=[n.validationtoken,n.validationToken,n["validation-token"],n["ms-validation-token"]];for(let c of t){let l=rr(Array.isArray(c)?c:[c]);if(l)return decodeURIComponent(l)}let r=Za({query:e.query},"validationToken");if(r)return r;let o=["x-forwarded-uri","x-original-uri","x-rewrite-url","x-envoy-original-path","referer"];for(let c of o){let l=n[c],u=Array.isArray(l)?l[0]:l;if(!(!u||typeof u!="string"))try{let p=(u.startsWith("http")?new URL(u):new URL(`https://example.invalid${u.startsWith("/")?u:`/${u}`}`)).searchParams.get("validationToken");if(p?.trim())return p.trim()}catch{continue}}let i=e.payload!==void 0?e.payload:e.body!==void 0?e.body:void 0,s=Gn(typeof i=="string"?(()=>{try{return JSON.parse(i)}catch{return i}})():i);return rr([s?.validationToken])??null}function xd(e){if(Ga(e))return!0;let n=Gn(e.body??e.payload);return qa(e.headers??{},"content-type")?.includes("text/plain")?!n||Object.keys(n).length===0:!1}function rr(e){for(let n of e){let t=Ka(n);if(t)return t}}function Id(e){let t=Gn(e.message)?.data;if(typeof t!="string")return null;try{return JSON.parse(Buffer.from(t,"base64").toString("utf8"))}catch{return null}}var Zn=Symbol.for("corsair:internal");function Ya(e){if(e.hub?.projectApiKey?.startsWith("ck_cloud_")&&oa(e.hub))return ia(e);let n=e.database?Qo(e.database,{dbTables:e.dbTables}):void 0,t=e.kek??"",r=n&&t?ea(e.plugins,n,t):Gt(!!n,!!t),o=sa(e),i={plugins:e.plugins,database:n,kek:t,multiTenancy:!!e.multiTenancy,permissions:o,manual:e.manual,hub:e.hub?ot(e.hub):void 0},s=Ji(n),a=xa(i);if(e.multiTenancy){let u=Object.assign({withTenant:d=>{if(!d)throw new Error("corsair.withTenant(tenantId): tenantId must be a non-empty string");let p=Oo(e.plugins,{database:n,tenantId:d,kek:t,rootErrorHandlers:e.errorHandlers,permissionsOptions:o,manualConfig:e.manual,hubConfig:i.hub,internalConfig:i});return Object.assign(p,{[Zn]:i})},keys:r,permissions:s,manage:a},{[Zn]:i});return za(u,i.hub),Va(u,i.hub),u}let c=Oo(e.plugins,{database:n,tenantId:void 0,kek:t,rootErrorHandlers:e.errorHandlers,permissionsOptions:o,manualConfig:e.manual,hubConfig:i.hub,internalConfig:i}),l=Object.assign({},c,{keys:r,permissions:s,manage:a,[Zn]:i});return za(l,i.hub),Va(l,i.hub),l}function za(e,n){n?.projectApiKey?.startsWith("ck_dev_")&&import("./loop-5OED2VBJ.js").then(t=>t.startConnectLoop(e)).catch(()=>{})}function Sd(e){return e?.projectApiKey?.startsWith("ck_dev_")?e.tunnel!==!1&&process.env.CORSAIR_TUNNEL!=="0":!1}var Ja=globalThis.__corsairTunnels??=new Set,_d=1e3,Ed=3e4;function Md(e){let n=e.schedule??((s,a)=>void setTimeout(s,a).unref?.()),t=e.minDelayMs??_d,r=e.maxDelayMs??Ed,o=t,i=()=>{let s=!1,a=()=>{s||(s=!0,n(i,o),o=Math.min(o*2,r))};e.start(a).then(()=>{o=t}).catch(a)};i()}function Va(e,n){if(!Sd(n))return;let t=n.projectApiKey;if(Ja.has(t))return;let r=Number(process.env.PORT);if(!Number.isInteger(r)||r<1||r>65535){console.error("[corsair] PORT is not set \u2014 dev tunnel skipped. Set PORT to your app port, or run `corsair http <port>`.");return}Ja.add(t);let o=typeof n.tunnel=="object"?n.tunnel:{},i=process.env.CORSAIR_FRP_HOST??o.shareHost??ar;Md({start:s=>import("./hub/tunnel/run-tunnel.js").then(a=>a.runTunnel({port:r,apiUrl:n.apiUrl,apiKey:t,shareHost:i,onClose:s})).then(({url:a})=>{console.log(`[corsair] tunnel active: ${a}${cr}`)}).catch(a=>{throw console.warn(`[corsair] tunnel down: ${a instanceof Error?a.message:String(a)}. Retrying \u2014 run \`corsair setup\` if it doesn't recover.`),a})})}var Dd={slack:{channels:{list:{}},users:{list:{}}},linear:{projects:{list:{}},issues:{list:{}},users:{list:{}}},github:{issues:{list:{}},repositories:{list:{}}},discord:{guilds:{list:{}},channels:{list:{}}},hubspot:{contacts:{getMany:{}},companies:{getMany:{}},deals:{getMany:{}}},gmail:{messages:{list:{}},labels:{list:{}},drafts:{list:{}},threads:{list:{}}},googlecalendar:{events:{getMany:{}}},googlemeet:{conferenceRecords:{list:{}}},googledrive:{files:{list:{}},folders:{list:{}},sharedDrives:{list:{}}},notion:{databases:{getManyDatabases:{}},databasePages:{getManyDatabasePages:{}},users:{getManyUsers:{}}},airtable:{bases:{getMany:{}}},todoist:{projects:{getMany:{}},tasks:{getMany:{}}},cal:{bookings:{list:{}}},zohomail:{folders:{list:{}},messages:{list:{}}}},Go=Dd;async function ft(e,n){let t=[],r=n?.silent??!1,o=g=>{t.push(g),r||console.log(g)},i=g=>{t.push(g),r||console.warn(g)},s=n?.caller??"script",a=ei(e);if(!a)throw new Error("setupCorsair: invalid corsair instance");if(!a.database)throw new Error("setupCorsair: a database must be configured on the corsair instance");let c=Kd(e,a.plugins,n),l={...a,database:a.database},u=l.database.db;await zd(l.database,i);let d=await Jd(u,l,c.tenantId,c.provisionAccounts,o);n?.credentials&&Object.keys(n.credentials).length>0&&await Qd(e,c,n.credentials,l,o,i);let p=await ep(d,c,o,s);if(n?.backfill){o("[corsair:setup] Starting backfill...");let g=Ya({plugins:a.plugins,database:u,kek:a.kek,multiTenancy:!0}).withTenant(c.tenantId);await np(g,a.plugins,p,o,i),o("[corsair:setup] Backfill complete.")}return t.join(`
|
|
63
|
+
`)}function zo(e,n,t){let r=t==="integration"?e.authConfig?.[n]?.integration??[]:e.authConfig?.[n]?.account??[];return new Set([...j[n][t],...r])}function qd(e,n){if(!e)return!1;for(let[t,r]of Object.entries(e)){let o=n.find(a=>a.id===t);if(!o)continue;let i=_(o);if(!i)continue;let s=zo(o,i,"account");for(let a of Object.keys(r))if(s.has(a))return!0}return!1}function Kd(e,n,t){let r=ni(e),o=t?.tenantId?.trim(),i=o!==void 0&&o.length>0;if(r&&t?.backfill&&!i)throw new Error("setupCorsair: tenantId is required for backfill on a multi-tenant instance");if(r&&qd(t?.credentials,n)&&!i)throw new Error("setupCorsair: tenantId is required when setting account-level credentials on a multi-tenant instance");if(i&&!o)throw new Error("setupCorsair: tenantId must be a non-empty string");return{multiTenant:r,tenantIdProvided:i,tenantId:i?o:"default",provisionAccounts:!r||i}}function Xa(e,n){return Ie(e)?n===0?!0:Object.values(e).every(t=>Xa(t,n-1)):!1}function Zd(e){return Xa(e,4)}var Gd=oi;function or(e){if(e instanceof Ld){let n={};for(let[t,r]of Object.entries(e.shape))n[t]=r instanceof jd?or(r):"unknown";return n}return e instanceof Ud?`${or(e.unwrap())} | null`:e instanceof Nd?`${or(e.unwrap())} | undefined`:e instanceof Bd?e.options.join(" | "):e instanceof Wd?"string":e instanceof Fd?"number":e instanceof Od?"boolean":e instanceof Hd?"date":e instanceof $d?"jsonb":"unknown"}async function zd(e,n){let t=await e.db.introspection.getTables(),r=new Set(t.map(i=>i.name)),o=e.tableNames??Yo();for(let[i,s]of Object.entries(Gd)){let a=o[i];if(!r.has(a)){let c=a!==i?` (dbTables.${i} \u2192 "${a}")`:"";n(`[corsair:setup] Table "${a}" does not exist${c}. Run your database migrations before calling setupCorsair.
|
|
64
|
+
Schema: ${JSON.stringify(or(s),null,2)}`)}}}async function Jd(e,n,t,r,o){let i=new Date,s=new Map;for(let a of n.plugins){let c=a.id,l=_(a),u=await e.selectFrom("corsair_integrations").selectAll().where("name","=",c).executeTakeFirst();if(!u){let h=crypto.randomUUID();await e.insertInto("corsair_integrations").values({id:h,name:c,config:{},created_at:i,updated_at:i}).execute(),u=await e.selectFrom("corsair_integrations").selectAll().where("id","=",h).executeTakeFirst(),o(`[corsair:setup] Created integration: ${c}`)}let d=l?a.authConfig?.[l]?.integration??[]:[],p=l?a.authConfig?.[l]?.account??[]:[],g=l&&u?F({authType:l,integrationName:c,kek:n.kek,database:n.database,extraIntegrationFields:d}):void 0;if(u&&!u.dek&&g&&(await g.issue_new_dek(),o(`[corsair:setup] Issued integration DEK: ${c}`)),!u||!l||!g)continue;let f;if(r){let h=await e.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",u.id).executeTakeFirst();if(!h){let k=crypto.randomUUID();await e.insertInto("corsair_accounts").values({id:k,tenant_id:t,integration_id:u.id,config:{},created_at:i,updated_at:i}).execute(),h=await e.selectFrom("corsair_accounts").selectAll().where("id","=",k).executeTakeFirst(),o(`[corsair:setup] Created account: ${c}`)}f=h&&B({authType:l,integrationName:c,tenantId:t,kek:n.kek,database:n.database,extraAccountFields:p}),h&&f&&!h.dek&&(await f.issue_new_dek(),o(`[corsair:setup] Issued account DEK: ${c}`))}s.set(c,{pluginId:c,authType:l,integration:g,account:f,integrationFields:[...j[l].integration,...d],accountFields:r?[...j[l].account,...p]:[]})}return s}function Vd(e){if(!Ie(e))return;let n=e.keys;return Ie(n)?n:void 0}function Yd(e,n){return"withTenant"in e&&typeof e.withTenant=="function"?e.withTenant(n):e}async function Qd(e,n,t,r,o,i){let s=Vd(e),a=n.provisionAccounts?Yd(e,n.tenantId):void 0;for(let[c,l]of Object.entries(t)){let u=r.plugins.find(b=>b.id===c);if(!u){i(`[corsair:setup] Unknown plugin '${c}' \u2014 skipping credentials.`);continue}let d=_(u);if(!d){i(`[corsair:setup] Plugin '${c}' has no auth type \u2014 skipping credentials.`);continue}let p=zo(u,d,"integration"),g=zo(u,d,"account"),f=s?.[c],h=a?.[c],k=Ie(h)?h.keys:void 0;for(let[b,v]of Object.entries(l))if(v){if(p.has(b)){if(n.multiTenant&&n.tenantIdProvided)throw new Error(`[corsair:setup] '${c}.${b}' is an integration-level credential shared across all tenants. You passed tenantId="${n.tenantId}", which only scopes account-level credentials. Run setup without --tenant if you intend to change this credential globally.`);let P=ee(f,`set_${b}`);if(!P){i(`[corsair:setup] Cannot set integration field '${b}' for '${c}'.`);continue}await P(v),o(`[corsair:setup] Set ${c} integration.${b}`);continue}if(g.has(b)){if(n.multiTenant&&!n.tenantIdProvided)throw new Error(`setupCorsair: tenantId is required to set account-level credential '${c}.${b}' on a multi-tenant instance`);let P=ee(k,`set_${b}`);if(!P){i(`[corsair:setup] Cannot set account field '${b}' for '${c}'.`);continue}await P(v),o(`[corsair:setup] Set ${c} account.${b} (tenant=${n.tenantId})`);continue}i(`[corsair:setup] Unknown credential field '${b}' for plugin '${c}'.`)}}}var Qa=new Set(["webhook_signature","expires_at","scope","redirect_url"]);async function Xd(e,n,t,r,o,i,s,a,c){let l=[],u=[];for(let p of o){if(Qa.has(p))continue;let g=ee(t,`get_${p}`);if(!g)continue;let f=null;try{let h=await g();f=typeof h=="string"?h:null}catch{}f||l.push(p)}if(r&&i.length>0)for(let p of i){if(Qa.has(p))continue;let g=ee(r,`get_${p}`);if(!g)continue;let f=null;try{let h=await g();f=typeof h=="string"?h:null}catch{}f||u.push(p)}let d=l.length===0&&u.length===0;if(n==="managed_pricing")a(`[corsair:setup] '${e}' (managed_pricing) uses Corsair metered credentials via Hub \u2014 nothing to store in your database. Pass hub: { ... } to createCorsair().`);else if(d)a(`[corsair:setup] '${e}' (${n}) is configured \u2713`);else if(n==="managed")a(`[corsair:setup] '${e}' (managed) is not connected yet. Use Connect in your app \u2014 Corsair Hub delivers OAuth tokens after authorization.`);else{let p=[...l,...u];if(c==="cli"){let g=p.map(f=>`${f}=VALUE`).join(" ");a(`[corsair:setup] '${e}' (${n}) needs credentials. Run:
|
|
65
|
+
corsair setup --${e} ${g}`)}else{let g=[`[corsair:setup] '${e}' (${n}) needs credentials. Call:`];for(let f of l)g.push(` await corsair.keys.${e}.set_${f}(value)`);for(let f of u){let h=s.provisionAccounts?s.tenantId==="default"?`corsair.${e}`:`corsair.withTenant(${JSON.stringify(s.tenantId)}).${e}`:`corsair.withTenant(<tenant>).${e}`;g.push(` await ${h}.keys.set_${f}(value)`)}a(g.join(`
|
|
66
|
+
`))}}return d}async function ep(e,n,t,r){let o=new Set;for(let i of e.values())await Xd(i.pluginId,i.authType,i.integration,i.account,i.integrationFields,i.accountFields,n,t,r)&&o.add(i.pluginId);return o}async function np(e,n,t,r,o){if(!Zd(Go)){o("[corsair:setup] Backfill config is invalid - skipping backfill.");return}let i=Go,s=new Set(n.map(a=>a.id));for(let[a,c]of Object.entries(i)){if(!s.has(a))continue;if(!t.has(a)){r(`[corsair:setup] Skipping backfill for '${a}' \u2014 auth not configured.`);continue}let l=Ie(e)?e[a]:void 0,u=Ie(l)?l.api:void 0;if(u)for(let[d,p]of Object.entries(c))for(let[g,f]of Object.entries(p)){r(`[corsair:setup] Backfilling ${a} \u203A ${d}.${g}...`);try{let h=Ie(u)?u[d]:void 0;await ee(h,g)?.(f)}catch(h){o(`[corsair:setup] ${a} \u203A ${d}.${g} failed: `+(h instanceof Error?h.message:String(h)))}}}}export{ii as a,Se as b,ye as c,Yn as d,Qn as e,Xn as f,tn as g,si as h,et as i,yr as j,Sn as k,gi as l,fi as m,_e as n,We as o,me as p,on as q,sn as r,Ee as s,hr as t,mi as u,Mn as v,he as w,Dn as x,br as y,ot as z,U as A,it as B,an as C,be as D,ke as E,ne as F,kr as G,On as H,Me as I,de as J,Hn as K,F as L,B as M,Ti as N,Pi as O,ft as P,Qd as Q,Oe as R,Cr as S,ln as T,pn as U,Tr as V,pt as W,Oi as X,Ze as Y,Z,Pr as _,Fn as $,Fi as aa,Uc as ba,yt as ca,mf as da,$i as ea,Wi as fa,ji as ga,qi as ha,mt as ia,Rr as ja,bt as ka,kt as la,He as ma,mn as na,Er as oa,zi as pa,Mr as qa,Lr as ra,Nr as sa,_t as ta,$r as ua,kn as va,wn as wa,Et as xa,Mt as ya,Ln as za,Wr as Aa,jr as Ba,Dt as Ca,Nn as Da,Ot as Ea,Ht as Fa,Ue as Ga,Cn as Ha,as as Ia,zr as Ja,Jr as Ka,ze as La,jn as Ma,qn as Na,Wt as Oa,Qr as Pa,Kn as Qa,qu as Ra,Ju as Sa,Qu as Ta,hs as Ua,bs as Va,qt as Wa,ks as Xa,ws as Ya,Je as Za,Ve as _a,to as $a,ro as ab,oo as bb,io as cb,so as db,Ye as eb,S as fb,ao as gb,As as hb,uo as ib,Is as jb,Ss as kb,_s as lb,lo as mb,po as nb,go as ob,fo as pb,yo as qb,mo as rb,ho as sb,bo as tb,ko as ub,wo as vb,Co as wb,vo as xb,To as yb,Po as zb,Ro as Ab,Xe as Bb,Ll as Cb,$ as Db,ya as Eb,ma as Fb,ha as Gb,ba as Hb,ka as Ib,wa as Jb,Ca as Kb,va as Lb,Ta as Mb,Pa as Nb,Ra as Ob,Aa as Pb,Ia as Qb,ld as Rb,gt as Sb,Da as Tb,gv as Ub,en as Vb,fv as Wb,er as Xb,kd as Yb,wd as Zb,tr as _b,Td as $b,ja as ac,Pd as bc,Rd as cc,qa as dc,Ka as ec,Gn as fc,Ad as gc,Za as hc,Ga as ic,xd as jc,rr as kc,Id as lc,Zn as mc,Ya as nc,Sd as oc,Md as pc};
|
|
@@ -24,7 +24,7 @@ declare const CorsairPermissionsSchema: z.ZodObject<{
|
|
|
24
24
|
}, z.core.$strip>;
|
|
25
25
|
type CorsairPermission = z.infer<typeof CorsairPermissionsSchema>;
|
|
26
26
|
|
|
27
|
-
type AuthTypes = 'oauth_2' | 'api_key' | 'bot_token' | 'managed';
|
|
27
|
+
type AuthTypes = 'oauth_2' | 'api_key' | 'bot_token' | 'managed' | 'managed_pricing';
|
|
28
28
|
|
|
29
29
|
type Tenant = {
|
|
30
30
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ga as a,ha as b,ia as c}from"./chunk-
|
|
1
|
+
import{ga as a,ha as b,ia as c}from"./chunk-OFDCTRKH.js";import"./chunk-6IURNA4L.js";import"./chunk-QAK6BJXE.js";import"./chunk-BRUFMVTV.js";import"./chunk-XPXWKPFZ.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{c as createHubConnectSession,b as createHubConnectSessionForPlugin,a as postHubConnectSession};
|