Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions integrations/n8n/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# 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 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)

### New
Expand Down
11 changes: 7 additions & 4 deletions integrations/n8n/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions integrations/n8n/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
5 changes: 4 additions & 1 deletion integrations/n8n/nodes/Pachca/SharedRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ interface FieldMap {
arrayType?: 'int' | 'string';
locator?: boolean;
subKey?: string;
default?: unknown;
}

interface QueryMap {
Expand Down Expand Up @@ -656,7 +657,7 @@ const ROUTES: Record<string, Record<string, RouteConfig>> = {
special: 'formBlocks',
bodyMap: [
{ api: 'title', n8n: 'formTitle' },
{ api: 'type', n8n: 'type' },
{ api: 'type', n8n: 'type', default: 'modal' },
{ api: 'trigger_id', n8n: 'triggerId' },
],
optionalBodyMap: [
Expand Down Expand Up @@ -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);
}
Expand Down
38 changes: 19 additions & 19 deletions integrations/n8n/nodes/Pachca/V2/FormDescription.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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',
},
],
}],
},
Expand Down
2 changes: 1 addition & 1 deletion integrations/n8n/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
50 changes: 29 additions & 21 deletions integrations/n8n/scripts/generate-n8n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',`);
Expand Down Expand Up @@ -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},`);
Expand Down Expand Up @@ -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(', ')} }`;
}

Expand Down Expand Up @@ -2776,6 +2781,7 @@ interface FieldMap {
\tarrayType?: 'int' | 'string';
\tlocator?: boolean;
\tsubKey?: string;
\tdefault?: unknown;
}

interface QueryMap {
Expand Down Expand Up @@ -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}
Expand Down
Loading