chore: add pre-built dist folder for npx usage

This commit is contained in:
thesved
2025-12-04 20:22:02 +02:00
committed by Romuald Członkowski
parent a70d96a373
commit 5057481e70
716 changed files with 48021 additions and 0 deletions

13
dist/utils/auth.d.ts vendored Normal file
View File

@@ -0,0 +1,13 @@
export declare class AuthManager {
private validTokens;
private tokenExpiry;
constructor();
validateToken(token: string | undefined, expectedToken?: string): boolean;
generateToken(expiryHours?: number): string;
revokeToken(token: string): void;
private cleanupExpiredTokens;
static hashToken(token: string): string;
static compareTokens(plainToken: string, hashedToken: string): boolean;
static timingSafeCompare(plainToken: string, expectedToken: string): boolean;
}
//# sourceMappingURL=auth.d.ts.map

1
dist/utils/auth.d.ts.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"AAEA,qBAAa,WAAW;IACtB,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,WAAW,CAAsB;;IAUzC,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO;IAmCzE,aAAa,CAAC,WAAW,GAAE,MAAW,GAAG,MAAM;IAgB/C,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAQhC,OAAO,CAAC,oBAAoB;IAa5B,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAOvC,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO;IA2BtE,MAAM,CAAC,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO;CAuB7E"}

82
dist/utils/auth.js vendored Normal file
View File

@@ -0,0 +1,82 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuthManager = void 0;
const crypto_1 = __importDefault(require("crypto"));
class AuthManager {
constructor() {
this.validTokens = new Set();
this.tokenExpiry = new Map();
}
validateToken(token, expectedToken) {
if (!expectedToken) {
return true;
}
if (!token) {
return false;
}
if (AuthManager.timingSafeCompare(token, expectedToken)) {
return true;
}
if (this.validTokens.has(token)) {
const expiry = this.tokenExpiry.get(token);
if (expiry && expiry > Date.now()) {
return true;
}
else {
this.validTokens.delete(token);
this.tokenExpiry.delete(token);
return false;
}
}
return false;
}
generateToken(expiryHours = 24) {
const token = crypto_1.default.randomBytes(32).toString('hex');
const expiryTime = Date.now() + (expiryHours * 60 * 60 * 1000);
this.validTokens.add(token);
this.tokenExpiry.set(token, expiryTime);
this.cleanupExpiredTokens();
return token;
}
revokeToken(token) {
this.validTokens.delete(token);
this.tokenExpiry.delete(token);
}
cleanupExpiredTokens() {
const now = Date.now();
for (const [token, expiry] of this.tokenExpiry.entries()) {
if (expiry <= now) {
this.validTokens.delete(token);
this.tokenExpiry.delete(token);
}
}
}
static hashToken(token) {
return crypto_1.default.createHash('sha256').update(token).digest('hex');
}
static compareTokens(plainToken, hashedToken) {
const hashedPlainToken = AuthManager.hashToken(plainToken);
return crypto_1.default.timingSafeEqual(Buffer.from(hashedPlainToken), Buffer.from(hashedToken));
}
static timingSafeCompare(plainToken, expectedToken) {
try {
if (!plainToken || !expectedToken) {
return false;
}
const plainBuffer = Buffer.from(plainToken, 'utf8');
const expectedBuffer = Buffer.from(expectedToken, 'utf8');
if (plainBuffer.length !== expectedBuffer.length) {
return false;
}
return crypto_1.default.timingSafeEqual(plainBuffer, expectedBuffer);
}
catch (error) {
return false;
}
}
}
exports.AuthManager = AuthManager;
//# sourceMappingURL=auth.js.map

1
dist/utils/auth.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"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"}

12
dist/utils/bridge.d.ts vendored Normal file
View File

@@ -0,0 +1,12 @@
import { INodeExecutionData, IDataObject } from 'n8n-workflow';
export declare class N8NMCPBridge {
static n8nToMCPToolArgs(data: IDataObject): any;
static mcpToN8NExecutionData(mcpResponse: any, itemIndex?: number): INodeExecutionData;
static n8nWorkflowToMCP(workflow: any): any;
static mcpToN8NWorkflow(mcpWorkflow: any): any;
static n8nExecutionToMCPResource(execution: any): any;
static mcpPromptArgsToN8N(promptArgs: any): IDataObject;
static sanitizeData(data: any): any;
static formatError(error: any): any;
}
//# sourceMappingURL=bridge.d.ts.map

1
dist/utils/bridge.d.ts.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/utils/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE/D,qBAAa,YAAY;IAIvB,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,GAAG;IAc/C,MAAM,CAAC,qBAAqB,CAAC,WAAW,EAAE,GAAG,EAAE,SAAS,GAAE,MAAU,GAAG,kBAAkB;IAkCzF,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG;IAyB3C,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,GAAG,GAAG,GAAG;IAgB9C,MAAM,CAAC,yBAAyB,CAAC,SAAS,EAAE,GAAG,GAAG,GAAG;IAsBrD,MAAM,CAAC,kBAAkB,CAAC,UAAU,EAAE,GAAG,GAAG,WAAW;IAWvD,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,GAAG,GAAG,GAAG;IAyBnC,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,GAAG,GAAG;CAYpC"}

127
dist/utils/bridge.js vendored Normal file
View File

@@ -0,0 +1,127 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.N8NMCPBridge = void 0;
class N8NMCPBridge {
static n8nToMCPToolArgs(data) {
if (data.json) {
return data.json;
}
const { pairedItem, ...cleanData } = data;
return cleanData;
}
static mcpToN8NExecutionData(mcpResponse, itemIndex = 0) {
if (mcpResponse.content && Array.isArray(mcpResponse.content)) {
const textContent = mcpResponse.content
.filter((c) => c.type === 'text')
.map((c) => c.text)
.join('\n');
try {
const parsed = JSON.parse(textContent);
return {
json: parsed,
pairedItem: itemIndex,
};
}
catch {
return {
json: { result: textContent },
pairedItem: itemIndex,
};
}
}
return {
json: mcpResponse,
pairedItem: itemIndex,
};
}
static n8nWorkflowToMCP(workflow) {
return {
id: workflow.id,
name: workflow.name,
description: workflow.description || '',
nodes: workflow.nodes?.map((node) => ({
id: node.id,
type: node.type,
name: node.name,
parameters: node.parameters,
position: node.position,
})),
connections: workflow.connections,
settings: workflow.settings,
metadata: {
createdAt: workflow.createdAt,
updatedAt: workflow.updatedAt,
active: workflow.active,
},
};
}
static mcpToN8NWorkflow(mcpWorkflow) {
return {
name: mcpWorkflow.name,
nodes: mcpWorkflow.nodes || [],
connections: mcpWorkflow.connections || {},
settings: mcpWorkflow.settings || {
executionOrder: 'v1',
},
staticData: null,
pinData: {},
};
}
static n8nExecutionToMCPResource(execution) {
return {
uri: `execution://${execution.id}`,
name: `Execution ${execution.id}`,
description: `Workflow: ${execution.workflowData?.name || 'Unknown'}`,
mimeType: 'application/json',
data: {
id: execution.id,
workflowId: execution.workflowId,
status: execution.finished ? 'completed' : execution.stoppedAt ? 'stopped' : 'running',
mode: execution.mode,
startedAt: execution.startedAt,
stoppedAt: execution.stoppedAt,
error: execution.data?.resultData?.error,
executionData: execution.data,
},
};
}
static mcpPromptArgsToN8N(promptArgs) {
return {
prompt: promptArgs.name || '',
arguments: promptArgs.arguments || {},
messages: promptArgs.messages || [],
};
}
static sanitizeData(data) {
if (data === null || data === undefined) {
return {};
}
if (typeof data !== 'object') {
return { value: data };
}
const seen = new WeakSet();
return JSON.parse(JSON.stringify(data, (_key, value) => {
if (typeof value === 'object' && value !== null) {
if (seen.has(value)) {
return '[Circular]';
}
seen.add(value);
}
return value;
}));
}
static formatError(error) {
return {
message: error.message || 'Unknown error',
type: error.name || 'Error',
stack: error.stack,
details: {
code: error.code,
statusCode: error.statusCode,
data: error.data,
},
};
}
}
exports.N8NMCPBridge = N8NMCPBridge;
//# sourceMappingURL=bridge.js.map

1
dist/utils/bridge.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../src/utils/bridge.ts"],"names":[],"mappings":"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"}

58
dist/utils/cache-utils.d.ts vendored Normal file
View File

@@ -0,0 +1,58 @@
import { LRUCache } from 'lru-cache';
export interface CacheMetrics {
hits: number;
misses: number;
evictions: number;
sets: number;
deletes: number;
clears: number;
size: number;
maxSize: number;
avgHitRate: number;
createdAt: Date;
lastResetAt: Date;
}
export interface CacheConfig {
max: number;
ttlMinutes: number;
}
declare class CacheMetricsTracker {
private metrics;
private startTime;
constructor();
reset(): void;
recordHit(): void;
recordMiss(): void;
recordEviction(): void;
recordSet(): void;
recordDelete(): void;
recordClear(): void;
updateSize(current: number, max: number): void;
private updateHitRate;
getMetrics(): CacheMetrics;
getFormattedMetrics(): string;
}
export declare const cacheMetrics: CacheMetricsTracker;
export declare function getCacheConfig(): CacheConfig;
export declare function createCacheKey(input: string): string;
export declare function createInstanceCache<T extends {}>(onDispose?: (value: T, key: string) => void): LRUCache<string, T>;
export declare class CacheMutex {
private locks;
private lockTimeouts;
private readonly timeout;
acquire(key: string): Promise<() => void>;
isLocked(key: string): boolean;
clearAll(): void;
}
export interface RetryConfig {
maxAttempts: number;
baseDelayMs: number;
maxDelayMs: number;
jitterFactor: number;
}
export declare const DEFAULT_RETRY_CONFIG: RetryConfig;
export declare function calculateBackoffDelay(attempt: number, config?: RetryConfig): number;
export declare function withRetry<T>(fn: () => Promise<T>, config?: RetryConfig, context?: string): Promise<T>;
export declare function getCacheStatistics(): string;
export {};
//# sourceMappingURL=cache-utils.d.ts.map

1
dist/utils/cache-utils.d.ts.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"cache-utils.d.ts","sourceRoot":"","sources":["../../src/utils/cache-utils.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAMrC,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,IAAI,CAAC;IAChB,WAAW,EAAE,IAAI,CAAC;CACnB;AAKD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB;AAYD,cAAM,mBAAmB;IACvB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,SAAS,CAAO;;IAUxB,KAAK,IAAI,IAAI;IAmBb,SAAS,IAAI,IAAI;IAQjB,UAAU,IAAI,IAAI;IAQlB,cAAc,IAAI,IAAI;IAOtB,SAAS,IAAI,IAAI;IAOjB,YAAY,IAAI,IAAI;IAOpB,WAAW,IAAI,IAAI;IAOnB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAQ9C,OAAO,CAAC,aAAa;IAUrB,UAAU,IAAI,YAAY;IAO1B,mBAAmB,IAAI,MAAM;CAI9B;AAGD,eAAO,MAAM,YAAY,qBAA4B,CAAC;AAMtD,wBAAgB,cAAc,IAAI,WAAW,CAqB5C;AAOD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAoBpD;AAOD,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,EAAE,EAC9C,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,GAC1C,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAkBrB;AAMD,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAAyC;IACtD,OAAO,CAAC,YAAY,CAA0C;IAC9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IAOlC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC;IAuC/C,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAO9B,QAAQ,IAAI,IAAI;CAKjB;AAKD,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAKD,eAAO,MAAM,oBAAoB,EAAE,WAKlC,CAAC;AAQF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,WAAkC,GAAG,MAAM,CAUzG;AASD,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,MAAM,GAAE,WAAkC,EAC1C,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,CAAC,CAAC,CAmCZ;AAqCD,wBAAgB,kBAAkB,IAAI,MAAM,CAc3C"}

243
dist/utils/cache-utils.js vendored Normal file
View File

@@ -0,0 +1,243 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DEFAULT_RETRY_CONFIG = exports.CacheMutex = exports.cacheMetrics = void 0;
exports.getCacheConfig = getCacheConfig;
exports.createCacheKey = createCacheKey;
exports.createInstanceCache = createInstanceCache;
exports.calculateBackoffDelay = calculateBackoffDelay;
exports.withRetry = withRetry;
exports.getCacheStatistics = getCacheStatistics;
const crypto_1 = require("crypto");
const lru_cache_1 = require("lru-cache");
const logger_1 = require("./logger");
const hashMemoCache = new Map();
const MAX_MEMO_SIZE = 1000;
class CacheMetricsTracker {
constructor() {
this.startTime = new Date();
this.reset();
}
reset() {
this.metrics = {
hits: 0,
misses: 0,
evictions: 0,
sets: 0,
deletes: 0,
clears: 0,
size: 0,
maxSize: 0,
avgHitRate: 0,
createdAt: this.startTime,
lastResetAt: new Date()
};
}
recordHit() {
this.metrics.hits++;
this.updateHitRate();
}
recordMiss() {
this.metrics.misses++;
this.updateHitRate();
}
recordEviction() {
this.metrics.evictions++;
}
recordSet() {
this.metrics.sets++;
}
recordDelete() {
this.metrics.deletes++;
}
recordClear() {
this.metrics.clears++;
}
updateSize(current, max) {
this.metrics.size = current;
this.metrics.maxSize = max;
}
updateHitRate() {
const total = this.metrics.hits + this.metrics.misses;
if (total > 0) {
this.metrics.avgHitRate = this.metrics.hits / total;
}
}
getMetrics() {
return { ...this.metrics };
}
getFormattedMetrics() {
const { hits, misses, evictions, avgHitRate, size, maxSize } = this.metrics;
return `Cache Metrics: Hits=${hits}, Misses=${misses}, HitRate=${(avgHitRate * 100).toFixed(2)}%, Size=${size}/${maxSize}, Evictions=${evictions}`;
}
}
exports.cacheMetrics = new CacheMetricsTracker();
function getCacheConfig() {
const max = parseInt(process.env.INSTANCE_CACHE_MAX || '100', 10);
const ttlMinutes = parseInt(process.env.INSTANCE_CACHE_TTL_MINUTES || '30', 10);
const validatedMax = Math.max(1, Math.min(10000, max)) || 100;
const validatedTtl = Math.max(1, Math.min(1440, ttlMinutes)) || 30;
if (validatedMax !== max || validatedTtl !== ttlMinutes) {
logger_1.logger.warn('Cache configuration adjusted to valid bounds', {
requestedMax: max,
requestedTtl: ttlMinutes,
actualMax: validatedMax,
actualTtl: validatedTtl
});
}
return {
max: validatedMax,
ttlMinutes: validatedTtl
};
}
function createCacheKey(input) {
if (hashMemoCache.has(input)) {
return hashMemoCache.get(input);
}
const hash = (0, crypto_1.createHash)('sha256').update(input).digest('hex');
if (hashMemoCache.size >= MAX_MEMO_SIZE) {
const firstKey = hashMemoCache.keys().next().value;
if (firstKey) {
hashMemoCache.delete(firstKey);
}
}
hashMemoCache.set(input, hash);
return hash;
}
function createInstanceCache(onDispose) {
const config = getCacheConfig();
return new lru_cache_1.LRUCache({
max: config.max,
ttl: config.ttlMinutes * 60 * 1000,
updateAgeOnGet: true,
dispose: (value, key) => {
exports.cacheMetrics.recordEviction();
if (onDispose) {
onDispose(value, key);
}
logger_1.logger.debug('Cache eviction', {
cacheKey: key.substring(0, 8) + '...',
metrics: exports.cacheMetrics.getFormattedMetrics()
});
}
});
}
class CacheMutex {
constructor() {
this.locks = new Map();
this.lockTimeouts = new Map();
this.timeout = 5000;
}
async acquire(key) {
while (this.locks.has(key)) {
try {
await this.locks.get(key);
}
catch {
}
}
let releaseLock;
const lockPromise = new Promise((resolve) => {
releaseLock = () => {
resolve();
this.locks.delete(key);
const timeout = this.lockTimeouts.get(key);
if (timeout) {
clearTimeout(timeout);
this.lockTimeouts.delete(key);
}
};
});
this.locks.set(key, lockPromise);
const timeout = setTimeout(() => {
logger_1.logger.warn('Cache lock timeout, forcefully releasing', { key: key.substring(0, 8) + '...' });
releaseLock();
}, this.timeout);
this.lockTimeouts.set(key, timeout);
return releaseLock;
}
isLocked(key) {
return this.locks.has(key);
}
clearAll() {
this.lockTimeouts.forEach(timeout => clearTimeout(timeout));
this.locks.clear();
this.lockTimeouts.clear();
}
}
exports.CacheMutex = CacheMutex;
exports.DEFAULT_RETRY_CONFIG = {
maxAttempts: 3,
baseDelayMs: 1000,
maxDelayMs: 10000,
jitterFactor: 0.3
};
function calculateBackoffDelay(attempt, config = exports.DEFAULT_RETRY_CONFIG) {
const exponentialDelay = Math.min(config.baseDelayMs * Math.pow(2, attempt), config.maxDelayMs);
const jitter = exponentialDelay * config.jitterFactor * Math.random();
return Math.floor(exponentialDelay + jitter);
}
async function withRetry(fn, config = exports.DEFAULT_RETRY_CONFIG, context) {
let lastError;
for (let attempt = 0; attempt < config.maxAttempts; attempt++) {
try {
return await fn();
}
catch (error) {
lastError = error;
if (!isRetryableError(error)) {
throw error;
}
if (attempt < config.maxAttempts - 1) {
const delay = calculateBackoffDelay(attempt, config);
logger_1.logger.debug('Retrying operation after delay', {
context,
attempt: attempt + 1,
maxAttempts: config.maxAttempts,
delayMs: delay,
error: lastError.message
});
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
logger_1.logger.error('All retry attempts exhausted', {
context,
attempts: config.maxAttempts,
lastError: lastError.message
});
throw lastError;
}
function isRetryableError(error) {
if (error.code === 'ECONNREFUSED' ||
error.code === 'ECONNRESET' ||
error.code === 'ETIMEDOUT' ||
error.code === 'ENOTFOUND') {
return true;
}
if (error.response?.status) {
const status = error.response.status;
return status === 429 ||
status === 503 ||
status === 504 ||
(status >= 500 && status < 600);
}
if (error.message && error.message.toLowerCase().includes('timeout')) {
return true;
}
return false;
}
function getCacheStatistics() {
const metrics = exports.cacheMetrics.getMetrics();
const runtime = Date.now() - metrics.createdAt.getTime();
const runtimeMinutes = Math.floor(runtime / 60000);
return `
Cache Statistics:
Runtime: ${runtimeMinutes} minutes
Total Operations: ${metrics.hits + metrics.misses}
Hit Rate: ${(metrics.avgHitRate * 100).toFixed(2)}%
Current Size: ${metrics.size}/${metrics.maxSize}
Total Evictions: ${metrics.evictions}
Sets: ${metrics.sets}, Deletes: ${metrics.deletes}, Clears: ${metrics.clears}
`.trim();
}
//# sourceMappingURL=cache-utils.js.map

1
dist/utils/cache-utils.js.map vendored Normal file

File diff suppressed because one or more lines are too long

10
dist/utils/console-manager.d.ts vendored Normal file
View File

@@ -0,0 +1,10 @@
export declare class ConsoleManager {
private originalConsole;
private isSilenced;
silence(): void;
restore(): void;
wrapOperation<T>(operation: () => T | Promise<T>): Promise<T>;
get isActive(): boolean;
}
export declare const consoleManager: ConsoleManager;
//# sourceMappingURL=console-manager.d.ts.map

1
dist/utils/console-manager.d.ts.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"console-manager.d.ts","sourceRoot":"","sources":["../../src/utils/console-manager.ts"],"names":[],"mappings":"AAMA,qBAAa,cAAc;IACzB,OAAO,CAAC,eAAe,CAOrB;IAEF,OAAO,CAAC,UAAU,CAAS;IAKpB,OAAO,IAAI,IAAI;IAkBf,OAAO,IAAI,IAAI;IAmBT,aAAa,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAkB1E,IAAW,QAAQ,IAAI,OAAO,CAE7B;CACF;AAGD,eAAO,MAAM,cAAc,gBAAuB,CAAC"}

63
dist/utils/console-manager.js vendored Normal file
View File

@@ -0,0 +1,63 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.consoleManager = exports.ConsoleManager = void 0;
class ConsoleManager {
constructor() {
this.originalConsole = {
log: console.log,
error: console.error,
warn: console.warn,
info: console.info,
debug: console.debug,
trace: console.trace
};
this.isSilenced = false;
}
silence() {
if (this.isSilenced || process.env.MCP_MODE !== 'http') {
return;
}
this.isSilenced = true;
process.env.MCP_REQUEST_ACTIVE = 'true';
console.log = () => { };
console.error = () => { };
console.warn = () => { };
console.info = () => { };
console.debug = () => { };
console.trace = () => { };
}
restore() {
if (!this.isSilenced) {
return;
}
this.isSilenced = false;
process.env.MCP_REQUEST_ACTIVE = 'false';
console.log = this.originalConsole.log;
console.error = this.originalConsole.error;
console.warn = this.originalConsole.warn;
console.info = this.originalConsole.info;
console.debug = this.originalConsole.debug;
console.trace = this.originalConsole.trace;
}
async wrapOperation(operation) {
this.silence();
try {
const result = operation();
if (result instanceof Promise) {
return await result.finally(() => this.restore());
}
this.restore();
return result;
}
catch (error) {
this.restore();
throw error;
}
}
get isActive() {
return this.isSilenced;
}
}
exports.ConsoleManager = ConsoleManager;
exports.consoleManager = new ConsoleManager();
//# sourceMappingURL=console-manager.js.map

1
dist/utils/console-manager.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"console-manager.js","sourceRoot":"","sources":["../../src/utils/console-manager.ts"],"names":[],"mappings":";;;AAMA,MAAa,cAAc;IAA3B;QACU,oBAAe,GAAG;YACxB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,KAAK,EAAE,OAAO,CAAC,KAAK;SACrB,CAAC;QAEM,eAAU,GAAG,KAAK,CAAC;IA+D7B,CAAC;IA1DQ,OAAO;QACZ,IAAI,IAAI,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;YACvD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,MAAM,CAAC;QACxC,OAAO,CAAC,GAAG,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;QACvB,OAAO,CAAC,KAAK,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;QACzB,OAAO,CAAC,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;QACxB,OAAO,CAAC,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;QACxB,OAAO,CAAC,KAAK,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;QACzB,OAAO,CAAC,KAAK,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;IAC3B,CAAC;IAKM,OAAO;QACZ,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,OAAO,CAAC;QACzC,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC;QACvC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;QAC3C,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;QACzC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;QACzC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;QAC3C,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;IAC7C,CAAC;IAMM,KAAK,CAAC,aAAa,CAAI,SAA+B;QAC3D,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;gBAC9B,OAAO,MAAM,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;YACpD,CAAC;YACD,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAKD,IAAW,QAAQ;QACjB,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;CACF;AAzED,wCAyEC;AAGY,QAAA,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC"}

2
dist/utils/documentation-fetcher.d.ts vendored Normal file
View File

@@ -0,0 +1,2 @@
export * from './enhanced-documentation-fetcher';
//# sourceMappingURL=documentation-fetcher.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"documentation-fetcher.d.ts","sourceRoot":"","sources":["../../src/utils/documentation-fetcher.ts"],"names":[],"mappings":"AACA,cAAc,kCAAkC,CAAC"}

18
dist/utils/documentation-fetcher.js vendored Normal file
View File

@@ -0,0 +1,18 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./enhanced-documentation-fetcher"), exports);
//# sourceMappingURL=documentation-fetcher.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"documentation-fetcher.js","sourceRoot":"","sources":["../../src/utils/documentation-fetcher.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,mEAAiD"}

View File

@@ -0,0 +1,74 @@
export interface EnhancedNodeDocumentation {
markdown: string;
url: string;
title?: string;
description?: string;
operations?: OperationInfo[];
apiMethods?: ApiMethodMapping[];
examples?: CodeExample[];
templates?: TemplateInfo[];
relatedResources?: RelatedResource[];
requiredScopes?: string[];
metadata?: DocumentationMetadata;
}
export interface OperationInfo {
resource: string;
operation: string;
description: string;
subOperations?: string[];
}
export interface ApiMethodMapping {
resource: string;
operation: string;
apiMethod: string;
apiUrl: string;
}
export interface CodeExample {
title?: string;
description?: string;
type: 'json' | 'javascript' | 'yaml' | 'text';
code: string;
language?: string;
}
export interface TemplateInfo {
name: string;
description?: string;
url?: string;
}
export interface RelatedResource {
title: string;
url: string;
type: 'documentation' | 'api' | 'tutorial' | 'external';
}
export interface DocumentationMetadata {
contentType?: string[];
priority?: string;
tags?: string[];
lastUpdated?: Date;
}
export declare class EnhancedDocumentationFetcher {
private docsPath;
private readonly docsRepoUrl;
private cloned;
constructor(docsPath?: string);
private sanitizePath;
ensureDocsRepository(): Promise<void>;
getEnhancedNodeDocumentation(nodeType: string): Promise<EnhancedNodeDocumentation | null>;
private parseEnhancedDocumentation;
private extractFrontmatter;
private extractTitle;
private extractDescription;
private extractOperations;
private extractApiMethods;
private extractCodeExamples;
private extractTemplates;
private extractRelatedResources;
private extractRequiredScopes;
private mapLanguageToType;
private isCredentialDoc;
private extractNodeName;
private searchForNodeDoc;
private generateDocUrl;
cleanup(): Promise<void>;
}
//# sourceMappingURL=enhanced-documentation-fetcher.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"enhanced-documentation-fetcher.d.ts","sourceRoot":"","sources":["../../src/utils/enhanced-documentation-fetcher.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,SAAS,CAAC,EAAE,YAAY,EAAE,CAAC;IAC3B,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,qBAAqB,CAAC;CAClC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,eAAe,GAAG,KAAK,GAAG,UAAU,GAAG,UAAU,CAAC;CACzD;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,IAAI,CAAC;CACpB;AAED,qBAAa,4BAA4B;IACvC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA4C;IACxE,OAAO,CAAC,MAAM,CAAS;gBAEX,QAAQ,CAAC,EAAE,MAAM;IA2C7B,OAAO,CAAC,YAAY;IAuBd,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAuErC,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC;IA4D/F,OAAO,CAAC,0BAA0B;IA8ClC,OAAO,CAAC,kBAAkB;IA8B1B,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,kBAAkB;IA2B1B,OAAO,CAAC,iBAAiB;IA8EzB,OAAO,CAAC,iBAAiB;IAiDzB,OAAO,CAAC,mBAAmB;IA6C3B,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,uBAAuB;IAkC/B,OAAO,CAAC,qBAAqB;IA0B7B,OAAO,CAAC,iBAAiB;IAoBzB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,eAAe;YAWT,gBAAgB;IA+G9B,OAAO,CAAC,cAAc;IAahB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAS/B"}

View File

@@ -0,0 +1,521 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EnhancedDocumentationFetcher = void 0;
const fs_1 = require("fs");
const path_1 = __importDefault(require("path"));
const logger_1 = require("./logger");
const child_process_1 = require("child_process");
class EnhancedDocumentationFetcher {
constructor(docsPath) {
this.docsRepoUrl = 'https://github.com/n8n-io/n8n-docs.git';
this.cloned = false;
const defaultPath = path_1.default.join(__dirname, '../../temp', 'n8n-docs');
if (!docsPath) {
this.docsPath = defaultPath;
}
else {
const sanitized = this.sanitizePath(docsPath);
if (!sanitized) {
logger_1.logger.error('Invalid docsPath rejected in constructor', { docsPath });
throw new Error('Invalid docsPath: path contains disallowed characters or patterns');
}
const absolutePath = path_1.default.resolve(sanitized);
if (absolutePath.startsWith('/etc') ||
absolutePath.startsWith('/sys') ||
absolutePath.startsWith('/proc') ||
absolutePath.startsWith('/var/log')) {
logger_1.logger.error('docsPath points to system directory - blocked', { docsPath, absolutePath });
throw new Error('Invalid docsPath: cannot use system directories');
}
this.docsPath = absolutePath;
logger_1.logger.info('docsPath validated and set', { docsPath: this.docsPath });
}
if (!this.docsRepoUrl.startsWith('https://')) {
logger_1.logger.error('docsRepoUrl must use HTTPS protocol', { url: this.docsRepoUrl });
throw new Error('Invalid repository URL: must use HTTPS protocol');
}
}
sanitizePath(inputPath) {
const dangerousChars = /[;&|`$(){}[\]<>'"\\#\n\r\t]/;
if (dangerousChars.test(inputPath)) {
logger_1.logger.warn('Path contains shell metacharacters - rejected', { path: inputPath });
return null;
}
if (inputPath.includes('..') || inputPath.startsWith('.')) {
logger_1.logger.warn('Path traversal attempt blocked', { path: inputPath });
return null;
}
return inputPath;
}
async ensureDocsRepository() {
try {
const exists = await fs_1.promises.access(this.docsPath).then(() => true).catch(() => false);
if (!exists) {
logger_1.logger.info('Cloning n8n-docs repository...', {
url: this.docsRepoUrl,
path: this.docsPath
});
await fs_1.promises.mkdir(path_1.default.dirname(this.docsPath), { recursive: true });
const cloneResult = (0, child_process_1.spawnSync)('git', [
'clone',
'--depth', '1',
this.docsRepoUrl,
this.docsPath
], {
stdio: 'pipe',
encoding: 'utf-8'
});
if (cloneResult.status !== 0) {
const error = cloneResult.stderr || cloneResult.error?.message || 'Unknown error';
logger_1.logger.error('Git clone failed', {
status: cloneResult.status,
stderr: error,
url: this.docsRepoUrl,
path: this.docsPath
});
throw new Error(`Git clone failed: ${error}`);
}
logger_1.logger.info('n8n-docs repository cloned successfully');
}
else {
logger_1.logger.info('Updating n8n-docs repository...', { path: this.docsPath });
const pullResult = (0, child_process_1.spawnSync)('git', [
'pull',
'--ff-only'
], {
cwd: this.docsPath,
stdio: 'pipe',
encoding: 'utf-8'
});
if (pullResult.status !== 0) {
const error = pullResult.stderr || pullResult.error?.message || 'Unknown error';
logger_1.logger.error('Git pull failed', {
status: pullResult.status,
stderr: error,
cwd: this.docsPath
});
throw new Error(`Git pull failed: ${error}`);
}
logger_1.logger.info('n8n-docs repository updated');
}
this.cloned = true;
}
catch (error) {
logger_1.logger.error('Failed to clone/update n8n-docs repository:', error);
throw error;
}
}
async getEnhancedNodeDocumentation(nodeType) {
if (!this.cloned) {
await this.ensureDocsRepository();
}
try {
const nodeName = this.extractNodeName(nodeType);
const possiblePaths = [
path_1.default.join(this.docsPath, 'docs', 'integrations', 'builtin', 'app-nodes', `${nodeType}.md`),
path_1.default.join(this.docsPath, 'docs', 'integrations', 'builtin', 'core-nodes', `${nodeType}.md`),
path_1.default.join(this.docsPath, 'docs', 'integrations', 'builtin', 'trigger-nodes', `${nodeType}.md`),
path_1.default.join(this.docsPath, 'docs', 'integrations', 'builtin', 'core-nodes', `${nodeName}.md`),
path_1.default.join(this.docsPath, 'docs', 'integrations', 'builtin', 'app-nodes', `${nodeName}.md`),
path_1.default.join(this.docsPath, 'docs', 'integrations', 'builtin', 'trigger-nodes', `${nodeName}.md`),
];
for (const docPath of possiblePaths) {
try {
const content = await fs_1.promises.readFile(docPath, 'utf-8');
logger_1.logger.debug(`Checking doc path: ${docPath}`);
if (this.isCredentialDoc(docPath, content)) {
logger_1.logger.debug(`Skipping credential doc: ${docPath}`);
continue;
}
logger_1.logger.info(`Found documentation for ${nodeType} at: ${docPath}`);
return this.parseEnhancedDocumentation(content, docPath);
}
catch (error) {
continue;
}
}
logger_1.logger.debug(`No exact match found, searching for ${nodeType}...`);
const foundPath = await this.searchForNodeDoc(nodeType);
if (foundPath) {
logger_1.logger.info(`Found documentation via search at: ${foundPath}`);
const content = await fs_1.promises.readFile(foundPath, 'utf-8');
if (!this.isCredentialDoc(foundPath, content)) {
return this.parseEnhancedDocumentation(content, foundPath);
}
}
logger_1.logger.warn(`No documentation found for node: ${nodeType}`);
return null;
}
catch (error) {
logger_1.logger.error(`Failed to get documentation for ${nodeType}:`, error);
return null;
}
}
parseEnhancedDocumentation(markdown, filePath) {
const doc = {
markdown,
url: this.generateDocUrl(filePath),
};
const metadata = this.extractFrontmatter(markdown);
if (metadata) {
doc.metadata = metadata;
doc.title = metadata.title;
doc.description = metadata.description;
}
if (!doc.title) {
doc.title = this.extractTitle(markdown);
}
if (!doc.description) {
doc.description = this.extractDescription(markdown);
}
doc.operations = this.extractOperations(markdown);
doc.apiMethods = this.extractApiMethods(markdown);
doc.examples = this.extractCodeExamples(markdown);
doc.templates = this.extractTemplates(markdown);
doc.relatedResources = this.extractRelatedResources(markdown);
doc.requiredScopes = this.extractRequiredScopes(markdown);
return doc;
}
extractFrontmatter(markdown) {
const frontmatterMatch = markdown.match(/^---\n([\s\S]*?)\n---/);
if (!frontmatterMatch)
return null;
const frontmatter = {};
const lines = frontmatterMatch[1].split('\n');
for (const line of lines) {
if (line.includes(':')) {
const [key, ...valueParts] = line.split(':');
const value = valueParts.join(':').trim();
if (value.startsWith('[') && value.endsWith(']')) {
frontmatter[key.trim()] = value
.slice(1, -1)
.split(',')
.map(v => v.trim());
}
else {
frontmatter[key.trim()] = value;
}
}
}
return frontmatter;
}
extractTitle(markdown) {
const match = markdown.match(/^#\s+(.+)$/m);
return match ? match[1].trim() : undefined;
}
extractDescription(markdown) {
const content = markdown.replace(/^---[\s\S]*?---\n/, '');
const lines = content.split('\n');
let foundTitle = false;
let description = '';
for (const line of lines) {
if (line.startsWith('#')) {
foundTitle = true;
continue;
}
if (foundTitle && line.trim() && !line.startsWith('#') && !line.startsWith('*') && !line.startsWith('-')) {
description = line.trim();
break;
}
}
return description || undefined;
}
extractOperations(markdown) {
const operations = [];
const operationsMatch = markdown.match(/##\s+Operations\s*\n([\s\S]*?)(?=\n##|\n#|$)/i);
if (!operationsMatch)
return operations;
const operationsText = operationsMatch[1];
let currentResource = null;
const lines = operationsText.split('\n');
for (const line of lines) {
const trimmedLine = line.trim();
if (!trimmedLine)
continue;
if (line.match(/^\*\s+\*\*[^*]+\*\*\s*$/) && !line.match(/^\s+/)) {
const match = trimmedLine.match(/^\*\s+\*\*([^*]+)\*\*/);
if (match) {
currentResource = match[1].trim();
}
continue;
}
if (!currentResource)
continue;
if (line.match(/^\s+\*\s+/) && currentResource) {
const operationMatch = trimmedLine.match(/^\*\s+\*\*([^*]+)\*\*(.*)$/);
if (operationMatch) {
const operation = operationMatch[1].trim();
let description = operationMatch[2].trim();
description = description.replace(/^:\s*/, '').replace(/\.$/, '').trim();
operations.push({
resource: currentResource,
operation,
description: description || operation,
});
}
else {
const simpleMatch = trimmedLine.match(/^\*\s+(.+)$/);
if (simpleMatch) {
const text = simpleMatch[1].trim();
const colonIndex = text.indexOf(':');
if (colonIndex > 0) {
operations.push({
resource: currentResource,
operation: text.substring(0, colonIndex).trim(),
description: text.substring(colonIndex + 1).trim() || text,
});
}
else {
operations.push({
resource: currentResource,
operation: text,
description: text,
});
}
}
}
}
}
return operations;
}
extractApiMethods(markdown) {
const apiMethods = [];
const tableRegex = /\|.*Resource.*\|.*Operation.*\|.*(?:Slack API method|API method|Method).*\|[\s\S]*?\n(?=\n[^|]|$)/gi;
const tables = markdown.match(tableRegex);
if (!tables)
return apiMethods;
for (const table of tables) {
const rows = table.split('\n').filter(row => row.trim() && !row.includes('---'));
for (let i = 1; i < rows.length; i++) {
const cells = rows[i].split('|').map(cell => cell.trim()).filter(Boolean);
if (cells.length >= 3) {
const resource = cells[0];
const operation = cells[1];
const apiMethodCell = cells[2];
const linkMatch = apiMethodCell.match(/\[([^\]]+)\]\(([^)]+)\)/);
if (linkMatch) {
apiMethods.push({
resource,
operation,
apiMethod: linkMatch[1],
apiUrl: linkMatch[2],
});
}
else {
apiMethods.push({
resource,
operation,
apiMethod: apiMethodCell,
apiUrl: '',
});
}
}
}
}
return apiMethods;
}
extractCodeExamples(markdown) {
const examples = [];
const codeBlockRegex = /```(\w+)?\n([\s\S]*?)```/g;
let match;
while ((match = codeBlockRegex.exec(markdown)) !== null) {
const language = match[1] || 'text';
const code = match[2].trim();
const beforeCodeIndex = match.index;
const beforeText = markdown.substring(Math.max(0, beforeCodeIndex - 200), beforeCodeIndex);
const titleMatch = beforeText.match(/(?:###|####)\s+(.+)$/m);
const example = {
type: this.mapLanguageToType(language),
language,
code,
};
if (titleMatch) {
example.title = titleMatch[1].trim();
}
if (language === 'json') {
try {
JSON.parse(code);
examples.push(example);
}
catch (e) {
}
}
else {
examples.push(example);
}
}
return examples;
}
extractTemplates(markdown) {
const templates = [];
const templateWidgetMatch = markdown.match(/\[\[\s*templatesWidget\s*\(\s*[^,]+,\s*'([^']+)'\s*\)\s*\]\]/);
if (templateWidgetMatch) {
templates.push({
name: templateWidgetMatch[1],
description: `Templates for ${templateWidgetMatch[1]}`,
});
}
return templates;
}
extractRelatedResources(markdown) {
const resources = [];
const relatedMatch = markdown.match(/##\s+(?:Related resources|Related|Resources)\s*\n([\s\S]*?)(?=\n##|\n#|$)/i);
if (!relatedMatch)
return resources;
const relatedText = relatedMatch[1];
const linkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
let match;
while ((match = linkRegex.exec(relatedText)) !== null) {
const title = match[1];
const url = match[2];
let type = 'external';
if (url.includes('docs.n8n.io') || url.startsWith('/')) {
type = 'documentation';
}
else if (url.includes('api.')) {
type = 'api';
}
resources.push({ title, url, type });
}
return resources;
}
extractRequiredScopes(markdown) {
const scopes = [];
const scopesMatch = markdown.match(/##\s+(?:Required scopes|Scopes)\s*\n([\s\S]*?)(?=\n##|\n#|$)/i);
if (!scopesMatch)
return scopes;
const scopesText = scopesMatch[1];
const scopeRegex = /`([a-z:._-]+)`/gi;
let match;
while ((match = scopeRegex.exec(scopesText)) !== null) {
const scope = match[1];
if (scope.includes(':') || scope.includes('.')) {
scopes.push(scope);
}
}
return [...new Set(scopes)];
}
mapLanguageToType(language) {
switch (language.toLowerCase()) {
case 'json':
return 'json';
case 'js':
case 'javascript':
case 'typescript':
case 'ts':
return 'javascript';
case 'yaml':
case 'yml':
return 'yaml';
default:
return 'text';
}
}
isCredentialDoc(filePath, content) {
return filePath.includes('/credentials/') ||
(content.includes('title: ') &&
content.includes(' credentials') &&
!content.includes(' node documentation'));
}
extractNodeName(nodeType) {
const parts = nodeType.split('.');
const name = parts[parts.length - 1];
return name.toLowerCase();
}
async searchForNodeDoc(nodeType) {
try {
const sanitized = nodeType.replace(/[^a-zA-Z0-9._-]/g, '');
if (!sanitized) {
logger_1.logger.warn('Invalid nodeType after sanitization', { nodeType });
return null;
}
if (sanitized.includes('..') || sanitized.startsWith('.') || sanitized.startsWith('/')) {
logger_1.logger.warn('Path traversal attempt blocked', { nodeType, sanitized });
return null;
}
if (sanitized !== nodeType) {
logger_1.logger.warn('nodeType was sanitized (potential injection attempt)', {
original: nodeType,
sanitized,
});
}
const safeName = path_1.default.basename(sanitized);
const searchPath = path_1.default.join(this.docsPath, 'docs', 'integrations', 'builtin');
const files = await fs_1.promises.readdir(searchPath, {
recursive: true,
encoding: 'utf-8'
});
let match = files.find(f => f.endsWith(`${safeName}.md`) &&
!f.includes('credentials') &&
!f.includes('trigger'));
if (match) {
const fullPath = path_1.default.join(searchPath, match);
if (!fullPath.startsWith(searchPath)) {
logger_1.logger.error('Path traversal blocked in final path', { fullPath, searchPath });
return null;
}
logger_1.logger.info('Found documentation (exact match)', { path: fullPath });
return fullPath;
}
const lowerSafeName = safeName.toLowerCase();
match = files.find(f => f.endsWith(`${lowerSafeName}.md`) &&
!f.includes('credentials') &&
!f.includes('trigger'));
if (match) {
const fullPath = path_1.default.join(searchPath, match);
if (!fullPath.startsWith(searchPath)) {
logger_1.logger.error('Path traversal blocked in final path', { fullPath, searchPath });
return null;
}
logger_1.logger.info('Found documentation (lowercase match)', { path: fullPath });
return fullPath;
}
const nodeName = this.extractNodeName(safeName);
match = files.find(f => f.toLowerCase().includes(nodeName.toLowerCase()) &&
f.endsWith('.md') &&
!f.includes('credentials') &&
!f.includes('trigger'));
if (match) {
const fullPath = path_1.default.join(searchPath, match);
if (!fullPath.startsWith(searchPath)) {
logger_1.logger.error('Path traversal blocked in final path', { fullPath, searchPath });
return null;
}
logger_1.logger.info('Found documentation (partial match)', { path: fullPath });
return fullPath;
}
logger_1.logger.debug('No documentation found', { nodeType: safeName });
return null;
}
catch (error) {
logger_1.logger.error('Error searching for node documentation:', {
error: error instanceof Error ? error.message : String(error),
nodeType,
});
return null;
}
}
generateDocUrl(filePath) {
const relativePath = path_1.default.relative(this.docsPath, filePath);
const urlPath = relativePath
.replace(/^docs\//, '')
.replace(/\.md$/, '')
.replace(/\\/g, '/');
return `https://docs.n8n.io/${urlPath}`;
}
async cleanup() {
try {
await fs_1.promises.rm(this.docsPath, { recursive: true, force: true });
this.cloned = false;
logger_1.logger.info('Cleaned up documentation repository');
}
catch (error) {
logger_1.logger.error('Failed to cleanup docs repository:', error);
}
}
}
exports.EnhancedDocumentationFetcher = EnhancedDocumentationFetcher;
//# sourceMappingURL=enhanced-documentation-fetcher.js.map

File diff suppressed because one or more lines are too long

24
dist/utils/error-handler.d.ts vendored Normal file
View File

@@ -0,0 +1,24 @@
export declare class MCPError extends Error {
code: string;
statusCode?: number;
data?: any;
constructor(message: string, code: string, statusCode?: number, data?: any);
}
export declare class N8NConnectionError extends MCPError {
constructor(message: string, data?: any);
}
export declare class AuthenticationError extends MCPError {
constructor(message?: string);
}
export declare class ValidationError extends MCPError {
constructor(message: string, data?: any);
}
export declare class ToolNotFoundError extends MCPError {
constructor(toolName: string);
}
export declare class ResourceNotFoundError extends MCPError {
constructor(resourceUri: string);
}
export declare function handleError(error: any): MCPError;
export declare function withErrorHandling<T>(operation: () => Promise<T>, context: string): Promise<T>;
//# sourceMappingURL=error-handler.d.ts.map

1
dist/utils/error-handler.d.ts.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/utils/error-handler.ts"],"names":[],"mappings":"AAEA,qBAAa,QAAS,SAAQ,KAAK;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,GAAG,CAAC;gBAEN,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG;CAO3E;AAED,qBAAa,kBAAmB,SAAQ,QAAQ;gBAClC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG;CAIxC;AAED,qBAAa,mBAAoB,SAAQ,QAAQ;gBACnC,OAAO,GAAE,MAAgC;CAItD;AAED,qBAAa,eAAgB,SAAQ,QAAQ;gBAC/B,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG;CAIxC;AAED,qBAAa,iBAAkB,SAAQ,QAAQ;gBACjC,QAAQ,EAAE,MAAM;CAI7B;AAED,qBAAa,qBAAsB,SAAQ,QAAQ;gBACrC,WAAW,EAAE,MAAM;CAIhC;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,GAAG,GAAG,QAAQ,CA+BhD;AAED,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,CAAC,CAAC,CAOZ"}

84
dist/utils/error-handler.js vendored Normal file
View File

@@ -0,0 +1,84 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ResourceNotFoundError = exports.ToolNotFoundError = exports.ValidationError = exports.AuthenticationError = exports.N8NConnectionError = exports.MCPError = void 0;
exports.handleError = handleError;
exports.withErrorHandling = withErrorHandling;
const logger_1 = require("./logger");
class MCPError extends Error {
constructor(message, code, statusCode, data) {
super(message);
this.name = 'MCPError';
this.code = code;
this.statusCode = statusCode;
this.data = data;
}
}
exports.MCPError = MCPError;
class N8NConnectionError extends MCPError {
constructor(message, data) {
super(message, 'N8N_CONNECTION_ERROR', 503, data);
this.name = 'N8NConnectionError';
}
}
exports.N8NConnectionError = N8NConnectionError;
class AuthenticationError extends MCPError {
constructor(message = 'Authentication failed') {
super(message, 'AUTH_ERROR', 401);
this.name = 'AuthenticationError';
}
}
exports.AuthenticationError = AuthenticationError;
class ValidationError extends MCPError {
constructor(message, data) {
super(message, 'VALIDATION_ERROR', 400, data);
this.name = 'ValidationError';
}
}
exports.ValidationError = ValidationError;
class ToolNotFoundError extends MCPError {
constructor(toolName) {
super(`Tool '${toolName}' not found`, 'TOOL_NOT_FOUND', 404);
this.name = 'ToolNotFoundError';
}
}
exports.ToolNotFoundError = ToolNotFoundError;
class ResourceNotFoundError extends MCPError {
constructor(resourceUri) {
super(`Resource '${resourceUri}' not found`, 'RESOURCE_NOT_FOUND', 404);
this.name = 'ResourceNotFoundError';
}
}
exports.ResourceNotFoundError = ResourceNotFoundError;
function handleError(error) {
if (error instanceof MCPError) {
return error;
}
if (error.response) {
const status = error.response.status;
const message = error.response.data?.message || error.message;
if (status === 401) {
return new AuthenticationError(message);
}
else if (status === 404) {
return new MCPError(message, 'NOT_FOUND', 404);
}
else if (status >= 500) {
return new N8NConnectionError(message);
}
return new MCPError(message, 'API_ERROR', status);
}
if (error.code === 'ECONNREFUSED') {
return new N8NConnectionError('Cannot connect to n8n API');
}
return new MCPError(error.message || 'An unexpected error occurred', 'UNKNOWN_ERROR', 500);
}
async function withErrorHandling(operation, context) {
try {
return await operation();
}
catch (error) {
logger_1.logger.error(`Error in ${context}:`, error);
throw handleError(error);
}
}
//# sourceMappingURL=error-handler.js.map

1
dist/utils/error-handler.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/utils/error-handler.ts"],"names":[],"mappings":"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"}

8
dist/utils/example-generator.d.ts vendored Normal file
View File

@@ -0,0 +1,8 @@
export declare class ExampleGenerator {
static generateFromNodeDefinition(nodeDefinition: any): any;
static generateExampleParameters(nodeDefinition: any): any;
private static generateExampleValue;
private static generateNodeId;
static generateFromOperations(operations: any[]): any;
}
//# sourceMappingURL=example-generator.d.ts.map

1
dist/utils/example-generator.d.ts.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"example-generator.d.ts","sourceRoot":"","sources":["../../src/utils/example-generator.ts"],"names":[],"mappings":"AAGA,qBAAa,gBAAgB;IAI3B,MAAM,CAAC,0BAA0B,CAAC,cAAc,EAAE,GAAG,GAAG,GAAG;IA0B3D,MAAM,CAAC,yBAAyB,CAAC,cAAc,EAAE,GAAG,GAAG,GAAG;IA6B1D,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAsCnC,OAAO,CAAC,MAAM,CAAC,cAAc;IAQ7B,MAAM,CAAC,sBAAsB,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,GAAG;CA+BtD"}

106
dist/utils/example-generator.js vendored Normal file
View File

@@ -0,0 +1,106 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExampleGenerator = void 0;
class ExampleGenerator {
static generateFromNodeDefinition(nodeDefinition) {
const nodeName = nodeDefinition.displayName || 'Example Node';
const nodeType = nodeDefinition.name || 'n8n-nodes-base.exampleNode';
return {
name: `${nodeName} Example Workflow`,
nodes: [
{
parameters: this.generateExampleParameters(nodeDefinition),
id: this.generateNodeId(),
name: nodeName,
type: nodeType,
typeVersion: nodeDefinition.version || 1,
position: [250, 300],
},
],
connections: {},
active: false,
settings: {},
tags: ['example', 'generated'],
};
}
static generateExampleParameters(nodeDefinition) {
const params = {};
if (Array.isArray(nodeDefinition.properties)) {
for (const prop of nodeDefinition.properties) {
if (prop.name && prop.type) {
params[prop.name] = this.generateExampleValue(prop);
}
}
}
if (nodeDefinition.displayName?.toLowerCase().includes('trigger')) {
params.pollTimes = {
item: [
{
mode: 'everyMinute',
},
],
};
}
return params;
}
static generateExampleValue(property) {
switch (property.type) {
case 'string':
if (property.name.toLowerCase().includes('url')) {
return 'https://example.com';
}
if (property.name.toLowerCase().includes('email')) {
return 'user@example.com';
}
if (property.name.toLowerCase().includes('name')) {
return 'Example Name';
}
return property.default || 'example-value';
case 'number':
return property.default || 10;
case 'boolean':
return property.default !== undefined ? property.default : true;
case 'options':
if (property.options && property.options.length > 0) {
return property.options[0].value;
}
return property.default || '';
case 'collection':
case 'fixedCollection':
return {};
default:
return property.default || null;
}
}
static generateNodeId() {
return Math.random().toString(36).substring(2, 15) +
Math.random().toString(36).substring(2, 15);
}
static generateFromOperations(operations) {
const examples = [];
if (!operations || operations.length === 0) {
return examples;
}
const resourceMap = new Map();
for (const op of operations) {
if (!resourceMap.has(op.resource)) {
resourceMap.set(op.resource, []);
}
resourceMap.get(op.resource).push(op);
}
for (const [resource, ops] of resourceMap) {
examples.push({
resource,
operation: ops[0].operation,
description: `Example: ${ops[0].description}`,
parameters: {
resource,
operation: ops[0].operation,
},
});
}
return examples;
}
}
exports.ExampleGenerator = ExampleGenerator;
//# sourceMappingURL=example-generator.js.map

1
dist/utils/example-generator.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"example-generator.js","sourceRoot":"","sources":["../../src/utils/example-generator.ts"],"names":[],"mappings":"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"}

6
dist/utils/expression-utils.d.ts vendored Normal file
View File

@@ -0,0 +1,6 @@
export declare function isExpression(value: unknown): value is string;
export declare function containsExpression(value: unknown): boolean;
export declare function shouldSkipLiteralValidation(value: unknown): boolean;
export declare function extractExpressionContent(value: string): string;
export declare function hasMixedContent(value: unknown): boolean;
//# sourceMappingURL=expression-utils.d.ts.map

1
dist/utils/expression-utils.d.ts.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"expression-utils.d.ts","sourceRoot":"","sources":["../../src/utils/expression-utils.ts"],"names":[],"mappings":"AAeA,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE5D;AAWD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAM1D;AAaD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEnE;AAYD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAc9D;AAYD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAqBvD"}

47
dist/utils/expression-utils.js vendored Normal file
View File

@@ -0,0 +1,47 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isExpression = isExpression;
exports.containsExpression = containsExpression;
exports.shouldSkipLiteralValidation = shouldSkipLiteralValidation;
exports.extractExpressionContent = extractExpressionContent;
exports.hasMixedContent = hasMixedContent;
function isExpression(value) {
return typeof value === 'string' && value.startsWith('=');
}
function containsExpression(value) {
if (typeof value !== 'string') {
return false;
}
return /\{\{.*\}\}/s.test(value);
}
function shouldSkipLiteralValidation(value) {
return isExpression(value) || containsExpression(value);
}
function extractExpressionContent(value) {
if (!isExpression(value)) {
return value;
}
const withoutPrefix = value.substring(1);
const match = withoutPrefix.match(/^\{\{(.+)\}\}$/s);
if (match) {
return match[1].trim();
}
return withoutPrefix;
}
function hasMixedContent(value) {
if (typeof value !== 'string') {
return false;
}
if (!containsExpression(value)) {
return false;
}
const trimmed = value.trim();
if (trimmed.startsWith('={{') && trimmed.endsWith('}}')) {
const count = (trimmed.match(/\{\{/g) || []).length;
if (count === 1) {
return false;
}
}
return true;
}
//# sourceMappingURL=expression-utils.js.map

1
dist/utils/expression-utils.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"expression-utils.js","sourceRoot":"","sources":["../../src/utils/expression-utils.ts"],"names":[],"mappings":";;AAeA,oCAEC;AAWD,gDAMC;AAaD,kEAEC;AAYD,4DAcC;AAYD,0CAqBC;AA7FD,SAAgB,YAAY,CAAC,KAAc;IACzC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAC5D,CAAC;AAWD,SAAgB,kBAAkB,CAAC,KAAc;IAC/C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACnC,CAAC;AAaD,SAAgB,2BAA2B,CAAC,KAAc;IACxD,OAAO,YAAY,CAAC,KAAK,CAAC,IAAI,kBAAkB,CAAC,KAAK,CAAC,CAAC;AAC1D,CAAC;AAYD,SAAgB,wBAAwB,CAAC,KAAa;IACpD,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,aAAa,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAGzC,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACrD,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACzB,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC;AAYD,SAAgB,eAAe,CAAC,KAAc;IAE5C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IAGD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAExD,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QACpD,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAChB,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}

View File

@@ -0,0 +1,35 @@
export type NodeConfigValue = string | number | boolean | null | undefined | NodeConfig | NodeConfigValue[];
export interface NodeConfig {
[key: string]: NodeConfigValue;
}
export interface FixedCollectionPattern {
nodeType: string;
property: string;
subProperty?: string;
expectedStructure: string;
invalidPatterns: string[];
}
export interface FixedCollectionValidationResult {
isValid: boolean;
errors: Array<{
pattern: string;
message: string;
fix: string;
}>;
autofix?: NodeConfig | NodeConfigValue[];
}
export declare class FixedCollectionValidator {
private static isNodeConfig;
private static getNestedValue;
private static readonly KNOWN_PATTERNS;
static validate(nodeType: string, config: NodeConfig): FixedCollectionValidationResult;
static applyAutofix(config: NodeConfig, pattern: FixedCollectionPattern): NodeConfig | NodeConfigValue[];
private static normalizeNodeType;
private static getPatternForNode;
private static hasInvalidStructure;
private static generateFixMessage;
private static generateAutofix;
static getAllPatterns(): FixedCollectionPattern[];
static isNodeSusceptible(nodeType: string): boolean;
}
//# sourceMappingURL=fixed-collection-validator.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"fixed-collection-validator.d.ts","sourceRoot":"","sources":["../../src/utils/fixed-collection-validator.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,UAAU,GAAG,eAAe,EAAE,CAAC;AAE5G,MAAM,WAAW,UAAU;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAAC;CAChC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,+BAA+B;IAC9C,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,KAAK,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC;KACb,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,UAAU,GAAG,eAAe,EAAE,CAAC;CAC1C;AAED,qBAAa,wBAAwB;IAInC,OAAO,CAAC,MAAM,CAAC,YAAY;IAO3B,OAAO,CAAC,MAAM,CAAC,cAAc;IAgB7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CA6EpC;IAMF,MAAM,CAAC,QAAQ,CACb,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,GACjB,+BAA+B;IAyClC,MAAM,CAAC,YAAY,CACjB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,sBAAsB,GAC9B,UAAU,GAAG,eAAe,EAAE;IAmBjC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAWhC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAQhC,OAAO,CAAC,MAAM,CAAC,mBAAmB;IA8ClC,OAAO,CAAC,MAAM,CAAC,kBAAkB;IA+BjC,OAAO,CAAC,MAAM,CAAC,eAAe;IAkK9B,MAAM,CAAC,cAAc,IAAI,sBAAsB,EAAE;IAUjD,MAAM,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;CAIpD"}

358
dist/utils/fixed-collection-validator.js vendored Normal file
View File

@@ -0,0 +1,358 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FixedCollectionValidator = void 0;
class FixedCollectionValidator {
static isNodeConfig(value) {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}
static getNestedValue(obj, path) {
const parts = path.split('.');
let current = obj;
for (const part of parts) {
if (!this.isNodeConfig(current)) {
return undefined;
}
current = current[part];
}
return current;
}
static validate(nodeType, config) {
if (typeof config !== 'object' || config === null || Array.isArray(config)) {
return { isValid: true, errors: [] };
}
const normalizedNodeType = this.normalizeNodeType(nodeType);
const pattern = this.getPatternForNode(normalizedNodeType);
if (!pattern) {
return { isValid: true, errors: [] };
}
const result = {
isValid: true,
errors: []
};
for (const invalidPattern of pattern.invalidPatterns) {
if (this.hasInvalidStructure(config, invalidPattern)) {
result.isValid = false;
result.errors.push({
pattern: invalidPattern,
message: `Invalid structure for nodes-base.${pattern.nodeType} node: found nested "${invalidPattern}" but expected "${pattern.expectedStructure}". This causes "propertyValues[itemName] is not iterable" error in n8n.`,
fix: this.generateFixMessage(pattern)
});
if (!result.autofix) {
result.autofix = this.generateAutofix(config, pattern);
}
}
}
return result;
}
static applyAutofix(config, pattern) {
const fixedConfig = this.generateAutofix(config, pattern);
if (pattern.nodeType === 'if' || pattern.nodeType === 'filter') {
const conditions = config.conditions;
if (conditions && typeof conditions === 'object' && !Array.isArray(conditions) && 'values' in conditions) {
const values = conditions.values;
if (values !== undefined && values !== null &&
(Array.isArray(values) || typeof values === 'object')) {
return values;
}
}
}
return fixedConfig;
}
static normalizeNodeType(nodeType) {
return nodeType
.replace('n8n-nodes-base.', '')
.replace('nodes-base.', '')
.replace('@n8n/n8n-nodes-langchain.', '')
.toLowerCase();
}
static getPatternForNode(nodeType) {
return this.KNOWN_PATTERNS.find(p => p.nodeType === nodeType);
}
static hasInvalidStructure(config, pattern) {
const parts = pattern.split('.');
let current = config;
const visited = new WeakSet();
for (const part of parts) {
if (current === null || current === undefined) {
return false;
}
if (typeof current !== 'object' || Array.isArray(current)) {
return false;
}
if (visited.has(current)) {
return false;
}
visited.add(current);
if (!Object.prototype.hasOwnProperty.call(current, part)) {
return false;
}
const nextValue = current[part];
if (typeof nextValue !== 'object' || nextValue === null) {
if (parts.indexOf(part) < parts.length - 1) {
return false;
}
}
current = nextValue;
}
return true;
}
static generateFixMessage(pattern) {
switch (pattern.nodeType) {
case 'switch':
return 'Use: { "rules": { "values": [{ "conditions": {...}, "outputKey": "output1" }] } }';
case 'if':
case 'filter':
return 'Use: { "conditions": {...} } or { "conditions": [...] } directly, not nested under "values"';
case 'summarize':
return 'Use: { "fieldsToSummarize": { "values": [...] } } not nested values.values';
case 'comparedatasets':
return 'Use: { "mergeByFields": { "values": [...] } } not nested values.values';
case 'sort':
return 'Use: { "sortFieldsUi": { "sortField": [...] } } not sortField.values';
case 'aggregate':
return 'Use: { "fieldsToAggregate": { "fieldToAggregate": [...] } } not fieldToAggregate.values';
case 'set':
return 'Use: { "fields": { "values": [...] } } not nested values.values';
case 'html':
return 'Use: { "extractionValues": { "values": [...] } } not nested values.values';
case 'httprequest':
return 'Use: { "body": { "parameters": [...] } } not parameters.values';
case 'airtable':
return 'Use: { "sort": { "sortField": [...] } } not sortField.values';
default:
return `Use ${pattern.expectedStructure} structure`;
}
}
static generateAutofix(config, pattern) {
const fixedConfig = { ...config };
switch (pattern.nodeType) {
case 'switch': {
const rules = config.rules;
if (this.isNodeConfig(rules)) {
const conditions = rules.conditions;
if (this.isNodeConfig(conditions) && 'values' in conditions) {
const values = conditions.values;
fixedConfig.rules = {
values: Array.isArray(values)
? values.map((condition, index) => ({
conditions: condition,
outputKey: `output${index + 1}`
}))
: [{
conditions: values,
outputKey: 'output1'
}]
};
}
else if (conditions) {
fixedConfig.rules = {
values: [{
conditions: conditions,
outputKey: 'output1'
}]
};
}
}
break;
}
case 'if':
case 'filter': {
const conditions = config.conditions;
if (this.isNodeConfig(conditions) && 'values' in conditions) {
const values = conditions.values;
if (values !== undefined && values !== null &&
(Array.isArray(values) || typeof values === 'object')) {
return values;
}
}
break;
}
case 'summarize': {
const fieldsToSummarize = config.fieldsToSummarize;
if (this.isNodeConfig(fieldsToSummarize)) {
const values = fieldsToSummarize.values;
if (this.isNodeConfig(values) && 'values' in values) {
fixedConfig.fieldsToSummarize = {
values: values.values
};
}
}
break;
}
case 'comparedatasets': {
const mergeByFields = config.mergeByFields;
if (this.isNodeConfig(mergeByFields)) {
const values = mergeByFields.values;
if (this.isNodeConfig(values) && 'values' in values) {
fixedConfig.mergeByFields = {
values: values.values
};
}
}
break;
}
case 'sort': {
const sortFieldsUi = config.sortFieldsUi;
if (this.isNodeConfig(sortFieldsUi)) {
const sortField = sortFieldsUi.sortField;
if (this.isNodeConfig(sortField) && 'values' in sortField) {
fixedConfig.sortFieldsUi = {
sortField: sortField.values
};
}
}
break;
}
case 'aggregate': {
const fieldsToAggregate = config.fieldsToAggregate;
if (this.isNodeConfig(fieldsToAggregate)) {
const fieldToAggregate = fieldsToAggregate.fieldToAggregate;
if (this.isNodeConfig(fieldToAggregate) && 'values' in fieldToAggregate) {
fixedConfig.fieldsToAggregate = {
fieldToAggregate: fieldToAggregate.values
};
}
}
break;
}
case 'set': {
const fields = config.fields;
if (this.isNodeConfig(fields)) {
const values = fields.values;
if (this.isNodeConfig(values) && 'values' in values) {
fixedConfig.fields = {
values: values.values
};
}
}
break;
}
case 'html': {
const extractionValues = config.extractionValues;
if (this.isNodeConfig(extractionValues)) {
const values = extractionValues.values;
if (this.isNodeConfig(values) && 'values' in values) {
fixedConfig.extractionValues = {
values: values.values
};
}
}
break;
}
case 'httprequest': {
const body = config.body;
if (this.isNodeConfig(body)) {
const parameters = body.parameters;
if (this.isNodeConfig(parameters) && 'values' in parameters) {
fixedConfig.body = {
...body,
parameters: parameters.values
};
}
}
break;
}
case 'airtable': {
const sort = config.sort;
if (this.isNodeConfig(sort)) {
const sortField = sort.sortField;
if (this.isNodeConfig(sortField) && 'values' in sortField) {
fixedConfig.sort = {
sortField: sortField.values
};
}
}
break;
}
}
return fixedConfig;
}
static getAllPatterns() {
return this.KNOWN_PATTERNS.map(pattern => ({
...pattern,
invalidPatterns: [...pattern.invalidPatterns]
}));
}
static isNodeSusceptible(nodeType) {
const normalizedType = this.normalizeNodeType(nodeType);
return this.KNOWN_PATTERNS.some(p => p.nodeType === normalizedType);
}
}
exports.FixedCollectionValidator = FixedCollectionValidator;
FixedCollectionValidator.KNOWN_PATTERNS = [
{
nodeType: 'switch',
property: 'rules',
expectedStructure: 'rules.values array',
invalidPatterns: ['rules.conditions', 'rules.conditions.values']
},
{
nodeType: 'if',
property: 'conditions',
expectedStructure: 'conditions array/object',
invalidPatterns: ['conditions.values']
},
{
nodeType: 'filter',
property: 'conditions',
expectedStructure: 'conditions array/object',
invalidPatterns: ['conditions.values']
},
{
nodeType: 'summarize',
property: 'fieldsToSummarize',
subProperty: 'values',
expectedStructure: 'fieldsToSummarize.values array',
invalidPatterns: ['fieldsToSummarize.values.values']
},
{
nodeType: 'comparedatasets',
property: 'mergeByFields',
subProperty: 'values',
expectedStructure: 'mergeByFields.values array',
invalidPatterns: ['mergeByFields.values.values']
},
{
nodeType: 'sort',
property: 'sortFieldsUi',
subProperty: 'sortField',
expectedStructure: 'sortFieldsUi.sortField array',
invalidPatterns: ['sortFieldsUi.sortField.values']
},
{
nodeType: 'aggregate',
property: 'fieldsToAggregate',
subProperty: 'fieldToAggregate',
expectedStructure: 'fieldsToAggregate.fieldToAggregate array',
invalidPatterns: ['fieldsToAggregate.fieldToAggregate.values']
},
{
nodeType: 'set',
property: 'fields',
subProperty: 'values',
expectedStructure: 'fields.values array',
invalidPatterns: ['fields.values.values']
},
{
nodeType: 'html',
property: 'extractionValues',
subProperty: 'values',
expectedStructure: 'extractionValues.values array',
invalidPatterns: ['extractionValues.values.values']
},
{
nodeType: 'httprequest',
property: 'body',
subProperty: 'parameters',
expectedStructure: 'body.parameters array',
invalidPatterns: ['body.parameters.values']
},
{
nodeType: 'airtable',
property: 'sort',
subProperty: 'sortField',
expectedStructure: 'sort.sortField array',
invalidPatterns: ['sort.sortField.values']
}
];
//# sourceMappingURL=fixed-collection-validator.js.map

File diff suppressed because one or more lines are too long

33
dist/utils/logger.d.ts vendored Normal file
View File

@@ -0,0 +1,33 @@
export declare enum LogLevel {
ERROR = 0,
WARN = 1,
INFO = 2,
DEBUG = 3
}
export interface LoggerConfig {
level: LogLevel;
prefix?: string;
timestamp?: boolean;
}
export declare class Logger {
private config;
private static instance;
private useFileLogging;
private fileStream;
private readonly isStdio;
private readonly isDisabled;
private readonly isHttp;
private readonly isTest;
constructor(config?: Partial<LoggerConfig>);
static getInstance(config?: Partial<LoggerConfig>): Logger;
private formatMessage;
private log;
error(message: string, ...args: any[]): void;
warn(message: string, ...args: any[]): void;
info(message: string, ...args: any[]): void;
debug(message: string, ...args: any[]): void;
setLevel(level: LogLevel): void;
static parseLogLevel(level: string): LogLevel;
}
export declare const logger: Logger;
//# sourceMappingURL=logger.d.ts.map

1
dist/utils/logger.d.ts.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,oBAAY,QAAQ;IAClB,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;CACV;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAS;IAChC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,UAAU,CAAa;IAE/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAC5D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiD;IAC5E,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmC;IAC1D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8E;gBAEzF,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC;IAS1C,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,MAAM;IAO1D,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,GAAG;IAqCX,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAI5C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAI3C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAI3C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAI5C,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAI/B,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ;CAa9C;AAGD,eAAO,MAAM,MAAM,QAEjB,CAAC"}

101
dist/utils/logger.js vendored Normal file
View File

@@ -0,0 +1,101 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.logger = exports.Logger = exports.LogLevel = void 0;
var LogLevel;
(function (LogLevel) {
LogLevel[LogLevel["ERROR"] = 0] = "ERROR";
LogLevel[LogLevel["WARN"] = 1] = "WARN";
LogLevel[LogLevel["INFO"] = 2] = "INFO";
LogLevel[LogLevel["DEBUG"] = 3] = "DEBUG";
})(LogLevel || (exports.LogLevel = LogLevel = {}));
class Logger {
constructor(config) {
this.useFileLogging = false;
this.fileStream = null;
this.isStdio = process.env.MCP_MODE === 'stdio';
this.isDisabled = process.env.DISABLE_CONSOLE_OUTPUT === 'true';
this.isHttp = process.env.MCP_MODE === 'http';
this.isTest = process.env.NODE_ENV === 'test' || process.env.TEST_ENVIRONMENT === 'true';
this.config = {
level: LogLevel.INFO,
prefix: 'n8n-mcp',
timestamp: true,
...config,
};
}
static getInstance(config) {
if (!Logger.instance) {
Logger.instance = new Logger(config);
}
return Logger.instance;
}
formatMessage(level, message) {
const parts = [];
if (this.config.timestamp) {
parts.push(`[${new Date().toISOString()}]`);
}
if (this.config.prefix) {
parts.push(`[${this.config.prefix}]`);
}
parts.push(`[${level}]`);
parts.push(message);
return parts.join(' ');
}
log(level, levelName, message, ...args) {
const allowErrorLogs = level === LogLevel.ERROR && (this.isHttp || process.env.DEBUG === 'true');
if (this.isStdio || this.isDisabled || (this.isTest && process.env.DEBUG !== 'true')) {
if (!allowErrorLogs) {
return;
}
}
if (level <= this.config.level || allowErrorLogs) {
const formattedMessage = this.formatMessage(levelName, message);
if (this.isHttp && process.env.MCP_REQUEST_ACTIVE === 'true' && !allowErrorLogs) {
return;
}
switch (level) {
case LogLevel.ERROR:
console.error(formattedMessage, ...args);
break;
case LogLevel.WARN:
console.warn(formattedMessage, ...args);
break;
default:
console.log(formattedMessage, ...args);
}
}
}
error(message, ...args) {
this.log(LogLevel.ERROR, 'ERROR', message, ...args);
}
warn(message, ...args) {
this.log(LogLevel.WARN, 'WARN', message, ...args);
}
info(message, ...args) {
this.log(LogLevel.INFO, 'INFO', message, ...args);
}
debug(message, ...args) {
this.log(LogLevel.DEBUG, 'DEBUG', message, ...args);
}
setLevel(level) {
this.config.level = level;
}
static parseLogLevel(level) {
switch (level.toLowerCase()) {
case 'error':
return LogLevel.ERROR;
case 'warn':
return LogLevel.WARN;
case 'debug':
return LogLevel.DEBUG;
case 'info':
default:
return LogLevel.INFO;
}
}
}
exports.Logger = Logger;
exports.logger = Logger.getInstance({
level: Logger.parseLogLevel(process.env.LOG_LEVEL || 'info'),
});
//# sourceMappingURL=logger.js.map

1
dist/utils/logger.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":";;;AAAA,IAAY,QAKX;AALD,WAAY,QAAQ;IAClB,yCAAS,CAAA;IACT,uCAAQ,CAAA;IACR,uCAAQ,CAAA;IACR,yCAAS,CAAA;AACX,CAAC,EALW,QAAQ,wBAAR,QAAQ,QAKnB;AAQD,MAAa,MAAM;IAWjB,YAAY,MAA8B;QARlC,mBAAc,GAAG,KAAK,CAAC;QACvB,eAAU,GAAQ,IAAI,CAAC;QAEd,YAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,OAAO,CAAC;QAC3C,eAAU,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,KAAK,MAAM,CAAC;QAC3D,WAAM,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,CAAC;QACzC,WAAM,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,MAAM,CAAC;QAGnG,IAAI,CAAC,MAAM,GAAG;YACZ,KAAK,EAAE,QAAQ,CAAC,IAAI;YACpB,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,IAAI;YACf,GAAG,MAAM;SACV,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,WAAW,CAAC,MAA8B;QAC/C,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACrB,MAAM,CAAC,QAAQ,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;QACD,OAAO,MAAM,CAAC,QAAQ,CAAC;IACzB,CAAC;IAEO,aAAa,CAAC,KAAa,EAAE,OAAe;QAClD,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QACxC,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEpB,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAEO,GAAG,CAAC,KAAe,EAAE,SAAiB,EAAE,OAAe,EAAE,GAAG,IAAW;QAE7E,MAAM,cAAc,GAAG,KAAK,KAAK,QAAQ,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC;QAKjG,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,MAAM,CAAC,EAAE,CAAC;YAErF,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,OAAO;YACT,CAAC;QACH,CAAC;QAED,IAAI,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,cAAc,EAAE,CAAC;YACjD,MAAM,gBAAgB,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAIhE,IAAI,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;gBAEhF,OAAO;YACT,CAAC;YAED,QAAQ,KAAK,EAAE,CAAC;gBACd,KAAK,QAAQ,CAAC,KAAK;oBACjB,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,IAAI,CAAC,CAAC;oBACzC,MAAM;gBACR,KAAK,QAAQ,CAAC,IAAI;oBAChB,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,GAAG,IAAI,CAAC,CAAC;oBACxC,MAAM;gBACR;oBACE,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,GAAG,IAAI,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAW;QACnC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAG,IAAW;QAClC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAG,IAAW;QAClC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAW;QACnC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACtD,CAAC;IAED,QAAQ,CAAC,KAAe;QACtB,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;IAC5B,CAAC;IAED,MAAM,CAAC,aAAa,CAAC,KAAa;QAChC,QAAQ,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YAC5B,KAAK,OAAO;gBACV,OAAO,QAAQ,CAAC,KAAK,CAAC;YACxB,KAAK,MAAM;gBACT,OAAO,QAAQ,CAAC,IAAI,CAAC;YACvB,KAAK,OAAO;gBACV,OAAO,QAAQ,CAAC,KAAK,CAAC;YACxB,KAAK,MAAM,CAAC;YACZ;gBACE,OAAO,QAAQ,CAAC,IAAI,CAAC;QACzB,CAAC;IACH,CAAC;CACF;AAlHD,wBAkHC;AAGY,QAAA,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC;IACvC,KAAK,EAAE,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,CAAC;CAC7D,CAAC,CAAC"}

21
dist/utils/mcp-client.d.ts vendored Normal file
View File

@@ -0,0 +1,21 @@
export interface MCPClientConfig {
serverUrl: string;
authToken?: string;
connectionType: 'http' | 'websocket' | 'stdio';
}
export declare class MCPClient {
private client;
private config;
private connected;
constructor(config: MCPClientConfig);
connect(): Promise<void>;
disconnect(): Promise<void>;
listTools(): Promise<any>;
callTool(name: string, args: any): Promise<any>;
listResources(): Promise<any>;
readResource(uri: string): Promise<any>;
listPrompts(): Promise<any>;
getPrompt(name: string, args?: any): Promise<any>;
private ensureConnected;
}
//# sourceMappingURL=mcp-client.d.ts.map

1
dist/utils/mcp-client.d.ts.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"mcp-client.d.ts","sourceRoot":"","sources":["../../src/utils/mcp-client.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,GAAG,WAAW,GAAG,OAAO,CAAC;CAChD;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,SAAS,CAAkB;gBAEvB,MAAM,EAAE,eAAe;IAa7B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA8BxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC;IAQzB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IAc/C,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC;IAQ7B,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAavC,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC;IAQ3B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;YAczC,eAAe;CAK9B"}

96
dist/utils/mcp-client.js vendored Normal file
View File

@@ -0,0 +1,96 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MCPClient = void 0;
const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
const stdio_js_1 = require("@modelcontextprotocol/sdk/client/stdio.js");
const websocket_js_1 = require("@modelcontextprotocol/sdk/client/websocket.js");
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
class MCPClient {
constructor(config) {
this.connected = false;
this.config = config;
this.client = new index_js_1.Client({
name: 'n8n-mcp-client',
version: '1.0.0',
}, {
capabilities: {},
});
}
async connect() {
if (this.connected) {
return;
}
let transport;
switch (this.config.connectionType) {
case 'websocket':
const wsUrl = this.config.serverUrl.replace(/^http/, 'ws');
transport = new websocket_js_1.WebSocketClientTransport(new URL(wsUrl));
break;
case 'stdio':
const [command, ...args] = this.config.serverUrl.split(' ');
transport = new stdio_js_1.StdioClientTransport({
command,
args,
});
break;
default:
throw new Error(`HTTP transport is not yet supported for MCP clients`);
}
await this.client.connect(transport);
this.connected = true;
}
async disconnect() {
if (this.connected) {
await this.client.close();
this.connected = false;
}
}
async listTools() {
await this.ensureConnected();
return await this.client.request({ method: 'tools/list' }, types_js_1.ListToolsResultSchema);
}
async callTool(name, args) {
await this.ensureConnected();
return await this.client.request({
method: 'tools/call',
params: {
name,
arguments: args,
},
}, types_js_1.CallToolResultSchema);
}
async listResources() {
await this.ensureConnected();
return await this.client.request({ method: 'resources/list' }, types_js_1.ListResourcesResultSchema);
}
async readResource(uri) {
await this.ensureConnected();
return await this.client.request({
method: 'resources/read',
params: {
uri,
},
}, types_js_1.ReadResourceResultSchema);
}
async listPrompts() {
await this.ensureConnected();
return await this.client.request({ method: 'prompts/list' }, types_js_1.ListPromptsResultSchema);
}
async getPrompt(name, args) {
await this.ensureConnected();
return await this.client.request({
method: 'prompts/get',
params: {
name,
arguments: args,
},
}, types_js_1.GetPromptResultSchema);
}
async ensureConnected() {
if (!this.connected) {
await this.connect();
}
}
}
exports.MCPClient = MCPClient;
//# sourceMappingURL=mcp-client.js.map

1
dist/utils/mcp-client.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../../src/utils/mcp-client.ts"],"names":[],"mappings":"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"}

27
dist/utils/n8n-errors.d.ts vendored Normal file
View File

@@ -0,0 +1,27 @@
export declare class N8nApiError extends Error {
statusCode?: number | undefined;
code?: string | undefined;
details?: unknown | undefined;
constructor(message: string, statusCode?: number | undefined, code?: string | undefined, details?: unknown | undefined);
}
export declare class N8nAuthenticationError extends N8nApiError {
constructor(message?: string);
}
export declare class N8nNotFoundError extends N8nApiError {
constructor(resource: string, id?: string);
}
export declare class N8nValidationError extends N8nApiError {
constructor(message: string, details?: unknown);
}
export declare class N8nRateLimitError extends N8nApiError {
constructor(retryAfter?: number);
}
export declare class N8nServerError extends N8nApiError {
constructor(message?: string, statusCode?: number);
}
export declare function handleN8nApiError(error: unknown): N8nApiError;
export declare function formatExecutionError(executionId: string, workflowId?: string): string;
export declare function formatNoExecutionError(): string;
export declare function getUserFriendlyErrorMessage(error: N8nApiError): string;
export declare function logN8nError(error: N8nApiError, context?: string): void;
//# sourceMappingURL=n8n-errors.d.ts.map

1
dist/utils/n8n-errors.d.ts.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"n8n-errors.d.ts","sourceRoot":"","sources":["../../src/utils/n8n-errors.ts"],"names":[],"mappings":"AAIA,qBAAa,WAAY,SAAQ,KAAK;IAG3B,UAAU,CAAC,EAAE,MAAM;IACnB,IAAI,CAAC,EAAE,MAAM;IACb,OAAO,CAAC,EAAE,OAAO;gBAHxB,OAAO,EAAE,MAAM,EACR,UAAU,CAAC,EAAE,MAAM,YAAA,EACnB,IAAI,CAAC,EAAE,MAAM,YAAA,EACb,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,sBAAuB,SAAQ,WAAW;gBACzC,OAAO,SAA0B;CAI9C;AAED,qBAAa,gBAAiB,SAAQ,WAAW;gBACnC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM;CAK1C;AAED,qBAAa,kBAAmB,SAAQ,WAAW;gBACrC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO;CAI/C;AAED,qBAAa,iBAAkB,SAAQ,WAAW;gBACpC,UAAU,CAAC,EAAE,MAAM;CAOhC;AAED,qBAAa,cAAe,SAAQ,WAAW;gBACjC,OAAO,SAA0B,EAAE,UAAU,SAAM;CAIhE;AAGD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAuC7D;AAQD,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAGrF;AAMD,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAGD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAmBtE;AAGD,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAiBtE"}

138
dist/utils/n8n-errors.js vendored Normal file
View File

@@ -0,0 +1,138 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.N8nServerError = exports.N8nRateLimitError = exports.N8nValidationError = exports.N8nNotFoundError = exports.N8nAuthenticationError = exports.N8nApiError = void 0;
exports.handleN8nApiError = handleN8nApiError;
exports.formatExecutionError = formatExecutionError;
exports.formatNoExecutionError = formatNoExecutionError;
exports.getUserFriendlyErrorMessage = getUserFriendlyErrorMessage;
exports.logN8nError = logN8nError;
const logger_1 = require("./logger");
class N8nApiError extends Error {
constructor(message, statusCode, code, details) {
super(message);
this.statusCode = statusCode;
this.code = code;
this.details = details;
this.name = 'N8nApiError';
}
}
exports.N8nApiError = N8nApiError;
class N8nAuthenticationError extends N8nApiError {
constructor(message = 'Authentication failed') {
super(message, 401, 'AUTHENTICATION_ERROR');
this.name = 'N8nAuthenticationError';
}
}
exports.N8nAuthenticationError = N8nAuthenticationError;
class N8nNotFoundError extends N8nApiError {
constructor(resource, id) {
const message = id ? `${resource} with ID ${id} not found` : `${resource} not found`;
super(message, 404, 'NOT_FOUND');
this.name = 'N8nNotFoundError';
}
}
exports.N8nNotFoundError = N8nNotFoundError;
class N8nValidationError extends N8nApiError {
constructor(message, details) {
super(message, 400, 'VALIDATION_ERROR', details);
this.name = 'N8nValidationError';
}
}
exports.N8nValidationError = N8nValidationError;
class N8nRateLimitError extends N8nApiError {
constructor(retryAfter) {
const message = retryAfter
? `Rate limit exceeded. Retry after ${retryAfter} seconds`
: 'Rate limit exceeded';
super(message, 429, 'RATE_LIMIT_ERROR', { retryAfter });
this.name = 'N8nRateLimitError';
}
}
exports.N8nRateLimitError = N8nRateLimitError;
class N8nServerError extends N8nApiError {
constructor(message = 'Internal server error', statusCode = 500) {
super(message, statusCode, 'SERVER_ERROR');
this.name = 'N8nServerError';
}
}
exports.N8nServerError = N8nServerError;
function handleN8nApiError(error) {
if (error instanceof N8nApiError) {
return error;
}
if (error instanceof Error) {
const axiosError = error;
if (axiosError.response) {
const { status, data } = axiosError.response;
const message = data?.message || axiosError.message;
switch (status) {
case 401:
return new N8nAuthenticationError(message);
case 404:
return new N8nNotFoundError('Resource', message);
case 400:
return new N8nValidationError(message, data);
case 429:
const retryAfter = axiosError.response.headers['retry-after'];
return new N8nRateLimitError(retryAfter ? parseInt(retryAfter) : undefined);
default:
if (status >= 500) {
return new N8nServerError(message, status);
}
return new N8nApiError(message, status, 'API_ERROR', data);
}
}
else if (axiosError.request) {
return new N8nApiError('No response from n8n server', undefined, 'NO_RESPONSE');
}
else {
return new N8nApiError(axiosError.message, undefined, 'REQUEST_ERROR');
}
}
return new N8nApiError('Unknown error occurred', undefined, 'UNKNOWN_ERROR', error);
}
function formatExecutionError(executionId, workflowId) {
const workflowPrefix = workflowId ? `Workflow ${workflowId} execution ` : 'Execution ';
return `${workflowPrefix}${executionId} failed. Use n8n_get_execution({id: '${executionId}', mode: 'preview'}) to investigate the error.`;
}
function formatNoExecutionError() {
return "Workflow failed to execute. Use n8n_list_executions to find recent executions, then n8n_get_execution with mode='preview' to investigate.";
}
function getUserFriendlyErrorMessage(error) {
switch (error.code) {
case 'AUTHENTICATION_ERROR':
return 'Failed to authenticate with n8n. Please check your API key.';
case 'NOT_FOUND':
return error.message;
case 'VALIDATION_ERROR':
return `Invalid request: ${error.message}`;
case 'RATE_LIMIT_ERROR':
return 'Too many requests. Please wait a moment and try again.';
case 'NO_RESPONSE':
return 'Unable to connect to n8n. Please check the server URL and ensure n8n is running.';
case 'SERVER_ERROR':
return error.message || 'n8n server error occurred';
default:
return error.message || 'An unexpected error occurred';
}
}
function logN8nError(error, context) {
const errorInfo = {
name: error.name,
message: error.message,
code: error.code,
statusCode: error.statusCode,
details: error.details,
context,
};
if (error.statusCode && error.statusCode >= 500) {
logger_1.logger.error('n8n API server error', errorInfo);
}
else if (error.statusCode && error.statusCode >= 400) {
logger_1.logger.warn('n8n API client error', errorInfo);
}
else {
logger_1.logger.error('n8n API error', errorInfo);
}
}
//# sourceMappingURL=n8n-errors.js.map

1
dist/utils/n8n-errors.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"n8n-errors.js","sourceRoot":"","sources":["../../src/utils/n8n-errors.ts"],"names":[],"mappings":"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"}

5
dist/utils/node-classification.d.ts vendored Normal file
View File

@@ -0,0 +1,5 @@
export declare function isStickyNote(nodeType: string): boolean;
export declare function isTriggerNode(nodeType: string): boolean;
export declare function isNonExecutableNode(nodeType: string): boolean;
export declare function requiresIncomingConnection(nodeType: string): boolean;
//# sourceMappingURL=node-classification.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"node-classification.d.ts","sourceRoot":"","sources":["../../src/utils/node-classification.ts"],"names":[],"mappings":"AA8BA,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAOtD;AAwBD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEvD;AAmBD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAI7D;AAqBD,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAapE"}

31
dist/utils/node-classification.js vendored Normal file
View File

@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isStickyNote = isStickyNote;
exports.isTriggerNode = isTriggerNode;
exports.isNonExecutableNode = isNonExecutableNode;
exports.requiresIncomingConnection = requiresIncomingConnection;
const node_type_utils_1 = require("./node-type-utils");
function isStickyNote(nodeType) {
const stickyNoteTypes = [
'n8n-nodes-base.stickyNote',
'nodes-base.stickyNote',
'@n8n/n8n-nodes-base.stickyNote'
];
return stickyNoteTypes.includes(nodeType);
}
function isTriggerNode(nodeType) {
return (0, node_type_utils_1.isTriggerNode)(nodeType);
}
function isNonExecutableNode(nodeType) {
return isStickyNote(nodeType);
}
function requiresIncomingConnection(nodeType) {
if (isNonExecutableNode(nodeType)) {
return false;
}
if (isTriggerNode(nodeType)) {
return false;
}
return true;
}
//# sourceMappingURL=node-classification.js.map

1
dist/utils/node-classification.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"node-classification.js","sourceRoot":"","sources":["../../src/utils/node-classification.ts"],"names":[],"mappings":";;AA8BA,oCAOC;AAwBD,sCAEC;AAmBD,kDAIC;AAqBD,gEAaC;AA7GD,uDAAuE;AAmBvE,SAAgB,YAAY,CAAC,QAAgB;IAC3C,MAAM,eAAe,GAAG;QACtB,2BAA2B;QAC3B,uBAAuB;QACvB,gCAAgC;KACjC,CAAC;IACF,OAAO,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC5C,CAAC;AAwBD,SAAgB,aAAa,CAAC,QAAgB;IAC5C,OAAO,IAAA,+BAAiB,EAAC,QAAQ,CAAC,CAAC;AACrC,CAAC;AAmBD,SAAgB,mBAAmB,CAAC,QAAgB;IAClD,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;AAGhC,CAAC;AAqBD,SAAgB,0BAA0B,CAAC,QAAgB;IAEzD,IAAI,mBAAmB,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;IAGD,IAAI,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAGD,OAAO,IAAI,CAAC;AACd,CAAC"}

21
dist/utils/node-source-extractor.d.ts vendored Normal file
View File

@@ -0,0 +1,21 @@
export interface NodeSourceInfo {
nodeType: string;
sourceCode: string;
credentialCode?: string;
packageInfo?: any;
location: string;
}
export declare class NodeSourceExtractor {
private n8nBasePaths;
extractNodeSource(nodeType: string): Promise<NodeSourceInfo>;
private parseNodeType;
private searchNodeInPath;
private searchInPnpm;
private searchWithGlobPattern;
private tryLoadNodeFile;
listAvailableNodes(category?: string, search?: string): Promise<any[]>;
private scanDirectoryForNodes;
private scanPnpmDirectory;
extractAIAgentNode(): Promise<NodeSourceInfo>;
}
//# sourceMappingURL=node-source-extractor.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"node-source-extractor.d.ts","sourceRoot":"","sources":["../../src/utils/node-source-extractor.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,YAAY,CAYF;IAKZ,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAyBlE,OAAO,CAAC,aAAa;YAkBP,gBAAgB;YAoEhB,YAAY;YA8CZ,qBAAqB;YAoErB,eAAe;IA4FvB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;YAiC9D,qBAAqB;YAsErB,iBAAiB;IA2BzB,kBAAkB,IAAI,OAAO,CAAC,cAAc,CAAC;CAIpD"}

377
dist/utils/node-source-extractor.js vendored Normal file
View File

@@ -0,0 +1,377 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.NodeSourceExtractor = void 0;
const fs = __importStar(require("fs/promises"));
const path = __importStar(require("path"));
const logger_1 = require("./logger");
class NodeSourceExtractor {
constructor() {
this.n8nBasePaths = [
'/usr/local/lib/node_modules/n8n/node_modules',
'/app/node_modules',
'/home/node/.n8n/custom/nodes',
'./node_modules',
'/var/lib/docker/volumes/n8n-mcp_n8n_modules/_data',
'/n8n-modules',
process.env.N8N_CUSTOM_EXTENSIONS || '',
path.join(process.cwd(), 'node_modules'),
].filter(Boolean);
}
async extractNodeSource(nodeType) {
logger_1.logger.info(`Extracting source code for node: ${nodeType}`);
const { packageName, nodeName } = this.parseNodeType(nodeType);
for (const basePath of this.n8nBasePaths) {
try {
const nodeInfo = await this.searchNodeInPath(basePath, packageName, nodeName);
if (nodeInfo) {
logger_1.logger.info(`Found node source at: ${nodeInfo.location}`);
return nodeInfo;
}
}
catch (error) {
logger_1.logger.debug(`Failed to search in ${basePath}: ${error}`);
}
}
throw new Error(`Node source code not found for: ${nodeType}`);
}
parseNodeType(nodeType) {
if (nodeType.includes('.')) {
const [pkg, node] = nodeType.split('.');
return { packageName: pkg, nodeName: node };
}
return { packageName: 'n8n-nodes-base', nodeName: nodeType };
}
async searchNodeInPath(basePath, packageName, nodeName) {
try {
const nodeNameVariants = [
nodeName,
nodeName.charAt(0).toUpperCase() + nodeName.slice(1),
nodeName.toLowerCase(),
nodeName.toUpperCase(),
];
for (const nameVariant of nodeNameVariants) {
const standardPatterns = [
`${packageName}/dist/nodes/${nameVariant}/${nameVariant}.node.js`,
`${packageName}/dist/nodes/${nameVariant}.node.js`,
`${packageName}/nodes/${nameVariant}/${nameVariant}.node.js`,
`${packageName}/nodes/${nameVariant}.node.js`,
`${nameVariant}/${nameVariant}.node.js`,
`${nameVariant}.node.js`,
];
const nestedPatterns = [
`${packageName}/dist/nodes/*/${nameVariant}/${nameVariant}.node.js`,
`${packageName}/dist/nodes/**/${nameVariant}/${nameVariant}.node.js`,
`${packageName}/nodes/*/${nameVariant}/${nameVariant}.node.js`,
`${packageName}/nodes/**/${nameVariant}/${nameVariant}.node.js`,
];
for (const pattern of standardPatterns) {
const fullPath = path.join(basePath, pattern);
const result = await this.tryLoadNodeFile(fullPath, packageName, nodeName, basePath);
if (result)
return result;
}
for (const pattern of nestedPatterns) {
const result = await this.searchWithGlobPattern(basePath, pattern, packageName, nodeName);
if (result)
return result;
}
}
if (basePath.includes('node_modules')) {
const pnpmPath = path.join(basePath, '.pnpm');
try {
await fs.access(pnpmPath);
const result = await this.searchInPnpm(pnpmPath, packageName, nodeName);
if (result)
return result;
}
catch {
}
}
}
catch (error) {
logger_1.logger.debug(`Error searching in path ${basePath}: ${error}`);
}
return null;
}
async searchInPnpm(pnpmPath, packageName, nodeName) {
try {
const entries = await fs.readdir(pnpmPath);
const packageEntries = entries.filter(entry => entry.includes(packageName.replace('/', '+')) ||
entry.includes(packageName));
for (const entry of packageEntries) {
const entryPath = path.join(pnpmPath, entry, 'node_modules', packageName);
const patterns = [
`dist/nodes/${nodeName}/${nodeName}.node.js`,
`dist/nodes/${nodeName}.node.js`,
`dist/nodes/*/${nodeName}/${nodeName}.node.js`,
`dist/nodes/**/${nodeName}/${nodeName}.node.js`,
];
for (const pattern of patterns) {
if (pattern.includes('*')) {
const result = await this.searchWithGlobPattern(entryPath, pattern, packageName, nodeName);
if (result)
return result;
}
else {
const fullPath = path.join(entryPath, pattern);
const result = await this.tryLoadNodeFile(fullPath, packageName, nodeName, entryPath);
if (result)
return result;
}
}
}
}
catch (error) {
logger_1.logger.debug(`Error searching in pnpm directory: ${error}`);
}
return null;
}
async searchWithGlobPattern(basePath, pattern, packageName, nodeName) {
const parts = pattern.split('/');
const targetFile = `${nodeName}.node.js`;
async function searchDir(currentPath, remainingParts) {
if (remainingParts.length === 0)
return null;
const part = remainingParts[0];
const isLastPart = remainingParts.length === 1;
try {
if (isLastPart && part === targetFile) {
const fullPath = path.join(currentPath, part);
await fs.access(fullPath);
return fullPath;
}
const entries = await fs.readdir(currentPath, { withFileTypes: true });
for (const entry of entries) {
if (!entry.isDirectory() && !isLastPart)
continue;
if (part === '*' || part === '**') {
if (entry.isDirectory()) {
const result = await searchDir(path.join(currentPath, entry.name), part === '**' ? remainingParts : remainingParts.slice(1));
if (result)
return result;
}
}
else if (entry.name === part || (isLastPart && entry.name === targetFile)) {
if (isLastPart && entry.isFile()) {
return path.join(currentPath, entry.name);
}
else if (!isLastPart && entry.isDirectory()) {
const result = await searchDir(path.join(currentPath, entry.name), remainingParts.slice(1));
if (result)
return result;
}
}
}
}
catch {
}
return null;
}
const foundPath = await searchDir(basePath, parts);
if (foundPath) {
return this.tryLoadNodeFile(foundPath, packageName, nodeName, basePath);
}
return null;
}
async tryLoadNodeFile(fullPath, packageName, nodeName, packageBasePath) {
try {
const sourceCode = await fs.readFile(fullPath, 'utf-8');
let credentialCode;
const credentialPath = fullPath.replace('.node.js', '.credentials.js');
try {
credentialCode = await fs.readFile(credentialPath, 'utf-8');
}
catch {
const possibleCredentialPaths = [
path.join(packageBasePath, packageName, 'dist/credentials', `${nodeName}Api.credentials.js`),
path.join(packageBasePath, packageName, 'dist/credentials', `${nodeName}OAuth2Api.credentials.js`),
path.join(packageBasePath, packageName, 'credentials', `${nodeName}Api.credentials.js`),
path.join(packageBasePath, packageName, 'credentials', `${nodeName}OAuth2Api.credentials.js`),
path.join(packageBasePath, 'dist/credentials', `${nodeName}Api.credentials.js`),
path.join(packageBasePath, 'dist/credentials', `${nodeName}OAuth2Api.credentials.js`),
path.join(packageBasePath, 'credentials', `${nodeName}Api.credentials.js`),
path.join(packageBasePath, 'credentials', `${nodeName}OAuth2Api.credentials.js`),
path.join(path.dirname(path.dirname(fullPath)), 'credentials', `${nodeName}Api.credentials.js`),
path.join(path.dirname(path.dirname(fullPath)), 'credentials', `${nodeName}OAuth2Api.credentials.js`),
path.join(path.dirname(path.dirname(path.dirname(fullPath))), 'credentials', `${nodeName}Api.credentials.js`),
path.join(path.dirname(path.dirname(path.dirname(fullPath))), 'credentials', `${nodeName}OAuth2Api.credentials.js`),
];
const allCredentials = [];
for (const credPath of possibleCredentialPaths) {
try {
const content = await fs.readFile(credPath, 'utf-8');
allCredentials.push(content);
logger_1.logger.debug(`Found credential file at: ${credPath}`);
}
catch {
}
}
if (allCredentials.length > 0) {
credentialCode = allCredentials.join('\n\n// --- Next Credential File ---\n\n');
}
}
let packageInfo;
const possiblePackageJsonPaths = [
path.join(packageBasePath, 'package.json'),
path.join(packageBasePath, packageName, 'package.json'),
path.join(path.dirname(path.dirname(fullPath)), 'package.json'),
path.join(path.dirname(path.dirname(path.dirname(fullPath))), 'package.json'),
path.join(fullPath.split('/dist/')[0], 'package.json'),
path.join(fullPath.split('/nodes/')[0], 'package.json'),
];
for (const packageJsonPath of possiblePackageJsonPaths) {
try {
const packageJson = await fs.readFile(packageJsonPath, 'utf-8');
packageInfo = JSON.parse(packageJson);
logger_1.logger.debug(`Found package.json at: ${packageJsonPath}`);
break;
}
catch {
}
}
return {
nodeType: `${packageName}.${nodeName}`,
sourceCode,
credentialCode,
packageInfo,
location: fullPath,
};
}
catch {
return null;
}
}
async listAvailableNodes(category, search) {
const nodes = [];
const seenNodes = new Set();
for (const basePath of this.n8nBasePaths) {
try {
const n8nNodesBasePath = path.join(basePath, 'n8n-nodes-base', 'dist', 'nodes');
try {
await fs.access(n8nNodesBasePath);
await this.scanDirectoryForNodes(n8nNodesBasePath, nodes, category, search, seenNodes);
}
catch {
const altPath = path.join(basePath, 'n8n-nodes-base', 'nodes');
try {
await fs.access(altPath);
await this.scanDirectoryForNodes(altPath, nodes, category, search, seenNodes);
}
catch {
await this.scanDirectoryForNodes(basePath, nodes, category, search, seenNodes);
}
}
}
catch (error) {
logger_1.logger.debug(`Failed to scan ${basePath}: ${error}`);
}
}
return nodes;
}
async scanDirectoryForNodes(dirPath, nodes, category, search, seenNodes) {
try {
const entries = await fs.readdir(dirPath, { withFileTypes: true });
for (const entry of entries) {
if (entry.isFile() && entry.name.endsWith('.node.js')) {
try {
const fullPath = path.join(dirPath, entry.name);
const content = await fs.readFile(fullPath, 'utf-8');
const nameMatch = content.match(/displayName:\s*['"`]([^'"`]+)['"`]/);
const descriptionMatch = content.match(/description:\s*['"`]([^'"`]+)['"`]/);
if (nameMatch) {
const nodeName = entry.name.replace('.node.js', '');
if (seenNodes && seenNodes.has(nodeName)) {
continue;
}
const nodeInfo = {
name: nodeName,
displayName: nameMatch[1],
description: descriptionMatch ? descriptionMatch[1] : '',
location: fullPath,
};
if (category && !nodeInfo.displayName.toLowerCase().includes(category.toLowerCase())) {
continue;
}
if (search && !nodeInfo.displayName.toLowerCase().includes(search.toLowerCase()) &&
!nodeInfo.description.toLowerCase().includes(search.toLowerCase())) {
continue;
}
nodes.push(nodeInfo);
if (seenNodes) {
seenNodes.add(nodeName);
}
}
}
catch {
}
}
else if (entry.isDirectory()) {
if (entry.name === '.pnpm') {
await this.scanPnpmDirectory(path.join(dirPath, entry.name), nodes, category, search, seenNodes);
}
else if (entry.name !== 'node_modules') {
await this.scanDirectoryForNodes(path.join(dirPath, entry.name), nodes, category, search, seenNodes);
}
}
}
}
catch (error) {
logger_1.logger.debug(`Error scanning directory ${dirPath}: ${error}`);
}
}
async scanPnpmDirectory(pnpmPath, nodes, category, search, seenNodes) {
try {
const entries = await fs.readdir(pnpmPath);
for (const entry of entries) {
const entryPath = path.join(pnpmPath, entry, 'node_modules');
try {
await fs.access(entryPath);
await this.scanDirectoryForNodes(entryPath, nodes, category, search, seenNodes);
}
catch {
}
}
}
catch (error) {
logger_1.logger.debug(`Error scanning pnpm directory ${pnpmPath}: ${error}`);
}
}
async extractAIAgentNode() {
return this.extractNodeSource('@n8n/n8n-nodes-langchain.Agent');
}
}
exports.NodeSourceExtractor = NodeSourceExtractor;
//# sourceMappingURL=node-source-extractor.js.map

File diff suppressed because one or more lines are too long

16
dist/utils/node-type-normalizer.d.ts vendored Normal file
View File

@@ -0,0 +1,16 @@
export interface NodeTypeNormalizationResult {
original: string;
normalized: string;
wasNormalized: boolean;
package: 'base' | 'langchain' | 'community' | 'unknown';
}
export declare class NodeTypeNormalizer {
static normalizeToFullForm(type: string): string;
static normalizeWithDetails(type: string): NodeTypeNormalizationResult;
private static detectPackage;
static normalizeBatch(types: string[]): Map<string, string>;
static normalizeWorkflowNodeTypes(workflow: any): any;
static isFullForm(type: string): boolean;
static isShortForm(type: string): boolean;
}
//# sourceMappingURL=node-type-normalizer.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"node-type-normalizer.d.ts","sourceRoot":"","sources":["../../src/utils/node-type-normalizer.ts"],"names":[],"mappings":"AA2CA,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;CACzD;AAED,qBAAa,kBAAkB;IAyB7B,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAuChD,MAAM,CAAC,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,2BAA2B;IAkBtE,OAAO,CAAC,MAAM,CAAC,aAAa;IAuB5B,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IA8B3D,MAAM,CAAC,0BAA0B,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG;IAoBrD,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAkBxC,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;CAU1C"}

75
dist/utils/node-type-normalizer.js vendored Normal file
View File

@@ -0,0 +1,75 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NodeTypeNormalizer = void 0;
class NodeTypeNormalizer {
static normalizeToFullForm(type) {
if (!type || typeof type !== 'string') {
return type;
}
if (type.startsWith('n8n-nodes-base.')) {
return type.replace(/^n8n-nodes-base\./, 'nodes-base.');
}
if (type.startsWith('@n8n/n8n-nodes-langchain.')) {
return type.replace(/^@n8n\/n8n-nodes-langchain\./, 'nodes-langchain.');
}
if (type.startsWith('n8n-nodes-langchain.')) {
return type.replace(/^n8n-nodes-langchain\./, 'nodes-langchain.');
}
return type;
}
static normalizeWithDetails(type) {
const original = type;
const normalized = this.normalizeToFullForm(type);
return {
original,
normalized,
wasNormalized: original !== normalized,
package: this.detectPackage(normalized)
};
}
static detectPackage(type) {
if (type.startsWith('nodes-base.') || type.startsWith('n8n-nodes-base.'))
return 'base';
if (type.startsWith('nodes-langchain.') || type.startsWith('@n8n/n8n-nodes-langchain.') || type.startsWith('n8n-nodes-langchain.'))
return 'langchain';
if (type.includes('.'))
return 'community';
return 'unknown';
}
static normalizeBatch(types) {
const result = new Map();
for (const type of types) {
result.set(type, this.normalizeToFullForm(type));
}
return result;
}
static normalizeWorkflowNodeTypes(workflow) {
if (!workflow?.nodes || !Array.isArray(workflow.nodes)) {
return workflow;
}
return {
...workflow,
nodes: workflow.nodes.map((node) => ({
...node,
type: this.normalizeToFullForm(node.type)
}))
};
}
static isFullForm(type) {
if (!type || typeof type !== 'string') {
return false;
}
return (type.startsWith('n8n-nodes-base.') ||
type.startsWith('@n8n/n8n-nodes-langchain.') ||
type.startsWith('n8n-nodes-langchain.'));
}
static isShortForm(type) {
if (!type || typeof type !== 'string') {
return false;
}
return (type.startsWith('nodes-base.') ||
type.startsWith('nodes-langchain.'));
}
}
exports.NodeTypeNormalizer = NodeTypeNormalizer;
//# sourceMappingURL=node-type-normalizer.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"node-type-normalizer.js","sourceRoot":"","sources":["../../src/utils/node-type-normalizer.ts"],"names":[],"mappings":"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"}

12
dist/utils/node-type-utils.d.ts vendored Normal file
View File

@@ -0,0 +1,12 @@
export declare function normalizeNodeType(type: string): string;
export declare function denormalizeNodeType(type: string, packageType: 'base' | 'langchain'): string;
export declare function extractNodeName(type: string): string;
export declare function getNodePackage(type: string): string | null;
export declare function isBaseNode(type: string): boolean;
export declare function isLangChainNode(type: string): boolean;
export declare function isValidNodeTypeFormat(type: string): boolean;
export declare function getNodeTypeVariations(type: string): string[];
export declare function isTriggerNode(nodeType: string): boolean;
export declare function isActivatableTrigger(nodeType: string): boolean;
export declare function getTriggerTypeDescription(nodeType: string): string;
//# sourceMappingURL=node-type-utils.d.ts.map

1
dist/utils/node-type-utils.d.ts.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"node-type-utils.d.ts","sourceRoot":"","sources":["../../src/utils/node-type-utils.ts"],"names":[],"mappings":"AAcA,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMtD;AASD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAQ3F;AASD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASpD;AASD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS1D;AAKD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGhD;AAKD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGrD;AAMD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAa3D;AAUD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAwB5D;AAkBD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAsBvD;AAoBD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAW9D;AAQD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAiClE"}

131
dist/utils/node-type-utils.js vendored Normal file
View File

@@ -0,0 +1,131 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.normalizeNodeType = normalizeNodeType;
exports.denormalizeNodeType = denormalizeNodeType;
exports.extractNodeName = extractNodeName;
exports.getNodePackage = getNodePackage;
exports.isBaseNode = isBaseNode;
exports.isLangChainNode = isLangChainNode;
exports.isValidNodeTypeFormat = isValidNodeTypeFormat;
exports.getNodeTypeVariations = getNodeTypeVariations;
exports.isTriggerNode = isTriggerNode;
exports.isActivatableTrigger = isActivatableTrigger;
exports.getTriggerTypeDescription = getTriggerTypeDescription;
function normalizeNodeType(type) {
if (!type)
return type;
return type
.replace(/^n8n-nodes-base\./, 'nodes-base.')
.replace(/^@n8n\/n8n-nodes-langchain\./, 'nodes-langchain.');
}
function denormalizeNodeType(type, packageType) {
if (!type)
return type;
if (packageType === 'base') {
return type.replace(/^nodes-base\./, 'n8n-nodes-base.');
}
return type.replace(/^nodes-langchain\./, '@n8n/n8n-nodes-langchain.');
}
function extractNodeName(type) {
if (!type)
return '';
const normalized = normalizeNodeType(type);
const parts = normalized.split('.');
return parts[parts.length - 1] || '';
}
function getNodePackage(type) {
if (!type || !type.includes('.'))
return null;
const normalized = normalizeNodeType(type);
const parts = normalized.split('.');
return parts[0] || null;
}
function isBaseNode(type) {
const normalized = normalizeNodeType(type);
return normalized.startsWith('nodes-base.');
}
function isLangChainNode(type) {
const normalized = normalizeNodeType(type);
return normalized.startsWith('nodes-langchain.');
}
function isValidNodeTypeFormat(type) {
if (!type || typeof type !== 'string')
return false;
if (!type.includes('.'))
return false;
const parts = type.split('.');
if (parts.length !== 2)
return false;
return parts[0].length > 0 && parts[1].length > 0;
}
function getNodeTypeVariations(type) {
const variations = [];
if (type.includes('.')) {
variations.push(normalizeNodeType(type));
const normalized = normalizeNodeType(type);
if (normalized.startsWith('nodes-base.')) {
variations.push(denormalizeNodeType(normalized, 'base'));
}
else if (normalized.startsWith('nodes-langchain.')) {
variations.push(denormalizeNodeType(normalized, 'langchain'));
}
}
else {
variations.push(`nodes-base.${type}`);
variations.push(`n8n-nodes-base.${type}`);
variations.push(`nodes-langchain.${type}`);
variations.push(`@n8n/n8n-nodes-langchain.${type}`);
}
return [...new Set(variations)];
}
function isTriggerNode(nodeType) {
const normalized = normalizeNodeType(nodeType);
const lowerType = normalized.toLowerCase();
if (lowerType.includes('trigger')) {
return true;
}
if (lowerType.includes('webhook') && !lowerType.includes('respond')) {
return true;
}
const specificTriggers = [
'nodes-base.start',
'nodes-base.manualTrigger',
'nodes-base.formTrigger'
];
return specificTriggers.includes(normalized);
}
function isActivatableTrigger(nodeType) {
const normalized = normalizeNodeType(nodeType);
const lowerType = normalized.toLowerCase();
if (lowerType.includes('executeworkflow')) {
return false;
}
return isTriggerNode(nodeType);
}
function getTriggerTypeDescription(nodeType) {
const normalized = normalizeNodeType(nodeType);
const lowerType = normalized.toLowerCase();
if (lowerType.includes('executeworkflow')) {
return 'Execute Workflow Trigger (invoked by other workflows)';
}
if (lowerType.includes('webhook')) {
return 'Webhook Trigger (HTTP requests)';
}
if (lowerType.includes('schedule') || lowerType.includes('cron')) {
return 'Schedule Trigger (time-based)';
}
if (lowerType.includes('manual') || normalized === 'nodes-base.start') {
return 'Manual Trigger (manual execution)';
}
if (lowerType.includes('email') || lowerType.includes('imap') || lowerType.includes('gmail')) {
return 'Email Trigger (polling)';
}
if (lowerType.includes('form')) {
return 'Form Trigger (form submissions)';
}
if (lowerType.includes('trigger')) {
return 'Trigger (event-based)';
}
return 'Unknown trigger type';
}
//# sourceMappingURL=node-type-utils.js.map

1
dist/utils/node-type-utils.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"node-type-utils.js","sourceRoot":"","sources":["../../src/utils/node-type-utils.ts"],"names":[],"mappings":"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"}

4
dist/utils/node-utils.d.ts vendored Normal file
View File

@@ -0,0 +1,4 @@
export declare function normalizeNodeType(nodeType: string): string;
export declare function getNodeTypeAlternatives(nodeType: string): string[];
export declare function getWorkflowNodeType(packageName: string, nodeType: string): string;
//# sourceMappingURL=node-utils.d.ts.map

1
dist/utils/node-utils.d.ts.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"node-utils.d.ts","sourceRoot":"","sources":["../../src/utils/node-utils.ts"],"names":[],"mappings":"AAYA,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAkB1D;AAQD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAiDlE;AAwDD,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAajF"}

81
dist/utils/node-utils.js vendored Normal file
View File

@@ -0,0 +1,81 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.normalizeNodeType = normalizeNodeType;
exports.getNodeTypeAlternatives = getNodeTypeAlternatives;
exports.getWorkflowNodeType = getWorkflowNodeType;
function normalizeNodeType(nodeType) {
if (nodeType.startsWith('n8n-nodes-base.')) {
return nodeType.replace('n8n-nodes-base.', 'nodes-base.');
}
if (nodeType.startsWith('@n8n/n8n-nodes-langchain.')) {
return nodeType.replace('@n8n/n8n-nodes-langchain.', 'nodes-langchain.');
}
if (nodeType.startsWith('n8n-nodes-langchain.')) {
return nodeType.replace('n8n-nodes-langchain.', 'nodes-langchain.');
}
return nodeType;
}
function getNodeTypeAlternatives(nodeType) {
if (!nodeType || typeof nodeType !== 'string' || nodeType.trim() === '') {
return [];
}
const alternatives = [];
alternatives.push(nodeType.toLowerCase());
if (nodeType.includes('.')) {
const [prefix, nodeName] = nodeType.split('.');
if (nodeName && nodeName.toLowerCase() !== nodeName) {
alternatives.push(`${prefix}.${nodeName.toLowerCase()}`);
}
if (nodeName && nodeName.toLowerCase() === nodeName && nodeName.length > 1) {
const camelCaseVariants = generateCamelCaseVariants(nodeName);
camelCaseVariants.forEach(variant => {
alternatives.push(`${prefix}.${variant}`);
});
}
}
if (!nodeType.includes('.')) {
alternatives.push(`nodes-base.${nodeType}`);
alternatives.push(`nodes-langchain.${nodeType}`);
const camelCaseVariants = generateCamelCaseVariants(nodeType);
camelCaseVariants.forEach(variant => {
alternatives.push(`nodes-base.${variant}`);
alternatives.push(`nodes-langchain.${variant}`);
});
}
const normalizedAlternatives = alternatives.map(alt => normalizeNodeType(alt));
return [...new Set([...alternatives, ...normalizedAlternatives])];
}
function generateCamelCaseVariants(str) {
const variants = [];
const patterns = [
/^(.+)(trigger|node|request|response)$/i,
/^(http|mysql|postgres|mongo|redis|mqtt|smtp|imap|ftp|ssh|api)(.+)$/i,
/^(google|microsoft|amazon|slack|discord|telegram)(.+)$/i,
];
for (const pattern of patterns) {
const match = str.toLowerCase().match(pattern);
if (match) {
const [, first, second] = match;
variants.push(first.toLowerCase() + second.charAt(0).toUpperCase() + second.slice(1).toLowerCase());
}
}
if (variants.length === 0) {
const words = str.split(/[-_\s]+/);
if (words.length > 1) {
const camelCase = words[0].toLowerCase() + words.slice(1).map(w => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join('');
variants.push(camelCase);
}
}
return variants;
}
function getWorkflowNodeType(packageName, nodeType) {
const nodeName = nodeType.split('.').pop() || nodeType;
if (packageName === 'n8n-nodes-base') {
return `n8n-nodes-base.${nodeName}`;
}
else if (packageName === '@n8n/n8n-nodes-langchain') {
return `@n8n/n8n-nodes-langchain.${nodeName}`;
}
return nodeType;
}
//# sourceMappingURL=node-utils.js.map

1
dist/utils/node-utils.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"node-utils.js","sourceRoot":"","sources":["../../src/utils/node-utils.ts"],"names":[],"mappings":";;AAYA,8CAkBC;AAQD,0DAiDC;AAwDD,kDAaC;AAhJD,SAAgB,iBAAiB,CAAC,QAAgB;IAEhD,IAAI,QAAQ,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAC3C,OAAO,QAAQ,CAAC,OAAO,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;IAC5D,CAAC;IAGD,IAAI,QAAQ,CAAC,UAAU,CAAC,2BAA2B,CAAC,EAAE,CAAC;QACrD,OAAO,QAAQ,CAAC,OAAO,CAAC,2BAA2B,EAAE,kBAAkB,CAAC,CAAC;IAC3E,CAAC;IAGD,IAAI,QAAQ,CAAC,UAAU,CAAC,sBAAsB,CAAC,EAAE,CAAC;QAChD,OAAO,QAAQ,CAAC,OAAO,CAAC,sBAAsB,EAAE,kBAAkB,CAAC,CAAC;IACtE,CAAC;IAGD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAQD,SAAgB,uBAAuB,CAAC,QAAgB;IAEtD,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACxE,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,YAAY,GAAa,EAAE,CAAC;IAGlC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;IAG1C,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAG/C,IAAI,QAAQ,IAAI,QAAQ,CAAC,WAAW,EAAE,KAAK,QAAQ,EAAE,CAAC;YACpD,YAAY,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAC3D,CAAC;QAID,IAAI,QAAQ,IAAI,QAAQ,CAAC,WAAW,EAAE,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAE3E,MAAM,iBAAiB,GAAG,yBAAyB,CAAC,QAAQ,CAAC,CAAC;YAC9D,iBAAiB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;gBAClC,YAAY,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC;YAC5C,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAGD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,YAAY,CAAC,IAAI,CAAC,cAAc,QAAQ,EAAE,CAAC,CAAC;QAC5C,YAAY,CAAC,IAAI,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;QAGjD,MAAM,iBAAiB,GAAG,yBAAyB,CAAC,QAAQ,CAAC,CAAC;QAC9D,iBAAiB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;YAClC,YAAY,CAAC,IAAI,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC;YAC3C,YAAY,CAAC,IAAI,CAAC,mBAAmB,OAAO,EAAE,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC;IAGD,MAAM,sBAAsB,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;IAG/E,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,YAAY,EAAE,GAAG,sBAAsB,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC;AAOD,SAAS,yBAAyB,CAAC,GAAW;IAC5C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAG9B,MAAM,QAAQ,GAAG;QAEf,wCAAwC;QAExC,qEAAqE;QAErE,yDAAyD;KAC1D,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC;YAEhC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QACtG,CAAC;IACH,CAAC;IAGD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAE1B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAChE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CACrD,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACX,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAcD,SAAgB,mBAAmB,CAAC,WAAmB,EAAE,QAAgB;IAEvE,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,QAAQ,CAAC;IAGvD,IAAI,WAAW,KAAK,gBAAgB,EAAE,CAAC;QACrC,OAAO,kBAAkB,QAAQ,EAAE,CAAC;IACtC,CAAC;SAAM,IAAI,WAAW,KAAK,0BAA0B,EAAE,CAAC;QACtD,OAAO,4BAA4B,QAAQ,EAAE,CAAC;IAChD,CAAC;IAGD,OAAO,QAAQ,CAAC;AAClB,CAAC"}

14
dist/utils/npm-version-checker.d.ts vendored Normal file
View File

@@ -0,0 +1,14 @@
export interface VersionCheckResult {
currentVersion: string;
latestVersion: string | null;
isOutdated: boolean;
updateAvailable: boolean;
error: string | null;
checkedAt: Date;
updateCommand?: string;
}
export declare function checkNpmVersion(forceRefresh?: boolean): Promise<VersionCheckResult>;
export declare function compareVersions(v1: string, v2: string): number;
export declare function clearVersionCheckCache(): void;
export declare function formatVersionMessage(result: VersionCheckResult): string;
//# sourceMappingURL=npm-version-checker.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"npm-version-checker.d.ts","sourceRoot":"","sources":["../../src/utils/npm-version-checker.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,IAAI,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAcD,wBAAsB,eAAe,CAAC,YAAY,GAAE,OAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA4GhG;AAUD,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAmB9D;AAKD,wBAAgB,sBAAsB,IAAI,IAAI,CAG7C;AAQD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAcvE"}

125
dist/utils/npm-version-checker.js vendored Normal file
View File

@@ -0,0 +1,125 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkNpmVersion = checkNpmVersion;
exports.compareVersions = compareVersions;
exports.clearVersionCheckCache = clearVersionCheckCache;
exports.formatVersionMessage = formatVersionMessage;
const logger_1 = require("./logger");
let versionCheckCache = null;
let lastCheckTime = 0;
const CACHE_TTL_MS = 1 * 60 * 60 * 1000;
async function checkNpmVersion(forceRefresh = false) {
const now = Date.now();
if (!forceRefresh && versionCheckCache && (now - lastCheckTime) < CACHE_TTL_MS) {
logger_1.logger.debug('Returning cached npm version check result');
return versionCheckCache;
}
const packageJson = require('../../package.json');
const currentVersion = packageJson.version;
try {
const response = await fetch('https://registry.npmjs.org/n8n-mcp/latest', {
headers: {
'Accept': 'application/json',
},
signal: AbortSignal.timeout(5000)
});
if (!response.ok) {
logger_1.logger.warn('Failed to fetch npm version info', {
status: response.status,
statusText: response.statusText
});
const result = {
currentVersion,
latestVersion: null,
isOutdated: false,
updateAvailable: false,
error: `npm registry returned ${response.status}`,
checkedAt: new Date()
};
versionCheckCache = result;
lastCheckTime = now;
return result;
}
let data;
try {
data = await response.json();
}
catch (error) {
throw new Error('Failed to parse npm registry response as JSON');
}
if (!data || typeof data !== 'object' || !('version' in data)) {
throw new Error('Invalid response format from npm registry');
}
const registryData = data;
const latestVersion = registryData.version;
if (!latestVersion || !/^\d+\.\d+\.\d+/.test(latestVersion)) {
throw new Error(`Invalid version format from npm registry: ${latestVersion}`);
}
const isOutdated = compareVersions(currentVersion, latestVersion) < 0;
const result = {
currentVersion,
latestVersion,
isOutdated,
updateAvailable: isOutdated,
error: null,
checkedAt: new Date(),
updateCommand: isOutdated ? `npm install -g n8n-mcp@${latestVersion}` : undefined
};
versionCheckCache = result;
lastCheckTime = now;
logger_1.logger.debug('npm version check completed', {
current: currentVersion,
latest: latestVersion,
outdated: isOutdated
});
return result;
}
catch (error) {
logger_1.logger.warn('Error checking npm version', {
error: error instanceof Error ? error.message : String(error)
});
const result = {
currentVersion,
latestVersion: null,
isOutdated: false,
updateAvailable: false,
error: error instanceof Error ? error.message : 'Unknown error',
checkedAt: new Date()
};
versionCheckCache = result;
lastCheckTime = now;
return result;
}
}
function compareVersions(v1, v2) {
const clean1 = v1.replace(/^v/, '');
const clean2 = v2.replace(/^v/, '');
const parts1 = clean1.split('.').map(n => parseInt(n, 10) || 0);
const parts2 = clean2.split('.').map(n => parseInt(n, 10) || 0);
for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
const p1 = parts1[i] || 0;
const p2 = parts2[i] || 0;
if (p1 < p2)
return -1;
if (p1 > p2)
return 1;
}
return 0;
}
function clearVersionCheckCache() {
versionCheckCache = null;
lastCheckTime = 0;
}
function formatVersionMessage(result) {
if (result.error) {
return `Version check failed: ${result.error}. Current version: ${result.currentVersion}`;
}
if (!result.latestVersion) {
return `Current version: ${result.currentVersion} (latest version unknown)`;
}
if (result.isOutdated) {
return `⚠️ Update available! Current: ${result.currentVersion} → Latest: ${result.latestVersion}`;
}
return `✓ You're up to date! Current version: ${result.currentVersion}`;
}
//# sourceMappingURL=npm-version-checker.js.map

1
dist/utils/npm-version-checker.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"npm-version-checker.js","sourceRoot":"","sources":["../../src/utils/npm-version-checker.ts"],"names":[],"mappings":"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"}

19
dist/utils/protocol-version.d.ts vendored Normal file
View File

@@ -0,0 +1,19 @@
export interface ClientInfo {
name?: string;
version?: string;
[key: string]: any;
}
export interface ProtocolNegotiationResult {
version: string;
isN8nClient: boolean;
reasoning: string;
}
export declare const STANDARD_PROTOCOL_VERSION = "2025-03-26";
export declare const N8N_PROTOCOL_VERSION = "2024-11-05";
export declare const SUPPORTED_VERSIONS: string[];
export declare function isN8nClient(clientInfo?: ClientInfo, userAgent?: string, headers?: Record<string, string | string[] | undefined>): boolean;
export declare function negotiateProtocolVersion(clientRequestedVersion?: string, clientInfo?: ClientInfo, userAgent?: string, headers?: Record<string, string | string[] | undefined>): ProtocolNegotiationResult;
export declare function isVersionSupported(version: string): boolean;
export declare function getCompatibleVersion(targetVersion?: string): string;
export declare function logProtocolNegotiation(result: ProtocolNegotiationResult, logger: any, context?: string): void;
//# sourceMappingURL=protocol-version.d.ts.map

1
dist/utils/protocol-version.d.ts.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"protocol-version.d.ts","sourceRoot":"","sources":["../../src/utils/protocol-version.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAKD,eAAO,MAAM,yBAAyB,eAAe,CAAC;AAKtD,eAAO,MAAM,oBAAoB,eAAe,CAAC;AAKjD,eAAO,MAAM,kBAAkB,UAI9B,CAAC;AAKF,wBAAgB,WAAW,CACzB,UAAU,CAAC,EAAE,UAAU,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GACtD,OAAO,CAqCT;AAKD,wBAAgB,wBAAwB,CACtC,sBAAsB,CAAC,EAAE,MAAM,EAC/B,UAAU,CAAC,EAAE,UAAU,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GACtD,yBAAyB,CAqC3B;AAKD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE3D;AAMD,wBAAgB,oBAAoB,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAWnE;AAKD,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,yBAAyB,EACjC,MAAM,EAAE,GAAG,EACX,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAYN"}

95
dist/utils/protocol-version.js vendored Normal file
View File

@@ -0,0 +1,95 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SUPPORTED_VERSIONS = exports.N8N_PROTOCOL_VERSION = exports.STANDARD_PROTOCOL_VERSION = void 0;
exports.isN8nClient = isN8nClient;
exports.negotiateProtocolVersion = negotiateProtocolVersion;
exports.isVersionSupported = isVersionSupported;
exports.getCompatibleVersion = getCompatibleVersion;
exports.logProtocolNegotiation = logProtocolNegotiation;
exports.STANDARD_PROTOCOL_VERSION = '2025-03-26';
exports.N8N_PROTOCOL_VERSION = '2024-11-05';
exports.SUPPORTED_VERSIONS = [
exports.STANDARD_PROTOCOL_VERSION,
exports.N8N_PROTOCOL_VERSION,
'2024-06-25',
];
function isN8nClient(clientInfo, userAgent, headers) {
if (clientInfo?.name) {
const clientName = clientInfo.name.toLowerCase();
if (clientName.includes('n8n') || clientName.includes('langchain')) {
return true;
}
}
if (userAgent) {
const ua = userAgent.toLowerCase();
if (ua.includes('n8n') || ua.includes('langchain')) {
return true;
}
}
if (headers) {
const headerValues = Object.values(headers).join(' ').toLowerCase();
if (headerValues.includes('n8n') || headerValues.includes('langchain')) {
return true;
}
if (headers['x-n8n-version'] || headers['x-langchain-version']) {
return true;
}
}
if (process.env.N8N_MODE === 'true') {
return true;
}
return false;
}
function negotiateProtocolVersion(clientRequestedVersion, clientInfo, userAgent, headers) {
const isN8n = isN8nClient(clientInfo, userAgent, headers);
if (isN8n) {
return {
version: exports.N8N_PROTOCOL_VERSION,
isN8nClient: true,
reasoning: 'n8n client detected, using n8n-compatible protocol version'
};
}
if (clientRequestedVersion && exports.SUPPORTED_VERSIONS.includes(clientRequestedVersion)) {
return {
version: clientRequestedVersion,
isN8nClient: false,
reasoning: `Using client-requested version: ${clientRequestedVersion}`
};
}
if (clientRequestedVersion) {
return {
version: exports.STANDARD_PROTOCOL_VERSION,
isN8nClient: false,
reasoning: `Client requested unsupported version ${clientRequestedVersion}, using standard version`
};
}
return {
version: exports.STANDARD_PROTOCOL_VERSION,
isN8nClient: false,
reasoning: 'No specific client detected, using standard protocol version'
};
}
function isVersionSupported(version) {
return exports.SUPPORTED_VERSIONS.includes(version);
}
function getCompatibleVersion(targetVersion) {
if (!targetVersion) {
return exports.STANDARD_PROTOCOL_VERSION;
}
if (exports.SUPPORTED_VERSIONS.includes(targetVersion)) {
return targetVersion;
}
return exports.STANDARD_PROTOCOL_VERSION;
}
function logProtocolNegotiation(result, logger, context) {
const logContext = context ? `[${context}] ` : '';
logger.info(`${logContext}Protocol version negotiated`, {
version: result.version,
isN8nClient: result.isN8nClient,
reasoning: result.reasoning
});
if (result.isN8nClient) {
logger.info(`${logContext}Using n8n-compatible protocol version for better integration`);
}
}
//# sourceMappingURL=protocol-version.js.map

1
dist/utils/protocol-version.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"protocol-version.js","sourceRoot":"","sources":["../../src/utils/protocol-version.ts"],"names":[],"mappings":"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"}

10
dist/utils/simple-cache.d.ts vendored Normal file
View File

@@ -0,0 +1,10 @@
export declare class SimpleCache {
private cache;
private cleanupTimer;
constructor();
get(key: string): any;
set(key: string, data: any, ttlSeconds?: number): void;
clear(): void;
destroy(): void;
}
//# sourceMappingURL=simple-cache.d.ts.map

1
dist/utils/simple-cache.d.ts.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"simple-cache.d.ts","sourceRoot":"","sources":["../../src/utils/simple-cache.ts"],"names":[],"mappings":"AAIA,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAqD;IAClE,OAAO,CAAC,YAAY,CAA+B;;IAYnD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG;IASrB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAE,MAAY,GAAG,IAAI;IAO3D,KAAK,IAAI,IAAI;IAQb,OAAO,IAAI,IAAI;CAOhB"}

42
dist/utils/simple-cache.js vendored Normal file
View File

@@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SimpleCache = void 0;
class SimpleCache {
constructor() {
this.cache = new Map();
this.cleanupTimer = null;
this.cleanupTimer = setInterval(() => {
const now = Date.now();
for (const [key, item] of this.cache.entries()) {
if (item.expires < now)
this.cache.delete(key);
}
}, 60000);
}
get(key) {
const item = this.cache.get(key);
if (!item || item.expires < Date.now()) {
this.cache.delete(key);
return null;
}
return item.data;
}
set(key, data, ttlSeconds = 300) {
this.cache.set(key, {
data,
expires: Date.now() + (ttlSeconds * 1000)
});
}
clear() {
this.cache.clear();
}
destroy() {
if (this.cleanupTimer) {
clearInterval(this.cleanupTimer);
this.cleanupTimer = null;
}
this.cache.clear();
}
}
exports.SimpleCache = SimpleCache;
//# sourceMappingURL=simple-cache.js.map

1
dist/utils/simple-cache.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"simple-cache.js","sourceRoot":"","sources":["../../src/utils/simple-cache.ts"],"names":[],"mappings":";;;AAIA,MAAa,WAAW;IAItB;QAHQ,UAAK,GAAG,IAAI,GAAG,EAA0C,CAAC;QAC1D,iBAAY,GAA0B,IAAI,CAAC;QAIjD,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC,GAAG,EAAE;YACnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;gBAC/C,IAAI,IAAI,CAAC,OAAO,GAAG,GAAG;oBAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjD,CAAC;QACH,CAAC,EAAE,KAAK,CAAC,CAAC;IACZ,CAAC;IAED,GAAG,CAAC,GAAW;QACb,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YACvC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,IAAS,EAAE,aAAqB,GAAG;QAClD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;YAClB,IAAI;YACJ,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC;SAC1C,CAAC,CAAC;IACL,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAMD,OAAO;QACL,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACjC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;CACF;AA7CD,kCA6CC"}

7
dist/utils/ssrf-protection.d.ts vendored Normal file
View File

@@ -0,0 +1,7 @@
export declare class SSRFProtection {
static validateWebhookUrl(urlString: string): Promise<{
valid: boolean;
reason?: string;
}>;
}
//# sourceMappingURL=ssrf-protection.d.ts.map

1
dist/utils/ssrf-protection.d.ts.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"ssrf-protection.d.ts","sourceRoot":"","sources":["../../src/utils/ssrf-protection.ts"],"names":[],"mappings":"AAoDA,qBAAa,cAAc;WAoBZ,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAC1D,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAC;CA+GH"}

118
dist/utils/ssrf-protection.js vendored Normal file
View File

@@ -0,0 +1,118 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SSRFProtection = void 0;
const url_1 = require("url");
const promises_1 = require("dns/promises");
const logger_1 = require("./logger");
const CLOUD_METADATA = new Set([
'169.254.169.254',
'169.254.170.2',
'metadata.google.internal',
'metadata',
'100.100.100.200',
'192.0.0.192',
]);
const LOCALHOST_PATTERNS = new Set([
'localhost',
'127.0.0.1',
'::1',
'0.0.0.0',
'localhost.localdomain',
]);
const PRIVATE_IP_RANGES = [
/^10\./,
/^192\.168\./,
/^172\.(1[6-9]|2[0-9]|3[0-1])\./,
/^169\.254\./,
/^127\./,
/^0\./,
];
class SSRFProtection {
static async validateWebhookUrl(urlString) {
try {
const url = new url_1.URL(urlString);
const mode = (process.env.WEBHOOK_SECURITY_MODE || 'strict');
if (!['http:', 'https:'].includes(url.protocol)) {
return { valid: false, reason: 'Invalid protocol. Only HTTP/HTTPS allowed.' };
}
let hostname = url.hostname.toLowerCase();
if (hostname.startsWith('[') && hostname.endsWith(']')) {
hostname = hostname.slice(1, -1);
}
if (CLOUD_METADATA.has(hostname)) {
logger_1.logger.warn('SSRF blocked: Cloud metadata endpoint', { hostname, mode });
return { valid: false, reason: 'Cloud metadata endpoint blocked' };
}
let resolvedIP;
try {
const { address } = await (0, promises_1.lookup)(hostname);
resolvedIP = address;
logger_1.logger.debug('DNS resolved for SSRF check', { hostname, resolvedIP, mode });
}
catch (error) {
logger_1.logger.warn('DNS resolution failed for webhook URL', {
hostname,
error: error instanceof Error ? error.message : String(error)
});
return { valid: false, reason: 'DNS resolution failed' };
}
if (CLOUD_METADATA.has(resolvedIP)) {
logger_1.logger.warn('SSRF blocked: Hostname resolves to cloud metadata IP', {
hostname,
resolvedIP,
mode
});
return { valid: false, reason: 'Hostname resolves to cloud metadata endpoint' };
}
if (mode === 'permissive') {
logger_1.logger.warn('SSRF protection in permissive mode (localhost and private IPs allowed)', {
hostname,
resolvedIP
});
return { valid: true };
}
const isLocalhost = LOCALHOST_PATTERNS.has(hostname) ||
resolvedIP === '::1' ||
resolvedIP.startsWith('127.');
if (mode === 'strict' && isLocalhost) {
logger_1.logger.warn('SSRF blocked: Localhost not allowed in strict mode', {
hostname,
resolvedIP
});
return { valid: false, reason: 'Localhost access is blocked in strict mode' };
}
if (mode === 'moderate' && isLocalhost) {
logger_1.logger.info('Localhost webhook allowed (moderate mode)', { hostname, resolvedIP });
return { valid: true };
}
if (PRIVATE_IP_RANGES.some(regex => regex.test(resolvedIP))) {
logger_1.logger.warn('SSRF blocked: Private IP address', { hostname, resolvedIP, mode });
return {
valid: false,
reason: mode === 'strict'
? 'Private IP addresses not allowed'
: 'Private IP addresses not allowed (use WEBHOOK_SECURITY_MODE=permissive if needed)'
};
}
if (resolvedIP === '::1' ||
resolvedIP === '::' ||
resolvedIP.startsWith('fe80:') ||
resolvedIP.startsWith('fc00:') ||
resolvedIP.startsWith('fd00:') ||
resolvedIP.startsWith('::ffff:')) {
logger_1.logger.warn('SSRF blocked: IPv6 private address', {
hostname,
resolvedIP,
mode
});
return { valid: false, reason: 'IPv6 private address not allowed' };
}
return { valid: true };
}
catch (error) {
return { valid: false, reason: 'Invalid URL format' };
}
}
}
exports.SSRFProtection = SSRFProtection;
//# sourceMappingURL=ssrf-protection.js.map

1
dist/utils/ssrf-protection.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"ssrf-protection.js","sourceRoot":"","sources":["../../src/utils/ssrf-protection.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,2 @@
export declare function resolveTemplateNodeTypes(nodeTypes: string[]): string[];
//# sourceMappingURL=template-node-resolver.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"template-node-resolver.d.ts","sourceRoot":"","sources":["../../src/utils/template-node-resolver.ts"],"names":[],"mappings":"AAoBA,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAgBtE"}

161
dist/utils/template-node-resolver.js vendored Normal file
View File

@@ -0,0 +1,161 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveTemplateNodeTypes = resolveTemplateNodeTypes;
const logger_1 = require("./logger");
function resolveTemplateNodeTypes(nodeTypes) {
const resolvedTypes = new Set();
for (const nodeType of nodeTypes) {
const variations = generateTemplateNodeVariations(nodeType);
variations.forEach(v => resolvedTypes.add(v));
}
const result = Array.from(resolvedTypes);
logger_1.logger.debug(`Resolved ${nodeTypes.length} input types to ${result.length} template variations`, {
input: nodeTypes,
output: result
});
return result;
}
function generateTemplateNodeVariations(nodeType) {
const variations = new Set();
if (nodeType.startsWith('n8n-nodes-base.') || nodeType.startsWith('@n8n/n8n-nodes-langchain.')) {
variations.add(nodeType);
return Array.from(variations);
}
if (nodeType.startsWith('nodes-base.')) {
const nodeName = nodeType.replace('nodes-base.', '');
variations.add(`n8n-nodes-base.${nodeName}`);
addCamelCaseVariations(variations, nodeName, 'n8n-nodes-base');
}
else if (nodeType.startsWith('nodes-langchain.')) {
const nodeName = nodeType.replace('nodes-langchain.', '');
variations.add(`@n8n/n8n-nodes-langchain.${nodeName}`);
addCamelCaseVariations(variations, nodeName, '@n8n/n8n-nodes-langchain');
}
else if (!nodeType.includes('.')) {
variations.add(`n8n-nodes-base.${nodeType}`);
addCamelCaseVariations(variations, nodeType, 'n8n-nodes-base');
variations.add(`@n8n/n8n-nodes-langchain.${nodeType}`);
addCamelCaseVariations(variations, nodeType, '@n8n/n8n-nodes-langchain');
addRelatedNodeTypes(variations, nodeType);
}
return Array.from(variations);
}
function addCamelCaseVariations(variations, nodeName, packagePrefix) {
const lowerName = nodeName.toLowerCase();
const patterns = [
{ suffix: 'trigger', capitalize: true },
{ suffix: 'Trigger', capitalize: false },
{ suffix: 'request', capitalize: true },
{ suffix: 'Request', capitalize: false },
{ suffix: 'database', capitalize: true },
{ suffix: 'Database', capitalize: false },
{ suffix: 'sheet', capitalize: true },
{ suffix: 'Sheet', capitalize: false },
{ suffix: 'sheets', capitalize: true },
{ suffix: 'Sheets', capitalize: false },
];
for (const pattern of patterns) {
const lowerSuffix = pattern.suffix.toLowerCase();
if (lowerName.endsWith(lowerSuffix)) {
const baseName = lowerName.slice(0, -lowerSuffix.length);
if (baseName) {
if (pattern.capitalize) {
const capitalizedSuffix = pattern.suffix.charAt(0).toUpperCase() + pattern.suffix.slice(1).toLowerCase();
variations.add(`${packagePrefix}.${baseName}${capitalizedSuffix}`);
}
else {
variations.add(`${packagePrefix}.${baseName}${pattern.suffix}`);
}
}
}
else if (!lowerName.includes(lowerSuffix)) {
if (pattern.capitalize) {
const capitalizedSuffix = pattern.suffix.charAt(0).toUpperCase() + pattern.suffix.slice(1).toLowerCase();
variations.add(`${packagePrefix}.${lowerName}${capitalizedSuffix}`);
}
}
}
const specificCases = {
'http': ['httpRequest'],
'httprequest': ['httpRequest'],
'mysql': ['mysql', 'mysqlDatabase'],
'postgres': ['postgres', 'postgresDatabase'],
'postgresql': ['postgres', 'postgresDatabase'],
'mongo': ['mongoDb', 'mongodb'],
'mongodb': ['mongoDb', 'mongodb'],
'google': ['googleSheets', 'googleDrive', 'googleCalendar'],
'googlesheet': ['googleSheets'],
'googlesheets': ['googleSheets'],
'microsoft': ['microsoftTeams', 'microsoftExcel', 'microsoftOutlook'],
'slack': ['slack'],
'discord': ['discord'],
'telegram': ['telegram'],
'webhook': ['webhook'],
'schedule': ['scheduleTrigger'],
'cron': ['cron', 'scheduleTrigger'],
'email': ['emailSend', 'emailReadImap', 'gmail'],
'gmail': ['gmail', 'gmailTrigger'],
'code': ['code'],
'javascript': ['code'],
'python': ['code'],
'js': ['code'],
'set': ['set'],
'if': ['if'],
'switch': ['switch'],
'merge': ['merge'],
'loop': ['splitInBatches'],
'split': ['splitInBatches', 'splitOut'],
'ai': ['openAi'],
'openai': ['openAi'],
'chatgpt': ['openAi'],
'gpt': ['openAi'],
'api': ['httpRequest', 'graphql', 'webhook'],
'csv': ['spreadsheetFile', 'readBinaryFile'],
'excel': ['microsoftExcel', 'spreadsheetFile'],
'spreadsheet': ['spreadsheetFile', 'googleSheets', 'microsoftExcel'],
};
const cases = specificCases[lowerName];
if (cases) {
cases.forEach(c => variations.add(`${packagePrefix}.${c}`));
}
}
function addRelatedNodeTypes(variations, nodeName) {
const lowerName = nodeName.toLowerCase();
const relatedTypes = {
'slack': ['slack', 'slackTrigger'],
'gmail': ['gmail', 'gmailTrigger'],
'telegram': ['telegram', 'telegramTrigger'],
'discord': ['discord', 'discordTrigger'],
'webhook': ['webhook', 'webhookTrigger'],
'http': ['httpRequest', 'webhook'],
'email': ['emailSend', 'emailReadImap', 'gmail', 'gmailTrigger'],
'google': ['googleSheets', 'googleDrive', 'googleCalendar', 'googleDocs'],
'microsoft': ['microsoftTeams', 'microsoftExcel', 'microsoftOutlook', 'microsoftOneDrive'],
'database': ['postgres', 'mysql', 'mongoDb', 'redis', 'postgresDatabase', 'mysqlDatabase'],
'db': ['postgres', 'mysql', 'mongoDb', 'redis'],
'sql': ['postgres', 'mysql', 'mssql'],
'nosql': ['mongoDb', 'redis', 'couchDb'],
'schedule': ['scheduleTrigger', 'cron'],
'time': ['scheduleTrigger', 'cron', 'wait'],
'file': ['readBinaryFile', 'writeBinaryFile', 'moveBinaryFile'],
'binary': ['readBinaryFile', 'writeBinaryFile', 'moveBinaryFile'],
'csv': ['spreadsheetFile', 'readBinaryFile'],
'excel': ['microsoftExcel', 'spreadsheetFile'],
'json': ['code', 'set'],
'transform': ['code', 'set', 'merge', 'splitInBatches'],
'ai': ['openAi', 'agent', 'lmChatOpenAi', 'lmChatAnthropic'],
'llm': ['openAi', 'agent', 'lmChatOpenAi', 'lmChatAnthropic', 'lmChatGoogleGemini'],
'agent': ['agent', 'toolAgent'],
'chat': ['chatTrigger', 'agent'],
};
const related = relatedTypes[lowerName];
if (related) {
related.forEach(r => {
variations.add(`n8n-nodes-base.${r}`);
if (['agent', 'toolAgent', 'chatTrigger', 'lmChatOpenAi', 'lmChatAnthropic', 'lmChatGoogleGemini'].includes(r)) {
variations.add(`@n8n/n8n-nodes-langchain.${r}`);
}
});
}
}
//# sourceMappingURL=template-node-resolver.js.map

File diff suppressed because one or more lines are too long

21
dist/utils/template-sanitizer.d.ts vendored Normal file
View File

@@ -0,0 +1,21 @@
export interface SanitizerConfig {
problematicTokens: string[];
tokenPatterns: RegExp[];
replacements: Map<string, string>;
}
export declare const defaultSanitizerConfig: SanitizerConfig;
export declare class TemplateSanitizer {
private config;
constructor(config?: SanitizerConfig);
addProblematicToken(token: string): void;
addTokenPattern(pattern: RegExp, replacement: string): void;
sanitizeWorkflow(workflow: any): {
sanitized: any;
wasModified: boolean;
};
needsSanitization(workflow: any): boolean;
detectTokens(workflow: any): string[];
private sanitizeObject;
private replaceTokens;
}
//# sourceMappingURL=template-sanitizer.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"template-sanitizer.d.ts","sourceRoot":"","sources":["../../src/utils/template-sanitizer.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,eAAe;IAC9B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAKD,eAAO,MAAM,sBAAsB,EAAE,eAoBpC,CAAC;AAKF,qBAAa,iBAAiB;IAChB,OAAO,CAAC,MAAM;gBAAN,MAAM,GAAE,eAAwC;IAKpE,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAUxC,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAW3D,gBAAgB,CAAC,QAAQ,EAAE,GAAG,GAAG;QAAE,SAAS,EAAE,GAAG,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE;IA2BzE,iBAAiB,CAAC,QAAQ,EAAE,GAAG,GAAG,OAAO;IAwBzC,YAAY,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM,EAAE;IAuBrC,OAAO,CAAC,cAAc;IAetB,OAAO,CAAC,aAAa;CAuBtB"}

126
dist/utils/template-sanitizer.js vendored Normal file
View File

@@ -0,0 +1,126 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TemplateSanitizer = exports.defaultSanitizerConfig = void 0;
const logger_1 = require("./logger");
exports.defaultSanitizerConfig = {
problematicTokens: [],
tokenPatterns: [
/apify_api_[A-Za-z0-9]+/g,
/sk-[A-Za-z0-9]+/g,
/pat[A-Za-z0-9_]{40,}/g,
/ghp_[A-Za-z0-9]{36,}/g,
/gho_[A-Za-z0-9]{36,}/g,
/Bearer\s+[A-Za-z0-9\-._~+\/]+=*/g
],
replacements: new Map([
['apify_api_', 'apify_api_YOUR_TOKEN_HERE'],
['sk-', 'sk-YOUR_OPENAI_KEY_HERE'],
['pat', 'patYOUR_AIRTABLE_TOKEN_HERE'],
['ghp_', 'ghp_YOUR_GITHUB_TOKEN_HERE'],
['gho_', 'gho_YOUR_GITHUB_TOKEN_HERE'],
['Bearer ', 'Bearer YOUR_TOKEN_HERE']
])
};
class TemplateSanitizer {
constructor(config = exports.defaultSanitizerConfig) {
this.config = config;
}
addProblematicToken(token) {
if (!this.config.problematicTokens.includes(token)) {
this.config.problematicTokens.push(token);
logger_1.logger.info(`Added problematic token to sanitizer: ${token.substring(0, 10)}...`);
}
}
addTokenPattern(pattern, replacement) {
this.config.tokenPatterns.push(pattern);
const prefix = pattern.source.match(/^([^[]+)/)?.[1] || '';
if (prefix) {
this.config.replacements.set(prefix, replacement);
}
}
sanitizeWorkflow(workflow) {
if (!workflow) {
return { sanitized: workflow, wasModified: false };
}
const original = JSON.stringify(workflow);
let sanitized = this.sanitizeObject(workflow);
if (sanitized && sanitized.pinData) {
delete sanitized.pinData;
}
if (sanitized && sanitized.executionId) {
delete sanitized.executionId;
}
if (sanitized && sanitized.staticData) {
delete sanitized.staticData;
}
const wasModified = JSON.stringify(sanitized) !== original;
return { sanitized, wasModified };
}
needsSanitization(workflow) {
const workflowStr = JSON.stringify(workflow);
for (const token of this.config.problematicTokens) {
if (workflowStr.includes(token)) {
return true;
}
}
for (const pattern of this.config.tokenPatterns) {
pattern.lastIndex = 0;
if (pattern.test(workflowStr)) {
return true;
}
}
return false;
}
detectTokens(workflow) {
const workflowStr = JSON.stringify(workflow);
const detectedTokens = [];
for (const token of this.config.problematicTokens) {
if (workflowStr.includes(token)) {
detectedTokens.push(token);
}
}
for (const pattern of this.config.tokenPatterns) {
pattern.lastIndex = 0;
const matches = workflowStr.match(pattern);
if (matches) {
detectedTokens.push(...matches);
}
}
return [...new Set(detectedTokens)];
}
sanitizeObject(obj) {
if (typeof obj === 'string') {
return this.replaceTokens(obj);
}
else if (Array.isArray(obj)) {
return obj.map(item => this.sanitizeObject(item));
}
else if (obj && typeof obj === 'object') {
const result = {};
for (const key in obj) {
result[key] = this.sanitizeObject(obj[key]);
}
return result;
}
return obj;
}
replaceTokens(str) {
let result = str;
this.config.problematicTokens.forEach(token => {
result = result.replace(new RegExp(token, 'g'), 'YOUR_API_TOKEN_HERE');
});
this.config.tokenPatterns.forEach(pattern => {
result = result.replace(pattern, (match) => {
for (const [prefix, replacement] of this.config.replacements) {
if (match.startsWith(prefix)) {
return replacement;
}
}
return 'YOUR_TOKEN_HERE';
});
});
return result;
}
}
exports.TemplateSanitizer = TemplateSanitizer;
//# sourceMappingURL=template-sanitizer.js.map

1
dist/utils/template-sanitizer.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"template-sanitizer.js","sourceRoot":"","sources":["../../src/utils/template-sanitizer.ts"],"names":[],"mappings":"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"}

9
dist/utils/url-detector.d.ts vendored Normal file
View File

@@ -0,0 +1,9 @@
import { Request } from 'express';
export declare function detectBaseUrl(req: Request | null, host: string, port: number): string;
export declare function getStartupBaseUrl(host: string, port: number): string;
export declare function formatEndpointUrls(baseUrl: string): {
health: string;
mcp: string;
root: string;
};
//# sourceMappingURL=url-detector.d.ts.map

1
dist/utils/url-detector.d.ts.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"url-detector.d.ts","sourceRoot":"","sources":["../../src/utils/url-detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AA8BlC,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAyDrF;AAMD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpE;AAKD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd,CAMA"}

79
dist/utils/url-detector.js vendored Normal file
View File

@@ -0,0 +1,79 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.detectBaseUrl = detectBaseUrl;
exports.getStartupBaseUrl = getStartupBaseUrl;
exports.formatEndpointUrls = formatEndpointUrls;
const logger_1 = require("./logger");
function isValidHostname(host) {
return /^[a-zA-Z0-9.-]+(:[0-9]+)?$/.test(host) && host.length < 256;
}
function isValidUrl(url) {
try {
const parsed = new URL(url);
return parsed.protocol === 'http:' || parsed.protocol === 'https:';
}
catch {
return false;
}
}
function detectBaseUrl(req, host, port) {
try {
const configuredUrl = process.env.BASE_URL || process.env.PUBLIC_URL;
if (configuredUrl) {
if (isValidUrl(configuredUrl)) {
logger_1.logger.debug('Using configured BASE_URL/PUBLIC_URL', { url: configuredUrl });
return configuredUrl.replace(/\/$/, '');
}
else {
logger_1.logger.warn('Invalid BASE_URL/PUBLIC_URL configured, falling back to auto-detection', { url: configuredUrl });
}
}
if (req && process.env.TRUST_PROXY && Number(process.env.TRUST_PROXY) > 0) {
const proto = req.get('X-Forwarded-Proto') || req.protocol || 'http';
const forwardedHost = req.get('X-Forwarded-Host');
const hostHeader = req.get('Host');
const detectedHost = forwardedHost || hostHeader;
if (detectedHost && isValidHostname(detectedHost)) {
const baseUrl = `${proto}://${detectedHost}`;
logger_1.logger.debug('Detected URL from proxy headers', {
proto,
forwardedHost,
hostHeader,
baseUrl
});
return baseUrl;
}
else if (detectedHost) {
logger_1.logger.warn('Invalid hostname detected in proxy headers, using fallback', { detectedHost });
}
}
const displayHost = host === '0.0.0.0' ? 'localhost' : host;
const protocol = 'http';
const needsPort = port !== 80;
const baseUrl = needsPort ?
`${protocol}://${displayHost}:${port}` :
`${protocol}://${displayHost}`;
logger_1.logger.debug('Using fallback URL from host/port', {
host,
displayHost,
port,
baseUrl
});
return baseUrl;
}
catch (error) {
logger_1.logger.error('Error detecting base URL, using fallback', error);
return `http://localhost:${port}`;
}
}
function getStartupBaseUrl(host, port) {
return detectBaseUrl(null, host, port);
}
function formatEndpointUrls(baseUrl) {
return {
health: `${baseUrl}/health`,
mcp: `${baseUrl}/mcp`,
root: baseUrl
};
}
//# sourceMappingURL=url-detector.js.map

1
dist/utils/url-detector.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"url-detector.js","sourceRoot":"","sources":["../../src/utils/url-detector.ts"],"names":[],"mappings":"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"}

Some files were not shown because too many files have changed in this diff Show More