@estaldo/n8n-nodes-postmarkapp 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -31,51 +31,56 @@ class PostmarkEmail {
31
31
  const items = this.getInputData();
32
32
  const out = [];
33
33
  for (let i = 0; i < items.length; i++) {
34
- const operation = this.getNodeParameter('operation', i);
35
- const path = operations_1.OPERATION_ENDPOINTS[operation];
36
- if (!path) {
37
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`, { itemIndex: i });
38
- }
39
- const defaultStream = this.getNodeParameter('messageStream', i, '');
40
- let body;
41
- if (operation === operations_1.Operation.Send || operation === operations_1.Operation.SendWithTemplate) {
42
- const kind = operation === operations_1.Operation.SendWithTemplate ? 'templated' : 'plain';
43
- const source = (0, helpers_1.collectSingleMessage)(this, i, kind);
44
- body = (0, helpers_1.buildEmailBody)(this, i, source, kind);
45
- (0, helpers_1.applyDefaultMessageStream)(body, defaultStream);
46
- }
47
- else {
48
- const kind = operation === operations_1.Operation.SendBatchWithTemplates ? 'templated' : 'plain';
49
- const messages = (0, helpers_1.collectBatchMessages)(this, i, kind);
50
- if (messages.length === 0) {
51
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'At least one message is required for a batch send', { itemIndex: i });
52
- }
53
- const messageBodies = messages.map((msg) => {
54
- const built = (0, helpers_1.buildEmailBody)(this, i, msg, kind);
55
- (0, helpers_1.applyDefaultMessageStream)(built, defaultStream);
56
- return built;
57
- });
58
- // Postmark's two batch endpoints differ in body shape:
59
- // - /email/batch → bare JSON array `[ {...}, {...} ]`.
60
- // - /email/batchWithTemplates → `{ "Messages": [ {...} ] }` (property name in
61
- // the body, not a path component).
62
- body = operation === operations_1.Operation.SendBatchWithTemplates
63
- ? { Messages: messageBodies }
64
- : messageBodies;
65
- }
66
- let response;
34
+ // One item is one send. A failure must not abandon the items after it, so the
35
+ // whole per-item body — parameter shaping included — sits inside the try.
67
36
  try {
68
- response = (await this.helpers.httpRequestWithAuthentication.call(this, 'postmarkApi', {
37
+ const operation = this.getNodeParameter('operation', i);
38
+ const path = operations_1.OPERATION_ENDPOINTS[operation];
39
+ if (!path) {
40
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`, { itemIndex: i });
41
+ }
42
+ const defaultStream = this.getNodeParameter('messageStream', i, '');
43
+ let body;
44
+ if (operation === operations_1.Operation.Send || operation === operations_1.Operation.SendWithTemplate) {
45
+ const kind = operation === operations_1.Operation.SendWithTemplate ? 'templated' : 'plain';
46
+ const source = (0, helpers_1.collectSingleMessage)(this, i, kind);
47
+ body = (0, helpers_1.buildEmailBody)(this, i, source, kind);
48
+ (0, helpers_1.applyDefaultMessageStream)(body, defaultStream);
49
+ }
50
+ else {
51
+ const kind = operation === operations_1.Operation.SendBatchWithTemplates ? 'templated' : 'plain';
52
+ const messages = (0, helpers_1.collectBatchMessages)(this, i, kind);
53
+ if (messages.length === 0) {
54
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'At least one message is required for a batch send', { itemIndex: i });
55
+ }
56
+ const messageBodies = messages.map((msg) => {
57
+ const built = (0, helpers_1.buildEmailBody)(this, i, msg, kind);
58
+ (0, helpers_1.applyDefaultMessageStream)(built, defaultStream);
59
+ return built;
60
+ });
61
+ // Postmark's two batch endpoints differ in body shape:
62
+ // - /email/batch → bare JSON array `[ {...}, {...} ]`.
63
+ // - /email/batchWithTemplates → `{ "Messages": [ {...} ] }` (property name in
64
+ // the body, not a path component).
65
+ body = operation === operations_1.Operation.SendBatchWithTemplates
66
+ ? { Messages: messageBodies }
67
+ : messageBodies;
68
+ }
69
+ const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'postmarkApi', {
69
70
  method: 'POST',
70
71
  url: `${POSTMARK_BASE_URL}${path}`,
71
72
  body,
72
73
  json: true,
73
74
  }));
75
+ out.push({ json: response, pairedItem: { item: i } });
74
76
  }
75
77
  catch (err) {
76
- throw (0, helpers_1.wrapPostmarkError)(this, err, i);
78
+ const error = (0, helpers_1.wrapPostmarkError)(this, err, i);
79
+ if (!this.continueOnFail()) {
80
+ throw error;
81
+ }
82
+ out.push({ json: { error: error.message }, error, pairedItem: { item: i } });
77
83
  }
78
- out.push({ json: response, pairedItem: { item: i } });
79
84
  }
80
85
  return [out];
81
86
  }
@@ -3,13 +3,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.wrapPostmarkError = wrapPostmarkError;
4
4
  const n8n_workflow_1 = require("n8n-workflow");
5
5
  function wrapPostmarkError(ctx, err, itemIndex) {
6
- // The HTTP helper surfaces Postmark's { ErrorCode, Message } body on error responses.
7
- // Pull it through so workflow authors see the API's reason rather than a generic 422.
8
- const e = err;
9
- const postmarkMessage = e.response?.body?.Message;
10
- const postmarkCode = e.response?.body?.ErrorCode;
6
+ // Parameter-shaping failures are already phrased for the workflow author.
7
+ if (err instanceof n8n_workflow_1.NodeOperationError) {
8
+ return err;
9
+ }
10
+ // n8n wraps an HTTP failure in a NodeApiError whose own `message` is a generic status
11
+ // sentence; the vendor body survives only on `context.data`. Read it structurally, not
12
+ // via `instanceof`: n8n throws from its own copy of n8n-workflow, never ours.
13
+ const body = err?.context
14
+ ?.data;
15
+ const postmarkMessage = typeof body?.Message === 'string' ? body.Message : undefined;
16
+ const postmarkCode = typeof body?.ErrorCode === 'number' ? body.ErrorCode : undefined;
11
17
  const detail = postmarkMessage
12
18
  ? `Postmark error ${postmarkCode ?? '?'}: ${postmarkMessage}`
13
- : (e.message ?? 'Unknown error');
19
+ : (err?.message ?? 'Unknown error');
14
20
  return new n8n_workflow_1.NodeOperationError(ctx.getNode(), detail, { itemIndex });
15
21
  }
@@ -1,5 +1,5 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60" width="60" height="60">
2
- <rect width="60" height="60" rx="10" fill="#FFDE00"/>
3
- <path d="M14 20 H46 V44 H14 Z" fill="none" stroke="#1A1A1A" stroke-width="3" stroke-linejoin="round"/>
4
- <path d="M14 20 L30 34 L46 20" fill="none" stroke="#1A1A1A" stroke-width="3" stroke-linejoin="round"/>
5
- </svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60" width="60" height="60">
2
+ <rect width="60" height="60" rx="10" fill="#FFDE00"/>
3
+ <path d="M14 20 H46 V44 H14 Z" fill="none" stroke="#1A1A1A" stroke-width="3" stroke-linejoin="round"/>
4
+ <path d="M14 20 L30 34 L46 20" fill="none" stroke="#1A1A1A" stroke-width="3" stroke-linejoin="round"/>
5
+ </svg>
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@estaldo/n8n-nodes-postmarkapp",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Postmark integration nodes for n8n",
5
5
  "n8n": {
6
6
  "n8nNodesApiVersion": 1,