feat(editor): Add HTTP request nodes for credentials without a node (#7157)

Github issue / Community forum post (link here to close automatically):

---------

Co-authored-by: Giulio Andreini <g.andreini@gmail.com>
Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in>
This commit is contained in:
Elias Meire
2023-11-13 12:11:16 +01:00
committed by GitHub
parent 460ac85fda
commit 14035e1244
62 changed files with 665 additions and 146 deletions

View File

@@ -2,7 +2,8 @@
const path = require('path');
const glob = require('fast-glob');
const { LoggerProxy } = require('n8n-workflow');
const uniq = require('lodash/uniq');
const { LoggerProxy, getCredentialsForNode } = require('n8n-workflow');
const { packageDir, writeJSON } = require('./common');
const { loadClassInIsolation } = require('../dist/ClassLoader');
@@ -19,48 +20,80 @@ const loadClass = (sourcePath) => {
}
};
const nodesToTestWith = {};
const generate = async (kind) => {
const data = glob
.sync(`dist/${kind}/**/*.${kind === 'nodes' ? 'node' : kind}.js`, {
cwd: packageDir,
})
const generateKnownNodes = async () => {
const nodeClasses = glob
.sync('dist/nodes/**/*.node.js', { cwd: packageDir })
.map(loadClass)
.filter((data) => !!data)
.reduce((obj, { className, sourcePath, instance }) => {
const name = kind === 'nodes' ? instance.description.name : instance.name;
if (!/[vV]\d.node\.js$/.test(sourcePath)) {
if (name in obj) console.error('already loaded', kind, name, sourcePath);
else obj[name] = { className, sourcePath };
// 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] = [];
}
if (kind === 'credentials' && Array.isArray(instance.extends)) {
obj[name].extends = instance.extends;
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 (kind === 'nodes') {
const { credentials } = instance.description;
if (credentials && credentials.length) {
for (const credential of credentials) {
nodesToTestWith[credential.name] = nodesToTestWith[credential.name] || [];
nodesToTestWith[credential.name].push(name);
}
}
} else {
if (name in nodesToTestWith) {
obj[name].nodesToTestWith = nodesToTestWith[name];
}
if (nodesByCredential[credentialName]) {
credential.supportedNodes = Array.from(new Set(nodesByCredential[credentialName]));
}
return obj;
}, {});
LoggerProxy.info(`Detected ${Object.keys(data).length} ${kind}`);
await writeJSON(`known/${kind}.json`, data);
return data;
credentials[credentialName] = credential;
return credentials;
},
{},
);
LoggerProxy.info(`Detected ${Object.keys(credentials).length} credentials`);
await writeJSON('known/credentials.json', credentials);
return credentials;
};
(async () => {
await generate('nodes');
await generate('credentials');
const { nodesByCredential } = await generateKnownNodes();
await generateKnownCredentials(nodesByCredential);
})();

View File

@@ -45,7 +45,14 @@ function addWebhookLifecycle(nodeType) {
const loader = new PackageDirectoryLoader(packageDir);
await loader.loadAll();
const credentialTypes = Object.values(loader.credentialTypes).map((data) => data.type);
const knownCredentials = loader.known.credentials;
const credentialTypes = Object.values(loader.credentialTypes).map((data) => {
const credentialType = data.type;
if (knownCredentials[credentialType.name].supportedNodes?.length > 0) {
delete credentialType.httpRequestNode;
}
return credentialType;
});
const loaderNodeTypes = Object.values(loader.nodeTypes);
@@ -75,13 +82,12 @@ function addWebhookLifecycle(nodeType) {
addWebhookLifecycle(nodeType);
return data.type;
})
.flatMap((nodeData) => {
return NodeHelpers.getVersionedNodeTypeAll(nodeData).map((item) => {
.flatMap((nodeType) =>
NodeHelpers.getVersionedNodeTypeAll(nodeType).map((item) => {
const { __loadOptionsMethods, ...rest } = item.description;
return rest;
});
});
}),
);
const referencedMethods = findReferencedMethods(nodeTypes);