n8n-nodes-xcredentialsx
Version:
Enhanced n8n nodes for credentials management and improved node execution with dropdown selection
239 lines (238 loc) • 11.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.XCredentialsXSimple = void 0;
const n8n_workflow_1 = require("n8n-workflow");
class XCredentialsXSimple {
constructor() {
this.description = {
displayName: 'X Credentials X (Simple)',
name: 'xCredentialsXSimple',
icon: 'fa:key',
group: ['utility'],
version: 1,
subtitle: '={{$parameter["operation"]}}',
description: 'List all Credentials IDs used in n8n workflows (No Auth Required)',
defaults: {
name: 'X Credentials X (Simple)',
},
inputs: ["main" /* NodeConnectionType.Main */],
outputs: ["main" /* NodeConnectionType.Main */],
properties: [
{
displayName: 'n8n Base URL',
name: 'baseUrl',
type: 'string',
default: 'http://localhost:5678',
required: true,
description: 'Base URL of your n8n instance',
},
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
options: [
{
name: 'List All Workflow Credentials',
value: 'listWorkflowCredentials',
description: 'Get all Credentials IDs used in workflows',
action: 'List all workflow credentials',
},
{
name: 'List Credentials by Workflow',
value: 'listByWorkflow',
description: 'Get Credentials IDs grouped by workflow',
action: 'List credentials by workflow',
},
{
name: 'Get Unique Credentials',
value: 'getUniqueCredentials',
description: 'Get unique Credentials IDs across all workflows',
action: 'Get unique credentials',
},
],
default: 'listWorkflowCredentials',
},
{
displayName: 'Include Workflow Details',
name: 'includeWorkflowDetails',
type: 'boolean',
displayOptions: {
show: {
operation: ['listWorkflowCredentials', 'listByWorkflow'],
},
},
default: true,
description: 'Whether to include workflow name and ID in the output',
},
{
displayName: 'Include Node Details',
name: 'includeNodeDetails',
type: 'boolean',
displayOptions: {
show: {
operation: ['listWorkflowCredentials', 'listByWorkflow'],
},
},
default: false,
description: 'Whether to include node name and type that uses the credential',
},
{
displayName: 'Skip SSL Verification',
name: 'skipSslVerification',
type: 'boolean',
default: true,
description: 'Skip SSL certificate verification (useful for local development)',
},
],
};
}
async execute() {
const items = this.getInputData();
const returnData = [];
for (let i = 0; i < items.length; i++) {
try {
const baseUrl = this.getNodeParameter('baseUrl', i);
const operation = this.getNodeParameter('operation', i);
const includeWorkflowDetails = this.getNodeParameter('includeWorkflowDetails', i, true);
const includeNodeDetails = this.getNodeParameter('includeNodeDetails', i, false);
const skipSslVerification = this.getNodeParameter('skipSslVerification', i, true);
// 直接访问本地 n8n API,无需认证
const workflows = await this.helpers.httpRequest({
method: 'GET',
url: `${baseUrl}/rest/workflows`,
headers: {
'accept': 'application/json',
'content-type': 'application/json',
},
skipSslCertificateValidation: skipSslVerification,
ignoreHttpStatusErrors: false,
});
const credentialsData = [];
const uniqueCredentials = new Set();
// 处理工作流数据
const workflowList = workflows.data || workflows;
if (!Array.isArray(workflowList)) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid response format from n8n API');
}
// 遍历每个工作流
for (const workflow of workflowList) {
if (workflow.nodes && Array.isArray(workflow.nodes)) {
// 遍历工作流中的每个节点
for (const node of workflow.nodes) {
if (node.credentials && typeof node.credentials === 'object') {
// 遍历节点使用的所有凭据类型
for (const [credentialType, credentialConfig] of Object.entries(node.credentials)) {
const credentialId = credentialConfig === null || credentialConfig === void 0 ? void 0 : credentialConfig.id;
if (credentialId && typeof credentialId === 'string') {
const credentialInfo = {
credentialId,
credentialType,
};
if (includeWorkflowDetails) {
credentialInfo.workflowId = workflow.id;
credentialInfo.workflowName = workflow.name;
credentialInfo.workflowActive = workflow.active;
}
if (includeNodeDetails) {
credentialInfo.nodeName = node.name;
credentialInfo.nodeType = node.type;
}
if (operation === 'listWorkflowCredentials') {
credentialsData.push(credentialInfo);
}
else if (operation === 'listByWorkflow') {
credentialInfo.workflowId = workflow.id;
credentialInfo.workflowName = workflow.name;
credentialsData.push(credentialInfo);
}
uniqueCredentials.add(credentialId);
}
}
}
}
}
}
// 根据操作类型返回数据
if (operation === 'getUniqueCredentials') {
// 返回唯一凭据列表
const uniqueList = Array.from(uniqueCredentials).map(credentialId => ({
credentialId,
totalUsage: credentialsData.filter(c => c.credentialId === credentialId).length,
}));
for (const cred of uniqueList) {
returnData.push({
json: cred,
pairedItem: { item: i },
});
}
}
else if (operation === 'listByWorkflow') {
// 按工作流分组凭据
const workflowGroups = {};
for (const cred of credentialsData) {
const workflowKey = cred.workflowId;
if (!workflowGroups[workflowKey]) {
workflowGroups[workflowKey] = {
workflowId: cred.workflowId,
workflowName: cred.workflowName,
workflowActive: cred.workflowActive,
credentials: [],
};
}
workflowGroups[workflowKey].credentials.push({
credentialId: cred.credentialId,
credentialType: cred.credentialType,
...(includeNodeDetails && {
nodeName: cred.nodeName,
nodeType: cred.nodeType,
}),
});
}
for (const group of Object.values(workflowGroups)) {
returnData.push({
json: group,
pairedItem: { item: i },
});
}
}
else {
// 返回所有凭据数据
for (const cred of credentialsData) {
returnData.push({
json: cred,
pairedItem: { item: i },
});
}
}
// 如果没有找到任何凭据,返回提示信息
if (returnData.length === 0) {
returnData.push({
json: {
message: 'No credentials found in any workflows',
totalWorkflows: workflowList.length,
operation,
},
pairedItem: { item: i },
});
}
}
catch (error) {
if (this.continueOnFail()) {
returnData.push({
json: {
error: error instanceof Error ? error.message : 'Unknown error',
operation: this.getNodeParameter('operation', i),
item: i,
},
pairedItem: { item: i },
});
continue;
}
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to fetch credentials data: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
return [returnData];
}
}
exports.XCredentialsXSimple = XCredentialsXSimple;