Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions packages/backend/src/adapters/adapters.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,21 @@ export class AdaptersService {
// Resolve {{VAR}} placeholders in baseUrl (e.g. weclapp tenant)
const resolvedBaseUrl = this.resolveString(adapter.connector.baseUrl, credentials);

// Resolve {{VAR}} placeholders in static connector headers (e.g. Harvest
// requires a per-tenant Harvest-Account-Id header on every call).
const adapterHeaders = (adapter.connector as { headers?: Record<string, string> }).headers;
const resolvedHeaders = adapterHeaders
? (this.resolveTemplate(adapterHeaders, credentials) as Record<string, string>)
: null;

// Persist the import credentials as envVars so the engine can use them
// for runtime $varname substitution inside tool bodies/queries/paths.
// (authConfig has its own {{VAR}} substitution; envVars covers everything
// outside auth/baseUrl.)
const envVarsToPersist = credentials && Object.keys(credentials).length > 0
? (credentials as Record<string, unknown>)
: null;

const connector = await this.prisma.connector.create({
data: {
userId,
Expand All @@ -64,6 +79,8 @@ export class AdaptersService {
isActive: true,
authType: (adapter.connector.authType as any) || 'NONE',
authConfig: encryptedAuth,
headers: resolvedHeaders as any,
envVars: envVarsToPersist as any,
instructions: adapter.instructions || null,
},
});
Expand Down
8 changes: 6 additions & 2 deletions packages/backend/src/adapters/catalog.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,17 @@ describe('adapter catalog', () => {
const strings: Array<{ path: string; value: string }> = [];
collectStrings(em[field], field, strings);
for (const { value } of strings) {
// Full-string reference: "$foo" → must be declared, unless it's an env placeholder
// Full-string reference: "$foo" → must be declared as a tool param,
// unless it's $$ (escape) or an env-var-style reference (UPPER_SNAKE_CASE,
// resolved at runtime from connector.envVars populated at import time).
const full = /^\$([\w$]+)$/.exec(value);
if (full && !value.startsWith('$$')) {
if (full && !value.startsWith('$$') && !/^[A-Z][A-Z0-9_]*$/.test(full[1])) {
expect(declaredParams.has(full[1])).toBe(true);
}
// Embedded references: "...${foo}..." — all names must be declared
// (same env-var exemption applies).
for (const match of value.matchAll(/\$\{([\w$]+)\}/g)) {
if (/^[A-Z][A-Z0-9_]*$/.test(match[1])) continue;
expect(declaredParams.has(match[1])).toBe(true);
}
}
Expand Down
66 changes: 66 additions & 0 deletions packages/backend/src/adapters/catalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,19 @@ import * as wise from './gb/wise.json';
import * as activecampaign from './intl/activecampaign.json';
import * as acuityScheduling from './intl/acuity-scheduling.json';
import * as adyen from './intl/adyen.json';
import * as agilecrm from './intl/agilecrm.json';
import * as amadeus from './intl/amadeus.json';
import * as apollo from './intl/apollo.json';
import * as attio from './intl/attio.json';
import * as bamboohr from './intl/bamboohr.json';
import * as basecamp from './intl/basecamp.json';
import * as beehiiv from './intl/beehiiv.json';
import * as bigcommerce from './intl/bigcommerce.json';
import * as bitrix24 from './intl/bitrix24.json';
import * as bluesky from './intl/bluesky.json';
import * as box from './intl/box.json';
import * as brevo from './intl/brevo.json';
import * as buffer from './intl/buffer.json';
import * as bugsnag from './intl/bugsnag.json';
import * as calendly from './intl/calendly.json';
import * as chargebee from './intl/chargebee.json';
Expand All @@ -55,20 +60,27 @@ import * as convertkit from './intl/convertkit.json';
import * as copper from './intl/copper.json';
import * as crisp from './intl/crisp.json';
import * as datadog from './intl/datadog.json';
import * as deel from './intl/deel.json';
import * as discordBot from './intl/discord-bot.json';
import * as drip from './intl/drip.json';
import * as dropbox from './intl/dropbox.json';
import * as dropboxSign from './intl/dropbox-sign.json';
import * as ecwid from './intl/ecwid.json';
import * as etsy from './intl/etsy.json';
import * as fathom from './intl/fathom.json';
import * as fillout from './intl/fillout.json';
import * as flutterwave from './intl/flutterwave.json';
import * as folk from './intl/folk.json';
import * as freshbooks from './intl/freshbooks.json';
import * as freshchat from './intl/freshchat.json';
import * as freshdesk from './intl/freshdesk.json';
import * as freshservice from './intl/freshservice.json';
import * as front from './intl/front.json';
import * as ghost from './intl/ghost.json';
import * as gitbook from './intl/gitbook.json';
import * as gocardless from './intl/gocardless.json';
import * as gorgias from './intl/gorgias.json';
import * as greenhouse from './intl/greenhouse.json';
import * as hackernews from './intl/hackernews.json';
import * as harvest from './intl/harvest.json';
import * as heap from './intl/heap.json';
Expand All @@ -77,14 +89,19 @@ import * as helpScout from './intl/help-scout.json';
import * as hunter from './intl/hunter.json';
import * as insightly from './intl/insightly.json';
import * as instantly from './intl/instantly.json';
import * as invoiced from './intl/invoiced.json';
import * as kashflow from './intl/kashflow.json';
import * as klaviyo from './intl/klaviyo.json';
import * as kustomer from './intl/kustomer.json';
import * as lemlist from './intl/lemlist.json';
import * as lemonsqueezy from './intl/lemonsqueezy.json';
import * as lessAnnoyingCrm from './intl/less-annoying-crm.json';
import * as lever from './intl/lever.json';
import * as linkedin from './intl/linkedin.json';
import * as loops from './intl/loops.json';
import * as magento from './intl/magento.json';
import * as mailchimp from './intl/mailchimp.json';
import * as mailerlite from './intl/mailerlite.json';
import * as mailshake from './intl/mailshake.json';
import * as mapbox from './intl/mapbox.json';
import * as mastodon from './intl/mastodon.json';
Expand All @@ -97,13 +114,21 @@ import * as mollie from './intl/mollie.json';
import * as neverbounce from './intl/neverbounce.json';
import * as newRelic from './intl/new-relic.json';
import * as newsapi from './intl/newsapi.json';
import * as nimble from './intl/nimble.json';
import * as nominatim from './intl/nominatim.json';
import * as nutshellCrm from './intl/nutshell-crm.json';
import * as omnisend from './intl/omnisend.json';
import * as openweather from './intl/openweather.json';
import * as outreach from './intl/outreach.json';
import * as pandadoc from './intl/pandadoc.json';
import * as pinterest from './intl/pinterest.json';
import * as pipedrive from './intl/pipedrive.json';
import * as plaid from './intl/plaid.json';
import * as planeSo from './intl/plane-so.json';
import * as recurly from './intl/recurly.json';
import * as reddit from './intl/reddit.json';
import * as sageBusinessCloud from './intl/sage-business-cloud.json';
import * as salesflare from './intl/salesflare.json';
import * as salesloft from './intl/salesloft.json';
import * as savvycal from './intl/savvycal.json';
import * as sendgrid from './intl/sendgrid.json';
Expand All @@ -112,23 +137,31 @@ import * as slab from './intl/slab.json';
import * as snov from './intl/snov.json';
import * as sorare from './intl/sorare.json';
import * as statsig from './intl/statsig.json';
import * as streak from './intl/streak.json';
import * as substack from './intl/substack.json';
import * as surveymonkey from './intl/surveymonkey.json';
import * as tally from './intl/tally.json';
import * as teamworkProjects from './intl/teamwork-projects.json';
import * as telegramBot from './intl/telegram-bot.json';
import * as ticktick from './intl/ticktick.json';
import * as tidio from './intl/tidio.json';
import * as timetastic from './intl/timetastic.json';
import * as todoist from './intl/todoist.json';
import * as togglTrack from './intl/toggl-track.json';
import * as trello from './intl/trello.json';
import * as typeform from './intl/typeform.json';
import * as uptimeRobot from './intl/uptime-robot.json';
import * as vercelAnalytics from './intl/vercel-analytics.json';
import * as waveAccounting from './intl/wave-accounting.json';
import * as whatsappBusiness from './intl/whatsapp-business.json';
import * as woocommerce from './intl/woocommerce.json';
import * as wordpress from './intl/wordpress.json';
import * as workable from './intl/workable.json';
import * as wrike from './intl/wrike.json';
import * as wufoo from './intl/wufoo.json';
import * as youtubeData from './intl/youtube-data.json';
import * as zendesk from './intl/zendesk.json';
import * as zohoCrm from './intl/zoho-crm.json';
import * as mercadoLibre from './br/mercado-libre.json';
import * as razorpay from './in/razorpay.json';
import * as lineMessaging from './jp/line-messaging.json';
Expand Down Expand Up @@ -240,14 +273,19 @@ const RAW_ADAPTERS: AdapterDefinition[] = [
activecampaign as unknown as AdapterDefinition,
acuityScheduling as unknown as AdapterDefinition,
adyen as unknown as AdapterDefinition,
agilecrm as unknown as AdapterDefinition,
amadeus as unknown as AdapterDefinition,
apollo as unknown as AdapterDefinition,
attio as unknown as AdapterDefinition,
bamboohr as unknown as AdapterDefinition,
basecamp as unknown as AdapterDefinition,
beehiiv as unknown as AdapterDefinition,
bigcommerce as unknown as AdapterDefinition,
bitrix24 as unknown as AdapterDefinition,
bluesky as unknown as AdapterDefinition,
box as unknown as AdapterDefinition,
brevo as unknown as AdapterDefinition,
buffer as unknown as AdapterDefinition,
bugsnag as unknown as AdapterDefinition,
calendly as unknown as AdapterDefinition,
chargebee as unknown as AdapterDefinition,
Expand All @@ -261,20 +299,27 @@ const RAW_ADAPTERS: AdapterDefinition[] = [
copper as unknown as AdapterDefinition,
crisp as unknown as AdapterDefinition,
datadog as unknown as AdapterDefinition,
deel as unknown as AdapterDefinition,
discordBot as unknown as AdapterDefinition,
drip as unknown as AdapterDefinition,
dropbox as unknown as AdapterDefinition,
dropboxSign as unknown as AdapterDefinition,
ecwid as unknown as AdapterDefinition,
etsy as unknown as AdapterDefinition,
fathom as unknown as AdapterDefinition,
fillout as unknown as AdapterDefinition,
flutterwave as unknown as AdapterDefinition,
folk as unknown as AdapterDefinition,
freshbooks as unknown as AdapterDefinition,
freshchat as unknown as AdapterDefinition,
freshdesk as unknown as AdapterDefinition,
freshservice as unknown as AdapterDefinition,
front as unknown as AdapterDefinition,
ghost as unknown as AdapterDefinition,
gitbook as unknown as AdapterDefinition,
gocardless as unknown as AdapterDefinition,
gorgias as unknown as AdapterDefinition,
greenhouse as unknown as AdapterDefinition,
hackernews as unknown as AdapterDefinition,
harvest as unknown as AdapterDefinition,
heap as unknown as AdapterDefinition,
Expand All @@ -283,14 +328,19 @@ const RAW_ADAPTERS: AdapterDefinition[] = [
hunter as unknown as AdapterDefinition,
insightly as unknown as AdapterDefinition,
instantly as unknown as AdapterDefinition,
invoiced as unknown as AdapterDefinition,
kashflow as unknown as AdapterDefinition,
klaviyo as unknown as AdapterDefinition,
kustomer as unknown as AdapterDefinition,
lemlist as unknown as AdapterDefinition,
lemonsqueezy as unknown as AdapterDefinition,
lessAnnoyingCrm as unknown as AdapterDefinition,
lever as unknown as AdapterDefinition,
linkedin as unknown as AdapterDefinition,
loops as unknown as AdapterDefinition,
magento as unknown as AdapterDefinition,
mailchimp as unknown as AdapterDefinition,
mailerlite as unknown as AdapterDefinition,
mailshake as unknown as AdapterDefinition,
mapbox as unknown as AdapterDefinition,
mastodon as unknown as AdapterDefinition,
Expand All @@ -303,13 +353,21 @@ const RAW_ADAPTERS: AdapterDefinition[] = [
neverbounce as unknown as AdapterDefinition,
newRelic as unknown as AdapterDefinition,
newsapi as unknown as AdapterDefinition,
nimble as unknown as AdapterDefinition,
nominatim as unknown as AdapterDefinition,
nutshellCrm as unknown as AdapterDefinition,
omnisend as unknown as AdapterDefinition,
openweather as unknown as AdapterDefinition,
outreach as unknown as AdapterDefinition,
pandadoc as unknown as AdapterDefinition,
pinterest as unknown as AdapterDefinition,
pipedrive as unknown as AdapterDefinition,
plaid as unknown as AdapterDefinition,
planeSo as unknown as AdapterDefinition,
recurly as unknown as AdapterDefinition,
reddit as unknown as AdapterDefinition,
sageBusinessCloud as unknown as AdapterDefinition,
salesflare as unknown as AdapterDefinition,
salesloft as unknown as AdapterDefinition,
savvycal as unknown as AdapterDefinition,
sendgrid as unknown as AdapterDefinition,
Expand All @@ -318,23 +376,31 @@ const RAW_ADAPTERS: AdapterDefinition[] = [
snov as unknown as AdapterDefinition,
sorare as unknown as AdapterDefinition,
statsig as unknown as AdapterDefinition,
streak as unknown as AdapterDefinition,
substack as unknown as AdapterDefinition,
surveymonkey as unknown as AdapterDefinition,
tally as unknown as AdapterDefinition,
teamworkProjects as unknown as AdapterDefinition,
telegramBot as unknown as AdapterDefinition,
ticktick as unknown as AdapterDefinition,
tidio as unknown as AdapterDefinition,
timetastic as unknown as AdapterDefinition,
todoist as unknown as AdapterDefinition,
togglTrack as unknown as AdapterDefinition,
trello as unknown as AdapterDefinition,
typeform as unknown as AdapterDefinition,
uptimeRobot as unknown as AdapterDefinition,
vercelAnalytics as unknown as AdapterDefinition,
waveAccounting as unknown as AdapterDefinition,
whatsappBusiness as unknown as AdapterDefinition,
woocommerce as unknown as AdapterDefinition,
wordpress as unknown as AdapterDefinition,
workable as unknown as AdapterDefinition,
wrike as unknown as AdapterDefinition,
wufoo as unknown as AdapterDefinition,
youtubeData as unknown as AdapterDefinition,
zendesk as unknown as AdapterDefinition,
zohoCrm as unknown as AdapterDefinition,
mercadoLibre as unknown as AdapterDefinition,
razorpay as unknown as AdapterDefinition,
lineMessaging as unknown as AdapterDefinition,
Expand Down
Loading
Loading