first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import { readFileSync, existsSync } from 'fs';
|
||||
import { jsonParse, type INodeTypeDescription } from 'n8n-workflow';
|
||||
import { join } from 'path';
|
||||
|
||||
interface NodeWithVersion extends INodeTypeDescription {
|
||||
version: number | number[];
|
||||
defaultVersion?: number;
|
||||
}
|
||||
|
||||
// These types are ignored because they tend to cause issues when generating workflows
|
||||
// Same as in ai-workflow-builder-agent.service.ts
|
||||
const IGNORED_TYPES = new Set([
|
||||
'@n8n/n8n-nodes-langchain.toolVectorStore',
|
||||
'@n8n/n8n-nodes-langchain.documentGithubLoader',
|
||||
'@n8n/n8n-nodes-langchain.code',
|
||||
]);
|
||||
|
||||
// Parse disabled nodes from environment variable (comma-separated)
|
||||
function getDisabledNodes(): Set<string> {
|
||||
const disabledNodesEnv = process.env.N8N_EVALS_DISABLED_NODES ?? '';
|
||||
return new Set(
|
||||
disabledNodesEnv
|
||||
.split(',')
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter node types similar to production service:
|
||||
* - Remove ignored types (hardcoded)
|
||||
* - Remove disabled types (from env var)
|
||||
* - Remove hidden nodes (except DataTable)
|
||||
* - Merge tool nodes with their non-tool counterparts
|
||||
*/
|
||||
function filterNodeTypes(
|
||||
nodeTypes: INodeTypeDescription[],
|
||||
disabledNodes: Set<string>,
|
||||
): INodeTypeDescription[] {
|
||||
const visibleNodeTypes = nodeTypes.filter(
|
||||
(nodeType) =>
|
||||
!IGNORED_TYPES.has(nodeType.name) &&
|
||||
!disabledNodes.has(nodeType.name) &&
|
||||
// Filter out hidden nodes, except for the Data Table node which has custom hiding logic
|
||||
(nodeType.hidden !== true || nodeType.name === 'n8n-nodes-base.dataTable'),
|
||||
);
|
||||
|
||||
return visibleNodeTypes.map((nodeType) => {
|
||||
// If the node type is a tool, merge it with the corresponding non-tool node type
|
||||
const isTool = nodeType.name.endsWith('Tool');
|
||||
if (!isTool) return nodeType;
|
||||
|
||||
const nonToolNode = nodeTypes.find((nt) => nt.name === nodeType.name.replace('Tool', ''));
|
||||
if (!nonToolNode) return nodeType;
|
||||
|
||||
return { ...nonToolNode, ...nodeType };
|
||||
});
|
||||
}
|
||||
|
||||
export function loadNodesFromFile(): INodeTypeDescription[] {
|
||||
const preferredPath = join(__dirname, '..', '.data', 'nodes.json');
|
||||
const legacyPath = join(__dirname, '..', 'nodes.json');
|
||||
const nodesPath = existsSync(preferredPath) ? preferredPath : legacyPath;
|
||||
|
||||
if (!existsSync(nodesPath)) {
|
||||
throw new Error(
|
||||
`nodes.json not found at ${nodesPath}. ` +
|
||||
'Run n8n and export node definitions to evaluations/.data/nodes.json',
|
||||
);
|
||||
}
|
||||
|
||||
const nodesData = readFileSync(nodesPath, 'utf-8');
|
||||
const allNodes = jsonParse<NodeWithVersion[]>(nodesData);
|
||||
|
||||
// Keep all version entries instead of selecting only the latest version.
|
||||
// Workflows may use older node versions (e.g., removeDuplicates v1.1), and
|
||||
// discarding those entries causes "Node type not found" validation errors.
|
||||
const disabledNodes = getDisabledNodes();
|
||||
return filterNodeTypes(allNodes, disabledNodes);
|
||||
}
|
||||
Reference in New Issue
Block a user