@mastra/connect 0.4.0 → 0.5.0-alpha.1
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/channels.d.ts +40 -32
- package/dist/channels.d.ts.map +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/index.cjs +100 -91
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +100 -91
- package/dist/index.js.map +1 -1
- package/dist/providers/channel-provider.d.ts +45 -17
- package/dist/providers/channel-provider.d.ts.map +1 -1
- package/dist/providers/channels.d.ts +1 -1
- package/dist/providers/channels.d.ts.map +1 -1
- package/package.json +8 -22
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export { connect } from './connect.js';
|
|
|
4
4
|
export type { ConnectOptions, ConnectIntegrationOptions, ConnectTools } from './connect.js';
|
|
5
5
|
export { channels } from './channels.js';
|
|
6
6
|
export type { ChannelsOptions, ChannelsIntegrationOptions, ChannelsResolver, ChannelsResolverContext, ResolvedChannels, } from './channels.js';
|
|
7
|
-
export type { ChannelProviderRegistration,
|
|
7
|
+
export type { ChannelProviderRegistration, ChannelInstance, ChannelRuntime } from './providers/channel-provider.js';
|
|
8
8
|
export { credential } from './credential.js';
|
|
9
9
|
export { environment } from './environment.js';
|
|
10
10
|
export type { ConnectEnvironment, EnvironmentIntegrationOptions, EnvironmentOptions } from './environment.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,YAAY,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACvF,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,cAAc,EAAE,yBAAyB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EACV,eAAe,EACf,0BAA0B,EAC1B,gBAAgB,EAChB,uBAAuB,EACvB,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,2BAA2B,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,YAAY,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACvF,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,cAAc,EAAE,yBAAyB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EACV,eAAe,EACf,0BAA0B,EAC1B,gBAAgB,EAChB,uBAAuB,EACvB,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,2BAA2B,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACpH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,kBAAkB,EAAE,6BAA6B,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC9G,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,YAAY,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC1D,YAAY,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACjG,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACtG,YAAY,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -346,14 +346,12 @@ async function proxyRequestWithResponse(client, connectionId, options) {
|
|
|
346
346
|
function credentialToken$1(credential) {
|
|
347
347
|
return credential.type === "oauth2" ? credential.accessToken : credential.apiKey;
|
|
348
348
|
}
|
|
349
|
-
function missingPeerError(integrationId, packageName, error) {
|
|
350
|
-
return new MastraConnectError("invalid_options", `channels() cannot build '${integrationId}' provider: install '${packageName}' as a dependency of your app (${error instanceof Error ? error.message : String(error)}).`);
|
|
351
|
-
}
|
|
352
349
|
const RESERVED_OPTION_KEYS = {
|
|
353
350
|
slack: [
|
|
354
351
|
"baseUrl",
|
|
355
352
|
"refreshToken",
|
|
356
353
|
"token",
|
|
354
|
+
"tokenResolver",
|
|
357
355
|
"encryptionKey"
|
|
358
356
|
],
|
|
359
357
|
telegram: [
|
|
@@ -383,61 +381,54 @@ function stripReservedOptions(integrationId, options) {
|
|
|
383
381
|
const CHANNELS$1 = [
|
|
384
382
|
{
|
|
385
383
|
integrationId: "slack",
|
|
386
|
-
async
|
|
387
|
-
const
|
|
388
|
-
let mod;
|
|
389
|
-
try {
|
|
390
|
-
mod = await import("@mastra/slack");
|
|
391
|
-
} catch (error) {
|
|
392
|
-
throw missingPeerError("slack", "@mastra/slack", error);
|
|
393
|
-
}
|
|
384
|
+
async create(options, runtime) {
|
|
385
|
+
const mod = await import("@mastra/slack");
|
|
394
386
|
const safeOptions = stripReservedOptions("slack", options);
|
|
395
|
-
|
|
396
|
-
|
|
387
|
+
const tokenResolver = async () => {
|
|
388
|
+
return credentialToken$1(await runtime.getCredential());
|
|
389
|
+
};
|
|
390
|
+
return { provider: new mod.SlackProvider({
|
|
391
|
+
tokenResolver,
|
|
397
392
|
...safeOptions ?? {}
|
|
398
|
-
});
|
|
393
|
+
}) };
|
|
399
394
|
}
|
|
400
395
|
},
|
|
401
396
|
{
|
|
402
397
|
integrationId: "telegram",
|
|
403
|
-
async
|
|
404
|
-
const
|
|
405
|
-
let mod;
|
|
406
|
-
try {
|
|
407
|
-
mod = await import("@mastra/telegram");
|
|
408
|
-
} catch (error) {
|
|
409
|
-
throw missingPeerError("telegram", "@mastra/telegram", error);
|
|
410
|
-
}
|
|
398
|
+
async create(options, runtime) {
|
|
399
|
+
const mod = await import("@mastra/telegram");
|
|
411
400
|
const safeOptions = stripReservedOptions("telegram", options);
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
401
|
+
const provider = new mod.TelegramProvider({ ...safeOptions ?? {} });
|
|
402
|
+
return {
|
|
403
|
+
provider,
|
|
404
|
+
async sync() {
|
|
405
|
+
const botToken = credentialToken$1(await runtime.getCredential());
|
|
406
|
+
await provider.configure?.({ botToken });
|
|
407
|
+
}
|
|
408
|
+
};
|
|
416
409
|
}
|
|
417
410
|
},
|
|
418
411
|
{
|
|
419
412
|
integrationId: "discord",
|
|
420
|
-
async
|
|
421
|
-
const
|
|
422
|
-
const
|
|
423
|
-
const
|
|
424
|
-
const
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
...rest
|
|
440
|
-
});
|
|
413
|
+
async create(options, runtime) {
|
|
414
|
+
const mod = await import("@mastra/discord");
|
|
415
|
+
const { applicationId: optionsAppId, publicKey: optionsPublicKey, ...rest } = options ?? {};
|
|
416
|
+
const safeOptions = stripReservedOptions("discord", rest);
|
|
417
|
+
const provider = new mod.DiscordProvider({ ...safeOptions ?? {} });
|
|
418
|
+
return {
|
|
419
|
+
provider,
|
|
420
|
+
async sync() {
|
|
421
|
+
const metadata = (await runtime.getConnectionContext())?.metadata ?? {};
|
|
422
|
+
const botToken = typeof metadata.botToken === "string" && metadata.botToken || typeof metadata.bot_token === "string" && metadata.bot_token || void 0;
|
|
423
|
+
if (!botToken) throw new MastraConnectError("no_active_connection", `Discord connection ${runtime.getConnectionId()} has no botToken in its metadata. Store the bot token on the connection (Nango setMetadata) to activate the Discord channel.`);
|
|
424
|
+
const applicationId = optionsAppId ?? (typeof metadata.applicationId === "string" ? metadata.applicationId : void 0) ?? (typeof metadata.application_id === "string" ? metadata.application_id : void 0);
|
|
425
|
+
const publicKey = optionsPublicKey ?? (typeof metadata.publicKey === "string" ? metadata.publicKey : void 0) ?? (typeof metadata.public_key === "string" ? metadata.public_key : void 0);
|
|
426
|
+
const credentials = { botToken };
|
|
427
|
+
if (applicationId) credentials.applicationId = applicationId;
|
|
428
|
+
if (publicKey) credentials.publicKey = publicKey;
|
|
429
|
+
await provider.configure?.(credentials);
|
|
430
|
+
}
|
|
431
|
+
};
|
|
441
432
|
}
|
|
442
433
|
}
|
|
443
434
|
];
|
|
@@ -66153,16 +66144,22 @@ const DEFAULT_TTL_MS = 3e4;
|
|
|
66153
66144
|
/** Minimum wait after a failed platform fetch before another background revalidation. */
|
|
66154
66145
|
const FAILURE_COOLDOWN_MS = 3e4;
|
|
66155
66146
|
/**
|
|
66156
|
-
* Returns a live channels resolver over the project's Platform connections
|
|
66157
|
-
*
|
|
66158
|
-
*
|
|
66159
|
-
*
|
|
66147
|
+
* Returns a live channels resolver over the project's Platform connections,
|
|
66148
|
+
* ready to hand to `new Mastra({ channels: await channels({...}) })`.
|
|
66149
|
+
*
|
|
66150
|
+
* Provider instances for every channel-capable integration (Slack, Telegram,
|
|
66151
|
+
* Discord) are constructed once, up front and credential-less, so their
|
|
66152
|
+
* webhook/OAuth routes can mount at Mastra construction. Each resolution
|
|
66153
|
+
* fetches the project's connections and late-binds credentials into the live
|
|
66154
|
+
* instances: integrations with an active connection appear in the resolved
|
|
66155
|
+
* map, others don't — so connecting a new channel on the platform takes
|
|
66156
|
+
* effect without redeploying the app.
|
|
66160
66157
|
*
|
|
66161
66158
|
* Configuration errors (missing project id, bad ttlMs, malformed integration
|
|
66162
|
-
* id)
|
|
66163
|
-
* problems
|
|
66164
|
-
* are downgraded to warn-and-skip so one
|
|
66165
|
-
* whole map.
|
|
66159
|
+
* id) reject at call time so they surface at startup. Actionable
|
|
66160
|
+
* per-integration problems (provider construction failure, needs re-auth,
|
|
66161
|
+
* ambiguity, credential sync failure) are downgraded to warn-and-skip so one
|
|
66162
|
+
* bad integration never takes down the whole map.
|
|
66166
66163
|
*
|
|
66167
66164
|
* @example
|
|
66168
66165
|
* ```ts
|
|
@@ -66175,13 +66172,48 @@ const FAILURE_COOLDOWN_MS = 3e4;
|
|
|
66175
66172
|
* });
|
|
66176
66173
|
* ```
|
|
66177
66174
|
*/
|
|
66178
|
-
function channels(options = {}) {
|
|
66175
|
+
async function channels(options = {}) {
|
|
66179
66176
|
const projectId = options.projectId?.trim() || process.env.MASTRA_PROJECT_ID?.trim();
|
|
66180
66177
|
if (!projectId) throw new MastraConnectError("missing_project_id", "Missing project id: set MASTRA_PROJECT_ID or pass projectId.");
|
|
66181
66178
|
if (options.ttlMs !== void 0 && (!Number.isFinite(options.ttlMs) || options.ttlMs < 0)) throw new MastraConnectError("invalid_options", `Invalid ttlMs (${options.ttlMs}): expected a finite number of milliseconds >= 0.`);
|
|
66182
66179
|
validateIntegrationOverrides(options.integrations);
|
|
66183
66180
|
const ttlMs = options.ttlMs ?? DEFAULT_TTL_MS;
|
|
66184
66181
|
const client = resolveClient(options.client);
|
|
66182
|
+
const states = [];
|
|
66183
|
+
for (const registration of CHANNELS) {
|
|
66184
|
+
const overrides = options.integrations?.[registration.integrationId] ?? {};
|
|
66185
|
+
if (overrides.disabled) continue;
|
|
66186
|
+
const state = {
|
|
66187
|
+
registration,
|
|
66188
|
+
instance: void 0,
|
|
66189
|
+
connectionId: void 0
|
|
66190
|
+
};
|
|
66191
|
+
const runtime = {
|
|
66192
|
+
client,
|
|
66193
|
+
getConnectionId: () => state.connectionId,
|
|
66194
|
+
getCredential: async () => {
|
|
66195
|
+
const connectionId = state.connectionId;
|
|
66196
|
+
if (!connectionId) throw new MastraConnectError("no_active_connection", `No active ${registration.integrationId} connection for project ${projectId}. Connect one on the platform, then retry.`);
|
|
66197
|
+
return getCredential(client, connectionId);
|
|
66198
|
+
},
|
|
66199
|
+
getConnectionContext: async () => {
|
|
66200
|
+
const connectionId = state.connectionId;
|
|
66201
|
+
if (!connectionId) return void 0;
|
|
66202
|
+
try {
|
|
66203
|
+
return await getConnectionContext(client, connectionId);
|
|
66204
|
+
} catch {
|
|
66205
|
+
return;
|
|
66206
|
+
}
|
|
66207
|
+
}
|
|
66208
|
+
};
|
|
66209
|
+
try {
|
|
66210
|
+
state.instance = await registration.create(overrides.providerOptions ?? {}, runtime);
|
|
66211
|
+
} catch (error) {
|
|
66212
|
+
console.warn(`[@mastra/connect] Skipping ${registration.integrationId} channel: ${error instanceof Error ? error.message : String(error)}`);
|
|
66213
|
+
continue;
|
|
66214
|
+
}
|
|
66215
|
+
states.push(state);
|
|
66216
|
+
}
|
|
66185
66217
|
let cache;
|
|
66186
66218
|
let inflight;
|
|
66187
66219
|
let lastFailureAt;
|
|
@@ -66195,17 +66227,20 @@ function channels(options = {}) {
|
|
|
66195
66227
|
}
|
|
66196
66228
|
const byIntegrationId = groupByIntegrationId(connections);
|
|
66197
66229
|
const providers = {};
|
|
66198
|
-
for (const
|
|
66199
|
-
const integrationId = registration.integrationId;
|
|
66230
|
+
for (const state of states) {
|
|
66231
|
+
const integrationId = state.registration.integrationId;
|
|
66200
66232
|
const overrides = options.integrations?.[integrationId] ?? {};
|
|
66201
|
-
if (overrides.disabled) continue;
|
|
66202
66233
|
const candidates = byIntegrationId.get(integrationId) ?? [];
|
|
66203
|
-
|
|
66204
|
-
|
|
66234
|
+
const connectionId = candidates.length === 0 ? void 0 : selectChannelConnection(integrationId, overrides.connectionId, candidates);
|
|
66235
|
+
state.connectionId = connectionId;
|
|
66205
66236
|
if (!connectionId) continue;
|
|
66206
|
-
|
|
66207
|
-
|
|
66208
|
-
|
|
66237
|
+
if (state.instance.sync) try {
|
|
66238
|
+
await state.instance.sync();
|
|
66239
|
+
} catch (error) {
|
|
66240
|
+
console.warn(`[@mastra/connect] Skipping ${integrationId} channel: ${error instanceof Error ? error.message : String(error)}`);
|
|
66241
|
+
continue;
|
|
66242
|
+
}
|
|
66243
|
+
providers[integrationId] = state.instance.provider;
|
|
66209
66244
|
}
|
|
66210
66245
|
lastFailureAt = void 0;
|
|
66211
66246
|
return providers;
|
|
@@ -66240,6 +66275,7 @@ function channels(options = {}) {
|
|
|
66240
66275
|
return refresh();
|
|
66241
66276
|
};
|
|
66242
66277
|
const invocable = ((_context) => resolve());
|
|
66278
|
+
invocable.getRoutes = () => states.flatMap((state) => state.instance.provider.getRoutes());
|
|
66243
66279
|
invocable.invalidate = () => {
|
|
66244
66280
|
cache = void 0;
|
|
66245
66281
|
};
|
|
@@ -66247,35 +66283,8 @@ function channels(options = {}) {
|
|
|
66247
66283
|
invocable.disconnect = async () => {
|
|
66248
66284
|
cache = void 0;
|
|
66249
66285
|
};
|
|
66250
|
-
invocable.then = ((onfulfilled, onrejected) => resolve().then(onfulfilled, onrejected));
|
|
66251
66286
|
return invocable;
|
|
66252
66287
|
}
|
|
66253
|
-
async function buildProvider(registration, connectionId, overrides, client) {
|
|
66254
|
-
let credential;
|
|
66255
|
-
try {
|
|
66256
|
-
credential = await getCredential(client, connectionId);
|
|
66257
|
-
} catch (error) {
|
|
66258
|
-
console.warn(`[@mastra/connect] Skipping ${registration.integrationId} channel: ${error instanceof Error ? error.message : String(error)}`);
|
|
66259
|
-
return;
|
|
66260
|
-
}
|
|
66261
|
-
let context = {
|
|
66262
|
-
connectionId,
|
|
66263
|
-
client
|
|
66264
|
-
};
|
|
66265
|
-
try {
|
|
66266
|
-
context = {
|
|
66267
|
-
connectionId,
|
|
66268
|
-
client,
|
|
66269
|
-
context: await getConnectionContext(client, connectionId)
|
|
66270
|
-
};
|
|
66271
|
-
} catch {}
|
|
66272
|
-
try {
|
|
66273
|
-
return await registration.build(credential, overrides.providerOptions ?? {}, context);
|
|
66274
|
-
} catch (error) {
|
|
66275
|
-
console.warn(`[@mastra/connect] Skipping ${registration.integrationId} channel: ${error instanceof Error ? error.message : String(error)}`);
|
|
66276
|
-
return;
|
|
66277
|
-
}
|
|
66278
|
-
}
|
|
66279
66288
|
/**
|
|
66280
66289
|
* Selects the connection `channels()` should use for one provider.
|
|
66281
66290
|
*
|