From fa386a11e5e7f23596686bbe92eaeefbd9f4e4ba Mon Sep 17 00:00:00 2001 From: lookinway Date: Tue, 7 Apr 2026 14:18:28 +0300 Subject: [PATCH 1/2] fix(n8n): form visual builder field ordering + bump 2.0.1 - Move Type field first in fixedCollection values so displayOptions.show.type works - Disable ESLint sort rule for FormDescription.ts (its autofix strips displayOptions) - Fix README archive install URL to use tag-specific path - Bump version to 2.0.1 --- integrations/n8n/CHANGELOG.md | 7 ++++ integrations/n8n/README.md | 11 +++-- integrations/n8n/eslint.config.mjs | 8 ++++ .../n8n/nodes/Pachca/V2/FormDescription.ts | 38 ++++++++--------- integrations/n8n/package.json | 2 +- integrations/n8n/scripts/generate-n8n.ts | 42 +++++++++---------- 6 files changed, 63 insertions(+), 45 deletions(-) diff --git a/integrations/n8n/CHANGELOG.md b/integrations/n8n/CHANGELOG.md index 781d3e60..4881aa38 100644 --- a/integrations/n8n/CHANGELOG.md +++ b/integrations/n8n/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 2.0.1 (2026-04-07) + +### Bug Fixes + +- Fix Form Visual Builder "Could not get parameter" error — `Type` field must be first in `fixedCollection` values so other fields can reference it via `displayOptions.show.type` +- Fix README archive installation URL (use tag-specific URL instead of unreliable `/releases/latest/`) + ## 2.0.0 (2026-04-03) ### New diff --git a/integrations/n8n/README.md b/integrations/n8n/README.md index f26cae17..61c706a4 100644 --- a/integrations/n8n/README.md +++ b/integrations/n8n/README.md @@ -18,15 +18,18 @@ Or install via CLI: npm install n8n-nodes-pachca ``` -Or install from archive: +Or install from archive (Docker, custom n8n images): ```bash +# Download from GitHub Releases +# Find the latest n8n-nodes-pachca.tgz at: +# https://github.com/pachca/openapi/releases?q=n8n +wget https://github.com/pachca/openapi/releases/download/n8n-v2.0.1/n8n-nodes-pachca.tgz + # Via npm (recommended) -wget https://github.com/pachca/openapi/releases/latest/download/n8n-nodes-pachca.tgz cd ~/.n8n/nodes && npm install ./n8n-nodes-pachca.tgz -# Or extract directly (Docker, no npm needed) -wget https://github.com/pachca/openapi/releases/latest/download/n8n-nodes-pachca.tgz +# Or extract directly (no npm needed) tar -xzf n8n-nodes-pachca.tgz -C ~/.n8n/nodes/ # Restart n8n diff --git a/integrations/n8n/eslint.config.mjs b/integrations/n8n/eslint.config.mjs index c2643cfe..242c12ec 100644 --- a/integrations/n8n/eslint.config.mjs +++ b/integrations/n8n/eslint.config.mjs @@ -16,6 +16,14 @@ export default [ '@n8n/community-nodes/icon-validation': 'off', }, }, + { + files: ['nodes/Pachca/V2/FormDescription.ts'], + rules: { + // Type field must be first in form block values (other fields reference it via displayOptions.show.type). + // The alphabetical sort autofix moves Type last AND strips displayOptions, breaking the visual builder. + 'n8n-nodes-base/node-param-fixed-collection-type-unsorted-items': 'off', + }, + }, { files: ['credentials/**/*.ts'], rules: { diff --git a/integrations/n8n/nodes/Pachca/V2/FormDescription.ts b/integrations/n8n/nodes/Pachca/V2/FormDescription.ts index dcf1f85f..d01b4a25 100644 --- a/integrations/n8n/nodes/Pachca/V2/FormDescription.ts +++ b/integrations/n8n/nodes/Pachca/V2/FormDescription.ts @@ -123,6 +123,25 @@ export const formFields: INodeProperties[] = [ name: 'block', displayName: 'Block', values: [ + { + displayName: 'Type', + name: 'type', + type: 'options', + options: [ + { name: '☑️ Checkboxes', value: 'checkbox' }, + { name: '➖ Divider', value: 'divider' }, + { name: '📄 Plain Text', value: 'plain_text' }, + { name: '📅 Date Picker', value: 'date' }, + { name: '📋 Select Dropdown', value: 'select' }, + { name: '📎 File Upload', value: 'file_input' }, + { name: '📝 Header', value: 'header' }, + { name: '📝 Markdown', value: 'markdown' }, + { name: '📝 Text Input', value: 'input' }, + { name: '🔘 Radio Buttons', value: 'radio' }, + { name: '🕐 Time Picker', value: 'time' }, + ], + default: 'input', + }, { displayName: 'Allowed File Types', name: 'filetypes', @@ -245,25 +264,6 @@ export const formFields: INodeProperties[] = [ default: '', displayOptions: { show: { type: ['header', 'plain_text', 'markdown'] } }, }, - { - displayName: 'Type', - name: 'type', - type: 'options', - options: [ - { name: '☑️ Checkboxes', value: 'checkbox' }, - { name: '➖ Divider', value: 'divider' }, - { name: '📄 Plain Text', value: 'plain_text' }, - { name: '📅 Date Picker', value: 'date' }, - { name: '📋 Select Dropdown', value: 'select' }, - { name: '📎 File Upload', value: 'file_input' }, - { name: '📝 Header', value: 'header' }, - { name: '📝 Markdown', value: 'markdown' }, - { name: '📝 Text Input', value: 'input' }, - { name: '🔘 Radio Buttons', value: 'radio' }, - { name: '🕐 Time Picker', value: 'time' }, - ], - default: 'input', - }, ], }], }, diff --git a/integrations/n8n/package.json b/integrations/n8n/package.json index c115d1f9..35e7bc5f 100644 --- a/integrations/n8n/package.json +++ b/integrations/n8n/package.json @@ -1,6 +1,6 @@ { "name": "n8n-nodes-pachca", - "version": "2.0.0", + "version": "2.0.1", "description": "Pachca node for n8n workflow automation", "license": "MIT", "main": "index.js", diff --git a/integrations/n8n/scripts/generate-n8n.ts b/integrations/n8n/scripts/generate-n8n.ts index 98ced762..36d82638 100644 --- a/integrations/n8n/scripts/generate-n8n.ts +++ b/integrations/n8n/scripts/generate-n8n.ts @@ -1214,7 +1214,27 @@ function generateResourceDescription( lines.push(`\t\t\tname: 'block',`); lines.push(`\t\t\tdisplayName: 'Block',`); lines.push(`\t\t\tvalues: [`); - // Fields in alphabetical order by displayName (required by n8n eslint rule) + // Block type selector — MUST be first because other fields reference it via displayOptions.show.type + lines.push(`\t\t\t\t{`); + lines.push(`\t\t\t\t\tdisplayName: 'Type',`); + lines.push(`\t\t\t\t\tname: 'type',`); + lines.push(`\t\t\t\t\ttype: 'options',`); + lines.push(`\t\t\t\t\toptions: [`); + lines.push(`\t\t\t\t\t\t{ name: '☑️ Checkboxes', value: 'checkbox' },`); + lines.push(`\t\t\t\t\t\t{ name: '➖ Divider', value: 'divider' },`); + lines.push(`\t\t\t\t\t\t{ name: '📄 Plain Text', value: 'plain_text' },`); + lines.push(`\t\t\t\t\t\t{ name: '📅 Date Picker', value: 'date' },`); + lines.push(`\t\t\t\t\t\t{ name: '📋 Select Dropdown', value: 'select' },`); + lines.push(`\t\t\t\t\t\t{ name: '📎 File Upload', value: 'file_input' },`); + lines.push(`\t\t\t\t\t\t{ name: '📝 Header', value: 'header' },`); + lines.push(`\t\t\t\t\t\t{ name: '📝 Markdown', value: 'markdown' },`); + lines.push(`\t\t\t\t\t\t{ name: '📝 Text Input', value: 'input' },`); + lines.push(`\t\t\t\t\t\t{ name: '🔘 Radio Buttons', value: 'radio' },`); + lines.push(`\t\t\t\t\t\t{ name: '🕐 Time Picker', value: 'time' },`); + lines.push(`\t\t\t\t\t],`); + lines.push(`\t\t\t\t\tdefault: 'input',`); + lines.push(`\t\t\t\t},`); + // Remaining fields in alphabetical order by displayName // Allowed File Types (file_input only) lines.push(`\t\t\t\t{`); lines.push(`\t\t\t\t\tdisplayName: 'Allowed File Types',`); @@ -1352,26 +1372,6 @@ function generateResourceDescription( lines.push(`\t\t\t\t\tdefault: '',`); lines.push(`\t\t\t\t\tdisplayOptions: { show: { type: ['header', 'plain_text', 'markdown'] } },`); lines.push(`\t\t\t\t},`); - // Block type selector - lines.push(`\t\t\t\t{`); - lines.push(`\t\t\t\t\tdisplayName: 'Type',`); - lines.push(`\t\t\t\t\tname: 'type',`); - lines.push(`\t\t\t\t\ttype: 'options',`); - lines.push(`\t\t\t\t\toptions: [`); - lines.push(`\t\t\t\t\t\t{ name: '☑️ Checkboxes', value: 'checkbox' },`); - lines.push(`\t\t\t\t\t\t{ name: '➖ Divider', value: 'divider' },`); - lines.push(`\t\t\t\t\t\t{ name: '📄 Plain Text', value: 'plain_text' },`); - lines.push(`\t\t\t\t\t\t{ name: '📅 Date Picker', value: 'date' },`); - lines.push(`\t\t\t\t\t\t{ name: '📋 Select Dropdown', value: 'select' },`); - lines.push(`\t\t\t\t\t\t{ name: '📎 File Upload', value: 'file_input' },`); - lines.push(`\t\t\t\t\t\t{ name: '📝 Header', value: 'header' },`); - lines.push(`\t\t\t\t\t\t{ name: '📝 Markdown', value: 'markdown' },`); - lines.push(`\t\t\t\t\t\t{ name: '📝 Text Input', value: 'input' },`); - lines.push(`\t\t\t\t\t\t{ name: '🔘 Radio Buttons', value: 'radio' },`); - lines.push(`\t\t\t\t\t\t{ name: '🕐 Time Picker', value: 'time' },`); - lines.push(`\t\t\t\t\t],`); - lines.push(`\t\t\t\t\tdefault: 'input',`); - lines.push(`\t\t\t\t},`); lines.push(`\t\t\t],`); lines.push(`\t\t}],`); lines.push(`\t},`); From 2ade2964a65b765ff56acfbd6b8797983bacbc5e Mon Sep 17 00:00:00 2001 From: lookinway Date: Tue, 7 Apr 2026 14:41:28 +0300 Subject: [PATCH 2/2] =?UTF-8?q?fix(n8n):=20v1=E2=86=92v2=20migration=20cra?= =?UTF-8?q?sh=20for=20Form=20createView=20=E2=80=94=20type=20param=20defau?= =?UTF-8?q?lt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit V1 Form node had no top-level `type` parameter (was hardcoded as `modal`). When SharedRouter maps v1 `createView` to v2 `create`, bodyMap tries to read `type` and throws "Could not get parameter". Added `default` support to FieldMap: when a bodyMap entry has a default value, getNodeParameter is wrapped in try/catch and falls back to the default. Form `type` field now defaults to `modal`. --- integrations/n8n/CHANGELOG.md | 1 + integrations/n8n/nodes/Pachca/SharedRouter.ts | 5 ++++- integrations/n8n/scripts/generate-n8n.ts | 8 ++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/integrations/n8n/CHANGELOG.md b/integrations/n8n/CHANGELOG.md index 4881aa38..8cbfff0b 100644 --- a/integrations/n8n/CHANGELOG.md +++ b/integrations/n8n/CHANGELOG.md @@ -5,6 +5,7 @@ ### Bug Fixes - Fix Form Visual Builder "Could not get parameter" error — `Type` field must be first in `fixedCollection` values so other fields can reference it via `displayOptions.show.type` +- Fix v1→v2 migration crash for Form `createView` operation — `type` parameter didn't exist in v1, now defaults to `modal` - Fix README archive installation URL (use tag-specific URL instead of unreliable `/releases/latest/`) ## 2.0.0 (2026-04-03) diff --git a/integrations/n8n/nodes/Pachca/SharedRouter.ts b/integrations/n8n/nodes/Pachca/SharedRouter.ts index 883160ae..64eae7a3 100644 --- a/integrations/n8n/nodes/Pachca/SharedRouter.ts +++ b/integrations/n8n/nodes/Pachca/SharedRouter.ts @@ -36,6 +36,7 @@ interface FieldMap { arrayType?: 'int' | 'string'; locator?: boolean; subKey?: string; + default?: unknown; } interface QueryMap { @@ -656,7 +657,7 @@ const ROUTES: Record> = { special: 'formBlocks', bodyMap: [ { api: 'title', n8n: 'formTitle' }, - { api: 'type', n8n: 'type' }, + { api: 'type', n8n: 'type', default: 'modal' }, { api: 'trigger_id', n8n: 'triggerId' }, ], optionalBodyMap: [ @@ -829,6 +830,8 @@ async function executeRoute( let raw: unknown; if (fm.locator) { raw = resolveResourceLocator(this, fm.n8n, i); + } else if (fm.default !== undefined) { + try { raw = this.getNodeParameter(fm.n8n, i); } catch { raw = fm.default; } } else { raw = this.getNodeParameter(fm.n8n, i); } diff --git a/integrations/n8n/scripts/generate-n8n.ts b/integrations/n8n/scripts/generate-n8n.ts index 36d82638..a3e3c2af 100644 --- a/integrations/n8n/scripts/generate-n8n.ts +++ b/integrations/n8n/scripts/generate-n8n.ts @@ -2492,6 +2492,11 @@ function buildFieldMapStr(resource: string, op: OperationInfo, f: BodyField): st parts.push(`subKey: '${subKey}'`); } + // v1 compat: form.type didn't exist in v1 — default to 'modal' + if (resource === 'form' && f.name === 'type') { + parts.push(`default: 'modal'`); + } + return `{ ${parts.join(', ')} }`; } @@ -2776,6 +2781,7 @@ interface FieldMap { \tarrayType?: 'int' | 'string'; \tlocator?: boolean; \tsubKey?: string; +\tdefault?: unknown; } interface QueryMap { @@ -2943,6 +2949,8 @@ async function executeRoute( \t\tlet raw: unknown; \t\tif (fm.locator) { \t\t\traw = resolveResourceLocator(this, fm.n8n, i); +\t\t} else if (fm.default !== undefined) { +\t\t\ttry { raw = this.getNodeParameter(fm.n8n, i); } catch { raw = fm.default; } \t\t} else { \t\t\traw = this.getNodeParameter(fm.n8n, i); \t\t}