@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.
@@ -1,6 +1,7 @@
1
1
  import type { ChannelProvider } from '@mastra/core/channels';
2
2
  import type { ConnectClientOptions } from './client.js';
3
3
  import type { DiscordReservedProviderOption, SlackReservedProviderOption, TelegramReservedProviderOption } from './providers/channels.js';
4
+ type ApiRoute = ReturnType<ChannelProvider['getRoutes']>[number];
4
5
  /**
5
6
  * `providerOptions` fields that `channels()` refuses to forward to a
6
7
  * `ChannelProvider` constructor. Marking them `never` here makes the compiler
@@ -33,9 +34,9 @@ export type DiscordChannelsProviderOptions = Record<string, unknown> & {
33
34
  export interface ChannelsIntegrationOptions<ProviderOptions = Record<string, unknown>> {
34
35
  /** Pin a specific connection id (bypasses single-active-connection resolution). */
35
36
  connectionId?: string;
36
- /** Exclude this provider entirely, even if a connection exists. */
37
+ /** Exclude this provider entirely — no instance is constructed and no routes are mounted. */
37
38
  disabled?: boolean;
38
- /** Provider-specific options merged into the second argument of `ChannelProviderRegistration.build()`. */
39
+ /** Provider-specific options merged into the first argument of `ChannelProviderRegistration.create()`. */
39
40
  providerOptions?: ProviderOptions;
40
41
  }
41
42
  /**
@@ -60,56 +61,63 @@ export interface ChannelsOptions {
60
61
  }
61
62
  /**
62
63
  * The result of resolving a project's connections into a
63
- * `ChannelProvider` map. Assignable directly to `Mastra({ channels })`.
64
+ * `ChannelProvider` map: integrations with an active connection, keyed by
65
+ * integrationId.
64
66
  */
65
67
  export type ResolvedChannels = Record<string, ChannelProvider>;
66
68
  /**
67
- * Callback context passed to `channels()`'s resolver when invoked with a
68
- * runtime context. Mirrors the shape used by `tools()` and other dynamic
69
- * agent fields — currently unused (per-request provider variance isn't
70
- * modeled here) but kept for signature symmetry.
69
+ * Callback context passed to the resolver when invoked with a runtime
70
+ * context. Mirrors `@mastra/core`'s `ChannelsResolverContext` — Mastra passes
71
+ * `{ mastra }` from `resolveChannels()`; the resolver currently doesn't vary
72
+ * output by context.
71
73
  */
72
74
  export interface ChannelsResolverContext {
73
75
  requestContext?: unknown;
74
76
  mastra?: unknown;
75
77
  }
76
78
  /**
77
- * The value returned by `channels()`. Symmetric with `tools()`:
79
+ * The value `channels()` resolves to. Satisfies `@mastra/core`'s
80
+ * `ChannelsResolver` contract, so it can be handed to
81
+ * `new Mastra({ channels })` directly:
78
82
  *
79
- * - Thenable — `await channels({ projectId })` yields a
80
- * `Record<string, ChannelProvider>` directly, ready to hand to
81
- * `new Mastra({ channels: await channels({ projectId }) })`.
82
- * - Callable — `channels(opts)(ctx)` returns the same
83
- * `Record<string, ChannelProvider>`; identical to `await channels(opts)`.
84
- * - Handles — `invalidate()` / `refresh()` / `disconnect()` scope to the
85
- * resolver's private cache only. `Mastra({ channels })` reads the
86
- * `Record<string, ChannelProvider>` **synchronously** at construction time,
87
- * so the constructed Mastra instance will not pick up newly-added
88
- * connections or rotated credentials without a restart. These handles are
89
- * for standalone/test usage where the resolver is being called directly —
90
- * not for the Mastra-registered snapshot.
83
+ * - Callable — returns the current `Record<string, ChannelProvider>` of
84
+ * integrations with an active connection. Mastra invokes it via
85
+ * `resolveChannels()`; the TTL cache makes repeat calls cheap.
86
+ * - `getRoutes()` — the union of routes for every non-disabled channel,
87
+ * available synchronously so Mastra can mount them at construction. Routes
88
+ * exist before (and after) their integration has an active connection.
89
+ * - Handles — `invalidate()` / `refresh()` / `disconnect()` control the
90
+ * resolver's private cache; `refresh()` forces a platform fetch now.
91
91
  */
92
- export interface ChannelsResolver extends PromiseLike<ResolvedChannels> {
93
- /** Callable form used for symmetry with `tools()`; returns the resolved map. */
92
+ export interface ChannelsResolver {
93
+ /** Returns the current provider map for integrations with an active connection. */
94
94
  (context?: ChannelsResolverContext): Promise<ResolvedChannels>;
95
+ /** Union of API routes for every non-disabled channel integration. */
96
+ getRoutes(): ApiRoute[];
95
97
  /** Drops the cached snapshot; the next resolution fetches fresh from the platform. */
96
98
  invalidate(): void;
97
- /** Fetches providers from the platform now and updates the cache. Rejects if the platform fetch fails. */
99
+ /** Fetches connections from the platform now and updates the cache. Rejects if the platform fetch fails. */
98
100
  refresh(): Promise<ResolvedChannels>;
99
101
  /** Clears the cached snapshot. Reserved for symmetry with `tools()`; currently a no-op beyond invalidation. */
100
102
  disconnect(): Promise<void>;
101
103
  }
102
104
  /**
103
- * Returns a live channels resolver over the project's Platform connections.
104
- * Channel-capable integrations (Slack, Telegram, Discord) with an active
105
- * project connection are materialized into `ChannelProvider` instances ready
106
- * to hand to `new Mastra({ channels: await channels({...}) })`.
105
+ * Returns a live channels resolver over the project's Platform connections,
106
+ * ready to hand to `new Mastra({ channels: await channels({...}) })`.
107
+ *
108
+ * Provider instances for every channel-capable integration (Slack, Telegram,
109
+ * Discord) are constructed once, up front and credential-less, so their
110
+ * webhook/OAuth routes can mount at Mastra construction. Each resolution
111
+ * fetches the project's connections and late-binds credentials into the live
112
+ * instances: integrations with an active connection appear in the resolved
113
+ * map, others don't — so connecting a new channel on the platform takes
114
+ * effect without redeploying the app.
107
115
  *
108
116
  * Configuration errors (missing project id, bad ttlMs, malformed integration
109
- * id) throw at call time so they surface at startup. Actionable per-integration
110
- * problems during resolution (needs re-auth, ambiguity, missing peer package)
111
- * are downgraded to warn-and-skip so one bad integration never takes down the
112
- * whole map.
117
+ * id) reject at call time so they surface at startup. Actionable
118
+ * per-integration problems (provider construction failure, needs re-auth,
119
+ * ambiguity, credential sync failure) are downgraded to warn-and-skip so one
120
+ * bad integration never takes down the whole map.
113
121
  *
114
122
  * @example
115
123
  * ```ts
@@ -122,6 +130,6 @@ export interface ChannelsResolver extends PromiseLike<ResolvedChannels> {
122
130
  * });
123
131
  * ```
124
132
  */
125
- export declare function channels(options?: ChannelsOptions): ChannelsResolver;
133
+ export declare function channels(options?: ChannelsOptions): Promise<ChannelsResolver>;
126
134
  export {};
127
135
  //# sourceMappingURL=channels.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../src/channels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,KAAK,EAAE,oBAAoB,EAA2D,MAAM,aAAa,CAAC;AAIjH,OAAO,KAAK,EACV,6BAA6B,EAC7B,2BAA2B,EAC3B,8BAA8B,EAC/B,MAAM,yBAAyB,CAAC;AAIjC;;;;;;;;;;;;;;;;;GAiBG;AACH,KAAK,qBAAqB,CAAC,QAAQ,SAAS,MAAM,IAAI;KAAG,CAAC,IAAI,QAAQ,CAAC,CAAC,EAAE,KAAK;CAAE,CAAC;AAElF,gFAAgF;AAChF,MAAM,MAAM,4BAA4B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,qBAAqB,CAAC,2BAA2B,CAAC,CAAC;AACxH,MAAM,MAAM,+BAA+B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnE,qBAAqB,CAAC,8BAA8B,CAAC,CAAC;AACxD,MAAM,MAAM,8BAA8B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IACrE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,qBAAqB,CAAC,6BAA6B,CAAC,CAAC;AAEzD,wGAAwG;AACxG,MAAM,WAAW,0BAA0B,CAAC,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACnF,mFAAmF;IACnF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0GAA0G;IAC1G,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAED;;;;GAIG;AACH,MAAM,WAAW,4BAA4B;IAC3C,KAAK,CAAC,EAAE,0BAA0B,CAAC,4BAA4B,CAAC,CAAC;IACjE,QAAQ,CAAC,EAAE,0BAA0B,CAAC,+BAA+B,CAAC,CAAC;IACvE,OAAO,CAAC,EAAE,0BAA0B,CAAC,8BAA8B,CAAC,CAAC;IACrE,CAAC,aAAa,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS,CAAC;CACjE;AAED,MAAM,WAAW,eAAe;IAC9B,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,4BAA4B,CAAC;IAC5C,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,mHAAmH;IACnH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,gBAAiB,SAAQ,WAAW,CAAC,gBAAgB,CAAC;IACrE,gFAAgF;IAChF,CAAC,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC/D,sFAAsF;IACtF,UAAU,IAAI,IAAI,CAAC;IACnB,0GAA0G;IAC1G,OAAO,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACrC,+GAA+G;IAC/G,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAMD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,gBAAgB,CAuGxE"}
1
+ {"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../src/channels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,KAAK,EAAE,oBAAoB,EAAqB,MAAM,aAAa,CAAC;AAI3E,OAAO,KAAK,EACV,6BAA6B,EAC7B,2BAA2B,EAC3B,8BAA8B,EAC/B,MAAM,yBAAyB,CAAC;AAIjC,KAAK,QAAQ,GAAG,UAAU,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE;;;;;;;;;;;;;;;;;GAiBG;AACH,KAAK,qBAAqB,CAAC,QAAQ,SAAS,MAAM,IAAI;KAAG,CAAC,IAAI,QAAQ,CAAC,CAAC,EAAE,KAAK;CAAE,CAAC;AAElF,gFAAgF;AAChF,MAAM,MAAM,4BAA4B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,qBAAqB,CAAC,2BAA2B,CAAC,CAAC;AACxH,MAAM,MAAM,+BAA+B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnE,qBAAqB,CAAC,8BAA8B,CAAC,CAAC;AACxD,MAAM,MAAM,8BAA8B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IACrE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,qBAAqB,CAAC,6BAA6B,CAAC,CAAC;AAEzD,wGAAwG;AACxG,MAAM,WAAW,0BAA0B,CAAC,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACnF,mFAAmF;IACnF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0GAA0G;IAC1G,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAED;;;;GAIG;AACH,MAAM,WAAW,4BAA4B;IAC3C,KAAK,CAAC,EAAE,0BAA0B,CAAC,4BAA4B,CAAC,CAAC;IACjE,QAAQ,CAAC,EAAE,0BAA0B,CAAC,+BAA+B,CAAC,CAAC;IACvE,OAAO,CAAC,EAAE,0BAA0B,CAAC,8BAA8B,CAAC,CAAC;IACrE,CAAC,aAAa,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS,CAAC;CACjE;AAED,MAAM,WAAW,eAAe;IAC9B,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,4BAA4B,CAAC;IAC5C,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,mHAAmH;IACnH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,gBAAgB;IAC/B,mFAAmF;IACnF,CAAC,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC/D,sEAAsE;IACtE,SAAS,IAAI,QAAQ,EAAE,CAAC;IACxB,sFAAsF;IACtF,UAAU,IAAI,IAAI,CAAC;IACnB,4GAA4G;IAC5G,OAAO,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACrC,+GAA+G;IAC/G,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAcD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAmKvF"}
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/errors.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type MastraConnectErrorCode = 'missing_access_token' | 'missing_project_id' | 'missing_connection_id' | 'invalid_options' | 'connection_not_found' | 'unauthorized' | 'proxy_error' | 'unsupported_credential_type' | 'platform_error';
1
+ export type MastraConnectErrorCode = 'missing_access_token' | 'missing_project_id' | 'missing_connection_id' | 'invalid_options' | 'connection_not_found' | 'unauthorized' | 'proxy_error' | 'unsupported_credential_type' | 'no_active_connection' | 'platform_error';
2
2
  export declare class MastraConnectError extends Error {
3
3
  readonly code: MastraConnectErrorCode;
4
4
  readonly status?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,sBAAsB,GAC9B,sBAAsB,GACtB,oBAAoB,GACpB,uBAAuB,GACvB,iBAAiB,GACjB,sBAAsB,GACtB,cAAc,GACd,aAAa,GACb,6BAA6B,GAC7B,gBAAgB,CAAC;AAIrB,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEzB,YAAY,IAAI,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAMxG;CACF;AAcD;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,OAAO,CAAA;CAAE,CAAC,CAuBrE"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,sBAAsB,GAC9B,sBAAsB,GACtB,oBAAoB,GACpB,uBAAuB,GACvB,iBAAiB,GACjB,sBAAsB,GACtB,cAAc,GACd,aAAa,GACb,6BAA6B,GAC7B,sBAAsB,GACtB,gBAAgB,CAAC;AAIrB,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEzB,YAAY,IAAI,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAMxG;CACF;AAcD;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,OAAO,CAAA;CAAE,CAAC,CAuBrE"}
package/dist/index.cjs CHANGED
@@ -347,14 +347,12 @@ async function proxyRequestWithResponse(client, connectionId, options) {
347
347
  function credentialToken$1(credential) {
348
348
  return credential.type === "oauth2" ? credential.accessToken : credential.apiKey;
349
349
  }
350
- function missingPeerError(integrationId, packageName, error) {
351
- 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)}).`);
352
- }
353
350
  const RESERVED_OPTION_KEYS = {
354
351
  slack: [
355
352
  "baseUrl",
356
353
  "refreshToken",
357
354
  "token",
355
+ "tokenResolver",
358
356
  "encryptionKey"
359
357
  ],
360
358
  telegram: [
@@ -384,61 +382,54 @@ function stripReservedOptions(integrationId, options) {
384
382
  const CHANNELS$1 = [
385
383
  {
386
384
  integrationId: "slack",
387
- async build(credential, options) {
388
- const refreshToken = credentialToken$1(credential);
389
- let mod;
390
- try {
391
- mod = await import("@mastra/slack");
392
- } catch (error) {
393
- throw missingPeerError("slack", "@mastra/slack", error);
394
- }
385
+ async create(options, runtime) {
386
+ const mod = await import("@mastra/slack");
395
387
  const safeOptions = stripReservedOptions("slack", options);
396
- return new mod.SlackProvider({
397
- refreshToken,
388
+ const tokenResolver = async () => {
389
+ return credentialToken$1(await runtime.getCredential());
390
+ };
391
+ return { provider: new mod.SlackProvider({
392
+ tokenResolver,
398
393
  ...safeOptions ?? {}
399
- });
394
+ }) };
400
395
  }
401
396
  },
402
397
  {
403
398
  integrationId: "telegram",
404
- async build(credential, options) {
405
- const botToken = credentialToken$1(credential);
406
- let mod;
407
- try {
408
- mod = await import("@mastra/telegram");
409
- } catch (error) {
410
- throw missingPeerError("telegram", "@mastra/telegram", error);
411
- }
399
+ async create(options, runtime) {
400
+ const mod = await import("@mastra/telegram");
412
401
  const safeOptions = stripReservedOptions("telegram", options);
413
- return new mod.TelegramProvider({
414
- botToken,
415
- ...safeOptions ?? {}
416
- });
402
+ const provider = new mod.TelegramProvider({ ...safeOptions ?? {} });
403
+ return {
404
+ provider,
405
+ async sync() {
406
+ const botToken = credentialToken$1(await runtime.getCredential());
407
+ await provider.configure?.({ botToken });
408
+ }
409
+ };
417
410
  }
418
411
  },
419
412
  {
420
413
  integrationId: "discord",
421
- async build(credential, options, context) {
422
- const botToken = credentialToken$1(credential);
423
- const metadata = context?.context?.metadata ?? {};
424
- const applicationId = options?.applicationId ?? (typeof metadata.applicationId === "string" ? metadata.applicationId : void 0) ?? (typeof metadata.application_id === "string" ? metadata.application_id : void 0);
425
- const publicKey = options?.publicKey ?? (typeof metadata.publicKey === "string" ? metadata.publicKey : void 0) ?? (typeof metadata.public_key === "string" ? metadata.public_key : void 0);
426
- let mod;
427
- try {
428
- mod = await import("@mastra/discord");
429
- } catch (error) {
430
- throw missingPeerError("discord", "@mastra/discord", error);
431
- }
432
- if (!applicationId || !publicKey) console.warn(`[@mastra/connect] discord channel: missing ${[!applicationId && "applicationId", !publicKey && "publicKey"].filter(Boolean).join(" + ")} on the connection. Store them on the connection's metadata or pass them via integrations.discord.providerOptions.`);
433
- const { applicationId: _optAppId, publicKey: _optPubKey, ...rest } = options ?? {};
434
- return new mod.DiscordProvider({
435
- app: {
436
- botToken,
437
- applicationId,
438
- publicKey
439
- },
440
- ...rest
441
- });
414
+ async create(options, runtime) {
415
+ const mod = await import("@mastra/discord");
416
+ const { applicationId: optionsAppId, publicKey: optionsPublicKey, ...rest } = options ?? {};
417
+ const safeOptions = stripReservedOptions("discord", rest);
418
+ const provider = new mod.DiscordProvider({ ...safeOptions ?? {} });
419
+ return {
420
+ provider,
421
+ async sync() {
422
+ const metadata = (await runtime.getConnectionContext())?.metadata ?? {};
423
+ const botToken = typeof metadata.botToken === "string" && metadata.botToken || typeof metadata.bot_token === "string" && metadata.bot_token || void 0;
424
+ 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.`);
425
+ const applicationId = optionsAppId ?? (typeof metadata.applicationId === "string" ? metadata.applicationId : void 0) ?? (typeof metadata.application_id === "string" ? metadata.application_id : void 0);
426
+ const publicKey = optionsPublicKey ?? (typeof metadata.publicKey === "string" ? metadata.publicKey : void 0) ?? (typeof metadata.public_key === "string" ? metadata.public_key : void 0);
427
+ const credentials = { botToken };
428
+ if (applicationId) credentials.applicationId = applicationId;
429
+ if (publicKey) credentials.publicKey = publicKey;
430
+ await provider.configure?.(credentials);
431
+ }
432
+ };
442
433
  }
443
434
  }
444
435
  ];
@@ -66154,16 +66145,22 @@ const DEFAULT_TTL_MS = 3e4;
66154
66145
  /** Minimum wait after a failed platform fetch before another background revalidation. */
66155
66146
  const FAILURE_COOLDOWN_MS = 3e4;
66156
66147
  /**
66157
- * Returns a live channels resolver over the project's Platform connections.
66158
- * Channel-capable integrations (Slack, Telegram, Discord) with an active
66159
- * project connection are materialized into `ChannelProvider` instances ready
66160
- * to hand to `new Mastra({ channels: await channels({...}) })`.
66148
+ * Returns a live channels resolver over the project's Platform connections,
66149
+ * ready to hand to `new Mastra({ channels: await channels({...}) })`.
66150
+ *
66151
+ * Provider instances for every channel-capable integration (Slack, Telegram,
66152
+ * Discord) are constructed once, up front and credential-less, so their
66153
+ * webhook/OAuth routes can mount at Mastra construction. Each resolution
66154
+ * fetches the project's connections and late-binds credentials into the live
66155
+ * instances: integrations with an active connection appear in the resolved
66156
+ * map, others don't — so connecting a new channel on the platform takes
66157
+ * effect without redeploying the app.
66161
66158
  *
66162
66159
  * Configuration errors (missing project id, bad ttlMs, malformed integration
66163
- * id) throw at call time so they surface at startup. Actionable per-integration
66164
- * problems during resolution (needs re-auth, ambiguity, missing peer package)
66165
- * are downgraded to warn-and-skip so one bad integration never takes down the
66166
- * whole map.
66160
+ * id) reject at call time so they surface at startup. Actionable
66161
+ * per-integration problems (provider construction failure, needs re-auth,
66162
+ * ambiguity, credential sync failure) are downgraded to warn-and-skip so one
66163
+ * bad integration never takes down the whole map.
66167
66164
  *
66168
66165
  * @example
66169
66166
  * ```ts
@@ -66176,13 +66173,48 @@ const FAILURE_COOLDOWN_MS = 3e4;
66176
66173
  * });
66177
66174
  * ```
66178
66175
  */
66179
- function channels(options = {}) {
66176
+ async function channels(options = {}) {
66180
66177
  const projectId = options.projectId?.trim() || process.env.MASTRA_PROJECT_ID?.trim();
66181
66178
  if (!projectId) throw new MastraConnectError("missing_project_id", "Missing project id: set MASTRA_PROJECT_ID or pass projectId.");
66182
66179
  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.`);
66183
66180
  validateIntegrationOverrides(options.integrations);
66184
66181
  const ttlMs = options.ttlMs ?? DEFAULT_TTL_MS;
66185
66182
  const client = resolveClient(options.client);
66183
+ const states = [];
66184
+ for (const registration of CHANNELS) {
66185
+ const overrides = options.integrations?.[registration.integrationId] ?? {};
66186
+ if (overrides.disabled) continue;
66187
+ const state = {
66188
+ registration,
66189
+ instance: void 0,
66190
+ connectionId: void 0
66191
+ };
66192
+ const runtime = {
66193
+ client,
66194
+ getConnectionId: () => state.connectionId,
66195
+ getCredential: async () => {
66196
+ const connectionId = state.connectionId;
66197
+ if (!connectionId) throw new MastraConnectError("no_active_connection", `No active ${registration.integrationId} connection for project ${projectId}. Connect one on the platform, then retry.`);
66198
+ return getCredential(client, connectionId);
66199
+ },
66200
+ getConnectionContext: async () => {
66201
+ const connectionId = state.connectionId;
66202
+ if (!connectionId) return void 0;
66203
+ try {
66204
+ return await getConnectionContext(client, connectionId);
66205
+ } catch {
66206
+ return;
66207
+ }
66208
+ }
66209
+ };
66210
+ try {
66211
+ state.instance = await registration.create(overrides.providerOptions ?? {}, runtime);
66212
+ } catch (error) {
66213
+ console.warn(`[@mastra/connect] Skipping ${registration.integrationId} channel: ${error instanceof Error ? error.message : String(error)}`);
66214
+ continue;
66215
+ }
66216
+ states.push(state);
66217
+ }
66186
66218
  let cache;
66187
66219
  let inflight;
66188
66220
  let lastFailureAt;
@@ -66196,17 +66228,20 @@ function channels(options = {}) {
66196
66228
  }
66197
66229
  const byIntegrationId = groupByIntegrationId(connections);
66198
66230
  const providers = {};
66199
- for (const registration of CHANNELS) {
66200
- const integrationId = registration.integrationId;
66231
+ for (const state of states) {
66232
+ const integrationId = state.registration.integrationId;
66201
66233
  const overrides = options.integrations?.[integrationId] ?? {};
66202
- if (overrides.disabled) continue;
66203
66234
  const candidates = byIntegrationId.get(integrationId) ?? [];
66204
- if (candidates.length === 0) continue;
66205
- const connectionId = selectChannelConnection(integrationId, overrides.connectionId, candidates);
66235
+ const connectionId = candidates.length === 0 ? void 0 : selectChannelConnection(integrationId, overrides.connectionId, candidates);
66236
+ state.connectionId = connectionId;
66206
66237
  if (!connectionId) continue;
66207
- const provider = await buildProvider(registration, connectionId, overrides, client);
66208
- if (!provider) continue;
66209
- providers[integrationId] = provider;
66238
+ if (state.instance.sync) try {
66239
+ await state.instance.sync();
66240
+ } catch (error) {
66241
+ console.warn(`[@mastra/connect] Skipping ${integrationId} channel: ${error instanceof Error ? error.message : String(error)}`);
66242
+ continue;
66243
+ }
66244
+ providers[integrationId] = state.instance.provider;
66210
66245
  }
66211
66246
  lastFailureAt = void 0;
66212
66247
  return providers;
@@ -66241,6 +66276,7 @@ function channels(options = {}) {
66241
66276
  return refresh();
66242
66277
  };
66243
66278
  const invocable = ((_context) => resolve());
66279
+ invocable.getRoutes = () => states.flatMap((state) => state.instance.provider.getRoutes());
66244
66280
  invocable.invalidate = () => {
66245
66281
  cache = void 0;
66246
66282
  };
@@ -66248,35 +66284,8 @@ function channels(options = {}) {
66248
66284
  invocable.disconnect = async () => {
66249
66285
  cache = void 0;
66250
66286
  };
66251
- invocable.then = ((onfulfilled, onrejected) => resolve().then(onfulfilled, onrejected));
66252
66287
  return invocable;
66253
66288
  }
66254
- async function buildProvider(registration, connectionId, overrides, client) {
66255
- let credential;
66256
- try {
66257
- credential = await getCredential(client, connectionId);
66258
- } catch (error) {
66259
- console.warn(`[@mastra/connect] Skipping ${registration.integrationId} channel: ${error instanceof Error ? error.message : String(error)}`);
66260
- return;
66261
- }
66262
- let context = {
66263
- connectionId,
66264
- client
66265
- };
66266
- try {
66267
- context = {
66268
- connectionId,
66269
- client,
66270
- context: await getConnectionContext(client, connectionId)
66271
- };
66272
- } catch {}
66273
- try {
66274
- return await registration.build(credential, overrides.providerOptions ?? {}, context);
66275
- } catch (error) {
66276
- console.warn(`[@mastra/connect] Skipping ${registration.integrationId} channel: ${error instanceof Error ? error.message : String(error)}`);
66277
- return;
66278
- }
66279
- }
66280
66289
  /**
66281
66290
  * Selects the connection `channels()` should use for one provider.
66282
66291
  *