@particle-academy/resend-js 0.3.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/flow.cjs CHANGED
@@ -6,15 +6,122 @@ var resendUi = require('@particle-academy/resend-ui');
6
6
  // src/flow.ts
7
7
 
8
8
  // src/faker.ts
9
+ function fakeAttachmentGet({ config, fake }) {
10
+ return {
11
+ "object": "attachment",
12
+ "id": config.attachmentId !== void 0 && config.attachmentId !== null && config.attachmentId !== "" ? String(config.attachmentId) : `${fake.hex(8)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(12)}`,
13
+ "filename": "avatar.png",
14
+ "size": 4096,
15
+ "content_type": "image/png",
16
+ "content_disposition": "inline",
17
+ "content_id": "img001",
18
+ "download_url": "https://inbound-cdn.resend.com/4ef9a417-02e9-4d39-ad75-9611e0fcc33c/attachments/2a0c9ce0-3112-4728-976e-47ddcd16a318?signature=fake",
19
+ "expires_at": "2026-10-17T14:29:41.521Z"
20
+ };
21
+ }
22
+ function fakeAttachmentList({ config, fake }) {
23
+ return {
24
+ "object": "list",
25
+ "has_more": false,
26
+ "data": [
27
+ {
28
+ "id": `${fake.hex(8)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(12)}`,
29
+ "filename": "avatar.png",
30
+ "size": 4096,
31
+ "content_type": "image/png",
32
+ "content_disposition": "inline",
33
+ "content_id": "img001",
34
+ "download_url": "https://inbound-cdn.resend.com/4ef9a417-02e9-4d39-ad75-9611e0fcc33c/attachments/2a0c9ce0-3112-4728-976e-47ddcd16a318?signature=fake",
35
+ "expires_at": "2026-10-17T14:29:41.521Z"
36
+ }
37
+ ]
38
+ };
39
+ }
40
+ function fakeEmailGet({ config, fake }) {
41
+ return {
42
+ "object": "email",
43
+ "id": config.emailId !== void 0 && config.emailId !== null && config.emailId !== "" ? String(config.emailId) : `${fake.hex(8)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(12)}`,
44
+ "to": [
45
+ "inbox@yourdomain.test"
46
+ ],
47
+ "from": "ada@example.test",
48
+ "created_at": "2026-09-15T12:00:11.894Z",
49
+ "subject": "Sending this example",
50
+ "html": "Congrats on receiving your <strong>first email</strong>!",
51
+ "html_format": "data_uri",
52
+ "text": null,
53
+ "headers": {
54
+ "from": "Ada Lovelace <ada@example.test>",
55
+ "return-path": "ada@example.test",
56
+ "mime-version": "1.0"
57
+ },
58
+ "bcc": [],
59
+ "cc": [],
60
+ "reply_to": [],
61
+ "received_for": [],
62
+ "message_id": "<111-222-333@email.example.test>",
63
+ "raw": {
64
+ "download_url": "https://example.resend.com/receiving/raw/054da427-439a-4e91-b785-e4fb1966285f?Signature=fake",
65
+ "expires_at": "2026-09-15T13:00:11.894Z"
66
+ },
67
+ "attachments": [
68
+ {
69
+ "id": `${fake.hex(8)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(12)}`,
70
+ "filename": "avatar.png",
71
+ "content_type": "image/png",
72
+ "content_disposition": "inline",
73
+ "content_id": "img001",
74
+ "size": 4096
75
+ }
76
+ ]
77
+ };
78
+ }
9
79
  function fakeEmailSend({ config, fake }) {
10
80
  return {
11
81
  "id": `${fake.hex(8)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(12)}`
12
82
  };
13
83
  }
84
+ function fakeEmailReceived({ config, fake }) {
85
+ const boundEmailid = `${fake.hex(8)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(12)}`;
86
+ return {
87
+ "type": "email.received",
88
+ "created_at": "2026-09-15T12:00:12.126Z",
89
+ "data": {
90
+ "email_id": boundEmailid,
91
+ "created_at": "2026-09-15T12:00:11.894Z",
92
+ "from": "ada@example.test",
93
+ "to": [
94
+ "inbox@yourdomain.test"
95
+ ],
96
+ "bcc": [],
97
+ "cc": [],
98
+ "received_for": [],
99
+ "message_id": "<111-222-333@email.example.test>",
100
+ "subject": "Sending this example",
101
+ "attachments": [
102
+ {
103
+ "id": `${fake.hex(8)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(12)}`,
104
+ "filename": "avatar.png",
105
+ "content_type": "image/png",
106
+ "content_disposition": "inline",
107
+ "content_id": "img001"
108
+ }
109
+ ]
110
+ }
111
+ };
112
+ }
14
113
  var resendFaker = (operation, request) => {
15
114
  switch (operation) {
115
+ case "attachment_get":
116
+ return fakeAttachmentGet(request);
117
+ case "attachment_list":
118
+ return fakeAttachmentList(request);
119
+ case "email_get":
120
+ return fakeEmailGet(request);
16
121
  case "email_send":
17
122
  return fakeEmailSend(request);
123
+ case "email_received":
124
+ return fakeEmailReceived(request);
18
125
  default:
19
126
  throw new Error(
20
127
  `resend: no fake response is defined for "${operation}". Add a fixture under provider/fixtures/ and regenerate \u2014 a connector without a faker cannot be developed against, tested, or demonstrated.`
@@ -48,6 +155,88 @@ var RESEND = {
48
155
  idempotencyHeader: "Idempotency-Key",
49
156
  faker: resendFaker
50
157
  };
158
+ var ATTACHMENT_GET_OPERATION = "attachment_get";
159
+ async function resendAttachmentGet(options) {
160
+ const config = options.config ?? {};
161
+ if (config.emailId === void 0 || config.emailId === null || config.emailId === "") {
162
+ throw new Error(`attachment_get: "emailId" is required (Email ID).`);
163
+ }
164
+ if (config.attachmentId === void 0 || config.attachmentId === null || config.attachmentId === "") {
165
+ throw new Error(`attachment_get: "attachmentId" is required (Attachment ID).`);
166
+ }
167
+ return fancyConnectorCore.callConnector(RESEND, {
168
+ operation: ATTACHMENT_GET_OPERATION,
169
+ config,
170
+ input: options.input,
171
+ ...options.credentials === void 0 ? {} : { credentials: options.credentials },
172
+ ...options.mode === void 0 ? {} : { mode: options.mode },
173
+ ...options.connectionId === void 0 ? {} : { connectionId: options.connectionId },
174
+ ...options.attempts === void 0 ? {} : { attempts: options.attempts },
175
+ ...options.transport === void 0 ? {} : { transport: options.transport },
176
+ request: {
177
+ method: "GET",
178
+ path: `/emails/receiving/${encodeURIComponent(String(config.emailId))}/attachments/${encodeURIComponent(String(config.attachmentId))}`,
179
+ query: {}
180
+ }
181
+ });
182
+ }
183
+ var ATTACHMENT_LIST_OPERATION = "attachment_list";
184
+ async function resendAttachmentList(options) {
185
+ const config = options.config ?? {};
186
+ if (config.emailId === void 0 || config.emailId === null || config.emailId === "") {
187
+ throw new Error(`attachment_list: "emailId" is required (Email ID).`);
188
+ }
189
+ {
190
+ const n = Number(config.limit);
191
+ const given = config.limit !== void 0 && config.limit !== null && config.limit !== "";
192
+ if (given && !(Number.isInteger(n) && n >= 1 && n <= 100)) {
193
+ throw new Error(
194
+ `attachment_list: "limit" must be a integer, got ${JSON.stringify(config.limit)}.`
195
+ );
196
+ }
197
+ }
198
+ return fancyConnectorCore.callConnector(RESEND, {
199
+ operation: ATTACHMENT_LIST_OPERATION,
200
+ config,
201
+ input: options.input,
202
+ ...options.credentials === void 0 ? {} : { credentials: options.credentials },
203
+ ...options.mode === void 0 ? {} : { mode: options.mode },
204
+ ...options.connectionId === void 0 ? {} : { connectionId: options.connectionId },
205
+ ...options.attempts === void 0 ? {} : { attempts: options.attempts },
206
+ ...options.transport === void 0 ? {} : { transport: options.transport },
207
+ request: {
208
+ method: "GET",
209
+ path: `/emails/receiving/${encodeURIComponent(String(config.emailId))}/attachments`,
210
+ query: {
211
+ ...config.limit !== void 0 && config.limit !== null && config.limit !== "" ? { "limit": Math.trunc(Number(config.limit)) } : {},
212
+ ...config.after !== void 0 && config.after !== null && config.after !== "" ? { "after": String(config.after) } : {},
213
+ ...config.before !== void 0 && config.before !== null && config.before !== "" ? { "before": String(config.before) } : {}
214
+ }
215
+ }
216
+ });
217
+ }
218
+ var EMAIL_GET_OPERATION = "email_get";
219
+ async function resendEmailGet(options) {
220
+ const config = options.config ?? {};
221
+ if (config.emailId === void 0 || config.emailId === null || config.emailId === "") {
222
+ throw new Error(`email_get: "emailId" is required (Email ID).`);
223
+ }
224
+ return fancyConnectorCore.callConnector(RESEND, {
225
+ operation: EMAIL_GET_OPERATION,
226
+ config,
227
+ input: options.input,
228
+ ...options.credentials === void 0 ? {} : { credentials: options.credentials },
229
+ ...options.mode === void 0 ? {} : { mode: options.mode },
230
+ ...options.connectionId === void 0 ? {} : { connectionId: options.connectionId },
231
+ ...options.attempts === void 0 ? {} : { attempts: options.attempts },
232
+ ...options.transport === void 0 ? {} : { transport: options.transport },
233
+ request: {
234
+ method: "GET",
235
+ path: `/emails/receiving/${encodeURIComponent(String(config.emailId))}`,
236
+ query: {}
237
+ }
238
+ });
239
+ }
51
240
  var EMAIL_SEND_OPERATION = "email_send";
52
241
  async function resendEmailSend(options) {
53
242
  const config = options.config ?? {};
@@ -97,8 +286,85 @@ function headersMap(value) {
97
286
  }
98
287
  return out;
99
288
  }
289
+ var RESEND_EMAIL_RECEIVED_SIGNATURE_HEADER = "svix-signature";
290
+ var RESEND_EMAIL_RECEIVED_TOLERANCE = 300;
291
+ var RESEND_EMAIL_RECEIVED_SCHEME = {
292
+ algorithm: "SHA-256",
293
+ payload: (raw, timestamp, id) => `${id}.${timestamp}.${raw}`,
294
+ tolerance: RESEND_EMAIL_RECEIVED_TOLERANCE,
295
+ encoding: "base64",
296
+ secretEncoding: "base64",
297
+ secretPrefix: "whsec_"
298
+ };
299
+ function parseResendSignature(raw) {
300
+ const result = { signatures: [] };
301
+ for (const part of raw.split(" ")) {
302
+ const [key, value] = part.trim().split(",", 2);
303
+ if (value === void 0) continue;
304
+ if (key === "v1") {
305
+ result.signatures.push(value);
306
+ }
307
+ }
308
+ return result;
309
+ }
310
+ var RESEND_EMAIL_RECEIVED = {
311
+ service: "resend",
312
+ operation: "email_received",
313
+ delivery: "webhook",
314
+ setup: "Point a receiving domain's MX record at Resend, then in the Resend dashboard (Webhooks \u2192 Add webhook) point an endpoint at the route your host mounts for this trigger and subscribe it to email.received. Put the endpoint's signing secret -- shown as whsec_\u2026 -- on the connection as `webhookSecret`, exactly as shown.",
315
+ verification: {
316
+ signatureHeader: RESEND_EMAIL_RECEIVED_SIGNATURE_HEADER,
317
+ scheme: RESEND_EMAIL_RECEIVED_SCHEME,
318
+ timestampHeader: "svix-timestamp",
319
+ idHeader: "svix-id",
320
+ parse: parseResendSignature
321
+ },
322
+ faker: resendFaker
323
+ };
100
324
 
101
325
  // src/flow.ts
326
+ var resendAttachmentGetExecutor = async (ctx) => {
327
+ const config = ctx.node.data?.config ?? {};
328
+ const result = await resendAttachmentGet({
329
+ config,
330
+ input: ctx.inputs?.in
331
+ });
332
+ ctx.emit({
333
+ type: "log",
334
+ level: "info",
335
+ nodeId: ctx.node.id,
336
+ message: `resend attachment_get ${result.data?.id} (${result.mode})`
337
+ });
338
+ return { __port: "out", value: result };
339
+ };
340
+ var resendAttachmentListExecutor = async (ctx) => {
341
+ const config = ctx.node.data?.config ?? {};
342
+ const result = await resendAttachmentList({
343
+ config,
344
+ input: ctx.inputs?.in
345
+ });
346
+ ctx.emit({
347
+ type: "log",
348
+ level: "info",
349
+ nodeId: ctx.node.id,
350
+ message: `resend attachment_list ${result.data?.id} (${result.mode})`
351
+ });
352
+ return { __port: "out", value: result };
353
+ };
354
+ var resendEmailGetExecutor = async (ctx) => {
355
+ const config = ctx.node.data?.config ?? {};
356
+ const result = await resendEmailGet({
357
+ config,
358
+ input: ctx.inputs?.in
359
+ });
360
+ ctx.emit({
361
+ type: "log",
362
+ level: "info",
363
+ nodeId: ctx.node.id,
364
+ message: `resend email_get ${result.data?.id} (${result.mode})`
365
+ });
366
+ return { __port: "out", value: result };
367
+ };
102
368
  var resendEmailSendExecutor = async (ctx) => {
103
369
  const config = ctx.node.data?.config ?? {};
104
370
  const idempotencyKey = fancyConnectorCore.idempotencyKeyFor(ctx, ctx.node.id, {
@@ -125,11 +391,56 @@ var resendEmailSendExecutor = async (ctx) => {
125
391
  });
126
392
  return { __port: "out", value: result };
127
393
  };
394
+ var resendEmailReceivedTriggerExecutor = async (ctx) => {
395
+ const config = ctx.node.data?.config ?? {};
396
+ const connection = fancyConnectorCore.resolveConnection({
397
+ service: RESEND.service,
398
+ operation: "email_received",
399
+ sandbox: RESEND.sandbox,
400
+ baseUrls: RESEND.baseUrls,
401
+ requires: RESEND.requires,
402
+ connectionId: typeof config.connection === "string" ? config.connection : null,
403
+ requested: typeof config.mode === "string" ? config.mode : null
404
+ });
405
+ const event = fancyConnectorCore.triggerEvent(RESEND_EMAIL_RECEIVED, connection, ctx.inputs?.in, config);
406
+ const thenEmailId = at(event, "data.email_id");
407
+ if (thenEmailId === void 0 || thenEmailId === null || thenEmailId === "") {
408
+ throw new Error("email_received: the delivery carries no data.email_id, so email_get cannot run");
409
+ }
410
+ const read = await resendEmailGet({
411
+ config: {
412
+ ...config.connection === void 0 || config.connection === null ? {} : { connection: config.connection },
413
+ ...config.mode === void 0 || config.mode === null ? {} : { mode: config.mode },
414
+ emailId: thenEmailId
415
+ },
416
+ input: event
417
+ });
418
+ const value = {
419
+ ...event,
420
+ email: read.data,
421
+ verdicts: null
422
+ };
423
+ return { __port: "out", value };
424
+ };
425
+ function at(value, path) {
426
+ return path.split(".").reduce(
427
+ (v, key) => v !== null && typeof v === "object" ? v[key] : void 0,
428
+ value
429
+ );
430
+ }
128
431
  var RESEND_RUNNABLE_KINDS = [
129
- { ...resendUi.resendEmailSendKind, executor: resendEmailSendExecutor }
432
+ { ...resendUi.resendAttachmentGetKind, executor: resendAttachmentGetExecutor },
433
+ { ...resendUi.resendAttachmentListKind, executor: resendAttachmentListExecutor },
434
+ { ...resendUi.resendEmailGetKind, executor: resendEmailGetExecutor },
435
+ { ...resendUi.resendEmailSendKind, executor: resendEmailSendExecutor },
436
+ { ...resendUi.resendEmailReceivedTriggerKind, executor: resendEmailReceivedTriggerExecutor }
130
437
  ];
131
438
 
132
439
  exports.RESEND_RUNNABLE_KINDS = RESEND_RUNNABLE_KINDS;
440
+ exports.resendAttachmentGetExecutor = resendAttachmentGetExecutor;
441
+ exports.resendAttachmentListExecutor = resendAttachmentListExecutor;
442
+ exports.resendEmailGetExecutor = resendEmailGetExecutor;
443
+ exports.resendEmailReceivedTriggerExecutor = resendEmailReceivedTriggerExecutor;
133
444
  exports.resendEmailSendExecutor = resendEmailSendExecutor;
134
445
  //# sourceMappingURL=flow.cjs.map
135
446
  //# sourceMappingURL=flow.cjs.map
package/dist/flow.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/faker.ts","../src/service.ts","../src/actions/email-send.ts","../src/flow.ts"],"names":["callConnector","idempotencyKeyFor","NO_IDEMPOTENCY_KEY_WARNING","resendEmailSendKind"],"mappings":"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","file":"flow.cjs","sourcesContent":["/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/fixtures/ by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/fixtures/ (or weaver's template/) and regenerate:\n *\n * npm run provider -- resend\n */\n\n/**\n * The Resend faker.\n *\n * Shapes, not behaviour: the goal is that a downstream node sees the field\n * NAMES Resend actually publishes, so an author can wire {{ $json.data.id }}\n * against a fake and have it keep working against the real thing.\n *\n * Deterministic — same inputs, same output. A faker returning a fresh uuid\n * every call cannot be asserted on, so its fixtures degrade to \"it did not\n * throw\", which is the assertion that catches nothing.\n */\n\nimport type { ConnectorFaker, FakeRequest } from \"@particle-academy/fancy-connector-core\";\n\nfunction fakeEmailSend({ config, fake }: FakeRequest): unknown {\n return {\n \"id\": `${fake.hex(8)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(12)}`,\n };\n}\n\nexport const resendFaker: ConnectorFaker = (operation, request) => {\n switch (operation) {\n case \"email_send\":\n return fakeEmailSend(request);\n\n default:\n // A faker asked for an operation it has no shape for must SAY so. Making\n // something up would produce a green run whose output silently has none\n // of the fields the author is about to reference.\n throw new Error(\n `resend: no fake response is defined for \"${operation}\". ` +\n \"Add a fixture under provider/fixtures/ and regenerate — a connector without a faker \" +\n \"cannot be developed against, tested, or demonstrated.\",\n );\n }\n};\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/manifest.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/manifest.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- resend\n */\n\n/**\n * Resend, as one service descriptor shared by every Resend operation.\n *\n * @particle-academy/fancy-connector-core carries what is true of ALL\n * connectors. This carries what is true of Resend: its base URL, its auth\n * scheme, its idempotency header, and its faker.\n *\n * ## The sandbox trap, written down where it is used\n *\n * Resend has NO test estate, and somebody checked. Its simulator RECIPIENTS --\n * delivered@resend.dev, bounced@resend.dev, complained@resend.dev,\n * suppressed@resend.dev -- are not one: the send is real, it is billed, and it\n * counts against the quota. Modelling them as a sandbox would put a live send\n * behind a control labelled \"test\", so `mode` does not offer sandbox at all\n * and `fake` is the primary development mode rather than the fallback.\n */\n\nimport type { ConnectorMode, PreparedRequest, ServiceDescriptor } from \"@particle-academy/fancy-connector-core\";\n\nimport { resendFaker } from \"./faker.js\";\n\n/**\n * The connector API version this package was GENERATED against.\n *\n * A literal, never imported. An imported constant lets an upgrade rewrite the\n * very claim it exists to detect, after which the copy agrees with itself\n * forever.\n */\nexport const CONNECTOR_API_VERSION = 1;\n\nexport const RESEND_BASE_URLS = {\n \"live\": \"https://api.resend.com\"\n} as const;\n\n/** Credential keys a remote call cannot proceed without. */\nexport const RESEND_REQUIRES = [\n \"apiKey\"\n] as const;\n\n/**\n * Apply Resend's auth scheme to an outgoing request.\n *\n *\n *\n * The mode is passed in because for some providers auth and estate are the\n * same decision expressed in the URL; here it is unused, and saying so is\n * cheaper than wondering later whether it was forgotten.\n */\nexport function resendAuthorize(\n credentials: Record<string, string | undefined>,\n request: PreparedRequest,\n _mode: ConnectorMode,\n): void {\n request.headers[\"User-Agent\"] = \"fancy-flow-connector\";\n\n request.headers.Authorization = `Bearer ${credentials.apiKey ?? \"\"}`;\n}\n\n/** The Resend service, for the TypeScript runtime. */\nexport const RESEND: ServiceDescriptor = {\n service: \"resend\",\n title: \"Resend\",\n sandbox: \"none\",\n baseUrls: { ...RESEND_BASE_URLS },\n requires: [...RESEND_REQUIRES],\n authorize: resendAuthorize,\n // Resend honours this for 24 hours. It is what makes a retried durable run\n // resend nothing instead of mailing the recipient twice -- the difference\n // between `idempotent` and `unsafe-to-replay` is that this one is merely\n // embarrassing, not financial, but the header costs nothing and removes it\n // entirely.\n idempotencyHeader: \"Idempotency-Key\",\n faker: resendFaker,\n};\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/email-send.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/email-send.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- resend\n */\n\n/**\n * Send an email through Resend.\n *\n * POST /emails — https://resend.com/docs/api-reference/emails/send-email\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls Resend or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { RESEND } from \"../service.js\";\n\nexport const EMAIL_SEND_OPERATION = \"email_send\";\n\nexport type EmailSendOptions = {\n /** The node's resolved config. Keys: from, to, subject, html, text, replyTo, headers. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n /** Derived from the run and the step, never fresh. See the note above. */\n idempotencyKey?: string;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function resendEmailSend(options: EmailSendOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n if (config.from === undefined || config.from === null || config.from === \"\") {\n throw new Error(`email_send: \"from\" is required (From).`);\n }\n\n if (config.to === undefined || config.to === null || config.to === \"\") {\n throw new Error(`email_send: \"to\" is required (To).`);\n }\n\n if (!((config.html !== undefined && config.html !== null && config.html !== \"\") || (config.text !== undefined && config.text !== null && config.text !== \"\"))) {\n throw new Error(`email_send: needs an \"html\" or \"text\" body — an empty email is never intended.`);\n }\n\n return callConnector(RESEND, {\n operation: EMAIL_SEND_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n ...(options.idempotencyKey === undefined ? {} : { idempotencyKey: options.idempotencyKey }),\n request: {\n method: \"POST\",\n path: \"/emails\",\n json: {\n \"from\": String(config.from),\n \"to\": toList(config.to),\n \"subject\": config.subject !== undefined && config.subject !== null && config.subject !== \"\" ? String(config.subject) : \"\",\n ...(config.html !== undefined && config.html !== null && config.html !== \"\" ? { \"html\": String(config.html) } : {}),\n ...(config.text !== undefined && config.text !== null && config.text !== \"\" ? { \"text\": String(config.text) } : {}),\n ...(config.replyTo !== undefined && config.replyTo !== null && config.replyTo !== \"\" ? { \"reply_to\": String(config.replyTo) } : {}),\n \"headers\": headersMap(config.headers),\n },\n },\n });\n}\n\n/** One value, a \",\"-separated string, or an array — all end up a list. */\nfunction toList(value: unknown): string[] {\n const items = Array.isArray(value)\n ? value.map(String)\n : typeof value === \"string\"\n ? value.split(\",\")\n : [];\n\n return items.map((item) => item.trim()).filter(Boolean);\n}\n\n/** `{ k: \"v\" }` → `{ \"headers\": { \"k\": \"v\" } }` — a JSON body wants the real object. */\nfunction headersMap(value: unknown): Record<string, string> {\n if (!value || typeof value !== \"object\") return {};\n\n const out: Record<string, string> = {};\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n if (item !== undefined && item !== null && item !== \"\") out[key] = String(item);\n }\n\n return out;\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/ + triggers/ by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/ + triggers/ (or weaver's template/) and regenerate:\n *\n * npm run provider -- resend\n */\n\n/**\n * Resend's node kinds with their TypeScript executors attached — for hosts\n * that EXECUTE on TS.\n *\n * The authoring surface in @particle-academy/resend-ui carries no executor:\n * the editor is React on every host, so a PHP or Python project installs the\n * ui package and never this one.\n */\n\nimport type { NodeExecutor, NodeKindDefinition } from \"@particle-academy/fancy-flow/engine\";\nimport {\n idempotencyKeyFor,\n NO_IDEMPOTENCY_KEY_WARNING,\n resolveConnection,\n triggerEvent,\n type RequestedMode,\n} from \"@particle-academy/fancy-connector-core\";\nimport { RESEND } from \"./service.js\";\n\nimport {\n resendEmailSendKind,\n} from \"@particle-academy/resend-ui\";\n\nimport { resendEmailSend } from \"./actions/email-send.js\";\n\nexport const resendEmailSendExecutor: NodeExecutor = async (ctx) => {\n const config = ((ctx.node.data as { config?: Record<string, unknown> })?.config ?? {});\n\n // Derived from the RUN and the NODE, never fresh. A retried durable run\n // must send the same key or Resend creates a second one — the exact\n // failure \"idempotent\" exists to prevent.\n const idempotencyKey = idempotencyKeyFor(ctx, ctx.node.id, {\n context: { service: \"resend\", operation: \"email_send\" },\n });\n if (idempotencyKey === null) {\n ctx.emit({\n type: \"log\",\n level: \"warn\",\n nodeId: ctx.node.id,\n message: `email_send: ${NO_IDEMPOTENCY_KEY_WARNING}`,\n });\n }\n\n const result = await resendEmailSend({\n config,\n input: ctx.inputs?.in,\n ...(idempotencyKey === null ? {} : { idempotencyKey }),\n });\n\n ctx.emit({\n type: \"log\",\n level: \"info\",\n nodeId: ctx.node.id,\n message: `resend email_send ${(result.data as { id?: string })?.id} (${result.mode})`,\n });\n\n return { __port: \"out\", value: result };\n};\n\n/** The kinds a TypeScript host registers. */\nexport const RESEND_RUNNABLE_KINDS: NodeKindDefinition[] = [\n { ...resendEmailSendKind, executor: resendEmailSendExecutor },\n];\n"]}
1
+ {"version":3,"sources":["../src/faker.ts","../src/service.ts","../src/actions/attachment-get.ts","../src/actions/attachment-list.ts","../src/actions/email-get.ts","../src/actions/email-send.ts","../src/triggers/email-received.ts","../src/flow.ts"],"names":["callConnector","idempotencyKeyFor","NO_IDEMPOTENCY_KEY_WARNING","resolveConnection","triggerEvent","resendAttachmentGetKind","resendAttachmentListKind","resendEmailGetKind","resendEmailSendKind","resendEmailReceivedTriggerKind"],"mappings":"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","file":"flow.cjs","sourcesContent":["/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/fixtures/ by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/fixtures/ (or weaver's template/) and regenerate:\n *\n * npm run provider -- resend\n */\n\n/**\n * The Resend faker.\n *\n * Shapes, not behaviour: the goal is that a downstream node sees the field\n * NAMES Resend actually publishes, so an author can wire {{ $json.data.id }}\n * against a fake and have it keep working against the real thing.\n *\n * Deterministic — same inputs, same output. A faker returning a fresh uuid\n * every call cannot be asserted on, so its fixtures degrade to \"it did not\n * throw\", which is the assertion that catches nothing.\n */\n\nimport type { ConnectorFaker, FakeRequest } from \"@particle-academy/fancy-connector-core\";\n\nfunction fakeAttachmentGet({ config, fake }: FakeRequest): unknown {\n return {\n \"object\": \"attachment\",\n \"id\": (config.attachmentId !== undefined && config.attachmentId !== null && config.attachmentId !== \"\" ? String(config.attachmentId) : `${fake.hex(8)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(12)}`),\n \"filename\": \"avatar.png\",\n \"size\": 4096,\n \"content_type\": \"image/png\",\n \"content_disposition\": \"inline\",\n \"content_id\": \"img001\",\n \"download_url\": \"https://inbound-cdn.resend.com/4ef9a417-02e9-4d39-ad75-9611e0fcc33c/attachments/2a0c9ce0-3112-4728-976e-47ddcd16a318?signature=fake\",\n \"expires_at\": \"2026-10-17T14:29:41.521Z\",\n };\n}\n\nfunction fakeAttachmentList({ config, fake }: FakeRequest): unknown {\n return {\n \"object\": \"list\",\n \"has_more\": false,\n \"data\": [\n {\n \"id\": `${fake.hex(8)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(12)}`,\n \"filename\": \"avatar.png\",\n \"size\": 4096,\n \"content_type\": \"image/png\",\n \"content_disposition\": \"inline\",\n \"content_id\": \"img001\",\n \"download_url\": \"https://inbound-cdn.resend.com/4ef9a417-02e9-4d39-ad75-9611e0fcc33c/attachments/2a0c9ce0-3112-4728-976e-47ddcd16a318?signature=fake\",\n \"expires_at\": \"2026-10-17T14:29:41.521Z\",\n },\n ],\n };\n}\n\nfunction fakeEmailGet({ config, fake }: FakeRequest): unknown {\n return {\n \"object\": \"email\",\n \"id\": (config.emailId !== undefined && config.emailId !== null && config.emailId !== \"\" ? String(config.emailId) : `${fake.hex(8)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(12)}`),\n \"to\": [\n \"inbox@yourdomain.test\",\n ],\n \"from\": \"ada@example.test\",\n \"created_at\": \"2026-09-15T12:00:11.894Z\",\n \"subject\": \"Sending this example\",\n \"html\": \"Congrats on receiving your <strong>first email</strong>!\",\n \"html_format\": \"data_uri\",\n \"text\": null,\n \"headers\": {\n \"from\": \"Ada Lovelace <ada@example.test>\",\n \"return-path\": \"ada@example.test\",\n \"mime-version\": \"1.0\",\n },\n \"bcc\": [],\n \"cc\": [],\n \"reply_to\": [],\n \"received_for\": [],\n \"message_id\": \"<111-222-333@email.example.test>\",\n \"raw\": {\n \"download_url\": \"https://example.resend.com/receiving/raw/054da427-439a-4e91-b785-e4fb1966285f?Signature=fake\",\n \"expires_at\": \"2026-09-15T13:00:11.894Z\",\n },\n \"attachments\": [\n {\n \"id\": `${fake.hex(8)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(12)}`,\n \"filename\": \"avatar.png\",\n \"content_type\": \"image/png\",\n \"content_disposition\": \"inline\",\n \"content_id\": \"img001\",\n \"size\": 4096,\n },\n ],\n };\n}\n\nfunction fakeEmailSend({ config, fake }: FakeRequest): unknown {\n return {\n \"id\": `${fake.hex(8)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(12)}`,\n };\n}\n\nfunction fakeEmailReceived({ config, fake }: FakeRequest): unknown {\n const boundEmailid = `${fake.hex(8)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(12)}`;\n\n return {\n \"type\": \"email.received\",\n \"created_at\": \"2026-09-15T12:00:12.126Z\",\n \"data\": {\n \"email_id\": boundEmailid,\n \"created_at\": \"2026-09-15T12:00:11.894Z\",\n \"from\": \"ada@example.test\",\n \"to\": [\n \"inbox@yourdomain.test\",\n ],\n \"bcc\": [],\n \"cc\": [],\n \"received_for\": [],\n \"message_id\": \"<111-222-333@email.example.test>\",\n \"subject\": \"Sending this example\",\n \"attachments\": [\n {\n \"id\": `${fake.hex(8)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(4)}-${fake.hex(12)}`,\n \"filename\": \"avatar.png\",\n \"content_type\": \"image/png\",\n \"content_disposition\": \"inline\",\n \"content_id\": \"img001\",\n },\n ],\n },\n };\n}\n\nexport const resendFaker: ConnectorFaker = (operation, request) => {\n switch (operation) {\n case \"attachment_get\":\n return fakeAttachmentGet(request);\n\n case \"attachment_list\":\n return fakeAttachmentList(request);\n\n case \"email_get\":\n return fakeEmailGet(request);\n\n case \"email_send\":\n return fakeEmailSend(request);\n\n case \"email_received\":\n return fakeEmailReceived(request);\n\n default:\n // A faker asked for an operation it has no shape for must SAY so. Making\n // something up would produce a green run whose output silently has none\n // of the fields the author is about to reference.\n throw new Error(\n `resend: no fake response is defined for \"${operation}\". ` +\n \"Add a fixture under provider/fixtures/ and regenerate — a connector without a faker \" +\n \"cannot be developed against, tested, or demonstrated.\",\n );\n }\n};\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/manifest.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/manifest.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- resend\n */\n\n/**\n * Resend, as one service descriptor shared by every Resend operation.\n *\n * @particle-academy/fancy-connector-core carries what is true of ALL\n * connectors. This carries what is true of Resend: its base URL, its auth\n * scheme, its idempotency header, and its faker.\n *\n * ## The sandbox trap, written down where it is used\n *\n * Resend has NO test estate, and somebody checked. Its simulator RECIPIENTS --\n * delivered@resend.dev, bounced@resend.dev, complained@resend.dev,\n * suppressed@resend.dev -- are not one: the send is real, it is billed, and it\n * counts against the quota. Modelling them as a sandbox would put a live send\n * behind a control labelled \"test\", so `mode` does not offer sandbox at all\n * and `fake` is the primary development mode rather than the fallback.\n */\n\nimport type { ConnectorMode, PreparedRequest, ServiceDescriptor } from \"@particle-academy/fancy-connector-core\";\n\nimport { resendFaker } from \"./faker.js\";\n\n/**\n * The connector API version this package was GENERATED against.\n *\n * A literal, never imported. An imported constant lets an upgrade rewrite the\n * very claim it exists to detect, after which the copy agrees with itself\n * forever.\n */\nexport const CONNECTOR_API_VERSION = 1;\n\nexport const RESEND_BASE_URLS = {\n \"live\": \"https://api.resend.com\"\n} as const;\n\n/** Credential keys a remote call cannot proceed without. */\nexport const RESEND_REQUIRES = [\n \"apiKey\"\n] as const;\n\n/**\n * Apply Resend's auth scheme to an outgoing request.\n *\n *\n *\n * The mode is passed in because for some providers auth and estate are the\n * same decision expressed in the URL; here it is unused, and saying so is\n * cheaper than wondering later whether it was forgotten.\n */\nexport function resendAuthorize(\n credentials: Record<string, string | undefined>,\n request: PreparedRequest,\n _mode: ConnectorMode,\n): void {\n request.headers[\"User-Agent\"] = \"fancy-flow-connector\";\n\n request.headers.Authorization = `Bearer ${credentials.apiKey ?? \"\"}`;\n}\n\n/** The Resend service, for the TypeScript runtime. */\nexport const RESEND: ServiceDescriptor = {\n service: \"resend\",\n title: \"Resend\",\n sandbox: \"none\",\n baseUrls: { ...RESEND_BASE_URLS },\n requires: [...RESEND_REQUIRES],\n authorize: resendAuthorize,\n // Resend honours this for 24 hours. It is what makes a retried durable run\n // resend nothing instead of mailing the recipient twice -- the difference\n // between `idempotent` and `unsafe-to-replay` is that this one is merely\n // embarrassing, not financial, but the header costs nothing and removes it\n // entirely.\n idempotencyHeader: \"Idempotency-Key\",\n faker: resendFaker,\n};\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/attachment-get.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/attachment-get.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- resend\n */\n\n/**\n * Turn one attachment of a received email into a signed download URL.\n *\n * GET /emails/receiving/{emailId}/attachments/{attachmentId} —\n * https://resend.com/docs/api-reference/emails/retrieve-received-email-attachment\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls Resend or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { RESEND } from \"../service.js\";\n\nexport const ATTACHMENT_GET_OPERATION = \"attachment_get\";\n\nexport type AttachmentGetOptions = {\n /** The node's resolved config. Keys: emailId, attachmentId. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function resendAttachmentGet(options: AttachmentGetOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n if (config.emailId === undefined || config.emailId === null || config.emailId === \"\") {\n throw new Error(`attachment_get: \"emailId\" is required (Email ID).`);\n }\n\n if (config.attachmentId === undefined || config.attachmentId === null || config.attachmentId === \"\") {\n throw new Error(`attachment_get: \"attachmentId\" is required (Attachment ID).`);\n }\n\n return callConnector(RESEND, {\n operation: ATTACHMENT_GET_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"GET\",\n path: `/emails/receiving/${encodeURIComponent(String(config.emailId))}/attachments/${encodeURIComponent(String(config.attachmentId))}`,\n query: {},\n },\n });\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/attachment-list.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/attachment-list.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- resend\n */\n\n/**\n * List a received email's attachments, each with a signed download URL.\n *\n * GET /emails/receiving/{emailId}/attachments —\n * https://resend.com/docs/api-reference/emails/list-received-email-attachments\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls Resend or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { RESEND } from \"../service.js\";\n\nexport const ATTACHMENT_LIST_OPERATION = \"attachment_list\";\n\nexport type AttachmentListOptions = {\n /** The node's resolved config. Keys: emailId, limit, after, before. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function resendAttachmentList(options: AttachmentListOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n if (config.emailId === undefined || config.emailId === null || config.emailId === \"\") {\n throw new Error(`attachment_list: \"emailId\" is required (Email ID).`);\n }\n\n {\n const n = Number(config.limit);\n const given = config.limit !== undefined && config.limit !== null && config.limit !== \"\";\n if (given && !(Number.isInteger(n) && n >= 1 && n <= 100)) {\n throw new Error(\n `attachment_list: \"limit\" must be a integer, got ${JSON.stringify(config.limit)}.`,\n );\n }\n }\n\n return callConnector(RESEND, {\n operation: ATTACHMENT_LIST_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"GET\",\n path: `/emails/receiving/${encodeURIComponent(String(config.emailId))}/attachments`,\n query: {\n ...(config.limit !== undefined && config.limit !== null && config.limit !== \"\" ? { \"limit\": Math.trunc(Number(config.limit)) } : {}),\n ...(config.after !== undefined && config.after !== null && config.after !== \"\" ? { \"after\": String(config.after) } : {}),\n ...(config.before !== undefined && config.before !== null && config.before !== \"\" ? { \"before\": String(config.before) } : {}),\n },\n },\n });\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/email-get.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/email-get.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- resend\n */\n\n/**\n * Read a received email in full: its bodies, its headers and the list of its\n * attachments.\n *\n * GET /emails/receiving/{emailId} —\n * https://resend.com/docs/api-reference/emails/retrieve-received-email\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls Resend or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { RESEND } from \"../service.js\";\n\nexport const EMAIL_GET_OPERATION = \"email_get\";\n\nexport type EmailGetOptions = {\n /** The node's resolved config. Keys: emailId. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function resendEmailGet(options: EmailGetOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n if (config.emailId === undefined || config.emailId === null || config.emailId === \"\") {\n throw new Error(`email_get: \"emailId\" is required (Email ID).`);\n }\n\n return callConnector(RESEND, {\n operation: EMAIL_GET_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"GET\",\n path: `/emails/receiving/${encodeURIComponent(String(config.emailId))}`,\n query: {},\n },\n });\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/email-send.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/email-send.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- resend\n */\n\n/**\n * Send an email through Resend.\n *\n * POST /emails — https://resend.com/docs/api-reference/emails/send-email\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls Resend or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { RESEND } from \"../service.js\";\n\nexport const EMAIL_SEND_OPERATION = \"email_send\";\n\nexport type EmailSendOptions = {\n /** The node's resolved config. Keys: from, to, subject, html, text, replyTo, headers. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n /** Derived from the run and the step, never fresh. See the note above. */\n idempotencyKey?: string;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function resendEmailSend(options: EmailSendOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n if (config.from === undefined || config.from === null || config.from === \"\") {\n throw new Error(`email_send: \"from\" is required (From).`);\n }\n\n if (config.to === undefined || config.to === null || config.to === \"\") {\n throw new Error(`email_send: \"to\" is required (To).`);\n }\n\n if (!((config.html !== undefined && config.html !== null && config.html !== \"\") || (config.text !== undefined && config.text !== null && config.text !== \"\"))) {\n throw new Error(`email_send: needs an \"html\" or \"text\" body — an empty email is never intended.`);\n }\n\n return callConnector(RESEND, {\n operation: EMAIL_SEND_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n ...(options.idempotencyKey === undefined ? {} : { idempotencyKey: options.idempotencyKey }),\n request: {\n method: \"POST\",\n path: \"/emails\",\n json: {\n \"from\": String(config.from),\n \"to\": toList(config.to),\n \"subject\": config.subject !== undefined && config.subject !== null && config.subject !== \"\" ? String(config.subject) : \"\",\n ...(config.html !== undefined && config.html !== null && config.html !== \"\" ? { \"html\": String(config.html) } : {}),\n ...(config.text !== undefined && config.text !== null && config.text !== \"\" ? { \"text\": String(config.text) } : {}),\n ...(config.replyTo !== undefined && config.replyTo !== null && config.replyTo !== \"\" ? { \"reply_to\": String(config.replyTo) } : {}),\n \"headers\": headersMap(config.headers),\n },\n },\n });\n}\n\n/** One value, a \",\"-separated string, or an array — all end up a list. */\nfunction toList(value: unknown): string[] {\n const items = Array.isArray(value)\n ? value.map(String)\n : typeof value === \"string\"\n ? value.split(\",\")\n : [];\n\n return items.map((item) => item.trim()).filter(Boolean);\n}\n\n/** `{ k: \"v\" }` → `{ \"headers\": { \"k\": \"v\" } }` — a JSON body wants the real object. */\nfunction headersMap(value: unknown): Record<string, string> {\n if (!value || typeof value !== \"object\") return {};\n\n const out: Record<string, string> = {};\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n if (item !== undefined && item !== null && item !== \"\") out[key] = String(item);\n }\n\n return out;\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/triggers/email-received.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/triggers/email-received.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- resend\n */\n\n/**\n * Resend's webhook trigger — the delivery contract.\n *\n * Kept beside the service descriptor rather than inside a node, because a\n * signature scheme is a fact about RESEND. Two Resend triggers must not be\n * able to disagree about how a delivery is verified.\n */\n\nimport { verifyDelivery, type HmacScheme, type InboundDelivery, type TriggerDescriptor, type WebhookVerification } from \"@particle-academy/fancy-connector-core\";\nimport { resendFaker } from \"../faker.js\";\n\nexport const RESEND_EMAIL_RECEIVED_SIGNATURE_HEADER = \"svix-signature\";\n/** The provider's documented replay window, in seconds. */\nexport const RESEND_EMAIL_RECEIVED_TOLERANCE = 300;\n\nexport const RESEND_EMAIL_RECEIVED_SCHEME: HmacScheme = {\n algorithm: \"SHA-256\",\n payload: (raw, timestamp, id) => `${id}.${timestamp}.${raw}`,\n tolerance: RESEND_EMAIL_RECEIVED_TOLERANCE,\n encoding: \"base64\",\n secretEncoding: \"base64\",\n secretPrefix: \"whsec_\",\n};\n\n/**\n * Split `v1,…` into its parts.\n *\n * EVERY signature the header carries is collected, and the delivery passes\n * when ANY matches: a provider rolling a secret signs once per active secret,\n * and a first-only rule refused the whole roll as a wrong secret.\n *\n * `v1,<base64> v1,<base64>` -- several during a secret rotation, and Svix says\n * yours must match ONE of them. Every `v1` is offered to the verifier; the\n * first-only rule that Stripe's header once carried refused a whole roll.\n */\nexport function parseResendSignature(raw: string): {\n signatures: string[];\n timestamp?: string;\n} {\n const result: { signatures: string[]; timestamp?: string } = { signatures: [] };\n\n for (const part of raw.split(\" \")) {\n const [key, value] = part.trim().split(\",\", 2);\n if (value === undefined) continue;\n\n if (key === \"v1\") {\n result.signatures.push(value);\n }\n }\n\n return result;\n}\n\nexport const RESEND_EMAIL_RECEIVED: TriggerDescriptor = {\n service: \"resend\",\n operation: \"email_received\",\n delivery: \"webhook\",\n setup:\n \"Point a receiving domain's MX record at Resend, then in the Resend dashboard (Webhooks → Add webhook) point an endpoint at the route your host mounts for this trigger and subscribe it to email.received. Put the endpoint's signing secret -- shown as whsec_… -- on the connection as `webhookSecret`, exactly as shown.\",\n verification: {\n signatureHeader: RESEND_EMAIL_RECEIVED_SIGNATURE_HEADER,\n scheme: RESEND_EMAIL_RECEIVED_SCHEME,\n timestampHeader: \"svix-timestamp\",\n idHeader: \"svix-id\",\n parse: parseResendSignature,\n },\n faker: resendFaker,\n};\n\n/**\n * Verify one inbound Resend delivery.\n *\n * The host calls this BEFORE starting a run, with the body exactly as\n * received. Re-serialised JSON changes key order and whitespace, and produces\n * a mismatch that looks precisely like a wrong secret — hours of debugging the\n * wrong thing.\n *\n * The secret is the connection's `webhookSecret`.\n */\nexport function verifyResendDelivery(\n delivery: InboundDelivery,\n webhookSecret: string | undefined,\n now?: number,\n): Promise<WebhookVerification> {\n return verifyDelivery(RESEND_EMAIL_RECEIVED, delivery, webhookSecret, now);\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/ + triggers/ by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/ + triggers/ (or weaver's template/) and regenerate:\n *\n * npm run provider -- resend\n */\n\n/**\n * Resend's node kinds with their TypeScript executors attached — for hosts\n * that EXECUTE on TS.\n *\n * The authoring surface in @particle-academy/resend-ui carries no executor:\n * the editor is React on every host, so a PHP or Python project installs the\n * ui package and never this one.\n */\n\nimport type { NodeExecutor, NodeKindDefinition } from \"@particle-academy/fancy-flow/engine\";\nimport {\n idempotencyKeyFor,\n NO_IDEMPOTENCY_KEY_WARNING,\n resolveConnection,\n triggerEvent,\n type RequestedMode,\n} from \"@particle-academy/fancy-connector-core\";\nimport { RESEND } from \"./service.js\";\n\nimport {\n resendAttachmentGetKind,\n resendAttachmentListKind,\n resendEmailGetKind,\n resendEmailSendKind,\n resendEmailReceivedTriggerKind,\n} from \"@particle-academy/resend-ui\";\n\nimport { resendAttachmentGet } from \"./actions/attachment-get.js\";\nimport { resendAttachmentList } from \"./actions/attachment-list.js\";\nimport { resendEmailGet } from \"./actions/email-get.js\";\nimport { resendEmailSend } from \"./actions/email-send.js\";\nimport { RESEND_EMAIL_RECEIVED } from \"./triggers/email-received.js\";\n\nexport const resendAttachmentGetExecutor: NodeExecutor = async (ctx) => {\n const config = ((ctx.node.data as { config?: Record<string, unknown> })?.config ?? {});\n\n const result = await resendAttachmentGet({\n config,\n input: ctx.inputs?.in,\n });\n\n ctx.emit({\n type: \"log\",\n level: \"info\",\n nodeId: ctx.node.id,\n message: `resend attachment_get ${(result.data as { id?: string })?.id} (${result.mode})`,\n });\n\n return { __port: \"out\", value: result };\n};\n\nexport const resendAttachmentListExecutor: NodeExecutor = async (ctx) => {\n const config = ((ctx.node.data as { config?: Record<string, unknown> })?.config ?? {});\n\n const result = await resendAttachmentList({\n config,\n input: ctx.inputs?.in,\n });\n\n ctx.emit({\n type: \"log\",\n level: \"info\",\n nodeId: ctx.node.id,\n message: `resend attachment_list ${(result.data as { id?: string })?.id} (${result.mode})`,\n });\n\n return { __port: \"out\", value: result };\n};\n\nexport const resendEmailGetExecutor: NodeExecutor = async (ctx) => {\n const config = ((ctx.node.data as { config?: Record<string, unknown> })?.config ?? {});\n\n const result = await resendEmailGet({\n config,\n input: ctx.inputs?.in,\n });\n\n ctx.emit({\n type: \"log\",\n level: \"info\",\n nodeId: ctx.node.id,\n message: `resend email_get ${(result.data as { id?: string })?.id} (${result.mode})`,\n });\n\n return { __port: \"out\", value: result };\n};\n\nexport const resendEmailSendExecutor: NodeExecutor = async (ctx) => {\n const config = ((ctx.node.data as { config?: Record<string, unknown> })?.config ?? {});\n\n // Derived from the RUN and the NODE, never fresh. A retried durable run\n // must send the same key or Resend creates a second one — the exact\n // failure \"idempotent\" exists to prevent.\n const idempotencyKey = idempotencyKeyFor(ctx, ctx.node.id, {\n context: { service: \"resend\", operation: \"email_send\" },\n });\n if (idempotencyKey === null) {\n ctx.emit({\n type: \"log\",\n level: \"warn\",\n nodeId: ctx.node.id,\n message: `email_send: ${NO_IDEMPOTENCY_KEY_WARNING}`,\n });\n }\n\n const result = await resendEmailSend({\n config,\n input: ctx.inputs?.in,\n ...(idempotencyKey === null ? {} : { idempotencyKey }),\n });\n\n ctx.emit({\n type: \"log\",\n level: \"info\",\n nodeId: ctx.node.id,\n message: `resend email_send ${(result.data as { id?: string })?.id} (${result.mode})`,\n });\n\n return { __port: \"out\", value: result };\n};\n\nexport const resendEmailReceivedTriggerExecutor: NodeExecutor = async (ctx) => {\n const config = ((ctx.node.data as { config?: Record<string, unknown> })?.config ?? {});\n const connection = resolveConnection({\n service: RESEND.service,\n operation: \"email_received\",\n sandbox: RESEND.sandbox,\n baseUrls: RESEND.baseUrls,\n requires: RESEND.requires,\n connectionId: typeof config.connection === \"string\" ? config.connection : null,\n requested: typeof config.mode === \"string\" ? (config.mode as RequestedMode) : null,\n });\n\n const event = triggerEvent(RESEND_EMAIL_RECEIVED, connection, ctx.inputs?.in, config);\n\n // The run's FIRST step. A Resend delivery only NAMES what arrived, so\n // `email_get` is read before anything downstream runs and published\n // under `email`. A failed read fails the run with the core's\n // classification: a delivery whose read failed must not start a flow\n // that assumes it succeeded. In fake mode the read is faked with the\n // delivery's own values, so the composite has the same shape on the\n // canvas as it does live.\n const thenEmailId = at(event, \"data.email_id\");\n if (thenEmailId === undefined || thenEmailId === null || thenEmailId === \"\") {\n throw new Error(\"email_received: the delivery carries no data.email_id, so email_get cannot run\");\n }\n const read = await resendEmailGet({\n config: {\n ...(config.connection === undefined || config.connection === null ? {} : { connection: config.connection }),\n ...(config.mode === undefined || config.mode === null ? {} : { mode: config.mode }),\n emailId: thenEmailId,\n },\n input: event,\n });\n\n const value = {\n ...(event as Record<string, unknown>),\n email: read.data,\n verdicts: null,\n };\n\n return { __port: \"out\", value };\n};\n\n/** A dotted path into a delivery; undefined wherever it stops. */\nfunction at(value: unknown, path: string): unknown {\n return path.split(\".\").reduce<unknown>(\n (v, key) => (v !== null && typeof v === \"object\" ? (v as Record<string, unknown>)[key] : undefined),\n value,\n );\n}\n\n/** The kinds a TypeScript host registers. */\nexport const RESEND_RUNNABLE_KINDS: NodeKindDefinition[] = [\n { ...resendAttachmentGetKind, executor: resendAttachmentGetExecutor },\n { ...resendAttachmentListKind, executor: resendAttachmentListExecutor },\n { ...resendEmailGetKind, executor: resendEmailGetExecutor },\n { ...resendEmailSendKind, executor: resendEmailSendExecutor },\n { ...resendEmailReceivedTriggerKind, executor: resendEmailReceivedTriggerExecutor },\n];\n"]}
package/dist/flow.d.cts CHANGED
@@ -19,8 +19,12 @@ import { NodeKindDefinition, NodeExecutor } from '@particle-academy/fancy-flow/e
19
19
  * ui package and never this one.
20
20
  */
21
21
 
22
+ declare const resendAttachmentGetExecutor: NodeExecutor;
23
+ declare const resendAttachmentListExecutor: NodeExecutor;
24
+ declare const resendEmailGetExecutor: NodeExecutor;
22
25
  declare const resendEmailSendExecutor: NodeExecutor;
26
+ declare const resendEmailReceivedTriggerExecutor: NodeExecutor;
23
27
  /** The kinds a TypeScript host registers. */
24
28
  declare const RESEND_RUNNABLE_KINDS: NodeKindDefinition[];
25
29
 
26
- export { RESEND_RUNNABLE_KINDS, resendEmailSendExecutor };
30
+ export { RESEND_RUNNABLE_KINDS, resendAttachmentGetExecutor, resendAttachmentListExecutor, resendEmailGetExecutor, resendEmailReceivedTriggerExecutor, resendEmailSendExecutor };
package/dist/flow.d.ts CHANGED
@@ -19,8 +19,12 @@ import { NodeKindDefinition, NodeExecutor } from '@particle-academy/fancy-flow/e
19
19
  * ui package and never this one.
20
20
  */
21
21
 
22
+ declare const resendAttachmentGetExecutor: NodeExecutor;
23
+ declare const resendAttachmentListExecutor: NodeExecutor;
24
+ declare const resendEmailGetExecutor: NodeExecutor;
22
25
  declare const resendEmailSendExecutor: NodeExecutor;
26
+ declare const resendEmailReceivedTriggerExecutor: NodeExecutor;
23
27
  /** The kinds a TypeScript host registers. */
24
28
  declare const RESEND_RUNNABLE_KINDS: NodeKindDefinition[];
25
29
 
26
- export { RESEND_RUNNABLE_KINDS, resendEmailSendExecutor };
30
+ export { RESEND_RUNNABLE_KINDS, resendAttachmentGetExecutor, resendAttachmentListExecutor, resendEmailGetExecutor, resendEmailReceivedTriggerExecutor, resendEmailSendExecutor };
package/dist/flow.js CHANGED
@@ -1,7 +1,49 @@
1
- import { resendEmailSend } from './chunk-QIYVVKWU.js';
2
- import { idempotencyKeyFor, NO_IDEMPOTENCY_KEY_WARNING } from '@particle-academy/fancy-connector-core';
3
- import { resendEmailSendKind } from '@particle-academy/resend-ui';
1
+ import { resendAttachmentGet, resendAttachmentList, resendEmailGet, resendEmailSend, RESEND, RESEND_EMAIL_RECEIVED } from './chunk-JEKUTTK2.js';
2
+ import { idempotencyKeyFor, NO_IDEMPOTENCY_KEY_WARNING, resolveConnection, triggerEvent } from '@particle-academy/fancy-connector-core';
3
+ import { resendAttachmentGetKind, resendAttachmentListKind, resendEmailGetKind, resendEmailSendKind, resendEmailReceivedTriggerKind } from '@particle-academy/resend-ui';
4
4
 
5
+ var resendAttachmentGetExecutor = async (ctx) => {
6
+ const config = ctx.node.data?.config ?? {};
7
+ const result = await resendAttachmentGet({
8
+ config,
9
+ input: ctx.inputs?.in
10
+ });
11
+ ctx.emit({
12
+ type: "log",
13
+ level: "info",
14
+ nodeId: ctx.node.id,
15
+ message: `resend attachment_get ${result.data?.id} (${result.mode})`
16
+ });
17
+ return { __port: "out", value: result };
18
+ };
19
+ var resendAttachmentListExecutor = async (ctx) => {
20
+ const config = ctx.node.data?.config ?? {};
21
+ const result = await resendAttachmentList({
22
+ config,
23
+ input: ctx.inputs?.in
24
+ });
25
+ ctx.emit({
26
+ type: "log",
27
+ level: "info",
28
+ nodeId: ctx.node.id,
29
+ message: `resend attachment_list ${result.data?.id} (${result.mode})`
30
+ });
31
+ return { __port: "out", value: result };
32
+ };
33
+ var resendEmailGetExecutor = async (ctx) => {
34
+ const config = ctx.node.data?.config ?? {};
35
+ const result = await resendEmailGet({
36
+ config,
37
+ input: ctx.inputs?.in
38
+ });
39
+ ctx.emit({
40
+ type: "log",
41
+ level: "info",
42
+ nodeId: ctx.node.id,
43
+ message: `resend email_get ${result.data?.id} (${result.mode})`
44
+ });
45
+ return { __port: "out", value: result };
46
+ };
5
47
  var resendEmailSendExecutor = async (ctx) => {
6
48
  const config = ctx.node.data?.config ?? {};
7
49
  const idempotencyKey = idempotencyKeyFor(ctx, ctx.node.id, {
@@ -28,10 +70,51 @@ var resendEmailSendExecutor = async (ctx) => {
28
70
  });
29
71
  return { __port: "out", value: result };
30
72
  };
73
+ var resendEmailReceivedTriggerExecutor = async (ctx) => {
74
+ const config = ctx.node.data?.config ?? {};
75
+ const connection = resolveConnection({
76
+ service: RESEND.service,
77
+ operation: "email_received",
78
+ sandbox: RESEND.sandbox,
79
+ baseUrls: RESEND.baseUrls,
80
+ requires: RESEND.requires,
81
+ connectionId: typeof config.connection === "string" ? config.connection : null,
82
+ requested: typeof config.mode === "string" ? config.mode : null
83
+ });
84
+ const event = triggerEvent(RESEND_EMAIL_RECEIVED, connection, ctx.inputs?.in, config);
85
+ const thenEmailId = at(event, "data.email_id");
86
+ if (thenEmailId === void 0 || thenEmailId === null || thenEmailId === "") {
87
+ throw new Error("email_received: the delivery carries no data.email_id, so email_get cannot run");
88
+ }
89
+ const read = await resendEmailGet({
90
+ config: {
91
+ ...config.connection === void 0 || config.connection === null ? {} : { connection: config.connection },
92
+ ...config.mode === void 0 || config.mode === null ? {} : { mode: config.mode },
93
+ emailId: thenEmailId
94
+ },
95
+ input: event
96
+ });
97
+ const value = {
98
+ ...event,
99
+ email: read.data,
100
+ verdicts: null
101
+ };
102
+ return { __port: "out", value };
103
+ };
104
+ function at(value, path) {
105
+ return path.split(".").reduce(
106
+ (v, key) => v !== null && typeof v === "object" ? v[key] : void 0,
107
+ value
108
+ );
109
+ }
31
110
  var RESEND_RUNNABLE_KINDS = [
32
- { ...resendEmailSendKind, executor: resendEmailSendExecutor }
111
+ { ...resendAttachmentGetKind, executor: resendAttachmentGetExecutor },
112
+ { ...resendAttachmentListKind, executor: resendAttachmentListExecutor },
113
+ { ...resendEmailGetKind, executor: resendEmailGetExecutor },
114
+ { ...resendEmailSendKind, executor: resendEmailSendExecutor },
115
+ { ...resendEmailReceivedTriggerKind, executor: resendEmailReceivedTriggerExecutor }
33
116
  ];
34
117
 
35
- export { RESEND_RUNNABLE_KINDS, resendEmailSendExecutor };
118
+ export { RESEND_RUNNABLE_KINDS, resendAttachmentGetExecutor, resendAttachmentListExecutor, resendEmailGetExecutor, resendEmailReceivedTriggerExecutor, resendEmailSendExecutor };
36
119
  //# sourceMappingURL=flow.js.map
37
120
  //# sourceMappingURL=flow.js.map