#!/usr/bin/env node const path = require('path'); const glob = require('fast-glob'); const uniq = require('lodash/uniq'); const { LoggerProxy, getCredentialsForNode } = require('n8n-workflow'); const { packageDir, writeJSON } = require('./common'); const { loadClassInIsolation } = require('../dist/ClassLoader'); LoggerProxy.init(console); const loadClass = (sourcePath) => { try { const [className] = path.parse(sourcePath).name.split('.'); const filePath = path.resolve(packageDir, sourcePath); const instance = loadClassInIsolation(filePath, className); return { instance, sourcePath, className }; } catch (e) { LoggerProxy.warn(`Failed to load ${sourcePath}: ${e.message}`); } }; const generateKnownNodes = async () => { const nodeClasses = glob .sync('dist/nodes/**/*.node.js', { cwd: packageDir }) .map(loadClass) // Ignore node versions .filter((nodeClass) => nodeClass && !/[vV]\d.node\.js$/.test(nodeClass.sourcePath)); const nodes = {}; const nodesByCredential = {}; for (const { className, sourcePath, instance } of nodeClasses) { const nodeName = instance.description.name; nodes[nodeName] = { className, sourcePath }; for (const credential of getCredentialsForNode(instance)) { if (!nodesByCredential[credential.name]) { nodesByCredential[credential.name] = []; } nodesByCredential[credential.name].push(nodeName); } } LoggerProxy.info(`Detected ${Object.keys(nodes).length} nodes`); await writeJSON('known/nodes.json', nodes); return { nodes, nodesByCredential }; }; const generateKnownCredentials = async (nodesByCredential) => { const credentialClasses = glob .sync(`dist/credentials/**/*.credentials.js`, { cwd: packageDir }) .map(loadClass) .filter((data) => !!data); for (const { instance } of credentialClasses) { if (Array.isArray(instance.extends)) { for (const extendedCredential of instance.extends) { nodesByCredential[extendedCredential] = [ ...(nodesByCredential[extendedCredential] ?? []), ...(nodesByCredential[instance.name] ?? []), ]; } } } const credentials = credentialClasses.reduce( (credentials, { className, sourcePath, instance }) => { const credentialName = instance.name; const credential = { className, sourcePath, }; if (Array.isArray(instance.extends)) { credential.extends = instance.extends; } if (nodesByCredential[credentialName]) { credential.supportedNodes = Array.from(new Set(nodesByCredential[credentialName])); } credentials[credentialName] = credential; return credentials; }, {}, ); LoggerProxy.info(`Detected ${Object.keys(credentials).length} credentials`); await writeJSON('known/credentials.json', credentials); return credentials; }; (async () => { const { nodesByCredential } = await generateKnownNodes(); await generateKnownCredentials(nodesByCredential); })();