@ironfang/n8n-nodes-ironfang 0.4.0 → 0.4.2

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/README.md CHANGED
@@ -6,7 +6,9 @@ Use Ironfang Render, Finance, Audit and Rig, and Ironfang's public developer
6
6
  tools, in n8n. The Ironfang action node has **162 operations**, grouped by
7
7
  product. Ironfang Trigger receives signed Audit, Finance and Render events.
8
8
 
9
- **Release: 0.4.0.** The products are named Ironfang Render, Finance and Audit
9
+ **Release: 0.4.2.** The API is now at `api.ironfang.com`; credentials saved with the old `api.ironfang.uk` address keep working unchanged. 0.4.1 made the package installable on n8n releases
10
+ before 2.33 that use PostgreSQL; see [Installation](#installation-and-credentials).
11
+ It includes 0.4.0, in which the products are named Ironfang Render, Finance and Audit
10
12
  (formerly Renderwolf, Financewolf and Auditwolf), and the node follows: requests
11
13
  go to the `/render`, `/finance` and `/audit` API prefixes and scopes are shown as
12
14
  `render:*`, `finance:*` and `audit:*`. It adds Ironfang Rig, Finance jobs,
@@ -18,10 +20,14 @@ change; see [Compatibility with earlier names](#compatibility-with-earlier-names
18
20
 
19
21
  On self-hosted n8n, open **Settings → Community Nodes → Install** and enter
20
22
  `@ironfang/n8n-nodes-ironfang`. The old `@ironfang/n8n-nodes-renderwolf` package
21
- is deprecated. n8n Cloud installation requires n8n's manual package verification;
23
+ is deprecated. Versions 0.2.3 to 0.4.0 cannot be installed on n8n releases
24
+ before 2.33 that use PostgreSQL: n8n reports `Failed to save installed package`
25
+ with `invalid input syntax for type integer`, because those releases store a
26
+ node's newest version as an integer and these packages' newest node version was
27
+ 1.1 or 1.2. Install 0.4.1 or later, or upgrade n8n. n8n Cloud installation requires n8n's manual package verification;
22
28
  npm publishing and automated checks do not establish that approval.
23
29
 
24
- Create an `if_live_` platform API key at [portal.ironfang.uk](https://portal.ironfang.uk)
30
+ Create an `if_live_` platform API key at [portal.ironfang.com](https://portal.ironfang.com)
25
31
  with the scopes your workflow needs, then select an Ironfang API credential.
26
32
  Existing `rw_live_` Render keys and both origin-only and `/renderwolf` base
27
33
  URLs remain supported. Other product bases and custom gateway prefixes work too.
@@ -48,10 +54,10 @@ The [operation reference](docs/operations.md) lists each action's endpoint,
48
54
  permission, query fields and request example. Complex API bodies use a JSON
49
55
  editor so nested fields remain available. Replace the example values before
50
56
  running a write operation. Request definitions are available in the product
51
- specifications: [Render](https://api.ironfang.uk/render/openapi.yaml),
52
- [Finance](https://api.ironfang.uk/finance/openapi.yaml),
53
- [Audit](https://api.ironfang.uk/audit/openapi.yaml),
54
- [Rig](https://api.ironfang.uk/rig/openapi.yaml).
57
+ specifications: [Render](https://api.ironfang.com/render/openapi.yaml),
58
+ [Finance](https://api.ironfang.com/finance/openapi.yaml),
59
+ [Audit](https://api.ironfang.com/audit/openapi.yaml),
60
+ [Rig](https://api.ironfang.com/rig/openapi.yaml).
55
61
 
56
62
  Screenshots support PNG/JPEG/WebP and phone/tablet device presets. Advanced
57
63
  Render Options accepts custom `css`, a page `script`, ordered `actions` (click,
@@ -192,7 +198,8 @@ Result against the current API: upgrade to fix it.
192
198
 
193
199
  Existing version 1 workflows retain string `bytes` and `error`
194
200
  fields. Version 1.1 uses numeric `bytes` and structured errors; version 1.2 adds
195
- paging to the Audit lists named above and is otherwise identical. All expose exact
201
+ paging to the Audit lists named above and is otherwise identical. Version 2,
202
+ which new nodes use, behaves as 1.2 does. All expose exact
196
203
  `byteLength`, item links and `_ironfang` response metadata when available:
197
204
  request ID, HTTP status, cache status and charged credits. Continued errors
198
205
  include available problem codes and retry information. New file operations use
@@ -214,15 +221,17 @@ and replace placeholder IDs, bucket names and example invoice data before runnin
214
221
  All examples are inactive on import.
215
222
 
216
223
  The tested n8n runtime is **2.38.1**, using its filesystem binary storage.
217
- Compilation/lint/unit checks run under Node.js 22 and 24. Saved version 1, 1.1
218
- and 1.2 workflows are exercised; older n8n host releases are not certified by this
224
+ Compilation/lint/unit checks run under Node.js 22 and 24. Saved version 1, 1.1,
225
+ 1.2 and 2 workflows are exercised; older n8n host releases are not certified by this
219
226
  matrix. The published node has no external runtime dependencies.
220
227
 
221
228
  ## Development and releases
222
229
 
223
230
  Run `npm ci --ignore-scripts` and `npm run check`. With Docker, run
224
- `bash scripts/check-runtime.sh` and `bash scripts/check-webhook-runtime.sh`.
225
- These execute local fixtures, including multipart/file handling and signed
231
+ `bash scripts/check-runtime.sh`, `bash scripts/check-webhook-runtime.sh` and
232
+ `bash scripts/check-postgres-install.sh`. The last installs the build through
233
+ n8n's community-package API on PostgreSQL, against n8n 2.32.4, from a throwaway
234
+ local registry. The first two execute local fixtures, including multipart/file handling and signed
226
235
  webhooks; they make no paid API calls. CI requires both before release.
227
236
  Lint runs with inline configuration disabled, matching the submission scanner's
228
237
  handling of suppression comments. Shared code in `lib/` is also linted and packaged.
@@ -5,7 +5,7 @@ class IronfangApi {
5
5
  name = 'ironfangApi';
6
6
  icon = { light: 'file:ironfang.svg', dark: 'file:ironfang.dark.svg' };
7
7
  displayName = 'Ironfang API';
8
- documentationUrl = 'https://ironfang.uk/render/docs';
8
+ documentationUrl = 'https://ironfang.com/render/docs';
9
9
  properties = [
10
10
  {
11
11
  displayName: 'API Key',
@@ -20,7 +20,7 @@ class IronfangApi {
20
20
  displayName: 'Base URL',
21
21
  name: 'baseUrl',
22
22
  type: 'string',
23
- default: 'https://api.ironfang.uk/render',
23
+ default: 'https://api.ironfang.com/render',
24
24
  description: 'API origin or product base URL. Origin-only and /renderwolf values saved by earlier versions remain valid; the node selects the requested product path.',
25
25
  },
26
26
  {
@@ -5,7 +5,7 @@ class IronfangS3 {
5
5
  name = 'ironfangS3';
6
6
  displayName = 'Ironfang S3 Destination';
7
7
  icon = { light: 'file:ironfang.svg', dark: 'file:ironfang.dark.svg' };
8
- documentationUrl = 'https://ironfang.uk/renderwolf/docs';
8
+ documentationUrl = 'https://ironfang.com/renderwolf/docs';
9
9
  properties = [
10
10
  { displayName: 'Access Key', name: 'accessKey', type: 'string', default: '', required: true },
11
11
  { displayName: 'Secret Key', name: 'secretKey', type: 'string', typeOptions: { password: true }, default: '', required: true },
@@ -5,7 +5,7 @@ class IronfangWebhookApi {
5
5
  name = 'ironfangWebhookApi';
6
6
  displayName = 'Ironfang Webhook API';
7
7
  icon = { light: 'file:ironfang.svg', dark: 'file:ironfang.dark.svg' };
8
- documentationUrl = 'https://ironfang.uk/audit/docs';
8
+ documentationUrl = 'https://ironfang.com/audit/docs';
9
9
  properties = [
10
10
  { displayName: 'Product', name: 'product', type: 'options', default: 'auditwolf', options: [{ name: 'Audit', value: 'auditwolf' }, { name: 'Finance', value: 'financewolf' }, { name: 'Render', value: 'renderwolf' }] },
11
11
  { displayName: 'Signing Secret', name: 'signingSecret', type: 'string', typeOptions: { password: true }, default: '', required: true, description: 'The one-time secret returned when creating the webhook endpoint or destination. This is not an API key.' },
@@ -2,7 +2,7 @@ import type { IExecuteFunctions, INodeExecutionData, INodeTypeDescription } from
2
2
  import { credentialTest } from '../nodes/Ironfang/credentialTest';
3
3
  /**
4
4
  * Ironfang node. One node per vendor: pick a product with Resource, then an
5
- * operation within it. Ironfang Render (https://ironfang.uk/render/docs) was the
5
+ * operation within it. Ironfang Render (https://ironfang.com/render/docs) was the
6
6
  * first product, and its saved resource value keeps the name it launched under; later ones are added as further resources rather than as
7
7
  * separate nodes.
8
8
  *
@@ -6,7 +6,7 @@ const transport_1 = require("../nodes/Ironfang/transport");
6
6
  const credentialTest_1 = require("../nodes/Ironfang/credentialTest");
7
7
  /**
8
8
  * Ironfang node. One node per vendor: pick a product with Resource, then an
9
- * operation within it. Ironfang Render (https://ironfang.uk/render/docs) was the
9
+ * operation within it. Ironfang Render (https://ironfang.com/render/docs) was the
10
10
  * first product, and its saved resource value keeps the name it launched under; later ones are added as further resources rather than as
11
11
  * separate nodes.
12
12
  *
@@ -19,7 +19,11 @@ exports.renderwolf = {
19
19
  icon: { light: 'file:ironfang.svg', dark: 'file:ironfang.dark.svg' },
20
20
  usableAsTool: true,
21
21
  group: ['transform'],
22
- version: [1, 1.1, 1.2],
22
+ // n8n before 2.33 stores a community node's newest version in an integer
23
+ // column on PostgreSQL and cannot install a package whose newest version
24
+ // is fractional, so the newest version here is always a whole number.
25
+ // Version 2 behaves as 1.2 does.
26
+ version: [1, 1.1, 1.2, 2],
23
27
  subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
24
28
  description: 'Rendering and developer APIs from Ironfang',
25
29
  defaults: { name: 'Ironfang' },
@@ -43,7 +43,7 @@ async function runOperation(context, item, op) {
43
43
  const publicMode = op.product === 'tools' || (op.product === 'financewolf' && parameter(context, 'authentication', item, 'apiKey') === 'public');
44
44
  if (publicMode && !op.public)
45
45
  throw new Error('This operation requires an API key; public mode cannot access saved results');
46
- const base = publicMode ? parameter(context, 'publicBaseUrl', item, 'https://api.ironfang.uk') : (await context.getCredentials('ironfangApi')).baseUrl;
46
+ const base = publicMode ? parameter(context, 'publicBaseUrl', item, 'https://api.ironfang.com') : (await context.getCredentials('ironfangApi')).baseUrl;
47
47
  const path = op.path.replace(/\{(\w+)\}/g, (_, name) => (0, transport_1.identifier)(context, parameter(context, name, item), item));
48
48
  const url = (0, transport_1.productBase)(base, op.product) + path;
49
49
  const qs = { ...parameter(context, 'query', item, {}) };
@@ -20,7 +20,7 @@ function queryField(field) {
20
20
  }
21
21
  exports.productParameters = [
22
22
  { displayName: 'Authentication', name: 'authentication', type: 'options', noDataExpression: true, default: 'apiKey', displayOptions: { show: { resource: ['financewolf'] } }, options: [{ name: 'API Key', value: 'apiKey' }, { name: 'Public (No Saved Results)', value: 'public' }], description: 'Public validation, generation, ruleset reads and report verification only. An invalid key never falls back to public access.' },
23
- { displayName: 'Public API Base URL', name: 'publicBaseUrl', type: 'string', default: 'https://api.ironfang.uk', displayOptions: { show: { resource: ['tools', 'financewolf'] } }, description: 'Used by public requests only; authenticated requests use the credential base URL' },
23
+ { displayName: 'Public API Base URL', name: 'publicBaseUrl', type: 'string', default: 'https://api.ironfang.com', displayOptions: { show: { resource: ['tools', 'financewolf'] } }, description: 'Used by public requests only; authenticated requests use the credential base URL' },
24
24
  { displayName: 'Public tools share per-address limits. Screenshot is limited to 20/hour/address and a shared daily ceiling. Render Screenshot is the account-based automation service.', name: 'toolsNotice', type: 'notice', default: '', displayOptions: { show: { resource: ['tools'] } } },
25
25
  ...catalog_1.operations.flatMap((op) => {
26
26
  const fields = [{ displayName: `Permission: ${op.scope}. ${op.description}.`, name: 'operationNotice', type: 'notice', default: '', displayOptions: show(op) }];
@@ -13,10 +13,16 @@ exports.productBase = productBase;
13
13
  exports.renderwolfBase = renderwolfBase;
14
14
  const n8n_workflow_1 = require("n8n-workflow");
15
15
  function apiBase(value) {
16
- const url = new URL(String(value || 'https://api.ironfang.uk/render'));
16
+ const url = new URL(String(value || 'https://api.ironfang.com/render'));
17
17
  if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password || url.search || url.hash) {
18
18
  throw new Error('Base URL must be an HTTP(S) URL without credentials, a query or fragment');
19
19
  }
20
+ // The API moved from ironfang.uk to ironfang.com on 28 Sep 2026. The old
21
+ // names redirect, but a redirect to another domain drops the API key, so
22
+ // credentials saved with an ironfang.uk address are sent to .com directly.
23
+ if (url.hostname === 'ironfang.uk' || url.hostname.endsWith('.ironfang.uk')) {
24
+ url.hostname = url.hostname.slice(0, -'uk'.length) + 'com';
25
+ }
20
26
  return url.toString().replace(/\/+$/, '');
21
27
  }
22
28
  function identifier(context, value, itemIndex) {