@budibase/pro 3.17.4 → 3.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/package.json +3 -4
package/dist/index.js
CHANGED
|
@@ -35,7 +35,7 @@ d/o3ZWE1TTj1zYwlCLN5qRKr3hU8nC3xEYNEbkB9SfTRaOq9Q7P8WmfLkoCPm3pR
|
|
|
35
35
|
mwIDAQAB
|
|
36
36
|
-----END PUBLIC KEY-----
|
|
37
37
|
`;function Vr(e){return _o.default.verify(e,_S,{algorithms:["RS256"]})}function xS(e,t){return _o.default.sign(t,e,{encoding:"utf-8",algorithm:"RS256"})}var Ja={};w(Ja,{getFeatures:()=>xo});var c=require("@budibase/types");var CS={[c.PlanType.FREE]:[...Ae.SELF_FREE_LICENSE.features],[c.PlanType.PREMIUM]:void 0,[c.PlanType.PREMIUM_PLUS]:[c.Feature.APP_BACKUPS,c.Feature.BRANDING,c.Feature.SYNC_AUTOMATIONS,c.Feature.APP_BUILDERS,c.Feature.VIEW_PERMISSIONS,c.Feature.TRIGGER_AUTOMATION_RUN,c.Feature.VIEW_READONLY_COLUMNS,c.Feature.AI_CUSTOM_CONFIGS,c.Feature.PDF,c.Feature.BUDIBASE_AI],[c.PlanType.PREMIUM_PLUS_TRIAL]:[c.Feature.APP_BACKUPS,c.Feature.BRANDING,c.Feature.SYNC_AUTOMATIONS,c.Feature.APP_BUILDERS,c.Feature.VIEW_PERMISSIONS,c.Feature.TRIGGER_AUTOMATION_RUN,c.Feature.VIEW_READONLY_COLUMNS,c.Feature.AI_CUSTOM_CONFIGS,c.Feature.PDF,c.Feature.BUDIBASE_AI],[c.PlanType.PRO]:[c.Feature.USER_GROUPS,c.Feature.APP_BACKUPS],[c.PlanType.TEAM]:[c.Feature.USER_GROUPS,c.Feature.APP_BACKUPS],[c.PlanType.BUSINESS]:[c.Feature.USER_GROUPS,c.Feature.APP_BACKUPS,c.Feature.ENVIRONMENT_VARIABLES,c.Feature.AUDIT_LOGS,c.Feature.BRANDING,c.Feature.SYNC_AUTOMATIONS,c.Feature.APP_BUILDERS,c.Feature.EXPANDED_PUBLIC_API,c.Feature.VIEW_PERMISSIONS,c.Feature.PDF,c.Feature.BUDIBASE_AI],[c.PlanType.ENTERPRISE_BASIC]:[c.Feature.USER_GROUPS,c.Feature.APP_BACKUPS,c.Feature.ENVIRONMENT_VARIABLES,c.Feature.ENFORCEABLE_SSO,c.Feature.AUDIT_LOGS,c.Feature.BRANDING,c.Feature.SYNC_AUTOMATIONS,c.Feature.OFFLINE,c.Feature.APP_BUILDERS,c.Feature.EXPANDED_PUBLIC_API,c.Feature.VIEW_PERMISSIONS,c.Feature.TRIGGER_AUTOMATION_RUN,c.Feature.SCIM,c.Feature.VIEW_READONLY_COLUMNS,c.Feature.AI_CUSTOM_CONFIGS,c.Feature.PWA,c.Feature.CUSTOM_APP_SCRIPTS,c.Feature.PDF,c.Feature.BUDIBASE_AI,c.Feature.RECAPTCHA,c.Feature.PKCE_OIDC],[c.PlanType.ENTERPRISE_BASIC_TRIAL]:[c.Feature.USER_GROUPS,c.Feature.APP_BACKUPS,c.Feature.ENVIRONMENT_VARIABLES,c.Feature.ENFORCEABLE_SSO,c.Feature.BRANDING,c.Feature.SYNC_AUTOMATIONS,c.Feature.APP_BUILDERS,c.Feature.EXPANDED_PUBLIC_API,c.Feature.VIEW_PERMISSIONS,c.Feature.TRIGGER_AUTOMATION_RUN,c.Feature.SCIM,c.Feature.VIEW_READONLY_COLUMNS,c.Feature.AI_CUSTOM_CONFIGS,c.Feature.PWA,c.Feature.CUSTOM_APP_SCRIPTS,c.Feature.PDF,c.Feature.BUDIBASE_AI,c.Feature.RECAPTCHA,c.Feature.PKCE_OIDC],[c.PlanType.ENTERPRISE]:[c.Feature.USER_GROUPS,c.Feature.APP_BACKUPS,c.Feature.ENVIRONMENT_VARIABLES,c.Feature.ENFORCEABLE_SSO,c.Feature.AUDIT_LOGS,c.Feature.BRANDING,c.Feature.SYNC_AUTOMATIONS,c.Feature.OFFLINE,c.Feature.APP_BUILDERS,c.Feature.EXPANDED_PUBLIC_API,c.Feature.VIEW_PERMISSIONS,c.Feature.TRIGGER_AUTOMATION_RUN,c.Feature.SCIM,c.Feature.VIEW_READONLY_COLUMNS,c.Feature.AI_CUSTOM_CONFIGS,c.Feature.PWA,c.Feature.CUSTOM_APP_SCRIPTS,c.Feature.PDF,c.Feature.BUDIBASE_AI,c.Feature.RECAPTCHA,c.Feature.PKCE_OIDC]},OS={[c.PlanType.FREE]:[...Ae.CLOUD_FREE_LICENSE.features],[c.PlanType.PREMIUM]:[c.Feature.APP_BACKUPS,c.Feature.BRANDING,c.Feature.APP_BUILDERS,c.Feature.VIEW_PERMISSIONS,c.Feature.PDF],[c.PlanType.PREMIUM_PLUS]:[c.Feature.APP_BACKUPS,c.Feature.BRANDING,c.Feature.SYNC_AUTOMATIONS,c.Feature.APP_BUILDERS,c.Feature.VIEW_PERMISSIONS,c.Feature.TRIGGER_AUTOMATION_RUN,c.Feature.VIEW_READONLY_COLUMNS,c.Feature.BUDIBASE_AI,c.Feature.PDF],[c.PlanType.PREMIUM_PLUS_TRIAL]:[c.Feature.APP_BACKUPS,c.Feature.BRANDING,c.Feature.SYNC_AUTOMATIONS,c.Feature.APP_BUILDERS,c.Feature.VIEW_PERMISSIONS,c.Feature.TRIGGER_AUTOMATION_RUN,c.Feature.VIEW_READONLY_COLUMNS,c.Feature.BUDIBASE_AI,c.Feature.PDF],[c.PlanType.PRO]:[c.Feature.USER_GROUPS,c.Feature.APP_BACKUPS,c.Feature.BRANDING],[c.PlanType.TEAM]:[c.Feature.USER_GROUPS,c.Feature.APP_BACKUPS,c.Feature.BRANDING],[c.PlanType.BUSINESS]:[c.Feature.USER_GROUPS,c.Feature.APP_BACKUPS,c.Feature.ENVIRONMENT_VARIABLES,c.Feature.AUDIT_LOGS,c.Feature.BRANDING,c.Feature.SYNC_AUTOMATIONS,c.Feature.APP_BUILDERS,c.Feature.EXPANDED_PUBLIC_API,c.Feature.VIEW_PERMISSIONS,c.Feature.BUDIBASE_AI,c.Feature.PDF],[c.PlanType.ENTERPRISE_BASIC]:[c.Feature.USER_GROUPS,c.Feature.APP_BACKUPS,c.Feature.ENVIRONMENT_VARIABLES,c.Feature.ENFORCEABLE_SSO,c.Feature.AUDIT_LOGS,c.Feature.BRANDING,c.Feature.SYNC_AUTOMATIONS,c.Feature.OFFLINE,c.Feature.APP_BUILDERS,c.Feature.EXPANDED_PUBLIC_API,c.Feature.VIEW_PERMISSIONS,c.Feature.TRIGGER_AUTOMATION_RUN,c.Feature.SCIM,c.Feature.VIEW_READONLY_COLUMNS,c.Feature.AI_CUSTOM_CONFIGS,c.Feature.BUDIBASE_AI,c.Feature.PWA,c.Feature.CUSTOM_APP_SCRIPTS,c.Feature.PDF,c.Feature.RECAPTCHA,c.Feature.PKCE_OIDC],[c.PlanType.ENTERPRISE_BASIC_TRIAL]:[c.Feature.USER_GROUPS,c.Feature.APP_BACKUPS,c.Feature.ENVIRONMENT_VARIABLES,c.Feature.ENFORCEABLE_SSO,c.Feature.BRANDING,c.Feature.SYNC_AUTOMATIONS,c.Feature.APP_BUILDERS,c.Feature.EXPANDED_PUBLIC_API,c.Feature.VIEW_PERMISSIONS,c.Feature.TRIGGER_AUTOMATION_RUN,c.Feature.SCIM,c.Feature.VIEW_READONLY_COLUMNS,c.Feature.AI_CUSTOM_CONFIGS,c.Feature.BUDIBASE_AI,c.Feature.PWA,c.Feature.CUSTOM_APP_SCRIPTS,c.Feature.PDF,c.Feature.RECAPTCHA,c.Feature.PKCE_OIDC],[c.PlanType.ENTERPRISE]:[c.Feature.USER_GROUPS,c.Feature.APP_BACKUPS,c.Feature.ENVIRONMENT_VARIABLES,c.Feature.ENFORCEABLE_SSO,c.Feature.AUDIT_LOGS,c.Feature.BRANDING,c.Feature.SYNC_AUTOMATIONS,c.Feature.APP_BUILDERS,c.Feature.EXPANDED_PUBLIC_API,c.Feature.VIEW_PERMISSIONS,c.Feature.TRIGGER_AUTOMATION_RUN,c.Feature.SCIM,c.Feature.VIEW_READONLY_COLUMNS,c.Feature.AI_CUSTOM_CONFIGS,c.Feature.BUDIBASE_AI,c.Feature.PWA,c.Feature.CUSTOM_APP_SCRIPTS,c.Feature.PDF,c.Feature.RECAPTCHA,c.Feature.PKCE_OIDC]};function xo(e,t){let r=[];function a(n){let o=n[t];if(!o)throw new Error(`Features do not exist for planType=${t} and hosting=${e}`);return o}switch(e){case c.Hosting.SELF:r=a(CS);break;case c.Hosting.CLOUD:r=a(OS);break}return r}var Xa={};w(Xa,{UNLIMITED:()=>d,getQuotas:()=>Co});var k=require("@budibase/types");var l=et,Ep=Ae,d=-1,Hr=e=>e*1e6,LS={[k.PlanType.FREE]:{...Ep.CLOUD_FREE_LICENSE.quotas},[k.PlanType.PREMIUM]:{usage:{monthly:{...l.queries(d),...l.automations(1e3),...l.budibaseAICredits(0),...l.actions(d)},static:{...l.rows(1e4),...l.apps(d),...l.users(d),...l.creators(d),...l.userGroups(0),...l.plugins(d),...l.customAIConfigurations(0)}},constant:{...l.automationLogRetentionDays(7),...l.appBackupRetentionDays(7)}},[k.PlanType.PREMIUM_PLUS]:{usage:{monthly:{...l.queries(d),...l.automations(5e3),...l.budibaseAICredits(Hr(2)),...l.actions(d)},static:{...l.rows(25e3),...l.apps(d),...l.users(d),...l.creators(d),...l.userGroups(0),...l.plugins(d),...l.customAIConfigurations(1)}},constant:{...l.automationLogRetentionDays(30),...l.appBackupRetentionDays(30)}},[k.PlanType.PREMIUM_PLUS_TRIAL]:{usage:{monthly:{...l.queries(d),...l.automations(5e3),...l.budibaseAICredits(Hr(2)),...l.actions(d)},static:{...l.rows(25e3),...l.apps(d),...l.users(d),...l.creators(d),...l.userGroups(0),...l.plugins(d),...l.customAIConfigurations(1)}},constant:{...l.automationLogRetentionDays(30),...l.appBackupRetentionDays(30)}},[k.PlanType.PRO]:{usage:{monthly:{...l.queries(d),...l.automations(1e3),...l.budibaseAICredits(0),...l.actions(d)},static:{...l.rows(d),...l.apps(d),...l.users(d),...l.creators(d),...l.userGroups(5),...l.plugins(d),...l.customAIConfigurations(0)}},constant:{...l.automationLogRetentionDays(7),...l.appBackupRetentionDays(7)}},[k.PlanType.TEAM]:{usage:{monthly:{...l.queries(d),...l.automations(5e3),...l.budibaseAICredits(0),...l.actions(d)},static:{...l.rows(d),...l.apps(d),...l.users(d),...l.creators(d),...l.userGroups(10),...l.plugins(d),...l.customAIConfigurations(0)}},constant:{...l.automationLogRetentionDays(30),...l.appBackupRetentionDays(90)}},[k.PlanType.BUSINESS]:{usage:{monthly:{...l.queries(d),...l.automations(1e4),...l.budibaseAICredits(0),...l.actions(d)},static:{...l.rows(5e4),...l.apps(d),...l.users(d),...l.creators(d),...l.userGroups(50),...l.plugins(d),...l.customAIConfigurations(0)}},constant:{...l.automationLogRetentionDays(365),...l.appBackupRetentionDays(365)}},[k.PlanType.ENTERPRISE_BASIC]:{usage:{monthly:{...l.queries(d),...l.automations(d),...l.budibaseAICredits(Hr(4)),...l.actions(d)},static:{...l.rows(d),...l.apps(d),...l.users(d),...l.creators(d),...l.userGroups(d),...l.plugins(d),...l.customAIConfigurations(d)}},constant:{...l.automationLogRetentionDays(d),...l.appBackupRetentionDays(d)}},[k.PlanType.ENTERPRISE_BASIC_TRIAL]:{usage:{monthly:{...l.queries(d),...l.automations(d),...l.budibaseAICredits(Hr(4)),...l.actions(d)},static:{...l.rows(d),...l.apps(d),...l.users(d),...l.creators(d),...l.userGroups(d),...l.plugins(d),...l.customAIConfigurations(d)}},constant:{...l.automationLogRetentionDays(15),...l.appBackupRetentionDays(15)}},[k.PlanType.ENTERPRISE]:{usage:{monthly:{...l.queries(d),...l.automations(d),...l.budibaseAICredits(Hr(4)),...l.actions(d)},static:{...l.rows(d),...l.apps(d),...l.users(d),...l.creators(d),...l.userGroups(d),...l.plugins(d),...l.customAIConfigurations(d)}},constant:{...l.automationLogRetentionDays(d),...l.appBackupRetentionDays(d)}}},PS={[k.PlanType.FREE]:{...Ep.SELF_FREE_LICENSE.quotas},[k.PlanType.PREMIUM]:void 0,[k.PlanType.PREMIUM_PLUS]:{usage:{monthly:{...l.queries(d),...l.automations(d),...l.budibaseAICredits(0),...l.actions(d)},static:{...l.rows(d),...l.apps(d),...l.users(d),...l.creators(d),...l.userGroups(0),...l.plugins(d),...l.customAIConfigurations(1)}},constant:{...l.automationLogRetentionDays(30),...l.appBackupRetentionDays(30)}},[k.PlanType.PREMIUM_PLUS_TRIAL]:{usage:{monthly:{...l.queries(d),...l.automations(d),...l.budibaseAICredits(0),...l.actions(d)},static:{...l.rows(d),...l.apps(d),...l.users(d),...l.creators(d),...l.userGroups(0),...l.plugins(d),...l.customAIConfigurations(1)}},constant:{...l.automationLogRetentionDays(30),...l.appBackupRetentionDays(30)}},[k.PlanType.PRO]:{usage:{monthly:{...l.queries(d),...l.automations(d),...l.budibaseAICredits(0),...l.actions(d)},static:{...l.rows(d),...l.apps(d),...l.users(d),...l.creators(d),...l.userGroups(5),...l.plugins(d),...l.customAIConfigurations(0)}},constant:{...l.automationLogRetentionDays(7),...l.appBackupRetentionDays(7)}},[k.PlanType.TEAM]:{usage:{monthly:{...l.queries(d),...l.automations(d),...l.budibaseAICredits(0),...l.actions(d)},static:{...l.rows(d),...l.apps(d),...l.users(d),...l.creators(d),...l.userGroups(10),...l.plugins(d),...l.customAIConfigurations(0)}},constant:{...l.automationLogRetentionDays(30),...l.appBackupRetentionDays(90)}},[k.PlanType.BUSINESS]:{usage:{monthly:{...l.queries(d),...l.automations(d),...l.budibaseAICredits(0),...l.actions(d)},static:{...l.rows(d),...l.apps(d),...l.users(d),...l.creators(d),...l.userGroups(50),...l.plugins(d),...l.customAIConfigurations(0)}},constant:{...l.automationLogRetentionDays(90),...l.appBackupRetentionDays(365)}},[k.PlanType.ENTERPRISE_BASIC]:{usage:{monthly:{...l.queries(d),...l.automations(d),...l.budibaseAICredits(0),...l.actions(d)},static:{...l.rows(d),...l.apps(d),...l.users(d),...l.creators(d),...l.userGroups(d),...l.plugins(d),...l.customAIConfigurations(d)}},constant:{...l.automationLogRetentionDays(d),...l.appBackupRetentionDays(d)}},[k.PlanType.ENTERPRISE_BASIC_TRIAL]:{usage:{monthly:{...l.queries(d),...l.automations(d),...l.budibaseAICredits(0),...l.actions(d)},static:{...l.rows(d),...l.apps(d),...l.users(d),...l.creators(d),...l.userGroups(d),...l.plugins(d),...l.customAIConfigurations(d)}},constant:{...l.automationLogRetentionDays(15),...l.appBackupRetentionDays(15)}},[k.PlanType.ENTERPRISE]:{usage:{monthly:{...l.queries(d),...l.automations(d),...l.budibaseAICredits(0),...l.actions(d)},static:{...l.rows(d),...l.apps(d),...l.users(d),...l.creators(d),...l.userGroups(d),...l.plugins(d),...l.customAIConfigurations(d)}},constant:{...l.automationLogRetentionDays(d),...l.appBackupRetentionDays(d)}}};function Co(e,t){let r;function a(n){let o=n[t];if(!o)throw new Error(`Quotas do not exist for planType=${t} and hosting=${e}`);return o}switch(e){case k.Hosting.SELF:r=a(PS);break;case k.Hosting.CLOUD:r=a(LS);break}return JSON.parse(JSON.stringify(r))}var Yt={};w(Yt,{appExists:()=>US,encoding:()=>Vt});var Rp=require("@budibase/backend-core");async function US(e){return(await Rp.db.getAllApps({all:!0,idsOnly:!0})).includes(e)}var Vt={};w(Vt,{base64ToObject:()=>DS,objectToBase64:()=>qS});function qS(e){let t=JSON.stringify(e);return Buffer.from(t).toString("base64")}function DS(e){let t=Buffer.from(e,"base64").toString();return JSON.parse(t)}var pf=require("@budibase/types"),ir=require("@budibase/backend-core"),cf=P(Fl()),lf=P(as());async function cx(e){await ve.save({offlineLicenseToken:e}),await Ct()}async function lx(){await ve.save({offlineLicenseToken:void 0}),await Ct()}async function df(){return(await ve.get()).offlineLicenseToken}async function ns(){let t=(await ir.installation.getInstall()).installId,r=ir.context.getTenantId(),a=await ir.events.identification.getUniqueTenantId(r);return{installId:t,tenantId:a}}async function dx(){let e=await ns();return Vt.objectToBase64(e)}function fx(e){return Vt.base64ToObject(e)}function ff(e){let t=Date.now(),r=new Date(e.expireAt).getTime();if(t>r)throw new Error(`Offline license has expired. expireAt=${e.expireAt}`)}async function mf(e){let t=await ns();if(e.identifier.installId!==t.installId||e.identifier.tenantId!==t.tenantId)throw new Error("Invalid offline license")}function gf(e){let t=e.plan.type,r=pf.Hosting.SELF,a=xo(r,t),n=Co(r,t);return e.features=(0,cf.default)(e.features,a),e.quotas=(0,lf.default)(e.quotas,n),e}async function os(){try{let e=await df();if(e){let t=await Vr(e);return ff(t),await mf(t),gf(t)}}catch(e){console.error("Error retrieving offline license",e)}}var ma={};w(ma,{deleteDevLicense:()=>Ax,getOfflineLicense:()=>yx,writeDevLicenseToDisk:()=>hx});var yf=require("@budibase/backend-core"),is=require("path"),hf=require("os"),Ot=P(require("fs"));var mx=yf.env.isTest()?".budibase-test":".budibase",ss=(0,is.join)((0,hf.tmpdir)(),mx),gx="dev_license.txt",fa=(0,is.join)(ss,gx);if(!Ot.default.existsSync(ss))try{Ot.default.mkdirSync(ss)}catch{}function yx(){try{if(Ot.default.existsSync(fa)){let e=Ot.default.readFileSync(fa,{encoding:"utf-8"});return Vr(e)}}catch(e){console.error("Error retrieving offline license from disk",e)}}function hx(e){console.log(`Writing license to: ${fa}`),Ot.default.writeFileSync(fa,e,{encoding:"utf-8"})}function Ax(){Ot.default.rmSync(fa,{force:!0})}var Af=require("dd-trace"),ps=async()=>await Af.tracer.trace("getLicense",async e=>{if(us.env.OFFLINE_MODE)return e.addTags({offline:!0}),os();let t=await Kt();return t||(e.addTags({offlineFallback:!0}),t=ma.getOfflineLicense()),t}),cs=e=>Ro(e),ls=()=>us.env.SELF_HOSTED?Ae.SELF_FREE_LICENSE:Ae.CLOUD_FREE_LICENSE;var fs={};w(fs,{activateLicenseKey:()=>bx,deleteLicenseKey:()=>Ix,getLicenseKey:()=>gn});var ds=P(require("dd-trace"));async function bx(e){await vo(e),await ve.save({licenseKey:e}),await Ct()}async function gn(){return await ds.default.trace("getLicenseKey",async e=>{let t=await ve.get();return e.addTags({licenseKey:t.licenseKey}),t.licenseKey})}async function Ix(){return await ds.default.trace("deleteLicenseKey",async()=>{await ve.save({licenseKey:void 0}),await Ct()})}var Lt=require("@budibase/backend-core"),yn=P(require("dd-trace")),bf=3600,Ct=async()=>{await wf(),await Sf()},If=async(e,t)=>{let{populateLicense:r=ps,populateFreeLicense:a=ls}=t||{};return await yn.default.trace("getCachedLicense",async n=>{let o=Lt.context.getLicense();if(o)return n.addTags({foundInContext:!0,features:o.features,plan:o.plan,quotas:o.quotas}),o;let s=Lt.tenancy.getTenantId(),i=await po(),p=await i.get(s);return n.addTags({tenantId:s,foundInCache:!!p}),p?(n.addTags({foundInCache:!0,refreshedAt:p.refreshedAt,features:p.features,plan:p.plan,quotas:p.quotas}),p):(p=await yn.default.trace("populateLicense",async()=>await r(s)),n.addTags({populatedLicense:!!p}),p||(p=yn.default.trace("populateFreeLicense",()=>a(e,s)),n.addTags({populatedFreeLicense:!!p})),p.refreshedAt=new Date().toISOString(),n.addTags({refreshedAt:p.refreshedAt,features:p.features,plan:p.plan,quotas:p.quotas,expirySeconds:bf}),await i.store(s,p,bf),p)})};Lt.env.isJest()&&(If=jest.fn());var Sf=If,wf=async()=>{let e=Lt.tenancy.getTenantId();await(await po()).delete(e)};async function re(e,t){Array.isArray(e)||(e=[e]),t||(t=await Ne.getCachedLicense());for(let r of e)if(!t?.features.includes(r))return!1;return!0}async function hn(e,t){if(!await re(e,t))throw new tt.FeatureDisabledError(`${e} is not currently enabled`,e)}async function ms(e,t){if(!await re(e,t)){let r=e.join(", ");throw new tt.FeatureDisabledError(`${r} are not currently enabled`,r)}}function ce(e){return async(...t)=>(await hn(te.Feature.APP_BACKUPS),e(...t))}async function gs(){return re(te.Feature.APP_BACKUPS)}async function ys(){return re(te.Feature.BRANDING)}async function Tf(){return re(te.Feature.ENFORCEABLE_SSO)}async function wx(){return re(te.Feature.SYNC_AUTOMATIONS)}async function Tx(){return re(te.Feature.TRIGGER_AUTOMATION_RUN)}async function Pt(){return re(te.Feature.APP_BUILDERS)}async function An(){return re(te.Feature.AUDIT_LOGS)}async function hs(){return re(te.Feature.USER_GROUPS)}function Ex(){return re(te.Feature.PWA)}function Rx(){return re(te.Feature.RECAPTCHA)}var vx=()=>re(te.Feature.PKCE_OIDC);async function rt(){return re(te.Feature.EXPANDED_PUBLIC_API)}async function _x(e){if(tt.env.ENABLE_SSO_MAINTENANCE_MODE||!await Tf())return!1;let r;return e?.config?r=e.config:r=await tt.configs.getSettingsConfig(),!!r.isSSOEnforced}var As=async()=>{let e=te.Feature.SCIM,t=await re(e),r=await tt.configs.getSCIMConfig();if(!t||!r?.enabled)throw new tt.FeatureDisabledError(`${e} is not currently enabled`,e);return!0};async function xx(){return re(te.Feature.VIEW_PERMISSIONS)}async function Cx(){return re(te.Feature.VIEW_READONLY_COLUMNS)}var Ox={faviconUrl:void 0,faviconUrlEtag:void 0,emailBrandingEnabled:!0,testimonialsEnabled:!0,platformTitle:void 0,loginHeading:void 0,loginButton:void 0,metaDescription:void 0,metaImageUrl:void 0,metaTitle:void 0};async function Lx(e){return await ys()?{faviconUrl:e.faviconUrl,faviconUrlEtag:e.faviconUrlEtag,emailBrandingEnabled:e.emailBrandingEnabled,testimonialsEnabled:e.testimonialsEnabled,platformTitle:e.platformTitle,loginHeading:e.loginHeading,loginButton:e.loginButton,metaDescription:e.metaDescription,metaImageUrl:e.metaImageUrl,metaTitle:e.metaTitle}:Ox}var Is={};w(Is,{enrichAIConfig:()=>bs});var Ef=require("@budibase/backend-core"),Px="budibase_ai";async function bs(e){if(Ef.env.SELF_HOSTED)return e;for(let t of Object.values(e.config))if(t.provider==="BudibaseAI")return e;return e.config[Px]={provider:"BudibaseAI",active:!0,isDefault:Object.keys(e.config).every(t=>!e.config[t].isDefault),defaultModel:process.env.BUDIBASE_AI_DEFAULT_MODEL||"gpt-5-mini",name:"Budibase AI"},e}var ze={};w(ze,{addAction:()=>Bx,addApp:()=>Mx,addAutomation:()=>Wx,addGroup:()=>ws,addPlugin:()=>Es,addRow:()=>Gx,addRows:()=>jx,addUsers:()=>wn,bustCache:()=>yo,decrement:()=>at,decrementMany:()=>ga,getCurrentUsageValues:()=>Xu,getLicensedQuota:()=>vf,getQuotaUsage:()=>Et,increment:()=>Ie,incrementBudibaseAICredits:()=>En,incrementMany:()=>qt,removeApp:()=>kx,removeGroup:()=>Ts,removePlugin:()=>Rs,removeRow:()=>Fx,removeRows:()=>Qx,removeUsers:()=>lr,set:()=>Ss,setAllUsage:()=>Ao,setAppUsageValue:()=>ho,setUsage:()=>Hu,setUsagePerApp:()=>zu,updatePluginCount:()=>vs,updateUsage:()=>ur,usageLimitIsExceeded:()=>Nx,utils:()=>_r});var In=require("@budibase/types");var z=require("@budibase/types");var ke=require("@budibase/backend-core");var Ut=require("dd-trace"),Ie=async(e,t,r)=>await Ut.tracer.trace("quotas.increment",async a=>(a.addTags({name:e,type:t}),await Rf({change:1,name:e,type:t,opts:r}))),qt=e=>Ut.tracer.trace("quotas.incrementMany",async()=>Rf(e)),Rf=async e=>await Ut.tracer.trace("quotas.tryIncrement",async t=>{let r=Array.isArray(e)?e:[e];t.addTags({numActions:r.length}),await ur(r.map(n=>({usageChange:n.change,name:n.name,type:n.type,opts:{dryRun:!0,suppressErrorLog:n.opts?.suppressErrorLog,id:n.opts?.id}})));let a=[];for(let n of r)await Ut.tracer.trace("quotas.incrementMany.fn",async o=>{o.addTags({actionName:n.name,actionType:n.type,actionChange:n.change});let s=n.opts?.fn;s&&a.push(await s())});return await ur(r.map(n=>({usageChange:n.change,name:n.name,type:n.type,opts:{dryRun:!1,valueFn:n.opts?.valueFn,suppressErrorLog:n.opts?.suppressErrorLog,id:n.opts?.id}}))),a[0]}),at=(e,t,r={})=>ur({usageChange:-1,name:e,type:t,opts:r}),ga=e=>{let t=Array.isArray(e)?e:[e];return ur(t.map(r=>({usageChange:-r.change,name:r.name,type:r.type,opts:r.opts})))},Ss=async(e,t,r)=>We.setUsage(r,e,t),Ux=(e,t,r)=>{if(e==z.QuotaUsageType.STATIC){let a=r.usageQuota.triggers;return a?a[t]||{}:{}}else{let a=We.utils.getCurrentMonthString(),n=r.monthly[a].triggers;return n?n[t]||{}:{}}},qx=async(e,t,r,a)=>{try{await ke.locks.doWithLock({type:z.LockType.TRY_ONCE,name:z.LockName.TRIGGER_QUOTA,resource:e,ttl:1e4},async()=>{let n={percentage:r,name:t.name};a&&(n.resetDate=a),await mt.triggerQuota(n)})}catch(n){ke.logging.logAlert("Error triggering quota",n)}},Dx=async(e,t,r,a)=>{let n=await Et(),o=e===z.QuotaUsageType.MONTHLY?n.quotaReset:void 0,s=await Ux(e,t,n),i=a.triggers,p=r/a.value*100;p>100&&(p=100);for(let[f,m]of i.entries())if(p>=m&&a.value!==et.UNLIMITED){if(!s[m]){s[m]=new Date().toISOString();let y=i[f+1]||100;(!(p>=y)||p===m)&&await qx(t,a,p,o)}}else s[m]=void 0;return s},ur=async e=>{await Ut.tracer.trace("quotas.updateUsage",async t=>{let r=ke.tenancy.getTenantId(),a=Array.isArray(e)?e:[e];t.addTags({numActions:a.length,tenantId:r});let n,o,s=[],i={},p={},f={},m={};for(let y of a)await Ut.tracer.trace("quotas.updateUsage.action",async I=>{I.addTags({actionName:y.name,actionType:y.type,actionUsageChange:y.usageChange});try{n=ke.context.getAppId()}catch{}if(z.APP_QUOTA_NAMES.includes(y.name)&&!n)throw new Error("App context required for quota update");try{o=await vf(z.QuotaType.USAGE,y.name,y.type),s.push(o);let{total:_,app:v,breakdown:R}=await We.getCurrentUsageValues(y.type,y.name,y.opts?.id);_+=y.usageChange,v!=null&&(v+=y.usageChange),R!=null&&(R+=y.usageChange);let U={};if(y.opts?.dryRun||(U=await Dx(y.type,y.name,_,o),m={...m,[y.name]:U}),o.value!==et.UNLIMITED&&_>o.value&&y.usageChange>0)throw new ke.UsageLimitError(`Licensed ${o.name} of ${o.value} has been exceeded`,o.name);if(_=Math.max(0,_),v&&(v=Math.max(0,v)),R&&(R=Math.max(0,R),f={...f,[y.name]:R}),!y.opts?.dryRun){let qe=y.opts?.valueFn;qe&&(_=await qe(),v=_),i={...i,[y.name]:_},p={...p,[y.name]:v}}}catch(_){throw y.opts?.suppressErrorLog||console.error(`Error updating usage quotas for ${y.name}`,_),_}});let g=a.filter(y=>!y.opts?.dryRun).map(y=>({name:y.name,type:y.type,values:{total:i[y.name],app:p[y.name],breakdown:f[y.name],triggers:m[y.name]},opts:{...y.opts,tenantId:r}}));g.length>0&&await We.setAllUsage(g)})},vf=async(e,t,r)=>{let a=await Ne.getCachedLicense();if(!a){let n=ke.tenancy.getTenantId();throw new Error("License not found for tenant id "+n)}if(r&&(0,z.isStaticQuota)(e,r,t))return a.quotas[e][r][t];if(r&&(0,z.isMonthlyQuota)(e,r,t))return a.quotas[e][r][t];if((0,z.isConstantQuota)(e,t))return a.quotas[e][t];throw new Error("Invalid quota type")},Nx=async({name:e,type:t,usageChange:r})=>{try{return await ur({usageChange:r,name:e,type:t,opts:{dryRun:!0}}),!1}catch(a){if(a.code===z.ErrorCode.USAGE_LIMIT_EXCEEDED)return!0;throw a}};var Bx=async e=>Ie(In.MonthlyQuotaName.ACTIONS,In.QuotaUsageType.MONTHLY,{fn:e});var pr=require("@budibase/types"),_f=require("@budibase/backend-core"),xf=async()=>{let e=await _f.db.getAllApps({dev:!0});return e?e.length:0},Mx=async(e,{appId:t}={})=>Ie(pr.StaticQuotaName.APPS,pr.QuotaUsageType.STATIC,{fn:e,valueFn:xf,id:t}),kx=async({appId:e}={})=>at(pr.StaticQuotaName.APPS,pr.QuotaUsageType.STATIC,{valueFn:xf,id:e});var Ye=require("@budibase/types"),Gx=async(e,{tableId:t}={})=>Ie(Ye.StaticQuotaName.ROWS,Ye.QuotaUsageType.STATIC,{fn:e,id:t}),Fx=async({tableId:e}={})=>at(Ye.StaticQuotaName.ROWS,Ye.QuotaUsageType.STATIC,{id:e}),jx=async(e,t,{tableId:r}={})=>qt({change:e,name:Ye.StaticQuotaName.ROWS,type:Ye.QuotaUsageType.STATIC,opts:{fn:t,id:r}}),Qx=async(e,{tableId:t}={})=>ga({change:e,name:Ye.StaticQuotaName.ROWS,type:Ye.QuotaUsageType.STATIC,opts:{id:t}});var Sn=require("@budibase/types"),Wx=async(e,{automationId:t}={})=>Ie(Sn.MonthlyQuotaName.AUTOMATIONS,Sn.QuotaUsageType.MONTHLY,{fn:e,id:t});var cr=require("@budibase/types"),ws=async e=>Ie(cr.StaticQuotaName.USER_GROUPS,cr.QuotaUsageType.STATIC,{fn:e}),Ts=async()=>at(cr.StaticQuotaName.USER_GROUPS,cr.QuotaUsageType.STATIC);var At=require("@budibase/types"),Es=async e=>Ie(At.StaticQuotaName.PLUGINS,At.QuotaUsageType.STATIC,{fn:e}),Rs=async()=>at(At.StaticQuotaName.PLUGINS,At.QuotaUsageType.STATIC),vs=async e=>Ss(At.StaticQuotaName.PLUGINS,At.QuotaUsageType.STATIC,e);var He=require("@budibase/types"),ya=require("@budibase/backend-core");var wn=async(e,t,r)=>{let a=[{change:e,name:He.StaticQuotaName.USERS,type:He.QuotaUsageType.STATIC,opts:{fn:r,valueFn:ya.users.getUserCount}}];t>0&&a.push({change:t,name:He.StaticQuotaName.CREATORS,type:He.QuotaUsageType.STATIC,opts:{valueFn:ya.users.getCreatorCount}});let n=await qt(a);return await Kt(),n},lr=async(e,t)=>{let r=[{change:e,name:He.StaticQuotaName.USERS,type:He.QuotaUsageType.STATIC,opts:{valueFn:ya.users.getUserCount}}];t>0&&r.push({change:t,name:He.StaticQuotaName.CREATORS,type:He.QuotaUsageType.STATIC,opts:{valueFn:ya.users.getCreatorCount}}),await ga(r),await Kt()};var Tn=require("@budibase/types"),En=async e=>qt({change:e,name:Tn.MonthlyQuotaName.BUDIBASE_AI_CREDITS,type:Tn.QuotaUsageType.MONTHLY});var nt={};w(nt,{addAppBuilder:()=>Hx,db:()=>Ce,removeAppBuilder:()=>zx});var Aa=require("@budibase/backend-core");var Q={};w(Q,{addAppBuilder:()=>Os,addUsers:()=>vn,adjustGroupCreatorsQuotas:()=>Yx,cleanupApp:()=>Vx,enrichUserRolesFromGroups:()=>Kx,fetch:()=>ha,get:()=>bt,getBulk:()=>Df,getGroupBuilderAppIds:()=>qf,getGroupRoleId:()=>$x,remove:()=>_s,removeAppBuilder:()=>Ls,removeUsers:()=>xs,save:()=>dr,updateGroupApps:()=>Cs});var x=require("@budibase/backend-core");var Cf=require("@budibase/backend-core"),Rn=class extends Cf.HTTPError{constructor(t){super(`Group name "${t}" is unavailable`,409)}};async function Pf(e,t){try{let r=[];for(let i of e)if(i.roles){let p=i.roles[x.db.getProdAppID(t)];p&&r.push(p)}let a=await Promise.all(r.map(async i=>({[i]:await x.roles.roleToNumber(i)}))),n,o,s={};a.forEach(i=>{let[p,f]=Object.entries(i)[0];s[p]={roleId:p,roleNum:f}});for(let{roleId:i,roleNum:p}of Object.values(s))(o===void 0||p>o)&&(o=p,n=i);return n}catch(r){throw x.logging.logAlert(`Error finding higest role for ${e.length} on app ${t}`,r),r}}async function Uf(e,t){return t?t=t.filter(r=>e.includes(r._id)):t=await M.getBulk(e,{enriched:!1}),t}async function qf(e,t){if(!e.userGroups)return[];let r=await Uf(e.userGroups,t?.groups),a=t?.appId?x.db.getProdAppID(t?.appId):null,n=[];for(let o of r){let s=o.builder?.apps;a&&s?.includes(a)?n.push(a):a||(n=n.concat(s||[]))}return[...new Set(n)]}async function $x(e,t,r){if(!e.userGroups)return null;let a=await Uf(e.userGroups,r?.groups),n=x.db.getProdAppID(t);return e.roles?.[n]?e.roles[n]:(a=a.filter(o=>o?.roles?Object.keys(o.roles).includes(n):!1),await Pf(a,t))}async function Kx(e){if(!e||!e.userGroups)return e;let t=await Df(e.userGroups,{enriched:!1}),r=[];for(let n of t)n?.roles&&(r=r.concat(Object.keys(n.roles)));r=[...new Set(r)];for(let n of r)await x.context.doInAppContext(n,async()=>{if(e.roles[n])return;let o=await Pf(t,n);o&&(e.roles[n]=o)});let a=await qf(e,{groups:t});if(a.length&&!e.builder?.global){let n=e.builder?.apps||[];e.builder={apps:n.concat(a)}}return e}async function ha(){return await M.fetch()}async function bt(e){return await M.get(e)}async function Df(e,t={enriched:!0}){return await M.getBulk(e,t)}async function Of(e){if(await M.getByName(e))throw new Rn(e)}async function Lf(e){let t=await M.getGroupUsers(e._id);if(!t.length)return 0;let a=await x.tenancy.getGlobalDB().getMultiple(t.map(o=>o._id));return(await x.userUtils.creatorsInList(a)).filter(o=>o).length}async function dr(e){let t=[],r=!e._id,a=0;if(delete e.users,!e._id)e._id=M.generateUserGroupID(),await Of(e.name),t.push(x.events.group.created(e));else{let o=await M.get(e._id);if(o.name!==e.name&&await Of(e.name),t.push(x.events.group.updated(e)),JSON.stringify(o.roles)!==JSON.stringify(e.roles)){let s=o.users?.length||0,i=0;s>0&&(i=await Lf(o)),Object.values(e.roles).includes("CREATOR")?a=s-i:a=-s,t.push(x.events.group.permissionsEdited(e))}}await Promise.all(t);let n=()=>M.save(e);if(r)return await ws(n);{let o=await n();if(a>0)await wn(0,a);else if(a<0){let s=await Lf(e),i=Math.abs(a)-s;i>0&&await lr(0,i)}return o}}async function _s(e,t){let r;try{r=await M.get(e)}catch{throw new Error("Group not found")}let a=Object.values(r.roles||{}).includes("CREATOR"),n=()=>{};if(a){let s=x.tenancy.getGlobalDB(),i=await M.getGroupUsers(e),f=(await Promise.all(i.map(I=>s.get(I._id)))).map(I=>({...I,userGroups:I.userGroups.filter(C=>C!==e)})),g=(await x.userUtils.creatorsInList(f)).filter(I=>I).length,y=i.length-g;y&&(n=()=>lr(0,y))}let o=await M.destroy(e,t);return await x.events.group.deleted(r),await Ts(),await n(),o}async function vn(e,t){let r=await M.get(e),a=await x.users.bulkGetGlobalUsersById(t),n=[];for(let p of a)p.userGroups||(p.userGroups=[]),p.userGroups.includes(e)||n.push(p);if(!n.length)return n;let o=n.map(p=>({...p,userGroups:[...p?.userGroups||[],e]}));if(await x.users.bulkUpdateGlobalUsers(o),Object.values(r.roles||{}).includes("CREATOR")){let f=(await x.userUtils.creatorsInList(n)).filter(g=>g).length,m=n.length-f;m&&await wn(0,m)}let i=[];for(let p of t)i.push(x.cache.user.invalidateUser(p));return await Promise.all(i),await x.events.group.usersAdded(o.length,r),o}async function xs(e,t){let r=await M.get(e),a=await x.users.bulkGetGlobalUsersById(t),n=[];for(let i of a){if(!i.userGroups||!i.userGroups.includes(e))continue;let p=i.userGroups.indexOf(e);i.userGroups.splice(p,1),n.push(i)}if(await x.users.bulkUpdateGlobalUsers(n),Object.values(r.roles||{}).includes("CREATOR")){let p=(await x.userUtils.creatorsInList(n)).filter(m=>m).length,f=n.length-p;f&&await lr(0,f)}let s=[];for(let i of t)s.push(x.cache.user.invalidateUser(i));return await Promise.all(s),n.length&&await x.events.group.usersDeleted(n.length,r),n}async function Cs(e,t){let r=await bt(e);if(r.roles||(r.roles={}),t.appsToAdd)for(let a of t.appsToAdd)r.roles[a.appId]=a.roleId;if(t.appsToRemove)for(let a of t.appsToRemove)delete r.roles[a.appId];return await dr(r)}async function Vx(e){let t=await ha(),r=[];for(let a of t)!a.roles||!a.roles[e]||(delete a.roles[e],r.push(a));return await M.bulkSave(r)}async function Os(e,t){if(!await Pt())throw new Error("Feature not enabled, please check license");let r=x.db.getProdAppID(t),a=await bt(e);a.builder??={apps:[]},a.builder.apps.includes(t)||(a.builder.apps.push(r),await dr(a))}async function Ls(e,t){if(!await Pt())throw new Error("Feature not enabled, please check license");let r=x.db.getProdAppID(t),a=await bt(e);a.builder?.apps.includes(t)&&(a.builder.apps=a.builder.apps.filter(n=>n!==r),await dr(a))}async function Yx(){if(!await hs()){let e=x.tenancy.getGlobalDB(),r=(await ha()||[]).filter(a=>Object.values(a?.roles||{}).includes("CREATOR"));for(let a of r){let n=await M.getGroupUsers(a._id),s=(await Promise.all(n.map(m=>e.get(m._id)))).map(m=>({...m,userGroups:m.userGroups.filter(g=>g!==a._id)})),p=(await x.userUtils.creatorsInList(s)).filter(m=>m).length,f=n.length-p;await M.save({...a,roles:{}}),f&&await lr(0,f)}}}Aa.users.UserDB.init(ze,Q,Me);var Ce=Aa.users.UserDB;async function Hx(e,t){if(!await Pt())throw new Error("Feature not enabled, please check license");await Aa.users.addAppBuilder(e,t)}async function zx(e,t){if(!await Pt())throw new Error("Feature not enabled, please check license");await Aa.users.removeAppBuilder(e,t)}var Cn={};w(Cn,{logs:()=>Ms});var Ms={};w(Ms,{logSearch:()=>oC,oldestLogDate:()=>jf,storeLog:()=>sC});var Ff=require("@budibase/types"),xn=require("@budibase/backend-core");var _n=require("@budibase/types");var Z=require("@budibase/backend-core");var Nf=require("@budibase/backend-core");async function Bf(e,t){let r,a=5,n=!1,o,s=!0;for(;a>0;a--)try{s?o=await e():o=await exports.randomDelay(e),n=!0;break}catch(i){r=i}return n||Nf.logging.logWarn(`Failed to backoff: ${t}`,r),o}var{SEPARATOR:ot,UNICODE_MAX:Jx,DocumentType:Mf,AutomationViewMode:Ps,ViewName:Xx,getQueryIndex:Zx}=Z.db,eC=new Date(0).toISOString(),tC=100,Us=async()=>Ka(_n.ConstantQuotaName.AUTOMATION_LOG_RETENTION_DAYS);function kf(e,t,{status:r,automationId:a}={},n={}){let o=a?`${a}${ot}`:"",s=r?`${r}${ot}`:"",i;return r&&a?i=`${Ps.ALL}${ot}${s}${o}`:r?i=`${Ps.STATUS}${ot}${s}`:a?i=`${Ps.AUTOMATION}${ot}${o}`:i=`${Mf.AUTOMATION_LOG}${ot}`,{...n,descending:!0,startkey:`${i}${t}${Jx}`,endkey:`${i}${e}`}}function rC(e,t,r){return`${Mf.AUTOMATION_LOG}${ot}${e}${ot}${r}${ot}${t}`}async function qs(e,t,r={docs:!0}){let a=Z.context.getProdAppDB();await a.exists()||(a=Z.context.getDevAppDB());let n={status:r.status},o=r?.limit?r.limit:r?.paginate?9+1:void 0,s=kf(e,t,n,{include_docs:r.docs,limit:o});r?.page&&(s.startkey=r.page);let i=await a.allDocs(s);return Or(i,{paginate:r?.paginate,pageSize:9})}async function Ds(e,t,r={}){let a=Z.context.getProdAppDB();await a.exists()||(a=Z.context.getDevAppDB());let n;try{let o={automationId:r?.automationId,status:r?.status},s=kf(e,t,o,{include_docs:!0,limit:9+1});r?.page&&(s.startkey=r.page),n=await a.query(Zx(Xx.AUTOMATION_LOGS),s)}catch(o){if(o!=null&&(o.name==="not_found"||o.error==="not_found"))return await pp(),Ds(e,t,r);throw o}return Or(n,{paginate:!0,pageSize:9})}async function Gf(e,t){let r=Z.context.getProdAppDB(),a=e._id,n=e.name,o=new Date().toISOString(),s=rC(o,t.status,a),i={...t,automationId:a,status:t.status,automationName:n,createdAt:o,_id:s};return await r.put(i),s}async function Ns(e,{clearing:t}={clearing:!1}){let r=Z.context.getProdAppDB();await Bf(async()=>{let a=await r.get(Z.db.DocumentType.APP_METADATA);for(let n of e){let o=n.split(Z.db.SEPARATOR),s=`${o[o.length-3]}${Z.db.SEPARATOR}${o[o.length-2]}`,i={};a.automationErrors&&(i=a.automationErrors),Array.isArray(i[s])||(i[s]=[]);let p=i[s].indexOf(n);t&&p!==-1?i[s].splice(p,1):i[s].push(n),i[s].length===0&&delete i[s],a.automationErrors=i}await r.put(a),await Z.cache.app.invalidateAppMetadata(a.appId,a)},"Failed to update app metadata with automation log error")}async function aC(){let e=await Us();try{return await qs(eC,e,{docs:!1,paginate:!1,limit:tC})}catch{return{data:[],hasNextPage:!1}}}async function Bs(){let e=Z.context.getProdAppDB();try{let t=await aC();if(!t.data||t.data.length===0)return;let r=t.data.map(n=>({_id:n.id,_rev:n.value.rev,_deleted:!0})),a=t.data.filter(n=>{let o=n.id.split(Z.db.SEPARATOR);return o[o.length-1]===_n.AutomationStatus.ERROR}).map(n=>n.id);await e.bulkDocs(r),a.length&&await Ns(a,{clearing:!0})}catch(t){Z.logging.logAlert(`Failed to cleanup automation log history - Database "${e.name}"`,t)}}var jf=Us;async function nC(e,t,r,a){let n,o=new Date().toISOString(),s=await jf();return(!e||e<s)&&(e=s),r||t?n=await Ds(e,o,{automationId:r,status:t,page:a}):n=await qs(e,o,{status:t,page:a,docs:!0,paginate:!0}),n}async function oC(e){return await Bs(),await nC(e.startDate,e.status,e.automationId,e.page)}async function sC(e,t){if(!xn.db.isProdAppID(xn.context.getAppId()))return;let r=await Gf(e,t);t.status===Ff.AutomationStatus.ERROR&&await Ns([r]),await Bs()}var On={};w(On,{checkPluginQuotas:()=>pC,deletePlugin:()=>uC,storePlugin:()=>iC});var Kf=require("@budibase/types"),J=require("@budibase/backend-core");var Qf=P(require("fs")),Wf=require("path");function $f(e,t){return Qf.default.readFileSync((0,Wf.join)(e,t),"utf8")}async function iC(metadata,directory,source){let db=J.tenancy.getGlobalDB(),version=metadata.package.version,name=metadata.package.name,description=metadata.package.description,hash=metadata.schema.hash,bucketPath=J.objectStore.getPluginS3Dir(name),files=await J.objectStore.uploadDirectory(J.objectStore.ObjectStoreBuckets.PLUGINS,directory,bucketPath),jsFile=files.find(e=>e.name.endsWith(".js")),iconFile=files.find(e=>e.name.endsWith(".svg"));if(!jsFile)throw new Error("Plugin missing .js file.");if(metadata.schema.type===Kf.PluginType.DATASOURCE){let js=$f(directory,jsFile.name);try{eval(js)}catch(e){let t=e?.message?e.message:JSON.stringify(e);throw new Error(`JS invalid: ${t}`)}}let iconFileName=iconFile?iconFile.name:null,pluginId=J.db.generatePluginID(name),rev;try{rev=(await db.get(pluginId))._rev}catch(e){rev=void 0}let doc={_id:pluginId,_rev:rev,...metadata,name,version,hash,description,source};iconFileName&&(doc.iconFileName=iconFileName),source&&(doc={...doc,source});let write=async()=>{let e=await db.put(doc);return await J.events.plugin.imported(doc),{...doc,_rev:e.rev}};return rev?await write():await Es(write)}async function uC(e){let t=J.tenancy.getGlobalDB();try{let r=await t.get(e),a=J.objectStore.getPluginS3Dir(r.name);await J.objectStore.deleteFolder(J.objectStore.ObjectStoreBuckets.PLUGINS,a),await t.remove(e,r._rev),await J.events.plugin.deleted(r),await Rs()}catch(r){let a=r?.message?r?.message:r;throw new Error(`Failed to delete plugin: ${a}`)}}async function pC(){let e=J.tenancy.getGlobalDB();try{let r=(await e.allDocs(J.db.getPluginParams())).rows.length;console.log(`Syncing plugin count: ${r}`),await vs(r)}catch(t){J.logging.logAlert("Unable to retrieve plugins for quota check",t)}}var Je={};w(Je,{fetch:()=>lC,fetchValues:()=>dC,isEncryptionKeyAvailable:()=>cC,isValid:()=>Hf,remove:()=>mC,update:()=>fC});var ba=require("@budibase/types"),Vf=require("@budibase/backend-core");function cC(){return!!Vf.env.ENCRYPTION_KEY}async function lC(){let e=await _t.get();return Object.keys(e.variables)}async function dC(e){let r=(await _t.get()).variables,a={};for(let[n,o]of Object.entries(r))switch(e){case ba.AppEnvironment.DEVELOPMENT:a[n]=o.development;break;case ba.AppEnvironment.PRODUCTION:default:a[n]=o.production;break}return a}async function Yf(e){if(!(await Ve.cache.getCachedLicense()).features.includes(ba.Feature.ENVIRONMENT_VARIABLES))throw new Error("User does not have access to environment variables feature.");let r=await _t.get();r.variables=e(r.variables),await _t.update(r)}async function fC(e,t){if(Hf(e))await Yf(a=>(a[e]=t,a));else throw new Error("Variable name has characters that are not allowed")}async function mC(e){await Yf(t=>(delete t[e],t))}function Hf(e){return/^[a-zA-Z0-9-_]+$/.test(e)}var It={};w(It,{definitions:()=>RC,download:()=>EC,fetch:()=>TC,write:()=>SC});var Pn=require("@budibase/types");var V=require("@budibase/backend-core"),Ge=require("@budibase/types");var zf=require("memorystream"),Jf=new V.sql.Sql(Ge.SqlClient.SQL_LITE);async function gC(e,t,r){let a={operation:Ge.Operation.READ,table:$t.searchTable(),tables:{},paginate:{limit:r||9,page:t},filters:e,resource:{fields:[]},sort:{timestamp:{direction:Ge.SortOrder.DESCENDING,type:Ge.SortType.STRING}}},n=Jf._query(a);if(Array.isArray(n))throw new Error("Cannot execute multiple queries for audit log search");return{sql:n.sql,bindings:n.bindings}}function yC(e){return`${V.DocumentType.AUDIT_LOG}${V.SEPARATOR}${e}${V.SEPARATOR}${V.utils.newid()}`}async function Xf(e){e._id||(e._id=yC(e.timestamp)),e.type||(e.type=Ge.AUDIT_LOG_TYPE);try{let r=await V.context.getAuditLogsDB().put(e);return{...e,_rev:r.rev}}catch(t){V.logging.logAlert("Failed to write audit log",t)}}async function ks(e,t,r){t||(t=1);let a=V.context.getAuditLogsDB();try{let n=9+1,o=await gC(e,t,n),s=$t.searchTable(),i=Jf.convertJsonStringColumns(s,await a.sql(o.sql,o.bindings)),p;i.length>n&&(p=i.pop());let f={rows:i,hasNextPage:!!p};return f.hasNextPage&&(f.bookmark=t+1),f}catch(n){if(n.status===404&&!r?.isRetry)return await hC(),await Zu(),await ks(e,t,{isRetry:!0});throw n}}async function hC(){let e=V.context.getAuditLogsDB(),r=(await e.allDocs(V.db.getDocParams(V.DocumentType.AUDIT_LOG,null,{include_docs:!0}))).rows.map(a=>a.doc).filter(a=>a&&!a.type).map(a=>({...a,type:Ge.AUDIT_LOG_TYPE}));await e.bulkDocs(r)}function Zf(e){let t=V.context.getAuditLogsDB(),r=new zf,a=t.dump(r,{filter:o=>{let s=o;if(!s._id?.startsWith(V.DocumentType.AUDIT_LOG))return!1;let i=!0,p=(f,m)=>{!f||f.length===0||(i=!!(i&&m&&f.includes(m)))};if(p(e.userIds,s.userId),p(e.appIds,s.appId),p(e.events,s.event),(e.startDate||e.endDate)&&(i=i&&s.timestamp>=e.startDate&&s.timestamp<=e.endDate),e.fullSearch){let f=JSON.stringify(o);i=i&&f.includes(e.fullSearch)}return i}}),n=new zf;return r.on("data",o=>{let s=JSON.parse(Buffer.from(o).toString());if(Array.isArray(s.docs)){let i="";for(let p of s.docs)i+=JSON.stringify(p)+`
|
|
38
|
-
`;n.write(i)}}),r.on("end",()=>{n.end()}),{promise:a,stream:n}}var me=require("@budibase/backend-core");var Ln=require("@budibase/types"),Ia=require("@budibase/string-templates"),Sa=require("@budibase/backend-core"),bC=Sa.constants.MIN_VALID_DATE.toISOString(),IC=Sa.constants.MAX_VALID_DATE.toISOString();function Gs(e){return(e.startDate||e.endDate)&&(e.startDate=e.startDate||bC,e.endDate=e.endDate||IC),e}async function em(e){Array.isArray(e.appIds)&&(e.appIds=e.appIds.map(a=>Sa.db.getProdAppID(a)));let t={};function r(a,n){n?.length&&(t.oneOf={...t.oneOf,[a]:n})}return r("userId",e.userIds),r("appId",e.appIds),r("event",e.events),e.fullSearch&&(t.fuzzyOr=!0,t.fuzzy={name:e.fullSearch,fallback:e.fullSearch}),(e.startDate||e.endDate)&&(e=Gs(e),t.range={timestamp:{high:e.endDate,low:e.startDate}}),Object.keys(t).length===0&&(t.notEmpty={event:!0}),t}function Fs(e,t,r){let a={_id:e,status:Ln.AuditLogResourceStatus.DELETED};switch(t){case"app":a.name=r?.appName;break;case"user":a.email=r?.email;break}return a}function Qs(e){let t=(0,Ia.findHBSBlocks)(e);for(let r of t){let a=` "${r}"`;e=e.replace(e.includes(a)?a:` ${r}`,""),e=(0,Ia.processStringSync)(e,{})}return e}function tm(e,t){let r=Ln.AuditedEventFriendlyName[e];if(!r)throw new Error("No friendly name found.");let a=(0,Ia.processStringSync)(r,t);return a.includes('""')&&(a=Qs(r)),a}async function SC(e,t,r){if(!await An()||!me.utils.isAudited(e))return;let a=tm(e,t),n=new Date;r?.timestamp&&(n=new Date(r.timestamp));let o={timestamp:n.toISOString(),event:e,name:a,userId:r?.userId||Pn.AuditLogSystemUser,metadata:{...t,...r?.hostInfo}},s={};try{if(r?.appId){o.appId=me.db.getProdAppID(r.appId);let i=await me.cache.app.getAppMetadata(r.appId);"name"in i&&(s.appName=i.name)}if(r?.userId){let i=await me.users.getById(r?.userId);s.email=i.email}}catch(i){me.logging.logAlert("Failed to retrieve fallback information for audit log",i)}return o.fallback=s,await Xf(o)}async function wC(e){let t=e.map(i=>i.userId),a=e.filter(i=>i.appId).map(i=>me.db.getDevAppID(i.appId)),n=await me.users.bulkGetGlobalUsersById([...new Set(t)],{cleanup:!0}),o=await me.db.getAppsByIDs([...new Set(a)]),s=[];for(let i of e){let p=n.find(g=>g?._id===i.userId),f=o.find(g=>me.db.isSameAppID(g?.appId,i.appId)),m={event:i.event,timestamp:i.timestamp,name:i.name,metadata:i.metadata,user:p||Fs(i.userId,"user",i.fallback)};i.appId&&(m.app=f||Fs(i.appId,"app",i.fallback)),s.push(m)}return s}async function TC(e){if(!await An())throw new Error("Audit logs not available - license required.");let t=await em(e);if(typeof e.bookmark=="string")throw new Error("String based bookmark not supported.");let r=await ks(t,e.bookmark);return{hasNextPage:r.hasNextPage,bookmark:r.bookmark,data:await wC(r.rows)}}function EC(e){return e=Gs(e),Zf(e)}function RC(){let e=Object.entries(Pn.AuditedEventFriendlyName).filter(r=>r[1]!=null),t={};for(let r of e)t[r[0]]=Qs(r[1]);return t}var Un={};w(Un,{applications:()=>Vs,roles:()=>$s,users:()=>Ws});var Ws={};w(Ws,{roleCheck:()=>_C});function vC(e,t){let r=e.request.body;return r.builder&&(r.builder=t?.builder||void 0),r.admin&&(r.admin=t?.admin||void 0),r.roles&&(r.roles=t?.roles||{}),e.request.body=r,e}async function _C(e,t){return await rt()||vC(e,t),e}var $s={};w($s,{assign:()=>xC,unAssign:()=>CC});var wa=require("@budibase/backend-core");async function xC(e,t){if(!await rt())throw new Error("Unable to assign roles - license required.");let r=await Ce.bulkGet(e);for(let a of r){if(t.role&&t.role.roleId){let n=wa.db.getProdAppID(t.role.appId);a.roles[n]=t.role.roleId}if(t.appBuilder){let n=wa.db.getProdAppID(t.appBuilder.appId),o=a.builder?.apps||[];a.builder={apps:o.concat([n])}}t.builder&&(a.builder={global:!0}),t.admin&&(a.admin={global:!0}),a.roles}await Ce.bulkUpdate(r)}async function CC(e,t){if(!await rt())throw new Error("Unable to un-assign roles - license required.");let r=await Ce.bulkGet(e);for(let a of r){if(t.role){let n=wa.db.getProdAppID(t.role?.appId);a.roles[n]===t.role.roleId&&delete a.roles[n]}if(t.appBuilder&&a.builder?.apps){let n=wa.db.getProdAppID(t.appBuilder.appId);a.builder.apps=a.builder.apps.filter(o=>o!==n)}t.builder&&a.builder&&delete a.builder,t.admin&&a.admin&&delete a.admin}}var Vs={};w(Vs,{buildExportFn:()=>LC,buildImportFn:()=>OC});var Ks=require("@budibase/backend-core");function OC(e){return async(t,r)=>{await rt()||t.throw(403,"Endpoint unavailable, license required."),t.request.files?.appExport||t.throw(400,"Must provide app export file for import."),await Ks.context.doInAppContext(t.params.appId,async()=>{await e(t),t.body=void 0,t.status=204,await r()})}}function LC(e){return async(t,r)=>{await rt()||t.throw(403,"Endpoint unavailable, license required.");let{encryptPassword:a,excludeRows:n}=t.request.body;await Ks.context.doInAppContext(t.params.appId,async()=>{t.request.body={encryptPassword:a,excludeRows:n},t.query.appId=t.params.appId,await e(t),await r()})}}var ne=require("@budibase/backend-core"),ae=require("@budibase/types");var Ys=require("@budibase/backend-core"),rm;function am(){rm=new Ys.queue.BudibaseQueue(Ys.queue.JobQueue.APP_BACKUP,{maxStalledCount:3,jobOptions:{attempts:3,removeOnFail:!0,removeOnComplete:!0}})}function Dt(){return rm}var nm=require("path"),om=P(require("fs"));async function Hs(e,t={}){return _e.storeAppBackupMetadata(e,t)}function sm(e){let t=new Date().toISOString();switch(e){case ae.AppBackupStatus.COMPLETE:case ae.AppBackupStatus.FAILED:return{timestamp:t,finishedAt:t};case ae.AppBackupStatus.STARTED:return{timestamp:t,startedAt:t};case ae.AppBackupStatus.PENDING:return{timestamp:t,createdAt:t}}}async function PC(e,t,r,a){let n=await qn(e);return await _e.storeAppBackupMetadata({...n,...sm(t),contents:r,status:t,type:ae.AppBackupType.BACKUP},{filename:a,docId:e})}async function UC(e,t,r){let a=await qn(e);return await _e.storeAppBackupMetadata({...a,...sm(r),status:r,type:ae.AppBackupType.RESTORE,trigger:ae.AppBackupTrigger.MANUAL},{docId:e,docRev:t})}async function qn(e){return _e.getAppBackupMetadata(e)}async function qC(e,t){return _e.updateAppBackupMetadata(e,t)}async function im(e){let t=await _e.getAppBackupMetadata(e);return t.filename&&await ne.objectStore.deleteFile(ne.objectStore.ObjectStoreBuckets.BACKUPS,t.filename),_e.deleteAppBackupMetadata(e)}async function DC(e){let t=[];for(let r of e)try{await im(r),t.push({backupId:r,success:!0})}catch(a){t.push({backupId:r,success:!1,error:a instanceof Error?a.message:"Unknown error"})}return t}async function NC(e,t){return _e.fetchAppBackups(e,t)}async function um(e){let t=await _e.getAppBackupMetadata(e);if(!t.filename)throw new Error("Backup incomplete - cannot download.");let r=await ne.objectStore.getReadStream(ne.objectStore.ObjectStoreBuckets.BACKUPS,t.filename);return{metadata:t,stream:r}}async function BC(e){let{stream:t}=await um(e),r=(0,nm.join)(ne.objectStore.budibaseTempDir(),ne.utils.newid()),a=om.default.createWriteStream(r);return new Promise((n,o)=>{t.on("error",o),a.on("error",o),t.pipe(a).on("close",()=>n(r))})}async function MC(e,t,r={}){let a;try{a=await Hs({appId:e,trigger:t,timestamp:new Date().toISOString(),status:ae.AppBackupStatus.PENDING,type:ae.AppBackupType.BACKUP,...r})}catch(n){if(n.status===409)return;throw n}return await Dt().add({docId:a.id,docRev:a.rev,appId:e,export:{trigger:t,...r}}),await ne.events.backup.appBackupTriggered(e,a.id,ae.AppBackupType.BACKUP,t,r?.name),a.id}async function kC(e,t,r,a){let n=await qn(t),o;try{o=await Hs({appId:e,timestamp:new Date().toISOString(),status:ae.AppBackupStatus.PENDING,type:ae.AppBackupType.RESTORE,createdBy:a})}catch(s){if(s?.status===409)return;throw s}return await Dt().add({appId:e,docId:o.id,docRev:o.rev,import:{nameForBackup:r,backupId:t,createdBy:a}}),{restoreId:o.id,metadata:n}}async function GC(e,t,r){let a=ne.db.getProdAppID(e);await ne.context.doInAppContext(a,async()=>{let n=ne.context.getProdAppDB();if(!await n.exists())return;let s=await n.tryGet(ae.DocumentType.APP_METADATA);s&&(s.backupErrors||(s.backupErrors={}),s.backupErrors[t]||(s.backupErrors[t]=[]),s.backupErrors[t].push(r),await n.put(s),await ne.cache.app.invalidateAppMetadata(s.appId,s))})}var FC={isEnabled:gs,triggerAppRestore:ce(kC),triggerAppBackup:ce(MC),getBackupDownloadStream:ce(um),downloadAppBackup:ce(BC),fetchAppBackups:ce(NC),storeAppBackupMetadata:ce(Hs),updateBackupStatus:ce(PC),updateRestoreStatus:ce(UC),getAppBackup:ce(qn),updateAppBackup:ce(qC),deleteAppBackup:ce(im),deleteAppBackups:ce(DC),trackBackupError:ce(GC)},Oe=FC;var Js={};w(Js,{init:()=>zs});var W=require("@budibase/backend-core");var Fe=require("@budibase/types");var fr=P(require("fs"));async function zs(e){Dt().process(async t=>{let r=t.data;try{if(r.export)return console.log("Exporting app backup:",r.appId,r.export.trigger),WC(t,e);if(r.import)return console.log("Importing app backup:",r.appId,r.import.backupId),QC(t,e)}catch(a){W.logging.logAlert(`Failed to perform backup for app ID: ${r.appId}`,a)}})}async function jC(e){await W.db.getDB(e,{skip_setup:!0}).destroy()}async function pm(e,t,r,a){let n=W.db.getDevAppID(r),o=W.db.getProdAppID(r),s=new Date().toISOString(),i=async(p,f)=>{a?.doc?await Oe.updateBackupStatus(a.doc.id,p,f?.contents,f?.filename):await Oe.storeAppBackupMetadata({appId:o,timestamp:s,trigger:e,status:p,name:a?.name,type:Fe.AppBackupType.BACKUP,contents:f?.contents,createdBy:a?.createdBy},{filename:f?.filename})};try{let p=await a.processing.exportAppFn(n,{tar:!0}),f=await a.processing.statsFn(n),m=`${o}/backup-${s}.tar.gz`,g=W.objectStore.ObjectStoreBuckets.BACKUPS,y=fr.default.createReadStream(p);await W.objectStore.streamUpload({bucket:g,filename:m,stream:y,extra:{type:"application/gzip",metadata:{name:a?.name,trigger:e,timestamp:s,appId:o}}}),await i(Fe.AppBackupStatus.COMPLETE,{filename:m,contents:f}),fr.default.existsSync(p)&&fr.default.rmSync(p)}catch(p){W.logging.logAlert("App backup error",p),await i(Fe.AppBackupStatus.FAILED);let f=a?.doc?.id||`backup-${s}`,m=p instanceof Error?p.message:String(p);await Oe.trackBackupError(o,f,`Backup export failed: ${m}`)}}async function QC(e,t){let r=e.data,a=r.appId,n=r.import.backupId,o=r.import.nameForBackup,s=r.import.createdBy,i=W.tenancy.getTenantIDFromAppID(a);return W.tenancy.doInTenant(i,async()=>{let p=W.db.getDevAppID(a),f=`${p}_temp_${Date.now()}`,{rev:m}=await Oe.updateRestoreStatus(r.docId,r.docRev,Fe.AppBackupStatus.STARTED);await pm(Fe.AppBackupTrigger.RESTORING,i,a,{processing:t,createdBy:s,name:o});let g=await Oe.downloadAppBackup(n),y=Fe.AppBackupStatus.COMPLETE;try{await t.importAppFn(f,W.db.getDB(f),{file:{type:"application/gzip",path:g},key:g}),await jC(p),await new W.db.Replication({source:f,target:p}).replicate()}catch(I){W.logging.logAlert("App restore error",I),y=Fe.AppBackupStatus.FAILED;let C=I instanceof Error?I.message:String(I);await Oe.trackBackupError(a,n,`Backup restore failed: ${C}`)}finally{try{await W.db.getDB(f,{skip_setup:!0}).destroy()}catch{}}await Oe.updateRestoreStatus(r.docId,m,y),fr.default.existsSync(g)&&fr.default.rmSync(g,{force:!0})})}async function WC(e,t){let r=e.data,a=r.appId,n=r.export.trigger,o=r.export.name,s=W.tenancy.getTenantIDFromAppID(a);await W.tenancy.doInTenant(s,async()=>{try{let{rev:i}=await Oe.updateBackupStatus(r.docId,Fe.AppBackupStatus.STARTED);return pm(n,s,a,{processing:t,doc:{id:r.docId,rev:i},name:o})}catch(i){W.logging.logAlert("App backup error",i);let p=i instanceof Error?i.message:String(i);await Oe.trackBackupError(a,r.docId,`Backup export failed: ${p}`)}})}var $C=async e=>{am(),await zs(e.processing)},Se={...Oe,processing:Js,init:$C,getBackupQueue:Dt};var cm=async e=>{e.backups&&await Se.init(e.backups)};var ye={};w(ye,{create:()=>MM,find:()=>BM,get:()=>NM,remove:()=>GM,update:()=>kM});var PA=P($i()),st=require("@budibase/backend-core");var UA=require("@budibase/types");async function NM(e){let t=st.tenancy.getGlobalDB(),r=new st.db.QueryBuilder(t.name,UA.SearchIndex.USER);r.setIndexBuilder(st.db.searchIndexes.createUserIndex),r.setLimit(e.pageSize),r.addEqual("scimInfo.isSync",!0);for(let[n,o]of Object.entries(e.filters?.equal??{}))r.addEqual(n,o);r.setSort("_id"),r.setSkip(e.skip);let a=await r.run();return{users:a.rows,total:a.totalRows}}async function BM(e){return await st.users.getById(e)}async function MM(e){let t=await Ce.getUserByEmail(e.email);if(t){if(t.scimInfo?.isSync)throw new st.HTTPError("User is already synched",409);e={...t,scimInfo:(0,PA.default)(t.scimInfo,e.scimInfo),password:void 0,firstName:e.firstName,lastName:e.lastName,updatedAt:e.updatedAt}}return await Ce.save(e,{requirePassword:!1})}async function kM(e,t){return await Ce.save(e,{requirePassword:!1,allowChangingEmail:t?.allowChangingEmail})}async function GM(e){return await Ce.destroy(e)}var br={};w(br,{create:()=>FM});var qA=P($i());var DA=require("@budibase/backend-core");async function FM(e){let t=await Io(e.name),r;if(!t)r=(await Q.save(e)).id;else{if(t.scimInfo?.isSync)throw new DA.HTTPError("Group is already synched",409);r=t._id,t.users&&(await Q.removeUsers(r,t.users.map(n=>n._id)),delete t.users),t.scimInfo=(0,qA.default)(t.scimInfo,e.scimInfo),await Q.save(t)}return await Q.get(r)}var Bt={};w(Bt,{logRequest:()=>jM,logResponse:()=>QM});var Ki=require("@budibase/backend-core");async function jM(e){Ki.logging.logWarn("SCIM request log",e)}async function QM(e){Ki.logging.logWarn("SCIM response error",e)}var Xi={};w(Xi,{doInScimContext:()=>Yi,feature:()=>$,internalGroupOnly:()=>_a,licenseAuth:()=>MA,licensing:()=>NA,requireSCIM:()=>Hi,scimGroupOnly:()=>va,scimUserOnly:()=>Ra});var St=require("@budibase/backend-core");var Vn=require("@budibase/types"),WM=(e={checkUsersLimit:!0})=>async(t,r)=>{if((e.licensingCheck?e.licensingCheck:()=>!!t.user)(t)){if(St.env.SELF_HOSTED&&St.env.DEFAULT_LICENSE)return t.user.license=wo,r();t.user.license=await Ve.cache.getCachedLicense(t,{populateLicense:e.populateLicense,populateFreeLicense:e.populateFreeLicense}),e.checkUsersLimit&&(St.utils.isServingApp(t)||St.utils.isServingBuilder(t)||St.utils.isServingBuilderPreview(t)||St.utils.isPublicApiRequest(t))&&await ze.usageLimitIsExceeded({name:Vn.StaticQuotaName.USERS,type:Vn.QuotaUsageType.STATIC,usageChange:0})}return r()},NA=WM;var $={};w($,{requireFeature:()=>$M,requireFeatures:()=>KM});var $M=e=>async(t,r)=>{await hn(e),await r()},KM=(...e)=>async(t,r)=>{await ms(e),await r()};var Yn=require("@budibase/backend-core");var Yi=async(e,t)=>(Yn.env.DISABLE_SCIM_CALLS||await Bt.logRequest({...e.request.toJSON(),body:e.request.body}),await Yn.context.doInScimContext(async()=>{let r=await t();return await Bt.logResponse({...e.response.toJSON(),body:e.response.body}),r}));var Hi=async(e,t)=>{await As(),await t()};var BA=require("@budibase/backend-core");var Ra=e=>zi(BA.users.getById,e,!0),va=e=>zi(M.get,e,!0),_a=e=>zi(M.get,e,!1);function zi(e,t,r){return async(a,n)=>{let o=a.params[t];return typeof o!="string"&&a.throw(404),!!(await e(o)).scimInfo?.isSync!==r&&a.throw(404),n()}}var xa=require("@budibase/backend-core");var Ji=require("dd-trace");async function MA(e,t){await Ji.tracer.trace("licenseAuth",async r=>{let a=e.request.headers[xa.constants.Header.LICENSE_KEY];Array.isArray(a)&&(a=a[0]),r.addTags({licenseKey:a}),a||e.throw(403,"License key not provided");let n=await cs(a);n||(r.addTags({licenseFound:!1}),e.throw(403,"License not found or invalid")),n.tenantId||e.throw(403,"License does not have a tenant ID"),Ji.tracer.setUser({id:"anonymous",tenantId:n.tenantId}),await xa.context.doInSelfHostTenantUsingCloud(n.tenantId,async()=>{await xa.context.doInLicenseContext(n,async()=>{await t()})})})}var iu={};w(iu,{appBackups:()=>vb,auditLogs:()=>yb,environmentVariables:()=>ib,groups:()=>XA,scim:()=>rI,users:()=>iI});var kA=require("@budibase/backend-core");async function GA(e){let t=e.request.body;if(t.name=t.name.trim(),delete t.roles,t._id){let a=await bt(t._id);t.roles=a.roles,t.scimInfo=a.scimInfo}let r=await dr(t);e.body={_id:r.id,_rev:r.rev}}async function FA(e){let t=e.params.groupId,r=e.request.body.add,a=e.request.body.remove;(r&&!Array.isArray(r)||a&&!Array.isArray(a))&&e.throw(400,"Must supply a list of users to add or to remove");let n,o;r&&(n=await vn(t,r)),a&&(o=await xs(t,a)),e.body={added:n,removed:o}}async function jA(e){let t=e.params.groupId,r=e.request.body.add,a=e.request.body.remove;(r&&!Array.isArray(r)||a&&!Array.isArray(a))&&e.throw(400,"Must supply a list of objects, with appId and roleId to add or remove"),e.body=await Cs(t,{appsToAdd:r,appsToRemove:a})}async function QA(e){e.body={data:await ha()}}async function WA(e){let{groupId:t,rev:r}=e.params;try{await _s(t,r),e.body={message:"Group deleted successfully"}}catch(a){e.throw(a.status,a)}}async function $A(e){try{e.body=await bt(e.params.groupId)}catch(t){e.throw(t.status,t)}}async function KA(e){let{pageSize:t=10,bookmark:r,emailSearch:a}=e.request.query,n=e.params.groupId,o={limit:t+1},s=await Wa(n,{...o,emailSearch:a,bookmark:r}),i=a?s[t]?.email:s[t]?._id,p=!!i;e.body={users:s.slice(0,t),bookmark:i,hasNextPage:p}}async function VA(e){let{groupId:t,appId:r}=e.params;await Os(t,r),e.body={message:"Group app builder access updated."}}async function YA(e){let{groupId:t,appId:r}=e.params;await Ls(t,r),e.body={message:"group app builder access removed."}}async function HA(e){let{groupId:t}=e.params,{csvContent:r}=e.request.body;(r===void 0||r.trim().length===0)&&e.throw(400,"CSV is empty");let a=await kA.csv.jsonFromCsvString(r,{allowSingleColumn:!0});(!a||a.length===0)&&e.throw(400,"CSV file is invalid");let o=Object.keys(a[0]).find(g=>/^(email|e-mail|email address|mail|e_mail)$/i.test(g.trim()));o||e.throw(400,"CSV file must contain an email column");let s=Array.from(new Set(a.map(g=>g[o]).filter(g=>g&&typeof g=="string"&&g.trim().length>0).map(g=>g.trim())));s.length===0&&e.throw(400,"No valid email addresses found in CSV");try{await bt(t)}catch(g){if(g.status===404)e.throw(404,"Group not found");else throw g}let i=[],p=[],f=[],m=await Promise.all(s.map(g=>Ce.getUserByEmail(g)));for(let g of s){let y=m.find(I=>I?.email===g);y?(i.push({_id:y._id,email:y.email}),f.push(y._id)):p.push({email:g,reason:"User not found"})}f.length>0&&await vn(t,f),e.body={added:i,skipped:p}}var zA=P(require("@koa/router")),le=P(require("joi"));var we=require("@budibase/types"),Le=require("@budibase/backend-core"),JA=new zA.default;function YM(){return Le.auth.joiValidator.body(le.default.object({_id:le.default.string().optional(),_rev:le.default.string().optional(),color:le.default.string().required(),icon:le.default.string().required(),name:le.default.string().trim().required().max(50),role:le.default.string().optional(),users:le.default.array().optional(),apps:le.default.array().optional(),roles:le.default.object().optional(),createdAt:le.default.string().optional(),updatedAt:le.default.string().optional()}).required())}JA.post("/api/global/groups",Le.auth.adminOnly,$.requireFeature(we.Feature.USER_GROUPS),YM(),GA).get("/api/global/groups",$.requireFeature(we.Feature.USER_GROUPS),QA).delete("/api/global/groups/:groupId/:rev",$.requireFeature(we.Feature.USER_GROUPS),Le.auth.adminOnly,_a("groupId"),WA).get("/api/global/groups/:groupId",$.requireFeature(we.Feature.USER_GROUPS),Le.auth.builderOrAdmin,$A).get("/api/global/groups/:groupId/users",$.requireFeature(we.Feature.USER_GROUPS),Le.auth.builderOrAdmin,KA).post("/api/global/groups/:groupId/users",Le.auth.adminOnly,$.requireFeature(we.Feature.USER_GROUPS),_a("groupId"),FA).post("/api/global/groups/:groupId/users/bulk",Le.auth.adminOnly,$.requireFeature(we.Feature.USER_GROUPS),_a("groupId"),Le.auth.joiValidator.body(le.default.object({csvContent:le.default.string().required()}).required()),HA).post("/api/global/groups/:groupId/apps",Le.auth.builderOrAdmin,$.requireFeature(we.Feature.USER_GROUPS),jA).post("/api/global/groups/:groupId/app/:appId/builder",Le.auth.builderOrAdmin,$.requireFeatures(we.Feature.USER_GROUPS,we.Feature.APP_BUILDERS),VA).delete("/api/global/groups/:groupId/app/:appId/builder",Le.auth.builderOrAdmin,$.requireFeatures(we.Feature.USER_GROUPS,we.Feature.APP_BUILDERS),YA);var XA=JA;var Zi=require("@budibase/types");var eu=require("@budibase/backend-core");async function ZA(e){e.body={encryptionKeyAvailable:Je.isEncryptionKeyAvailable()}}async function eb(e){e.body={variables:await Je.fetch()}}async function tb(e){let{name:t,production:r,development:a}=e.request.body;await Je.update(t,{production:r,development:a});let n=[Zi.AppEnvironment.PRODUCTION];r!==a&&n.push(Zi.AppEnvironment.DEVELOPMENT),await eu.events.environmentVariable.created(t,n),e.body={message:`Environment variable "${t}" created.`}}async function rb(e){let{production:t,development:r}=e.request.body,a=e.params.varName;await Je.update(a,{production:t,development:r}),e.body={message:`Environment variable "${a}" updated.`}}async function ab(e){let t=e.params.varName;await Je.remove(t),await eu.events.environmentVariable.deleted(t),e.body={message:`Environment variable "${t}" deleted.`}}var Mt=require("@budibase/backend-core"),ob=P(require("@koa/router")),Ca=P(require("joi")),sb=new ob.default;function nb(){return Mt.auth.joiValidator.body(Ca.default.object({name:Ca.default.string().optional(),production:Ca.default.string().required(),development:Ca.default.string().required()}))}sb.get("/api/env/variables/status",Mt.auth.builderOrAdmin,ZA).get("/api/env/variables",Mt.auth.builderOrAdmin,eb).post("/api/env/variables",Mt.auth.builderOrAdmin,nb(),tb).patch("/api/env/variables/:varName",Mt.auth.builderOrAdmin,nb(),rb).delete("/api/env/variables/:varName",Mt.auth.builderOrAdmin,ab);var ib=sb;var tu=require("@budibase/backend-core");async function ub(e){let t=e.request.body,r=await It.fetch(t);await tu.events.auditLog.filtered(t),e.body=r}async function pb(e){let t=e.request.body,{stream:r}=It.download(t);await tu.events.auditLog.downloaded(t),e.attachment(`audit-logs-${Date.now()}.log`),e.body=r}async function cb(e){e.body={events:It.definitions()}}var fb=require("@budibase/types"),kt=require("@budibase/backend-core"),mb=P(require("@koa/router")),Pe=P(require("joi"));function lb(){return kt.auth.joiValidator.body(Pe.default.object({userIds:Pe.default.array().items(Pe.default.string()).optional(),appIds:Pe.default.array().items(Pe.default.string()).optional(),events:Pe.default.array().items(Pe.default.string().valid(...Object.values(fb.Event))).optional(),startDate:Pe.default.string().optional().allow(""),endDate:Pe.default.string().optional().allow(""),fullSearch:Pe.default.string().optional().allow(""),bookmark:Pe.default.number()}))}var gb=new mb.default;gb.post("/api/global/auditlogs/search",kt.auth.adminOnly,lb(),ub).get("/api/global/auditlogs/download",kt.auth.adminOnly,kt.middleware.querystringToBody,lb(),pb).get("/api/global/auditlogs/definitions",kt.auth.adminOnly,cb);var yb=gb;var ru=require("@budibase/types");var Hn=require("@budibase/backend-core");async function Gt(e,t){t||e.throw(400,"App ID missing"),await Yt.appExists(t)||e.throw(400,`Provided app ID: ${t} - is invalid.`)}async function hb(e){let t=e.params.appId;await Gt(e,t);let r=e.request.body,a=e.user?._id,n=await Se.triggerAppBackup(t,ru.AppBackupTrigger.MANUAL,{name:r.name,createdBy:a});n||e.throw(500,"Unable to start backup."),e.body={backupId:n,message:"Backup triggered - process starting."}}async function Ab(e){let t=e.params.appId;await Gt(e,t);let r=e.params.backupId,a=e.request.body.name,n=await Se.triggerAppRestore(t,r,a,e.user?._id);n||e.throw(500,"Unable to start restore."),await Hn.events.backup.appBackupRestored(n.metadata),e.body={restoredId:n?.restoreId,message:"Restore triggered - process starting."}}async function bb(e){let t=e.params.appId;await Gt(e,t);let r=e.params.backupId;await Se.deleteAppBackup(r),e.body={message:"Backup deleted successfully."}}async function Ib(e){let t=Hn.context.getAppId();await Gt(e,t);let{backupIds:r}=e.request.body;(!Array.isArray(r)||r.length===0)&&e.throw(400,"backupIds must be a non-empty array");let a=await Se.deleteAppBackups(r),n=a.filter(s=>s.success).length,o=a.length-n;e.body={message:`${n} backups deleted successfully${o>0?`, ${o} failed`:""}.`,results:a,successCount:n,failureCount:o}}async function Sb(e){let t=e.params.appId;await Gt(e,t);let r=e.request.body;r?.trigger&&(r.trigger=r.trigger.toLowerCase(),Object.values(ru.AppBackupTrigger).includes(r.trigger)||e.throw(400,"Provided trigger is not a valid option.")),e.body=await Se.fetchAppBackups(t,{paginate:!0,...r})}async function wb(e){let t=e.params.appId;await Gt(e,t);let r=e.params.backupId,a=e.request.body;e.body=await Se.updateAppBackup(r,a.name)}async function Tb(e){let t=e.params.appId;await Gt(e,t);let r=e.params.backupId,{metadata:a,stream:n}=await Se.getBackupDownloadStream(r);e.attachment(`backup-${a.timestamp}.tar.gz`),e.body=n}var Eb=P(require("@koa/router")),Ft=P(require("joi")),zn=require("@budibase/types"),it=require("@budibase/backend-core"),Rb=new Eb.default;function XM(){return it.auth.joiValidator.body(Ft.default.object({trigger:Ft.default.string().valid(...Object.values(zn.AppBackupTrigger)),type:Ft.default.string().valid(...Object.values(zn.AppBackupType)),startDate:Ft.default.date(),endDate:Ft.default.date(),page:Ft.default.string()}))}Rb.post("/api/apps/:appId/backups",it.auth.builderOrAdmin,hb).post("/api/apps/:appId/backups/search",it.auth.builderOrAdmin,XM(),Sb).get("/api/apps/:appId/backups/:backupId/file",it.auth.builderOrAdmin,Tb).patch("/api/apps/:appId/backups/:backupId",it.auth.builderOrAdmin,wb).delete("/api/apps/:appId/backups/:backupId",it.auth.builderOrAdmin,bb).delete("/api/apps/:appId/backups",it.auth.builderOrAdmin,Ib).post("/api/apps/:appId/backups/:backupId/import",it.auth.builderOrAdmin,Ab);var vb=Rb;var tI=P(require("@koa/router"));var Jn=require("scim-patch");var xb=require("@budibase/backend-core");function _b(e,t){let r=e.request.query[t];if(r!==void 0)return+r}var Cb=async e=>{let t=_b(e,"pageSize")??20,r=_b(e,"startIndex"),a;e.request.query.filter&&(a=Y.user.userFilters(e.request.query.filter));let n=await ye.get({pageSize:t,skip:r,filters:a});e.body={schemas:["urn:ietf:params:scim:api:messages:2.0:ListResponse"],totalResults:n.total,Resources:n.users.map(Y.user.toScimUserResponse),startIndex:(r||0)+1,itemsPerPage:t}},Ob=async e=>{let{id:t}=e.params;typeof t!="string"&&e.throw(404);let r=await ye.find(t);e.body=Y.user.toScimUserResponse(r)},Lb=async e=>{let t=Y.user.fromScimUser(e.request.body);try{let r=await ye.create(t);e.body=Y.user.toScimUserResponse(r)}catch(r){throw r instanceof xb.EmailUnavailableError&&e.throw(409,"Email already in use"),r}};function ZM(e){let t=e.Operations.find(r=>(r.op==="Replace"||r.op==="replace")&&r.path==="active");return t?t.value===!1||t.value?.toLowerCase?.()==="false":!1}var Pb=async e=>{let t=await ye.find(e.params.id);t||e.throw(404);let r=Y.user.toScimUserResponse(t),a=e.request.body;try{(0,Jn.patchBodyValidation)(a)}catch{}if(ZM(a))return au(e);let n;try{n=(0,Jn.scimPatch)(r,a.Operations)}catch{}n||e.throw(500);let o=Y.user.fromScimUser(n);await ye.update(o,{allowChangingEmail:!0}),e.body=Y.user.toScimUserResponse(o)},au=async e=>{let{id:t}=e.params;typeof t!="string"&&e.throw(404),await ye.remove(t),e.status=204};var Vb=P(Kb()),Yb=require("@budibase/shared-core"),Xn=require("scim-patch");var Zn=require("scim2-parse-filter");function Hb(e,t){for(let r of t.split(","))delete e[r]}var zb=async e=>{let r=(await Q.fetch()).filter(o=>o.scimInfo?.isSync).map(Y.group.toScimGroupResponse),{filter:a,excludedAttributes:n}=e.request.query;if(a){let o=(0,Zn.filter)((0,Zn.parse)(a));r=r.filter(o)}n&&r.forEach(o=>{Hb(o,n)}),e.body={schemas:["urn:ietf:params:scim:api:messages:2.0:ListResponse"],totalResults:r.length,Resources:r,startIndex:1,itemsPerPage:r.length}},Jb=async e=>{let t=Y.group.fromScimGroup(e.request.body),r=await br.create(t);e.body=Y.group.toScimGroupResponse(r)},Xb=async e=>{let{id:t}=e.params,r=await Q.get(t),a=Y.group.toScimGroupResponse(r),{excludedAttributes:n}=e.request.query;n&&Hb(a,n),e.body=a},Zb=async e=>{let{id:t}=e.params,r=await Q.get(t);await Q.remove(t,r._rev),e.status=204},eI=async e=>{let{id:t}=e.params,r=await Q.get(t),a=Y.group.toScimGroupResponse(r),n=e.request.body;try{(0,Xn.patchBodyValidation)(n)}catch{e.throw(400)}let{true:o,false:s}=(0,Vb.default)(n.Operations,i=>i.path==="members");if(s?.length){let i=(0,Xn.scimPatch)(a,s);i||e.throw(500);let p={...Y.group.fromScimGroup(i),_rev:r._rev};await Q.save(p)}if(o?.length){let i=[],p=[];for(let{op:f,value:m}of o)switch(f){case"add":case"Add":for(let g of m)i.push(await ye.find(g.value));break;case"remove":case"Remove":for(let g of m)p.push(await ye.find(g.value));break;case"replace":case"Replace":throw new Error("Replacing members is not allowed");default:Yb.utils.unreachable(f)}i.length&&await Q.addUsers(t,i.map(f=>f._id)),p.length&&await Q.removeUsers(t,p.map(f=>f._id))}e.body=Y.group.toScimGroupResponse(await Q.get(t))};var Oa=require("@budibase/types"),Te=new tI.default({prefix:"/api/global/scim/v2"});Te.use(Hi);Te.use(Yi);Te.get("/users",Cb);Te.get("/users/:id",Ra("id"),Ob);Te.post("/users",Lb);Te.patch("/users/:id",Ra("id"),Pb);Te.delete("/users/:id",Ra("id"),au);Te.get("/groups",zb);Te.post("/groups",$.requireFeature(Oa.Feature.USER_GROUPS),Jb);Te.get("/groups/:id",$.requireFeature(Oa.Feature.USER_GROUPS),va("id"),Xb);Te.delete("/groups/:id",$.requireFeature(Oa.Feature.USER_GROUPS),va("id"),Zb);Te.patch("/groups/:id",$.requireFeature(Oa.Feature.USER_GROUPS),va("id"),eI);var rI=Te;var oI=P(require("@koa/router"));var nu=require("@budibase/backend-core");async function aI(e){let{userId:t,appId:r}=e.params,a=await nt.db.getUser(t);if(nu.users.isGlobalBuilder(a)){e.body={message:"User already admin - no permissions updated."};return}await nt.addAppBuilder(a,r),e.body={message:`User "${a.email}" app builder access updated.`}}async function nI(e){let{userId:t,appId:r}=e.params,a=await nt.db.getUser(t);if(nu.users.isGlobalBuilder(a)){e.body={message:"User already admin - no permissions removed."};return}await nt.removeAppBuilder(a,r),e.body={message:`User "${a.email}" app builder access removed.`}}var ou=require("@budibase/types"),su=require("@budibase/backend-core"),sI=new oI.default;sI.post("/api/global/users/:userId/app/:appId/builder",su.auth.builderOrAdmin,$.requireFeatures(ou.Feature.APP_BUILDERS),aI).delete("/api/global/users/:userId/app/:appId/builder",su.auth.builderOrAdmin,$.requireFeatures(ou.Feature.APP_BUILDERS),nI);var iI=sI;var Y={};w(Y,{group:()=>pu,user:()=>uu});var uu={};w(uu,{fromScimUser:()=>xk,toScimUserResponse:()=>Rk,userFilters:()=>Ck});var eo=require("@budibase/types"),uI=require("scim2-parse-filter"),pI=require("@budibase/backend-core"),cI=require("@budibase/shared-core"),{unreachable:Ek}=cI.utils,Rk=e=>{let{isSync:t,roles:r,...a}=e.scimInfo||{},n={...a,schemas:["urn:ietf:params:scim:schemas:core:2.0:User"],id:e._id,meta:{resourceType:"User",created:new Date(e.createdAt),lastModified:new Date(e.updatedAt)},active:e.status===eo.UserStatus.ACTIVE};return(e.firstName||e.lastName)&&(n.name={formatted:[e.firstName,e.lastName].filter(o=>o).join(" "),familyName:e.lastName,givenName:e.firstName}),n},vk=e=>!!e?.id;function _k(e){if(pI.utils.validEmail(e.userName))return e.userName;if(e.emails)return e.emails.find(t=>t.primary)?.value||e.emails[0]?.value}var xk=e=>{let t=vk(e)?e:void 0,r=_k(e);if(!r)throw new Error("Email is required");let a;switch(e.active){case"True":case"true":case!0:a=!0;break;case"False":case"false":case!1:a=!1;break;default:Ek(e.active)}let n,o;return e.name?.givenName?(n=e.name?.givenName,o=e.name?.familyName):n=e.displayName,{tenantId:"",_id:t?.id,userId:t?.id,email:r,firstName:n,lastName:o,scimInfo:{...e,isSync:!0},roles:{},status:a?eo.UserStatus.ACTIVE:eo.UserStatus.INACTIVE,createdAt:t?.meta.created.getTime(),updatedAt:t?.meta.lastModified.toISOString()}},Ck=e=>{let t={equal:{}},r=(0,uI.parse)(e);function a(n){switch(n.op){case"eq":{let o=n.attrPath,s;switch(o){case"emails.value":s="email";break;default:s=`scimInfo.${o}`}t.equal[s]=n.compValue;break}case"and":for(let o of n.filters)a(o);break;default:console.warn("Filter not handled",{filter:n})}}return a(r),t};var pu={};w(pu,{fromScimGroup:()=>Pk,toScimGroupResponse:()=>Ok});var Ok=e=>({schemas:["urn:ietf:params:scim:schemas:core:2.0:Group"],id:e._id,externalId:e.scimInfo.externalId,meta:{resourceType:"Group",created:new Date(e.createdAt),lastModified:new Date(e.updatedAt)},displayName:e.name,members:e.users?.map(t=>({value:t._id}))}),Lk=e=>!!e?.id,Pk=e=>{let t=Lk(e)?e:void 0;return{_id:t?.id,name:e.displayName,scimInfo:{externalId:e.externalId,isSync:!0},icon:"UserGroup",color:"var(--spectrum-global-color-blue-600)",createdAt:t?.meta.created.getTime(),updatedAt:t?.meta.lastModified.toISOString()}};var Uu={};w(Uu,{LLM:()=>Xe,LLMRequest:()=>K,TableGeneration:()=>Pu,agentHistoryTitleSystemPrompt:()=>Qk,agentSystemPrompt:()=>jk,aiColumnSchemas:()=>Ou,aiTableResponseToTableSchema:()=>vu,appendAIColumns:()=>_u,classifyText:()=>du,cleanData:()=>fu,extractFileData:()=>Mk,generateAIColumns:()=>Eu,generateCode:()=>Fk,generateCronExpression:()=>mu,generateData:()=>Ru,generateJs:()=>Au,generateSQL:()=>Gk,generateTables:()=>Tu,generationStructure:()=>Cu,getLLM:()=>Ua,getLLMConfig:()=>wu,getLLMOrThrow:()=>SI,normalizeContentType:()=>cu,parseResponseFormat:()=>ro,sanitiseToolName:()=>Uk,searchWeb:()=>hu,sentimentAnalysis:()=>yu,summarizeText:()=>to,tableDataStructuredOutput:()=>Lu,translate:()=>gu});var La=require("@budibase/types");function Uk(e){if(e.length>64)throw new Error("Tool name must be under 64 characters long");return e.replace(/[^a-zA-Z0-9_-]/g,"_")}function cu(e){return e?e.includes("/")?e:{[La.SupportedFileType.PDF]:"application/pdf",[La.SupportedFileType.JPG]:"image/jpeg",[La.SupportedFileType.JPEG]:"image/jpeg",[La.SupportedFileType.PNG]:"image/png"}[e.toLowerCase()]||"application/octet-stream":"application/octet-stream"}var io=require("@budibase/types");var Ze=require("@budibase/backend-core"),hI=require("@budibase/types");var ao=P(require("openai"));var wt=require("@budibase/types");var lI=require("@budibase/shared-core");var Tt=P(require("dd-trace"));function lu(e,t){return t.map(r=>e[r]).join(" ")}var Xe=class{constructor({model:t,apiKey:r,maxTokens:a}){this._model=t,this._apiKey=r,this._maxTokens=a??parseInt(process.env.BUDIBASE_AI_MAX_PROMPT_TOKENS||"1000")}get model(){return this._model}get apiKey(){return this._apiKey}get maxTokens(){return this._maxTokens}async prompt(t){return await Tt.default.trace("prompt",async()=>{let r=typeof t=="string"?new K().addUserMessage(t):t,{messages:a,tokensUsed:n}=await Tt.default.trace("chatCompletion",()=>this.chatCompletion(r));return!a||a.length===0?{message:"",tokensUsed:n}:{message:a[a.length-1].content||"",tokensUsed:n}})}async chat(t){return await Tt.default.trace("chat",async()=>await this.chatCompletion(t))}async*chatStream(t){yield*this.chatCompletionStream(t)}async summarizeText(t){return Tt.default.trace("summarizeText",()=>this.prompt(to(t)))}async generateCronExpression(t){return Tt.default.trace("generateCronExpression",()=>this.prompt(mu(t)))}async operation(t,r){return Tt.default.trace("operation",a=>{a.addTags({operation:t.operation,rowId:r.id});let n=this.promptForOperation(t,r);return this.prompt(n)})}promptForOperation(t,r){let{operation:a,column:n,columns:o,language:s,categories:i,prompt:p}=t;switch(a){case wt.AIOperationEnum.SUMMARISE_TEXT:return to(lu(r,o));case wt.AIOperationEnum.CLEAN_DATA:return fu(r[n]);case wt.AIOperationEnum.TRANSLATE:return gu(r[n],s);case wt.AIOperationEnum.CATEGORISE_TEXT:if(!i)throw Error("No categories provided for categorise text operation. Please provide categories.");return du(lu(r,o),i.split(","));case wt.AIOperationEnum.SENTIMENT_ANALYSIS:return yu(r[n]);case wt.AIOperationEnum.PROMPT:return p;case wt.AIOperationEnum.SEARCH_WEB:return hu(lu(r,o));default:throw lI.utils.unreachable(a)}}async generateJs(t,r){return await Tt.default.trace("generateJs",async()=>{let{bindings:a=[],snippets:n=[]}=r||{};return await this.prompt(Au(a,n).addUserMessage(t))})}};var fI=require("@budibase/types"),bu=require("openai/helpers/zod");var mI=(a=>(a.GPT_5_MINI="gpt-5-mini",a.GPT_5="gpt-5",a.GPT_5_NANO="gpt-5-nano",a))(mI||{});function ro(e){if(e)return e==="text"?{type:"text"}:e==="json"?{type:"json_object"}:e}function dI(e){if(!e)return 0;let t=e.prompt_tokens;return e.completion_tokens*3+t}var Ue=class extends Xe{constructor(r){super(r);this.client=this.getClient(r)}getClient(r){if(!r.apiKey)throw new Error("No OpenAI API key found");return new ao.default({apiKey:r.apiKey})}async uploadFile(r,a,n){let o=cu(n);if(fI.ImageContentTypes.includes(o.toLowerCase())){let p;if(Buffer.isBuffer(r))p=r;else{let m=[];for await(let g of r)m.push(g);p=Buffer.concat(m)}let f=p.toString("base64");return`data:${o};base64,${f}`}let s=await(0,ao.toFile)(r,a);return(await this.client.files.create({file:s,purpose:"assistants"})).id}async chatCompletion(r){let a={model:this.model,messages:r.messages,max_completion_tokens:this._maxTokens,response_format:ro(r.format)};Object.values(mI).includes(this.model)&&(a.verbosity="low",a.reasoning_effort="minimal"),r.tools&&r.tools.length>0&&(a.tool_choice="auto",a.tools=r.tools.map(bu.zodFunction));let n=await this.client.chat.completions.create(a),o=n?.choices?.[0]?.message;if(o?.tool_calls){r.addMessage(o);let s=[];for(let i of o.tool_calls){if(i.type!=="function"||!i.function){console.warn(`[OPENAI TOOL WARN] Unsupported tool call type: ${i.type}`);continue}let p=i.function.name,f=r.findTool(p);if(!f)throw new Error(`Tool ${p} not found in prompt tools`);let m=JSON.parse(i.function.arguments);s.push(f.handler(m).then(g=>({role:"tool",tool_call_id:i.id,content:g})).catch(g=>(console.error(`[OPENAI TOOL ERROR] Tool ${p} failed in OpenAI handler:`,g),{role:"tool",tool_call_id:i.id,content:`Error: ${g.message}`})))}return r.addMessages(await Promise.all(s)),this.chatCompletion(r)}else{if(o?.content)return{messages:[...r.messages,{role:o.role,content:o.content}],tokensUsed:dI(n.usage)};throw new Error("No response found")}}async*chatCompletionStream(r){let a={model:this.model,messages:r.messages,max_tokens:this.maxTokens,response_format:ro(r.format),stream:!0};r.tools&&r.tools.length>0&&(a.tool_choice="auto",a.tools=r.tools.map(bu.zodFunction));try{let n=await this.client.chat.completions.create(a),o=null,s="",i=null;for await(let f of n){let m=f?.choices?.[0]?.delta;if(m){if(m.content&&(s+=m.content,yield{type:"content",content:m.content}),m.tool_calls&&m.tool_calls.length>0){let g=m.tool_calls[0];g.id?(o={id:g.id,name:g.function?.name||"",arguments:g.function?.arguments||""},yield{type:"tool_call_start",toolCall:{id:o.id,name:o.name,arguments:o.arguments}}):o&&g.function?.arguments&&(o.arguments+=g.function.arguments,yield{type:"tool_call_start",toolCall:{id:o.id,name:o.name,arguments:o.arguments}})}f.usage&&(i=f.usage)}}let p=i?dI(i):0;if(o){r.addMessage({role:"assistant",content:"",tool_calls:[{id:o.id,type:"function",function:{name:o.name,arguments:o.arguments}}]});let f=r.findTool(o.name);if(f)try{let m=JSON.parse(o.arguments),g=await f.handler(m);yield{type:"tool_call_result",toolResult:{id:o.id,result:g}},r.addMessage({role:"tool",tool_call_id:o.id,content:g}),yield*this.chatCompletionStream(r);return}catch(m){yield{type:"tool_call_result",toolResult:{id:o.id,result:`Error: ${m.message}`,error:m.message}},r.addMessage({role:"tool",tool_call_id:o.id,content:`Error: ${m.message}`}),yield*this.chatCompletionStream(r);return}else{let m=`Tool '${o.name}' not found`;yield{type:"tool_call_result",toolResult:{id:o.id,result:m,error:m}},r.addMessage({role:"tool",tool_call_id:o.id,content:m}),yield*this.chatCompletionStream(r);return}}s&&r.addMessage({role:"assistant",content:s}),yield{type:"done",messages:r.messages,tokensUsed:p}}catch(n){yield{type:"error",content:n.message}}}};var ee=require("@budibase/backend-core"),gI=require("@budibase/types");var Iu=require("dd-trace"),no=class extends Xe{async prompt(t){let r=await super.prompt(t);return r.tokensUsed&&await En(r.tokensUsed),r}async chat(t){let r=await super.chat(t);return r.tokensUsed&&await En(r.tokensUsed),r}async uploadFile(t,r,a){return ee.env.SELF_HOSTED?this.uploadFileSelfHost(t,r,a):this.uploadFileCloud(t,r,a)}async uploadFileCloud(t,r,a){return new Ue({apiKey:ee.env.OPENAI_API_KEY,model:this.model,max_completion_tokens:this.maxTokens}).uploadFile(t,r,a)}async uploadFileSelfHost(t,r,a){let n;if(Buffer.isBuffer(t))n=t;else{let p=[];for await(let f of t)p.push(f);n=Buffer.concat(p)}let o=n.toString("base64");if(a&&gI.ImageContentTypes.includes(a.toLowerCase()))return`data:image/jpeg;base64,${o}`;if(!ee.env.BUDICLOUD_URL)throw new Error("No Budibase URL found");if(!this._apiKey){let p=await gn();if(!p)throw new Error("No license key found");this._apiKey=p}let s=await fetch(`${ee.env.BUDICLOUD_URL}/api/ai/upload-file`,{method:"POST",headers:{"Content-Type":"application/json",[ee.constants.Header.LICENSE_KEY]:this._apiKey},body:JSON.stringify({data:o,filename:r,contentType:a})});if(!s.ok)throw await ee.HTTPError.fromResponse(s);return(await s.json()).fileId}async chatCompletion(t){return ee.env.SELF_HOSTED?this.chatCompletionSelfHost(t):this.chatCompletionCloud(t)}async chatCompletionCloud(t){return await Iu.tracer.trace("chatCompletionCloud",async()=>await new Ue({apiKey:ee.env.OPENAI_API_KEY,model:this.model,max_completion_tokens:this.maxTokens}).chatCompletion(t))}async chatCompletionSelfHost(t){return await Iu.tracer.trace("chatCompletionSelfHost",async r=>{if(!ee.env.BUDICLOUD_URL)throw new Error("No Budibase URL found");if(r.addTags({budicloudUrl:ee.env.BUDICLOUD_URL}),!this._apiKey){let o=await gn();if(!o)throw new Error("No license key found");this._apiKey=o,r.addTags({licenseKey:this._apiKey})}let a={messages:t.messages,format:t.format,useTools:t.tools.length>0},n=await fetch(`${ee.env.BUDICLOUD_URL}/api/ai/chat`,{method:"POST",headers:{"Content-Type":"application/json",[ee.constants.Header.LICENSE_KEY]:this._apiKey},body:JSON.stringify(a)});if(!n.ok)throw await ee.HTTPError.fromResponse(n);return await n.json()})}async*chatCompletionStream(t){ee.env.SELF_HOSTED?yield*this.chatCompletionStreamSelfHost(t):yield*this.chatCompletionStreamCloud(t)}async*chatCompletionStreamCloud(t){yield*new Ue({apiKey:ee.env.OPENAI_API_KEY,model:this.model,max_completion_tokens:this.maxTokens}).chatCompletionStream(t)}async*chatCompletionStreamSelfHost(t){try{let r=await this.chatCompletionSelfHost(t);if(r.messages.length>0){let a=r.messages[r.messages.length-1];a.content&&(yield{type:"content",content:a.content})}yield{type:"done",messages:r.messages,tokensUsed:r.tokensUsed}}catch(r){yield{type:"error",content:r.message}}}};var Pa=require("dd-trace");var Su=P(require("@anthropic-ai/sdk"));function qk(e){if(!e)return 0;let t=e.input_tokens;return e.output_tokens*3+t}var oo=class extends Xe{constructor(r){super(r);this.client=new Su.default({apiKey:r.apiKey})}firstTextBlock(r){for(let a of r.content)if(a.type==="text")return a.text}async uploadFile(r,a,n){throw new Error("File upload not supported for this LLM provider")}async chatCompletion(r){try{let a=await this.client.messages.create({model:this.model,messages:r.messages.map(({content:o})=>{if(o==null)return{role:"user",content:""};if(typeof o=="string")return{role:"user",content:o};let s="";for(let i of o)i.type==="text"?s+=i.text:["image_url","input_audio","file"].includes(i.type);return{role:"user",content:s}}),max_tokens:this.maxTokens}),n=this.firstTextBlock(a)||"";return{messages:[...r.messages,{role:"assistant",content:n}],tokensUsed:qk(a.usage)}}catch(a){throw a instanceof Su.default.APIError&&console.error(`Anthropic Prompt failed with error ${a.name} and status: ${a.status}`),a}}async*chatCompletionStream(r){try{let a=await this.chatCompletion(r);if(a.messages.length>0){let n=a.messages[a.messages.length-1];n.content&&(yield{type:"content",content:n.content})}yield{type:"done",messages:a.messages,tokensUsed:a.tokensUsed}}catch(a){yield{type:"error",content:a.message}}}};var AI=require("zod"),bI=require("openai/helpers/zod");var yI=require("openai"),so=class extends Ue{getClient(t){if(!t.apiKey)throw new Error("No Azure OpenAI API key found");if(!t.model)throw new Error("No Azure OpenAI model specified");return new yI.AzureOpenAI({apiKey:t.apiKey,apiVersion:"2024-10-01-preview",baseURL:t.baseUrl})}};var II="gpt-5-mini",Dk={OpenAI:Ue,TogetherAI:Ue,AzureOpenAI:so,Custom:Ue,Anthropic:oo,BudibaseAI:no};async function Nk(){return await Pa.tracer.trace("getAIConfig",async e=>{let t={type:hI.ConfigType.AI,config:{}};if(!Ze.context.isSelfHostUsingCloud()){let a=await Ze.configs.getAIConfig();a&&(t=a)}await bs(t);let r=Object.values(t.config).find(a=>a.active&&a.isDefault);if(!r){e.addTags({enabled:!1,reason:"no provider found"});return}return e.addTags({enabled:!0}),{provider:r.provider,model:r.defaultModel||II,apiKey:r.apiKey,baseUrl:r.baseUrl}})}async function Bk(){return Pa.tracer.trace("getSelfHostOpenAIKeyConfig",e=>{if(!Ze.env.SELF_HOSTED){e.addTags({enabled:!1,reason:"not self host"});return}if(!Ze.env.OPENAI_API_KEY){e.addTags({enabled:!1,reason:"no OPENAI_API_KEY"});return}return e.addTags({enabled:!0}),{provider:"OpenAI",model:II,apiKey:Ze.env.OPENAI_API_KEY}})}async function wu(){return Pa.tracer.trace("getLLMConfig",async()=>await Nk()||await Bk())}async function Ua(e){return await Pa.tracer.trace("getLLM",async t=>{let{model:r,maxTokens:a}=e||{},n=await wu();if(!n){t.addTags({enabled:!1,reason:"no config found"});return}r&&(n.model=r),a&&(n.maxTokens=a);let o=Dk[n.provider];if(!o){t.addTags({enabled:!1,reason:"no provider found",provider:n.provider});return}return new o(n)})}async function SI(){let e=await Ua();if(!e)throw new Ze.HTTPError("No available LLM configurations",500);return e}var K=class e{constructor(){this.messages=[];this.tools=[]}addTool(t){return this.tools.push(t),this}addTools(t){return this.tools.push(...t),this}findTool(t){return this.tools.find(r=>r.name===t)}withFormat(t){return t instanceof AI.z.ZodType?this.format=(0,bI.zodResponseFormat)(t,"key"):this.format=t,this}addMessage(t){return this.messages.push(t),this}addMessages(t){return this.messages.push(...t),this}addUserMessage(t){return this.messages.push({role:"user",content:t}),this}addSystemMessage(t){return this.messages.push({role:"system",content:t}),this}static fromRequest(t){let r=new e;return t.messages&&r.addMessages(t.messages),t.format&&r.withFormat(t.format),r}};var ut=require("zod");function to(e,t){let r=`Summarize this text:
|
|
38
|
+
`;n.write(i)}}),r.on("end",()=>{n.end()}),{promise:a,stream:n}}var me=require("@budibase/backend-core");var Ln=require("@budibase/types"),Ia=require("@budibase/string-templates"),Sa=require("@budibase/backend-core"),bC=Sa.constants.MIN_VALID_DATE.toISOString(),IC=Sa.constants.MAX_VALID_DATE.toISOString();function Gs(e){return(e.startDate||e.endDate)&&(e.startDate=e.startDate||bC,e.endDate=e.endDate||IC),e}async function em(e){Array.isArray(e.appIds)&&(e.appIds=e.appIds.map(a=>Sa.db.getProdAppID(a)));let t={};function r(a,n){n?.length&&(t.oneOf={...t.oneOf,[a]:n})}return r("userId",e.userIds),r("appId",e.appIds),r("event",e.events),e.fullSearch&&(t.fuzzyOr=!0,t.fuzzy={name:e.fullSearch,fallback:e.fullSearch}),(e.startDate||e.endDate)&&(e=Gs(e),t.range={timestamp:{high:e.endDate,low:e.startDate}}),Object.keys(t).length===0&&(t.notEmpty={event:!0}),t}function Fs(e,t,r){let a={_id:e,status:Ln.AuditLogResourceStatus.DELETED};switch(t){case"app":a.name=r?.appName;break;case"user":a.email=r?.email;break}return a}function Qs(e){let t=(0,Ia.findHBSBlocks)(e);for(let r of t){let a=` "${r}"`;e=e.replace(e.includes(a)?a:` ${r}`,""),e=(0,Ia.processStringSync)(e,{})}return e}function tm(e,t){let r=Ln.AuditedEventFriendlyName[e];if(!r)throw new Error("No friendly name found.");let a=(0,Ia.processStringSync)(r,t);return a.includes('""')&&(a=Qs(r)),a}async function SC(e,t,r){if(!await An()||!me.utils.isAudited(e))return;let a=tm(e,t),n=new Date;r?.timestamp&&(n=new Date(r.timestamp));let o={timestamp:n.toISOString(),event:e,name:a,userId:r?.userId||Pn.AuditLogSystemUser,metadata:{...t,...r?.hostInfo}},s={};try{if(r?.appId){o.appId=me.db.getProdAppID(r.appId);let i=await me.cache.app.getAppMetadata(r.appId);"name"in i&&(s.appName=i.name)}if(r?.userId){let i=await me.users.getById(r?.userId);s.email=i.email}}catch(i){me.logging.logAlert("Failed to retrieve fallback information for audit log",i)}return o.fallback=s,await Xf(o)}async function wC(e){let t=e.map(i=>i.userId),a=e.filter(i=>i.appId).map(i=>me.db.getDevAppID(i.appId)),n=await me.users.bulkGetGlobalUsersById([...new Set(t)],{cleanup:!0}),o=await me.db.getAppsByIDs([...new Set(a)]),s=[];for(let i of e){let p=n.find(g=>g?._id===i.userId),f=o.find(g=>me.db.isSameAppID(g?.appId,i.appId)),m={event:i.event,timestamp:i.timestamp,name:i.name,metadata:i.metadata,user:p||Fs(i.userId,"user",i.fallback)};i.appId&&(m.app=f||Fs(i.appId,"app",i.fallback)),s.push(m)}return s}async function TC(e){if(!await An())throw new Error("Audit logs not available - license required.");let t=await em(e);if(typeof e.bookmark=="string")throw new Error("String based bookmark not supported.");let r=await ks(t,e.bookmark);return{hasNextPage:r.hasNextPage,bookmark:r.bookmark,data:await wC(r.rows)}}function EC(e){return e=Gs(e),Zf(e)}function RC(){let e=Object.entries(Pn.AuditedEventFriendlyName).filter(r=>r[1]!=null),t={};for(let r of e)t[r[0]]=Qs(r[1]);return t}var Un={};w(Un,{applications:()=>Vs,roles:()=>$s,users:()=>Ws});var Ws={};w(Ws,{roleCheck:()=>_C});function vC(e,t){let r=e.request.body;return r.builder&&(r.builder=t?.builder||void 0),r.admin&&(r.admin=t?.admin||void 0),r.roles&&(r.roles=t?.roles||{}),e.request.body=r,e}async function _C(e,t){return await rt()||vC(e,t),e}var $s={};w($s,{assign:()=>xC,unAssign:()=>CC});var wa=require("@budibase/backend-core");async function xC(e,t){if(!await rt())throw new Error("Unable to assign roles - license required.");let r=await Ce.bulkGet(e);for(let a of r){if(t.role&&t.role.roleId){let n=wa.db.getProdAppID(t.role.appId);a.roles[n]=t.role.roleId}if(t.appBuilder){let n=wa.db.getProdAppID(t.appBuilder.appId),o=a.builder?.apps||[];a.builder={apps:o.concat([n])}}t.builder&&(a.builder={global:!0}),t.admin&&(a.admin={global:!0}),a.roles}await Ce.bulkUpdate(r)}async function CC(e,t){if(!await rt())throw new Error("Unable to un-assign roles - license required.");let r=await Ce.bulkGet(e);for(let a of r){if(t.role){let n=wa.db.getProdAppID(t.role?.appId);a.roles[n]===t.role.roleId&&delete a.roles[n]}if(t.appBuilder&&a.builder?.apps){let n=wa.db.getProdAppID(t.appBuilder.appId);a.builder.apps=a.builder.apps.filter(o=>o!==n)}t.builder&&a.builder&&delete a.builder,t.admin&&a.admin&&delete a.admin}}var Vs={};w(Vs,{buildExportFn:()=>LC,buildImportFn:()=>OC});var Ks=require("@budibase/backend-core");function OC(e){return async(t,r)=>{await rt()||t.throw(403,"Endpoint unavailable, license required."),t.request.files?.appExport||t.throw(400,"Must provide app export file for import."),await Ks.context.doInAppContext(t.params.appId,async()=>{await e(t),t.body=void 0,t.status=204,await r()})}}function LC(e){return async(t,r)=>{await rt()||t.throw(403,"Endpoint unavailable, license required.");let{encryptPassword:a,excludeRows:n}=t.request.body;await Ks.context.doInAppContext(t.params.appId,async()=>{t.request.body={encryptPassword:a,excludeRows:n},t.query.appId=t.params.appId,await e(t),await r()})}}var ne=require("@budibase/backend-core"),ae=require("@budibase/types");var Ys=require("@budibase/backend-core"),rm;function am(){rm=new Ys.queue.BudibaseQueue(Ys.queue.JobQueue.APP_BACKUP,{maxStalledCount:3,jobOptions:{attempts:3,removeOnFail:!0,removeOnComplete:!0}})}function Dt(){return rm}var nm=require("path"),om=P(require("fs"));async function Hs(e,t={}){return _e.storeAppBackupMetadata(e,t)}function sm(e){let t=new Date().toISOString();switch(e){case ae.AppBackupStatus.COMPLETE:case ae.AppBackupStatus.FAILED:return{timestamp:t,finishedAt:t};case ae.AppBackupStatus.STARTED:return{timestamp:t,startedAt:t};case ae.AppBackupStatus.PENDING:return{timestamp:t,createdAt:t}}}async function PC(e,t,r,a){let n=await qn(e);return await _e.storeAppBackupMetadata({...n,...sm(t),contents:r,status:t,type:ae.AppBackupType.BACKUP},{filename:a,docId:e})}async function UC(e,t,r){let a=await qn(e);return await _e.storeAppBackupMetadata({...a,...sm(r),status:r,type:ae.AppBackupType.RESTORE,trigger:ae.AppBackupTrigger.MANUAL},{docId:e,docRev:t})}async function qn(e){return _e.getAppBackupMetadata(e)}async function qC(e,t){return _e.updateAppBackupMetadata(e,t)}async function im(e){let t=await _e.getAppBackupMetadata(e);return t.filename&&await ne.objectStore.deleteFile(ne.objectStore.ObjectStoreBuckets.BACKUPS,t.filename),_e.deleteAppBackupMetadata(e)}async function DC(e){let t=[];for(let r of e)try{await im(r),t.push({backupId:r,success:!0})}catch(a){t.push({backupId:r,success:!1,error:a instanceof Error?a.message:"Unknown error"})}return t}async function NC(e,t){return _e.fetchAppBackups(e,t)}async function um(e){let t=await _e.getAppBackupMetadata(e);if(!t.filename)throw new Error("Backup incomplete - cannot download.");let r=await ne.objectStore.getReadStream(ne.objectStore.ObjectStoreBuckets.BACKUPS,t.filename);return{metadata:t,stream:r}}async function BC(e){let{stream:t}=await um(e),r=(0,nm.join)(ne.objectStore.budibaseTempDir(),ne.utils.newid()),a=om.default.createWriteStream(r);return new Promise((n,o)=>{t.on("error",o),a.on("error",o),t.pipe(a).on("close",()=>n(r))})}async function MC(e,t,r={}){let a;try{a=await Hs({appId:e,trigger:t,timestamp:new Date().toISOString(),status:ae.AppBackupStatus.PENDING,type:ae.AppBackupType.BACKUP,...r})}catch(n){if(n.status===409)return;throw n}return await Dt().add({docId:a.id,docRev:a.rev,appId:e,export:{trigger:t,...r}}),await ne.events.backup.appBackupTriggered(e,a.id,ae.AppBackupType.BACKUP,t,r?.name),a.id}async function kC(e,t,r,a){let n=await qn(t),o;try{o=await Hs({appId:e,timestamp:new Date().toISOString(),status:ae.AppBackupStatus.PENDING,type:ae.AppBackupType.RESTORE,createdBy:a})}catch(s){if(s?.status===409)return;throw s}return await Dt().add({appId:e,docId:o.id,docRev:o.rev,import:{nameForBackup:r,backupId:t,createdBy:a}}),{restoreId:o.id,metadata:n}}async function GC(e,t,r){let a=ne.db.getProdAppID(e);await ne.context.doInAppContext(a,async()=>{let n=ne.context.getProdAppDB();if(!await n.exists())return;let s=await n.tryGet(ae.DocumentType.APP_METADATA);s&&(s.backupErrors||(s.backupErrors={}),s.backupErrors[t]||(s.backupErrors[t]=[]),s.backupErrors[t].push(r),await n.put(s),await ne.cache.app.invalidateAppMetadata(s.appId,s))})}var FC={isEnabled:gs,triggerAppRestore:ce(kC),triggerAppBackup:ce(MC),getBackupDownloadStream:ce(um),downloadAppBackup:ce(BC),fetchAppBackups:ce(NC),storeAppBackupMetadata:ce(Hs),updateBackupStatus:ce(PC),updateRestoreStatus:ce(UC),getAppBackup:ce(qn),updateAppBackup:ce(qC),deleteAppBackup:ce(im),deleteAppBackups:ce(DC),trackBackupError:ce(GC)},Oe=FC;var Js={};w(Js,{init:()=>zs});var W=require("@budibase/backend-core");var Fe=require("@budibase/types");var fr=P(require("fs"));async function zs(e){Dt().process(async t=>{let r=t.data;try{if(r.export)return console.log("Exporting app backup:",r.appId,r.export.trigger),WC(t,e);if(r.import)return console.log("Importing app backup:",r.appId,r.import.backupId),QC(t,e)}catch(a){W.logging.logAlert(`Failed to perform backup for app ID: ${r.appId}`,a)}})}async function jC(e){await W.db.getDB(e,{skip_setup:!0}).destroy()}async function pm(e,t,r,a){let n=W.db.getDevAppID(r),o=W.db.getProdAppID(r),s=new Date().toISOString(),i=async(p,f)=>{a?.doc?await Oe.updateBackupStatus(a.doc.id,p,f?.contents,f?.filename):await Oe.storeAppBackupMetadata({appId:o,timestamp:s,trigger:e,status:p,name:a?.name,type:Fe.AppBackupType.BACKUP,contents:f?.contents,createdBy:a?.createdBy},{filename:f?.filename})};try{let p=await a.processing.exportAppFn(n,{tar:!0}),f=await a.processing.statsFn(n),m=`${o}/backup-${s}.tar.gz`,g=W.objectStore.ObjectStoreBuckets.BACKUPS,y=fr.default.createReadStream(p);await W.objectStore.streamUpload({bucket:g,filename:m,stream:y,extra:{type:"application/gzip",metadata:{name:a?.name,trigger:e,timestamp:s,appId:o}}}),await i(Fe.AppBackupStatus.COMPLETE,{filename:m,contents:f}),fr.default.existsSync(p)&&fr.default.rmSync(p)}catch(p){W.logging.logAlert("App backup error",p),await i(Fe.AppBackupStatus.FAILED);let f=a?.doc?.id||`backup-${s}`,m=p instanceof Error?p.message:String(p);await Oe.trackBackupError(o,f,`Backup export failed: ${m}`)}}async function QC(e,t){let r=e.data,a=r.appId,n=r.import.backupId,o=r.import.nameForBackup,s=r.import.createdBy,i=W.tenancy.getTenantIDFromAppID(a);return W.tenancy.doInTenant(i,async()=>{let p=W.db.getDevAppID(a),f=`${p}_temp_${Date.now()}`,{rev:m}=await Oe.updateRestoreStatus(r.docId,r.docRev,Fe.AppBackupStatus.STARTED);await pm(Fe.AppBackupTrigger.RESTORING,i,a,{processing:t,createdBy:s,name:o});let g=await Oe.downloadAppBackup(n),y=Fe.AppBackupStatus.COMPLETE;try{await t.importAppFn(f,W.db.getDB(f),{file:{type:"application/gzip",path:g},key:g}),await jC(p),await new W.db.Replication({source:f,target:p}).replicate()}catch(I){W.logging.logAlert("App restore error",I),y=Fe.AppBackupStatus.FAILED;let C=I instanceof Error?I.message:String(I);await Oe.trackBackupError(a,n,`Backup restore failed: ${C}`)}finally{try{await W.db.getDB(f,{skip_setup:!0}).destroy()}catch{}}await Oe.updateRestoreStatus(r.docId,m,y),fr.default.existsSync(g)&&fr.default.rmSync(g,{force:!0})})}async function WC(e,t){let r=e.data,a=r.appId,n=r.export.trigger,o=r.export.name,s=W.tenancy.getTenantIDFromAppID(a);await W.tenancy.doInTenant(s,async()=>{try{let{rev:i}=await Oe.updateBackupStatus(r.docId,Fe.AppBackupStatus.STARTED);return pm(n,s,a,{processing:t,doc:{id:r.docId,rev:i},name:o})}catch(i){W.logging.logAlert("App backup error",i);let p=i instanceof Error?i.message:String(i);await Oe.trackBackupError(a,r.docId,`Backup export failed: ${p}`)}})}var $C=async e=>{am(),await zs(e.processing)},Se={...Oe,processing:Js,init:$C,getBackupQueue:Dt};var cm=async e=>{e.backups&&await Se.init(e.backups)};var ye={};w(ye,{create:()=>MM,find:()=>BM,get:()=>NM,remove:()=>GM,update:()=>kM});var PA=P($i()),st=require("@budibase/backend-core");var UA=require("@budibase/types");async function NM(e){let t=st.tenancy.getGlobalDB(),r=new st.db.QueryBuilder(t.name,UA.SearchIndex.USER);r.setIndexBuilder(st.db.searchIndexes.createUserIndex),r.setLimit(e.pageSize),r.addEqual("scimInfo.isSync",!0);for(let[n,o]of Object.entries(e.filters?.equal??{}))r.addEqual(n,o);r.setSort("_id"),r.setSkip(e.skip);let a=await r.run();return{users:a.rows,total:a.totalRows}}async function BM(e){return await st.users.getById(e)}async function MM(e){let t=await Ce.getUserByEmail(e.email);if(t){if(t.scimInfo?.isSync)throw new st.HTTPError("User is already synched",409);e={...t,scimInfo:(0,PA.default)(t.scimInfo,e.scimInfo),password:void 0,firstName:e.firstName,lastName:e.lastName,updatedAt:e.updatedAt}}return await Ce.save(e,{requirePassword:!1})}async function kM(e,t){return await Ce.save(e,{requirePassword:!1,allowChangingEmail:t?.allowChangingEmail})}async function GM(e){return await Ce.destroy(e)}var br={};w(br,{create:()=>FM});var qA=P($i());var DA=require("@budibase/backend-core");async function FM(e){let t=await Io(e.name),r;if(!t)r=(await Q.save(e)).id;else{if(t.scimInfo?.isSync)throw new DA.HTTPError("Group is already synched",409);r=t._id,t.users&&(await Q.removeUsers(r,t.users.map(n=>n._id)),delete t.users),t.scimInfo=(0,qA.default)(t.scimInfo,e.scimInfo),await Q.save(t)}return await Q.get(r)}var Bt={};w(Bt,{logRequest:()=>jM,logResponse:()=>QM});var Ki=require("@budibase/backend-core");async function jM(e){Ki.logging.logWarn("SCIM request log",e)}async function QM(e){Ki.logging.logWarn("SCIM response error",e)}var Xi={};w(Xi,{doInScimContext:()=>Yi,feature:()=>$,internalGroupOnly:()=>_a,licenseAuth:()=>MA,licensing:()=>NA,requireSCIM:()=>Hi,scimGroupOnly:()=>va,scimUserOnly:()=>Ra});var St=require("@budibase/backend-core");var Vn=require("@budibase/types"),WM=(e={checkUsersLimit:!0})=>async(t,r)=>{if((e.licensingCheck?e.licensingCheck:()=>!!t.user)(t)){if(St.env.SELF_HOSTED&&St.env.DEFAULT_LICENSE)return t.user.license=wo,r();t.user.license=await Ve.cache.getCachedLicense(t,{populateLicense:e.populateLicense,populateFreeLicense:e.populateFreeLicense}),e.checkUsersLimit&&(St.utils.isServingApp(t)||St.utils.isServingBuilder(t)||St.utils.isServingBuilderPreview(t)||St.utils.isPublicApiRequest(t))&&await ze.usageLimitIsExceeded({name:Vn.StaticQuotaName.USERS,type:Vn.QuotaUsageType.STATIC,usageChange:0})}return r()},NA=WM;var $={};w($,{requireFeature:()=>$M,requireFeatures:()=>KM});var $M=e=>async(t,r)=>{await hn(e),await r()},KM=(...e)=>async(t,r)=>{await ms(e),await r()};var Yn=require("@budibase/backend-core");var Yi=async(e,t)=>(Yn.env.DISABLE_SCIM_CALLS||await Bt.logRequest({...e.request.toJSON(),body:e.request.body}),await Yn.context.doInScimContext(async()=>{let r=await t();return await Bt.logResponse({...e.response.toJSON(),body:e.response.body}),r}));var Hi=async(e,t)=>{await As(),await t()};var BA=require("@budibase/backend-core");var Ra=e=>zi(BA.users.getById,e,!0),va=e=>zi(M.get,e,!0),_a=e=>zi(M.get,e,!1);function zi(e,t,r){return async(a,n)=>{let o=a.params[t];return typeof o!="string"&&a.throw(404),!!(await e(o)).scimInfo?.isSync!==r&&a.throw(404),n()}}var xa=require("@budibase/backend-core");var Ji=require("dd-trace");async function MA(e,t){await Ji.tracer.trace("licenseAuth",async r=>{let a=e.request.headers[xa.constants.Header.LICENSE_KEY];Array.isArray(a)&&(a=a[0]),r.addTags({licenseKey:a}),a||e.throw(403,"License key not provided");let n=await cs(a);n||(r.addTags({licenseFound:!1}),e.throw(403,"License not found or invalid")),n.tenantId||e.throw(403,"License does not have a tenant ID"),Ji.tracer.setUser({id:"anonymous",tenantId:n.tenantId}),await xa.context.doInSelfHostTenantUsingCloud(n.tenantId,async()=>{await xa.context.doInLicenseContext(n,async()=>{await t()})})})}var iu={};w(iu,{appBackups:()=>vb,auditLogs:()=>yb,environmentVariables:()=>ib,groups:()=>XA,scim:()=>rI,users:()=>iI});var kA=require("@budibase/backend-core");async function GA(e){let t=e.request.body;if(t.name=t.name.trim(),delete t.roles,t._id){let a=await bt(t._id);t.roles=a.roles,t.scimInfo=a.scimInfo}let r=await dr(t);e.body={_id:r.id,_rev:r.rev}}async function FA(e){let t=e.params.groupId,r=e.request.body.add,a=e.request.body.remove;(r&&!Array.isArray(r)||a&&!Array.isArray(a))&&e.throw(400,"Must supply a list of users to add or to remove");let n,o;r&&(n=await vn(t,r)),a&&(o=await xs(t,a)),e.body={added:n,removed:o}}async function jA(e){let t=e.params.groupId,r=e.request.body.add,a=e.request.body.remove;(r&&!Array.isArray(r)||a&&!Array.isArray(a))&&e.throw(400,"Must supply a list of objects, with appId and roleId to add or remove"),e.body=await Cs(t,{appsToAdd:r,appsToRemove:a})}async function QA(e){e.body={data:await ha()}}async function WA(e){let{groupId:t,rev:r}=e.params;try{await _s(t,r),e.body={message:"Group deleted successfully"}}catch(a){e.throw(a.status,a)}}async function $A(e){try{e.body=await bt(e.params.groupId)}catch(t){e.throw(t.status,t)}}async function KA(e){let{pageSize:t=10,bookmark:r,emailSearch:a}=e.request.query,n=e.params.groupId,o={limit:t+1},s=await Wa(n,{...o,emailSearch:a,bookmark:r}),i=a?s[t]?.email:s[t]?._id,p=!!i;e.body={users:s.slice(0,t),bookmark:i,hasNextPage:p}}async function VA(e){let{groupId:t,appId:r}=e.params;await Os(t,r),e.body={message:"Group app builder access updated."}}async function YA(e){let{groupId:t,appId:r}=e.params;await Ls(t,r),e.body={message:"group app builder access removed."}}async function HA(e){let{groupId:t}=e.params,{csvContent:r}=e.request.body;(r===void 0||r.trim().length===0)&&e.throw(400,"CSV is empty");let a=await kA.csv.jsonFromCsvString(r,{allowSingleColumn:!0});(!a||a.length===0)&&e.throw(400,"CSV file is invalid");let o=Object.keys(a[0]).find(g=>/^(email|e-mail|email address|mail|e_mail)$/i.test(g.trim()));o||e.throw(400,"CSV file must contain an email column");let s=Array.from(new Set(a.map(g=>g[o]).filter(g=>g&&typeof g=="string"&&g.trim().length>0).map(g=>g.trim())));s.length===0&&e.throw(400,"No valid email addresses found in CSV");try{await bt(t)}catch(g){if(g.status===404)e.throw(404,"Group not found");else throw g}let i=[],p=[],f=[],m=await Promise.all(s.map(g=>Ce.getUserByEmail(g)));for(let g of s){let y=m.find(I=>I?.email===g);y?(i.push({_id:y._id,email:y.email}),f.push(y._id)):p.push({email:g,reason:"User not found"})}f.length>0&&await vn(t,f),e.body={added:i,skipped:p}}var zA=P(require("@koa/router")),le=P(require("joi"));var we=require("@budibase/types"),Le=require("@budibase/backend-core"),JA=new zA.default;function YM(){return Le.auth.joiValidator.body(le.default.object({_id:le.default.string().optional(),_rev:le.default.string().optional(),color:le.default.string().required(),icon:le.default.string().required(),name:le.default.string().trim().required().max(50),role:le.default.string().optional(),users:le.default.array().optional(),apps:le.default.array().optional(),roles:le.default.object().optional(),createdAt:le.default.string().optional(),updatedAt:le.default.string().optional()}).required())}JA.post("/api/global/groups",Le.auth.adminOnly,$.requireFeature(we.Feature.USER_GROUPS),YM(),GA).get("/api/global/groups",$.requireFeature(we.Feature.USER_GROUPS),QA).delete("/api/global/groups/:groupId/:rev",$.requireFeature(we.Feature.USER_GROUPS),Le.auth.adminOnly,_a("groupId"),WA).get("/api/global/groups/:groupId",$.requireFeature(we.Feature.USER_GROUPS),Le.auth.builderOrAdmin,$A).get("/api/global/groups/:groupId/users",$.requireFeature(we.Feature.USER_GROUPS),Le.auth.builderOrAdmin,KA).post("/api/global/groups/:groupId/users",Le.auth.adminOnly,$.requireFeature(we.Feature.USER_GROUPS),_a("groupId"),FA).post("/api/global/groups/:groupId/users/bulk",Le.auth.adminOnly,$.requireFeature(we.Feature.USER_GROUPS),_a("groupId"),Le.auth.joiValidator.body(le.default.object({csvContent:le.default.string().required()}).required()),HA).post("/api/global/groups/:groupId/apps",Le.auth.builderOrAdmin,$.requireFeature(we.Feature.USER_GROUPS),jA).post("/api/global/groups/:groupId/app/:appId/builder",Le.auth.builderOrAdmin,$.requireFeatures(we.Feature.USER_GROUPS,we.Feature.APP_BUILDERS),VA).delete("/api/global/groups/:groupId/app/:appId/builder",Le.auth.builderOrAdmin,$.requireFeatures(we.Feature.USER_GROUPS,we.Feature.APP_BUILDERS),YA);var XA=JA;var Zi=require("@budibase/types");var eu=require("@budibase/backend-core");async function ZA(e){e.body={encryptionKeyAvailable:Je.isEncryptionKeyAvailable()}}async function eb(e){e.body={variables:await Je.fetch()}}async function tb(e){let{name:t,production:r,development:a}=e.request.body;await Je.update(t,{production:r,development:a});let n=[Zi.AppEnvironment.PRODUCTION];r!==a&&n.push(Zi.AppEnvironment.DEVELOPMENT),await eu.events.environmentVariable.created(t,n),e.body={message:`Environment variable "${t}" created.`}}async function rb(e){let{production:t,development:r}=e.request.body,a=e.params.varName;await Je.update(a,{production:t,development:r}),e.body={message:`Environment variable "${a}" updated.`}}async function ab(e){let t=e.params.varName;await Je.remove(t),await eu.events.environmentVariable.deleted(t),e.body={message:`Environment variable "${t}" deleted.`}}var Mt=require("@budibase/backend-core"),ob=P(require("@koa/router")),Ca=P(require("joi")),sb=new ob.default;function nb(){return Mt.auth.joiValidator.body(Ca.default.object({name:Ca.default.string().optional(),production:Ca.default.string().required(),development:Ca.default.string().required()}))}sb.get("/api/env/variables/status",Mt.auth.builderOrAdmin,ZA).get("/api/env/variables",Mt.auth.builderOrAdmin,eb).post("/api/env/variables",Mt.auth.builderOrAdmin,nb(),tb).patch("/api/env/variables/:varName",Mt.auth.builderOrAdmin,nb(),rb).delete("/api/env/variables/:varName",Mt.auth.builderOrAdmin,ab);var ib=sb;var tu=require("@budibase/backend-core");async function ub(e){let t=e.request.body,r=await It.fetch(t);await tu.events.auditLog.filtered(t),e.body=r}async function pb(e){let t=e.request.body,{stream:r}=It.download(t);await tu.events.auditLog.downloaded(t),e.attachment(`audit-logs-${Date.now()}.log`),e.body=r}async function cb(e){e.body={events:It.definitions()}}var fb=require("@budibase/types"),kt=require("@budibase/backend-core"),mb=P(require("@koa/router")),Pe=P(require("joi"));function lb(){return kt.auth.joiValidator.body(Pe.default.object({userIds:Pe.default.array().items(Pe.default.string()).optional(),appIds:Pe.default.array().items(Pe.default.string()).optional(),events:Pe.default.array().items(Pe.default.string().valid(...Object.values(fb.Event))).optional(),startDate:Pe.default.string().optional().allow(""),endDate:Pe.default.string().optional().allow(""),fullSearch:Pe.default.string().optional().allow(""),bookmark:Pe.default.number()}))}var gb=new mb.default;gb.post("/api/global/auditlogs/search",kt.auth.adminOnly,lb(),ub).get("/api/global/auditlogs/download",kt.auth.adminOnly,kt.middleware.querystringToBody,lb(),pb).get("/api/global/auditlogs/definitions",kt.auth.adminOnly,cb);var yb=gb;var ru=require("@budibase/types");var Hn=require("@budibase/backend-core");async function Gt(e,t){t||e.throw(400,"App ID missing"),await Yt.appExists(t)||e.throw(400,`Provided app ID: ${t} - is invalid.`)}async function hb(e){let t=e.params.appId;await Gt(e,t);let r=e.request.body,a=e.user?._id,n=await Se.triggerAppBackup(t,ru.AppBackupTrigger.MANUAL,{name:r.name,createdBy:a});n||e.throw(500,"Unable to start backup."),e.body={backupId:n,message:"Backup triggered - process starting."}}async function Ab(e){let t=e.params.appId;await Gt(e,t);let r=e.params.backupId,a=e.request.body.name,n=await Se.triggerAppRestore(t,r,a,e.user?._id);n||e.throw(500,"Unable to start restore."),await Hn.events.backup.appBackupRestored(n.metadata),e.body={restoredId:n?.restoreId,message:"Restore triggered - process starting."}}async function bb(e){let t=e.params.appId;await Gt(e,t);let r=e.params.backupId;await Se.deleteAppBackup(r),e.body={message:"Backup deleted successfully."}}async function Ib(e){let t=Hn.context.getAppId();await Gt(e,t);let{backupIds:r}=e.request.body;(!Array.isArray(r)||r.length===0)&&e.throw(400,"backupIds must be a non-empty array");let a=await Se.deleteAppBackups(r),n=a.filter(s=>s.success).length,o=a.length-n;e.body={message:`${n} backups deleted successfully${o>0?`, ${o} failed`:""}.`,results:a,successCount:n,failureCount:o}}async function Sb(e){let t=e.params.appId;await Gt(e,t);let r=e.request.body;r?.trigger&&(r.trigger=r.trigger.toLowerCase(),Object.values(ru.AppBackupTrigger).includes(r.trigger)||e.throw(400,"Provided trigger is not a valid option.")),e.body=await Se.fetchAppBackups(t,{paginate:!0,...r})}async function wb(e){let t=e.params.appId;await Gt(e,t);let r=e.params.backupId,a=e.request.body;e.body=await Se.updateAppBackup(r,a.name)}async function Tb(e){let t=e.params.appId;await Gt(e,t);let r=e.params.backupId,{metadata:a,stream:n}=await Se.getBackupDownloadStream(r);e.attachment(`backup-${a.timestamp}.tar.gz`),e.body=n}var Eb=P(require("@koa/router")),Ft=P(require("joi")),zn=require("@budibase/types"),it=require("@budibase/backend-core"),Rb=new Eb.default;function XM(){return it.auth.joiValidator.body(Ft.default.object({trigger:Ft.default.string().valid(...Object.values(zn.AppBackupTrigger)),type:Ft.default.string().valid(...Object.values(zn.AppBackupType)),startDate:Ft.default.date(),endDate:Ft.default.date(),page:Ft.default.string()}))}Rb.post("/api/apps/:appId/backups",it.auth.builderOrAdmin,hb).post("/api/apps/:appId/backups/search",it.auth.builderOrAdmin,XM(),Sb).get("/api/apps/:appId/backups/:backupId/file",it.auth.builderOrAdmin,Tb).patch("/api/apps/:appId/backups/:backupId",it.auth.builderOrAdmin,wb).delete("/api/apps/:appId/backups/:backupId",it.auth.builderOrAdmin,bb).delete("/api/apps/:appId/backups",it.auth.builderOrAdmin,Ib).post("/api/apps/:appId/backups/:backupId/import",it.auth.builderOrAdmin,Ab);var vb=Rb;var tI=P(require("@koa/router"));var Jn=require("scim-patch");var xb=require("@budibase/backend-core");function _b(e,t){let r=e.request.query[t];if(r!==void 0)return+r}var Cb=async e=>{let t=_b(e,"pageSize")??20,r=_b(e,"startIndex"),a;e.request.query.filter&&(a=Y.user.userFilters(e.request.query.filter));let n=await ye.get({pageSize:t,skip:r,filters:a});e.body={schemas:["urn:ietf:params:scim:api:messages:2.0:ListResponse"],totalResults:n.total,Resources:n.users.map(Y.user.toScimUserResponse),startIndex:(r||0)+1,itemsPerPage:t}},Ob=async e=>{let{id:t}=e.params;typeof t!="string"&&e.throw(404);let r=await ye.find(t);e.body=Y.user.toScimUserResponse(r)},Lb=async e=>{let t=Y.user.fromScimUser(e.request.body);try{let r=await ye.create(t);e.body=Y.user.toScimUserResponse(r)}catch(r){throw r instanceof xb.EmailUnavailableError&&e.throw(409,"Email already in use"),r}};function ZM(e){let t=e.Operations.find(r=>(r.op==="Replace"||r.op==="replace")&&r.path==="active");return t?t.value===!1||t.value?.toLowerCase?.()==="false":!1}var Pb=async e=>{let t=await ye.find(e.params.id);t||e.throw(404);let r=Y.user.toScimUserResponse(t),a=e.request.body;try{(0,Jn.patchBodyValidation)(a)}catch{}if(ZM(a))return au(e);let n;try{n=(0,Jn.scimPatch)(r,a.Operations)}catch{}n||e.throw(500);let o=Y.user.fromScimUser(n);await ye.update(o,{allowChangingEmail:!0}),e.body=Y.user.toScimUserResponse(o)},au=async e=>{let{id:t}=e.params;typeof t!="string"&&e.throw(404),await ye.remove(t),e.status=204};var Vb=P(Kb()),Yb=require("@budibase/shared-core"),Xn=require("scim-patch");var Zn=require("scim2-parse-filter");function Hb(e,t){for(let r of t.split(","))delete e[r]}var zb=async e=>{let r=(await Q.fetch()).filter(o=>o.scimInfo?.isSync).map(Y.group.toScimGroupResponse),{filter:a,excludedAttributes:n}=e.request.query;if(a){let o=(0,Zn.filter)((0,Zn.parse)(a));r=r.filter(o)}n&&r.forEach(o=>{Hb(o,n)}),e.body={schemas:["urn:ietf:params:scim:api:messages:2.0:ListResponse"],totalResults:r.length,Resources:r,startIndex:1,itemsPerPage:r.length}},Jb=async e=>{let t=Y.group.fromScimGroup(e.request.body),r=await br.create(t);e.body=Y.group.toScimGroupResponse(r)},Xb=async e=>{let{id:t}=e.params,r=await Q.get(t),a=Y.group.toScimGroupResponse(r),{excludedAttributes:n}=e.request.query;n&&Hb(a,n),e.body=a},Zb=async e=>{let{id:t}=e.params,r=await Q.get(t);await Q.remove(t,r._rev),e.status=204},eI=async e=>{let{id:t}=e.params,r=await Q.get(t),a=Y.group.toScimGroupResponse(r),n=e.request.body;try{(0,Xn.patchBodyValidation)(n)}catch{e.throw(400)}let{true:o,false:s}=(0,Vb.default)(n.Operations,i=>i.path==="members");if(s?.length){let i=(0,Xn.scimPatch)(a,s);i||e.throw(500);let p={...Y.group.fromScimGroup(i),_rev:r._rev};await Q.save(p)}if(o?.length){let i=[],p=[];for(let{op:f,value:m}of o)switch(f){case"add":case"Add":for(let g of m)i.push(await ye.find(g.value));break;case"remove":case"Remove":for(let g of m)p.push(await ye.find(g.value));break;case"replace":case"Replace":throw new Error("Replacing members is not allowed");default:Yb.utils.unreachable(f)}i.length&&await Q.addUsers(t,i.map(f=>f._id)),p.length&&await Q.removeUsers(t,p.map(f=>f._id))}e.body=Y.group.toScimGroupResponse(await Q.get(t))};var Oa=require("@budibase/types"),Te=new tI.default({prefix:"/api/global/scim/v2"});Te.use(Hi);Te.use(Yi);Te.get("/users",Cb);Te.get("/users/:id",Ra("id"),Ob);Te.post("/users",Lb);Te.patch("/users/:id",Ra("id"),Pb);Te.delete("/users/:id",Ra("id"),au);Te.get("/groups",zb);Te.post("/groups",$.requireFeature(Oa.Feature.USER_GROUPS),Jb);Te.get("/groups/:id",$.requireFeature(Oa.Feature.USER_GROUPS),va("id"),Xb);Te.delete("/groups/:id",$.requireFeature(Oa.Feature.USER_GROUPS),va("id"),Zb);Te.patch("/groups/:id",$.requireFeature(Oa.Feature.USER_GROUPS),va("id"),eI);var rI=Te;var oI=P(require("@koa/router"));var nu=require("@budibase/backend-core");async function aI(e){let{userId:t,appId:r}=e.params,a=await nt.db.getUser(t);if(nu.users.isGlobalBuilder(a)){e.body={message:"User already admin - no permissions updated."};return}await nt.addAppBuilder(a,r),e.body={message:`User "${a.email}" app builder access updated.`}}async function nI(e){let{userId:t,appId:r}=e.params,a=await nt.db.getUser(t);if(nu.users.isGlobalBuilder(a)){e.body={message:"User already admin - no permissions removed."};return}await nt.removeAppBuilder(a,r),e.body={message:`User "${a.email}" app builder access removed.`}}var ou=require("@budibase/types"),su=require("@budibase/backend-core"),sI=new oI.default;sI.post("/api/global/users/:userId/app/:appId/builder",su.auth.builderOrAdmin,$.requireFeatures(ou.Feature.APP_BUILDERS),aI).delete("/api/global/users/:userId/app/:appId/builder",su.auth.builderOrAdmin,$.requireFeatures(ou.Feature.APP_BUILDERS),nI);var iI=sI;var Y={};w(Y,{group:()=>pu,user:()=>uu});var uu={};w(uu,{fromScimUser:()=>xk,toScimUserResponse:()=>Rk,userFilters:()=>Ck});var eo=require("@budibase/types"),uI=require("scim2-parse-filter"),pI=require("@budibase/backend-core"),cI=require("@budibase/shared-core"),{unreachable:Ek}=cI.utils,Rk=e=>{let{isSync:t,roles:r,...a}=e.scimInfo||{},n={...a,schemas:["urn:ietf:params:scim:schemas:core:2.0:User"],id:e._id,meta:{resourceType:"User",created:new Date(e.createdAt),lastModified:new Date(e.updatedAt)},active:e.status===eo.UserStatus.ACTIVE};return(e.firstName||e.lastName)&&(n.name={formatted:[e.firstName,e.lastName].filter(o=>o).join(" "),familyName:e.lastName,givenName:e.firstName}),n},vk=e=>!!e?.id;function _k(e){if(pI.utils.validEmail(e.userName))return e.userName;if(e.emails)return e.emails.find(t=>t.primary)?.value||e.emails[0]?.value}var xk=e=>{let t=vk(e)?e:void 0,r=_k(e);if(!r)throw new Error("Email is required");let a;switch(e.active){case"True":case"true":case!0:a=!0;break;case"False":case"false":case!1:a=!1;break;default:Ek(e.active)}let n,o;return e.name?.givenName?(n=e.name?.givenName,o=e.name?.familyName):n=e.displayName,{tenantId:"",_id:t?.id,userId:t?.id,email:r,firstName:n,lastName:o,scimInfo:{...e,isSync:!0},roles:{},status:a?eo.UserStatus.ACTIVE:eo.UserStatus.INACTIVE,createdAt:t?.meta.created.getTime(),updatedAt:t?.meta.lastModified.toISOString()}},Ck=e=>{let t={equal:{}},r=(0,uI.parse)(e);function a(n){switch(n.op){case"eq":{let o=n.attrPath,s;switch(o){case"emails.value":s="email";break;default:s=`scimInfo.${o}`}t.equal[s]=n.compValue;break}case"and":for(let o of n.filters)a(o);break;default:console.warn("Filter not handled",{filter:n})}}return a(r),t};var pu={};w(pu,{fromScimGroup:()=>Pk,toScimGroupResponse:()=>Ok});var Ok=e=>({schemas:["urn:ietf:params:scim:schemas:core:2.0:Group"],id:e._id,externalId:e.scimInfo.externalId,meta:{resourceType:"Group",created:new Date(e.createdAt),lastModified:new Date(e.updatedAt)},displayName:e.name,members:e.users?.map(t=>({value:t._id}))}),Lk=e=>!!e?.id,Pk=e=>{let t=Lk(e)?e:void 0;return{_id:t?.id,name:e.displayName,scimInfo:{externalId:e.externalId,isSync:!0},icon:"UserGroup",color:"var(--spectrum-global-color-blue-600)",createdAt:t?.meta.created.getTime(),updatedAt:t?.meta.lastModified.toISOString()}};var Uu={};w(Uu,{LLM:()=>Xe,LLMRequest:()=>K,TableGeneration:()=>Pu,agentHistoryTitleSystemPrompt:()=>Qk,agentSystemPrompt:()=>jk,aiColumnSchemas:()=>Ou,aiTableResponseToTableSchema:()=>vu,appendAIColumns:()=>_u,classifyText:()=>du,cleanData:()=>fu,extractFileData:()=>Mk,generateAIColumns:()=>Eu,generateCode:()=>Fk,generateCronExpression:()=>mu,generateData:()=>Ru,generateJs:()=>Au,generateSQL:()=>Gk,generateTables:()=>Tu,generationStructure:()=>Cu,getLLM:()=>Ua,getLLMConfig:()=>wu,getLLMOrThrow:()=>SI,normalizeContentType:()=>cu,parseResponseFormat:()=>ro,sanitiseToolName:()=>Uk,searchWeb:()=>hu,sentimentAnalysis:()=>yu,summarizeText:()=>to,tableDataStructuredOutput:()=>Lu,translate:()=>gu});var La=require("@budibase/types");function Uk(e){if(e.length>64)throw new Error("Tool name must be under 64 characters long");return e.replace(/[^a-zA-Z0-9_-]/g,"_")}function cu(e){return e?e.includes("/")?e:{[La.SupportedFileType.PDF]:"application/pdf",[La.SupportedFileType.JPG]:"image/jpeg",[La.SupportedFileType.JPEG]:"image/jpeg",[La.SupportedFileType.PNG]:"image/png"}[e.toLowerCase()]||"application/octet-stream":"application/octet-stream"}var io=require("@budibase/types");var Ze=require("@budibase/backend-core"),hI=require("@budibase/types");var ao=P(require("openai"));var wt=require("@budibase/types");var lI=require("@budibase/shared-core");var Tt=P(require("dd-trace"));function lu(e,t){return t.map(r=>e[r]).join(" ")}var Xe=class{constructor({model:t,apiKey:r,maxTokens:a}){this._model=t,this._apiKey=r,this._maxTokens=a??parseInt(process.env.BUDIBASE_AI_MAX_PROMPT_TOKENS||"1000")}get model(){return this._model}get apiKey(){return this._apiKey}get maxTokens(){return this._maxTokens}async prompt(t){return await Tt.default.trace("prompt",async()=>{let r=typeof t=="string"?new K().addUserMessage(t):t,{messages:a,tokensUsed:n}=await Tt.default.trace("chatCompletion",()=>this.chatCompletion(r));return!a||a.length===0?{message:"",tokensUsed:n}:{message:a[a.length-1].content||"",tokensUsed:n}})}async chat(t){return await Tt.default.trace("chat",async()=>await this.chatCompletion(t))}async*chatStream(t){yield*this.chatCompletionStream(t)}async summarizeText(t){return Tt.default.trace("summarizeText",()=>this.prompt(to(t)))}async generateCronExpression(t){return Tt.default.trace("generateCronExpression",()=>this.prompt(mu(t)))}async operation(t,r){return Tt.default.trace("operation",a=>{a.addTags({operation:t.operation,rowId:r.id});let n=this.promptForOperation(t,r);return this.prompt(n)})}promptForOperation(t,r){let{operation:a,column:n,columns:o,language:s,categories:i,prompt:p}=t;switch(a){case wt.AIOperationEnum.SUMMARISE_TEXT:return to(lu(r,o));case wt.AIOperationEnum.CLEAN_DATA:return fu(r[n]);case wt.AIOperationEnum.TRANSLATE:return gu(r[n],s);case wt.AIOperationEnum.CATEGORISE_TEXT:if(!i)throw Error("No categories provided for categorise text operation. Please provide categories.");return du(lu(r,o),i.split(","));case wt.AIOperationEnum.SENTIMENT_ANALYSIS:return yu(r[n]);case wt.AIOperationEnum.PROMPT:return p;case wt.AIOperationEnum.SEARCH_WEB:return hu(lu(r,o));default:throw lI.utils.unreachable(a)}}async generateJs(t,r){return await Tt.default.trace("generateJs",async()=>{let{bindings:a=[],snippets:n=[]}=r||{};return await this.prompt(Au(a,n).addUserMessage(t))})}};var fI=require("@budibase/types"),bu=require("openai/helpers/zod");var mI=(a=>(a.GPT_5_MINI="gpt-5-mini",a.GPT_5="gpt-5",a.GPT_5_NANO="gpt-5-nano",a))(mI||{});function ro(e){if(e)return e==="text"?{type:"text"}:e==="json"?{type:"json_object"}:e}function dI(e){if(!e)return 0;let t=e.prompt_tokens;return e.completion_tokens*3+t}var Ue=class extends Xe{constructor(r){super(r);this.client=this.getClient(r)}getClient(r){if(!r.apiKey)throw new Error("No OpenAI API key found");return new ao.default({apiKey:r.apiKey})}async uploadFile(r,a,n){let o=cu(n);if(fI.ImageContentTypes.includes(o.toLowerCase())){let p;if(Buffer.isBuffer(r))p=r;else{let m=[];for await(let g of r)m.push(new Uint8Array(g));p=Buffer.concat(m)}let f=p.toString("base64");return`data:${o};base64,${f}`}let s=await(0,ao.toFile)(r,a);return(await this.client.files.create({file:s,purpose:"assistants"})).id}async chatCompletion(r){let a={model:this.model,messages:r.messages,max_completion_tokens:this._maxTokens,response_format:ro(r.format)};Object.values(mI).includes(this.model)&&(a.verbosity="low",a.reasoning_effort="minimal"),r.tools&&r.tools.length>0&&(a.tool_choice="auto",a.tools=r.tools.map(bu.zodFunction));let n=await this.client.chat.completions.create(a),o=n?.choices?.[0]?.message;if(o?.tool_calls){r.addMessage(o);let s=[];for(let i of o.tool_calls){if(i.type!=="function"||!i.function){console.warn(`[OPENAI TOOL WARN] Unsupported tool call type: ${i.type}`);continue}let p=i.function.name,f=r.findTool(p);if(!f)throw new Error(`Tool ${p} not found in prompt tools`);let m=JSON.parse(i.function.arguments);s.push(f.handler(m).then(g=>({role:"tool",tool_call_id:i.id,content:g})).catch(g=>(console.error(`[OPENAI TOOL ERROR] Tool ${p} failed in OpenAI handler:`,g),{role:"tool",tool_call_id:i.id,content:`Error: ${g.message}`})))}return r.addMessages(await Promise.all(s)),this.chatCompletion(r)}else{if(o?.content)return{messages:[...r.messages,{role:o.role,content:o.content}],tokensUsed:dI(n.usage)};throw new Error("No response found")}}async*chatCompletionStream(r){let a={model:this.model,messages:r.messages,max_tokens:this.maxTokens,response_format:ro(r.format),stream:!0};r.tools&&r.tools.length>0&&(a.tool_choice="auto",a.tools=r.tools.map(bu.zodFunction));try{let n=await this.client.chat.completions.create(a),o=null,s="",i=null;for await(let f of n){let m=f?.choices?.[0]?.delta;if(m){if(m.content&&(s+=m.content,yield{type:"content",content:m.content}),m.tool_calls&&m.tool_calls.length>0){let g=m.tool_calls[0];g.id?(o={id:g.id,name:g.function?.name||"",arguments:g.function?.arguments||""},yield{type:"tool_call_start",toolCall:{id:o.id,name:o.name,arguments:o.arguments}}):o&&g.function?.arguments&&(o.arguments+=g.function.arguments,yield{type:"tool_call_start",toolCall:{id:o.id,name:o.name,arguments:o.arguments}})}f.usage&&(i=f.usage)}}let p=i?dI(i):0;if(o){r.addMessage({role:"assistant",content:"",tool_calls:[{id:o.id,type:"function",function:{name:o.name,arguments:o.arguments}}]});let f=r.findTool(o.name);if(f)try{let m=JSON.parse(o.arguments),g=await f.handler(m);yield{type:"tool_call_result",toolResult:{id:o.id,result:g}},r.addMessage({role:"tool",tool_call_id:o.id,content:g}),yield*this.chatCompletionStream(r);return}catch(m){yield{type:"tool_call_result",toolResult:{id:o.id,result:`Error: ${m.message}`,error:m.message}},r.addMessage({role:"tool",tool_call_id:o.id,content:`Error: ${m.message}`}),yield*this.chatCompletionStream(r);return}else{let m=`Tool '${o.name}' not found`;yield{type:"tool_call_result",toolResult:{id:o.id,result:m,error:m}},r.addMessage({role:"tool",tool_call_id:o.id,content:m}),yield*this.chatCompletionStream(r);return}}s&&r.addMessage({role:"assistant",content:s}),yield{type:"done",messages:r.messages,tokensUsed:p}}catch(n){yield{type:"error",content:n.message}}}};var ee=require("@budibase/backend-core"),gI=require("@budibase/types");var Iu=require("dd-trace"),no=class extends Xe{async prompt(t){let r=await super.prompt(t);return r.tokensUsed&&await En(r.tokensUsed),r}async chat(t){let r=await super.chat(t);return r.tokensUsed&&await En(r.tokensUsed),r}async uploadFile(t,r,a){return ee.env.SELF_HOSTED?this.uploadFileSelfHost(t,r,a):this.uploadFileCloud(t,r,a)}async uploadFileCloud(t,r,a){return new Ue({apiKey:ee.env.OPENAI_API_KEY,model:this.model,max_completion_tokens:this.maxTokens}).uploadFile(t,r,a)}async uploadFileSelfHost(t,r,a){let n;if(Buffer.isBuffer(t))n=t;else{let p=[];for await(let f of t)p.push(new Uint8Array(f));n=Buffer.concat(p)}let o=n.toString("base64");if(a&&gI.ImageContentTypes.includes(a.toLowerCase()))return`data:image/jpeg;base64,${o}`;if(!ee.env.BUDICLOUD_URL)throw new Error("No Budibase URL found");if(!this._apiKey){let p=await gn();if(!p)throw new Error("No license key found");this._apiKey=p}let s=await fetch(`${ee.env.BUDICLOUD_URL}/api/ai/upload-file`,{method:"POST",headers:{"Content-Type":"application/json",[ee.constants.Header.LICENSE_KEY]:this._apiKey},body:JSON.stringify({data:o,filename:r,contentType:a})});if(!s.ok)throw await ee.HTTPError.fromResponse(s);return(await s.json()).fileId}async chatCompletion(t){return ee.env.SELF_HOSTED?this.chatCompletionSelfHost(t):this.chatCompletionCloud(t)}async chatCompletionCloud(t){return await Iu.tracer.trace("chatCompletionCloud",async()=>await new Ue({apiKey:ee.env.OPENAI_API_KEY,model:this.model,max_completion_tokens:this.maxTokens}).chatCompletion(t))}async chatCompletionSelfHost(t){return await Iu.tracer.trace("chatCompletionSelfHost",async r=>{if(!ee.env.BUDICLOUD_URL)throw new Error("No Budibase URL found");if(r.addTags({budicloudUrl:ee.env.BUDICLOUD_URL}),!this._apiKey){let o=await gn();if(!o)throw new Error("No license key found");this._apiKey=o,r.addTags({licenseKey:this._apiKey})}let a={messages:t.messages,format:t.format,useTools:t.tools.length>0},n=await fetch(`${ee.env.BUDICLOUD_URL}/api/ai/chat`,{method:"POST",headers:{"Content-Type":"application/json",[ee.constants.Header.LICENSE_KEY]:this._apiKey},body:JSON.stringify(a)});if(!n.ok)throw await ee.HTTPError.fromResponse(n);return await n.json()})}async*chatCompletionStream(t){ee.env.SELF_HOSTED?yield*this.chatCompletionStreamSelfHost(t):yield*this.chatCompletionStreamCloud(t)}async*chatCompletionStreamCloud(t){yield*new Ue({apiKey:ee.env.OPENAI_API_KEY,model:this.model,max_completion_tokens:this.maxTokens}).chatCompletionStream(t)}async*chatCompletionStreamSelfHost(t){try{let r=await this.chatCompletionSelfHost(t);if(r.messages.length>0){let a=r.messages[r.messages.length-1];a.content&&(yield{type:"content",content:a.content})}yield{type:"done",messages:r.messages,tokensUsed:r.tokensUsed}}catch(r){yield{type:"error",content:r.message}}}};var Pa=require("dd-trace");var Su=P(require("@anthropic-ai/sdk"));function qk(e){if(!e)return 0;let t=e.input_tokens;return e.output_tokens*3+t}var oo=class extends Xe{constructor(r){super(r);this.client=new Su.default({apiKey:r.apiKey})}firstTextBlock(r){for(let a of r.content)if(a.type==="text")return a.text}async uploadFile(r,a,n){throw new Error("File upload not supported for this LLM provider")}async chatCompletion(r){try{let a=await this.client.messages.create({model:this.model,messages:r.messages.map(({content:o})=>{if(o==null)return{role:"user",content:""};if(typeof o=="string")return{role:"user",content:o};let s="";for(let i of o)i.type==="text"?s+=i.text:["image_url","input_audio","file"].includes(i.type);return{role:"user",content:s}}),max_tokens:this.maxTokens}),n=this.firstTextBlock(a)||"";return{messages:[...r.messages,{role:"assistant",content:n}],tokensUsed:qk(a.usage)}}catch(a){throw a instanceof Su.default.APIError&&console.error(`Anthropic Prompt failed with error ${a.name} and status: ${a.status}`),a}}async*chatCompletionStream(r){try{let a=await this.chatCompletion(r);if(a.messages.length>0){let n=a.messages[a.messages.length-1];n.content&&(yield{type:"content",content:n.content})}yield{type:"done",messages:a.messages,tokensUsed:a.tokensUsed}}catch(a){yield{type:"error",content:a.message}}}};var AI=require("zod"),bI=require("openai/helpers/zod");var yI=require("openai"),so=class extends Ue{getClient(t){if(!t.apiKey)throw new Error("No Azure OpenAI API key found");if(!t.model)throw new Error("No Azure OpenAI model specified");return new yI.AzureOpenAI({apiKey:t.apiKey,apiVersion:"2024-10-01-preview",baseURL:t.baseUrl})}};var II="gpt-5-mini",Dk={OpenAI:Ue,TogetherAI:Ue,AzureOpenAI:so,Custom:Ue,Anthropic:oo,BudibaseAI:no};async function Nk(){return await Pa.tracer.trace("getAIConfig",async e=>{let t={type:hI.ConfigType.AI,config:{}};if(!Ze.context.isSelfHostUsingCloud()){let a=await Ze.configs.getAIConfig();a&&(t=a)}await bs(t);let r=Object.values(t.config).find(a=>a.active&&a.isDefault);if(!r){e.addTags({enabled:!1,reason:"no provider found"});return}return e.addTags({enabled:!0}),{provider:r.provider,model:r.defaultModel||II,apiKey:r.apiKey,baseUrl:r.baseUrl}})}async function Bk(){return Pa.tracer.trace("getSelfHostOpenAIKeyConfig",e=>{if(!Ze.env.SELF_HOSTED){e.addTags({enabled:!1,reason:"not self host"});return}if(!Ze.env.OPENAI_API_KEY){e.addTags({enabled:!1,reason:"no OPENAI_API_KEY"});return}return e.addTags({enabled:!0}),{provider:"OpenAI",model:II,apiKey:Ze.env.OPENAI_API_KEY}})}async function wu(){return Pa.tracer.trace("getLLMConfig",async()=>await Nk()||await Bk())}async function Ua(e){return await Pa.tracer.trace("getLLM",async t=>{let{model:r,maxTokens:a}=e||{},n=await wu();if(!n){t.addTags({enabled:!1,reason:"no config found"});return}r&&(n.model=r),a&&(n.maxTokens=a);let o=Dk[n.provider];if(!o){t.addTags({enabled:!1,reason:"no provider found",provider:n.provider});return}return new o(n)})}async function SI(){let e=await Ua();if(!e)throw new Ze.HTTPError("No available LLM configurations",500);return e}var K=class e{constructor(){this.messages=[];this.tools=[]}addTool(t){return this.tools.push(t),this}addTools(t){return this.tools.push(...t),this}findTool(t){return this.tools.find(r=>r.name===t)}withFormat(t){return t instanceof AI.z.ZodType?this.format=(0,bI.zodResponseFormat)(t,"key"):this.format=t,this}addMessage(t){return this.messages.push(t),this}addMessages(t){return this.messages.push(...t),this}addUserMessage(t){return this.messages.push({role:"user",content:t}),this}addSystemMessage(t){return this.messages.push({role:"system",content:t}),this}static fromRequest(t){let r=new e;return t.messages&&r.addMessages(t.messages),t.format&&r.withFormat(t.format),r}};var ut=require("zod");function to(e,t){let r=`Summarize this text:
|
|
39
39
|
${e}`,a="";if(t)switch(t){case io.SummariseLength.SHORT:a="In 1-2 concise sentences, ";break;case io.SummariseLength.MEDIUM:a="In 2-3 paragraphs, ";break;case io.SummariseLength.LONG:a="In multiple detailed paragraphs, ";break}return new K().addUserMessage(`${a}${r}.
|
|
40
40
|
Only return the summary.`)}function Mk(e,t){let r=["You are a data extraction assistant.","Extract data from the attached document/image that matches the provided schema.","The schema defines the structure where values like 'string', 'number', 'boolean' indicate the expected data types.","Extract all items that match the schema from the document.","Return the data in json format","If no matching data is found, return an empty data array."].join(`
|
|
41
41
|
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"dist"
|
|
5
5
|
],
|
|
6
6
|
"license": "UNLICENSED",
|
|
7
|
-
"version": "3.
|
|
7
|
+
"version": "3.18.0",
|
|
8
8
|
"description": "Budibase Pro (Backend)",
|
|
9
9
|
"main": "dist/index.js",
|
|
10
10
|
"types": "dist/index.d.ts",
|
|
@@ -43,8 +43,7 @@
|
|
|
43
43
|
"timekeeper": "^2.2.0",
|
|
44
44
|
"ts-jest": "29.1.1",
|
|
45
45
|
"ts-node": "10.8.1",
|
|
46
|
-
"tsconfig-paths": "^4.2.0"
|
|
47
|
-
"typescript": "5.7.2"
|
|
46
|
+
"tsconfig-paths": "^4.2.0"
|
|
48
47
|
},
|
|
49
48
|
"scripts": {
|
|
50
49
|
"setup": "yarn && yarn build",
|
|
@@ -73,5 +72,5 @@
|
|
|
73
72
|
}
|
|
74
73
|
}
|
|
75
74
|
},
|
|
76
|
-
"gitHead": "
|
|
75
|
+
"gitHead": "255f35eea6023bbc035d9dee8c56ba3e600c6b89"
|
|
77
76
|
}
|