@vibesdotdev/integrations-resend 0.0.0-stage → 1.0.0-rc.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.
Files changed (83) hide show
  1. package/LICENSE +126 -0
  2. package/README.md +21 -2
  3. package/dist/client/index.d.ts +3 -0
  4. package/dist/client/index.d.ts.map +1 -0
  5. package/dist/client/index.js +2 -0
  6. package/dist/client/index.js.map +1 -0
  7. package/dist/client/runtime-client.d.ts +12 -0
  8. package/dist/client/runtime-client.d.ts.map +1 -0
  9. package/dist/client/runtime-client.js +61 -0
  10. package/dist/client/runtime-client.js.map +1 -0
  11. package/dist/config/resend.config.descriptor.d.ts +46 -0
  12. package/dist/config/resend.config.descriptor.d.ts.map +1 -0
  13. package/dist/config/resend.config.descriptor.js +50 -0
  14. package/dist/config/resend.config.descriptor.js.map +1 -0
  15. package/dist/index.d.ts +15 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +15 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/resend/index.d.ts +10 -0
  20. package/dist/resend/index.d.ts.map +1 -0
  21. package/dist/resend/index.js +10 -0
  22. package/dist/resend/index.js.map +1 -0
  23. package/dist/resend/resend-events.descriptors.d.ts +62 -0
  24. package/dist/resend/resend-events.descriptors.d.ts.map +1 -0
  25. package/dist/resend/resend-events.descriptors.js +55 -0
  26. package/dist/resend/resend-events.descriptors.js.map +1 -0
  27. package/dist/resend/resend-events.impls.d.ts +35 -0
  28. package/dist/resend/resend-events.impls.d.ts.map +1 -0
  29. package/dist/resend/resend-events.impls.js +115 -0
  30. package/dist/resend/resend-events.impls.js.map +1 -0
  31. package/dist/resend/resend-message-source.descriptor.d.ts +30 -0
  32. package/dist/resend/resend-message-source.descriptor.d.ts.map +1 -0
  33. package/dist/resend/resend-message-source.descriptor.js +24 -0
  34. package/dist/resend/resend-message-source.descriptor.js.map +1 -0
  35. package/dist/resend/resend-normalize.d.ts +24 -0
  36. package/dist/resend/resend-normalize.d.ts.map +1 -0
  37. package/dist/resend/resend-normalize.js +22 -0
  38. package/dist/resend/resend-normalize.js.map +1 -0
  39. package/dist/resend/resend-received.d.ts +25 -0
  40. package/dist/resend/resend-received.d.ts.map +1 -0
  41. package/dist/resend/resend-received.js +26 -0
  42. package/dist/resend/resend-received.js.map +1 -0
  43. package/dist/resend/resend-response.d.ts +3 -0
  44. package/dist/resend/resend-response.d.ts.map +1 -0
  45. package/dist/resend/resend-response.js +14 -0
  46. package/dist/resend/resend-response.js.map +1 -0
  47. package/dist/resend/resend-signature-verifier.descriptor.d.ts +20 -0
  48. package/dist/resend/resend-signature-verifier.descriptor.d.ts.map +1 -0
  49. package/dist/resend/resend-signature-verifier.descriptor.js +20 -0
  50. package/dist/resend/resend-signature-verifier.descriptor.js.map +1 -0
  51. package/dist/resend/resend-signature-verifier.impl.d.ts +16 -0
  52. package/dist/resend/resend-signature-verifier.impl.d.ts.map +1 -0
  53. package/dist/resend/resend-signature-verifier.impl.js +19 -0
  54. package/dist/resend/resend-signature-verifier.impl.js.map +1 -0
  55. package/dist/resend/resend-signature.d.ts +32 -0
  56. package/dist/resend/resend-signature.d.ts.map +1 -0
  57. package/dist/resend/resend-signature.js +77 -0
  58. package/dist/resend/resend-signature.js.map +1 -0
  59. package/dist/resend/resend-webhook.descriptor.d.ts +39 -0
  60. package/dist/resend/resend-webhook.descriptor.d.ts.map +1 -0
  61. package/dist/resend/resend-webhook.descriptor.js +24 -0
  62. package/dist/resend/resend-webhook.descriptor.js.map +1 -0
  63. package/dist/resend/resend-webhook.impl.d.ts +19 -0
  64. package/dist/resend/resend-webhook.impl.d.ts.map +1 -0
  65. package/dist/resend/resend-webhook.impl.js +111 -0
  66. package/dist/resend/resend-webhook.impl.js.map +1 -0
  67. package/dist/resend/resend.descriptor.d.ts +37 -0
  68. package/dist/resend/resend.descriptor.d.ts.map +1 -0
  69. package/dist/resend/resend.descriptor.js +107 -0
  70. package/dist/resend/resend.descriptor.js.map +1 -0
  71. package/dist/resend/resend.impl.d.ts +24 -0
  72. package/dist/resend/resend.impl.d.ts.map +1 -0
  73. package/dist/resend/resend.impl.js +258 -0
  74. package/dist/resend/resend.impl.js.map +1 -0
  75. package/dist/resend.plugin.d.ts +19 -0
  76. package/dist/resend.plugin.d.ts.map +1 -0
  77. package/dist/resend.plugin.js +88 -0
  78. package/dist/resend.plugin.js.map +1 -0
  79. package/dist/schemas/resend.d.ts +421 -0
  80. package/dist/schemas/resend.d.ts.map +1 -0
  81. package/dist/schemas/resend.js +97 -0
  82. package/dist/schemas/resend.js.map +1 -0
  83. package/package.json +107 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resend-webhook.descriptor.js","sourceRoot":"","sources":["../../src/resend/resend-webhook.descriptor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAGjE,eAAe,kBAAkB,CAAgC;IAChE,IAAI,EAAE,uBAAuB;IAC7B,EAAE,EAAE,0BAA0B;IAC9B,IAAI,EAAE,wBAAwB;IAC9B,WAAW,EACV,kFAAkF;IACnF,QAAQ,EAAE,QAAQ;IAClB,eAAe,EAAE,gBAAgB;IACjC,OAAO,EAAE,IAAI;IACb,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC;CAC5C,CAAC,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Resend webhook handler implementation.
3
+ *
4
+ * Svix-style HMAC-SHA256 verification — no `svix` SDK dependency. The
5
+ * algorithm lives once in `./resend-signature.ts` (Web Crypto only, so the
6
+ * pack is universal scope); this handler adds the per-delivery secret lookup,
7
+ * the distinct failure messages, and the event normalization.
8
+ */
9
+ import type { RuntimeRef } from '@vibesdotdev/kernel';
10
+ import type { EmailWebhookHandlerDescriptor, EmailWebhookHandlerImplementation } from '@vibesdotdev/email/schemas/email-webhook';
11
+ /**
12
+ * Factory: returns a verifier impl bound to the descriptor + the integration
13
+ * id whose `webhookSecret` credential we'll use to verify deliveries. The
14
+ * plugin wires this for the canonical Resend integration; multi-tenant apps
15
+ * with multiple Resend accounts register additional descriptors and call
16
+ * this factory for each.
17
+ */
18
+ export declare function createResendWebhookHandler(runtime: Pick<RuntimeRef, 'query'>, descriptor: EmailWebhookHandlerDescriptor, integrationId: string): EmailWebhookHandlerImplementation;
19
+ //# sourceMappingURL=resend-webhook.impl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resend-webhook.impl.d.ts","sourceRoot":"","sources":["../../src/resend/resend-webhook.impl.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EACX,6BAA6B,EAC7B,iCAAiC,EAEjC,MAAM,0CAA0C,CAAC;AAqDlD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACzC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,EAClC,UAAU,EAAE,6BAA6B,EACzC,aAAa,EAAE,MAAM,GACnB,iCAAiC,CAsDnC"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Resend webhook handler implementation.
3
+ *
4
+ * Svix-style HMAC-SHA256 verification — no `svix` SDK dependency. The
5
+ * algorithm lives once in `./resend-signature.ts` (Web Crypto only, so the
6
+ * pack is universal scope); this handler adds the per-delivery secret lookup,
7
+ * the distinct failure messages, and the event normalization.
8
+ */
9
+ import { CapabilityError, CaughtFailureSchema, valueFreeFailure } from '@vibesdotdev/kernel';
10
+ import { webhookPayloadSchema } from "../schemas/resend.js";
11
+ import { SVIX_REPLAY_WINDOW_SEC, computeSvixSignature, svixSignatureMatches } from "./resend-signature.js";
12
+ /** Maximum allowed clock-skew between the webhook timestamp and now. */
13
+ const REPLAY_WINDOW_MS = SVIX_REPLAY_WINDOW_SEC * 1000;
14
+ /**
15
+ * Map Resend's webhook event types to the substrate's canonical status enum.
16
+ * Keep in sync with `mapResendStatus` in `resend.impl.ts`.
17
+ */
18
+ function mapEventStatus(type) {
19
+ switch (type) {
20
+ case 'email.sent':
21
+ return 'sent';
22
+ case 'email.delivered':
23
+ return 'delivered';
24
+ case 'email.bounced':
25
+ return 'bounced';
26
+ case 'email.complained':
27
+ return 'complained';
28
+ case 'email.opened':
29
+ return 'opened';
30
+ case 'email.clicked':
31
+ return 'clicked';
32
+ case 'email.delivery_delayed':
33
+ return 'queued';
34
+ case 'email.failed':
35
+ return 'failed';
36
+ }
37
+ }
38
+ /**
39
+ * Resolve the active Resend integration so we can read its `webhookSecret`
40
+ * credential. Webhooks arrive at the platform without per-call auth, so the
41
+ * secret has to come from the registered integration the descriptor refers
42
+ * to. The resolved impl satisfies `IntegrationProviderImplementation` —
43
+ * `getCredentials()` is the canonical path; no provider-specific casts.
44
+ */
45
+ async function resolveWebhookSecret(runtime, integrationId) {
46
+ const impl = await runtime
47
+ .query('integration/provider')
48
+ .withId(integrationId)
49
+ .resolve();
50
+ const credentials = await impl.getCredentials();
51
+ const secret = credentials.webhookSecret;
52
+ return secret && secret.length > 0 ? secret : null;
53
+ }
54
+ /**
55
+ * Factory: returns a verifier impl bound to the descriptor + the integration
56
+ * id whose `webhookSecret` credential we'll use to verify deliveries. The
57
+ * plugin wires this for the canonical Resend integration; multi-tenant apps
58
+ * with multiple Resend accounts register additional descriptors and call
59
+ * this factory for each.
60
+ */
61
+ export function createResendWebhookHandler(runtime, descriptor, integrationId) {
62
+ return {
63
+ descriptor,
64
+ async verify({ headers, rawBody }) {
65
+ const svixId = headers['svix-id'];
66
+ const svixTimestamp = headers['svix-timestamp'];
67
+ const svixSignature = headers['svix-signature'];
68
+ if (!svixId || !svixTimestamp || !svixSignature) {
69
+ throw new CapabilityError('Resend webhook missing required svix-id / svix-timestamp / svix-signature header.', 'INVALID_INPUT', { reason: 'resend-webhook-invalid' });
70
+ }
71
+ const timestampSec = Number(svixTimestamp);
72
+ if (!Number.isFinite(timestampSec)) {
73
+ throw new CapabilityError('Resend webhook svix-timestamp is not a number.', 'INVALID_INPUT', { reason: 'resend-webhook-invalid' });
74
+ }
75
+ const ageMs = Math.abs(Date.now() - timestampSec * 1000);
76
+ if (ageMs > REPLAY_WINDOW_MS) {
77
+ throw new CapabilityError(`Resend webhook timestamp outside ${REPLAY_WINDOW_MS / 1000}s replay window (age ${Math.round(ageMs / 1000)}s).`, 'PERMISSION_DENIED', { reason: 'resend-signature-invalid' });
78
+ }
79
+ const secret = await resolveWebhookSecret(runtime, integrationId);
80
+ if (!secret) {
81
+ throw new CapabilityError(`Resend webhook secret not configured on integration '${integrationId}'.`, 'AUTH_REQUIRED', { reason: 'resend-webhook-secret-missing' });
82
+ }
83
+ const expected = await computeSvixSignature(secret, svixId, svixTimestamp, rawBody);
84
+ const matched = svixSignatureMatches(svixSignature, expected);
85
+ if (!matched)
86
+ throw new CapabilityError('Resend webhook signature verification failed.', 'PERMISSION_DENIED', { reason: 'resend-signature-invalid' });
87
+ let body;
88
+ try {
89
+ body = JSON.parse(rawBody);
90
+ }
91
+ catch (cause) {
92
+ throw new CapabilityError('Resend webhook body is not valid JSON.', 'INVALID_INPUT', { reason: 'resend-webhook-invalid', details: { failure: valueFreeFailure(CaughtFailureSchema.parse(cause)) } });
93
+ }
94
+ const admitted = webhookPayloadSchema.safeParse(body);
95
+ if (!admitted.success)
96
+ throw new CapabilityError('Resend webhook payload missing `type` or `data.email_id`, or has an invalid event shape.', 'INVALID_INPUT', { reason: 'resend-webhook-invalid' });
97
+ const payload = admitted.data;
98
+ const event = {
99
+ provider: 'resend',
100
+ messageId: payload.data.email_id,
101
+ status: mapEventStatus(payload.type),
102
+ to: payload.data.to?.[0],
103
+ reason: payload.data.bounce?.message ?? payload.data.failed?.reason,
104
+ timestamp: payload.created_at,
105
+ raw: payload
106
+ };
107
+ return [event];
108
+ }
109
+ };
110
+ }
111
+ //# sourceMappingURL=resend-webhook.impl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resend-webhook.impl.js","sourceRoot":"","sources":["../../src/resend/resend-webhook.impl.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Resend `integration/provider` descriptor.
3
+ *
4
+ * Vendor pack for the Resend HTTP email API. Registers under
5
+ * `category: 'email'` so `packages/email`'s `EmailClient` picks it up at
6
+ * dispatch time alongside any other email integrations the app registers.
7
+ *
8
+ * Credentials:
9
+ * - `apiKey` Resend API key, scoped per org so multi-tenant apps can
10
+ * route different orgs through different Resend accounts.
11
+ * - `webhookSecret` Svix signing secret (Resend uses Svix for webhooks).
12
+ * Required for the `email/webhook-handler` to verify
13
+ * inbound delivery events.
14
+ *
15
+ * Config:
16
+ * - `defaultFrom` Optional fallback `from` address when the caller
17
+ * doesn't supply one on the `EmailSendInput`.
18
+ *
19
+ * Operations are the substrate canonical `send`/`check`/`receive`. Resend
20
+ * is webhook-push for inbound; `receive` is not supported and surfaces as
21
+ * `EmailReceiveNotSupportedError`.
22
+ */
23
+ import { type IntegrationProviderDescriptorInput } from '@vibesdotdev/integrations/schemas/integration-descriptor';
24
+ import { type ResendHostOptions } from '../schemas/resend.ts';
25
+ export type { ResendHostOptions } from '../schemas/resend.ts';
26
+ type ResendDescriptor = IntegrationProviderDescriptorInput & Required<Pick<IntegrationProviderDescriptorInput, 'name' | 'provider' | 'config'>>;
27
+ declare const resendDescriptor: ResendDescriptor;
28
+ /**
29
+ * The Resend descriptor with the host's declared default sender. A descriptor
30
+ * that carries a host credential reference takes its config from the
31
+ * descriptor alone (never from tenant settings), so the host declares
32
+ * `defaultFrom` here, the same way `createHostSmtpDescriptor` declares SMTP's.
33
+ * Callers then send without a `from`: the provider fills it.
34
+ */
35
+ export declare function createHostResendDescriptor(options: ResendHostOptions): ResendDescriptor;
36
+ export default resendDescriptor;
37
+ //# sourceMappingURL=resend.descriptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resend.descriptor.d.ts","sourceRoot":"","sources":["../../src/resend/resend.descriptor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EACN,KAAK,kCAAkC,EACvC,MAAM,0DAA0D,CAAC;AAElE,OAAO,EAA2B,KAAK,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACvF,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,KAAK,gBAAgB,GAAG,kCAAkC,GACzD,QAAQ,CAAC,IAAI,CAAC,kCAAkC,EAAE,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC;AAEpF,QAAA,MAAM,gBAAgB,kBAmEpB,CAAC;AAEH;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,CAMvF;AAED,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Resend `integration/provider` descriptor.
3
+ *
4
+ * Vendor pack for the Resend HTTP email API. Registers under
5
+ * `category: 'email'` so `packages/email`'s `EmailClient` picks it up at
6
+ * dispatch time alongside any other email integrations the app registers.
7
+ *
8
+ * Credentials:
9
+ * - `apiKey` Resend API key, scoped per org so multi-tenant apps can
10
+ * route different orgs through different Resend accounts.
11
+ * - `webhookSecret` Svix signing secret (Resend uses Svix for webhooks).
12
+ * Required for the `email/webhook-handler` to verify
13
+ * inbound delivery events.
14
+ *
15
+ * Config:
16
+ * - `defaultFrom` Optional fallback `from` address when the caller
17
+ * doesn't supply one on the `EmailSendInput`.
18
+ *
19
+ * Operations are the substrate canonical `send`/`check`/`receive`. Resend
20
+ * is webhook-push for inbound; `receive` is not supported and surfaces as
21
+ * `EmailReceiveNotSupportedError`.
22
+ */
23
+ import { createRuntimeAsset } from '@vibesdotdev/kernel/factory';
24
+ import {} from '@vibesdotdev/integrations/schemas/integration-descriptor';
25
+ import { emailCapabilityEgressSchema } from '@vibesdotdev/email/schemas/email-egress';
26
+ import { resendHostOptionsSchema } from "../schemas/resend.js";
27
+ const resendDescriptor = createRuntimeAsset({
28
+ kind: 'integration/provider',
29
+ id: 'integration.email.resend',
30
+ name: 'Resend',
31
+ description: 'Resend HTTP email API. Outbound send + status lookup; inbound delivery events via Svix-signed webhooks.',
32
+ provider: 'resend',
33
+ category: 'email',
34
+ enabled: true,
35
+ priority: 100,
36
+ baseUrl: 'https://api.resend.com',
37
+ configSettingKey: 'integrations.email.resend.config',
38
+ config: {
39
+ defaultFrom: '',
40
+ emailEgress: emailCapabilityEgressSchema.parse({ kind: 'fixed-https', host: 'api.resend.com', baseUrlKey: 'baseUrl' })
41
+ },
42
+ credentials: [
43
+ {
44
+ key: 'apiKey',
45
+ source: 'secret',
46
+ providerType: 'resend',
47
+ scope: 'org',
48
+ required: false
49
+ },
50
+ {
51
+ key: 'apiKey',
52
+ source: 'secret',
53
+ reference: { source: 'secret', key: 'RESEND_API_KEY' },
54
+ required: false
55
+ },
56
+ {
57
+ key: 'webhookSecret',
58
+ source: 'secret',
59
+ providerType: 'resend',
60
+ scope: 'org',
61
+ required: false
62
+ }
63
+ ],
64
+ operations: [
65
+ {
66
+ id: 'get-received-attachment',
67
+ name: 'Download received attachment',
68
+ description: 'Retrieve received attachment bytes through the selected account and a fresh provider download URL.',
69
+ requiresOrg: false
70
+ },
71
+ {
72
+ id: 'send',
73
+ name: 'Send email',
74
+ description: 'POST /emails — deliver a message via the Resend HTTP API.',
75
+ requiresOrg: false
76
+ },
77
+ {
78
+ id: 'check',
79
+ name: 'Check status / health',
80
+ description: 'GET /emails/{id} for status lookup, or GET /domains as a health probe.',
81
+ requiresOrg: false
82
+ },
83
+ {
84
+ id: 'get-received',
85
+ name: 'Retrieve received email',
86
+ description: 'GET /emails/receiving/{emailId} — retrieve the complete body and headers with the selected account.',
87
+ requiresOrg: false
88
+ }
89
+ ],
90
+ tags: ['email', 'resend', 'http'],
91
+ });
92
+ /**
93
+ * The Resend descriptor with the host's declared default sender. A descriptor
94
+ * that carries a host credential reference takes its config from the
95
+ * descriptor alone (never from tenant settings), so the host declares
96
+ * `defaultFrom` here, the same way `createHostSmtpDescriptor` declares SMTP's.
97
+ * Callers then send without a `from`: the provider fills it.
98
+ */
99
+ export function createHostResendDescriptor(options) {
100
+ const { defaultFrom } = resendHostOptionsSchema.parse(options);
101
+ return createRuntimeAsset({
102
+ ...resendDescriptor,
103
+ config: { ...resendDescriptor.config, defaultFrom }
104
+ });
105
+ }
106
+ export default resendDescriptor;
107
+ //# sourceMappingURL=resend.descriptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resend.descriptor.js","sourceRoot":"","sources":["../../src/resend/resend.descriptor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAEN,MAAM,0DAA0D,CAAC;AAClE,OAAO,EAAE,2BAA2B,EAAE,MAAM,yCAAyC,CAAC;AACtF,OAAO,EAAE,uBAAuB,EAA0B,MAAM,sBAAsB,CAAC;AAMvF,MAAM,gBAAgB,GAAG,kBAAkB,CAAmB;IAC7D,IAAI,EAAE,sBAAsB;IAC5B,EAAE,EAAE,0BAA0B;IAC9B,IAAI,EAAE,QAAQ;IACd,WAAW,EACV,yGAAyG;IAC1G,QAAQ,EAAE,QAAQ;IAClB,QAAQ,EAAE,OAAO;IACjB,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,GAAG;IACb,OAAO,EAAE,wBAAwB;IACjC,gBAAgB,EAAE,kCAAkC;IACpD,MAAM,EAAE;QACP,WAAW,EAAE,EAAE;QACf,WAAW,EAAE,2BAA2B,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,gBAAgB,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;KACtH;IACD,WAAW,EAAE;QACZ;YACC,GAAG,EAAE,QAAQ;YACb,MAAM,EAAE,QAAQ;YAChB,YAAY,EAAE,QAAQ;YACtB,KAAK,EAAE,KAAK;YACZ,QAAQ,EAAE,KAAK;SACf;QACD;YACC,GAAG,EAAE,QAAQ;YACb,MAAM,EAAE,QAAQ;YAChB,SAAS,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,gBAAgB,EAAE;YACtD,QAAQ,EAAE,KAAK;SACf;QACD;YACC,GAAG,EAAE,eAAe;YACpB,MAAM,EAAE,QAAQ;YAChB,YAAY,EAAE,QAAQ;YACtB,KAAK,EAAE,KAAK;YACZ,QAAQ,EAAE,KAAK;SACf;KACD;IACD,UAAU,EAAE;QACX;YACC,EAAE,EAAE,yBAAyB;YAC7B,IAAI,EAAE,8BAA8B;YACpC,WAAW,EAAE,oGAAoG;YACjH,WAAW,EAAE,KAAK;SAClB;QACD;YACC,EAAE,EAAE,MAAM;YACV,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,2DAA2D;YACxE,WAAW,EAAE,KAAK;SAClB;QACD;YACC,EAAE,EAAE,OAAO;YACX,IAAI,EAAE,uBAAuB;YAC7B,WAAW,EACV,wEAAwE;YACzE,WAAW,EAAE,KAAK;SAClB;QACD;YACC,EAAE,EAAE,cAAc;YAClB,IAAI,EAAE,yBAAyB;YAC/B,WAAW,EACV,qGAAqG;YACtG,WAAW,EAAE,KAAK;SAClB;KACD;IACD,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC;CACjC,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,0BAA0B,CAAC,OAA0B;IACpE,MAAM,EAAE,WAAW,EAAE,GAAG,uBAAuB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/D,OAAO,kBAAkB,CAAmB;QAC3C,GAAG,gBAAgB;QACnB,MAAM,EAAE,EAAE,GAAG,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE;KACnD,CAAC,CAAC;AACJ,CAAC;AAED,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { EmailIntegrationImplementation } from '@vibesdotdev/email/services/email-integration';
2
+ import { BaseIntegrationProvider } from '@vibesdotdev/integrations/kinds/integration';
3
+ import type { IntegrationConnectionSelector, IntegrationOperationResult } from '@vibesdotdev/integrations/schemas/integration-descriptor';
4
+ import type { EmailSendInput, EmailSendResult, EmailStatusResult, EmailHealthResult } from '@vibesdotdev/email/schemas/email-data';
5
+ export declare class ResendEmailIntegration extends BaseIntegrationProvider implements EmailIntegrationImplementation {
6
+ invokeOperation<T = unknown>(opId: string, args?: import('../schemas/resend.ts').ResendOperationArgs): Promise<IntegrationOperationResult<T>>;
7
+ invokeOperationForConnection<T = unknown>(selector: Readonly<IntegrationConnectionSelector>, opId: string, args?: import('../schemas/resend.ts').ResendOperationArgs): Promise<IntegrationOperationResult<T>>;
8
+ /**
9
+ * Bearer-token POST to Resend's send endpoint. Network egress is the
10
+ * canonical work; everything else is shape translation + error mapping.
11
+ * Throws on non-2xx so the typed `send` contract returns either a valid
12
+ * `EmailSendResult` or a thrown error (which `EmailClient.send` and
13
+ * `invokeOperation` translate into the right surface for each caller).
14
+ */
15
+ send(input: EmailSendInput, selector?: Readonly<IntegrationConnectionSelector>): Promise<EmailSendResult>;
16
+ /**
17
+ * `check(messageId)` performs a status lookup; `check()` performs a
18
+ * health probe by verifying the API key works against Resend's
19
+ * `GET /domains` endpoint.
20
+ */
21
+ check(messageId?: string, selector?: Readonly<IntegrationConnectionSelector>): Promise<EmailStatusResult | EmailHealthResult>;
22
+ }
23
+ export default ResendEmailIntegration;
24
+ //# sourceMappingURL=resend.impl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resend.impl.d.ts","sourceRoot":"","sources":["../../src/resend/resend.impl.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EAAE,uBAAuB,EAAE,MAAM,6CAA6C,CAAC;AACtF,OAAO,KAAK,EAAE,6BAA6B,EAAE,0BAA0B,EAAE,MAAM,0DAA0D,CAAC;AAG1I,OAAO,KAAK,EACX,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EAEjB,MAAM,uCAAuC,CAAC;AAiF/C,qBAAa,sBACZ,SAAQ,uBACR,YAAW,8BAA8B;IAE1B,eAAe,CAAC,CAAC,GAAG,OAAO,EACzC,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,sBAAsB,EAAE,mBAAmB,GACvD,OAAO,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC;IAInC,4BAA4B,CAAC,CAAC,GAAG,OAAO,EAC7C,QAAQ,EAAE,QAAQ,CAAC,6BAA6B,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,sBAAsB,EAAE,mBAAmB,GACxH,OAAO,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC;IA+CzC;;;;;;OAMG;IACG,IAAI,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,6BAA6B,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC;IAgD/G;;;;OAIG;IACG,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,6BAA6B,CAAC,GAAG,OAAO,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;CA6CnI;AAED,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,258 @@
1
+ import { readResendResponse } from "./resend-response.js";
2
+ /**
3
+ * Resend integration implementation.
4
+ *
5
+ * Extends the Integrations-owned `BaseIntegrationProvider`, so live config and
6
+ * credentials stay runtime-backed while `send`, `check`, and optional
7
+ * `receive` are wired through the substrate's `EmailClient` and canonical
8
+ * `email` tool. Generic operations delegate to the Email-owned dispatcher.
9
+ *
10
+ * Resend's inbound surface is webhook-push only — there is no IMAP / poll
11
+ * endpoint. The dispatcher reports `EmailReceiveNotSupportedError` when
12
+ * `receive()` is absent; `EmailClient.receive()` catches that and returns `[]`
13
+ * so the typed surface stays uniform across packs.
14
+ */
15
+ import { CapabilityError, CaughtFailureSchema, valueFreeFailure } from '@vibesdotdev/kernel';
16
+ import { emailSendInputSchema } from '@vibesdotdev/email/schemas/email-data';
17
+ import { attachmentInputSchema, attachmentReceiptSchema, receivedInputSchema, resendConfigSchema, sendResponseSchema, statusResponseSchema } from "../schemas/resend.js";
18
+ import { invokeEmailIntegrationOperation } from '@vibesdotdev/email/services/email-integration';
19
+ import { BaseIntegrationProvider } from '@vibesdotdev/integrations/kinds/integration';
20
+ import { retrieveResendReceivedEmail } from "./resend-received.js";
21
+ import { resolveResendBaseUrl } from "../config/resend.config.descriptor.js";
22
+ /**
23
+ * Map Resend's `last_event` strings to the substrate's canonical
24
+ * `EmailDeliveryStatus` enum. `created` collapses to `queued` since Resend
25
+ * has accepted the message but has not yet handed it to a downstream MTA.
26
+ * `delivery_delayed` also collapses to `queued` because the message hasn't
27
+ * reached its terminal state yet.
28
+ */
29
+ function mapResendStatus(event) {
30
+ switch (event) {
31
+ case 'created':
32
+ case 'delivery_delayed':
33
+ return 'queued';
34
+ case 'sent':
35
+ return 'sent';
36
+ case 'delivered':
37
+ return 'delivered';
38
+ case 'bounced':
39
+ return 'bounced';
40
+ case 'complained':
41
+ return 'complained';
42
+ case 'opened':
43
+ return 'opened';
44
+ case 'clicked':
45
+ return 'clicked';
46
+ case 'failed':
47
+ return 'failed';
48
+ }
49
+ }
50
+ /**
51
+ * Translate the substrate's canonical `EmailSendInput` into Resend's request
52
+ * body. Drops fields Resend doesn't accept (`idempotencyKey`) and renames
53
+ * the ones it spells differently (`replyTo` → `reply_to`, attachment
54
+ * `disposition` → omitted because Resend infers from `contentId`).
55
+ */
56
+ function toResendBody(input, fallbackFrom) {
57
+ const from = input.from ?? fallbackFrom;
58
+ if (!from) {
59
+ throw new CapabilityError('Resend send requires a `from` address. Pass one on the EmailSendInput or set the `defaultFrom` config on the integration.', 'INVALID_INPUT', { reason: 'resend-sender-missing' });
60
+ }
61
+ return {
62
+ from, to: Array.isArray(input.to) ? input.to : [input.to],
63
+ cc: input.cc, bcc: input.bcc, reply_to: input.replyTo,
64
+ subject: input.subject, html: input.html, text: input.text,
65
+ headers: input.inReplyTo ? { ...input.headers, 'In-Reply-To': input.inReplyTo } : input.headers,
66
+ attachments: input.attachments?.map(a => ({
67
+ filename: a.filename, content: a.content, content_type: a.contentType, content_id: a.contentId
68
+ })),
69
+ tags: input.tags?.map(name => ({ name, value: 'true' }))
70
+ };
71
+ }
72
+ async function readAttachment(response, maxBytes) {
73
+ if (!response.body)
74
+ throw new CapabilityError('Attachment body is missing', 'UNAVAILABLE', { reason: 'resend-attachment-invalid' });
75
+ const reader = response.body.getReader();
76
+ const chunks = [];
77
+ let total = 0;
78
+ try {
79
+ while (true) {
80
+ const { done, value } = await reader.read();
81
+ if (done)
82
+ break;
83
+ total += value.byteLength;
84
+ if (total > maxBytes) {
85
+ await reader.cancel();
86
+ throw new CapabilityError('Attachment exceeds its allowed size', 'UNAVAILABLE', { reason: 'resend-attachment-invalid' });
87
+ }
88
+ chunks.push(value);
89
+ }
90
+ }
91
+ finally {
92
+ reader.releaseLock();
93
+ }
94
+ const bytes = new Uint8Array(total);
95
+ let offset = 0;
96
+ for (const chunk of chunks) {
97
+ bytes.set(chunk, offset);
98
+ offset += chunk.byteLength;
99
+ }
100
+ return bytes;
101
+ }
102
+ export class ResendEmailIntegration extends BaseIntegrationProvider {
103
+ async invokeOperation(opId, args) {
104
+ return invokeEmailIntegrationOperation(this, opId, args);
105
+ }
106
+ async invokeOperationForConnection(selector, opId, args) {
107
+ this.requireDeclaredOperation(opId);
108
+ try {
109
+ if (opId === 'get-received-attachment') {
110
+ const input = attachmentInputSchema.parse(args);
111
+ const { credentials } = await this.getResolvedConfiguration(selector);
112
+ if (!credentials.apiKey)
113
+ throw new CapabilityError('Selected account credential is missing', 'AUTH_REQUIRED', { reason: 'resend-credential-missing' });
114
+ const baseUrl = await resolveResendBaseUrl(this.context.runtime, this.descriptor.baseUrl);
115
+ const metadataResponse = await fetch(`${baseUrl.replace(/\/$/, '')}/emails/receiving/${encodeURIComponent(input.emailId)}/attachments/${encodeURIComponent(input.attachmentId)}`, {
116
+ headers: { Authorization: `Bearer ${credentials.apiKey}` }, redirect: 'error', signal: AbortSignal.timeout(15_000)
117
+ });
118
+ if (!metadataResponse.ok)
119
+ throw new CapabilityError('Resend attachment lookup was refused.', 'UNAVAILABLE', { reason: 'resend-upstream-refused', details: { status: metadataResponse.status } });
120
+ const receipt = attachmentReceiptSchema.safeParse(await readResendResponse(metadataResponse));
121
+ if (!receipt.success)
122
+ throw new CapabilityError('Invalid attachment receipt', 'UNAVAILABLE', { reason: 'resend-attachment-invalid' });
123
+ const metadata = receipt.data;
124
+ if (metadata.id !== input.attachmentId)
125
+ throw new CapabilityError('Invalid attachment receipt identity', 'UNAVAILABLE', { reason: 'resend-attachment-invalid' });
126
+ const url = new URL(metadata.download_url);
127
+ // The short-lived CDN URL is provider-signed. Never forward the account API key.
128
+ const response = await fetch(url, { redirect: 'error', signal: AbortSignal.timeout(20_000) });
129
+ if (!response.ok)
130
+ throw new CapabilityError('Resend attachment download was refused.', 'UNAVAILABLE', { reason: 'resend-upstream-refused', details: { status: response.status } });
131
+ const bytes = await readAttachment(response, metadata.size);
132
+ if (bytes.byteLength !== metadata.size)
133
+ throw new CapabilityError('Attachment size does not match its provider receipt', 'UNAVAILABLE', { reason: 'resend-attachment-invalid' });
134
+ let binary = '';
135
+ for (let offset = 0; offset < bytes.length; offset += 8192)
136
+ binary += String.fromCharCode(...bytes.subarray(offset, offset + 8192));
137
+ // SAFETY: the legacy owner generic binds T at dispatch; this branch constructs the declared attachment result.
138
+ return { ok: true, data: { content: btoa(binary) } };
139
+ }
140
+ if (opId === 'get-received') {
141
+ const { emailId } = receivedInputSchema.parse(args);
142
+ const { credentials } = await this.getResolvedConfiguration(selector);
143
+ // SAFETY: the owner dispatch generic associates T with get-received; hydration validates the normalized result.
144
+ return { ok: true, data: await retrieveResendReceivedEmail({ emailId, apiKey: credentials.apiKey, baseUrl: await resolveResendBaseUrl(this.context.runtime, this.descriptor.baseUrl) }) };
145
+ }
146
+ if (opId === 'send' || opId === 'check') {
147
+ return invokeEmailIntegrationOperation({
148
+ descriptor: this.descriptor,
149
+ send: (input) => this.send(input, selector),
150
+ check: (messageId) => this.check(messageId, selector)
151
+ }, opId, args);
152
+ }
153
+ throw new Error(`Resend selected-account operation '${opId}' is not implemented.`);
154
+ }
155
+ catch (error) {
156
+ const refusal = { ok: false, errors: ['Resend selected-account operation failed.'], failure: valueFreeFailure(CaughtFailureSchema.parse(error)) };
157
+ return refusal;
158
+ }
159
+ }
160
+ /**
161
+ * Bearer-token POST to Resend's send endpoint. Network egress is the
162
+ * canonical work; everything else is shape translation + error mapping.
163
+ * Throws on non-2xx so the typed `send` contract returns either a valid
164
+ * `EmailSendResult` or a thrown error (which `EmailClient.send` and
165
+ * `invokeOperation` translate into the right surface for each caller).
166
+ */
167
+ async send(input, selector) {
168
+ const { config, credentials } = await this.getResolvedConfiguration(selector);
169
+ const apiKey = credentials.apiKey;
170
+ if (!apiKey) {
171
+ throw new CapabilityError(`Resend integration '${this.descriptor.id}' has no apiKey credential. ` +
172
+ `Connect the integration via the credentials API before calling send.`, 'AUTH_REQUIRED', { reason: 'resend-credential-missing' });
173
+ }
174
+ const baseUrl = await resolveResendBaseUrl(this.context.runtime, this.descriptor.baseUrl);
175
+ const defaultFrom = resendConfigSchema.parse(config).defaultFrom || undefined;
176
+ input = emailSendInputSchema.parse(input);
177
+ if (selector && (!defaultFrom || (input.from && input.from !== defaultFrom))) {
178
+ throw new CapabilityError('Selected Resend delivery requires the saved connection sender; an unrelated From address is not allowed.', 'PERMISSION_DENIED', { reason: 'resend-sender-mismatch' });
179
+ }
180
+ const body = toResendBody(input, defaultFrom);
181
+ const t0 = Date.now();
182
+ const response = await fetch(`${baseUrl}/emails`, {
183
+ method: 'POST',
184
+ headers: {
185
+ Authorization: `Bearer ${apiKey}`,
186
+ 'Content-Type': 'application/json',
187
+ ...Object.fromEntries(input.idempotencyKey ? [['Idempotency-Key', input.idempotencyKey]] : [])
188
+ },
189
+ body: JSON.stringify(body)
190
+ });
191
+ const durationMs = Date.now() - t0;
192
+ if (!response.ok) {
193
+ throw new CapabilityError(`Resend send returned ${response.status}.`, 'UNAVAILABLE', {
194
+ reason: 'resend-upstream-refused', details: { status: response.status }
195
+ });
196
+ }
197
+ const admitted = sendResponseSchema.safeParse(await readResendResponse(response));
198
+ if (!admitted.success)
199
+ throw new CapabilityError('Resend send response missing or invalid id field.', 'UNAVAILABLE', { reason: 'resend-result-invalid' });
200
+ const parsed = admitted.data;
201
+ return {
202
+ messageId: parsed.id,
203
+ providerId: this.descriptor.id,
204
+ durationMs
205
+ };
206
+ }
207
+ /**
208
+ * `check(messageId)` performs a status lookup; `check()` performs a
209
+ * health probe by verifying the API key works against Resend's
210
+ * `GET /domains` endpoint.
211
+ */
212
+ async check(messageId, selector) {
213
+ const { credentials } = await this.getResolvedConfiguration(selector);
214
+ const apiKey = credentials.apiKey;
215
+ if (!apiKey) {
216
+ return {
217
+ ok: false,
218
+ providerId: this.descriptor.id,
219
+ error: 'Resend integration has no apiKey credential.'
220
+ };
221
+ }
222
+ const baseUrl = await resolveResendBaseUrl(this.context.runtime, this.descriptor.baseUrl);
223
+ if (messageId) {
224
+ const response = await fetch(`${baseUrl}/emails/${encodeURIComponent(messageId)}`, {
225
+ headers: { Authorization: `Bearer ${apiKey}` }
226
+ });
227
+ if (!response.ok) {
228
+ throw new CapabilityError('Resend status lookup was refused.', 'UNAVAILABLE', {
229
+ reason: 'resend-upstream-refused', details: { status: response.status }
230
+ });
231
+ }
232
+ const admitted = statusResponseSchema.safeParse(await readResendResponse(response));
233
+ if (!admitted.success || admitted.data.id !== messageId)
234
+ throw new CapabilityError('Invalid Resend status response identity or shape.', 'UNAVAILABLE', { reason: 'resend-result-invalid' });
235
+ const data = admitted.data;
236
+ return {
237
+ messageId: data.id,
238
+ status: mapResendStatus(data.last_event),
239
+ providerId: this.descriptor.id,
240
+ timestamp: data.created_at
241
+ };
242
+ }
243
+ // Health probe: any authenticated endpoint will do; /domains is cheap.
244
+ const response = await fetch(`${baseUrl}/domains`, {
245
+ headers: { Authorization: `Bearer ${apiKey}` }
246
+ });
247
+ if (!response.ok) {
248
+ return {
249
+ ok: false,
250
+ providerId: this.descriptor.id,
251
+ error: `Resend /domains returned ${response.status}.`
252
+ };
253
+ }
254
+ return { ok: true, providerId: this.descriptor.id };
255
+ }
256
+ }
257
+ export default ResendEmailIntegration;
258
+ //# sourceMappingURL=resend.impl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resend.impl.js","sourceRoot":"","sources":["../../src/resend/resend.impl.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Runtime plugin for the Resend email integration vendor pack.
3
+ *
4
+ * Registers:
5
+ * 1. The `integration/provider` descriptor + `ResendEmailIntegration` loader.
6
+ * `packages/email`'s `EmailClient` picks this up automatically by
7
+ * filtering `category === 'email'` at dispatch time.
8
+ * 2. The `email/webhook-handler` descriptor + loader for the platform-app
9
+ * `+server.ts` route that ingests Resend webhooks.
10
+ *
11
+ * Also registers the account-aware consumer client and inbound agent source.
12
+ * Hosts register the owning kind plugins before this vendor plugin.
13
+ */
14
+ import { type ResendHostOptions } from './resend/resend.descriptor.ts';
15
+ /** Omit options to leave the sender to callers; pass options to declare the host's default sender. */
16
+ export declare function createResendPlugin(options?: ResendHostOptions): import("@vibesdotdev/kernel").RuntimePlugin;
17
+ export declare const resendPlugin: import("@vibesdotdev/kernel").RuntimePlugin;
18
+ export default resendPlugin;
19
+ //# sourceMappingURL=resend.plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resend.plugin.d.ts","sourceRoot":"","sources":["../src/resend.plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,OAA6B,EAA8B,KAAK,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AASzH,sGAAsG;AACtG,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,iBAAiB,+CA6D7D;AAED,eAAO,MAAM,YAAY,6CAAuB,CAAC;AAEjD,eAAe,YAAY,CAAC"}