corsair 0.1.73 → 0.1.75
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/{chunk-EK7JQYHJ.js → chunk-6OUDU5GH.js} +1 -1
- package/dist/chunk-FL4GOHVN.js +1 -0
- package/dist/chunk-PCO6RKXN.js +26 -0
- package/dist/chunk-UBM25HVI.js +1 -0
- package/dist/core.d.ts +1 -1
- package/dist/core.js +1 -1
- package/dist/db.d.ts +2 -4
- package/dist/db.js +1 -1
- package/dist/{index-Cc9JiMef.d.ts → index-nV76ScYN.d.ts} +4 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/oauth.js +1 -1
- package/dist/orm.d.ts +1 -4
- package/dist/orm.js +1 -1
- package/dist/setup.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-6KMLS5U6.js +0 -1
- package/dist/chunk-AAWROBCK.js +0 -1
- package/dist/chunk-W6KENKHM.js +0 -26
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{C as R,D as v,j as m,k as A,l as _}from"./chunk-
|
|
1
|
+
import{C as R,D as v,j as m,k as A,l as _}from"./chunk-PCO6RKXN.js";import{a as j}from"./chunk-UBM25HVI.js";import{Kysely as F}from"kysely";import{ZodBoolean as x,ZodDate as E,ZodEnum as D,ZodNullable as K,ZodNumber as N,ZodObject as B,ZodOptional as Z,ZodRecord as L,ZodString as U,ZodType as W}from"zod";var I={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:{}}},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:{}}}};async function pn(n,e){let s=[],i=d=>{s.push(d),console.log(d)},a=d=>{s.push(d),console.warn(d)},t=e?.caller??"script",f=q(n);if(!f)throw new Error("setupCorsair: invalid corsair instance");if(!f.database)throw new Error("setupCorsair: a database must be configured on the corsair instance");let o=Q(n,f.plugins,e),r={...f,database:f.database},c=r.database.db;await X(c,a);let l=await nn(c,r,o.tenantId,o.provisionAccounts,i);e?.credentials&&Object.keys(e.credentials).length>0&&await sn(n,o,e.credentials,r,i,a);let y=await rn(l,o,i,t);if(e?.backfill){i("[corsair:setup] Starting backfill...");let d=v({plugins:f.plugins,database:c,kek:f.kek,multiTenancy:!0}).withTenant(o.tenantId);await on(d,f.plugins,y,i,a),i("[corsair:setup] Backfill complete.")}return s.join(`
|
|
2
2
|
`)}function w(n){return typeof n=="object"&&n!==null}function Y(n){return!w(n)||!Array.isArray(n.plugins)||typeof n.kek!="string"||typeof n.multiTenancy!="boolean"?!1:n.database===void 0?!0:w(n.database)?n.database.db instanceof F:!1}function q(n){let e=Object.getOwnPropertyDescriptor(n,R);if(e)return Y(e.value)?e.value:void 0}function H(n){return n==="oauth_2"||n==="api_key"||n==="bot_token"}function P(n){let e=n.options?.authType;return H(e)?e:void 0}function J(n){return"withTenant"in n&&typeof n.withTenant=="function"}function $(n,e,s){let i=s==="integration"?n.authConfig?.[e]?.integration??[]:n.authConfig?.[e]?.account??[];return new Set([...m[e][s],...i])}function z(n,e){if(!n)return!1;for(let[s,i]of Object.entries(n)){let a=e.find(o=>o.id===s);if(!a)continue;let t=P(a);if(!t)continue;let f=$(a,t,"account");for(let o of Object.keys(i))if(f.has(o))return!0}return!1}function Q(n,e,s){let i=J(n),a=s?.tenantId?.trim(),t=a!==void 0&&a.length>0;if(i&&s?.backfill&&!t)throw new Error("setupCorsair: tenantId is required for backfill on a multi-tenant instance");if(i&&z(s?.credentials,e)&&!t)throw new Error("setupCorsair: tenantId is required when setting account-level credentials on a multi-tenant instance");if(t&&!a)throw new Error("setupCorsair: tenantId must be a non-empty string");return{multiTenant:i,tenantIdProvided:t,tenantId:t?a:"default",provisionAccounts:!i||t}}function C(n,e){if(!w(n))return;let s=n[e];return typeof s=="function"?(...i)=>Reflect.apply(s,n,i):void 0}function O(n,e){return w(n)?e===0?!0:Object.values(n).every(s=>O(s,e-1)):!1}function V(n){return O(n,4)}var G={...j};function S(n){if(n instanceof B){let e={};for(let[s,i]of Object.entries(n.shape))e[s]=i instanceof W?S(i):"unknown";return e}return n instanceof K?`${S(n.unwrap())} | null`:n instanceof Z?`${S(n.unwrap())} | undefined`:n instanceof D?n.options.join(" | "):n instanceof U?"string":n instanceof N?"number":n instanceof x?"boolean":n instanceof E?"date":n instanceof L?"jsonb":"unknown"}async function X(n,e){let s=await n.introspection.getTables(),i=new Set(s.map(a=>a.name));for(let[a,t]of Object.entries(G))i.has(a)||e(`[corsair:setup] Table "${a}" does not exist. Run your database migrations before calling setupCorsair.
|
|
3
3
|
Schema: ${JSON.stringify(S(t),null,2)}`)}async function nn(n,e,s,i,a){let t=new Date,f=new Map;for(let o of e.plugins){let r=o.id,c=P(o),l=await n.selectFrom("corsair_integrations").selectAll().where("name","=",r).executeTakeFirst();if(!l){let u=crypto.randomUUID();await n.insertInto("corsair_integrations").values({id:u,name:r,config:{},created_at:t,updated_at:t}).execute(),l=await n.selectFrom("corsair_integrations").selectAll().where("id","=",u).executeTakeFirst(),a(`[corsair:setup] Created integration: ${r}`)}let y=c?o.authConfig?.[c]?.integration??[]:[],d=c?o.authConfig?.[c]?.account??[]:[],g=c&&l?A({authType:c,integrationName:r,kek:e.kek,database:e.database,extraIntegrationFields:y}):void 0;if(l&&!l.dek&&g&&(await g.issue_new_dek(),a(`[corsair:setup] Issued integration DEK: ${r}`)),!l||!c||!g)continue;let p;if(i){let u=await n.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",s).where("integration_id","=",l.id).executeTakeFirst();if(!u){let h=crypto.randomUUID();await n.insertInto("corsair_accounts").values({id:h,tenant_id:s,integration_id:l.id,config:{},created_at:t,updated_at:t}).execute(),u=await n.selectFrom("corsair_accounts").selectAll().where("id","=",h).executeTakeFirst(),a(`[corsair:setup] Created account: ${r}`)}p=u&&_({authType:c,integrationName:r,tenantId:s,kek:e.kek,database:e.database,extraAccountFields:d}),u&&p&&!u.dek&&(await p.issue_new_dek(),a(`[corsair:setup] Issued account DEK: ${r}`))}f.set(r,{pluginId:r,authType:c,integration:g,account:p,integrationFields:[...m[c].integration,...y],accountFields:i?[...m[c].account,...d]:[]})}return f}function en(n){if(!w(n))return;let e=n.keys;return w(e)?e:void 0}function tn(n,e){return"withTenant"in n&&typeof n.withTenant=="function"?n.withTenant(e):n}async function sn(n,e,s,i,a,t){let f=en(n),o=e.provisionAccounts?tn(n,e.tenantId):void 0;for(let[r,c]of Object.entries(s)){let l=i.plugins.find(b=>b.id===r);if(!l){t(`[corsair:setup] Unknown plugin '${r}' \u2014 skipping credentials.`);continue}let y=P(l);if(!y){t(`[corsair:setup] Plugin '${r}' has no auth type \u2014 skipping credentials.`);continue}let d=$(l,y,"integration"),g=$(l,y,"account"),p=f?.[r],u=o?.[r],h=w(u)?u.keys:void 0;for(let[b,T]of Object.entries(c))if(T){if(d.has(b)){if(e.multiTenant&&e.tenantIdProvided)throw new Error(`[corsair:setup] '${r}.${b}' is an integration-level credential shared across all tenants. You passed tenantId="${e.tenantId}", which only scopes account-level credentials. Run setup without --tenant if you intend to change this credential globally.`);let k=C(p,`set_${b}`);if(!k){t(`[corsair:setup] Cannot set integration field '${b}' for '${r}'.`);continue}await k(T),a(`[corsair:setup] Set ${r} integration.${b}`);continue}if(g.has(b)){if(e.multiTenant&&!e.tenantIdProvided)throw new Error(`setupCorsair: tenantId is required to set account-level credential '${r}.${b}' on a multi-tenant instance`);let k=C(h,`set_${b}`);if(!k){t(`[corsair:setup] Cannot set account field '${b}' for '${r}'.`);continue}await k(T),a(`[corsair:setup] Set ${r} account.${b} (tenant=${e.tenantId})`);continue}t(`[corsair:setup] Unknown credential field '${b}' for plugin '${r}'.`)}}}var M=new Set(["webhook_signature","expires_at","scope","redirect_url"]);async function an(n,e,s,i,a,t,f,o,r){let c=[],l=[];for(let d of a){if(M.has(d))continue;let g=C(s,`get_${d}`);if(!g)continue;let p=null;try{let u=await g();p=typeof u=="string"?u:null}catch{}p||c.push(d)}if(i&&t.length>0)for(let d of t){if(M.has(d))continue;let g=C(i,`get_${d}`);if(!g)continue;let p=null;try{let u=await g();p=typeof u=="string"?u:null}catch{}p||l.push(d)}let y=c.length===0&&l.length===0;if(y)o(`[corsair:setup] '${n}' (${e}) is configured \u2713`);else{let d=[...c,...l];if(r==="cli"){let g=d.map(p=>`${p}=VALUE`).join(" ");o(`[corsair:setup] '${n}' (${e}) needs credentials. Run:
|
|
4
4
|
corsair setup --${n} ${g}`)}else{let g=[`[corsair:setup] '${n}' (${e}) needs credentials. Call:`];for(let p of c)g.push(` await corsair.keys.${n}.set_${p}(value)`);for(let p of l){let u=f.provisionAccounts?f.tenantId==="default"?`corsair.${n}`:`corsair.withTenant(${JSON.stringify(f.tenantId)}).${n}`:`corsair.withTenant(<tenant>).${n}`;g.push(` await ${u}.keys.set_${p}(value)`)}o(g.join(`
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as i}from"./chunk-QAIKSQAD.js";import{Kysely as s,PostgresDialect as b,SqliteDialect as w}from"kysely";import{PostgresJSDialect as C}from"kysely-postgres-js";function D(e){return typeof e.query=="function"&&typeof e.connect=="function"}function d(e){let n=e;return typeof n.prepare=="function"&&typeof n.exec=="function"&&typeof n.close=="function"&&!("query"in e)}function S(e){return typeof e=="function"&&typeof e.begin=="function"&&typeof e.end=="function"}function u(e,n){return typeof e=="function"?e.bind(n):e}var g=114,m=3802;function q(e){if(typeof e!="object"||e===null||Buffer.isBuffer(e))return!1;if(Array.isArray(e))return!0;let n=Object.getPrototypeOf(e);return n===Object.prototype||n===null}function k(e){return e instanceof Date?e.toISOString():q(e)?JSON.stringify(e):e}function P(e){let n=e.options?.serializers;if(!n)return;let t=r=>r;n[g]=t,n[m]=t}function K(e){return new Proxy(e,{get(n,t,r){return t!=="reserve"?u(Reflect.get(n,t,r),n):async function(){let c=await n.reserve();return new Proxy(c,{get(o,a,f){return a!=="unsafe"?u(Reflect.get(o,a,f),o):function(y,l,p){return o.unsafe(y,l?.map(k),p)}}})}}})}function I(e){return typeof e.selectFrom=="function"}function J(e){if(I(e))return{db:e};if(d(e))return{db:new s({dialect:new w({database:e}),plugins:[new i]})};if(D(e))return{db:new s({dialect:new b({pool:e})})};if(S(e))return P(e),{db:new s({dialect:new C({postgres:K(e)})})};throw new Error("Unsupported database input. Expected a pg Pool, postgres.js Sql, better-sqlite3 Database, or a Kysely instance.")}export{J as a};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import{a as Pe,b as de}from"./chunk-OZHME3EO.js";import{a as xe}from"./chunk-FL4GOHVN.js";var N=class extends Error{pluginId;authType;constructor(n,o,t){super(t??`[auth-missing:${n}:${o}]`),Object.setPrototypeOf(this,new.target.prototype),this.name="AuthMissingError",this.pluginId=n,this.authType=o}};import{createCipheriv as Ee,createDecipheriv as Re,randomBytes as ne,scrypt as on}from"crypto";import{promisify as rn}from"util";var Ie=rn(on),te="aes-256-gcm",De=12,oe=16,sn=16,V=32;function B(){return ne(V).toString("base64")}async function j(e,n){let o=ne(sn),t=await Ie(n,o,V),r=ne(De),i=Ee(te,t,r,{authTagLength:oe}),s=Buffer.concat([i.update(e,"utf8"),i.final()]),a=i.getAuthTag();return[o.toString("base64"),r.toString("base64"),a.toString("base64"),s.toString("base64")].join(":")}async function M(e,n){let[o,t,r,i]=e.split(":");if(!o||!t||!r||!i)throw new Error("Invalid encrypted DEK format");let s=Buffer.from(o,"base64"),a=Buffer.from(t,"base64"),d=Buffer.from(r,"base64"),p=Buffer.from(i,"base64"),c=await Ie(n,s,V),l=Re(te,c,a,{authTagLength:oe});return l.setAuthTag(d),Buffer.concat([l.update(p),l.final()]).toString("utf8")}function ue(e,n){let o=Buffer.from(n,"base64"),t=ne(De),r=Ee(te,o,t,{authTagLength:oe}),i=Buffer.concat([r.update(e,"utf8"),r.final()]),s=r.getAuthTag();return[t.toString("base64"),s.toString("base64"),i.toString("base64")].join(":")}function le(e,n){let[o,t,r]=e.split(":");if(!o||!t||!r)throw new Error("Invalid encrypted data format");let i=Buffer.from(n,"base64"),s=Buffer.from(o,"base64"),a=Buffer.from(t,"base64"),d=Buffer.from(r,"base64"),p=Re(te,i,s,{authTagLength:oe});return p.setAuthTag(a),Buffer.concat([p.update(d),p.final()]).toString("utf8")}function H(e,n){let o={};for(let[t,r]of Object.entries(e))o[t]=ue(r,n);return o}function L(e,n){let o={};for(let[t,r]of Object.entries(e))o[t]=le(r,n);return o}function Y(e,n,o){let t=L(e,n);return H(t,o)}function re(e,n){let o=[];e||o.push("database"),n||o.push("kek");let t={};return new Proxy(t,{get(r,i){let s=o.length>1;throw new Error(`corsair.keys.${String(i)}: Cannot access keys because ${o.join(" and ")} ${s?"are":"is"} not configured. Provide both 'database' and 'kek' in createCorsair() to enable key management.
|
|
2
|
+
|
|
3
|
+
To generate a KEK, run: openssl rand -base64 ${V}`)}})}var Q={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"]}};function ve(e,n,o){let t={};for(let r of o)t[`get_${r}`]=async()=>(await e())[r]??null,t[`set_${r}`]=async i=>{let s=[null,void 0,""].includes(i)?null:i;await n({[r]:s})};return t}var pe=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};function q(e){let{authType:n,integrationName:o,kek:t,database:r,extraIntegrationFields:i=[]}=e,s=[...Q[n].integration,...i],a=null,d={kek:t,integrationName:o,getIntegration:async()=>{if(a)return a;let u=await r.db.selectFrom("corsair_integrations").selectAll().where("name","=",o).executeTakeFirst();if(!u)throw new Error(`Integration "${o}" not found. Make sure to create the integration first.`);return a={id:u.id,config:pe(u.config),dek:u.dek??null},a},updateIntegration:async u=>{let h=await d.getIntegration();await r.db.updateTable("corsair_integrations").set({...u.config!==void 0?{config:u.config}:{},...u.dek!==void 0?{dek:u.dek}:{},updated_at:new Date}).where("id","=",h.id).execute(),a=null}},p=null,c=async()=>{if(p)return p;let u=await d.getIntegration();if(!u.dek)throw new Error(`No DEK found for integration "${o}". Initialize the integration first.`);return p=await M(u.dek,t),p},l=async()=>{let u=await d.getIntegration(),h=await c(),b=u.config;return!b||Object.keys(b).length===0?{}:L(b,h)};return{get_dek:c,issue_new_dek:async()=>{let u=await d.getIntegration(),h=B(),b={};if(u.dek){let w=await M(u.dek,t),A=u.config;A&&Object.keys(A).length>0&&(b=Y(A,w,h))}let k=await j(h,t);return await d.updateIntegration({config:b,dek:k}),p=h,h},...ve(l,async u=>{let h=await c(),b;try{b=await l()}catch(A){console.error(`[corsair] Failed to decrypt config for integration "${o}", starting fresh:`,A),b={}}let k={...b};for(let[A,y]of Object.entries(u))y===null?delete k[A]:k[A]=y;let w=H(k,h);await d.updateIntegration({config:w})},s)}}function ie(e){let{authType:n,integrationName:o,tenantId:t,kek:r,database:i,extraAccountFields:s=[]}=e,a=[...Q[n].account,...s],d=null,p=null,c=async()=>{if(p)return p;let y=await i.db.selectFrom("corsair_integrations").selectAll().where("name","=",o).executeTakeFirst();if(!y)throw new Error(`Integration "${o}" not found. Make sure to create the integration first.`);return p={id:y.id,config:pe(y.config),dek:y.dek??null},p},l={kek:r,integrationName:o,tenantId:t,getIntegration:c,getAccount:async()=>{if(d)return d;let y=await c(),m=await i.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",y.id).executeTakeFirst();if(!m)throw new Error(`Account not found for tenant "${t}" and integration "${o}". Make sure to create the account first.`);return d={id:m.id,config:pe(m.config),dek:m.dek??null},d},updateAccount:async y=>{let m=await l.getAccount();await i.db.updateTable("corsair_accounts").set({...y.config!==void 0?{config:y.config}:{},...y.dek!==void 0?{dek:y.dek}:{},updated_at:new Date}).where("id","=",m.id).execute(),d=null}},f=null,g=null,u=async()=>{if(f)return f;let y=await l.getAccount();if(!y.dek)throw new Error(`No DEK found for account (tenant: "${t}", integration: "${o}"). Initialize the account first.`);return f=await M(y.dek,r),f},h=async()=>{if(g)return g;let y=await l.getIntegration();if(!y.dek)throw new Error(`No DEK found for integration "${o}". Initialize the integration first.`);return g=await M(y.dek,r),g},b=async()=>{let y=await l.getAccount(),m=await u(),T=y.config;return!T||Object.keys(T).length===0?{}:L(T,m)},k=async()=>{let y=await l.getIntegration(),m=await h(),T=y.config;return!T||Object.keys(T).length===0?{}:L(T,m)},A={get_dek:u,issue_new_dek:async()=>{let y=await l.getAccount(),m=B(),T={};if(y.dek){let I=await M(y.dek,r),C=y.config;C&&Object.keys(C).length>0&&(T=Y(C,I,m))}let P=await j(m,r);return await l.updateAccount({config:T,dek:P}),f=m,m},...ve(b,async y=>{let m=await u(),T;try{T=await b()}catch(C){console.error(`[corsair] Failed to decrypt config for account (tenant: "${t}", integration: "${o}"), starting fresh:`,C),T={}}let P={...T};for(let[C,O]of Object.entries(y))O===null?delete P[C]:P[C]=O;let I=H(P,m);await l.updateAccount({config:I})},a)};return n==="oauth_2"&&(A.get_integration_credentials=async()=>{let y=await k();return{client_id:y.client_id||null,client_secret:y.client_secret||null,redirect_url:y.redirect_url??null}}),A}async function _e(e,n,o){let t=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!t)throw new Error(`Integration "${n}" not found.`);let r=B(),i=await j(r,o);return await e.db.updateTable("corsair_integrations").set({dek:i,updated_at:new Date}).where("id","=",t.id).execute(),r}async function Se(e,n,o,t){let r=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!r)throw new Error(`Integration "${n}" not found.`);let i=await e.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",o).where("integration_id","=",r.id).executeTakeFirst();if(!i)throw new Error(`Account not found for tenant "${o}" and integration "${n}".`);let s=B(),a=await j(s,t);return await e.db.updateTable("corsair_accounts").set({dek:a,updated_at:new Date}).where("id","=",i.id).execute(),s}import*as X from"crypto";function Oe(e,n){return Buffer.from(JSON.stringify({plugin:e,tenantId:n,iat:Date.now()})).toString("base64url")}function an(e,{maxAgeMs:n}={}){try{let o=e.includes(".")?e.split(".")[0]:e,t=JSON.parse(Buffer.from(o,"base64url").toString("utf-8"));if(t!==null&&typeof t=="object"&&"plugin"in t&&"tenantId"in t&&typeof t.plugin=="string"&&typeof t.tenantId=="string"){let r=t;return n!==void 0&&typeof r.iat=="number"&&Date.now()-r.iat>n?null:r}return null}catch{return null}}function Fe(e,n){let o=X.createHmac("sha256",n).update(e).digest("base64url");return`${e}.${o}`}var cn=600*1e3;function $e(e,n){let o=e.lastIndexOf(".");if(o===-1)return null;let t=e.slice(0,o),r=e.slice(o+1),i=X.createHmac("sha256",n).update(t).digest("base64url"),s=Buffer.from(r,"base64url"),a=Buffer.from(i,"base64url");return s.length!==a.length||!X.timingSafeEqual(s,a)?null:an(t,{maxAgeMs:cn})}var dn=async(e,n)=>(console.error(`[corsair:${n.pluginId}:${n.operation}]`,{error:e.message,input:n.input}),{maxRetries:0});async function Me(e,n,o,t,r){let i={pluginId:n,operation:o,input:t,originalError:e},s=Object.keys(r).find(p=>r[p]?.match(e,i));return await(r[s||"DEFAULT"]?.handler||dn)(e,i)}import{randomBytes as un}from"crypto";import{v4 as ln}from"uuid";var pn={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 gn(e,n,o){return o!==void 0?o:pn[n][e]}function Ke(e){let n=/(\d+)(d|h|m|s)/g,o=0,t;for(;(t=n.exec(e))!==null;){let r=parseInt(t[1],10);switch(t[2]){case"d":o+=r*864e5;break;case"h":o+=r*36e5;break;case"m":o+=r*6e4;break;case"s":o+=r*1e3;break}}return o>0?o:600*1e3}function Ne(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 Ze(e,n,o){let t=Date.now()+o;for(;Date.now()<t;){let r=await e.db.selectFrom("corsair_permissions").select(["id","status"]).where("id","=",n).executeTakeFirst();if(!r)return{result:"blocked",reason:"pending"};if(r.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(r.status==="denied")return{result:"blocked",reason:"denied"};if(r.status==="expired"||r.status==="failed")return{result:"blocked",reason:"timeout"};await new Promise(i=>setTimeout(i,500))}return{result:"blocked",reason:"timeout"}}async function Be(e){let n=gn(e.riskLevel,e.mode,e.override);if(n==="allow")return{result:"allow"};let o=e.meta?.irreversible?" (irreversible)":"",t=e.meta?.description?`${e.meta.description}${o}`:`${e.pluginId}.${e.endpointPath}${o}`;if(n==="deny"||!e.db)return console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 denied by permission mode '${e.mode}'.`,`
|
|
4
|
+
Action: ${t}`,`
|
|
5
|
+
To allow this, update the permission mode or add an override in your corsair config.`),{result:"blocked",reason:"policy"};let r=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","=",r).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 u=e.db,h=a.id;return{result:"allow",onComplete:async()=>{await u.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.`,`
|
|
6
|
+
Action: ${t}`,`
|
|
7
|
+
Permission ID: ${a.id}`,`
|
|
8
|
+
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Ze(e.db,a.id,e.timeoutMs??600*1e3):{result:"blocked",reason:"pending",id:a.id,token:a.token})}let d=ln(),p=un(32).toString("hex"),c=e.timeoutMs??600*1e3,l=new Date(Date.now()+c).toISOString();return await e.db.db.insertInto("corsair_permissions").values({id:d,created_at:new Date,updated_at:new Date,token:p,plugin:e.pluginId,endpoint:e.endpointPath,args:r,tenant_id:s,status:"pending",expires_at:l}).execute(),console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval required.`,`
|
|
9
|
+
Action: ${t}`,`
|
|
10
|
+
Permission ID: ${d}`,`
|
|
11
|
+
Permission token: ${p}`,`
|
|
12
|
+
Expires at: ${l}`,`
|
|
13
|
+
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Ze(e.db,d,c):{result:"blocked",reason:"pending",id:d,token:p}}function fn(e){return typeof e=="function"}function yn(e,n,o){let t=Fe(Oe(e,n.tenantId??o??"default"),n.kek),r=new URL(n.baseUrl);r.searchParams.set("state",t);let i=r.toString(),s=n.onAuthMissing?n.onAuthMissing({plugin:e,connectUrl:i,state:t}):`[auth-missing:${e}] Authentication required. Direct the user to connect their account: ${i}`;return new Error(s)}function ge({endpoints:e,hooks:n,ctx:o,tree:t,pluginId:r,errorHandlers:i,currentPath:s=[],keyBuilder:a,permissionsConfig:d,endpointMeta:p,database:c,approvalConfig:l,tenantId:f,connectConfig:g}){for(let[u,h]of Object.entries(e)){let b=n?.[u];if(fn(h)){let k=b,w=[...s,u].join("."),A=async(y={})=>{let m;if(d){let E=p?.[w],{result:U,reason:S,onComplete:J,token:F,id:K}=await Be({pluginId:r,endpointPath:w,args:y,mode:d.mode,override:d.overrides?.[w],riskLevel:E?.riskLevel??"write",meta:E,db:c,timeoutMs:l?Ke(l.timeout):void 0,tenantId:f,approvalMode:l?.mode});if(U==="blocked"){let x;throw S==="denied"?x=`Action '${w}' was denied by the user. Await further instructions before proceeding.`:S==="policy"?x=`Action '${w}' is blocked by the permission policy. Update the corsair config to allow it.`:S==="timeout"?x=`Action '${w}' timed out waiting for approval.`:l?.formatAsyncMessage&&F&&K?x=l.formatAsyncMessage({token:F,id:K,plugin:r,endpoint:w,args:y}):x=`Action '${w}' requires user approval before it can run.`,new Error(x)}m=J}let T=async(E,U,S)=>{try{return await h(U,S)}catch(J){if(J instanceof Error){let F=await Me(J,r,w,typeof S=="object"&&S!==null?S:{args:S},i);if(E<(F.maxRetries||0)){let K=E+1;console.log(`Retrying (${K} / ${F.maxRetries})...`);let x;if(F.headersRetryAfterMs)x=F.headersRetryAfterMs;else switch(F.retryStrategy){case"exponential_backoff":x=Math.pow(2,K-1)*1e3;break;case"exponential_backoff_jitter":let ce=Math.pow(2,K-1)*1e3,tn=(Math.random()-.5)*1e3;x=Math.max(0,ce+tn);break;case"linear_1s":x=1e3;break;case"linear_2s":x=2e3;break;case"linear_3s":x=3e3;break;case"linear_4s":x=4e3;break;default:x=1e3;break}await new Promise(ce=>setTimeout(ce,x)),await T(K,U,S),console.log(`[corsair:${r}:${w}] Retry strategy:`,F)}}throw J}},P;try{P=a?await a(o,"endpoint"):void 0}catch(E){throw g?.oauthConfig&&g.kek&&E instanceof N&&E.authType==="oauth_2"?yn(r,g,f):E}if(!k?.before&&!k?.after){let E=await T(0,{...o,key:P},y);return await m?.(),E}let I={...o,key:P},C=k.before?await k.before(I,y):{ctx:I,args:y,continue:!0,passToAfter:void 0};if(C.continue===!1)return;let O=await T(0,C.ctx,C.args);return await k.after?.(C.ctx,O,C.passToAfter),await m?.(),O};t[u]=A}else if(h&&typeof h=="object"){let k={};ge({endpoints:h,hooks:b,ctx:o,tree:k,pluginId:r,errorHandlers:i,currentPath:[...s,u],keyBuilder:a,permissionsConfig:d,endpointMeta:p,database:c,approvalConfig:l,tenantId:f,connectConfig:g}),t[u]=k}}}function hn(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function fe({webhooks:e,hooks:n,ctx:o,webhooksTree:t,keyBuilder:r}){for(let[i,s]of Object.entries(e)){let a=n?.[i];if(hn(s)){let d=a,p=async c=>{let l=(g,u)=>s.handler(g,u),f=r?await r(o,"webhook"):void 0;return!d?.before&&!d?.after?l({...o,key:f},c):(async()=>{let g={...o,key:f},u=d.before?await d.before(g,c):{ctx:g,args:c,continue:!0,passToAfter:void 0};if(u.continue===!1)return;let h=await l(u.ctx,u.args);return h?.success===!0&&await d.after?.(u.ctx,h,u.passToAfter),h})()};t[i]={match:s.match,handler:p}}else if(s&&typeof s=="object"){let d={};fe({webhooks:s,hooks:a,ctx:o,webhooksTree:d,keyBuilder:r}),t[i]=d}}}function mn(e,n,o){let t=null;return async()=>{if(t)return t;if(!e)throw new Error("Database not configured");let r=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!r)throw new Error(`Integration "${n}" not found. Make sure to create the integration first.`);let i=await e.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",o).where("integration_id","=",r.id).executeTakeFirst();if(!i)throw new Error(`Account not found for tenant "${o}" and integration "${n}". Make sure to create the account first.`);return t=i.id,t}}function kn(e,n,o,t,r){return e?de(e.db,n,o,t,r):{findByEntityId: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 ye(e,n){let{database:o,tenantId:t,kek:r,rootErrorHandlers:i,approvalConfig:s,connectConfig:a}=n,d={},p={};for(let c of e)d[c.id]={},p[c.id]={};for(let c of e){let l=c.schema,f=t??"default",g=mn(o,c.id,f);if(l?.entities){let C={};for(let[O,E]of Object.entries(l.entities)){let U=o?de(o.db,g,O,l.version,E):kn(void 0,g,O,l.version,E);C[O]=U}p[c.id].db=C,d[c.id].db=C}let u=c.options,h=c.authConfig,b;if(o&&r&&u?.authType){let C=h?.[u.authType]?.account??[];b=ie({authType:u.authType,integrationName:c.id,tenantId:f,kek:r,database:o,extraAccountFields:C}),d[c.id].keys=b}let k={database:o,db:p[c.id]?.db??{},$getAccountId:g,...c.options?{options:c.options}:{},...b?{keys:b,authType:u?.authType}:{},...t?{tenantId:t}:{}},w=c.endpoints??{},A=c.hooks,y={...i,...c.errorHandlers},m={},T=c.options?.permissions;ge({endpoints:w,hooks:A,ctx:k,tree:m,pluginId:c.id,errorHandlers:y,currentPath:[],keyBuilder:c.keyBuilder,permissionsConfig:T,endpointMeta:c.endpointMeta,database:o,approvalConfig:s,tenantId:t,connectConfig:a?{...a,oauthConfig:c.oauthConfig,kek:r,tenantId:f}:void 0}),Object.keys(m).length>0&&(d[c.id].api=m),k.endpoints=m;let P=c.webhooks??{},I=c.webhookHooks;if(Object.keys(P).length>0){let C={};fe({webhooks:P,hooks:I,ctx:k,webhooksTree:C,keyBuilder:c.keyBuilder}),d[c.id].webhooks=C,c.pluginWebhookMatcher&&(d[c.id].pluginWebhookMatcher=c.pluginWebhookMatcher)}}return d}function je(e,n,o){let t={};for(let r of e){let i=r.options,s=r.authConfig;if(i?.authType){let a=s?.[i.authType]?.integration??[],d=q({authType:i.authType,integrationName:r.id,kek:o,database:n,extraIntegrationFields:a});t[r.id]=d}}return t}async function Le(e,n,o,t,r="pending"){if(!e)return null;try{let i=Pe(),s=new Date;return await e.db.insertInto("corsair_events").values({id:i,created_at:s,updated_at:s,account_id:n,event_type:o,payload:t,status:r}).execute(),i}catch(i){return console.warn("Failed to log event:",i),null}}async function bn(e,n,o,t="pending"){try{let r=await e.$getAccountId();return Le(e.database,r,n,o,t)}catch(r){return console.warn("Failed to log event:",r),null}}import*as We from"https";import*as Ue from"querystring";function He(e,n,o,t,r){let i=new URL(t.tokenUrl),s=t.tokenAuthMethod==="basic";return new Promise((a,d)=>{let p={code:e.trim(),redirect_uri:r,grant_type:"authorization_code"};s||(p.client_id=n,p.client_secret=o);let c=Ue.stringify(p),l={"Content-Type":"application/x-www-form-urlencoded","Content-Length":Buffer.byteLength(c).toString()};s&&(l.Authorization=`Basic ${Buffer.from(`${n}:${o}`).toString("base64")}`);let f=We.request({hostname:i.hostname,...i.port?{port:Number(i.port)}:{},path:i.pathname+i.search,method:"POST",headers:l},g=>{let u="";g.on("data",h=>{u+=h}),g.on("end",()=>{if(g.statusCode!==200){d(new Error(`Token exchange failed (${g.statusCode}): ${u}`));return}try{a(JSON.parse(u))}catch{d(new Error(`Token endpoint returned non-JSON response: ${u}`))}})});f.on("error",g=>d(new Error(`Request failed: ${g.message}`))),f.write(c),f.end()})}import*as qe from"querystring";function wn(e){let n=e[ee];if(!n)throw new Error("Invalid corsair instance");return n}function Cn(e,n){let o=e.plugins.find(t=>t.id===n);if(!o)throw new Error(`Plugin '${n}' not found`);return o}function Tn(e){let n=e.oauthConfig;if(!n)throw new Error(`Plugin '${e.id}' has no oauthConfig`);return n}async function An(e,n){let o=wn(e);if(!o.database)throw new Error("No database configured on corsair instance");let t=o.connect?.redirectUri;if(!t)throw new Error("No redirectUri configured. Set connect.redirectUri in createCorsair().");let r=$e(n,o.kek);if(!r)throw new Error("Invalid or tampered state parameter");let{plugin:i,tenantId:s}=r,a=Cn(o,i),d=Tn(a),c=await q({authType:"oauth_2",integrationName:i,kek:o.kek,database:o.database}).get_client_id();if(!c)throw new Error(`client_id not configured for '${i}'`);let l={...d.authParams,client_id:c,redirect_uri:t,response_type:"code",scope:d.scopes.join(" "),state:n},f=`${d.authUrl}?${qe.stringify(l)}`;return{plugin:i,tenantId:s,providerName:d.providerName,oauthUrl:f,state:n}}var ze=["airtable","amplitude","asana","bitwarden","bluesky","box","cal","calendly","cloudflare","cursor","discord","dodopayments","dropbox","exa","figma","firecrawl","fireflies","github","gitlab","gmail","googlecalendar","googledrive","googlesheets","grafana","hackernews","hubspot","intercom","jira","linear","monday","notion","onedrive","openweathermap","oura","outlook","pagerduty","posthog","razorpay","reddit","resend","sentry","sharepoint","slack","spotify","strava","stripe","tally","tavily","teams","telegram","todoist","trello","twitter","twitterapiio","typeform","vapi","xquik","youtube","zendesk","zoom"];var Ge=" ";function v(e){let n=e;return n._def??n.def??{}}function _(e){let n=e.typeName;if(n)return n;let o=e.type;if(o)return`Zod${o.split("_").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join("")}`}function D(e){return e.innerType??e.schema??e.out??e.in}function Ve(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 D(e)}}function Ye(e){let n=e.type;return e.element??(typeof n=="string"?void 0:n)}function ae(e,n){let o=n.shape??e.shape;return typeof o=="function"?o():o}function z(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 Qe(e,n){return e.description??n.description}function xn(e){let n=e;for(;n;){let o=v(n),t=Qe(n,o);if(t)return t;let r=_(o);if(we(r)||r==="ZodPipe"||r==="ZodEffects"||r==="ZodTransform"){n=Ve(o,r);continue}break}}function we(e){return e==="ZodOptional"||e==="ZodNullable"||e==="ZodDefault"||e==="ZodCatch"}function R(e){let n=v(e),o=_(n);switch(o){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??z(n)[0]??"unknown");case"ZodEnum":return z(n).map(t=>String(t)).join(" | ");case"ZodOptional":{let t=D(n);return t?R(t):"unknown"}case"ZodNullable":{let t=D(n);return`${t?R(t):"unknown"} | null`}case"ZodDefault":case"ZodCatch":{let t=D(n);return t?R(t):"unknown"}case"ZodArray":{let t=Ye(n);if(!t)return"unknown[]";let r=v(t),i=_(r)==="ZodUnion",s=R(t);return`${i?`(${s})`:s}[]`}case"ZodRecord":return"{}";case"ZodObject":{let t=ae(e,n),r=Object.entries(t);return r.length===0?"{}":`{ ${r.map(([s,a])=>{let d=_(v(a));return`${d==="ZodOptional"||d==="ZodNullable"?s+"?":s}: ${R(a)}`}).join(", ")} }`}case"ZodUnion":return z(n).map(t=>R(t)).join(" | ");case"ZodIntersection":return`${R(n.left)} & ${R(n.right)}`;case"ZodPipe":case"ZodTransform":case"ZodEffects":{let t=Ve(n,o);return t?R(t):"unknown"}default:return(o??"unknown").replace("Zod","").toLowerCase()}}function $(e){let n=v(e),o=_(n),t=Qe(e,n);switch(o){case"ZodString":return{kind:"string",optional:!1,description:t};case"ZodNumber":return{kind:"number",optional:!1,description:t};case"ZodBoolean":return{kind:"boolean",optional:!1,description:t};case"ZodLiteral":{let r=n.value??z(n)[0],i=typeof r=="string"||typeof r=="number"||typeof r=="boolean"?r:String(r??"");return{kind:"literal",optional:!1,description:t,value:i}}case"ZodEnum":{let r=z(n).map(i=>String(i));return{kind:"string",optional:!1,description:t,enum:r}}case"ZodOptional":{let r=D(n),i=r?$(r):{kind:"unknown",optional:!1};return{...i,optional:!0,description:t??i.description}}case"ZodNullable":{let r=D(n),i=r?$(r):{kind:"unknown",optional:!1};return{...i,optional:!0,description:t??i.description}}case"ZodDefault":case"ZodCatch":{let r=D(n);return r?{...$(r),description:t}:{kind:"unknown",optional:!1,description:t}}case"ZodArray":{let r=Ye(n);return{kind:"array",optional:!1,description:t,items:r?$(r):{kind:"unknown",optional:!1}}}case"ZodObject":{let r=ae(e,n),i={};for(let[s,a]of Object.entries(r))i[s]=$(a);return{kind:"object",optional:!1,description:t,fields:i}}case"ZodRecord":return{kind:"unknown",optional:!1,description:t};case"ZodUnion":{let r=z(n);for(let i of r){let s=v(i);if(_(s)==="ZodObject")return{...$(i),description:t}}return{kind:"unknown",optional:!1,description:t}}case"ZodIntersection":case"ZodPipe":case"ZodTransform":case"ZodEffects":{let r=D(n);return r?{...$(r),description:t}:{kind:"unknown",optional:!1,description:t}}default:return{kind:"unknown",optional:!1,description:t}}}function wt(e,n){let o=n.toLowerCase(),t=o.indexOf(".");if(t===-1)return null;let r=o.slice(0,t),i=o.slice(t+1),s=e.find(c=>c.id===r);if(!s)return null;let a=i;a.startsWith("api.")&&(a=a.slice(4));let d=Z(s.endpointMeta,a),p=Z(s.endpointSchemas,a);return!d&&!p?null:{input:p?.input?$(p.input):null,output:p?.output?$(p.output):null,description:d?.description}}var Ce=["equals","contains","startsWith","endsWith","in"],Pn=["equals","gt","gte","lt","lte","in"],En=["equals"],Rn=["equals","before","after","between"];function Xe(e){let n=v(e);switch(_(n)){case"ZodOptional":case"ZodNullable":case"ZodDefault":case"ZodCatch":{let t=D(n);return t?Xe(t):null}case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"date";default:return null}}function Te(e){let n=v(e),o=_(n);if(we(o)){let i=D(n);return i?Te(i):{}}if(o!=="ZodObject")return{};let t=ae(e,n),r={};for(let[i,s]of Object.entries(t)){let a=Xe(s);a==="string"?r[i]={type:"string",operators:Ce}:a==="number"?r[i]={type:"number",operators:Pn}:a==="boolean"?r[i]={type:"boolean",operators:En}:a==="date"&&(r[i]={type:"date",operators:Rn})}return r}function en(e,n){for(let[o,t]of Object.entries(e))if(o.toLowerCase()===n)return[o,t]}function me(e,n,o){for(let[t,r]of Object.entries(e)){let i=[...n,t];typeof r=="function"?o.push(i.join(".")):r!==null&&typeof r=="object"&&me(r,i,o)}}function ke(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function be(e,n,o){for(let[t,r]of Object.entries(e)){let i=[...n,t];ke(r)?o.push(i.join(".")):r!==null&&typeof r=="object"&&be(r,i,o)}}function Ae(e,n){if(n.length===0)return null;let[o,...t]=n,r=Object.entries(e).find(([a])=>a.toLowerCase()===o);if(!r)return null;let[i,s]=r;if(t.length===0)return ke(s)?[i]:null;if(s!==null&&typeof s=="object"&&!ke(s)){let a=Ae(s,t);if(a!==null)return[i,...a]}return null}function nn(e,n){let o=[];o.push(`${e}({`),o.push(" webhookHooks: {");for(let i=0;i<n.length;i++){let s=" ".repeat(i+2);o.push(`${s}${n[i]}: {`)}let t=" ".repeat(n.length+2),r=t+" ";o.push(`${t}before(ctx, args) {`),o.push(`${r}return { ctx, args };`),o.push(`${t}},`),o.push(`${t}after(ctx, response) {`),o.push(`${t}},`);for(let i=n.length-1;i>=0;i--){let s=" ".repeat(i+2);o.push(`${s}},`)}return o.push(" },"),o.push("})"),o.join(`
|
|
14
|
+
`)}var In=new Set(ze);function W(e,n){let o=n?.type??"api",t=n?.plugin;if(t!==void 0){let i=e.find(a=>a.id===t);if(!i)return In.has(t)?`This plugin (${t}) is not configured. Please add it to the Corsair instance to see its associated methods.`:W(e);if(o==="webhooks"){if(!i.webhooks)return[];let a=[];return be(i.webhooks,[],a),a.map(d=>`${i.id}.webhooks.${d}`)}if(o==="db"){let a=i.schema?.entities;return a?Object.keys(a).map(d=>`${i.id}.db.${d}.search`):[]}if(!i.endpoints)return[];let s=[];return me(i.endpoints,[],s),s.map(a=>`${i.id}.api.${a}`)}let r={};if(o==="webhooks")for(let i of e){if(!i.webhooks)continue;let s=[];be(i.webhooks,[],s),r[i.id]=s.map(a=>`${i.id}.webhooks.${a}`)}else if(o==="db")for(let i of e){let s=i.schema?.entities;s&&(r[i.id]=Object.keys(s).map(a=>`${i.id}.db.${a}.search`))}else for(let i of e){if(!i.endpoints)continue;let s=[];me(i.endpoints,[],s),r[i.id]=s.map(a=>`${i.id}.api.${a}`)}return r}function Z(e,n){if(e){for(let[o,t]of Object.entries(e))if(o.toLowerCase()===n)return t}}function Dn(e,n){let o=e.toLowerCase(),t=n.toLowerCase();if(!o.startsWith(`${t}.`)){let i=o.slice(n.length+1),s=i.startsWith(".")?i.slice(1):i;return s.startsWith("api.")&&(s=s.slice(4)),{shortPath:s,lookupKey:s}}let r=e.slice(n.length+1);return r.toLowerCase().startsWith("api.")&&(r=r.slice(4)),{shortPath:r,lookupKey:r.toLowerCase()}}function he(e,n){return typeof e=="string"?e:Array.isArray(e)?`${n}:
|
|
15
|
+
${e.join(", ")}`:`${n}:
|
|
16
|
+
`+Object.entries(e).map(([o,t])=>` ${o}: ${t.join(", ")}`).join(`
|
|
17
|
+
`)}function Ct(e,n){let o=n.toLowerCase(),t=o.indexOf(".");if(t!==-1){let r=o.slice(0,t),i=o.slice(t+1),s=e.find(a=>a.id===r);if(s){if(i.startsWith("db.")){let c=i.slice(3),l=c.lastIndexOf(".");if(l!==-1){let f=c.slice(0,l),g=c.slice(l+1),u=s.schema?.entities;if(g==="search"&&u){let h=en(u,f);if(h){let[b,k]=h,w=Te(k),A=[`Search ${r} ${b} stored in the local database.`,"Pass limit and offset as numbers for pagination.","","filters {",` entity_id: string [${Ce.join(", ")}]`];for(let[y,m]of Object.entries(w))A.push(` ${y}?: ${m.type} [${m.operators.join(", ")}]`);return A.push("}"),A.join(`
|
|
18
|
+
`)}}}return he(W(e,{type:"db"}),"Path not found. Available db operations")}if(i.startsWith("webhooks.")){let c=i.slice(9);if(s.webhooks){let l=Ae(s.webhooks,c.split("."));if(l!==null){let f=l.join("."),g=Z(s.webhookSchemas,f.toLowerCase()),u=g?.response?R(g.response):null,h=[];return g?.description&&h.push(g.description),g?.payload&&h.push(`payload ${se(G(g.payload))}`),u&&h.push(`response: ${u}`),h.push(`usage:
|
|
19
|
+
${nn(r,l)}`),h.join(`
|
|
20
|
+
|
|
21
|
+
`)}}return he(W(e,{type:"webhooks"}),"Path not found. Available webhooks")}let a=i;a.startsWith("api.")&&(a=a.slice(4));let d=Z(s.endpointMeta,a),p=Z(s.endpointSchemas,a);if(d||p){let c=[],l=[d?.riskLevel?`[${d.riskLevel}]`:"",d?.irreversible?"[irreversible]":""].filter(Boolean).join(" "),f=[d?.description,l].filter(Boolean).join(" ");return f&&c.push(f),p?.input&&c.push(`input ${se(G(p.input))}`),p?.output&&c.push(`output ${se(G(p.output))}`),c.join(`
|
|
22
|
+
|
|
23
|
+
`)}}}return he(W(e),"Path not found. Available operations")}function Je(e){let n=e;for(;;){let o=v(n),t=_(o);if(we(t)){let r=D(o);if(!r)return n;n=r;continue}return n}}function G(e){if(e===void 0)return{kind:"inline",type:"unknown"};let n=Je(e),o=v(n);if(_(o)==="ZodObject"){let r=ae(n,o),i=[];for(let[s,a]of Object.entries(r)){let d=v(a),p=_(d),c=p==="ZodOptional"||p==="ZodNullable",l=Je(a),f=xn(a);i.push({key:s,optional:c,type:R(l),...f!==void 0?{description:f}:{}})}return{kind:"object",fields:i}}return{kind:"inline",type:R(n)}}function se(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 o=Ge.repeat(n+1),t=Ge.repeat(n);return`{
|
|
24
|
+
${e.fields.map(i=>{let s=i.optional?`${i.key}?`:i.key,a=i.description?` // ${i.description}`:"";return`${o}${s}: ${i.type}${a}`}).join(`
|
|
25
|
+
`)}
|
|
26
|
+
${t}}`}return"unknown"}function vn(e,n){let o=W(e,{plugin:n,type:"api"});if(typeof o=="string")return{ok:!1,error:o};if(!Array.isArray(o))return{ok:!1,error:"list_operations did not return a path array \u2014 pass a configured plugin id."};let t=e.find(c=>c.id===n);if(!t)return{ok:!1,error:`Plugin "${n}" is not configured on this instance.`};let r=[];for(let c of o){let{shortPath:l,lookupKey:f}=Dn(c,n),g=Z(t.endpointMeta,f),u=Z(t.endpointSchemas,f);!g&&!u||r.push({path:c,shortPath:l,description:g?.description,riskLevel:g?.riskLevel,irreversible:g?.irreversible,input:G(u?.input),output:G(u?.output)})}r.sort((c,l)=>c.path.localeCompare(l.path));let i=[],s=W(e,{plugin:n,type:"webhooks"});if(Array.isArray(s)&&t.webhooks)for(let c of s){let f=c.toLowerCase().slice(n.length+1),g=f.startsWith(".")?f.slice(1):f;if(!g.startsWith("webhooks."))continue;let u=g.slice(9),h=Ae(t.webhooks,u.split("."));if(h===null)continue;let b=h.join("."),k=Z(t.webhookSchemas,b.toLowerCase()),w=k?.response?R(k.response):void 0;i.push({path:c,description:k?.description,payload:G(k?.payload),responseType:w,usageExample:nn(n,h)})}i.sort((c,l)=>c.path.localeCompare(l.path));let a=[],d=W(e,{plugin:n,type:"db"}),p=t.schema?.entities;if(Array.isArray(d)&&p)for(let c of d){let f=c.toLowerCase().slice(n.length+1),g=f.startsWith(".")?f.slice(1):f;if(!g.startsWith("db."))continue;let u=g.slice(3),h=u.lastIndexOf(".");if(h===-1)continue;let b=u.slice(0,h);if(u.slice(h+1)!=="search")continue;let w=en(p,b);if(!w)continue;let[A,y]=w,m=Te(y),T=Object.entries(m).map(([P,I])=>({field:P,type:I.type,operators:I.operators}));a.push({path:c,entityName:A,filters:[{field:"entity_id",type:"string",operators:Ce},...T]})}return a.sort((c,l)=>c.path.localeCompare(l.path)),{ok:!0,data:{pluginId:n,api:r,webhooks:i,db:a}}}var ee=Symbol.for("corsair:internal");function Rt(e){let n=e.database?xe(e.database):void 0,o=n&&e.kek?je(e.plugins,n,e.kek):re(!!n,!!e.kek),t={plugins:e.plugins,database:n,kek:e.kek,multiTenancy:!!e.multiTenancy,approval:e.approval,connect:e.connect},r=Ne(n);if(e.multiTenancy)return Object.assign({withTenant:s=>{if(!s)throw new Error("corsair.withTenant(tenantId): tenantId must be a non-empty string");let a=ye(e.plugins,{database:n,tenantId:s,kek:e.kek,rootErrorHandlers:e.errorHandlers,approvalConfig:e.approval,connectConfig:e.connect});return Object.assign(a,{[ee]:t})},keys:o,permissions:r},{[ee]:t});let i=ye(e.plugins,{database:n,tenantId:void 0,kek:e.kek,rootErrorHandlers:e.errorHandlers,approvalConfig:e.approval,connectConfig:e.connect});return Object.assign({},i,{keys:o,permissions:r,[ee]:t})}export{N as a,B as b,j as c,M as d,ue as e,le as f,H as g,L as h,Y as i,Q as j,q as k,ie as l,_e as m,Se as n,Oe as o,an as p,Fe as q,$e as r,Le as s,bn as t,He as u,An as v,ze as w,wt as x,W as y,Ct as z,se as A,vn as B,ee as C,Rt as D};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as h,b}from"./chunk-OZHME3EO.js";import{a as E,b as I,c as x,d as D}from"./chunk-3USHGH6P.js";var k={corsair_integrations:E,corsair_accounts:I,corsair_entities:x,corsair_events:D};function F(t){return k[t]}function _(t){if(typeof t=="string")try{return JSON.parse(t)}catch{return t}return t}function d(t){if(!t)throw new Error("Corsair database is not configured. Pass `database` to createCorsair(...) to enable ORM.")}function g(t){if(!t)return[];let n=[];for(let r in t){let e=r,i=t[e];if(i!==void 0)if(typeof i=="object"&&i!==null&&!Array.isArray(i)&&!(i instanceof Date)){let s=i;"in"in s&&Array.isArray(s.in)?n.push({field:e,operator:"in",value:s.in}):"like"in s&&typeof s.like=="string"&&n.push({field:e,operator:"like",value:s.like})}else n.push({field:e,value:i})}return n}function p(t,n){if(!n?.length)return t;let r=t;for(let e of n){let i=e.operator??"=";r=r.where(e.field,i,e.value)}return r}function S(t){return typeof t=="number"?t:typeof t=="bigint"?Number(t):Number.parseInt(String(t??0),10)}function T(t,n){let r=F(n),e=()=>(d(t),t),i=()=>e().db.selectFrom(n),s=()=>e().db.insertInto(n),u=()=>e().db.updateTable(n),c=()=>e().db.deleteFrom(n);function m(o){let a={};for(let[l,y]of Object.entries(o))a[l]=_(y);return r.parse(a)}function C(o){let a={};for(let[l,y]of Object.entries(o))a[l]=_(y);return r.parse(a)}return{findById:async o=>{d(t);let a=i().selectAll();a=p(a,[{field:"id",value:o}]);let l=await a.executeTakeFirst();return l?m(l):null},findOne:async o=>{d(t);let a=i().selectAll();a=p(a,g(o));let l=await a.executeTakeFirst();return l?m(l):null},findMany:async o=>{d(t);let a=i().selectAll();return a=p(a,g(o?.where)),typeof o?.limit=="number"&&(a=a.limit(o.limit)),typeof o?.offset=="number"&&(a=a.offset(o.offset)),(await a.execute()).map(y=>m(y))},create:async o=>{d(t);let a=new Date,l={id:o.id??h(),created_at:a,updated_at:a,...o},y=await s().values(l).returningAll().executeTakeFirst();return y?m(y):C(l)},update:async(o,a)=>{d(t);let l={...a,updated_at:new Date},y=u().set(l).returningAll();y=p(y,[{field:"id",value:o}]);let f=await y.executeTakeFirst();return f?m(f):null},updateMany:async(o,a)=>{d(t);let l={...a,updated_at:new Date},y=i().select("id");y=p(y,g(o));let f=await y.execute();for(let P of f){let w=u().set(l);w=p(w,[{field:"id",value:P.id}]),await w.execute()}return f.length},delete:async o=>{d(t);let a=c();a=p(a,[{field:"id",value:o}]);let l=await a.executeTakeFirst();return Number(l?.numDeletedRows??0)>0},deleteMany:async o=>{d(t);let a=c();a=p(a,g(o));let l=await a.executeTakeFirst();return Number(l?.numDeletedRows??0)},count:async o=>{d(t);let a=i().select(y=>y.fn.countAll().as("count"));a=p(a,g(o));let l=await a.executeTakeFirst();return S(l?.count)}}}function R(t){let n=T(t,"corsair_integrations");return{...n,findByName:r=>n.findOne({name:r}),upsertByName:async(r,e)=>{let i=await n.findOne({name:r});return i?await n.update(i.id,e):n.create({...e,name:r})}}}function O(t){let n=T(t,"corsair_accounts");return{...n,findByTenantAndIntegration:async(r,e)=>{d(t);let i=await t.db.selectFrom("corsair_integrations").selectAll().where("name","=",e).executeTakeFirst();return i?n.findOne({tenant_id:r,integration_id:i.id}):null},listByTenant:(r,e)=>n.findMany({where:{tenant_id:r},limit:e?.limit,offset:e?.offset}),upsertByTenantAndIntegration:async(r,e,i)=>{let s=await n.findOne({tenant_id:r,integration_id:e});return s?await n.update(s.id,i):n.create({...i,tenant_id:r,integration_id:e})}}}function v(t){let n=T(t,"corsair_entities");return{...n,findByEntityId:({accountId:r,entityType:e,entityId:i})=>n.findOne({account_id:r,entity_type:e,entity_id:i}),findManyByEntityIds:async({accountId:r,entityType:e,entityIds:i})=>i.length===0?[]:(d(t),await t.db.selectFrom("corsair_entities").selectAll().where("account_id","=",r).where("entity_type","=",e).where("entity_id","in",i).execute()),listByScope:({accountId:r,entityType:e,limit:i,offset:s})=>n.findMany({where:{account_id:r,entity_type:e},limit:i,offset:s}),searchByEntityId:async({accountId:r,entityType:e,query:i,limit:s,offset:u})=>{d(t);let c=t.db.selectFrom("corsair_entities").selectAll().where("account_id","=",r).where("entity_type","=",e).where("entity_id","like",`%${i}%`);return typeof s=="number"&&(c=c.limit(s)),typeof u=="number"&&(c=c.offset(u)),await c.execute()},upsertByEntityId:async({accountId:r,entityType:e,entityId:i,version:s,data:u})=>{let c=await n.findOne({account_id:r,entity_type:e,entity_id:i});return c?await n.update(c.id,{version:s,data:u}):n.create({account_id:r,entity_type:e,entity_id:i,version:s,data:u})},deleteByEntityId:async({accountId:r,entityType:e,entityId:i})=>{d(t);let s=await t.db.deleteFrom("corsair_entities").where("account_id","=",r).where("entity_type","=",e).where("entity_id","=",i).executeTakeFirst();return Number(s.numDeletedRows)>0}}}function N(t){let n=T(t,"corsair_events");return{...n,listByAccount:(r,e)=>n.findMany({where:{account_id:r},limit:e?.limit,offset:e?.offset}),listByStatus:(r,e)=>{let i={status:r};return e?.accountId&&(i.account_id=e.accountId),n.findMany({where:i,limit:e?.limit,offset:e?.offset})},listPending:r=>{let e={status:"pending"};return r?.accountId&&(e.account_id=r.accountId),n.findMany({where:e,limit:r?.limit??100})},updateStatus:(r,e)=>n.update(r,{status:e})}}function A(t){return{integrations:R(t),accounts:O(t),entities:v(t),events:N(t)}}function W(t,n,r,e,i){let s=null;async function u(){if(s!==null)return s;d(t);let c=await t.db.selectFrom("corsair_integrations").selectAll().where("name","=",n.integrationName).executeTakeFirst();if(!c)throw new Error(`Integration "${n.integrationName}" not found. Make sure to create the integration first.`);let m=await t.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",n.tenantId).where("integration_id","=",c.id).executeTakeFirst();if(!m)throw new Error(`Account not found for tenant "${n.tenantId}" and integration "${n.integrationName}". Make sure to create the account first.`);return s=m.id,s}return d(t),b(t.db,u,r,e,i)}function B(t){let{database:n,integrationName:r,schema:e,tenantId:i}=t,s=A(n),u={tenantId:i,integrationName:r},c=null;async function m(){if(c!==null)return c;d(n);let o=await n.db.selectFrom("corsair_integrations").selectAll().where("name","=",r).executeTakeFirst();if(!o)throw new Error(`Integration "${r}" not found. Make sure to create the integration first.`);let a=await n.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",i).where("integration_id","=",o.id).executeTakeFirst();if(!a)throw new Error(`Account not found for tenant "${i}" and integration "${r}". Make sure to create the account first.`);return c=a.id,c}let C={};for(let[o,a]of Object.entries(e.entities))C[o]=W(n,u,o,e.version,a);return{...C,$orm:s,$integrationName:r,$tenantId:i,$getAccountId:m}}function q(t,n){let r=A(t);return{$tenantId:n,$orm:r,listAccounts:e=>r.accounts.listByTenant(n,e),findAccountByIntegration:e=>r.accounts.findByTenantAndIntegration(n,e),listEntities:async e=>{d(t);let i=await t.db.selectFrom("corsair_accounts").select("id").where("tenant_id","=",n).execute();if(i.length===0)return[];let s=i.map(c=>c.id),u=t.db.selectFrom("corsair_entities").selectAll().where("account_id","in",s);return e?.entityType&&(u=u.where("entity_type","=",e.entityType)),typeof e?.limit=="number"&&(u=u.limit(e.limit)),typeof e?.offset=="number"&&(u=u.offset(e.offset)),await u.execute()},listEvents:async e=>{d(t);let i=await t.db.selectFrom("corsair_accounts").select("id").where("tenant_id","=",n).execute();if(i.length===0)return[];let s=i.map(c=>c.id),u=t.db.selectFrom("corsair_events").selectAll().where("account_id","in",s);return e?.status&&(u=u.where("status","=",e.status)),typeof e?.limit=="number"&&(u=u.limit(e.limit)),typeof e?.offset=="number"&&(u=u.offset(e.offset)),await u.execute()},forIntegration:e=>B({database:t,integrationName:e.integrationName,schema:e.schema,tenantId:n})}}function K(t,n){return{forTenant:r=>B({database:t,integrationName:n.integrationName,schema:n.schema,tenantId:r})}}export{k as a,A as b,B as c,q as d,K as e};
|
package/dist/core.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { O as OAuthConfig, A as AuthTypes, g as AccountKeyManagerFor, I as IntegrationKeyManagerFor } from './index-DLSRcm5o.js';
|
|
2
2
|
export { j as AccountFieldNames, p as AllProviders, o as BASE_AUTH_FIELDS, k as BaseAuthFieldConfig, l as BaseKeyManager, e as BaseProviders, M as BeforeHookResult, r as BindEndpoints, a6 as BindWebhooks, a4 as Bivariant, s as BoundEndpointFn, t as BoundEndpointTree, a7 as BoundWebhook, B as BoundWebhookTree, h as CORSAIR_INTERNAL, c as CorsairClient, u as CorsairContext, v as CorsairEndpoint, y as CorsairErrorHandler, N as CorsairIntegration, i as CorsairInternalConfig, Q as CorsairKeyBuilder, S as CorsairKeyBuilderBase, d as CorsairPermissionsNamespace, a as CorsairPlugin, T as CorsairPluginContext, C as CorsairSingleTenantClient, b as CorsairTenantWrapper, a8 as CorsairWebhook, a9 as CorsairWebhookHandler, aa as CorsairWebhookMatcher, U as EndpointHooks, V as EndpointMetaEntry, w as EndpointPathsOf, E as EndpointRiskLevel, x as EndpointTree, K as EnforcePermissionOptions, L as EnforcePermissionResult, z as ErrorContext, D as ErrorHandler, F as ErrorHandlerAndMatchFunction, G as ErrorMatcher, m as IntegrationFieldNames, X as KeyBuilderContext, n as OAuth2IntegrationCredentials, Y as PermissionMode, Z as PermissionPolicy, q as PickAuth, P as PluginAuthConfig, _ as PluginEndpointMeta, $ as PluginPermissionsConfig, R as RawWebhookRequest, a0 as RequiredPluginEndpointMeta, a1 as RequiredPluginEndpointSchemas, a2 as RequiredPluginWebhookSchemas, H as RetryStrategies, J as RetryStrategy, a5 as UnionToIntersection, a3 as WebhookHooks, ab as WebhookPathsOf, ac as WebhookRequest, W as WebhookResponse, ad as WebhookTree, f as createCorsair } from './index-DLSRcm5o.js';
|
|
3
3
|
import { CorsairDatabase } from './db.js';
|
|
4
|
-
export { A as AuthMissingError, D as DocSchemaFieldRow, a as DocSchemaShape, b as DocsApiEndpoint, c as DocsDbEntity, d as DocsDbFilterField, e as DocsWebhook, E as EndpointSchemaResult, I as IntrospectPluginForDocsResult, L as ListOperationsOptions, P as PluginDocsIntrospection, R as ResolveConnectLinkResult, f as formatDocSchemaShape, i as introspectPluginForDocs, r as resolveConnectLink } from './index-
|
|
4
|
+
export { A as AuthMissingError, D as DocSchemaFieldRow, a as DocSchemaShape, b as DocsApiEndpoint, c as DocsDbEntity, d as DocsDbFilterField, e as DocsWebhook, E as EndpointSchemaResult, I as IntrospectPluginForDocsResult, L as ListOperationsOptions, P as PluginDocsIntrospection, R as ResolveConnectLinkResult, f as formatDocSchemaShape, i as introspectPluginForDocs, r as resolveConnectLink } from './index-nV76ScYN.js';
|
|
5
5
|
import 'zod';
|
|
6
6
|
import './orm.js';
|
|
7
7
|
import 'kysely';
|
package/dist/core.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{A as s,B as t,C as u,D as v,a,b,c,d,e,f,g,h,i,j,k,l,m,n,s as o,t as p,u as q,v as r}from"./chunk-
|
|
1
|
+
import{A as s,B as t,C as u,D as v,a,b,c,d,e,f,g,h,i,j,k,l,m,n,s as o,t as p,u as q,v as r}from"./chunk-PCO6RKXN.js";import"./chunk-OZHME3EO.js";import"./chunk-FL4GOHVN.js";import"./chunk-QAIKSQAD.js";export{a as AuthMissingError,j as BASE_AUTH_FIELDS,u as CORSAIR_INTERNAL,l as createAccountKeyManager,v as createCorsair,k as createIntegrationKeyManager,h as decryptConfig,d as decryptDEK,f as decryptWithDEK,g as encryptConfig,c as encryptDEK,e as encryptWithDEK,q as exchangeCodeForTokens,s as formatDocSchemaShape,b as generateDEK,n as initializeAccountDEK,m as initializeIntegrationDEK,t as introspectPluginForDocs,o as logEvent,p as logEventFromContext,i as reEncryptConfig,r as resolveConnectLink};
|
package/dist/db.d.ts
CHANGED
|
@@ -97,8 +97,7 @@ type CorsairIntegrationInsert = {
|
|
|
97
97
|
created_at?: Date;
|
|
98
98
|
updated_at?: Date;
|
|
99
99
|
name: string;
|
|
100
|
-
|
|
101
|
-
config?: Record<string, unknown>;
|
|
100
|
+
config: Record<string, unknown>;
|
|
102
101
|
dek?: string;
|
|
103
102
|
};
|
|
104
103
|
type CorsairAccountInsert = {
|
|
@@ -107,8 +106,7 @@ type CorsairAccountInsert = {
|
|
|
107
106
|
updated_at?: Date;
|
|
108
107
|
tenant_id: string;
|
|
109
108
|
integration_id: string;
|
|
110
|
-
|
|
111
|
-
config?: Record<string, unknown>;
|
|
109
|
+
config: Record<string, unknown>;
|
|
112
110
|
dek?: string;
|
|
113
111
|
};
|
|
114
112
|
type CorsairEntityInsert = {
|
package/dist/db.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as g}from"./chunk-N2XRSSRL.js";import{a as b,b as c,c as d,d as e,e as f}from"./chunk-3USHGH6P.js";import{a}from"./chunk-
|
|
1
|
+
import{a as g}from"./chunk-N2XRSSRL.js";import{a as b,b as c,c as d,d as e,e as f}from"./chunk-3USHGH6P.js";import{a}from"./chunk-FL4GOHVN.js";import"./chunk-QAIKSQAD.js";export{c as CorsairAccountsSchema,d as CorsairEntitiesSchema,e as CorsairEventsSchema,b as CorsairIntegrationsSchema,f as CorsairPermissionsSchema,a as createCorsairDatabase,g as sql};
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { E as EndpointRiskLevel, a as CorsairPlugin } from './index-DLSRcm5o.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Error thrown when a plugin endpoint is called but the
|
|
5
|
-
*
|
|
4
|
+
* Error thrown when a plugin endpoint is called but the required auth credentials
|
|
5
|
+
* are missing. Corsair intercepts this error and, for OAuth auth types, returns a
|
|
6
6
|
* connect link the agent can present to the user.
|
|
7
7
|
*/
|
|
8
8
|
declare class AuthMissingError extends Error {
|
|
9
9
|
pluginId: string;
|
|
10
|
-
|
|
10
|
+
authType: string;
|
|
11
|
+
constructor(pluginId: string, authType: string, message?: string);
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
type ResolveConnectLinkResult = {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { C as CorsairSingleTenantClient, a as CorsairPlugin, b as CorsairTenantWrapper, c as CorsairClient, d as CorsairPermissionsNamespace, B as BoundWebhookTree, R as RawWebhookRequest, e as BaseProviders, W as WebhookResponse } from './index-DLSRcm5o.js';
|
|
2
2
|
export { f as createCorsair } from './index-DLSRcm5o.js';
|
|
3
|
-
import { F as FormFieldSchema, L as ListOperationsOptions } from './index-
|
|
4
|
-
export { A as AuthMissingError, R as ResolveConnectLinkResult, f as formatDocSchemaShape, r as resolveConnectLink } from './index-
|
|
3
|
+
import { F as FormFieldSchema, L as ListOperationsOptions } from './index-nV76ScYN.js';
|
|
4
|
+
export { A as AuthMissingError, R as ResolveConnectLinkResult, f as formatDocSchemaShape, r as resolveConnectLink } from './index-nV76ScYN.js';
|
|
5
5
|
export { SetupCorsairOptions, setupCorsair } from './setup.js';
|
|
6
6
|
import './db.js';
|
|
7
7
|
import 'kysely';
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{a as A}from"./chunk-
|
|
1
|
+
import{a as A}from"./chunk-6OUDU5GH.js";import{A as x,C,D as T,a as I,v as O,w as k,x as y,y as b,z as w}from"./chunk-PCO6RKXN.js";import"./chunk-UBM25HVI.js";import"./chunk-OZHME3EO.js";import"./chunk-3USHGH6P.js";import"./chunk-FL4GOHVN.js";import"./chunk-QAIKSQAD.js";function h(n){let r=n[C];if(!r)throw new Error("listOperations / getSchema: invalid corsair instance. Pass the value returned by createCorsair() or corsair.withTenant().");return r.plugins}function B(n,r){let o=b(h(n),r);return typeof o=="string"?o:Array.isArray(o)?o.join(`
|
|
2
2
|
`):Object.values(o).flat().join(`
|
|
3
3
|
`)}function E(n,r){return w(h(n),r)}function F(n,r){return y(h(n),r)}var $=Symbol.for("corsair:internal");function j(n,r){let o=n;for(let e of r){if(!o||typeof o!="object")return null;o=o[e]}return typeof o=="function"?o:null}function S(n){return n[$]?.database}async function _(n,r){let o=new Date().toISOString(),e=await n.permissions.find_by_token(r);if(!e)return console.error("executePermission: no permission found for token."),{error:"executePermission: no permission found for token."};if(e.status!=="approved")return console.error(`executePermission: permission '${e.id}' is '${e.status}', expected 'approved'.`),{endpoint:e.endpoint,plugin:e.plugin,result:null,error:`executePermission: permission '${e.id}' is '${e.status}', expected 'approved'.`};if(e.expires_at<o){let i=S(n);return i&&await i.db.updateTable("corsair_permissions").set({status:"expired",updated_at:new Date}).where("id","=",e.id).execute(),console.error(`executePermission: permission '${e.id}' has expired.`),{error:`executePermission: permission '${e.id}' has expired.`,endpoint:e.endpoint,plugin:e.plugin,result:null}}let t=e.tenant_id??"default",g=(n.withTenant?n.withTenant(t):n)[e.plugin];if(!g?.api)return console.error(`executePermission: plugin '${e.plugin}' not found or has no API on this corsair instance.`),{error:`executePermission: plugin '${e.plugin}' not found or has no API on this corsair instance.`,plugin:e.plugin,endpoint:e.endpoint,result:null};let c=j(g.api,e.endpoint.split("."));if(!c)return console.error(`executePermission: endpoint '${e.endpoint}' not found in plugin '${e.plugin}'.`),{endpoint:e.endpoint,plugin:e.plugin,result:null,error:`executePermission: endpoint '${e.endpoint}' not found in plugin '${e.plugin}'.`};await n.permissions.set_executing(e.id);try{let i=typeof e.args=="string"?JSON.parse(e.args):e.args,u=await c(i);return await n.permissions.set_completed(e.id),{plugin:e.plugin,endpoint:e.endpoint,result:u}}catch(i){let u=i instanceof Error?i.message:String(i),d=S(n);return d&&await d.db.updateTable("corsair_permissions").set({status:"failed",error:u,updated_at:new Date}).where("id","=",e.id).execute(),{plugin:e.plugin,endpoint:e.endpoint,result:null,error:u}}}function v(n){return n!==null&&typeof n=="object"&&"match"in n&&"handler"in n&&typeof n.match=="function"&&typeof n.handler=="function"}function R(n,r,o=[]){for(let[e,t]of Object.entries(n))if(v(t)){if(t.match(r))return{webhook:t,path:[...o,e]}}else if(t&&typeof t=="object"){let s=R(t,r,[...o,e]);if(s)return s}return null}function N(n){let r={};for(let[o,e]of Object.entries(n))r[o.toLowerCase()]=Array.isArray(e)?e[0]:e;return r}function L(n){let r=n["x-goog-resource-uri"],o=n["x-goog-channel-id"];if(!r||!o)return null;let e={resourceId:n["x-goog-resource-id"]||"",resourceState:n["x-goog-resource-state"]||"",resourceUri:r,channelId:o,channelExpiration:n["x-goog-channel-expiration"]||""};return r.includes("/drive/")&&(e.kind="drive#change"),{message:{data:Buffer.from(JSON.stringify(e)).toString("base64"),messageId:n["x-goog-message-number"]||""}}}async function D(n,r,o,e){let t=N(r),s=typeof o=="string"?JSON.parse(o):o;(!s||typeof s=="object"&&Object.keys(s).length===0)&&t["x-goog-resource-uri"]&&(s=L(t)||s);let c={headers:t,body:s},i=e?.tenantId||"default",u=n.withTenant?n.withTenant(i):n,d=k;for(let l of d){let p=u[l];if(!p||!p.webhooks||p.pluginWebhookMatcher&&!p.pluginWebhookMatcher(c))continue;let f=R(p.webhooks,c);if(!f)continue;let m=f.path.join("."),P={payload:s,headers:t,rawBody:typeof o=="string"?o:JSON.stringify(o)};try{let a=await f.webhook.handler(P),W=!!Object.keys(a.returnToSender||{})?.length;return{plugin:l,action:m,body:s,response:W?{...a?.returnToSender,success:!0}:{success:!0},...a.responseHeaders&&{responseHeaders:a.responseHeaders}}}catch(a){return console.error(`Error executing webhook handler for ${l}.${m}:`,a),{plugin:l,action:m,body:s,response:{success:!1,error:a instanceof Error?a.message:"Unknown error"}}}}return{plugin:null,action:null,body:null}}export{I as AuthMissingError,T as createCorsair,_ as executePermission,x as formatDocSchemaShape,E as getSchema,F as getStructuredSchema,B as listOperations,D as processWebhook,O as resolveConnectLink,A as setupCorsair};
|
package/dist/oauth.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as x,b as C,c as O,k as p,l as m,o as f,p as _,q as A,r as y,u as b}from"./chunk-
|
|
1
|
+
import{C as x,b as C,c as O,k as p,l as m,o as f,p as _,q as A,r as y,u as b}from"./chunk-PCO6RKXN.js";import{b as P}from"./chunk-UBM25HVI.js";import"./chunk-OZHME3EO.js";import"./chunk-3USHGH6P.js";import"./chunk-FL4GOHVN.js";import"./chunk-QAIKSQAD.js";import*as E from"querystring";function I(n){let e=n[x];if(!e)throw new Error("Invalid corsair instance");return e}function U(n,e){let o=n.plugins.find(a=>a.id===e);if(!o)throw new Error(`Plugin '${e}' not found`);return o}function N(n){let e=n.oauthConfig;if(!e)throw new Error(`Plugin '${n.id}' has no oauthConfig`);return e}async function R(n,e,o,a){let i=P(n),t=await i.integrations.findByName(e);if(!t)throw new Error(`Integration '${e}' not found. Run setupCorsair first.`);if(await i.accounts.findOne({tenant_id:o,integration_id:t.id}))return;let r=C(),s=await O(r,a);await i.accounts.create({tenant_id:o,integration_id:t.id,config:{},dek:s})}async function S(n,e,o){let{tenantId:a,redirectUri:i}=o,t=I(n);if(!t.database)throw new Error("No database configured on corsair instance");let u=U(t,e),r=N(u),d=await p({authType:"oauth_2",integrationName:e,kek:t.kek,database:t.database}).get_client_id();if(!d)throw new Error(`client_id not configured for '${e}'`);let g=A(f(e,a),t.kek),l={...r.authParams,client_id:d,redirect_uri:i,response_type:"code",scope:r.scopes.join(" "),state:g};return{url:`${r.authUrl}?${E.stringify(l)}`,state:g}}async function K(n,e){let{code:o,state:a,redirectUri:i}=e,t=I(n),u=y(a,t.kek);if(!u)throw new Error("Invalid or tampered state parameter");let{plugin:r,tenantId:s}=u;if(!t.database)throw new Error("No database configured on corsair instance");let d=U(t,r),g=N(d),l=p({authType:"oauth_2",integrationName:r,kek:t.kek,database:t.database}),k=await l.get_client_id(),w=await l.get_client_secret();if(!k||!w)throw new Error(`Credentials not configured for '${r}'`);await R(t.database,r,s,t.kek);let c=await b(o,k,w,g,i);if(!c.access_token)throw new Error(`No access_token returned from ${g.providerName}`);let h=m({authType:"oauth_2",integrationName:r,tenantId:s,kek:t.kek,database:t.database});return await h.set_access_token(c.access_token),c.refresh_token&&await h.set_refresh_token(c.refresh_token),c.expires_in&&await h.set_expires_at(String(Math.floor(Date.now()/1e3)+c.expires_in)),{plugin:r,tenantId:s}}export{_ as decodeOAuthState,f as encodeOAuthState,S as generateOAuthUrl,K as processOAuthCallback};
|
package/dist/orm.d.ts
CHANGED
|
@@ -15,11 +15,8 @@ type CorsairOrmTableName = keyof CorsairOrmDatabase;
|
|
|
15
15
|
/**
|
|
16
16
|
* Input type for creating a new row (without auto-generated fields).
|
|
17
17
|
*/
|
|
18
|
-
type CreateInput<T> = Omit<T, 'id' | 'created_at' | 'updated_at'
|
|
18
|
+
type CreateInput<T> = Omit<T, 'id' | 'created_at' | 'updated_at'> & {
|
|
19
19
|
id?: string;
|
|
20
|
-
config?: T extends {
|
|
21
|
-
config: infer C;
|
|
22
|
-
} ? C : never;
|
|
23
20
|
};
|
|
24
21
|
/**
|
|
25
22
|
* Input type for updating an existing row.
|
package/dist/orm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./chunk-N2XRSSRL.js";import{b as o,c as e,d as n,e as s}from"./chunk-
|
|
1
|
+
import"./chunk-N2XRSSRL.js";import{b as o,c as e,d as n,e as s}from"./chunk-UBM25HVI.js";import"./chunk-OZHME3EO.js";import{a as r,b as t,c as i,d as a}from"./chunk-3USHGH6P.js";import"./chunk-FL4GOHVN.js";import"./chunk-QAIKSQAD.js";export{t as CorsairAccountsSchema,i as CorsairEntitiesSchema,a as CorsairEventsSchema,r as CorsairIntegrationsSchema,o as createCorsairOrm,e as createPluginOrm,s as createPluginOrmFactory,n as createTenantScopedOrm};
|
package/dist/setup.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as o,b as r}from"./chunk-
|
|
1
|
+
import{a as o,b as r}from"./chunk-6OUDU5GH.js";import"./chunk-PCO6RKXN.js";import"./chunk-UBM25HVI.js";import"./chunk-OZHME3EO.js";import"./chunk-3USHGH6P.js";import"./chunk-FL4GOHVN.js";import"./chunk-QAIKSQAD.js";export{r as applySetupCredentials,o as setupCorsair};
|
package/package.json
CHANGED
package/dist/chunk-6KMLS5U6.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a}from"./chunk-QAIKSQAD.js";import{Kysely as n,PostgresDialect as b,SqliteDialect as C}from"kysely";import{PostgresJSDialect as D}from"kysely-postgres-js";function w(e){return typeof e.query=="function"&&typeof e.connect=="function"}function d(e){let t=e;return typeof t.prepare=="function"&&typeof t.exec=="function"&&typeof t.close=="function"&&!("query"in e)}function g(e){return typeof e=="function"&&typeof e.begin=="function"&&typeof e.end=="function"}function i(e,t){return typeof e=="function"?e.bind(t):e}function m(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&!Buffer.isBuffer(e)&&Object.getPrototypeOf(e)===Object.prototype&&Object.keys(e).length===0}function S(e){return e instanceof Date?e.toISOString():m(e)?"{}":e}function q(e){return new Proxy(e,{get(t,o,y){return o!=="reserve"?i(Reflect.get(t,o,y),t):async function(){let c=await t.reserve();return new Proxy(c,{get(r,s,f){return s!=="unsafe"?i(Reflect.get(r,s,f),r):function(u,l,p){return r.unsafe(u,l?.map(S),p)}}})}}})}function P(e){return typeof e.selectFrom=="function"}function I(e){if(P(e))return{db:e};if(d(e))return{db:new n({dialect:new C({database:e}),plugins:[new a]})};if(w(e))return{db:new n({dialect:new b({pool:e})})};if(g(e))return{db:new n({dialect:new D({postgres:q(e)})})};throw new Error("Unsupported database input. Expected a pg Pool, postgres.js Sql, better-sqlite3 Database, or a Kysely instance.")}export{I as a};
|
package/dist/chunk-AAWROBCK.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as b,b as h}from"./chunk-OZHME3EO.js";import{a as E,b as I,c as x,d as D}from"./chunk-3USHGH6P.js";var k={corsair_integrations:E,corsair_accounts:I,corsair_entities:x,corsair_events:D};function F(e){return k[e]}function _(e){if(typeof e=="string")try{return JSON.parse(e)}catch{return e}return e}function S(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&Object.getPrototypeOf(e)===Object.prototype&&Object.keys(e).length===0}function R(e){if(!("config"in e)||!S(e.config))return e;let{config:n,...r}=e;return r}function d(e){if(!e)throw new Error("Corsair database is not configured. Pass `database` to createCorsair(...) to enable ORM.")}function g(e){if(!e)return[];let n=[];for(let r in e){let t=r,i=e[t];if(i!==void 0)if(typeof i=="object"&&i!==null&&!Array.isArray(i)&&!(i instanceof Date)){let s=i;"in"in s&&Array.isArray(s.in)?n.push({field:t,operator:"in",value:s.in}):"like"in s&&typeof s.like=="string"&&n.push({field:t,operator:"like",value:s.like})}else n.push({field:t,value:i})}return n}function p(e,n){if(!n?.length)return e;let r=e;for(let t of n){let i=t.operator??"=";r=r.where(t.field,i,t.value)}return r}function O(e){return typeof e=="number"?e:typeof e=="bigint"?Number(e):Number.parseInt(String(e??0),10)}function T(e,n){let r=F(n),t=()=>(d(e),e),i=()=>t().db.selectFrom(n),s=()=>t().db.insertInto(n),u=()=>t().db.updateTable(n),c=()=>t().db.deleteFrom(n);function m(o){let a={};for(let[l,y]of Object.entries(o))a[l]=_(y);return r.parse(a)}function C(o){let a={};for(let[l,y]of Object.entries(o))a[l]=_(y);return r.parse(a)}return{findById:async o=>{d(e);let a=i().selectAll();a=p(a,[{field:"id",value:o}]);let l=await a.executeTakeFirst();return l?m(l):null},findOne:async o=>{d(e);let a=i().selectAll();a=p(a,g(o));let l=await a.executeTakeFirst();return l?m(l):null},findMany:async o=>{d(e);let a=i().selectAll();return a=p(a,g(o?.where)),typeof o?.limit=="number"&&(a=a.limit(o.limit)),typeof o?.offset=="number"&&(a=a.offset(o.offset)),(await a.execute()).map(y=>m(y))},create:async o=>{d(e);let a=new Date,l=R({id:o.id??b(),created_at:a,updated_at:a,...o}),y=await s().values(l).returningAll().executeTakeFirst();return y?m(y):C(l)},update:async(o,a)=>{d(e);let l={...a,updated_at:new Date},y=u().set(l).returningAll();y=p(y,[{field:"id",value:o}]);let f=await y.executeTakeFirst();return f?m(f):null},updateMany:async(o,a)=>{d(e);let l={...a,updated_at:new Date},y=i().select("id");y=p(y,g(o));let f=await y.execute();for(let B of f){let w=u().set(l);w=p(w,[{field:"id",value:B.id}]),await w.execute()}return f.length},delete:async o=>{d(e);let a=c();a=p(a,[{field:"id",value:o}]);let l=await a.executeTakeFirst();return Number(l?.numDeletedRows??0)>0},deleteMany:async o=>{d(e);let a=c();a=p(a,g(o));let l=await a.executeTakeFirst();return Number(l?.numDeletedRows??0)},count:async o=>{d(e);let a=i().select(y=>y.fn.countAll().as("count"));a=p(a,g(o));let l=await a.executeTakeFirst();return O(l?.count)}}}function N(e){let n=T(e,"corsair_integrations");return{...n,findByName:r=>n.findOne({name:r}),upsertByName:async(r,t)=>{let i=await n.findOne({name:r});return i?await n.update(i.id,t):n.create({...t,name:r})}}}function v(e){let n=T(e,"corsair_accounts");return{...n,findByTenantAndIntegration:async(r,t)=>{d(e);let i=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();return i?n.findOne({tenant_id:r,integration_id:i.id}):null},listByTenant:(r,t)=>n.findMany({where:{tenant_id:r},limit:t?.limit,offset:t?.offset}),upsertByTenantAndIntegration:async(r,t,i)=>{let s=await n.findOne({tenant_id:r,integration_id:t});return s?await n.update(s.id,i):n.create({...i,tenant_id:r,integration_id:t})}}}function W(e){let n=T(e,"corsair_entities");return{...n,findByEntityId:({accountId:r,entityType:t,entityId:i})=>n.findOne({account_id:r,entity_type:t,entity_id:i}),findManyByEntityIds:async({accountId:r,entityType:t,entityIds:i})=>i.length===0?[]:(d(e),await e.db.selectFrom("corsair_entities").selectAll().where("account_id","=",r).where("entity_type","=",t).where("entity_id","in",i).execute()),listByScope:({accountId:r,entityType:t,limit:i,offset:s})=>n.findMany({where:{account_id:r,entity_type:t},limit:i,offset:s}),searchByEntityId:async({accountId:r,entityType:t,query:i,limit:s,offset:u})=>{d(e);let c=e.db.selectFrom("corsair_entities").selectAll().where("account_id","=",r).where("entity_type","=",t).where("entity_id","like",`%${i}%`);return typeof s=="number"&&(c=c.limit(s)),typeof u=="number"&&(c=c.offset(u)),await c.execute()},upsertByEntityId:async({accountId:r,entityType:t,entityId:i,version:s,data:u})=>{let c=await n.findOne({account_id:r,entity_type:t,entity_id:i});return c?await n.update(c.id,{version:s,data:u}):n.create({account_id:r,entity_type:t,entity_id:i,version:s,data:u})},deleteByEntityId:async({accountId:r,entityType:t,entityId:i})=>{d(e);let s=await e.db.deleteFrom("corsair_entities").where("account_id","=",r).where("entity_type","=",t).where("entity_id","=",i).executeTakeFirst();return Number(s.numDeletedRows)>0}}}function M(e){let n=T(e,"corsair_events");return{...n,listByAccount:(r,t)=>n.findMany({where:{account_id:r},limit:t?.limit,offset:t?.offset}),listByStatus:(r,t)=>{let i={status:r};return t?.accountId&&(i.account_id=t.accountId),n.findMany({where:i,limit:t?.limit,offset:t?.offset})},listPending:r=>{let t={status:"pending"};return r?.accountId&&(t.account_id=r.accountId),n.findMany({where:t,limit:r?.limit??100})},updateStatus:(r,t)=>n.update(r,{status:t})}}function A(e){return{integrations:N(e),accounts:v(e),entities:W(e),events:M(e)}}function $(e,n,r,t,i){let s=null;async function u(){if(s!==null)return s;d(e);let c=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n.integrationName).executeTakeFirst();if(!c)throw new Error(`Integration "${n.integrationName}" not found. Make sure to create the integration first.`);let m=await e.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",n.tenantId).where("integration_id","=",c.id).executeTakeFirst();if(!m)throw new Error(`Account not found for tenant "${n.tenantId}" and integration "${n.integrationName}". Make sure to create the account first.`);return s=m.id,s}return d(e),h(e.db,u,r,t,i)}function P(e){let{database:n,integrationName:r,schema:t,tenantId:i}=e,s=A(n),u={tenantId:i,integrationName:r},c=null;async function m(){if(c!==null)return c;d(n);let o=await n.db.selectFrom("corsair_integrations").selectAll().where("name","=",r).executeTakeFirst();if(!o)throw new Error(`Integration "${r}" not found. Make sure to create the integration first.`);let a=await n.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",i).where("integration_id","=",o.id).executeTakeFirst();if(!a)throw new Error(`Account not found for tenant "${i}" and integration "${r}". Make sure to create the account first.`);return c=a.id,c}let C={};for(let[o,a]of Object.entries(t.entities))C[o]=$(n,u,o,t.version,a);return{...C,$orm:s,$integrationName:r,$tenantId:i,$getAccountId:m}}function Z(e,n){let r=A(e);return{$tenantId:n,$orm:r,listAccounts:t=>r.accounts.listByTenant(n,t),findAccountByIntegration:t=>r.accounts.findByTenantAndIntegration(n,t),listEntities:async t=>{d(e);let i=await e.db.selectFrom("corsair_accounts").select("id").where("tenant_id","=",n).execute();if(i.length===0)return[];let s=i.map(c=>c.id),u=e.db.selectFrom("corsair_entities").selectAll().where("account_id","in",s);return t?.entityType&&(u=u.where("entity_type","=",t.entityType)),typeof t?.limit=="number"&&(u=u.limit(t.limit)),typeof t?.offset=="number"&&(u=u.offset(t.offset)),await u.execute()},listEvents:async t=>{d(e);let i=await e.db.selectFrom("corsair_accounts").select("id").where("tenant_id","=",n).execute();if(i.length===0)return[];let s=i.map(c=>c.id),u=e.db.selectFrom("corsair_events").selectAll().where("account_id","in",s);return t?.status&&(u=u.where("status","=",t.status)),typeof t?.limit=="number"&&(u=u.limit(t.limit)),typeof t?.offset=="number"&&(u=u.offset(t.offset)),await u.execute()},forIntegration:t=>P({database:e,integrationName:t.integrationName,schema:t.schema,tenantId:n})}}function j(e,n){return{forTenant:r=>P({database:e,integrationName:n.integrationName,schema:n.schema,tenantId:r})}}export{k as a,A as b,P as c,Z as d,j as e};
|
package/dist/chunk-W6KENKHM.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import{a as Pe,b as de}from"./chunk-OZHME3EO.js";import{a as xe}from"./chunk-6KMLS5U6.js";var N=class extends Error{pluginId;constructor(n,r){super(r??`[auth-missing:${n}]`),Object.setPrototypeOf(this,new.target.prototype),this.name="AuthMissingError",this.pluginId=n}};import{createCipheriv as Ee,createDecipheriv as Re,randomBytes as ne,scrypt as on}from"crypto";import{promisify as sn}from"util";var Ie=sn(on),te="aes-256-gcm",De=12,re=16,an=16,V=32;function B(){return ne(V).toString("base64")}async function j(e,n){let r=ne(an),t=await Ie(n,r,V),o=ne(De),i=Ee(te,t,o,{authTagLength:re}),s=Buffer.concat([i.update(e,"utf8"),i.final()]),a=i.getAuthTag();return[r.toString("base64"),o.toString("base64"),a.toString("base64"),s.toString("base64")].join(":")}async function M(e,n){let[r,t,o,i]=e.split(":");if(!r||!t||!o||!i)throw new Error("Invalid encrypted DEK format");let s=Buffer.from(r,"base64"),a=Buffer.from(t,"base64"),d=Buffer.from(o,"base64"),p=Buffer.from(i,"base64"),c=await Ie(n,s,V),l=Re(te,c,a,{authTagLength:re});return l.setAuthTag(d),Buffer.concat([l.update(p),l.final()]).toString("utf8")}function ue(e,n){let r=Buffer.from(n,"base64"),t=ne(De),o=Ee(te,r,t,{authTagLength:re}),i=Buffer.concat([o.update(e,"utf8"),o.final()]),s=o.getAuthTag();return[t.toString("base64"),s.toString("base64"),i.toString("base64")].join(":")}function le(e,n){let[r,t,o]=e.split(":");if(!r||!t||!o)throw new Error("Invalid encrypted data format");let i=Buffer.from(n,"base64"),s=Buffer.from(r,"base64"),a=Buffer.from(t,"base64"),d=Buffer.from(o,"base64"),p=Re(te,i,s,{authTagLength:re});return p.setAuthTag(a),Buffer.concat([p.update(d),p.final()]).toString("utf8")}function H(e,n){let r={};for(let[t,o]of Object.entries(e))r[t]=ue(o,n);return r}function L(e,n){let r={};for(let[t,o]of Object.entries(e))r[t]=le(o,n);return r}function Y(e,n,r){let t=L(e,n);return H(t,r)}function oe(e,n){let r=[];e||r.push("database"),n||r.push("kek");let t={};return new Proxy(t,{get(o,i){let s=r.length>1;throw new Error(`corsair.keys.${String(i)}: Cannot access keys because ${r.join(" and ")} ${s?"are":"is"} not configured. Provide both 'database' and 'kek' in createCorsair() to enable key management.
|
|
2
|
-
|
|
3
|
-
To generate a KEK, run: openssl rand -base64 ${V}`)}})}var Q={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"]}};function ve(e,n,r){let t={};for(let o of r)t[`get_${o}`]=async()=>(await e())[o]??null,t[`set_${o}`]=async i=>{let s=[null,void 0,""].includes(i)?null:i;await n({[o]:s})};return t}var pe=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};function q(e){let{authType:n,integrationName:r,kek:t,database:o,extraIntegrationFields:i=[]}=e,s=[...Q[n].integration,...i],a=null,d={kek:t,integrationName:r,getIntegration:async()=>{if(a)return a;let u=await o.db.selectFrom("corsair_integrations").selectAll().where("name","=",r).executeTakeFirst();if(!u)throw new Error(`Integration "${r}" not found. Make sure to create the integration first.`);return a={id:u.id,config:pe(u.config),dek:u.dek??null},a},updateIntegration:async u=>{let h=await d.getIntegration();await o.db.updateTable("corsair_integrations").set({...u.config!==void 0?{config:u.config}:{},...u.dek!==void 0?{dek:u.dek}:{},updated_at:new Date}).where("id","=",h.id).execute(),a=null}},p=null,c=async()=>{if(p)return p;let u=await d.getIntegration();if(!u.dek)throw new Error(`No DEK found for integration "${r}". Initialize the integration first.`);return p=await M(u.dek,t),p},l=async()=>{let u=await d.getIntegration(),h=await c(),b=u.config;return!b||Object.keys(b).length===0?{}:L(b,h)};return{get_dek:c,issue_new_dek:async()=>{let u=await d.getIntegration(),h=B(),b={};if(u.dek){let w=await M(u.dek,t),A=u.config;A&&Object.keys(A).length>0&&(b=Y(A,w,h))}let k=await j(h,t);return await d.updateIntegration({config:b,dek:k}),p=h,h},...ve(l,async u=>{let h=await c(),b;try{b=await l()}catch(A){console.error(`[corsair] Failed to decrypt config for integration "${r}", starting fresh:`,A),b={}}let k={...b};for(let[A,y]of Object.entries(u))y===null?delete k[A]:k[A]=y;let w=H(k,h);await d.updateIntegration({config:w})},s)}}function ie(e){let{authType:n,integrationName:r,tenantId:t,kek:o,database:i,extraAccountFields:s=[]}=e,a=[...Q[n].account,...s],d=null,p=null,c=async()=>{if(p)return p;let y=await i.db.selectFrom("corsair_integrations").selectAll().where("name","=",r).executeTakeFirst();if(!y)throw new Error(`Integration "${r}" not found. Make sure to create the integration first.`);return p={id:y.id,config:pe(y.config),dek:y.dek??null},p},l={kek:o,integrationName:r,tenantId:t,getIntegration:c,getAccount:async()=>{if(d)return d;let y=await c(),m=await i.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",y.id).executeTakeFirst();if(!m)throw new Error(`Account not found for tenant "${t}" and integration "${r}". Make sure to create the account first.`);return d={id:m.id,config:pe(m.config),dek:m.dek??null},d},updateAccount:async y=>{let m=await l.getAccount();await i.db.updateTable("corsair_accounts").set({...y.config!==void 0?{config:y.config}:{},...y.dek!==void 0?{dek:y.dek}:{},updated_at:new Date}).where("id","=",m.id).execute(),d=null}},f=null,g=null,u=async()=>{if(f)return f;let y=await l.getAccount();if(!y.dek)throw new Error(`No DEK found for account (tenant: "${t}", integration: "${r}"). Initialize the account first.`);return f=await M(y.dek,o),f},h=async()=>{if(g)return g;let y=await l.getIntegration();if(!y.dek)throw new Error(`No DEK found for integration "${r}". Initialize the integration first.`);return g=await M(y.dek,o),g},b=async()=>{let y=await l.getAccount(),m=await u(),T=y.config;return!T||Object.keys(T).length===0?{}:L(T,m)},k=async()=>{let y=await l.getIntegration(),m=await h(),T=y.config;return!T||Object.keys(T).length===0?{}:L(T,m)},A={get_dek:u,issue_new_dek:async()=>{let y=await l.getAccount(),m=B(),T={};if(y.dek){let I=await M(y.dek,o),C=y.config;C&&Object.keys(C).length>0&&(T=Y(C,I,m))}let P=await j(m,o);return await l.updateAccount({config:T,dek:P}),f=m,m},...ve(b,async y=>{let m=await u(),T;try{T=await b()}catch(C){console.error(`[corsair] Failed to decrypt config for account (tenant: "${t}", integration: "${r}"), starting fresh:`,C),T={}}let P={...T};for(let[C,O]of Object.entries(y))O===null?delete P[C]:P[C]=O;let I=H(P,m);await l.updateAccount({config:I})},a)};return n==="oauth_2"&&(A.get_integration_credentials=async()=>{let y=await k();return{client_id:y.client_id||null,client_secret:y.client_secret||null,redirect_url:y.redirect_url??null}}),A}async function _e(e,n,r){let t=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!t)throw new Error(`Integration "${n}" not found.`);let o=B(),i=await j(o,r);return await e.db.updateTable("corsair_integrations").set({dek:i,updated_at:new Date}).where("id","=",t.id).execute(),o}async function Se(e,n,r,t){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","=",r).where("integration_id","=",o.id).executeTakeFirst();if(!i)throw new Error(`Account not found for tenant "${r}" and integration "${n}".`);let s=B(),a=await j(s,t);return await e.db.updateTable("corsair_accounts").set({dek:a,updated_at:new Date}).where("id","=",i.id).execute(),s}import*as X from"crypto";function Oe(e,n){return Buffer.from(JSON.stringify({plugin:e,tenantId:n,iat:Date.now()})).toString("base64url")}function cn(e,{maxAgeMs:n}={}){try{let r=e.includes(".")?e.split(".")[0]:e,t=JSON.parse(Buffer.from(r,"base64url").toString("utf-8"));if(t!==null&&typeof t=="object"&&"plugin"in t&&"tenantId"in t&&typeof t.plugin=="string"&&typeof t.tenantId=="string"){let o=t;return n!==void 0&&typeof o.iat=="number"&&Date.now()-o.iat>n?null:o}return null}catch{return null}}function Fe(e,n){let r=X.createHmac("sha256",n).update(e).digest("base64url");return`${e}.${r}`}var dn=600*1e3;function $e(e,n){let r=e.lastIndexOf(".");if(r===-1)return null;let t=e.slice(0,r),o=e.slice(r+1),i=X.createHmac("sha256",n).update(t).digest("base64url"),s=Buffer.from(o,"base64url"),a=Buffer.from(i,"base64url");return s.length!==a.length||!X.timingSafeEqual(s,a)?null:cn(t,{maxAgeMs:dn})}var un=async(e,n)=>(console.error(`[corsair:${n.pluginId}:${n.operation}]`,{error:e.message,input:n.input}),{maxRetries:0});async function Me(e,n,r,t,o){let i={pluginId:n,operation:r,input:t,originalError:e},s=Object.keys(o).find(p=>o[p]?.match(e,i));return await(o[s||"DEFAULT"]?.handler||un)(e,i)}import{randomBytes as ln}from"crypto";import{v4 as pn}from"uuid";var gn={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 fn(e,n,r){return r!==void 0?r:gn[n][e]}function Ke(e){let n=/(\d+)(d|h|m|s)/g,r=0,t;for(;(t=n.exec(e))!==null;){let o=parseInt(t[1],10);switch(t[2]){case"d":r+=o*864e5;break;case"h":r+=o*36e5;break;case"m":r+=o*6e4;break;case"s":r+=o*1e3;break}}return r>0?r:600*1e3}function Ne(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 Ze(e,n,r){let t=Date.now()+r;for(;Date.now()<t;){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 Be(e){let n=fn(e.riskLevel,e.mode,e.override);if(n==="allow")return{result:"allow"};let r=e.meta?.irreversible?" (irreversible)":"",t=e.meta?.description?`${e.meta.description}${r}`:`${e.pluginId}.${e.endpointPath}${r}`;if(n==="deny"||!e.db)return console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 denied by permission mode '${e.mode}'.`,`
|
|
4
|
-
Action: ${t}`,`
|
|
5
|
-
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 u=e.db,h=a.id;return{result:"allow",onComplete:async()=>{await u.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.`,`
|
|
6
|
-
Action: ${t}`,`
|
|
7
|
-
Permission ID: ${a.id}`,`
|
|
8
|
-
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Ze(e.db,a.id,e.timeoutMs??600*1e3):{result:"blocked",reason:"pending",id:a.id,token:a.token})}let d=pn(),p=ln(32).toString("hex"),c=e.timeoutMs??600*1e3,l=new Date(Date.now()+c).toISOString();return await e.db.db.insertInto("corsair_permissions").values({id:d,created_at:new Date,updated_at:new Date,token:p,plugin:e.pluginId,endpoint:e.endpointPath,args:o,tenant_id:s,status:"pending",expires_at:l}).execute(),console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval required.`,`
|
|
9
|
-
Action: ${t}`,`
|
|
10
|
-
Permission ID: ${d}`,`
|
|
11
|
-
Permission token: ${p}`,`
|
|
12
|
-
Expires at: ${l}`,`
|
|
13
|
-
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Ze(e.db,d,c):{result:"blocked",reason:"pending",id:d,token:p}}function yn(e){return typeof e=="function"}function je(e,n,r){let t=Fe(Oe(e,n.tenantId??r??"default"),n.kek),o=new URL(n.baseUrl);o.searchParams.set("state",t);let i=o.toString(),s=n.onAuthMissing?n.onAuthMissing({plugin:e,connectUrl:i,state:t}):`[auth-missing:${e}] Authentication required. Direct the user to connect their account: ${i}`;return new Error(s)}function ge({endpoints:e,hooks:n,ctx:r,tree:t,pluginId:o,errorHandlers:i,currentPath:s=[],keyBuilder:a,permissionsConfig:d,endpointMeta:p,database:c,approvalConfig:l,tenantId:f,connectConfig:g}){for(let[u,h]of Object.entries(e)){let b=n?.[u];if(yn(h)){let k=b,w=[...s,u].join("."),A=async(y={})=>{let m;if(d){let E=p?.[w],{result:U,reason:S,onComplete:J,token:F,id:K}=await Be({pluginId:o,endpointPath:w,args:y,mode:d.mode,override:d.overrides?.[w],riskLevel:E?.riskLevel??"write",meta:E,db:c,timeoutMs:l?Ke(l.timeout):void 0,tenantId:f,approvalMode:l?.mode});if(U==="blocked"){let x;throw S==="denied"?x=`Action '${w}' was denied by the user. Await further instructions before proceeding.`:S==="policy"?x=`Action '${w}' is blocked by the permission policy. Update the corsair config to allow it.`:S==="timeout"?x=`Action '${w}' timed out waiting for approval.`:l?.formatAsyncMessage&&F&&K?x=l.formatAsyncMessage({token:F,id:K,plugin:o,endpoint:w,args:y}):x=`Action '${w}' requires user approval before it can run.`,new Error(x)}m=J}let T=async(E,U,S)=>{try{return await h(U,S)}catch(J){if(J instanceof Error){let F=await Me(J,o,w,typeof S=="object"&&S!==null?S:{args:S},i);if(E<(F.maxRetries||0)){let K=E+1;console.log(`Retrying (${K} / ${F.maxRetries})...`);let x;if(F.headersRetryAfterMs)x=F.headersRetryAfterMs;else switch(F.retryStrategy){case"exponential_backoff":x=Math.pow(2,K-1)*1e3;break;case"exponential_backoff_jitter":let ce=Math.pow(2,K-1)*1e3,rn=(Math.random()-.5)*1e3;x=Math.max(0,ce+rn);break;case"linear_1s":x=1e3;break;case"linear_2s":x=2e3;break;case"linear_3s":x=3e3;break;case"linear_4s":x=4e3;break;default:x=1e3;break}await new Promise(ce=>setTimeout(ce,x)),await T(K,U,S),console.log(`[corsair:${o}:${w}] Retry strategy:`,F)}}throw J}},P;try{P=a?await a(r,"endpoint"):void 0}catch(E){throw g?.oauthConfig&&g.kek&&E instanceof N?je(o,g,f):E}if(!P&&a&&g?.oauthConfig&&g.kek)throw je(o,g,f);if(!k?.before&&!k?.after){let E=await T(0,{...r,key:P},y);return await m?.(),E}let I={...r,key:P},C=k.before?await k.before(I,y):{ctx:I,args:y,continue:!0,passToAfter:void 0};if(C.continue===!1)return;let O=await T(0,C.ctx,C.args);return await k.after?.(C.ctx,O,C.passToAfter),await m?.(),O};t[u]=A}else if(h&&typeof h=="object"){let k={};ge({endpoints:h,hooks:b,ctx:r,tree:k,pluginId:o,errorHandlers:i,currentPath:[...s,u],keyBuilder:a,permissionsConfig:d,endpointMeta:p,database:c,approvalConfig:l,tenantId:f,connectConfig:g}),t[u]=k}}}function hn(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function fe({webhooks:e,hooks:n,ctx:r,webhooksTree:t,keyBuilder:o}){for(let[i,s]of Object.entries(e)){let a=n?.[i];if(hn(s)){let d=a,p=async c=>{let l=(g,u)=>s.handler(g,u),f=o?await o(r,"webhook"):void 0;return!d?.before&&!d?.after?l({...r,key:f},c):(async()=>{let g={...r,key:f},u=d.before?await d.before(g,c):{ctx:g,args:c,continue:!0,passToAfter:void 0};if(u.continue===!1)return;let h=await l(u.ctx,u.args);return h?.success===!0&&await d.after?.(u.ctx,h,u.passToAfter),h})()};t[i]={match:s.match,handler:p}}else if(s&&typeof s=="object"){let d={};fe({webhooks:s,hooks:a,ctx:r,webhooksTree:d,keyBuilder:o}),t[i]=d}}}function mn(e,n,r){let t=null;return async()=>{if(t)return t;if(!e)throw new Error("Database not configured");let o=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!o)throw new Error(`Integration "${n}" not found. Make sure to create the integration first.`);let i=await e.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",r).where("integration_id","=",o.id).executeTakeFirst();if(!i)throw new Error(`Account not found for tenant "${r}" and integration "${n}". Make sure to create the account first.`);return t=i.id,t}}function kn(e,n,r,t,o){return e?de(e.db,n,r,t,o):{findByEntityId: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 ye(e,n){let{database:r,tenantId:t,kek:o,rootErrorHandlers:i,approvalConfig:s,connectConfig:a}=n,d={},p={};for(let c of e)d[c.id]={},p[c.id]={};for(let c of e){let l=c.schema,f=t??"default",g=mn(r,c.id,f);if(l?.entities){let C={};for(let[O,E]of Object.entries(l.entities)){let U=r?de(r.db,g,O,l.version,E):kn(void 0,g,O,l.version,E);C[O]=U}p[c.id].db=C,d[c.id].db=C}let u=c.options,h=c.authConfig,b;if(r&&o&&u?.authType){let C=h?.[u.authType]?.account??[];b=ie({authType:u.authType,integrationName:c.id,tenantId:f,kek:o,database:r,extraAccountFields:C}),d[c.id].keys=b}let k={database:r,db:p[c.id]?.db??{},$getAccountId:g,...c.options?{options:c.options}:{},...b?{keys:b,authType:u?.authType}:{},...t?{tenantId:t}:{}},w=c.endpoints??{},A=c.hooks,y={...i,...c.errorHandlers},m={},T=c.options?.permissions;ge({endpoints:w,hooks:A,ctx:k,tree:m,pluginId:c.id,errorHandlers:y,currentPath:[],keyBuilder:c.keyBuilder,permissionsConfig:T,endpointMeta:c.endpointMeta,database:r,approvalConfig:s,tenantId:t,connectConfig:a?{...a,oauthConfig:c.oauthConfig,kek:o,tenantId:f}:void 0}),Object.keys(m).length>0&&(d[c.id].api=m),k.endpoints=m;let P=c.webhooks??{},I=c.webhookHooks;if(Object.keys(P).length>0){let C={};fe({webhooks:P,hooks:I,ctx:k,webhooksTree:C,keyBuilder:c.keyBuilder}),d[c.id].webhooks=C,c.pluginWebhookMatcher&&(d[c.id].pluginWebhookMatcher=c.pluginWebhookMatcher)}}return d}function Le(e,n,r){let t={};for(let o of e){let i=o.options,s=o.authConfig;if(i?.authType){let a=s?.[i.authType]?.integration??[],d=q({authType:i.authType,integrationName:o.id,kek:r,database:n,extraIntegrationFields:a});t[o.id]=d}}return t}async function We(e,n,r,t,o="pending"){if(!e)return null;try{let i=Pe(),s=new Date;return await e.db.insertInto("corsair_events").values({id:i,created_at:s,updated_at:s,account_id:n,event_type:r,payload:t,status:o}).execute(),i}catch(i){return console.warn("Failed to log event:",i),null}}async function bn(e,n,r,t="pending"){try{let o=await e.$getAccountId();return We(e.database,o,n,r,t)}catch(o){return console.warn("Failed to log event:",o),null}}import*as Ue from"https";import*as He from"querystring";function qe(e,n,r,t,o){let i=new URL(t.tokenUrl),s=t.tokenAuthMethod==="basic";return new Promise((a,d)=>{let p={code:e.trim(),redirect_uri:o,grant_type:"authorization_code"};s||(p.client_id=n,p.client_secret=r);let c=He.stringify(p),l={"Content-Type":"application/x-www-form-urlencoded","Content-Length":Buffer.byteLength(c).toString()};s&&(l.Authorization=`Basic ${Buffer.from(`${n}:${r}`).toString("base64")}`);let f=Ue.request({hostname:i.hostname,...i.port?{port:Number(i.port)}:{},path:i.pathname+i.search,method:"POST",headers:l},g=>{let u="";g.on("data",h=>{u+=h}),g.on("end",()=>{if(g.statusCode!==200){d(new Error(`Token exchange failed (${g.statusCode}): ${u}`));return}try{a(JSON.parse(u))}catch{d(new Error(`Token endpoint returned non-JSON response: ${u}`))}})});f.on("error",g=>d(new Error(`Request failed: ${g.message}`))),f.write(c),f.end()})}import*as ze from"querystring";function wn(e){let n=e[ee];if(!n)throw new Error("Invalid corsair instance");return n}function Cn(e,n){let r=e.plugins.find(t=>t.id===n);if(!r)throw new Error(`Plugin '${n}' not found`);return r}function Tn(e){let n=e.oauthConfig;if(!n)throw new Error(`Plugin '${e.id}' has no oauthConfig`);return n}async function An(e,n){let r=wn(e);if(!r.database)throw new Error("No database configured on corsair instance");let t=r.connect?.redirectUri;if(!t)throw new Error("No redirectUri configured. Set connect.redirectUri in createCorsair().");let o=$e(n,r.kek);if(!o)throw new Error("Invalid or tampered state parameter");let{plugin:i,tenantId:s}=o,a=Cn(r,i),d=Tn(a),c=await q({authType:"oauth_2",integrationName:i,kek:r.kek,database:r.database}).get_client_id();if(!c)throw new Error(`client_id not configured for '${i}'`);let l={...d.authParams,client_id:c,redirect_uri:t,response_type:"code",scope:d.scopes.join(" "),state:n},f=`${d.authUrl}?${ze.stringify(l)}`;return{plugin:i,tenantId:s,providerName:d.providerName,oauthUrl:f,state:n}}var Ge=["airtable","amplitude","asana","bitwarden","bluesky","box","cal","calendly","cloudflare","cursor","discord","dodopayments","dropbox","exa","figma","firecrawl","fireflies","github","gitlab","gmail","googlecalendar","googledrive","googlesheets","grafana","hackernews","hubspot","intercom","jira","linear","monday","notion","onedrive","openweathermap","oura","outlook","pagerduty","posthog","razorpay","reddit","resend","sentry","sharepoint","slack","spotify","strava","stripe","tally","tavily","teams","telegram","todoist","trello","twitter","twitterapiio","typeform","vapi","xquik","youtube","zendesk","zoom"];var Je=" ";function v(e){let n=e;return n._def??n.def??{}}function _(e){let n=e.typeName;if(n)return n;let r=e.type;if(r)return`Zod${r.split("_").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join("")}`}function D(e){return e.innerType??e.schema??e.out??e.in}function Ye(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 D(e)}}function Qe(e){let n=e.type;return e.element??(typeof n=="string"?void 0:n)}function ae(e,n){let r=n.shape??e.shape;return typeof r=="function"?r():r}function z(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 Xe(e,n){return e.description??n.description}function xn(e){let n=e;for(;n;){let r=v(n),t=Xe(n,r);if(t)return t;let o=_(r);if(we(o)||o==="ZodPipe"||o==="ZodEffects"||o==="ZodTransform"){n=Ye(r,o);continue}break}}function we(e){return e==="ZodOptional"||e==="ZodNullable"||e==="ZodDefault"||e==="ZodCatch"}function R(e){let n=v(e),r=_(n);switch(r){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??z(n)[0]??"unknown");case"ZodEnum":return z(n).map(t=>String(t)).join(" | ");case"ZodOptional":{let t=D(n);return t?R(t):"unknown"}case"ZodNullable":{let t=D(n);return`${t?R(t):"unknown"} | null`}case"ZodDefault":case"ZodCatch":{let t=D(n);return t?R(t):"unknown"}case"ZodArray":{let t=Qe(n);if(!t)return"unknown[]";let o=v(t),i=_(o)==="ZodUnion",s=R(t);return`${i?`(${s})`:s}[]`}case"ZodRecord":return"{}";case"ZodObject":{let t=ae(e,n),o=Object.entries(t);return o.length===0?"{}":`{ ${o.map(([s,a])=>{let d=_(v(a));return`${d==="ZodOptional"||d==="ZodNullable"?s+"?":s}: ${R(a)}`}).join(", ")} }`}case"ZodUnion":return z(n).map(t=>R(t)).join(" | ");case"ZodIntersection":return`${R(n.left)} & ${R(n.right)}`;case"ZodPipe":case"ZodTransform":case"ZodEffects":{let t=Ye(n,r);return t?R(t):"unknown"}default:return(r??"unknown").replace("Zod","").toLowerCase()}}function $(e){let n=v(e),r=_(n),t=Xe(e,n);switch(r){case"ZodString":return{kind:"string",optional:!1,description:t};case"ZodNumber":return{kind:"number",optional:!1,description:t};case"ZodBoolean":return{kind:"boolean",optional:!1,description:t};case"ZodLiteral":{let o=n.value??z(n)[0],i=typeof o=="string"||typeof o=="number"||typeof o=="boolean"?o:String(o??"");return{kind:"literal",optional:!1,description:t,value:i}}case"ZodEnum":{let o=z(n).map(i=>String(i));return{kind:"string",optional:!1,description:t,enum:o}}case"ZodOptional":{let o=D(n),i=o?$(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:t??i.description}}case"ZodNullable":{let o=D(n),i=o?$(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:t??i.description}}case"ZodDefault":case"ZodCatch":{let o=D(n);return o?{...$(o),description:t}:{kind:"unknown",optional:!1,description:t}}case"ZodArray":{let o=Qe(n);return{kind:"array",optional:!1,description:t,items:o?$(o):{kind:"unknown",optional:!1}}}case"ZodObject":{let o=ae(e,n),i={};for(let[s,a]of Object.entries(o))i[s]=$(a);return{kind:"object",optional:!1,description:t,fields:i}}case"ZodRecord":return{kind:"unknown",optional:!1,description:t};case"ZodUnion":{let o=z(n);for(let i of o){let s=v(i);if(_(s)==="ZodObject")return{...$(i),description:t}}return{kind:"unknown",optional:!1,description:t}}case"ZodIntersection":case"ZodPipe":case"ZodTransform":case"ZodEffects":{let o=D(n);return o?{...$(o),description:t}:{kind:"unknown",optional:!1,description:t}}default:return{kind:"unknown",optional:!1,description:t}}}function wt(e,n){let r=n.toLowerCase(),t=r.indexOf(".");if(t===-1)return null;let o=r.slice(0,t),i=r.slice(t+1),s=e.find(c=>c.id===o);if(!s)return null;let a=i;a.startsWith("api.")&&(a=a.slice(4));let d=Z(s.endpointMeta,a),p=Z(s.endpointSchemas,a);return!d&&!p?null:{input:p?.input?$(p.input):null,output:p?.output?$(p.output):null,description:d?.description}}var Ce=["equals","contains","startsWith","endsWith","in"],Pn=["equals","gt","gte","lt","lte","in"],En=["equals"],Rn=["equals","before","after","between"];function en(e){let n=v(e);switch(_(n)){case"ZodOptional":case"ZodNullable":case"ZodDefault":case"ZodCatch":{let t=D(n);return t?en(t):null}case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"date";default:return null}}function Te(e){let n=v(e),r=_(n);if(we(r)){let i=D(n);return i?Te(i):{}}if(r!=="ZodObject")return{};let t=ae(e,n),o={};for(let[i,s]of Object.entries(t)){let a=en(s);a==="string"?o[i]={type:"string",operators:Ce}:a==="number"?o[i]={type:"number",operators:Pn}:a==="boolean"?o[i]={type:"boolean",operators:En}:a==="date"&&(o[i]={type:"date",operators:Rn})}return o}function nn(e,n){for(let[r,t]of Object.entries(e))if(r.toLowerCase()===n)return[r,t]}function me(e,n,r){for(let[t,o]of Object.entries(e)){let i=[...n,t];typeof o=="function"?r.push(i.join(".")):o!==null&&typeof o=="object"&&me(o,i,r)}}function ke(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function be(e,n,r){for(let[t,o]of Object.entries(e)){let i=[...n,t];ke(o)?r.push(i.join(".")):o!==null&&typeof o=="object"&&be(o,i,r)}}function Ae(e,n){if(n.length===0)return null;let[r,...t]=n,o=Object.entries(e).find(([a])=>a.toLowerCase()===r);if(!o)return null;let[i,s]=o;if(t.length===0)return ke(s)?[i]:null;if(s!==null&&typeof s=="object"&&!ke(s)){let a=Ae(s,t);if(a!==null)return[i,...a]}return null}function tn(e,n){let r=[];r.push(`${e}({`),r.push(" webhookHooks: {");for(let i=0;i<n.length;i++){let s=" ".repeat(i+2);r.push(`${s}${n[i]}: {`)}let t=" ".repeat(n.length+2),o=t+" ";r.push(`${t}before(ctx, args) {`),r.push(`${o}return { ctx, args };`),r.push(`${t}},`),r.push(`${t}after(ctx, response) {`),r.push(`${t}},`);for(let i=n.length-1;i>=0;i--){let s=" ".repeat(i+2);r.push(`${s}},`)}return r.push(" },"),r.push("})"),r.join(`
|
|
14
|
-
`)}var In=new Set(Ge);function W(e,n){let r=n?.type??"api",t=n?.plugin;if(t!==void 0){let i=e.find(a=>a.id===t);if(!i)return In.has(t)?`This plugin (${t}) is not configured. Please add it to the Corsair instance to see its associated methods.`:W(e);if(r==="webhooks"){if(!i.webhooks)return[];let a=[];return be(i.webhooks,[],a),a.map(d=>`${i.id}.webhooks.${d}`)}if(r==="db"){let a=i.schema?.entities;return a?Object.keys(a).map(d=>`${i.id}.db.${d}.search`):[]}if(!i.endpoints)return[];let s=[];return me(i.endpoints,[],s),s.map(a=>`${i.id}.api.${a}`)}let o={};if(r==="webhooks")for(let i of e){if(!i.webhooks)continue;let s=[];be(i.webhooks,[],s),o[i.id]=s.map(a=>`${i.id}.webhooks.${a}`)}else if(r==="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=[];me(i.endpoints,[],s),o[i.id]=s.map(a=>`${i.id}.api.${a}`)}return o}function Z(e,n){if(e){for(let[r,t]of Object.entries(e))if(r.toLowerCase()===n)return t}}function Dn(e,n){let r=e.toLowerCase(),t=n.toLowerCase();if(!r.startsWith(`${t}.`)){let i=r.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 he(e,n){return typeof e=="string"?e:Array.isArray(e)?`${n}:
|
|
15
|
-
${e.join(", ")}`:`${n}:
|
|
16
|
-
`+Object.entries(e).map(([r,t])=>` ${r}: ${t.join(", ")}`).join(`
|
|
17
|
-
`)}function Ct(e,n){let r=n.toLowerCase(),t=r.indexOf(".");if(t!==-1){let o=r.slice(0,t),i=r.slice(t+1),s=e.find(a=>a.id===o);if(s){if(i.startsWith("db.")){let c=i.slice(3),l=c.lastIndexOf(".");if(l!==-1){let f=c.slice(0,l),g=c.slice(l+1),u=s.schema?.entities;if(g==="search"&&u){let h=nn(u,f);if(h){let[b,k]=h,w=Te(k),A=[`Search ${o} ${b} stored in the local database.`,"Pass limit and offset as numbers for pagination.","","filters {",` entity_id: string [${Ce.join(", ")}]`];for(let[y,m]of Object.entries(w))A.push(` ${y}?: ${m.type} [${m.operators.join(", ")}]`);return A.push("}"),A.join(`
|
|
18
|
-
`)}}}return he(W(e,{type:"db"}),"Path not found. Available db operations")}if(i.startsWith("webhooks.")){let c=i.slice(9);if(s.webhooks){let l=Ae(s.webhooks,c.split("."));if(l!==null){let f=l.join("."),g=Z(s.webhookSchemas,f.toLowerCase()),u=g?.response?R(g.response):null,h=[];return g?.description&&h.push(g.description),g?.payload&&h.push(`payload ${se(G(g.payload))}`),u&&h.push(`response: ${u}`),h.push(`usage:
|
|
19
|
-
${tn(o,l)}`),h.join(`
|
|
20
|
-
|
|
21
|
-
`)}}return he(W(e,{type:"webhooks"}),"Path not found. Available webhooks")}let a=i;a.startsWith("api.")&&(a=a.slice(4));let d=Z(s.endpointMeta,a),p=Z(s.endpointSchemas,a);if(d||p){let c=[],l=[d?.riskLevel?`[${d.riskLevel}]`:"",d?.irreversible?"[irreversible]":""].filter(Boolean).join(" "),f=[d?.description,l].filter(Boolean).join(" ");return f&&c.push(f),p?.input&&c.push(`input ${se(G(p.input))}`),p?.output&&c.push(`output ${se(G(p.output))}`),c.join(`
|
|
22
|
-
|
|
23
|
-
`)}}}return he(W(e),"Path not found. Available operations")}function Ve(e){let n=e;for(;;){let r=v(n),t=_(r);if(we(t)){let o=D(r);if(!o)return n;n=o;continue}return n}}function G(e){if(e===void 0)return{kind:"inline",type:"unknown"};let n=Ve(e),r=v(n);if(_(r)==="ZodObject"){let o=ae(n,r),i=[];for(let[s,a]of Object.entries(o)){let d=v(a),p=_(d),c=p==="ZodOptional"||p==="ZodNullable",l=Ve(a),f=xn(a);i.push({key:s,optional:c,type:R(l),...f!==void 0?{description:f}:{}})}return{kind:"object",fields:i}}return{kind:"inline",type:R(n)}}function se(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 r=Je.repeat(n+1),t=Je.repeat(n);return`{
|
|
24
|
-
${e.fields.map(i=>{let s=i.optional?`${i.key}?`:i.key,a=i.description?` // ${i.description}`:"";return`${r}${s}: ${i.type}${a}`}).join(`
|
|
25
|
-
`)}
|
|
26
|
-
${t}}`}return"unknown"}function vn(e,n){let r=W(e,{plugin:n,type:"api"});if(typeof r=="string")return{ok:!1,error:r};if(!Array.isArray(r))return{ok:!1,error:"list_operations did not return a path array \u2014 pass a configured plugin id."};let t=e.find(c=>c.id===n);if(!t)return{ok:!1,error:`Plugin "${n}" is not configured on this instance.`};let o=[];for(let c of r){let{shortPath:l,lookupKey:f}=Dn(c,n),g=Z(t.endpointMeta,f),u=Z(t.endpointSchemas,f);!g&&!u||o.push({path:c,shortPath:l,description:g?.description,riskLevel:g?.riskLevel,irreversible:g?.irreversible,input:G(u?.input),output:G(u?.output)})}o.sort((c,l)=>c.path.localeCompare(l.path));let i=[],s=W(e,{plugin:n,type:"webhooks"});if(Array.isArray(s)&&t.webhooks)for(let c of s){let f=c.toLowerCase().slice(n.length+1),g=f.startsWith(".")?f.slice(1):f;if(!g.startsWith("webhooks."))continue;let u=g.slice(9),h=Ae(t.webhooks,u.split("."));if(h===null)continue;let b=h.join("."),k=Z(t.webhookSchemas,b.toLowerCase()),w=k?.response?R(k.response):void 0;i.push({path:c,description:k?.description,payload:G(k?.payload),responseType:w,usageExample:tn(n,h)})}i.sort((c,l)=>c.path.localeCompare(l.path));let a=[],d=W(e,{plugin:n,type:"db"}),p=t.schema?.entities;if(Array.isArray(d)&&p)for(let c of d){let f=c.toLowerCase().slice(n.length+1),g=f.startsWith(".")?f.slice(1):f;if(!g.startsWith("db."))continue;let u=g.slice(3),h=u.lastIndexOf(".");if(h===-1)continue;let b=u.slice(0,h);if(u.slice(h+1)!=="search")continue;let w=nn(p,b);if(!w)continue;let[A,y]=w,m=Te(y),T=Object.entries(m).map(([P,I])=>({field:P,type:I.type,operators:I.operators}));a.push({path:c,entityName:A,filters:[{field:"entity_id",type:"string",operators:Ce},...T]})}return a.sort((c,l)=>c.path.localeCompare(l.path)),{ok:!0,data:{pluginId:n,api:o,webhooks:i,db:a}}}var ee=Symbol.for("corsair:internal");function Rt(e){let n=e.database?xe(e.database):void 0,r=n&&e.kek?Le(e.plugins,n,e.kek):oe(!!n,!!e.kek),t={plugins:e.plugins,database:n,kek:e.kek,multiTenancy:!!e.multiTenancy,approval:e.approval,connect:e.connect},o=Ne(n);if(e.multiTenancy)return Object.assign({withTenant:s=>{if(!s)throw new Error("corsair.withTenant(tenantId): tenantId must be a non-empty string");let a=ye(e.plugins,{database:n,tenantId:s,kek:e.kek,rootErrorHandlers:e.errorHandlers,approvalConfig:e.approval,connectConfig:e.connect});return Object.assign(a,{[ee]:t})},keys:r,permissions:o},{[ee]:t});let i=ye(e.plugins,{database:n,tenantId:void 0,kek:e.kek,rootErrorHandlers:e.errorHandlers,approvalConfig:e.approval,connectConfig:e.connect});return Object.assign({},i,{keys:r,permissions:o,[ee]:t})}export{N as a,B as b,j as c,M as d,ue as e,le as f,H as g,L as h,Y as i,Q as j,q as k,ie as l,_e as m,Se as n,Oe as o,cn as p,Fe as q,$e as r,We as s,bn as t,qe as u,An as v,Ge as w,wt as x,W as y,Ct as z,se as A,vn as B,ee as C,Rt as D};
|