From 934124fa7b7af4487fa53062724beb95c1900a1e Mon Sep 17 00:00:00 2001 From: thesved <2893181+thesved@users.noreply.github.com> Date: Thu, 4 Dec 2025 15:46:29 +0200 Subject: [PATCH 1/5] Fix: n8n_update_partial_workflow fails with additional properties error (#466) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The n8n Public API uses strict JSON schema validation (additionalProperties: false). The cleanWorkflowForUpdate() function was sending properties that the API rejects. Changes: - Filter out activeVersionId and activeVersion (read-only fields) - Update settings whitelist to include all 12 properties from n8n OpenAPI spec - Simplify settings handling (empty {} is now accepted by n8n API) Source of truth for allowed properties: - https://github.com/n8n-io/n8n/blob/master/packages/cli/src/public-api/v1/handlers/workflows/spec/schemas/workflow.yml - https://github.com/n8n-io/n8n/blob/master/packages/cli/src/public-api/v1/handlers/workflows/spec/schemas/workflowSettings.yml Fixes #466 Conceived by Romuald Członkowski - www.aiadvisors.pl/en 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/services/n8n-validation.ts | 49 +++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/src/services/n8n-validation.ts b/src/services/n8n-validation.ts index 3371fde..ec866e5 100644 --- a/src/services/n8n-validation.ts +++ b/src/services/n8n-validation.ts @@ -149,6 +149,9 @@ export function cleanWorkflowForUpdate(workflow: Workflow): Partial { triggerCount, shared, active, + // Remove version-related read-only fields (Issue #466) + activeVersionId, + activeVersion, // Keep everything else ...cleanedWorkflow } = workflow as any; @@ -173,18 +176,24 @@ export function cleanWorkflowForUpdate(workflow: Workflow): Partial { // - OpenAPI spec: workflowSettings schema // - Tested on n8n.estyl.team (cloud) and localhost (self-hosted) - // Whitelisted settings properties from n8n OpenAPI spec + // Whitelisted settings properties from n8n Public API OpenAPI spec + // Source: https://github.com/n8n-io/n8n/blob/master/packages/cli/src/public-api/v1/handlers/workflows/spec/schemas/workflowSettings.yml + // + // CRITICAL: The n8n Public API uses strict JSON schema validation with + // additionalProperties: false. These 12 properties are accepted: const safeSettingsProperties = [ - 'saveExecutionProgress', - 'saveManualExecutions', - 'saveDataErrorExecution', - 'saveDataSuccessExecution', - 'executionTimeout', - 'errorWorkflow', - 'timezone', - 'executionOrder', - 'callerPolicy', - 'availableInMCP', + 'saveExecutionProgress', // boolean + 'saveManualExecutions', // boolean + 'saveDataErrorExecution', // string enum: 'all' | 'none' + 'saveDataSuccessExecution', // string enum: 'all' | 'none' + 'executionTimeout', // number (max: 3600) + 'errorWorkflow', // string (workflow ID) + 'timezone', // string (e.g., 'America/New_York') + 'executionOrder', // string (e.g., 'v1') + 'callerPolicy', // string enum: 'any' | 'none' | 'workflowsFromAList' | 'workflowsFromSameOwner' + 'callerIds', // string (comma-separated workflow IDs) + 'timeSavedPerExecution', // number (in minutes) + 'availableInMCP', // boolean (default: false) ]; if (cleanedWorkflow.settings && typeof cleanedWorkflow.settings === 'object') { @@ -196,18 +205,14 @@ export function cleanWorkflowForUpdate(workflow: Workflow): Partial { } } - // n8n API requires settings to be present but rejects empty settings objects. - // If no valid properties remain after filtering, include minimal default settings. - if (Object.keys(filteredSettings).length > 0) { - cleanedWorkflow.settings = filteredSettings; - } else { - // Provide minimal valid settings (executionOrder v1 is the modern default) - cleanedWorkflow.settings = { executionOrder: 'v1' as const }; - } + // n8n API behavior with settings: + // - The settings property is REQUIRED by the API + // - Empty settings objects {} are now accepted (n8n preserves existing settings) + // - Only whitelisted properties are accepted; others cause "additional properties" error + cleanedWorkflow.settings = filteredSettings; } else { - // No settings provided - include minimal default settings - // n8n API requires settings in workflow updates (v1 is the modern default) - cleanedWorkflow.settings = { executionOrder: 'v1' as const }; + // No settings provided - use empty object (required by API) + cleanedWorkflow.settings = {}; } return cleanedWorkflow; From a70d96a373ddc945e997af1db5b3499e58106a6f Mon Sep 17 00:00:00 2001 From: thesved <2893181+thesved@users.noreply.github.com> Date: Thu, 4 Dec 2025 19:49:18 +0200 Subject: [PATCH 2/5] Add version-aware settings filtering for n8n API compatibility This commit adds automatic detection of n8n server version and filters workflow settings properties based on what the target version supports. Changes: - Add n8n-version.ts service for version detection via /rest/settings - Fix nested response structure handling (data.data.versionCli) - Add N8nVersionInfo and N8nSettingsData types - Update N8nApiClient with getVersion() and version-aware filtering - Clean workflow settings before API update based on detected version Version compatibility: - n8n < 1.37.0: 7 core properties only - n8n 1.37.0+: adds executionOrder - n8n 1.119.0+: adds callerPolicy, callerIds, timeSavedPerExecution, availableInMCP Fixes #466 --- src/services/n8n-api-client.ts | 79 +++++- src/services/n8n-validation.ts | 97 +++---- src/services/n8n-version.ts | 225 +++++++++++++++ src/types/n8n-api.ts | 22 ++ tests/unit/services/n8n-validation.test.ts | 40 +-- tests/unit/services/n8n-version.test.ts | 313 +++++++++++++++++++++ 6 files changed, 684 insertions(+), 92 deletions(-) create mode 100644 src/services/n8n-version.ts create mode 100644 tests/unit/services/n8n-version.test.ts diff --git a/src/services/n8n-api-client.ts b/src/services/n8n-api-client.ts index a369d35..a697dbf 100644 --- a/src/services/n8n-api-client.ts +++ b/src/services/n8n-api-client.ts @@ -14,6 +14,7 @@ import { TagListParams, TagListResponse, HealthCheckResponse, + N8nVersionInfo, Variable, WebhookRequest, WorkflowExport, @@ -24,6 +25,11 @@ import { } from '../types/n8n-api'; import { handleN8nApiError, logN8nError } from '../utils/n8n-errors'; import { cleanWorkflowForCreate, cleanWorkflowForUpdate } from './n8n-validation'; +import { + fetchN8nVersion, + cleanSettingsForVersion, + getCachedVersion, +} from './n8n-version'; export interface N8nApiClientConfig { baseUrl: string; @@ -35,15 +41,19 @@ export interface N8nApiClientConfig { export class N8nApiClient { private client: AxiosInstance; private maxRetries: number; + private baseUrl: string; + private versionInfo: N8nVersionInfo | null = null; + private versionFetched = false; constructor(config: N8nApiClientConfig) { const { baseUrl, apiKey, timeout = 30000, maxRetries = 3 } = config; this.maxRetries = maxRetries; + this.baseUrl = baseUrl; // Ensure baseUrl ends with /api/v1 - const apiUrl = baseUrl.endsWith('/api/v1') - ? baseUrl + const apiUrl = baseUrl.endsWith('/api/v1') + ? baseUrl : `${baseUrl.replace(/\/$/, '')}/api/v1`; this.client = axios.create({ @@ -84,25 +94,52 @@ export class N8nApiClient { ); } + /** + * Get the n8n version, fetching it if not already cached + */ + async getVersion(): Promise { + if (!this.versionFetched) { + // Check if already cached globally + this.versionInfo = getCachedVersion(this.baseUrl); + if (!this.versionInfo) { + // Fetch from server + this.versionInfo = await fetchN8nVersion(this.baseUrl); + } + this.versionFetched = true; + } + return this.versionInfo; + } + + /** + * Get cached version info without fetching + */ + getCachedVersionInfo(): N8nVersionInfo | null { + return this.versionInfo; + } + // Health check to verify API connectivity async healthCheck(): Promise { try { // Try the standard healthz endpoint (available on all n8n instances) const baseUrl = this.client.defaults.baseURL || ''; const healthzUrl = baseUrl.replace(/\/api\/v\d+\/?$/, '') + '/healthz'; - + const response = await axios.get(healthzUrl, { timeout: 5000, validateStatus: (status) => status < 500 }); - + + // Also fetch version info (will be cached) + const versionInfo = await this.getVersion(); + if (response.status === 200 && response.data?.status === 'ok') { - return { + return { status: 'ok', - features: {} // Features detection would require additional endpoints + n8nVersion: versionInfo?.version, + features: {} }; } - + // If healthz doesn't work, fall back to API check throw new Error('healthz endpoint not available'); } catch (error) { @@ -110,8 +147,13 @@ export class N8nApiClient { // This is a fallback for older n8n versions try { await this.client.get('/workflows', { params: { limit: 1 } }); - return { + + // Still try to get version + const versionInfo = await this.getVersion(); + + return { status: 'ok', + n8nVersion: versionInfo?.version, features: {} }; } catch (fallbackError) { @@ -142,8 +184,25 @@ export class N8nApiClient { async updateWorkflow(id: string, workflow: Partial): Promise { try { - // First, try PUT method (newer n8n versions) + // Step 1: Basic cleaning (remove read-only fields, filter to known settings) const cleanedWorkflow = cleanWorkflowForUpdate(workflow as Workflow); + + // Step 2: Version-aware settings filtering for older n8n compatibility + // This prevents "additional properties" errors on n8n < 1.119.0 + const versionInfo = await this.getVersion(); + if (versionInfo) { + logger.debug(`Updating workflow with n8n version ${versionInfo.version}`); + // Apply version-specific filtering to settings + cleanedWorkflow.settings = cleanSettingsForVersion( + cleanedWorkflow.settings as Record, + versionInfo + ); + } else { + logger.warn('Could not determine n8n version, sending all known settings properties'); + // Without version info, we send all known properties (might fail on old n8n) + } + + // First, try PUT method (newer n8n versions) try { const response = await this.client.put(`/workflows/${id}`, cleanedWorkflow); return response.data; @@ -288,7 +347,7 @@ export class N8nApiClient { // Create a new axios instance for webhook requests to avoid API interceptors const webhookClient = axios.create({ baseURL: new URL('/', webhookUrl).toString(), - validateStatus: (status) => status < 500, // Don't throw on 4xx + validateStatus: (status: number) => status < 500, // Don't throw on 4xx }); const response = await webhookClient.request(config); diff --git a/src/services/n8n-validation.ts b/src/services/n8n-validation.ts index ec866e5..3fe3a15 100644 --- a/src/services/n8n-validation.ts +++ b/src/services/n8n-validation.ts @@ -116,102 +116,73 @@ export function cleanWorkflowForCreate(workflow: Partial): Partial { const { - // Remove read-only/computed fields + // Remove ALL read-only/computed fields (comprehensive list) id, createdAt, updatedAt, versionId, - versionCounter, // Added: n8n 1.118.1+ returns this but rejects it in updates + versionCounter, meta, staticData, - // Remove fields that cause API errors pinData, tags, - description, // Issue #431: n8n returns this field but rejects it in updates - // Remove additional fields that n8n API doesn't accept + description, isArchived, usedCredentials, sharedWithProjects, triggerCount, shared, active, - // Remove version-related read-only fields (Issue #466) activeVersionId, activeVersion, // Keep everything else ...cleanedWorkflow } = workflow as any; - // CRITICAL FIX for Issue #248: - // The n8n API has version-specific behavior for settings in workflow updates: - // - // PROBLEM: - // - Some versions reject updates with settings properties (community forum reports) - // - Properties like callerPolicy cause "additional properties" errors - // - Empty settings objects {} cause "additional properties" validation errors (Issue #431) - // - // SOLUTION: - // - Filter settings to only include whitelisted properties (OpenAPI spec) - // - If no settings after filtering, omit the property entirely (n8n API rejects empty objects) - // - Omitting the property prevents "additional properties" validation errors - // - Whitelisted properties prevent "additional properties" errors - // - // References: - // - Issue #431: Empty settings validation error - // - https://community.n8n.io/t/api-workflow-update-endpoint-doesnt-support-setting-callerpolicy/161916 - // - OpenAPI spec: workflowSettings schema - // - Tested on n8n.estyl.team (cloud) and localhost (self-hosted) - - // Whitelisted settings properties from n8n Public API OpenAPI spec - // Source: https://github.com/n8n-io/n8n/blob/master/packages/cli/src/public-api/v1/handlers/workflows/spec/schemas/workflowSettings.yml - // - // CRITICAL: The n8n Public API uses strict JSON schema validation with - // additionalProperties: false. These 12 properties are accepted: - const safeSettingsProperties = [ - 'saveExecutionProgress', // boolean - 'saveManualExecutions', // boolean - 'saveDataErrorExecution', // string enum: 'all' | 'none' - 'saveDataSuccessExecution', // string enum: 'all' | 'none' - 'executionTimeout', // number (max: 3600) - 'errorWorkflow', // string (workflow ID) - 'timezone', // string (e.g., 'America/New_York') - 'executionOrder', // string (e.g., 'v1') - 'callerPolicy', // string enum: 'any' | 'none' | 'workflowsFromAList' | 'workflowsFromSameOwner' - 'callerIds', // string (comma-separated workflow IDs) - 'timeSavedPerExecution', // number (in minutes) - 'availableInMCP', // boolean (default: false) - ]; + // ALL known settings properties accepted by n8n Public API (as of n8n 1.119.0+) + // This list is the UNION of all properties ever accepted by any n8n version + // Version-specific filtering is handled by N8nApiClient.updateWorkflow() + const ALL_KNOWN_SETTINGS_PROPERTIES = new Set([ + // Core properties (all versions) + 'saveExecutionProgress', + 'saveManualExecutions', + 'saveDataErrorExecution', + 'saveDataSuccessExecution', + 'executionTimeout', + 'errorWorkflow', + 'timezone', + // Added in n8n 1.37.0 + 'executionOrder', + // Added in n8n 1.119.0 + 'callerPolicy', + 'callerIds', + 'timeSavedPerExecution', + 'availableInMCP', + ]); if (cleanedWorkflow.settings && typeof cleanedWorkflow.settings === 'object') { - // Filter to only safe properties - const filteredSettings: any = {}; - for (const key of safeSettingsProperties) { - if (key in cleanedWorkflow.settings) { - filteredSettings[key] = (cleanedWorkflow.settings as any)[key]; + // Filter to only known properties (security + prevent garbage) + const filteredSettings: Record = {}; + for (const [key, value] of Object.entries(cleanedWorkflow.settings)) { + if (ALL_KNOWN_SETTINGS_PROPERTIES.has(key)) { + filteredSettings[key] = value; } } - - // n8n API behavior with settings: - // - The settings property is REQUIRED by the API - // - Empty settings objects {} are now accepted (n8n preserves existing settings) - // - Only whitelisted properties are accepted; others cause "additional properties" error cleanedWorkflow.settings = filteredSettings; } else { - // No settings provided - use empty object (required by API) cleanedWorkflow.settings = {}; } diff --git a/src/services/n8n-version.ts b/src/services/n8n-version.ts new file mode 100644 index 0000000..3c6f279 --- /dev/null +++ b/src/services/n8n-version.ts @@ -0,0 +1,225 @@ +/** + * n8n Version Detection and Version-Aware Settings Filtering + * + * This module provides version detection for n8n instances and filters + * workflow settings based on what the target n8n version supports. + * + * VERSION HISTORY for workflowSettings in n8n Public API: + * - All versions: 7 core properties (saveExecutionProgress, saveManualExecutions, + * saveDataErrorExecution, saveDataSuccessExecution, executionTimeout, + * errorWorkflow, timezone) + * - 1.37.0+: Added executionOrder + * - 1.119.0+: Added callerPolicy, callerIds, timeSavedPerExecution, availableInMCP + * + * References: + * - https://github.com/n8n-io/n8n/pull/21297 (PR adding 4 new properties in 1.119.0) + * - https://community.n8n.io/t/n8n-api-update-workflow-does-not-accept-executionorder-setting/44512 + */ + +import axios from 'axios'; +import { logger } from '../utils/logger'; +import { N8nVersionInfo, N8nSettingsResponse } from '../types/n8n-api'; + +// Cache version info per base URL to avoid repeated API calls +const versionCache = new Map(); + +// Settings properties supported by each n8n version range +// These are CUMULATIVE - each version adds to the previous +const SETTINGS_BY_VERSION = { + // Core properties supported by all versions + core: [ + 'saveExecutionProgress', + 'saveManualExecutions', + 'saveDataErrorExecution', + 'saveDataSuccessExecution', + 'executionTimeout', + 'errorWorkflow', + 'timezone', + ], + // Added in n8n 1.37.0 + v1_37_0: [ + 'executionOrder', + ], + // Added in n8n 1.119.0 (PR #21297) + v1_119_0: [ + 'callerPolicy', + 'callerIds', + 'timeSavedPerExecution', + 'availableInMCP', + ], +}; + +/** + * Parse version string into structured version info + */ +export function parseVersion(versionString: string): N8nVersionInfo | null { + // Handle formats like "1.119.0", "1.37.0-beta.1", "0.200.0" + const match = versionString.match(/^(\d+)\.(\d+)\.(\d+)/); + if (!match) { + return null; + } + + return { + version: versionString, + major: parseInt(match[1], 10), + minor: parseInt(match[2], 10), + patch: parseInt(match[3], 10), + }; +} + +/** + * Compare two versions: returns -1 if a < b, 0 if equal, 1 if a > b + */ +export function compareVersions(a: N8nVersionInfo, b: N8nVersionInfo): number { + if (a.major !== b.major) return a.major - b.major; + if (a.minor !== b.minor) return a.minor - b.minor; + return a.patch - b.patch; +} + +/** + * Check if version meets minimum requirement + */ +export function versionAtLeast(version: N8nVersionInfo, major: number, minor: number, patch = 0): boolean { + const target = { version: '', major, minor, patch }; + return compareVersions(version, target) >= 0; +} + +/** + * Get supported settings properties for a given n8n version + */ +export function getSupportedSettingsProperties(version: N8nVersionInfo): Set { + const supported = new Set(SETTINGS_BY_VERSION.core); + + // Add executionOrder if >= 1.37.0 + if (versionAtLeast(version, 1, 37, 0)) { + SETTINGS_BY_VERSION.v1_37_0.forEach(prop => supported.add(prop)); + } + + // Add new properties if >= 1.119.0 + if (versionAtLeast(version, 1, 119, 0)) { + SETTINGS_BY_VERSION.v1_119_0.forEach(prop => supported.add(prop)); + } + + return supported; +} + +/** + * Fetch n8n version from /rest/settings endpoint + * + * This endpoint is available on all n8n instances and doesn't require authentication. + * Note: There's a security concern about this being unauthenticated (see n8n community), + * but it's the only reliable way to get version info. + */ +export async function fetchN8nVersion(baseUrl: string): Promise { + // Check cache first + const cached = versionCache.get(baseUrl); + if (cached) { + logger.debug(`Using cached n8n version for ${baseUrl}: ${cached.version}`); + return cached; + } + + try { + // Remove /api/v1 suffix if present to get base URL + const cleanBaseUrl = baseUrl.replace(/\/api\/v\d+\/?$/, '').replace(/\/$/, ''); + const settingsUrl = `${cleanBaseUrl}/rest/settings`; + + logger.debug(`Fetching n8n version from ${settingsUrl}`); + + const response = await axios.get(settingsUrl, { + timeout: 5000, + validateStatus: (status: number) => status < 500, + }); + + if (response.status === 200 && response.data) { + // n8n wraps the settings in a "data" property + const settings = response.data.data; + if (!settings) { + logger.warn('No data in settings response'); + return null; + } + + // n8n can return version in different fields + const versionString = settings.n8nVersion || settings.versionCli; + + if (versionString) { + const versionInfo = parseVersion(versionString); + if (versionInfo) { + // Cache the result + versionCache.set(baseUrl, versionInfo); + logger.debug(`Detected n8n version: ${versionInfo.version}`); + return versionInfo; + } + } + } + + logger.warn(`Could not determine n8n version from ${settingsUrl}`); + return null; + } catch (error) { + logger.warn(`Failed to fetch n8n version: ${error instanceof Error ? error.message : 'Unknown error'}`); + return null; + } +} + +/** + * Clear version cache (useful for testing or when server changes) + */ +export function clearVersionCache(): void { + versionCache.clear(); +} + +/** + * Get cached version for a base URL (or null if not cached) + */ +export function getCachedVersion(baseUrl: string): N8nVersionInfo | null { + return versionCache.get(baseUrl) || null; +} + +/** + * Set cached version (useful for testing or when version is known) + */ +export function setCachedVersion(baseUrl: string, version: N8nVersionInfo): void { + versionCache.set(baseUrl, version); +} + +/** + * Clean workflow settings for API update based on n8n version + * + * This function filters workflow settings to only include properties + * that the target n8n version supports, preventing "additional properties" errors. + * + * @param settings - The workflow settings to clean + * @param version - The target n8n version (if null, returns settings unchanged) + * @returns Cleaned settings object + */ +export function cleanSettingsForVersion( + settings: Record | undefined, + version: N8nVersionInfo | null +): Record { + if (!settings || typeof settings !== 'object') { + return {}; + } + + // If version unknown, return settings unchanged (let the API decide) + if (!version) { + return settings; + } + + const supportedProperties = getSupportedSettingsProperties(version); + + const cleaned: Record = {}; + for (const [key, value] of Object.entries(settings)) { + if (supportedProperties.has(key)) { + cleaned[key] = value; + } else { + logger.debug(`Filtered out unsupported settings property: ${key} (n8n ${version.version})`); + } + } + + return cleaned; +} + +// Export version thresholds for testing +export const VERSION_THRESHOLDS = { + EXECUTION_ORDER: { major: 1, minor: 37, patch: 0 }, + CALLER_POLICY: { major: 1, minor: 119, patch: 0 }, +}; diff --git a/src/types/n8n-api.ts b/src/types/n8n-api.ts index 66c7254..8801074 100644 --- a/src/types/n8n-api.ts +++ b/src/types/n8n-api.ts @@ -225,6 +225,28 @@ export interface HealthCheckResponse { }; } +// n8n Version Information +export interface N8nVersionInfo { + version: string; // Full version string, e.g., "1.119.0" + major: number; // Major version number + minor: number; // Minor version number + patch: number; // Patch version number +} + +// Settings data within the response +export interface N8nSettingsData { + n8nVersion?: string; + versionCli?: string; + instanceId?: string; + [key: string]: unknown; +} + +// Response from /rest/settings endpoint (unauthenticated) +// The actual response wraps settings in a "data" property +export interface N8nSettingsResponse { + data?: N8nSettingsData; +} + // Request Parameter Types export interface WorkflowListParams { limit?: number; diff --git a/tests/unit/services/n8n-validation.test.ts b/tests/unit/services/n8n-validation.test.ts index 0211818..ffc44fe 100644 --- a/tests/unit/services/n8n-validation.test.ts +++ b/tests/unit/services/n8n-validation.test.ts @@ -383,7 +383,7 @@ describe('n8n-validation', () => { expect(cleaned.name).toBe('Test Workflow'); }); - it('should provide minimal default settings when no settings provided (Issue #431)', () => { + it('should provide empty settings when no settings provided (Issue #431)', () => { const workflow = { name: 'Test Workflow', nodes: [], @@ -391,8 +391,8 @@ describe('n8n-validation', () => { } as any; const cleaned = cleanWorkflowForUpdate(workflow); - // n8n API requires settings to be present, so we provide minimal defaults (v1 is modern default) - expect(cleaned.settings).toEqual({ executionOrder: 'v1' }); + // n8n API now accepts empty settings {} - server preserves existing values + expect(cleaned.settings).toEqual({}); }); it('should filter settings to safe properties to prevent API errors (Issue #248 - final fix)', () => { @@ -403,20 +403,22 @@ describe('n8n-validation', () => { settings: { executionOrder: 'v1' as const, saveDataSuccessExecution: 'none' as const, - callerPolicy: 'workflowsFromSameOwner' as const, // Now whitelisted (n8n 1.121+) - timeSavedPerExecution: 5, // Filtered out (UI-only property) + callerPolicy: 'workflowsFromSameOwner' as const, // Whitelisted (n8n 1.119+) + timeSavedPerExecution: 5, // Whitelisted (n8n 1.119+, PR #21297) + unknownProperty: 'should be filtered', // Unknown properties ARE filtered }, } as any; const cleaned = cleanWorkflowForUpdate(workflow); - // Unsafe properties filtered out, safe properties kept (callerPolicy now whitelisted) + // All 4 properties from n8n 1.119+ are whitelisted, unknown properties filtered expect(cleaned.settings).toEqual({ executionOrder: 'v1', saveDataSuccessExecution: 'none', - callerPolicy: 'workflowsFromSameOwner' + callerPolicy: 'workflowsFromSameOwner', + timeSavedPerExecution: 5, }); - expect(cleaned.settings).not.toHaveProperty('timeSavedPerExecution'); + expect(cleaned.settings).not.toHaveProperty('unknownProperty'); }); it('should preserve callerPolicy and availableInMCP (n8n 1.121+ settings)', () => { @@ -487,26 +489,26 @@ describe('n8n-validation', () => { } as any; const cleaned = cleanWorkflowForUpdate(workflow); - // n8n API requires settings, so we provide minimal defaults (v1 is modern default) - expect(cleaned.settings).toEqual({ executionOrder: 'v1' }); + // n8n API now accepts empty settings {} - server preserves existing values + expect(cleaned.settings).toEqual({}); }); - it('should provide minimal settings when only non-whitelisted properties exist (Issue #431)', () => { + it('should return empty settings when only non-whitelisted properties exist (Issue #431)', () => { const workflow = { name: 'Test Workflow', nodes: [], connections: {}, settings: { - timeSavedPerExecution: 5, // Filtered out (UI-only) - someOtherProperty: 'value', // Filtered out + timeSavedPerExecution: 5, // Whitelisted (n8n 1.119+) + someOtherProperty: 'value', // Filtered out (unknown) }, } as any; const cleaned = cleanWorkflowForUpdate(workflow); - // All properties were filtered out, but n8n API requires settings - // so we provide minimal defaults (v1 is modern default) to avoid both - // "additional properties" and "required property" API errors - expect(cleaned.settings).toEqual({ executionOrder: 'v1' }); + // timeSavedPerExecution is now whitelisted, someOtherProperty is filtered out + // n8n API now accepts empty or partial settings {} - server preserves existing values + expect(cleaned.settings).toEqual({ timeSavedPerExecution: 5 }); + expect(cleaned.settings).not.toHaveProperty('someOtherProperty'); }); it('should preserve whitelisted settings when mixed with non-whitelisted (Issue #431)', () => { @@ -1408,8 +1410,8 @@ describe('n8n-validation', () => { expect(forUpdate).not.toHaveProperty('active'); expect(forUpdate).not.toHaveProperty('tags'); expect(forUpdate).not.toHaveProperty('meta'); - // n8n API requires settings in updates, so minimal defaults (v1) are provided (Issue #431) - expect(forUpdate.settings).toEqual({ executionOrder: 'v1' }); + // n8n API now accepts empty settings {} - server preserves existing values + expect(forUpdate.settings).toEqual({}); expect(validateWorkflowStructure(forUpdate)).toEqual([]); }); }); diff --git a/tests/unit/services/n8n-version.test.ts b/tests/unit/services/n8n-version.test.ts new file mode 100644 index 0000000..6e7826f --- /dev/null +++ b/tests/unit/services/n8n-version.test.ts @@ -0,0 +1,313 @@ +import { describe, it, expect, beforeEach } from 'vitest'; +import { + parseVersion, + compareVersions, + versionAtLeast, + getSupportedSettingsProperties, + cleanSettingsForVersion, + clearVersionCache, + setCachedVersion, + getCachedVersion, + VERSION_THRESHOLDS, +} from '@/services/n8n-version'; +import type { N8nVersionInfo } from '@/types/n8n-api'; + +describe('n8n-version', () => { + beforeEach(() => { + clearVersionCache(); + }); + + describe('parseVersion', () => { + it('should parse standard version strings', () => { + expect(parseVersion('1.119.0')).toEqual({ + version: '1.119.0', + major: 1, + minor: 119, + patch: 0, + }); + + expect(parseVersion('1.37.0')).toEqual({ + version: '1.37.0', + major: 1, + minor: 37, + patch: 0, + }); + + expect(parseVersion('0.200.0')).toEqual({ + version: '0.200.0', + major: 0, + minor: 200, + patch: 0, + }); + }); + + it('should parse beta/pre-release versions', () => { + const result = parseVersion('1.119.0-beta.1'); + expect(result).toEqual({ + version: '1.119.0-beta.1', + major: 1, + minor: 119, + patch: 0, + }); + }); + + it('should return null for invalid versions', () => { + expect(parseVersion('invalid')).toBeNull(); + expect(parseVersion('')).toBeNull(); + expect(parseVersion('1.2')).toBeNull(); + expect(parseVersion('v1.2.3')).toBeNull(); // No 'v' prefix support + }); + }); + + describe('compareVersions', () => { + it('should compare major versions correctly', () => { + const v1 = parseVersion('1.0.0')!; + const v2 = parseVersion('2.0.0')!; + expect(compareVersions(v1, v2)).toBeLessThan(0); + expect(compareVersions(v2, v1)).toBeGreaterThan(0); + }); + + it('should compare minor versions correctly', () => { + const v1 = parseVersion('1.37.0')!; + const v2 = parseVersion('1.119.0')!; + expect(compareVersions(v1, v2)).toBeLessThan(0); + expect(compareVersions(v2, v1)).toBeGreaterThan(0); + }); + + it('should compare patch versions correctly', () => { + const v1 = parseVersion('1.119.0')!; + const v2 = parseVersion('1.119.1')!; + expect(compareVersions(v1, v2)).toBeLessThan(0); + }); + + it('should return 0 for equal versions', () => { + const v1 = parseVersion('1.119.0')!; + const v2 = parseVersion('1.119.0')!; + expect(compareVersions(v1, v2)).toBe(0); + }); + }); + + describe('versionAtLeast', () => { + it('should return true when version meets requirement', () => { + const v = parseVersion('1.119.0')!; + expect(versionAtLeast(v, 1, 119, 0)).toBe(true); + expect(versionAtLeast(v, 1, 37, 0)).toBe(true); + expect(versionAtLeast(v, 1, 0, 0)).toBe(true); + expect(versionAtLeast(v, 0, 200, 0)).toBe(true); + }); + + it('should return false when version is too old', () => { + const v = parseVersion('1.36.0')!; + expect(versionAtLeast(v, 1, 37, 0)).toBe(false); + expect(versionAtLeast(v, 1, 119, 0)).toBe(false); + expect(versionAtLeast(v, 2, 0, 0)).toBe(false); + }); + + it('should handle edge cases at version boundaries', () => { + const v37 = parseVersion('1.37.0')!; + const v36 = parseVersion('1.36.99')!; + + expect(versionAtLeast(v37, 1, 37, 0)).toBe(true); + expect(versionAtLeast(v36, 1, 37, 0)).toBe(false); + }); + }); + + describe('getSupportedSettingsProperties', () => { + it('should return core properties for old versions (< 1.37.0)', () => { + const v = parseVersion('1.30.0')!; + const supported = getSupportedSettingsProperties(v); + + // Core properties should be supported + expect(supported.has('saveExecutionProgress')).toBe(true); + expect(supported.has('saveManualExecutions')).toBe(true); + expect(supported.has('saveDataErrorExecution')).toBe(true); + expect(supported.has('saveDataSuccessExecution')).toBe(true); + expect(supported.has('executionTimeout')).toBe(true); + expect(supported.has('errorWorkflow')).toBe(true); + expect(supported.has('timezone')).toBe(true); + + // executionOrder should NOT be supported + expect(supported.has('executionOrder')).toBe(false); + + // New properties should NOT be supported + expect(supported.has('callerPolicy')).toBe(false); + expect(supported.has('callerIds')).toBe(false); + expect(supported.has('timeSavedPerExecution')).toBe(false); + expect(supported.has('availableInMCP')).toBe(false); + }); + + it('should return core + executionOrder for v1.37.0+', () => { + const v = parseVersion('1.37.0')!; + const supported = getSupportedSettingsProperties(v); + + // Core properties + expect(supported.has('saveExecutionProgress')).toBe(true); + expect(supported.has('timezone')).toBe(true); + + // executionOrder should be supported + expect(supported.has('executionOrder')).toBe(true); + + // New properties should NOT be supported + expect(supported.has('callerPolicy')).toBe(false); + }); + + it('should return all properties for v1.119.0+', () => { + const v = parseVersion('1.119.0')!; + const supported = getSupportedSettingsProperties(v); + + // All 12 properties should be supported + expect(supported.has('saveExecutionProgress')).toBe(true); + expect(supported.has('saveManualExecutions')).toBe(true); + expect(supported.has('saveDataErrorExecution')).toBe(true); + expect(supported.has('saveDataSuccessExecution')).toBe(true); + expect(supported.has('executionTimeout')).toBe(true); + expect(supported.has('errorWorkflow')).toBe(true); + expect(supported.has('timezone')).toBe(true); + expect(supported.has('executionOrder')).toBe(true); + expect(supported.has('callerPolicy')).toBe(true); + expect(supported.has('callerIds')).toBe(true); + expect(supported.has('timeSavedPerExecution')).toBe(true); + expect(supported.has('availableInMCP')).toBe(true); + + expect(supported.size).toBe(12); + }); + }); + + describe('cleanSettingsForVersion', () => { + const fullSettings = { + saveExecutionProgress: false, + saveManualExecutions: true, + saveDataErrorExecution: 'all', + saveDataSuccessExecution: 'none', + executionTimeout: 3600, + errorWorkflow: '', + timezone: 'UTC', + executionOrder: 'v1', + callerPolicy: 'workflowsFromSameOwner', + callerIds: '', + timeSavedPerExecution: 0, + availableInMCP: false, + }; + + it('should filter to core properties for old versions', () => { + const v = parseVersion('1.30.0')!; + const cleaned = cleanSettingsForVersion(fullSettings, v); + + expect(Object.keys(cleaned)).toHaveLength(7); + expect(cleaned).toHaveProperty('saveExecutionProgress'); + expect(cleaned).toHaveProperty('timezone'); + expect(cleaned).not.toHaveProperty('executionOrder'); + expect(cleaned).not.toHaveProperty('callerPolicy'); + }); + + it('should include executionOrder for v1.37.0+', () => { + const v = parseVersion('1.37.0')!; + const cleaned = cleanSettingsForVersion(fullSettings, v); + + expect(Object.keys(cleaned)).toHaveLength(8); + expect(cleaned).toHaveProperty('executionOrder'); + expect(cleaned).not.toHaveProperty('callerPolicy'); + }); + + it('should include all properties for v1.119.0+', () => { + const v = parseVersion('1.119.0')!; + const cleaned = cleanSettingsForVersion(fullSettings, v); + + expect(Object.keys(cleaned)).toHaveLength(12); + expect(cleaned).toHaveProperty('callerPolicy'); + expect(cleaned).toHaveProperty('availableInMCP'); + }); + + it('should return settings unchanged when version is null', () => { + // When version unknown, return settings unchanged (let API decide) + const cleaned = cleanSettingsForVersion(fullSettings, null); + expect(cleaned).toEqual(fullSettings); + }); + + it('should handle empty settings', () => { + const v = parseVersion('1.119.0')!; + expect(cleanSettingsForVersion({}, v)).toEqual({}); + expect(cleanSettingsForVersion(undefined, v)).toEqual({}); + }); + }); + + describe('Version cache', () => { + it('should cache and retrieve versions', () => { + const baseUrl = 'http://localhost:5678'; + const version: N8nVersionInfo = { + version: '1.119.0', + major: 1, + minor: 119, + patch: 0, + }; + + expect(getCachedVersion(baseUrl)).toBeNull(); + + setCachedVersion(baseUrl, version); + expect(getCachedVersion(baseUrl)).toEqual(version); + + clearVersionCache(); + expect(getCachedVersion(baseUrl)).toBeNull(); + }); + + it('should handle multiple base URLs', () => { + const url1 = 'http://localhost:5678'; + const url2 = 'http://production:5678'; + + const v1: N8nVersionInfo = { version: '1.119.0', major: 1, minor: 119, patch: 0 }; + const v2: N8nVersionInfo = { version: '1.37.0', major: 1, minor: 37, patch: 0 }; + + setCachedVersion(url1, v1); + setCachedVersion(url2, v2); + + expect(getCachedVersion(url1)).toEqual(v1); + expect(getCachedVersion(url2)).toEqual(v2); + }); + }); + + describe('VERSION_THRESHOLDS', () => { + it('should have correct threshold values', () => { + expect(VERSION_THRESHOLDS.EXECUTION_ORDER).toEqual({ major: 1, minor: 37, patch: 0 }); + expect(VERSION_THRESHOLDS.CALLER_POLICY).toEqual({ major: 1, minor: 119, patch: 0 }); + }); + }); + + describe('Real-world version scenarios', () => { + it('should handle n8n cloud versions', () => { + // Cloud typically runs latest + const cloudVersion = parseVersion('1.125.0')!; + const supported = getSupportedSettingsProperties(cloudVersion); + expect(supported.size).toBe(12); + }); + + it('should handle self-hosted older versions', () => { + // Common self-hosted older version + const selfHosted = parseVersion('1.50.0')!; + const supported = getSupportedSettingsProperties(selfHosted); + + expect(supported.has('executionOrder')).toBe(true); + expect(supported.has('callerPolicy')).toBe(false); + }); + + it('should handle workflow migration scenario', () => { + // Workflow from n8n 1.119+ with all settings + const fullSettings = { + saveExecutionProgress: true, + executionOrder: 'v1', + callerPolicy: 'workflowsFromSameOwner', + callerIds: '', + timeSavedPerExecution: 5, + availableInMCP: true, + }; + + // Updating to n8n 1.100 (older) + const targetVersion = parseVersion('1.100.0')!; + const cleaned = cleanSettingsForVersion(fullSettings, targetVersion); + + // Should filter out properties not supported in 1.100 + expect(cleaned).toHaveProperty('executionOrder'); + expect(cleaned).not.toHaveProperty('callerPolicy'); + expect(cleaned).not.toHaveProperty('availableInMCP'); + }); + }); +}); From 5057481e70136163e00c7ee66f96d8ff8108041b Mon Sep 17 00:00:00 2001 From: thesved <2893181+thesved@users.noreply.github.com> Date: Thu, 4 Dec 2025 20:22:02 +0200 Subject: [PATCH 3/5] chore: add pre-built dist folder for npx usage --- dist/config/n8n-api.d.ts | 15 + dist/config/n8n-api.d.ts.map | 1 + dist/config/n8n-api.js | 53 + dist/config/n8n-api.js.map | 1 + dist/constants/type-structures.d.ts | 123 + dist/constants/type-structures.d.ts.map | 1 + dist/constants/type-structures.js | 654 ++++ dist/constants/type-structures.js.map | 1 + dist/database/database-adapter.d.ts | 33 + dist/database/database-adapter.d.ts.map | 1 + dist/database/database-adapter.js | 420 +++ dist/database/database-adapter.js.map | 1 + dist/database/node-repository.d.ts | 91 + dist/database/node-repository.d.ts.map | 1 + dist/database/node-repository.js | 603 ++++ dist/database/node-repository.js.map | 1 + dist/errors/validation-service-error.d.ts | 10 + dist/errors/validation-service-error.d.ts.map | 1 + dist/errors/validation-service-error.js | 26 + dist/errors/validation-service-error.js.map | 1 + dist/http-server-single-session.d.ts | 52 + dist/http-server-single-session.d.ts.map | 1 + dist/http-server-single-session.js | 1171 +++++++ dist/http-server-single-session.js.map | 1 + dist/http-server.d.ts | 9 + dist/http-server.d.ts.map | 1 + dist/http-server.js | 478 +++ dist/http-server.js.map | 1 + dist/index.d.ts | 11 + dist/index.d.ts.map | 1 + dist/index.js | 20 + dist/index.js.map | 1 + dist/loaders/node-loader.d.ts | 11 + dist/loaders/node-loader.d.ts.map | 1 + dist/loaders/node-loader.js | 79 + dist/loaders/node-loader.js.map | 1 + dist/mappers/docs-mapper.d.ts | 7 + dist/mappers/docs-mapper.d.ts.map | 1 + dist/mappers/docs-mapper.js | 106 + dist/mappers/docs-mapper.js.map | 1 + dist/mcp-engine.d.ts | 36 + dist/mcp-engine.d.ts.map | 1 + dist/mcp-engine.js | 77 + dist/mcp-engine.js.map | 1 + dist/mcp-tools-engine.d.ts | 47 + dist/mcp-tools-engine.d.ts.map | 1 + dist/mcp-tools-engine.js | 89 + dist/mcp-tools-engine.js.map | 1 + dist/mcp/handlers-n8n-manager.d.ts | 29 + dist/mcp/handlers-n8n-manager.d.ts.map | 1 + dist/mcp/handlers-n8n-manager.js | 1993 ++++++++++++ dist/mcp/handlers-n8n-manager.js.map | 1 + dist/mcp/handlers-workflow-diff.d.ts | 5 + dist/mcp/handlers-workflow-diff.d.ts.map | 1 + dist/mcp/handlers-workflow-diff.js | 459 +++ dist/mcp/handlers-workflow-diff.js.map | 1 + dist/mcp/index.d.ts | 3 + dist/mcp/index.d.ts.map | 1 + dist/mcp/index.js | 219 ++ dist/mcp/index.js.map | 1 + dist/mcp/server.d.ts | 79 + dist/mcp/server.d.ts.map | 1 + dist/mcp/server.js | 2780 +++++++++++++++++ dist/mcp/server.js.map | 1 + dist/mcp/stdio-wrapper.d.ts | 3 + dist/mcp/stdio-wrapper.d.ts.map | 1 + dist/mcp/stdio-wrapper.js | 81 + dist/mcp/stdio-wrapper.js.map | 1 + .../mcp/tool-docs/configuration/get-node.d.ts | 3 + .../tool-docs/configuration/get-node.d.ts.map | 1 + dist/mcp/tool-docs/configuration/get-node.js | 90 + .../tool-docs/configuration/get-node.js.map | 1 + dist/mcp/tool-docs/configuration/index.d.ts | 2 + .../tool-docs/configuration/index.d.ts.map | 1 + dist/mcp/tool-docs/configuration/index.js | 6 + dist/mcp/tool-docs/configuration/index.js.map | 1 + dist/mcp/tool-docs/discovery/index.d.ts | 2 + dist/mcp/tool-docs/discovery/index.d.ts.map | 1 + dist/mcp/tool-docs/discovery/index.js | 6 + dist/mcp/tool-docs/discovery/index.js.map | 1 + .../mcp/tool-docs/discovery/search-nodes.d.ts | 3 + .../tool-docs/discovery/search-nodes.d.ts.map | 1 + dist/mcp/tool-docs/discovery/search-nodes.js | 56 + .../tool-docs/discovery/search-nodes.js.map | 1 + .../mcp/tool-docs/guides/ai-agents-guide.d.ts | 3 + .../tool-docs/guides/ai-agents-guide.d.ts.map | 1 + dist/mcp/tool-docs/guides/ai-agents-guide.js | 739 +++++ .../tool-docs/guides/ai-agents-guide.js.map | 1 + dist/mcp/tool-docs/guides/index.d.ts | 2 + dist/mcp/tool-docs/guides/index.d.ts.map | 1 + dist/mcp/tool-docs/guides/index.js | 6 + dist/mcp/tool-docs/guides/index.js.map | 1 + dist/mcp/tool-docs/index.d.ts | 4 + dist/mcp/tool-docs/index.d.ts.map | 1 + dist/mcp/tool-docs/index.js | 34 + dist/mcp/tool-docs/index.js.map | 1 + dist/mcp/tool-docs/system/index.d.ts | 3 + dist/mcp/tool-docs/system/index.d.ts.map | 1 + dist/mcp/tool-docs/system/index.js | 8 + dist/mcp/tool-docs/system/index.js.map | 1 + dist/mcp/tool-docs/system/n8n-diagnostic.d.ts | 3 + .../tool-docs/system/n8n-diagnostic.d.ts.map | 1 + dist/mcp/tool-docs/system/n8n-diagnostic.js | 99 + .../tool-docs/system/n8n-diagnostic.js.map | 1 + .../tool-docs/system/n8n-health-check.d.ts | 3 + .../system/n8n-health-check.d.ts.map | 1 + dist/mcp/tool-docs/system/n8n-health-check.js | 102 + .../tool-docs/system/n8n-health-check.js.map | 1 + .../system/n8n-list-available-tools.d.ts | 3 + .../system/n8n-list-available-tools.d.ts.map | 1 + .../system/n8n-list-available-tools.js | 75 + .../system/n8n-list-available-tools.js.map | 1 + .../tool-docs/system/tools-documentation.d.ts | 3 + .../system/tools-documentation.d.ts.map | 1 + .../tool-docs/system/tools-documentation.js | 65 + .../system/tools-documentation.js.map | 1 + .../mcp/tool-docs/templates/get-template.d.ts | 3 + .../tool-docs/templates/get-template.d.ts.map | 1 + dist/mcp/tool-docs/templates/get-template.js | 84 + .../tool-docs/templates/get-template.js.map | 1 + dist/mcp/tool-docs/templates/index.d.ts | 3 + dist/mcp/tool-docs/templates/index.d.ts.map | 1 + dist/mcp/tool-docs/templates/index.js | 8 + dist/mcp/tool-docs/templates/index.js.map | 1 + .../tool-docs/templates/search-templates.d.ts | 3 + .../templates/search-templates.d.ts.map | 1 + .../tool-docs/templates/search-templates.js | 143 + .../templates/search-templates.js.map | 1 + dist/mcp/tool-docs/types.d.ts | 32 + dist/mcp/tool-docs/types.d.ts.map | 1 + dist/mcp/tool-docs/types.js | 3 + dist/mcp/tool-docs/types.js.map | 1 + dist/mcp/tool-docs/validation/index.d.ts | 3 + dist/mcp/tool-docs/validation/index.d.ts.map | 1 + dist/mcp/tool-docs/validation/index.js | 8 + dist/mcp/tool-docs/validation/index.js.map | 1 + .../tool-docs/validation/validate-node.d.ts | 3 + .../validation/validate-node.d.ts.map | 1 + .../mcp/tool-docs/validation/validate-node.js | 82 + .../tool-docs/validation/validate-node.js.map | 1 + .../validation/validate-workflow.d.ts | 3 + .../validation/validate-workflow.d.ts.map | 1 + .../tool-docs/validation/validate-workflow.js | 86 + .../validation/validate-workflow.js.map | 1 + .../tool-docs/workflow_management/index.d.ts | 13 + .../workflow_management/index.d.ts.map | 1 + .../tool-docs/workflow_management/index.js | 28 + .../workflow_management/index.js.map | 1 + .../n8n-autofix-workflow.d.ts | 3 + .../n8n-autofix-workflow.d.ts.map | 1 + .../n8n-autofix-workflow.js | 162 + .../n8n-autofix-workflow.js.map | 1 + .../n8n-create-workflow.d.ts | 3 + .../n8n-create-workflow.d.ts.map | 1 + .../n8n-create-workflow.js | 102 + .../n8n-create-workflow.js.map | 1 + .../n8n-delete-workflow.d.ts | 3 + .../n8n-delete-workflow.d.ts.map | 1 + .../n8n-delete-workflow.js | 52 + .../n8n-delete-workflow.js.map | 1 + .../n8n-deploy-template.d.ts | 3 + .../n8n-deploy-template.d.ts.map | 1 + .../n8n-deploy-template.js | 73 + .../n8n-deploy-template.js.map | 1 + .../workflow_management/n8n-executions.d.ts | 3 + .../n8n-executions.d.ts.map | 1 + .../workflow_management/n8n-executions.js | 84 + .../workflow_management/n8n-executions.js.map | 1 + .../workflow_management/n8n-get-workflow.d.ts | 3 + .../n8n-get-workflow.d.ts.map | 1 + .../workflow_management/n8n-get-workflow.js | 68 + .../n8n-get-workflow.js.map | 1 + .../n8n-list-workflows.d.ts | 3 + .../n8n-list-workflows.d.ts.map | 1 + .../workflow_management/n8n-list-workflows.js | 57 + .../n8n-list-workflows.js.map | 1 + .../n8n-test-workflow.d.ts | 3 + .../n8n-test-workflow.d.ts.map | 1 + .../workflow_management/n8n-test-workflow.js | 140 + .../n8n-test-workflow.js.map | 1 + .../n8n-update-full-workflow.d.ts | 3 + .../n8n-update-full-workflow.d.ts.map | 1 + .../n8n-update-full-workflow.js | 61 + .../n8n-update-full-workflow.js.map | 1 + .../n8n-update-partial-workflow.d.ts | 3 + .../n8n-update-partial-workflow.d.ts.map | 1 + .../n8n-update-partial-workflow.js | 420 +++ .../n8n-update-partial-workflow.js.map | 1 + .../n8n-validate-workflow.d.ts | 3 + .../n8n-validate-workflow.d.ts.map | 1 + .../n8n-validate-workflow.js | 73 + .../n8n-validate-workflow.js.map | 1 + .../n8n-workflow-versions.d.ts | 3 + .../n8n-workflow-versions.d.ts.map | 1 + .../n8n-workflow-versions.js | 170 + .../n8n-workflow-versions.js.map | 1 + dist/mcp/tools-documentation.d.ts | 6 + dist/mcp/tools-documentation.d.ts.map | 1 + dist/mcp/tools-documentation.js | 682 ++++ dist/mcp/tools-documentation.js.map | 1 + dist/mcp/tools-n8n-friendly.d.ts | 6 + dist/mcp/tools-n8n-friendly.d.ts.map | 1 + dist/mcp/tools-n8n-friendly.js | 89 + dist/mcp/tools-n8n-friendly.js.map | 1 + dist/mcp/tools-n8n-manager.d.ts | 3 + dist/mcp/tools-n8n-manager.d.ts.map | 1 + dist/mcp/tools-n8n-manager.js | 491 +++ dist/mcp/tools-n8n-manager.js.map | 1 + dist/mcp/tools.d.ts | 3 + dist/mcp/tools.d.ts.map | 1 + dist/mcp/tools.js | 383 +++ dist/mcp/tools.js.map | 1 + dist/mcp/workflow-examples.d.ts | 76 + dist/mcp/workflow-examples.d.ts.map | 1 + dist/mcp/workflow-examples.js | 111 + dist/mcp/workflow-examples.js.map | 1 + dist/n8n/MCPApi.credentials.d.ts | 8 + dist/n8n/MCPApi.credentials.d.ts.map | 1 + dist/n8n/MCPApi.credentials.js | 53 + dist/n8n/MCPApi.credentials.js.map | 1 + dist/n8n/MCPNode.node.d.ts | 13 + dist/n8n/MCPNode.node.d.ts.map | 1 + dist/n8n/MCPNode.node.js | 260 ++ dist/n8n/MCPNode.node.js.map | 1 + dist/parsers/node-parser.d.ts | 35 + dist/parsers/node-parser.d.ts.map | 1 + dist/parsers/node-parser.js | 250 ++ dist/parsers/node-parser.js.map | 1 + dist/parsers/property-extractor.d.ts | 11 + dist/parsers/property-extractor.d.ts.map | 1 + dist/parsers/property-extractor.js | 172 + dist/parsers/property-extractor.js.map | 1 + dist/parsers/simple-parser.d.ts | 25 + dist/parsers/simple-parser.d.ts.map | 1 + dist/parsers/simple-parser.js | 212 ++ dist/parsers/simple-parser.js.map | 1 + dist/scripts/debug-http-search.d.ts | 3 + dist/scripts/debug-http-search.d.ts.map | 1 + dist/scripts/debug-http-search.js | 57 + dist/scripts/debug-http-search.js.map | 1 + dist/scripts/extract-from-docker.d.ts | 3 + dist/scripts/extract-from-docker.d.ts.map | 1 + dist/scripts/extract-from-docker.js | 210 ++ dist/scripts/extract-from-docker.js.map | 1 + dist/scripts/fetch-templates-robust.d.ts | 4 + dist/scripts/fetch-templates-robust.d.ts.map | 1 + dist/scripts/fetch-templates-robust.js | 132 + dist/scripts/fetch-templates-robust.js.map | 1 + dist/scripts/fetch-templates.d.ts | 4 + dist/scripts/fetch-templates.d.ts.map | 1 + dist/scripts/fetch-templates.js | 411 +++ dist/scripts/fetch-templates.js.map | 1 + dist/scripts/rebuild-database.d.ts | 4 + dist/scripts/rebuild-database.d.ts.map | 1 + dist/scripts/rebuild-database.js | 95 + dist/scripts/rebuild-database.js.map | 1 + dist/scripts/rebuild-optimized.d.ts | 3 + dist/scripts/rebuild-optimized.d.ts.map | 1 + dist/scripts/rebuild-optimized.js | 198 ++ dist/scripts/rebuild-optimized.js.map | 1 + dist/scripts/rebuild.d.ts | 3 + dist/scripts/rebuild.d.ts.map | 1 + dist/scripts/rebuild.js | 234 ++ dist/scripts/rebuild.js.map | 1 + dist/scripts/sanitize-templates.d.ts | 3 + dist/scripts/sanitize-templates.d.ts.map | 1 + dist/scripts/sanitize-templates.js | 88 + dist/scripts/sanitize-templates.js.map | 1 + dist/scripts/seed-canonical-ai-examples.d.ts | 4 + .../seed-canonical-ai-examples.d.ts.map | 1 + dist/scripts/seed-canonical-ai-examples.js | 121 + .../scripts/seed-canonical-ai-examples.js.map | 1 + dist/scripts/test-autofix-documentation.d.ts | 3 + .../test-autofix-documentation.d.ts.map | 1 + dist/scripts/test-autofix-documentation.js | 103 + .../scripts/test-autofix-documentation.js.map | 1 + dist/scripts/test-autofix-workflow.d.ts | 2 + dist/scripts/test-autofix-workflow.d.ts.map | 1 + dist/scripts/test-autofix-workflow.js | 223 ++ dist/scripts/test-autofix-workflow.js.map | 1 + dist/scripts/test-execution-filtering.d.ts | 3 + .../scripts/test-execution-filtering.d.ts.map | 1 + dist/scripts/test-execution-filtering.js | 206 ++ dist/scripts/test-execution-filtering.js.map | 1 + dist/scripts/test-node-suggestions.d.ts | 3 + dist/scripts/test-node-suggestions.d.ts.map | 1 + dist/scripts/test-node-suggestions.js | 165 + dist/scripts/test-node-suggestions.js.map | 1 + dist/scripts/test-protocol-negotiation.d.ts | 3 + .../test-protocol-negotiation.d.ts.map | 1 + dist/scripts/test-protocol-negotiation.js | 154 + dist/scripts/test-protocol-negotiation.js.map | 1 + dist/scripts/test-summary.d.ts | 3 + dist/scripts/test-summary.d.ts.map | 1 + dist/scripts/test-summary.js | 77 + dist/scripts/test-summary.js.map | 1 + .../test-telemetry-mutations-verbose.d.ts | 2 + .../test-telemetry-mutations-verbose.d.ts.map | 1 + .../test-telemetry-mutations-verbose.js | 133 + .../test-telemetry-mutations-verbose.js.map | 1 + dist/scripts/test-telemetry-mutations.d.ts | 2 + .../scripts/test-telemetry-mutations.d.ts.map | 1 + dist/scripts/test-telemetry-mutations.js | 129 + dist/scripts/test-telemetry-mutations.js.map | 1 + dist/scripts/test-webhook-autofix.d.ts | 3 + dist/scripts/test-webhook-autofix.d.ts.map | 1 + dist/scripts/test-webhook-autofix.js | 117 + dist/scripts/test-webhook-autofix.js.map | 1 + dist/scripts/validate.d.ts | 3 + dist/scripts/validate.d.ts.map | 1 + dist/scripts/validate.js | 121 + dist/scripts/validate.js.map | 1 + dist/scripts/validation-summary.d.ts | 3 + dist/scripts/validation-summary.d.ts.map | 1 + dist/scripts/validation-summary.js | 135 + dist/scripts/validation-summary.js.map | 1 + dist/services/ai-node-validator.d.ts | 12 + dist/services/ai-node-validator.d.ts.map | 1 + dist/services/ai-node-validator.js | 429 +++ dist/services/ai-node-validator.js.map | 1 + dist/services/ai-tool-validators.d.ts | 58 + dist/services/ai-tool-validators.d.ts.map | 1 + dist/services/ai-tool-validators.js | 438 +++ dist/services/ai-tool-validators.js.map | 1 + dist/services/breaking-change-detector.d.ts | 38 + .../breaking-change-detector.d.ts.map | 1 + dist/services/breaking-change-detector.js | 184 ++ dist/services/breaking-change-detector.js.map | 1 + dist/services/breaking-changes-registry.d.ts | 28 + .../breaking-changes-registry.d.ts.map | 1 + dist/services/breaking-changes-registry.js | 200 ++ .../services/breaking-changes-registry.js.map | 1 + dist/services/confidence-scorer.d.ts | 24 + dist/services/confidence-scorer.d.ts.map | 1 + dist/services/confidence-scorer.js | 139 + dist/services/confidence-scorer.js.map | 1 + dist/services/config-validator.d.ts | 47 + dist/services/config-validator.d.ts.map | 1 + dist/services/config-validator.js | 671 ++++ dist/services/config-validator.js.map | 1 + dist/services/enhanced-config-validator.d.ts | 54 + .../enhanced-config-validator.d.ts.map | 1 + dist/services/enhanced-config-validator.js | 789 +++++ .../services/enhanced-config-validator.js.map | 1 + dist/services/example-generator.d.ts | 14 + dist/services/example-generator.d.ts.map | 1 + dist/services/example-generator.js | 970 ++++++ dist/services/example-generator.js.map | 1 + dist/services/execution-processor.d.ts | 8 + dist/services/execution-processor.d.ts.map | 1 + dist/services/execution-processor.js | 359 +++ dist/services/execution-processor.js.map | 1 + .../services/expression-format-validator.d.ts | 33 + .../expression-format-validator.d.ts.map | 1 + dist/services/expression-format-validator.js | 209 ++ .../expression-format-validator.js.map | 1 + dist/services/expression-validator.d.ts | 27 + dist/services/expression-validator.d.ts.map | 1 + dist/services/expression-validator.js | 187 ++ dist/services/expression-validator.js.map | 1 + dist/services/n8n-api-client.d.ts | 47 + dist/services/n8n-api-client.d.ts.map | 1 + dist/services/n8n-api-client.js | 445 +++ dist/services/n8n-api-client.js.map | 1 + dist/services/n8n-validation.d.ts | 273 ++ dist/services/n8n-validation.d.ts.map | 1 + dist/services/n8n-validation.js | 481 +++ dist/services/n8n-validation.js.map | 1 + dist/services/n8n-version.d.ts | 23 + dist/services/n8n-version.d.ts.map | 1 + dist/services/n8n-version.js | 142 + dist/services/n8n-version.js.map | 1 + dist/services/node-documentation-service.d.ts | 70 + .../node-documentation-service.d.ts.map | 1 + dist/services/node-documentation-service.js | 518 +++ .../node-documentation-service.js.map | 1 + dist/services/node-migration-service.d.ts | 44 + dist/services/node-migration-service.d.ts.map | 1 + dist/services/node-migration-service.js | 231 ++ dist/services/node-migration-service.js.map | 1 + dist/services/node-sanitizer.d.ts | 5 + dist/services/node-sanitizer.d.ts.map | 1 + dist/services/node-sanitizer.js | 225 ++ dist/services/node-sanitizer.js.map | 1 + dist/services/node-similarity-service.d.ts | 51 + .../services/node-similarity-service.d.ts.map | 1 + dist/services/node-similarity-service.js | 335 ++ dist/services/node-similarity-service.js.map | 1 + dist/services/node-specific-validators.d.ts | 37 + .../node-specific-validators.d.ts.map | 1 + dist/services/node-specific-validators.js | 1331 ++++++++ dist/services/node-specific-validators.js.map | 1 + dist/services/node-version-service.d.ts | 63 + dist/services/node-version-service.d.ts.map | 1 + dist/services/node-version-service.js | 215 ++ dist/services/node-version-service.js.map | 1 + .../operation-similarity-service.d.ts | 32 + .../operation-similarity-service.d.ts.map | 1 + dist/services/operation-similarity-service.js | 341 ++ .../operation-similarity-service.js.map | 1 + dist/services/post-update-validator.d.ts | 59 + dist/services/post-update-validator.d.ts.map | 1 + dist/services/post-update-validator.js | 231 ++ dist/services/post-update-validator.js.map | 1 + dist/services/property-dependencies.d.ts | 36 + dist/services/property-dependencies.d.ts.map | 1 + dist/services/property-dependencies.js | 168 + dist/services/property-dependencies.js.map | 1 + dist/services/property-filter.d.ts | 44 + dist/services/property-filter.d.ts.map | 1 + dist/services/property-filter.js | 395 +++ dist/services/property-filter.js.map | 1 + .../services/resource-similarity-service.d.ts | 33 + .../resource-similarity-service.d.ts.map | 1 + dist/services/resource-similarity-service.js | 358 +++ .../resource-similarity-service.js.map | 1 + dist/services/sqlite-storage-service.d.ts | 11 + dist/services/sqlite-storage-service.d.ts.map | 1 + dist/services/sqlite-storage-service.js | 74 + dist/services/sqlite-storage-service.js.map | 1 + dist/services/task-templates.d.ts | 27 + dist/services/task-templates.d.ts.map | 1 + dist/services/task-templates.js | 1397 +++++++++ dist/services/task-templates.js.map | 1 + dist/services/type-structure-service.d.ts | 23 + dist/services/type-structure-service.d.ts.map | 1 + dist/services/type-structure-service.js | 109 + dist/services/type-structure-service.js.map | 1 + .../universal-expression-validator.d.ts | 20 + .../universal-expression-validator.d.ts.map | 1 + .../universal-expression-validator.js | 192 ++ .../universal-expression-validator.js.map | 1 + dist/services/workflow-auto-fixer.d.ts | 73 + dist/services/workflow-auto-fixer.d.ts.map | 1 + dist/services/workflow-auto-fixer.js | 515 +++ dist/services/workflow-auto-fixer.js.map | 1 + dist/services/workflow-diff-engine.d.ts | 45 + dist/services/workflow-diff-engine.d.ts.map | 1 + dist/services/workflow-diff-engine.js | 830 +++++ dist/services/workflow-diff-engine.js.map | 1 + dist/services/workflow-validator.d.ts | 104 + dist/services/workflow-validator.d.ts.map | 1 + dist/services/workflow-validator.js | 1249 ++++++++ dist/services/workflow-validator.js.map | 1 + .../services/workflow-versioning-service.d.ts | 102 + .../workflow-versioning-service.d.ts.map | 1 + dist/services/workflow-versioning-service.js | 264 ++ .../workflow-versioning-service.js.map | 1 + dist/telemetry/batch-processor.d.ts | 34 + dist/telemetry/batch-processor.d.ts.map | 1 + dist/telemetry/batch-processor.js | 343 ++ dist/telemetry/batch-processor.js.map | 1 + dist/telemetry/config-manager.d.ts | 32 + dist/telemetry/config-manager.d.ts.map | 1 + dist/telemetry/config-manager.js | 289 ++ dist/telemetry/config-manager.js.map | 1 + dist/telemetry/early-error-logger.d.ts | 26 + dist/telemetry/early-error-logger.d.ts.map | 1 + dist/telemetry/early-error-logger.js | 187 ++ dist/telemetry/early-error-logger.js.map | 1 + dist/telemetry/error-sanitization-utils.d.ts | 2 + .../error-sanitization-utils.d.ts.map | 1 + dist/telemetry/error-sanitization-utils.js | 37 + .../telemetry/error-sanitization-utils.js.map | 1 + dist/telemetry/error-sanitizer.d.ts | 4 + dist/telemetry/error-sanitizer.d.ts.map | 1 + dist/telemetry/error-sanitizer.js | 45 + dist/telemetry/error-sanitizer.js.map | 1 + dist/telemetry/event-tracker.d.ts | 71 + dist/telemetry/event-tracker.d.ts.map | 1 + dist/telemetry/event-tracker.js | 356 +++ dist/telemetry/event-tracker.js.map | 1 + dist/telemetry/event-validator.d.ts | 78 + dist/telemetry/event-validator.d.ts.map | 1 + dist/telemetry/event-validator.js | 227 ++ dist/telemetry/event-validator.js.map | 1 + dist/telemetry/index.d.ts | 5 + dist/telemetry/index.d.ts.map | 1 + dist/telemetry/index.js | 11 + dist/telemetry/index.js.map | 1 + dist/telemetry/intent-classifier.d.ts | 11 + dist/telemetry/intent-classifier.d.ts.map | 1 + dist/telemetry/intent-classifier.js | 141 + dist/telemetry/intent-classifier.js.map | 1 + dist/telemetry/intent-sanitizer.d.ts | 9 + dist/telemetry/intent-sanitizer.d.ts.map | 1 + dist/telemetry/intent-sanitizer.js | 103 + dist/telemetry/intent-sanitizer.js.map | 1 + dist/telemetry/mutation-tracker.d.ts | 15 + dist/telemetry/mutation-tracker.d.ts.map | 1 + dist/telemetry/mutation-tracker.js | 177 ++ dist/telemetry/mutation-tracker.js.map | 1 + dist/telemetry/mutation-types.d.ts | 106 + dist/telemetry/mutation-types.d.ts.map | 1 + dist/telemetry/mutation-types.js | 18 + dist/telemetry/mutation-types.js.map | 1 + dist/telemetry/mutation-validator.d.ts | 20 + dist/telemetry/mutation-validator.d.ts.map | 1 + dist/telemetry/mutation-validator.js | 144 + dist/telemetry/mutation-validator.js.map | 1 + dist/telemetry/performance-monitor.d.ts | 113 + dist/telemetry/performance-monitor.d.ts.map | 1 + dist/telemetry/performance-monitor.js | 208 ++ dist/telemetry/performance-monitor.js.map | 1 + dist/telemetry/rate-limiter.d.ts | 30 + dist/telemetry/rate-limiter.d.ts.map | 1 + dist/telemetry/rate-limiter.js | 103 + dist/telemetry/rate-limiter.js.map | 1 + dist/telemetry/startup-checkpoints.d.ts | 26 + dist/telemetry/startup-checkpoints.d.ts.map | 1 + dist/telemetry/startup-checkpoints.js | 65 + dist/telemetry/startup-checkpoints.js.map | 1 + dist/telemetry/telemetry-error.d.ts | 44 + dist/telemetry/telemetry-error.d.ts.map | 1 + dist/telemetry/telemetry-error.js | 153 + dist/telemetry/telemetry-error.js.map | 1 + dist/telemetry/telemetry-manager.d.ts | 130 + dist/telemetry/telemetry-manager.d.ts.map | 1 + dist/telemetry/telemetry-manager.js | 257 ++ dist/telemetry/telemetry-manager.js.map | 1 + dist/telemetry/telemetry-types.d.ts | 103 + dist/telemetry/telemetry-types.d.ts.map | 1 + dist/telemetry/telemetry-types.js | 29 + dist/telemetry/telemetry-types.js.map | 1 + dist/telemetry/workflow-sanitizer.d.ts | 34 + dist/telemetry/workflow-sanitizer.d.ts.map | 1 + dist/telemetry/workflow-sanitizer.js | 242 ++ dist/telemetry/workflow-sanitizer.js.map | 1 + dist/templates/batch-processor.d.ts | 35 + dist/templates/batch-processor.d.ts.map | 1 + dist/templates/batch-processor.js | 320 ++ dist/templates/batch-processor.js.map | 1 + dist/templates/metadata-generator.d.ts | 52 + dist/templates/metadata-generator.d.ts.map | 1 + dist/templates/metadata-generator.js | 252 ++ dist/templates/metadata-generator.js.map | 1 + dist/templates/template-fetcher.d.ts | 45 + dist/templates/template-fetcher.d.ts.map | 1 + dist/templates/template-fetcher.js | 122 + dist/templates/template-fetcher.js.map | 1 + dist/templates/template-repository.d.ts | 93 + dist/templates/template-repository.d.ts.map | 1 + dist/templates/template-repository.js | 644 ++++ dist/templates/template-repository.js.map | 1 + dist/templates/template-service.d.ts | 79 + dist/templates/template-service.d.ts.map | 1 + dist/templates/template-service.js | 300 ++ dist/templates/template-service.js.map | 1 + dist/triggers/handlers/base-handler.d.ts | 21 + dist/triggers/handlers/base-handler.d.ts.map | 1 + dist/triggers/handlers/base-handler.js | 60 + dist/triggers/handlers/base-handler.js.map | 1 + dist/triggers/handlers/chat-handler.d.ts | 38 + dist/triggers/handlers/chat-handler.d.ts.map | 1 + dist/triggers/handlers/chat-handler.js | 129 + dist/triggers/handlers/chat-handler.js.map | 1 + dist/triggers/handlers/form-handler.d.ts | 35 + dist/triggers/handlers/form-handler.d.ts.map | 1 + dist/triggers/handlers/form-handler.js | 362 +++ dist/triggers/handlers/form-handler.js.map | 1 + dist/triggers/handlers/webhook-handler.d.ts | 38 + .../handlers/webhook-handler.d.ts.map | 1 + dist/triggers/handlers/webhook-handler.js | 115 + dist/triggers/handlers/webhook-handler.js.map | 1 + dist/triggers/index.d.ts | 5 + dist/triggers/index.d.ts.map | 1 + dist/triggers/index.js | 14 + dist/triggers/index.js.map | 1 + dist/triggers/trigger-detector.d.ts | 6 + dist/triggers/trigger-detector.d.ts.map | 1 + dist/triggers/trigger-detector.js | 201 ++ dist/triggers/trigger-detector.js.map | 1 + dist/triggers/trigger-registry.d.ts | 18 + dist/triggers/trigger-registry.d.ts.map | 1 + dist/triggers/trigger-registry.js | 87 + dist/triggers/trigger-registry.js.map | 1 + dist/triggers/types.d.ts | 76 + dist/triggers/types.d.ts.map | 1 + dist/triggers/types.js | 3 + dist/triggers/types.js.map | 1 + dist/types/index.d.ts | 41 + dist/types/index.d.ts.map | 1 + dist/types/index.js | 21 + dist/types/index.js.map | 1 + dist/types/instance-context.d.ts | 15 + dist/types/instance-context.d.ts.map | 1 + dist/types/instance-context.js | 127 + dist/types/instance-context.js.map | 1 + dist/types/n8n-api.d.ts | 336 ++ dist/types/n8n-api.d.ts.map | 1 + dist/types/n8n-api.js | 10 + dist/types/n8n-api.js.map | 1 + dist/types/node-types.d.ts | 19 + dist/types/node-types.d.ts.map | 1 + dist/types/node-types.js | 62 + dist/types/node-types.js.map | 1 + dist/types/session-state.d.ts | 15 + dist/types/session-state.d.ts.map | 1 + dist/types/session-state.js | 3 + dist/types/session-state.js.map | 1 + dist/types/type-structures.d.ts | 42 + dist/types/type-structures.d.ts.map | 1 + dist/types/type-structures.js | 32 + dist/types/type-structures.js.map | 1 + dist/types/workflow-diff.d.ts | 148 + dist/types/workflow-diff.d.ts.map | 1 + dist/types/workflow-diff.js | 15 + dist/types/workflow-diff.js.map | 1 + dist/utils/auth.d.ts | 13 + dist/utils/auth.d.ts.map | 1 + dist/utils/auth.js | 82 + dist/utils/auth.js.map | 1 + dist/utils/bridge.d.ts | 12 + dist/utils/bridge.d.ts.map | 1 + dist/utils/bridge.js | 127 + dist/utils/bridge.js.map | 1 + dist/utils/cache-utils.d.ts | 58 + dist/utils/cache-utils.d.ts.map | 1 + dist/utils/cache-utils.js | 243 ++ dist/utils/cache-utils.js.map | 1 + dist/utils/console-manager.d.ts | 10 + dist/utils/console-manager.d.ts.map | 1 + dist/utils/console-manager.js | 63 + dist/utils/console-manager.js.map | 1 + dist/utils/documentation-fetcher.d.ts | 2 + dist/utils/documentation-fetcher.d.ts.map | 1 + dist/utils/documentation-fetcher.js | 18 + dist/utils/documentation-fetcher.js.map | 1 + .../utils/enhanced-documentation-fetcher.d.ts | 74 + .../enhanced-documentation-fetcher.d.ts.map | 1 + dist/utils/enhanced-documentation-fetcher.js | 521 +++ .../enhanced-documentation-fetcher.js.map | 1 + dist/utils/error-handler.d.ts | 24 + dist/utils/error-handler.d.ts.map | 1 + dist/utils/error-handler.js | 84 + dist/utils/error-handler.js.map | 1 + dist/utils/example-generator.d.ts | 8 + dist/utils/example-generator.d.ts.map | 1 + dist/utils/example-generator.js | 106 + dist/utils/example-generator.js.map | 1 + dist/utils/expression-utils.d.ts | 6 + dist/utils/expression-utils.d.ts.map | 1 + dist/utils/expression-utils.js | 47 + dist/utils/expression-utils.js.map | 1 + dist/utils/fixed-collection-validator.d.ts | 35 + .../utils/fixed-collection-validator.d.ts.map | 1 + dist/utils/fixed-collection-validator.js | 358 +++ dist/utils/fixed-collection-validator.js.map | 1 + dist/utils/logger.d.ts | 33 + dist/utils/logger.d.ts.map | 1 + dist/utils/logger.js | 101 + dist/utils/logger.js.map | 1 + dist/utils/mcp-client.d.ts | 21 + dist/utils/mcp-client.d.ts.map | 1 + dist/utils/mcp-client.js | 96 + dist/utils/mcp-client.js.map | 1 + dist/utils/n8n-errors.d.ts | 27 + dist/utils/n8n-errors.d.ts.map | 1 + dist/utils/n8n-errors.js | 138 + dist/utils/n8n-errors.js.map | 1 + dist/utils/node-classification.d.ts | 5 + dist/utils/node-classification.d.ts.map | 1 + dist/utils/node-classification.js | 31 + dist/utils/node-classification.js.map | 1 + dist/utils/node-source-extractor.d.ts | 21 + dist/utils/node-source-extractor.d.ts.map | 1 + dist/utils/node-source-extractor.js | 377 +++ dist/utils/node-source-extractor.js.map | 1 + dist/utils/node-type-normalizer.d.ts | 16 + dist/utils/node-type-normalizer.d.ts.map | 1 + dist/utils/node-type-normalizer.js | 75 + dist/utils/node-type-normalizer.js.map | 1 + dist/utils/node-type-utils.d.ts | 12 + dist/utils/node-type-utils.d.ts.map | 1 + dist/utils/node-type-utils.js | 131 + dist/utils/node-type-utils.js.map | 1 + dist/utils/node-utils.d.ts | 4 + dist/utils/node-utils.d.ts.map | 1 + dist/utils/node-utils.js | 81 + dist/utils/node-utils.js.map | 1 + dist/utils/npm-version-checker.d.ts | 14 + dist/utils/npm-version-checker.d.ts.map | 1 + dist/utils/npm-version-checker.js | 125 + dist/utils/npm-version-checker.js.map | 1 + dist/utils/protocol-version.d.ts | 19 + dist/utils/protocol-version.d.ts.map | 1 + dist/utils/protocol-version.js | 95 + dist/utils/protocol-version.js.map | 1 + dist/utils/simple-cache.d.ts | 10 + dist/utils/simple-cache.d.ts.map | 1 + dist/utils/simple-cache.js | 42 + dist/utils/simple-cache.js.map | 1 + dist/utils/ssrf-protection.d.ts | 7 + dist/utils/ssrf-protection.d.ts.map | 1 + dist/utils/ssrf-protection.js | 118 + dist/utils/ssrf-protection.js.map | 1 + dist/utils/template-node-resolver.d.ts | 2 + dist/utils/template-node-resolver.d.ts.map | 1 + dist/utils/template-node-resolver.js | 161 + dist/utils/template-node-resolver.js.map | 1 + dist/utils/template-sanitizer.d.ts | 21 + dist/utils/template-sanitizer.d.ts.map | 1 + dist/utils/template-sanitizer.js | 126 + dist/utils/template-sanitizer.js.map | 1 + dist/utils/url-detector.d.ts | 9 + dist/utils/url-detector.d.ts.map | 1 + dist/utils/url-detector.js | 79 + dist/utils/url-detector.js.map | 1 + dist/utils/validation-schemas.d.ts | 32 + dist/utils/validation-schemas.d.ts.map | 1 + dist/utils/validation-schemas.js | 219 ++ dist/utils/validation-schemas.js.map | 1 + dist/utils/version.d.ts | 2 + dist/utils/version.d.ts.map | 1 + dist/utils/version.js | 18 + dist/utils/version.js.map | 1 + 716 files changed, 48021 insertions(+) create mode 100644 dist/config/n8n-api.d.ts create mode 100644 dist/config/n8n-api.d.ts.map create mode 100644 dist/config/n8n-api.js create mode 100644 dist/config/n8n-api.js.map create mode 100644 dist/constants/type-structures.d.ts create mode 100644 dist/constants/type-structures.d.ts.map create mode 100644 dist/constants/type-structures.js create mode 100644 dist/constants/type-structures.js.map create mode 100644 dist/database/database-adapter.d.ts create mode 100644 dist/database/database-adapter.d.ts.map create mode 100644 dist/database/database-adapter.js create mode 100644 dist/database/database-adapter.js.map create mode 100644 dist/database/node-repository.d.ts create mode 100644 dist/database/node-repository.d.ts.map create mode 100644 dist/database/node-repository.js create mode 100644 dist/database/node-repository.js.map create mode 100644 dist/errors/validation-service-error.d.ts create mode 100644 dist/errors/validation-service-error.d.ts.map create mode 100644 dist/errors/validation-service-error.js create mode 100644 dist/errors/validation-service-error.js.map create mode 100644 dist/http-server-single-session.d.ts create mode 100644 dist/http-server-single-session.d.ts.map create mode 100644 dist/http-server-single-session.js create mode 100644 dist/http-server-single-session.js.map create mode 100644 dist/http-server.d.ts create mode 100644 dist/http-server.d.ts.map create mode 100644 dist/http-server.js create mode 100644 dist/http-server.js.map create mode 100644 dist/index.d.ts create mode 100644 dist/index.d.ts.map create mode 100644 dist/index.js create mode 100644 dist/index.js.map create mode 100644 dist/loaders/node-loader.d.ts create mode 100644 dist/loaders/node-loader.d.ts.map create mode 100644 dist/loaders/node-loader.js create mode 100644 dist/loaders/node-loader.js.map create mode 100644 dist/mappers/docs-mapper.d.ts create mode 100644 dist/mappers/docs-mapper.d.ts.map create mode 100644 dist/mappers/docs-mapper.js create mode 100644 dist/mappers/docs-mapper.js.map create mode 100644 dist/mcp-engine.d.ts create mode 100644 dist/mcp-engine.d.ts.map create mode 100644 dist/mcp-engine.js create mode 100644 dist/mcp-engine.js.map create mode 100644 dist/mcp-tools-engine.d.ts create mode 100644 dist/mcp-tools-engine.d.ts.map create mode 100644 dist/mcp-tools-engine.js create mode 100644 dist/mcp-tools-engine.js.map create mode 100644 dist/mcp/handlers-n8n-manager.d.ts create mode 100644 dist/mcp/handlers-n8n-manager.d.ts.map create mode 100644 dist/mcp/handlers-n8n-manager.js create mode 100644 dist/mcp/handlers-n8n-manager.js.map create mode 100644 dist/mcp/handlers-workflow-diff.d.ts create mode 100644 dist/mcp/handlers-workflow-diff.d.ts.map create mode 100644 dist/mcp/handlers-workflow-diff.js create mode 100644 dist/mcp/handlers-workflow-diff.js.map create mode 100644 dist/mcp/index.d.ts create mode 100644 dist/mcp/index.d.ts.map create mode 100644 dist/mcp/index.js create mode 100644 dist/mcp/index.js.map create mode 100644 dist/mcp/server.d.ts create mode 100644 dist/mcp/server.d.ts.map create mode 100644 dist/mcp/server.js create mode 100644 dist/mcp/server.js.map create mode 100644 dist/mcp/stdio-wrapper.d.ts create mode 100644 dist/mcp/stdio-wrapper.d.ts.map create mode 100644 dist/mcp/stdio-wrapper.js create mode 100644 dist/mcp/stdio-wrapper.js.map create mode 100644 dist/mcp/tool-docs/configuration/get-node.d.ts create mode 100644 dist/mcp/tool-docs/configuration/get-node.d.ts.map create mode 100644 dist/mcp/tool-docs/configuration/get-node.js create mode 100644 dist/mcp/tool-docs/configuration/get-node.js.map create mode 100644 dist/mcp/tool-docs/configuration/index.d.ts create mode 100644 dist/mcp/tool-docs/configuration/index.d.ts.map create mode 100644 dist/mcp/tool-docs/configuration/index.js create mode 100644 dist/mcp/tool-docs/configuration/index.js.map create mode 100644 dist/mcp/tool-docs/discovery/index.d.ts create mode 100644 dist/mcp/tool-docs/discovery/index.d.ts.map create mode 100644 dist/mcp/tool-docs/discovery/index.js create mode 100644 dist/mcp/tool-docs/discovery/index.js.map create mode 100644 dist/mcp/tool-docs/discovery/search-nodes.d.ts create mode 100644 dist/mcp/tool-docs/discovery/search-nodes.d.ts.map create mode 100644 dist/mcp/tool-docs/discovery/search-nodes.js create mode 100644 dist/mcp/tool-docs/discovery/search-nodes.js.map create mode 100644 dist/mcp/tool-docs/guides/ai-agents-guide.d.ts create mode 100644 dist/mcp/tool-docs/guides/ai-agents-guide.d.ts.map create mode 100644 dist/mcp/tool-docs/guides/ai-agents-guide.js create mode 100644 dist/mcp/tool-docs/guides/ai-agents-guide.js.map create mode 100644 dist/mcp/tool-docs/guides/index.d.ts create mode 100644 dist/mcp/tool-docs/guides/index.d.ts.map create mode 100644 dist/mcp/tool-docs/guides/index.js create mode 100644 dist/mcp/tool-docs/guides/index.js.map create mode 100644 dist/mcp/tool-docs/index.d.ts create mode 100644 dist/mcp/tool-docs/index.d.ts.map create mode 100644 dist/mcp/tool-docs/index.js create mode 100644 dist/mcp/tool-docs/index.js.map create mode 100644 dist/mcp/tool-docs/system/index.d.ts create mode 100644 dist/mcp/tool-docs/system/index.d.ts.map create mode 100644 dist/mcp/tool-docs/system/index.js create mode 100644 dist/mcp/tool-docs/system/index.js.map create mode 100644 dist/mcp/tool-docs/system/n8n-diagnostic.d.ts create mode 100644 dist/mcp/tool-docs/system/n8n-diagnostic.d.ts.map create mode 100644 dist/mcp/tool-docs/system/n8n-diagnostic.js create mode 100644 dist/mcp/tool-docs/system/n8n-diagnostic.js.map create mode 100644 dist/mcp/tool-docs/system/n8n-health-check.d.ts create mode 100644 dist/mcp/tool-docs/system/n8n-health-check.d.ts.map create mode 100644 dist/mcp/tool-docs/system/n8n-health-check.js create mode 100644 dist/mcp/tool-docs/system/n8n-health-check.js.map create mode 100644 dist/mcp/tool-docs/system/n8n-list-available-tools.d.ts create mode 100644 dist/mcp/tool-docs/system/n8n-list-available-tools.d.ts.map create mode 100644 dist/mcp/tool-docs/system/n8n-list-available-tools.js create mode 100644 dist/mcp/tool-docs/system/n8n-list-available-tools.js.map create mode 100644 dist/mcp/tool-docs/system/tools-documentation.d.ts create mode 100644 dist/mcp/tool-docs/system/tools-documentation.d.ts.map create mode 100644 dist/mcp/tool-docs/system/tools-documentation.js create mode 100644 dist/mcp/tool-docs/system/tools-documentation.js.map create mode 100644 dist/mcp/tool-docs/templates/get-template.d.ts create mode 100644 dist/mcp/tool-docs/templates/get-template.d.ts.map create mode 100644 dist/mcp/tool-docs/templates/get-template.js create mode 100644 dist/mcp/tool-docs/templates/get-template.js.map create mode 100644 dist/mcp/tool-docs/templates/index.d.ts create mode 100644 dist/mcp/tool-docs/templates/index.d.ts.map create mode 100644 dist/mcp/tool-docs/templates/index.js create mode 100644 dist/mcp/tool-docs/templates/index.js.map create mode 100644 dist/mcp/tool-docs/templates/search-templates.d.ts create mode 100644 dist/mcp/tool-docs/templates/search-templates.d.ts.map create mode 100644 dist/mcp/tool-docs/templates/search-templates.js create mode 100644 dist/mcp/tool-docs/templates/search-templates.js.map create mode 100644 dist/mcp/tool-docs/types.d.ts create mode 100644 dist/mcp/tool-docs/types.d.ts.map create mode 100644 dist/mcp/tool-docs/types.js create mode 100644 dist/mcp/tool-docs/types.js.map create mode 100644 dist/mcp/tool-docs/validation/index.d.ts create mode 100644 dist/mcp/tool-docs/validation/index.d.ts.map create mode 100644 dist/mcp/tool-docs/validation/index.js create mode 100644 dist/mcp/tool-docs/validation/index.js.map create mode 100644 dist/mcp/tool-docs/validation/validate-node.d.ts create mode 100644 dist/mcp/tool-docs/validation/validate-node.d.ts.map create mode 100644 dist/mcp/tool-docs/validation/validate-node.js create mode 100644 dist/mcp/tool-docs/validation/validate-node.js.map create mode 100644 dist/mcp/tool-docs/validation/validate-workflow.d.ts create mode 100644 dist/mcp/tool-docs/validation/validate-workflow.d.ts.map create mode 100644 dist/mcp/tool-docs/validation/validate-workflow.js create mode 100644 dist/mcp/tool-docs/validation/validate-workflow.js.map create mode 100644 dist/mcp/tool-docs/workflow_management/index.d.ts create mode 100644 dist/mcp/tool-docs/workflow_management/index.d.ts.map create mode 100644 dist/mcp/tool-docs/workflow_management/index.js create mode 100644 dist/mcp/tool-docs/workflow_management/index.js.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.d.ts create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.d.ts.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.js create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.js.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-create-workflow.d.ts create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-create-workflow.d.ts.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-create-workflow.js create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-create-workflow.js.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.d.ts create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.d.ts.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.js create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.js.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-deploy-template.d.ts create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-deploy-template.d.ts.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-deploy-template.js create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-deploy-template.js.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-executions.d.ts create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-executions.d.ts.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-executions.js create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-executions.js.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-get-workflow.d.ts create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-get-workflow.d.ts.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-get-workflow.js create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-get-workflow.js.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-list-workflows.d.ts create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-list-workflows.d.ts.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-list-workflows.js create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-list-workflows.js.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-test-workflow.d.ts create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-test-workflow.d.ts.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-test-workflow.js create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-test-workflow.js.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.d.ts create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.d.ts.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.js create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.js.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.d.ts create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.d.ts.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.js create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.js.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.d.ts create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.d.ts.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.js create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.js.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.d.ts create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.d.ts.map create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.js create mode 100644 dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.js.map create mode 100644 dist/mcp/tools-documentation.d.ts create mode 100644 dist/mcp/tools-documentation.d.ts.map create mode 100644 dist/mcp/tools-documentation.js create mode 100644 dist/mcp/tools-documentation.js.map create mode 100644 dist/mcp/tools-n8n-friendly.d.ts create mode 100644 dist/mcp/tools-n8n-friendly.d.ts.map create mode 100644 dist/mcp/tools-n8n-friendly.js create mode 100644 dist/mcp/tools-n8n-friendly.js.map create mode 100644 dist/mcp/tools-n8n-manager.d.ts create mode 100644 dist/mcp/tools-n8n-manager.d.ts.map create mode 100644 dist/mcp/tools-n8n-manager.js create mode 100644 dist/mcp/tools-n8n-manager.js.map create mode 100644 dist/mcp/tools.d.ts create mode 100644 dist/mcp/tools.d.ts.map create mode 100644 dist/mcp/tools.js create mode 100644 dist/mcp/tools.js.map create mode 100644 dist/mcp/workflow-examples.d.ts create mode 100644 dist/mcp/workflow-examples.d.ts.map create mode 100644 dist/mcp/workflow-examples.js create mode 100644 dist/mcp/workflow-examples.js.map create mode 100644 dist/n8n/MCPApi.credentials.d.ts create mode 100644 dist/n8n/MCPApi.credentials.d.ts.map create mode 100644 dist/n8n/MCPApi.credentials.js create mode 100644 dist/n8n/MCPApi.credentials.js.map create mode 100644 dist/n8n/MCPNode.node.d.ts create mode 100644 dist/n8n/MCPNode.node.d.ts.map create mode 100644 dist/n8n/MCPNode.node.js create mode 100644 dist/n8n/MCPNode.node.js.map create mode 100644 dist/parsers/node-parser.d.ts create mode 100644 dist/parsers/node-parser.d.ts.map create mode 100644 dist/parsers/node-parser.js create mode 100644 dist/parsers/node-parser.js.map create mode 100644 dist/parsers/property-extractor.d.ts create mode 100644 dist/parsers/property-extractor.d.ts.map create mode 100644 dist/parsers/property-extractor.js create mode 100644 dist/parsers/property-extractor.js.map create mode 100644 dist/parsers/simple-parser.d.ts create mode 100644 dist/parsers/simple-parser.d.ts.map create mode 100644 dist/parsers/simple-parser.js create mode 100644 dist/parsers/simple-parser.js.map create mode 100644 dist/scripts/debug-http-search.d.ts create mode 100644 dist/scripts/debug-http-search.d.ts.map create mode 100644 dist/scripts/debug-http-search.js create mode 100644 dist/scripts/debug-http-search.js.map create mode 100644 dist/scripts/extract-from-docker.d.ts create mode 100644 dist/scripts/extract-from-docker.d.ts.map create mode 100644 dist/scripts/extract-from-docker.js create mode 100644 dist/scripts/extract-from-docker.js.map create mode 100644 dist/scripts/fetch-templates-robust.d.ts create mode 100644 dist/scripts/fetch-templates-robust.d.ts.map create mode 100644 dist/scripts/fetch-templates-robust.js create mode 100644 dist/scripts/fetch-templates-robust.js.map create mode 100644 dist/scripts/fetch-templates.d.ts create mode 100644 dist/scripts/fetch-templates.d.ts.map create mode 100644 dist/scripts/fetch-templates.js create mode 100644 dist/scripts/fetch-templates.js.map create mode 100644 dist/scripts/rebuild-database.d.ts create mode 100644 dist/scripts/rebuild-database.d.ts.map create mode 100644 dist/scripts/rebuild-database.js create mode 100644 dist/scripts/rebuild-database.js.map create mode 100644 dist/scripts/rebuild-optimized.d.ts create mode 100644 dist/scripts/rebuild-optimized.d.ts.map create mode 100644 dist/scripts/rebuild-optimized.js create mode 100644 dist/scripts/rebuild-optimized.js.map create mode 100644 dist/scripts/rebuild.d.ts create mode 100644 dist/scripts/rebuild.d.ts.map create mode 100644 dist/scripts/rebuild.js create mode 100644 dist/scripts/rebuild.js.map create mode 100644 dist/scripts/sanitize-templates.d.ts create mode 100644 dist/scripts/sanitize-templates.d.ts.map create mode 100644 dist/scripts/sanitize-templates.js create mode 100644 dist/scripts/sanitize-templates.js.map create mode 100644 dist/scripts/seed-canonical-ai-examples.d.ts create mode 100644 dist/scripts/seed-canonical-ai-examples.d.ts.map create mode 100644 dist/scripts/seed-canonical-ai-examples.js create mode 100644 dist/scripts/seed-canonical-ai-examples.js.map create mode 100644 dist/scripts/test-autofix-documentation.d.ts create mode 100644 dist/scripts/test-autofix-documentation.d.ts.map create mode 100644 dist/scripts/test-autofix-documentation.js create mode 100644 dist/scripts/test-autofix-documentation.js.map create mode 100644 dist/scripts/test-autofix-workflow.d.ts create mode 100644 dist/scripts/test-autofix-workflow.d.ts.map create mode 100644 dist/scripts/test-autofix-workflow.js create mode 100644 dist/scripts/test-autofix-workflow.js.map create mode 100644 dist/scripts/test-execution-filtering.d.ts create mode 100644 dist/scripts/test-execution-filtering.d.ts.map create mode 100644 dist/scripts/test-execution-filtering.js create mode 100644 dist/scripts/test-execution-filtering.js.map create mode 100644 dist/scripts/test-node-suggestions.d.ts create mode 100644 dist/scripts/test-node-suggestions.d.ts.map create mode 100644 dist/scripts/test-node-suggestions.js create mode 100644 dist/scripts/test-node-suggestions.js.map create mode 100644 dist/scripts/test-protocol-negotiation.d.ts create mode 100644 dist/scripts/test-protocol-negotiation.d.ts.map create mode 100644 dist/scripts/test-protocol-negotiation.js create mode 100644 dist/scripts/test-protocol-negotiation.js.map create mode 100644 dist/scripts/test-summary.d.ts create mode 100644 dist/scripts/test-summary.d.ts.map create mode 100644 dist/scripts/test-summary.js create mode 100644 dist/scripts/test-summary.js.map create mode 100644 dist/scripts/test-telemetry-mutations-verbose.d.ts create mode 100644 dist/scripts/test-telemetry-mutations-verbose.d.ts.map create mode 100644 dist/scripts/test-telemetry-mutations-verbose.js create mode 100644 dist/scripts/test-telemetry-mutations-verbose.js.map create mode 100644 dist/scripts/test-telemetry-mutations.d.ts create mode 100644 dist/scripts/test-telemetry-mutations.d.ts.map create mode 100644 dist/scripts/test-telemetry-mutations.js create mode 100644 dist/scripts/test-telemetry-mutations.js.map create mode 100644 dist/scripts/test-webhook-autofix.d.ts create mode 100644 dist/scripts/test-webhook-autofix.d.ts.map create mode 100644 dist/scripts/test-webhook-autofix.js create mode 100644 dist/scripts/test-webhook-autofix.js.map create mode 100644 dist/scripts/validate.d.ts create mode 100644 dist/scripts/validate.d.ts.map create mode 100644 dist/scripts/validate.js create mode 100644 dist/scripts/validate.js.map create mode 100644 dist/scripts/validation-summary.d.ts create mode 100644 dist/scripts/validation-summary.d.ts.map create mode 100644 dist/scripts/validation-summary.js create mode 100644 dist/scripts/validation-summary.js.map create mode 100644 dist/services/ai-node-validator.d.ts create mode 100644 dist/services/ai-node-validator.d.ts.map create mode 100644 dist/services/ai-node-validator.js create mode 100644 dist/services/ai-node-validator.js.map create mode 100644 dist/services/ai-tool-validators.d.ts create mode 100644 dist/services/ai-tool-validators.d.ts.map create mode 100644 dist/services/ai-tool-validators.js create mode 100644 dist/services/ai-tool-validators.js.map create mode 100644 dist/services/breaking-change-detector.d.ts create mode 100644 dist/services/breaking-change-detector.d.ts.map create mode 100644 dist/services/breaking-change-detector.js create mode 100644 dist/services/breaking-change-detector.js.map create mode 100644 dist/services/breaking-changes-registry.d.ts create mode 100644 dist/services/breaking-changes-registry.d.ts.map create mode 100644 dist/services/breaking-changes-registry.js create mode 100644 dist/services/breaking-changes-registry.js.map create mode 100644 dist/services/confidence-scorer.d.ts create mode 100644 dist/services/confidence-scorer.d.ts.map create mode 100644 dist/services/confidence-scorer.js create mode 100644 dist/services/confidence-scorer.js.map create mode 100644 dist/services/config-validator.d.ts create mode 100644 dist/services/config-validator.d.ts.map create mode 100644 dist/services/config-validator.js create mode 100644 dist/services/config-validator.js.map create mode 100644 dist/services/enhanced-config-validator.d.ts create mode 100644 dist/services/enhanced-config-validator.d.ts.map create mode 100644 dist/services/enhanced-config-validator.js create mode 100644 dist/services/enhanced-config-validator.js.map create mode 100644 dist/services/example-generator.d.ts create mode 100644 dist/services/example-generator.d.ts.map create mode 100644 dist/services/example-generator.js create mode 100644 dist/services/example-generator.js.map create mode 100644 dist/services/execution-processor.d.ts create mode 100644 dist/services/execution-processor.d.ts.map create mode 100644 dist/services/execution-processor.js create mode 100644 dist/services/execution-processor.js.map create mode 100644 dist/services/expression-format-validator.d.ts create mode 100644 dist/services/expression-format-validator.d.ts.map create mode 100644 dist/services/expression-format-validator.js create mode 100644 dist/services/expression-format-validator.js.map create mode 100644 dist/services/expression-validator.d.ts create mode 100644 dist/services/expression-validator.d.ts.map create mode 100644 dist/services/expression-validator.js create mode 100644 dist/services/expression-validator.js.map create mode 100644 dist/services/n8n-api-client.d.ts create mode 100644 dist/services/n8n-api-client.d.ts.map create mode 100644 dist/services/n8n-api-client.js create mode 100644 dist/services/n8n-api-client.js.map create mode 100644 dist/services/n8n-validation.d.ts create mode 100644 dist/services/n8n-validation.d.ts.map create mode 100644 dist/services/n8n-validation.js create mode 100644 dist/services/n8n-validation.js.map create mode 100644 dist/services/n8n-version.d.ts create mode 100644 dist/services/n8n-version.d.ts.map create mode 100644 dist/services/n8n-version.js create mode 100644 dist/services/n8n-version.js.map create mode 100644 dist/services/node-documentation-service.d.ts create mode 100644 dist/services/node-documentation-service.d.ts.map create mode 100644 dist/services/node-documentation-service.js create mode 100644 dist/services/node-documentation-service.js.map create mode 100644 dist/services/node-migration-service.d.ts create mode 100644 dist/services/node-migration-service.d.ts.map create mode 100644 dist/services/node-migration-service.js create mode 100644 dist/services/node-migration-service.js.map create mode 100644 dist/services/node-sanitizer.d.ts create mode 100644 dist/services/node-sanitizer.d.ts.map create mode 100644 dist/services/node-sanitizer.js create mode 100644 dist/services/node-sanitizer.js.map create mode 100644 dist/services/node-similarity-service.d.ts create mode 100644 dist/services/node-similarity-service.d.ts.map create mode 100644 dist/services/node-similarity-service.js create mode 100644 dist/services/node-similarity-service.js.map create mode 100644 dist/services/node-specific-validators.d.ts create mode 100644 dist/services/node-specific-validators.d.ts.map create mode 100644 dist/services/node-specific-validators.js create mode 100644 dist/services/node-specific-validators.js.map create mode 100644 dist/services/node-version-service.d.ts create mode 100644 dist/services/node-version-service.d.ts.map create mode 100644 dist/services/node-version-service.js create mode 100644 dist/services/node-version-service.js.map create mode 100644 dist/services/operation-similarity-service.d.ts create mode 100644 dist/services/operation-similarity-service.d.ts.map create mode 100644 dist/services/operation-similarity-service.js create mode 100644 dist/services/operation-similarity-service.js.map create mode 100644 dist/services/post-update-validator.d.ts create mode 100644 dist/services/post-update-validator.d.ts.map create mode 100644 dist/services/post-update-validator.js create mode 100644 dist/services/post-update-validator.js.map create mode 100644 dist/services/property-dependencies.d.ts create mode 100644 dist/services/property-dependencies.d.ts.map create mode 100644 dist/services/property-dependencies.js create mode 100644 dist/services/property-dependencies.js.map create mode 100644 dist/services/property-filter.d.ts create mode 100644 dist/services/property-filter.d.ts.map create mode 100644 dist/services/property-filter.js create mode 100644 dist/services/property-filter.js.map create mode 100644 dist/services/resource-similarity-service.d.ts create mode 100644 dist/services/resource-similarity-service.d.ts.map create mode 100644 dist/services/resource-similarity-service.js create mode 100644 dist/services/resource-similarity-service.js.map create mode 100644 dist/services/sqlite-storage-service.d.ts create mode 100644 dist/services/sqlite-storage-service.d.ts.map create mode 100644 dist/services/sqlite-storage-service.js create mode 100644 dist/services/sqlite-storage-service.js.map create mode 100644 dist/services/task-templates.d.ts create mode 100644 dist/services/task-templates.d.ts.map create mode 100644 dist/services/task-templates.js create mode 100644 dist/services/task-templates.js.map create mode 100644 dist/services/type-structure-service.d.ts create mode 100644 dist/services/type-structure-service.d.ts.map create mode 100644 dist/services/type-structure-service.js create mode 100644 dist/services/type-structure-service.js.map create mode 100644 dist/services/universal-expression-validator.d.ts create mode 100644 dist/services/universal-expression-validator.d.ts.map create mode 100644 dist/services/universal-expression-validator.js create mode 100644 dist/services/universal-expression-validator.js.map create mode 100644 dist/services/workflow-auto-fixer.d.ts create mode 100644 dist/services/workflow-auto-fixer.d.ts.map create mode 100644 dist/services/workflow-auto-fixer.js create mode 100644 dist/services/workflow-auto-fixer.js.map create mode 100644 dist/services/workflow-diff-engine.d.ts create mode 100644 dist/services/workflow-diff-engine.d.ts.map create mode 100644 dist/services/workflow-diff-engine.js create mode 100644 dist/services/workflow-diff-engine.js.map create mode 100644 dist/services/workflow-validator.d.ts create mode 100644 dist/services/workflow-validator.d.ts.map create mode 100644 dist/services/workflow-validator.js create mode 100644 dist/services/workflow-validator.js.map create mode 100644 dist/services/workflow-versioning-service.d.ts create mode 100644 dist/services/workflow-versioning-service.d.ts.map create mode 100644 dist/services/workflow-versioning-service.js create mode 100644 dist/services/workflow-versioning-service.js.map create mode 100644 dist/telemetry/batch-processor.d.ts create mode 100644 dist/telemetry/batch-processor.d.ts.map create mode 100644 dist/telemetry/batch-processor.js create mode 100644 dist/telemetry/batch-processor.js.map create mode 100644 dist/telemetry/config-manager.d.ts create mode 100644 dist/telemetry/config-manager.d.ts.map create mode 100644 dist/telemetry/config-manager.js create mode 100644 dist/telemetry/config-manager.js.map create mode 100644 dist/telemetry/early-error-logger.d.ts create mode 100644 dist/telemetry/early-error-logger.d.ts.map create mode 100644 dist/telemetry/early-error-logger.js create mode 100644 dist/telemetry/early-error-logger.js.map create mode 100644 dist/telemetry/error-sanitization-utils.d.ts create mode 100644 dist/telemetry/error-sanitization-utils.d.ts.map create mode 100644 dist/telemetry/error-sanitization-utils.js create mode 100644 dist/telemetry/error-sanitization-utils.js.map create mode 100644 dist/telemetry/error-sanitizer.d.ts create mode 100644 dist/telemetry/error-sanitizer.d.ts.map create mode 100644 dist/telemetry/error-sanitizer.js create mode 100644 dist/telemetry/error-sanitizer.js.map create mode 100644 dist/telemetry/event-tracker.d.ts create mode 100644 dist/telemetry/event-tracker.d.ts.map create mode 100644 dist/telemetry/event-tracker.js create mode 100644 dist/telemetry/event-tracker.js.map create mode 100644 dist/telemetry/event-validator.d.ts create mode 100644 dist/telemetry/event-validator.d.ts.map create mode 100644 dist/telemetry/event-validator.js create mode 100644 dist/telemetry/event-validator.js.map create mode 100644 dist/telemetry/index.d.ts create mode 100644 dist/telemetry/index.d.ts.map create mode 100644 dist/telemetry/index.js create mode 100644 dist/telemetry/index.js.map create mode 100644 dist/telemetry/intent-classifier.d.ts create mode 100644 dist/telemetry/intent-classifier.d.ts.map create mode 100644 dist/telemetry/intent-classifier.js create mode 100644 dist/telemetry/intent-classifier.js.map create mode 100644 dist/telemetry/intent-sanitizer.d.ts create mode 100644 dist/telemetry/intent-sanitizer.d.ts.map create mode 100644 dist/telemetry/intent-sanitizer.js create mode 100644 dist/telemetry/intent-sanitizer.js.map create mode 100644 dist/telemetry/mutation-tracker.d.ts create mode 100644 dist/telemetry/mutation-tracker.d.ts.map create mode 100644 dist/telemetry/mutation-tracker.js create mode 100644 dist/telemetry/mutation-tracker.js.map create mode 100644 dist/telemetry/mutation-types.d.ts create mode 100644 dist/telemetry/mutation-types.d.ts.map create mode 100644 dist/telemetry/mutation-types.js create mode 100644 dist/telemetry/mutation-types.js.map create mode 100644 dist/telemetry/mutation-validator.d.ts create mode 100644 dist/telemetry/mutation-validator.d.ts.map create mode 100644 dist/telemetry/mutation-validator.js create mode 100644 dist/telemetry/mutation-validator.js.map create mode 100644 dist/telemetry/performance-monitor.d.ts create mode 100644 dist/telemetry/performance-monitor.d.ts.map create mode 100644 dist/telemetry/performance-monitor.js create mode 100644 dist/telemetry/performance-monitor.js.map create mode 100644 dist/telemetry/rate-limiter.d.ts create mode 100644 dist/telemetry/rate-limiter.d.ts.map create mode 100644 dist/telemetry/rate-limiter.js create mode 100644 dist/telemetry/rate-limiter.js.map create mode 100644 dist/telemetry/startup-checkpoints.d.ts create mode 100644 dist/telemetry/startup-checkpoints.d.ts.map create mode 100644 dist/telemetry/startup-checkpoints.js create mode 100644 dist/telemetry/startup-checkpoints.js.map create mode 100644 dist/telemetry/telemetry-error.d.ts create mode 100644 dist/telemetry/telemetry-error.d.ts.map create mode 100644 dist/telemetry/telemetry-error.js create mode 100644 dist/telemetry/telemetry-error.js.map create mode 100644 dist/telemetry/telemetry-manager.d.ts create mode 100644 dist/telemetry/telemetry-manager.d.ts.map create mode 100644 dist/telemetry/telemetry-manager.js create mode 100644 dist/telemetry/telemetry-manager.js.map create mode 100644 dist/telemetry/telemetry-types.d.ts create mode 100644 dist/telemetry/telemetry-types.d.ts.map create mode 100644 dist/telemetry/telemetry-types.js create mode 100644 dist/telemetry/telemetry-types.js.map create mode 100644 dist/telemetry/workflow-sanitizer.d.ts create mode 100644 dist/telemetry/workflow-sanitizer.d.ts.map create mode 100644 dist/telemetry/workflow-sanitizer.js create mode 100644 dist/telemetry/workflow-sanitizer.js.map create mode 100644 dist/templates/batch-processor.d.ts create mode 100644 dist/templates/batch-processor.d.ts.map create mode 100644 dist/templates/batch-processor.js create mode 100644 dist/templates/batch-processor.js.map create mode 100644 dist/templates/metadata-generator.d.ts create mode 100644 dist/templates/metadata-generator.d.ts.map create mode 100644 dist/templates/metadata-generator.js create mode 100644 dist/templates/metadata-generator.js.map create mode 100644 dist/templates/template-fetcher.d.ts create mode 100644 dist/templates/template-fetcher.d.ts.map create mode 100644 dist/templates/template-fetcher.js create mode 100644 dist/templates/template-fetcher.js.map create mode 100644 dist/templates/template-repository.d.ts create mode 100644 dist/templates/template-repository.d.ts.map create mode 100644 dist/templates/template-repository.js create mode 100644 dist/templates/template-repository.js.map create mode 100644 dist/templates/template-service.d.ts create mode 100644 dist/templates/template-service.d.ts.map create mode 100644 dist/templates/template-service.js create mode 100644 dist/templates/template-service.js.map create mode 100644 dist/triggers/handlers/base-handler.d.ts create mode 100644 dist/triggers/handlers/base-handler.d.ts.map create mode 100644 dist/triggers/handlers/base-handler.js create mode 100644 dist/triggers/handlers/base-handler.js.map create mode 100644 dist/triggers/handlers/chat-handler.d.ts create mode 100644 dist/triggers/handlers/chat-handler.d.ts.map create mode 100644 dist/triggers/handlers/chat-handler.js create mode 100644 dist/triggers/handlers/chat-handler.js.map create mode 100644 dist/triggers/handlers/form-handler.d.ts create mode 100644 dist/triggers/handlers/form-handler.d.ts.map create mode 100644 dist/triggers/handlers/form-handler.js create mode 100644 dist/triggers/handlers/form-handler.js.map create mode 100644 dist/triggers/handlers/webhook-handler.d.ts create mode 100644 dist/triggers/handlers/webhook-handler.d.ts.map create mode 100644 dist/triggers/handlers/webhook-handler.js create mode 100644 dist/triggers/handlers/webhook-handler.js.map create mode 100644 dist/triggers/index.d.ts create mode 100644 dist/triggers/index.d.ts.map create mode 100644 dist/triggers/index.js create mode 100644 dist/triggers/index.js.map create mode 100644 dist/triggers/trigger-detector.d.ts create mode 100644 dist/triggers/trigger-detector.d.ts.map create mode 100644 dist/triggers/trigger-detector.js create mode 100644 dist/triggers/trigger-detector.js.map create mode 100644 dist/triggers/trigger-registry.d.ts create mode 100644 dist/triggers/trigger-registry.d.ts.map create mode 100644 dist/triggers/trigger-registry.js create mode 100644 dist/triggers/trigger-registry.js.map create mode 100644 dist/triggers/types.d.ts create mode 100644 dist/triggers/types.d.ts.map create mode 100644 dist/triggers/types.js create mode 100644 dist/triggers/types.js.map create mode 100644 dist/types/index.d.ts create mode 100644 dist/types/index.d.ts.map create mode 100644 dist/types/index.js create mode 100644 dist/types/index.js.map create mode 100644 dist/types/instance-context.d.ts create mode 100644 dist/types/instance-context.d.ts.map create mode 100644 dist/types/instance-context.js create mode 100644 dist/types/instance-context.js.map create mode 100644 dist/types/n8n-api.d.ts create mode 100644 dist/types/n8n-api.d.ts.map create mode 100644 dist/types/n8n-api.js create mode 100644 dist/types/n8n-api.js.map create mode 100644 dist/types/node-types.d.ts create mode 100644 dist/types/node-types.d.ts.map create mode 100644 dist/types/node-types.js create mode 100644 dist/types/node-types.js.map create mode 100644 dist/types/session-state.d.ts create mode 100644 dist/types/session-state.d.ts.map create mode 100644 dist/types/session-state.js create mode 100644 dist/types/session-state.js.map create mode 100644 dist/types/type-structures.d.ts create mode 100644 dist/types/type-structures.d.ts.map create mode 100644 dist/types/type-structures.js create mode 100644 dist/types/type-structures.js.map create mode 100644 dist/types/workflow-diff.d.ts create mode 100644 dist/types/workflow-diff.d.ts.map create mode 100644 dist/types/workflow-diff.js create mode 100644 dist/types/workflow-diff.js.map create mode 100644 dist/utils/auth.d.ts create mode 100644 dist/utils/auth.d.ts.map create mode 100644 dist/utils/auth.js create mode 100644 dist/utils/auth.js.map create mode 100644 dist/utils/bridge.d.ts create mode 100644 dist/utils/bridge.d.ts.map create mode 100644 dist/utils/bridge.js create mode 100644 dist/utils/bridge.js.map create mode 100644 dist/utils/cache-utils.d.ts create mode 100644 dist/utils/cache-utils.d.ts.map create mode 100644 dist/utils/cache-utils.js create mode 100644 dist/utils/cache-utils.js.map create mode 100644 dist/utils/console-manager.d.ts create mode 100644 dist/utils/console-manager.d.ts.map create mode 100644 dist/utils/console-manager.js create mode 100644 dist/utils/console-manager.js.map create mode 100644 dist/utils/documentation-fetcher.d.ts create mode 100644 dist/utils/documentation-fetcher.d.ts.map create mode 100644 dist/utils/documentation-fetcher.js create mode 100644 dist/utils/documentation-fetcher.js.map create mode 100644 dist/utils/enhanced-documentation-fetcher.d.ts create mode 100644 dist/utils/enhanced-documentation-fetcher.d.ts.map create mode 100644 dist/utils/enhanced-documentation-fetcher.js create mode 100644 dist/utils/enhanced-documentation-fetcher.js.map create mode 100644 dist/utils/error-handler.d.ts create mode 100644 dist/utils/error-handler.d.ts.map create mode 100644 dist/utils/error-handler.js create mode 100644 dist/utils/error-handler.js.map create mode 100644 dist/utils/example-generator.d.ts create mode 100644 dist/utils/example-generator.d.ts.map create mode 100644 dist/utils/example-generator.js create mode 100644 dist/utils/example-generator.js.map create mode 100644 dist/utils/expression-utils.d.ts create mode 100644 dist/utils/expression-utils.d.ts.map create mode 100644 dist/utils/expression-utils.js create mode 100644 dist/utils/expression-utils.js.map create mode 100644 dist/utils/fixed-collection-validator.d.ts create mode 100644 dist/utils/fixed-collection-validator.d.ts.map create mode 100644 dist/utils/fixed-collection-validator.js create mode 100644 dist/utils/fixed-collection-validator.js.map create mode 100644 dist/utils/logger.d.ts create mode 100644 dist/utils/logger.d.ts.map create mode 100644 dist/utils/logger.js create mode 100644 dist/utils/logger.js.map create mode 100644 dist/utils/mcp-client.d.ts create mode 100644 dist/utils/mcp-client.d.ts.map create mode 100644 dist/utils/mcp-client.js create mode 100644 dist/utils/mcp-client.js.map create mode 100644 dist/utils/n8n-errors.d.ts create mode 100644 dist/utils/n8n-errors.d.ts.map create mode 100644 dist/utils/n8n-errors.js create mode 100644 dist/utils/n8n-errors.js.map create mode 100644 dist/utils/node-classification.d.ts create mode 100644 dist/utils/node-classification.d.ts.map create mode 100644 dist/utils/node-classification.js create mode 100644 dist/utils/node-classification.js.map create mode 100644 dist/utils/node-source-extractor.d.ts create mode 100644 dist/utils/node-source-extractor.d.ts.map create mode 100644 dist/utils/node-source-extractor.js create mode 100644 dist/utils/node-source-extractor.js.map create mode 100644 dist/utils/node-type-normalizer.d.ts create mode 100644 dist/utils/node-type-normalizer.d.ts.map create mode 100644 dist/utils/node-type-normalizer.js create mode 100644 dist/utils/node-type-normalizer.js.map create mode 100644 dist/utils/node-type-utils.d.ts create mode 100644 dist/utils/node-type-utils.d.ts.map create mode 100644 dist/utils/node-type-utils.js create mode 100644 dist/utils/node-type-utils.js.map create mode 100644 dist/utils/node-utils.d.ts create mode 100644 dist/utils/node-utils.d.ts.map create mode 100644 dist/utils/node-utils.js create mode 100644 dist/utils/node-utils.js.map create mode 100644 dist/utils/npm-version-checker.d.ts create mode 100644 dist/utils/npm-version-checker.d.ts.map create mode 100644 dist/utils/npm-version-checker.js create mode 100644 dist/utils/npm-version-checker.js.map create mode 100644 dist/utils/protocol-version.d.ts create mode 100644 dist/utils/protocol-version.d.ts.map create mode 100644 dist/utils/protocol-version.js create mode 100644 dist/utils/protocol-version.js.map create mode 100644 dist/utils/simple-cache.d.ts create mode 100644 dist/utils/simple-cache.d.ts.map create mode 100644 dist/utils/simple-cache.js create mode 100644 dist/utils/simple-cache.js.map create mode 100644 dist/utils/ssrf-protection.d.ts create mode 100644 dist/utils/ssrf-protection.d.ts.map create mode 100644 dist/utils/ssrf-protection.js create mode 100644 dist/utils/ssrf-protection.js.map create mode 100644 dist/utils/template-node-resolver.d.ts create mode 100644 dist/utils/template-node-resolver.d.ts.map create mode 100644 dist/utils/template-node-resolver.js create mode 100644 dist/utils/template-node-resolver.js.map create mode 100644 dist/utils/template-sanitizer.d.ts create mode 100644 dist/utils/template-sanitizer.d.ts.map create mode 100644 dist/utils/template-sanitizer.js create mode 100644 dist/utils/template-sanitizer.js.map create mode 100644 dist/utils/url-detector.d.ts create mode 100644 dist/utils/url-detector.d.ts.map create mode 100644 dist/utils/url-detector.js create mode 100644 dist/utils/url-detector.js.map create mode 100644 dist/utils/validation-schemas.d.ts create mode 100644 dist/utils/validation-schemas.d.ts.map create mode 100644 dist/utils/validation-schemas.js create mode 100644 dist/utils/validation-schemas.js.map create mode 100644 dist/utils/version.d.ts create mode 100644 dist/utils/version.d.ts.map create mode 100644 dist/utils/version.js create mode 100644 dist/utils/version.js.map diff --git a/dist/config/n8n-api.d.ts b/dist/config/n8n-api.d.ts new file mode 100644 index 0000000..f4f3364 --- /dev/null +++ b/dist/config/n8n-api.d.ts @@ -0,0 +1,15 @@ +export declare function getN8nApiConfig(): { + baseUrl: string; + apiKey: string; + timeout: number; + maxRetries: number; +} | null; +export declare function isN8nApiConfigured(): boolean; +export declare function getN8nApiConfigFromContext(context: { + n8nApiUrl?: string; + n8nApiKey?: string; + n8nApiTimeout?: number; + n8nApiMaxRetries?: number; +}): N8nApiConfig | null; +export type N8nApiConfig = NonNullable>; +//# sourceMappingURL=n8n-api.d.ts.map \ No newline at end of file diff --git a/dist/config/n8n-api.d.ts.map b/dist/config/n8n-api.d.ts.map new file mode 100644 index 0000000..41df912 --- /dev/null +++ b/dist/config/n8n-api.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-api.d.ts","sourceRoot":"","sources":["../../src/config/n8n-api.ts"],"names":[],"mappings":"AAgBA,wBAAgB,eAAe;;;;;SA0B9B;AAGD,wBAAgB,kBAAkB,IAAI,OAAO,CAG5C;AAMD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,GAAG,YAAY,GAAG,IAAI,CAWtB;AAGD,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/dist/config/n8n-api.js b/dist/config/n8n-api.js new file mode 100644 index 0000000..f96f8cf --- /dev/null +++ b/dist/config/n8n-api.js @@ -0,0 +1,53 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getN8nApiConfig = getN8nApiConfig; +exports.isN8nApiConfigured = isN8nApiConfigured; +exports.getN8nApiConfigFromContext = getN8nApiConfigFromContext; +const zod_1 = require("zod"); +const dotenv_1 = __importDefault(require("dotenv")); +const n8nApiConfigSchema = zod_1.z.object({ + N8N_API_URL: zod_1.z.string().url().optional(), + N8N_API_KEY: zod_1.z.string().min(1).optional(), + N8N_API_TIMEOUT: zod_1.z.coerce.number().positive().default(30000), + N8N_API_MAX_RETRIES: zod_1.z.coerce.number().positive().default(3), +}); +let envLoaded = false; +function getN8nApiConfig() { + if (!envLoaded) { + dotenv_1.default.config(); + envLoaded = true; + } + const result = n8nApiConfigSchema.safeParse(process.env); + if (!result.success) { + return null; + } + const config = result.data; + if (!config.N8N_API_URL || !config.N8N_API_KEY) { + return null; + } + return { + baseUrl: config.N8N_API_URL, + apiKey: config.N8N_API_KEY, + timeout: config.N8N_API_TIMEOUT, + maxRetries: config.N8N_API_MAX_RETRIES, + }; +} +function isN8nApiConfigured() { + const config = getN8nApiConfig(); + return config !== null; +} +function getN8nApiConfigFromContext(context) { + if (!context.n8nApiUrl || !context.n8nApiKey) { + return null; + } + return { + baseUrl: context.n8nApiUrl, + apiKey: context.n8nApiKey, + timeout: context.n8nApiTimeout ?? 30000, + maxRetries: context.n8nApiMaxRetries ?? 3, + }; +} +//# sourceMappingURL=n8n-api.js.map \ No newline at end of file diff --git a/dist/config/n8n-api.js.map b/dist/config/n8n-api.js.map new file mode 100644 index 0000000..1d756d9 --- /dev/null +++ b/dist/config/n8n-api.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-api.js","sourceRoot":"","sources":["../../src/config/n8n-api.ts"],"names":[],"mappings":";;;;;AAgBA,0CA0BC;AAGD,gDAGC;AAMD,gEAgBC;AAtED,6BAAwB;AACxB,oDAA4B;AAI5B,MAAM,kBAAkB,GAAG,OAAC,CAAC,MAAM,CAAC;IAClC,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACxC,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACzC,eAAe,EAAE,OAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAC5D,mBAAmB,EAAE,OAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;CAC7D,CAAC,CAAC;AAGH,IAAI,SAAS,GAAG,KAAK,CAAC;AAGtB,SAAgB,eAAe;IAE7B,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,gBAAM,CAAC,MAAM,EAAE,CAAC;QAChB,SAAS,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,MAAM,MAAM,GAAG,kBAAkB,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAEzD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC;IAG3B,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QAC/C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,WAAW;QAC3B,MAAM,EAAE,MAAM,CAAC,WAAW;QAC1B,OAAO,EAAE,MAAM,CAAC,eAAe;QAC/B,UAAU,EAAE,MAAM,CAAC,mBAAmB;KACvC,CAAC;AACJ,CAAC;AAGD,SAAgB,kBAAkB;IAChC,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;IACjC,OAAO,MAAM,KAAK,IAAI,CAAC;AACzB,CAAC;AAMD,SAAgB,0BAA0B,CAAC,OAK1C;IACC,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QAC7C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,SAAS;QAC1B,MAAM,EAAE,OAAO,CAAC,SAAS;QACzB,OAAO,EAAE,OAAO,CAAC,aAAa,IAAI,KAAK;QACvC,UAAU,EAAE,OAAO,CAAC,gBAAgB,IAAI,CAAC;KAC1C,CAAC;AACJ,CAAC"} \ No newline at end of file diff --git a/dist/constants/type-structures.d.ts b/dist/constants/type-structures.d.ts new file mode 100644 index 0000000..f755c7a --- /dev/null +++ b/dist/constants/type-structures.d.ts @@ -0,0 +1,123 @@ +import type { NodePropertyTypes } from 'n8n-workflow'; +import type { TypeStructure } from '../types/type-structures'; +export declare const TYPE_STRUCTURES: Record; +export declare const COMPLEX_TYPE_EXAMPLES: { + collection: { + basic: { + name: string; + email: string; + }; + nested: { + user: { + firstName: string; + lastName: string; + }; + preferences: { + theme: string; + notifications: boolean; + }; + }; + withExpressions: { + id: string; + timestamp: string; + data: string; + }; + }; + fixedCollection: { + httpHeaders: { + headers: { + name: string; + value: string; + }[]; + }; + queryParameters: { + queryParameters: { + name: string; + value: string; + }[]; + }; + multipleCollections: { + headers: { + name: string; + value: string; + }[]; + queryParameters: { + name: string; + value: string; + }[]; + }; + }; + filter: { + simple: { + conditions: { + id: string; + leftValue: string; + operator: { + type: string; + operation: string; + }; + rightValue: string; + }[]; + combinator: string; + }; + complex: { + conditions: ({ + id: string; + leftValue: string; + operator: { + type: string; + operation: string; + }; + rightValue: number; + } | { + id: string; + leftValue: string; + operator: { + type: string; + operation: string; + }; + rightValue: string; + })[]; + combinator: string; + }; + }; + resourceMapper: { + autoMap: { + mappingMode: string; + value: {}; + }; + manual: { + mappingMode: string; + value: { + firstName: string; + lastName: string; + email: string; + status: string; + }; + }; + }; + assignmentCollection: { + basic: { + assignments: { + id: string; + name: string; + value: string; + type: string; + }[]; + }; + multiple: { + assignments: ({ + id: string; + name: string; + value: string; + type: string; + } | { + id: string; + name: string; + value: boolean; + type: string; + })[]; + }; + }; +}; +//# sourceMappingURL=type-structures.d.ts.map \ No newline at end of file diff --git a/dist/constants/type-structures.d.ts.map b/dist/constants/type-structures.d.ts.map new file mode 100644 index 0000000..43a52de --- /dev/null +++ b/dist/constants/type-structures.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"type-structures.d.ts","sourceRoot":"","sources":["../../src/constants/type-structures.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAe9D,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,iBAAiB,EAAE,aAAa,CAilBpE,CAAC;AAUF,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4GjC,CAAC"} \ No newline at end of file diff --git a/dist/constants/type-structures.js b/dist/constants/type-structures.js new file mode 100644 index 0000000..fc39b78 --- /dev/null +++ b/dist/constants/type-structures.js @@ -0,0 +1,654 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.COMPLEX_TYPE_EXAMPLES = exports.TYPE_STRUCTURES = void 0; +exports.TYPE_STRUCTURES = { + string: { + type: 'primitive', + jsType: 'string', + description: 'A text value that can contain any characters', + example: 'Hello World', + examples: ['', 'A simple text', '{{ $json.name }}', 'https://example.com'], + validation: { + allowEmpty: true, + allowExpressions: true, + }, + notes: ['Most common property type', 'Supports n8n expressions'], + }, + number: { + type: 'primitive', + jsType: 'number', + description: 'A numeric value (integer or decimal)', + example: 42, + examples: [0, -10, 3.14, 100], + validation: { + allowEmpty: false, + allowExpressions: true, + }, + notes: ['Can be constrained with min/max in typeOptions'], + }, + boolean: { + type: 'primitive', + jsType: 'boolean', + description: 'A true/false toggle value', + example: true, + examples: [true, false], + validation: { + allowEmpty: false, + allowExpressions: false, + }, + notes: ['Rendered as checkbox in n8n UI'], + }, + dateTime: { + type: 'primitive', + jsType: 'string', + description: 'A date and time value in ISO 8601 format', + example: '2024-01-20T10:30:00Z', + examples: [ + '2024-01-20T10:30:00Z', + '2024-01-20', + '{{ $now }}', + ], + validation: { + allowEmpty: false, + allowExpressions: true, + pattern: '^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z?)?$', + }, + notes: ['Accepts ISO 8601 format', 'Can use n8n date expressions'], + }, + color: { + type: 'primitive', + jsType: 'string', + description: 'A color value in hex format', + example: '#FF5733', + examples: ['#FF5733', '#000000', '#FFFFFF', '{{ $json.color }}'], + validation: { + allowEmpty: false, + allowExpressions: true, + pattern: '^#[0-9A-Fa-f]{6}$', + }, + notes: ['Must be 6-digit hex color', 'Rendered with color picker in UI'], + }, + json: { + type: 'primitive', + jsType: 'string', + description: 'A JSON string that can be parsed into any structure', + example: '{"key": "value", "nested": {"data": 123}}', + examples: [ + '{}', + '{"name": "John", "age": 30}', + '[1, 2, 3]', + '{{ $json }}', + ], + validation: { + allowEmpty: false, + allowExpressions: true, + }, + notes: ['Must be valid JSON when parsed', 'Often used for custom payloads'], + }, + options: { + type: 'primitive', + jsType: 'string', + description: 'Single selection from a list of predefined options', + example: 'option1', + examples: ['GET', 'POST', 'channelMessage', 'update'], + validation: { + allowEmpty: false, + allowExpressions: false, + }, + notes: [ + 'Value must match one of the defined option values', + 'Rendered as dropdown in UI', + 'Options defined in property.options array', + ], + }, + multiOptions: { + type: 'array', + jsType: 'array', + description: 'Multiple selections from a list of predefined options', + structure: { + items: { + type: 'string', + description: 'Selected option value', + }, + }, + example: ['option1', 'option2'], + examples: [[], ['GET', 'POST'], ['read', 'write', 'delete']], + validation: { + allowEmpty: true, + allowExpressions: false, + }, + notes: [ + 'Array of option values', + 'Each value must exist in property.options', + 'Rendered as multi-select dropdown', + ], + }, + collection: { + type: 'collection', + jsType: 'object', + description: 'A group of related properties with dynamic values', + structure: { + properties: { + '': { + type: 'any', + description: 'Any nested property from the collection definition', + }, + }, + flexible: true, + }, + example: { + name: 'John Doe', + email: 'john@example.com', + age: 30, + }, + examples: [ + {}, + { key1: 'value1', key2: 123 }, + { nested: { deep: { value: true } } }, + ], + validation: { + allowEmpty: true, + allowExpressions: true, + }, + notes: [ + 'Properties defined in property.values array', + 'Each property can be any type', + 'UI renders as expandable section', + ], + }, + fixedCollection: { + type: 'collection', + jsType: 'object', + description: 'A collection with predefined groups of properties', + structure: { + properties: { + '': { + type: 'array', + description: 'Array of collection items', + items: { + type: 'object', + description: 'Collection item with defined properties', + }, + }, + }, + required: [], + }, + example: { + headers: [ + { name: 'Content-Type', value: 'application/json' }, + { name: 'Authorization', value: 'Bearer token' }, + ], + }, + examples: [ + {}, + { queryParameters: [{ name: 'id', value: '123' }] }, + { + headers: [{ name: 'Accept', value: '*/*' }], + queryParameters: [{ name: 'limit', value: '10' }], + }, + ], + validation: { + allowEmpty: true, + allowExpressions: true, + }, + notes: [ + 'Each collection has predefined structure', + 'Often used for headers, parameters, etc.', + 'Supports multiple values per collection', + ], + }, + resourceLocator: { + type: 'special', + jsType: 'object', + description: 'A flexible way to specify a resource by ID, name, URL, or list', + structure: { + properties: { + mode: { + type: 'string', + description: 'How the resource is specified', + enum: ['id', 'url', 'list'], + required: true, + }, + value: { + type: 'string', + description: 'The resource identifier', + required: true, + }, + }, + required: ['mode', 'value'], + }, + example: { + mode: 'id', + value: 'abc123', + }, + examples: [ + { mode: 'url', value: 'https://example.com/resource/123' }, + { mode: 'list', value: 'item-from-dropdown' }, + { mode: 'id', value: '{{ $json.resourceId }}' }, + ], + validation: { + allowEmpty: false, + allowExpressions: true, + }, + notes: [ + 'Provides flexible resource selection', + 'Mode determines how value is interpreted', + 'UI adapts based on selected mode', + ], + }, + resourceMapper: { + type: 'special', + jsType: 'object', + description: 'Maps input data fields to resource fields with transformation options', + structure: { + properties: { + mappingMode: { + type: 'string', + description: 'How fields are mapped', + enum: ['defineBelow', 'autoMapInputData'], + }, + value: { + type: 'object', + description: 'Field mappings', + properties: { + '': { + type: 'string', + description: 'Expression or value for this field', + }, + }, + flexible: true, + }, + }, + }, + example: { + mappingMode: 'defineBelow', + value: { + name: '{{ $json.fullName }}', + email: '{{ $json.emailAddress }}', + status: 'active', + }, + }, + examples: [ + { mappingMode: 'autoMapInputData', value: {} }, + { + mappingMode: 'defineBelow', + value: { id: '{{ $json.userId }}', name: '{{ $json.name }}' }, + }, + ], + validation: { + allowEmpty: false, + allowExpressions: true, + }, + notes: [ + 'Complex mapping with UI assistance', + 'Can auto-map or manually define', + 'Supports field transformations', + ], + }, + filter: { + type: 'special', + jsType: 'object', + description: 'Defines conditions for filtering data with boolean logic', + structure: { + properties: { + conditions: { + type: 'array', + description: 'Array of filter conditions', + items: { + type: 'object', + properties: { + id: { + type: 'string', + description: 'Unique condition identifier', + required: true, + }, + leftValue: { + type: 'any', + description: 'Left side of comparison', + }, + operator: { + type: 'object', + description: 'Comparison operator', + required: true, + properties: { + type: { + type: 'string', + enum: ['string', 'number', 'boolean', 'dateTime', 'array', 'object'], + required: true, + }, + operation: { + type: 'string', + description: 'Operation to perform', + required: true, + }, + }, + }, + rightValue: { + type: 'any', + description: 'Right side of comparison', + }, + }, + }, + required: true, + }, + combinator: { + type: 'string', + description: 'How to combine conditions', + enum: ['and', 'or'], + required: true, + }, + }, + required: ['conditions', 'combinator'], + }, + example: { + conditions: [ + { + id: 'abc-123', + leftValue: '{{ $json.status }}', + operator: { type: 'string', operation: 'equals' }, + rightValue: 'active', + }, + ], + combinator: 'and', + }, + validation: { + allowEmpty: false, + allowExpressions: true, + }, + notes: [ + 'Advanced filtering UI in n8n', + 'Supports complex boolean logic', + 'Operations vary by data type', + ], + }, + assignmentCollection: { + type: 'special', + jsType: 'object', + description: 'Defines variable assignments with expressions', + structure: { + properties: { + assignments: { + type: 'array', + description: 'Array of variable assignments', + items: { + type: 'object', + properties: { + id: { + type: 'string', + description: 'Unique assignment identifier', + required: true, + }, + name: { + type: 'string', + description: 'Variable name', + required: true, + }, + value: { + type: 'any', + description: 'Value to assign', + required: true, + }, + type: { + type: 'string', + description: 'Data type of the value', + enum: ['string', 'number', 'boolean', 'array', 'object'], + }, + }, + }, + required: true, + }, + }, + required: ['assignments'], + }, + example: { + assignments: [ + { + id: 'abc-123', + name: 'userName', + value: '{{ $json.name }}', + type: 'string', + }, + { + id: 'def-456', + name: 'userAge', + value: 30, + type: 'number', + }, + ], + }, + validation: { + allowEmpty: false, + allowExpressions: true, + }, + notes: [ + 'Used in Set node and similar', + 'Each assignment can use expressions', + 'Type helps with validation', + ], + }, + credentials: { + type: 'special', + jsType: 'string', + description: 'Reference to credential configuration', + example: 'googleSheetsOAuth2Api', + examples: ['httpBasicAuth', 'slackOAuth2Api', 'postgresApi'], + validation: { + allowEmpty: false, + allowExpressions: false, + }, + notes: [ + 'References credential type name', + 'Credential must be configured in n8n', + 'Type name matches credential definition', + ], + }, + credentialsSelect: { + type: 'special', + jsType: 'string', + description: 'Dropdown to select from available credentials', + example: 'credential-id-123', + examples: ['cred-abc', 'cred-def', '{{ $credentials.id }}'], + validation: { + allowEmpty: false, + allowExpressions: true, + }, + notes: [ + 'User selects from configured credentials', + 'Returns credential ID', + 'Used when multiple credential instances exist', + ], + }, + hidden: { + type: 'special', + jsType: 'string', + description: 'Hidden property not shown in UI (used for internal logic)', + example: '', + validation: { + allowEmpty: true, + allowExpressions: true, + }, + notes: [ + 'Not rendered in UI', + 'Can store metadata or computed values', + 'Often used for version tracking', + ], + }, + button: { + type: 'special', + jsType: 'string', + description: 'Clickable button that triggers an action', + example: '', + validation: { + allowEmpty: true, + allowExpressions: false, + }, + notes: [ + 'Triggers action when clicked', + 'Does not store a value', + 'Action defined in routing property', + ], + }, + callout: { + type: 'special', + jsType: 'string', + description: 'Informational message box (warning, info, success, error)', + example: '', + validation: { + allowEmpty: true, + allowExpressions: false, + }, + notes: [ + 'Display-only, no value stored', + 'Used for warnings and hints', + 'Style controlled by typeOptions', + ], + }, + notice: { + type: 'special', + jsType: 'string', + description: 'Notice message displayed to user', + example: '', + validation: { + allowEmpty: true, + allowExpressions: false, + }, + notes: ['Similar to callout', 'Display-only element', 'Provides contextual information'], + }, + workflowSelector: { + type: 'special', + jsType: 'string', + description: 'Dropdown to select another workflow', + example: 'workflow-123', + examples: ['wf-abc', '{{ $json.workflowId }}'], + validation: { + allowEmpty: false, + allowExpressions: true, + }, + notes: [ + 'Selects from available workflows', + 'Returns workflow ID', + 'Used in Execute Workflow node', + ], + }, + curlImport: { + type: 'special', + jsType: 'string', + description: 'Import configuration from cURL command', + example: 'curl -X GET https://api.example.com/data', + validation: { + allowEmpty: true, + allowExpressions: false, + }, + notes: [ + 'Parses cURL command to populate fields', + 'Used in HTTP Request node', + 'One-time import feature', + ], + }, +}; +exports.COMPLEX_TYPE_EXAMPLES = { + collection: { + basic: { + name: 'John Doe', + email: 'john@example.com', + }, + nested: { + user: { + firstName: 'Jane', + lastName: 'Smith', + }, + preferences: { + theme: 'dark', + notifications: true, + }, + }, + withExpressions: { + id: '{{ $json.userId }}', + timestamp: '{{ $now }}', + data: '{{ $json.payload }}', + }, + }, + fixedCollection: { + httpHeaders: { + headers: [ + { name: 'Content-Type', value: 'application/json' }, + { name: 'Authorization', value: 'Bearer {{ $credentials.token }}' }, + ], + }, + queryParameters: { + queryParameters: [ + { name: 'page', value: '1' }, + { name: 'limit', value: '100' }, + ], + }, + multipleCollections: { + headers: [{ name: 'Accept', value: 'application/json' }], + queryParameters: [{ name: 'filter', value: 'active' }], + }, + }, + filter: { + simple: { + conditions: [ + { + id: '1', + leftValue: '{{ $json.status }}', + operator: { type: 'string', operation: 'equals' }, + rightValue: 'active', + }, + ], + combinator: 'and', + }, + complex: { + conditions: [ + { + id: '1', + leftValue: '{{ $json.age }}', + operator: { type: 'number', operation: 'gt' }, + rightValue: 18, + }, + { + id: '2', + leftValue: '{{ $json.country }}', + operator: { type: 'string', operation: 'equals' }, + rightValue: 'US', + }, + ], + combinator: 'and', + }, + }, + resourceMapper: { + autoMap: { + mappingMode: 'autoMapInputData', + value: {}, + }, + manual: { + mappingMode: 'defineBelow', + value: { + firstName: '{{ $json.first_name }}', + lastName: '{{ $json.last_name }}', + email: '{{ $json.email_address }}', + status: 'active', + }, + }, + }, + assignmentCollection: { + basic: { + assignments: [ + { + id: '1', + name: 'fullName', + value: '{{ $json.firstName }} {{ $json.lastName }}', + type: 'string', + }, + ], + }, + multiple: { + assignments: [ + { id: '1', name: 'userName', value: '{{ $json.name }}', type: 'string' }, + { id: '2', name: 'userAge', value: '{{ $json.age }}', type: 'number' }, + { id: '3', name: 'isActive', value: true, type: 'boolean' }, + ], + }, + }, +}; +//# sourceMappingURL=type-structures.js.map \ No newline at end of file diff --git a/dist/constants/type-structures.js.map b/dist/constants/type-structures.js.map new file mode 100644 index 0000000..3b1e96f --- /dev/null +++ b/dist/constants/type-structures.js.map @@ -0,0 +1 @@ +{"version":3,"file":"type-structures.js","sourceRoot":"","sources":["../../src/constants/type-structures.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/database/database-adapter.d.ts b/dist/database/database-adapter.d.ts new file mode 100644 index 0000000..8615a50 --- /dev/null +++ b/dist/database/database-adapter.d.ts @@ -0,0 +1,33 @@ +export interface DatabaseAdapter { + prepare(sql: string): PreparedStatement; + exec(sql: string): void; + close(): void; + pragma(key: string, value?: any): any; + readonly inTransaction: boolean; + transaction(fn: () => T): T; + checkFTS5Support(): boolean; +} +export interface PreparedStatement { + run(...params: any[]): RunResult; + get(...params: any[]): any; + all(...params: any[]): any[]; + iterate(...params: any[]): IterableIterator; + pluck(toggle?: boolean): this; + expand(toggle?: boolean): this; + raw(toggle?: boolean): this; + columns(): ColumnDefinition[]; + bind(...params: any[]): this; +} +export interface RunResult { + changes: number; + lastInsertRowid: number | bigint; +} +export interface ColumnDefinition { + name: string; + column: string | null; + table: string | null; + database: string | null; + type: string | null; +} +export declare function createDatabaseAdapter(dbPath: string): Promise; +//# sourceMappingURL=database-adapter.d.ts.map \ No newline at end of file diff --git a/dist/database/database-adapter.d.ts.map b/dist/database/database-adapter.d.ts.map new file mode 100644 index 0000000..bfa7077 --- /dev/null +++ b/dist/database/database-adapter.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"database-adapter.d.ts","sourceRoot":"","sources":["../../src/database/database-adapter.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAAC;IACxC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;IACtC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAC/B,gBAAgB,IAAI,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC;IACjC,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAC3B,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC;IAC7B,OAAO,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACjD,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9B,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,GAAG,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5B,OAAO,IAAI,gBAAgB,EAAE,CAAC;IAC9B,IAAI,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,GAAG,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAMD,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAoDpF"} \ No newline at end of file diff --git a/dist/database/database-adapter.js b/dist/database/database-adapter.js new file mode 100644 index 0000000..21192cf --- /dev/null +++ b/dist/database/database-adapter.js @@ -0,0 +1,420 @@ +"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; + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createDatabaseAdapter = createDatabaseAdapter; +const fs_1 = require("fs"); +const fsSync = __importStar(require("fs")); +const path_1 = __importDefault(require("path")); +const logger_1 = require("../utils/logger"); +async function createDatabaseAdapter(dbPath) { + if (process.env.MCP_MODE !== 'stdio') { + logger_1.logger.info(`Node.js version: ${process.version}`); + } + if (process.env.MCP_MODE !== 'stdio') { + logger_1.logger.info(`Platform: ${process.platform} ${process.arch}`); + } + try { + if (process.env.MCP_MODE !== 'stdio') { + logger_1.logger.info('Attempting to use better-sqlite3...'); + } + const adapter = await createBetterSQLiteAdapter(dbPath); + if (process.env.MCP_MODE !== 'stdio') { + logger_1.logger.info('Successfully initialized better-sqlite3 adapter'); + } + return adapter; + } + catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + if (errorMessage.includes('NODE_MODULE_VERSION') || errorMessage.includes('was compiled against a different Node.js version')) { + if (process.env.MCP_MODE !== 'stdio') { + logger_1.logger.warn(`Node.js version mismatch detected. Better-sqlite3 was compiled for a different Node.js version.`); + } + if (process.env.MCP_MODE !== 'stdio') { + logger_1.logger.warn(`Current Node.js version: ${process.version}`); + } + } + if (process.env.MCP_MODE !== 'stdio') { + logger_1.logger.warn('Failed to initialize better-sqlite3, falling back to sql.js', error); + } + try { + const adapter = await createSQLJSAdapter(dbPath); + if (process.env.MCP_MODE !== 'stdio') { + logger_1.logger.info('Successfully initialized sql.js adapter (pure JavaScript, no native dependencies)'); + } + return adapter; + } + catch (sqlJsError) { + if (process.env.MCP_MODE !== 'stdio') { + logger_1.logger.error('Failed to initialize sql.js adapter', sqlJsError); + } + throw new Error('Failed to initialize any database adapter'); + } + } +} +async function createBetterSQLiteAdapter(dbPath) { + try { + const Database = require('better-sqlite3'); + const db = new Database(dbPath); + return new BetterSQLiteAdapter(db); + } + catch (error) { + throw new Error(`Failed to create better-sqlite3 adapter: ${error}`); + } +} +async function createSQLJSAdapter(dbPath) { + let initSqlJs; + try { + initSqlJs = require('sql.js'); + } + catch (error) { + logger_1.logger.error('Failed to load sql.js module:', error); + throw new Error('sql.js module not found. This might be an issue with npm package installation.'); + } + const SQL = await initSqlJs({ + locateFile: (file) => { + if (file.endsWith('.wasm')) { + const possiblePaths = [ + path_1.default.join(__dirname, '../../node_modules/sql.js/dist/', file), + path_1.default.join(__dirname, '../../../sql.js/dist/', file), + path_1.default.join(process.cwd(), 'node_modules/sql.js/dist/', file), + path_1.default.join(path_1.default.dirname(require.resolve('sql.js')), '../dist/', file) + ]; + for (const tryPath of possiblePaths) { + if (fsSync.existsSync(tryPath)) { + if (process.env.MCP_MODE !== 'stdio') { + logger_1.logger.debug(`Found WASM file at: ${tryPath}`); + } + return tryPath; + } + } + try { + const wasmPath = require.resolve('sql.js/dist/sql-wasm.wasm'); + if (process.env.MCP_MODE !== 'stdio') { + logger_1.logger.debug(`Found WASM file via require.resolve: ${wasmPath}`); + } + return wasmPath; + } + catch (e) { + logger_1.logger.warn(`Could not find WASM file, using default path: ${file}`); + return file; + } + } + return file; + } + }); + let db; + try { + const data = await fs_1.promises.readFile(dbPath); + db = new SQL.Database(new Uint8Array(data)); + logger_1.logger.info(`Loaded existing database from ${dbPath}`); + } + catch (error) { + db = new SQL.Database(); + logger_1.logger.info(`Created new database at ${dbPath}`); + } + return new SQLJSAdapter(db, dbPath); +} +class BetterSQLiteAdapter { + constructor(db) { + this.db = db; + } + prepare(sql) { + const stmt = this.db.prepare(sql); + return new BetterSQLiteStatement(stmt); + } + exec(sql) { + this.db.exec(sql); + } + close() { + this.db.close(); + } + pragma(key, value) { + return this.db.pragma(key, value); + } + get inTransaction() { + return this.db.inTransaction; + } + transaction(fn) { + return this.db.transaction(fn)(); + } + checkFTS5Support() { + try { + this.exec("CREATE VIRTUAL TABLE IF NOT EXISTS test_fts5 USING fts5(content);"); + this.exec("DROP TABLE IF EXISTS test_fts5;"); + return true; + } + catch (error) { + return false; + } + } +} +class SQLJSAdapter { + constructor(db, dbPath) { + this.db = db; + this.dbPath = dbPath; + this.saveTimer = null; + this.closed = false; + const envInterval = process.env.SQLJS_SAVE_INTERVAL_MS; + this.saveIntervalMs = envInterval ? parseInt(envInterval, 10) : SQLJSAdapter.DEFAULT_SAVE_INTERVAL_MS; + if (isNaN(this.saveIntervalMs) || this.saveIntervalMs < 100 || this.saveIntervalMs > 60000) { + logger_1.logger.warn(`Invalid SQLJS_SAVE_INTERVAL_MS value: ${envInterval} (must be 100-60000ms), ` + + `using default ${SQLJSAdapter.DEFAULT_SAVE_INTERVAL_MS}ms`); + this.saveIntervalMs = SQLJSAdapter.DEFAULT_SAVE_INTERVAL_MS; + } + logger_1.logger.debug(`SQLJSAdapter initialized with save interval: ${this.saveIntervalMs}ms`); + } + prepare(sql) { + const stmt = this.db.prepare(sql); + return new SQLJSStatement(stmt, () => this.scheduleSave()); + } + exec(sql) { + this.db.exec(sql); + this.scheduleSave(); + } + close() { + if (this.closed) { + logger_1.logger.debug('SQLJSAdapter already closed, skipping'); + return; + } + this.saveToFile(); + if (this.saveTimer) { + clearTimeout(this.saveTimer); + this.saveTimer = null; + } + this.db.close(); + this.closed = true; + } + pragma(key, value) { + if (key === 'journal_mode' && value === 'WAL') { + return 'memory'; + } + return null; + } + get inTransaction() { + return false; + } + transaction(fn) { + try { + this.exec('BEGIN'); + const result = fn(); + this.exec('COMMIT'); + return result; + } + catch (error) { + this.exec('ROLLBACK'); + throw error; + } + } + checkFTS5Support() { + try { + this.exec("CREATE VIRTUAL TABLE IF NOT EXISTS test_fts5 USING fts5(content);"); + this.exec("DROP TABLE IF EXISTS test_fts5;"); + return true; + } + catch (error) { + return false; + } + } + scheduleSave() { + if (this.saveTimer) { + clearTimeout(this.saveTimer); + } + this.saveTimer = setTimeout(() => { + this.saveToFile(); + }, this.saveIntervalMs); + } + saveToFile() { + try { + const data = this.db.export(); + fsSync.writeFileSync(this.dbPath, data); + logger_1.logger.debug(`Database saved to ${this.dbPath}`); + } + catch (error) { + logger_1.logger.error('Failed to save database', error); + } + } +} +SQLJSAdapter.DEFAULT_SAVE_INTERVAL_MS = 5000; +class BetterSQLiteStatement { + constructor(stmt) { + this.stmt = stmt; + } + run(...params) { + return this.stmt.run(...params); + } + get(...params) { + return this.stmt.get(...params); + } + all(...params) { + return this.stmt.all(...params); + } + iterate(...params) { + return this.stmt.iterate(...params); + } + pluck(toggle) { + this.stmt.pluck(toggle); + return this; + } + expand(toggle) { + this.stmt.expand(toggle); + return this; + } + raw(toggle) { + this.stmt.raw(toggle); + return this; + } + columns() { + return this.stmt.columns(); + } + bind(...params) { + this.stmt.bind(...params); + return this; + } +} +class SQLJSStatement { + constructor(stmt, onModify) { + this.stmt = stmt; + this.onModify = onModify; + this.boundParams = null; + } + run(...params) { + try { + if (params.length > 0) { + this.bindParams(params); + if (this.boundParams) { + this.stmt.bind(this.boundParams); + } + } + this.stmt.run(); + this.onModify(); + return { + changes: 1, + lastInsertRowid: 0 + }; + } + catch (error) { + this.stmt.reset(); + throw error; + } + } + get(...params) { + try { + if (params.length > 0) { + this.bindParams(params); + if (this.boundParams) { + this.stmt.bind(this.boundParams); + } + } + if (this.stmt.step()) { + const result = this.stmt.getAsObject(); + this.stmt.reset(); + return this.convertIntegerColumns(result); + } + this.stmt.reset(); + return undefined; + } + catch (error) { + this.stmt.reset(); + throw error; + } + } + all(...params) { + try { + if (params.length > 0) { + this.bindParams(params); + if (this.boundParams) { + this.stmt.bind(this.boundParams); + } + } + const results = []; + while (this.stmt.step()) { + results.push(this.convertIntegerColumns(this.stmt.getAsObject())); + } + this.stmt.reset(); + return results; + } + catch (error) { + this.stmt.reset(); + throw error; + } + } + iterate(...params) { + return this.all(...params)[Symbol.iterator](); + } + pluck(toggle) { + return this; + } + expand(toggle) { + return this; + } + raw(toggle) { + return this; + } + columns() { + return []; + } + bind(...params) { + this.bindParams(params); + return this; + } + bindParams(params) { + if (params.length === 0) { + this.boundParams = null; + return; + } + if (params.length === 1 && typeof params[0] === 'object' && !Array.isArray(params[0]) && params[0] !== null) { + this.boundParams = params[0]; + } + else { + this.boundParams = params.map(p => p === undefined ? null : p); + } + } + convertIntegerColumns(row) { + if (!row) + return row; + const integerColumns = ['is_ai_tool', 'is_trigger', 'is_webhook', 'is_versioned']; + const converted = { ...row }; + for (const col of integerColumns) { + if (col in converted && typeof converted[col] === 'string') { + converted[col] = parseInt(converted[col], 10); + } + } + return converted; + } +} +//# sourceMappingURL=database-adapter.js.map \ No newline at end of file diff --git a/dist/database/database-adapter.js.map b/dist/database/database-adapter.js.map new file mode 100644 index 0000000..ca7c7f3 --- /dev/null +++ b/dist/database/database-adapter.js.map @@ -0,0 +1 @@ +{"version":3,"file":"database-adapter.js","sourceRoot":"","sources":["../../src/database/database-adapter.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/database/node-repository.d.ts b/dist/database/node-repository.d.ts new file mode 100644 index 0000000..f1a6863 --- /dev/null +++ b/dist/database/node-repository.d.ts @@ -0,0 +1,91 @@ +import { DatabaseAdapter } from './database-adapter'; +import { ParsedNode } from '../parsers/node-parser'; +import { SQLiteStorageService } from '../services/sqlite-storage-service'; +export declare class NodeRepository { + private db; + constructor(dbOrService: DatabaseAdapter | SQLiteStorageService); + saveNode(node: ParsedNode): void; + getNode(nodeType: string): any; + getAITools(): any[]; + private safeJsonParse; + upsertNode(node: ParsedNode): void; + getNodeByType(nodeType: string): any; + getNodesByCategory(category: string): any[]; + searchNodes(query: string, mode?: 'OR' | 'AND' | 'FUZZY', limit?: number): any[]; + getAllNodes(limit?: number): any[]; + getNodeCount(): number; + getAIToolNodes(): any[]; + getNodesByPackage(packageName: string): any[]; + searchNodeProperties(nodeType: string, query: string, maxResults?: number): any[]; + private parseNodeRow; + getNodeOperations(nodeType: string, resource?: string): any[]; + getNodeResources(nodeType: string): any[]; + getOperationsForResource(nodeType: string, resource: string): any[]; + getAllOperations(): Map; + getAllResources(): Map; + getNodePropertyDefaults(nodeType: string): Record; + getDefaultOperationForResource(nodeType: string, resource?: string): string | undefined; + saveNodeVersion(versionData: { + nodeType: string; + version: string; + packageName: string; + displayName: string; + description?: string; + category?: string; + isCurrentMax?: boolean; + propertiesSchema?: any; + operations?: any; + credentialsRequired?: any; + outputs?: any; + minimumN8nVersion?: string; + breakingChanges?: any[]; + deprecatedProperties?: string[]; + addedProperties?: string[]; + releasedAt?: Date; + }): void; + getNodeVersions(nodeType: string): any[]; + getLatestNodeVersion(nodeType: string): any | null; + getNodeVersion(nodeType: string, version: string): any | null; + savePropertyChange(changeData: { + nodeType: string; + fromVersion: string; + toVersion: string; + propertyName: string; + changeType: 'added' | 'removed' | 'renamed' | 'type_changed' | 'requirement_changed' | 'default_changed'; + isBreaking?: boolean; + oldValue?: string; + newValue?: string; + migrationHint?: string; + autoMigratable?: boolean; + migrationStrategy?: any; + severity?: 'LOW' | 'MEDIUM' | 'HIGH'; + }): void; + getPropertyChanges(nodeType: string, fromVersion: string, toVersion: string): any[]; + getBreakingChanges(nodeType: string, fromVersion: string, toVersion?: string): any[]; + getAutoMigratableChanges(nodeType: string, fromVersion: string, toVersion: string): any[]; + hasVersionUpgradePath(nodeType: string, fromVersion: string, toVersion: string): boolean; + getVersionedNodesCount(): number; + private parseNodeVersionRow; + private parsePropertyChangeRow; + createWorkflowVersion(data: { + workflowId: string; + versionNumber: number; + workflowName: string; + workflowSnapshot: any; + trigger: 'partial_update' | 'full_update' | 'autofix'; + operations?: any[]; + fixTypes?: string[]; + metadata?: any; + }): number; + getWorkflowVersions(workflowId: string, limit?: number): any[]; + getWorkflowVersion(versionId: number): any | null; + getLatestWorkflowVersion(workflowId: string): any | null; + deleteWorkflowVersion(versionId: number): void; + deleteWorkflowVersionsByWorkflowId(workflowId: string): number; + pruneWorkflowVersions(workflowId: string, keepCount: number): number; + truncateWorkflowVersions(): number; + getWorkflowVersionCount(workflowId: string): number; + getVersionStorageStats(): any; + private parseWorkflowVersionRow; +} +//# sourceMappingURL=node-repository.d.ts.map \ No newline at end of file diff --git a/dist/database/node-repository.d.ts.map b/dist/database/node-repository.d.ts.map new file mode 100644 index 0000000..14287b6 --- /dev/null +++ b/dist/database/node-repository.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"node-repository.d.ts","sourceRoot":"","sources":["../../src/database/node-repository.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/database/node-repository.js b/dist/database/node-repository.js new file mode 100644 index 0000000..c58e5f9 --- /dev/null +++ b/dist/database/node-repository.js @@ -0,0 +1,603 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.NodeRepository = void 0; +const sqlite_storage_service_1 = require("../services/sqlite-storage-service"); +const node_type_normalizer_1 = require("../utils/node-type-normalizer"); +class NodeRepository { + constructor(dbOrService) { + if (dbOrService instanceof sqlite_storage_service_1.SQLiteStorageService) { + this.db = dbOrService.db; + return; + } + this.db = dbOrService; + } + saveNode(node) { + const stmt = this.db.prepare(` + INSERT OR REPLACE INTO nodes ( + node_type, package_name, display_name, description, + category, development_style, is_ai_tool, is_trigger, + is_webhook, is_versioned, version, documentation, + properties_schema, operations, credentials_required, + outputs, output_names + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `); + stmt.run(node.nodeType, node.packageName, node.displayName, node.description, node.category, node.style, node.isAITool ? 1 : 0, node.isTrigger ? 1 : 0, node.isWebhook ? 1 : 0, node.isVersioned ? 1 : 0, node.version, node.documentation || null, JSON.stringify(node.properties, null, 2), JSON.stringify(node.operations, null, 2), JSON.stringify(node.credentials, null, 2), node.outputs ? JSON.stringify(node.outputs, null, 2) : null, node.outputNames ? JSON.stringify(node.outputNames, null, 2) : null); + } + getNode(nodeType) { + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + const row = this.db.prepare(` + SELECT * FROM nodes WHERE node_type = ? + `).get(normalizedType); + if (!row && normalizedType !== nodeType) { + const originalRow = this.db.prepare(` + SELECT * FROM nodes WHERE node_type = ? + `).get(nodeType); + if (originalRow) { + return this.parseNodeRow(originalRow); + } + } + if (!row) + return null; + return this.parseNodeRow(row); + } + getAITools() { + const rows = this.db.prepare(` + SELECT node_type, display_name, description, package_name + FROM nodes + WHERE is_ai_tool = 1 + ORDER BY display_name + `).all(); + return rows.map(row => ({ + nodeType: row.node_type, + displayName: row.display_name, + description: row.description, + package: row.package_name + })); + } + safeJsonParse(json, defaultValue) { + try { + return JSON.parse(json); + } + catch { + return defaultValue; + } + } + upsertNode(node) { + this.saveNode(node); + } + getNodeByType(nodeType) { + return this.getNode(nodeType); + } + getNodesByCategory(category) { + const rows = this.db.prepare(` + SELECT * FROM nodes WHERE category = ? + ORDER BY display_name + `).all(category); + return rows.map(row => this.parseNodeRow(row)); + } + searchNodes(query, mode = 'OR', limit = 20) { + let sql = ''; + const params = []; + if (mode === 'FUZZY') { + sql = ` + SELECT * FROM nodes + WHERE node_type LIKE ? OR display_name LIKE ? OR description LIKE ? + ORDER BY display_name + LIMIT ? + `; + const fuzzyQuery = `%${query}%`; + params.push(fuzzyQuery, fuzzyQuery, fuzzyQuery, limit); + } + else { + const words = query.split(/\s+/).filter(w => w.length > 0); + const conditions = words.map(() => '(node_type LIKE ? OR display_name LIKE ? OR description LIKE ?)'); + const operator = mode === 'AND' ? ' AND ' : ' OR '; + sql = ` + SELECT * FROM nodes + WHERE ${conditions.join(operator)} + ORDER BY display_name + LIMIT ? + `; + for (const word of words) { + const searchTerm = `%${word}%`; + params.push(searchTerm, searchTerm, searchTerm); + } + params.push(limit); + } + const rows = this.db.prepare(sql).all(...params); + return rows.map(row => this.parseNodeRow(row)); + } + getAllNodes(limit) { + let sql = 'SELECT * FROM nodes ORDER BY display_name'; + if (limit) { + sql += ` LIMIT ${limit}`; + } + const rows = this.db.prepare(sql).all(); + return rows.map(row => this.parseNodeRow(row)); + } + getNodeCount() { + const result = this.db.prepare('SELECT COUNT(*) as count FROM nodes').get(); + return result.count; + } + getAIToolNodes() { + return this.getAITools(); + } + getNodesByPackage(packageName) { + const rows = this.db.prepare(` + SELECT * FROM nodes WHERE package_name = ? + ORDER BY display_name + `).all(packageName); + return rows.map(row => this.parseNodeRow(row)); + } + searchNodeProperties(nodeType, query, maxResults = 20) { + const node = this.getNode(nodeType); + if (!node || !node.properties) + return []; + const results = []; + const searchLower = query.toLowerCase(); + function searchProperties(properties, path = []) { + for (const prop of properties) { + if (results.length >= maxResults) + break; + const currentPath = [...path, prop.name || prop.displayName]; + const pathString = currentPath.join('.'); + if (prop.name?.toLowerCase().includes(searchLower) || + prop.displayName?.toLowerCase().includes(searchLower) || + prop.description?.toLowerCase().includes(searchLower)) { + results.push({ + path: pathString, + property: prop, + description: prop.description + }); + } + if (prop.options) { + searchProperties(prop.options, currentPath); + } + } + } + searchProperties(node.properties); + return results; + } + parseNodeRow(row) { + return { + nodeType: row.node_type, + displayName: row.display_name, + description: row.description, + category: row.category, + developmentStyle: row.development_style, + package: row.package_name, + isAITool: Number(row.is_ai_tool) === 1, + isTrigger: Number(row.is_trigger) === 1, + isWebhook: Number(row.is_webhook) === 1, + isVersioned: Number(row.is_versioned) === 1, + version: row.version, + properties: this.safeJsonParse(row.properties_schema, []), + operations: this.safeJsonParse(row.operations, []), + credentials: this.safeJsonParse(row.credentials_required, []), + hasDocumentation: !!row.documentation, + outputs: row.outputs ? this.safeJsonParse(row.outputs, null) : null, + outputNames: row.output_names ? this.safeJsonParse(row.output_names, null) : null + }; + } + getNodeOperations(nodeType, resource) { + const node = this.getNode(nodeType); + if (!node) + return []; + const operations = []; + if (node.operations) { + if (Array.isArray(node.operations)) { + operations.push(...node.operations); + } + else if (typeof node.operations === 'object') { + if (resource && node.operations[resource]) { + return node.operations[resource]; + } + else { + Object.values(node.operations).forEach(ops => { + if (Array.isArray(ops)) { + operations.push(...ops); + } + }); + } + } + } + if (node.properties && Array.isArray(node.properties)) { + for (const prop of node.properties) { + if (prop.name === 'operation' && prop.options) { + if (resource && prop.displayOptions?.show?.resource) { + const allowedResources = Array.isArray(prop.displayOptions.show.resource) + ? prop.displayOptions.show.resource + : [prop.displayOptions.show.resource]; + if (!allowedResources.includes(resource)) { + continue; + } + } + operations.push(...prop.options); + } + } + } + return operations; + } + getNodeResources(nodeType) { + const node = this.getNode(nodeType); + if (!node || !node.properties) + return []; + const resources = []; + for (const prop of node.properties) { + if (prop.name === 'resource' && prop.options) { + resources.push(...prop.options); + } + } + return resources; + } + getOperationsForResource(nodeType, resource) { + const node = this.getNode(nodeType); + if (!node || !node.properties) + return []; + const operations = []; + for (const prop of node.properties) { + if (prop.name === 'operation' && prop.displayOptions?.show?.resource) { + const allowedResources = Array.isArray(prop.displayOptions.show.resource) + ? prop.displayOptions.show.resource + : [prop.displayOptions.show.resource]; + if (allowedResources.includes(resource) && prop.options) { + operations.push(...prop.options); + } + } + } + return operations; + } + getAllOperations() { + const allOperations = new Map(); + const nodes = this.getAllNodes(); + for (const node of nodes) { + const operations = this.getNodeOperations(node.nodeType); + if (operations.length > 0) { + allOperations.set(node.nodeType, operations); + } + } + return allOperations; + } + getAllResources() { + const allResources = new Map(); + const nodes = this.getAllNodes(); + for (const node of nodes) { + const resources = this.getNodeResources(node.nodeType); + if (resources.length > 0) { + allResources.set(node.nodeType, resources); + } + } + return allResources; + } + getNodePropertyDefaults(nodeType) { + try { + const node = this.getNode(nodeType); + if (!node || !node.properties) + return {}; + const defaults = {}; + for (const prop of node.properties) { + if (prop.name && prop.default !== undefined) { + defaults[prop.name] = prop.default; + } + } + return defaults; + } + catch (error) { + console.error(`Error getting property defaults for ${nodeType}:`, error); + return {}; + } + } + getDefaultOperationForResource(nodeType, resource) { + try { + const node = this.getNode(nodeType); + if (!node || !node.properties) + return undefined; + for (const prop of node.properties) { + if (prop.name === 'operation') { + if (resource && prop.displayOptions?.show?.resource) { + const resourceDep = prop.displayOptions.show.resource; + if (!Array.isArray(resourceDep) && typeof resourceDep !== 'string') { + continue; + } + const allowedResources = Array.isArray(resourceDep) + ? resourceDep + : [resourceDep]; + if (!allowedResources.includes(resource)) { + continue; + } + } + if (prop.default !== undefined) { + return prop.default; + } + if (prop.options && Array.isArray(prop.options) && prop.options.length > 0) { + const firstOption = prop.options[0]; + return typeof firstOption === 'string' ? firstOption : firstOption.value; + } + } + } + } + catch (error) { + console.error(`Error getting default operation for ${nodeType}:`, error); + return undefined; + } + return undefined; + } + saveNodeVersion(versionData) { + const stmt = this.db.prepare(` + INSERT OR REPLACE INTO node_versions ( + node_type, version, package_name, display_name, description, + category, is_current_max, properties_schema, operations, + credentials_required, outputs, minimum_n8n_version, + breaking_changes, deprecated_properties, added_properties, + released_at + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `); + stmt.run(versionData.nodeType, versionData.version, versionData.packageName, versionData.displayName, versionData.description || null, versionData.category || null, versionData.isCurrentMax ? 1 : 0, versionData.propertiesSchema ? JSON.stringify(versionData.propertiesSchema) : null, versionData.operations ? JSON.stringify(versionData.operations) : null, versionData.credentialsRequired ? JSON.stringify(versionData.credentialsRequired) : null, versionData.outputs ? JSON.stringify(versionData.outputs) : null, versionData.minimumN8nVersion || null, versionData.breakingChanges ? JSON.stringify(versionData.breakingChanges) : null, versionData.deprecatedProperties ? JSON.stringify(versionData.deprecatedProperties) : null, versionData.addedProperties ? JSON.stringify(versionData.addedProperties) : null, versionData.releasedAt || null); + } + getNodeVersions(nodeType) { + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + const rows = this.db.prepare(` + SELECT * FROM node_versions + WHERE node_type = ? + ORDER BY version DESC + `).all(normalizedType); + return rows.map(row => this.parseNodeVersionRow(row)); + } + getLatestNodeVersion(nodeType) { + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + const row = this.db.prepare(` + SELECT * FROM node_versions + WHERE node_type = ? AND is_current_max = 1 + LIMIT 1 + `).get(normalizedType); + if (!row) + return null; + return this.parseNodeVersionRow(row); + } + getNodeVersion(nodeType, version) { + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + const row = this.db.prepare(` + SELECT * FROM node_versions + WHERE node_type = ? AND version = ? + `).get(normalizedType, version); + if (!row) + return null; + return this.parseNodeVersionRow(row); + } + savePropertyChange(changeData) { + const stmt = this.db.prepare(` + INSERT INTO version_property_changes ( + node_type, from_version, to_version, property_name, change_type, + is_breaking, old_value, new_value, migration_hint, auto_migratable, + migration_strategy, severity + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `); + stmt.run(changeData.nodeType, changeData.fromVersion, changeData.toVersion, changeData.propertyName, changeData.changeType, changeData.isBreaking ? 1 : 0, changeData.oldValue || null, changeData.newValue || null, changeData.migrationHint || null, changeData.autoMigratable ? 1 : 0, changeData.migrationStrategy ? JSON.stringify(changeData.migrationStrategy) : null, changeData.severity || 'MEDIUM'); + } + getPropertyChanges(nodeType, fromVersion, toVersion) { + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + const rows = this.db.prepare(` + SELECT * FROM version_property_changes + WHERE node_type = ? AND from_version = ? AND to_version = ? + ORDER BY severity DESC, property_name + `).all(normalizedType, fromVersion, toVersion); + return rows.map(row => this.parsePropertyChangeRow(row)); + } + getBreakingChanges(nodeType, fromVersion, toVersion) { + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + let sql = ` + SELECT * FROM version_property_changes + WHERE node_type = ? AND is_breaking = 1 + `; + const params = [normalizedType]; + if (toVersion) { + sql += ` AND from_version >= ? AND to_version <= ?`; + params.push(fromVersion, toVersion); + } + else { + sql += ` AND from_version >= ?`; + params.push(fromVersion); + } + sql += ` ORDER BY from_version, to_version, severity DESC`; + const rows = this.db.prepare(sql).all(...params); + return rows.map(row => this.parsePropertyChangeRow(row)); + } + getAutoMigratableChanges(nodeType, fromVersion, toVersion) { + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + const rows = this.db.prepare(` + SELECT * FROM version_property_changes + WHERE node_type = ? + AND from_version = ? + AND to_version = ? + AND auto_migratable = 1 + ORDER BY severity DESC + `).all(normalizedType, fromVersion, toVersion); + return rows.map(row => this.parsePropertyChangeRow(row)); + } + hasVersionUpgradePath(nodeType, fromVersion, toVersion) { + const versions = this.getNodeVersions(nodeType); + if (versions.length === 0) + return false; + const fromExists = versions.some(v => v.version === fromVersion); + const toExists = versions.some(v => v.version === toVersion); + return fromExists && toExists; + } + getVersionedNodesCount() { + const result = this.db.prepare(` + SELECT COUNT(DISTINCT node_type) as count + FROM node_versions + `).get(); + return result.count; + } + parseNodeVersionRow(row) { + return { + id: row.id, + nodeType: row.node_type, + version: row.version, + packageName: row.package_name, + displayName: row.display_name, + description: row.description, + category: row.category, + isCurrentMax: Number(row.is_current_max) === 1, + propertiesSchema: row.properties_schema ? this.safeJsonParse(row.properties_schema, []) : null, + operations: row.operations ? this.safeJsonParse(row.operations, []) : null, + credentialsRequired: row.credentials_required ? this.safeJsonParse(row.credentials_required, []) : null, + outputs: row.outputs ? this.safeJsonParse(row.outputs, null) : null, + minimumN8nVersion: row.minimum_n8n_version, + breakingChanges: row.breaking_changes ? this.safeJsonParse(row.breaking_changes, []) : [], + deprecatedProperties: row.deprecated_properties ? this.safeJsonParse(row.deprecated_properties, []) : [], + addedProperties: row.added_properties ? this.safeJsonParse(row.added_properties, []) : [], + releasedAt: row.released_at, + createdAt: row.created_at + }; + } + parsePropertyChangeRow(row) { + return { + id: row.id, + nodeType: row.node_type, + fromVersion: row.from_version, + toVersion: row.to_version, + propertyName: row.property_name, + changeType: row.change_type, + isBreaking: Number(row.is_breaking) === 1, + oldValue: row.old_value, + newValue: row.new_value, + migrationHint: row.migration_hint, + autoMigratable: Number(row.auto_migratable) === 1, + migrationStrategy: row.migration_strategy ? this.safeJsonParse(row.migration_strategy, null) : null, + severity: row.severity, + createdAt: row.created_at + }; + } + createWorkflowVersion(data) { + const stmt = this.db.prepare(` + INSERT INTO workflow_versions ( + workflow_id, version_number, workflow_name, workflow_snapshot, + trigger, operations, fix_types, metadata + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) + `); + const result = stmt.run(data.workflowId, data.versionNumber, data.workflowName, JSON.stringify(data.workflowSnapshot), data.trigger, data.operations ? JSON.stringify(data.operations) : null, data.fixTypes ? JSON.stringify(data.fixTypes) : null, data.metadata ? JSON.stringify(data.metadata) : null); + return result.lastInsertRowid; + } + getWorkflowVersions(workflowId, limit) { + let sql = ` + SELECT * FROM workflow_versions + WHERE workflow_id = ? + ORDER BY version_number DESC + `; + if (limit) { + sql += ` LIMIT ?`; + const rows = this.db.prepare(sql).all(workflowId, limit); + return rows.map(row => this.parseWorkflowVersionRow(row)); + } + const rows = this.db.prepare(sql).all(workflowId); + return rows.map(row => this.parseWorkflowVersionRow(row)); + } + getWorkflowVersion(versionId) { + const row = this.db.prepare(` + SELECT * FROM workflow_versions WHERE id = ? + `).get(versionId); + if (!row) + return null; + return this.parseWorkflowVersionRow(row); + } + getLatestWorkflowVersion(workflowId) { + const row = this.db.prepare(` + SELECT * FROM workflow_versions + WHERE workflow_id = ? + ORDER BY version_number DESC + LIMIT 1 + `).get(workflowId); + if (!row) + return null; + return this.parseWorkflowVersionRow(row); + } + deleteWorkflowVersion(versionId) { + this.db.prepare(` + DELETE FROM workflow_versions WHERE id = ? + `).run(versionId); + } + deleteWorkflowVersionsByWorkflowId(workflowId) { + const result = this.db.prepare(` + DELETE FROM workflow_versions WHERE workflow_id = ? + `).run(workflowId); + return result.changes; + } + pruneWorkflowVersions(workflowId, keepCount) { + const versions = this.db.prepare(` + SELECT id FROM workflow_versions + WHERE workflow_id = ? + ORDER BY version_number DESC + `).all(workflowId); + if (versions.length <= keepCount) { + return 0; + } + const idsToDelete = versions.slice(keepCount).map(v => v.id); + if (idsToDelete.length === 0) { + return 0; + } + const placeholders = idsToDelete.map(() => '?').join(','); + const result = this.db.prepare(` + DELETE FROM workflow_versions WHERE id IN (${placeholders}) + `).run(...idsToDelete); + return result.changes; + } + truncateWorkflowVersions() { + const result = this.db.prepare(` + DELETE FROM workflow_versions + `).run(); + return result.changes; + } + getWorkflowVersionCount(workflowId) { + const result = this.db.prepare(` + SELECT COUNT(*) as count FROM workflow_versions WHERE workflow_id = ? + `).get(workflowId); + return result.count; + } + getVersionStorageStats() { + const totalResult = this.db.prepare(` + SELECT COUNT(*) as count FROM workflow_versions + `).get(); + const sizeResult = this.db.prepare(` + SELECT SUM(LENGTH(workflow_snapshot)) as total_size FROM workflow_versions + `).get(); + const byWorkflow = this.db.prepare(` + SELECT + workflow_id, + workflow_name, + COUNT(*) as version_count, + SUM(LENGTH(workflow_snapshot)) as total_size, + MAX(created_at) as last_backup + FROM workflow_versions + GROUP BY workflow_id + ORDER BY version_count DESC + `).all(); + return { + totalVersions: totalResult.count, + totalSize: sizeResult.total_size || 0, + byWorkflow: byWorkflow.map(row => ({ + workflowId: row.workflow_id, + workflowName: row.workflow_name, + versionCount: row.version_count, + totalSize: row.total_size, + lastBackup: row.last_backup + })) + }; + } + parseWorkflowVersionRow(row) { + return { + id: row.id, + workflowId: row.workflow_id, + versionNumber: row.version_number, + workflowName: row.workflow_name, + workflowSnapshot: this.safeJsonParse(row.workflow_snapshot, null), + trigger: row.trigger, + operations: row.operations ? this.safeJsonParse(row.operations, null) : null, + fixTypes: row.fix_types ? this.safeJsonParse(row.fix_types, null) : null, + metadata: row.metadata ? this.safeJsonParse(row.metadata, null) : null, + createdAt: row.created_at + }; + } +} +exports.NodeRepository = NodeRepository; +//# sourceMappingURL=node-repository.js.map \ No newline at end of file diff --git a/dist/database/node-repository.js.map b/dist/database/node-repository.js.map new file mode 100644 index 0000000..7e37ef4 --- /dev/null +++ b/dist/database/node-repository.js.map @@ -0,0 +1 @@ +{"version":3,"file":"node-repository.js","sourceRoot":"","sources":["../../src/database/node-repository.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/errors/validation-service-error.d.ts b/dist/errors/validation-service-error.d.ts new file mode 100644 index 0000000..20261ea --- /dev/null +++ b/dist/errors/validation-service-error.d.ts @@ -0,0 +1,10 @@ +export declare class ValidationServiceError extends Error { + readonly nodeType?: string | undefined; + readonly property?: string | undefined; + readonly cause?: Error | undefined; + constructor(message: string, nodeType?: string | undefined, property?: string | undefined, cause?: Error | undefined); + static jsonParseError(nodeType: string, cause: Error): ValidationServiceError; + static nodeNotFound(nodeType: string): ValidationServiceError; + static dataExtractionError(nodeType: string, dataType: string, cause?: Error): ValidationServiceError; +} +//# sourceMappingURL=validation-service-error.d.ts.map \ No newline at end of file diff --git a/dist/errors/validation-service-error.d.ts.map b/dist/errors/validation-service-error.d.ts.map new file mode 100644 index 0000000..76d90ce --- /dev/null +++ b/dist/errors/validation-service-error.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"validation-service-error.d.ts","sourceRoot":"","sources":["../../src/errors/validation-service-error.ts"],"names":[],"mappings":"AAGA,qBAAa,sBAAuB,SAAQ,KAAK;aAG7B,QAAQ,CAAC,EAAE,MAAM;aACjB,QAAQ,CAAC,EAAE,MAAM;aACjB,KAAK,CAAC,EAAE,KAAK;gBAH7B,OAAO,EAAE,MAAM,EACC,QAAQ,CAAC,EAAE,MAAM,YAAA,EACjB,QAAQ,CAAC,EAAE,MAAM,YAAA,EACjB,KAAK,CAAC,EAAE,KAAK,YAAA;IAc/B,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,sBAAsB;IAY7E,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,sBAAsB;IAU7D,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,sBAAsB;CAQtG"} \ No newline at end of file diff --git a/dist/errors/validation-service-error.js b/dist/errors/validation-service-error.js new file mode 100644 index 0000000..8e10086 --- /dev/null +++ b/dist/errors/validation-service-error.js @@ -0,0 +1,26 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ValidationServiceError = void 0; +class ValidationServiceError extends Error { + constructor(message, nodeType, property, cause) { + super(message); + this.nodeType = nodeType; + this.property = property; + this.cause = cause; + this.name = 'ValidationServiceError'; + if (Error.captureStackTrace) { + Error.captureStackTrace(this, ValidationServiceError); + } + } + static jsonParseError(nodeType, cause) { + return new ValidationServiceError(`Failed to parse JSON data for node ${nodeType}`, nodeType, undefined, cause); + } + static nodeNotFound(nodeType) { + return new ValidationServiceError(`Node type ${nodeType} not found in repository`, nodeType); + } + static dataExtractionError(nodeType, dataType, cause) { + return new ValidationServiceError(`Failed to extract ${dataType} for node ${nodeType}`, nodeType, dataType, cause); + } +} +exports.ValidationServiceError = ValidationServiceError; +//# sourceMappingURL=validation-service-error.js.map \ No newline at end of file diff --git a/dist/errors/validation-service-error.js.map b/dist/errors/validation-service-error.js.map new file mode 100644 index 0000000..6651411 --- /dev/null +++ b/dist/errors/validation-service-error.js.map @@ -0,0 +1 @@ +{"version":3,"file":"validation-service-error.js","sourceRoot":"","sources":["../../src/errors/validation-service-error.ts"],"names":[],"mappings":";;;AAGA,MAAa,sBAAuB,SAAQ,KAAK;IAC/C,YACE,OAAe,EACC,QAAiB,EACjB,QAAiB,EACjB,KAAa;QAE7B,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,aAAQ,GAAR,QAAQ,CAAS;QACjB,aAAQ,GAAR,QAAQ,CAAS;QACjB,UAAK,GAAL,KAAK,CAAQ;QAG7B,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QAGrC,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAKD,MAAM,CAAC,cAAc,CAAC,QAAgB,EAAE,KAAY;QAClD,OAAO,IAAI,sBAAsB,CAC/B,sCAAsC,QAAQ,EAAE,EAChD,QAAQ,EACR,SAAS,EACT,KAAK,CACN,CAAC;IACJ,CAAC;IAKD,MAAM,CAAC,YAAY,CAAC,QAAgB;QAClC,OAAO,IAAI,sBAAsB,CAC/B,aAAa,QAAQ,0BAA0B,EAC/C,QAAQ,CACT,CAAC;IACJ,CAAC;IAKD,MAAM,CAAC,mBAAmB,CAAC,QAAgB,EAAE,QAAgB,EAAE,KAAa;QAC1E,OAAO,IAAI,sBAAsB,CAC/B,qBAAqB,QAAQ,aAAa,QAAQ,EAAE,EACpD,QAAQ,EACR,QAAQ,EACR,KAAK,CACN,CAAC;IACJ,CAAC;CACF;AAjDD,wDAiDC"} \ No newline at end of file diff --git a/dist/http-server-single-session.d.ts b/dist/http-server-single-session.d.ts new file mode 100644 index 0000000..80ce0ab --- /dev/null +++ b/dist/http-server-single-session.d.ts @@ -0,0 +1,52 @@ +#!/usr/bin/env node +import express from 'express'; +import { InstanceContext } from './types/instance-context'; +import { SessionState } from './types/session-state'; +export declare class SingleSessionHTTPServer { + private transports; + private servers; + private sessionMetadata; + private sessionContexts; + private contextSwitchLocks; + private session; + private consoleManager; + private expressServer; + private sessionTimeout; + private authToken; + private cleanupTimer; + constructor(); + private startSessionCleanup; + private cleanupExpiredSessions; + private removeSession; + private getActiveSessionCount; + private canCreateSession; + private isValidSessionId; + private sanitizeErrorForClient; + private updateSessionAccess; + private switchSessionContext; + private performContextSwitch; + private getSessionMetrics; + private loadAuthToken; + private validateEnvironment; + handleRequest(req: express.Request, res: express.Response, instanceContext?: InstanceContext): Promise; + private resetSessionSSE; + private isExpired; + private isSessionExpired; + start(): Promise; + shutdown(): Promise; + getSessionInfo(): { + active: boolean; + sessionId?: string; + age?: number; + sessions?: { + total: number; + active: number; + expired: number; + max: number; + sessionIds: string[]; + }; + }; + exportSessionState(): SessionState[]; + restoreSessionState(sessions: SessionState[]): number; +} +//# sourceMappingURL=http-server-single-session.d.ts.map \ No newline at end of file diff --git a/dist/http-server-single-session.d.ts.map b/dist/http-server-single-session.d.ts.map new file mode 100644 index 0000000..8cc109c --- /dev/null +++ b/dist/http-server-single-session.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"http-server-single-session.d.ts","sourceRoot":"","sources":["../src/http-server-single-session.ts"],"names":[],"mappings":";AAMA,OAAO,OAAO,MAAM,SAAS,CAAC;AAoB9B,OAAO,EAAE,eAAe,EAA2B,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAuErD,qBAAa,uBAAuB;IAElC,OAAO,CAAC,UAAU,CAA8D;IAChF,OAAO,CAAC,OAAO,CAA0D;IACzE,OAAO,CAAC,eAAe,CAAsE;IAC7F,OAAO,CAAC,eAAe,CAA4D;IACnF,OAAO,CAAC,kBAAkB,CAAyC;IACnE,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,YAAY,CAA+B;;IAcnD,OAAO,CAAC,mBAAmB;IAmB3B,OAAO,CAAC,sBAAsB;YAqChB,aAAa;IA2B3B,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,sBAAsB;IAkC9B,OAAO,CAAC,mBAAmB;YASb,oBAAoB;YAwBpB,oBAAoB;IAwBlC,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,aAAa;IA2BrB,OAAO,CAAC,mBAAmB;IAoDrB,aAAa,CACjB,GAAG,EAAE,OAAO,CAAC,OAAO,EACpB,GAAG,EAAE,OAAO,CAAC,QAAQ,EACrB,eAAe,CAAC,EAAE,eAAe,GAChC,OAAO,CAAC,IAAI,CAAC;YAmOF,eAAe;IA8C7B,OAAO,CAAC,SAAS;IAYjB,OAAO,CAAC,gBAAgB;IASlB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgnBtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAkD/B,cAAc,IAAI;QAChB,MAAM,EAAE,OAAO,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE;YACT,KAAK,EAAE,MAAM,CAAC;YACd,MAAM,EAAE,MAAM,CAAC;YACf,OAAO,EAAE,MAAM,CAAC;YAChB,GAAG,EAAE,MAAM,CAAC;YACZ,UAAU,EAAE,MAAM,EAAE,CAAC;SACtB,CAAC;KACH;IAmDM,kBAAkB,IAAI,YAAY,EAAE;IAoEpC,mBAAmB,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM;CAsG7D"} \ No newline at end of file diff --git a/dist/http-server-single-session.js b/dist/http-server-single-session.js new file mode 100644 index 0000000..2b7ffa8 --- /dev/null +++ b/dist/http-server-single-session.js @@ -0,0 +1,1171 @@ +#!/usr/bin/env node +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.SingleSessionHTTPServer = void 0; +const express_1 = __importDefault(require("express")); +const express_rate_limit_1 = __importDefault(require("express-rate-limit")); +const streamableHttp_js_1 = require("@modelcontextprotocol/sdk/server/streamableHttp.js"); +const sse_js_1 = require("@modelcontextprotocol/sdk/server/sse.js"); +const server_1 = require("./mcp/server"); +const console_manager_1 = require("./utils/console-manager"); +const logger_1 = require("./utils/logger"); +const auth_1 = require("./utils/auth"); +const fs_1 = require("fs"); +const dotenv_1 = __importDefault(require("dotenv")); +const url_detector_1 = require("./utils/url-detector"); +const version_1 = require("./utils/version"); +const uuid_1 = require("uuid"); +const crypto_1 = require("crypto"); +const types_js_1 = require("@modelcontextprotocol/sdk/types.js"); +const protocol_version_1 = require("./utils/protocol-version"); +const instance_context_1 = require("./types/instance-context"); +dotenv_1.default.config(); +const DEFAULT_PROTOCOL_VERSION = protocol_version_1.STANDARD_PROTOCOL_VERSION; +const MAX_SESSIONS = 100; +const SESSION_CLEANUP_INTERVAL = 5 * 60 * 1000; +function extractMultiTenantHeaders(req) { + return { + 'x-n8n-url': req.headers['x-n8n-url'], + 'x-n8n-key': req.headers['x-n8n-key'], + 'x-instance-id': req.headers['x-instance-id'], + 'x-session-id': req.headers['x-session-id'], + }; +} +function logSecurityEvent(event, details) { + const timestamp = new Date().toISOString(); + const logEntry = { + timestamp, + event, + ...details + }; + logger_1.logger.info(`[SECURITY] ${event}`, logEntry); +} +class SingleSessionHTTPServer { + constructor() { + this.transports = {}; + this.servers = {}; + this.sessionMetadata = {}; + this.sessionContexts = {}; + this.contextSwitchLocks = new Map(); + this.session = null; + this.consoleManager = new console_manager_1.ConsoleManager(); + this.sessionTimeout = 30 * 60 * 1000; + this.authToken = null; + this.cleanupTimer = null; + this.validateEnvironment(); + this.startSessionCleanup(); + } + startSessionCleanup() { + this.cleanupTimer = setInterval(async () => { + try { + await this.cleanupExpiredSessions(); + } + catch (error) { + logger_1.logger.error('Error during session cleanup', error); + } + }, SESSION_CLEANUP_INTERVAL); + logger_1.logger.info('Session cleanup started', { + interval: SESSION_CLEANUP_INTERVAL / 1000 / 60, + maxSessions: MAX_SESSIONS, + sessionTimeout: this.sessionTimeout / 1000 / 60 + }); + } + cleanupExpiredSessions() { + const now = Date.now(); + const expiredSessions = []; + for (const sessionId in this.sessionMetadata) { + const metadata = this.sessionMetadata[sessionId]; + if (now - metadata.lastAccess.getTime() > this.sessionTimeout) { + expiredSessions.push(sessionId); + } + } + for (const sessionId in this.sessionContexts) { + if (!this.sessionMetadata[sessionId]) { + delete this.sessionContexts[sessionId]; + logger_1.logger.debug('Cleaned orphaned session context', { sessionId }); + } + } + for (const sessionId of expiredSessions) { + this.removeSession(sessionId, 'expired'); + } + if (expiredSessions.length > 0) { + logger_1.logger.info('Cleaned up expired sessions', { + removed: expiredSessions.length, + remaining: this.getActiveSessionCount() + }); + } + } + async removeSession(sessionId, reason) { + try { + const transport = this.transports[sessionId]; + delete this.transports[sessionId]; + delete this.servers[sessionId]; + delete this.sessionMetadata[sessionId]; + delete this.sessionContexts[sessionId]; + if (transport) { + await transport.close(); + } + logger_1.logger.info('Session removed', { sessionId, reason }); + } + catch (error) { + logger_1.logger.warn('Error removing session', { sessionId, reason, error }); + } + } + getActiveSessionCount() { + return Object.keys(this.transports).length; + } + canCreateSession() { + return this.getActiveSessionCount() < MAX_SESSIONS; + } + isValidSessionId(sessionId) { + return Boolean(sessionId && sessionId.length > 0); + } + sanitizeErrorForClient(error) { + const isProduction = process.env.NODE_ENV === 'production'; + if (error instanceof Error) { + if (isProduction) { + if (error.message.includes('Unauthorized') || error.message.includes('authentication')) { + return { message: 'Authentication failed', code: 'AUTH_ERROR' }; + } + if (error.message.includes('Session') || error.message.includes('session')) { + return { message: 'Session error', code: 'SESSION_ERROR' }; + } + if (error.message.includes('Invalid') || error.message.includes('validation')) { + return { message: 'Validation error', code: 'VALIDATION_ERROR' }; + } + return { message: 'Internal server error', code: 'INTERNAL_ERROR' }; + } + return { + message: error.message.substring(0, 200), + code: error.name || 'ERROR' + }; + } + return { message: 'An error occurred', code: 'UNKNOWN_ERROR' }; + } + updateSessionAccess(sessionId) { + if (this.sessionMetadata[sessionId]) { + this.sessionMetadata[sessionId].lastAccess = new Date(); + } + } + async switchSessionContext(sessionId, newContext) { + const existingLock = this.contextSwitchLocks.get(sessionId); + if (existingLock) { + await existingLock; + return; + } + const switchPromise = this.performContextSwitch(sessionId, newContext); + this.contextSwitchLocks.set(sessionId, switchPromise); + try { + await switchPromise; + } + finally { + this.contextSwitchLocks.delete(sessionId); + } + } + async performContextSwitch(sessionId, newContext) { + const existingContext = this.sessionContexts[sessionId]; + if (JSON.stringify(existingContext) !== JSON.stringify(newContext)) { + logger_1.logger.info('Multi-tenant shared mode: Updating instance context for session', { + sessionId, + oldInstanceId: existingContext?.instanceId, + newInstanceId: newContext.instanceId + }); + this.sessionContexts[sessionId] = newContext; + if (this.servers[sessionId]) { + this.servers[sessionId].instanceContext = newContext; + } + } + } + getSessionMetrics() { + const now = Date.now(); + let expiredCount = 0; + for (const sessionId in this.sessionMetadata) { + const metadata = this.sessionMetadata[sessionId]; + if (now - metadata.lastAccess.getTime() > this.sessionTimeout) { + expiredCount++; + } + } + return { + totalSessions: Object.keys(this.sessionMetadata).length, + activeSessions: this.getActiveSessionCount(), + expiredSessions: expiredCount, + lastCleanup: new Date() + }; + } + loadAuthToken() { + if (process.env.AUTH_TOKEN) { + logger_1.logger.info('Using AUTH_TOKEN from environment variable'); + return process.env.AUTH_TOKEN; + } + if (process.env.AUTH_TOKEN_FILE) { + try { + const token = (0, fs_1.readFileSync)(process.env.AUTH_TOKEN_FILE, 'utf-8').trim(); + logger_1.logger.info(`Loaded AUTH_TOKEN from file: ${process.env.AUTH_TOKEN_FILE}`); + return token; + } + catch (error) { + logger_1.logger.error(`Failed to read AUTH_TOKEN_FILE: ${process.env.AUTH_TOKEN_FILE}`, error); + console.error(`ERROR: Failed to read AUTH_TOKEN_FILE: ${process.env.AUTH_TOKEN_FILE}`); + console.error(error instanceof Error ? error.message : 'Unknown error'); + return null; + } + } + return null; + } + validateEnvironment() { + this.authToken = this.loadAuthToken(); + if (!this.authToken || this.authToken.trim() === '') { + const message = 'No authentication token found or token is empty. Set AUTH_TOKEN environment variable or AUTH_TOKEN_FILE pointing to a file containing the token.'; + logger_1.logger.error(message); + throw new Error(message); + } + this.authToken = this.authToken.trim(); + if (this.authToken.length < 32) { + logger_1.logger.warn('AUTH_TOKEN should be at least 32 characters for security'); + } + const isDefaultToken = this.authToken === 'REPLACE_THIS_AUTH_TOKEN_32_CHARS_MIN_abcdefgh'; + const isProduction = process.env.NODE_ENV === 'production'; + if (isDefaultToken) { + if (isProduction) { + const message = 'CRITICAL SECURITY ERROR: Cannot start in production with default AUTH_TOKEN. Generate secure token: openssl rand -base64 32'; + logger_1.logger.error(message); + console.error('\n🚨 CRITICAL SECURITY ERROR 🚨'); + console.error(message); + console.error('Set NODE_ENV to development for testing, or update AUTH_TOKEN for production\n'); + throw new Error(message); + } + logger_1.logger.warn('⚠️ SECURITY WARNING: Using default AUTH_TOKEN - CHANGE IMMEDIATELY!'); + logger_1.logger.warn('Generate secure token with: openssl rand -base64 32'); + if (process.env.MCP_MODE === 'http') { + console.warn('\n⚠️ SECURITY WARNING ⚠️'); + console.warn('Using default AUTH_TOKEN - CHANGE IMMEDIATELY!'); + console.warn('Generate secure token: openssl rand -base64 32'); + console.warn('Update via Railway dashboard environment variables\n'); + } + } + } + async handleRequest(req, res, instanceContext) { + const startTime = Date.now(); + return this.consoleManager.wrapOperation(async () => { + try { + const sessionId = req.headers['mcp-session-id']; + const isInitialize = req.body ? (0, types_js_1.isInitializeRequest)(req.body) : false; + logger_1.logger.info('handleRequest: Processing MCP request - SDK PATTERN', { + requestId: req.get('x-request-id') || 'unknown', + sessionId: sessionId, + method: req.method, + url: req.url, + bodyType: typeof req.body, + bodyContent: req.body ? JSON.stringify(req.body, null, 2) : 'undefined', + existingTransports: Object.keys(this.transports), + isInitializeRequest: isInitialize + }); + let transport; + if (isInitialize) { + if (!this.canCreateSession()) { + logger_1.logger.warn('handleRequest: Session limit reached', { + currentSessions: this.getActiveSessionCount(), + maxSessions: MAX_SESSIONS + }); + res.status(429).json({ + jsonrpc: '2.0', + error: { + code: -32000, + message: `Session limit reached (${MAX_SESSIONS}). Please wait for existing sessions to expire.` + }, + id: req.body?.id || null + }); + return; + } + logger_1.logger.info('handleRequest: Creating new transport for initialize request'); + let sessionIdToUse; + const isMultiTenantEnabled = process.env.ENABLE_MULTI_TENANT === 'true'; + const sessionStrategy = process.env.MULTI_TENANT_SESSION_STRATEGY || 'instance'; + if (isMultiTenantEnabled && sessionStrategy === 'instance' && instanceContext?.instanceId) { + const configHash = (0, crypto_1.createHash)('sha256') + .update(JSON.stringify({ + url: instanceContext.n8nApiUrl, + instanceId: instanceContext.instanceId + })) + .digest('hex') + .substring(0, 8); + sessionIdToUse = `instance-${instanceContext.instanceId}-${configHash}-${(0, uuid_1.v4)()}`; + logger_1.logger.info('Multi-tenant mode: Creating instance-specific session', { + instanceId: instanceContext.instanceId, + configHash, + sessionId: sessionIdToUse + }); + } + else { + sessionIdToUse = sessionId || (0, uuid_1.v4)(); + } + const server = new server_1.N8NDocumentationMCPServer(instanceContext); + transport = new streamableHttp_js_1.StreamableHTTPServerTransport({ + sessionIdGenerator: () => sessionIdToUse, + onsessioninitialized: (initializedSessionId) => { + logger_1.logger.info('handleRequest: Session initialized, storing transport and server', { + sessionId: initializedSessionId + }); + this.transports[initializedSessionId] = transport; + this.servers[initializedSessionId] = server; + this.sessionMetadata[initializedSessionId] = { + lastAccess: new Date(), + createdAt: new Date() + }; + this.sessionContexts[initializedSessionId] = instanceContext; + } + }); + transport.onclose = () => { + const sid = transport.sessionId; + if (sid) { + logger_1.logger.info('handleRequest: Transport closed, cleaning up', { sessionId: sid }); + this.removeSession(sid, 'transport_closed'); + } + }; + transport.onerror = (error) => { + const sid = transport.sessionId; + logger_1.logger.error('Transport error', { sessionId: sid, error: error.message }); + if (sid) { + this.removeSession(sid, 'transport_error').catch(err => { + logger_1.logger.error('Error during transport error cleanup', { error: err }); + }); + } + }; + logger_1.logger.info('handleRequest: Connecting server to new transport'); + await server.connect(transport); + } + else if (sessionId && this.transports[sessionId]) { + if (!this.isValidSessionId(sessionId)) { + logger_1.logger.warn('handleRequest: Invalid session ID format', { sessionId }); + res.status(400).json({ + jsonrpc: '2.0', + error: { + code: -32602, + message: 'Invalid session ID format' + }, + id: req.body?.id || null + }); + return; + } + logger_1.logger.info('handleRequest: Reusing existing transport for session', { sessionId }); + transport = this.transports[sessionId]; + const isMultiTenantEnabled = process.env.ENABLE_MULTI_TENANT === 'true'; + const sessionStrategy = process.env.MULTI_TENANT_SESSION_STRATEGY || 'instance'; + if (isMultiTenantEnabled && sessionStrategy === 'shared' && instanceContext) { + await this.switchSessionContext(sessionId, instanceContext); + } + this.updateSessionAccess(sessionId); + } + else { + const errorDetails = { + hasSessionId: !!sessionId, + isInitialize: isInitialize, + sessionIdValid: sessionId ? this.isValidSessionId(sessionId) : false, + sessionExists: sessionId ? !!this.transports[sessionId] : false + }; + logger_1.logger.warn('handleRequest: Invalid request - no session ID and not initialize', errorDetails); + let errorMessage = 'Bad Request: No valid session ID provided and not an initialize request'; + if (sessionId && !this.isValidSessionId(sessionId)) { + errorMessage = 'Bad Request: Invalid session ID format'; + } + else if (sessionId && !this.transports[sessionId]) { + errorMessage = 'Bad Request: Session not found or expired'; + } + res.status(400).json({ + jsonrpc: '2.0', + error: { + code: -32000, + message: errorMessage + }, + id: req.body?.id || null + }); + return; + } + logger_1.logger.info('handleRequest: Handling request with transport', { + sessionId: isInitialize ? 'new' : sessionId, + isInitialize + }); + await transport.handleRequest(req, res, req.body); + const duration = Date.now() - startTime; + logger_1.logger.info('MCP request completed', { duration, sessionId: transport.sessionId }); + } + catch (error) { + logger_1.logger.error('handleRequest: MCP request error:', { + error: error instanceof Error ? error.message : error, + errorName: error instanceof Error ? error.name : 'Unknown', + stack: error instanceof Error ? error.stack : undefined, + activeTransports: Object.keys(this.transports), + requestDetails: { + method: req.method, + url: req.url, + hasBody: !!req.body, + sessionId: req.headers['mcp-session-id'] + }, + duration: Date.now() - startTime + }); + if (!res.headersSent) { + const sanitizedError = this.sanitizeErrorForClient(error); + res.status(500).json({ + jsonrpc: '2.0', + error: { + code: -32603, + message: sanitizedError.message, + data: { + code: sanitizedError.code + } + }, + id: req.body?.id || null + }); + } + } + }); + } + async resetSessionSSE(res) { + if (this.session) { + try { + logger_1.logger.info('Closing previous session for SSE', { sessionId: this.session.sessionId }); + await this.session.transport.close(); + } + catch (error) { + logger_1.logger.warn('Error closing previous session:', error); + } + } + try { + logger_1.logger.info('Creating new N8NDocumentationMCPServer for SSE...'); + const server = new server_1.N8NDocumentationMCPServer(); + const sessionId = (0, uuid_1.v4)(); + logger_1.logger.info('Creating SSEServerTransport...'); + const transport = new sse_js_1.SSEServerTransport('/mcp', res); + logger_1.logger.info('Connecting server to SSE transport...'); + await server.connect(transport); + this.session = { + server, + transport, + lastAccess: new Date(), + sessionId, + initialized: false, + isSSE: true + }; + logger_1.logger.info('Created new SSE session successfully', { sessionId: this.session.sessionId }); + } + catch (error) { + logger_1.logger.error('Failed to create SSE session:', error); + throw error; + } + } + isExpired() { + if (!this.session) + return true; + return Date.now() - this.session.lastAccess.getTime() > this.sessionTimeout; + } + isSessionExpired(sessionId) { + const metadata = this.sessionMetadata[sessionId]; + if (!metadata) + return true; + return Date.now() - metadata.lastAccess.getTime() > this.sessionTimeout; + } + async start() { + const app = (0, express_1.default)(); + const jsonParser = express_1.default.json({ limit: '10mb' }); + const trustProxy = process.env.TRUST_PROXY ? Number(process.env.TRUST_PROXY) : 0; + if (trustProxy > 0) { + app.set('trust proxy', trustProxy); + logger_1.logger.info(`Trust proxy enabled with ${trustProxy} hop(s)`); + } + app.use((req, res, next) => { + res.setHeader('X-Content-Type-Options', 'nosniff'); + res.setHeader('X-Frame-Options', 'DENY'); + res.setHeader('X-XSS-Protection', '1; mode=block'); + res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains'); + next(); + }); + app.use((req, res, next) => { + const allowedOrigin = process.env.CORS_ORIGIN || '*'; + res.setHeader('Access-Control-Allow-Origin', allowedOrigin); + res.setHeader('Access-Control-Allow-Methods', 'POST, GET, DELETE, OPTIONS'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, Accept, Mcp-Session-Id'); + res.setHeader('Access-Control-Expose-Headers', 'Mcp-Session-Id'); + res.setHeader('Access-Control-Max-Age', '86400'); + if (req.method === 'OPTIONS') { + res.sendStatus(204); + return; + } + next(); + }); + app.use((req, res, next) => { + logger_1.logger.info(`${req.method} ${req.path}`, { + ip: req.ip, + userAgent: req.get('user-agent'), + contentLength: req.get('content-length') + }); + next(); + }); + app.get('/', (req, res) => { + const port = parseInt(process.env.PORT || '3000'); + const host = process.env.HOST || '0.0.0.0'; + const baseUrl = (0, url_detector_1.detectBaseUrl)(req, host, port); + const endpoints = (0, url_detector_1.formatEndpointUrls)(baseUrl); + res.json({ + name: 'n8n Documentation MCP Server', + version: version_1.PROJECT_VERSION, + description: 'Model Context Protocol server providing comprehensive n8n node documentation and workflow management', + endpoints: { + health: { + url: endpoints.health, + method: 'GET', + description: 'Health check and status information' + }, + mcp: { + url: endpoints.mcp, + method: 'GET/POST', + description: 'MCP endpoint - GET for info, POST for JSON-RPC' + } + }, + authentication: { + type: 'Bearer Token', + header: 'Authorization: Bearer ', + required_for: ['POST /mcp'] + }, + documentation: 'https://github.com/czlonkowski/n8n-mcp' + }); + }); + app.get('/health', (req, res) => { + const activeTransports = Object.keys(this.transports); + const activeServers = Object.keys(this.servers); + const sessionMetrics = this.getSessionMetrics(); + const isProduction = process.env.NODE_ENV === 'production'; + const isDefaultToken = this.authToken === 'REPLACE_THIS_AUTH_TOKEN_32_CHARS_MIN_abcdefgh'; + res.json({ + status: 'ok', + mode: 'sdk-pattern-transports', + version: version_1.PROJECT_VERSION, + environment: process.env.NODE_ENV || 'development', + uptime: Math.floor(process.uptime()), + sessions: { + active: sessionMetrics.activeSessions, + total: sessionMetrics.totalSessions, + expired: sessionMetrics.expiredSessions, + max: MAX_SESSIONS, + usage: `${sessionMetrics.activeSessions}/${MAX_SESSIONS}`, + sessionIds: activeTransports + }, + security: { + production: isProduction, + defaultToken: isDefaultToken, + tokenLength: this.authToken?.length || 0 + }, + activeTransports: activeTransports.length, + activeServers: activeServers.length, + legacySessionActive: !!this.session, + memory: { + used: Math.round(process.memoryUsage().heapUsed / 1024 / 1024), + total: Math.round(process.memoryUsage().heapTotal / 1024 / 1024), + unit: 'MB' + }, + timestamp: new Date().toISOString() + }); + }); + app.post('/mcp/test', jsonParser, async (req, res) => { + logger_1.logger.info('TEST ENDPOINT: Manual test request received', { + method: req.method, + headers: req.headers, + body: req.body, + bodyType: typeof req.body, + bodyContent: req.body ? JSON.stringify(req.body, null, 2) : 'undefined' + }); + const negotiationResult = (0, protocol_version_1.negotiateProtocolVersion)(undefined, undefined, req.get('user-agent'), req.headers); + (0, protocol_version_1.logProtocolNegotiation)(negotiationResult, logger_1.logger, 'TEST_ENDPOINT'); + const testResponse = { + jsonrpc: '2.0', + id: req.body?.id || 1, + result: { + protocolVersion: negotiationResult.version, + capabilities: { + tools: {} + }, + serverInfo: { + name: 'n8n-mcp', + version: version_1.PROJECT_VERSION + } + } + }; + logger_1.logger.info('TEST ENDPOINT: Sending test response', { + response: testResponse + }); + res.json(testResponse); + }); + app.get('/mcp', async (req, res) => { + const sessionId = req.headers['mcp-session-id']; + if (sessionId && this.transports[sessionId]) { + try { + await this.transports[sessionId].handleRequest(req, res, undefined); + return; + } + catch (error) { + logger_1.logger.error('StreamableHTTP GET request failed:', error); + } + } + const accept = req.headers.accept; + if (accept && accept.includes('text/event-stream')) { + logger_1.logger.info('SSE stream request received - establishing SSE connection'); + try { + await this.resetSessionSSE(res); + logger_1.logger.info('SSE connection established successfully'); + } + catch (error) { + logger_1.logger.error('Failed to establish SSE connection:', error); + res.status(500).json({ + jsonrpc: '2.0', + error: { + code: -32603, + message: 'Failed to establish SSE connection' + }, + id: null + }); + } + return; + } + if (process.env.N8N_MODE === 'true') { + const negotiationResult = (0, protocol_version_1.negotiateProtocolVersion)(undefined, undefined, req.get('user-agent'), req.headers); + (0, protocol_version_1.logProtocolNegotiation)(negotiationResult, logger_1.logger, 'N8N_MODE_GET'); + res.json({ + protocolVersion: negotiationResult.version, + serverInfo: { + name: 'n8n-mcp', + version: version_1.PROJECT_VERSION, + capabilities: { + tools: {} + } + } + }); + return; + } + res.json({ + description: 'n8n Documentation MCP Server', + version: version_1.PROJECT_VERSION, + endpoints: { + mcp: { + method: 'POST', + path: '/mcp', + description: 'Main MCP JSON-RPC endpoint', + authentication: 'Bearer token required' + }, + health: { + method: 'GET', + path: '/health', + description: 'Health check endpoint', + authentication: 'None' + }, + root: { + method: 'GET', + path: '/', + description: 'API information', + authentication: 'None' + } + }, + documentation: 'https://github.com/czlonkowski/n8n-mcp' + }); + }); + app.delete('/mcp', async (req, res) => { + const mcpSessionId = req.headers['mcp-session-id']; + if (!mcpSessionId) { + res.status(400).json({ + jsonrpc: '2.0', + error: { + code: -32602, + message: 'Mcp-Session-Id header is required' + }, + id: null + }); + return; + } + if (!this.isValidSessionId(mcpSessionId)) { + res.status(400).json({ + jsonrpc: '2.0', + error: { + code: -32602, + message: 'Invalid session ID format' + }, + id: null + }); + return; + } + if (this.transports[mcpSessionId]) { + logger_1.logger.info('Terminating session via DELETE request', { sessionId: mcpSessionId }); + try { + await this.removeSession(mcpSessionId, 'manual_termination'); + res.status(204).send(); + } + catch (error) { + logger_1.logger.error('Error terminating session:', error); + res.status(500).json({ + jsonrpc: '2.0', + error: { + code: -32603, + message: 'Error terminating session' + }, + id: null + }); + } + } + else { + res.status(404).json({ + jsonrpc: '2.0', + error: { + code: -32001, + message: 'Session not found' + }, + id: null + }); + } + }); + const authLimiter = (0, express_rate_limit_1.default)({ + windowMs: parseInt(process.env.AUTH_RATE_LIMIT_WINDOW || '900000'), + max: parseInt(process.env.AUTH_RATE_LIMIT_MAX || '20'), + message: { + jsonrpc: '2.0', + error: { + code: -32000, + message: 'Too many authentication attempts. Please try again later.' + }, + id: null + }, + standardHeaders: true, + legacyHeaders: false, + handler: (req, res) => { + logger_1.logger.warn('Rate limit exceeded', { + ip: req.ip, + userAgent: req.get('user-agent'), + event: 'rate_limit' + }); + res.status(429).json({ + jsonrpc: '2.0', + error: { + code: -32000, + message: 'Too many authentication attempts' + }, + id: null + }); + } + }); + app.post('/mcp', authLimiter, jsonParser, async (req, res) => { + logger_1.logger.info('POST /mcp request received - DETAILED DEBUG', { + headers: req.headers, + readable: req.readable, + readableEnded: req.readableEnded, + complete: req.complete, + bodyType: typeof req.body, + bodyContent: req.body ? JSON.stringify(req.body, null, 2) : 'undefined', + contentLength: req.get('content-length'), + contentType: req.get('content-type'), + userAgent: req.get('user-agent'), + ip: req.ip, + method: req.method, + url: req.url, + originalUrl: req.originalUrl + }); + const sessionId = req.headers['mcp-session-id']; + if (typeof req.on === 'function') { + const closeHandler = () => { + if (!res.headersSent && sessionId) { + logger_1.logger.info('Connection closed before response sent', { sessionId }); + setImmediate(() => { + if (this.sessionMetadata[sessionId]) { + const metadata = this.sessionMetadata[sessionId]; + const timeSinceAccess = Date.now() - metadata.lastAccess.getTime(); + if (timeSinceAccess > 60000) { + this.removeSession(sessionId, 'connection_closed').catch(err => { + logger_1.logger.error('Error during connection close cleanup', { error: err }); + }); + } + } + }); + } + }; + req.on('close', closeHandler); + res.on('finish', () => { + req.removeListener('close', closeHandler); + }); + } + const authHeader = req.headers.authorization; + if (!authHeader) { + logger_1.logger.warn('Authentication failed: Missing Authorization header', { + ip: req.ip, + userAgent: req.get('user-agent'), + reason: 'no_auth_header' + }); + res.status(401).json({ + jsonrpc: '2.0', + error: { + code: -32001, + message: 'Unauthorized' + }, + id: null + }); + return; + } + if (!authHeader.startsWith('Bearer ')) { + logger_1.logger.warn('Authentication failed: Invalid Authorization header format (expected Bearer token)', { + ip: req.ip, + userAgent: req.get('user-agent'), + reason: 'invalid_auth_format', + headerPrefix: authHeader.substring(0, Math.min(authHeader.length, 10)) + '...' + }); + res.status(401).json({ + jsonrpc: '2.0', + error: { + code: -32001, + message: 'Unauthorized' + }, + id: null + }); + return; + } + const token = authHeader.slice(7).trim(); + const isValidToken = this.authToken && + auth_1.AuthManager.timingSafeCompare(token, this.authToken); + if (!isValidToken) { + logger_1.logger.warn('Authentication failed: Invalid token', { + ip: req.ip, + userAgent: req.get('user-agent'), + reason: 'invalid_token' + }); + res.status(401).json({ + jsonrpc: '2.0', + error: { + code: -32001, + message: 'Unauthorized' + }, + id: null + }); + return; + } + logger_1.logger.info('Authentication successful - proceeding to handleRequest', { + hasSession: !!this.session, + sessionType: this.session?.isSSE ? 'SSE' : 'StreamableHTTP', + sessionInitialized: this.session?.initialized + }); + const instanceContext = (() => { + const headers = extractMultiTenantHeaders(req); + const hasUrl = headers['x-n8n-url']; + const hasKey = headers['x-n8n-key']; + if (!hasUrl && !hasKey) + return undefined; + const context = { + n8nApiUrl: hasUrl || undefined, + n8nApiKey: hasKey || undefined, + instanceId: headers['x-instance-id'] || undefined, + sessionId: headers['x-session-id'] || undefined + }; + if (req.headers['user-agent'] || req.ip) { + context.metadata = { + userAgent: req.headers['user-agent'], + ip: req.ip + }; + } + const validation = (0, instance_context_1.validateInstanceContext)(context); + if (!validation.valid) { + logger_1.logger.warn('Invalid instance context from headers', { + errors: validation.errors, + hasUrl: !!hasUrl, + hasKey: !!hasKey + }); + return undefined; + } + return context; + })(); + if (instanceContext) { + logger_1.logger.debug('Instance context extracted from headers', { + hasUrl: !!instanceContext.n8nApiUrl, + hasKey: !!instanceContext.n8nApiKey, + instanceId: instanceContext.instanceId ? instanceContext.instanceId.substring(0, 8) + '...' : undefined, + sessionId: instanceContext.sessionId ? instanceContext.sessionId.substring(0, 8) + '...' : undefined, + urlDomain: instanceContext.n8nApiUrl ? new URL(instanceContext.n8nApiUrl).hostname : undefined + }); + } + await this.handleRequest(req, res, instanceContext); + logger_1.logger.info('POST /mcp request completed - checking response status', { + responseHeadersSent: res.headersSent, + responseStatusCode: res.statusCode, + responseFinished: res.finished + }); + }); + app.use((req, res) => { + res.status(404).json({ + error: 'Not found', + message: `Cannot ${req.method} ${req.path}` + }); + }); + app.use((err, req, res, next) => { + logger_1.logger.error('Express error handler:', err); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: '2.0', + error: { + code: -32603, + message: 'Internal server error', + data: process.env.NODE_ENV === 'development' ? err.message : undefined + }, + id: null + }); + } + }); + const port = parseInt(process.env.PORT || '3000'); + const host = process.env.HOST || '0.0.0.0'; + this.expressServer = app.listen(port, host, () => { + const isProduction = process.env.NODE_ENV === 'production'; + const isDefaultToken = this.authToken === 'REPLACE_THIS_AUTH_TOKEN_32_CHARS_MIN_abcdefgh'; + logger_1.logger.info(`n8n MCP Single-Session HTTP Server started`, { + port, + host, + environment: process.env.NODE_ENV || 'development', + maxSessions: MAX_SESSIONS, + sessionTimeout: this.sessionTimeout / 1000 / 60, + production: isProduction, + defaultToken: isDefaultToken + }); + const baseUrl = (0, url_detector_1.getStartupBaseUrl)(host, port); + const endpoints = (0, url_detector_1.formatEndpointUrls)(baseUrl); + console.log(`n8n MCP Single-Session HTTP Server running on ${host}:${port}`); + console.log(`Environment: ${process.env.NODE_ENV || 'development'}`); + console.log(`Session Limits: ${MAX_SESSIONS} max sessions, ${this.sessionTimeout / 1000 / 60}min timeout`); + console.log(`Health check: ${endpoints.health}`); + console.log(`MCP endpoint: ${endpoints.mcp}`); + if (isProduction) { + console.log('🔒 Running in PRODUCTION mode - enhanced security enabled'); + } + else { + console.log('🛠️ Running in DEVELOPMENT mode'); + } + console.log('\nPress Ctrl+C to stop the server'); + if (isDefaultToken && !isProduction) { + setInterval(() => { + logger_1.logger.warn('⚠️ Still using default AUTH_TOKEN - security risk!'); + if (process.env.MCP_MODE === 'http') { + console.warn('⚠️ REMINDER: Still using default AUTH_TOKEN - please change it!'); + } + }, 300000); + } + if (process.env.BASE_URL || process.env.PUBLIC_URL) { + console.log(`\nPublic URL configured: ${baseUrl}`); + } + else if (process.env.TRUST_PROXY && Number(process.env.TRUST_PROXY) > 0) { + console.log(`\nNote: TRUST_PROXY is enabled. URLs will be auto-detected from proxy headers.`); + } + }); + this.expressServer.on('error', (error) => { + if (error.code === 'EADDRINUSE') { + logger_1.logger.error(`Port ${port} is already in use`); + console.error(`ERROR: Port ${port} is already in use`); + process.exit(1); + } + else { + logger_1.logger.error('Server error:', error); + console.error('Server error:', error); + process.exit(1); + } + }); + } + async shutdown() { + logger_1.logger.info('Shutting down Single-Session HTTP server...'); + if (this.cleanupTimer) { + clearInterval(this.cleanupTimer); + this.cleanupTimer = null; + logger_1.logger.info('Session cleanup timer stopped'); + } + const sessionIds = Object.keys(this.transports); + logger_1.logger.info(`Closing ${sessionIds.length} active sessions`); + for (const sessionId of sessionIds) { + try { + logger_1.logger.info(`Closing transport for session ${sessionId}`); + await this.removeSession(sessionId, 'server_shutdown'); + } + catch (error) { + logger_1.logger.warn(`Error closing transport for session ${sessionId}:`, error); + } + } + if (this.session) { + try { + await this.session.transport.close(); + logger_1.logger.info('Legacy session closed'); + } + catch (error) { + logger_1.logger.warn('Error closing legacy session:', error); + } + this.session = null; + } + if (this.expressServer) { + await new Promise((resolve) => { + this.expressServer.close(() => { + logger_1.logger.info('HTTP server closed'); + resolve(); + }); + }); + } + logger_1.logger.info('Single-Session HTTP server shutdown completed'); + } + getSessionInfo() { + const metrics = this.getSessionMetrics(); + if (!this.session) { + return { + active: false, + sessions: { + total: metrics.totalSessions, + active: metrics.activeSessions, + expired: metrics.expiredSessions, + max: MAX_SESSIONS, + sessionIds: Object.keys(this.transports) + } + }; + } + return { + active: true, + sessionId: this.session.sessionId, + age: Date.now() - this.session.lastAccess.getTime(), + sessions: { + total: metrics.totalSessions, + active: metrics.activeSessions, + expired: metrics.expiredSessions, + max: MAX_SESSIONS, + sessionIds: Object.keys(this.transports) + } + }; + } + exportSessionState() { + const sessions = []; + const seenSessionIds = new Set(); + for (const sessionId of Object.keys(this.sessionMetadata)) { + if (seenSessionIds.has(sessionId)) { + logger_1.logger.warn(`Duplicate sessionId detected during export: ${sessionId}`); + continue; + } + if (this.isSessionExpired(sessionId)) { + continue; + } + const metadata = this.sessionMetadata[sessionId]; + const context = this.sessionContexts[sessionId]; + if (!context || !context.n8nApiUrl || !context.n8nApiKey) { + logger_1.logger.debug(`Skipping session ${sessionId} - missing required context`); + continue; + } + seenSessionIds.add(sessionId); + sessions.push({ + sessionId, + metadata: { + createdAt: metadata.createdAt.toISOString(), + lastAccess: metadata.lastAccess.toISOString() + }, + context: { + n8nApiUrl: context.n8nApiUrl, + n8nApiKey: context.n8nApiKey, + instanceId: context.instanceId || sessionId, + sessionId: context.sessionId, + metadata: context.metadata + } + }); + } + logger_1.logger.info(`Exported ${sessions.length} session(s) for persistence`); + logSecurityEvent('session_export', { count: sessions.length }); + return sessions; + } + restoreSessionState(sessions) { + let restoredCount = 0; + for (const sessionState of sessions) { + try { + if (!sessionState || typeof sessionState !== 'object' || !sessionState.sessionId) { + logger_1.logger.warn('Skipping invalid session state object'); + continue; + } + if (Object.keys(this.sessionMetadata).length >= MAX_SESSIONS) { + logger_1.logger.warn(`Reached MAX_SESSIONS limit (${MAX_SESSIONS}), skipping remaining sessions`); + logSecurityEvent('max_sessions_reached', { count: MAX_SESSIONS }); + break; + } + if (this.sessionMetadata[sessionState.sessionId]) { + logger_1.logger.debug(`Skipping session ${sessionState.sessionId} - already exists`); + continue; + } + const createdAt = new Date(sessionState.metadata.createdAt); + const lastAccess = new Date(sessionState.metadata.lastAccess); + if (isNaN(createdAt.getTime()) || isNaN(lastAccess.getTime())) { + logger_1.logger.warn(`Skipping session ${sessionState.sessionId} - invalid date format`); + continue; + } + const age = Date.now() - lastAccess.getTime(); + if (age > this.sessionTimeout) { + logger_1.logger.debug(`Skipping session ${sessionState.sessionId} - expired (age: ${Math.round(age / 1000)}s)`); + continue; + } + if (!sessionState.context) { + logger_1.logger.warn(`Skipping session ${sessionState.sessionId} - missing context`); + continue; + } + const validation = (0, instance_context_1.validateInstanceContext)(sessionState.context); + if (!validation.valid) { + const reason = validation.errors?.join(', ') || 'invalid context'; + logger_1.logger.warn(`Skipping session ${sessionState.sessionId} - invalid context: ${reason}`); + logSecurityEvent('session_restore_failed', { + sessionId: sessionState.sessionId, + reason + }); + continue; + } + this.sessionMetadata[sessionState.sessionId] = { + createdAt, + lastAccess + }; + this.sessionContexts[sessionState.sessionId] = { + n8nApiUrl: sessionState.context.n8nApiUrl, + n8nApiKey: sessionState.context.n8nApiKey, + instanceId: sessionState.context.instanceId, + sessionId: sessionState.context.sessionId, + metadata: sessionState.context.metadata + }; + logger_1.logger.debug(`Restored session ${sessionState.sessionId}`); + logSecurityEvent('session_restore', { + sessionId: sessionState.sessionId, + instanceId: sessionState.context.instanceId + }); + restoredCount++; + } + catch (error) { + logger_1.logger.error(`Failed to restore session ${sessionState.sessionId}:`, error); + logSecurityEvent('session_restore_failed', { + sessionId: sessionState.sessionId, + reason: error instanceof Error ? error.message : 'unknown error' + }); + } + } + logger_1.logger.info(`Restored ${restoredCount}/${sessions.length} session(s) from persistence`); + return restoredCount; + } +} +exports.SingleSessionHTTPServer = SingleSessionHTTPServer; +if (require.main === module) { + const server = new SingleSessionHTTPServer(); + const shutdown = async () => { + await server.shutdown(); + process.exit(0); + }; + process.on('SIGTERM', shutdown); + process.on('SIGINT', shutdown); + process.on('uncaughtException', (error) => { + logger_1.logger.error('Uncaught exception:', error); + console.error('Uncaught exception:', error); + shutdown(); + }); + process.on('unhandledRejection', (reason, promise) => { + logger_1.logger.error('Unhandled rejection:', reason); + console.error('Unhandled rejection at:', promise, 'reason:', reason); + shutdown(); + }); + server.start().catch(error => { + logger_1.logger.error('Failed to start Single-Session HTTP server:', error); + console.error('Failed to start Single-Session HTTP server:', error); + process.exit(1); + }); +} +//# sourceMappingURL=http-server-single-session.js.map \ No newline at end of file diff --git a/dist/http-server-single-session.js.map b/dist/http-server-single-session.js.map new file mode 100644 index 0000000..c19970e --- /dev/null +++ b/dist/http-server-single-session.js.map @@ -0,0 +1 @@ +{"version":3,"file":"http-server-single-session.js","sourceRoot":"","sources":["../src/http-server-single-session.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/http-server.d.ts b/dist/http-server.d.ts new file mode 100644 index 0000000..0d3b5fc --- /dev/null +++ b/dist/http-server.d.ts @@ -0,0 +1,9 @@ +#!/usr/bin/env node +export declare function loadAuthToken(): string | null; +export declare function startFixedHTTPServer(): Promise; +declare module './mcp/server' { + interface N8NDocumentationMCPServer { + executeTool(name: string, args: any): Promise; + } +} +//# sourceMappingURL=http-server.d.ts.map \ No newline at end of file diff --git a/dist/http-server.d.ts.map b/dist/http-server.d.ts.map new file mode 100644 index 0000000..408f515 --- /dev/null +++ b/dist/http-server.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":";AA0CA,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAsB7C;AA+DD,wBAAsB,oBAAoB,kBA+dzC;AAGD,OAAO,QAAQ,cAAc,CAAC;IAC5B,UAAU,yBAAyB;QACjC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;KACpD;CACF"} \ No newline at end of file diff --git a/dist/http-server.js b/dist/http-server.js new file mode 100644 index 0000000..7f03fed --- /dev/null +++ b/dist/http-server.js @@ -0,0 +1,478 @@ +#!/usr/bin/env node +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.loadAuthToken = loadAuthToken; +exports.startFixedHTTPServer = startFixedHTTPServer; +const express_1 = __importDefault(require("express")); +const tools_1 = require("./mcp/tools"); +const tools_n8n_manager_1 = require("./mcp/tools-n8n-manager"); +const server_1 = require("./mcp/server"); +const logger_1 = require("./utils/logger"); +const auth_1 = require("./utils/auth"); +const version_1 = require("./utils/version"); +const n8n_api_1 = require("./config/n8n-api"); +const dotenv_1 = __importDefault(require("dotenv")); +const fs_1 = require("fs"); +const url_detector_1 = require("./utils/url-detector"); +const protocol_version_1 = require("./utils/protocol-version"); +dotenv_1.default.config(); +let expressServer; +let authToken = null; +function loadAuthToken() { + if (process.env.AUTH_TOKEN) { + logger_1.logger.info('Using AUTH_TOKEN from environment variable'); + return process.env.AUTH_TOKEN; + } + if (process.env.AUTH_TOKEN_FILE) { + try { + const token = (0, fs_1.readFileSync)(process.env.AUTH_TOKEN_FILE, 'utf-8').trim(); + logger_1.logger.info(`Loaded AUTH_TOKEN from file: ${process.env.AUTH_TOKEN_FILE}`); + return token; + } + catch (error) { + logger_1.logger.error(`Failed to read AUTH_TOKEN_FILE: ${process.env.AUTH_TOKEN_FILE}`, error); + console.error(`ERROR: Failed to read AUTH_TOKEN_FILE: ${process.env.AUTH_TOKEN_FILE}`); + console.error(error instanceof Error ? error.message : 'Unknown error'); + return null; + } + } + return null; +} +function validateEnvironment() { + authToken = loadAuthToken(); + if (!authToken || authToken.trim() === '') { + logger_1.logger.error('No authentication token found or token is empty'); + console.error('ERROR: AUTH_TOKEN is required for HTTP mode and cannot be empty'); + console.error('Set AUTH_TOKEN environment variable or AUTH_TOKEN_FILE pointing to a file containing the token'); + console.error('Generate AUTH_TOKEN with: openssl rand -base64 32'); + process.exit(1); + } + authToken = authToken.trim(); + if (authToken.length < 32) { + logger_1.logger.warn('AUTH_TOKEN should be at least 32 characters for security'); + console.warn('WARNING: AUTH_TOKEN should be at least 32 characters for security'); + } + if (authToken === 'REPLACE_THIS_AUTH_TOKEN_32_CHARS_MIN_abcdefgh') { + logger_1.logger.warn('⚠️ SECURITY WARNING: Using default AUTH_TOKEN - CHANGE IMMEDIATELY!'); + logger_1.logger.warn('Generate secure token with: openssl rand -base64 32'); + if (process.env.MCP_MODE === 'http') { + console.warn('\n⚠️ SECURITY WARNING ⚠️'); + console.warn('Using default AUTH_TOKEN - CHANGE IMMEDIATELY!'); + console.warn('Generate secure token: openssl rand -base64 32'); + console.warn('Update via Railway dashboard environment variables\n'); + } + } +} +async function shutdown() { + logger_1.logger.info('Shutting down HTTP server...'); + console.log('Shutting down HTTP server...'); + if (expressServer) { + expressServer.close(() => { + logger_1.logger.info('HTTP server closed'); + console.log('HTTP server closed'); + process.exit(0); + }); + setTimeout(() => { + logger_1.logger.error('Forced shutdown after timeout'); + process.exit(1); + }, 10000); + } + else { + process.exit(0); + } +} +async function startFixedHTTPServer() { + validateEnvironment(); + const app = (0, express_1.default)(); + const trustProxy = process.env.TRUST_PROXY ? Number(process.env.TRUST_PROXY) : 0; + if (trustProxy > 0) { + app.set('trust proxy', trustProxy); + logger_1.logger.info(`Trust proxy enabled with ${trustProxy} hop(s)`); + } + app.use((req, res, next) => { + res.setHeader('X-Content-Type-Options', 'nosniff'); + res.setHeader('X-Frame-Options', 'DENY'); + res.setHeader('X-XSS-Protection', '1; mode=block'); + res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains'); + next(); + }); + app.use((req, res, next) => { + const allowedOrigin = process.env.CORS_ORIGIN || '*'; + res.setHeader('Access-Control-Allow-Origin', allowedOrigin); + res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, Accept'); + res.setHeader('Access-Control-Max-Age', '86400'); + if (req.method === 'OPTIONS') { + res.sendStatus(204); + return; + } + next(); + }); + app.use((req, res, next) => { + logger_1.logger.info(`${req.method} ${req.path}`, { + ip: req.ip, + userAgent: req.get('user-agent'), + contentLength: req.get('content-length') + }); + next(); + }); + const mcpServer = new server_1.N8NDocumentationMCPServer(); + logger_1.logger.info('Created persistent MCP server instance'); + app.get('/', (req, res) => { + const port = parseInt(process.env.PORT || '3000'); + const host = process.env.HOST || '0.0.0.0'; + const baseUrl = (0, url_detector_1.detectBaseUrl)(req, host, port); + const endpoints = (0, url_detector_1.formatEndpointUrls)(baseUrl); + res.json({ + name: 'n8n Documentation MCP Server', + version: version_1.PROJECT_VERSION, + description: 'Model Context Protocol server providing comprehensive n8n node documentation and workflow management', + endpoints: { + health: { + url: endpoints.health, + method: 'GET', + description: 'Health check and status information' + }, + mcp: { + url: endpoints.mcp, + method: 'GET/POST', + description: 'MCP endpoint - GET for info, POST for JSON-RPC' + } + }, + authentication: { + type: 'Bearer Token', + header: 'Authorization: Bearer ', + required_for: ['POST /mcp'] + }, + documentation: 'https://github.com/czlonkowski/n8n-mcp' + }); + }); + app.get('/health', (req, res) => { + res.json({ + status: 'ok', + mode: 'http-fixed', + version: version_1.PROJECT_VERSION, + uptime: Math.floor(process.uptime()), + memory: { + used: Math.round(process.memoryUsage().heapUsed / 1024 / 1024), + total: Math.round(process.memoryUsage().heapTotal / 1024 / 1024), + unit: 'MB' + }, + timestamp: new Date().toISOString() + }); + }); + app.get('/version', (req, res) => { + res.json({ + version: version_1.PROJECT_VERSION, + buildTime: new Date().toISOString(), + tools: tools_1.n8nDocumentationToolsFinal.map(t => t.name), + commit: process.env.GIT_COMMIT || 'unknown' + }); + }); + app.get('/test-tools', async (req, res) => { + try { + const result = await mcpServer.executeTool('get_node_essentials', { nodeType: 'nodes-base.httpRequest' }); + res.json({ status: 'ok', hasData: !!result, toolCount: tools_1.n8nDocumentationToolsFinal.length }); + } + catch (error) { + res.json({ status: 'error', message: error instanceof Error ? error.message : 'Unknown error' }); + } + }); + app.get('/mcp', (req, res) => { + res.json({ + description: 'n8n Documentation MCP Server', + version: version_1.PROJECT_VERSION, + endpoints: { + mcp: { + method: 'POST', + path: '/mcp', + description: 'Main MCP JSON-RPC endpoint', + authentication: 'Bearer token required' + }, + health: { + method: 'GET', + path: '/health', + description: 'Health check endpoint', + authentication: 'None' + }, + root: { + method: 'GET', + path: '/', + description: 'API information', + authentication: 'None' + } + }, + documentation: 'https://github.com/czlonkowski/n8n-mcp' + }); + }); + app.post('/mcp', async (req, res) => { + const startTime = Date.now(); + const authHeader = req.headers.authorization; + if (!authHeader) { + logger_1.logger.warn('Authentication failed: Missing Authorization header', { + ip: req.ip, + userAgent: req.get('user-agent'), + reason: 'no_auth_header' + }); + res.status(401).json({ + jsonrpc: '2.0', + error: { + code: -32001, + message: 'Unauthorized' + }, + id: null + }); + return; + } + if (!authHeader.startsWith('Bearer ')) { + logger_1.logger.warn('Authentication failed: Invalid Authorization header format (expected Bearer token)', { + ip: req.ip, + userAgent: req.get('user-agent'), + reason: 'invalid_auth_format', + headerPrefix: authHeader.substring(0, Math.min(authHeader.length, 10)) + '...' + }); + res.status(401).json({ + jsonrpc: '2.0', + error: { + code: -32001, + message: 'Unauthorized' + }, + id: null + }); + return; + } + const token = authHeader.slice(7).trim(); + const isValidToken = authToken && + auth_1.AuthManager.timingSafeCompare(token, authToken); + if (!isValidToken) { + logger_1.logger.warn('Authentication failed: Invalid token', { + ip: req.ip, + userAgent: req.get('user-agent'), + reason: 'invalid_token' + }); + res.status(401).json({ + jsonrpc: '2.0', + error: { + code: -32001, + message: 'Unauthorized' + }, + id: null + }); + return; + } + try { + let body = ''; + req.on('data', chunk => { + body += chunk.toString(); + }); + req.on('end', async () => { + try { + const jsonRpcRequest = JSON.parse(body); + logger_1.logger.debug('Received JSON-RPC request:', { method: jsonRpcRequest.method }); + let response; + switch (jsonRpcRequest.method) { + case 'initialize': + const negotiationResult = (0, protocol_version_1.negotiateProtocolVersion)(jsonRpcRequest.params?.protocolVersion, jsonRpcRequest.params?.clientInfo, req.get('user-agent'), req.headers); + (0, protocol_version_1.logProtocolNegotiation)(negotiationResult, logger_1.logger, 'HTTP_SERVER_INITIALIZE'); + response = { + jsonrpc: '2.0', + result: { + protocolVersion: negotiationResult.version, + capabilities: { + tools: {}, + resources: {} + }, + serverInfo: { + name: 'n8n-documentation-mcp', + version: version_1.PROJECT_VERSION + } + }, + id: jsonRpcRequest.id + }; + break; + case 'tools/list': + const tools = [...tools_1.n8nDocumentationToolsFinal]; + if ((0, n8n_api_1.isN8nApiConfigured)()) { + tools.push(...tools_n8n_manager_1.n8nManagementTools); + } + response = { + jsonrpc: '2.0', + result: { + tools + }, + id: jsonRpcRequest.id + }; + break; + case 'tools/call': + const toolName = jsonRpcRequest.params?.name; + const toolArgs = jsonRpcRequest.params?.arguments || {}; + try { + const result = await mcpServer.executeTool(toolName, toolArgs); + let responseText = JSON.stringify(result, null, 2); + const mcpResult = { + content: [ + { + type: 'text', + text: responseText + } + ] + }; + if (toolName.startsWith('validate_')) { + const resultSize = responseText.length; + if (resultSize > 1000000) { + logger_1.logger.warn(`Validation tool ${toolName} response is very large (${resultSize} chars). ` + + `Truncating for HTTP transport safety.`); + mcpResult.content[0].text = responseText.substring(0, 999000) + + '\n\n[Response truncated due to size limits]'; + } + else { + mcpResult.structuredContent = result; + } + } + response = { + jsonrpc: '2.0', + result: mcpResult, + id: jsonRpcRequest.id + }; + } + catch (error) { + response = { + jsonrpc: '2.0', + error: { + code: -32603, + message: `Error executing tool ${toolName}: ${error instanceof Error ? error.message : 'Unknown error'}` + }, + id: jsonRpcRequest.id + }; + } + break; + default: + response = { + jsonrpc: '2.0', + error: { + code: -32601, + message: `Method not found: ${jsonRpcRequest.method}` + }, + id: jsonRpcRequest.id + }; + } + res.setHeader('Content-Type', 'application/json'); + res.json(response); + const duration = Date.now() - startTime; + logger_1.logger.info('MCP request completed', { + duration, + method: jsonRpcRequest.method + }); + } + catch (error) { + logger_1.logger.error('Error processing request:', error); + res.status(400).json({ + jsonrpc: '2.0', + error: { + code: -32700, + message: 'Parse error', + data: error instanceof Error ? error.message : 'Unknown error' + }, + id: null + }); + } + }); + } + catch (error) { + logger_1.logger.error('MCP request error:', error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: '2.0', + error: { + code: -32603, + message: 'Internal server error', + data: process.env.NODE_ENV === 'development' + ? error.message + : undefined + }, + id: null + }); + } + } + }); + app.use((req, res) => { + res.status(404).json({ + error: 'Not found', + message: `Cannot ${req.method} ${req.path}` + }); + }); + app.use((err, req, res, next) => { + logger_1.logger.error('Express error handler:', err); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: '2.0', + error: { + code: -32603, + message: 'Internal server error', + data: process.env.NODE_ENV === 'development' ? err.message : undefined + }, + id: null + }); + } + }); + const port = parseInt(process.env.PORT || '3000'); + const host = process.env.HOST || '0.0.0.0'; + expressServer = app.listen(port, host, () => { + logger_1.logger.info(`n8n MCP Fixed HTTP Server started`, { port, host }); + const baseUrl = (0, url_detector_1.getStartupBaseUrl)(host, port); + const endpoints = (0, url_detector_1.formatEndpointUrls)(baseUrl); + console.log(`n8n MCP Fixed HTTP Server running on ${host}:${port}`); + console.log(`Health check: ${endpoints.health}`); + console.log(`MCP endpoint: ${endpoints.mcp}`); + console.log('\nPress Ctrl+C to stop the server'); + if (authToken === 'REPLACE_THIS_AUTH_TOKEN_32_CHARS_MIN_abcdefgh') { + setInterval(() => { + logger_1.logger.warn('⚠️ Still using default AUTH_TOKEN - security risk!'); + if (process.env.MCP_MODE === 'http') { + console.warn('⚠️ REMINDER: Still using default AUTH_TOKEN - please change it!'); + } + }, 300000); + } + if (process.env.BASE_URL || process.env.PUBLIC_URL) { + console.log(`\nPublic URL configured: ${baseUrl}`); + } + else if (process.env.TRUST_PROXY && Number(process.env.TRUST_PROXY) > 0) { + console.log(`\nNote: TRUST_PROXY is enabled. URLs will be auto-detected from proxy headers.`); + } + }); + expressServer.on('error', (error) => { + if (error.code === 'EADDRINUSE') { + logger_1.logger.error(`Port ${port} is already in use`); + console.error(`ERROR: Port ${port} is already in use`); + process.exit(1); + } + else { + logger_1.logger.error('Server error:', error); + console.error('Server error:', error); + process.exit(1); + } + }); + process.on('SIGTERM', shutdown); + process.on('SIGINT', shutdown); + process.on('uncaughtException', (error) => { + logger_1.logger.error('Uncaught exception:', error); + console.error('Uncaught exception:', error); + shutdown(); + }); + process.on('unhandledRejection', (reason, promise) => { + logger_1.logger.error('Unhandled rejection:', reason); + console.error('Unhandled rejection at:', promise, 'reason:', reason); + shutdown(); + }); +} +if (typeof require !== 'undefined' && require.main === module) { + startFixedHTTPServer().catch(error => { + logger_1.logger.error('Failed to start Fixed HTTP server:', error); + console.error('Failed to start Fixed HTTP server:', error); + process.exit(1); + }); +} +//# sourceMappingURL=http-server.js.map \ No newline at end of file diff --git a/dist/http-server.js.map b/dist/http-server.js.map new file mode 100644 index 0000000..d0ba88a --- /dev/null +++ b/dist/http-server.js.map @@ -0,0 +1 @@ +{"version":3,"file":"http-server.js","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.d.ts b/dist/index.d.ts new file mode 100644 index 0000000..2dd6712 --- /dev/null +++ b/dist/index.d.ts @@ -0,0 +1,11 @@ +export { N8NMCPEngine, EngineHealth, EngineOptions } from './mcp-engine'; +export { SingleSessionHTTPServer } from './http-server-single-session'; +export { ConsoleManager } from './utils/console-manager'; +export { N8NDocumentationMCPServer } from './mcp/server'; +export type { InstanceContext } from './types/instance-context'; +export { validateInstanceContext, isInstanceContext } from './types/instance-context'; +export type { SessionState } from './types/session-state'; +export type { Tool, CallToolResult, ListToolsResult } from '@modelcontextprotocol/sdk/types.js'; +import N8NMCPEngine from './mcp-engine'; +export default N8NMCPEngine; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/index.d.ts.map b/dist/index.d.ts.map new file mode 100644 index 0000000..528f794 --- /dev/null +++ b/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAGzD,YAAY,EACV,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EAClB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,YAAY,EACb,MAAM,uBAAuB,CAAC;AAG/B,YAAY,EACV,IAAI,EACJ,cAAc,EACd,eAAe,EAChB,MAAM,oCAAoC,CAAC;AAG5C,OAAO,YAAY,MAAM,cAAc,CAAC;AACxC,eAAe,YAAY,CAAC"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..fbc5207 --- /dev/null +++ b/dist/index.js @@ -0,0 +1,20 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isInstanceContext = exports.validateInstanceContext = exports.N8NDocumentationMCPServer = exports.ConsoleManager = exports.SingleSessionHTTPServer = exports.N8NMCPEngine = void 0; +var mcp_engine_1 = require("./mcp-engine"); +Object.defineProperty(exports, "N8NMCPEngine", { enumerable: true, get: function () { return mcp_engine_1.N8NMCPEngine; } }); +var http_server_single_session_1 = require("./http-server-single-session"); +Object.defineProperty(exports, "SingleSessionHTTPServer", { enumerable: true, get: function () { return http_server_single_session_1.SingleSessionHTTPServer; } }); +var console_manager_1 = require("./utils/console-manager"); +Object.defineProperty(exports, "ConsoleManager", { enumerable: true, get: function () { return console_manager_1.ConsoleManager; } }); +var server_1 = require("./mcp/server"); +Object.defineProperty(exports, "N8NDocumentationMCPServer", { enumerable: true, get: function () { return server_1.N8NDocumentationMCPServer; } }); +var instance_context_1 = require("./types/instance-context"); +Object.defineProperty(exports, "validateInstanceContext", { enumerable: true, get: function () { return instance_context_1.validateInstanceContext; } }); +Object.defineProperty(exports, "isInstanceContext", { enumerable: true, get: function () { return instance_context_1.isInstanceContext; } }); +const mcp_engine_2 = __importDefault(require("./mcp-engine")); +exports.default = mcp_engine_2.default; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/index.js.map b/dist/index.js.map new file mode 100644 index 0000000..fde0259 --- /dev/null +++ b/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAOA,2CAAyE;AAAhE,0GAAA,YAAY,OAAA;AACrB,2EAAuE;AAA9D,qIAAA,uBAAuB,OAAA;AAChC,2DAAyD;AAAhD,iHAAA,cAAc,OAAA;AACvB,uCAAyD;AAAhD,mHAAA,yBAAyB,OAAA;AAMlC,6DAGkC;AAFhC,2HAAA,uBAAuB,OAAA;AACvB,qHAAA,iBAAiB,OAAA;AAcnB,8DAAwC;AACxC,kBAAe,oBAAY,CAAC"} \ No newline at end of file diff --git a/dist/loaders/node-loader.d.ts b/dist/loaders/node-loader.d.ts new file mode 100644 index 0000000..da4c600 --- /dev/null +++ b/dist/loaders/node-loader.d.ts @@ -0,0 +1,11 @@ +export interface LoadedNode { + packageName: string; + nodeName: string; + NodeClass: any; +} +export declare class N8nNodeLoader { + private readonly CORE_PACKAGES; + loadAllNodes(): Promise; + private loadPackageNodes; +} +//# sourceMappingURL=node-loader.d.ts.map \ No newline at end of file diff --git a/dist/loaders/node-loader.d.ts.map b/dist/loaders/node-loader.d.ts.map new file mode 100644 index 0000000..428ce36 --- /dev/null +++ b/dist/loaders/node-loader.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"node-loader.d.ts","sourceRoot":"","sources":["../../src/loaders/node-loader.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,GAAG,CAAC;CAChB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAG5B;IAEI,YAAY,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YAmB7B,gBAAgB;CAqD/B"} \ No newline at end of file diff --git a/dist/loaders/node-loader.js b/dist/loaders/node-loader.js new file mode 100644 index 0000000..4ee59d8 --- /dev/null +++ b/dist/loaders/node-loader.js @@ -0,0 +1,79 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.N8nNodeLoader = void 0; +const path_1 = __importDefault(require("path")); +class N8nNodeLoader { + constructor() { + this.CORE_PACKAGES = [ + { name: 'n8n-nodes-base', path: 'n8n-nodes-base' }, + { name: '@n8n/n8n-nodes-langchain', path: '@n8n/n8n-nodes-langchain' } + ]; + } + async loadAllNodes() { + const results = []; + for (const pkg of this.CORE_PACKAGES) { + try { + console.log(`\n📦 Loading package: ${pkg.name} from ${pkg.path}`); + const packageJson = require(`${pkg.path}/package.json`); + console.log(` Found ${Object.keys(packageJson.n8n?.nodes || {}).length} nodes in package.json`); + const nodes = await this.loadPackageNodes(pkg.name, pkg.path, packageJson); + results.push(...nodes); + } + catch (error) { + console.error(`Failed to load ${pkg.name}:`, error); + } + } + return results; + } + async loadPackageNodes(packageName, packagePath, packageJson) { + const n8nConfig = packageJson.n8n || {}; + const nodes = []; + const nodesList = n8nConfig.nodes || []; + if (Array.isArray(nodesList)) { + for (const nodePath of nodesList) { + try { + const fullPath = require.resolve(`${packagePath}/${nodePath}`); + const nodeModule = require(fullPath); + const nodeNameMatch = nodePath.match(/\/([^\/]+)\.node\.(js|ts)$/); + const nodeName = nodeNameMatch ? nodeNameMatch[1] : path_1.default.basename(nodePath, '.node.js'); + const NodeClass = nodeModule.default || nodeModule[nodeName] || Object.values(nodeModule)[0]; + if (NodeClass) { + nodes.push({ packageName, nodeName, NodeClass }); + console.log(` ✓ Loaded ${nodeName} from ${packageName}`); + } + else { + console.warn(` ⚠ No valid export found for ${nodeName} in ${packageName}`); + } + } + catch (error) { + console.error(` ✗ Failed to load node from ${packageName}/${nodePath}:`, error.message); + } + } + } + else { + for (const [nodeName, nodePath] of Object.entries(nodesList)) { + try { + const fullPath = require.resolve(`${packagePath}/${nodePath}`); + const nodeModule = require(fullPath); + const NodeClass = nodeModule.default || nodeModule[nodeName] || Object.values(nodeModule)[0]; + if (NodeClass) { + nodes.push({ packageName, nodeName, NodeClass }); + console.log(` ✓ Loaded ${nodeName} from ${packageName}`); + } + else { + console.warn(` ⚠ No valid export found for ${nodeName} in ${packageName}`); + } + } + catch (error) { + console.error(` ✗ Failed to load node ${nodeName} from ${packageName}:`, error.message); + } + } + } + return nodes; + } +} +exports.N8nNodeLoader = N8nNodeLoader; +//# sourceMappingURL=node-loader.js.map \ No newline at end of file diff --git a/dist/loaders/node-loader.js.map b/dist/loaders/node-loader.js.map new file mode 100644 index 0000000..05f2c0b --- /dev/null +++ b/dist/loaders/node-loader.js.map @@ -0,0 +1 @@ +{"version":3,"file":"node-loader.js","sourceRoot":"","sources":["../../src/loaders/node-loader.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/mappers/docs-mapper.d.ts b/dist/mappers/docs-mapper.d.ts new file mode 100644 index 0000000..8a7bf2d --- /dev/null +++ b/dist/mappers/docs-mapper.d.ts @@ -0,0 +1,7 @@ +export declare class DocsMapper { + private docsPath; + private readonly KNOWN_FIXES; + fetchDocumentation(nodeType: string): Promise; + private enhanceLoopNodeDocumentation; +} +//# sourceMappingURL=docs-mapper.d.ts.map \ No newline at end of file diff --git a/dist/mappers/docs-mapper.d.ts.map b/dist/mappers/docs-mapper.d.ts.map new file mode 100644 index 0000000..ca40475 --- /dev/null +++ b/dist/mappers/docs-mapper.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"docs-mapper.d.ts","sourceRoot":"","sources":["../../src/mappers/docs-mapper.ts"],"names":[],"mappings":"AAGA,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAwC;IAGxD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAU1B;IAEI,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAkDlE,OAAO,CAAC,4BAA4B;CAmDrC"} \ No newline at end of file diff --git a/dist/mappers/docs-mapper.js b/dist/mappers/docs-mapper.js new file mode 100644 index 0000000..6c2373f --- /dev/null +++ b/dist/mappers/docs-mapper.js @@ -0,0 +1,106 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DocsMapper = void 0; +const fs_1 = require("fs"); +const path_1 = __importDefault(require("path")); +class DocsMapper { + constructor() { + this.docsPath = path_1.default.join(process.cwd(), 'n8n-docs'); + this.KNOWN_FIXES = { + 'httpRequest': 'httprequest', + 'code': 'code', + 'webhook': 'webhook', + 'respondToWebhook': 'respondtowebhook', + 'n8n-nodes-base.httpRequest': 'httprequest', + 'n8n-nodes-base.code': 'code', + 'n8n-nodes-base.webhook': 'webhook', + 'n8n-nodes-base.respondToWebhook': 'respondtowebhook' + }; + } + async fetchDocumentation(nodeType) { + const fixedType = this.KNOWN_FIXES[nodeType] || nodeType; + const nodeName = fixedType.split('.').pop()?.toLowerCase(); + if (!nodeName) { + console.log(`⚠️ Could not extract node name from: ${nodeType}`); + return null; + } + console.log(`📄 Looking for docs for: ${nodeType} -> ${nodeName}`); + const possiblePaths = [ + `docs/integrations/builtin/core-nodes/n8n-nodes-base.${nodeName}.md`, + `docs/integrations/builtin/app-nodes/n8n-nodes-base.${nodeName}.md`, + `docs/integrations/builtin/trigger-nodes/n8n-nodes-base.${nodeName}.md`, + `docs/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.${nodeName}.md`, + `docs/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.${nodeName}.md`, + `docs/integrations/builtin/core-nodes/n8n-nodes-base.${nodeName}/index.md`, + `docs/integrations/builtin/app-nodes/n8n-nodes-base.${nodeName}/index.md`, + `docs/integrations/builtin/trigger-nodes/n8n-nodes-base.${nodeName}/index.md`, + `docs/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.${nodeName}/index.md`, + `docs/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.${nodeName}/index.md` + ]; + for (const relativePath of possiblePaths) { + try { + const fullPath = path_1.default.join(this.docsPath, relativePath); + let content = await fs_1.promises.readFile(fullPath, 'utf-8'); + console.log(` ✓ Found docs at: ${relativePath}`); + content = this.enhanceLoopNodeDocumentation(nodeType, content); + return content; + } + catch (error) { + continue; + } + } + console.log(` ✗ No docs found for ${nodeName}`); + return null; + } + enhanceLoopNodeDocumentation(nodeType, content) { + if (nodeType.includes('splitInBatches')) { + const outputGuidance = ` + +## CRITICAL OUTPUT CONNECTION INFORMATION + +**⚠️ OUTPUT INDICES ARE COUNTERINTUITIVE ⚠️** + +The SplitInBatches node has TWO outputs with specific indices: +- **Output 0 (index 0) = "done"**: Receives final processed data when loop completes +- **Output 1 (index 1) = "loop"**: Receives current batch data during iteration + +### Correct Connection Pattern: +1. Connect nodes that PROCESS items inside the loop to **Output 1 ("loop")** +2. Connect nodes that run AFTER the loop completes to **Output 0 ("done")** +3. The last processing node in the loop must connect back to the SplitInBatches node + +### Common Mistake: +AI assistants often connect these backwards because the logical flow (loop first, then done) doesn't match the technical indices (done=0, loop=1). + +`; + const insertPoint = content.indexOf('## When to use'); + if (insertPoint > -1) { + content = content.slice(0, insertPoint) + outputGuidance + content.slice(insertPoint); + } + else { + content = outputGuidance + '\n' + content; + } + } + if (nodeType.includes('.if')) { + const outputGuidance = ` + +## Output Connection Information + +The IF node has TWO outputs: +- **Output 0 (index 0) = "true"**: Items that match the condition +- **Output 1 (index 1) = "false"**: Items that do not match the condition + +`; + const insertPoint = content.indexOf('## Node parameters'); + if (insertPoint > -1) { + content = content.slice(0, insertPoint) + outputGuidance + content.slice(insertPoint); + } + } + return content; + } +} +exports.DocsMapper = DocsMapper; +//# sourceMappingURL=docs-mapper.js.map \ No newline at end of file diff --git a/dist/mappers/docs-mapper.js.map b/dist/mappers/docs-mapper.js.map new file mode 100644 index 0000000..c28df18 --- /dev/null +++ b/dist/mappers/docs-mapper.js.map @@ -0,0 +1 @@ +{"version":3,"file":"docs-mapper.js","sourceRoot":"","sources":["../../src/mappers/docs-mapper.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/mcp-engine.d.ts b/dist/mcp-engine.d.ts new file mode 100644 index 0000000..dffef0b --- /dev/null +++ b/dist/mcp-engine.d.ts @@ -0,0 +1,36 @@ +import { Request, Response } from 'express'; +import { InstanceContext } from './types/instance-context'; +import { SessionState } from './types/session-state'; +export interface EngineHealth { + status: 'healthy' | 'unhealthy'; + uptime: number; + sessionActive: boolean; + memoryUsage: { + used: number; + total: number; + unit: string; + }; + version: string; +} +export interface EngineOptions { + sessionTimeout?: number; + logLevel?: 'error' | 'warn' | 'info' | 'debug'; +} +export declare class N8NMCPEngine { + private server; + private startTime; + constructor(options?: EngineOptions); + processRequest(req: Request, res: Response, instanceContext?: InstanceContext): Promise; + healthCheck(): Promise; + getSessionInfo(): { + active: boolean; + sessionId?: string; + age?: number; + }; + exportSessionState(): SessionState[]; + restoreSessionState(sessions: SessionState[]): number; + shutdown(): Promise; + start(): Promise; +} +export default N8NMCPEngine; +//# sourceMappingURL=mcp-engine.d.ts.map \ No newline at end of file diff --git a/dist/mcp-engine.d.ts.map b/dist/mcp-engine.d.ts.map new file mode 100644 index 0000000..62c11ff --- /dev/null +++ b/dist/mcp-engine.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"mcp-engine.d.ts","sourceRoot":"","sources":["../src/mcp-engine.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,SAAS,GAAG,WAAW,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CAChD;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,SAAS,CAAO;gBAEZ,OAAO,GAAE,aAAkB;IA8BjC,cAAc,CAClB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,eAAe,CAAC,EAAE,eAAe,GAChC,OAAO,CAAC,IAAI,CAAC;IAkBV,WAAW,IAAI,OAAO,CAAC,YAAY,CAAC;IAgC1C,cAAc,IAAI;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE;IAoBvE,kBAAkB,IAAI,YAAY,EAAE;IAwBpC,mBAAmB,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM;IAiB/C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IASzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B;AA2CD,eAAe,YAAY,CAAC"} \ No newline at end of file diff --git a/dist/mcp-engine.js b/dist/mcp-engine.js new file mode 100644 index 0000000..24f8abb --- /dev/null +++ b/dist/mcp-engine.js @@ -0,0 +1,77 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.N8NMCPEngine = void 0; +const http_server_single_session_1 = require("./http-server-single-session"); +const logger_1 = require("./utils/logger"); +class N8NMCPEngine { + constructor(options = {}) { + this.server = new http_server_single_session_1.SingleSessionHTTPServer(); + this.startTime = new Date(); + if (options.logLevel) { + process.env.LOG_LEVEL = options.logLevel; + } + } + async processRequest(req, res, instanceContext) { + try { + await this.server.handleRequest(req, res, instanceContext); + } + catch (error) { + logger_1.logger.error('Engine processRequest error:', error); + throw error; + } + } + async healthCheck() { + try { + const sessionInfo = this.server.getSessionInfo(); + const memoryUsage = process.memoryUsage(); + return { + status: 'healthy', + uptime: Math.floor((Date.now() - this.startTime.getTime()) / 1000), + sessionActive: sessionInfo.active, + memoryUsage: { + used: Math.round(memoryUsage.heapUsed / 1024 / 1024), + total: Math.round(memoryUsage.heapTotal / 1024 / 1024), + unit: 'MB' + }, + version: '2.24.1' + }; + } + catch (error) { + logger_1.logger.error('Health check failed:', error); + return { + status: 'unhealthy', + uptime: 0, + sessionActive: false, + memoryUsage: { used: 0, total: 0, unit: 'MB' }, + version: '2.24.1' + }; + } + } + getSessionInfo() { + return this.server.getSessionInfo(); + } + exportSessionState() { + if (!this.server) { + logger_1.logger.warn('Cannot export sessions: server not initialized'); + return []; + } + return this.server.exportSessionState(); + } + restoreSessionState(sessions) { + if (!this.server) { + logger_1.logger.warn('Cannot restore sessions: server not initialized'); + return 0; + } + return this.server.restoreSessionState(sessions); + } + async shutdown() { + logger_1.logger.info('Shutting down N8N MCP Engine...'); + await this.server.shutdown(); + } + async start() { + await this.server.start(); + } +} +exports.N8NMCPEngine = N8NMCPEngine; +exports.default = N8NMCPEngine; +//# sourceMappingURL=mcp-engine.js.map \ No newline at end of file diff --git a/dist/mcp-engine.js.map b/dist/mcp-engine.js.map new file mode 100644 index 0000000..8847459 --- /dev/null +++ b/dist/mcp-engine.js.map @@ -0,0 +1 @@ +{"version":3,"file":"mcp-engine.js","sourceRoot":"","sources":["../src/mcp-engine.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/mcp-tools-engine.d.ts b/dist/mcp-tools-engine.d.ts new file mode 100644 index 0000000..d7d079d --- /dev/null +++ b/dist/mcp-tools-engine.d.ts @@ -0,0 +1,47 @@ +import { NodeRepository } from './database/node-repository'; +import { WorkflowValidationResult } from './services/workflow-validator'; +export declare class MCPEngine { + private repository; + private workflowValidator; + constructor(repository: NodeRepository); + listNodes(args?: any): Promise; + searchNodes(args: any): Promise; + getNodeInfo(args: any): Promise; + getNodeEssentials(args: any): Promise<{ + nodeType: any; + displayName: any; + description: any; + category: any; + required: import("./services/property-filter").SimplifiedProperty[]; + common: import("./services/property-filter").SimplifiedProperty[]; + } | null>; + getNodeDocumentation(args: any): Promise; + validateNodeOperation(args: any): Promise; + validateNodeMinimal(args: any): Promise<{ + missingFields: never[]; + error: string; + } | { + missingFields: string[]; + error?: undefined; + }>; + searchNodeProperties(args: any): Promise; + listAITools(args: any): Promise; + getDatabaseStatistics(args: any): Promise<{ + totalNodes: number; + aiToolsCount: number; + categories: string[]; + }>; + validateWorkflow(args: any): Promise; +} +//# sourceMappingURL=mcp-tools-engine.d.ts.map \ No newline at end of file diff --git a/dist/mcp-tools-engine.d.ts.map b/dist/mcp-tools-engine.d.ts.map new file mode 100644 index 0000000..6c39c92 --- /dev/null +++ b/dist/mcp-tools-engine.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"mcp-tools-engine.d.ts","sourceRoot":"","sources":["../src/mcp-tools-engine.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAK5D,OAAO,EAAqB,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAE5F,qBAAa,SAAS;IAGR,OAAO,CAAC,UAAU;IAF9B,OAAO,CAAC,iBAAiB,CAAoB;gBAEzB,UAAU,EAAE,cAAc;IAIxC,SAAS,CAAC,IAAI,GAAE,GAAQ;IAIxB,WAAW,CAAC,IAAI,EAAE,GAAG;IAIrB,WAAW,CAAC,IAAI,EAAE,GAAG;IAIrB,iBAAiB,CAAC,IAAI,EAAE,GAAG;;;;;;;;IAgB3B,oBAAoB,CAAC,IAAI,EAAE,GAAG;IAK9B,qBAAqB,CAAC,IAAI,EAAE,GAAG;;;;;;;;;;;;IAqB/B,mBAAmB,CAAC,IAAI,EAAE,GAAG;;;;;;;IAmB7B,oBAAoB,CAAC,IAAI,EAAE,GAAG;IAI9B,WAAW,CAAC,IAAI,EAAE,GAAG;IAIrB,qBAAqB,CAAC,IAAI,EAAE,GAAG;;;;;IAU/B,gBAAgB,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,wBAAwB,CAAC;CAGrE"} \ No newline at end of file diff --git a/dist/mcp-tools-engine.js b/dist/mcp-tools-engine.js new file mode 100644 index 0000000..2a72b94 --- /dev/null +++ b/dist/mcp-tools-engine.js @@ -0,0 +1,89 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.MCPEngine = void 0; +const property_filter_1 = require("./services/property-filter"); +const config_validator_1 = require("./services/config-validator"); +const enhanced_config_validator_1 = require("./services/enhanced-config-validator"); +const workflow_validator_1 = require("./services/workflow-validator"); +class MCPEngine { + constructor(repository) { + this.repository = repository; + this.workflowValidator = new workflow_validator_1.WorkflowValidator(repository, enhanced_config_validator_1.EnhancedConfigValidator); + } + async listNodes(args = {}) { + return this.repository.getAllNodes(args.limit); + } + async searchNodes(args) { + return this.repository.searchNodes(args.query, args.mode || 'OR', args.limit || 20); + } + async getNodeInfo(args) { + return this.repository.getNodeByType(args.nodeType); + } + async getNodeEssentials(args) { + const node = await this.repository.getNodeByType(args.nodeType); + if (!node) + return null; + const essentials = property_filter_1.PropertyFilter.getEssentials(node.properties || [], args.nodeType); + return { + nodeType: node.nodeType, + displayName: node.displayName, + description: node.description, + category: node.category, + required: essentials.required, + common: essentials.common + }; + } + async getNodeDocumentation(args) { + const node = await this.repository.getNodeByType(args.nodeType); + return node?.documentation || null; + } + async validateNodeOperation(args) { + const node = await this.repository.getNodeByType(args.nodeType); + if (!node) { + return { + valid: false, + errors: [{ type: 'invalid_configuration', property: '', message: 'Node type not found' }], + warnings: [], + suggestions: [], + visibleProperties: [], + hiddenProperties: [] + }; + } + const userProvidedKeys = new Set(Object.keys(args.config || {})); + return config_validator_1.ConfigValidator.validate(args.nodeType, args.config, node.properties || [], userProvidedKeys); + } + async validateNodeMinimal(args) { + const node = await this.repository.getNodeByType(args.nodeType); + if (!node) { + return { missingFields: [], error: 'Node type not found' }; + } + const missingFields = []; + const requiredFields = property_filter_1.PropertyFilter.getEssentials(node.properties || [], args.nodeType).required; + for (const field of requiredFields) { + if (!args.config[field.name]) { + missingFields.push(field.name); + } + } + return { missingFields }; + } + async searchNodeProperties(args) { + return this.repository.searchNodeProperties(args.nodeType, args.query, args.maxResults || 20); + } + async listAITools(args) { + return this.repository.getAIToolNodes(); + } + async getDatabaseStatistics(args) { + const count = await this.repository.getNodeCount(); + const aiTools = await this.repository.getAIToolNodes(); + return { + totalNodes: count, + aiToolsCount: aiTools.length, + categories: ['trigger', 'transform', 'output', 'input'] + }; + } + async validateWorkflow(args) { + return this.workflowValidator.validateWorkflow(args.workflow, args.options); + } +} +exports.MCPEngine = MCPEngine; +//# sourceMappingURL=mcp-tools-engine.js.map \ No newline at end of file diff --git a/dist/mcp-tools-engine.js.map b/dist/mcp-tools-engine.js.map new file mode 100644 index 0000000..697dc94 --- /dev/null +++ b/dist/mcp-tools-engine.js.map @@ -0,0 +1 @@ +{"version":3,"file":"mcp-tools-engine.js","sourceRoot":"","sources":["../src/mcp-tools-engine.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/mcp/handlers-n8n-manager.d.ts b/dist/mcp/handlers-n8n-manager.d.ts new file mode 100644 index 0000000..803fa26 --- /dev/null +++ b/dist/mcp/handlers-n8n-manager.d.ts @@ -0,0 +1,29 @@ +import { N8nApiClient } from '../services/n8n-api-client'; +import { McpToolResponse } from '../types/n8n-api'; +import { NodeRepository } from '../database/node-repository'; +import { InstanceContext } from '../types/instance-context'; +import { TemplateService } from '../templates/template-service'; +export declare function getInstanceCacheStatistics(): string; +export declare function getInstanceCacheMetrics(): import("../utils/cache-utils").CacheMetrics; +export declare function clearInstanceCache(): void; +export declare function getN8nApiClient(context?: InstanceContext): N8nApiClient | null; +export declare function handleCreateWorkflow(args: unknown, context?: InstanceContext): Promise; +export declare function handleGetWorkflow(args: unknown, context?: InstanceContext): Promise; +export declare function handleGetWorkflowDetails(args: unknown, context?: InstanceContext): Promise; +export declare function handleGetWorkflowStructure(args: unknown, context?: InstanceContext): Promise; +export declare function handleGetWorkflowMinimal(args: unknown, context?: InstanceContext): Promise; +export declare function handleUpdateWorkflow(args: unknown, repository: NodeRepository, context?: InstanceContext): Promise; +export declare function handleDeleteWorkflow(args: unknown, context?: InstanceContext): Promise; +export declare function handleListWorkflows(args: unknown, context?: InstanceContext): Promise; +export declare function handleValidateWorkflow(args: unknown, repository: NodeRepository, context?: InstanceContext): Promise; +export declare function handleAutofixWorkflow(args: unknown, repository: NodeRepository, context?: InstanceContext): Promise; +export declare function handleTestWorkflow(args: unknown, context?: InstanceContext): Promise; +export declare function handleGetExecution(args: unknown, context?: InstanceContext): Promise; +export declare function handleListExecutions(args: unknown, context?: InstanceContext): Promise; +export declare function handleDeleteExecution(args: unknown, context?: InstanceContext): Promise; +export declare function handleHealthCheck(context?: InstanceContext): Promise; +export declare function handleDiagnostic(request: any, context?: InstanceContext): Promise; +export declare function handleWorkflowVersions(args: unknown, repository: NodeRepository, context?: InstanceContext): Promise; +export declare function handleDeployTemplate(args: unknown, templateService: TemplateService, repository: NodeRepository, context?: InstanceContext): Promise; +export declare function handleTriggerWebhookWorkflow(args: unknown, context?: InstanceContext): Promise; +//# sourceMappingURL=handlers-n8n-manager.d.ts.map \ No newline at end of file diff --git a/dist/mcp/handlers-n8n-manager.d.ts.map b/dist/mcp/handlers-n8n-manager.d.ts.map new file mode 100644 index 0000000..849ab61 --- /dev/null +++ b/dist/mcp/handlers-n8n-manager.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"handlers-n8n-manager.d.ts","sourceRoot":"","sources":["../../src/mcp/handlers-n8n-manager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/mcp/handlers-n8n-manager.js b/dist/mcp/handlers-n8n-manager.js new file mode 100644 index 0000000..5cb78a5 --- /dev/null +++ b/dist/mcp/handlers-n8n-manager.js @@ -0,0 +1,1993 @@ +"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.getInstanceCacheStatistics = getInstanceCacheStatistics; +exports.getInstanceCacheMetrics = getInstanceCacheMetrics; +exports.clearInstanceCache = clearInstanceCache; +exports.getN8nApiClient = getN8nApiClient; +exports.handleCreateWorkflow = handleCreateWorkflow; +exports.handleGetWorkflow = handleGetWorkflow; +exports.handleGetWorkflowDetails = handleGetWorkflowDetails; +exports.handleGetWorkflowStructure = handleGetWorkflowStructure; +exports.handleGetWorkflowMinimal = handleGetWorkflowMinimal; +exports.handleUpdateWorkflow = handleUpdateWorkflow; +exports.handleDeleteWorkflow = handleDeleteWorkflow; +exports.handleListWorkflows = handleListWorkflows; +exports.handleValidateWorkflow = handleValidateWorkflow; +exports.handleAutofixWorkflow = handleAutofixWorkflow; +exports.handleTestWorkflow = handleTestWorkflow; +exports.handleGetExecution = handleGetExecution; +exports.handleListExecutions = handleListExecutions; +exports.handleDeleteExecution = handleDeleteExecution; +exports.handleHealthCheck = handleHealthCheck; +exports.handleDiagnostic = handleDiagnostic; +exports.handleWorkflowVersions = handleWorkflowVersions; +exports.handleDeployTemplate = handleDeployTemplate; +exports.handleTriggerWebhookWorkflow = handleTriggerWebhookWorkflow; +const n8n_api_client_1 = require("../services/n8n-api-client"); +const n8n_api_1 = require("../config/n8n-api"); +const n8n_api_2 = require("../types/n8n-api"); +const n8n_validation_1 = require("../services/n8n-validation"); +const n8n_errors_1 = require("../utils/n8n-errors"); +const logger_1 = require("../utils/logger"); +const zod_1 = require("zod"); +const workflow_validator_1 = require("../services/workflow-validator"); +const enhanced_config_validator_1 = require("../services/enhanced-config-validator"); +const instance_context_1 = require("../types/instance-context"); +const workflow_auto_fixer_1 = require("../services/workflow-auto-fixer"); +const expression_format_validator_1 = require("../services/expression-format-validator"); +const workflow_versioning_service_1 = require("../services/workflow-versioning-service"); +const handlers_workflow_diff_1 = require("./handlers-workflow-diff"); +const telemetry_1 = require("../telemetry"); +const cache_utils_1 = require("../utils/cache-utils"); +const execution_processor_1 = require("../services/execution-processor"); +const npm_version_checker_1 = require("../utils/npm-version-checker"); +let defaultApiClient = null; +let lastDefaultConfigUrl = null; +const cacheMutex = new cache_utils_1.CacheMutex(); +const instanceClients = (0, cache_utils_1.createInstanceCache)((client, key) => { + logger_1.logger.debug('Evicting API client from cache', { + cacheKey: key.substring(0, 8) + '...' + }); +}); +function getInstanceCacheStatistics() { + return (0, cache_utils_1.getCacheStatistics)(); +} +function getInstanceCacheMetrics() { + return cache_utils_1.cacheMetrics.getMetrics(); +} +function clearInstanceCache() { + instanceClients.clear(); + cache_utils_1.cacheMetrics.recordClear(); + cache_utils_1.cacheMetrics.updateSize(0, instanceClients.max); +} +function getN8nApiClient(context) { + if (context?.n8nApiUrl && context?.n8nApiKey) { + const validation = (0, instance_context_1.validateInstanceContext)(context); + if (!validation.valid) { + logger_1.logger.warn('Invalid instance context provided', { + instanceId: context.instanceId, + errors: validation.errors + }); + return null; + } + const cacheKey = (0, cache_utils_1.createCacheKey)(`${context.n8nApiUrl}:${context.n8nApiKey}:${context.instanceId || ''}`); + if (instanceClients.has(cacheKey)) { + cache_utils_1.cacheMetrics.recordHit(); + return instanceClients.get(cacheKey) || null; + } + cache_utils_1.cacheMetrics.recordMiss(); + if (cacheMutex.isLocked(cacheKey)) { + const waitTime = 100; + const start = Date.now(); + while (cacheMutex.isLocked(cacheKey) && (Date.now() - start) < 1000) { + } + if (instanceClients.has(cacheKey)) { + cache_utils_1.cacheMetrics.recordHit(); + return instanceClients.get(cacheKey) || null; + } + } + const config = (0, n8n_api_1.getN8nApiConfigFromContext)(context); + if (config) { + logger_1.logger.info('Creating instance-specific n8n API client', { + url: config.baseUrl.replace(/^(https?:\/\/[^\/]+).*/, '$1'), + instanceId: context.instanceId, + cacheKey: cacheKey.substring(0, 8) + '...' + }); + const client = new n8n_api_client_1.N8nApiClient(config); + instanceClients.set(cacheKey, client); + cache_utils_1.cacheMetrics.recordSet(); + cache_utils_1.cacheMetrics.updateSize(instanceClients.size, instanceClients.max); + return client; + } + return null; + } + logger_1.logger.info('Falling back to environment configuration for n8n API client'); + const config = (0, n8n_api_1.getN8nApiConfig)(); + if (!config) { + if (defaultApiClient) { + logger_1.logger.info('n8n API configuration removed, clearing default client'); + defaultApiClient = null; + lastDefaultConfigUrl = null; + } + return null; + } + if (!defaultApiClient || lastDefaultConfigUrl !== config.baseUrl) { + logger_1.logger.info('n8n API client initialized from environment', { url: config.baseUrl }); + defaultApiClient = new n8n_api_client_1.N8nApiClient(config); + lastDefaultConfigUrl = config.baseUrl; + } + return defaultApiClient; +} +function ensureApiConfigured(context) { + const client = getN8nApiClient(context); + if (!client) { + if (context?.instanceId) { + throw new Error(`n8n API not configured for instance ${context.instanceId}. Please provide n8nApiUrl and n8nApiKey in the instance context.`); + } + throw new Error('n8n API not configured. Please set N8N_API_URL and N8N_API_KEY environment variables.'); + } + return client; +} +const createWorkflowSchema = zod_1.z.object({ + name: zod_1.z.string(), + nodes: zod_1.z.array(zod_1.z.any()), + connections: zod_1.z.record(zod_1.z.any()), + settings: zod_1.z.object({ + executionOrder: zod_1.z.enum(['v0', 'v1']).optional(), + timezone: zod_1.z.string().optional(), + saveDataErrorExecution: zod_1.z.enum(['all', 'none']).optional(), + saveDataSuccessExecution: zod_1.z.enum(['all', 'none']).optional(), + saveManualExecutions: zod_1.z.boolean().optional(), + saveExecutionProgress: zod_1.z.boolean().optional(), + executionTimeout: zod_1.z.number().optional(), + errorWorkflow: zod_1.z.string().optional(), + }).optional(), +}); +const updateWorkflowSchema = zod_1.z.object({ + id: zod_1.z.string(), + name: zod_1.z.string().optional(), + nodes: zod_1.z.array(zod_1.z.any()).optional(), + connections: zod_1.z.record(zod_1.z.any()).optional(), + settings: zod_1.z.any().optional(), + createBackup: zod_1.z.boolean().optional(), + intent: zod_1.z.string().optional(), +}); +const listWorkflowsSchema = zod_1.z.object({ + limit: zod_1.z.number().min(1).max(100).optional(), + cursor: zod_1.z.string().optional(), + active: zod_1.z.boolean().optional(), + tags: zod_1.z.array(zod_1.z.string()).optional(), + projectId: zod_1.z.string().optional(), + excludePinnedData: zod_1.z.boolean().optional(), +}); +const validateWorkflowSchema = zod_1.z.object({ + id: zod_1.z.string(), + options: zod_1.z.object({ + validateNodes: zod_1.z.boolean().optional(), + validateConnections: zod_1.z.boolean().optional(), + validateExpressions: zod_1.z.boolean().optional(), + profile: zod_1.z.enum(['minimal', 'runtime', 'ai-friendly', 'strict']).optional(), + }).optional(), +}); +const autofixWorkflowSchema = zod_1.z.object({ + id: zod_1.z.string(), + applyFixes: zod_1.z.boolean().optional().default(false), + fixTypes: zod_1.z.array(zod_1.z.enum([ + 'expression-format', + 'typeversion-correction', + 'error-output-config', + 'node-type-correction', + 'webhook-missing-path', + 'typeversion-upgrade', + 'version-migration' + ])).optional(), + confidenceThreshold: zod_1.z.enum(['high', 'medium', 'low']).optional().default('medium'), + maxFixes: zod_1.z.number().optional().default(50) +}); +const testWorkflowSchema = zod_1.z.object({ + workflowId: zod_1.z.string(), + triggerType: zod_1.z.enum(['webhook', 'form', 'chat']).optional(), + httpMethod: zod_1.z.enum(['GET', 'POST', 'PUT', 'DELETE']).optional(), + webhookPath: zod_1.z.string().optional(), + message: zod_1.z.string().optional(), + sessionId: zod_1.z.string().optional(), + data: zod_1.z.record(zod_1.z.unknown()).optional(), + headers: zod_1.z.record(zod_1.z.string()).optional(), + timeout: zod_1.z.number().optional(), + waitForResponse: zod_1.z.boolean().optional(), +}); +const listExecutionsSchema = zod_1.z.object({ + limit: zod_1.z.number().min(1).max(100).optional(), + cursor: zod_1.z.string().optional(), + workflowId: zod_1.z.string().optional(), + projectId: zod_1.z.string().optional(), + status: zod_1.z.enum(['success', 'error', 'waiting']).optional(), + includeData: zod_1.z.boolean().optional(), +}); +const workflowVersionsSchema = zod_1.z.object({ + mode: zod_1.z.enum(['list', 'get', 'rollback', 'delete', 'prune', 'truncate']), + workflowId: zod_1.z.string().optional(), + versionId: zod_1.z.number().optional(), + limit: zod_1.z.number().default(10).optional(), + validateBefore: zod_1.z.boolean().default(true).optional(), + deleteAll: zod_1.z.boolean().default(false).optional(), + maxVersions: zod_1.z.number().default(10).optional(), + confirmTruncate: zod_1.z.boolean().default(false).optional(), +}); +async function handleCreateWorkflow(args, context) { + try { + const client = ensureApiConfigured(context); + const input = createWorkflowSchema.parse(args); + const shortFormErrors = []; + input.nodes?.forEach((node, index) => { + if (node.type?.startsWith('nodes-base.') || node.type?.startsWith('nodes-langchain.')) { + const fullForm = node.type.startsWith('nodes-base.') + ? node.type.replace('nodes-base.', 'n8n-nodes-base.') + : node.type.replace('nodes-langchain.', '@n8n/n8n-nodes-langchain.'); + shortFormErrors.push(`Node ${index} ("${node.name}") uses SHORT form "${node.type}". ` + + `The n8n API requires FULL form. Change to "${fullForm}"`); + } + }); + if (shortFormErrors.length > 0) { + telemetry_1.telemetry.trackWorkflowCreation(input, false); + return { + success: false, + error: 'Node type format error: n8n API requires FULL form node types', + details: { + errors: shortFormErrors, + hint: 'Use n8n-nodes-base.* instead of nodes-base.* for standard nodes' + } + }; + } + const errors = (0, n8n_validation_1.validateWorkflowStructure)(input); + if (errors.length > 0) { + telemetry_1.telemetry.trackWorkflowCreation(input, false); + return { + success: false, + error: 'Workflow validation failed', + details: { errors } + }; + } + const workflow = await client.createWorkflow(input); + telemetry_1.telemetry.trackWorkflowCreation(workflow, true); + return { + success: true, + data: workflow, + message: `Workflow "${workflow.name}" created successfully with ID: ${workflow.id}` + }; + } + catch (error) { + if (error instanceof zod_1.z.ZodError) { + return { + success: false, + error: 'Invalid input', + details: { errors: error.errors } + }; + } + if (error instanceof n8n_errors_1.N8nApiError) { + return { + success: false, + error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error), + code: error.code, + details: error.details + }; + } + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} +async function handleGetWorkflow(args, context) { + try { + const client = ensureApiConfigured(context); + const { id } = zod_1.z.object({ id: zod_1.z.string() }).parse(args); + const workflow = await client.getWorkflow(id); + return { + success: true, + data: workflow + }; + } + catch (error) { + if (error instanceof zod_1.z.ZodError) { + return { + success: false, + error: 'Invalid input', + details: { errors: error.errors } + }; + } + if (error instanceof n8n_errors_1.N8nApiError) { + return { + success: false, + error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error), + code: error.code + }; + } + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} +async function handleGetWorkflowDetails(args, context) { + try { + const client = ensureApiConfigured(context); + const { id } = zod_1.z.object({ id: zod_1.z.string() }).parse(args); + const workflow = await client.getWorkflow(id); + const executions = await client.listExecutions({ + workflowId: id, + limit: 10 + }); + const stats = { + totalExecutions: executions.data.length, + successCount: executions.data.filter(e => e.status === n8n_api_2.ExecutionStatus.SUCCESS).length, + errorCount: executions.data.filter(e => e.status === n8n_api_2.ExecutionStatus.ERROR).length, + lastExecutionTime: executions.data[0]?.startedAt || null + }; + return { + success: true, + data: { + workflow, + executionStats: stats, + hasWebhookTrigger: (0, n8n_validation_1.hasWebhookTrigger)(workflow), + webhookPath: (0, n8n_validation_1.getWebhookUrl)(workflow) + } + }; + } + catch (error) { + if (error instanceof zod_1.z.ZodError) { + return { + success: false, + error: 'Invalid input', + details: { errors: error.errors } + }; + } + if (error instanceof n8n_errors_1.N8nApiError) { + return { + success: false, + error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error), + code: error.code + }; + } + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} +async function handleGetWorkflowStructure(args, context) { + try { + const client = ensureApiConfigured(context); + const { id } = zod_1.z.object({ id: zod_1.z.string() }).parse(args); + const workflow = await client.getWorkflow(id); + const simplifiedNodes = workflow.nodes.map(node => ({ + id: node.id, + name: node.name, + type: node.type, + position: node.position, + disabled: node.disabled || false + })); + return { + success: true, + data: { + id: workflow.id, + name: workflow.name, + active: workflow.active, + isArchived: workflow.isArchived, + nodes: simplifiedNodes, + connections: workflow.connections, + nodeCount: workflow.nodes.length, + connectionCount: Object.keys(workflow.connections).length + } + }; + } + catch (error) { + if (error instanceof zod_1.z.ZodError) { + return { + success: false, + error: 'Invalid input', + details: { errors: error.errors } + }; + } + if (error instanceof n8n_errors_1.N8nApiError) { + return { + success: false, + error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error), + code: error.code + }; + } + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} +async function handleGetWorkflowMinimal(args, context) { + try { + const client = ensureApiConfigured(context); + const { id } = zod_1.z.object({ id: zod_1.z.string() }).parse(args); + const workflow = await client.getWorkflow(id); + return { + success: true, + data: { + id: workflow.id, + name: workflow.name, + active: workflow.active, + isArchived: workflow.isArchived, + tags: workflow.tags || [], + createdAt: workflow.createdAt, + updatedAt: workflow.updatedAt + } + }; + } + catch (error) { + if (error instanceof zod_1.z.ZodError) { + return { + success: false, + error: 'Invalid input', + details: { errors: error.errors } + }; + } + if (error instanceof n8n_errors_1.N8nApiError) { + return { + success: false, + error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error), + code: error.code + }; + } + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} +async function handleUpdateWorkflow(args, repository, context) { + const startTime = Date.now(); + const sessionId = `mutation_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`; + let workflowBefore = null; + let userIntent = 'Full workflow update'; + try { + const client = ensureApiConfigured(context); + const input = updateWorkflowSchema.parse(args); + const { id, createBackup, intent, ...updateData } = input; + userIntent = intent || 'Full workflow update'; + if (updateData.nodes || updateData.connections) { + const current = await client.getWorkflow(id); + workflowBefore = JSON.parse(JSON.stringify(current)); + if (createBackup !== false) { + try { + const versioningService = new workflow_versioning_service_1.WorkflowVersioningService(repository, client); + const backupResult = await versioningService.createBackup(id, current, { + trigger: 'full_update' + }); + logger_1.logger.info('Workflow backup created', { + workflowId: id, + versionId: backupResult.versionId, + versionNumber: backupResult.versionNumber, + pruned: backupResult.pruned + }); + } + catch (error) { + logger_1.logger.warn('Failed to create workflow backup', { + workflowId: id, + error: error.message + }); + } + } + const fullWorkflow = { + ...current, + ...updateData + }; + const errors = (0, n8n_validation_1.validateWorkflowStructure)(fullWorkflow); + if (errors.length > 0) { + return { + success: false, + error: 'Workflow validation failed', + details: { errors } + }; + } + } + const workflow = await client.updateWorkflow(id, updateData); + if (workflowBefore) { + trackWorkflowMutationForFullUpdate({ + sessionId, + toolName: 'n8n_update_full_workflow', + userIntent, + operations: [], + workflowBefore, + workflowAfter: workflow, + mutationSuccess: true, + durationMs: Date.now() - startTime, + }).catch(err => { + logger_1.logger.warn('Failed to track mutation telemetry:', err); + }); + } + return { + success: true, + data: workflow, + message: `Workflow "${workflow.name}" updated successfully` + }; + } + catch (error) { + if (workflowBefore) { + trackWorkflowMutationForFullUpdate({ + sessionId, + toolName: 'n8n_update_full_workflow', + userIntent, + operations: [], + workflowBefore, + workflowAfter: workflowBefore, + mutationSuccess: false, + mutationError: error instanceof Error ? error.message : 'Unknown error', + durationMs: Date.now() - startTime, + }).catch(err => { + logger_1.logger.warn('Failed to track mutation telemetry for failed operation:', err); + }); + } + if (error instanceof zod_1.z.ZodError) { + return { + success: false, + error: 'Invalid input', + details: { errors: error.errors } + }; + } + if (error instanceof n8n_errors_1.N8nApiError) { + return { + success: false, + error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error), + code: error.code, + details: error.details + }; + } + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} +async function trackWorkflowMutationForFullUpdate(data) { + try { + const { telemetry } = await Promise.resolve().then(() => __importStar(require('../telemetry/telemetry-manager.js'))); + await telemetry.trackWorkflowMutation(data); + } + catch (error) { + logger_1.logger.debug('Telemetry tracking failed:', error); + } +} +async function handleDeleteWorkflow(args, context) { + try { + const client = ensureApiConfigured(context); + const { id } = zod_1.z.object({ id: zod_1.z.string() }).parse(args); + const deleted = await client.deleteWorkflow(id); + return { + success: true, + data: deleted, + message: `Workflow ${id} deleted successfully` + }; + } + catch (error) { + if (error instanceof zod_1.z.ZodError) { + return { + success: false, + error: 'Invalid input', + details: { errors: error.errors } + }; + } + if (error instanceof n8n_errors_1.N8nApiError) { + return { + success: false, + error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error), + code: error.code + }; + } + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} +async function handleListWorkflows(args, context) { + try { + const client = ensureApiConfigured(context); + const input = listWorkflowsSchema.parse(args || {}); + const tagsParam = input.tags && input.tags.length > 0 + ? input.tags.join(',') + : undefined; + const response = await client.listWorkflows({ + limit: input.limit || 100, + cursor: input.cursor, + active: input.active, + tags: tagsParam, + projectId: input.projectId, + excludePinnedData: input.excludePinnedData ?? true + }); + const minimalWorkflows = response.data.map(workflow => ({ + id: workflow.id, + name: workflow.name, + active: workflow.active, + isArchived: workflow.isArchived, + createdAt: workflow.createdAt, + updatedAt: workflow.updatedAt, + tags: workflow.tags || [], + nodeCount: workflow.nodes?.length || 0 + })); + return { + success: true, + data: { + workflows: minimalWorkflows, + returned: minimalWorkflows.length, + nextCursor: response.nextCursor, + hasMore: !!response.nextCursor, + ...(response.nextCursor ? { + _note: "More workflows available. Use cursor to get next page." + } : {}) + } + }; + } + catch (error) { + if (error instanceof zod_1.z.ZodError) { + return { + success: false, + error: 'Invalid input', + details: { errors: error.errors } + }; + } + if (error instanceof n8n_errors_1.N8nApiError) { + return { + success: false, + error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error), + code: error.code + }; + } + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} +async function handleValidateWorkflow(args, repository, context) { + try { + const client = ensureApiConfigured(context); + const input = validateWorkflowSchema.parse(args); + const workflowResponse = await handleGetWorkflow({ id: input.id }); + if (!workflowResponse.success) { + return workflowResponse; + } + const workflow = workflowResponse.data; + const validator = new workflow_validator_1.WorkflowValidator(repository, enhanced_config_validator_1.EnhancedConfigValidator); + const validationResult = await validator.validateWorkflow(workflow, input.options); + const response = { + valid: validationResult.valid, + workflowId: workflow.id, + workflowName: workflow.name, + summary: { + totalNodes: validationResult.statistics.totalNodes, + enabledNodes: validationResult.statistics.enabledNodes, + triggerNodes: validationResult.statistics.triggerNodes, + validConnections: validationResult.statistics.validConnections, + invalidConnections: validationResult.statistics.invalidConnections, + expressionsValidated: validationResult.statistics.expressionsValidated, + errorCount: validationResult.errors.length, + warningCount: validationResult.warnings.length + } + }; + if (validationResult.errors.length > 0) { + response.errors = validationResult.errors.map(e => ({ + node: e.nodeName || 'workflow', + nodeName: e.nodeName, + message: e.message, + details: e.details + })); + } + if (validationResult.warnings.length > 0) { + response.warnings = validationResult.warnings.map(w => ({ + node: w.nodeName || 'workflow', + nodeName: w.nodeName, + message: w.message, + details: w.details + })); + } + if (validationResult.suggestions.length > 0) { + response.suggestions = validationResult.suggestions; + } + if (validationResult.valid) { + telemetry_1.telemetry.trackWorkflowCreation(workflow, true); + } + return { + success: true, + data: response + }; + } + catch (error) { + if (error instanceof zod_1.z.ZodError) { + return { + success: false, + error: 'Invalid input', + details: { errors: error.errors } + }; + } + if (error instanceof n8n_errors_1.N8nApiError) { + return { + success: false, + error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error), + code: error.code + }; + } + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} +async function handleAutofixWorkflow(args, repository, context) { + try { + const client = ensureApiConfigured(context); + const input = autofixWorkflowSchema.parse(args); + const workflowResponse = await handleGetWorkflow({ id: input.id }, context); + if (!workflowResponse.success) { + return workflowResponse; + } + const workflow = workflowResponse.data; + const validator = new workflow_validator_1.WorkflowValidator(repository, enhanced_config_validator_1.EnhancedConfigValidator); + const validationResult = await validator.validateWorkflow(workflow, { + validateNodes: true, + validateConnections: true, + validateExpressions: true, + profile: 'ai-friendly' + }); + const allFormatIssues = []; + for (const node of workflow.nodes) { + const formatContext = { + nodeType: node.type, + nodeName: node.name, + nodeId: node.id + }; + const nodeFormatIssues = expression_format_validator_1.ExpressionFormatValidator.validateNodeParameters(node.parameters, formatContext); + const enrichedIssues = nodeFormatIssues.map(issue => ({ + ...issue, + nodeName: node.name, + nodeId: node.id + })); + allFormatIssues.push(...enrichedIssues); + } + const autoFixer = new workflow_auto_fixer_1.WorkflowAutoFixer(repository); + const fixResult = await autoFixer.generateFixes(workflow, validationResult, allFormatIssues, { + applyFixes: input.applyFixes, + fixTypes: input.fixTypes, + confidenceThreshold: input.confidenceThreshold, + maxFixes: input.maxFixes + }); + if (fixResult.fixes.length === 0) { + return { + success: true, + data: { + workflowId: workflow.id, + workflowName: workflow.name, + message: 'No automatic fixes available for this workflow', + validationSummary: { + errors: validationResult.errors.length, + warnings: validationResult.warnings.length + } + } + }; + } + if (!input.applyFixes) { + return { + success: true, + data: { + workflowId: workflow.id, + workflowName: workflow.name, + preview: true, + fixesAvailable: fixResult.fixes.length, + fixes: fixResult.fixes, + summary: fixResult.summary, + stats: fixResult.stats, + message: `${fixResult.fixes.length} fixes available. Set applyFixes=true to apply them.` + } + }; + } + if (fixResult.operations.length > 0) { + const updateResult = await (0, handlers_workflow_diff_1.handleUpdatePartialWorkflow)({ + id: workflow.id, + operations: fixResult.operations, + createBackup: true + }, repository, context); + if (!updateResult.success) { + return { + success: false, + error: 'Failed to apply fixes', + details: { + fixes: fixResult.fixes, + updateError: updateResult.error + } + }; + } + return { + success: true, + data: { + workflowId: workflow.id, + workflowName: workflow.name, + fixesApplied: fixResult.fixes.length, + fixes: fixResult.fixes, + summary: fixResult.summary, + stats: fixResult.stats, + message: `Successfully applied ${fixResult.fixes.length} fixes to workflow "${workflow.name}"` + } + }; + } + return { + success: true, + data: { + workflowId: workflow.id, + workflowName: workflow.name, + message: 'No fixes needed' + } + }; + } + catch (error) { + if (error instanceof zod_1.z.ZodError) { + return { + success: false, + error: 'Invalid input', + details: { errors: error.errors } + }; + } + if (error instanceof n8n_errors_1.N8nApiError) { + return { + success: false, + error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error), + code: error.code + }; + } + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} +async function handleTestWorkflow(args, context) { + try { + const client = ensureApiConfigured(context); + const input = testWorkflowSchema.parse(args); + const { detectTriggerFromWorkflow, ensureRegistryInitialized, TriggerRegistry, } = await Promise.resolve().then(() => __importStar(require('../triggers'))); + await ensureRegistryInitialized(); + const workflow = await client.getWorkflow(input.workflowId); + let triggerType = input.triggerType; + let triggerInfo; + const detection = detectTriggerFromWorkflow(workflow); + if (!triggerType) { + if (detection.detected && detection.trigger) { + triggerType = detection.trigger.type; + triggerInfo = detection.trigger; + } + else { + return { + success: false, + error: 'Workflow cannot be triggered externally', + details: { + workflowId: input.workflowId, + reason: detection.reason, + hint: 'Only workflows with webhook, form, or chat triggers can be executed via the API. Add one of these trigger nodes to your workflow.', + }, + }; + } + } + else { + if (detection.detected && detection.trigger?.type === triggerType) { + triggerInfo = detection.trigger; + } + else if (!detection.detected || detection.trigger?.type !== triggerType) { + return { + success: false, + error: `Workflow does not have a ${triggerType} trigger`, + details: { + workflowId: input.workflowId, + requestedTrigger: triggerType, + detectedTrigger: detection.trigger?.type || 'none', + hint: detection.detected + ? `Workflow has a ${detection.trigger?.type} trigger. Either use that type or omit triggerType for auto-detection.` + : 'Workflow has no externally-triggerable triggers (webhook, form, or chat).', + }, + }; + } + } + const handler = TriggerRegistry.getHandler(triggerType, client, context); + if (!handler) { + return { + success: false, + error: `No handler registered for trigger type: ${triggerType}`, + details: { + supportedTypes: TriggerRegistry.getRegisteredTypes(), + }, + }; + } + if (handler.capabilities.requiresActiveWorkflow && !workflow.active) { + return { + success: false, + error: 'Workflow must be active to trigger via this method', + details: { + workflowId: input.workflowId, + triggerType, + hint: 'Activate the workflow in n8n using n8n_update_partial_workflow with [{type: "activateWorkflow"}]', + }, + }; + } + if (triggerType === 'chat' && !input.message) { + return { + success: false, + error: 'Chat trigger requires a message parameter', + details: { + hint: 'Provide message="your message" for chat triggers', + }, + }; + } + const triggerInput = { + workflowId: input.workflowId, + triggerType, + httpMethod: input.httpMethod, + webhookPath: input.webhookPath, + message: input.message || '', + sessionId: input.sessionId, + data: input.data, + formData: input.data, + headers: input.headers, + timeout: input.timeout, + waitForResponse: input.waitForResponse, + }; + const response = await handler.execute(triggerInput, workflow, triggerInfo); + return { + success: response.success, + data: response.data, + message: response.success + ? `Workflow triggered successfully via ${triggerType}` + : response.error, + executionId: response.executionId, + workflowId: input.workflowId, + details: { + triggerType, + metadata: response.metadata, + ...(response.details || {}), + }, + }; + } + catch (error) { + if (error instanceof zod_1.z.ZodError) { + return { + success: false, + error: 'Invalid input', + details: { errors: error.errors }, + }; + } + if (error instanceof n8n_errors_1.N8nApiError) { + return { + success: false, + error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error), + code: error.code, + details: error.details, + }; + } + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error occurred', + }; + } +} +async function handleGetExecution(args, context) { + try { + const client = ensureApiConfigured(context); + const schema = zod_1.z.object({ + id: zod_1.z.string(), + mode: zod_1.z.enum(['preview', 'summary', 'filtered', 'full']).optional(), + nodeNames: zod_1.z.array(zod_1.z.string()).optional(), + itemsLimit: zod_1.z.number().optional(), + includeInputData: zod_1.z.boolean().optional(), + includeData: zod_1.z.boolean().optional() + }); + const params = schema.parse(args); + const { id, mode, nodeNames, itemsLimit, includeInputData, includeData } = params; + let effectiveMode = mode; + if (!effectiveMode && includeData !== undefined) { + effectiveMode = includeData ? 'summary' : undefined; + } + const fetchFullData = effectiveMode !== undefined || includeData === true; + const execution = await client.getExecution(id, fetchFullData); + if (!effectiveMode && !nodeNames && itemsLimit === undefined) { + return { + success: true, + data: execution + }; + } + const filterOptions = { + mode: effectiveMode, + nodeNames, + itemsLimit, + includeInputData + }; + const processedExecution = (0, execution_processor_1.processExecution)(execution, filterOptions); + return { + success: true, + data: processedExecution + }; + } + catch (error) { + if (error instanceof zod_1.z.ZodError) { + return { + success: false, + error: 'Invalid input', + details: { errors: error.errors } + }; + } + if (error instanceof n8n_errors_1.N8nApiError) { + return { + success: false, + error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error), + code: error.code + }; + } + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} +async function handleListExecutions(args, context) { + try { + const client = ensureApiConfigured(context); + const input = listExecutionsSchema.parse(args || {}); + const response = await client.listExecutions({ + limit: input.limit || 100, + cursor: input.cursor, + workflowId: input.workflowId, + projectId: input.projectId, + status: input.status, + includeData: input.includeData || false + }); + return { + success: true, + data: { + executions: response.data, + returned: response.data.length, + nextCursor: response.nextCursor, + hasMore: !!response.nextCursor, + ...(response.nextCursor ? { + _note: "More executions available. Use cursor to get next page." + } : {}) + } + }; + } + catch (error) { + if (error instanceof zod_1.z.ZodError) { + return { + success: false, + error: 'Invalid input', + details: { errors: error.errors } + }; + } + if (error instanceof n8n_errors_1.N8nApiError) { + return { + success: false, + error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error), + code: error.code + }; + } + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} +async function handleDeleteExecution(args, context) { + try { + const client = ensureApiConfigured(context); + const { id } = zod_1.z.object({ id: zod_1.z.string() }).parse(args); + await client.deleteExecution(id); + return { + success: true, + message: `Execution ${id} deleted successfully` + }; + } + catch (error) { + if (error instanceof zod_1.z.ZodError) { + return { + success: false, + error: 'Invalid input', + details: { errors: error.errors } + }; + } + if (error instanceof n8n_errors_1.N8nApiError) { + return { + success: false, + error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error), + code: error.code + }; + } + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} +async function handleHealthCheck(context) { + const startTime = Date.now(); + try { + const client = ensureApiConfigured(context); + const health = await client.healthCheck(); + const packageJson = require('../../package.json'); + const mcpVersion = packageJson.version; + const supportedN8nVersion = packageJson.dependencies?.n8n?.replace(/[^0-9.]/g, ''); + const versionCheck = await (0, npm_version_checker_1.checkNpmVersion)(); + const cacheMetricsData = getInstanceCacheMetrics(); + const responseTime = Date.now() - startTime; + const responseData = { + status: health.status, + instanceId: health.instanceId, + n8nVersion: health.n8nVersion, + features: health.features, + apiUrl: (0, n8n_api_1.getN8nApiConfig)()?.baseUrl, + mcpVersion, + supportedN8nVersion, + versionCheck: { + current: versionCheck.currentVersion, + latest: versionCheck.latestVersion, + upToDate: !versionCheck.isOutdated, + message: (0, npm_version_checker_1.formatVersionMessage)(versionCheck), + ...(versionCheck.updateCommand ? { updateCommand: versionCheck.updateCommand } : {}) + }, + performance: { + responseTimeMs: responseTime, + cacheHitRate: (cacheMetricsData.hits + cacheMetricsData.misses) > 0 + ? ((cacheMetricsData.hits / (cacheMetricsData.hits + cacheMetricsData.misses)) * 100).toFixed(2) + '%' + : 'N/A', + cachedInstances: cacheMetricsData.size + } + }; + responseData.nextSteps = [ + '• Create workflow: n8n_create_workflow', + '• List workflows: n8n_list_workflows', + '• Search nodes: search_nodes', + '• Browse templates: search_templates' + ]; + if (versionCheck.isOutdated && versionCheck.latestVersion) { + responseData.updateWarning = `⚠️ n8n-mcp v${versionCheck.latestVersion} is available (you have v${versionCheck.currentVersion}). Update recommended.`; + } + telemetry_1.telemetry.trackEvent('health_check_completed', { + success: true, + responseTimeMs: responseTime, + upToDate: !versionCheck.isOutdated, + apiConnected: true + }); + return { + success: true, + data: responseData + }; + } + catch (error) { + const responseTime = Date.now() - startTime; + telemetry_1.telemetry.trackEvent('health_check_failed', { + success: false, + responseTimeMs: responseTime, + errorType: error instanceof n8n_errors_1.N8nApiError ? error.code : 'unknown' + }); + if (error instanceof n8n_errors_1.N8nApiError) { + return { + success: false, + error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error), + code: error.code, + details: { + apiUrl: (0, n8n_api_1.getN8nApiConfig)()?.baseUrl, + hint: 'Check if n8n is running and API is enabled', + troubleshooting: [ + '1. Verify n8n instance is running', + '2. Check N8N_API_URL is correct', + '3. Verify N8N_API_KEY has proper permissions', + '4. Run n8n_health_check with mode="diagnostic" for detailed analysis' + ] + } + }; + } + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} +function detectCloudPlatform() { + if (process.env.RAILWAY_ENVIRONMENT) + return 'railway'; + if (process.env.RENDER) + return 'render'; + if (process.env.FLY_APP_NAME) + return 'fly'; + if (process.env.HEROKU_APP_NAME) + return 'heroku'; + if (process.env.AWS_EXECUTION_ENV) + return 'aws'; + if (process.env.KUBERNETES_SERVICE_HOST) + return 'kubernetes'; + if (process.env.GOOGLE_CLOUD_PROJECT) + return 'gcp'; + if (process.env.AZURE_FUNCTIONS_ENVIRONMENT) + return 'azure'; + return null; +} +function getModeSpecificDebug(mcpMode) { + if (mcpMode === 'http') { + const port = process.env.MCP_PORT || process.env.PORT || 3000; + return { + mode: 'HTTP Server', + port, + authTokenConfigured: !!(process.env.MCP_AUTH_TOKEN || process.env.AUTH_TOKEN), + corsEnabled: true, + serverUrl: `http://localhost:${port}`, + healthCheckUrl: `http://localhost:${port}/health`, + troubleshooting: [ + `1. Test server health: curl http://localhost:${port}/health`, + '2. Check browser console for CORS errors', + '3. Verify MCP_AUTH_TOKEN or AUTH_TOKEN if authentication enabled', + `4. Ensure port ${port} is not in use: lsof -i :${port} (macOS/Linux) or netstat -ano | findstr :${port} (Windows)`, + '5. Check firewall settings for port access', + '6. Review server logs for connection errors' + ], + commonIssues: [ + 'CORS policy blocking browser requests', + 'Port already in use by another application', + 'Authentication token mismatch', + 'Network firewall blocking connections' + ] + }; + } + else { + const configLocation = process.platform === 'darwin' + ? '~/Library/Application Support/Claude/claude_desktop_config.json' + : process.platform === 'win32' + ? '%APPDATA%\\Claude\\claude_desktop_config.json' + : '~/.config/Claude/claude_desktop_config.json'; + return { + mode: 'Standard I/O (Claude Desktop)', + configLocation, + troubleshooting: [ + '1. Verify Claude Desktop config file exists and is valid JSON', + '2. Check MCP server entry: {"mcpServers": {"n8n": {"command": "npx", "args": ["-y", "n8n-mcp"]}}}', + '3. Restart Claude Desktop after config changes', + '4. Check Claude Desktop logs for startup errors', + '5. Test npx can run: npx -y n8n-mcp --version', + '6. Verify executable permissions if using local installation' + ], + commonIssues: [ + 'Invalid JSON in claude_desktop_config.json', + 'Incorrect command or args in MCP server config', + 'Claude Desktop not restarted after config changes', + 'npx unable to download or run package', + 'Missing execute permissions on local binary' + ] + }; + } +} +function getDockerDebug(isDocker) { + if (!isDocker) + return null; + return { + containerDetected: true, + troubleshooting: [ + '1. Verify volume mounts for data/nodes.db', + '2. Check network connectivity to n8n instance', + '3. Ensure ports are correctly mapped', + '4. Review container logs: docker logs ', + '5. Verify environment variables passed to container', + '6. Check IS_DOCKER=true is set correctly' + ], + commonIssues: [ + 'Volume mount not persisting database', + 'Network isolation preventing n8n API access', + 'Port mapping conflicts', + 'Missing environment variables in container' + ] + }; +} +function getCloudPlatformDebug(cloudPlatform) { + if (!cloudPlatform) + return null; + const platformGuides = { + railway: { + name: 'Railway', + troubleshooting: [ + '1. Check Railway environment variables are set', + '2. Verify deployment logs in Railway dashboard', + '3. Ensure PORT matches Railway assigned port (automatic)', + '4. Check networking configuration for external access' + ] + }, + render: { + name: 'Render', + troubleshooting: [ + '1. Verify Render environment variables', + '2. Check Render logs for startup errors', + '3. Ensure health check endpoint is responding', + '4. Verify instance type has sufficient resources' + ] + }, + fly: { + name: 'Fly.io', + troubleshooting: [ + '1. Check Fly.io logs: flyctl logs', + '2. Verify fly.toml configuration', + '3. Ensure volumes are properly mounted', + '4. Check app status: flyctl status' + ] + }, + heroku: { + name: 'Heroku', + troubleshooting: [ + '1. Check Heroku logs: heroku logs --tail', + '2. Verify Procfile configuration', + '3. Ensure dynos are running: heroku ps', + '4. Check environment variables: heroku config' + ] + }, + kubernetes: { + name: 'Kubernetes', + troubleshooting: [ + '1. Check pod logs: kubectl logs ', + '2. Verify service and ingress configuration', + '3. Check persistent volume claims', + '4. Verify resource limits and requests' + ] + }, + aws: { + name: 'AWS', + troubleshooting: [ + '1. Check CloudWatch logs', + '2. Verify IAM roles and permissions', + '3. Check security groups and networking', + '4. Verify environment variables in service config' + ] + } + }; + return platformGuides[cloudPlatform] || { + name: cloudPlatform.toUpperCase(), + troubleshooting: [ + '1. Check cloud platform logs', + '2. Verify environment variables are set', + '3. Check networking and port configuration', + '4. Review platform-specific documentation' + ] + }; +} +async function handleDiagnostic(request, context) { + const startTime = Date.now(); + const verbose = request.params?.arguments?.verbose || false; + const mcpMode = process.env.MCP_MODE || 'stdio'; + const isDocker = process.env.IS_DOCKER === 'true'; + const cloudPlatform = detectCloudPlatform(); + const envVars = { + N8N_API_URL: process.env.N8N_API_URL || null, + N8N_API_KEY: process.env.N8N_API_KEY ? '***configured***' : null, + NODE_ENV: process.env.NODE_ENV || 'production', + MCP_MODE: mcpMode, + isDocker, + cloudPlatform, + nodeVersion: process.version, + platform: process.platform + }; + const apiConfig = (0, n8n_api_1.getN8nApiConfig)(); + const apiConfigured = apiConfig !== null; + const apiClient = getN8nApiClient(context); + let apiStatus = { + configured: apiConfigured, + connected: false, + error: null, + version: null + }; + if (apiClient) { + try { + const health = await apiClient.healthCheck(); + apiStatus.connected = true; + apiStatus.version = health.n8nVersion || 'unknown'; + } + catch (error) { + apiStatus.error = error instanceof Error ? error.message : 'Unknown error'; + } + } + const documentationTools = 7; + const managementTools = apiConfigured ? 13 : 0; + const totalTools = documentationTools + managementTools; + const versionCheck = await (0, npm_version_checker_1.checkNpmVersion)(); + const cacheMetricsData = getInstanceCacheMetrics(); + const responseTime = Date.now() - startTime; + const diagnostic = { + timestamp: new Date().toISOString(), + environment: envVars, + apiConfiguration: { + configured: apiConfigured, + status: apiStatus, + config: apiConfig ? { + baseUrl: apiConfig.baseUrl, + timeout: apiConfig.timeout, + maxRetries: apiConfig.maxRetries + } : null + }, + versionInfo: { + current: versionCheck.currentVersion, + latest: versionCheck.latestVersion, + upToDate: !versionCheck.isOutdated, + message: (0, npm_version_checker_1.formatVersionMessage)(versionCheck), + ...(versionCheck.updateCommand ? { updateCommand: versionCheck.updateCommand } : {}) + }, + toolsAvailability: { + documentationTools: { + count: documentationTools, + enabled: true, + description: 'Always available - node info, search, validation, etc.' + }, + managementTools: { + count: managementTools, + enabled: apiConfigured, + description: apiConfigured ? + 'Management tools are ENABLED - create, update, execute workflows' : + 'Management tools are DISABLED - configure N8N_API_URL and N8N_API_KEY to enable' + }, + totalAvailable: totalTools + }, + performance: { + diagnosticResponseTimeMs: responseTime, + cacheHitRate: (cacheMetricsData.hits + cacheMetricsData.misses) > 0 + ? ((cacheMetricsData.hits / (cacheMetricsData.hits + cacheMetricsData.misses)) * 100).toFixed(2) + '%' + : 'N/A', + cachedInstances: cacheMetricsData.size + }, + modeSpecificDebug: getModeSpecificDebug(mcpMode) + }; + if (apiConfigured && apiStatus.connected) { + diagnostic.nextSteps = { + message: '✓ API connected! Here\'s what you can do:', + recommended: [ + { + action: 'n8n_list_workflows', + description: 'See your existing workflows', + timing: 'Fast (6 seconds median)' + }, + { + action: 'n8n_create_workflow', + description: 'Create a new workflow', + timing: 'Typically 6-14 minutes to build' + }, + { + action: 'search_nodes', + description: 'Discover available nodes', + timing: 'Fast - explore 500+ nodes' + }, + { + action: 'search_templates', + description: 'Browse pre-built workflows', + timing: 'Find examples quickly' + } + ], + tips: [ + '82% of users start creating workflows after diagnostics - you\'re ready to go!', + 'Most common first action: n8n_update_partial_workflow (managing existing workflows)', + 'Use n8n_validate_workflow before deploying to catch issues early' + ] + }; + } + else if (apiConfigured && !apiStatus.connected) { + diagnostic.troubleshooting = { + issue: '⚠️ API configured but connection failed', + error: apiStatus.error, + steps: [ + '1. Verify n8n instance is running and accessible', + '2. Check N8N_API_URL is correct (currently: ' + apiConfig?.baseUrl + ')', + '3. Test URL in browser: ' + apiConfig?.baseUrl + '/healthz', + '4. Verify N8N_API_KEY has proper permissions', + '5. Check firewall/network settings if using remote n8n', + '6. Try running n8n_health_check again after fixes' + ], + commonIssues: [ + 'Wrong port number in N8N_API_URL', + 'API key doesn\'t have sufficient permissions', + 'n8n instance not running or crashed', + 'Network firewall blocking connection' + ], + documentation: 'https://github.com/czlonkowski/n8n-mcp?tab=readme-ov-file#n8n-management-tools-optional---requires-api-configuration' + }; + } + else { + diagnostic.setupGuide = { + message: 'n8n API not configured. You can still use documentation tools!', + whatYouCanDoNow: { + documentation: [ + { + tool: 'search_nodes', + description: 'Search 500+ n8n nodes', + example: 'search_nodes({query: "slack"})' + }, + { + tool: 'get_node_essentials', + description: 'Get node configuration details', + example: 'get_node_essentials({nodeType: "nodes-base.httpRequest"})' + }, + { + tool: 'search_templates', + description: 'Browse workflow templates', + example: 'search_templates({query: "chatbot"})' + }, + { + tool: 'validate_workflow', + description: 'Validate workflow JSON', + example: 'validate_workflow({workflow: {...}})' + } + ], + note: '14 documentation tools available without API configuration' + }, + whatYouCannotDo: [ + '✗ Create/update workflows in n8n instance', + '✗ List your workflows', + '✗ Execute workflows', + '✗ View execution results' + ], + howToEnable: { + steps: [ + '1. Get your n8n API key: [Your n8n instance]/settings/api', + '2. Set environment variables:', + ' N8N_API_URL=https://your-n8n-instance.com', + ' N8N_API_KEY=your_api_key_here', + '3. Restart the MCP server', + '4. Run n8n_health_check with mode="diagnostic" to verify', + '5. All 19 tools will be available!' + ], + documentation: 'https://github.com/czlonkowski/n8n-mcp?tab=readme-ov-file#n8n-management-tools-optional---requires-api-configuration' + } + }; + } + if (versionCheck.isOutdated && versionCheck.latestVersion) { + diagnostic.updateWarning = { + message: `⚠️ Update available: v${versionCheck.currentVersion} → v${versionCheck.latestVersion}`, + command: versionCheck.updateCommand, + benefits: [ + 'Latest bug fixes and improvements', + 'New features and tools', + 'Better performance and reliability' + ] + }; + } + const dockerDebug = getDockerDebug(isDocker); + if (dockerDebug) { + diagnostic.dockerDebug = dockerDebug; + } + const cloudDebug = getCloudPlatformDebug(cloudPlatform); + if (cloudDebug) { + diagnostic.cloudPlatformDebug = cloudDebug; + } + if (verbose) { + diagnostic.debug = { + processEnv: Object.keys(process.env).filter(key => key.startsWith('N8N_') || key.startsWith('MCP_')), + nodeVersion: process.version, + platform: process.platform, + workingDirectory: process.cwd(), + cacheMetrics: cacheMetricsData + }; + } + telemetry_1.telemetry.trackEvent('diagnostic_completed', { + success: true, + apiConfigured, + apiConnected: apiStatus.connected, + toolsAvailable: totalTools, + responseTimeMs: responseTime, + upToDate: !versionCheck.isOutdated, + verbose + }); + return { + success: true, + data: diagnostic + }; +} +async function handleWorkflowVersions(args, repository, context) { + try { + const input = workflowVersionsSchema.parse(args); + const client = context ? getN8nApiClient(context) : null; + const versioningService = new workflow_versioning_service_1.WorkflowVersioningService(repository, client || undefined); + switch (input.mode) { + case 'list': { + if (!input.workflowId) { + return { + success: false, + error: 'workflowId is required for list mode' + }; + } + const versions = await versioningService.getVersionHistory(input.workflowId, input.limit); + return { + success: true, + data: { + workflowId: input.workflowId, + versions, + count: versions.length, + message: `Found ${versions.length} version(s) for workflow ${input.workflowId}` + } + }; + } + case 'get': { + if (!input.versionId) { + return { + success: false, + error: 'versionId is required for get mode' + }; + } + const version = await versioningService.getVersion(input.versionId); + if (!version) { + return { + success: false, + error: `Version ${input.versionId} not found` + }; + } + return { + success: true, + data: version + }; + } + case 'rollback': { + if (!input.workflowId) { + return { + success: false, + error: 'workflowId is required for rollback mode' + }; + } + if (!client) { + return { + success: false, + error: 'n8n API not configured. Cannot perform rollback without API access.' + }; + } + const result = await versioningService.restoreVersion(input.workflowId, input.versionId, input.validateBefore); + return { + success: result.success, + data: result.success ? result : undefined, + error: result.success ? undefined : result.message, + details: result.success ? undefined : { + validationErrors: result.validationErrors + } + }; + } + case 'delete': { + if (input.deleteAll) { + if (!input.workflowId) { + return { + success: false, + error: 'workflowId is required for deleteAll mode' + }; + } + const result = await versioningService.deleteAllVersions(input.workflowId); + return { + success: true, + data: { + workflowId: input.workflowId, + deleted: result.deleted, + message: result.message + } + }; + } + else { + if (!input.versionId) { + return { + success: false, + error: 'versionId is required for single version delete' + }; + } + const result = await versioningService.deleteVersion(input.versionId); + return { + success: result.success, + data: result.success ? { message: result.message } : undefined, + error: result.success ? undefined : result.message + }; + } + } + case 'prune': { + if (!input.workflowId) { + return { + success: false, + error: 'workflowId is required for prune mode' + }; + } + const result = await versioningService.pruneVersions(input.workflowId, input.maxVersions || 10); + return { + success: true, + data: { + workflowId: input.workflowId, + pruned: result.pruned, + remaining: result.remaining, + message: `Pruned ${result.pruned} old version(s), ${result.remaining} version(s) remaining` + } + }; + } + case 'truncate': { + if (!input.confirmTruncate) { + return { + success: false, + error: 'confirmTruncate must be true to truncate all versions. This action cannot be undone.' + }; + } + const result = await versioningService.truncateAllVersions(true); + return { + success: true, + data: { + deleted: result.deleted, + message: result.message + } + }; + } + default: + return { + success: false, + error: `Unknown mode: ${input.mode}` + }; + } + } + catch (error) { + if (error instanceof zod_1.z.ZodError) { + return { + success: false, + error: 'Invalid input', + details: { errors: error.errors } + }; + } + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} +const deployTemplateSchema = zod_1.z.object({ + templateId: zod_1.z.number().positive().int(), + name: zod_1.z.string().optional(), + autoUpgradeVersions: zod_1.z.boolean().default(true), + autoFix: zod_1.z.boolean().default(true), + stripCredentials: zod_1.z.boolean().default(true) +}); +async function handleDeployTemplate(args, templateService, repository, context) { + try { + const client = ensureApiConfigured(context); + const input = deployTemplateSchema.parse(args); + const template = await templateService.getTemplate(input.templateId, 'full'); + if (!template) { + return { + success: false, + error: `Template ${input.templateId} not found`, + details: { + hint: 'Use search_templates to find available templates', + templateUrl: `https://n8n.io/workflows/${input.templateId}` + } + }; + } + const workflow = JSON.parse(JSON.stringify(template.workflow)); + if (!workflow || !workflow.nodes) { + return { + success: false, + error: 'Template has invalid workflow structure', + details: { templateId: input.templateId } + }; + } + const workflowName = input.name || template.name; + const requiredCredentials = []; + for (const node of workflow.nodes) { + if (node.credentials && typeof node.credentials === 'object') { + for (const [credType] of Object.entries(node.credentials)) { + requiredCredentials.push({ + nodeType: node.type, + nodeName: node.name, + credentialType: credType + }); + } + } + } + if (input.stripCredentials) { + workflow.nodes = workflow.nodes.map((node) => { + const { credentials, ...rest } = node; + return rest; + }); + } + if (input.autoUpgradeVersions) { + const autoFixer = new workflow_auto_fixer_1.WorkflowAutoFixer(repository); + const validator = new workflow_validator_1.WorkflowValidator(repository, enhanced_config_validator_1.EnhancedConfigValidator); + const validationResult = await validator.validateWorkflow(workflow, { + validateNodes: true, + validateConnections: false, + validateExpressions: false, + profile: 'runtime' + }); + const fixResult = await autoFixer.generateFixes(workflow, validationResult, [], { fixTypes: ['typeversion-upgrade', 'typeversion-correction'] }); + if (fixResult.operations.length > 0) { + for (const op of fixResult.operations) { + if (op.type === 'updateNode' && op.updates) { + const node = workflow.nodes.find((n) => n.id === op.nodeId || n.name === op.nodeName); + if (node) { + for (const [path, value] of Object.entries(op.updates)) { + if (path === 'typeVersion') { + node.typeVersion = value; + } + } + } + } + } + } + } + const triggerNode = workflow.nodes.find((n) => n.type?.includes('Trigger') || + n.type?.includes('webhook') || + n.type === 'n8n-nodes-base.webhook'); + const triggerType = triggerNode?.type?.split('.').pop() || 'manual'; + const createdWorkflow = await client.createWorkflow({ + name: workflowName, + nodes: workflow.nodes, + connections: workflow.connections, + settings: workflow.settings || { executionOrder: 'v1' } + }); + const apiConfig = context ? (0, n8n_api_1.getN8nApiConfigFromContext)(context) : (0, n8n_api_1.getN8nApiConfig)(); + const baseUrl = apiConfig?.baseUrl?.replace('/api/v1', '') || ''; + let fixesApplied = []; + let fixSummary = ''; + let autoFixStatus = 'skipped'; + if (input.autoFix) { + try { + const autofixResult = await handleAutofixWorkflow({ + id: createdWorkflow.id, + applyFixes: true, + fixTypes: ['expression-format', 'typeversion-upgrade'], + confidenceThreshold: 'medium' + }, repository, context); + if (autofixResult.success && autofixResult.data) { + const fixData = autofixResult.data; + autoFixStatus = 'success'; + if (fixData.fixesApplied && fixData.fixesApplied > 0) { + fixesApplied = fixData.fixes || []; + fixSummary = ` Auto-fixed ${fixData.fixesApplied} issue(s).`; + } + } + } + catch (fixError) { + autoFixStatus = 'failed'; + logger_1.logger.warn('Auto-fix failed after template deployment', { + workflowId: createdWorkflow.id, + error: fixError instanceof Error ? fixError.message : 'Unknown error' + }); + fixSummary = ' Auto-fix failed (workflow deployed successfully).'; + } + } + return { + success: true, + data: { + workflowId: createdWorkflow.id, + name: createdWorkflow.name, + active: false, + nodeCount: workflow.nodes.length, + triggerType, + requiredCredentials: requiredCredentials.length > 0 ? requiredCredentials : undefined, + url: baseUrl ? `${baseUrl}/workflow/${createdWorkflow.id}` : undefined, + templateId: input.templateId, + templateUrl: template.url || `https://n8n.io/workflows/${input.templateId}`, + autoFixStatus, + fixesApplied: fixesApplied.length > 0 ? fixesApplied : undefined + }, + message: `Workflow "${createdWorkflow.name}" deployed successfully from template ${input.templateId}.${fixSummary} ${requiredCredentials.length > 0 + ? `Configure ${requiredCredentials.length} credential(s) in n8n to activate.` + : ''}` + }; + } + catch (error) { + if (error instanceof zod_1.z.ZodError) { + return { + success: false, + error: 'Invalid input', + details: { errors: error.errors } + }; + } + if (error instanceof n8n_errors_1.N8nApiError) { + return { + success: false, + error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error), + code: error.code, + details: error.details + }; + } + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} +async function handleTriggerWebhookWorkflow(args, context) { + const triggerWebhookSchema = zod_1.z.object({ + webhookUrl: zod_1.z.string().url(), + httpMethod: zod_1.z.enum(['GET', 'POST', 'PUT', 'DELETE']).optional(), + data: zod_1.z.record(zod_1.z.unknown()).optional(), + headers: zod_1.z.record(zod_1.z.string()).optional(), + waitForResponse: zod_1.z.boolean().optional(), + }); + try { + const client = ensureApiConfigured(context); + const input = triggerWebhookSchema.parse(args); + const webhookRequest = { + webhookUrl: input.webhookUrl, + httpMethod: input.httpMethod || 'POST', + data: input.data, + headers: input.headers, + waitForResponse: input.waitForResponse ?? true + }; + const response = await client.triggerWebhook(webhookRequest); + return { + success: true, + data: response, + message: 'Webhook triggered successfully' + }; + } + catch (error) { + if (error instanceof zod_1.z.ZodError) { + return { + success: false, + error: 'Invalid input', + details: { errors: error.errors } + }; + } + if (error instanceof n8n_errors_1.N8nApiError) { + const errorData = error.details; + const executionId = errorData?.executionId || errorData?.id || errorData?.execution?.id; + const workflowId = errorData?.workflowId || errorData?.workflow?.id; + if (executionId) { + return { + success: false, + error: (0, n8n_errors_1.formatExecutionError)(executionId, workflowId), + code: error.code, + executionId, + workflowId: workflowId || undefined + }; + } + if (error.code === 'SERVER_ERROR' || error.statusCode && error.statusCode >= 500) { + return { + success: false, + error: (0, n8n_errors_1.formatNoExecutionError)(), + code: error.code + }; + } + return { + success: false, + error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error), + code: error.code, + details: error.details + }; + } + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} +//# sourceMappingURL=handlers-n8n-manager.js.map \ No newline at end of file diff --git a/dist/mcp/handlers-n8n-manager.js.map b/dist/mcp/handlers-n8n-manager.js.map new file mode 100644 index 0000000..63d8d98 --- /dev/null +++ b/dist/mcp/handlers-n8n-manager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"handlers-n8n-manager.js","sourceRoot":"","sources":["../../src/mcp/handlers-n8n-manager.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0PA,gEAEC;AAMD,0DAEC;AAKD,gDAIC;AAED,0CAgFC;AAqHD,oDA8EC;AAED,8CAiCC;AAED,4DAoDC;AAED,gEAmDC;AAED,4DAyCC;AAED,oDA6HC;AAeD,oDAkCC;AAED,kDAiEC;AAED,wDA8FC;AAED,sDAwKC;AAQD,gDAwJC;AAED,gDA4FC;AAED,oDAgDC;AAED,sDAiCC;AAID,8CAwGC;AAkLD,4CAkQC;AAED,wDA0LC;AA+BD,oDAyMC;AAQD,oEAyEC;AAhkFD,+DAA0D;AAC1D,+CAAgF;AAChF,8CAS0B;AAE1B,+DAIoC;AACpC,oDAM6B;AAC7B,4CAAyC;AACzC,6BAAwB;AACxB,uEAAmE;AACnE,qFAAgF;AAEhF,gEAAqF;AAErF,yEAAmF;AACnF,yFAA2G;AAC3G,yFAAoF;AACpF,qEAAuE;AACvE,4CAAyC;AAEzC,sDAO8B;AAC9B,yEAAmE;AACnE,sEAAqF;AAqKrF,IAAI,gBAAgB,GAAwB,IAAI,CAAC;AACjD,IAAI,oBAAoB,GAAkB,IAAI,CAAC;AAG/C,MAAM,UAAU,GAAG,IAAI,wBAAU,EAAE,CAAC;AAGpC,MAAM,eAAe,GAAG,IAAA,iCAAmB,EAAe,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;IAExE,eAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE;QAC7C,QAAQ,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK;KACtC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AA0BH,SAAgB,0BAA0B;IACxC,OAAO,IAAA,gCAAkB,GAAE,CAAC;AAC9B,CAAC;AAMD,SAAgB,uBAAuB;IACrC,OAAO,0BAAY,CAAC,UAAU,EAAE,CAAC;AACnC,CAAC;AAKD,SAAgB,kBAAkB;IAChC,eAAe,CAAC,KAAK,EAAE,CAAC;IACxB,0BAAY,CAAC,WAAW,EAAE,CAAC;IAC3B,0BAAY,CAAC,UAAU,CAAC,CAAC,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC;AAClD,CAAC;AAED,SAAgB,eAAe,CAAC,OAAyB;IAEvD,IAAI,OAAO,EAAE,SAAS,IAAI,OAAO,EAAE,SAAS,EAAE,CAAC;QAE7C,MAAM,UAAU,GAAG,IAAA,0CAAuB,EAAC,OAAO,CAAC,CAAC;QACpD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YACtB,eAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE;gBAC/C,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,QAAQ,GAAG,IAAA,4BAAc,EAC7B,GAAG,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,UAAU,IAAI,EAAE,EAAE,CACxE,CAAC;QAGF,IAAI,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClC,0BAAY,CAAC,SAAS,EAAE,CAAC;YACzB,OAAO,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC;QAC/C,CAAC;QAED,0BAAY,CAAC,UAAU,EAAE,CAAC;QAG1B,IAAI,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAElC,MAAM,QAAQ,GAAG,GAAG,CAAC;YACrB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACzB,OAAO,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC;YAEtE,CAAC;YAED,IAAI,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAClC,0BAAY,CAAC,SAAS,EAAE,CAAC;gBACzB,OAAO,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC;YAC/C,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,IAAA,oCAA0B,EAAC,OAAO,CAAC,CAAC;QACnD,IAAI,MAAM,EAAE,CAAC;YAEX,eAAM,CAAC,IAAI,CAAC,2CAA2C,EAAE;gBACvD,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,wBAAwB,EAAE,IAAI,CAAC;gBAC3D,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK;aAC3C,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,IAAI,6BAAY,CAAC,MAAM,CAAC,CAAC;YACxC,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACtC,0BAAY,CAAC,SAAS,EAAE,CAAC;YACzB,0BAAY,CAAC,UAAU,CAAC,eAAe,CAAC,IAAI,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC;YACnE,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAGD,eAAM,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;IAC5E,MAAM,MAAM,GAAG,IAAA,yBAAe,GAAE,CAAC;IAEjC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,IAAI,gBAAgB,EAAE,CAAC;YACrB,eAAM,CAAC,IAAI,CAAC,wDAAwD,CAAC,CAAC;YACtE,gBAAgB,GAAG,IAAI,CAAC;YACxB,oBAAoB,GAAG,IAAI,CAAC;QAC9B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAGD,IAAI,CAAC,gBAAgB,IAAI,oBAAoB,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC;QACjE,eAAM,CAAC,IAAI,CAAC,6CAA6C,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QACpF,gBAAgB,GAAG,IAAI,6BAAY,CAAC,MAAM,CAAC,CAAC;QAC5C,oBAAoB,GAAG,MAAM,CAAC,OAAO,CAAC;IACxC,CAAC;IAED,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAQD,SAAS,mBAAmB,CAAC,OAAyB;IACpD,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,IAAI,OAAO,EAAE,UAAU,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,uCAAuC,OAAO,CAAC,UAAU,mEAAmE,CAAC,CAAC;QAChJ,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,uFAAuF,CAAC,CAAC;IAC3G,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAGD,MAAM,oBAAoB,GAAG,OAAC,CAAC,MAAM,CAAC;IACpC,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;IAChB,KAAK,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,GAAG,EAAE,CAAC;IACvB,WAAW,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,GAAG,EAAE,CAAC;IAC9B,QAAQ,EAAE,OAAC,CAAC,MAAM,CAAC;QACjB,cAAc,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE;QAC/C,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC/B,sBAAsB,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;QAC1D,wBAAwB,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;QAC5D,oBAAoB,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;QAC5C,qBAAqB,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;QAC7C,gBAAgB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACvC,aAAa,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KACrC,CAAC,CAAC,QAAQ,EAAE;CACd,CAAC,CAAC;AAEH,MAAM,oBAAoB,GAAG,OAAC,CAAC,MAAM,CAAC;IACpC,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,KAAK,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE;IAClC,WAAW,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE;IACzC,QAAQ,EAAE,OAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC5B,YAAY,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACpC,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC9B,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAAG,OAAC,CAAC,MAAM,CAAC;IACnC,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IAC5C,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,MAAM,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC9B,IAAI,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACpC,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,iBAAiB,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC;AAEH,MAAM,sBAAsB,GAAG,OAAC,CAAC,MAAM,CAAC;IACtC,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE;IACd,OAAO,EAAE,OAAC,CAAC,MAAM,CAAC;QAChB,aAAa,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;QACrC,mBAAmB,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;QAC3C,mBAAmB,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;QAC3C,OAAO,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE;KAC5E,CAAC,CAAC,QAAQ,EAAE;CACd,CAAC,CAAC;AAEH,MAAM,qBAAqB,GAAG,OAAC,CAAC,MAAM,CAAC;IACrC,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE;IACd,UAAU,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACjD,QAAQ,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,IAAI,CAAC;QACvB,mBAAmB;QACnB,wBAAwB;QACxB,qBAAqB;QACrB,sBAAsB;QACtB,sBAAsB;QACtB,qBAAqB;QACrB,mBAAmB;KACpB,CAAC,CAAC,CAAC,QAAQ,EAAE;IACd,mBAAmB,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC;IACnF,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;CAC5C,CAAC,CAAC;AAGH,MAAM,kBAAkB,GAAG,OAAC,CAAC,MAAM,CAAC;IAClC,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE;IACtB,WAAW,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC3D,UAAU,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC/D,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,IAAI,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;IACtC,OAAO,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACxC,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,eAAe,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACxC,CAAC,CAAC;AAEH,MAAM,oBAAoB,GAAG,OAAC,CAAC,MAAM,CAAC;IACpC,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IAC5C,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,MAAM,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC1D,WAAW,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACpC,CAAC,CAAC;AAEH,MAAM,sBAAsB,GAAG,OAAC,CAAC,MAAM,CAAC;IACtC,IAAI,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IACxE,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;IACxC,cAAc,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;IACpD,SAAS,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE;IAChD,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC9C,eAAe,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE;CACvD,CAAC,CAAC;AAII,KAAK,UAAU,oBAAoB,CAAC,IAAa,EAAE,OAAyB;IACjF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAG/C,MAAM,eAAe,GAAa,EAAE,CAAC;QACrC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,IAAS,EAAE,KAAa,EAAE,EAAE;YAChD,IAAI,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBACtF,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;oBAClD,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,iBAAiB,CAAC;oBACrD,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,2BAA2B,CAAC,CAAC;gBACvE,eAAe,CAAC,IAAI,CAClB,QAAQ,KAAK,MAAM,IAAI,CAAC,IAAI,uBAAuB,IAAI,CAAC,IAAI,KAAK;oBACjE,8CAA8C,QAAQ,GAAG,CAC1D,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,qBAAS,CAAC,qBAAqB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAC9C,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,+DAA+D;gBACtE,OAAO,EAAE;oBACP,MAAM,EAAE,eAAe;oBACvB,IAAI,EAAE,iEAAiE;iBACxE;aACF,CAAC;QACJ,CAAC;QAGD,MAAM,MAAM,GAAG,IAAA,0CAAyB,EAAC,KAAK,CAAC,CAAC;QAChD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAEtB,qBAAS,CAAC,qBAAqB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAE9C,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,4BAA4B;gBACnC,OAAO,EAAE,EAAE,MAAM,EAAE;aACpB,CAAC;QACJ,CAAC;QAGD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAGpD,qBAAS,CAAC,qBAAqB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAEhD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,aAAa,QAAQ,CAAC,IAAI,mCAAmC,QAAQ,CAAC,EAAE,EAAE;SACpF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;aAClC,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,YAAY,wBAAW,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAA,wCAA2B,EAAC,KAAK,CAAC;gBACzC,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,KAAK,CAAC,OAA8C;aAC9D,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,iBAAiB,CAAC,IAAa,EAAE,OAAyB;IAC9E,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,EAAE,EAAE,EAAE,GAAG,OAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAExD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAE9C,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,QAAQ;SACf,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;aAClC,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,YAAY,wBAAW,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAA,wCAA2B,EAAC,KAAK,CAAC;gBACzC,IAAI,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,wBAAwB,CAAC,IAAa,EAAE,OAAyB;IACrF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,EAAE,EAAE,EAAE,GAAG,OAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAExD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAG9C,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC;YAC7C,UAAU,EAAE,EAAE;YACd,KAAK,EAAE,EAAE;SACV,CAAC,CAAC;QAGH,MAAM,KAAK,GAAG;YACZ,eAAe,EAAE,UAAU,CAAC,IAAI,CAAC,MAAM;YACvC,YAAY,EAAE,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,yBAAe,CAAC,OAAO,CAAC,CAAC,MAAM;YACtF,UAAU,EAAE,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,yBAAe,CAAC,KAAK,CAAC,CAAC,MAAM;YAClF,iBAAiB,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,IAAI,IAAI;SACzD,CAAC;QAEF,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACJ,QAAQ;gBACR,cAAc,EAAE,KAAK;gBACrB,iBAAiB,EAAE,IAAA,kCAAiB,EAAC,QAAQ,CAAC;gBAC9C,WAAW,EAAE,IAAA,8BAAa,EAAC,QAAQ,CAAC;aACrC;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;aAClC,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,YAAY,wBAAW,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAA,wCAA2B,EAAC,KAAK,CAAC;gBACzC,IAAI,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,0BAA0B,CAAC,IAAa,EAAE,OAAyB;IACvF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,EAAE,EAAE,EAAE,GAAG,OAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAExD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAG9C,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAClD,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,KAAK;SACjC,CAAC,CAAC,CAAC;QAEJ,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACJ,EAAE,EAAE,QAAQ,CAAC,EAAE;gBACf,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;gBAC/B,KAAK,EAAE,eAAe;gBACtB,WAAW,EAAE,QAAQ,CAAC,WAAW;gBACjC,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM;gBAChC,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,MAAM;aAC1D;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;aAClC,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,YAAY,wBAAW,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAA,wCAA2B,EAAC,KAAK,CAAC;gBACzC,IAAI,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,wBAAwB,CAAC,IAAa,EAAE,OAAyB;IACrF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,EAAE,EAAE,EAAE,GAAG,OAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAExD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAE9C,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACJ,EAAE,EAAE,QAAQ,CAAC,EAAE;gBACf,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;gBAC/B,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,EAAE;gBACzB,SAAS,EAAE,QAAQ,CAAC,SAAS;gBAC7B,SAAS,EAAE,QAAQ,CAAC,SAAS;aAC9B;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;aAClC,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,YAAY,wBAAW,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAA,wCAA2B,EAAC,KAAK,CAAC;gBACzC,IAAI,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,oBAAoB,CACxC,IAAa,EACb,UAA0B,EAC1B,OAAyB;IAEzB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,SAAS,GAAG,YAAY,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;IACtF,IAAI,cAAc,GAAQ,IAAI,CAAC;IAC/B,IAAI,UAAU,GAAG,sBAAsB,CAAC;IAExC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,EAAE,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,GAAG,KAAK,CAAC;QAC1D,UAAU,GAAG,MAAM,IAAI,sBAAsB,CAAC;QAG9C,IAAI,UAAU,CAAC,KAAK,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;YAE/C,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YAC7C,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;YAGrD,IAAI,YAAY,KAAK,KAAK,EAAE,CAAC;gBAC3B,IAAI,CAAC;oBACH,MAAM,iBAAiB,GAAG,IAAI,uDAAyB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;oBAC5E,MAAM,YAAY,GAAG,MAAM,iBAAiB,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,EAAE;wBACrE,OAAO,EAAE,aAAa;qBACvB,CAAC,CAAC;oBAEH,eAAM,CAAC,IAAI,CAAC,yBAAyB,EAAE;wBACrC,UAAU,EAAE,EAAE;wBACd,SAAS,EAAE,YAAY,CAAC,SAAS;wBACjC,aAAa,EAAE,YAAY,CAAC,aAAa;wBACzC,MAAM,EAAE,YAAY,CAAC,MAAM;qBAC5B,CAAC,CAAC;gBACL,CAAC;gBAAC,OAAO,KAAU,EAAE,CAAC;oBACpB,eAAM,CAAC,IAAI,CAAC,kCAAkC,EAAE;wBAC9C,UAAU,EAAE,EAAE;wBACd,KAAK,EAAE,KAAK,CAAC,OAAO;qBACrB,CAAC,CAAC;gBAEL,CAAC;YACH,CAAC;YAED,MAAM,YAAY,GAAG;gBACnB,GAAG,OAAO;gBACV,GAAG,UAAU;aACd,CAAC;YAGF,MAAM,MAAM,GAAG,IAAA,0CAAyB,EAAC,YAAY,CAAC,CAAC;YACvD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,4BAA4B;oBACnC,OAAO,EAAE,EAAE,MAAM,EAAE;iBACpB,CAAC;YACJ,CAAC;QACH,CAAC;QAGD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QAG7D,IAAI,cAAc,EAAE,CAAC;YACnB,kCAAkC,CAAC;gBACjC,SAAS;gBACT,QAAQ,EAAE,0BAA0B;gBACpC,UAAU;gBACV,UAAU,EAAE,EAAE;gBACd,cAAc;gBACd,aAAa,EAAE,QAAQ;gBACvB,eAAe,EAAE,IAAI;gBACrB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;aACnC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;gBACb,eAAM,CAAC,IAAI,CAAC,qCAAqC,EAAE,GAAG,CAAC,CAAC;YAC1D,CAAC,CAAC,CAAC;QACL,CAAC;QAED,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,aAAa,QAAQ,CAAC,IAAI,wBAAwB;SAC5D,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAEf,IAAI,cAAc,EAAE,CAAC;YACnB,kCAAkC,CAAC;gBACjC,SAAS;gBACT,QAAQ,EAAE,0BAA0B;gBACpC,UAAU;gBACV,UAAU,EAAE,EAAE;gBACd,cAAc;gBACd,aAAa,EAAE,cAAc;gBAC7B,eAAe,EAAE,KAAK;gBACtB,aAAa,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;gBACvE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;aACnC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;gBACb,eAAM,CAAC,IAAI,CAAC,0DAA0D,EAAE,GAAG,CAAC,CAAC;YAC/E,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;aAClC,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,YAAY,wBAAW,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAA,wCAA2B,EAAC,KAAK,CAAC;gBACzC,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,KAAK,CAAC,OAA8C;aAC9D,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAKD,KAAK,UAAU,kCAAkC,CAAC,IAAS;IACzD,IAAI,CAAC;QACH,MAAM,EAAE,SAAS,EAAE,GAAG,wDAAa,mCAAmC,GAAC,CAAC;QACxE,MAAM,SAAS,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAEf,eAAM,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;IACpD,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,oBAAoB,CAAC,IAAa,EAAE,OAAyB;IACjF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,EAAE,EAAE,EAAE,GAAG,OAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAExD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QAEhD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,YAAY,EAAE,uBAAuB;SAC/C,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;aAClC,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,YAAY,wBAAW,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAA,wCAA2B,EAAC,KAAK,CAAC;gBACzC,IAAI,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,mBAAmB,CAAC,IAAa,EAAE,OAAyB;IAChF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAGpD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;YACnD,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;YACtB,CAAC,CAAC,SAAS,CAAC;QAEd,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC;YAC1C,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,GAAG;YACzB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,IAAI,EAAE,SAAgB;YACtB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,IAAI,IAAI;SACnD,CAAC,CAAC;QAGH,MAAM,gBAAgB,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACtD,EAAE,EAAE,QAAQ,CAAC,EAAE;YACf,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,EAAE;YACzB,SAAS,EAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;SACvC,CAAC,CAAC,CAAC;QAEJ,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACJ,SAAS,EAAE,gBAAgB;gBAC3B,QAAQ,EAAE,gBAAgB,CAAC,MAAM;gBACjC,UAAU,EAAE,QAAQ,CAAC,UAAU;gBAC/B,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,UAAU;gBAC9B,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;oBACxB,KAAK,EAAE,wDAAwD;iBAChE,CAAC,CAAC,CAAC,EAAE,CAAC;aACR;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;aAClC,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,YAAY,wBAAW,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAA,wCAA2B,EAAC,KAAK,CAAC;gBACzC,IAAI,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,sBAAsB,CAC1C,IAAa,EACb,UAA0B,EAC1B,OAAyB;IAEzB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAGjD,MAAM,gBAAgB,GAAG,MAAM,iBAAiB,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QAEnE,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;YAC9B,OAAO,gBAAgB,CAAC;QAC1B,CAAC;QAED,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAgB,CAAC;QAGnD,MAAM,SAAS,GAAG,IAAI,sCAAiB,CAAC,UAAU,EAAE,mDAAuB,CAAC,CAAC;QAG7E,MAAM,gBAAgB,GAAG,MAAM,SAAS,CAAC,gBAAgB,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAGnF,MAAM,QAAQ,GAA+B;YAC3C,KAAK,EAAE,gBAAgB,CAAC,KAAK;YAC7B,UAAU,EAAE,QAAQ,CAAC,EAAE;YACvB,YAAY,EAAE,QAAQ,CAAC,IAAI;YAC3B,OAAO,EAAE;gBACP,UAAU,EAAE,gBAAgB,CAAC,UAAU,CAAC,UAAU;gBAClD,YAAY,EAAE,gBAAgB,CAAC,UAAU,CAAC,YAAY;gBACtD,YAAY,EAAE,gBAAgB,CAAC,UAAU,CAAC,YAAY;gBACtD,gBAAgB,EAAE,gBAAgB,CAAC,UAAU,CAAC,gBAAgB;gBAC9D,kBAAkB,EAAE,gBAAgB,CAAC,UAAU,CAAC,kBAAkB;gBAClE,oBAAoB,EAAE,gBAAgB,CAAC,UAAU,CAAC,oBAAoB;gBACtE,UAAU,EAAE,gBAAgB,CAAC,MAAM,CAAC,MAAM;gBAC1C,YAAY,EAAE,gBAAgB,CAAC,QAAQ,CAAC,MAAM;aAC/C;SACF,CAAC;QAEF,IAAI,gBAAgB,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvC,QAAQ,CAAC,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAClD,IAAI,EAAE,CAAC,CAAC,QAAQ,IAAI,UAAU;gBAC9B,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,OAAO,EAAE,CAAC,CAAC,OAAO;gBAClB,OAAO,EAAE,CAAC,CAAC,OAAO;aACnB,CAAC,CAAC,CAAC;QACN,CAAC;QAED,IAAI,gBAAgB,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzC,QAAQ,CAAC,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACtD,IAAI,EAAE,CAAC,CAAC,QAAQ,IAAI,UAAU;gBAC9B,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,OAAO,EAAE,CAAC,CAAC,OAAO;gBAClB,OAAO,EAAE,CAAC,CAAC,OAAO;aACnB,CAAC,CAAC,CAAC;QACN,CAAC;QAED,IAAI,gBAAgB,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,QAAQ,CAAC,WAAW,GAAG,gBAAgB,CAAC,WAAW,CAAC;QACtD,CAAC;QAGD,IAAI,gBAAgB,CAAC,KAAK,EAAE,CAAC;YAC3B,qBAAS,CAAC,qBAAqB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC;QAED,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,QAAQ;SACf,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;aAClC,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,YAAY,wBAAW,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAA,wCAA2B,EAAC,KAAK,CAAC;gBACzC,IAAI,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,qBAAqB,CACzC,IAAa,EACb,UAA0B,EAC1B,OAAyB;IAEzB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,qBAAqB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAGhD,MAAM,gBAAgB,GAAG,MAAM,iBAAiB,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;QAE5E,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;YAC9B,OAAO,gBAAgB,CAAC;QAC1B,CAAC;QAED,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAgB,CAAC;QAGnD,MAAM,SAAS,GAAG,IAAI,sCAAiB,CAAC,UAAU,EAAE,mDAAuB,CAAC,CAAC;QAG7E,MAAM,gBAAgB,GAAG,MAAM,SAAS,CAAC,gBAAgB,CAAC,QAAQ,EAAE;YAClE,aAAa,EAAE,IAAI;YACnB,mBAAmB,EAAE,IAAI;YACzB,mBAAmB,EAAE,IAAI;YACzB,OAAO,EAAE,aAAa;SACvB,CAAC,CAAC;QAGH,MAAM,eAAe,GAA4B,EAAE,CAAC;QACpD,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YAClC,MAAM,aAAa,GAAG;gBACpB,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,MAAM,EAAE,IAAI,CAAC,EAAE;aAChB,CAAC;YAEF,MAAM,gBAAgB,GAAG,uDAAyB,CAAC,sBAAsB,CACvE,IAAI,CAAC,UAAU,EACf,aAAa,CACd,CAAC;YAGF,MAAM,cAAc,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACpD,GAAG,KAAK;gBACR,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,MAAM,EAAE,IAAI,CAAC,EAAE;aAChB,CAAC,CAAC,CAAC;YAEJ,eAAe,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC;QAC1C,CAAC;QAGD,MAAM,SAAS,GAAG,IAAI,uCAAiB,CAAC,UAAU,CAAC,CAAC;QACpD,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,aAAa,CAC7C,QAAQ,EACR,gBAAgB,EAChB,eAAe,EACf;YACE,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,mBAAmB,EAAE,KAAK,CAAC,mBAAmB;YAC9C,QAAQ,EAAE,KAAK,CAAC,QAAQ;SACzB,CACF,CAAC;QAGF,IAAI,SAAS,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE;oBACJ,UAAU,EAAE,QAAQ,CAAC,EAAE;oBACvB,YAAY,EAAE,QAAQ,CAAC,IAAI;oBAC3B,OAAO,EAAE,gDAAgD;oBACzD,iBAAiB,EAAE;wBACjB,MAAM,EAAE,gBAAgB,CAAC,MAAM,CAAC,MAAM;wBACtC,QAAQ,EAAE,gBAAgB,CAAC,QAAQ,CAAC,MAAM;qBAC3C;iBACF;aACF,CAAC;QACJ,CAAC;QAGD,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;YACtB,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE;oBACJ,UAAU,EAAE,QAAQ,CAAC,EAAE;oBACvB,YAAY,EAAE,QAAQ,CAAC,IAAI;oBAC3B,OAAO,EAAE,IAAI;oBACb,cAAc,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM;oBACtC,KAAK,EAAE,SAAS,CAAC,KAAK;oBACtB,OAAO,EAAE,SAAS,CAAC,OAAO;oBAC1B,KAAK,EAAE,SAAS,CAAC,KAAK;oBACtB,OAAO,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM,sDAAsD;iBACzF;aACF,CAAC;QACJ,CAAC;QAGD,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpC,MAAM,YAAY,GAAG,MAAM,IAAA,oDAA2B,EACpD;gBACE,EAAE,EAAE,QAAQ,CAAC,EAAE;gBACf,UAAU,EAAE,SAAS,CAAC,UAAU;gBAChC,YAAY,EAAE,IAAI;aACnB,EACD,UAAU,EACV,OAAO,CACR,CAAC;YAEF,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;gBAC1B,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,uBAAuB;oBAC9B,OAAO,EAAE;wBACP,KAAK,EAAE,SAAS,CAAC,KAAK;wBACtB,WAAW,EAAE,YAAY,CAAC,KAAK;qBAChC;iBACF,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE;oBACJ,UAAU,EAAE,QAAQ,CAAC,EAAE;oBACvB,YAAY,EAAE,QAAQ,CAAC,IAAI;oBAC3B,YAAY,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM;oBACpC,KAAK,EAAE,SAAS,CAAC,KAAK;oBACtB,OAAO,EAAE,SAAS,CAAC,OAAO;oBAC1B,KAAK,EAAE,SAAS,CAAC,KAAK;oBACtB,OAAO,EAAE,wBAAwB,SAAS,CAAC,KAAK,CAAC,MAAM,uBAAuB,QAAQ,CAAC,IAAI,GAAG;iBAC/F;aACF,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACJ,UAAU,EAAE,QAAQ,CAAC,EAAE;gBACvB,YAAY,EAAE,QAAQ,CAAC,IAAI;gBAC3B,OAAO,EAAE,iBAAiB;aAC3B;SACF,CAAC;IAEJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;aAClC,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,YAAY,wBAAW,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAA,wCAA2B,EAAC,KAAK,CAAC;gBACzC,IAAI,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAQM,KAAK,UAAU,kBAAkB,CAAC,IAAa,EAAE,OAAyB;IAC/E,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAG7C,MAAM,EACJ,yBAAyB,EACzB,yBAAyB,EACzB,eAAe,GAChB,GAAG,wDAAa,aAAa,GAAC,CAAC;QAGhC,MAAM,yBAAyB,EAAE,CAAC;QAGlC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAG5D,IAAI,WAAW,GAA4B,KAAK,CAAC,WAAsC,CAAC;QACxF,IAAI,WAAW,CAAC;QAGhB,MAAM,SAAS,GAAG,yBAAyB,CAAC,QAAQ,CAAC,CAAC;QAEtD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,IAAI,SAAS,CAAC,QAAQ,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;gBAC5C,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC;gBACrC,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC;YAClC,CAAC;iBAAM,CAAC;gBAEN,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,yCAAyC;oBAChD,OAAO,EAAE;wBACP,UAAU,EAAE,KAAK,CAAC,UAAU;wBAC5B,MAAM,EAAE,SAAS,CAAC,MAAM;wBACxB,IAAI,EAAE,mIAAmI;qBAC1I;iBACF,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,CAAC;YAEN,IAAI,SAAS,CAAC,QAAQ,IAAI,SAAS,CAAC,OAAO,EAAE,IAAI,KAAK,WAAW,EAAE,CAAC;gBAClE,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC;YAClC,CAAC;iBAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,IAAI,SAAS,CAAC,OAAO,EAAE,IAAI,KAAK,WAAW,EAAE,CAAC;gBAC1E,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,4BAA4B,WAAW,UAAU;oBACxD,OAAO,EAAE;wBACP,UAAU,EAAE,KAAK,CAAC,UAAU;wBAC5B,gBAAgB,EAAE,WAAW;wBAC7B,eAAe,EAAE,SAAS,CAAC,OAAO,EAAE,IAAI,IAAI,MAAM;wBAClD,IAAI,EAAE,SAAS,CAAC,QAAQ;4BACtB,CAAC,CAAC,kBAAkB,SAAS,CAAC,OAAO,EAAE,IAAI,wEAAwE;4BACnH,CAAC,CAAC,2EAA2E;qBAChF;iBACF,CAAC;YACJ,CAAC;QACH,CAAC;QAGD,MAAM,OAAO,GAAG,eAAe,CAAC,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QACzE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,2CAA2C,WAAW,EAAE;gBAC/D,OAAO,EAAE;oBACP,cAAc,EAAE,eAAe,CAAC,kBAAkB,EAAE;iBACrD;aACF,CAAC;QACJ,CAAC;QAGD,IAAI,OAAO,CAAC,YAAY,CAAC,sBAAsB,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACpE,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,oDAAoD;gBAC3D,OAAO,EAAE;oBACP,UAAU,EAAE,KAAK,CAAC,UAAU;oBAC5B,WAAW;oBACX,IAAI,EAAE,kGAAkG;iBACzG;aACF,CAAC;QACJ,CAAC;QAGD,IAAI,WAAW,KAAK,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YAC7C,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,2CAA2C;gBAClD,OAAO,EAAE;oBACP,IAAI,EAAE,kDAAkD;iBACzD;aACF,CAAC;QACJ,CAAC;QAGD,MAAM,YAAY,GAAG;YACnB,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,WAAW;YACX,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE;YAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,QAAQ,EAAE,KAAK,CAAC,IAAI;YACpB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,eAAe,EAAE,KAAK,CAAC,eAAe;SACvC,CAAC;QAGF,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,YAAmB,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAEnF,OAAO;YACL,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,OAAO,EAAE,QAAQ,CAAC,OAAO;gBACvB,CAAC,CAAC,uCAAuC,WAAW,EAAE;gBACtD,CAAC,CAAC,QAAQ,CAAC,KAAK;YAClB,WAAW,EAAE,QAAQ,CAAC,WAAW;YACjC,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,OAAO,EAAE;gBACP,WAAW;gBACX,QAAQ,EAAE,QAAQ,CAAC,QAAQ;gBAC3B,GAAG,CAAC,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC;aAC5B;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;aAClC,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,YAAY,wBAAW,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAA,wCAA2B,EAAC,KAAK,CAAC;gBACzC,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,KAAK,CAAC,OAA8C;aAC9D,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,kBAAkB,CAAC,IAAa,EAAE,OAAyB;IAC/E,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAG5C,MAAM,MAAM,GAAG,OAAC,CAAC,MAAM,CAAC;YACtB,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE;YAEd,IAAI,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;YACnE,SAAS,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;YACzC,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACjC,gBAAgB,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;YAExC,WAAW,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;SACpC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,gBAAgB,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;QAkBlF,IAAI,aAAa,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,aAAa,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAChD,aAAa,GAAG,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QACtD,CAAC;QAKD,MAAM,aAAa,GAAG,aAAa,KAAK,SAAS,IAAI,WAAW,KAAK,IAAI,CAAC;QAG1E,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;QAG/D,IAAI,CAAC,aAAa,IAAI,CAAC,SAAS,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7D,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,SAAS;aAChB,CAAC;QACJ,CAAC;QAGD,MAAM,aAAa,GAA2B;YAC5C,IAAI,EAAE,aAAa;YACnB,SAAS;YACT,UAAU;YACV,gBAAgB;SACjB,CAAC;QAEF,MAAM,kBAAkB,GAAG,IAAA,sCAAgB,EAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QAEtE,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,kBAAkB;SACzB,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;aAClC,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,YAAY,wBAAW,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAA,wCAA2B,EAAC,KAAK,CAAC;gBACzC,IAAI,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,oBAAoB,CAAC,IAAa,EAAE,OAAyB;IACjF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,oBAAoB,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAErD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC;YAC3C,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,GAAG;YACzB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,MAAM,EAAE,KAAK,CAAC,MAAqC;YACnD,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,KAAK;SACxC,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACJ,UAAU,EAAE,QAAQ,CAAC,IAAI;gBACzB,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM;gBAC9B,UAAU,EAAE,QAAQ,CAAC,UAAU;gBAC/B,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,UAAU;gBAC9B,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;oBACxB,KAAK,EAAE,yDAAyD;iBACjE,CAAC,CAAC,CAAC,EAAE,CAAC;aACR;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;aAClC,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,YAAY,wBAAW,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAA,wCAA2B,EAAC,KAAK,CAAC;gBACzC,IAAI,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,qBAAqB,CAAC,IAAa,EAAE,OAAyB;IAClF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,EAAE,EAAE,EAAE,GAAG,OAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAExD,MAAM,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;QAEjC,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,aAAa,EAAE,uBAAuB;SAChD,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;aAClC,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,YAAY,wBAAW,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAA,wCAA2B,EAAC,KAAK,CAAC;gBACzC,IAAI,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAIM,KAAK,UAAU,iBAAiB,CAAC,OAAyB;IAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;QAG1C,MAAM,WAAW,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAClD,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC;QACvC,MAAM,mBAAmB,GAAG,WAAW,CAAC,YAAY,EAAE,GAAG,EAAE,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAGnF,MAAM,YAAY,GAAG,MAAM,IAAA,qCAAe,GAAE,CAAC;QAG7C,MAAM,gBAAgB,GAAG,uBAAuB,EAAE,CAAC;QAGnD,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAG5C,MAAM,YAAY,GAA4B;YAC5C,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,MAAM,EAAE,IAAA,yBAAe,GAAE,EAAE,OAAO;YAClC,UAAU;YACV,mBAAmB;YACnB,YAAY,EAAE;gBACZ,OAAO,EAAE,YAAY,CAAC,cAAc;gBACpC,MAAM,EAAE,YAAY,CAAC,aAAa;gBAClC,QAAQ,EAAE,CAAC,YAAY,CAAC,UAAU;gBAClC,OAAO,EAAE,IAAA,0CAAoB,EAAC,YAAY,CAAC;gBAC3C,GAAG,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,YAAY,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACrF;YACD,WAAW,EAAE;gBACX,cAAc,EAAE,YAAY;gBAC5B,YAAY,EAAE,CAAC,gBAAgB,CAAC,IAAI,GAAG,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC;oBACjE,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,gBAAgB,CAAC,IAAI,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG;oBACtG,CAAC,CAAC,KAAK;gBACT,eAAe,EAAE,gBAAgB,CAAC,IAAI;aACvC;SACF,CAAC;QAGF,YAAY,CAAC,SAAS,GAAG;YACvB,wCAAwC;YACxC,sCAAsC;YACtC,8BAA8B;YAC9B,sCAAsC;SACvC,CAAC;QAGF,IAAI,YAAY,CAAC,UAAU,IAAI,YAAY,CAAC,aAAa,EAAE,CAAC;YAC1D,YAAY,CAAC,aAAa,GAAG,gBAAgB,YAAY,CAAC,aAAa,4BAA4B,YAAY,CAAC,cAAc,wBAAwB,CAAC;QACzJ,CAAC;QAGD,qBAAS,CAAC,UAAU,CAAC,wBAAwB,EAAE;YAC7C,OAAO,EAAE,IAAI;YACb,cAAc,EAAE,YAAY;YAC5B,QAAQ,EAAE,CAAC,YAAY,CAAC,UAAU;YAClC,YAAY,EAAE,IAAI;SACnB,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,YAAY;SACnB,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAG5C,qBAAS,CAAC,UAAU,CAAC,qBAAqB,EAAE;YAC1C,OAAO,EAAE,KAAK;YACd,cAAc,EAAE,YAAY;YAC5B,SAAS,EAAE,KAAK,YAAY,wBAAW,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;SACjE,CAAC,CAAC;QAEH,IAAI,KAAK,YAAY,wBAAW,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAA,wCAA2B,EAAC,KAAK,CAAC;gBACzC,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE;oBACP,MAAM,EAAE,IAAA,yBAAe,GAAE,EAAE,OAAO;oBAClC,IAAI,EAAE,4CAA4C;oBAClD,eAAe,EAAE;wBACf,mCAAmC;wBACnC,iCAAiC;wBACjC,8CAA8C;wBAC9C,sEAAsE;qBACvE;iBACF;aACF,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAQD,SAAS,mBAAmB;IAC1B,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB;QAAE,OAAO,SAAS,CAAC;IACtD,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM;QAAE,OAAO,QAAQ,CAAC;IACxC,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY;QAAE,OAAO,KAAK,CAAC;IAC3C,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe;QAAE,OAAO,QAAQ,CAAC;IACjD,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAAE,OAAO,KAAK,CAAC;IAChD,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB;QAAE,OAAO,YAAY,CAAC;IAC7D,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB;QAAE,OAAO,KAAK,CAAC;IACnD,IAAI,OAAO,CAAC,GAAG,CAAC,2BAA2B;QAAE,OAAO,OAAO,CAAC;IAC5D,OAAO,IAAI,CAAC;AACd,CAAC;AAKD,SAAS,oBAAoB,CAAC,OAAe;IAC3C,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC;QAC9D,OAAO;YACL,IAAI,EAAE,aAAa;YACnB,IAAI;YACJ,mBAAmB,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;YAC7E,WAAW,EAAE,IAAI;YACjB,SAAS,EAAE,oBAAoB,IAAI,EAAE;YACrC,cAAc,EAAE,oBAAoB,IAAI,SAAS;YACjD,eAAe,EAAE;gBACf,gDAAgD,IAAI,SAAS;gBAC7D,0CAA0C;gBAC1C,kEAAkE;gBAClE,kBAAkB,IAAI,4BAA4B,IAAI,6CAA6C,IAAI,YAAY;gBACnH,4CAA4C;gBAC5C,6CAA6C;aAC9C;YACD,YAAY,EAAE;gBACZ,uCAAuC;gBACvC,4CAA4C;gBAC5C,+BAA+B;gBAC/B,uCAAuC;aACxC;SACF,CAAC;IACJ,CAAC;SAAM,CAAC;QAEN,MAAM,cAAc,GAAG,OAAO,CAAC,QAAQ,KAAK,QAAQ;YAClD,CAAC,CAAC,iEAAiE;YACnE,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO;gBAC9B,CAAC,CAAC,+CAA+C;gBACjD,CAAC,CAAC,6CAA6C,CAAC;QAElD,OAAO;YACL,IAAI,EAAE,+BAA+B;YACrC,cAAc;YACd,eAAe,EAAE;gBACf,+DAA+D;gBAC/D,mGAAmG;gBACnG,gDAAgD;gBAChD,iDAAiD;gBACjD,+CAA+C;gBAC/C,8DAA8D;aAC/D;YACD,YAAY,EAAE;gBACZ,4CAA4C;gBAC5C,gDAAgD;gBAChD,mDAAmD;gBACnD,uCAAuC;gBACvC,6CAA6C;aAC9C;SACF,CAAC;IACJ,CAAC;AACH,CAAC;AAKD,SAAS,cAAc,CAAC,QAAiB;IACvC,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE3B,OAAO;QACL,iBAAiB,EAAE,IAAI;QACvB,eAAe,EAAE;YACf,2CAA2C;YAC3C,+CAA+C;YAC/C,sCAAsC;YACtC,wDAAwD;YACxD,qDAAqD;YACrD,0CAA0C;SAC3C;QACD,YAAY,EAAE;YACZ,sCAAsC;YACtC,6CAA6C;YAC7C,wBAAwB;YACxB,4CAA4C;SAC7C;KACF,CAAC;AACJ,CAAC;AAKD,SAAS,qBAAqB,CAAC,aAA4B;IACzD,IAAI,CAAC,aAAa;QAAE,OAAO,IAAI,CAAC;IAEhC,MAAM,cAAc,GAAuC;QACzD,OAAO,EAAE;YACP,IAAI,EAAE,SAAS;YACf,eAAe,EAAE;gBACf,gDAAgD;gBAChD,gDAAgD;gBAChD,0DAA0D;gBAC1D,uDAAuD;aACxD;SACF;QACD,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,eAAe,EAAE;gBACf,wCAAwC;gBACxC,yCAAyC;gBACzC,+CAA+C;gBAC/C,kDAAkD;aACnD;SACF;QACD,GAAG,EAAE;YACH,IAAI,EAAE,QAAQ;YACd,eAAe,EAAE;gBACf,mCAAmC;gBACnC,kCAAkC;gBAClC,wCAAwC;gBACxC,oCAAoC;aACrC;SACF;QACD,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,eAAe,EAAE;gBACf,0CAA0C;gBAC1C,kCAAkC;gBAClC,wCAAwC;gBACxC,+CAA+C;aAChD;SACF;QACD,UAAU,EAAE;YACV,IAAI,EAAE,YAAY;YAClB,eAAe,EAAE;gBACf,4CAA4C;gBAC5C,6CAA6C;gBAC7C,mCAAmC;gBACnC,wCAAwC;aACzC;SACF;QACD,GAAG,EAAE;YACH,IAAI,EAAE,KAAK;YACX,eAAe,EAAE;gBACf,0BAA0B;gBAC1B,qCAAqC;gBACrC,yCAAyC;gBACzC,mDAAmD;aACpD;SACF;KACF,CAAC;IAEF,OAAO,cAAc,CAAC,aAAa,CAAC,IAAI;QACtC,IAAI,EAAE,aAAa,CAAC,WAAW,EAAE;QACjC,eAAe,EAAE;YACf,8BAA8B;YAC9B,yCAAyC;YACzC,4CAA4C;YAC5C,2CAA2C;SAC5C;KACF,CAAC;AACJ,CAAC;AAGM,KAAK,UAAU,gBAAgB,CAAC,OAAY,EAAE,OAAyB;IAC5E,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,IAAI,KAAK,CAAC;IAG5D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC;IAChD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,MAAM,CAAC;IAClD,MAAM,aAAa,GAAG,mBAAmB,EAAE,CAAC;IAG5C,MAAM,OAAO,GAAG;QACd,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI;QAC5C,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI;QAChE,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,YAAY;QAC9C,QAAQ,EAAE,OAAO;QACjB,QAAQ;QACR,aAAa;QACb,WAAW,EAAE,OAAO,CAAC,OAAO;QAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC;IAGF,MAAM,SAAS,GAAG,IAAA,yBAAe,GAAE,CAAC;IACpC,MAAM,aAAa,GAAG,SAAS,KAAK,IAAI,CAAC;IACzC,MAAM,SAAS,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IAG3C,IAAI,SAAS,GAAG;QACd,UAAU,EAAE,aAAa;QACzB,SAAS,EAAE,KAAK;QAChB,KAAK,EAAE,IAAqB;QAC5B,OAAO,EAAE,IAAqB;KAC/B,CAAC;IAEF,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,WAAW,EAAE,CAAC;YAC7C,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC;YAC3B,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC,UAAU,IAAI,SAAS,CAAC;QACrD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,CAAC,KAAK,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QAC7E,CAAC;IACH,CAAC;IAGD,MAAM,kBAAkB,GAAG,CAAC,CAAC;IAC7B,MAAM,eAAe,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,kBAAkB,GAAG,eAAe,CAAC;IAGxD,MAAM,YAAY,GAAG,MAAM,IAAA,qCAAe,GAAE,CAAC;IAG7C,MAAM,gBAAgB,GAAG,uBAAuB,EAAE,CAAC;IACnD,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IAG5C,MAAM,UAAU,GAA2B;QACzC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,WAAW,EAAE,OAAO;QACpB,gBAAgB,EAAE;YAChB,UAAU,EAAE,aAAa;YACzB,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;gBAClB,OAAO,EAAE,SAAS,CAAC,OAAO;gBAC1B,OAAO,EAAE,SAAS,CAAC,OAAO;gBAC1B,UAAU,EAAE,SAAS,CAAC,UAAU;aACjC,CAAC,CAAC,CAAC,IAAI;SACT;QACD,WAAW,EAAE;YACX,OAAO,EAAE,YAAY,CAAC,cAAc;YACpC,MAAM,EAAE,YAAY,CAAC,aAAa;YAClC,QAAQ,EAAE,CAAC,YAAY,CAAC,UAAU;YAClC,OAAO,EAAE,IAAA,0CAAoB,EAAC,YAAY,CAAC;YAC3C,GAAG,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,YAAY,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrF;QACD,iBAAiB,EAAE;YACjB,kBAAkB,EAAE;gBAClB,KAAK,EAAE,kBAAkB;gBACzB,OAAO,EAAE,IAAI;gBACb,WAAW,EAAE,wDAAwD;aACtE;YACD,eAAe,EAAE;gBACf,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,aAAa;gBACtB,WAAW,EAAE,aAAa,CAAC,CAAC;oBAC1B,kEAAkE,CAAC,CAAC;oBACpE,iFAAiF;aACpF;YACD,cAAc,EAAE,UAAU;SAC3B;QACD,WAAW,EAAE;YACX,wBAAwB,EAAE,YAAY;YACtC,YAAY,EAAE,CAAC,gBAAgB,CAAC,IAAI,GAAG,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC;gBACjE,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,gBAAgB,CAAC,IAAI,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG;gBACtG,CAAC,CAAC,KAAK;YACT,eAAe,EAAE,gBAAgB,CAAC,IAAI;SACvC;QACD,iBAAiB,EAAE,oBAAoB,CAAC,OAAO,CAAC;KACjD,CAAC;IAGF,IAAI,aAAa,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;QAEzC,UAAU,CAAC,SAAS,GAAG;YACrB,OAAO,EAAE,2CAA2C;YACpD,WAAW,EAAE;gBACX;oBACE,MAAM,EAAE,oBAAoB;oBAC5B,WAAW,EAAE,6BAA6B;oBAC1C,MAAM,EAAE,yBAAyB;iBAClC;gBACD;oBACE,MAAM,EAAE,qBAAqB;oBAC7B,WAAW,EAAE,uBAAuB;oBACpC,MAAM,EAAE,iCAAiC;iBAC1C;gBACD;oBACE,MAAM,EAAE,cAAc;oBACtB,WAAW,EAAE,0BAA0B;oBACvC,MAAM,EAAE,2BAA2B;iBACpC;gBACD;oBACE,MAAM,EAAE,kBAAkB;oBAC1B,WAAW,EAAE,4BAA4B;oBACzC,MAAM,EAAE,uBAAuB;iBAChC;aACF;YACD,IAAI,EAAE;gBACJ,gFAAgF;gBAChF,qFAAqF;gBACrF,kEAAkE;aACnE;SACF,CAAC;IACJ,CAAC;SAAM,IAAI,aAAa,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;QAEjD,UAAU,CAAC,eAAe,GAAG;YAC3B,KAAK,EAAE,yCAAyC;YAChD,KAAK,EAAE,SAAS,CAAC,KAAK;YACtB,KAAK,EAAE;gBACL,kDAAkD;gBAClD,8CAA8C,GAAG,SAAS,EAAE,OAAO,GAAG,GAAG;gBACzE,0BAA0B,GAAG,SAAS,EAAE,OAAO,GAAG,UAAU;gBAC5D,8CAA8C;gBAC9C,wDAAwD;gBACxD,mDAAmD;aACpD;YACD,YAAY,EAAE;gBACZ,kCAAkC;gBAClC,8CAA8C;gBAC9C,qCAAqC;gBACrC,sCAAsC;aACvC;YACD,aAAa,EAAE,sHAAsH;SACtI,CAAC;IACJ,CAAC;SAAM,CAAC;QAEN,UAAU,CAAC,UAAU,GAAG;YACtB,OAAO,EAAE,gEAAgE;YACzE,eAAe,EAAE;gBACf,aAAa,EAAE;oBACb;wBACE,IAAI,EAAE,cAAc;wBACpB,WAAW,EAAE,uBAAuB;wBACpC,OAAO,EAAE,gCAAgC;qBAC1C;oBACD;wBACE,IAAI,EAAE,qBAAqB;wBAC3B,WAAW,EAAE,gCAAgC;wBAC7C,OAAO,EAAE,2DAA2D;qBACrE;oBACD;wBACE,IAAI,EAAE,kBAAkB;wBACxB,WAAW,EAAE,2BAA2B;wBACxC,OAAO,EAAE,sCAAsC;qBAChD;oBACD;wBACE,IAAI,EAAE,mBAAmB;wBACzB,WAAW,EAAE,wBAAwB;wBACrC,OAAO,EAAE,sCAAsC;qBAChD;iBACF;gBACD,IAAI,EAAE,4DAA4D;aACnE;YACD,eAAe,EAAE;gBACf,2CAA2C;gBAC3C,uBAAuB;gBACvB,qBAAqB;gBACrB,0BAA0B;aAC3B;YACD,WAAW,EAAE;gBACX,KAAK,EAAE;oBACL,2DAA2D;oBAC3D,+BAA+B;oBAC/B,8CAA8C;oBAC9C,kCAAkC;oBAClC,2BAA2B;oBAC3B,0DAA0D;oBAC1D,oCAAoC;iBACrC;gBACD,aAAa,EAAE,sHAAsH;aACtI;SACF,CAAC;IACJ,CAAC;IAGD,IAAI,YAAY,CAAC,UAAU,IAAI,YAAY,CAAC,aAAa,EAAE,CAAC;QAC1D,UAAU,CAAC,aAAa,GAAG;YACzB,OAAO,EAAE,yBAAyB,YAAY,CAAC,cAAc,OAAO,YAAY,CAAC,aAAa,EAAE;YAChG,OAAO,EAAE,YAAY,CAAC,aAAa;YACnC,QAAQ,EAAE;gBACR,mCAAmC;gBACnC,wBAAwB;gBACxB,oCAAoC;aACrC;SACF,CAAC;IACJ,CAAC;IAGD,MAAM,WAAW,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC7C,IAAI,WAAW,EAAE,CAAC;QAChB,UAAU,CAAC,WAAW,GAAG,WAAW,CAAC;IACvC,CAAC;IAGD,MAAM,UAAU,GAAG,qBAAqB,CAAC,aAAa,CAAC,CAAC;IACxD,IAAI,UAAU,EAAE,CAAC;QACf,UAAU,CAAC,kBAAkB,GAAG,UAAU,CAAC;IAC7C,CAAC;IAGD,IAAI,OAAO,EAAE,CAAC;QACZ,UAAU,CAAC,KAAK,GAAG;YACjB,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAChD,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CACjD;YACD,WAAW,EAAE,OAAO,CAAC,OAAO;YAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,gBAAgB,EAAE,OAAO,CAAC,GAAG,EAAE;YAC/B,YAAY,EAAE,gBAAgB;SAC/B,CAAC;IACJ,CAAC;IAGD,qBAAS,CAAC,UAAU,CAAC,sBAAsB,EAAE;QAC3C,OAAO,EAAE,IAAI;QACb,aAAa;QACb,YAAY,EAAE,SAAS,CAAC,SAAS;QACjC,cAAc,EAAE,UAAU;QAC1B,cAAc,EAAE,YAAY;QAC5B,QAAQ,EAAE,CAAC,YAAY,CAAC,UAAU;QAClC,OAAO;KACR,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,UAAU;KACjB,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,sBAAsB,CAC1C,IAAa,EACb,UAA0B,EAC1B,OAAyB;IAEzB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACzD,MAAM,iBAAiB,GAAG,IAAI,uDAAyB,CAAC,UAAU,EAAE,MAAM,IAAI,SAAS,CAAC,CAAC;QAEzF,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;oBACtB,OAAO;wBACL,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,sCAAsC;qBAC9C,CAAC;gBACJ,CAAC;gBAED,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,iBAAiB,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;gBAE1F,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,IAAI,EAAE;wBACJ,UAAU,EAAE,KAAK,CAAC,UAAU;wBAC5B,QAAQ;wBACR,KAAK,EAAE,QAAQ,CAAC,MAAM;wBACtB,OAAO,EAAE,SAAS,QAAQ,CAAC,MAAM,4BAA4B,KAAK,CAAC,UAAU,EAAE;qBAChF;iBACF,CAAC;YACJ,CAAC;YAED,KAAK,KAAK,CAAC,CAAC,CAAC;gBACX,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;oBACrB,OAAO;wBACL,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,oCAAoC;qBAC5C,CAAC;gBACJ,CAAC;gBAED,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;gBAEpE,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO;wBACL,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,WAAW,KAAK,CAAC,SAAS,YAAY;qBAC9C,CAAC;gBACJ,CAAC;gBAED,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,IAAI,EAAE,OAAO;iBACd,CAAC;YACJ,CAAC;YAED,KAAK,UAAU,CAAC,CAAC,CAAC;gBAChB,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;oBACtB,OAAO;wBACL,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,0CAA0C;qBAClD,CAAC;gBACJ,CAAC;gBAED,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,OAAO;wBACL,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,qEAAqE;qBAC7E,CAAC;gBACJ,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,cAAc,CACnD,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,cAAc,CACrB,CAAC;gBAEF,OAAO;oBACL,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;oBACzC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO;oBAClD,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;wBACpC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;qBAC1C;iBACF,CAAC;YACJ,CAAC;YAED,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;oBACpB,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;wBACtB,OAAO;4BACL,OAAO,EAAE,KAAK;4BACd,KAAK,EAAE,2CAA2C;yBACnD,CAAC;oBACJ,CAAC;oBAED,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,iBAAiB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;oBAE3E,OAAO;wBACL,OAAO,EAAE,IAAI;wBACb,IAAI,EAAE;4BACJ,UAAU,EAAE,KAAK,CAAC,UAAU;4BAC5B,OAAO,EAAE,MAAM,CAAC,OAAO;4BACvB,OAAO,EAAE,MAAM,CAAC,OAAO;yBACxB;qBACF,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;wBACrB,OAAO;4BACL,OAAO,EAAE,KAAK;4BACd,KAAK,EAAE,iDAAiD;yBACzD,CAAC;oBACJ,CAAC;oBAED,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;oBAEtE,OAAO;wBACL,OAAO,EAAE,MAAM,CAAC,OAAO;wBACvB,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS;wBAC9D,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO;qBACnD,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;oBACtB,OAAO;wBACL,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,uCAAuC;qBAC/C,CAAC;gBACJ,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,aAAa,CAClD,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,WAAW,IAAI,EAAE,CACxB,CAAC;gBAEF,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,IAAI,EAAE;wBACJ,UAAU,EAAE,KAAK,CAAC,UAAU;wBAC5B,MAAM,EAAE,MAAM,CAAC,MAAM;wBACrB,SAAS,EAAE,MAAM,CAAC,SAAS;wBAC3B,OAAO,EAAE,UAAU,MAAM,CAAC,MAAM,oBAAoB,MAAM,CAAC,SAAS,uBAAuB;qBAC5F;iBACF,CAAC;YACJ,CAAC;YAED,KAAK,UAAU,CAAC,CAAC,CAAC;gBAChB,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;oBAC3B,OAAO;wBACL,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,sFAAsF;qBAC9F,CAAC;gBACJ,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;gBAEjE,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,IAAI,EAAE;wBACJ,OAAO,EAAE,MAAM,CAAC,OAAO;wBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;qBACxB;iBACF,CAAC;YACJ,CAAC;YAED;gBACE,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,iBAAiB,KAAK,CAAC,IAAI,EAAE;iBACrC,CAAC;QACN,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;aAClC,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAMD,MAAM,oBAAoB,GAAG,OAAC,CAAC,MAAM,CAAC;IACpC,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE;IACvC,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,mBAAmB,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC9C,OAAO,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAClC,gBAAgB,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;CAC5C,CAAC,CAAC;AAmBI,KAAK,UAAU,oBAAoB,CACxC,IAAa,EACb,eAAgC,EAChC,UAA0B,EAC1B,OAAyB;IAEzB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAG/C,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC7E,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,YAAY,KAAK,CAAC,UAAU,YAAY;gBAC/C,OAAO,EAAE;oBACP,IAAI,EAAE,kDAAkD;oBACxD,WAAW,EAAE,4BAA4B,KAAK,CAAC,UAAU,EAAE;iBAC5D;aACF,CAAC;QACJ,CAAC;QAGD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC/D,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,yCAAyC;gBAChD,OAAO,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE;aAC1C,CAAC;QACJ,CAAC;QAGD,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC;QAGjD,MAAM,mBAAmB,GAAyB,EAAE,CAAC;QACrD,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,WAAW,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;gBAC7D,KAAK,MAAM,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;oBAC1D,mBAAmB,CAAC,IAAI,CAAC;wBACvB,QAAQ,EAAE,IAAI,CAAC,IAAI;wBACnB,QAAQ,EAAE,IAAI,CAAC,IAAI;wBACnB,cAAc,EAAE,QAAQ;qBACzB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAGD,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;YAC3B,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAS,EAAE,EAAE;gBAChD,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;gBACtC,OAAO,IAAI,CAAC;YACd,CAAC,CAAC,CAAC;QACL,CAAC;QAGD,IAAI,KAAK,CAAC,mBAAmB,EAAE,CAAC;YAC9B,MAAM,SAAS,GAAG,IAAI,uCAAiB,CAAC,UAAU,CAAC,CAAC;YAGpD,MAAM,SAAS,GAAG,IAAI,sCAAiB,CAAC,UAAU,EAAE,mDAAuB,CAAC,CAAC;YAC7E,MAAM,gBAAgB,GAAG,MAAM,SAAS,CAAC,gBAAgB,CAAC,QAAQ,EAAE;gBAClE,aAAa,EAAE,IAAI;gBACnB,mBAAmB,EAAE,KAAK;gBAC1B,mBAAmB,EAAE,KAAK;gBAC1B,OAAO,EAAE,SAAS;aACnB,CAAC,CAAC;YAGH,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,aAAa,CAC7C,QAAQ,EACR,gBAAgB,EAChB,EAAE,EACF,EAAE,QAAQ,EAAE,CAAC,qBAAqB,EAAE,wBAAwB,CAAC,EAAE,CAChE,CAAC;YAGF,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpC,KAAK,MAAM,EAAE,IAAI,SAAS,CAAC,UAAU,EAAE,CAAC;oBACtC,IAAI,EAAE,CAAC,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;wBAC3C,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAC1C,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,QAAQ,CAC7C,CAAC;wBACF,IAAI,IAAI,EAAE,CAAC;4BACT,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;gCACvD,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;oCAC3B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;gCAC3B,CAAC;4BACH,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAGD,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CACjD,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAC;YAC3B,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAC;YAC3B,CAAC,CAAC,IAAI,KAAK,wBAAwB,CACpC,CAAC;QACF,MAAM,WAAW,GAAG,WAAW,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,QAAQ,CAAC;QAIpE,MAAM,eAAe,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC;YAClD,IAAI,EAAE,YAAY;YAClB,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,WAAW,EAAE,QAAQ,CAAC,WAAW;YACjC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE;SACxD,CAAC,CAAC;QAGH,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,IAAA,oCAA0B,EAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAA,yBAAe,GAAE,CAAC;QACpF,MAAM,OAAO,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;QAGjE,IAAI,YAAY,GAAiB,EAAE,CAAC;QACpC,IAAI,UAAU,GAAG,EAAE,CAAC;QACpB,IAAI,aAAa,GAAqC,SAAS,CAAC;QAEhE,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC;gBAEH,MAAM,aAAa,GAAG,MAAM,qBAAqB,CAC/C;oBACE,EAAE,EAAE,eAAe,CAAC,EAAE;oBACtB,UAAU,EAAE,IAAI;oBAChB,QAAQ,EAAE,CAAC,mBAAmB,EAAE,qBAAqB,CAAC;oBACtD,mBAAmB,EAAE,QAAQ;iBAC9B,EACD,UAAU,EACV,OAAO,CACR,CAAC;gBAEF,IAAI,aAAa,CAAC,OAAO,IAAI,aAAa,CAAC,IAAI,EAAE,CAAC;oBAChD,MAAM,OAAO,GAAG,aAAa,CAAC,IAAyB,CAAC;oBACxD,aAAa,GAAG,SAAS,CAAC;oBAC1B,IAAI,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC;wBACrD,YAAY,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;wBACnC,UAAU,GAAG,eAAe,OAAO,CAAC,YAAY,YAAY,CAAC;oBAC/D,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,QAAQ,EAAE,CAAC;gBAElB,aAAa,GAAG,QAAQ,CAAC;gBACzB,eAAM,CAAC,IAAI,CAAC,2CAA2C,EAAE;oBACvD,UAAU,EAAE,eAAe,CAAC,EAAE;oBAC9B,KAAK,EAAE,QAAQ,YAAY,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;iBACtE,CAAC,CAAC;gBACH,UAAU,GAAG,oDAAoD,CAAC;YACpE,CAAC;QACH,CAAC;QAED,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACJ,UAAU,EAAE,eAAe,CAAC,EAAE;gBAC9B,IAAI,EAAE,eAAe,CAAC,IAAI;gBAC1B,MAAM,EAAE,KAAK;gBACb,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM;gBAChC,WAAW;gBACX,mBAAmB,EAAE,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,SAAS;gBACrF,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,aAAa,eAAe,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS;gBACtE,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,WAAW,EAAE,QAAQ,CAAC,GAAG,IAAI,4BAA4B,KAAK,CAAC,UAAU,EAAE;gBAC3E,aAAa;gBACb,YAAY,EAAE,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;aACjE;YACD,OAAO,EAAE,aAAa,eAAe,CAAC,IAAI,yCAAyC,KAAK,CAAC,UAAU,IAAI,UAAU,IAC/G,mBAAmB,CAAC,MAAM,GAAG,CAAC;gBAC5B,CAAC,CAAC,aAAa,mBAAmB,CAAC,MAAM,oCAAoC;gBAC7E,CAAC,CAAC,EACN,EAAE;SACH,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;aAClC,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,YAAY,wBAAW,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAA,wCAA2B,EAAC,KAAK,CAAC;gBACzC,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,KAAK,CAAC,OAA8C;aAC9D,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAQM,KAAK,UAAU,4BAA4B,CAAC,IAAa,EAAE,OAAyB;IACzF,MAAM,oBAAoB,GAAG,OAAC,CAAC,MAAM,CAAC;QACpC,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;QAC5B,UAAU,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE;QAC/D,IAAI,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;QACtC,OAAO,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;QACxC,eAAe,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;KACxC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE/C,MAAM,cAAc,GAAmB;YACrC,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,MAAM;YACtC,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,eAAe,EAAE,KAAK,CAAC,eAAe,IAAI,IAAI;SAC/C,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;QAE7D,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,gCAAgC;SAC1C,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;aAClC,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,YAAY,wBAAW,EAAE,CAAC;YACjC,MAAM,SAAS,GAAG,KAAK,CAAC,OAAc,CAAC;YACvC,MAAM,WAAW,GAAG,SAAS,EAAE,WAAW,IAAI,SAAS,EAAE,EAAE,IAAI,SAAS,EAAE,SAAS,EAAE,EAAE,CAAC;YACxF,MAAM,UAAU,GAAG,SAAS,EAAE,UAAU,IAAI,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC;YAEpE,IAAI,WAAW,EAAE,CAAC;gBAChB,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,IAAA,iCAAoB,EAAC,WAAW,EAAE,UAAU,CAAC;oBACpD,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,WAAW;oBACX,UAAU,EAAE,UAAU,IAAI,SAAS;iBACpC,CAAC;YACJ,CAAC;YAED,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,IAAI,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,IAAI,GAAG,EAAE,CAAC;gBACjF,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,IAAA,mCAAsB,GAAE;oBAC/B,IAAI,EAAE,KAAK,CAAC,IAAI;iBACjB,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAA,wCAA2B,EAAC,KAAK,CAAC;gBACzC,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,KAAK,CAAC,OAA8C;aAC9D,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC"} \ No newline at end of file diff --git a/dist/mcp/handlers-workflow-diff.d.ts b/dist/mcp/handlers-workflow-diff.d.ts new file mode 100644 index 0000000..8f99268 --- /dev/null +++ b/dist/mcp/handlers-workflow-diff.d.ts @@ -0,0 +1,5 @@ +import { McpToolResponse } from '../types/n8n-api'; +import { InstanceContext } from '../types/instance-context'; +import { NodeRepository } from '../database/node-repository'; +export declare function handleUpdatePartialWorkflow(args: unknown, repository: NodeRepository, context?: InstanceContext): Promise; +//# sourceMappingURL=handlers-workflow-diff.d.ts.map \ No newline at end of file diff --git a/dist/mcp/handlers-workflow-diff.d.ts.map b/dist/mcp/handlers-workflow-diff.d.ts.map new file mode 100644 index 0000000..232fc53 --- /dev/null +++ b/dist/mcp/handlers-workflow-diff.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"handlers-workflow-diff.d.ts","sourceRoot":"","sources":["../../src/mcp/handlers-workflow-diff.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAMnD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AA0D7D,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,cAAc,EAC1B,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,eAAe,CAAC,CA2V1B"} \ No newline at end of file diff --git a/dist/mcp/handlers-workflow-diff.js b/dist/mcp/handlers-workflow-diff.js new file mode 100644 index 0000000..504f5bd --- /dev/null +++ b/dist/mcp/handlers-workflow-diff.js @@ -0,0 +1,459 @@ +"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.handleUpdatePartialWorkflow = handleUpdatePartialWorkflow; +const zod_1 = require("zod"); +const workflow_diff_engine_1 = require("../services/workflow-diff-engine"); +const handlers_n8n_manager_1 = require("./handlers-n8n-manager"); +const n8n_errors_1 = require("../utils/n8n-errors"); +const logger_1 = require("../utils/logger"); +const n8n_validation_1 = require("../services/n8n-validation"); +const workflow_versioning_service_1 = require("../services/workflow-versioning-service"); +const workflow_validator_1 = require("../services/workflow-validator"); +const enhanced_config_validator_1 = require("../services/enhanced-config-validator"); +let cachedValidator = null; +function getValidator(repository) { + if (!cachedValidator) { + cachedValidator = new workflow_validator_1.WorkflowValidator(repository, enhanced_config_validator_1.EnhancedConfigValidator); + } + return cachedValidator; +} +const workflowDiffSchema = zod_1.z.object({ + id: zod_1.z.string(), + operations: zod_1.z.array(zod_1.z.object({ + type: zod_1.z.string(), + description: zod_1.z.string().optional(), + node: zod_1.z.any().optional(), + nodeId: zod_1.z.string().optional(), + nodeName: zod_1.z.string().optional(), + updates: zod_1.z.any().optional(), + position: zod_1.z.tuple([zod_1.z.number(), zod_1.z.number()]).optional(), + source: zod_1.z.string().optional(), + target: zod_1.z.string().optional(), + from: zod_1.z.string().optional(), + to: zod_1.z.string().optional(), + sourceOutput: zod_1.z.string().optional(), + targetInput: zod_1.z.string().optional(), + sourceIndex: zod_1.z.number().optional(), + targetIndex: zod_1.z.number().optional(), + branch: zod_1.z.enum(['true', 'false']).optional(), + case: zod_1.z.number().optional(), + ignoreErrors: zod_1.z.boolean().optional(), + dryRun: zod_1.z.boolean().optional(), + connections: zod_1.z.any().optional(), + settings: zod_1.z.any().optional(), + name: zod_1.z.string().optional(), + tag: zod_1.z.string().optional(), + })), + validateOnly: zod_1.z.boolean().optional(), + continueOnError: zod_1.z.boolean().optional(), + createBackup: zod_1.z.boolean().optional(), + intent: zod_1.z.string().optional(), +}); +async function handleUpdatePartialWorkflow(args, repository, context) { + const startTime = Date.now(); + const sessionId = `mutation_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`; + let workflowBefore = null; + let validationBefore = null; + let validationAfter = null; + try { + if (process.env.DEBUG_MCP === 'true') { + logger_1.logger.debug('Workflow diff request received', { + argsType: typeof args, + hasWorkflowId: args && typeof args === 'object' && 'workflowId' in args, + operationCount: args && typeof args === 'object' && 'operations' in args ? + args.operations?.length : 0 + }); + } + const input = workflowDiffSchema.parse(args); + const client = (0, handlers_n8n_manager_1.getN8nApiClient)(context); + if (!client) { + return { + success: false, + error: 'n8n API not configured. Please set N8N_API_URL and N8N_API_KEY environment variables.' + }; + } + let workflow; + try { + workflow = await client.getWorkflow(input.id); + workflowBefore = JSON.parse(JSON.stringify(workflow)); + try { + const validator = getValidator(repository); + validationBefore = await validator.validateWorkflow(workflowBefore, { + validateNodes: true, + validateConnections: true, + validateExpressions: true, + profile: 'runtime' + }); + } + catch (validationError) { + logger_1.logger.debug('Pre-mutation validation failed (non-blocking):', validationError); + validationBefore = { + valid: false, + errors: [{ type: 'validation_error', message: 'Validation failed' }] + }; + } + } + catch (error) { + if (error instanceof n8n_errors_1.N8nApiError) { + return { + success: false, + error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error), + code: error.code + }; + } + throw error; + } + if (input.createBackup !== false && !input.validateOnly) { + try { + const versioningService = new workflow_versioning_service_1.WorkflowVersioningService(repository, client); + const backupResult = await versioningService.createBackup(input.id, workflow, { + trigger: 'partial_update', + operations: input.operations + }); + logger_1.logger.info('Workflow backup created', { + workflowId: input.id, + versionId: backupResult.versionId, + versionNumber: backupResult.versionNumber, + pruned: backupResult.pruned + }); + } + catch (error) { + logger_1.logger.warn('Failed to create workflow backup', { + workflowId: input.id, + error: error.message + }); + } + } + const diffEngine = new workflow_diff_engine_1.WorkflowDiffEngine(); + const diffRequest = input; + const diffResult = await diffEngine.applyDiff(workflow, diffRequest); + if (!diffResult.success) { + if (diffRequest.continueOnError && diffResult.workflow && diffResult.operationsApplied && diffResult.operationsApplied > 0) { + logger_1.logger.info(`continueOnError mode: Applying ${diffResult.operationsApplied} successful operations despite ${diffResult.failed?.length || 0} failures`); + } + else { + return { + success: false, + error: 'Failed to apply diff operations', + details: { + errors: diffResult.errors, + warnings: diffResult.warnings, + operationsApplied: diffResult.operationsApplied, + applied: diffResult.applied, + failed: diffResult.failed + } + }; + } + } + if (input.validateOnly) { + return { + success: true, + message: diffResult.message, + data: { + valid: true, + operationsToApply: input.operations.length + }, + details: { + warnings: diffResult.warnings + } + }; + } + if (diffResult.workflow) { + const structureErrors = (0, n8n_validation_1.validateWorkflowStructure)(diffResult.workflow); + if (structureErrors.length > 0) { + const skipValidation = process.env.SKIP_WORKFLOW_VALIDATION === 'true'; + logger_1.logger.warn('Workflow structure validation failed after applying diff operations', { + workflowId: input.id, + errors: structureErrors, + blocking: !skipValidation + }); + const errorTypes = new Set(); + structureErrors.forEach(err => { + if (err.includes('operator') || err.includes('singleValue')) + errorTypes.add('operator_issues'); + if (err.includes('connection') || err.includes('referenced')) + errorTypes.add('connection_issues'); + if (err.includes('Missing') || err.includes('missing')) + errorTypes.add('missing_metadata'); + if (err.includes('branch') || err.includes('output')) + errorTypes.add('branch_mismatch'); + }); + const recoverySteps = []; + if (errorTypes.has('operator_issues')) { + recoverySteps.push('Operator structure issue detected. Use validate_node_operation to check specific nodes.'); + recoverySteps.push('Binary operators (equals, contains, greaterThan, etc.) must NOT have singleValue:true'); + recoverySteps.push('Unary operators (isEmpty, isNotEmpty, true, false) REQUIRE singleValue:true'); + } + if (errorTypes.has('connection_issues')) { + recoverySteps.push('Connection validation failed. Check all node connections reference existing nodes.'); + recoverySteps.push('Use cleanStaleConnections operation to remove connections to non-existent nodes.'); + } + if (errorTypes.has('missing_metadata')) { + recoverySteps.push('Missing metadata detected. Ensure filter-based nodes (IF v2.2+, Switch v3.2+) have complete conditions.options.'); + recoverySteps.push('Required options: {version: 2, leftValue: "", caseSensitive: true, typeValidation: "strict"}'); + } + if (errorTypes.has('branch_mismatch')) { + recoverySteps.push('Branch count mismatch. Ensure Switch nodes have outputs for all rules (e.g., 3 rules = 3 output branches).'); + } + if (recoverySteps.length === 0) { + recoverySteps.push('Review the validation errors listed above'); + recoverySteps.push('Fix issues using updateNode or cleanStaleConnections operations'); + recoverySteps.push('Run validate_workflow again to verify fixes'); + } + const errorMessage = structureErrors.length === 1 + ? `Workflow validation failed: ${structureErrors[0]}` + : `Workflow validation failed with ${structureErrors.length} structural issues`; + if (!skipValidation) { + return { + success: false, + error: errorMessage, + details: { + errors: structureErrors, + errorCount: structureErrors.length, + operationsApplied: diffResult.operationsApplied, + applied: diffResult.applied, + recoveryGuidance: recoverySteps, + note: 'Operations were applied but created an invalid workflow structure. The workflow was NOT saved to n8n to prevent UI rendering errors.', + autoSanitizationNote: 'Auto-sanitization runs on all nodes during updates to fix operator structures and add missing metadata. However, it cannot fix all issues (e.g., broken connections, branch mismatches). Use the recovery guidance above to resolve remaining issues.' + } + }; + } + logger_1.logger.info('Workflow validation skipped (SKIP_WORKFLOW_VALIDATION=true): Allowing workflow with validation warnings to proceed', { + workflowId: input.id, + warningCount: structureErrors.length + }); + } + } + try { + const updatedWorkflow = await client.updateWorkflow(input.id, diffResult.workflow); + let finalWorkflow = updatedWorkflow; + let activationMessage = ''; + try { + const validator = getValidator(repository); + validationAfter = await validator.validateWorkflow(finalWorkflow, { + validateNodes: true, + validateConnections: true, + validateExpressions: true, + profile: 'runtime' + }); + } + catch (validationError) { + logger_1.logger.debug('Post-mutation validation failed (non-blocking):', validationError); + validationAfter = { + valid: false, + errors: [{ type: 'validation_error', message: 'Validation failed' }] + }; + } + if (diffResult.shouldActivate) { + try { + finalWorkflow = await client.activateWorkflow(input.id); + activationMessage = ' Workflow activated.'; + } + catch (activationError) { + logger_1.logger.error('Failed to activate workflow after update', activationError); + return { + success: false, + error: 'Workflow updated successfully but activation failed', + details: { + workflowUpdated: true, + activationError: activationError instanceof Error ? activationError.message : 'Unknown error' + } + }; + } + } + else if (diffResult.shouldDeactivate) { + try { + finalWorkflow = await client.deactivateWorkflow(input.id); + activationMessage = ' Workflow deactivated.'; + } + catch (deactivationError) { + logger_1.logger.error('Failed to deactivate workflow after update', deactivationError); + return { + success: false, + error: 'Workflow updated successfully but deactivation failed', + details: { + workflowUpdated: true, + deactivationError: deactivationError instanceof Error ? deactivationError.message : 'Unknown error' + } + }; + } + } + if (workflowBefore && !input.validateOnly) { + trackWorkflowMutation({ + sessionId, + toolName: 'n8n_update_partial_workflow', + userIntent: input.intent || 'Partial workflow update', + operations: input.operations, + workflowBefore, + workflowAfter: finalWorkflow, + validationBefore, + validationAfter, + mutationSuccess: true, + durationMs: Date.now() - startTime, + }).catch(err => { + logger_1.logger.debug('Failed to track mutation telemetry:', err); + }); + } + return { + success: true, + data: finalWorkflow, + message: `Workflow "${finalWorkflow.name}" updated successfully. Applied ${diffResult.operationsApplied} operations.${activationMessage}`, + details: { + operationsApplied: diffResult.operationsApplied, + workflowId: finalWorkflow.id, + workflowName: finalWorkflow.name, + active: finalWorkflow.active, + applied: diffResult.applied, + failed: diffResult.failed, + errors: diffResult.errors, + warnings: diffResult.warnings + } + }; + } + catch (error) { + if (workflowBefore && !input.validateOnly) { + trackWorkflowMutation({ + sessionId, + toolName: 'n8n_update_partial_workflow', + userIntent: input.intent || 'Partial workflow update', + operations: input.operations, + workflowBefore, + workflowAfter: workflowBefore, + validationBefore, + validationAfter: validationBefore, + mutationSuccess: false, + mutationError: error instanceof Error ? error.message : 'Unknown error', + durationMs: Date.now() - startTime, + }).catch(err => { + logger_1.logger.warn('Failed to track mutation telemetry for failed operation:', err); + }); + } + if (error instanceof n8n_errors_1.N8nApiError) { + return { + success: false, + error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error), + code: error.code, + details: error.details + }; + } + throw error; + } + } + catch (error) { + if (error instanceof zod_1.z.ZodError) { + return { + success: false, + error: 'Invalid input', + details: { errors: error.errors } + }; + } + logger_1.logger.error('Failed to update partial workflow', error); + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} +function inferIntentFromOperations(operations) { + if (!operations || operations.length === 0) { + return 'Partial workflow update'; + } + const opTypes = operations.map((op) => op.type); + const opCount = operations.length; + if (opCount === 1) { + const op = operations[0]; + switch (op.type) { + case 'addNode': + return `Add ${op.node?.type || 'node'}`; + case 'removeNode': + return `Remove node ${op.nodeName || op.nodeId || ''}`.trim(); + case 'updateNode': + return `Update node ${op.nodeName || op.nodeId || ''}`.trim(); + case 'addConnection': + return `Connect ${op.source || 'node'} to ${op.target || 'node'}`; + case 'removeConnection': + return `Disconnect ${op.source || 'node'} from ${op.target || 'node'}`; + case 'rewireConnection': + return `Rewire ${op.source || 'node'} from ${op.from || ''} to ${op.to || ''}`.trim(); + case 'updateName': + return `Rename workflow to "${op.name || ''}"`; + case 'activateWorkflow': + return 'Activate workflow'; + case 'deactivateWorkflow': + return 'Deactivate workflow'; + default: + return `Workflow ${op.type}`; + } + } + const typeSet = new Set(opTypes); + const summary = []; + if (typeSet.has('addNode')) { + const count = opTypes.filter((t) => t === 'addNode').length; + summary.push(`add ${count} node${count > 1 ? 's' : ''}`); + } + if (typeSet.has('removeNode')) { + const count = opTypes.filter((t) => t === 'removeNode').length; + summary.push(`remove ${count} node${count > 1 ? 's' : ''}`); + } + if (typeSet.has('updateNode')) { + const count = opTypes.filter((t) => t === 'updateNode').length; + summary.push(`update ${count} node${count > 1 ? 's' : ''}`); + } + if (typeSet.has('addConnection') || typeSet.has('rewireConnection')) { + summary.push('modify connections'); + } + if (typeSet.has('updateName') || typeSet.has('updateSettings')) { + summary.push('update metadata'); + } + return summary.length > 0 + ? `Workflow update: ${summary.join(', ')}` + : `Workflow update: ${opCount} operations`; +} +async function trackWorkflowMutation(data) { + try { + if (!data.userIntent || + data.userIntent === 'Partial workflow update' || + data.userIntent.length < 10) { + data.userIntent = inferIntentFromOperations(data.operations); + } + const { telemetry } = await Promise.resolve().then(() => __importStar(require('../telemetry/telemetry-manager.js'))); + await telemetry.trackWorkflowMutation(data); + } + catch (error) { + logger_1.logger.debug('Telemetry tracking failed:', error); + } +} +//# sourceMappingURL=handlers-workflow-diff.js.map \ No newline at end of file diff --git a/dist/mcp/handlers-workflow-diff.js.map b/dist/mcp/handlers-workflow-diff.js.map new file mode 100644 index 0000000..cb47c60 --- /dev/null +++ b/dist/mcp/handlers-workflow-diff.js.map @@ -0,0 +1 @@ +{"version":3,"file":"handlers-workflow-diff.js","sourceRoot":"","sources":["../../src/mcp/handlers-workflow-diff.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/mcp/index.d.ts b/dist/mcp/index.d.ts new file mode 100644 index 0000000..dc1ec89 --- /dev/null +++ b/dist/mcp/index.d.ts @@ -0,0 +1,3 @@ +#!/usr/bin/env node +export {}; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/mcp/index.d.ts.map b/dist/mcp/index.d.ts.map new file mode 100644 index 0000000..8eb9b20 --- /dev/null +++ b/dist/mcp/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/mcp/index.js b/dist/mcp/index.js new file mode 100644 index 0000000..1987488 --- /dev/null +++ b/dist/mcp/index.js @@ -0,0 +1,219 @@ +#!/usr/bin/env node +"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 }); +const server_1 = require("./server"); +const logger_1 = require("../utils/logger"); +const config_manager_1 = require("../telemetry/config-manager"); +const early_error_logger_1 = require("../telemetry/early-error-logger"); +const startup_checkpoints_1 = require("../telemetry/startup-checkpoints"); +const fs_1 = require("fs"); +process.on('uncaughtException', (error) => { + if (process.env.MCP_MODE !== 'stdio') { + console.error('Uncaught Exception:', error); + } + logger_1.logger.error('Uncaught Exception:', error); + process.exit(1); +}); +process.on('unhandledRejection', (reason, promise) => { + if (process.env.MCP_MODE !== 'stdio') { + console.error('Unhandled Rejection at:', promise, 'reason:', reason); + } + logger_1.logger.error('Unhandled Rejection:', reason); + process.exit(1); +}); +function isContainerEnvironment() { + const dockerEnv = (process.env.IS_DOCKER || '').toLowerCase(); + const containerEnv = (process.env.IS_CONTAINER || '').toLowerCase(); + if (['true', '1', 'yes'].includes(dockerEnv)) { + return true; + } + if (['true', '1', 'yes'].includes(containerEnv)) { + return true; + } + try { + return (0, fs_1.existsSync)('/.dockerenv') || (0, fs_1.existsSync)('/run/.containerenv'); + } + catch (error) { + logger_1.logger.debug('Container detection filesystem check failed:', error); + return false; + } +} +async function main() { + const startTime = Date.now(); + const earlyLogger = early_error_logger_1.EarlyErrorLogger.getInstance(); + const checkpoints = []; + try { + earlyLogger.logCheckpoint(startup_checkpoints_1.STARTUP_CHECKPOINTS.PROCESS_STARTED); + checkpoints.push(startup_checkpoints_1.STARTUP_CHECKPOINTS.PROCESS_STARTED); + const args = process.argv.slice(2); + if (args.length > 0 && args[0] === 'telemetry') { + const telemetryConfig = config_manager_1.TelemetryConfigManager.getInstance(); + const action = args[1]; + switch (action) { + case 'enable': + telemetryConfig.enable(); + process.exit(0); + break; + case 'disable': + telemetryConfig.disable(); + process.exit(0); + break; + case 'status': + console.log(telemetryConfig.getStatus()); + process.exit(0); + break; + default: + console.log(` +Usage: n8n-mcp telemetry [command] + +Commands: + enable Enable anonymous telemetry + disable Disable anonymous telemetry + status Show current telemetry status + +Learn more: https://github.com/czlonkowski/n8n-mcp/blob/main/PRIVACY.md +`); + process.exit(args[1] ? 1 : 0); + } + } + const mode = process.env.MCP_MODE || 'stdio'; + earlyLogger.logCheckpoint(startup_checkpoints_1.STARTUP_CHECKPOINTS.TELEMETRY_INITIALIZING); + checkpoints.push(startup_checkpoints_1.STARTUP_CHECKPOINTS.TELEMETRY_INITIALIZING); + earlyLogger.logCheckpoint(startup_checkpoints_1.STARTUP_CHECKPOINTS.TELEMETRY_READY); + checkpoints.push(startup_checkpoints_1.STARTUP_CHECKPOINTS.TELEMETRY_READY); + try { + if (mode === 'http') { + console.error(`Starting n8n Documentation MCP Server in ${mode} mode...`); + console.error('Current directory:', process.cwd()); + console.error('Node version:', process.version); + } + earlyLogger.logCheckpoint(startup_checkpoints_1.STARTUP_CHECKPOINTS.MCP_HANDSHAKE_STARTING); + checkpoints.push(startup_checkpoints_1.STARTUP_CHECKPOINTS.MCP_HANDSHAKE_STARTING); + if (mode === 'http') { + if (process.env.USE_FIXED_HTTP === 'true') { + const { startFixedHTTPServer } = await Promise.resolve().then(() => __importStar(require('../http-server'))); + await startFixedHTTPServer(); + } + else { + const { SingleSessionHTTPServer } = await Promise.resolve().then(() => __importStar(require('../http-server-single-session'))); + const server = new SingleSessionHTTPServer(); + const shutdown = async () => { + await server.shutdown(); + process.exit(0); + }; + process.on('SIGTERM', shutdown); + process.on('SIGINT', shutdown); + await server.start(); + } + } + else { + const server = new server_1.N8NDocumentationMCPServer(undefined, earlyLogger); + let isShuttingDown = false; + const shutdown = async (signal = 'UNKNOWN') => { + if (isShuttingDown) + return; + isShuttingDown = true; + try { + logger_1.logger.info(`Shutdown initiated by: ${signal}`); + await server.shutdown(); + if (process.stdin && !process.stdin.destroyed) { + process.stdin.pause(); + process.stdin.destroy(); + } + setTimeout(() => { + logger_1.logger.warn('Shutdown timeout exceeded, forcing exit'); + process.exit(0); + }, 1000).unref(); + } + catch (error) { + logger_1.logger.error('Error during shutdown:', error); + process.exit(1); + } + }; + process.on('SIGTERM', () => shutdown('SIGTERM')); + process.on('SIGINT', () => shutdown('SIGINT')); + process.on('SIGHUP', () => shutdown('SIGHUP')); + const isContainer = isContainerEnvironment(); + if (!isContainer && process.stdin.readable && !process.stdin.destroyed) { + try { + process.stdin.on('end', () => shutdown('STDIN_END')); + process.stdin.on('close', () => shutdown('STDIN_CLOSE')); + } + catch (error) { + logger_1.logger.error('Failed to register stdin handlers, using signal handlers only:', error); + } + } + await server.run(); + } + earlyLogger.logCheckpoint(startup_checkpoints_1.STARTUP_CHECKPOINTS.MCP_HANDSHAKE_COMPLETE); + checkpoints.push(startup_checkpoints_1.STARTUP_CHECKPOINTS.MCP_HANDSHAKE_COMPLETE); + earlyLogger.logCheckpoint(startup_checkpoints_1.STARTUP_CHECKPOINTS.SERVER_READY); + checkpoints.push(startup_checkpoints_1.STARTUP_CHECKPOINTS.SERVER_READY); + const startupDuration = Date.now() - startTime; + earlyLogger.logStartupSuccess(checkpoints, startupDuration); + logger_1.logger.info(`Server startup completed in ${startupDuration}ms (${checkpoints.length} checkpoints passed)`); + } + catch (error) { + const failedCheckpoint = (0, startup_checkpoints_1.findFailedCheckpoint)(checkpoints); + earlyLogger.logStartupError(failedCheckpoint, error); + if (mode !== 'stdio') { + console.error('Failed to start MCP server:', error); + logger_1.logger.error('Failed to start MCP server', error); + if (error instanceof Error && error.message.includes('nodes.db not found')) { + console.error('\nTo fix this issue:'); + console.error('1. cd to the n8n-mcp directory'); + console.error('2. Run: npm run build'); + console.error('3. Run: npm run rebuild'); + } + else if (error instanceof Error && error.message.includes('NODE_MODULE_VERSION')) { + console.error('\nTo fix this Node.js version mismatch:'); + console.error('1. cd to the n8n-mcp directory'); + console.error('2. Run: npm rebuild better-sqlite3'); + console.error('3. If that doesn\'t work, try: rm -rf node_modules && npm install'); + } + } + process.exit(1); + } + } + catch (outerError) { + logger_1.logger.error('Critical startup error:', outerError); + process.exit(1); + } +} +if (require.main === module) { + main().catch(console.error); +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/mcp/index.js.map b/dist/mcp/index.js.map new file mode 100644 index 0000000..2ad52d5 --- /dev/null +++ b/dist/mcp/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,qCAAqD;AACrD,4CAAyC;AACzC,gEAAqE;AACrE,wEAAmE;AACnE,0EAAgH;AAChH,2BAAgC;AAGhC,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,EAAE;IACxC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACrC,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC;IACD,eAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;IAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;IACnD,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACrC,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IACvE,CAAC;IACD,eAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;IAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAQH,SAAS,sBAAsB;IAE7B,MAAM,SAAS,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC9D,MAAM,YAAY,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAEpE,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;IAKD,IAAI,CAAC;QACH,OAAO,IAAA,eAAU,EAAC,aAAa,CAAC,IAAI,IAAA,eAAU,EAAC,oBAAoB,CAAC,CAAC;IACvE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAEf,eAAM,CAAC,KAAK,CAAC,8CAA8C,EAAE,KAAK,CAAC,CAAC;QACpE,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IAGjB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,WAAW,GAAG,qCAAgB,CAAC,WAAW,EAAE,CAAC;IACnD,MAAM,WAAW,GAAwB,EAAE,CAAC;IAE5C,IAAI,CAAC;QAEH,WAAW,CAAC,aAAa,CAAC,yCAAmB,CAAC,eAAe,CAAC,CAAC;QAC/D,WAAW,CAAC,IAAI,CAAC,yCAAmB,CAAC,eAAe,CAAC,CAAC;QAGtD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACrC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,WAAW,EAAE,CAAC;YAC/C,MAAM,eAAe,GAAG,uCAAsB,CAAC,WAAW,EAAE,CAAC;YAC7D,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YAEvB,QAAQ,MAAM,EAAE,CAAC;gBACf,KAAK,QAAQ;oBACX,eAAe,CAAC,MAAM,EAAE,CAAC;oBACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAChB,MAAM;gBACR,KAAK,SAAS;oBACZ,eAAe,CAAC,OAAO,EAAE,CAAC;oBAC1B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAChB,MAAM;gBACR,KAAK,QAAQ;oBACX,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,SAAS,EAAE,CAAC,CAAC;oBACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAChB,MAAM;gBACR;oBACE,OAAO,CAAC,GAAG,CAAC;;;;;;;;;CASnB,CAAC,CAAC;oBACK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QAED,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC;QAG3C,WAAW,CAAC,aAAa,CAAC,yCAAmB,CAAC,sBAAsB,CAAC,CAAC;QACtE,WAAW,CAAC,IAAI,CAAC,yCAAmB,CAAC,sBAAsB,CAAC,CAAC;QAI7D,WAAW,CAAC,aAAa,CAAC,yCAAmB,CAAC,eAAe,CAAC,CAAC;QAC/D,WAAW,CAAC,IAAI,CAAC,yCAAmB,CAAC,eAAe,CAAC,CAAC;QAExD,IAAI,CAAC;YAEH,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBACpB,OAAO,CAAC,KAAK,CAAC,4CAA4C,IAAI,UAAU,CAAC,CAAC;gBAC1E,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;gBACnD,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;YAClD,CAAC;YAGD,WAAW,CAAC,aAAa,CAAC,yCAAmB,CAAC,sBAAsB,CAAC,CAAC;YACtE,WAAW,CAAC,IAAI,CAAC,yCAAmB,CAAC,sBAAsB,CAAC,CAAC;YAE7D,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBAEpB,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,MAAM,EAAE,CAAC;oBAE1C,MAAM,EAAE,oBAAoB,EAAE,GAAG,wDAAa,gBAAgB,GAAC,CAAC;oBAChE,MAAM,oBAAoB,EAAE,CAAC;gBAC/B,CAAC;qBAAM,CAAC;oBAEN,MAAM,EAAE,uBAAuB,EAAE,GAAG,wDAAa,+BAA+B,GAAC,CAAC;oBAClF,MAAM,MAAM,GAAG,IAAI,uBAAuB,EAAE,CAAC;oBAG7C,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;wBAC1B,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;wBACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAClB,CAAC,CAAC;oBAEF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;oBAChC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;oBAE/B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;gBACvB,CAAC;YACH,CAAC;iBAAM,CAAC;gBAEN,MAAM,MAAM,GAAG,IAAI,kCAAyB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;gBAGrE,IAAI,cAAc,GAAG,KAAK,CAAC;gBAC3B,MAAM,QAAQ,GAAG,KAAK,EAAE,SAAiB,SAAS,EAAE,EAAE;oBACpD,IAAI,cAAc;wBAAE,OAAO;oBAC3B,cAAc,GAAG,IAAI,CAAC;oBAEtB,IAAI,CAAC;wBACH,eAAM,CAAC,IAAI,CAAC,0BAA0B,MAAM,EAAE,CAAC,CAAC;wBAEhD,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;wBAGxB,IAAI,OAAO,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;4BAC9C,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;4BACtB,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;wBAC1B,CAAC;wBAID,UAAU,CAAC,GAAG,EAAE;4BACd,eAAM,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;4BACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;wBAClB,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;oBAInB,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,eAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;wBAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAClB,CAAC;gBACH,CAAC,CAAC;gBAUF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;gBACjD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAC/C,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAM/C,MAAM,WAAW,GAAG,sBAAsB,EAAE,CAAC;gBAE7C,IAAI,CAAC,WAAW,IAAI,OAAO,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;oBACvE,IAAI,CAAC;wBACH,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;wBACrD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;oBAC3D,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,eAAM,CAAC,KAAK,CAAC,gEAAgE,EAAE,KAAK,CAAC,CAAC;oBAExF,CAAC;gBACH,CAAC;gBAED,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;YACrB,CAAC;YAGD,WAAW,CAAC,aAAa,CAAC,yCAAmB,CAAC,sBAAsB,CAAC,CAAC;YACtE,WAAW,CAAC,IAAI,CAAC,yCAAmB,CAAC,sBAAsB,CAAC,CAAC;YAG7D,WAAW,CAAC,aAAa,CAAC,yCAAmB,CAAC,YAAY,CAAC,CAAC;YAC5D,WAAW,CAAC,IAAI,CAAC,yCAAmB,CAAC,YAAY,CAAC,CAAC;YAGnD,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAC/C,WAAW,CAAC,iBAAiB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;YAE5D,eAAM,CAAC,IAAI,CAAC,+BAA+B,eAAe,OAAO,WAAW,CAAC,MAAM,sBAAsB,CAAC,CAAC;QAE7G,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAEf,MAAM,gBAAgB,GAAG,IAAA,0CAAoB,EAAC,WAAW,CAAC,CAAC;YAC3D,WAAW,CAAC,eAAe,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;YAGrD,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;gBACrB,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;gBACpD,eAAM,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;gBAGlD,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC;oBAC3E,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;oBACtC,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;oBAChD,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;oBACvC,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;gBAC3C,CAAC;qBAAM,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC;oBACnF,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;oBACzD,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;oBAChD,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;oBACpD,OAAO,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;gBACrF,CAAC;YACH,CAAC;YAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACD,CAAC;IAAC,OAAO,UAAU,EAAE,CAAC;QAEpB,eAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,UAAU,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAGD,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC"} \ No newline at end of file diff --git a/dist/mcp/server.d.ts b/dist/mcp/server.d.ts new file mode 100644 index 0000000..0ee7c07 --- /dev/null +++ b/dist/mcp/server.d.ts @@ -0,0 +1,79 @@ +import { InstanceContext } from '../types/instance-context'; +import { EarlyErrorLogger } from '../telemetry/early-error-logger'; +export declare class N8NDocumentationMCPServer { + private server; + private db; + private repository; + private templateService; + private initialized; + private cache; + private clientInfo; + private instanceContext?; + private previousTool; + private previousToolTimestamp; + private earlyLogger; + private disabledToolsCache; + constructor(instanceContext?: InstanceContext, earlyLogger?: EarlyErrorLogger); + private initializeDatabase; + private initializeInMemorySchema; + private parseSQLStatements; + private ensureInitialized; + private dbHealthChecked; + private validateDatabaseHealth; + private getDisabledTools; + private setupHandlers; + private sanitizeValidationResult; + private validateToolParams; + private validateToolParamsBasic; + private validateExtractedArgs; + private listNodes; + private getNodeInfo; + private searchNodes; + private searchNodesFTS; + private searchNodesFuzzy; + private calculateFuzzyScore; + private getEditDistance; + private searchNodesLIKE; + private calculateRelevance; + private calculateRelevanceScore; + private rankSearchResults; + private listAITools; + private getNodeDocumentation; + private getDatabaseStatistics; + private getNodeEssentials; + private getNode; + private handleInfoMode; + private handleVersionMode; + private getVersionSummary; + private getVersionHistory; + private compareVersions; + private getBreakingChanges; + private getMigrations; + private enrichPropertyWithTypeInfo; + private enrichPropertiesWithTypeInfo; + private searchNodeProperties; + private getPropertyValue; + private listTasks; + private validateNodeConfig; + private getPropertyDependencies; + private getNodeAsToolInfo; + private getOutputDescriptions; + private getCommonAIToolUseCases; + private getAIToolExamples; + private validateNodeMinimal; + private getToolsDocumentation; + connect(transport: any): Promise; + private listTemplates; + private listNodeTemplates; + private getTemplate; + private searchTemplates; + private getTemplatesForTask; + private searchTemplatesByMetadata; + private getTaskDescription; + private validateWorkflow; + private validateWorkflowConnections; + private validateWorkflowExpressions; + run(): Promise; + shutdown(): Promise; +} +//# sourceMappingURL=server.d.ts.map \ No newline at end of file diff --git a/dist/mcp/server.d.ts.map b/dist/mcp/server.d.ts.map new file mode 100644 index 0000000..125685a --- /dev/null +++ b/dist/mcp/server.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAsCA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAkFnE,qBAAa,yBAAyB;IACpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,EAAE,CAAgC;IAC1C,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,eAAe,CAAC,CAAkB;IAC1C,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,qBAAqB,CAAsB;IACnD,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,kBAAkB,CAA4B;gBAE1C,eAAe,CAAC,EAAE,eAAe,EAAE,WAAW,CAAC,EAAE,gBAAgB;YAuF/D,kBAAkB;YAwClB,wBAAwB;IA0BtC,OAAO,CAAC,kBAAkB;YA6CZ,iBAAiB;IAa/B,OAAO,CAAC,eAAe,CAAkB;YAE3B,sBAAsB;IAgDpC,OAAO,CAAC,gBAAgB;IAqCxB,OAAO,CAAC,aAAa;IAoTrB,OAAO,CAAC,wBAAwB;IAoFhC,OAAO,CAAC,kBAAkB;IAqE1B,OAAO,CAAC,uBAAuB;IAwB/B,OAAO,CAAC,qBAAqB;YAgTf,SAAS;YA2DT,WAAW;YA0EX,WAAW;YAyCX,cAAc;YAyKd,gBAAgB;IAqD9B,OAAO,CAAC,mBAAmB;IAwE3B,OAAO,CAAC,eAAe;YAsBT,eAAe;IAqI7B,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,uBAAuB;IA0D/B,OAAO,CAAC,iBAAiB;YAqFX,WAAW;YAgCX,oBAAoB;YA2EpB,qBAAqB;YAwDrB,iBAAiB;YA2JjB,OAAO;YAgDP,cAAc;YAgFd,iBAAiB;IAqC/B,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,eAAe;IAwCvB,OAAO,CAAC,kBAAkB;IAiC1B,OAAO,CAAC,aAAa;IAoCrB,OAAO,CAAC,0BAA0B;IAgClC,OAAO,CAAC,4BAA4B;YAKtB,oBAAoB;IAsDlC,OAAO,CAAC,gBAAgB;YAiBV,SAAS;YA6CT,kBAAkB;YA+DlB,uBAAuB;YAsDvB,iBAAiB;IAqE/B,OAAO,CAAC,qBAAqB;IA8C7B,OAAO,CAAC,uBAAuB;IAwD/B,OAAO,CAAC,iBAAiB;YAoDX,mBAAmB;YAkGnB,qBAAqB;IAS7B,OAAO,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;YAS9B,aAAa;YAcb,iBAAiB;YAoBjB,WAAW;YAwBX,eAAe;YAqBf,mBAAmB;YAwBnB,yBAAyB;IA4CvC,OAAO,CAAC,kBAAkB;YAiBZ,gBAAgB;YA6HhB,2BAA2B;YAiE3B,2BAA2B;IAyEnC,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IA0BpB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAuBhC"} \ No newline at end of file diff --git a/dist/mcp/server.js b/dist/mcp/server.js new file mode 100644 index 0000000..236afc2 --- /dev/null +++ b/dist/mcp/server.js @@ -0,0 +1,2780 @@ +"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; + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.N8NDocumentationMCPServer = void 0; +const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js"); +const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js"); +const types_js_1 = require("@modelcontextprotocol/sdk/types.js"); +const fs_1 = require("fs"); +const path_1 = __importDefault(require("path")); +const tools_1 = require("./tools"); +const tools_n8n_manager_1 = require("./tools-n8n-manager"); +const tools_n8n_friendly_1 = require("./tools-n8n-friendly"); +const workflow_examples_1 = require("./workflow-examples"); +const logger_1 = require("../utils/logger"); +const node_repository_1 = require("../database/node-repository"); +const database_adapter_1 = require("../database/database-adapter"); +const property_filter_1 = require("../services/property-filter"); +const task_templates_1 = require("../services/task-templates"); +const enhanced_config_validator_1 = require("../services/enhanced-config-validator"); +const property_dependencies_1 = require("../services/property-dependencies"); +const type_structure_service_1 = require("../services/type-structure-service"); +const simple_cache_1 = require("../utils/simple-cache"); +const template_service_1 = require("../templates/template-service"); +const workflow_validator_1 = require("../services/workflow-validator"); +const n8n_api_1 = require("../config/n8n-api"); +const n8nHandlers = __importStar(require("./handlers-n8n-manager")); +const handlers_workflow_diff_1 = require("./handlers-workflow-diff"); +const tools_documentation_1 = require("./tools-documentation"); +const version_1 = require("../utils/version"); +const node_utils_1 = require("../utils/node-utils"); +const node_type_normalizer_1 = require("../utils/node-type-normalizer"); +const validation_schemas_1 = require("../utils/validation-schemas"); +const protocol_version_1 = require("../utils/protocol-version"); +const telemetry_1 = require("../telemetry"); +const startup_checkpoints_1 = require("../telemetry/startup-checkpoints"); +class N8NDocumentationMCPServer { + constructor(instanceContext, earlyLogger) { + this.db = null; + this.repository = null; + this.templateService = null; + this.cache = new simple_cache_1.SimpleCache(); + this.clientInfo = null; + this.previousTool = null; + this.previousToolTimestamp = Date.now(); + this.earlyLogger = null; + this.disabledToolsCache = null; + this.dbHealthChecked = false; + this.instanceContext = instanceContext; + this.earlyLogger = earlyLogger || null; + const envDbPath = process.env.NODE_DB_PATH; + let dbPath = null; + let possiblePaths = []; + if (envDbPath && (envDbPath === ':memory:' || (0, fs_1.existsSync)(envDbPath))) { + dbPath = envDbPath; + } + else { + possiblePaths = [ + path_1.default.join(process.cwd(), 'data', 'nodes.db'), + path_1.default.join(__dirname, '../../data', 'nodes.db'), + './data/nodes.db' + ]; + for (const p of possiblePaths) { + if ((0, fs_1.existsSync)(p)) { + dbPath = p; + break; + } + } + } + if (!dbPath) { + logger_1.logger.error('Database not found in any of the expected locations:', possiblePaths); + throw new Error('Database nodes.db not found. Please run npm run rebuild first.'); + } + this.initialized = this.initializeDatabase(dbPath).then(() => { + if (this.earlyLogger) { + this.earlyLogger.logCheckpoint(startup_checkpoints_1.STARTUP_CHECKPOINTS.N8N_API_CHECKING); + } + const apiConfigured = (0, n8n_api_1.isN8nApiConfigured)(); + const totalTools = apiConfigured ? + tools_1.n8nDocumentationToolsFinal.length + tools_n8n_manager_1.n8nManagementTools.length : + tools_1.n8nDocumentationToolsFinal.length; + logger_1.logger.info(`MCP server initialized with ${totalTools} tools (n8n API: ${apiConfigured ? 'configured' : 'not configured'})`); + if (this.earlyLogger) { + this.earlyLogger.logCheckpoint(startup_checkpoints_1.STARTUP_CHECKPOINTS.N8N_API_READY); + } + }); + logger_1.logger.info('Initializing n8n Documentation MCP server'); + this.server = new index_js_1.Server({ + name: 'n8n-documentation-mcp', + version: version_1.PROJECT_VERSION, + icons: [ + { + src: "https://www.n8n-mcp.com/logo.png", + mimeType: "image/png", + sizes: ["192x192"] + }, + { + src: "https://www.n8n-mcp.com/logo-128.png", + mimeType: "image/png", + sizes: ["128x128"] + }, + { + src: "https://www.n8n-mcp.com/logo-48.png", + mimeType: "image/png", + sizes: ["48x48"] + } + ], + websiteUrl: "https://n8n-mcp.com" + }, { + capabilities: { + tools: {}, + }, + }); + this.setupHandlers(); + } + async initializeDatabase(dbPath) { + try { + if (this.earlyLogger) { + this.earlyLogger.logCheckpoint(startup_checkpoints_1.STARTUP_CHECKPOINTS.DATABASE_CONNECTING); + } + logger_1.logger.debug('Database initialization starting...', { dbPath }); + this.db = await (0, database_adapter_1.createDatabaseAdapter)(dbPath); + logger_1.logger.debug('Database adapter created'); + if (dbPath === ':memory:') { + await this.initializeInMemorySchema(); + logger_1.logger.debug('In-memory schema initialized'); + } + this.repository = new node_repository_1.NodeRepository(this.db); + logger_1.logger.debug('Node repository initialized'); + this.templateService = new template_service_1.TemplateService(this.db); + logger_1.logger.debug('Template service initialized'); + enhanced_config_validator_1.EnhancedConfigValidator.initializeSimilarityServices(this.repository); + logger_1.logger.debug('Similarity services initialized'); + if (this.earlyLogger) { + this.earlyLogger.logCheckpoint(startup_checkpoints_1.STARTUP_CHECKPOINTS.DATABASE_CONNECTED); + } + logger_1.logger.info(`Database initialized successfully from: ${dbPath}`); + } + catch (error) { + logger_1.logger.error('Failed to initialize database:', error); + throw new Error(`Failed to open database: ${error instanceof Error ? error.message : 'Unknown error'}`); + } + } + async initializeInMemorySchema() { + if (!this.db) + return; + const schemaPath = path_1.default.join(__dirname, '../../src/database/schema.sql'); + const schema = await fs_1.promises.readFile(schemaPath, 'utf-8'); + const statements = this.parseSQLStatements(schema); + for (const statement of statements) { + if (statement.trim()) { + try { + this.db.exec(statement); + } + catch (error) { + logger_1.logger.error(`Failed to execute SQL statement: ${statement.substring(0, 100)}...`, error); + throw error; + } + } + } + } + parseSQLStatements(sql) { + const statements = []; + let current = ''; + let inBlock = false; + const lines = sql.split('\n'); + for (const line of lines) { + const trimmed = line.trim().toUpperCase(); + if (trimmed.startsWith('--') || trimmed === '') { + continue; + } + if (trimmed.includes('BEGIN')) { + inBlock = true; + } + current += line + '\n'; + if (inBlock && trimmed === 'END;') { + statements.push(current.trim()); + current = ''; + inBlock = false; + continue; + } + if (!inBlock && trimmed.endsWith(';')) { + statements.push(current.trim()); + current = ''; + } + } + if (current.trim()) { + statements.push(current.trim()); + } + return statements.filter(s => s.length > 0); + } + async ensureInitialized() { + await this.initialized; + if (!this.db || !this.repository) { + throw new Error('Database not initialized'); + } + if (!this.dbHealthChecked) { + await this.validateDatabaseHealth(); + this.dbHealthChecked = true; + } + } + async validateDatabaseHealth() { + if (!this.db) + return; + try { + const nodeCount = this.db.prepare('SELECT COUNT(*) as count FROM nodes').get(); + if (nodeCount.count === 0) { + logger_1.logger.error('CRITICAL: Database is empty - no nodes found! Please run: npm run rebuild'); + throw new Error('Database is empty. Run "npm run rebuild" to populate node data.'); + } + try { + const ftsExists = this.db.prepare(` + SELECT name FROM sqlite_master + WHERE type='table' AND name='nodes_fts' + `).get(); + if (!ftsExists) { + logger_1.logger.warn('FTS5 table missing - search performance will be degraded. Please run: npm run rebuild'); + } + else { + const ftsCount = this.db.prepare('SELECT COUNT(*) as count FROM nodes_fts').get(); + if (ftsCount.count === 0) { + logger_1.logger.warn('FTS5 index is empty - search will not work properly. Please run: npm run rebuild'); + } + } + } + catch (ftsError) { + logger_1.logger.warn('FTS5 not available - using fallback search. For better performance, ensure better-sqlite3 is properly installed.'); + } + logger_1.logger.info(`Database health check passed: ${nodeCount.count} nodes loaded`); + } + catch (error) { + logger_1.logger.error('Database health check failed:', error); + throw error; + } + } + getDisabledTools() { + if (this.disabledToolsCache !== null) { + return this.disabledToolsCache; + } + let disabledToolsEnv = process.env.DISABLED_TOOLS || ''; + if (!disabledToolsEnv) { + this.disabledToolsCache = new Set(); + return this.disabledToolsCache; + } + if (disabledToolsEnv.length > 10000) { + logger_1.logger.warn(`DISABLED_TOOLS environment variable too long (${disabledToolsEnv.length} chars), truncating to 10000`); + disabledToolsEnv = disabledToolsEnv.substring(0, 10000); + } + let tools = disabledToolsEnv + .split(',') + .map(t => t.trim()) + .filter(Boolean); + if (tools.length > 200) { + logger_1.logger.warn(`DISABLED_TOOLS contains ${tools.length} tools, limiting to first 200`); + tools = tools.slice(0, 200); + } + if (tools.length > 0) { + logger_1.logger.info(`Disabled tools configured: ${tools.join(', ')}`); + } + this.disabledToolsCache = new Set(tools); + return this.disabledToolsCache; + } + setupHandlers() { + this.server.setRequestHandler(types_js_1.InitializeRequestSchema, async (request) => { + const clientVersion = request.params.protocolVersion; + const clientCapabilities = request.params.capabilities; + const clientInfo = request.params.clientInfo; + logger_1.logger.info('MCP Initialize request received', { + clientVersion, + clientCapabilities, + clientInfo + }); + telemetry_1.telemetry.trackSessionStart(); + this.clientInfo = clientInfo; + const negotiationResult = (0, protocol_version_1.negotiateProtocolVersion)(clientVersion, clientInfo, undefined, undefined); + (0, protocol_version_1.logProtocolNegotiation)(negotiationResult, logger_1.logger, 'MCP_INITIALIZE'); + if (clientVersion && clientVersion !== negotiationResult.version) { + logger_1.logger.warn(`Protocol version negotiated: client requested ${clientVersion}, server will use ${negotiationResult.version}`, { + reasoning: negotiationResult.reasoning + }); + } + const response = { + protocolVersion: negotiationResult.version, + capabilities: { + tools: {}, + }, + serverInfo: { + name: 'n8n-documentation-mcp', + version: version_1.PROJECT_VERSION, + }, + }; + logger_1.logger.info('MCP Initialize response', { response }); + return response; + }); + this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, async (request) => { + const disabledTools = this.getDisabledTools(); + const enabledDocTools = tools_1.n8nDocumentationToolsFinal.filter(tool => !disabledTools.has(tool.name)); + let tools = [...enabledDocTools]; + const hasEnvConfig = (0, n8n_api_1.isN8nApiConfigured)(); + const hasInstanceConfig = !!(this.instanceContext?.n8nApiUrl && this.instanceContext?.n8nApiKey); + const isMultiTenantEnabled = process.env.ENABLE_MULTI_TENANT === 'true'; + const shouldIncludeManagementTools = hasEnvConfig || hasInstanceConfig || isMultiTenantEnabled; + if (shouldIncludeManagementTools) { + const enabledMgmtTools = tools_n8n_manager_1.n8nManagementTools.filter(tool => !disabledTools.has(tool.name)); + tools.push(...enabledMgmtTools); + logger_1.logger.debug(`Tool listing: ${tools.length} tools available (${enabledDocTools.length} documentation + ${enabledMgmtTools.length} management)`, { + hasEnvConfig, + hasInstanceConfig, + isMultiTenantEnabled, + disabledToolsCount: disabledTools.size + }); + } + else { + logger_1.logger.debug(`Tool listing: ${tools.length} tools available (documentation only)`, { + hasEnvConfig, + hasInstanceConfig, + isMultiTenantEnabled, + disabledToolsCount: disabledTools.size + }); + } + if (disabledTools.size > 0) { + const totalAvailableTools = tools_1.n8nDocumentationToolsFinal.length + (shouldIncludeManagementTools ? tools_n8n_manager_1.n8nManagementTools.length : 0); + logger_1.logger.debug(`Filtered ${disabledTools.size} disabled tools, ${tools.length}/${totalAvailableTools} tools available`); + } + const clientInfo = this.clientInfo; + const isN8nClient = clientInfo?.name?.includes('n8n') || + clientInfo?.name?.includes('langchain'); + if (isN8nClient) { + logger_1.logger.info('Detected n8n client, using n8n-friendly tool descriptions'); + tools = (0, tools_n8n_friendly_1.makeToolsN8nFriendly)(tools); + } + const validationTools = tools.filter(t => t.name.startsWith('validate_')); + validationTools.forEach(tool => { + logger_1.logger.info('Validation tool schema', { + toolName: tool.name, + inputSchema: JSON.stringify(tool.inputSchema, null, 2), + hasOutputSchema: !!tool.outputSchema, + description: tool.description + }); + }); + return { tools }; + }); + this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => { + const { name, arguments: args } = request.params; + logger_1.logger.info('Tool call received - DETAILED DEBUG', { + toolName: name, + arguments: JSON.stringify(args, null, 2), + argumentsType: typeof args, + argumentsKeys: args ? Object.keys(args) : [], + hasNodeType: args && 'nodeType' in args, + hasConfig: args && 'config' in args, + configType: args && args.config ? typeof args.config : 'N/A', + rawRequest: JSON.stringify(request.params) + }); + const disabledTools = this.getDisabledTools(); + if (disabledTools.has(name)) { + logger_1.logger.warn(`Attempted to call disabled tool: ${name}`); + return { + content: [{ + type: 'text', + text: JSON.stringify({ + error: 'TOOL_DISABLED', + message: `Tool '${name}' is not available in this deployment. It has been disabled via DISABLED_TOOLS environment variable.`, + tool: name + }, null, 2) + }] + }; + } + let processedArgs = args; + if (args && typeof args === 'object' && 'output' in args) { + try { + const possibleNestedData = args.output; + if (typeof possibleNestedData === 'string' && possibleNestedData.trim().startsWith('{')) { + const parsed = JSON.parse(possibleNestedData); + if (parsed && typeof parsed === 'object') { + logger_1.logger.warn('Detected n8n nested output bug, attempting to extract actual arguments', { + originalArgs: args, + extractedArgs: parsed + }); + if (this.validateExtractedArgs(name, parsed)) { + processedArgs = parsed; + } + else { + logger_1.logger.warn('Extracted arguments failed validation, using original args', { + toolName: name, + extractedArgs: parsed + }); + } + } + } + } + catch (parseError) { + logger_1.logger.debug('Failed to parse nested output, continuing with original args', { + error: parseError instanceof Error ? parseError.message : String(parseError) + }); + } + } + try { + logger_1.logger.debug(`Executing tool: ${name}`, { args: processedArgs }); + const startTime = Date.now(); + const result = await this.executeTool(name, processedArgs); + const duration = Date.now() - startTime; + logger_1.logger.debug(`Tool ${name} executed successfully`); + telemetry_1.telemetry.trackToolUsage(name, true, duration); + if (this.previousTool) { + const timeDelta = Date.now() - this.previousToolTimestamp; + telemetry_1.telemetry.trackToolSequence(this.previousTool, name, timeDelta); + } + this.previousTool = name; + this.previousToolTimestamp = Date.now(); + let responseText; + let structuredContent = null; + try { + if (name.startsWith('validate_') && typeof result === 'object' && result !== null) { + const cleanResult = this.sanitizeValidationResult(result, name); + structuredContent = cleanResult; + responseText = JSON.stringify(cleanResult, null, 2); + } + else { + responseText = typeof result === 'string' ? result : JSON.stringify(result, null, 2); + } + } + catch (jsonError) { + logger_1.logger.warn(`Failed to stringify tool result for ${name}:`, jsonError); + responseText = String(result); + } + if (responseText.length > 1000000) { + logger_1.logger.warn(`Tool ${name} response is very large (${responseText.length} chars), truncating`); + responseText = responseText.substring(0, 999000) + '\n\n[Response truncated due to size limits]'; + structuredContent = null; + } + const mcpResponse = { + content: [ + { + type: 'text', + text: responseText, + }, + ], + }; + if (name.startsWith('validate_') && structuredContent !== null) { + mcpResponse.structuredContent = structuredContent; + } + return mcpResponse; + } + catch (error) { + logger_1.logger.error(`Error executing tool ${name}`, error); + const errorMessage = error instanceof Error ? error.message : 'Unknown error'; + telemetry_1.telemetry.trackToolUsage(name, false); + telemetry_1.telemetry.trackError(error instanceof Error ? error.constructor.name : 'UnknownError', `tool_execution`, name, errorMessage); + if (this.previousTool) { + const timeDelta = Date.now() - this.previousToolTimestamp; + telemetry_1.telemetry.trackToolSequence(this.previousTool, name, timeDelta); + } + this.previousTool = name; + this.previousToolTimestamp = Date.now(); + let helpfulMessage = `Error executing tool ${name}: ${errorMessage}`; + if (errorMessage.includes('required') || errorMessage.includes('missing')) { + helpfulMessage += '\n\nNote: This error often occurs when the AI agent sends incomplete or incorrectly formatted parameters. Please ensure all required fields are provided with the correct types.'; + } + else if (errorMessage.includes('type') || errorMessage.includes('expected')) { + helpfulMessage += '\n\nNote: This error indicates a type mismatch. The AI agent may be sending data in the wrong format (e.g., string instead of object).'; + } + else if (errorMessage.includes('Unknown category') || errorMessage.includes('not found')) { + helpfulMessage += '\n\nNote: The requested resource or category was not found. Please check the available options.'; + } + if (name.startsWith('validate_') && (errorMessage.includes('config') || errorMessage.includes('nodeType'))) { + helpfulMessage += '\n\nFor validation tools:\n- nodeType should be a string (e.g., "nodes-base.webhook")\n- config should be an object (e.g., {})'; + } + return { + content: [ + { + type: 'text', + text: helpfulMessage, + }, + ], + isError: true, + }; + } + }); + } + sanitizeValidationResult(result, toolName) { + if (!result || typeof result !== 'object') { + return result; + } + const sanitized = { ...result }; + if (toolName === 'validate_node_minimal') { + const filtered = { + nodeType: String(sanitized.nodeType || ''), + displayName: String(sanitized.displayName || ''), + valid: Boolean(sanitized.valid), + missingRequiredFields: Array.isArray(sanitized.missingRequiredFields) + ? sanitized.missingRequiredFields.map(String) + : [] + }; + return filtered; + } + else if (toolName === 'validate_node_operation') { + let summary = sanitized.summary; + if (!summary || typeof summary !== 'object') { + summary = { + hasErrors: Array.isArray(sanitized.errors) ? sanitized.errors.length > 0 : false, + errorCount: Array.isArray(sanitized.errors) ? sanitized.errors.length : 0, + warningCount: Array.isArray(sanitized.warnings) ? sanitized.warnings.length : 0, + suggestionCount: Array.isArray(sanitized.suggestions) ? sanitized.suggestions.length : 0 + }; + } + const filtered = { + nodeType: String(sanitized.nodeType || ''), + workflowNodeType: String(sanitized.workflowNodeType || sanitized.nodeType || ''), + displayName: String(sanitized.displayName || ''), + valid: Boolean(sanitized.valid), + errors: Array.isArray(sanitized.errors) ? sanitized.errors : [], + warnings: Array.isArray(sanitized.warnings) ? sanitized.warnings : [], + suggestions: Array.isArray(sanitized.suggestions) ? sanitized.suggestions : [], + summary: summary + }; + return filtered; + } + else if (toolName.startsWith('validate_workflow')) { + sanitized.valid = Boolean(sanitized.valid); + sanitized.errors = Array.isArray(sanitized.errors) ? sanitized.errors : []; + sanitized.warnings = Array.isArray(sanitized.warnings) ? sanitized.warnings : []; + if (toolName === 'validate_workflow') { + if (!sanitized.summary || typeof sanitized.summary !== 'object') { + sanitized.summary = { + totalNodes: 0, + enabledNodes: 0, + triggerNodes: 0, + validConnections: 0, + invalidConnections: 0, + expressionsValidated: 0, + errorCount: sanitized.errors.length, + warningCount: sanitized.warnings.length + }; + } + } + else { + if (!sanitized.statistics || typeof sanitized.statistics !== 'object') { + sanitized.statistics = { + totalNodes: 0, + triggerNodes: 0, + validConnections: 0, + invalidConnections: 0, + expressionsValidated: 0 + }; + } + } + } + return JSON.parse(JSON.stringify(sanitized)); + } + validateToolParams(toolName, args, legacyRequiredParams) { + try { + let validationResult; + switch (toolName) { + case 'validate_node': + validationResult = validation_schemas_1.ToolValidation.validateNodeOperation(args); + break; + case 'validate_workflow': + validationResult = validation_schemas_1.ToolValidation.validateWorkflow(args); + break; + case 'search_nodes': + validationResult = validation_schemas_1.ToolValidation.validateSearchNodes(args); + break; + case 'n8n_create_workflow': + validationResult = validation_schemas_1.ToolValidation.validateCreateWorkflow(args); + break; + case 'n8n_get_workflow': + case 'n8n_update_full_workflow': + case 'n8n_delete_workflow': + case 'n8n_validate_workflow': + case 'n8n_autofix_workflow': + validationResult = validation_schemas_1.ToolValidation.validateWorkflowId(args); + break; + case 'n8n_executions': + validationResult = args.action + ? { valid: true, errors: [] } + : { valid: false, errors: [{ field: 'action', message: 'action is required' }] }; + break; + case 'n8n_deploy_template': + validationResult = args.templateId !== undefined + ? { valid: true, errors: [] } + : { valid: false, errors: [{ field: 'templateId', message: 'templateId is required' }] }; + break; + default: + return this.validateToolParamsBasic(toolName, args, legacyRequiredParams || []); + } + if (!validationResult.valid) { + const errorMessage = validation_schemas_1.Validator.formatErrors(validationResult, toolName); + logger_1.logger.error(`Parameter validation failed for ${toolName}:`, errorMessage); + throw new validation_schemas_1.ValidationError(errorMessage); + } + } + catch (error) { + if (error instanceof validation_schemas_1.ValidationError) { + throw error; + } + logger_1.logger.error(`Validation system error for ${toolName}:`, error); + const errorMessage = error instanceof Error + ? `Internal validation error: ${error.message}` + : `Internal validation error while processing ${toolName}`; + throw new Error(errorMessage); + } + } + validateToolParamsBasic(toolName, args, requiredParams) { + const missing = []; + const invalid = []; + for (const param of requiredParams) { + if (!(param in args) || args[param] === undefined || args[param] === null) { + missing.push(param); + } + else if (typeof args[param] === 'string' && args[param].trim() === '') { + invalid.push(`${param} (empty string)`); + } + } + if (missing.length > 0) { + throw new Error(`Missing required parameters for ${toolName}: ${missing.join(', ')}. Please provide the required parameters to use this tool.`); + } + if (invalid.length > 0) { + throw new Error(`Invalid parameters for ${toolName}: ${invalid.join(', ')}. String parameters cannot be empty.`); + } + } + validateExtractedArgs(toolName, args) { + if (!args || typeof args !== 'object') { + return false; + } + const allTools = [...tools_1.n8nDocumentationToolsFinal, ...tools_n8n_manager_1.n8nManagementTools]; + const tool = allTools.find(t => t.name === toolName); + if (!tool || !tool.inputSchema) { + return true; + } + const schema = tool.inputSchema; + const required = schema.required || []; + const properties = schema.properties || {}; + for (const requiredField of required) { + if (!(requiredField in args)) { + logger_1.logger.debug(`Extracted args missing required field: ${requiredField}`, { + toolName, + extractedArgs: args, + required + }); + return false; + } + } + for (const [fieldName, fieldValue] of Object.entries(args)) { + if (properties[fieldName]) { + const expectedType = properties[fieldName].type; + const actualType = Array.isArray(fieldValue) ? 'array' : typeof fieldValue; + if (expectedType && expectedType !== actualType) { + if (expectedType === 'number' && actualType === 'string' && !isNaN(Number(fieldValue))) { + continue; + } + logger_1.logger.debug(`Extracted args field type mismatch: ${fieldName}`, { + toolName, + expectedType, + actualType, + fieldValue + }); + return false; + } + } + } + if (schema.additionalProperties === false) { + const allowedFields = Object.keys(properties); + const extraFields = Object.keys(args).filter(field => !allowedFields.includes(field)); + if (extraFields.length > 0) { + logger_1.logger.debug(`Extracted args have extra fields`, { + toolName, + extraFields, + allowedFields + }); + } + } + return true; + } + async executeTool(name, args) { + args = args || {}; + const disabledTools = this.getDisabledTools(); + if (disabledTools.has(name)) { + throw new Error(`Tool '${name}' is disabled via DISABLED_TOOLS environment variable`); + } + logger_1.logger.info(`Tool execution: ${name}`, { + args: typeof args === 'object' ? JSON.stringify(args) : args, + argsType: typeof args, + argsKeys: typeof args === 'object' ? Object.keys(args) : 'not-object' + }); + if (typeof args !== 'object' || args === null) { + throw new Error(`Invalid arguments for tool ${name}: expected object, got ${typeof args}`); + } + switch (name) { + case 'tools_documentation': + return this.getToolsDocumentation(args.topic, args.depth); + case 'search_nodes': + this.validateToolParams(name, args, ['query']); + const limit = args.limit !== undefined ? Number(args.limit) || 20 : 20; + return this.searchNodes(args.query, limit, { mode: args.mode, includeExamples: args.includeExamples }); + case 'get_node': + this.validateToolParams(name, args, ['nodeType']); + if (args.mode === 'docs') { + return this.getNodeDocumentation(args.nodeType); + } + if (args.mode === 'search_properties') { + if (!args.propertyQuery) { + throw new Error('propertyQuery is required for mode=search_properties'); + } + const maxResults = args.maxPropertyResults !== undefined ? Number(args.maxPropertyResults) || 20 : 20; + return this.searchNodeProperties(args.nodeType, args.propertyQuery, maxResults); + } + return this.getNode(args.nodeType, args.detail, args.mode, args.includeTypeInfo, args.includeExamples, args.fromVersion, args.toVersion); + case 'validate_node': + this.validateToolParams(name, args, ['nodeType', 'config']); + if (typeof args.config !== 'object' || args.config === null) { + logger_1.logger.warn(`validate_node called with invalid config type: ${typeof args.config}`); + const validationMode = args.mode || 'full'; + if (validationMode === 'minimal') { + return { + nodeType: args.nodeType || 'unknown', + displayName: 'Unknown Node', + valid: false, + missingRequiredFields: [ + 'Invalid config format - expected object', + '🔧 RECOVERY: Use format { "resource": "...", "operation": "..." } or {} for empty config' + ] + }; + } + return { + nodeType: args.nodeType || 'unknown', + workflowNodeType: args.nodeType || 'unknown', + displayName: 'Unknown Node', + valid: false, + errors: [{ + type: 'config', + property: 'config', + message: 'Invalid config format - expected object', + fix: 'Provide config as an object with node properties' + }], + warnings: [], + suggestions: [ + '🔧 RECOVERY: Invalid config detected. Fix with:', + ' • Ensure config is an object: { "resource": "...", "operation": "..." }', + ' • Use get_node to see required fields for this node type', + ' • Check if the node type is correct before configuring it' + ], + summary: { + hasErrors: true, + errorCount: 1, + warningCount: 0, + suggestionCount: 3 + } + }; + } + const validationMode = args.mode || 'full'; + if (validationMode === 'minimal') { + return this.validateNodeMinimal(args.nodeType, args.config); + } + return this.validateNodeConfig(args.nodeType, args.config, 'operation', args.profile); + case 'get_template': + this.validateToolParams(name, args, ['templateId']); + const templateId = Number(args.templateId); + const templateMode = args.mode || 'full'; + return this.getTemplate(templateId, templateMode); + case 'search_templates': { + const searchMode = args.searchMode || 'keyword'; + const searchLimit = Math.min(Math.max(Number(args.limit) || 20, 1), 100); + const searchOffset = Math.max(Number(args.offset) || 0, 0); + switch (searchMode) { + case 'by_nodes': + if (!args.nodeTypes || !Array.isArray(args.nodeTypes) || args.nodeTypes.length === 0) { + throw new Error('nodeTypes array is required for searchMode=by_nodes'); + } + return this.listNodeTemplates(args.nodeTypes, searchLimit, searchOffset); + case 'by_task': + if (!args.task) { + throw new Error('task is required for searchMode=by_task'); + } + return this.getTemplatesForTask(args.task, searchLimit, searchOffset); + case 'by_metadata': + return this.searchTemplatesByMetadata({ + category: args.category, + complexity: args.complexity, + maxSetupMinutes: args.maxSetupMinutes ? Number(args.maxSetupMinutes) : undefined, + minSetupMinutes: args.minSetupMinutes ? Number(args.minSetupMinutes) : undefined, + requiredService: args.requiredService, + targetAudience: args.targetAudience + }, searchLimit, searchOffset); + case 'keyword': + default: + if (!args.query) { + throw new Error('query is required for searchMode=keyword'); + } + const searchFields = args.fields; + return this.searchTemplates(args.query, searchLimit, searchOffset, searchFields); + } + } + case 'validate_workflow': + this.validateToolParams(name, args, ['workflow']); + return this.validateWorkflow(args.workflow, args.options); + case 'n8n_create_workflow': + this.validateToolParams(name, args, ['name', 'nodes', 'connections']); + return n8nHandlers.handleCreateWorkflow(args, this.instanceContext); + case 'n8n_get_workflow': { + this.validateToolParams(name, args, ['id']); + const workflowMode = args.mode || 'full'; + switch (workflowMode) { + case 'details': + return n8nHandlers.handleGetWorkflowDetails(args, this.instanceContext); + case 'structure': + return n8nHandlers.handleGetWorkflowStructure(args, this.instanceContext); + case 'minimal': + return n8nHandlers.handleGetWorkflowMinimal(args, this.instanceContext); + case 'full': + default: + return n8nHandlers.handleGetWorkflow(args, this.instanceContext); + } + } + case 'n8n_update_full_workflow': + this.validateToolParams(name, args, ['id']); + return n8nHandlers.handleUpdateWorkflow(args, this.repository, this.instanceContext); + case 'n8n_update_partial_workflow': + this.validateToolParams(name, args, ['id', 'operations']); + return (0, handlers_workflow_diff_1.handleUpdatePartialWorkflow)(args, this.repository, this.instanceContext); + case 'n8n_delete_workflow': + this.validateToolParams(name, args, ['id']); + return n8nHandlers.handleDeleteWorkflow(args, this.instanceContext); + case 'n8n_list_workflows': + return n8nHandlers.handleListWorkflows(args, this.instanceContext); + case 'n8n_validate_workflow': + this.validateToolParams(name, args, ['id']); + await this.ensureInitialized(); + if (!this.repository) + throw new Error('Repository not initialized'); + return n8nHandlers.handleValidateWorkflow(args, this.repository, this.instanceContext); + case 'n8n_autofix_workflow': + this.validateToolParams(name, args, ['id']); + await this.ensureInitialized(); + if (!this.repository) + throw new Error('Repository not initialized'); + return n8nHandlers.handleAutofixWorkflow(args, this.repository, this.instanceContext); + case 'n8n_test_workflow': + this.validateToolParams(name, args, ['workflowId']); + return n8nHandlers.handleTestWorkflow(args, this.instanceContext); + case 'n8n_executions': { + this.validateToolParams(name, args, ['action']); + const execAction = args.action; + switch (execAction) { + case 'get': + if (!args.id) { + throw new Error('id is required for action=get'); + } + return n8nHandlers.handleGetExecution(args, this.instanceContext); + case 'list': + return n8nHandlers.handleListExecutions(args, this.instanceContext); + case 'delete': + if (!args.id) { + throw new Error('id is required for action=delete'); + } + return n8nHandlers.handleDeleteExecution(args, this.instanceContext); + default: + throw new Error(`Unknown action: ${execAction}. Valid actions: get, list, delete`); + } + } + case 'n8n_health_check': + if (args.mode === 'diagnostic') { + return n8nHandlers.handleDiagnostic({ params: { arguments: args } }, this.instanceContext); + } + return n8nHandlers.handleHealthCheck(this.instanceContext); + case 'n8n_workflow_versions': + this.validateToolParams(name, args, ['mode']); + return n8nHandlers.handleWorkflowVersions(args, this.repository, this.instanceContext); + case 'n8n_deploy_template': + this.validateToolParams(name, args, ['templateId']); + await this.ensureInitialized(); + if (!this.templateService) + throw new Error('Template service not initialized'); + if (!this.repository) + throw new Error('Repository not initialized'); + return n8nHandlers.handleDeployTemplate(args, this.templateService, this.repository, this.instanceContext); + default: + throw new Error(`Unknown tool: ${name}`); + } + } + async listNodes(filters = {}) { + await this.ensureInitialized(); + let query = 'SELECT * FROM nodes WHERE 1=1'; + const params = []; + if (filters.package) { + const packageVariants = [ + filters.package, + `@n8n/${filters.package}`, + filters.package.replace('@n8n/', '') + ]; + query += ' AND package_name IN (' + packageVariants.map(() => '?').join(',') + ')'; + params.push(...packageVariants); + } + if (filters.category) { + query += ' AND category = ?'; + params.push(filters.category); + } + if (filters.developmentStyle) { + query += ' AND development_style = ?'; + params.push(filters.developmentStyle); + } + if (filters.isAITool !== undefined) { + query += ' AND is_ai_tool = ?'; + params.push(filters.isAITool ? 1 : 0); + } + query += ' ORDER BY display_name'; + if (filters.limit) { + query += ' LIMIT ?'; + params.push(filters.limit); + } + const nodes = this.db.prepare(query).all(...params); + return { + nodes: nodes.map(node => ({ + nodeType: node.node_type, + displayName: node.display_name, + description: node.description, + category: node.category, + package: node.package_name, + developmentStyle: node.development_style, + isAITool: Number(node.is_ai_tool) === 1, + isTrigger: Number(node.is_trigger) === 1, + isVersioned: Number(node.is_versioned) === 1, + })), + totalCount: nodes.length, + }; + } + async getNodeInfo(nodeType) { + await this.ensureInitialized(); + if (!this.repository) + throw new Error('Repository not initialized'); + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + let node = this.repository.getNode(normalizedType); + if (!node && normalizedType !== nodeType) { + node = this.repository.getNode(nodeType); + } + if (!node) { + const alternatives = (0, node_utils_1.getNodeTypeAlternatives)(normalizedType); + for (const alt of alternatives) { + const found = this.repository.getNode(alt); + if (found) { + node = found; + break; + } + } + } + if (!node) { + throw new Error(`Node ${nodeType} not found`); + } + const aiToolCapabilities = { + canBeUsedAsTool: true, + hasUsableAsToolProperty: node.isAITool ?? false, + requiresEnvironmentVariable: !(node.isAITool ?? false) && node.package !== 'n8n-nodes-base', + toolConnectionType: 'ai_tool', + commonToolUseCases: this.getCommonAIToolUseCases(node.nodeType), + environmentRequirement: node.package && node.package !== 'n8n-nodes-base' ? + 'N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true' : + null + }; + let outputs = undefined; + if (node.outputNames && Array.isArray(node.outputNames) && node.outputNames.length > 0) { + outputs = node.outputNames.map((name, index) => { + const descriptions = this.getOutputDescriptions(node.nodeType, name, index); + return { + index, + name, + description: descriptions?.description ?? '', + connectionGuidance: descriptions?.connectionGuidance ?? '' + }; + }); + } + return { + ...node, + workflowNodeType: (0, node_utils_1.getWorkflowNodeType)(node.package ?? 'n8n-nodes-base', node.nodeType), + aiToolCapabilities, + outputs + }; + } + async searchNodes(query, limit = 20, options) { + await this.ensureInitialized(); + if (!this.db) + throw new Error('Database not initialized'); + let normalizedQuery = query; + if (query.includes('n8n-nodes-base.') || query.includes('@n8n/n8n-nodes-langchain.')) { + normalizedQuery = query + .replace(/n8n-nodes-base\./g, 'nodes-base.') + .replace(/@n8n\/n8n-nodes-langchain\./g, 'nodes-langchain.'); + } + const searchMode = options?.mode || 'OR'; + const ftsExists = this.db.prepare(` + SELECT name FROM sqlite_master + WHERE type='table' AND name='nodes_fts' + `).get(); + if (ftsExists) { + logger_1.logger.debug(`Using FTS5 search with includeExamples=${options?.includeExamples}`); + return this.searchNodesFTS(normalizedQuery, limit, searchMode, options); + } + else { + logger_1.logger.debug('Using LIKE search (no FTS5)'); + return this.searchNodesLIKE(normalizedQuery, limit, options); + } + } + async searchNodesFTS(query, limit, mode, options) { + if (!this.db) + throw new Error('Database not initialized'); + const cleanedQuery = query.trim(); + if (!cleanedQuery) { + return { query, results: [], totalCount: 0 }; + } + if (mode === 'FUZZY') { + return this.searchNodesFuzzy(cleanedQuery, limit); + } + let ftsQuery; + if (cleanedQuery.startsWith('"') && cleanedQuery.endsWith('"')) { + ftsQuery = cleanedQuery; + } + else { + const words = cleanedQuery.split(/\s+/).filter(w => w.length > 0); + switch (mode) { + case 'AND': + ftsQuery = words.join(' AND '); + break; + case 'OR': + default: + ftsQuery = words.join(' OR '); + break; + } + } + try { + const nodes = this.db.prepare(` + SELECT + n.*, + rank + FROM nodes n + JOIN nodes_fts ON n.rowid = nodes_fts.rowid + WHERE nodes_fts MATCH ? + ORDER BY + CASE + WHEN LOWER(n.display_name) = LOWER(?) THEN 0 + WHEN LOWER(n.display_name) LIKE LOWER(?) THEN 1 + WHEN LOWER(n.node_type) LIKE LOWER(?) THEN 2 + ELSE 3 + END, + rank, + n.display_name + LIMIT ? + `).all(ftsQuery, cleanedQuery, `%${cleanedQuery}%`, `%${cleanedQuery}%`, limit); + const scoredNodes = nodes.map(node => { + const relevanceScore = this.calculateRelevanceScore(node, cleanedQuery); + return { ...node, relevanceScore }; + }); + scoredNodes.sort((a, b) => { + if (a.display_name.toLowerCase() === cleanedQuery.toLowerCase()) + return -1; + if (b.display_name.toLowerCase() === cleanedQuery.toLowerCase()) + return 1; + if (a.relevanceScore !== b.relevanceScore) { + return b.relevanceScore - a.relevanceScore; + } + return a.rank - b.rank; + }); + const hasHttpRequest = scoredNodes.some(n => n.node_type === 'nodes-base.httpRequest'); + if (cleanedQuery.toLowerCase().includes('http') && !hasHttpRequest) { + logger_1.logger.debug('FTS missed HTTP Request node, augmenting with LIKE search'); + return this.searchNodesLIKE(query, limit); + } + const result = { + query, + results: scoredNodes.map(node => ({ + nodeType: node.node_type, + workflowNodeType: (0, node_utils_1.getWorkflowNodeType)(node.package_name, node.node_type), + displayName: node.display_name, + description: node.description, + category: node.category, + package: node.package_name, + relevance: this.calculateRelevance(node, cleanedQuery) + })), + totalCount: scoredNodes.length + }; + if (mode !== 'OR') { + result.mode = mode; + } + if (options && options.includeExamples) { + try { + for (const nodeResult of result.results) { + const examples = this.db.prepare(` + SELECT + parameters_json, + template_name, + template_views + FROM template_node_configs + WHERE node_type = ? + ORDER BY rank + LIMIT 2 + `).all(nodeResult.workflowNodeType); + if (examples.length > 0) { + nodeResult.examples = examples.map((ex) => ({ + configuration: JSON.parse(ex.parameters_json), + template: ex.template_name, + views: ex.template_views + })); + } + } + } + catch (error) { + logger_1.logger.error(`Failed to add examples:`, error); + } + } + telemetry_1.telemetry.trackSearchQuery(query, scoredNodes.length, mode ?? 'OR'); + return result; + } + catch (error) { + logger_1.logger.warn('FTS5 search failed, falling back to LIKE search:', error.message); + if (error.message.includes('syntax error') || error.message.includes('fts5')) { + logger_1.logger.warn(`FTS5 syntax error for query "${query}" in mode ${mode}`); + const likeResult = await this.searchNodesLIKE(query, limit); + telemetry_1.telemetry.trackSearchQuery(query, likeResult.results?.length ?? 0, `${mode}_LIKE_FALLBACK`); + return { + ...likeResult, + mode + }; + } + return this.searchNodesLIKE(query, limit); + } + } + async searchNodesFuzzy(query, limit) { + if (!this.db) + throw new Error('Database not initialized'); + const words = query.toLowerCase().split(/\s+/).filter(w => w.length > 0); + if (words.length === 0) { + return { query, results: [], totalCount: 0, mode: 'FUZZY' }; + } + const candidateNodes = this.db.prepare(` + SELECT * FROM nodes + `).all(); + const scoredNodes = candidateNodes.map(node => { + const score = this.calculateFuzzyScore(node, query); + return { node, score }; + }); + const matchingNodes = scoredNodes + .filter(item => item.score >= 200) + .sort((a, b) => b.score - a.score) + .slice(0, limit) + .map(item => item.node); + if (matchingNodes.length === 0) { + const topScores = scoredNodes + .sort((a, b) => b.score - a.score) + .slice(0, 5); + logger_1.logger.debug(`FUZZY search for "${query}" - no matches above 400. Top scores:`, topScores.map(s => ({ name: s.node.display_name, score: s.score }))); + } + return { + query, + mode: 'FUZZY', + results: matchingNodes.map(node => ({ + nodeType: node.node_type, + workflowNodeType: (0, node_utils_1.getWorkflowNodeType)(node.package_name, node.node_type), + displayName: node.display_name, + description: node.description, + category: node.category, + package: node.package_name + })), + totalCount: matchingNodes.length + }; + } + calculateFuzzyScore(node, query) { + const queryLower = query.toLowerCase(); + const displayNameLower = node.display_name.toLowerCase(); + const nodeTypeLower = node.node_type.toLowerCase(); + const nodeTypeClean = nodeTypeLower.replace(/^nodes-base\./, '').replace(/^nodes-langchain\./, ''); + if (displayNameLower === queryLower || nodeTypeClean === queryLower) { + return 1000; + } + const nameDistance = this.getEditDistance(queryLower, displayNameLower); + const typeDistance = this.getEditDistance(queryLower, nodeTypeClean); + const nameWords = displayNameLower.split(/\s+/); + let minWordDistance = Infinity; + for (const word of nameWords) { + const distance = this.getEditDistance(queryLower, word); + if (distance < minWordDistance) { + minWordDistance = distance; + } + } + const bestDistance = Math.min(nameDistance, typeDistance, minWordDistance); + let matchedLen = queryLower.length; + if (minWordDistance === bestDistance) { + for (const word of nameWords) { + if (this.getEditDistance(queryLower, word) === minWordDistance) { + matchedLen = Math.max(queryLower.length, word.length); + break; + } + } + } + else if (typeDistance === bestDistance) { + matchedLen = Math.max(queryLower.length, nodeTypeClean.length); + } + else { + matchedLen = Math.max(queryLower.length, displayNameLower.length); + } + const similarity = 1 - (bestDistance / matchedLen); + if (displayNameLower.includes(queryLower) || nodeTypeClean.includes(queryLower)) { + return 800 + (similarity * 100); + } + if (displayNameLower.startsWith(queryLower) || + nodeTypeClean.startsWith(queryLower) || + nameWords.some(w => w.startsWith(queryLower))) { + return 700 + (similarity * 100); + } + if (bestDistance <= 2) { + return 500 + ((2 - bestDistance) * 100) + (similarity * 50); + } + if (bestDistance <= 3 && queryLower.length >= 4) { + return 400 + ((3 - bestDistance) * 50) + (similarity * 50); + } + return similarity * 300; + } + getEditDistance(s1, s2) { + const m = s1.length; + const n = s2.length; + const dp = Array(m + 1).fill(null).map(() => Array(n + 1).fill(0)); + for (let i = 0; i <= m; i++) + dp[i][0] = i; + for (let j = 0; j <= n; j++) + dp[0][j] = j; + for (let i = 1; i <= m; i++) { + for (let j = 1; j <= n; j++) { + if (s1[i - 1] === s2[j - 1]) { + dp[i][j] = dp[i - 1][j - 1]; + } + else { + dp[i][j] = 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]); + } + } + } + return dp[m][n]; + } + async searchNodesLIKE(query, limit, options) { + if (!this.db) + throw new Error('Database not initialized'); + if (query.startsWith('"') && query.endsWith('"')) { + const exactPhrase = query.slice(1, -1); + const nodes = this.db.prepare(` + SELECT * FROM nodes + WHERE node_type LIKE ? OR display_name LIKE ? OR description LIKE ? + LIMIT ? + `).all(`%${exactPhrase}%`, `%${exactPhrase}%`, `%${exactPhrase}%`, limit * 3); + const rankedNodes = this.rankSearchResults(nodes, exactPhrase, limit); + const result = { + query, + results: rankedNodes.map(node => ({ + nodeType: node.node_type, + workflowNodeType: (0, node_utils_1.getWorkflowNodeType)(node.package_name, node.node_type), + displayName: node.display_name, + description: node.description, + category: node.category, + package: node.package_name + })), + totalCount: rankedNodes.length + }; + if (options?.includeExamples) { + for (const nodeResult of result.results) { + try { + const examples = this.db.prepare(` + SELECT + parameters_json, + template_name, + template_views + FROM template_node_configs + WHERE node_type = ? + ORDER BY rank + LIMIT 2 + `).all(nodeResult.workflowNodeType); + if (examples.length > 0) { + nodeResult.examples = examples.map((ex) => ({ + configuration: JSON.parse(ex.parameters_json), + template: ex.template_name, + views: ex.template_views + })); + } + } + catch (error) { + logger_1.logger.warn(`Failed to fetch examples for ${nodeResult.nodeType}:`, error.message); + } + } + } + return result; + } + const words = query.toLowerCase().split(/\s+/).filter(w => w.length > 0); + if (words.length === 0) { + return { query, results: [], totalCount: 0 }; + } + const conditions = words.map(() => '(node_type LIKE ? OR display_name LIKE ? OR description LIKE ?)').join(' OR '); + const params = words.flatMap(w => [`%${w}%`, `%${w}%`, `%${w}%`]); + params.push(limit * 3); + const nodes = this.db.prepare(` + SELECT DISTINCT * FROM nodes + WHERE ${conditions} + LIMIT ? + `).all(...params); + const rankedNodes = this.rankSearchResults(nodes, query, limit); + const result = { + query, + results: rankedNodes.map(node => ({ + nodeType: node.node_type, + workflowNodeType: (0, node_utils_1.getWorkflowNodeType)(node.package_name, node.node_type), + displayName: node.display_name, + description: node.description, + category: node.category, + package: node.package_name + })), + totalCount: rankedNodes.length + }; + if (options?.includeExamples) { + for (const nodeResult of result.results) { + try { + const examples = this.db.prepare(` + SELECT + parameters_json, + template_name, + template_views + FROM template_node_configs + WHERE node_type = ? + ORDER BY rank + LIMIT 2 + `).all(nodeResult.workflowNodeType); + if (examples.length > 0) { + nodeResult.examples = examples.map((ex) => ({ + configuration: JSON.parse(ex.parameters_json), + template: ex.template_name, + views: ex.template_views + })); + } + } + catch (error) { + logger_1.logger.warn(`Failed to fetch examples for ${nodeResult.nodeType}:`, error.message); + } + } + } + return result; + } + calculateRelevance(node, query) { + const lowerQuery = query.toLowerCase(); + if (node.node_type.toLowerCase().includes(lowerQuery)) + return 'high'; + if (node.display_name.toLowerCase().includes(lowerQuery)) + return 'high'; + if (node.description?.toLowerCase().includes(lowerQuery)) + return 'medium'; + return 'low'; + } + calculateRelevanceScore(node, query) { + const query_lower = query.toLowerCase(); + const name_lower = node.display_name.toLowerCase(); + const type_lower = node.node_type.toLowerCase(); + const type_without_prefix = type_lower.replace(/^nodes-base\./, '').replace(/^nodes-langchain\./, ''); + let score = 0; + if (name_lower === query_lower) { + score = 1000; + } + else if (type_without_prefix === query_lower) { + score = 950; + } + else if (query_lower === 'webhook' && node.node_type === 'nodes-base.webhook') { + score = 900; + } + else if ((query_lower === 'http' || query_lower === 'http request' || query_lower === 'http call') && node.node_type === 'nodes-base.httpRequest') { + score = 900; + } + else if (query_lower.includes('http') && query_lower.includes('call') && node.node_type === 'nodes-base.httpRequest') { + score = 890; + } + else if (query_lower.includes('http') && node.node_type === 'nodes-base.httpRequest') { + score = 850; + } + else if (query_lower.includes('webhook') && node.node_type === 'nodes-base.webhook') { + score = 850; + } + else if (name_lower.startsWith(query_lower)) { + score = 800; + } + else if (new RegExp(`\\b${query_lower}\\b`, 'i').test(node.display_name)) { + score = 700; + } + else if (name_lower.includes(query_lower)) { + score = 600; + } + else if (type_without_prefix.includes(query_lower)) { + score = 500; + } + else if (node.description?.toLowerCase().includes(query_lower)) { + score = 400; + } + return score; + } + rankSearchResults(nodes, query, limit) { + const query_lower = query.toLowerCase(); + const scoredNodes = nodes.map(node => { + const name_lower = node.display_name.toLowerCase(); + const type_lower = node.node_type.toLowerCase(); + const type_without_prefix = type_lower.replace(/^nodes-base\./, '').replace(/^nodes-langchain\./, ''); + let score = 0; + if (name_lower === query_lower) { + score = 1000; + } + else if (type_without_prefix === query_lower) { + score = 950; + } + else if (query_lower === 'webhook' && node.node_type === 'nodes-base.webhook') { + score = 900; + } + else if ((query_lower === 'http' || query_lower === 'http request' || query_lower === 'http call') && node.node_type === 'nodes-base.httpRequest') { + score = 900; + } + else if (query_lower.includes('webhook') && node.node_type === 'nodes-base.webhook') { + score = 850; + } + else if (query_lower.includes('http') && node.node_type === 'nodes-base.httpRequest') { + score = 850; + } + else if (name_lower.startsWith(query_lower)) { + score = 800; + } + else if (new RegExp(`\\b${query_lower}\\b`, 'i').test(node.display_name)) { + score = 700; + } + else if (name_lower.includes(query_lower)) { + score = 600; + } + else if (type_without_prefix.includes(query_lower)) { + score = 500; + } + else if (node.description?.toLowerCase().includes(query_lower)) { + score = 400; + } + const words = query_lower.split(/\s+/).filter(w => w.length > 0); + if (words.length > 1) { + const allWordsInName = words.every(word => name_lower.includes(word)); + const allWordsInDesc = words.every(word => node.description?.toLowerCase().includes(word)); + if (allWordsInName) + score += 200; + else if (allWordsInDesc) + score += 100; + if (query_lower === 'http call' && name_lower === 'http request') { + score = 920; + } + } + return { node, score }; + }); + scoredNodes.sort((a, b) => { + if (a.score !== b.score) { + return b.score - a.score; + } + return a.node.display_name.localeCompare(b.node.display_name); + }); + return scoredNodes.slice(0, limit).map(item => item.node); + } + async listAITools() { + await this.ensureInitialized(); + if (!this.repository) + throw new Error('Repository not initialized'); + const tools = this.repository.getAITools(); + const aiCount = this.db.prepare('SELECT COUNT(*) as ai_count FROM nodes WHERE is_ai_tool = 1').get(); + return { + tools, + totalCount: tools.length, + requirements: { + environmentVariable: 'N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true', + nodeProperty: 'usableAsTool: true', + }, + usage: { + description: 'These nodes have the usableAsTool property set to true, making them optimized for AI agent usage.', + note: 'ANY node in n8n can be used as an AI tool by connecting it to the ai_tool port of an AI Agent node.', + examples: [ + 'Regular nodes like Slack, Google Sheets, or HTTP Request can be used as tools', + 'Connect any node to an AI Agent\'s tool port to make it available for AI-driven automation', + 'Community nodes require the environment variable to be set' + ] + } + }; + } + async getNodeDocumentation(nodeType) { + await this.ensureInitialized(); + if (!this.db) + throw new Error('Database not initialized'); + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + let node = this.db.prepare(` + SELECT node_type, display_name, documentation, description + FROM nodes + WHERE node_type = ? + `).get(normalizedType); + if (!node && normalizedType !== nodeType) { + node = this.db.prepare(` + SELECT node_type, display_name, documentation, description + FROM nodes + WHERE node_type = ? + `).get(nodeType); + } + if (!node) { + const alternatives = (0, node_utils_1.getNodeTypeAlternatives)(normalizedType); + for (const alt of alternatives) { + node = this.db.prepare(` + SELECT node_type, display_name, documentation, description + FROM nodes + WHERE node_type = ? + `).get(alt); + if (node) + break; + } + } + if (!node) { + throw new Error(`Node ${nodeType} not found`); + } + if (!node.documentation) { + const essentials = await this.getNodeEssentials(nodeType); + return { + nodeType: node.node_type, + displayName: node.display_name || 'Unknown Node', + documentation: ` +# ${node.display_name || 'Unknown Node'} + +${node.description || 'No description available.'} + +## Common Properties + +${essentials?.commonProperties?.length > 0 ? + essentials.commonProperties.map((p) => `### ${p.displayName || 'Property'}\n${p.description || `Type: ${p.type || 'unknown'}`}`).join('\n\n') : + 'No common properties available.'} + +## Note +Full documentation is being prepared. For now, use get_node_essentials for configuration help. +`, + hasDocumentation: false + }; + } + return { + nodeType: node.node_type, + displayName: node.display_name || 'Unknown Node', + documentation: node.documentation, + hasDocumentation: true, + }; + } + async getDatabaseStatistics() { + await this.ensureInitialized(); + if (!this.db) + throw new Error('Database not initialized'); + const stats = this.db.prepare(` + SELECT + COUNT(*) as total, + SUM(is_ai_tool) as ai_tools, + SUM(is_trigger) as triggers, + SUM(is_versioned) as versioned, + SUM(CASE WHEN documentation IS NOT NULL THEN 1 ELSE 0 END) as with_docs, + COUNT(DISTINCT package_name) as packages, + COUNT(DISTINCT category) as categories + FROM nodes + `).get(); + const packages = this.db.prepare(` + SELECT package_name, COUNT(*) as count + FROM nodes + GROUP BY package_name + `).all(); + const templateStats = this.db.prepare(` + SELECT + COUNT(*) as total_templates, + AVG(views) as avg_views, + MIN(views) as min_views, + MAX(views) as max_views + FROM templates + `).get(); + return { + totalNodes: stats.total, + totalTemplates: templateStats.total_templates || 0, + statistics: { + aiTools: stats.ai_tools, + triggers: stats.triggers, + versionedNodes: stats.versioned, + nodesWithDocumentation: stats.with_docs, + documentationCoverage: Math.round((stats.with_docs / stats.total) * 100) + '%', + uniquePackages: stats.packages, + uniqueCategories: stats.categories, + templates: { + total: templateStats.total_templates || 0, + avgViews: Math.round(templateStats.avg_views || 0), + minViews: templateStats.min_views || 0, + maxViews: templateStats.max_views || 0 + } + }, + packageBreakdown: packages.map(pkg => ({ + package: pkg.package_name, + nodeCount: pkg.count, + })), + }; + } + async getNodeEssentials(nodeType, includeExamples) { + await this.ensureInitialized(); + if (!this.repository) + throw new Error('Repository not initialized'); + const cacheKey = `essentials:${nodeType}:${includeExamples ? 'withExamples' : 'basic'}`; + const cached = this.cache.get(cacheKey); + if (cached) + return cached; + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + let node = this.repository.getNode(normalizedType); + if (!node && normalizedType !== nodeType) { + node = this.repository.getNode(nodeType); + } + if (!node) { + const alternatives = (0, node_utils_1.getNodeTypeAlternatives)(normalizedType); + for (const alt of alternatives) { + const found = this.repository.getNode(alt); + if (found) { + node = found; + break; + } + } + } + if (!node) { + throw new Error(`Node ${nodeType} not found`); + } + const allProperties = node.properties || []; + const essentials = property_filter_1.PropertyFilter.getEssentials(allProperties, node.nodeType); + const operations = node.operations || []; + const latestVersion = node.version ?? '1'; + const result = { + nodeType: node.nodeType, + workflowNodeType: (0, node_utils_1.getWorkflowNodeType)(node.package ?? 'n8n-nodes-base', node.nodeType), + displayName: node.displayName, + description: node.description, + category: node.category, + version: latestVersion, + isVersioned: node.isVersioned ?? false, + versionNotice: `⚠️ Use typeVersion: ${latestVersion} when creating this node`, + requiredProperties: essentials.required, + commonProperties: essentials.common, + operations: operations.map((op) => ({ + name: op.name || op.operation, + description: op.description, + action: op.action, + resource: op.resource + })), + metadata: { + totalProperties: allProperties.length, + isAITool: node.isAITool ?? false, + isTrigger: node.isTrigger ?? false, + isWebhook: node.isWebhook ?? false, + hasCredentials: node.credentials ? true : false, + package: node.package ?? 'n8n-nodes-base', + developmentStyle: node.developmentStyle ?? 'programmatic' + } + }; + if (includeExamples) { + try { + const examples = this.db.prepare(` + SELECT + parameters_json, + template_name, + template_views, + complexity, + use_cases, + has_credentials, + has_expressions + FROM template_node_configs + WHERE node_type = ? + ORDER BY rank + LIMIT 3 + `).all(result.workflowNodeType); + if (examples.length > 0) { + result.examples = examples.map((ex) => ({ + configuration: JSON.parse(ex.parameters_json), + source: { + template: ex.template_name, + views: ex.template_views, + complexity: ex.complexity + }, + useCases: ex.use_cases ? JSON.parse(ex.use_cases).slice(0, 2) : [], + metadata: { + hasCredentials: ex.has_credentials === 1, + hasExpressions: ex.has_expressions === 1 + } + })); + result.examplesCount = examples.length; + } + else { + result.examples = []; + result.examplesCount = 0; + } + } + catch (error) { + logger_1.logger.warn(`Failed to fetch examples for ${nodeType}:`, error.message); + result.examples = []; + result.examplesCount = 0; + } + } + this.cache.set(cacheKey, result, 3600); + return result; + } + async getNode(nodeType, detail = 'standard', mode = 'info', includeTypeInfo, includeExamples, fromVersion, toVersion) { + await this.ensureInitialized(); + if (!this.repository) + throw new Error('Repository not initialized'); + const validDetailLevels = ['minimal', 'standard', 'full']; + const validModes = ['info', 'versions', 'compare', 'breaking', 'migrations']; + if (!validDetailLevels.includes(detail)) { + throw new Error(`get_node: Invalid detail level "${detail}". Valid options: ${validDetailLevels.join(', ')}`); + } + if (!validModes.includes(mode)) { + throw new Error(`get_node: Invalid mode "${mode}". Valid options: ${validModes.join(', ')}`); + } + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + if (mode !== 'info') { + return this.handleVersionMode(normalizedType, mode, fromVersion, toVersion); + } + return this.handleInfoMode(normalizedType, detail, includeTypeInfo, includeExamples); + } + async handleInfoMode(nodeType, detail, includeTypeInfo, includeExamples) { + switch (detail) { + case 'minimal': { + let node = this.repository.getNode(nodeType); + if (!node) { + const alternatives = (0, node_utils_1.getNodeTypeAlternatives)(nodeType); + for (const alt of alternatives) { + const found = this.repository.getNode(alt); + if (found) { + node = found; + break; + } + } + } + if (!node) { + throw new Error(`Node ${nodeType} not found`); + } + return { + nodeType: node.nodeType, + workflowNodeType: (0, node_utils_1.getWorkflowNodeType)(node.package ?? 'n8n-nodes-base', node.nodeType), + displayName: node.displayName, + description: node.description, + category: node.category, + package: node.package, + isAITool: node.isAITool, + isTrigger: node.isTrigger, + isWebhook: node.isWebhook + }; + } + case 'standard': { + const essentials = await this.getNodeEssentials(nodeType, includeExamples); + const versionSummary = this.getVersionSummary(nodeType); + if (includeTypeInfo) { + essentials.requiredProperties = this.enrichPropertiesWithTypeInfo(essentials.requiredProperties); + essentials.commonProperties = this.enrichPropertiesWithTypeInfo(essentials.commonProperties); + } + return { + ...essentials, + versionInfo: versionSummary + }; + } + case 'full': { + const fullInfo = await this.getNodeInfo(nodeType); + const versionSummary = this.getVersionSummary(nodeType); + if (includeTypeInfo && fullInfo.properties) { + fullInfo.properties = this.enrichPropertiesWithTypeInfo(fullInfo.properties); + } + return { + ...fullInfo, + versionInfo: versionSummary + }; + } + default: + throw new Error(`Unknown detail level: ${detail}`); + } + } + async handleVersionMode(nodeType, mode, fromVersion, toVersion) { + switch (mode) { + case 'versions': + return this.getVersionHistory(nodeType); + case 'compare': + if (!fromVersion) { + throw new Error(`get_node: fromVersion is required for compare mode (nodeType: ${nodeType})`); + } + return this.compareVersions(nodeType, fromVersion, toVersion); + case 'breaking': + if (!fromVersion) { + throw new Error(`get_node: fromVersion is required for breaking mode (nodeType: ${nodeType})`); + } + return this.getBreakingChanges(nodeType, fromVersion, toVersion); + case 'migrations': + if (!fromVersion || !toVersion) { + throw new Error(`get_node: Both fromVersion and toVersion are required for migrations mode (nodeType: ${nodeType})`); + } + return this.getMigrations(nodeType, fromVersion, toVersion); + default: + throw new Error(`get_node: Unknown mode: ${mode} (nodeType: ${nodeType})`); + } + } + getVersionSummary(nodeType) { + const cacheKey = `version-summary:${nodeType}`; + const cached = this.cache.get(cacheKey); + if (cached) { + return cached; + } + const versions = this.repository.getNodeVersions(nodeType); + const latest = this.repository.getLatestNodeVersion(nodeType); + const summary = { + currentVersion: latest?.version || 'unknown', + totalVersions: versions.length, + hasVersionHistory: versions.length > 0 + }; + this.cache.set(cacheKey, summary, 86400000); + return summary; + } + getVersionHistory(nodeType) { + const versions = this.repository.getNodeVersions(nodeType); + return { + nodeType, + totalVersions: versions.length, + versions: versions.map(v => ({ + version: v.version, + isCurrent: v.isCurrentMax, + minimumN8nVersion: v.minimumN8nVersion, + releasedAt: v.releasedAt, + hasBreakingChanges: (v.breakingChanges || []).length > 0, + breakingChangesCount: (v.breakingChanges || []).length, + deprecatedProperties: v.deprecatedProperties || [], + addedProperties: v.addedProperties || [] + })), + available: versions.length > 0, + message: versions.length === 0 ? + 'No version history available. Version tracking may not be enabled for this node.' : + undefined + }; + } + compareVersions(nodeType, fromVersion, toVersion) { + const latest = this.repository.getLatestNodeVersion(nodeType); + const targetVersion = toVersion || latest?.version; + if (!targetVersion) { + throw new Error('No target version available'); + } + const changes = this.repository.getPropertyChanges(nodeType, fromVersion, targetVersion); + return { + nodeType, + fromVersion, + toVersion: targetVersion, + totalChanges: changes.length, + breakingChanges: changes.filter(c => c.isBreaking).length, + changes: changes.map(c => ({ + property: c.propertyName, + changeType: c.changeType, + isBreaking: c.isBreaking, + severity: c.severity, + oldValue: c.oldValue, + newValue: c.newValue, + migrationHint: c.migrationHint, + autoMigratable: c.autoMigratable + })) + }; + } + getBreakingChanges(nodeType, fromVersion, toVersion) { + const breakingChanges = this.repository.getBreakingChanges(nodeType, fromVersion, toVersion); + return { + nodeType, + fromVersion, + toVersion: toVersion || 'latest', + totalBreakingChanges: breakingChanges.length, + changes: breakingChanges.map(c => ({ + fromVersion: c.fromVersion, + toVersion: c.toVersion, + property: c.propertyName, + changeType: c.changeType, + severity: c.severity, + migrationHint: c.migrationHint, + oldValue: c.oldValue, + newValue: c.newValue + })), + upgradeSafe: breakingChanges.length === 0 + }; + } + getMigrations(nodeType, fromVersion, toVersion) { + const migrations = this.repository.getAutoMigratableChanges(nodeType, fromVersion, toVersion); + const allChanges = this.repository.getPropertyChanges(nodeType, fromVersion, toVersion); + return { + nodeType, + fromVersion, + toVersion, + autoMigratableChanges: migrations.length, + totalChanges: allChanges.length, + migrations: migrations.map(m => ({ + property: m.propertyName, + changeType: m.changeType, + migrationStrategy: m.migrationStrategy, + severity: m.severity + })), + requiresManualMigration: migrations.length < allChanges.length + }; + } + enrichPropertyWithTypeInfo(property) { + if (!property || !property.type) + return property; + const structure = type_structure_service_1.TypeStructureService.getStructure(property.type); + if (!structure) + return property; + return { + ...property, + typeInfo: { + category: structure.type, + jsType: structure.jsType, + description: structure.description, + isComplex: type_structure_service_1.TypeStructureService.isComplexType(property.type), + isPrimitive: type_structure_service_1.TypeStructureService.isPrimitiveType(property.type), + allowsExpressions: structure.validation?.allowExpressions ?? true, + allowsEmpty: structure.validation?.allowEmpty ?? false, + ...(structure.structure && { + structureHints: { + hasProperties: !!structure.structure.properties, + hasItems: !!structure.structure.items, + isFlexible: structure.structure.flexible ?? false, + requiredFields: structure.structure.required ?? [] + } + }), + ...(structure.notes && { notes: structure.notes }) + } + }; + } + enrichPropertiesWithTypeInfo(properties) { + if (!properties || !Array.isArray(properties)) + return properties; + return properties.map((prop) => this.enrichPropertyWithTypeInfo(prop)); + } + async searchNodeProperties(nodeType, query, maxResults = 20) { + await this.ensureInitialized(); + if (!this.repository) + throw new Error('Repository not initialized'); + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + let node = this.repository.getNode(normalizedType); + if (!node && normalizedType !== nodeType) { + node = this.repository.getNode(nodeType); + } + if (!node) { + const alternatives = (0, node_utils_1.getNodeTypeAlternatives)(normalizedType); + for (const alt of alternatives) { + const found = this.repository.getNode(alt); + if (found) { + node = found; + break; + } + } + } + if (!node) { + throw new Error(`Node ${nodeType} not found`); + } + const allProperties = node.properties || []; + const matches = property_filter_1.PropertyFilter.searchProperties(allProperties, query, maxResults); + return { + nodeType: node.nodeType, + query, + matches: matches.map((match) => ({ + name: match.name, + displayName: match.displayName, + type: match.type, + description: match.description, + path: match.path || match.name, + required: match.required, + default: match.default, + options: match.options, + showWhen: match.showWhen + })), + totalMatches: matches.length, + searchedIn: allProperties.length + ' properties' + }; + } + getPropertyValue(config, path) { + const parts = path.split('.'); + let value = config; + for (const part of parts) { + const arrayMatch = part.match(/^(\w+)\[(\d+)\]$/); + if (arrayMatch) { + value = value?.[arrayMatch[1]]?.[parseInt(arrayMatch[2])]; + } + else { + value = value?.[part]; + } + } + return value; + } + async listTasks(category) { + if (category) { + const categories = task_templates_1.TaskTemplates.getTaskCategories(); + const tasks = categories[category]; + if (!tasks) { + throw new Error(`Unknown category: ${category}. Available categories: ${Object.keys(categories).join(', ')}`); + } + return { + category, + tasks: tasks.map(task => { + const template = task_templates_1.TaskTemplates.getTaskTemplate(task); + return { + task, + description: template?.description || '', + nodeType: template?.nodeType || '' + }; + }) + }; + } + const categories = task_templates_1.TaskTemplates.getTaskCategories(); + const result = { + totalTasks: task_templates_1.TaskTemplates.getAllTasks().length, + categories: {} + }; + for (const [cat, tasks] of Object.entries(categories)) { + result.categories[cat] = tasks.map(task => { + const template = task_templates_1.TaskTemplates.getTaskTemplate(task); + return { + task, + description: template?.description || '', + nodeType: template?.nodeType || '' + }; + }); + } + return result; + } + async validateNodeConfig(nodeType, config, mode = 'operation', profile = 'ai-friendly') { + await this.ensureInitialized(); + if (!this.repository) + throw new Error('Repository not initialized'); + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + let node = this.repository.getNode(normalizedType); + if (!node && normalizedType !== nodeType) { + node = this.repository.getNode(nodeType); + } + if (!node) { + const alternatives = (0, node_utils_1.getNodeTypeAlternatives)(normalizedType); + for (const alt of alternatives) { + const found = this.repository.getNode(alt); + if (found) { + node = found; + break; + } + } + } + if (!node) { + throw new Error(`Node ${nodeType} not found`); + } + const properties = node.properties || []; + const validationResult = enhanced_config_validator_1.EnhancedConfigValidator.validateWithMode(node.nodeType, config, properties, mode, profile); + return { + nodeType: node.nodeType, + workflowNodeType: (0, node_utils_1.getWorkflowNodeType)(node.package, node.nodeType), + displayName: node.displayName, + ...validationResult, + summary: { + hasErrors: !validationResult.valid, + errorCount: validationResult.errors.length, + warningCount: validationResult.warnings.length, + suggestionCount: validationResult.suggestions.length + } + }; + } + async getPropertyDependencies(nodeType, config) { + await this.ensureInitialized(); + if (!this.repository) + throw new Error('Repository not initialized'); + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + let node = this.repository.getNode(normalizedType); + if (!node && normalizedType !== nodeType) { + node = this.repository.getNode(nodeType); + } + if (!node) { + const alternatives = (0, node_utils_1.getNodeTypeAlternatives)(normalizedType); + for (const alt of alternatives) { + const found = this.repository.getNode(alt); + if (found) { + node = found; + break; + } + } + } + if (!node) { + throw new Error(`Node ${nodeType} not found`); + } + const properties = node.properties || []; + const analysis = property_dependencies_1.PropertyDependencies.analyze(properties); + let visibilityImpact = null; + if (config) { + visibilityImpact = property_dependencies_1.PropertyDependencies.getVisibilityImpact(properties, config); + } + return { + nodeType: node.nodeType, + displayName: node.displayName, + ...analysis, + currentConfig: config ? { + providedValues: config, + visibilityImpact + } : undefined + }; + } + async getNodeAsToolInfo(nodeType) { + await this.ensureInitialized(); + if (!this.repository) + throw new Error('Repository not initialized'); + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + let node = this.repository.getNode(normalizedType); + if (!node && normalizedType !== nodeType) { + node = this.repository.getNode(nodeType); + } + if (!node) { + const alternatives = (0, node_utils_1.getNodeTypeAlternatives)(normalizedType); + for (const alt of alternatives) { + const found = this.repository.getNode(alt); + if (found) { + node = found; + break; + } + } + } + if (!node) { + throw new Error(`Node ${nodeType} not found`); + } + const commonUseCases = this.getCommonAIToolUseCases(node.nodeType); + const aiToolCapabilities = { + canBeUsedAsTool: true, + hasUsableAsToolProperty: node.isAITool, + requiresEnvironmentVariable: !node.isAITool && node.package !== 'n8n-nodes-base', + connectionType: 'ai_tool', + commonUseCases, + requirements: { + connection: 'Connect to the "ai_tool" port of an AI Agent node', + environment: node.package !== 'n8n-nodes-base' ? + 'Set N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true for community nodes' : + 'No special environment variables needed for built-in nodes' + }, + examples: this.getAIToolExamples(node.nodeType), + tips: [ + 'Give the tool a clear, descriptive name in the AI Agent settings', + 'Write a detailed tool description to help the AI understand when to use it', + 'Test the node independently before connecting it as a tool', + node.isAITool ? + 'This node is optimized for AI tool usage' : + 'This is a regular node that can be used as an AI tool' + ] + }; + return { + nodeType: node.nodeType, + workflowNodeType: (0, node_utils_1.getWorkflowNodeType)(node.package, node.nodeType), + displayName: node.displayName, + description: node.description, + package: node.package, + isMarkedAsAITool: node.isAITool, + aiToolCapabilities + }; + } + getOutputDescriptions(nodeType, outputName, index) { + if (nodeType === 'nodes-base.splitInBatches') { + if (outputName === 'done' && index === 0) { + return { + description: 'Final processed data after all iterations complete', + connectionGuidance: 'Connect to nodes that should run AFTER the loop completes' + }; + } + else if (outputName === 'loop' && index === 1) { + return { + description: 'Current batch data for this iteration', + connectionGuidance: 'Connect to nodes that process items INSIDE the loop (and connect their output back to this node)' + }; + } + } + if (nodeType === 'nodes-base.if') { + if (outputName === 'true' && index === 0) { + return { + description: 'Items that match the condition', + connectionGuidance: 'Connect to nodes that handle the TRUE case' + }; + } + else if (outputName === 'false' && index === 1) { + return { + description: 'Items that do not match the condition', + connectionGuidance: 'Connect to nodes that handle the FALSE case' + }; + } + } + if (nodeType === 'nodes-base.switch') { + return { + description: `Output ${index}: ${outputName || 'Route ' + index}`, + connectionGuidance: `Connect to nodes for the "${outputName || 'route ' + index}" case` + }; + } + return { + description: outputName || `Output ${index}`, + connectionGuidance: `Connect to downstream nodes` + }; + } + getCommonAIToolUseCases(nodeType) { + const useCaseMap = { + 'nodes-base.slack': [ + 'Send notifications about task completion', + 'Post updates to channels', + 'Send direct messages', + 'Create alerts and reminders' + ], + 'nodes-base.googleSheets': [ + 'Read data for analysis', + 'Log results and outputs', + 'Update spreadsheet records', + 'Create reports' + ], + 'nodes-base.gmail': [ + 'Send email notifications', + 'Read and process emails', + 'Send reports and summaries', + 'Handle email-based workflows' + ], + 'nodes-base.httpRequest': [ + 'Call external APIs', + 'Fetch data from web services', + 'Send webhooks', + 'Integrate with any REST API' + ], + 'nodes-base.postgres': [ + 'Query database for information', + 'Store analysis results', + 'Update records based on AI decisions', + 'Generate reports from data' + ], + 'nodes-base.webhook': [ + 'Receive external triggers', + 'Create callback endpoints', + 'Handle incoming data', + 'Integrate with external systems' + ] + }; + for (const [key, useCases] of Object.entries(useCaseMap)) { + if (nodeType.includes(key)) { + return useCases; + } + } + return [ + 'Perform automated actions', + 'Integrate with external services', + 'Process and transform data', + 'Extend AI agent capabilities' + ]; + } + getAIToolExamples(nodeType) { + const exampleMap = { + 'nodes-base.slack': { + toolName: 'Send Slack Message', + toolDescription: 'Sends a message to a specified Slack channel or user. Use this to notify team members about important events or results.', + nodeConfig: { + resource: 'message', + operation: 'post', + channel: '={{ $fromAI("channel", "The Slack channel to send to, e.g. #general") }}', + text: '={{ $fromAI("message", "The message content to send") }}' + } + }, + 'nodes-base.googleSheets': { + toolName: 'Update Google Sheet', + toolDescription: 'Reads or updates data in a Google Sheets spreadsheet. Use this to log information, retrieve data, or update records.', + nodeConfig: { + operation: 'append', + sheetId: 'your-sheet-id', + range: 'A:Z', + dataMode: 'autoMap' + } + }, + 'nodes-base.httpRequest': { + toolName: 'Call API', + toolDescription: 'Makes HTTP requests to external APIs. Use this to fetch data, trigger webhooks, or integrate with any web service.', + nodeConfig: { + method: '={{ $fromAI("method", "HTTP method: GET, POST, PUT, DELETE") }}', + url: '={{ $fromAI("url", "The complete API endpoint URL") }}', + sendBody: true, + bodyContentType: 'json', + jsonBody: '={{ $fromAI("body", "Request body as JSON object") }}' + } + } + }; + for (const [key, example] of Object.entries(exampleMap)) { + if (nodeType.includes(key)) { + return example; + } + } + return { + toolName: 'Custom Tool', + toolDescription: 'Performs specific operations. Describe what this tool does and when to use it.', + nodeConfig: { + note: 'Configure the node based on its specific requirements' + } + }; + } + async validateNodeMinimal(nodeType, config) { + await this.ensureInitialized(); + if (!this.repository) + throw new Error('Repository not initialized'); + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + let node = this.repository.getNode(normalizedType); + if (!node && normalizedType !== nodeType) { + node = this.repository.getNode(nodeType); + } + if (!node) { + const alternatives = (0, node_utils_1.getNodeTypeAlternatives)(normalizedType); + for (const alt of alternatives) { + const found = this.repository.getNode(alt); + if (found) { + node = found; + break; + } + } + } + if (!node) { + throw new Error(`Node ${nodeType} not found`); + } + const properties = node.properties || []; + const operationContext = { + resource: config?.resource, + operation: config?.operation, + action: config?.action, + mode: config?.mode + }; + const missingFields = []; + for (const prop of properties) { + if (!prop.required) + continue; + if (prop.displayOptions) { + let isVisible = true; + if (prop.displayOptions.show) { + for (const [key, values] of Object.entries(prop.displayOptions.show)) { + const configValue = config?.[key]; + const expectedValues = Array.isArray(values) ? values : [values]; + if (!expectedValues.includes(configValue)) { + isVisible = false; + break; + } + } + } + if (isVisible && prop.displayOptions.hide) { + for (const [key, values] of Object.entries(prop.displayOptions.hide)) { + const configValue = config?.[key]; + const expectedValues = Array.isArray(values) ? values : [values]; + if (expectedValues.includes(configValue)) { + isVisible = false; + break; + } + } + } + if (!isVisible) + continue; + } + if (!config || !(prop.name in config)) { + missingFields.push(prop.displayName || prop.name); + } + } + return { + nodeType: node.nodeType, + displayName: node.displayName, + valid: missingFields.length === 0, + missingRequiredFields: missingFields + }; + } + async getToolsDocumentation(topic, depth = 'essentials') { + if (!topic || topic === 'overview') { + return (0, tools_documentation_1.getToolsOverview)(depth); + } + return (0, tools_documentation_1.getToolDocumentation)(topic, depth); + } + async connect(transport) { + await this.ensureInitialized(); + await this.server.connect(transport); + logger_1.logger.info('MCP Server connected', { + transportType: transport.constructor.name + }); + } + async listTemplates(limit = 10, offset = 0, sortBy = 'views', includeMetadata = false) { + await this.ensureInitialized(); + if (!this.templateService) + throw new Error('Template service not initialized'); + const result = await this.templateService.listTemplates(limit, offset, sortBy, includeMetadata); + return { + ...result, + tip: result.items.length > 0 ? + `Use get_template(templateId) to get full workflow details. Total: ${result.total} templates available.` : + "No templates found. Run 'npm run fetch:templates' to update template database" + }; + } + async listNodeTemplates(nodeTypes, limit = 10, offset = 0) { + await this.ensureInitialized(); + if (!this.templateService) + throw new Error('Template service not initialized'); + const result = await this.templateService.listNodeTemplates(nodeTypes, limit, offset); + if (result.items.length === 0 && offset === 0) { + return { + ...result, + message: `No templates found using nodes: ${nodeTypes.join(', ')}`, + tip: "Try searching with more common nodes or run 'npm run fetch:templates' to update template database" + }; + } + return { + ...result, + tip: `Showing ${result.items.length} of ${result.total} templates. Use offset for pagination.` + }; + } + async getTemplate(templateId, mode = 'full') { + await this.ensureInitialized(); + if (!this.templateService) + throw new Error('Template service not initialized'); + const template = await this.templateService.getTemplate(templateId, mode); + if (!template) { + return { + error: `Template ${templateId} not found`, + tip: "Use list_templates, list_node_templates or search_templates to find available templates" + }; + } + const usage = mode === 'nodes_only' ? "Node list for quick overview" : + mode === 'structure' ? "Workflow structure without full details" : + "Complete workflow JSON ready to import into n8n"; + return { + mode, + template, + usage + }; + } + async searchTemplates(query, limit = 20, offset = 0, fields) { + await this.ensureInitialized(); + if (!this.templateService) + throw new Error('Template service not initialized'); + const result = await this.templateService.searchTemplates(query, limit, offset, fields); + if (result.items.length === 0 && offset === 0) { + return { + ...result, + message: `No templates found matching: "${query}"`, + tip: "Try different keywords or run 'npm run fetch:templates' to update template database" + }; + } + return { + ...result, + query, + tip: `Found ${result.total} templates matching "${query}". Showing ${result.items.length}.` + }; + } + async getTemplatesForTask(task, limit = 10, offset = 0) { + await this.ensureInitialized(); + if (!this.templateService) + throw new Error('Template service not initialized'); + const result = await this.templateService.getTemplatesForTask(task, limit, offset); + const availableTasks = this.templateService.listAvailableTasks(); + if (result.items.length === 0 && offset === 0) { + return { + ...result, + message: `No templates found for task: ${task}`, + availableTasks, + tip: "Try a different task or use search_templates for custom searches" + }; + } + return { + ...result, + task, + description: this.getTaskDescription(task), + tip: `${result.total} templates available for ${task}. Showing ${result.items.length}.` + }; + } + async searchTemplatesByMetadata(filters, limit = 20, offset = 0) { + await this.ensureInitialized(); + if (!this.templateService) + throw new Error('Template service not initialized'); + const result = await this.templateService.searchTemplatesByMetadata(filters, limit, offset); + const filterSummary = []; + if (filters.category) + filterSummary.push(`category: ${filters.category}`); + if (filters.complexity) + filterSummary.push(`complexity: ${filters.complexity}`); + if (filters.maxSetupMinutes) + filterSummary.push(`max setup: ${filters.maxSetupMinutes} min`); + if (filters.minSetupMinutes) + filterSummary.push(`min setup: ${filters.minSetupMinutes} min`); + if (filters.requiredService) + filterSummary.push(`service: ${filters.requiredService}`); + if (filters.targetAudience) + filterSummary.push(`audience: ${filters.targetAudience}`); + if (result.items.length === 0 && offset === 0) { + const availableCategories = await this.templateService.getAvailableCategories(); + const availableAudiences = await this.templateService.getAvailableTargetAudiences(); + return { + ...result, + message: `No templates found with filters: ${filterSummary.join(', ')}`, + availableCategories: availableCategories.slice(0, 10), + availableAudiences: availableAudiences.slice(0, 5), + tip: "Try broader filters or different categories. Use list_templates to see all templates." + }; + } + return { + ...result, + filters, + filterSummary: filterSummary.join(', '), + tip: `Found ${result.total} templates matching filters. Showing ${result.items.length}. Each includes AI-generated metadata.` + }; + } + getTaskDescription(task) { + const descriptions = { + 'ai_automation': 'AI-powered workflows using OpenAI, LangChain, and other AI tools', + 'data_sync': 'Synchronize data between databases, spreadsheets, and APIs', + 'webhook_processing': 'Process incoming webhooks and trigger automated actions', + 'email_automation': 'Send, receive, and process emails automatically', + 'slack_integration': 'Integrate with Slack for notifications and bot interactions', + 'data_transformation': 'Transform, clean, and manipulate data', + 'file_processing': 'Handle file uploads, downloads, and transformations', + 'scheduling': 'Schedule recurring tasks and time-based automations', + 'api_integration': 'Connect to external APIs and web services', + 'database_operations': 'Query, insert, update, and manage database records' + }; + return descriptions[task] || 'Workflow templates for this task'; + } + async validateWorkflow(workflow, options) { + await this.ensureInitialized(); + if (!this.repository) + throw new Error('Repository not initialized'); + logger_1.logger.info('Workflow validation requested', { + hasWorkflow: !!workflow, + workflowType: typeof workflow, + hasNodes: workflow?.nodes !== undefined, + nodesType: workflow?.nodes ? typeof workflow.nodes : 'undefined', + nodesIsArray: Array.isArray(workflow?.nodes), + nodesCount: Array.isArray(workflow?.nodes) ? workflow.nodes.length : 0, + hasConnections: workflow?.connections !== undefined, + connectionsType: workflow?.connections ? typeof workflow.connections : 'undefined', + options: options + }); + if (!workflow || typeof workflow !== 'object') { + return { + valid: false, + errors: [{ + node: 'workflow', + message: 'Workflow must be an object with nodes and connections', + details: 'Expected format: ' + (0, workflow_examples_1.getWorkflowExampleString)() + }], + summary: { errorCount: 1 } + }; + } + if (!workflow.nodes || !Array.isArray(workflow.nodes)) { + return { + valid: false, + errors: [{ + node: 'workflow', + message: 'Workflow must have a nodes array', + details: 'Expected: workflow.nodes = [array of node objects]. ' + (0, workflow_examples_1.getWorkflowExampleString)() + }], + summary: { errorCount: 1 } + }; + } + if (!workflow.connections || typeof workflow.connections !== 'object') { + return { + valid: false, + errors: [{ + node: 'workflow', + message: 'Workflow must have a connections object', + details: 'Expected: workflow.connections = {} (can be empty object). ' + (0, workflow_examples_1.getWorkflowExampleString)() + }], + summary: { errorCount: 1 } + }; + } + const validator = new workflow_validator_1.WorkflowValidator(this.repository, enhanced_config_validator_1.EnhancedConfigValidator); + try { + const result = await validator.validateWorkflow(workflow, options); + const response = { + valid: result.valid, + summary: { + totalNodes: result.statistics.totalNodes, + enabledNodes: result.statistics.enabledNodes, + triggerNodes: result.statistics.triggerNodes, + validConnections: result.statistics.validConnections, + invalidConnections: result.statistics.invalidConnections, + expressionsValidated: result.statistics.expressionsValidated, + errorCount: result.errors.length, + warningCount: result.warnings.length + }, + errors: result.errors.map(e => ({ + node: e.nodeName || 'workflow', + message: e.message, + details: e.details + })), + warnings: result.warnings.map(w => ({ + node: w.nodeName || 'workflow', + message: w.message, + details: w.details + })) + }; + if (result.suggestions.length > 0) { + response.suggestions = result.suggestions; + } + if (!result.valid && result.errors.length > 0) { + result.errors.forEach(error => { + telemetry_1.telemetry.trackValidationDetails(error.nodeName || 'workflow', error.type || 'validation_error', { + message: error.message, + nodeCount: workflow.nodes?.length ?? 0, + hasConnections: Object.keys(workflow.connections || {}).length > 0 + }); + }); + } + if (result.valid) { + telemetry_1.telemetry.trackWorkflowCreation(workflow, true); + } + return response; + } + catch (error) { + logger_1.logger.error('Error validating workflow:', error); + return { + valid: false, + error: error instanceof Error ? error.message : 'Unknown error validating workflow', + tip: 'Ensure the workflow JSON includes nodes array and connections object' + }; + } + } + async validateWorkflowConnections(workflow) { + await this.ensureInitialized(); + if (!this.repository) + throw new Error('Repository not initialized'); + const validator = new workflow_validator_1.WorkflowValidator(this.repository, enhanced_config_validator_1.EnhancedConfigValidator); + try { + const result = await validator.validateWorkflow(workflow, { + validateNodes: false, + validateConnections: true, + validateExpressions: false + }); + const response = { + valid: result.errors.length === 0, + statistics: { + totalNodes: result.statistics.totalNodes, + triggerNodes: result.statistics.triggerNodes, + validConnections: result.statistics.validConnections, + invalidConnections: result.statistics.invalidConnections + } + }; + const connectionErrors = result.errors.filter(e => e.message.includes('connection') || + e.message.includes('cycle') || + e.message.includes('orphaned')); + const connectionWarnings = result.warnings.filter(w => w.message.includes('connection') || + w.message.includes('orphaned') || + w.message.includes('trigger')); + if (connectionErrors.length > 0) { + response.errors = connectionErrors.map(e => ({ + node: e.nodeName || 'workflow', + message: e.message + })); + } + if (connectionWarnings.length > 0) { + response.warnings = connectionWarnings.map(w => ({ + node: w.nodeName || 'workflow', + message: w.message + })); + } + return response; + } + catch (error) { + logger_1.logger.error('Error validating workflow connections:', error); + return { + valid: false, + error: error instanceof Error ? error.message : 'Unknown error validating connections' + }; + } + } + async validateWorkflowExpressions(workflow) { + await this.ensureInitialized(); + if (!this.repository) + throw new Error('Repository not initialized'); + const validator = new workflow_validator_1.WorkflowValidator(this.repository, enhanced_config_validator_1.EnhancedConfigValidator); + try { + const result = await validator.validateWorkflow(workflow, { + validateNodes: false, + validateConnections: false, + validateExpressions: true + }); + const response = { + valid: result.errors.length === 0, + statistics: { + totalNodes: result.statistics.totalNodes, + expressionsValidated: result.statistics.expressionsValidated + } + }; + const expressionErrors = result.errors.filter(e => e.message.includes('Expression') || + e.message.includes('$') || + e.message.includes('{{')); + const expressionWarnings = result.warnings.filter(w => w.message.includes('Expression') || + w.message.includes('$') || + w.message.includes('{{')); + if (expressionErrors.length > 0) { + response.errors = expressionErrors.map(e => ({ + node: e.nodeName || 'workflow', + message: e.message + })); + } + if (expressionWarnings.length > 0) { + response.warnings = expressionWarnings.map(w => ({ + node: w.nodeName || 'workflow', + message: w.message + })); + } + if (expressionErrors.length > 0 || expressionWarnings.length > 0) { + response.tips = [ + 'Use {{ }} to wrap expressions', + 'Reference data with $json.propertyName', + 'Reference other nodes with $node["Node Name"].json', + 'Use $input.item for input data in loops' + ]; + } + return response; + } + catch (error) { + logger_1.logger.error('Error validating workflow expressions:', error); + return { + valid: false, + error: error instanceof Error ? error.message : 'Unknown error validating expressions' + }; + } + } + async run() { + await this.ensureInitialized(); + const transport = new stdio_js_1.StdioServerTransport(); + await this.server.connect(transport); + if (!process.stdout.isTTY || process.env.IS_DOCKER) { + const originalWrite = process.stdout.write.bind(process.stdout); + process.stdout.write = function (chunk, encoding, callback) { + const result = originalWrite(chunk, encoding, callback); + process.stdout.emit('drain'); + return result; + }; + } + logger_1.logger.info('n8n Documentation MCP Server running on stdio transport'); + process.stdin.resume(); + } + async shutdown() { + logger_1.logger.info('Shutting down MCP server...'); + if (this.cache) { + try { + this.cache.destroy(); + logger_1.logger.info('Cache timers cleaned up'); + } + catch (error) { + logger_1.logger.error('Error cleaning up cache:', error); + } + } + if (this.db) { + try { + await this.db.close(); + logger_1.logger.info('Database connection closed'); + } + catch (error) { + logger_1.logger.error('Error closing database:', error); + } + } + } +} +exports.N8NDocumentationMCPServer = N8NDocumentationMCPServer; +//# sourceMappingURL=server.js.map \ No newline at end of file diff --git a/dist/mcp/server.js.map b/dist/mcp/server.js.map new file mode 100644 index 0000000..e697d15 --- /dev/null +++ b/dist/mcp/server.js.map @@ -0,0 +1 @@ +{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/mcp/stdio-wrapper.d.ts b/dist/mcp/stdio-wrapper.d.ts new file mode 100644 index 0000000..1ad4e17 --- /dev/null +++ b/dist/mcp/stdio-wrapper.d.ts @@ -0,0 +1,3 @@ +#!/usr/bin/env node +export {}; +//# sourceMappingURL=stdio-wrapper.d.ts.map \ No newline at end of file diff --git a/dist/mcp/stdio-wrapper.d.ts.map b/dist/mcp/stdio-wrapper.d.ts.map new file mode 100644 index 0000000..8dc26eb --- /dev/null +++ b/dist/mcp/stdio-wrapper.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"stdio-wrapper.d.ts","sourceRoot":"","sources":["../../src/mcp/stdio-wrapper.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/mcp/stdio-wrapper.js b/dist/mcp/stdio-wrapper.js new file mode 100644 index 0000000..f5a50e8 --- /dev/null +++ b/dist/mcp/stdio-wrapper.js @@ -0,0 +1,81 @@ +#!/usr/bin/env node +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +process.env.MCP_MODE = 'stdio'; +process.env.DISABLE_CONSOLE_OUTPUT = 'true'; +process.env.LOG_LEVEL = 'error'; +const originalConsoleLog = console.log; +const originalConsoleError = console.error; +const originalConsoleWarn = console.warn; +const originalConsoleInfo = console.info; +const originalConsoleDebug = console.debug; +const originalConsoleTrace = console.trace; +const originalConsoleDir = console.dir; +const originalConsoleTime = console.time; +const originalConsoleTimeEnd = console.timeEnd; +console.log = () => { }; +console.error = () => { }; +console.warn = () => { }; +console.info = () => { }; +console.debug = () => { }; +console.trace = () => { }; +console.dir = () => { }; +console.time = () => { }; +console.timeEnd = () => { }; +console.timeLog = () => { }; +console.group = () => { }; +console.groupEnd = () => { }; +console.table = () => { }; +console.clear = () => { }; +console.count = () => { }; +console.countReset = () => { }; +const server_1 = require("./server"); +let server = null; +async function main() { + try { + server = new server_1.N8NDocumentationMCPServer(); + await server.run(); + } + catch (error) { + originalConsoleError('Fatal error:', error); + process.exit(1); + } +} +process.on('uncaughtException', (error) => { + originalConsoleError('Uncaught exception:', error); + process.exit(1); +}); +process.on('unhandledRejection', (reason) => { + originalConsoleError('Unhandled rejection:', reason); + process.exit(1); +}); +let isShuttingDown = false; +async function shutdown(signal) { + if (isShuttingDown) + return; + isShuttingDown = true; + originalConsoleError(`Received ${signal}, shutting down gracefully...`); + try { + if (server) { + await server.shutdown(); + } + } + catch (error) { + originalConsoleError('Error during shutdown:', error); + } + process.stdin.pause(); + process.stdin.destroy(); + setTimeout(() => { + process.exit(0); + }, 500).unref(); + process.exit(0); +} +process.on('SIGTERM', () => void shutdown('SIGTERM')); +process.on('SIGINT', () => void shutdown('SIGINT')); +process.on('SIGHUP', () => void shutdown('SIGHUP')); +process.stdin.on('end', () => { + originalConsoleError('stdin closed, shutting down...'); + void shutdown('STDIN_CLOSE'); +}); +main(); +//# sourceMappingURL=stdio-wrapper.js.map \ No newline at end of file diff --git a/dist/mcp/stdio-wrapper.js.map b/dist/mcp/stdio-wrapper.js.map new file mode 100644 index 0000000..a60c865 --- /dev/null +++ b/dist/mcp/stdio-wrapper.js.map @@ -0,0 +1 @@ +{"version":3,"file":"stdio-wrapper.js","sourceRoot":"","sources":["../../src/mcp/stdio-wrapper.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/configuration/get-node.d.ts b/dist/mcp/tool-docs/configuration/get-node.d.ts new file mode 100644 index 0000000..5eaa149 --- /dev/null +++ b/dist/mcp/tool-docs/configuration/get-node.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const getNodeDoc: ToolDocumentation; +//# sourceMappingURL=get-node.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/configuration/get-node.d.ts.map b/dist/mcp/tool-docs/configuration/get-node.d.ts.map new file mode 100644 index 0000000..bf2088a --- /dev/null +++ b/dist/mcp/tool-docs/configuration/get-node.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"get-node.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/configuration/get-node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,UAAU,EAAE,iBAqFxB,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/configuration/get-node.js b/dist/mcp/tool-docs/configuration/get-node.js new file mode 100644 index 0000000..2e8a4ae --- /dev/null +++ b/dist/mcp/tool-docs/configuration/get-node.js @@ -0,0 +1,90 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getNodeDoc = void 0; +exports.getNodeDoc = { + name: 'get_node', + category: 'configuration', + essentials: { + description: 'Unified node information tool with progressive detail levels and multiple modes. Get node schema, docs, search properties, or version info.', + keyParameters: ['nodeType', 'detail', 'mode', 'includeTypeInfo', 'includeExamples'], + example: 'get_node({nodeType: "nodes-base.httpRequest", detail: "standard"})', + performance: 'Instant (<10ms) for minimal/standard, moderate for full', + tips: [ + 'Use detail="standard" (default) for most tasks - shows required fields', + 'Use mode="docs" for readable markdown documentation', + 'Use mode="search_properties" with propertyQuery to find specific fields', + 'Use mode="versions" to check version history and breaking changes', + 'Add includeExamples=true to get real-world configuration examples' + ] + }, + full: { + description: `**Detail Levels (mode="info", default):** +- minimal (~200 tokens): Basic metadata only - nodeType, displayName, description, category +- standard (~1-2K tokens): Essential properties + operations - recommended for most tasks +- full (~3-8K tokens): Complete node schema - use only when standard insufficient + +**Operation Modes:** +- info (default): Node schema with configurable detail level +- docs: Readable markdown documentation with examples and patterns +- search_properties: Find specific properties within a node +- versions: List all available versions with breaking changes summary +- compare: Compare two versions with property-level changes +- breaking: Show only breaking changes between versions +- migrations: Show auto-migratable changes between versions`, + parameters: { + nodeType: { type: 'string', required: true, description: 'Full node type with prefix: "nodes-base.httpRequest" or "nodes-langchain.agent"' }, + detail: { type: 'string', required: false, description: 'Detail level for mode=info: "minimal", "standard" (default), "full"' }, + mode: { type: 'string', required: false, description: 'Operation mode: "info" (default), "docs", "search_properties", "versions", "compare", "breaking", "migrations"' }, + includeTypeInfo: { type: 'boolean', required: false, description: 'Include type structure metadata (validation rules, JS types). Adds ~80-120 tokens per property' }, + includeExamples: { type: 'boolean', required: false, description: 'Include real-world configuration examples from templates. Adds ~200-400 tokens per example' }, + propertyQuery: { type: 'string', required: false, description: 'For mode=search_properties: search term to find properties (e.g., "auth", "header", "body")' }, + maxPropertyResults: { type: 'number', required: false, description: 'For mode=search_properties: max results (default 20)' }, + fromVersion: { type: 'string', required: false, description: 'For compare/breaking/migrations modes: source version (e.g., "1.0")' }, + toVersion: { type: 'string', required: false, description: 'For compare mode: target version (e.g., "2.0"). Defaults to latest' } + }, + returns: `Depends on mode: +- info: Node schema with properties based on detail level +- docs: Markdown documentation string +- search_properties: Array of matching property paths with descriptions +- versions: Version history with breaking changes flags +- compare/breaking/migrations: Version comparison details`, + examples: [ + '// Standard detail (recommended for AI agents)\nget_node({nodeType: "nodes-base.httpRequest"})', + '// Minimal for quick metadata check\nget_node({nodeType: "nodes-base.slack", detail: "minimal"})', + '// Full detail with examples\nget_node({nodeType: "nodes-base.googleSheets", detail: "full", includeExamples: true})', + '// Get readable documentation\nget_node({nodeType: "nodes-base.webhook", mode: "docs"})', + '// Search for authentication properties\nget_node({nodeType: "nodes-base.httpRequest", mode: "search_properties", propertyQuery: "auth"})', + '// Check version history\nget_node({nodeType: "nodes-base.executeWorkflow", mode: "versions"})', + '// Compare specific versions\nget_node({nodeType: "nodes-base.httpRequest", mode: "compare", fromVersion: "3.0", toVersion: "4.1"})' + ], + useCases: [ + 'Configure nodes for workflow building (use detail=standard)', + 'Find specific configuration options (use mode=search_properties)', + 'Get human-readable node documentation (use mode=docs)', + 'Check for breaking changes before version upgrades (use mode=breaking)', + 'Understand complex types with includeTypeInfo=true' + ], + performance: `Token costs by detail level: +- minimal: ~200 tokens +- standard: ~1000-2000 tokens (default) +- full: ~3000-8000 tokens +- includeTypeInfo: +80-120 tokens per property +- includeExamples: +200-400 tokens per example +- Version modes: ~400-1200 tokens`, + bestPractices: [ + 'Start with detail="standard" - it covers 95% of use cases', + 'Only use detail="full" if standard is missing required properties', + 'Use mode="docs" when explaining nodes to users', + 'Combine includeTypeInfo=true for complex nodes (filter, resourceMapper)', + 'Check version history before configuring versioned nodes' + ], + pitfalls: [ + 'detail="full" returns large responses (~100KB) - use sparingly', + 'Node type must include prefix (nodes-base. or nodes-langchain.)', + 'includeExamples only works with mode=info and detail=standard', + 'Version modes require nodes with multiple versions in database' + ], + relatedTools: ['search_nodes', 'validate_node', 'validate_workflow'] + } +}; +//# sourceMappingURL=get-node.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/configuration/get-node.js.map b/dist/mcp/tool-docs/configuration/get-node.js.map new file mode 100644 index 0000000..c80578a --- /dev/null +++ b/dist/mcp/tool-docs/configuration/get-node.js.map @@ -0,0 +1 @@ +{"version":3,"file":"get-node.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/configuration/get-node.ts"],"names":[],"mappings":";;;AAEa,QAAA,UAAU,GAAsB;IAC3C,IAAI,EAAE,UAAU;IAChB,QAAQ,EAAE,eAAe;IACzB,UAAU,EAAE;QACV,WAAW,EAAE,6IAA6I;QAC1J,aAAa,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,iBAAiB,EAAE,iBAAiB,CAAC;QACnF,OAAO,EAAE,oEAAoE;QAC7E,WAAW,EAAE,yDAAyD;QACtE,IAAI,EAAE;YACJ,wEAAwE;YACxE,qDAAqD;YACrD,yEAAyE;YACzE,mEAAmE;YACnE,mEAAmE;SACpE;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE;;;;;;;;;;;;4DAY2C;QACxD,UAAU,EAAE;YACV,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,iFAAiF,EAAE;YAC5I,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,qEAAqE,EAAE;YAC/H,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,gHAAgH,EAAE;YACxK,eAAe,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,gGAAgG,EAAE;YACpK,eAAe,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,4FAA4F,EAAE;YAChK,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,6FAA6F,EAAE;YAC9J,kBAAkB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,sDAAsD,EAAE;YAC5H,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,qEAAqE,EAAE;YACpI,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,oEAAoE,EAAE;SAClI;QACD,OAAO,EAAE;;;;;0DAK6C;QACtD,QAAQ,EAAE;YACR,gGAAgG;YAChG,kGAAkG;YAClG,sHAAsH;YACtH,yFAAyF;YACzF,2IAA2I;YAC3I,gGAAgG;YAChG,qIAAqI;SACtI;QACD,QAAQ,EAAE;YACR,6DAA6D;YAC7D,kEAAkE;YAClE,uDAAuD;YACvD,wEAAwE;YACxE,oDAAoD;SACrD;QACD,WAAW,EAAE;;;;;;kCAMiB;QAC9B,aAAa,EAAE;YACb,2DAA2D;YAC3D,mEAAmE;YACnE,gDAAgD;YAChD,yEAAyE;YACzE,0DAA0D;SAC3D;QACD,QAAQ,EAAE;YACR,gEAAgE;YAChE,iEAAiE;YACjE,+DAA+D;YAC/D,gEAAgE;SACjE;QACD,YAAY,EAAE,CAAC,cAAc,EAAE,eAAe,EAAE,mBAAmB,CAAC;KACrE;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/configuration/index.d.ts b/dist/mcp/tool-docs/configuration/index.d.ts new file mode 100644 index 0000000..ae340b6 --- /dev/null +++ b/dist/mcp/tool-docs/configuration/index.d.ts @@ -0,0 +1,2 @@ +export { getNodeDoc } from './get-node'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/configuration/index.d.ts.map b/dist/mcp/tool-docs/configuration/index.d.ts.map new file mode 100644 index 0000000..2017228 --- /dev/null +++ b/dist/mcp/tool-docs/configuration/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/configuration/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/configuration/index.js b/dist/mcp/tool-docs/configuration/index.js new file mode 100644 index 0000000..02ed863 --- /dev/null +++ b/dist/mcp/tool-docs/configuration/index.js @@ -0,0 +1,6 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getNodeDoc = void 0; +var get_node_1 = require("./get-node"); +Object.defineProperty(exports, "getNodeDoc", { enumerable: true, get: function () { return get_node_1.getNodeDoc; } }); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/configuration/index.js.map b/dist/mcp/tool-docs/configuration/index.js.map new file mode 100644 index 0000000..189c2e2 --- /dev/null +++ b/dist/mcp/tool-docs/configuration/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/configuration/index.ts"],"names":[],"mappings":";;;AAAA,uCAAwC;AAA/B,sGAAA,UAAU,OAAA"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/discovery/index.d.ts b/dist/mcp/tool-docs/discovery/index.d.ts new file mode 100644 index 0000000..acf79d3 --- /dev/null +++ b/dist/mcp/tool-docs/discovery/index.d.ts @@ -0,0 +1,2 @@ +export { searchNodesDoc } from './search-nodes'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/discovery/index.d.ts.map b/dist/mcp/tool-docs/discovery/index.d.ts.map new file mode 100644 index 0000000..48304fd --- /dev/null +++ b/dist/mcp/tool-docs/discovery/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/discovery/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/discovery/index.js b/dist/mcp/tool-docs/discovery/index.js new file mode 100644 index 0000000..ed7a8ab --- /dev/null +++ b/dist/mcp/tool-docs/discovery/index.js @@ -0,0 +1,6 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.searchNodesDoc = void 0; +var search_nodes_1 = require("./search-nodes"); +Object.defineProperty(exports, "searchNodesDoc", { enumerable: true, get: function () { return search_nodes_1.searchNodesDoc; } }); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/discovery/index.js.map b/dist/mcp/tool-docs/discovery/index.js.map new file mode 100644 index 0000000..9c3e387 --- /dev/null +++ b/dist/mcp/tool-docs/discovery/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/discovery/index.ts"],"names":[],"mappings":";;;AAAA,+CAAgD;AAAvC,8GAAA,cAAc,OAAA"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/discovery/search-nodes.d.ts b/dist/mcp/tool-docs/discovery/search-nodes.d.ts new file mode 100644 index 0000000..a8f0689 --- /dev/null +++ b/dist/mcp/tool-docs/discovery/search-nodes.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const searchNodesDoc: ToolDocumentation; +//# sourceMappingURL=search-nodes.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/discovery/search-nodes.d.ts.map b/dist/mcp/tool-docs/discovery/search-nodes.d.ts.map new file mode 100644 index 0000000..12c7f50 --- /dev/null +++ b/dist/mcp/tool-docs/discovery/search-nodes.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"search-nodes.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/discovery/search-nodes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,cAAc,EAAE,iBAmD5B,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/discovery/search-nodes.js b/dist/mcp/tool-docs/discovery/search-nodes.js new file mode 100644 index 0000000..58d1d1c --- /dev/null +++ b/dist/mcp/tool-docs/discovery/search-nodes.js @@ -0,0 +1,56 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.searchNodesDoc = void 0; +exports.searchNodesDoc = { + name: 'search_nodes', + category: 'discovery', + essentials: { + description: 'Text search across node names and descriptions. Returns most relevant nodes first, with frequently-used nodes (HTTP Request, Webhook, Set, Code, Slack) prioritized in results. Searches all 500+ nodes in the database.', + keyParameters: ['query', 'mode', 'limit'], + example: 'search_nodes({query: "webhook"})', + performance: '<20ms even for complex queries', + tips: [ + 'OR mode (default): Matches any search word', + 'AND mode: Requires all words present', + 'FUZZY mode: Handles typos and spelling errors', + 'Use quotes for exact phrases: "google sheets"' + ] + }, + full: { + description: 'Full-text search engine for n8n nodes using SQLite FTS5. Searches across node names, descriptions, and aliases. Results are ranked by relevance with commonly-used nodes given priority. Common nodes include: HTTP Request, Webhook, Set, Code, IF, Switch, Merge, SplitInBatches, Slack, Google Sheets.', + parameters: { + query: { type: 'string', description: 'Search keywords. Use quotes for exact phrases like "google sheets"', required: true }, + limit: { type: 'number', description: 'Maximum results to return. Default: 20, Max: 100', required: false }, + mode: { type: 'string', description: 'Search mode: "OR" (any word matches, default), "AND" (all words required), "FUZZY" (typo-tolerant)', required: false } + }, + returns: 'Array of node objects sorted by relevance score. Each object contains: nodeType, displayName, description, category, relevance score. Common nodes appear first when relevance is similar.', + examples: [ + 'search_nodes({query: "webhook"}) - Returns Webhook node as top result', + 'search_nodes({query: "database"}) - Returns MySQL, Postgres, MongoDB, Redis, etc.', + 'search_nodes({query: "google sheets", mode: "AND"}) - Requires both words', + 'search_nodes({query: "slak", mode: "FUZZY"}) - Finds Slack despite typo', + 'search_nodes({query: "http api"}) - Finds HTTP Request, GraphQL, REST nodes', + 'search_nodes({query: "transform data"}) - Finds Set, Code, Function, Item Lists nodes' + ], + useCases: [ + 'Finding nodes when you know partial names', + 'Discovering nodes by functionality (e.g., "email", "database", "transform")', + 'Handling user typos in node names', + 'Finding all nodes related to a service (e.g., "google", "aws", "microsoft")' + ], + performance: '<20ms for simple queries, <50ms for complex FUZZY searches. Uses FTS5 index for speed', + bestPractices: [ + 'Start with single keywords for broadest results', + 'Use FUZZY mode when users might misspell node names', + 'AND mode works best for 2-3 word searches', + 'Combine with get_node after finding the right node' + ], + pitfalls: [ + 'AND mode searches all fields (name, description) not just node names', + 'FUZZY mode with very short queries (1-2 chars) may return unexpected results', + 'Exact matches in quotes are case-sensitive' + ], + relatedTools: ['get_node to configure found nodes', 'search_templates to find workflow examples', 'validate_node to check configurations'] + } +}; +//# sourceMappingURL=search-nodes.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/discovery/search-nodes.js.map b/dist/mcp/tool-docs/discovery/search-nodes.js.map new file mode 100644 index 0000000..7486677 --- /dev/null +++ b/dist/mcp/tool-docs/discovery/search-nodes.js.map @@ -0,0 +1 @@ +{"version":3,"file":"search-nodes.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/discovery/search-nodes.ts"],"names":[],"mappings":";;;AAEa,QAAA,cAAc,GAAsB;IAC/C,IAAI,EAAE,cAAc;IACpB,QAAQ,EAAE,WAAW;IACrB,UAAU,EAAE;QACV,WAAW,EAAE,0NAA0N;QACvO,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC;QACzC,OAAO,EAAE,kCAAkC;QAC3C,WAAW,EAAE,gCAAgC;QAC7C,IAAI,EAAE;YACJ,4CAA4C;YAC5C,sCAAsC;YACtC,+CAA+C;YAC/C,+CAA+C;SAChD;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE,2SAA2S;QACxT,UAAU,EAAE;YACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oEAAoE,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC5H,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kDAAkD,EAAE,QAAQ,EAAE,KAAK,EAAE;YAC3G,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oGAAoG,EAAE,QAAQ,EAAE,KAAK,EAAE;SAC7J;QACD,OAAO,EAAE,4LAA4L;QACrM,QAAQ,EAAE;YACR,uEAAuE;YACvE,mFAAmF;YACnF,2EAA2E;YAC3E,yEAAyE;YACzE,6EAA6E;YAC7E,uFAAuF;SACxF;QACD,QAAQ,EAAE;YACR,2CAA2C;YAC3C,6EAA6E;YAC7E,mCAAmC;YACnC,6EAA6E;SAC9E;QACD,WAAW,EAAE,uFAAuF;QACpG,aAAa,EAAE;YACb,iDAAiD;YACjD,qDAAqD;YACrD,2CAA2C;YAC3C,oDAAoD;SACrD;QACD,QAAQ,EAAE;YACR,sEAAsE;YACtE,8EAA8E;YAC9E,4CAA4C;SAC7C;QACD,YAAY,EAAE,CAAC,mCAAmC,EAAE,4CAA4C,EAAE,uCAAuC,CAAC;KAC3I;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/guides/ai-agents-guide.d.ts b/dist/mcp/tool-docs/guides/ai-agents-guide.d.ts new file mode 100644 index 0000000..e219ea5 --- /dev/null +++ b/dist/mcp/tool-docs/guides/ai-agents-guide.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const aiAgentsGuide: ToolDocumentation; +//# sourceMappingURL=ai-agents-guide.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/guides/ai-agents-guide.d.ts.map b/dist/mcp/tool-docs/guides/ai-agents-guide.d.ts.map new file mode 100644 index 0000000..92370ac --- /dev/null +++ b/dist/mcp/tool-docs/guides/ai-agents-guide.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"ai-agents-guide.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/guides/ai-agents-guide.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,aAAa,EAAE,iBA8tB3B,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/guides/ai-agents-guide.js b/dist/mcp/tool-docs/guides/ai-agents-guide.js new file mode 100644 index 0000000..58d075f --- /dev/null +++ b/dist/mcp/tool-docs/guides/ai-agents-guide.js @@ -0,0 +1,739 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.aiAgentsGuide = void 0; +exports.aiAgentsGuide = { + name: 'ai_agents_guide', + category: 'guides', + essentials: { + description: 'Comprehensive guide to building AI Agent workflows in n8n. Covers architecture, connections, tools, validation, and best practices for production AI systems.', + keyParameters: [], + example: 'Use tools_documentation({topic: "ai_agents_guide"}) to access this guide', + performance: 'N/A - Documentation only', + tips: [ + 'Start with Chat Trigger → AI Agent → Language Model pattern', + 'Always connect language model BEFORE enabling AI Agent', + 'Use proper toolDescription for all AI tools (15+ characters)', + 'Validate workflows with n8n_validate_workflow before deployment', + 'Use includeExamples=true when searching for AI nodes', + 'Check FINAL_AI_VALIDATION_SPEC.md for detailed requirements' + ] + }, + full: { + description: `# Complete Guide to AI Agents in n8n + +This comprehensive guide covers everything you need to build production-ready AI Agent workflows in n8n. + +## Table of Contents +1. [AI Agent Architecture](#architecture) +2. [Essential Connection Types](#connections) +3. [Building Your First AI Agent](#first-agent) +4. [AI Tools Deep Dive](#tools) +5. [Advanced Patterns](#advanced) +6. [Validation & Best Practices](#validation) +7. [Troubleshooting](#troubleshooting) + +--- + +## 1. AI Agent Architecture {#architecture} + +### Core Components + +An n8n AI Agent workflow typically consists of: + +1. **Chat Trigger**: Entry point for user interactions + - Webhook-based or manual trigger + - Supports streaming responses (responseMode) + - Passes user message to AI Agent + +2. **AI Agent**: The orchestrator + - Manages conversation flow + - Decides when to use tools + - Iterates until task is complete + - Supports fallback models for reliability + +3. **Language Model**: The AI brain + - OpenAI GPT-4, Claude, Gemini, etc. + - Connected via ai_languageModel port + - Can have primary + fallback for reliability + +4. **Tools**: AI Agent's capabilities + - HTTP Request, Code, Vector Store, etc. + - Connected via ai_tool port + - Each tool needs clear toolDescription + +5. **Optional Components**: + - Memory (conversation history) + - Output Parser (structured responses) + - Vector Store (knowledge retrieval) + +### Connection Flow + +**CRITICAL**: AI connections flow TO the consumer (reversed from standard n8n): + +\`\`\` +Standard n8n: [Source] --main--> [Target] +AI pattern: [Language Model] --ai_languageModel--> [AI Agent] + [HTTP Tool] --ai_tool--> [AI Agent] +\`\`\` + +This is why you use \`sourceOutput: "ai_languageModel"\` when connecting components. + +--- + +## 2. Essential Connection Types {#connections} + +### The 8 AI Connection Types + +1. **ai_languageModel** + - FROM: OpenAI Chat Model, Anthropic, Google Gemini, etc. + - TO: AI Agent, Basic LLM Chain + - REQUIRED: Every AI Agent needs 1-2 language models + - Example: \`{type: "addConnection", source: "OpenAI", target: "AI Agent", sourceOutput: "ai_languageModel"}\` + +2. **ai_tool** + - FROM: Any tool node (HTTP Request Tool, Code Tool, etc.) + - TO: AI Agent + - REQUIRED: At least 1 tool recommended + - Example: \`{type: "addConnection", source: "HTTP Request Tool", target: "AI Agent", sourceOutput: "ai_tool"}\` + +3. **ai_memory** + - FROM: Window Buffer Memory, Conversation Summary, etc. + - TO: AI Agent + - OPTIONAL: 0-1 memory system + - Enables conversation history tracking + +4. **ai_outputParser** + - FROM: Structured Output Parser, JSON Parser, etc. + - TO: AI Agent + - OPTIONAL: For structured responses + - Must set hasOutputParser=true on AI Agent + +5. **ai_embedding** + - FROM: Embeddings OpenAI, Embeddings Google, etc. + - TO: Vector Store (Pinecone, In-Memory, etc.) + - REQUIRED: For vector-based retrieval + +6. **ai_vectorStore** + - FROM: Vector Store node + - TO: Vector Store Tool + - REQUIRED: For retrieval-augmented generation (RAG) + +7. **ai_document** + - FROM: Document Loader, Default Data Loader + - TO: Vector Store + - REQUIRED: Provides data for vector storage + +8. **ai_textSplitter** + - FROM: Text Splitter nodes + - TO: Document processing chains + - OPTIONAL: Chunk large documents + +### Connection Examples + +\`\`\`typescript +// Basic AI Agent setup +n8n_update_partial_workflow({ + id: "workflow_id", + operations: [ + // Connect language model (REQUIRED) + { + type: "addConnection", + source: "OpenAI Chat Model", + target: "AI Agent", + sourceOutput: "ai_languageModel" + }, + // Connect tools + { + type: "addConnection", + source: "HTTP Request Tool", + target: "AI Agent", + sourceOutput: "ai_tool" + }, + { + type: "addConnection", + source: "Code Tool", + target: "AI Agent", + sourceOutput: "ai_tool" + }, + // Add memory (optional) + { + type: "addConnection", + source: "Window Buffer Memory", + target: "AI Agent", + sourceOutput: "ai_memory" + } + ] +}) +\`\`\` + +--- + +## 3. Building Your First AI Agent {#first-agent} + +### Step-by-Step Tutorial + +#### Step 1: Create Chat Trigger + +Use \`n8n_create_workflow\` or manually create a workflow with: + +\`\`\`typescript +{ + name: "My First AI Agent", + nodes: [ + { + id: "chat_trigger", + name: "Chat Trigger", + type: "@n8n/n8n-nodes-langchain.chatTrigger", + position: [100, 100], + parameters: { + options: { + responseMode: "lastNode" // or "streaming" for real-time + } + } + } + ], + connections: {} +} +\`\`\` + +#### Step 2: Add Language Model + +\`\`\`typescript +n8n_update_partial_workflow({ + id: "workflow_id", + operations: [ + { + type: "addNode", + node: { + name: "OpenAI Chat Model", + type: "@n8n/n8n-nodes-langchain.lmChatOpenAi", + position: [300, 50], + parameters: { + model: "gpt-4", + temperature: 0.7 + } + } + } + ] +}) +\`\`\` + +#### Step 3: Add AI Agent + +\`\`\`typescript +n8n_update_partial_workflow({ + id: "workflow_id", + operations: [ + { + type: "addNode", + node: { + name: "AI Agent", + type: "@n8n/n8n-nodes-langchain.agent", + position: [300, 150], + parameters: { + promptType: "auto", + systemMessage: "You are a helpful assistant. Be concise and accurate." + } + } + } + ] +}) +\`\`\` + +#### Step 4: Connect Components + +\`\`\`typescript +n8n_update_partial_workflow({ + id: "workflow_id", + operations: [ + // Chat Trigger → AI Agent (main connection) + { + type: "addConnection", + source: "Chat Trigger", + target: "AI Agent" + }, + // Language Model → AI Agent (AI connection) + { + type: "addConnection", + source: "OpenAI Chat Model", + target: "AI Agent", + sourceOutput: "ai_languageModel" + } + ] +}) +\`\`\` + +#### Step 5: Validate + +\`\`\`typescript +n8n_validate_workflow({id: "workflow_id"}) +\`\`\` + +--- + +## 4. AI Tools Deep Dive {#tools} + +### Tool Types and When to Use Them + +#### 1. HTTP Request Tool +**Use when**: AI needs to call external APIs + +**Critical Requirements**: +- \`toolDescription\`: Clear, 15+ character description +- \`url\`: API endpoint (can include placeholders) +- \`placeholderDefinitions\`: Define all {placeholders} +- Proper authentication if needed + +**Example**: +\`\`\`typescript +{ + type: "addNode", + node: { + name: "GitHub Issues Tool", + type: "@n8n/n8n-nodes-langchain.toolHttpRequest", + position: [500, 100], + parameters: { + method: "POST", + url: "https://api.github.com/repos/{owner}/{repo}/issues", + toolDescription: "Create GitHub issues. Requires owner (username), repo (repository name), title, and body.", + placeholderDefinitions: { + values: [ + {name: "owner", description: "Repository owner username"}, + {name: "repo", description: "Repository name"}, + {name: "title", description: "Issue title"}, + {name: "body", description: "Issue description"} + ] + }, + sendBody: true, + jsonBody: "={{ { title: $json.title, body: $json.body } }}" + } + } +} +\`\`\` + +#### 2. Code Tool +**Use when**: AI needs to run custom logic + +**Critical Requirements**: +- \`name\`: Function name (alphanumeric + underscore) +- \`description\`: 10+ character explanation +- \`code\`: JavaScript or Python code +- \`inputSchema\`: Define expected inputs (recommended) + +**Example**: +\`\`\`typescript +{ + type: "addNode", + node: { + name: "Calculate Shipping", + type: "@n8n/n8n-nodes-langchain.toolCode", + position: [500, 200], + parameters: { + name: "calculate_shipping", + description: "Calculate shipping cost based on weight (kg) and distance (km)", + language: "javaScript", + code: "const cost = 5 + ($input.weight * 2) + ($input.distance * 0.1); return { cost };", + specifyInputSchema: true, + inputSchema: "{ \\"type\\": \\"object\\", \\"properties\\": { \\"weight\\": { \\"type\\": \\"number\\" }, \\"distance\\": { \\"type\\": \\"number\\" } } }" + } + } +} +\`\`\` + +#### 3. Vector Store Tool +**Use when**: AI needs to search knowledge base + +**Setup**: Requires Vector Store + Embeddings + Documents + +**Example**: +\`\`\`typescript +// Step 1: Create Vector Store with embeddings and documents +n8n_update_partial_workflow({ + operations: [ + {type: "addConnection", source: "Embeddings OpenAI", target: "Pinecone", sourceOutput: "ai_embedding"}, + {type: "addConnection", source: "Document Loader", target: "Pinecone", sourceOutput: "ai_document"} + ] +}) + +// Step 2: Connect Vector Store to Vector Store Tool +n8n_update_partial_workflow({ + operations: [ + {type: "addConnection", source: "Pinecone", target: "Vector Store Tool", sourceOutput: "ai_vectorStore"} + ] +}) + +// Step 3: Connect tool to AI Agent +n8n_update_partial_workflow({ + operations: [ + {type: "addConnection", source: "Vector Store Tool", target: "AI Agent", sourceOutput: "ai_tool"} + ] +}) +\`\`\` + +#### 4. AI Agent Tool (Sub-Agents) +**Use when**: Need specialized expertise + +**Example**: Research specialist sub-agent +\`\`\`typescript +{ + type: "addNode", + node: { + name: "Research Specialist", + type: "@n8n/n8n-nodes-langchain.agentTool", + position: [500, 300], + parameters: { + name: "research_specialist", + description: "Expert researcher that searches multiple sources and synthesizes information. Use for detailed research tasks.", + systemMessage: "You are a research specialist. Search thoroughly, cite sources, and provide comprehensive analysis." + } + } +} +\`\`\` + +#### 5. MCP Client Tool +**Use when**: Need to use Model Context Protocol servers + +**Example**: Filesystem access +\`\`\`typescript +{ + type: "addNode", + node: { + name: "Filesystem Tool", + type: "@n8n/n8n-nodes-langchain.mcpClientTool", + position: [500, 400], + parameters: { + description: "Access file system to read files, list directories, and search content", + mcpServer: { + transport: "stdio", + command: "npx", + args: ["-y", "@modelcontextprotocol/server-filesystem", "/allowed/path"] + }, + tool: "read_file" + } + } +} +\`\`\` + +--- + +## 5. Advanced Patterns {#advanced} + +### Pattern 1: Streaming Responses + +For real-time user experience: + +\`\`\`typescript +// Set Chat Trigger to streaming mode +{ + parameters: { + options: { + responseMode: "streaming" + } + } +} + +// CRITICAL: AI Agent must NOT have main output connections in streaming mode +// Responses stream back through Chat Trigger automatically +\`\`\` + +**Validation will fail if**: +- Chat Trigger has streaming but target is not AI Agent +- AI Agent in streaming mode has main output connections + +### Pattern 2: Fallback Language Models + +For production reliability with fallback language models: + +\`\`\`typescript +n8n_update_partial_workflow({ + operations: [ + // Primary model + { + type: "addConnection", + source: "OpenAI GPT-4", + target: "AI Agent", + sourceOutput: "ai_languageModel", + targetIndex: 0 + }, + // Fallback model + { + type: "addConnection", + source: "Anthropic Claude", + target: "AI Agent", + sourceOutput: "ai_languageModel", + targetIndex: 1 + } + ] +}) + +// Enable fallback on AI Agent +{ + type: "updateNode", + nodeName: "AI Agent", + updates: { + "parameters.needsFallback": true + } +} +\`\`\` + +### Pattern 3: RAG (Retrieval-Augmented Generation) + +Complete knowledge base setup: + +\`\`\`typescript +// 1. Load documents +{type: "addConnection", source: "PDF Loader", target: "Text Splitter", sourceOutput: "ai_document"} + +// 2. Split and embed +{type: "addConnection", source: "Text Splitter", target: "Vector Store"} +{type: "addConnection", source: "Embeddings", target: "Vector Store", sourceOutput: "ai_embedding"} + +// 3. Create search tool +{type: "addConnection", source: "Vector Store", target: "Vector Store Tool", sourceOutput: "ai_vectorStore"} + +// 4. Give tool to agent +{type: "addConnection", source: "Vector Store Tool", target: "AI Agent", sourceOutput: "ai_tool"} +\`\`\` + +### Pattern 4: Multi-Agent Systems + +Specialized sub-agents for complex tasks: + +\`\`\`typescript +// Create sub-agents with specific expertise +[ + {name: "research_agent", description: "Deep research specialist"}, + {name: "data_analyst", description: "Data analysis expert"}, + {name: "writer_agent", description: "Content writing specialist"} +].forEach(agent => { + // Add as AI Agent Tool to main coordinator agent + { + type: "addConnection", + source: agent.name, + target: "Coordinator Agent", + sourceOutput: "ai_tool" + } +}) +\`\`\` + +--- + +## 6. Validation & Best Practices {#validation} + +### Always Validate Before Deployment + +\`\`\`typescript +const result = n8n_validate_workflow({id: "workflow_id"}) + +if (!result.valid) { + console.log("Errors:", result.errors) + console.log("Warnings:", result.warnings) + console.log("Suggestions:", result.suggestions) +} +\`\`\` + +### Common Validation Errors + +1. **MISSING_LANGUAGE_MODEL** + - Problem: AI Agent has no ai_languageModel connection + - Fix: Connect a language model before creating AI Agent + +2. **MISSING_TOOL_DESCRIPTION** + - Problem: HTTP Request Tool has no toolDescription + - Fix: Add clear description (15+ characters) + +3. **STREAMING_WITH_MAIN_OUTPUT** + - Problem: AI Agent in streaming mode has outgoing main connections + - Fix: Remove main connections when using streaming + +4. **FALLBACK_MISSING_SECOND_MODEL** + - Problem: needsFallback=true but only 1 language model + - Fix: Add second language model or disable needsFallback + +### Best Practices Checklist + +✅ **Before Creating AI Agent**: +- [ ] Language model is connected first +- [ ] At least one tool is prepared (or will be added) +- [ ] System message is thoughtful and specific + +✅ **For Each Tool**: +- [ ] Has toolDescription/description (15+ characters) +- [ ] toolDescription explains WHEN to use the tool +- [ ] All required parameters are configured +- [ ] Credentials are set up if needed + +✅ **For Production**: +- [ ] Workflow validated with n8n_validate_workflow +- [ ] Tested with real user queries +- [ ] Fallback model configured for reliability +- [ ] Error handling in place +- [ ] maxIterations set appropriately (default 10, max 50) + +--- + +## 7. Troubleshooting {#troubleshooting} + +### Problem: "AI Agent has no language model" + +**Cause**: Connection created AFTER AI Agent or using wrong sourceOutput + +**Solution**: +\`\`\`typescript +n8n_update_partial_workflow({ + operations: [ + { + type: "addConnection", + source: "OpenAI Chat Model", + target: "AI Agent", + sourceOutput: "ai_languageModel" // ← CRITICAL + } + ] +}) +\`\`\` + +### Problem: "Tool has no description" + +**Cause**: HTTP Request Tool or Code Tool missing toolDescription/description + +**Solution**: +\`\`\`typescript +{ + type: "updateNode", + nodeName: "HTTP Request Tool", + updates: { + "parameters.toolDescription": "Call weather API to get current conditions for a city" + } +} +\`\`\` + +### Problem: "Streaming mode not working" + +**Causes**: +1. Chat Trigger not set to streaming +2. AI Agent has main output connections +3. Target of Chat Trigger is not AI Agent + +**Solution**: +\`\`\`typescript +// 1. Set Chat Trigger to streaming +{ + type: "updateNode", + nodeName: "Chat Trigger", + updates: { + "parameters.options.responseMode": "streaming" + } +} + +// 2. Remove AI Agent main outputs +{ + type: "removeConnection", + source: "AI Agent", + target: "Any Output Node" +} +\`\`\` + +### Problem: "Agent keeps looping" + +**Cause**: Tool not returning proper response or agent stuck in reasoning loop + +**Solutions**: +1. Set maxIterations lower: \`"parameters.maxIterations": 5\` +2. Improve tool descriptions to be more specific +3. Add system message guidance: "Use tools efficiently, don't repeat actions" + +--- + +## Quick Reference + +### Essential Tools + +| Tool | Purpose | Key Parameters | +|------|---------|----------------| +| HTTP Request Tool | API calls | toolDescription, url, placeholders | +| Code Tool | Custom logic | name, description, code, inputSchema | +| Vector Store Tool | Knowledge search | description, topK | +| AI Agent Tool | Sub-agents | name, description, systemMessage | +| MCP Client Tool | MCP protocol | description, mcpServer, tool | + +### Connection Quick Codes + +\`\`\`typescript +// Language Model → AI Agent +sourceOutput: "ai_languageModel" + +// Tool → AI Agent +sourceOutput: "ai_tool" + +// Memory → AI Agent +sourceOutput: "ai_memory" + +// Parser → AI Agent +sourceOutput: "ai_outputParser" + +// Embeddings → Vector Store +sourceOutput: "ai_embedding" + +// Vector Store → Vector Store Tool +sourceOutput: "ai_vectorStore" +\`\`\` + +### Validation Command + +\`\`\`typescript +n8n_validate_workflow({id: "workflow_id"}) +\`\`\` + +--- + +## Related Resources + +- **FINAL_AI_VALIDATION_SPEC.md**: Complete validation rules +- **n8n_update_partial_workflow**: Workflow modification tool +- **search_nodes({query: "AI", includeExamples: true})**: Find AI nodes with examples +- **get_node({nodeType: "...", detail: "standard", includeExamples: true})**: Node details with examples + +--- + +*This guide is part of the n8n-mcp documentation system. For questions or issues, refer to the validation spec or use tools_documentation() for specific topics.*`, + parameters: {}, + returns: 'Complete AI Agents guide with architecture, patterns, validation, and troubleshooting', + examples: [ + 'tools_documentation({topic: "ai_agents_guide"}) - Full guide', + 'tools_documentation({topic: "ai_agents_guide", depth: "essentials"}) - Quick reference', + 'When user asks about AI Agents, Chat Trigger, or building AI workflows → Point to this guide' + ], + useCases: [ + 'Learning AI Agent architecture in n8n', + 'Understanding AI connection types and patterns', + 'Building first AI Agent workflow step-by-step', + 'Implementing advanced patterns (streaming, fallback, RAG, multi-agent)', + 'Troubleshooting AI workflow issues', + 'Validating AI workflows before deployment', + 'Quick reference for connection types and tools' + ], + performance: 'N/A - Static documentation', + bestPractices: [ + 'Reference this guide when users ask about AI Agents', + 'Point to specific sections based on user needs', + 'Combine with search_nodes(includeExamples=true) for working examples', + 'Validate workflows after following guide instructions', + 'Use FINAL_AI_VALIDATION_SPEC.md for detailed requirements' + ], + pitfalls: [ + 'This is a guide, not an executable tool', + 'Always validate workflows after making changes', + 'AI connections require sourceOutput parameter', + 'Streaming mode has specific constraints', + 'Fallback models require AI Agent node with fallback support' + ], + relatedTools: [ + 'n8n_create_workflow', + 'n8n_update_partial_workflow', + 'n8n_validate_workflow', + 'search_nodes', + 'get_node' + ] + } +}; +//# sourceMappingURL=ai-agents-guide.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/guides/ai-agents-guide.js.map b/dist/mcp/tool-docs/guides/ai-agents-guide.js.map new file mode 100644 index 0000000..777982a --- /dev/null +++ b/dist/mcp/tool-docs/guides/ai-agents-guide.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ai-agents-guide.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/guides/ai-agents-guide.ts"],"names":[],"mappings":";;;AAEa,QAAA,aAAa,GAAsB;IAC9C,IAAI,EAAE,iBAAiB;IACvB,QAAQ,EAAE,QAAQ;IAClB,UAAU,EAAE;QACV,WAAW,EAAE,+JAA+J;QAC5K,aAAa,EAAE,EAAE;QACjB,OAAO,EAAE,0EAA0E;QACnF,WAAW,EAAE,0BAA0B;QACvC,IAAI,EAAE;YACJ,6DAA6D;YAC7D,wDAAwD;YACxD,8DAA8D;YAC9D,iEAAiE;YACjE,sDAAsD;YACtD,6DAA6D;SAC9D;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kKAoqBiJ;QAC9J,UAAU,EAAE,EAAE;QACd,OAAO,EAAE,uFAAuF;QAChG,QAAQ,EAAE;YACR,8DAA8D;YAC9D,wFAAwF;YACxF,8FAA8F;SAC/F;QACD,QAAQ,EAAE;YACR,uCAAuC;YACvC,gDAAgD;YAChD,+CAA+C;YAC/C,wEAAwE;YACxE,oCAAoC;YACpC,2CAA2C;YAC3C,gDAAgD;SACjD;QACD,WAAW,EAAE,4BAA4B;QACzC,aAAa,EAAE;YACb,qDAAqD;YACrD,gDAAgD;YAChD,sEAAsE;YACtE,uDAAuD;YACvD,2DAA2D;SAC5D;QACD,QAAQ,EAAE;YACR,yCAAyC;YACzC,gDAAgD;YAChD,+CAA+C;YAC/C,yCAAyC;YACzC,6DAA6D;SAC9D;QACD,YAAY,EAAE;YACZ,qBAAqB;YACrB,6BAA6B;YAC7B,uBAAuB;YACvB,cAAc;YACd,UAAU;SACX;KACF;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/guides/index.d.ts b/dist/mcp/tool-docs/guides/index.d.ts new file mode 100644 index 0000000..9196111 --- /dev/null +++ b/dist/mcp/tool-docs/guides/index.d.ts @@ -0,0 +1,2 @@ +export { aiAgentsGuide } from './ai-agents-guide'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/guides/index.d.ts.map b/dist/mcp/tool-docs/guides/index.d.ts.map new file mode 100644 index 0000000..a8e8fd1 --- /dev/null +++ b/dist/mcp/tool-docs/guides/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/guides/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/guides/index.js b/dist/mcp/tool-docs/guides/index.js new file mode 100644 index 0000000..e09c314 --- /dev/null +++ b/dist/mcp/tool-docs/guides/index.js @@ -0,0 +1,6 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.aiAgentsGuide = void 0; +var ai_agents_guide_1 = require("./ai-agents-guide"); +Object.defineProperty(exports, "aiAgentsGuide", { enumerable: true, get: function () { return ai_agents_guide_1.aiAgentsGuide; } }); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/guides/index.js.map b/dist/mcp/tool-docs/guides/index.js.map new file mode 100644 index 0000000..ba7b02a --- /dev/null +++ b/dist/mcp/tool-docs/guides/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/guides/index.ts"],"names":[],"mappings":";;;AACA,qDAAkD;AAAzC,gHAAA,aAAa,OAAA"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/index.d.ts b/dist/mcp/tool-docs/index.d.ts new file mode 100644 index 0000000..2957abe --- /dev/null +++ b/dist/mcp/tool-docs/index.d.ts @@ -0,0 +1,4 @@ +import { ToolDocumentation } from './types'; +export declare const toolsDocumentation: Record; +export type { ToolDocumentation } from './types'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/index.d.ts.map b/dist/mcp/tool-docs/index.d.ts.map new file mode 100644 index 0000000..5470a19 --- /dev/null +++ b/dist/mcp/tool-docs/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/mcp/tool-docs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AA4B5C,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAmChE,CAAC;AAGF,YAAY,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/index.js b/dist/mcp/tool-docs/index.js new file mode 100644 index 0000000..3b57041 --- /dev/null +++ b/dist/mcp/tool-docs/index.js @@ -0,0 +1,34 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.toolsDocumentation = void 0; +const discovery_1 = require("./discovery"); +const configuration_1 = require("./configuration"); +const validation_1 = require("./validation"); +const templates_1 = require("./templates"); +const system_1 = require("./system"); +const guides_1 = require("./guides"); +const workflow_management_1 = require("./workflow_management"); +exports.toolsDocumentation = { + tools_documentation: system_1.toolsDocumentationDoc, + n8n_health_check: system_1.n8nHealthCheckDoc, + ai_agents_guide: guides_1.aiAgentsGuide, + search_nodes: discovery_1.searchNodesDoc, + get_node: configuration_1.getNodeDoc, + validate_node: validation_1.validateNodeDoc, + validate_workflow: validation_1.validateWorkflowDoc, + get_template: templates_1.getTemplateDoc, + search_templates: templates_1.searchTemplatesDoc, + n8n_create_workflow: workflow_management_1.n8nCreateWorkflowDoc, + n8n_get_workflow: workflow_management_1.n8nGetWorkflowDoc, + n8n_update_full_workflow: workflow_management_1.n8nUpdateFullWorkflowDoc, + n8n_update_partial_workflow: workflow_management_1.n8nUpdatePartialWorkflowDoc, + n8n_delete_workflow: workflow_management_1.n8nDeleteWorkflowDoc, + n8n_list_workflows: workflow_management_1.n8nListWorkflowsDoc, + n8n_validate_workflow: workflow_management_1.n8nValidateWorkflowDoc, + n8n_autofix_workflow: workflow_management_1.n8nAutofixWorkflowDoc, + n8n_test_workflow: workflow_management_1.n8nTestWorkflowDoc, + n8n_executions: workflow_management_1.n8nExecutionsDoc, + n8n_workflow_versions: workflow_management_1.n8nWorkflowVersionsDoc, + n8n_deploy_template: workflow_management_1.n8nDeployTemplateDoc +}; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/index.js.map b/dist/mcp/tool-docs/index.js.map new file mode 100644 index 0000000..a8a1d5f --- /dev/null +++ b/dist/mcp/tool-docs/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mcp/tool-docs/index.ts"],"names":[],"mappings":";;;AAGA,2CAA6C;AAC7C,mDAA6C;AAC7C,6CAAoE;AACpE,2CAAiE;AACjE,qCAGkB;AAClB,qCAAyC;AACzC,+DAa+B;AAGlB,QAAA,kBAAkB,GAAsC;IAEnE,mBAAmB,EAAE,8BAAqB;IAC1C,gBAAgB,EAAE,0BAAiB;IAGnC,eAAe,EAAE,sBAAa;IAG9B,YAAY,EAAE,0BAAc;IAG5B,QAAQ,EAAE,0BAAU;IAGpB,aAAa,EAAE,4BAAe;IAC9B,iBAAiB,EAAE,gCAAmB;IAGtC,YAAY,EAAE,0BAAc;IAC5B,gBAAgB,EAAE,8BAAkB;IAGpC,mBAAmB,EAAE,0CAAoB;IACzC,gBAAgB,EAAE,uCAAiB;IACnC,wBAAwB,EAAE,8CAAwB;IAClD,2BAA2B,EAAE,iDAA2B;IACxD,mBAAmB,EAAE,0CAAoB;IACzC,kBAAkB,EAAE,yCAAmB;IACvC,qBAAqB,EAAE,4CAAsB;IAC7C,oBAAoB,EAAE,2CAAqB;IAC3C,iBAAiB,EAAE,wCAAkB;IACrC,cAAc,EAAE,sCAAgB;IAChC,qBAAqB,EAAE,4CAAsB;IAC7C,mBAAmB,EAAE,0CAAoB;CAC1C,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/index.d.ts b/dist/mcp/tool-docs/system/index.d.ts new file mode 100644 index 0000000..8458a16 --- /dev/null +++ b/dist/mcp/tool-docs/system/index.d.ts @@ -0,0 +1,3 @@ +export { toolsDocumentationDoc } from './tools-documentation'; +export { n8nHealthCheckDoc } from './n8n-health-check'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/index.d.ts.map b/dist/mcp/tool-docs/system/index.d.ts.map new file mode 100644 index 0000000..1d13442 --- /dev/null +++ b/dist/mcp/tool-docs/system/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/system/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/index.js b/dist/mcp/tool-docs/system/index.js new file mode 100644 index 0000000..0893d7c --- /dev/null +++ b/dist/mcp/tool-docs/system/index.js @@ -0,0 +1,8 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nHealthCheckDoc = exports.toolsDocumentationDoc = void 0; +var tools_documentation_1 = require("./tools-documentation"); +Object.defineProperty(exports, "toolsDocumentationDoc", { enumerable: true, get: function () { return tools_documentation_1.toolsDocumentationDoc; } }); +var n8n_health_check_1 = require("./n8n-health-check"); +Object.defineProperty(exports, "n8nHealthCheckDoc", { enumerable: true, get: function () { return n8n_health_check_1.n8nHealthCheckDoc; } }); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/index.js.map b/dist/mcp/tool-docs/system/index.js.map new file mode 100644 index 0000000..a99e871 --- /dev/null +++ b/dist/mcp/tool-docs/system/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/system/index.ts"],"names":[],"mappings":";;;AAAA,6DAA8D;AAArD,4HAAA,qBAAqB,OAAA;AAC9B,uDAAuD;AAA9C,qHAAA,iBAAiB,OAAA"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/n8n-diagnostic.d.ts b/dist/mcp/tool-docs/system/n8n-diagnostic.d.ts new file mode 100644 index 0000000..559d7d2 --- /dev/null +++ b/dist/mcp/tool-docs/system/n8n-diagnostic.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const n8nDiagnosticDoc: ToolDocumentation; +//# sourceMappingURL=n8n-diagnostic.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/n8n-diagnostic.d.ts.map b/dist/mcp/tool-docs/system/n8n-diagnostic.d.ts.map new file mode 100644 index 0000000..6647934 --- /dev/null +++ b/dist/mcp/tool-docs/system/n8n-diagnostic.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-diagnostic.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/system/n8n-diagnostic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,gBAAgB,EAAE,iBA8F9B,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/n8n-diagnostic.js b/dist/mcp/tool-docs/system/n8n-diagnostic.js new file mode 100644 index 0000000..f28d334 --- /dev/null +++ b/dist/mcp/tool-docs/system/n8n-diagnostic.js @@ -0,0 +1,99 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nDiagnosticDoc = void 0; +exports.n8nDiagnosticDoc = { + name: 'n8n_diagnostic', + category: 'system', + essentials: { + description: 'Comprehensive diagnostic with environment-aware debugging, version checks, performance metrics, and mode-specific troubleshooting', + keyParameters: ['verbose'], + example: 'n8n_diagnostic({verbose: true})', + performance: 'Fast - checks environment, API, and npm version (~180ms median)', + tips: [ + 'Now includes environment-aware debugging based on MCP_MODE (http/stdio)', + 'Provides mode-specific troubleshooting (HTTP server vs Claude Desktop)', + 'Detects Docker and cloud platforms for targeted guidance', + 'Shows performance metrics: response time and cache statistics', + 'Includes data-driven tips based on 82% user success rate' + ] + }, + full: { + description: `Comprehensive diagnostic tool for troubleshooting n8n API configuration and management tool availability. + +This tool performs a detailed check of: +- Environment variable configuration (N8N_API_URL, N8N_API_KEY) +- API connectivity and authentication +- Tool availability status +- Common configuration issues + +The diagnostic is essential when: +- n8n management tools aren't showing up in the available tools list +- API calls are failing with authentication or connection errors +- You need to verify your n8n instance configuration`, + parameters: { + verbose: { + type: 'boolean', + description: 'Include detailed debug information including full environment variables and API response details', + required: false, + default: false + } + }, + returns: `Comprehensive diagnostic report containing: +- timestamp: ISO timestamp of diagnostic run +- environment: Enhanced environment variables + - N8N_API_URL, N8N_API_KEY (masked), NODE_ENV, MCP_MODE + - isDocker: Boolean indicating if running in Docker + - cloudPlatform: Detected cloud platform (railway/render/fly/etc.) or null + - nodeVersion: Node.js version + - platform: OS platform (darwin/win32/linux) +- apiConfiguration: API configuration and connectivity status + - configured, status (connected/error/version), config details +- versionInfo: Version check results (current, latest, upToDate, message, updateCommand) +- toolsAvailability: Tool availability breakdown (doc tools + management tools) +- performance: Performance metrics (responseTimeMs, cacheHitRate, cachedInstances) +- modeSpecificDebug: Mode-specific debugging (ALWAYS PRESENT) + - HTTP mode: port, authTokenConfigured, serverUrl, healthCheckUrl, troubleshooting steps, commonIssues + - stdio mode: configLocation, troubleshooting steps, commonIssues +- dockerDebug: Docker-specific guidance (if IS_DOCKER=true) + - containerDetected, troubleshooting steps, commonIssues +- cloudPlatformDebug: Cloud platform-specific tips (if platform detected) + - name, troubleshooting steps tailored to platform (Railway/Render/Fly/K8s/AWS/etc.) +- nextSteps: Context-specific guidance (if API connected) +- troubleshooting: Troubleshooting guidance (if API not connecting) +- setupGuide: Setup guidance (if API not configured) +- updateWarning: Update recommendation (if version outdated) +- debug: Verbose debug information (if verbose=true)`, + examples: [ + 'n8n_diagnostic({}) - Quick diagnostic check', + 'n8n_diagnostic({verbose: true}) - Detailed diagnostic with environment info', + 'n8n_diagnostic({verbose: false}) - Standard diagnostic without sensitive data' + ], + useCases: [ + 'Initial setup verification after configuring N8N_API_URL and N8N_API_KEY', + 'Troubleshooting when n8n management tools are not available', + 'Debugging API connection failures or authentication errors', + 'Verifying n8n instance compatibility and feature availability', + 'Pre-deployment checks before using workflow management tools' + ], + performance: `Instant response time: +- No database queries +- Only checks environment and makes one test API call +- Verbose mode adds minimal overhead +- Safe to run frequently for monitoring`, + bestPractices: [ + 'Always run diagnostic first when encountering n8n tool issues', + 'Use verbose mode only in secure environments (may expose API URLs)', + 'Check diagnostic before attempting workflow operations', + 'Include diagnostic output when reporting issues', + 'Run after any configuration changes to verify setup' + ], + pitfalls: [ + 'Verbose mode may expose sensitive configuration details - use carefully', + 'Requires proper environment variables to detect n8n configuration', + 'API connectivity test requires network access to n8n instance', + 'Does not test specific workflow operations, only basic connectivity' + ], + relatedTools: ['n8n_health_check', 'n8n_list_available_tools', 'tools_documentation'] + } +}; +//# sourceMappingURL=n8n-diagnostic.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/n8n-diagnostic.js.map b/dist/mcp/tool-docs/system/n8n-diagnostic.js.map new file mode 100644 index 0000000..afc8f2a --- /dev/null +++ b/dist/mcp/tool-docs/system/n8n-diagnostic.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-diagnostic.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/system/n8n-diagnostic.ts"],"names":[],"mappings":";;;AAEa,QAAA,gBAAgB,GAAsB;IACjD,IAAI,EAAE,gBAAgB;IACtB,QAAQ,EAAE,QAAQ;IAClB,UAAU,EAAE;QACV,WAAW,EAAE,mIAAmI;QAChJ,aAAa,EAAE,CAAC,SAAS,CAAC;QAC1B,OAAO,EAAE,iCAAiC;QAC1C,WAAW,EAAE,iEAAiE;QAC9E,IAAI,EAAE;YACJ,yEAAyE;YACzE,wEAAwE;YACxE,0DAA0D;YAC1D,+DAA+D;YAC/D,0DAA0D;SAC3D;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE;;;;;;;;;;;qDAWoC;QACjD,UAAU,EAAE;YACV,OAAO,EAAE;gBACP,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,kGAAkG;gBAC/G,QAAQ,EAAE,KAAK;gBACf,OAAO,EAAE,KAAK;aACf;SACF;QACD,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;qDAwBwC;QACjD,QAAQ,EAAE;YACR,6CAA6C;YAC7C,6EAA6E;YAC7E,+EAA+E;SAChF;QACD,QAAQ,EAAE;YACR,0EAA0E;YAC1E,6DAA6D;YAC7D,4DAA4D;YAC5D,+DAA+D;YAC/D,8DAA8D;SAC/D;QACD,WAAW,EAAE;;;;wCAIuB;QACpC,aAAa,EAAE;YACb,+DAA+D;YAC/D,oEAAoE;YACpE,wDAAwD;YACxD,iDAAiD;YACjD,qDAAqD;SACtD;QACD,QAAQ,EAAE;YACR,yEAAyE;YACzE,mEAAmE;YACnE,+DAA+D;YAC/D,qEAAqE;SACtE;QACD,YAAY,EAAE,CAAC,kBAAkB,EAAE,0BAA0B,EAAE,qBAAqB,CAAC;KACtF;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/n8n-health-check.d.ts b/dist/mcp/tool-docs/system/n8n-health-check.d.ts new file mode 100644 index 0000000..ca40c52 --- /dev/null +++ b/dist/mcp/tool-docs/system/n8n-health-check.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const n8nHealthCheckDoc: ToolDocumentation; +//# sourceMappingURL=n8n-health-check.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/n8n-health-check.d.ts.map b/dist/mcp/tool-docs/system/n8n-health-check.d.ts.map new file mode 100644 index 0000000..3724344 --- /dev/null +++ b/dist/mcp/tool-docs/system/n8n-health-check.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-health-check.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/system/n8n-health-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,iBAAiB,EAAE,iBAiG/B,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/n8n-health-check.js b/dist/mcp/tool-docs/system/n8n-health-check.js new file mode 100644 index 0000000..f48e8cb --- /dev/null +++ b/dist/mcp/tool-docs/system/n8n-health-check.js @@ -0,0 +1,102 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nHealthCheckDoc = void 0; +exports.n8nHealthCheckDoc = { + name: 'n8n_health_check', + category: 'system', + essentials: { + description: 'Check n8n instance health, API connectivity, version status, and performance metrics', + keyParameters: ['mode', 'verbose'], + example: 'n8n_health_check({mode: "status"})', + performance: 'Fast - single API call (~150-200ms median)', + tips: [ + 'Use before starting workflow operations to ensure n8n is responsive', + 'Automatically checks if n8n-mcp version is outdated', + 'Returns version info, performance metrics, and next-step recommendations', + 'New: Shows cache hit rate and response time for performance monitoring' + ] + }, + full: { + description: `Performs a comprehensive health check of the configured n8n instance through its API. + +This tool verifies: +- API endpoint accessibility and response time +- n8n instance version and build information +- Authentication status and permissions +- Available features and enterprise capabilities +- Database connectivity (as reported by n8n) +- Queue system status (if configured) + +Health checks are crucial for: +- Monitoring n8n instance availability +- Detecting performance degradation +- Verifying API compatibility before operations +- Ensuring authentication is working correctly`, + parameters: { + mode: { + type: 'string', + required: false, + description: 'Operation mode: "status" (default) for quick health check, "diagnostic" for detailed debug info including env vars and tool status', + default: 'status', + enum: ['status', 'diagnostic'] + }, + verbose: { + type: 'boolean', + required: false, + description: 'Include extra details in diagnostic mode', + default: false + } + }, + returns: `Health status object containing: +- status: Overall health status ('healthy', 'degraded', 'error') +- n8nVersion: n8n instance version information +- instanceId: Unique identifier for the n8n instance +- features: Object listing available features and their status +- mcpVersion: Current n8n-mcp version +- supportedN8nVersion: Recommended n8n version for compatibility +- versionCheck: Version status information + - current: Current n8n-mcp version + - latest: Latest available version from npm + - upToDate: Boolean indicating if version is current + - message: Formatted version status message + - updateCommand: Command to update (if outdated) +- performance: Performance metrics + - responseTimeMs: API response time in milliseconds + - cacheHitRate: Cache efficiency percentage + - cachedInstances: Number of cached API instances +- nextSteps: Recommended actions after health check +- updateWarning: Warning if version is outdated (if applicable)`, + examples: [ + 'n8n_health_check({}) - Complete health check with version and performance data', + '// Use in monitoring scripts\nconst health = await n8n_health_check({});\nif (health.status !== "ok") alert("n8n is down!");\nif (!health.versionCheck.upToDate) console.log("Update available:", health.versionCheck.updateCommand);', + '// Check before critical operations\nconst health = await n8n_health_check({});\nif (health.performance.responseTimeMs > 1000) console.warn("n8n is slow");\nif (health.versionCheck.isOutdated) console.log(health.updateWarning);' + ], + useCases: [ + 'Pre-flight checks before workflow deployments', + 'Continuous monitoring of n8n instance health', + 'Troubleshooting connectivity or performance issues', + 'Verifying n8n version compatibility with workflows', + 'Detecting feature availability (enterprise features, queue mode, etc.)' + ], + performance: `Fast response expected: +- Single HTTP request to /health endpoint +- Typically responds in <100ms for healthy instances +- Timeout after 10 seconds indicates severe issues +- Minimal server load - safe for frequent polling`, + bestPractices: [ + 'Run health checks before batch operations or deployments', + 'Set up automated monitoring with regular health checks', + 'Log response times to detect performance trends', + 'Check version compatibility when deploying workflows', + 'Use health status to implement circuit breaker patterns' + ], + pitfalls: [ + 'Requires N8N_API_URL and N8N_API_KEY to be configured', + 'Network issues may cause false negatives', + 'Does not check individual workflow health', + 'Health endpoint might be cached - not real-time for all metrics' + ], + relatedTools: ['n8n_list_workflows', 'n8n_validate_workflow', 'n8n_workflow_versions'] + } +}; +//# sourceMappingURL=n8n-health-check.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/n8n-health-check.js.map b/dist/mcp/tool-docs/system/n8n-health-check.js.map new file mode 100644 index 0000000..15e9609 --- /dev/null +++ b/dist/mcp/tool-docs/system/n8n-health-check.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-health-check.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/system/n8n-health-check.ts"],"names":[],"mappings":";;;AAEa,QAAA,iBAAiB,GAAsB;IAClD,IAAI,EAAE,kBAAkB;IACxB,QAAQ,EAAE,QAAQ;IAClB,UAAU,EAAE;QACV,WAAW,EAAE,sFAAsF;QACnG,aAAa,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC;QAClC,OAAO,EAAE,oCAAoC;QAC7C,WAAW,EAAE,4CAA4C;QACzD,IAAI,EAAE;YACJ,qEAAqE;YACrE,qDAAqD;YACrD,0EAA0E;YAC1E,wEAAwE;SACzE;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE;;;;;;;;;;;;;;+CAc8B;QAC3C,UAAU,EAAE;YACV,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,oIAAoI;gBACjJ,OAAO,EAAE,QAAQ;gBACjB,IAAI,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC;aAC/B;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,0CAA0C;gBACvD,OAAO,EAAE,KAAK;aACf;SACF;QACD,OAAO,EAAE;;;;;;;;;;;;;;;;;;gEAkBmD;QAC5D,QAAQ,EAAE;YACR,gFAAgF;YAChF,uOAAuO;YACvO,qOAAqO;SACtO;QACD,QAAQ,EAAE;YACR,+CAA+C;YAC/C,8CAA8C;YAC9C,oDAAoD;YACpD,oDAAoD;YACpD,wEAAwE;SACzE;QACD,WAAW,EAAE;;;;kDAIiC;QAC9C,aAAa,EAAE;YACb,0DAA0D;YAC1D,wDAAwD;YACxD,iDAAiD;YACjD,sDAAsD;YACtD,yDAAyD;SAC1D;QACD,QAAQ,EAAE;YACR,uDAAuD;YACvD,0CAA0C;YAC1C,2CAA2C;YAC3C,iEAAiE;SAClE;QACD,YAAY,EAAE,CAAC,oBAAoB,EAAE,uBAAuB,EAAE,uBAAuB,CAAC;KACvF;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/n8n-list-available-tools.d.ts b/dist/mcp/tool-docs/system/n8n-list-available-tools.d.ts new file mode 100644 index 0000000..97c6120 --- /dev/null +++ b/dist/mcp/tool-docs/system/n8n-list-available-tools.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const n8nListAvailableToolsDoc: ToolDocumentation; +//# sourceMappingURL=n8n-list-available-tools.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/n8n-list-available-tools.d.ts.map b/dist/mcp/tool-docs/system/n8n-list-available-tools.d.ts.map new file mode 100644 index 0000000..08dac1b --- /dev/null +++ b/dist/mcp/tool-docs/system/n8n-list-available-tools.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-list-available-tools.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/system/n8n-list-available-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,wBAAwB,EAAE,iBAsEtC,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/n8n-list-available-tools.js b/dist/mcp/tool-docs/system/n8n-list-available-tools.js new file mode 100644 index 0000000..23da376 --- /dev/null +++ b/dist/mcp/tool-docs/system/n8n-list-available-tools.js @@ -0,0 +1,75 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nListAvailableToolsDoc = void 0; +exports.n8nListAvailableToolsDoc = { + name: 'n8n_list_available_tools', + category: 'system', + essentials: { + description: 'List all available n8n management tools and their capabilities', + keyParameters: [], + example: 'n8n_list_available_tools({})', + performance: 'Instant - returns static tool list', + tips: [ + 'Shows only tools available with current API configuration', + 'If no n8n tools appear, run n8n_diagnostic to troubleshoot', + 'Tool availability depends on N8N_API_URL and N8N_API_KEY being set' + ] + }, + full: { + description: `Lists all available n8n management tools based on current configuration. + +This tool provides: +- Complete list of n8n management tools (when API is configured) +- Tool descriptions and capabilities +- Categorized tool listing (workflow, execution, system) +- Dynamic availability based on API configuration + +The tool list is dynamic: +- Shows 14+ management tools when N8N_API_URL and N8N_API_KEY are configured +- Shows only documentation tools when API is not configured +- Helps discover available functionality +- Provides quick reference for tool names and purposes`, + parameters: {}, + returns: `Object containing: +- tools: Array of available tool objects, each with: + - name: Tool identifier (e.g., 'n8n_create_workflow') + - description: Brief description of tool functionality + - category: Tool category ('workflow', 'execution', 'system') + - requiresApi: Whether tool needs API configuration +- categories: Summary count by category +- totalTools: Total number of available tools +- apiConfigured: Whether n8n API is configured`, + examples: [ + 'n8n_list_available_tools({}) - List all available tools', + '// Check for specific tool availability\nconst tools = await n8n_list_available_tools({});\nconst hasWorkflowTools = tools.tools.some(t => t.category === "workflow");', + '// Discover management capabilities\nconst result = await n8n_list_available_tools({});\nconsole.log(`${result.totalTools} tools available`);' + ], + useCases: [ + 'Discovering available n8n management capabilities', + 'Checking if API configuration is working correctly', + 'Finding the right tool for a specific task', + 'Generating help documentation or command lists', + 'Verifying tool availability before automation scripts' + ], + performance: `Instant response: +- No API calls required +- Returns pre-defined tool list +- Filtered based on configuration +- Zero network overhead`, + bestPractices: [ + 'Check tool availability before building automation workflows', + 'Use with n8n_diagnostic if expected tools are missing', + 'Reference tool names exactly as returned by this tool', + 'Group operations by category for better organization', + 'Cache results as tool list only changes with configuration' + ], + pitfalls: [ + 'Tool list is empty if N8N_API_URL and N8N_API_KEY are not set', + 'Does not validate if tools will actually work - just shows availability', + 'Tool names must be used exactly as returned', + 'Does not show tool parameters - use tools_documentation for details' + ], + relatedTools: ['n8n_diagnostic', 'n8n_health_check', 'tools_documentation'] + } +}; +//# sourceMappingURL=n8n-list-available-tools.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/n8n-list-available-tools.js.map b/dist/mcp/tool-docs/system/n8n-list-available-tools.js.map new file mode 100644 index 0000000..0185ac6 --- /dev/null +++ b/dist/mcp/tool-docs/system/n8n-list-available-tools.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-list-available-tools.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/system/n8n-list-available-tools.ts"],"names":[],"mappings":";;;AAEa,QAAA,wBAAwB,GAAsB;IACzD,IAAI,EAAE,0BAA0B;IAChC,QAAQ,EAAE,QAAQ;IAClB,UAAU,EAAE;QACV,WAAW,EAAE,gEAAgE;QAC7E,aAAa,EAAE,EAAE;QACjB,OAAO,EAAE,8BAA8B;QACvC,WAAW,EAAE,oCAAoC;QACjD,IAAI,EAAE;YACJ,2DAA2D;YAC3D,4DAA4D;YAC5D,oEAAoE;SACrE;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE;;;;;;;;;;;;uDAYsC;QACnD,UAAU,EAAE,EAAE;QACd,OAAO,EAAE;;;;;;;;+CAQkC;QAC3C,QAAQ,EAAE;YACR,yDAAyD;YACzD,wKAAwK;YACxK,+IAA+I;SAChJ;QACD,QAAQ,EAAE;YACR,mDAAmD;YACnD,oDAAoD;YACpD,4CAA4C;YAC5C,gDAAgD;YAChD,uDAAuD;SACxD;QACD,WAAW,EAAE;;;;wBAIO;QACpB,aAAa,EAAE;YACb,8DAA8D;YAC9D,uDAAuD;YACvD,uDAAuD;YACvD,sDAAsD;YACtD,4DAA4D;SAC7D;QACD,QAAQ,EAAE;YACR,+DAA+D;YAC/D,yEAAyE;YACzE,6CAA6C;YAC7C,qEAAqE;SACtE;QACD,YAAY,EAAE,CAAC,gBAAgB,EAAE,kBAAkB,EAAE,qBAAqB,CAAC;KAC5E;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/tools-documentation.d.ts b/dist/mcp/tool-docs/system/tools-documentation.d.ts new file mode 100644 index 0000000..940c817 --- /dev/null +++ b/dist/mcp/tool-docs/system/tools-documentation.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const toolsDocumentationDoc: ToolDocumentation; +//# sourceMappingURL=tools-documentation.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/tools-documentation.d.ts.map b/dist/mcp/tool-docs/system/tools-documentation.d.ts.map new file mode 100644 index 0000000..cf0393b --- /dev/null +++ b/dist/mcp/tool-docs/system/tools-documentation.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"tools-documentation.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/system/tools-documentation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,qBAAqB,EAAE,iBA4DnC,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/tools-documentation.js b/dist/mcp/tool-docs/system/tools-documentation.js new file mode 100644 index 0000000..901d031 --- /dev/null +++ b/dist/mcp/tool-docs/system/tools-documentation.js @@ -0,0 +1,65 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.toolsDocumentationDoc = void 0; +exports.toolsDocumentationDoc = { + name: 'tools_documentation', + category: 'system', + essentials: { + description: 'The meta-documentation tool. Returns documentation for any MCP tool, including itself. Call without parameters for a comprehensive overview of all available tools. This is your starting point for discovering n8n MCP capabilities.', + keyParameters: ['topic', 'depth'], + example: 'tools_documentation({topic: "search_nodes"})', + performance: 'Instant (static content)', + tips: [ + 'Call without parameters first to see all tools', + 'Can document itself: tools_documentation({topic: "tools_documentation"})', + 'Use depth:"full" for comprehensive details' + ] + }, + full: { + description: 'The self-referential documentation system for all MCP tools. This tool can document any other tool, including itself. It\'s the primary discovery mechanism for understanding what tools are available and how to use them. Returns utilitarian documentation optimized for AI agent consumption.', + parameters: { + topic: { type: 'string', description: 'Tool name (e.g., "search_nodes"), special topic ("javascript_code_node_guide", "python_code_node_guide"), or "overview". Leave empty for quick reference.', required: false }, + depth: { type: 'string', description: 'Level of detail: "essentials" (default, concise) or "full" (comprehensive with examples)', required: false } + }, + returns: 'Markdown-formatted documentation tailored for the requested tool and depth. For essentials: key info, parameters, example, tips. For full: complete details, all examples, use cases, best practices.', + examples: [ + '// Get started - see all available tools', + 'tools_documentation()', + '', + '// Learn about a specific tool', + 'tools_documentation({topic: "search_nodes"})', + '', + '// Get comprehensive details', + 'tools_documentation({topic: "validate_workflow", depth: "full"})', + '', + '// Self-referential example - document this tool', + 'tools_documentation({topic: "tools_documentation", depth: "full"})', + '', + '// Code node guides', + 'tools_documentation({topic: "javascript_code_node_guide"})', + 'tools_documentation({topic: "python_code_node_guide"})' + ], + useCases: [ + 'Initial discovery of available MCP tools', + 'Learning how to use specific tools', + 'Finding required and optional parameters', + 'Getting working examples to copy', + 'Understanding tool performance characteristics', + 'Discovering related tools for workflows' + ], + performance: 'Instant - all documentation is pre-loaded in memory', + bestPractices: [ + 'Always start with tools_documentation() to see available tools', + 'Use essentials for quick parameter reference during coding', + 'Switch to full depth when debugging or learning new tools', + 'Check Code node guides when working with Code nodes' + ], + pitfalls: [ + 'Tool names must match exactly - use the overview to find correct names', + 'Not all internal functions are documented', + 'Special topics (code guides) require exact names' + ], + relatedTools: ['n8n_health_check for verifying API connection', 'search_templates for workflow examples', 'search_nodes for finding nodes'] + } +}; +//# sourceMappingURL=tools-documentation.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/system/tools-documentation.js.map b/dist/mcp/tool-docs/system/tools-documentation.js.map new file mode 100644 index 0000000..f355090 --- /dev/null +++ b/dist/mcp/tool-docs/system/tools-documentation.js.map @@ -0,0 +1 @@ +{"version":3,"file":"tools-documentation.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/system/tools-documentation.ts"],"names":[],"mappings":";;;AAEa,QAAA,qBAAqB,GAAsB;IACtD,IAAI,EAAE,qBAAqB;IAC3B,QAAQ,EAAE,QAAQ;IAClB,UAAU,EAAE;QACV,WAAW,EAAE,uOAAuO;QACpP,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;QACjC,OAAO,EAAE,8CAA8C;QACvD,WAAW,EAAE,0BAA0B;QACvC,IAAI,EAAE;YACJ,gDAAgD;YAChD,0EAA0E;YAC1E,4CAA4C;SAC7C;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE,mSAAmS;QAChT,UAAU,EAAE;YACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,2JAA2J,EAAE,QAAQ,EAAE,KAAK,EAAE;YACpN,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0FAA0F,EAAE,QAAQ,EAAE,KAAK,EAAE;SACpJ;QACD,OAAO,EAAE,uMAAuM;QAChN,QAAQ,EAAE;YACR,0CAA0C;YAC1C,uBAAuB;YACvB,EAAE;YACF,gCAAgC;YAChC,8CAA8C;YAC9C,EAAE;YACF,8BAA8B;YAC9B,kEAAkE;YAClE,EAAE;YACF,kDAAkD;YAClD,oEAAoE;YACpE,EAAE;YACF,qBAAqB;YACrB,4DAA4D;YAC5D,wDAAwD;SACzD;QACD,QAAQ,EAAE;YACR,0CAA0C;YAC1C,oCAAoC;YACpC,0CAA0C;YAC1C,kCAAkC;YAClC,gDAAgD;YAChD,yCAAyC;SAC1C;QACD,WAAW,EAAE,qDAAqD;QAClE,aAAa,EAAE;YACb,gEAAgE;YAChE,4DAA4D;YAC5D,2DAA2D;YAC3D,qDAAqD;SACtD;QACD,QAAQ,EAAE;YACR,wEAAwE;YACxE,2CAA2C;YAC3C,kDAAkD;SACnD;QACD,YAAY,EAAE,CAAC,+CAA+C,EAAE,wCAAwC,EAAE,gCAAgC,CAAC;KAC5I;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/templates/get-template.d.ts b/dist/mcp/tool-docs/templates/get-template.d.ts new file mode 100644 index 0000000..c9a3f24 --- /dev/null +++ b/dist/mcp/tool-docs/templates/get-template.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const getTemplateDoc: ToolDocumentation; +//# sourceMappingURL=get-template.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/templates/get-template.d.ts.map b/dist/mcp/tool-docs/templates/get-template.d.ts.map new file mode 100644 index 0000000..12e298b --- /dev/null +++ b/dist/mcp/tool-docs/templates/get-template.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"get-template.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/templates/get-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,cAAc,EAAE,iBA+E5B,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/templates/get-template.js b/dist/mcp/tool-docs/templates/get-template.js new file mode 100644 index 0000000..1019ed7 --- /dev/null +++ b/dist/mcp/tool-docs/templates/get-template.js @@ -0,0 +1,84 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getTemplateDoc = void 0; +exports.getTemplateDoc = { + name: 'get_template', + category: 'templates', + essentials: { + description: 'Get workflow template by ID with configurable detail level. Ready to import. IDs from search_templates.', + keyParameters: ['templateId', 'mode'], + example: 'get_template({templateId: 1234, mode: "full"})', + performance: 'Fast (<100ms) - single database lookup', + tips: [ + 'Get template IDs from search_templates first', + 'Use mode="nodes_only" for quick overview, "structure" for topology, "full" for import', + 'Returns complete workflow JSON ready for import into n8n' + ] + }, + full: { + description: `Retrieves the complete workflow JSON for a specific template by its ID. The returned workflow can be directly imported into n8n through the UI or API. This tool fetches pre-built workflows from the community template library containing 2,700+ curated workflows.`, + parameters: { + templateId: { + type: 'number', + required: true, + description: 'The numeric ID of the template to retrieve. Get IDs from search_templates' + }, + mode: { + type: 'string', + required: false, + description: 'Response detail level: "nodes_only" (minimal - just node list), "structure" (nodes + connections), "full" (complete workflow JSON, default)', + default: 'full', + enum: ['nodes_only', 'structure', 'full'] + } + }, + returns: `Returns an object containing: +- template: Complete template information including workflow JSON + - id: Template ID + - name: Template name + - description: What the workflow does + - author: Creator information (name, username, verified status) + - nodes: Array of node types used + - views: Number of times viewed + - created: Creation date + - url: Link to template on n8n.io + - workflow: Complete workflow JSON with structure: + - nodes: Array of node objects (id, name, type, typeVersion, position, parameters) + - connections: Object mapping source nodes to targets + - settings: Workflow configuration (timezone, error handling, etc.) +- usage: Instructions for using the workflow`, + examples: [ + 'get_template({templateId: 1234}) - Get complete workflow (default mode="full")', + 'get_template({templateId: 1234, mode: "nodes_only"}) - Get just the node list', + 'get_template({templateId: 1234, mode: "structure"}) - Get nodes and connections', + 'get_template({templateId: 5678, mode: "full"}) - Get complete workflow JSON for import' + ], + useCases: [ + 'Download workflows for direct import into n8n', + 'Study workflow patterns and best practices', + 'Get complete workflow JSON for customization', + 'Clone popular workflows for your use case', + 'Learn how complex automations are built' + ], + performance: `Fast performance with single database lookup: +- Query time: <10ms for template retrieval +- Workflow JSON parsing: <50ms +- Total response time: <100ms +- No network calls (uses local cache)`, + bestPractices: [ + 'Always check if template exists before attempting modifications', + 'Review workflow nodes before importing to ensure compatibility', + 'Save template JSON locally if planning multiple customizations', + 'Check template creation date for most recent patterns', + 'Verify all required credentials are configured before import' + ], + pitfalls: [ + 'Template IDs change when database is refreshed', + 'Some templates may use deprecated node versions', + 'Credentials in templates are placeholders - configure your own', + 'Not all templates work with all n8n versions', + 'Template may reference external services you don\'t have access to' + ], + relatedTools: ['search_templates', 'n8n_create_workflow'] + } +}; +//# sourceMappingURL=get-template.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/templates/get-template.js.map b/dist/mcp/tool-docs/templates/get-template.js.map new file mode 100644 index 0000000..138aa13 --- /dev/null +++ b/dist/mcp/tool-docs/templates/get-template.js.map @@ -0,0 +1 @@ +{"version":3,"file":"get-template.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/templates/get-template.ts"],"names":[],"mappings":";;;AAEa,QAAA,cAAc,GAAsB;IAC/C,IAAI,EAAE,cAAc;IACpB,QAAQ,EAAE,WAAW;IACrB,UAAU,EAAE;QACV,WAAW,EAAE,yGAAyG;QACtH,aAAa,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC;QACrC,OAAO,EAAE,gDAAgD;QACzD,WAAW,EAAE,wCAAwC;QACrD,IAAI,EAAE;YACJ,8CAA8C;YAC9C,uFAAuF;YACvF,0DAA0D;SAC3D;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE,uQAAuQ;QACpR,UAAU,EAAE;YACV,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,2EAA2E;aACzF;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,6IAA6I;gBAC1J,OAAO,EAAE,MAAM;gBACf,IAAI,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,MAAM,CAAC;aAC1C;SACF;QACD,OAAO,EAAE;;;;;;;;;;;;;;6CAcgC;QACzC,QAAQ,EAAE;YACR,gFAAgF;YAChF,+EAA+E;YAC/E,iFAAiF;YACjF,wFAAwF;SACzF;QACD,QAAQ,EAAE;YACR,+CAA+C;YAC/C,4CAA4C;YAC5C,8CAA8C;YAC9C,2CAA2C;YAC3C,yCAAyC;SAC1C;QACD,WAAW,EAAE;;;;sCAIqB;QAClC,aAAa,EAAE;YACb,iEAAiE;YACjE,gEAAgE;YAChE,gEAAgE;YAChE,uDAAuD;YACvD,8DAA8D;SAC/D;QACD,QAAQ,EAAE;YACR,gDAAgD;YAChD,iDAAiD;YACjD,gEAAgE;YAChE,8CAA8C;YAC9C,oEAAoE;SACrE;QACD,YAAY,EAAE,CAAC,kBAAkB,EAAE,qBAAqB,CAAC;KAC1D;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/templates/index.d.ts b/dist/mcp/tool-docs/templates/index.d.ts new file mode 100644 index 0000000..002d92c --- /dev/null +++ b/dist/mcp/tool-docs/templates/index.d.ts @@ -0,0 +1,3 @@ +export { getTemplateDoc } from './get-template'; +export { searchTemplatesDoc } from './search-templates'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/templates/index.d.ts.map b/dist/mcp/tool-docs/templates/index.d.ts.map new file mode 100644 index 0000000..b6d37bc --- /dev/null +++ b/dist/mcp/tool-docs/templates/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/templates/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/templates/index.js b/dist/mcp/tool-docs/templates/index.js new file mode 100644 index 0000000..17ccd2a --- /dev/null +++ b/dist/mcp/tool-docs/templates/index.js @@ -0,0 +1,8 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.searchTemplatesDoc = exports.getTemplateDoc = void 0; +var get_template_1 = require("./get-template"); +Object.defineProperty(exports, "getTemplateDoc", { enumerable: true, get: function () { return get_template_1.getTemplateDoc; } }); +var search_templates_1 = require("./search-templates"); +Object.defineProperty(exports, "searchTemplatesDoc", { enumerable: true, get: function () { return search_templates_1.searchTemplatesDoc; } }); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/templates/index.js.map b/dist/mcp/tool-docs/templates/index.js.map new file mode 100644 index 0000000..f7f1a62 --- /dev/null +++ b/dist/mcp/tool-docs/templates/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/templates/index.ts"],"names":[],"mappings":";;;AAAA,+CAAgD;AAAvC,8GAAA,cAAc,OAAA;AACvB,uDAAwD;AAA/C,sHAAA,kBAAkB,OAAA"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/templates/search-templates.d.ts b/dist/mcp/tool-docs/templates/search-templates.d.ts new file mode 100644 index 0000000..176c261 --- /dev/null +++ b/dist/mcp/tool-docs/templates/search-templates.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const searchTemplatesDoc: ToolDocumentation; +//# sourceMappingURL=search-templates.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/templates/search-templates.d.ts.map b/dist/mcp/tool-docs/templates/search-templates.d.ts.map new file mode 100644 index 0000000..7bbd1ab --- /dev/null +++ b/dist/mcp/tool-docs/templates/search-templates.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"search-templates.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/templates/search-templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,kBAAkB,EAAE,iBA0IhC,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/templates/search-templates.js b/dist/mcp/tool-docs/templates/search-templates.js new file mode 100644 index 0000000..9cbff2e --- /dev/null +++ b/dist/mcp/tool-docs/templates/search-templates.js @@ -0,0 +1,143 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.searchTemplatesDoc = void 0; +exports.searchTemplatesDoc = { + name: 'search_templates', + category: 'templates', + essentials: { + description: 'Unified template search with multiple modes: keyword search, by node types, by task type, or by metadata. 2,700+ templates available.', + keyParameters: ['searchMode', 'query', 'nodeTypes', 'task', 'limit'], + example: 'search_templates({searchMode: "by_task", task: "webhook_processing"})', + performance: 'Fast (<100ms) - FTS5 full-text search', + tips: [ + 'searchMode="keyword" (default): Search by name/description', + 'searchMode="by_nodes": Find templates using specific nodes', + 'searchMode="by_task": Get curated templates for common tasks', + 'searchMode="by_metadata": Filter by complexity, services, audience' + ] + }, + full: { + description: `**Search Modes:** +- keyword (default): Full-text search across template names and descriptions +- by_nodes: Find templates that use specific node types +- by_task: Get curated templates for predefined task categories +- by_metadata: Filter by complexity, setup time, required services, or target audience + +**Available Task Types (for searchMode="by_task"):** +ai_automation, data_sync, webhook_processing, email_automation, slack_integration, data_transformation, file_processing, scheduling, api_integration, database_operations`, + parameters: { + searchMode: { + type: 'string', + required: false, + description: 'Search mode: "keyword" (default), "by_nodes", "by_task", "by_metadata"' + }, + query: { + type: 'string', + required: false, + description: 'For searchMode=keyword: Search keywords (e.g., "chatbot", "automation")' + }, + nodeTypes: { + type: 'array', + required: false, + description: 'For searchMode=by_nodes: Array of node types (e.g., ["n8n-nodes-base.httpRequest", "n8n-nodes-base.slack"])' + }, + task: { + type: 'string', + required: false, + description: 'For searchMode=by_task: Task type (ai_automation, data_sync, webhook_processing, email_automation, slack_integration, data_transformation, file_processing, scheduling, api_integration, database_operations)' + }, + complexity: { + type: 'string', + required: false, + description: 'For searchMode=by_metadata: Filter by complexity ("simple", "medium", "complex")' + }, + maxSetupMinutes: { + type: 'number', + required: false, + description: 'For searchMode=by_metadata: Maximum setup time in minutes (5-480)' + }, + minSetupMinutes: { + type: 'number', + required: false, + description: 'For searchMode=by_metadata: Minimum setup time in minutes (5-480)' + }, + requiredService: { + type: 'string', + required: false, + description: 'For searchMode=by_metadata: Filter by required service (e.g., "openai", "slack", "google")' + }, + targetAudience: { + type: 'string', + required: false, + description: 'For searchMode=by_metadata: Filter by target audience (e.g., "developers", "marketers")' + }, + category: { + type: 'string', + required: false, + description: 'For searchMode=by_metadata: Filter by category (e.g., "automation", "integration")' + }, + fields: { + type: 'array', + required: false, + description: 'For searchMode=keyword: Fields to include (id, name, description, author, nodes, views, created, url, metadata)' + }, + limit: { + type: 'number', + required: false, + description: 'Maximum results (default 20, max 100)' + }, + offset: { + type: 'number', + required: false, + description: 'Pagination offset (default 0)' + } + }, + returns: `Returns an object containing: +- templates: Array of matching templates + - id: Template ID for get_template() + - name: Template name + - description: What the workflow does + - author: Creator information + - nodes: Array of node types used + - views: Popularity metric + - created: Creation date + - url: Link to template + - metadata: AI-generated metadata (complexity, services, etc.) +- totalFound: Total matching templates +- searchMode: The mode used`, + examples: [ + '// Keyword search (default)\nsearch_templates({query: "chatbot"})', + '// Find templates using specific nodes\nsearch_templates({searchMode: "by_nodes", nodeTypes: ["n8n-nodes-base.httpRequest", "n8n-nodes-base.slack"]})', + '// Get templates for a task type\nsearch_templates({searchMode: "by_task", task: "webhook_processing"})', + '// Filter by metadata\nsearch_templates({searchMode: "by_metadata", complexity: "simple", requiredService: "openai"})', + '// Combine metadata filters\nsearch_templates({searchMode: "by_metadata", maxSetupMinutes: 30, targetAudience: "developers"})' + ], + useCases: [ + 'Find workflows by business purpose (keyword search)', + 'Find templates using specific integrations (by_nodes)', + 'Get pre-built solutions for common tasks (by_task)', + 'Filter by complexity for team skill level (by_metadata)', + 'Find templates requiring specific services (by_metadata)' + ], + performance: `Fast performance across all modes: +- keyword: <50ms with FTS5 indexing +- by_nodes: <100ms with indexed lookups +- by_task: <50ms from curated cache +- by_metadata: <100ms with filtered queries`, + bestPractices: [ + 'Use searchMode="by_task" for common automation patterns', + 'Use searchMode="by_nodes" when you know which integrations you need', + 'Use searchMode="keyword" for general discovery', + 'Combine by_metadata filters for precise matching', + 'Use get_template(id) to get the full workflow JSON' + ], + pitfalls: [ + 'searchMode="keyword" searches names/descriptions, not node types', + 'by_nodes requires full node type with prefix (n8n-nodes-base.xxx)', + 'by_metadata filters may return fewer results', + 'Not all templates have complete metadata' + ], + relatedTools: ['get_template', 'search_nodes', 'validate_workflow'] + } +}; +//# sourceMappingURL=search-templates.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/templates/search-templates.js.map b/dist/mcp/tool-docs/templates/search-templates.js.map new file mode 100644 index 0000000..0c0037b --- /dev/null +++ b/dist/mcp/tool-docs/templates/search-templates.js.map @@ -0,0 +1 @@ +{"version":3,"file":"search-templates.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/templates/search-templates.ts"],"names":[],"mappings":";;;AAEa,QAAA,kBAAkB,GAAsB;IACnD,IAAI,EAAE,kBAAkB;IACxB,QAAQ,EAAE,WAAW;IACrB,UAAU,EAAE;QACV,WAAW,EAAE,uIAAuI;QACpJ,aAAa,EAAE,CAAC,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC;QACpE,OAAO,EAAE,uEAAuE;QAChF,WAAW,EAAE,uCAAuC;QACpD,IAAI,EAAE;YACJ,4DAA4D;YAC5D,4DAA4D;YAC5D,8DAA8D;YAC9D,oEAAoE;SACrE;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE;;;;;;;0KAOyJ;QACtK,UAAU,EAAE;YACV,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,wEAAwE;aACtF;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,yEAAyE;aACvF;YACD,SAAS,EAAE;gBACT,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,6GAA6G;aAC3H;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,+MAA+M;aAC7N;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,kFAAkF;aAChG;YACD,eAAe,EAAE;gBACf,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,mEAAmE;aACjF;YACD,eAAe,EAAE;gBACf,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,mEAAmE;aACjF;YACD,eAAe,EAAE;gBACf,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,4FAA4F;aAC1G;YACD,cAAc,EAAE;gBACd,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,yFAAyF;aACvG;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,oFAAoF;aAClG;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,iHAAiH;aAC/H;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,uCAAuC;aACrD;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,+BAA+B;aAC7C;SACF;QACD,OAAO,EAAE;;;;;;;;;;;;4BAYe;QACxB,QAAQ,EAAE;YACR,mEAAmE;YACnE,uJAAuJ;YACvJ,yGAAyG;YACzG,uHAAuH;YACvH,+HAA+H;SAChI;QACD,QAAQ,EAAE;YACR,qDAAqD;YACrD,uDAAuD;YACvD,oDAAoD;YACpD,yDAAyD;YACzD,0DAA0D;SAC3D;QACD,WAAW,EAAE;;;;4CAI2B;QACxC,aAAa,EAAE;YACb,yDAAyD;YACzD,qEAAqE;YACrE,gDAAgD;YAChD,kDAAkD;YAClD,oDAAoD;SACrD;QACD,QAAQ,EAAE;YACR,kEAAkE;YAClE,mEAAmE;YACnE,8CAA8C;YAC9C,0CAA0C;SAC3C;QACD,YAAY,EAAE,CAAC,cAAc,EAAE,cAAc,EAAE,mBAAmB,CAAC;KACpE;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/types.d.ts b/dist/mcp/tool-docs/types.d.ts new file mode 100644 index 0000000..9f3cb70 --- /dev/null +++ b/dist/mcp/tool-docs/types.d.ts @@ -0,0 +1,32 @@ +export interface ToolDocumentation { + name: string; + category: string; + essentials: { + description: string; + keyParameters: string[]; + example: string; + performance: string; + tips: string[]; + }; + full: { + description: string; + parameters: Record; + returns: string; + examples: string[]; + useCases: string[]; + performance: string; + errorHandling?: string; + bestPractices: string[]; + pitfalls: string[]; + modeComparison?: string; + relatedTools: string[]; + }; +} +//# sourceMappingURL=types.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/types.d.ts.map b/dist/mcp/tool-docs/types.d.ts.map new file mode 100644 index 0000000..56ca72c --- /dev/null +++ b/dist/mcp/tool-docs/types.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/mcp/tool-docs/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE;QACV,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,EAAE,CAAC;KAChB,CAAC;IACF,IAAI,EAAE;QACJ,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE;YACzB,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,CAAC;YACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;YACnB,OAAO,CAAC,EAAE,GAAG,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;SACjB,CAAC,CAAC;QACH,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,MAAM,EAAE,CAAC;KACxB,CAAC;CACH"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/types.js b/dist/mcp/tool-docs/types.js new file mode 100644 index 0000000..11e638d --- /dev/null +++ b/dist/mcp/tool-docs/types.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/types.js.map b/dist/mcp/tool-docs/types.js.map new file mode 100644 index 0000000..f912470 --- /dev/null +++ b/dist/mcp/tool-docs/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/mcp/tool-docs/types.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/mcp/tool-docs/validation/index.d.ts b/dist/mcp/tool-docs/validation/index.d.ts new file mode 100644 index 0000000..721d044 --- /dev/null +++ b/dist/mcp/tool-docs/validation/index.d.ts @@ -0,0 +1,3 @@ +export { validateNodeDoc } from './validate-node'; +export { validateWorkflowDoc } from './validate-workflow'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/validation/index.d.ts.map b/dist/mcp/tool-docs/validation/index.d.ts.map new file mode 100644 index 0000000..8bf5152 --- /dev/null +++ b/dist/mcp/tool-docs/validation/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/validation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/validation/index.js b/dist/mcp/tool-docs/validation/index.js new file mode 100644 index 0000000..88f2eed --- /dev/null +++ b/dist/mcp/tool-docs/validation/index.js @@ -0,0 +1,8 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.validateWorkflowDoc = exports.validateNodeDoc = void 0; +var validate_node_1 = require("./validate-node"); +Object.defineProperty(exports, "validateNodeDoc", { enumerable: true, get: function () { return validate_node_1.validateNodeDoc; } }); +var validate_workflow_1 = require("./validate-workflow"); +Object.defineProperty(exports, "validateWorkflowDoc", { enumerable: true, get: function () { return validate_workflow_1.validateWorkflowDoc; } }); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/validation/index.js.map b/dist/mcp/tool-docs/validation/index.js.map new file mode 100644 index 0000000..8d0e01f --- /dev/null +++ b/dist/mcp/tool-docs/validation/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/validation/index.ts"],"names":[],"mappings":";;;AAAA,iDAAkD;AAAzC,gHAAA,eAAe,OAAA;AACxB,yDAA0D;AAAjD,wHAAA,mBAAmB,OAAA"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/validation/validate-node.d.ts b/dist/mcp/tool-docs/validation/validate-node.d.ts new file mode 100644 index 0000000..4be5af2 --- /dev/null +++ b/dist/mcp/tool-docs/validation/validate-node.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const validateNodeDoc: ToolDocumentation; +//# sourceMappingURL=validate-node.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/validation/validate-node.d.ts.map b/dist/mcp/tool-docs/validation/validate-node.d.ts.map new file mode 100644 index 0000000..b471494 --- /dev/null +++ b/dist/mcp/tool-docs/validation/validate-node.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"validate-node.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/validation/validate-node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,eAAe,EAAE,iBA6E7B,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/validation/validate-node.js b/dist/mcp/tool-docs/validation/validate-node.js new file mode 100644 index 0000000..31671dd --- /dev/null +++ b/dist/mcp/tool-docs/validation/validate-node.js @@ -0,0 +1,82 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.validateNodeDoc = void 0; +exports.validateNodeDoc = { + name: 'validate_node', + category: 'validation', + essentials: { + description: 'Validate n8n node configuration. Use mode="full" for comprehensive validation with errors/warnings/suggestions, mode="minimal" for quick required fields check.', + keyParameters: ['nodeType', 'config', 'mode', 'profile'], + example: 'validate_node({nodeType: "nodes-base.slack", config: {resource: "channel", operation: "create"}})', + performance: 'Fast (<100ms)', + tips: [ + 'Always call get_node({detail:"standard"}) first to see required fields', + 'Use mode="minimal" for quick checks during development', + 'Use mode="full" with profile="strict" before production deployment', + 'Includes automatic structure validation for filter, resourceMapper, etc.' + ] + }, + full: { + description: `**Validation Modes:** +- full (default): Comprehensive validation with errors, warnings, suggestions, and automatic structure validation +- minimal: Quick check for required fields only - fast but less thorough + +**Validation Profiles (for mode="full"):** +- minimal: Very lenient, basic checks only +- runtime: Standard validation (default) +- ai-friendly: Balanced for AI agent workflows +- strict: Most thorough, recommended for production + +**Automatic Structure Validation:** +Validates complex n8n types automatically: +- filter (FilterValue): 40+ operations (equals, contains, regex, etc.) +- resourceMapper (ResourceMapperValue): Data mapping configuration +- assignmentCollection (AssignmentCollectionValue): Variable assignments +- resourceLocator (INodeParameterResourceLocator): Resource selection modes`, + parameters: { + nodeType: { type: 'string', required: true, description: 'Node type with prefix: "nodes-base.slack"' }, + config: { type: 'object', required: true, description: 'Configuration object to validate. Use {} for empty config' }, + mode: { type: 'string', required: false, description: 'Validation mode: "full" (default) or "minimal"' }, + profile: { type: 'string', required: false, description: 'Validation profile for mode=full: "minimal", "runtime" (default), "ai-friendly", "strict"' } + }, + returns: `Object containing: +- nodeType: The validated node type +- workflowNodeType: Type to use in workflow JSON +- displayName: Human-readable node name +- valid: Boolean indicating if configuration is valid +- errors: Array of error objects with type, property, message, fix +- warnings: Array of warning objects with suggestions +- suggestions: Array of improvement suggestions +- missingRequiredFields: (mode=minimal only) Array of missing required field names +- summary: Object with hasErrors, errorCount, warningCount, suggestionCount`, + examples: [ + '// Full validation with default profile\nvalidate_node({nodeType: "nodes-base.slack", config: {resource: "channel", operation: "create"}})', + '// Quick required fields check\nvalidate_node({nodeType: "nodes-base.webhook", config: {}, mode: "minimal"})', + '// Strict validation for production\nvalidate_node({nodeType: "nodes-base.httpRequest", config: {...}, mode: "full", profile: "strict"})', + '// Validate IF node with filter\nvalidate_node({nodeType: "nodes-base.if", config: {conditions: {combinator: "and", conditions: [...]}}})' + ], + useCases: [ + 'Validate node configuration before adding to workflow', + 'Quick check for required fields during development', + 'Pre-production validation with strict profile', + 'Validate complex structures (filters, resource mappers)', + 'Get suggestions for improving node configuration' + ], + performance: 'Fast validation: <50ms for minimal mode, <100ms for full mode. Structure validation adds minimal overhead.', + bestPractices: [ + 'Always call get_node() first to understand required fields', + 'Use mode="minimal" for rapid iteration during development', + 'Use profile="strict" before deploying to production', + 'Pay attention to warnings - they often prevent runtime issues', + 'Validate after any configuration changes' + ], + pitfalls: [ + 'Empty config {} is valid for some nodes (e.g., manual trigger)', + 'mode="minimal" only checks required fields, not value validity', + 'Some warnings may be acceptable for specific use cases', + 'Credential validation requires runtime context' + ], + relatedTools: ['get_node', 'validate_workflow', 'n8n_autofix_workflow'] + } +}; +//# sourceMappingURL=validate-node.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/validation/validate-node.js.map b/dist/mcp/tool-docs/validation/validate-node.js.map new file mode 100644 index 0000000..bac8308 --- /dev/null +++ b/dist/mcp/tool-docs/validation/validate-node.js.map @@ -0,0 +1 @@ +{"version":3,"file":"validate-node.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/validation/validate-node.ts"],"names":[],"mappings":";;;AAEa,QAAA,eAAe,GAAsB;IAChD,IAAI,EAAE,eAAe;IACrB,QAAQ,EAAE,YAAY;IACtB,UAAU,EAAE;QACV,WAAW,EAAE,iKAAiK;QAC9K,aAAa,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC;QACxD,OAAO,EAAE,mGAAmG;QAC5G,WAAW,EAAE,eAAe;QAC5B,IAAI,EAAE;YACJ,wEAAwE;YACxE,wDAAwD;YACxD,oEAAoE;YACpE,0EAA0E;SAC3E;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE;;;;;;;;;;;;;;;4EAe2D;QACxE,UAAU,EAAE;YACV,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,2CAA2C,EAAE;YACtG,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,2DAA2D,EAAE;YACpH,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,gDAAgD,EAAE;YACxG,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,2FAA2F,EAAE;SACvJ;QACD,OAAO,EAAE;;;;;;;;;4EAS+D;QACxE,QAAQ,EAAE;YACR,4IAA4I;YAC5I,8GAA8G;YAC9G,0IAA0I;YAC1I,2IAA2I;SAC5I;QACD,QAAQ,EAAE;YACR,uDAAuD;YACvD,oDAAoD;YACpD,+CAA+C;YAC/C,yDAAyD;YACzD,kDAAkD;SACnD;QACD,WAAW,EAAE,4GAA4G;QACzH,aAAa,EAAE;YACb,4DAA4D;YAC5D,2DAA2D;YAC3D,qDAAqD;YACrD,+DAA+D;YAC/D,0CAA0C;SAC3C;QACD,QAAQ,EAAE;YACR,gEAAgE;YAChE,gEAAgE;YAChE,wDAAwD;YACxD,gDAAgD;SACjD;QACD,YAAY,EAAE,CAAC,UAAU,EAAE,mBAAmB,EAAE,sBAAsB,CAAC;KACxE;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/validation/validate-workflow.d.ts b/dist/mcp/tool-docs/validation/validate-workflow.d.ts new file mode 100644 index 0000000..fd80762 --- /dev/null +++ b/dist/mcp/tool-docs/validation/validate-workflow.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const validateWorkflowDoc: ToolDocumentation; +//# sourceMappingURL=validate-workflow.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/validation/validate-workflow.d.ts.map b/dist/mcp/tool-docs/validation/validate-workflow.d.ts.map new file mode 100644 index 0000000..2272e5a --- /dev/null +++ b/dist/mcp/tool-docs/validation/validate-workflow.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"validate-workflow.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/validation/validate-workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,mBAAmB,EAAE,iBAiFjC,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/validation/validate-workflow.js b/dist/mcp/tool-docs/validation/validate-workflow.js new file mode 100644 index 0000000..204e929 --- /dev/null +++ b/dist/mcp/tool-docs/validation/validate-workflow.js @@ -0,0 +1,86 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.validateWorkflowDoc = void 0; +exports.validateWorkflowDoc = { + name: 'validate_workflow', + category: 'validation', + essentials: { + description: 'Full workflow validation: structure, connections, expressions, AI tools. Returns errors/warnings/fixes. Essential before deploy.', + keyParameters: ['workflow', 'options'], + example: 'validate_workflow({workflow: {nodes: [...], connections: {...}}})', + performance: 'Moderate (100-500ms)', + tips: [ + 'Always validate before n8n_create_workflow to catch errors early', + 'Use options.profile="minimal" for quick checks during development', + 'AI tool connections are automatically validated for proper node references', + 'Detects operator structure issues (binary vs unary, singleValue requirements)' + ] + }, + full: { + description: 'Performs comprehensive validation of n8n workflows including structure, node configurations, connections, and expressions. This is a three-layer validation system that catches errors before deployment, validates complex multi-node workflows, checks all n8n expressions for syntax errors, and ensures proper node connections and data flow.', + parameters: { + workflow: { + type: 'object', + required: true, + description: 'The complete workflow JSON to validate. Must include nodes array and connections object.' + }, + options: { + type: 'object', + required: false, + description: 'Validation options object' + }, + 'options.validateNodes': { + type: 'boolean', + required: false, + description: 'Validate individual node configurations. Default: true' + }, + 'options.validateConnections': { + type: 'boolean', + required: false, + description: 'Validate node connections and flow. Default: true' + }, + 'options.validateExpressions': { + type: 'boolean', + required: false, + description: 'Validate n8n expressions syntax and references. Default: true' + }, + 'options.profile': { + type: 'string', + required: false, + description: 'Validation profile for node validation: minimal, runtime (default), ai-friendly, strict' + } + }, + returns: 'Object with valid (boolean), errors (array), warnings (array), statistics (object), and suggestions (array)', + examples: [ + 'validate_workflow({workflow: myWorkflow}) - Full validation with default settings', + 'validate_workflow({workflow: myWorkflow, options: {profile: "minimal"}}) - Quick validation for editing', + 'validate_workflow({workflow: myWorkflow, options: {validateExpressions: false}}) - Skip expression validation' + ], + useCases: [ + 'Pre-deployment validation to catch all workflow issues', + 'Quick validation during workflow development', + 'Validate workflows with AI Agent nodes and tool connections', + 'Check expression syntax before workflow execution', + 'Ensure workflow structure integrity after modifications' + ], + performance: 'Moderate (100-500ms). Depends on workflow size and validation options. Expression validation adds ~50-100ms.', + bestPractices: [ + 'Always validate workflows before creating or updating in n8n', + 'Use minimal profile during development, strict profile before production', + 'Pay attention to warnings - they often indicate potential runtime issues', + 'Validate after any workflow modifications, especially connection changes', + 'Check statistics to understand workflow complexity', + '**Auto-sanitization runs during create/update**: Operator structures and missing metadata are automatically fixed when workflows are created or updated, but validation helps catch issues before they reach n8n', + 'If validation detects operator issues, they will be auto-fixed during n8n_create_workflow or n8n_update_partial_workflow' + ], + pitfalls: [ + 'Large workflows (100+ nodes) may take longer to validate', + 'Expression validation requires proper node references to exist', + 'Some warnings may be acceptable depending on use case', + 'Validation cannot catch all runtime errors (e.g., API failures)', + 'Profile setting only affects node validation, not connection/expression checks' + ], + relatedTools: ['validate_node', 'n8n_create_workflow', 'n8n_update_partial_workflow', 'n8n_autofix_workflow'] + } +}; +//# sourceMappingURL=validate-workflow.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/validation/validate-workflow.js.map b/dist/mcp/tool-docs/validation/validate-workflow.js.map new file mode 100644 index 0000000..f6095e2 --- /dev/null +++ b/dist/mcp/tool-docs/validation/validate-workflow.js.map @@ -0,0 +1 @@ +{"version":3,"file":"validate-workflow.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/validation/validate-workflow.ts"],"names":[],"mappings":";;;AAEa,QAAA,mBAAmB,GAAsB;IACpD,IAAI,EAAE,mBAAmB;IACzB,QAAQ,EAAE,YAAY;IACtB,UAAU,EAAE;QACV,WAAW,EAAE,kIAAkI;QAC/I,aAAa,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC;QACtC,OAAO,EAAE,mEAAmE;QAC5E,WAAW,EAAE,sBAAsB;QACnC,IAAI,EAAE;YACJ,kEAAkE;YAClE,mEAAmE;YACnE,4EAA4E;YAC5E,+EAA+E;SAChF;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE,oVAAoV;QACjW,UAAU,EAAE;YACV,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,0FAA0F;aACxG;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,2BAA2B;aACzC;YACD,uBAAuB,EAAE;gBACvB,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,wDAAwD;aACtE;YACD,6BAA6B,EAAE;gBAC7B,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,mDAAmD;aACjE;YACD,6BAA6B,EAAE;gBAC7B,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,+DAA+D;aAC7E;YACD,iBAAiB,EAAE;gBACjB,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,yFAAyF;aACvG;SACF;QACD,OAAO,EAAE,6GAA6G;QACtH,QAAQ,EAAE;YACR,mFAAmF;YACnF,yGAAyG;YACzG,+GAA+G;SAChH;QACD,QAAQ,EAAE;YACR,wDAAwD;YACxD,8CAA8C;YAC9C,6DAA6D;YAC7D,mDAAmD;YACnD,yDAAyD;SAC1D;QACD,WAAW,EAAE,8GAA8G;QAC3H,aAAa,EAAE;YACb,8DAA8D;YAC9D,0EAA0E;YAC1E,0EAA0E;YAC1E,0EAA0E;YAC1E,oDAAoD;YACpD,kNAAkN;YAClN,0HAA0H;SAC3H;QACD,QAAQ,EAAE;YACR,0DAA0D;YAC1D,gEAAgE;YAChE,uDAAuD;YACvD,iEAAiE;YACjE,gFAAgF;SACjF;QACD,YAAY,EAAE,CAAC,eAAe,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,sBAAsB,CAAC;KAC9G;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/index.d.ts b/dist/mcp/tool-docs/workflow_management/index.d.ts new file mode 100644 index 0000000..9b143a7 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/index.d.ts @@ -0,0 +1,13 @@ +export { n8nCreateWorkflowDoc } from './n8n-create-workflow'; +export { n8nGetWorkflowDoc } from './n8n-get-workflow'; +export { n8nUpdateFullWorkflowDoc } from './n8n-update-full-workflow'; +export { n8nUpdatePartialWorkflowDoc } from './n8n-update-partial-workflow'; +export { n8nDeleteWorkflowDoc } from './n8n-delete-workflow'; +export { n8nListWorkflowsDoc } from './n8n-list-workflows'; +export { n8nValidateWorkflowDoc } from './n8n-validate-workflow'; +export { n8nAutofixWorkflowDoc } from './n8n-autofix-workflow'; +export { n8nTestWorkflowDoc } from './n8n-test-workflow'; +export { n8nExecutionsDoc } from './n8n-executions'; +export { n8nWorkflowVersionsDoc } from './n8n-workflow-versions'; +export { n8nDeployTemplateDoc } from './n8n-deploy-template'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/index.d.ts.map b/dist/mcp/tool-docs/workflow_management/index.d.ts.map new file mode 100644 index 0000000..845628d --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/index.js b/dist/mcp/tool-docs/workflow_management/index.js new file mode 100644 index 0000000..849e27e --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/index.js @@ -0,0 +1,28 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nDeployTemplateDoc = exports.n8nWorkflowVersionsDoc = exports.n8nExecutionsDoc = exports.n8nTestWorkflowDoc = exports.n8nAutofixWorkflowDoc = exports.n8nValidateWorkflowDoc = exports.n8nListWorkflowsDoc = exports.n8nDeleteWorkflowDoc = exports.n8nUpdatePartialWorkflowDoc = exports.n8nUpdateFullWorkflowDoc = exports.n8nGetWorkflowDoc = exports.n8nCreateWorkflowDoc = void 0; +var n8n_create_workflow_1 = require("./n8n-create-workflow"); +Object.defineProperty(exports, "n8nCreateWorkflowDoc", { enumerable: true, get: function () { return n8n_create_workflow_1.n8nCreateWorkflowDoc; } }); +var n8n_get_workflow_1 = require("./n8n-get-workflow"); +Object.defineProperty(exports, "n8nGetWorkflowDoc", { enumerable: true, get: function () { return n8n_get_workflow_1.n8nGetWorkflowDoc; } }); +var n8n_update_full_workflow_1 = require("./n8n-update-full-workflow"); +Object.defineProperty(exports, "n8nUpdateFullWorkflowDoc", { enumerable: true, get: function () { return n8n_update_full_workflow_1.n8nUpdateFullWorkflowDoc; } }); +var n8n_update_partial_workflow_1 = require("./n8n-update-partial-workflow"); +Object.defineProperty(exports, "n8nUpdatePartialWorkflowDoc", { enumerable: true, get: function () { return n8n_update_partial_workflow_1.n8nUpdatePartialWorkflowDoc; } }); +var n8n_delete_workflow_1 = require("./n8n-delete-workflow"); +Object.defineProperty(exports, "n8nDeleteWorkflowDoc", { enumerable: true, get: function () { return n8n_delete_workflow_1.n8nDeleteWorkflowDoc; } }); +var n8n_list_workflows_1 = require("./n8n-list-workflows"); +Object.defineProperty(exports, "n8nListWorkflowsDoc", { enumerable: true, get: function () { return n8n_list_workflows_1.n8nListWorkflowsDoc; } }); +var n8n_validate_workflow_1 = require("./n8n-validate-workflow"); +Object.defineProperty(exports, "n8nValidateWorkflowDoc", { enumerable: true, get: function () { return n8n_validate_workflow_1.n8nValidateWorkflowDoc; } }); +var n8n_autofix_workflow_1 = require("./n8n-autofix-workflow"); +Object.defineProperty(exports, "n8nAutofixWorkflowDoc", { enumerable: true, get: function () { return n8n_autofix_workflow_1.n8nAutofixWorkflowDoc; } }); +var n8n_test_workflow_1 = require("./n8n-test-workflow"); +Object.defineProperty(exports, "n8nTestWorkflowDoc", { enumerable: true, get: function () { return n8n_test_workflow_1.n8nTestWorkflowDoc; } }); +var n8n_executions_1 = require("./n8n-executions"); +Object.defineProperty(exports, "n8nExecutionsDoc", { enumerable: true, get: function () { return n8n_executions_1.n8nExecutionsDoc; } }); +var n8n_workflow_versions_1 = require("./n8n-workflow-versions"); +Object.defineProperty(exports, "n8nWorkflowVersionsDoc", { enumerable: true, get: function () { return n8n_workflow_versions_1.n8nWorkflowVersionsDoc; } }); +var n8n_deploy_template_1 = require("./n8n-deploy-template"); +Object.defineProperty(exports, "n8nDeployTemplateDoc", { enumerable: true, get: function () { return n8n_deploy_template_1.n8nDeployTemplateDoc; } }); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/index.js.map b/dist/mcp/tool-docs/workflow_management/index.js.map new file mode 100644 index 0000000..1e782f8 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/index.ts"],"names":[],"mappings":";;;AAAA,6DAA6D;AAApD,2HAAA,oBAAoB,OAAA;AAC7B,uDAAuD;AAA9C,qHAAA,iBAAiB,OAAA;AAC1B,uEAAsE;AAA7D,oIAAA,wBAAwB,OAAA;AACjC,6EAA4E;AAAnE,0IAAA,2BAA2B,OAAA;AACpC,6DAA6D;AAApD,2HAAA,oBAAoB,OAAA;AAC7B,2DAA2D;AAAlD,yHAAA,mBAAmB,OAAA;AAC5B,iEAAiE;AAAxD,+HAAA,sBAAsB,OAAA;AAC/B,+DAA+D;AAAtD,6HAAA,qBAAqB,OAAA;AAC9B,yDAAyD;AAAhD,uHAAA,kBAAkB,OAAA;AAC3B,mDAAoD;AAA3C,kHAAA,gBAAgB,OAAA;AACzB,iEAAiE;AAAxD,+HAAA,sBAAsB,OAAA;AAC/B,6DAA6D;AAApD,2HAAA,oBAAoB,OAAA"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.d.ts b/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.d.ts new file mode 100644 index 0000000..3a62aff --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const n8nAutofixWorkflowDoc: ToolDocumentation; +//# sourceMappingURL=n8n-autofix-workflow.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.d.ts.map b/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.d.ts.map new file mode 100644 index 0000000..70ff489 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-autofix-workflow.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-autofix-workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,qBAAqB,EAAE,iBA6JnC,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.js b/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.js new file mode 100644 index 0000000..dd846a6 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.js @@ -0,0 +1,162 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nAutofixWorkflowDoc = void 0; +exports.n8nAutofixWorkflowDoc = { + name: 'n8n_autofix_workflow', + category: 'workflow_management', + essentials: { + description: 'Automatically fix common workflow validation errors - expression formats, typeVersions, error outputs, webhook paths, and smart version upgrades', + keyParameters: ['id', 'applyFixes'], + example: 'n8n_autofix_workflow({id: "wf_abc123", applyFixes: false})', + performance: 'Network-dependent (200-1500ms) - fetches, validates, and optionally updates workflow with smart migrations', + tips: [ + 'Use applyFixes: false to preview changes before applying', + 'Set confidenceThreshold to control fix aggressiveness (high/medium/low)', + 'Supports expression formats, typeVersion issues, error outputs, node corrections, webhook paths, AND version upgrades', + 'High-confidence fixes (≥90%) are safe for auto-application', + 'Version upgrades include smart migration with breaking change detection', + 'Post-update guidance provides AI-friendly step-by-step instructions for manual changes' + ] + }, + full: { + description: `Automatically detects and fixes common workflow validation errors in n8n workflows. This tool: + +- Fetches the workflow from your n8n instance +- Runs comprehensive validation to detect issues +- Generates targeted fixes for common problems +- Optionally applies the fixes back to the workflow + +The auto-fixer can resolve: +1. **Expression Format Issues**: Missing '=' prefix in n8n expressions (e.g., {{ $json.field }} → ={{ $json.field }}) +2. **TypeVersion Corrections**: Downgrades nodes with unsupported typeVersions to maximum supported +3. **Error Output Configuration**: Removes conflicting onError settings when error connections are missing +4. **Node Type Corrections**: Intelligently fixes unknown node types using similarity matching: + - Handles deprecated package prefixes (n8n-nodes-base. → nodes-base.) + - Corrects capitalization mistakes (HttpRequest → httpRequest) + - Suggests correct packages (nodes-base.openai → nodes-langchain.openAi) + - Uses multi-factor scoring: name similarity, category match, package match, pattern match + - Only auto-fixes suggestions with ≥90% confidence + - Leverages NodeSimilarityService with 5-minute caching for performance +5. **Webhook Path Generation**: Automatically generates UUIDs for webhook nodes missing path configuration: + - Generates a unique UUID for webhook path + - Sets both 'path' parameter and 'webhookId' field to the same UUID + - Ensures webhook nodes become functional with valid endpoints + - High confidence fix as UUID generation is deterministic +6. **Smart Version Upgrades** (NEW): Proactively upgrades nodes to their latest versions: + - Detects outdated node versions and recommends upgrades + - Applies smart migrations with auto-migratable property changes + - Handles breaking changes intelligently (Execute Workflow v1.0→v1.1, Webhook v2.0→v2.1, etc.) + - Generates UUIDs for required fields (webhookId), sets sensible defaults + - HIGH confidence for non-breaking upgrades, MEDIUM for breaking changes with auto-migration + - Example: Execute Workflow v1.0→v1.1 adds inputFieldMapping automatically +7. **Version Migration Guidance** (NEW): Documents complex migrations requiring manual intervention: + - Identifies breaking changes that cannot be auto-migrated + - Provides AI-friendly post-update guidance with step-by-step instructions + - Lists required actions by priority (CRITICAL, HIGH, MEDIUM, LOW) + - Documents behavior changes and their impact + - Estimates time required for manual migration steps + - MEDIUM/LOW confidence - requires review before applying + +The tool uses a confidence-based system to ensure safe fixes: +- **High (≥90%)**: Safe to auto-apply (exact matches, known patterns) +- **Medium (70-89%)**: Generally safe but review recommended +- **Low (<70%)**: Manual review strongly recommended + +Requires N8N_API_URL and N8N_API_KEY environment variables to be configured.`, + parameters: { + id: { + type: 'string', + required: true, + description: 'The workflow ID to fix in your n8n instance' + }, + applyFixes: { + type: 'boolean', + required: false, + description: 'Whether to apply fixes to the workflow (default: false - preview mode). When false, returns proposed fixes without modifying the workflow.' + }, + fixTypes: { + type: 'array', + required: false, + description: 'Types of fixes to apply. Options: ["expression-format", "typeversion-correction", "error-output-config", "node-type-correction", "webhook-missing-path", "typeversion-upgrade", "version-migration"]. Default: all types. NEW: "typeversion-upgrade" for smart version upgrades, "version-migration" for complex migration guidance.' + }, + confidenceThreshold: { + type: 'string', + required: false, + description: 'Minimum confidence level for fixes: "high" (≥90%), "medium" (≥70%), "low" (any). Default: "medium".' + }, + maxFixes: { + type: 'number', + required: false, + description: 'Maximum number of fixes to apply (default: 50). Useful for limiting scope of changes.' + } + }, + returns: `AutoFixResult object containing: +- operations: Array of diff operations that will be/were applied +- fixes: Detailed list of individual fixes with before/after values +- summary: Human-readable summary of fixes +- stats: Statistics by fix type and confidence level +- applied: Boolean indicating if fixes were applied (when applyFixes: true) +- postUpdateGuidance: (NEW) Array of AI-friendly migration guidance for version upgrades, including: + * Required actions by priority (CRITICAL, HIGH, MEDIUM, LOW) + * Deprecated properties to remove + * Behavior changes and their impact + * Step-by-step migration instructions + * Estimated time for manual changes`, + examples: [ + 'n8n_autofix_workflow({id: "wf_abc123"}) - Preview all possible fixes including version upgrades', + 'n8n_autofix_workflow({id: "wf_abc123", applyFixes: true}) - Apply all medium+ confidence fixes', + 'n8n_autofix_workflow({id: "wf_abc123", applyFixes: true, confidenceThreshold: "high"}) - Only apply high-confidence fixes', + 'n8n_autofix_workflow({id: "wf_abc123", fixTypes: ["expression-format"]}) - Only fix expression format issues', + 'n8n_autofix_workflow({id: "wf_abc123", fixTypes: ["webhook-missing-path"]}) - Only fix webhook path issues', + 'n8n_autofix_workflow({id: "wf_abc123", fixTypes: ["typeversion-upgrade"]}) - NEW: Only upgrade node versions with smart migrations', + 'n8n_autofix_workflow({id: "wf_abc123", fixTypes: ["typeversion-upgrade", "version-migration"]}) - NEW: Upgrade versions and provide migration guidance', + 'n8n_autofix_workflow({id: "wf_abc123", applyFixes: true, maxFixes: 10}) - Apply up to 10 fixes' + ], + useCases: [ + 'Fixing workflows imported from older n8n versions', + 'Correcting expression syntax after manual edits', + 'Resolving typeVersion conflicts after n8n upgrades', + 'Cleaning up workflows before production deployment', + 'Batch fixing common issues across multiple workflows', + 'Migrating workflows between n8n instances with different versions', + 'Repairing webhook nodes that lost their path configuration', + 'Upgrading Execute Workflow nodes from v1.0 to v1.1+ with automatic inputFieldMapping', + 'Modernizing webhook nodes to v2.1+ with stable webhookId fields', + 'Proactively keeping workflows up-to-date with latest node versions', + 'Getting detailed migration guidance for complex breaking changes' + ], + performance: 'Depends on workflow size and number of issues. Preview mode: 200-500ms. Apply mode: 500-1500ms for medium workflows with version upgrades. Node similarity matching and version metadata are cached for 5 minutes for improved performance on repeated validations.', + bestPractices: [ + 'Always preview fixes first (applyFixes: false) before applying', + 'Start with high confidence threshold for production workflows', + 'Review the fix summary to understand what changed', + 'Test workflows after auto-fixing to ensure expected behavior', + 'Use fixTypes parameter to target specific issue categories', + 'Keep maxFixes reasonable to avoid too many changes at once', + 'NEW: Review postUpdateGuidance for version upgrades - contains step-by-step migration instructions', + 'NEW: Test workflows after version upgrades - behavior may change even with successful auto-migration', + 'NEW: Apply version upgrades incrementally - start with high-confidence, non-breaking upgrades' + ], + pitfalls: [ + 'Some fixes may change workflow behavior - always test after fixing', + 'Low confidence fixes might not be the intended solution', + 'Expression format fixes assume standard n8n syntax requirements', + 'Node type corrections only work for known node types in the database', + 'Cannot fix structural issues like missing nodes or invalid connections', + 'TypeVersion downgrades might remove node features added in newer versions', + 'Generated webhook paths are new UUIDs - existing webhook URLs will change', + 'NEW: Version upgrades may introduce breaking changes - review postUpdateGuidance carefully', + 'NEW: Auto-migrated properties use sensible defaults which may not match your use case', + 'NEW: Execute Workflow v1.1+ requires explicit inputFieldMapping - automatic mapping uses empty array', + 'NEW: Some breaking changes cannot be auto-migrated and require manual intervention', + 'NEW: Version history is based on registry - unknown nodes cannot be upgraded' + ], + relatedTools: [ + 'n8n_validate_workflow', + 'validate_workflow', + 'validate_node', + 'n8n_update_partial_workflow' + ] + } +}; +//# sourceMappingURL=n8n-autofix-workflow.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.js.map b/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.js.map new file mode 100644 index 0000000..0cdc11d --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-autofix-workflow.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-autofix-workflow.ts"],"names":[],"mappings":";;;AAEa,QAAA,qBAAqB,GAAsB;IACtD,IAAI,EAAE,sBAAsB;IAC5B,QAAQ,EAAE,qBAAqB;IAC/B,UAAU,EAAE;QACV,WAAW,EAAE,kJAAkJ;QAC/J,aAAa,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;QACnC,OAAO,EAAE,4DAA4D;QACrE,WAAW,EAAE,4GAA4G;QACzH,IAAI,EAAE;YACJ,0DAA0D;YAC1D,yEAAyE;YACzE,uHAAuH;YACvH,4DAA4D;YAC5D,yEAAyE;YACzE,wFAAwF;SACzF;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6EA2C4D;QACzE,UAAU,EAAE;YACV,EAAE,EAAE;gBACF,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,6CAA6C;aAC3D;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,4IAA4I;aAC1J;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,sUAAsU;aACpV;YACD,mBAAmB,EAAE;gBACnB,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,qGAAqG;aACnH;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,uFAAuF;aACrG;SACF;QACD,OAAO,EAAE;;;;;;;;;;;sCAWyB;QAClC,QAAQ,EAAE;YACR,iGAAiG;YACjG,gGAAgG;YAChG,2HAA2H;YAC3H,8GAA8G;YAC9G,4GAA4G;YAC5G,oIAAoI;YACpI,wJAAwJ;YACxJ,gGAAgG;SACjG;QACD,QAAQ,EAAE;YACR,mDAAmD;YACnD,iDAAiD;YACjD,oDAAoD;YACpD,oDAAoD;YACpD,sDAAsD;YACtD,mEAAmE;YACnE,4DAA4D;YAC5D,sFAAsF;YACtF,iEAAiE;YACjE,oEAAoE;YACpE,kEAAkE;SACnE;QACD,WAAW,EAAE,qQAAqQ;QAClR,aAAa,EAAE;YACb,gEAAgE;YAChE,+DAA+D;YAC/D,mDAAmD;YACnD,8DAA8D;YAC9D,4DAA4D;YAC5D,4DAA4D;YAC5D,oGAAoG;YACpG,sGAAsG;YACtG,+FAA+F;SAChG;QACD,QAAQ,EAAE;YACR,oEAAoE;YACpE,yDAAyD;YACzD,iEAAiE;YACjE,sEAAsE;YACtE,wEAAwE;YACxE,2EAA2E;YAC3E,2EAA2E;YAC3E,4FAA4F;YAC5F,uFAAuF;YACvF,sGAAsG;YACtG,oFAAoF;YACpF,8EAA8E;SAC/E;QACD,YAAY,EAAE;YACZ,uBAAuB;YACvB,mBAAmB;YACnB,eAAe;YACf,6BAA6B;SAC9B;KACF;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.d.ts b/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.d.ts new file mode 100644 index 0000000..59f41fc --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const n8nCreateWorkflowDoc: ToolDocumentation; +//# sourceMappingURL=n8n-create-workflow.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.d.ts.map b/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.d.ts.map new file mode 100644 index 0000000..1c65dc8 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-create-workflow.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-create-workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,oBAAoB,EAAE,iBAiGlC,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.js b/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.js new file mode 100644 index 0000000..41ba5a3 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.js @@ -0,0 +1,102 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nCreateWorkflowDoc = void 0; +exports.n8nCreateWorkflowDoc = { + name: 'n8n_create_workflow', + category: 'workflow_management', + essentials: { + description: 'Create workflow. Requires: name, nodes[], connections{}. Created inactive. Returns workflow with ID.', + keyParameters: ['name', 'nodes', 'connections'], + example: 'n8n_create_workflow({name: "My Flow", nodes: [...], connections: {...}})', + performance: 'Network-dependent', + tips: [ + 'Workflow created inactive', + 'Returns ID for future updates', + 'Validate first with validate_workflow', + 'Auto-sanitization fixes operator structures and missing metadata during creation' + ] + }, + full: { + description: 'Creates a new workflow in n8n with specified nodes and connections. Workflow is created in inactive state. Each node requires: id, name, type, typeVersion, position, and parameters.', + parameters: { + name: { type: 'string', required: true, description: 'Workflow name' }, + nodes: { type: 'array', required: true, description: 'Array of nodes with id, name, type, typeVersion, position, parameters' }, + connections: { type: 'object', required: true, description: 'Node connections. Keys are source node IDs' }, + settings: { type: 'object', description: 'Optional workflow settings (timezone, error handling, etc.)' } + }, + returns: 'Created workflow object with id, name, nodes, connections, active status', + examples: [ + `// Basic webhook to Slack workflow +n8n_create_workflow({ + name: "Webhook to Slack", + nodes: [ + { + id: "webhook_1", + name: "Webhook", + type: "n8n-nodes-base.webhook", + typeVersion: 1, + position: [250, 300], + parameters: { + httpMethod: "POST", + path: "slack-notify" + } + }, + { + id: "slack_1", + name: "Slack", + type: "n8n-nodes-base.slack", + typeVersion: 1, + position: [450, 300], + parameters: { + resource: "message", + operation: "post", + channel: "#general", + text: "={{$json.message}}" + } + } + ], + connections: { + "webhook_1": { + "main": [[{node: "slack_1", type: "main", index: 0}]] + } + } +})`, + `// Workflow with settings and error handling +n8n_create_workflow({ + name: "Data Processing", + nodes: [...], + connections: {...}, + settings: { + timezone: "America/New_York", + errorWorkflow: "error_handler_workflow_id", + saveDataSuccessExecution: "all", + saveDataErrorExecution: "all" + } +})` + ], + useCases: [ + 'Deploy validated workflows', + 'Automate workflow creation', + 'Clone workflow structures', + 'Template deployment' + ], + performance: 'Network-dependent - Typically 100-500ms depending on workflow size', + bestPractices: [ + 'Validate with validate_workflow first', + 'Use unique node IDs', + 'Position nodes for readability', + 'Test with n8n_test_workflow' + ], + pitfalls: [ + '**REQUIRES N8N_API_URL and N8N_API_KEY environment variables** - tool unavailable without n8n API access', + 'Workflows created in INACTIVE state - must activate separately', + 'Node IDs must be unique within workflow', + 'Credentials must be configured separately in n8n', + 'Node type names must include package prefix (e.g., "n8n-nodes-base.slack")', + '**Auto-sanitization runs on creation**: All nodes sanitized before workflow created (operator structures fixed, missing metadata added)', + '**Auto-sanitization cannot prevent all failures**: Broken connections or invalid node configurations may still cause creation to fail' + ], + relatedTools: ['validate_workflow', 'n8n_update_partial_workflow', 'n8n_test_workflow'] + } +}; +//# sourceMappingURL=n8n-create-workflow.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.js.map b/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.js.map new file mode 100644 index 0000000..6aef0d6 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-create-workflow.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-create-workflow.ts"],"names":[],"mappings":";;;AAEa,QAAA,oBAAoB,GAAsB;IACrD,IAAI,EAAE,qBAAqB;IAC3B,QAAQ,EAAE,qBAAqB;IAC/B,UAAU,EAAE;QACV,WAAW,EAAE,sGAAsG;QACnH,aAAa,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC;QAC/C,OAAO,EAAE,0EAA0E;QACnF,WAAW,EAAE,mBAAmB;QAChC,IAAI,EAAE;YACJ,2BAA2B;YAC3B,+BAA+B;YAC/B,uCAAuC;YACvC,kFAAkF;SACnF;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE,uLAAuL;QACpM,UAAU,EAAE;YACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,eAAe,EAAE;YACtE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,uEAAuE,EAAE;YAC9H,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,4CAA4C,EAAE;YAC1G,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6DAA6D,EAAE;SACzG;QACD,OAAO,EAAE,0EAA0E;QACnF,QAAQ,EAAE;YACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCH;YACG;;;;;;;;;;;GAWH;SACE;QACD,QAAQ,EAAE;YACR,4BAA4B;YAC5B,4BAA4B;YAC5B,2BAA2B;YAC3B,qBAAqB;SACtB;QACD,WAAW,EAAE,oEAAoE;QACjF,aAAa,EAAE;YACb,uCAAuC;YACvC,qBAAqB;YACrB,gCAAgC;YAChC,6BAA6B;SAC9B;QACD,QAAQ,EAAE;YACR,0GAA0G;YAC1G,gEAAgE;YAChE,yCAAyC;YACzC,kDAAkD;YAClD,4EAA4E;YAC5E,yIAAyI;YACzI,uIAAuI;SACxI;QACD,YAAY,EAAE,CAAC,mBAAmB,EAAE,6BAA6B,EAAE,mBAAmB,CAAC;KACxF;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.d.ts b/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.d.ts new file mode 100644 index 0000000..6dd8e6c --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const n8nDeleteWorkflowDoc: ToolDocumentation; +//# sourceMappingURL=n8n-delete-workflow.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.d.ts.map b/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.d.ts.map new file mode 100644 index 0000000..0bfc3de --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-delete-workflow.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-delete-workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,oBAAoB,EAAE,iBA+ClC,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.js b/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.js new file mode 100644 index 0000000..1889d02 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.js @@ -0,0 +1,52 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nDeleteWorkflowDoc = void 0; +exports.n8nDeleteWorkflowDoc = { + name: 'n8n_delete_workflow', + category: 'workflow_management', + essentials: { + description: 'Permanently delete a workflow. This action cannot be undone.', + keyParameters: ['id'], + example: 'n8n_delete_workflow({id: "workflow_123"})', + performance: 'Fast (50-150ms)', + tips: [ + 'Action is irreversible', + 'Deletes all execution history', + 'Check workflow first with n8n_get_workflow({mode: "minimal"})' + ] + }, + full: { + description: 'Permanently deletes a workflow from n8n including all associated data, execution history, and settings. This is an irreversible operation that should be used with caution. The workflow must exist and the user must have appropriate permissions.', + parameters: { + id: { type: 'string', required: true, description: 'Workflow ID to delete permanently' } + }, + returns: 'Success confirmation or error if workflow not found/cannot be deleted', + examples: [ + 'n8n_delete_workflow({id: "abc123"}) - Delete specific workflow', + 'if (confirm) { n8n_delete_workflow({id: wf.id}); } // With confirmation' + ], + useCases: [ + 'Remove obsolete workflows', + 'Clean up test workflows', + 'Delete failed experiments', + 'Manage workflow limits', + 'Remove duplicates' + ], + performance: 'Fast operation - typically 50-150ms. May take longer if workflow has extensive execution history.', + bestPractices: [ + 'Always confirm before deletion', + 'Check workflow with n8n_get_workflow({mode: "minimal"}) first', + 'Consider deactivating instead of deleting', + 'Export workflow before deletion for backup' + ], + pitfalls: [ + 'Requires N8N_API_URL and N8N_API_KEY configured', + 'Cannot be undone - permanent deletion', + 'Deletes all execution history', + 'Active workflows can be deleted', + 'No built-in confirmation' + ], + relatedTools: ['n8n_get_workflow', 'n8n_list_workflows', 'n8n_update_partial_workflow', 'n8n_executions'] + } +}; +//# sourceMappingURL=n8n-delete-workflow.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.js.map b/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.js.map new file mode 100644 index 0000000..d2e5e1b --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-delete-workflow.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-delete-workflow.ts"],"names":[],"mappings":";;;AAEa,QAAA,oBAAoB,GAAsB;IACrD,IAAI,EAAE,qBAAqB;IAC3B,QAAQ,EAAE,qBAAqB;IAC/B,UAAU,EAAE;QACV,WAAW,EAAE,8DAA8D;QAC3E,aAAa,EAAE,CAAC,IAAI,CAAC;QACrB,OAAO,EAAE,2CAA2C;QACpD,WAAW,EAAE,iBAAiB;QAC9B,IAAI,EAAE;YACJ,wBAAwB;YACxB,+BAA+B;YAC/B,+DAA+D;SAChE;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE,qPAAqP;QAClQ,UAAU,EAAE;YACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,mCAAmC,EAAE;SACzF;QACD,OAAO,EAAE,uEAAuE;QAChF,QAAQ,EAAE;YACR,gEAAgE;YAChE,yEAAyE;SAC1E;QACD,QAAQ,EAAE;YACR,2BAA2B;YAC3B,yBAAyB;YACzB,2BAA2B;YAC3B,wBAAwB;YACxB,mBAAmB;SACpB;QACD,WAAW,EAAE,mGAAmG;QAChH,aAAa,EAAE;YACb,gCAAgC;YAChC,+DAA+D;YAC/D,2CAA2C;YAC3C,4CAA4C;SAC7C;QACD,QAAQ,EAAE;YACR,iDAAiD;YACjD,uCAAuC;YACvC,+BAA+B;YAC/B,iCAAiC;YACjC,0BAA0B;SAC3B;QACD,YAAY,EAAE,CAAC,kBAAkB,EAAE,oBAAoB,EAAE,6BAA6B,EAAE,gBAAgB,CAAC;KAC1G;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-deploy-template.d.ts b/dist/mcp/tool-docs/workflow_management/n8n-deploy-template.d.ts new file mode 100644 index 0000000..89a5fcc --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-deploy-template.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const n8nDeployTemplateDoc: ToolDocumentation; +//# sourceMappingURL=n8n-deploy-template.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-deploy-template.d.ts.map b/dist/mcp/tool-docs/workflow_management/n8n-deploy-template.d.ts.map new file mode 100644 index 0000000..a9ed3da --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-deploy-template.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-deploy-template.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-deploy-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,oBAAoB,EAAE,iBAoElC,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-deploy-template.js b/dist/mcp/tool-docs/workflow_management/n8n-deploy-template.js new file mode 100644 index 0000000..adb9f1e --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-deploy-template.js @@ -0,0 +1,73 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nDeployTemplateDoc = void 0; +exports.n8nDeployTemplateDoc = { + name: 'n8n_deploy_template', + category: 'workflow_management', + essentials: { + description: 'Deploy a workflow template from n8n.io directly to your n8n instance. Deploys first, then auto-fixes common issues (expression format, typeVersions).', + keyParameters: ['templateId', 'name', 'autoUpgradeVersions', 'autoFix', 'stripCredentials'], + example: 'n8n_deploy_template({templateId: 2776, name: "My Deployed Template"})', + performance: 'Network-dependent', + tips: [ + 'Auto-fixes expression format issues after deployment', + 'Workflow created inactive - configure credentials in n8n UI first', + 'Returns list of required credentials and fixes applied', + 'Use search_templates to find template IDs' + ] + }, + full: { + description: 'Deploys a workflow template from n8n.io directly to your n8n instance. This tool deploys first, then automatically fixes common issues like missing expression prefixes (=) and outdated typeVersions. Templates are stored locally and fetched from the database. The workflow is always created in an inactive state, allowing you to configure credentials before activation.', + parameters: { + templateId: { type: 'number', required: true, description: 'Template ID from n8n.io (find via search_templates)' }, + name: { type: 'string', description: 'Custom workflow name (default: template name)' }, + autoUpgradeVersions: { type: 'boolean', description: 'Upgrade node typeVersions to latest supported (default: true)' }, + autoFix: { type: 'boolean', description: 'Auto-apply fixes after deployment for expression format issues, missing = prefix, etc. (default: true)' }, + stripCredentials: { type: 'boolean', description: 'Remove credential references - user configures in n8n UI (default: true)' } + }, + returns: 'Object with workflowId, name, nodeCount, triggerType, requiredCredentials array, url, templateId, templateUrl, autoFixStatus (success/failed/skipped), and fixesApplied array', + examples: [ + `// Deploy template with default settings (auto-fix enabled) +n8n_deploy_template({templateId: 2776})`, + `// Deploy with custom name +n8n_deploy_template({ + templateId: 2776, + name: "My Google Drive to Airtable Sync" +})`, + `// Deploy without auto-fix (not recommended) +n8n_deploy_template({ + templateId: 2776, + autoFix: false +})`, + `// Keep original node versions (useful for compatibility) +n8n_deploy_template({ + templateId: 2776, + autoUpgradeVersions: false +})` + ], + useCases: [ + 'Quickly deploy pre-built workflow templates', + 'Set up common automation patterns', + 'Bootstrap new projects with proven workflows', + 'Deploy templates found via search_templates' + ], + performance: 'Network-dependent - Typically 300-800ms (template fetch + workflow creation + autofix)', + bestPractices: [ + 'Use search_templates to find templates by use case', + 'Review required credentials in the response', + 'Check autoFixStatus in response - "success", "failed", or "skipped"', + 'Check fixesApplied in response to see what was automatically corrected', + 'Configure credentials in n8n UI before activating', + 'Test workflow before connecting to production systems' + ], + pitfalls: [ + '**REQUIRES N8N_API_URL and N8N_API_KEY environment variables** - tool unavailable without n8n API access', + 'Workflows created in INACTIVE state - must configure credentials and activate in n8n', + 'Templates may reference services you do not have (Slack, Google, etc.)', + 'Template database must be populated - run npm run fetch:templates if templates not found', + 'Some issues may not be auto-fixable (e.g., missing required fields that need user input)' + ], + relatedTools: ['search_templates', 'get_template', 'n8n_create_workflow', 'n8n_autofix_workflow'] + } +}; +//# sourceMappingURL=n8n-deploy-template.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-deploy-template.js.map b/dist/mcp/tool-docs/workflow_management/n8n-deploy-template.js.map new file mode 100644 index 0000000..eb49b60 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-deploy-template.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-deploy-template.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-deploy-template.ts"],"names":[],"mappings":";;;AAEa,QAAA,oBAAoB,GAAsB;IACrD,IAAI,EAAE,qBAAqB;IAC3B,QAAQ,EAAE,qBAAqB;IAC/B,UAAU,EAAE;QACV,WAAW,EAAE,uJAAuJ;QACpK,aAAa,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,qBAAqB,EAAE,SAAS,EAAE,kBAAkB,CAAC;QAC3F,OAAO,EAAE,uEAAuE;QAChF,WAAW,EAAE,mBAAmB;QAChC,IAAI,EAAE;YACJ,sDAAsD;YACtD,mEAAmE;YACnE,wDAAwD;YACxD,2CAA2C;SAC5C;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE,kXAAkX;QAC/X,UAAU,EAAE;YACV,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,qDAAqD,EAAE;YAClH,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+CAA+C,EAAE;YACtF,mBAAmB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,+DAA+D,EAAE;YACtH,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,wGAAwG,EAAE;YACnJ,gBAAgB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,0EAA0E,EAAE;SAC/H;QACD,OAAO,EAAE,+KAA+K;QACxL,QAAQ,EAAE;YACR;wCACkC;YAClC;;;;GAIH;YACG;;;;GAIH;YACG;;;;GAIH;SACE;QACD,QAAQ,EAAE;YACR,6CAA6C;YAC7C,mCAAmC;YACnC,8CAA8C;YAC9C,6CAA6C;SAC9C;QACD,WAAW,EAAE,wFAAwF;QACrG,aAAa,EAAE;YACb,oDAAoD;YACpD,6CAA6C;YAC7C,qEAAqE;YACrE,wEAAwE;YACxE,mDAAmD;YACnD,uDAAuD;SACxD;QACD,QAAQ,EAAE;YACR,0GAA0G;YAC1G,sFAAsF;YACtF,wEAAwE;YACxE,0FAA0F;YAC1F,0FAA0F;SAC3F;QACD,YAAY,EAAE,CAAC,kBAAkB,EAAE,cAAc,EAAE,qBAAqB,EAAE,sBAAsB,CAAC;KAClG;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-executions.d.ts b/dist/mcp/tool-docs/workflow_management/n8n-executions.d.ts new file mode 100644 index 0000000..d8f2f49 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-executions.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const n8nExecutionsDoc: ToolDocumentation; +//# sourceMappingURL=n8n-executions.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-executions.d.ts.map b/dist/mcp/tool-docs/workflow_management/n8n-executions.d.ts.map new file mode 100644 index 0000000..9578751 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-executions.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-executions.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-executions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,gBAAgB,EAAE,iBA+E9B,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-executions.js b/dist/mcp/tool-docs/workflow_management/n8n-executions.js new file mode 100644 index 0000000..8226158 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-executions.js @@ -0,0 +1,84 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nExecutionsDoc = void 0; +exports.n8nExecutionsDoc = { + name: 'n8n_executions', + category: 'workflow_management', + essentials: { + description: 'Manage workflow executions: get details, list, or delete. Unified tool for all execution operations.', + keyParameters: ['action', 'id', 'workflowId', 'status'], + example: 'n8n_executions({action: "list", workflowId: "abc123", status: "error"})', + performance: 'Fast (50-200ms)', + tips: [ + 'action="get": Get execution details by ID', + 'action="list": List executions with filters', + 'action="delete": Delete execution record', + 'Use mode parameter for action=get to control detail level' + ] + }, + full: { + description: `**Actions:** +- get: Retrieve execution details by ID with configurable detail level +- list: List executions with filtering and pagination +- delete: Remove an execution record from history + +**Detail Modes for action="get":** +- preview: Structure only, no data +- summary: 2 items per node (default) +- filtered: Custom items limit, optionally filter by node names +- full: All execution data (can be very large)`, + parameters: { + action: { type: 'string', required: true, description: 'Operation: "get", "list", or "delete"' }, + id: { type: 'string', required: false, description: 'Execution ID (required for action=get or action=delete)' }, + mode: { type: 'string', required: false, description: 'For action=get: "preview", "summary" (default), "filtered", "full"' }, + nodeNames: { type: 'array', required: false, description: 'For action=get with mode=filtered: Filter to specific nodes by name' }, + itemsLimit: { type: 'number', required: false, description: 'For action=get with mode=filtered: Items per node (0=structure, 2=default, -1=unlimited)' }, + includeInputData: { type: 'boolean', required: false, description: 'For action=get: Include input data in addition to output (default: false)' }, + workflowId: { type: 'string', required: false, description: 'For action=list: Filter by workflow ID' }, + status: { type: 'string', required: false, description: 'For action=list: Filter by status ("success", "error", "waiting")' }, + limit: { type: 'number', required: false, description: 'For action=list: Number of results (1-100, default: 100)' }, + cursor: { type: 'string', required: false, description: 'For action=list: Pagination cursor from previous response' }, + projectId: { type: 'string', required: false, description: 'For action=list: Filter by project ID (enterprise)' }, + includeData: { type: 'boolean', required: false, description: 'For action=list: Include execution data (default: false)' } + }, + returns: `Depends on action: +- get: Execution object with data based on mode +- list: { data: [...executions], nextCursor?: string } +- delete: { success: boolean, message: string }`, + examples: [ + '// List recent executions for a workflow\nn8n_executions({action: "list", workflowId: "abc123", limit: 10})', + '// List failed executions\nn8n_executions({action: "list", status: "error"})', + '// Get execution summary\nn8n_executions({action: "get", id: "exec_456"})', + '// Get full execution data\nn8n_executions({action: "get", id: "exec_456", mode: "full"})', + '// Get specific nodes from execution\nn8n_executions({action: "get", id: "exec_456", mode: "filtered", nodeNames: ["HTTP Request", "Slack"]})', + '// Delete an execution\nn8n_executions({action: "delete", id: "exec_456"})' + ], + useCases: [ + 'Debug workflow failures (get with mode=full)', + 'Monitor workflow health (list with status filter)', + 'Audit execution history', + 'Clean up old execution records', + 'Analyze specific node outputs' + ], + performance: `Response times: +- list: 50-150ms depending on filters +- get (preview/summary): 30-100ms +- get (full): 100-500ms+ depending on data size +- delete: 30-80ms`, + bestPractices: [ + 'Use mode="summary" (default) for debugging - shows enough data', + 'Use mode="filtered" with nodeNames for large workflows', + 'Filter by workflowId when listing to reduce results', + 'Use cursor for pagination through large result sets', + 'Delete old executions to save storage' + ], + pitfalls: [ + 'Requires N8N_API_URL and N8N_API_KEY configured', + 'mode="full" can return very large responses for complex workflows', + 'Execution must exist or returns 404', + 'Delete is permanent - cannot undo' + ], + relatedTools: ['n8n_get_workflow', 'n8n_test_workflow', 'n8n_validate_workflow'] + } +}; +//# sourceMappingURL=n8n-executions.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-executions.js.map b/dist/mcp/tool-docs/workflow_management/n8n-executions.js.map new file mode 100644 index 0000000..06ed7fc --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-executions.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-executions.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-executions.ts"],"names":[],"mappings":";;;AAEa,QAAA,gBAAgB,GAAsB;IACjD,IAAI,EAAE,gBAAgB;IACtB,QAAQ,EAAE,qBAAqB;IAC/B,UAAU,EAAE;QACV,WAAW,EAAE,sGAAsG;QACnH,aAAa,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,CAAC;QACvD,OAAO,EAAE,yEAAyE;QAClF,WAAW,EAAE,iBAAiB;QAC9B,IAAI,EAAE;YACJ,2CAA2C;YAC3C,6CAA6C;YAC7C,0CAA0C;YAC1C,2DAA2D;SAC5D;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE;;;;;;;;;+CAS8B;QAC3C,UAAU,EAAE;YACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,uCAAuC,EAAE;YAChG,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,yDAAyD,EAAE;YAC/G,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,oEAAoE,EAAE;YAC5H,SAAS,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,qEAAqE,EAAE;YACjI,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,0FAA0F,EAAE;YACxJ,gBAAgB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,2EAA2E,EAAE;YAChJ,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,wCAAwC,EAAE;YACtG,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,mEAAmE,EAAE;YAC7H,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,0DAA0D,EAAE;YACnH,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,2DAA2D,EAAE;YACrH,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,oDAAoD,EAAE;YACjH,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,0DAA0D,EAAE;SAC3H;QACD,OAAO,EAAE;;;gDAGmC;QAC5C,QAAQ,EAAE;YACR,6GAA6G;YAC7G,8EAA8E;YAC9E,2EAA2E;YAC3E,2FAA2F;YAC3F,+IAA+I;YAC/I,4EAA4E;SAC7E;QACD,QAAQ,EAAE;YACR,8CAA8C;YAC9C,mDAAmD;YACnD,yBAAyB;YACzB,gCAAgC;YAChC,+BAA+B;SAChC;QACD,WAAW,EAAE;;;;kBAIC;QACd,aAAa,EAAE;YACb,gEAAgE;YAChE,wDAAwD;YACxD,qDAAqD;YACrD,qDAAqD;YACrD,uCAAuC;SACxC;QACD,QAAQ,EAAE;YACR,iDAAiD;YACjD,mEAAmE;YACnE,qCAAqC;YACrC,mCAAmC;SACpC;QACD,YAAY,EAAE,CAAC,kBAAkB,EAAE,mBAAmB,EAAE,uBAAuB,CAAC;KACjF;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.d.ts b/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.d.ts new file mode 100644 index 0000000..0ddb8a8 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const n8nGetWorkflowDoc: ToolDocumentation; +//# sourceMappingURL=n8n-get-workflow.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.d.ts.map b/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.d.ts.map new file mode 100644 index 0000000..db34887 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-get-workflow.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-get-workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,iBAAiB,EAAE,iBA+D/B,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.js b/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.js new file mode 100644 index 0000000..da2af78 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.js @@ -0,0 +1,68 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nGetWorkflowDoc = void 0; +exports.n8nGetWorkflowDoc = { + name: 'n8n_get_workflow', + category: 'workflow_management', + essentials: { + description: 'Get workflow by ID with different detail levels. Use mode to control response size and content.', + keyParameters: ['id', 'mode'], + example: 'n8n_get_workflow({id: "workflow_123", mode: "structure"})', + performance: 'Fast (50-200ms)', + tips: [ + 'mode="full" (default): Complete workflow with all data', + 'mode="details": Full workflow + execution stats', + 'mode="structure": Just nodes and connections (topology)', + 'mode="minimal": Only id, name, active status, tags' + ] + }, + full: { + description: `**Modes:** +- full (default): Complete workflow including all nodes with parameters, connections, and settings +- details: Full workflow plus execution statistics (success/error counts, last execution time) +- structure: Nodes and connections only - useful for topology analysis +- minimal: Just id, name, active status, and tags - fastest response`, + parameters: { + id: { type: 'string', required: true, description: 'Workflow ID to retrieve' }, + mode: { type: 'string', required: false, description: 'Detail level: "full" (default), "details", "structure", "minimal"' } + }, + returns: `Depends on mode: +- full: Complete workflow object (id, name, active, nodes[], connections{}, settings, createdAt, updatedAt) +- details: Full workflow + executionStats (successCount, errorCount, lastExecution, etc.) +- structure: { nodes: [...], connections: {...} } - topology only +- minimal: { id, name, active, tags, createdAt, updatedAt }`, + examples: [ + '// Get complete workflow (default)\nn8n_get_workflow({id: "abc123"})', + '// Get workflow with execution stats\nn8n_get_workflow({id: "abc123", mode: "details"})', + '// Get just the topology\nn8n_get_workflow({id: "abc123", mode: "structure"})', + '// Quick metadata check\nn8n_get_workflow({id: "abc123", mode: "minimal"})' + ], + useCases: [ + 'View and edit workflow (mode=full)', + 'Analyze workflow performance (mode=details)', + 'Clone or compare workflow structure (mode=structure)', + 'List workflows with status (mode=minimal)', + 'Debug workflow issues' + ], + performance: `Response times vary by mode: +- minimal: ~20-50ms (smallest response) +- structure: ~30-80ms (nodes + connections only) +- full: ~50-200ms (complete workflow) +- details: ~100-300ms (includes execution queries)`, + bestPractices: [ + 'Use mode="minimal" when listing or checking status', + 'Use mode="structure" for workflow analysis or cloning', + 'Use mode="full" (default) when editing', + 'Use mode="details" for debugging execution issues', + 'Validate workflow after retrieval if planning modifications' + ], + pitfalls: [ + 'Requires N8N_API_URL and N8N_API_KEY configured', + 'mode="details" adds database queries for execution stats', + 'Workflow must exist or returns 404 error', + 'Credentials are referenced by ID but values not included' + ], + relatedTools: ['n8n_list_workflows', 'n8n_update_full_workflow', 'n8n_update_partial_workflow', 'n8n_validate_workflow'] + } +}; +//# sourceMappingURL=n8n-get-workflow.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.js.map b/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.js.map new file mode 100644 index 0000000..6b60a36 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-get-workflow.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-get-workflow.ts"],"names":[],"mappings":";;;AAEa,QAAA,iBAAiB,GAAsB;IAClD,IAAI,EAAE,kBAAkB;IACxB,QAAQ,EAAE,qBAAqB;IAC/B,UAAU,EAAE;QACV,WAAW,EAAE,iGAAiG;QAC9G,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC;QAC7B,OAAO,EAAE,2DAA2D;QACpE,WAAW,EAAE,iBAAiB;QAC9B,IAAI,EAAE;YACJ,wDAAwD;YACxD,iDAAiD;YACjD,yDAAyD;YACzD,oDAAoD;SACrD;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE;;;;qEAIoD;QACjE,UAAU,EAAE;YACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,yBAAyB,EAAE;YAC9E,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,mEAAmE,EAAE;SAC5H;QACD,OAAO,EAAE;;;;4DAI+C;QACxD,QAAQ,EAAE;YACR,sEAAsE;YACtE,yFAAyF;YACzF,+EAA+E;YAC/E,4EAA4E;SAC7E;QACD,QAAQ,EAAE;YACR,oCAAoC;YACpC,6CAA6C;YAC7C,sDAAsD;YACtD,2CAA2C;YAC3C,uBAAuB;SACxB;QACD,WAAW,EAAE;;;;mDAIkC;QAC/C,aAAa,EAAE;YACb,oDAAoD;YACpD,uDAAuD;YACvD,wCAAwC;YACxC,mDAAmD;YACnD,6DAA6D;SAC9D;QACD,QAAQ,EAAE;YACR,iDAAiD;YACjD,0DAA0D;YAC1D,0CAA0C;YAC1C,0DAA0D;SAC3D;QACD,YAAY,EAAE,CAAC,oBAAoB,EAAE,0BAA0B,EAAE,6BAA6B,EAAE,uBAAuB,CAAC;KACzH;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.d.ts b/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.d.ts new file mode 100644 index 0000000..d7cc651 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const n8nListWorkflowsDoc: ToolDocumentation; +//# sourceMappingURL=n8n-list-workflows.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.d.ts.map b/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.d.ts.map new file mode 100644 index 0000000..36b49c8 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-list-workflows.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-list-workflows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,mBAAmB,EAAE,iBAoDjC,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.js b/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.js new file mode 100644 index 0000000..aa27140 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.js @@ -0,0 +1,57 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nListWorkflowsDoc = void 0; +exports.n8nListWorkflowsDoc = { + name: 'n8n_list_workflows', + category: 'workflow_management', + essentials: { + description: 'List workflows (minimal metadata only - no nodes/connections). Supports pagination via cursor.', + keyParameters: ['limit', 'active', 'tags'], + example: 'n8n_list_workflows({limit: 20, active: true})', + performance: 'Fast (100-300ms)', + tips: [ + 'Use cursor for pagination', + 'Filter by active status', + 'Tag filtering for organization' + ] + }, + full: { + description: 'Lists workflows from n8n with powerful filtering options. Returns ONLY minimal metadata (id, name, active, dates, tags, nodeCount) - no workflow structure, nodes, or connections. Use n8n_get_workflow to fetch full workflow details.', + parameters: { + limit: { type: 'number', description: 'Number of workflows to return (1-100, default: 100)' }, + cursor: { type: 'string', description: 'Pagination cursor from previous response for next page' }, + active: { type: 'boolean', description: 'Filter by active/inactive status' }, + tags: { type: 'array', description: 'Filter by exact tag matches (AND logic)' }, + projectId: { type: 'string', description: 'Filter by project ID (enterprise feature)' }, + excludePinnedData: { type: 'boolean', description: 'Exclude pinned data from response (default: true)' } + }, + returns: 'Object with: workflows array (minimal fields: id, name, active, createdAt, updatedAt, tags, nodeCount), returned (count in this response), hasMore (boolean), nextCursor (for pagination), and _note (guidance when more data exists)', + examples: [ + 'n8n_list_workflows({limit: 20}) - First 20 workflows', + 'n8n_list_workflows({active: true, tags: ["production"]}) - Active production workflows', + 'n8n_list_workflows({cursor: "abc123", limit: 50}) - Next page of results' + ], + useCases: [ + 'Build workflow dashboards', + 'Find workflows by status', + 'Organize by tags', + 'Bulk workflow operations', + 'Generate workflow reports' + ], + performance: 'Very fast - typically 50-200ms. Returns only minimal metadata without workflow structure.', + bestPractices: [ + 'Always check hasMore flag to determine if pagination is needed', + 'Use cursor from previous response to get next page', + 'The returned count is NOT the total in the system', + 'Iterate with cursor until hasMore is false for complete list' + ], + pitfalls: [ + 'Requires N8N_API_URL and N8N_API_KEY configured', + 'Maximum 100 workflows per request', + 'Server may return fewer than requested limit', + 'returned field is count of current page only, not system total' + ], + relatedTools: ['n8n_get_workflow', 'n8n_update_partial_workflow', 'n8n_executions'] + } +}; +//# sourceMappingURL=n8n-list-workflows.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.js.map b/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.js.map new file mode 100644 index 0000000..e62bcf8 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-list-workflows.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-list-workflows.ts"],"names":[],"mappings":";;;AAEa,QAAA,mBAAmB,GAAsB;IACpD,IAAI,EAAE,oBAAoB;IAC1B,QAAQ,EAAE,qBAAqB;IAC/B,UAAU,EAAE;QACV,WAAW,EAAE,gGAAgG;QAC7G,aAAa,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC;QAC1C,OAAO,EAAE,+CAA+C;QACxD,WAAW,EAAE,kBAAkB;QAC/B,IAAI,EAAE;YACJ,2BAA2B;YAC3B,yBAAyB;YACzB,gCAAgC;SACjC;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE,yOAAyO;QACtP,UAAU,EAAE;YACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qDAAqD,EAAE;YAC7F,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wDAAwD,EAAE;YACjG,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,kCAAkC,EAAE;YAC5E,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,yCAAyC,EAAE;YAC/E,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,2CAA2C,EAAE;YACvF,iBAAiB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,mDAAmD,EAAE;SACzG;QACD,OAAO,EAAE,uOAAuO;QAChP,QAAQ,EAAE;YACR,sDAAsD;YACtD,wFAAwF;YACxF,0EAA0E;SAC3E;QACD,QAAQ,EAAE;YACR,2BAA2B;YAC3B,0BAA0B;YAC1B,kBAAkB;YAClB,0BAA0B;YAC1B,2BAA2B;SAC5B;QACD,WAAW,EAAE,2FAA2F;QACxG,aAAa,EAAE;YACb,gEAAgE;YAChE,oDAAoD;YACpD,mDAAmD;YACnD,8DAA8D;SAC/D;QACD,QAAQ,EAAE;YACR,iDAAiD;YACjD,mCAAmC;YACnC,8CAA8C;YAC9C,gEAAgE;SACjE;QACD,YAAY,EAAE,CAAC,kBAAkB,EAAE,6BAA6B,EAAE,gBAAgB,CAAC;KACpF;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-test-workflow.d.ts b/dist/mcp/tool-docs/workflow_management/n8n-test-workflow.d.ts new file mode 100644 index 0000000..d74e614 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-test-workflow.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const n8nTestWorkflowDoc: ToolDocumentation; +//# sourceMappingURL=n8n-test-workflow.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-test-workflow.d.ts.map b/dist/mcp/tool-docs/workflow_management/n8n-test-workflow.d.ts.map new file mode 100644 index 0000000..3572867 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-test-workflow.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-test-workflow.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-test-workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,kBAAkB,EAAE,iBAuIhC,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-test-workflow.js b/dist/mcp/tool-docs/workflow_management/n8n-test-workflow.js new file mode 100644 index 0000000..1a6ea71 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-test-workflow.js @@ -0,0 +1,140 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nTestWorkflowDoc = void 0; +exports.n8nTestWorkflowDoc = { + name: 'n8n_test_workflow', + category: 'workflow_management', + essentials: { + description: 'Test/trigger workflow execution. Auto-detects trigger type (webhook/form/chat). Only workflows with these triggers can be executed externally.', + keyParameters: ['workflowId', 'triggerType', 'data', 'message'], + example: 'n8n_test_workflow({workflowId: "123"}) - auto-detect trigger', + performance: 'Immediate trigger, response time depends on workflow complexity', + tips: [ + 'Auto-detects trigger type from workflow if not specified', + 'Workflow must have a webhook, form, or chat trigger to be executable', + 'For chat triggers, message is required', + 'All trigger types require the workflow to be ACTIVE' + ] + }, + full: { + description: `Test and trigger n8n workflows through HTTP-based methods. This unified tool supports multiple trigger types: + +**Trigger Types:** +- **webhook**: HTTP-based triggers (GET/POST/PUT/DELETE) +- **form**: Form submission triggers +- **chat**: AI chat triggers with conversation support + +**Important:** n8n's public API does not support direct workflow execution. Only workflows with webhook, form, or chat triggers can be executed externally. Workflows with schedule, manual, or other trigger types cannot be triggered via this API. + +The tool auto-detects the appropriate trigger type by analyzing the workflow's trigger node. You can override this with the triggerType parameter.`, + parameters: { + workflowId: { + type: 'string', + required: true, + description: 'Workflow ID to execute' + }, + triggerType: { + type: 'string', + required: false, + enum: ['webhook', 'form', 'chat'], + description: 'Trigger type. Auto-detected if not specified. Workflow must have matching trigger node.' + }, + httpMethod: { + type: 'string', + required: false, + enum: ['GET', 'POST', 'PUT', 'DELETE'], + description: 'For webhook: HTTP method (default: from workflow config or POST)' + }, + webhookPath: { + type: 'string', + required: false, + description: 'For webhook: override the webhook path' + }, + message: { + type: 'string', + required: false, + description: 'For chat: message to send (required for chat triggers)' + }, + sessionId: { + type: 'string', + required: false, + description: 'For chat: session ID for conversation continuity' + }, + data: { + type: 'object', + required: false, + description: 'Input data/payload for webhook or form fields' + }, + headers: { + type: 'object', + required: false, + description: 'Custom HTTP headers' + }, + timeout: { + type: 'number', + required: false, + description: 'Timeout in ms (default: 120000)' + }, + waitForResponse: { + type: 'boolean', + required: false, + description: 'Wait for workflow completion (default: true)' + } + }, + returns: `Execution response including: +- success: boolean +- data: workflow output data +- executionId: for tracking/debugging +- triggerType: detected or specified trigger type +- metadata: timing and request details`, + examples: [ + 'n8n_test_workflow({workflowId: "123"}) - Auto-detect and trigger', + 'n8n_test_workflow({workflowId: "123", triggerType: "webhook", data: {name: "John"}}) - Webhook with data', + 'n8n_test_workflow({workflowId: "123", triggerType: "chat", message: "Hello AI"}) - Chat trigger', + 'n8n_test_workflow({workflowId: "123", triggerType: "form", data: {email: "test@example.com"}}) - Form submission' + ], + useCases: [ + 'Test workflows during development', + 'Trigger AI chat workflows with messages', + 'Submit form data to form-triggered workflows', + 'Integrate n8n workflows with external systems via webhooks' + ], + performance: `Performance varies based on workflow complexity and waitForResponse setting: +- Webhook: Immediate trigger, depends on workflow +- Form: Immediate trigger, depends on workflow +- Chat: May have additional AI processing time`, + errorHandling: `**Error Response with Execution Guidance** + +When execution fails, the response includes guidance for debugging: + +**With Execution ID** (workflow started but failed): +- Use n8n_executions({action: 'get', id: executionId, mode: 'preview'}) to investigate + +**Without Execution ID** (workflow didn't start): +- Use n8n_executions({action: 'list', workflowId: 'wf_id'}) to find recent executions + +**Common Errors:** +- "Workflow not found" - Check workflow ID exists +- "Workflow not active" - Activate workflow (required for all trigger types) +- "Workflow cannot be triggered externally" - Workflow has no webhook/form/chat trigger +- "Chat message required" - Provide message parameter for chat triggers +- "SSRF protection" - URL validation failed`, + bestPractices: [ + 'Let auto-detection choose the trigger type when possible', + 'Ensure workflow has a webhook, form, or chat trigger before testing', + 'For chat workflows, provide sessionId for multi-turn conversations', + 'Use mode="preview" with n8n_executions for efficient debugging', + 'Test with small data payloads first', + 'Activate workflows before testing (use n8n_update_partial_workflow with activateWorkflow)' + ], + pitfalls: [ + 'All trigger types require the workflow to be ACTIVE', + 'Workflows without webhook/form/chat triggers cannot be executed externally', + 'Chat trigger requires message parameter', + 'Form data must match expected form fields', + 'Webhook method must match node configuration' + ], + relatedTools: ['n8n_executions', 'n8n_get_workflow', 'n8n_create_workflow', 'n8n_validate_workflow'] + } +}; +//# sourceMappingURL=n8n-test-workflow.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-test-workflow.js.map b/dist/mcp/tool-docs/workflow_management/n8n-test-workflow.js.map new file mode 100644 index 0000000..2e861d3 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-test-workflow.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-test-workflow.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-test-workflow.ts"],"names":[],"mappings":";;;AAEa,QAAA,kBAAkB,GAAsB;IACnD,IAAI,EAAE,mBAAmB;IACzB,QAAQ,EAAE,qBAAqB;IAC/B,UAAU,EAAE;QACV,WAAW,EAAE,gJAAgJ;QAC7J,aAAa,EAAE,CAAC,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,CAAC;QAC/D,OAAO,EAAE,8DAA8D;QACvE,WAAW,EAAE,iEAAiE;QAC9E,IAAI,EAAE;YACJ,0DAA0D;YAC1D,sEAAsE;YACtE,wCAAwC;YACxC,qDAAqD;SACtD;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE;;;;;;;;;mJASkI;QAC/I,UAAU,EAAE;YACV,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,wBAAwB;aACtC;YACD,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC;gBACjC,WAAW,EAAE,yFAAyF;aACvG;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC;gBACtC,WAAW,EAAE,kEAAkE;aAChF;YACD,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,wCAAwC;aACtD;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,wDAAwD;aACtE;YACD,SAAS,EAAE;gBACT,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,kDAAkD;aAChE;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,+CAA+C;aAC7D;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,qBAAqB;aACnC;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,iCAAiC;aAC/C;YACD,eAAe,EAAE;gBACf,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,8CAA8C;aAC5D;SACF;QACD,OAAO,EAAE;;;;;uCAK0B;QACnC,QAAQ,EAAE;YACR,kEAAkE;YAClE,0GAA0G;YAC1G,iGAAiG;YACjG,kHAAkH;SACnH;QACD,QAAQ,EAAE;YACR,mCAAmC;YACnC,yCAAyC;YACzC,8CAA8C;YAC9C,4DAA4D;SAC7D;QACD,WAAW,EAAE;;;+CAG8B;QAC3C,aAAa,EAAE;;;;;;;;;;;;;;;4CAeyB;QACxC,aAAa,EAAE;YACb,0DAA0D;YAC1D,qEAAqE;YACrE,oEAAoE;YACpE,gEAAgE;YAChE,qCAAqC;YACrC,2FAA2F;SAC5F;QACD,QAAQ,EAAE;YACR,qDAAqD;YACrD,4EAA4E;YAC5E,yCAAyC;YACzC,2CAA2C;YAC3C,8CAA8C;SAC/C;QACD,YAAY,EAAE,CAAC,gBAAgB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,uBAAuB,CAAC;KACrG;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.d.ts b/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.d.ts new file mode 100644 index 0000000..14abc90 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const n8nUpdateFullWorkflowDoc: ToolDocumentation; +//# sourceMappingURL=n8n-update-full-workflow.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.d.ts.map b/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.d.ts.map new file mode 100644 index 0000000..4331a81 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-update-full-workflow.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-update-full-workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,wBAAwB,EAAE,iBAwDtC,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.js b/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.js new file mode 100644 index 0000000..280904e --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.js @@ -0,0 +1,61 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nUpdateFullWorkflowDoc = void 0; +exports.n8nUpdateFullWorkflowDoc = { + name: 'n8n_update_full_workflow', + category: 'workflow_management', + essentials: { + description: 'Full workflow update. Requires complete nodes[] and connections{}. For incremental use n8n_update_partial_workflow.', + keyParameters: ['id', 'nodes', 'connections'], + example: 'n8n_update_full_workflow({id: "wf_123", nodes: [...], connections: {...}})', + performance: 'Network-dependent', + tips: [ + 'Include intent parameter in every call - helps to return better responses', + 'Must provide complete workflow', + 'Use update_partial for small changes', + 'Validate before updating' + ] + }, + full: { + description: 'Performs a complete workflow update by replacing the entire workflow definition. Requires providing the complete nodes array and connections object, even for small changes. This is a full replacement operation - any nodes or connections not included will be removed.', + parameters: { + id: { type: 'string', required: true, description: 'Workflow ID to update' }, + name: { type: 'string', description: 'New workflow name (optional)' }, + nodes: { type: 'array', description: 'Complete array of workflow nodes (required if modifying structure)' }, + connections: { type: 'object', description: 'Complete connections object (required if modifying structure)' }, + settings: { type: 'object', description: 'Workflow settings to update (timezone, error handling, etc.)' }, + intent: { type: 'string', description: 'Intent of the change - helps to return better response. Include in every tool call. Example: "Migrate workflow to new node versions".' } + }, + returns: 'Updated workflow object with all fields including the changes applied', + examples: [ + 'n8n_update_full_workflow({id: "abc", intent: "Rename workflow for clarity", name: "New Name"}) - Rename with intent', + 'n8n_update_full_workflow({id: "abc", name: "New Name"}) - Rename only', + 'n8n_update_full_workflow({id: "xyz", intent: "Add error handling nodes", nodes: [...], connections: {...}}) - Full structure update', + 'const wf = n8n_get_workflow({id}); wf.nodes.push(newNode); n8n_update_full_workflow({...wf, intent: "Add data processing node"}); // Add node' + ], + useCases: [ + 'Major workflow restructuring', + 'Bulk node updates', + 'Workflow imports/cloning', + 'Complete workflow replacement', + 'Settings changes' + ], + performance: 'Network-dependent - typically 200-500ms. Larger workflows take longer. Consider update_partial for better performance.', + bestPractices: [ + 'Always include intent parameter - it helps provide better responses', + 'Get workflow first, modify, then update', + 'Validate with validate_workflow before updating', + 'Use update_partial for small changes', + 'Test updates in non-production first' + ], + pitfalls: [ + 'Requires N8N_API_URL and N8N_API_KEY configured', + 'Must include ALL nodes/connections', + 'Missing nodes will be deleted', + 'Can break active workflows', + 'No partial updates - use update_partial instead' + ], + relatedTools: ['n8n_get_workflow', 'n8n_update_partial_workflow', 'validate_workflow', 'n8n_create_workflow'] + } +}; +//# sourceMappingURL=n8n-update-full-workflow.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.js.map b/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.js.map new file mode 100644 index 0000000..00b676c --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-update-full-workflow.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-update-full-workflow.ts"],"names":[],"mappings":";;;AAEa,QAAA,wBAAwB,GAAsB;IACzD,IAAI,EAAE,0BAA0B;IAChC,QAAQ,EAAE,qBAAqB;IAC/B,UAAU,EAAE;QACV,WAAW,EAAE,qHAAqH;QAClI,aAAa,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,aAAa,CAAC;QAC7C,OAAO,EAAE,4EAA4E;QACrF,WAAW,EAAE,mBAAmB;QAChC,IAAI,EAAE;YACJ,2EAA2E;YAC3E,gCAAgC;YAChC,sCAAsC;YACtC,0BAA0B;SAC3B;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE,4QAA4Q;QACzR,UAAU,EAAE;YACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,uBAAuB,EAAE;YAC5E,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8BAA8B,EAAE;YACrE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,oEAAoE,EAAE;YAC3G,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+DAA+D,EAAE;YAC7G,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8DAA8D,EAAE;YACzG,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uIAAuI,EAAE;SACjL;QACD,OAAO,EAAE,uEAAuE;QAChF,QAAQ,EAAE;YACR,qHAAqH;YACrH,uEAAuE;YACvE,qIAAqI;YACrI,+IAA+I;SAChJ;QACD,QAAQ,EAAE;YACR,8BAA8B;YAC9B,mBAAmB;YACnB,0BAA0B;YAC1B,+BAA+B;YAC/B,kBAAkB;SACnB;QACD,WAAW,EAAE,wHAAwH;QACrI,aAAa,EAAE;YACb,qEAAqE;YACrE,yCAAyC;YACzC,iDAAiD;YACjD,sCAAsC;YACtC,sCAAsC;SACvC;QACD,QAAQ,EAAE;YACR,iDAAiD;YACjD,oCAAoC;YACpC,+BAA+B;YAC/B,4BAA4B;YAC5B,iDAAiD;SAClD;QACD,YAAY,EAAE,CAAC,kBAAkB,EAAE,6BAA6B,EAAE,mBAAmB,EAAE,qBAAqB,CAAC;KAC9G;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.d.ts b/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.d.ts new file mode 100644 index 0000000..f5bf4b9 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const n8nUpdatePartialWorkflowDoc: ToolDocumentation; +//# sourceMappingURL=n8n-update-partial-workflow.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.d.ts.map b/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.d.ts.map new file mode 100644 index 0000000..f1bb709 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-update-partial-workflow.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,2BAA2B,EAAE,iBA+ZzC,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.js b/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.js new file mode 100644 index 0000000..1d093e1 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.js @@ -0,0 +1,420 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nUpdatePartialWorkflowDoc = void 0; +exports.n8nUpdatePartialWorkflowDoc = { + name: 'n8n_update_partial_workflow', + category: 'workflow_management', + essentials: { + description: 'Update workflow incrementally with diff operations. Types: addNode, removeNode, updateNode, moveNode, enable/disableNode, addConnection, removeConnection, rewireConnection, cleanStaleConnections, replaceConnections, updateSettings, updateName, add/removeTag, activateWorkflow, deactivateWorkflow. Supports smart parameters (branch, case) for multi-output nodes. Full support for AI connections (ai_languageModel, ai_tool, ai_memory, ai_embedding, ai_vectorStore, ai_document, ai_textSplitter, ai_outputParser).', + keyParameters: ['id', 'operations', 'continueOnError'], + example: 'n8n_update_partial_workflow({id: "wf_123", operations: [{type: "rewireConnection", source: "IF", from: "Old", to: "New", branch: "true"}]})', + performance: 'Fast (50-200ms)', + tips: [ + 'ALWAYS provide intent parameter describing what you\'re doing (e.g., "Add error handling", "Fix webhook URL", "Connect Slack to error output")', + 'DON\'T use generic intent like "update workflow" or "partial update" - be specific about your goal', + 'Use rewireConnection to change connection targets', + 'Use branch="true"/"false" for IF nodes', + 'Use case=N for Switch nodes', + 'Use cleanStaleConnections to auto-remove broken connections', + 'Set ignoreErrors:true on removeConnection for cleanup', + 'Use continueOnError mode for best-effort bulk operations', + 'Validate with validateOnly first', + 'For AI connections, specify sourceOutput type (ai_languageModel, ai_tool, etc.)', + 'Batch AI component connections for atomic updates', + 'Auto-sanitization: ALL nodes auto-fixed during updates (operator structures, missing metadata)', + 'Node renames automatically update all connection references - no manual connection operations needed', + 'Activate/deactivate workflows: Use activateWorkflow/deactivateWorkflow operations (requires activatable triggers like webhook/schedule)' + ] + }, + full: { + description: `Updates workflows using surgical diff operations instead of full replacement. Supports 17 operation types for precise modifications. Operations are validated and applied atomically by default - all succeed or none are applied. + +## Available Operations: + +### Node Operations (6 types): +- **addNode**: Add a new node with name, type, and position (required) +- **removeNode**: Remove a node by ID or name +- **updateNode**: Update node properties using dot notation (e.g., 'parameters.url') +- **moveNode**: Change node position [x, y] +- **enableNode**: Enable a disabled node +- **disableNode**: Disable an active node + +### Connection Operations (5 types): +- **addConnection**: Connect nodes (source→target). Supports smart parameters: branch="true"/"false" for IF nodes, case=N for Switch nodes. +- **removeConnection**: Remove connection between nodes (supports ignoreErrors flag) +- **rewireConnection**: Change connection target from one node to another. Supports smart parameters. +- **cleanStaleConnections**: Auto-remove all connections referencing non-existent nodes +- **replaceConnections**: Replace entire connections object + +### Metadata Operations (4 types): +- **updateSettings**: Modify workflow settings +- **updateName**: Rename the workflow +- **addTag**: Add a workflow tag +- **removeTag**: Remove a workflow tag + +### Workflow Activation Operations (2 types): +- **activateWorkflow**: Activate the workflow to enable automatic execution via triggers +- **deactivateWorkflow**: Deactivate the workflow to prevent automatic execution + +## Smart Parameters for Multi-Output Nodes + +For **IF nodes**, use semantic 'branch' parameter instead of technical sourceIndex: +- **branch="true"**: Routes to true branch (sourceIndex=0) +- **branch="false"**: Routes to false branch (sourceIndex=1) + +For **Switch nodes**, use semantic 'case' parameter: +- **case=0**: First output +- **case=1**: Second output +- **case=N**: Nth output + +Works with addConnection and rewireConnection operations. Explicit sourceIndex overrides smart parameters. + +## AI Connection Support + +Full support for all 8 AI connection types used in n8n AI workflows: + +**Connection Types**: +- **ai_languageModel**: Connect language models (OpenAI, Anthropic, Google Gemini) to AI Agents +- **ai_tool**: Connect tools (HTTP Request Tool, Code Tool, etc.) to AI Agents +- **ai_memory**: Connect memory systems (Window Buffer, Conversation Summary) to AI Agents +- **ai_outputParser**: Connect output parsers (Structured, JSON) to AI Agents +- **ai_embedding**: Connect embedding models to Vector Stores +- **ai_vectorStore**: Connect vector stores to Vector Store Tools +- **ai_document**: Connect document loaders to Vector Stores +- **ai_textSplitter**: Connect text splitters to document processing chains + +**AI Connection Examples**: +- Single connection: \`{type: "addConnection", source: "OpenAI", target: "AI Agent", sourceOutput: "ai_languageModel"}\` +- Fallback model: Use targetIndex (0=primary, 1=fallback) for dual language model setup +- Multiple tools: Batch multiple \`sourceOutput: "ai_tool"\` connections to one AI Agent +- Vector retrieval: Chain ai_embedding → ai_vectorStore → ai_tool → AI Agent + +**Important Notes**: +- **AI nodes do NOT require main connections**: Nodes like OpenAI Chat Model, Postgres Chat Memory, Embeddings OpenAI, and Supabase Vector Store use AI-specific connection types exclusively. They should ONLY have connections like \`ai_languageModel\`, \`ai_memory\`, \`ai_embedding\`, or \`ai_tool\` - NOT \`main\` connections. + +**Best Practices**: +- Always specify \`sourceOutput\` for AI connections (defaults to "main" if omitted) +- Connect language model BEFORE creating/enabling AI Agent (validation requirement) +- Use atomic mode (default) when setting up AI workflows to ensure complete configuration +- Validate AI workflows after changes with \`n8n_validate_workflow\` tool + +## Cleanup & Recovery Features + +### Automatic Cleanup +The **cleanStaleConnections** operation automatically removes broken connection references after node renames/deletions. Essential for workflow recovery. + +### Best-Effort Mode +Set **continueOnError: true** to apply valid operations even if some fail. Returns detailed results showing which operations succeeded/failed. Perfect for bulk cleanup operations. + +### Graceful Error Handling +Add **ignoreErrors: true** to removeConnection operations to prevent failures when connections don't exist. + +## Auto-Sanitization System + +### What Gets Auto-Fixed +When ANY workflow update is made, ALL nodes in the workflow are automatically sanitized to ensure complete metadata and correct structure: + +1. **Operator Structure Fixes**: + - Binary operators (equals, contains, greaterThan, etc.) automatically have \`singleValue\` removed + - Unary operators (isEmpty, isNotEmpty, true, false) automatically get \`singleValue: true\` added + - Invalid operator structures (e.g., \`{type: "isNotEmpty"}\`) are corrected to \`{type: "boolean", operation: "isNotEmpty"}\` + +2. **Missing Metadata Added**: + - IF nodes with conditions get complete \`conditions.options\` structure if missing + - Switch nodes with conditions get complete \`conditions.options\` for all rules + - Required fields: \`{version: 2, leftValue: "", caseSensitive: true, typeValidation: "strict"}\` + +### Sanitization Scope +- Runs on **ALL nodes** in the workflow, not just modified ones +- Triggered by ANY update operation (addNode, updateNode, addConnection, etc.) +- Prevents workflow corruption that would make UI unrenderable + +### Limitations +Auto-sanitization CANNOT fix: +- Broken connections (connections referencing non-existent nodes) - use \`cleanStaleConnections\` +- Branch count mismatches (e.g., Switch with 3 rules but only 2 outputs) - requires manual connection fixes +- Workflows in paradoxical corrupt states (API returns corrupt data, API rejects updates) - must recreate workflow + +### Recovery Guidance +If validation still fails after auto-sanitization: +1. Check error details for specific issues +2. Use \`validate_workflow\` to see all validation errors +3. For connection issues, use \`cleanStaleConnections\` operation +4. For branch mismatches, add missing output connections +5. For paradoxical corrupted workflows, create new workflow and migrate nodes + +## Automatic Connection Reference Updates + +When you rename a node using **updateNode**, all connection references throughout the workflow are automatically updated. Both the connection source keys and target references are updated for all connection types (main, error, ai_tool, ai_languageModel, ai_memory, etc.) and all branch configurations (IF node branches, Switch node cases, error outputs). + +### Basic Example +\`\`\`javascript +// Rename a node - connections update automatically +n8n_update_partial_workflow({ + id: "wf_123", + operations: [{ + type: "updateNode", + nodeId: "node_abc", + updates: { name: "Data Processor" } + }] +}); +// All incoming and outgoing connections now reference "Data Processor" +\`\`\` + +### Multi-Output Node Example +\`\`\`javascript +// Rename nodes in a branching workflow +n8n_update_partial_workflow({ + id: "workflow_id", + operations: [ + { + type: "updateNode", + nodeId: "if_node_id", + updates: { name: "Value Checker" } + }, + { + type: "updateNode", + nodeId: "error_node_id", + updates: { name: "Error Handler" } + } + ] +}); +// IF node branches and error connections automatically updated +\`\`\` + +### Name Collision Protection +Attempting to rename a node to an existing name returns a clear error: +\`\`\` +Cannot rename node "Old Name" to "New Name": A node with that name already exists (id: abc123...). +Please choose a different name. +\`\`\` + +### Usage Notes +- Simply rename nodes with updateNode - no manual connection operations needed +- Multiple renames in one call work atomically +- Can rename a node and add/remove connections using the new name in the same batch +- Use \`validateOnly: true\` to preview effects before applying + +## Removing Properties with undefined + +To remove a property from a node, set its value to \`undefined\` in the updates object. This is essential when migrating from deprecated properties or cleaning up optional configuration fields. + +### Why Use undefined? +- **Property removal vs. null**: Setting a property to \`undefined\` removes it completely from the node object, while \`null\` sets the property to a null value +- **Validation constraints**: Some properties are mutually exclusive (e.g., \`continueOnFail\` and \`onError\`). Simply setting one without removing the other will fail validation +- **Deprecated property migration**: When n8n deprecates properties, you must remove the old property before the new one will work + +### Basic Property Removal +\`\`\`javascript +// Remove error handling configuration +n8n_update_partial_workflow({ + id: "wf_123", + operations: [{ + type: "updateNode", + nodeName: "HTTP Request", + updates: { onError: undefined } + }] +}); + +// Remove disabled flag +n8n_update_partial_workflow({ + id: "wf_456", + operations: [{ + type: "updateNode", + nodeId: "node_abc", + updates: { disabled: undefined } + }] +}); +\`\`\` + +### Nested Property Removal +Use dot notation to remove nested properties: +\`\`\`javascript +// Remove nested parameter +n8n_update_partial_workflow({ + id: "wf_789", + operations: [{ + type: "updateNode", + nodeName: "API Request", + updates: { "parameters.authentication": undefined } + }] +}); + +// Remove entire array property +n8n_update_partial_workflow({ + id: "wf_012", + operations: [{ + type: "updateNode", + nodeName: "HTTP Request", + updates: { "parameters.headers": undefined } + }] +}); +\`\`\` + +### Migrating from Deprecated Properties +Common scenario: replacing \`continueOnFail\` with \`onError\`: +\`\`\`javascript +// WRONG: Setting only the new property leaves the old one +n8n_update_partial_workflow({ + id: "wf_123", + operations: [{ + type: "updateNode", + nodeName: "HTTP Request", + updates: { onError: "continueErrorOutput" } + }] +}); +// Error: continueOnFail and onError are mutually exclusive + +// CORRECT: Remove the old property first +n8n_update_partial_workflow({ + id: "wf_123", + operations: [{ + type: "updateNode", + nodeName: "HTTP Request", + updates: { + continueOnFail: undefined, + onError: "continueErrorOutput" + } + }] +}); +\`\`\` + +### Batch Property Removal +Remove multiple properties in one operation: +\`\`\`javascript +n8n_update_partial_workflow({ + id: "wf_345", + operations: [{ + type: "updateNode", + nodeName: "Data Processor", + updates: { + continueOnFail: undefined, + alwaysOutputData: undefined, + "parameters.legacy_option": undefined + } + }] +}); +\`\`\` + +### When to Use undefined +- Removing deprecated properties during migration +- Cleaning up optional configuration flags +- Resolving mutual exclusivity validation errors +- Removing stale or unnecessary node metadata +- Simplifying node configuration`, + parameters: { + id: { type: 'string', required: true, description: 'Workflow ID to update' }, + operations: { + type: 'array', + required: true, + description: 'Array of diff operations. Each must have "type" field and operation-specific properties. Nodes can be referenced by ID or name.' + }, + validateOnly: { type: 'boolean', description: 'If true, only validate operations without applying them' }, + continueOnError: { type: 'boolean', description: 'If true, apply valid operations even if some fail (best-effort mode). Returns applied and failed operation indices. Default: false (atomic)' }, + intent: { type: 'string', description: 'Intent of the change - helps to return better response. Include in every tool call. Example: "Add error handling for API failures".' } + }, + returns: 'Updated workflow object or validation results if validateOnly=true', + examples: [ + '// Include intent parameter for better responses\nn8n_update_partial_workflow({id: "abc", intent: "Add error handling for API failures", operations: [{type: "addConnection", source: "HTTP Request", target: "Error Handler"}]})', + '// Add a basic node (minimal configuration)\nn8n_update_partial_workflow({id: "abc", operations: [{type: "addNode", node: {name: "Process Data", type: "n8n-nodes-base.set", position: [400, 300], parameters: {}}}]})', + '// Add node with full configuration\nn8n_update_partial_workflow({id: "def", operations: [{type: "addNode", node: {name: "Send Slack Alert", type: "n8n-nodes-base.slack", position: [600, 300], typeVersion: 2, parameters: {resource: "message", operation: "post", channel: "#alerts", text: "Success!"}}}]})', + '// Add node AND connect it (common pattern)\nn8n_update_partial_workflow({id: "ghi", operations: [\n {type: "addNode", node: {name: "HTTP Request", type: "n8n-nodes-base.httpRequest", position: [400, 300], parameters: {url: "https://api.example.com", method: "GET"}}},\n {type: "addConnection", source: "Webhook", target: "HTTP Request"}\n]})', + '// Rewire connection from one target to another\nn8n_update_partial_workflow({id: "xyz", operations: [{type: "rewireConnection", source: "Webhook", from: "Old Handler", to: "New Handler"}]})', + '// Smart parameter: IF node true branch\nn8n_update_partial_workflow({id: "abc", operations: [{type: "addConnection", source: "IF", target: "Success Handler", branch: "true"}]})', + '// Smart parameter: IF node false branch\nn8n_update_partial_workflow({id: "def", operations: [{type: "addConnection", source: "IF", target: "Error Handler", branch: "false"}]})', + '// Smart parameter: Switch node case routing\nn8n_update_partial_workflow({id: "ghi", operations: [\n {type: "addConnection", source: "Switch", target: "Handler A", case: 0},\n {type: "addConnection", source: "Switch", target: "Handler B", case: 1},\n {type: "addConnection", source: "Switch", target: "Handler C", case: 2}\n]})', + '// Rewire with smart parameter\nn8n_update_partial_workflow({id: "jkl", operations: [{type: "rewireConnection", source: "IF", from: "Old True Handler", to: "New True Handler", branch: "true"}]})', + '// Add multiple nodes in batch\nn8n_update_partial_workflow({id: "mno", operations: [\n {type: "addNode", node: {name: "Filter", type: "n8n-nodes-base.filter", position: [400, 300], parameters: {}}},\n {type: "addNode", node: {name: "Transform", type: "n8n-nodes-base.set", position: [600, 300], parameters: {}}},\n {type: "addConnection", source: "Filter", target: "Transform"}\n]})', + '// Clean up stale connections after node renames/deletions\nn8n_update_partial_workflow({id: "pqr", operations: [{type: "cleanStaleConnections"}]})', + '// Remove connection gracefully (no error if it doesn\'t exist)\nn8n_update_partial_workflow({id: "stu", operations: [{type: "removeConnection", source: "Old Node", target: "Target", ignoreErrors: true}]})', + '// Best-effort mode: apply what works, report what fails\nn8n_update_partial_workflow({id: "vwx", operations: [\n {type: "updateName", name: "Fixed Workflow"},\n {type: "removeConnection", source: "Broken", target: "Node"},\n {type: "cleanStaleConnections"}\n], continueOnError: true})', + '// Update node parameter\nn8n_update_partial_workflow({id: "yza", operations: [{type: "updateNode", nodeName: "HTTP Request", updates: {"parameters.url": "https://api.example.com"}}]})', + '// Validate before applying\nn8n_update_partial_workflow({id: "bcd", operations: [{type: "removeNode", nodeName: "Old Process"}], validateOnly: true})', + '\n// ============ AI CONNECTION EXAMPLES ============', + '// Connect language model to AI Agent\nn8n_update_partial_workflow({id: "ai1", operations: [{type: "addConnection", source: "OpenAI Chat Model", target: "AI Agent", sourceOutput: "ai_languageModel"}]})', + '// Connect tool to AI Agent\nn8n_update_partial_workflow({id: "ai2", operations: [{type: "addConnection", source: "HTTP Request Tool", target: "AI Agent", sourceOutput: "ai_tool"}]})', + '// Connect memory to AI Agent\nn8n_update_partial_workflow({id: "ai3", operations: [{type: "addConnection", source: "Window Buffer Memory", target: "AI Agent", sourceOutput: "ai_memory"}]})', + '// Connect output parser to AI Agent\nn8n_update_partial_workflow({id: "ai4", operations: [{type: "addConnection", source: "Structured Output Parser", target: "AI Agent", sourceOutput: "ai_outputParser"}]})', + '// Complete AI Agent setup: Add language model, tools, and memory\nn8n_update_partial_workflow({id: "ai5", operations: [\n {type: "addConnection", source: "OpenAI Chat Model", target: "AI Agent", sourceOutput: "ai_languageModel"},\n {type: "addConnection", source: "HTTP Request Tool", target: "AI Agent", sourceOutput: "ai_tool"},\n {type: "addConnection", source: "Code Tool", target: "AI Agent", sourceOutput: "ai_tool"},\n {type: "addConnection", source: "Window Buffer Memory", target: "AI Agent", sourceOutput: "ai_memory"}\n]})', + '// Add fallback model to AI Agent for reliability\nn8n_update_partial_workflow({id: "ai6", operations: [\n {type: "addConnection", source: "OpenAI Chat Model", target: "AI Agent", sourceOutput: "ai_languageModel", targetIndex: 0},\n {type: "addConnection", source: "Anthropic Chat Model", target: "AI Agent", sourceOutput: "ai_languageModel", targetIndex: 1}\n]})', + '// Vector Store setup: Connect embeddings and documents\nn8n_update_partial_workflow({id: "ai7", operations: [\n {type: "addConnection", source: "Embeddings OpenAI", target: "Pinecone Vector Store", sourceOutput: "ai_embedding"},\n {type: "addConnection", source: "Default Data Loader", target: "Pinecone Vector Store", sourceOutput: "ai_document"}\n]})', + '// Connect Vector Store Tool to AI Agent (retrieval setup)\nn8n_update_partial_workflow({id: "ai8", operations: [\n {type: "addConnection", source: "Pinecone Vector Store", target: "Vector Store Tool", sourceOutput: "ai_vectorStore"},\n {type: "addConnection", source: "Vector Store Tool", target: "AI Agent", sourceOutput: "ai_tool"}\n]})', + '// Rewire AI Agent to use different language model\nn8n_update_partial_workflow({id: "ai9", operations: [{type: "rewireConnection", source: "AI Agent", from: "OpenAI Chat Model", to: "Anthropic Chat Model", sourceOutput: "ai_languageModel"}]})', + '// Replace all AI tools for an agent\nn8n_update_partial_workflow({id: "ai10", operations: [\n {type: "removeConnection", source: "Old Tool 1", target: "AI Agent", sourceOutput: "ai_tool"},\n {type: "removeConnection", source: "Old Tool 2", target: "AI Agent", sourceOutput: "ai_tool"},\n {type: "addConnection", source: "New HTTP Tool", target: "AI Agent", sourceOutput: "ai_tool"},\n {type: "addConnection", source: "New Code Tool", target: "AI Agent", sourceOutput: "ai_tool"}\n]})', + '\n// ============ REMOVING PROPERTIES EXAMPLES ============', + '// Remove a simple property\nn8n_update_partial_workflow({id: "rm1", operations: [{type: "updateNode", nodeName: "HTTP Request", updates: {onError: undefined}}]})', + '// Migrate from deprecated continueOnFail to onError\nn8n_update_partial_workflow({id: "rm2", operations: [{type: "updateNode", nodeName: "HTTP Request", updates: {continueOnFail: undefined, onError: "continueErrorOutput"}}]})', + '// Remove nested property\nn8n_update_partial_workflow({id: "rm3", operations: [{type: "updateNode", nodeName: "API Request", updates: {"parameters.authentication": undefined}}]})', + '// Remove multiple properties\nn8n_update_partial_workflow({id: "rm4", operations: [{type: "updateNode", nodeName: "Data Processor", updates: {continueOnFail: undefined, alwaysOutputData: undefined, "parameters.legacy_option": undefined}}]})', + '// Remove entire array property\nn8n_update_partial_workflow({id: "rm5", operations: [{type: "updateNode", nodeName: "HTTP Request", updates: {"parameters.headers": undefined}}]})' + ], + useCases: [ + 'Rewire connections when replacing nodes', + 'Route IF/Switch node outputs with semantic parameters', + 'Clean up broken workflows after node renames/deletions', + 'Bulk connection cleanup with best-effort mode', + 'Update single node parameters', + 'Replace all connections at once', + 'Graceful cleanup operations that don\'t fail', + 'Enable/disable nodes', + 'Rename workflows or nodes', + 'Manage tags efficiently', + 'Connect AI components (language models, tools, memory, parsers)', + 'Set up AI Agent workflows with multiple tools', + 'Add fallback language models to AI Agents', + 'Configure Vector Store retrieval systems', + 'Swap language models in existing AI workflows', + 'Batch-update AI tool connections' + ], + performance: 'Very fast - typically 50-200ms. Much faster than full updates as only changes are processed.', + bestPractices: [ + 'Always include intent parameter with specific description (e.g., "Add error handling to HTTP Request node", "Fix authentication flow", "Connect Slack notification to errors"). Avoid generic phrases like "update workflow" or "partial update"', + 'Use rewireConnection instead of remove+add for changing targets', + 'Use branch="true"/"false" for IF nodes instead of sourceIndex', + 'Use case=N for Switch nodes instead of sourceIndex', + 'Use cleanStaleConnections after renaming/removing nodes', + 'Use continueOnError for bulk cleanup operations', + 'Set ignoreErrors:true on removeConnection for graceful cleanup', + 'Use validateOnly to test operations before applying', + 'Group related changes in one call', + 'Check operation order for dependencies', + 'Use atomic mode (default) for critical updates', + 'For AI connections, always specify sourceOutput (ai_languageModel, ai_tool, ai_memory, etc.)', + 'Connect language model BEFORE adding AI Agent to ensure validation passes', + 'Use targetIndex for fallback models (primary=0, fallback=1)', + 'Batch AI component connections in a single operation for atomicity', + 'Validate AI workflows after connection changes to catch configuration errors', + 'To remove properties, set them to undefined (not null) in the updates object', + 'When migrating from deprecated properties, remove the old property and add the new one in the same operation', + 'Use undefined to resolve mutual exclusivity validation errors between properties', + 'Batch multiple property removals in a single updateNode operation for efficiency' + ], + pitfalls: [ + '**REQUIRES N8N_API_URL and N8N_API_KEY environment variables** - will not work without n8n API access', + 'Atomic mode (default): all operations must succeed or none are applied', + 'continueOnError breaks atomic guarantees - use with caution', + 'Order matters for dependent operations (e.g., must add node before connecting to it)', + 'Node references accept ID or name, but name must be unique', + 'Node names with special characters (apostrophes, quotes) work correctly', + 'For best compatibility, prefer node IDs over names when dealing with special characters', + 'Use "updates" property for updateNode operations: {type: "updateNode", updates: {...}}', + 'Smart parameters (branch, case) only work with IF and Switch nodes - ignored for other node types', + 'Explicit sourceIndex overrides smart parameters (branch, case) if both provided', + '**CRITICAL**: For If nodes, ALWAYS use branch="true"/"false" instead of sourceIndex. Using sourceIndex=0 for multiple connections will put them ALL on the TRUE branch (main[0]), breaking your workflow logic!', + '**CRITICAL**: For Switch nodes, ALWAYS use case=N instead of sourceIndex. Using same sourceIndex for multiple connections will put them on the same case output.', + 'cleanStaleConnections removes ALL broken connections - cannot be selective', + 'replaceConnections overwrites entire connections object - all previous connections lost', + '**Auto-sanitization behavior**: Binary operators (equals, contains) automatically have singleValue removed; unary operators (isEmpty, isNotEmpty) automatically get singleValue:true added', + '**Auto-sanitization runs on ALL nodes**: When ANY update is made, ALL nodes in the workflow are sanitized (not just modified ones)', + '**Auto-sanitization cannot fix everything**: It fixes operator structures and missing metadata, but cannot fix broken connections or branch mismatches', + '**Corrupted workflows beyond repair**: Workflows in paradoxical states (API returns corrupt, API rejects updates) cannot be fixed via API - must be recreated', + 'Setting a property to null does NOT remove it - use undefined instead', + 'When properties are mutually exclusive (e.g., continueOnFail and onError), setting only the new property will fail - you must remove the old one with undefined', + 'Removing a required property may cause validation errors - check node documentation first', + 'Nested property removal with dot notation only removes the specific nested field, not the entire parent object', + 'Array index notation (e.g., "parameters.headers[0]") is not supported - remove the entire array property instead' + ], + relatedTools: ['n8n_update_full_workflow', 'n8n_get_workflow', 'validate_workflow', 'tools_documentation'] + } +}; +//# sourceMappingURL=n8n-update-partial-workflow.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.js.map b/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.js.map new file mode 100644 index 0000000..8e8ef13 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-update-partial-workflow.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.d.ts b/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.d.ts new file mode 100644 index 0000000..1fcebd3 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const n8nValidateWorkflowDoc: ToolDocumentation; +//# sourceMappingURL=n8n-validate-workflow.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.d.ts.map b/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.d.ts.map new file mode 100644 index 0000000..261c1a8 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-validate-workflow.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-validate-workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,sBAAsB,EAAE,iBAoEpC,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.js b/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.js new file mode 100644 index 0000000..193a139 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.js @@ -0,0 +1,73 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nValidateWorkflowDoc = void 0; +exports.n8nValidateWorkflowDoc = { + name: 'n8n_validate_workflow', + category: 'workflow_management', + essentials: { + description: 'Validate workflow from n8n instance by ID - checks nodes, connections, expressions, and returns errors/warnings', + keyParameters: ['id'], + example: 'n8n_validate_workflow({id: "wf_abc123"})', + performance: 'Network-dependent (100-500ms) - fetches and validates workflow', + tips: [ + 'Use options.profile to control validation strictness (minimal/runtime/ai-friendly/strict)', + 'Validation includes node configs, connections, and n8n expression syntax', + 'Returns categorized errors, warnings, and actionable fix suggestions' + ] + }, + full: { + description: `Validates a workflow stored in your n8n instance by fetching it via API and running comprehensive validation checks. This tool: + +- Fetches the workflow from n8n using the workflow ID +- Validates all node configurations based on their schemas +- Checks workflow connections and data flow +- Validates n8n expression syntax in all fields +- Returns categorized issues with fix suggestions + +The validation uses the same engine as validate_workflow but works with workflows already in n8n, making it perfect for validating existing workflows before execution. + +Requires N8N_API_URL and N8N_API_KEY environment variables to be configured.`, + parameters: { + id: { + type: 'string', + required: true, + description: 'The workflow ID to validate from your n8n instance' + }, + options: { + type: 'object', + required: false, + description: 'Validation options: {validateNodes: bool (default true), validateConnections: bool (default true), validateExpressions: bool (default true), profile: "minimal"|"runtime"|"ai-friendly"|"strict" (default "runtime")}' + } + }, + returns: 'ValidationResult object containing isValid boolean, arrays of errors/warnings, and suggestions for fixes', + examples: [ + 'n8n_validate_workflow({id: "wf_abc123"}) - Validate with default settings', + 'n8n_validate_workflow({id: "wf_abc123", options: {profile: "strict"}}) - Strict validation', + 'n8n_validate_workflow({id: "wf_abc123", options: {validateExpressions: false}}) - Skip expression validation' + ], + useCases: [ + 'Validating workflows before running them in production', + 'Checking imported workflows for compatibility', + 'Debugging workflow execution failures', + 'Ensuring workflows follow best practices', + 'Pre-deployment validation in CI/CD pipelines' + ], + performance: 'Depends on workflow size and API latency. Typically 100-500ms for medium workflows.', + bestPractices: [ + 'Run validation before activating workflows in production', + 'Use "runtime" profile for pre-execution checks', + 'Use "strict" profile for code review and best practices', + 'Fix errors before warnings - errors will likely cause execution failures', + 'Pay attention to expression validation - syntax errors are common' + ], + pitfalls: [ + 'Requires valid API credentials - check n8n_health_check first', + 'Large workflows may take longer to validate', + 'Some warnings may be intentional (e.g., optional parameters)', + 'Profile affects validation time - strict is slower but more thorough', + 'Expression validation may flag working but non-standard syntax' + ], + relatedTools: ['validate_workflow', 'n8n_get_workflow', 'n8n_health_check', 'n8n_autofix_workflow'] + } +}; +//# sourceMappingURL=n8n-validate-workflow.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.js.map b/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.js.map new file mode 100644 index 0000000..06e6341 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-validate-workflow.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-validate-workflow.ts"],"names":[],"mappings":";;;AAEa,QAAA,sBAAsB,GAAsB;IACvD,IAAI,EAAE,uBAAuB;IAC7B,QAAQ,EAAE,qBAAqB;IAC/B,UAAU,EAAE;QACV,WAAW,EAAE,iHAAiH;QAC9H,aAAa,EAAE,CAAC,IAAI,CAAC;QACrB,OAAO,EAAE,0CAA0C;QACnD,WAAW,EAAE,gEAAgE;QAC7E,IAAI,EAAE;YACJ,2FAA2F;YAC3F,0EAA0E;YAC1E,sEAAsE;SACvE;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE;;;;;;;;;;6EAU4D;QACzE,UAAU,EAAE;YACV,EAAE,EAAE;gBACF,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,oDAAoD;aAClE;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,uNAAuN;aACrO;SACF;QACD,OAAO,EAAE,0GAA0G;QACnH,QAAQ,EAAE;YACR,2EAA2E;YAC3E,4FAA4F;YAC5F,8GAA8G;SAC/G;QACD,QAAQ,EAAE;YACR,wDAAwD;YACxD,+CAA+C;YAC/C,uCAAuC;YACvC,0CAA0C;YAC1C,8CAA8C;SAC/C;QACD,WAAW,EAAE,qFAAqF;QAClG,aAAa,EAAE;YACb,0DAA0D;YAC1D,gDAAgD;YAChD,yDAAyD;YACzD,0EAA0E;YAC1E,mEAAmE;SACpE;QACD,QAAQ,EAAE;YACR,+DAA+D;YAC/D,6CAA6C;YAC7C,8DAA8D;YAC9D,sEAAsE;YACtE,gEAAgE;SACjE;QACD,YAAY,EAAE,CAAC,mBAAmB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,sBAAsB,CAAC;KACpG;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.d.ts b/dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.d.ts new file mode 100644 index 0000000..8bfcb80 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.d.ts @@ -0,0 +1,3 @@ +import { ToolDocumentation } from '../types'; +export declare const n8nWorkflowVersionsDoc: ToolDocumentation; +//# sourceMappingURL=n8n-workflow-versions.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.d.ts.map b/dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.d.ts.map new file mode 100644 index 0000000..0c8c230 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-workflow-versions.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-workflow-versions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,sBAAsB,EAAE,iBAqKpC,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.js b/dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.js new file mode 100644 index 0000000..dddcab6 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.js @@ -0,0 +1,170 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nWorkflowVersionsDoc = void 0; +exports.n8nWorkflowVersionsDoc = { + name: 'n8n_workflow_versions', + category: 'workflow_management', + essentials: { + description: 'Manage workflow version history, rollback to previous versions, and cleanup old versions', + keyParameters: ['mode', 'workflowId', 'versionId'], + example: 'n8n_workflow_versions({mode: "list", workflowId: "abc123"})', + performance: 'Fast for list/get (~100ms), moderate for rollback (~200-500ms)', + tips: [ + 'Use mode="list" to see all saved versions before rollback', + 'Rollback creates a backup version automatically', + 'Use prune to clean up old versions and save storage', + 'truncate requires explicit confirmTruncate: true' + ] + }, + full: { + description: `Comprehensive workflow version management system. Supports six operations: + +**list** - Show version history for a workflow +- Returns all saved versions with timestamps, snapshot sizes, and metadata +- Use limit parameter to control how many versions to return + +**get** - Get details of a specific version +- Returns the complete workflow snapshot from that version +- Use to compare versions or extract old configurations + +**rollback** - Restore workflow to a previous version +- Creates a backup of the current workflow before rollback +- Optionally validates the workflow structure before applying +- Returns the restored workflow and backup version ID + +**delete** - Delete specific version(s) +- Delete a single version by versionId +- Delete all versions for a workflow with deleteAll: true + +**prune** - Clean up old versions +- Keeps only the N most recent versions (default: 10) +- Useful for managing storage and keeping history manageable + +**truncate** - Delete ALL versions for ALL workflows +- Dangerous operation requiring explicit confirmation +- Use for complete version history cleanup`, + parameters: { + mode: { + type: 'string', + required: true, + description: 'Operation mode: "list", "get", "rollback", "delete", "prune", or "truncate"', + enum: ['list', 'get', 'rollback', 'delete', 'prune', 'truncate'] + }, + workflowId: { + type: 'string', + required: false, + description: 'Workflow ID (required for list, rollback, delete, prune modes)' + }, + versionId: { + type: 'number', + required: false, + description: 'Version ID (required for get mode, optional for rollback to specific version, required for single delete)' + }, + limit: { + type: 'number', + required: false, + default: 10, + description: 'Maximum versions to return in list mode' + }, + validateBefore: { + type: 'boolean', + required: false, + default: true, + description: 'Validate workflow structure before rollback (rollback mode only)' + }, + deleteAll: { + type: 'boolean', + required: false, + default: false, + description: 'Delete all versions for workflow (delete mode only)' + }, + maxVersions: { + type: 'number', + required: false, + default: 10, + description: 'Keep N most recent versions (prune mode only)' + }, + confirmTruncate: { + type: 'boolean', + required: false, + default: false, + description: 'REQUIRED: Must be true to truncate all versions (truncate mode only)' + } + }, + returns: `Response varies by mode: + +**list mode:** +- versions: Array of version objects with id, workflowId, snapshotSize, createdAt +- totalCount: Total number of versions + +**get mode:** +- version: Complete version object including workflow snapshot + +**rollback mode:** +- success: Boolean indicating success +- restoredVersion: The version that was restored +- backupVersionId: ID of the backup created before rollback + +**delete mode:** +- deletedCount: Number of versions deleted + +**prune mode:** +- prunedCount: Number of old versions removed +- remainingCount: Number of versions kept + +**truncate mode:** +- deletedCount: Total versions deleted across all workflows`, + examples: [ + '// List version history\nn8n_workflow_versions({mode: "list", workflowId: "abc123", limit: 5})', + '// Get specific version details\nn8n_workflow_versions({mode: "get", versionId: 42})', + '// Rollback to latest saved version\nn8n_workflow_versions({mode: "rollback", workflowId: "abc123"})', + '// Rollback to specific version\nn8n_workflow_versions({mode: "rollback", workflowId: "abc123", versionId: 42})', + '// Delete specific version\nn8n_workflow_versions({mode: "delete", workflowId: "abc123", versionId: 42})', + '// Delete all versions for workflow\nn8n_workflow_versions({mode: "delete", workflowId: "abc123", deleteAll: true})', + '// Prune to keep only 5 most recent\nn8n_workflow_versions({mode: "prune", workflowId: "abc123", maxVersions: 5})', + '// Truncate all versions (dangerous!)\nn8n_workflow_versions({mode: "truncate", confirmTruncate: true})' + ], + useCases: [ + 'Recover from accidental workflow changes', + 'Compare workflow versions to understand changes', + 'Maintain audit trail of workflow modifications', + 'Clean up old versions to save database storage', + 'Roll back failed workflow deployments' + ], + performance: `Performance varies by operation: +- list: Fast (~100ms) - simple database query +- get: Fast (~100ms) - single row retrieval +- rollback: Moderate (~200-500ms) - includes backup creation and workflow update +- delete: Fast (~50-100ms) - database delete operation +- prune: Moderate (~100-300ms) - depends on number of versions to delete +- truncate: Slow (1-5s) - deletes all records across all workflows`, + modeComparison: `| Mode | Required Params | Optional Params | Risk Level | +|------|-----------------|-----------------|------------| +| list | workflowId | limit | Low | +| get | versionId | - | Low | +| rollback | workflowId | versionId, validateBefore | Medium | +| delete | workflowId | versionId, deleteAll | High | +| prune | workflowId | maxVersions | Medium | +| truncate | confirmTruncate=true | - | Critical |`, + bestPractices: [ + 'Always list versions before rollback to pick the right one', + 'Enable validateBefore for rollback to catch structural issues', + 'Use prune regularly to keep version history manageable', + 'Never use truncate in production without explicit need', + 'Document why you are rolling back for audit purposes' + ], + pitfalls: [ + 'Rollback overwrites current workflow - backup is created automatically', + 'Deleted versions cannot be recovered', + 'Truncate affects ALL workflows - use with extreme caution', + 'Version IDs are sequential but may have gaps after deletes', + 'Large workflows may have significant version storage overhead' + ], + relatedTools: [ + 'n8n_get_workflow - View current workflow state', + 'n8n_update_partial_workflow - Make incremental changes', + 'n8n_validate_workflow - Validate before deployment' + ] + } +}; +//# sourceMappingURL=n8n-workflow-versions.js.map \ No newline at end of file diff --git a/dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.js.map b/dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.js.map new file mode 100644 index 0000000..7b2c579 --- /dev/null +++ b/dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-workflow-versions.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-workflow-versions.ts"],"names":[],"mappings":";;;AAEa,QAAA,sBAAsB,GAAsB;IACvD,IAAI,EAAE,uBAAuB;IAC7B,QAAQ,EAAE,qBAAqB;IAC/B,UAAU,EAAE;QACV,WAAW,EAAE,0FAA0F;QACvG,aAAa,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,CAAC;QAClD,OAAO,EAAE,6DAA6D;QACtE,WAAW,EAAE,gEAAgE;QAC7E,IAAI,EAAE;YACJ,2DAA2D;YAC3D,iDAAiD;YACjD,qDAAqD;YACrD,kDAAkD;SACnD;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;2CAyB0B;QACvC,UAAU,EAAE;YACV,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,6EAA6E;gBAC1F,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC;aACjE;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,gEAAgE;aAC9E;YACD,SAAS,EAAE;gBACT,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,2GAA2G;aACzH;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,yCAAyC;aACvD;YACD,cAAc,EAAE;gBACd,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,KAAK;gBACf,OAAO,EAAE,IAAI;gBACb,WAAW,EAAE,kEAAkE;aAChF;YACD,SAAS,EAAE;gBACT,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,KAAK;gBACf,OAAO,EAAE,KAAK;gBACd,WAAW,EAAE,qDAAqD;aACnE;YACD,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,+CAA+C;aAC7D;YACD,eAAe,EAAE;gBACf,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,KAAK;gBACf,OAAO,EAAE,KAAK;gBACd,WAAW,EAAE,sEAAsE;aACpF;SACF;QACD,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;4DAsB+C;QACxD,QAAQ,EAAE;YACR,gGAAgG;YAChG,sFAAsF;YACtF,sGAAsG;YACtG,iHAAiH;YACjH,0GAA0G;YAC1G,qHAAqH;YACrH,mHAAmH;YACnH,yGAAyG;SAC1G;QACD,QAAQ,EAAE;YACR,0CAA0C;YAC1C,iDAAiD;YACjD,gDAAgD;YAChD,gDAAgD;YAChD,uCAAuC;SACxC;QACD,WAAW,EAAE;;;;;;mEAMkD;QAC/D,cAAc,EAAE;;;;;;;mDAO+B;QAC/C,aAAa,EAAE;YACb,4DAA4D;YAC5D,+DAA+D;YAC/D,wDAAwD;YACxD,wDAAwD;YACxD,sDAAsD;SACvD;QACD,QAAQ,EAAE;YACR,wEAAwE;YACxE,sCAAsC;YACtC,2DAA2D;YAC3D,4DAA4D;YAC5D,+DAA+D;SAChE;QACD,YAAY,EAAE;YACZ,gDAAgD;YAChD,wDAAwD;YACxD,oDAAoD;SACrD;KACF;CACF,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tools-documentation.d.ts b/dist/mcp/tools-documentation.d.ts new file mode 100644 index 0000000..2e2f2f0 --- /dev/null +++ b/dist/mcp/tools-documentation.d.ts @@ -0,0 +1,6 @@ +export declare function getToolDocumentation(toolName: string, depth?: 'essentials' | 'full'): string; +export declare function getToolsOverview(depth?: 'essentials' | 'full'): string; +export declare function searchToolDocumentation(keyword: string): string[]; +export declare function getToolsByCategory(category: string): string[]; +export declare function getAllCategories(): string[]; +//# sourceMappingURL=tools-documentation.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tools-documentation.d.ts.map b/dist/mcp/tools-documentation.d.ts.map new file mode 100644 index 0000000..a7685e0 --- /dev/null +++ b/dist/mcp/tools-documentation.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"tools-documentation.d.ts","sourceRoot":"","sources":["../../src/mcp/tools-documentation.ts"],"names":[],"mappings":"AAEA,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,GAAE,YAAY,GAAG,MAAqB,GAAG,MAAM,CA+D1G;AAED,wBAAgB,gBAAgB,CAAC,KAAK,GAAE,YAAY,GAAG,MAAqB,GAAG,MAAM,CAsHpF;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAWjE;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAI7D;AAED,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAM3C"} \ No newline at end of file diff --git a/dist/mcp/tools-documentation.js b/dist/mcp/tools-documentation.js new file mode 100644 index 0000000..702b1eb --- /dev/null +++ b/dist/mcp/tools-documentation.js @@ -0,0 +1,682 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getToolDocumentation = getToolDocumentation; +exports.getToolsOverview = getToolsOverview; +exports.searchToolDocumentation = searchToolDocumentation; +exports.getToolsByCategory = getToolsByCategory; +exports.getAllCategories = getAllCategories; +const tool_docs_1 = require("./tool-docs"); +function getToolDocumentation(toolName, depth = 'essentials') { + if (toolName === 'javascript_code_node_guide') { + return getJavaScriptCodeNodeGuide(depth); + } + if (toolName === 'python_code_node_guide') { + return getPythonCodeNodeGuide(depth); + } + const tool = tool_docs_1.toolsDocumentation[toolName]; + if (!tool) { + return `Tool '${toolName}' not found. Use tools_documentation() to see available tools.`; + } + if (depth === 'essentials') { + const { essentials } = tool; + return `# ${tool.name} + +${essentials.description} + +**Example**: ${essentials.example} + +**Key parameters**: ${essentials.keyParameters.join(', ')} + +**Performance**: ${essentials.performance} + +**Tips**: +${essentials.tips.map(tip => `- ${tip}`).join('\n')} + +For full documentation, use: tools_documentation({topic: "${toolName}", depth: "full"})`; + } + const { full } = tool; + return `# ${tool.name} + +${full.description} + +## Parameters +${Object.entries(full.parameters).map(([param, info]) => `- **${param}** (${info.type}${info.required ? ', required' : ''}): ${info.description}`).join('\n')} + +## Returns +${full.returns} + +## Examples +${full.examples.map(ex => `\`\`\`javascript\n${ex}\n\`\`\``).join('\n\n')} + +## Common Use Cases +${full.useCases.map(uc => `- ${uc}`).join('\n')} + +## Performance +${full.performance} + +## Best Practices +${full.bestPractices.map(bp => `- ${bp}`).join('\n')} + +## Common Pitfalls +${full.pitfalls.map(p => `- ${p}`).join('\n')} + +## Related Tools +${full.relatedTools.map(t => `- ${t}`).join('\n')}`; +} +function getToolsOverview(depth = 'essentials') { + const packageJson = require('../../package.json'); + const supportedN8nVersion = packageJson.dependencies?.n8n?.replace(/[^0-9.]/g, '') || 'latest'; + if (depth === 'essentials') { + return `# n8n MCP Tools Reference + +## Important: Compatibility Notice +⚠️ This MCP server is tested with n8n version ${supportedN8nVersion}. +Inform the user to check their n8n version matches or is compatible with the supported version listed above. + +## Code Node Configuration +When working with Code nodes, always start by calling the relevant guide: +- tools_documentation({topic: "javascript_code_node_guide"}) for JavaScript Code nodes +- tools_documentation({topic: "python_code_node_guide"}) for Python Code nodes + +## Standard Workflow Pattern + +⚠️ **CRITICAL**: Always call get_node() with detail='standard' FIRST before configuring any node! + +1. **Find** the node you need: + - search_nodes({query: "slack"}) - Search by keyword + - search_nodes({query: "communication"}) - Search by category name + - search_nodes({query: "AI langchain"}) - Search for AI-capable nodes + +2. **Configure** the node (ALWAYS START WITH STANDARD DETAIL): + - ✅ get_node({nodeType: "nodes-base.slack", detail: "standard"}) - Get essential properties FIRST (~1-2KB, shows required fields) + - get_node({nodeType: "nodes-base.slack", detail: "full"}) - Get complete schema only if standard insufficient (~100KB+) + - get_node({nodeType: "nodes-base.slack", mode: "docs"}) - Get readable markdown documentation + - get_node({nodeType: "nodes-base.slack", mode: "search_properties", propertyQuery: "auth"}) - Find specific properties + +3. **Validate** before deployment: + - validate_node({nodeType: "nodes-base.slack", config: {...}, mode: "minimal"}) - Quick required fields check + - validate_node({nodeType: "nodes-base.slack", config: {...}}) - Full validation with errors/warnings/suggestions + - validate_workflow({workflow: {...}}) - Validate entire workflow + +## Tool Categories (19 Tools Total) + +**Discovery Tools** (1 tool) +- search_nodes - Full-text search across all nodes (supports OR, AND, FUZZY modes) + +**Configuration Tools** (1 consolidated tool) +- get_node - Unified node information tool: + - detail='minimal'/'standard'/'full': Progressive detail levels + - mode='docs': Readable markdown documentation + - mode='search_properties': Find specific properties + - mode='versions'/'compare'/'breaking'/'migrations': Version management + +**Validation Tools** (2 tools) +- validate_node - Unified validation with mode='full' or mode='minimal' +- validate_workflow - Complete workflow validation (nodes, connections, expressions) + +**Template Tools** (2 tools) +- get_template - Get complete workflow JSON by ID +- search_templates - Unified template search: + - searchMode='keyword': Text search (default) + - searchMode='by_nodes': Find templates using specific nodes + - searchMode='by_task': Curated task-based templates + - searchMode='by_metadata': Filter by complexity/services + +**n8n API Tools** (13 tools, requires N8N_API_URL configuration) +- n8n_create_workflow - Create new workflows +- n8n_get_workflow - Get workflow with mode='full'/'details'/'structure'/'minimal' +- n8n_update_full_workflow - Full workflow replacement +- n8n_update_partial_workflow - Incremental diff-based updates +- n8n_delete_workflow - Delete workflow +- n8n_list_workflows - List workflows with filters +- n8n_validate_workflow - Validate workflow by ID +- n8n_autofix_workflow - Auto-fix common issues +- n8n_test_workflow - Test/trigger workflows (webhook, form, chat, execute) +- n8n_executions - Unified execution management (action='get'/'list'/'delete') +- n8n_health_check - Check n8n API connectivity +- n8n_workflow_versions - Version history and rollback +- n8n_deploy_template - Deploy templates directly to n8n instance + +## Performance Characteristics +- Instant (<10ms): search_nodes, get_node (minimal/standard) +- Fast (<100ms): validate_node, get_template +- Moderate (100-500ms): validate_workflow, get_node (full detail) +- Network-dependent: All n8n_* tools + +For comprehensive documentation on any tool: +tools_documentation({topic: "tool_name", depth: "full"})`; + } + const categories = getAllCategories(); + return `# n8n MCP Tools - Complete Reference + +## Important: Compatibility Notice +⚠️ This MCP server is tested with n8n version ${supportedN8nVersion}. +Run n8n_health_check() to verify your n8n instance compatibility and API connectivity. + +## Code Node Guides +For Code node configuration, use these comprehensive guides: +- tools_documentation({topic: "javascript_code_node_guide", depth: "full"}) - JavaScript patterns, n8n variables, error handling +- tools_documentation({topic: "python_code_node_guide", depth: "full"}) - Python patterns, data access, debugging + +## All Available Tools by Category + +${categories.map(cat => { + const tools = getToolsByCategory(cat); + const categoryName = cat.charAt(0).toUpperCase() + cat.slice(1).replace('_', ' '); + return `### ${categoryName} +${tools.map(toolName => { + const tool = tool_docs_1.toolsDocumentation[toolName]; + return `- **${toolName}**: ${tool.essentials.description}`; + }).join('\n')}`; + }).join('\n\n')} + +## Usage Notes +- All node types require the "nodes-base." or "nodes-langchain." prefix +- Use get_node() with detail='standard' first for most tasks (~95% smaller than detail='full') +- Validation profiles: minimal (editing), runtime (default), strict (deployment) +- n8n API tools only available when N8N_API_URL and N8N_API_KEY are configured + +For detailed documentation on any tool: +tools_documentation({topic: "tool_name", depth: "full"})`; +} +function searchToolDocumentation(keyword) { + const results = []; + for (const [toolName, tool] of Object.entries(tool_docs_1.toolsDocumentation)) { + const searchText = `${toolName} ${tool.essentials.description} ${tool.full.description}`.toLowerCase(); + if (searchText.includes(keyword.toLowerCase())) { + results.push(toolName); + } + } + return results; +} +function getToolsByCategory(category) { + return Object.entries(tool_docs_1.toolsDocumentation) + .filter(([_, tool]) => tool.category === category) + .map(([name, _]) => name); +} +function getAllCategories() { + const categories = new Set(); + Object.values(tool_docs_1.toolsDocumentation).forEach(tool => { + categories.add(tool.category); + }); + return Array.from(categories); +} +function getJavaScriptCodeNodeGuide(depth = 'essentials') { + if (depth === 'essentials') { + return `# JavaScript Code Node Guide + +Essential patterns for JavaScript in n8n Code nodes. + +**Key Concepts**: +- Access all items: \`$input.all()\` (not items[0]) +- Current item data: \`$json\` +- Return format: \`[{json: {...}}]\` (array of objects) + +**Available Helpers**: +- \`$helpers.httpRequest()\` - Make HTTP requests +- \`$jmespath()\` - Query JSON data +- \`DateTime\` - Luxon for date handling + +**Common Patterns**: +\`\`\`javascript +// Process all items +const allItems = $input.all(); +return allItems.map(item => ({ + json: { + processed: true, + original: item.json, + timestamp: DateTime.now().toISO() + } +})); +\`\`\` + +**Tips**: +- Webhook data is under \`.body\` property +- Use async/await for HTTP requests +- Always return array format + +For full guide: tools_documentation({topic: "javascript_code_node_guide", depth: "full"})`; + } + return `# JavaScript Code Node Complete Guide + +Comprehensive guide for using JavaScript in n8n Code nodes. + +## Data Access Patterns + +### Accessing Input Data +\`\`\`javascript +// Get all items from previous node +const allItems = $input.all(); + +// Get specific node's output +const webhookData = $node["Webhook"].json; + +// Current item in loop +const currentItem = $json; + +// First item only +const firstItem = $input.first().json; +\`\`\` + +### Webhook Data Structure +**CRITICAL**: Webhook data is nested under \`.body\`: +\`\`\`javascript +// WRONG - Won't work +const data = $json.name; + +// CORRECT - Webhook data is under body +const data = $json.body.name; +\`\`\` + +## Available Built-in Functions + +### HTTP Requests +\`\`\`javascript +// Make HTTP request +const response = await $helpers.httpRequest({ + method: 'GET', + url: 'https://api.example.com/data', + headers: { + 'Authorization': 'Bearer token' + } +}); +\`\`\` + +### Date/Time Handling +\`\`\`javascript +// Using Luxon DateTime +const now = DateTime.now(); +const formatted = now.toFormat('yyyy-MM-dd'); +const iso = now.toISO(); +const plus5Days = now.plus({ days: 5 }); +\`\`\` + +### JSON Querying +\`\`\`javascript +// JMESPath queries +const result = $jmespath($json, "users[?age > 30].name"); +\`\`\` + +## Return Format Requirements + +### Correct Format +\`\`\`javascript +// MUST return array of objects with json property +return [{ + json: { + result: "success", + data: processedData + } +}]; + +// Multiple items +return items.map(item => ({ + json: { + id: item.id, + processed: true + } +})); +\`\`\` + +### Binary Data +\`\`\`javascript +// Return with binary data +return [{ + json: { filename: "report.pdf" }, + binary: { + data: Buffer.from(pdfContent).toString('base64') + } +}]; +\`\`\` + +## Common Patterns + +### Processing Webhook Data +\`\`\`javascript +// Extract webhook payload +const webhookBody = $json.body; +const { username, email, items } = webhookBody; + +// Process and return +return [{ + json: { + username, + email, + itemCount: items.length, + processedAt: DateTime.now().toISO() + } +}]; +\`\`\` + +### Aggregating Data +\`\`\`javascript +// Sum values across all items +const allItems = $input.all(); +const total = allItems.reduce((sum, item) => { + return sum + (item.json.amount || 0); +}, 0); + +return [{ + json: { + total, + itemCount: allItems.length, + average: total / allItems.length + } +}]; +\`\`\` + +### Error Handling +\`\`\`javascript +try { + const response = await $helpers.httpRequest({ + url: 'https://api.example.com/data' + }); + + return [{ + json: { + success: true, + data: response + } + }]; +} catch (error) { + return [{ + json: { + success: false, + error: error.message + } + }]; +} +\`\`\` + +## Available Node.js Modules +- crypto (built-in) +- Buffer +- URL/URLSearchParams +- Basic Node.js globals + +## Common Pitfalls +1. Using \`items[0]\` instead of \`$input.all()\` +2. Forgetting webhook data is under \`.body\` +3. Returning plain objects instead of \`[{json: {...}}]\` +4. Using \`require()\` for external modules (not allowed) +5. Trying to use expression syntax \`{{}}\` inside code + +## Best Practices +1. Always validate input data exists before accessing +2. Use try-catch for HTTP requests +3. Return early on validation failures +4. Keep code simple and readable +5. Use descriptive variable names + +## Related Tools +- get_node({nodeType: "nodes-base.code"}) - Get Code node configuration details +- validate_node({nodeType: "nodes-base.code", config: {...}}) - Validate Code node setup +- python_code_node_guide (for Python syntax)`; +} +function getPythonCodeNodeGuide(depth = 'essentials') { + if (depth === 'essentials') { + return `# Python Code Node Guide + +Essential patterns for Python in n8n Code nodes. + +**Key Concepts**: +- Access all items: \`_input.all()\` (not items[0]) +- Current item data: \`_json\` +- Return format: \`[{"json": {...}}]\` (list of dicts) + +**Limitations**: +- No external libraries (no requests, pandas, numpy) +- Use built-in functions only +- No pip install available + +**Common Patterns**: +\`\`\`python +# Process all items +all_items = _input.all() +return [{ + "json": { + "processed": True, + "count": len(all_items), + "first_item": all_items[0]["json"] if all_items else None + } +}] +\`\`\` + +**Tips**: +- Webhook data is under ["body"] key +- Use json module for parsing +- datetime for date handling + +For full guide: tools_documentation({topic: "python_code_node_guide", depth: "full"})`; + } + return `# Python Code Node Complete Guide + +Comprehensive guide for using Python in n8n Code nodes. + +## Data Access Patterns + +### Accessing Input Data +\`\`\`python +# Get all items from previous node +all_items = _input.all() + +# Get specific node's output (use _node) +webhook_data = _node["Webhook"]["json"] + +# Current item in loop +current_item = _json + +# First item only +first_item = _input.first()["json"] +\`\`\` + +### Webhook Data Structure +**CRITICAL**: Webhook data is nested under ["body"]: +\`\`\`python +# WRONG - Won't work +data = _json["name"] + +# CORRECT - Webhook data is under body +data = _json["body"]["name"] +\`\`\` + +## Available Built-in Modules + +### Standard Library Only +\`\`\`python +import json +import datetime +import base64 +import hashlib +import urllib.parse +import re +import math +import random +\`\`\` + +### Date/Time Handling +\`\`\`python +from datetime import datetime, timedelta + +# Current time +now = datetime.now() +iso_format = now.isoformat() + +# Date arithmetic +future = now + timedelta(days=5) +formatted = now.strftime("%Y-%m-%d") +\`\`\` + +### JSON Operations +\`\`\`python +# Parse JSON string +data = json.loads(json_string) + +# Convert to JSON +json_output = json.dumps({"key": "value"}) +\`\`\` + +## Return Format Requirements + +### Correct Format +\`\`\`python +# MUST return list of dictionaries with "json" key +return [{ + "json": { + "result": "success", + "data": processed_data + } +}] + +# Multiple items +return [ + {"json": {"id": item["json"]["id"], "processed": True}} + for item in all_items +] +\`\`\` + +### Binary Data +\`\`\`python +# Return with binary data +import base64 + +return [{ + "json": {"filename": "report.pdf"}, + "binary": { + "data": base64.b64encode(pdf_content).decode() + } +}] +\`\`\` + +## Common Patterns + +### Processing Webhook Data +\`\`\`python +# Extract webhook payload +webhook_body = _json["body"] +username = webhook_body.get("username") +email = webhook_body.get("email") +items = webhook_body.get("items", []) + +# Process and return +return [{ + "json": { + "username": username, + "email": email, + "item_count": len(items), + "processed_at": datetime.now().isoformat() + } +}] +\`\`\` + +### Aggregating Data +\`\`\`python +# Sum values across all items +all_items = _input.all() +total = sum(item["json"].get("amount", 0) for item in all_items) + +return [{ + "json": { + "total": total, + "item_count": len(all_items), + "average": total / len(all_items) if all_items else 0 + } +}] +\`\`\` + +### Error Handling +\`\`\`python +try: + # Process data + webhook_data = _json["body"] + result = process_data(webhook_data) + + return [{ + "json": { + "success": True, + "data": result + } + }] +except Exception as e: + return [{ + "json": { + "success": False, + "error": str(e) + } + }] +\`\`\` + +### Data Transformation +\`\`\`python +# Transform all items +all_items = _input.all() +transformed = [] + +for item in all_items: + data = item["json"] + transformed.append({ + "json": { + "id": data.get("id"), + "name": data.get("name", "").upper(), + "timestamp": datetime.now().isoformat(), + "valid": bool(data.get("email")) + } + }) + +return transformed +\`\`\` + +## Limitations & Workarounds + +### No External Libraries +\`\`\`python +# CANNOT USE: +# import requests # Not available +# import pandas # Not available +# import numpy # Not available + +# WORKAROUND: Use JavaScript Code node for HTTP requests +# Or use HTTP Request node before Code node +\`\`\` + +### HTTP Requests Alternative +Since Python requests library is not available, use: +1. JavaScript Code node with $helpers.httpRequest() +2. HTTP Request node before your Python Code node +3. Webhook node to receive data + +## Common Pitfalls +1. Trying to import external libraries (requests, pandas) +2. Using items[0] instead of _input.all() +3. Forgetting webhook data is under ["body"] +4. Returning dictionaries instead of [{"json": {...}}] +5. Not handling missing keys with .get() + +## Best Practices +1. Always use .get() for dictionary access +2. Validate data before processing +3. Handle empty input arrays +4. Use list comprehensions for transformations +5. Return meaningful error messages + +## Type Conversions +\`\`\`python +# String to number +value = float(_json.get("amount", "0")) + +# Boolean conversion +is_active = str(_json.get("active", "")).lower() == "true" + +# Safe JSON parsing +try: + data = json.loads(_json.get("json_string", "{}")) +except json.JSONDecodeError: + data = {} +\`\`\` + +## Related Tools +- get_node({nodeType: "nodes-base.code"}) - Get Code node configuration details +- validate_node({nodeType: "nodes-base.code", config: {...}}) - Validate Code node setup +- javascript_code_node_guide (for JavaScript syntax)`; +} +//# sourceMappingURL=tools-documentation.js.map \ No newline at end of file diff --git a/dist/mcp/tools-documentation.js.map b/dist/mcp/tools-documentation.js.map new file mode 100644 index 0000000..1628133 --- /dev/null +++ b/dist/mcp/tools-documentation.js.map @@ -0,0 +1 @@ +{"version":3,"file":"tools-documentation.js","sourceRoot":"","sources":["../../src/mcp/tools-documentation.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/mcp/tools-n8n-friendly.d.ts b/dist/mcp/tools-n8n-friendly.d.ts new file mode 100644 index 0000000..7e9d7f3 --- /dev/null +++ b/dist/mcp/tools-n8n-friendly.d.ts @@ -0,0 +1,6 @@ +export declare const n8nFriendlyDescriptions: Record; +}>; +export declare function makeToolsN8nFriendly(tools: any[]): any[]; +//# sourceMappingURL=tools-n8n-friendly.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tools-n8n-friendly.d.ts.map b/dist/mcp/tools-n8n-friendly.d.ts.map new file mode 100644 index 0000000..ddae62f --- /dev/null +++ b/dist/mcp/tools-n8n-friendly.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"tools-n8n-friendly.d.ts","sourceRoot":"","sources":["../../src/mcp/tools-n8n-friendly.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC,CAqEA,CAAC;AAMF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,CAiCxD"} \ No newline at end of file diff --git a/dist/mcp/tools-n8n-friendly.js b/dist/mcp/tools-n8n-friendly.js new file mode 100644 index 0000000..57f4cf6 --- /dev/null +++ b/dist/mcp/tools-n8n-friendly.js @@ -0,0 +1,89 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nFriendlyDescriptions = void 0; +exports.makeToolsN8nFriendly = makeToolsN8nFriendly; +exports.n8nFriendlyDescriptions = { + validate_node: { + description: 'Validate n8n node config. Pass nodeType (string) and config (object). Use mode="full" for comprehensive validation, mode="minimal" for quick check. Example: {"nodeType": "nodes-base.slack", "config": {"resource": "channel", "operation": "create"}}', + params: { + nodeType: 'String value like "nodes-base.slack"', + config: 'Object value like {"resource": "channel", "operation": "create"} or empty object {}', + mode: 'Optional string: "full" (default) or "minimal"', + profile: 'Optional string: "minimal" or "runtime" or "ai-friendly" or "strict"' + } + }, + search_nodes: { + description: 'Search nodes. Pass query (string). Example: {"query": "webhook"}', + params: { + query: 'String keyword like "webhook" or "database"', + limit: 'Optional number, default 20' + } + }, + get_node: { + description: 'Get node info with multiple modes. Pass nodeType (string). Use mode="info" for config, mode="docs" for documentation, mode="search_properties" with propertyQuery for finding fields. Example: {"nodeType": "nodes-base.httpRequest", "detail": "standard"}', + params: { + nodeType: 'String with prefix like "nodes-base.httpRequest"', + mode: 'Optional string: "info" (default), "docs", "search_properties", "versions", "compare", "breaking", "migrations"', + detail: 'Optional string: "minimal", "standard" (default), "full"', + propertyQuery: 'For mode="search_properties": search term like "auth"' + } + }, + validate_workflow: { + description: 'Validate workflow structure, connections, and expressions. Pass workflow object. MUST have: {"workflow": {"nodes": [array of node objects], "connections": {object with node connections}}}. Each node needs: name, type, typeVersion, position.', + params: { + workflow: 'Object with two required fields: nodes (array) and connections (object). Example: {"nodes": [{"name": "Webhook", "type": "n8n-nodes-base.webhook", "typeVersion": 2, "position": [250, 300], "parameters": {}}], "connections": {}}', + options: 'Optional object. Example: {"validateNodes": true, "validateConnections": true, "validateExpressions": true, "profile": "runtime"}' + } + }, + search_templates: { + description: 'Search workflow templates with multiple modes. Use searchMode="keyword" for text search, searchMode="by_nodes" to find by node types, searchMode="by_task" for task-based templates, searchMode="by_metadata" for filtering. Example: {"query": "chatbot"} or {"searchMode": "by_task", "task": "webhook_processing"}', + params: { + query: 'For searchMode="keyword": string keyword like "chatbot"', + searchMode: 'Optional: "keyword" (default), "by_nodes", "by_task", "by_metadata"', + nodeTypes: 'For searchMode="by_nodes": array like ["n8n-nodes-base.httpRequest"]', + task: 'For searchMode="by_task": task like "webhook_processing", "ai_automation"', + limit: 'Optional number, default 20' + } + }, + get_template: { + description: 'Get template by ID. Pass templateId (number). Example: {"templateId": 1234}', + params: { + templateId: 'Number ID like 1234', + mode: 'Optional: "full" (default), "nodes_only", "structure"' + } + }, + tools_documentation: { + description: 'Get tool docs. Pass optional depth (string). Example: {"depth": "essentials"} or {}', + params: { + depth: 'Optional string: "essentials" (default) or "full"', + topic: 'Optional string tool name like "search_nodes"' + } + } +}; +function makeToolsN8nFriendly(tools) { + return tools.map(tool => { + const toolName = tool.name; + const friendlyDesc = exports.n8nFriendlyDescriptions[toolName]; + if (friendlyDesc) { + const updatedTool = { ...tool }; + updatedTool.description = friendlyDesc.description; + if (tool.inputSchema?.properties) { + updatedTool.inputSchema = { + ...tool.inputSchema, + properties: { ...tool.inputSchema.properties } + }; + Object.keys(updatedTool.inputSchema.properties).forEach(param => { + if (friendlyDesc.params[param]) { + updatedTool.inputSchema.properties[param] = { + ...updatedTool.inputSchema.properties[param], + description: friendlyDesc.params[param] + }; + } + }); + } + return updatedTool; + } + return tool; + }); +} +//# sourceMappingURL=tools-n8n-friendly.js.map \ No newline at end of file diff --git a/dist/mcp/tools-n8n-friendly.js.map b/dist/mcp/tools-n8n-friendly.js.map new file mode 100644 index 0000000..f263c28 --- /dev/null +++ b/dist/mcp/tools-n8n-friendly.js.map @@ -0,0 +1 @@ +{"version":3,"file":"tools-n8n-friendly.js","sourceRoot":"","sources":["../../src/mcp/tools-n8n-friendly.ts"],"names":[],"mappings":";;;AAyFA,oDAiCC;AA/GY,QAAA,uBAAuB,GAG/B;IAEH,aAAa,EAAE;QACb,WAAW,EAAE,yPAAyP;QACtQ,MAAM,EAAE;YACN,QAAQ,EAAE,sCAAsC;YAChD,MAAM,EAAE,qFAAqF;YAC7F,IAAI,EAAE,gDAAgD;YACtD,OAAO,EAAE,sEAAsE;SAChF;KACF;IAGD,YAAY,EAAE;QACZ,WAAW,EAAE,kEAAkE;QAC/E,MAAM,EAAE;YACN,KAAK,EAAE,6CAA6C;YACpD,KAAK,EAAE,6BAA6B;SACrC;KACF;IAGD,QAAQ,EAAE;QACR,WAAW,EAAE,6PAA6P;QAC1Q,MAAM,EAAE;YACN,QAAQ,EAAE,kDAAkD;YAC5D,IAAI,EAAE,iHAAiH;YACvH,MAAM,EAAE,0DAA0D;YAClE,aAAa,EAAE,uDAAuD;SACvE;KACF;IAGD,iBAAiB,EAAE;QACjB,WAAW,EAAE,kPAAkP;QAC/P,MAAM,EAAE;YACN,QAAQ,EAAE,qOAAqO;YAC/O,OAAO,EAAE,mIAAmI;SAC7I;KACF;IAGD,gBAAgB,EAAE;QAChB,WAAW,EAAE,uTAAuT;QACpU,MAAM,EAAE;YACN,KAAK,EAAE,yDAAyD;YAChE,UAAU,EAAE,qEAAqE;YACjF,SAAS,EAAE,sEAAsE;YACjF,IAAI,EAAE,2EAA2E;YACjF,KAAK,EAAE,6BAA6B;SACrC;KACF;IAED,YAAY,EAAE;QACZ,WAAW,EAAE,6EAA6E;QAC1F,MAAM,EAAE;YACN,UAAU,EAAE,qBAAqB;YACjC,IAAI,EAAE,uDAAuD;SAC9D;KACF;IAGD,mBAAmB,EAAE;QACnB,WAAW,EAAE,qFAAqF;QAClG,MAAM,EAAE;YACN,KAAK,EAAE,mDAAmD;YAC1D,KAAK,EAAE,+CAA+C;SACvD;KACF;CACF,CAAC;AAMF,SAAgB,oBAAoB,CAAC,KAAY;IAC/C,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAc,CAAC;QACrC,MAAM,YAAY,GAAG,+BAAuB,CAAC,QAAQ,CAAC,CAAC;QACvD,IAAI,YAAY,EAAE,CAAC;YAEjB,MAAM,WAAW,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;YAGhC,WAAW,CAAC,WAAW,GAAG,YAAY,CAAC,WAAW,CAAC;YAGnD,IAAI,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,CAAC;gBACjC,WAAW,CAAC,WAAW,GAAG;oBACxB,GAAG,IAAI,CAAC,WAAW;oBACnB,UAAU,EAAE,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE;iBAC/C,CAAC;gBAGF,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;oBAC9D,IAAI,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;wBAC/B,WAAW,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG;4BAC1C,GAAG,WAAW,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC;4BAC5C,WAAW,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC;yBACxC,CAAC;oBACJ,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;YAED,OAAO,WAAW,CAAC;QACrB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tools-n8n-manager.d.ts b/dist/mcp/tools-n8n-manager.d.ts new file mode 100644 index 0000000..ae0de53 --- /dev/null +++ b/dist/mcp/tools-n8n-manager.d.ts @@ -0,0 +1,3 @@ +import { ToolDefinition } from '../types'; +export declare const n8nManagementTools: ToolDefinition[]; +//# sourceMappingURL=tools-n8n-manager.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tools-n8n-manager.d.ts.map b/dist/mcp/tools-n8n-manager.d.ts.map new file mode 100644 index 0000000..fe6bddb --- /dev/null +++ b/dist/mcp/tools-n8n-manager.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"tools-n8n-manager.d.ts","sourceRoot":"","sources":["../../src/mcp/tools-n8n-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAQ1C,eAAO,MAAM,kBAAkB,EAAE,cAAc,EAmf9C,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tools-n8n-manager.js b/dist/mcp/tools-n8n-manager.js new file mode 100644 index 0000000..32373a9 --- /dev/null +++ b/dist/mcp/tools-n8n-manager.js @@ -0,0 +1,491 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nManagementTools = void 0; +exports.n8nManagementTools = [ + { + name: 'n8n_create_workflow', + description: `Create workflow. Requires: name, nodes[], connections{}. Created inactive. Returns workflow with ID.`, + inputSchema: { + type: 'object', + properties: { + name: { + type: 'string', + description: 'Workflow name (required)' + }, + nodes: { + type: 'array', + description: 'Array of workflow nodes. Each node must have: id, name, type, typeVersion, position, and parameters', + items: { + type: 'object', + required: ['id', 'name', 'type', 'typeVersion', 'position', 'parameters'], + properties: { + id: { type: 'string' }, + name: { type: 'string' }, + type: { type: 'string' }, + typeVersion: { type: 'number' }, + position: { + type: 'array', + items: { type: 'number' }, + minItems: 2, + maxItems: 2 + }, + parameters: { type: 'object' }, + credentials: { type: 'object' }, + disabled: { type: 'boolean' }, + notes: { type: 'string' }, + continueOnFail: { type: 'boolean' }, + retryOnFail: { type: 'boolean' }, + maxTries: { type: 'number' }, + waitBetweenTries: { type: 'number' } + } + } + }, + connections: { + type: 'object', + description: 'Workflow connections object. Keys are source node IDs, values define output connections' + }, + settings: { + type: 'object', + description: 'Optional workflow settings (execution order, timezone, error handling)', + properties: { + executionOrder: { type: 'string', enum: ['v0', 'v1'] }, + timezone: { type: 'string' }, + saveDataErrorExecution: { type: 'string', enum: ['all', 'none'] }, + saveDataSuccessExecution: { type: 'string', enum: ['all', 'none'] }, + saveManualExecutions: { type: 'boolean' }, + saveExecutionProgress: { type: 'boolean' }, + executionTimeout: { type: 'number' }, + errorWorkflow: { type: 'string' } + } + } + }, + required: ['name', 'nodes', 'connections'] + } + }, + { + name: 'n8n_get_workflow', + description: `Get workflow by ID with different detail levels. Use mode='full' for complete workflow, 'details' for metadata+stats, 'structure' for nodes/connections only, 'minimal' for id/name/active/tags.`, + inputSchema: { + type: 'object', + properties: { + id: { + type: 'string', + description: 'Workflow ID' + }, + mode: { + type: 'string', + enum: ['full', 'details', 'structure', 'minimal'], + default: 'full', + description: 'Detail level: full=complete workflow, details=full+execution stats, structure=nodes/connections topology, minimal=metadata only' + } + }, + required: ['id'] + } + }, + { + name: 'n8n_update_full_workflow', + description: `Full workflow update. Requires complete nodes[] and connections{}. For incremental use n8n_update_partial_workflow.`, + inputSchema: { + type: 'object', + properties: { + id: { + type: 'string', + description: 'Workflow ID to update' + }, + name: { + type: 'string', + description: 'New workflow name' + }, + nodes: { + type: 'array', + description: 'Complete array of workflow nodes (required if modifying workflow structure)', + items: { + type: 'object', + additionalProperties: true + } + }, + connections: { + type: 'object', + description: 'Complete connections object (required if modifying workflow structure)' + }, + settings: { + type: 'object', + description: 'Workflow settings to update' + } + }, + required: ['id'] + } + }, + { + name: 'n8n_update_partial_workflow', + description: `Update workflow incrementally with diff operations. Types: addNode, removeNode, updateNode, moveNode, enable/disableNode, addConnection, removeConnection, updateSettings, updateName, add/removeTag. See tools_documentation("n8n_update_partial_workflow", "full") for details.`, + inputSchema: { + type: 'object', + additionalProperties: true, + properties: { + id: { + type: 'string', + description: 'Workflow ID to update' + }, + operations: { + type: 'array', + description: 'Array of diff operations to apply. Each operation must have a "type" field and relevant properties for that operation type.', + items: { + type: 'object', + additionalProperties: true + } + }, + validateOnly: { + type: 'boolean', + description: 'If true, only validate operations without applying them' + }, + continueOnError: { + type: 'boolean', + description: 'If true, apply valid operations even if some fail (best-effort mode). Returns applied and failed operation indices. Default: false (atomic)' + } + }, + required: ['id', 'operations'] + } + }, + { + name: 'n8n_delete_workflow', + description: `Permanently delete a workflow. This action cannot be undone.`, + inputSchema: { + type: 'object', + properties: { + id: { + type: 'string', + description: 'Workflow ID to delete' + } + }, + required: ['id'] + } + }, + { + name: 'n8n_list_workflows', + description: `List workflows (minimal metadata only). Returns id/name/active/dates/tags. Check hasMore/nextCursor for pagination.`, + inputSchema: { + type: 'object', + properties: { + limit: { + type: 'number', + description: 'Number of workflows to return (1-100, default: 100)' + }, + cursor: { + type: 'string', + description: 'Pagination cursor from previous response' + }, + active: { + type: 'boolean', + description: 'Filter by active status' + }, + tags: { + type: 'array', + items: { type: 'string' }, + description: 'Filter by tags (exact match)' + }, + projectId: { + type: 'string', + description: 'Filter by project ID (enterprise feature)' + }, + excludePinnedData: { + type: 'boolean', + description: 'Exclude pinned data from response (default: true)' + } + } + } + }, + { + name: 'n8n_validate_workflow', + description: `Validate workflow by ID. Checks nodes, connections, expressions. Returns errors/warnings/suggestions.`, + inputSchema: { + type: 'object', + properties: { + id: { + type: 'string', + description: 'Workflow ID to validate' + }, + options: { + type: 'object', + description: 'Validation options', + properties: { + validateNodes: { + type: 'boolean', + description: 'Validate node configurations (default: true)' + }, + validateConnections: { + type: 'boolean', + description: 'Validate workflow connections (default: true)' + }, + validateExpressions: { + type: 'boolean', + description: 'Validate n8n expressions (default: true)' + }, + profile: { + type: 'string', + enum: ['minimal', 'runtime', 'ai-friendly', 'strict'], + description: 'Validation profile to use (default: runtime)' + } + } + } + }, + required: ['id'] + } + }, + { + name: 'n8n_autofix_workflow', + description: `Automatically fix common workflow validation errors. Preview fixes or apply them. Fixes expression format, typeVersion, error output config, webhook paths.`, + inputSchema: { + type: 'object', + properties: { + id: { + type: 'string', + description: 'Workflow ID to fix' + }, + applyFixes: { + type: 'boolean', + description: 'Apply fixes to workflow (default: false - preview mode)' + }, + fixTypes: { + type: 'array', + description: 'Types of fixes to apply (default: all)', + items: { + type: 'string', + enum: ['expression-format', 'typeversion-correction', 'error-output-config', 'node-type-correction', 'webhook-missing-path', 'typeversion-upgrade', 'version-migration'] + } + }, + confidenceThreshold: { + type: 'string', + enum: ['high', 'medium', 'low'], + description: 'Minimum confidence level for fixes (default: medium)' + }, + maxFixes: { + type: 'number', + description: 'Maximum number of fixes to apply (default: 50)' + } + }, + required: ['id'] + } + }, + { + name: 'n8n_test_workflow', + description: `Test/trigger workflow execution. Auto-detects trigger type (webhook/form/chat). Supports: webhook (HTTP), form (fields), chat (message). Note: Only workflows with these trigger types can be executed externally.`, + inputSchema: { + type: 'object', + properties: { + workflowId: { + type: 'string', + description: 'Workflow ID to execute (required)' + }, + triggerType: { + type: 'string', + enum: ['webhook', 'form', 'chat'], + description: 'Trigger type. Auto-detected if not specified. Workflow must have a matching trigger node.' + }, + httpMethod: { + type: 'string', + enum: ['GET', 'POST', 'PUT', 'DELETE'], + description: 'For webhook: HTTP method (default: from workflow config or POST)' + }, + webhookPath: { + type: 'string', + description: 'For webhook: override the webhook path' + }, + message: { + type: 'string', + description: 'For chat: message to send (required for chat triggers)' + }, + sessionId: { + type: 'string', + description: 'For chat: session ID for conversation continuity' + }, + data: { + type: 'object', + description: 'Input data/payload for webhook, form fields, or execution data' + }, + headers: { + type: 'object', + description: 'Custom HTTP headers' + }, + timeout: { + type: 'number', + description: 'Timeout in ms (default: 120000)' + }, + waitForResponse: { + type: 'boolean', + description: 'Wait for workflow completion (default: true)' + } + }, + required: ['workflowId'] + } + }, + { + name: 'n8n_executions', + description: `Manage workflow executions: get details, list, or delete. Use action='get' with id for execution details, action='list' for listing executions, action='delete' to remove execution record.`, + inputSchema: { + type: 'object', + properties: { + action: { + type: 'string', + enum: ['get', 'list', 'delete'], + description: 'Operation: get=get execution details, list=list executions, delete=delete execution' + }, + id: { + type: 'string', + description: 'Execution ID (required for action=get or action=delete)' + }, + mode: { + type: 'string', + enum: ['preview', 'summary', 'filtered', 'full'], + description: 'For action=get: preview=structure only, summary=2 items (default), filtered=custom, full=all data' + }, + nodeNames: { + type: 'array', + items: { type: 'string' }, + description: 'For action=get with mode=filtered: filter to specific nodes by name' + }, + itemsLimit: { + type: 'number', + description: 'For action=get with mode=filtered: items per node (0=structure, 2=default, -1=unlimited)' + }, + includeInputData: { + type: 'boolean', + description: 'For action=get: include input data in addition to output (default: false)' + }, + limit: { + type: 'number', + description: 'For action=list: number of executions to return (1-100, default: 100)' + }, + cursor: { + type: 'string', + description: 'For action=list: pagination cursor from previous response' + }, + workflowId: { + type: 'string', + description: 'For action=list: filter by workflow ID' + }, + projectId: { + type: 'string', + description: 'For action=list: filter by project ID (enterprise feature)' + }, + status: { + type: 'string', + enum: ['success', 'error', 'waiting'], + description: 'For action=list: filter by execution status' + }, + includeData: { + type: 'boolean', + description: 'For action=list: include execution data (default: false)' + } + }, + required: ['action'] + } + }, + { + name: 'n8n_health_check', + description: `Check n8n instance health and API connectivity. Use mode='diagnostic' for detailed troubleshooting with env vars and tool status.`, + inputSchema: { + type: 'object', + properties: { + mode: { + type: 'string', + enum: ['status', 'diagnostic'], + description: 'Mode: "status" (default) for quick health check, "diagnostic" for detailed debug info including env vars and tool status', + default: 'status' + }, + verbose: { + type: 'boolean', + description: 'Include extra details in diagnostic mode (default: false)' + } + } + } + }, + { + name: 'n8n_workflow_versions', + description: `Manage workflow version history, rollback, and cleanup. Six modes: +- list: Show version history for a workflow +- get: Get details of specific version +- rollback: Restore workflow to previous version (creates backup first) +- delete: Delete specific version or all versions for a workflow +- prune: Manually trigger pruning to keep N most recent versions +- truncate: Delete ALL versions for ALL workflows (requires confirmation)`, + inputSchema: { + type: 'object', + properties: { + mode: { + type: 'string', + enum: ['list', 'get', 'rollback', 'delete', 'prune', 'truncate'], + description: 'Operation mode' + }, + workflowId: { + type: 'string', + description: 'Workflow ID (required for list, rollback, delete, prune)' + }, + versionId: { + type: 'number', + description: 'Version ID (required for get mode and single version delete, optional for rollback)' + }, + limit: { + type: 'number', + default: 10, + description: 'Max versions to return in list mode' + }, + validateBefore: { + type: 'boolean', + default: true, + description: 'Validate workflow structure before rollback' + }, + deleteAll: { + type: 'boolean', + default: false, + description: 'Delete all versions for workflow (delete mode only)' + }, + maxVersions: { + type: 'number', + default: 10, + description: 'Keep N most recent versions (prune mode only)' + }, + confirmTruncate: { + type: 'boolean', + default: false, + description: 'REQUIRED: Must be true to truncate all versions (truncate mode only)' + } + }, + required: ['mode'] + } + }, + { + name: 'n8n_deploy_template', + description: `Deploy a workflow template from n8n.io directly to your n8n instance. Deploys first, then auto-fixes common issues (expression format, typeVersions). Returns workflow ID, required credentials, and fixes applied.`, + inputSchema: { + type: 'object', + properties: { + templateId: { + type: 'number', + description: 'Template ID from n8n.io (required)' + }, + name: { + type: 'string', + description: 'Custom workflow name (default: template name)' + }, + autoUpgradeVersions: { + type: 'boolean', + default: true, + description: 'Automatically upgrade node typeVersions to latest supported (default: true)' + }, + autoFix: { + type: 'boolean', + default: true, + description: 'Auto-apply fixes after deployment for expression format issues, missing = prefix, etc. (default: true)' + }, + stripCredentials: { + type: 'boolean', + default: true, + description: 'Remove credential references from nodes - user configures in n8n UI (default: true)' + } + }, + required: ['templateId'] + } + } +]; +//# sourceMappingURL=tools-n8n-manager.js.map \ No newline at end of file diff --git a/dist/mcp/tools-n8n-manager.js.map b/dist/mcp/tools-n8n-manager.js.map new file mode 100644 index 0000000..1bb08df --- /dev/null +++ b/dist/mcp/tools-n8n-manager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"tools-n8n-manager.js","sourceRoot":"","sources":["../../src/mcp/tools-n8n-manager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/mcp/tools.d.ts b/dist/mcp/tools.d.ts new file mode 100644 index 0000000..23c4a0a --- /dev/null +++ b/dist/mcp/tools.d.ts @@ -0,0 +1,3 @@ +import { ToolDefinition } from '../types'; +export declare const n8nDocumentationToolsFinal: ToolDefinition[]; +//# sourceMappingURL=tools.d.ts.map \ No newline at end of file diff --git a/dist/mcp/tools.d.ts.map b/dist/mcp/tools.d.ts.map new file mode 100644 index 0000000..eee8379 --- /dev/null +++ b/dist/mcp/tools.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAQ1C,eAAO,MAAM,0BAA0B,EAAE,cAAc,EA+XtD,CAAC"} \ No newline at end of file diff --git a/dist/mcp/tools.js b/dist/mcp/tools.js new file mode 100644 index 0000000..4bbe214 --- /dev/null +++ b/dist/mcp/tools.js @@ -0,0 +1,383 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.n8nDocumentationToolsFinal = void 0; +exports.n8nDocumentationToolsFinal = [ + { + name: 'tools_documentation', + description: `Get documentation for n8n MCP tools. Call without parameters for quick start guide. Use topic parameter to get documentation for specific tools. Use depth='full' for comprehensive documentation.`, + inputSchema: { + type: 'object', + properties: { + topic: { + type: 'string', + description: 'Tool name (e.g., "search_nodes") or "overview" for general guide. Leave empty for quick reference.', + }, + depth: { + type: 'string', + enum: ['essentials', 'full'], + description: 'Level of detail. "essentials" (default) for quick reference, "full" for comprehensive docs.', + default: 'essentials', + }, + }, + }, + }, + { + name: 'search_nodes', + description: `Search n8n nodes by keyword with optional real-world examples. Pass query as string. Example: query="webhook" or query="database". Returns max 20 results. Use includeExamples=true to get top 2 template configs per node.`, + inputSchema: { + type: 'object', + properties: { + query: { + type: 'string', + description: 'Search terms. Use quotes for exact phrase.', + }, + limit: { + type: 'number', + description: 'Max results (default 20)', + default: 20, + }, + mode: { + type: 'string', + enum: ['OR', 'AND', 'FUZZY'], + description: 'OR=any word, AND=all words, FUZZY=typo-tolerant', + default: 'OR', + }, + includeExamples: { + type: 'boolean', + description: 'Include top 2 real-world configuration examples from popular templates (default: false)', + default: false, + }, + }, + required: ['query'], + }, + }, + { + name: 'get_node', + description: `Get node info with progressive detail levels and multiple modes. Detail: minimal (~200 tokens), standard (~1-2K, default), full (~3-8K). Modes: info (default), docs (markdown documentation), search_properties (find properties), versions/compare/breaking/migrations (version info). Use format='docs' for readable documentation, mode='search_properties' with propertyQuery for finding specific fields.`, + inputSchema: { + type: 'object', + properties: { + nodeType: { + type: 'string', + description: 'Full node type: "nodes-base.httpRequest" or "nodes-langchain.agent"', + }, + detail: { + type: 'string', + enum: ['minimal', 'standard', 'full'], + default: 'standard', + description: 'Information detail level. standard=essential properties (recommended), full=everything', + }, + mode: { + type: 'string', + enum: ['info', 'docs', 'search_properties', 'versions', 'compare', 'breaking', 'migrations'], + default: 'info', + description: 'Operation mode. info=node schema, docs=readable markdown documentation, search_properties=find specific properties, versions/compare/breaking/migrations=version info', + }, + includeTypeInfo: { + type: 'boolean', + default: false, + description: 'Include type structure metadata (type category, JS type, validation rules). Only applies to mode=info. Adds ~80-120 tokens per property.', + }, + includeExamples: { + type: 'boolean', + default: false, + description: 'Include real-world configuration examples from templates. Only applies to mode=info with detail=standard. Adds ~200-400 tokens per example.', + }, + fromVersion: { + type: 'string', + description: 'Source version for compare/breaking/migrations modes (e.g., "1.0")', + }, + toVersion: { + type: 'string', + description: 'Target version for compare mode (e.g., "2.0"). Defaults to latest if omitted.', + }, + propertyQuery: { + type: 'string', + description: 'For mode=search_properties: search term to find properties (e.g., "auth", "header", "body")', + }, + maxPropertyResults: { + type: 'number', + description: 'For mode=search_properties: max results (default 20)', + default: 20, + }, + }, + required: ['nodeType'], + }, + }, + { + name: 'validate_node', + description: `Validate n8n node configuration. Use mode='full' for comprehensive validation with errors/warnings/suggestions, mode='minimal' for quick required fields check. Example: nodeType="nodes-base.slack", config={resource:"channel",operation:"create"}`, + inputSchema: { + type: 'object', + properties: { + nodeType: { + type: 'string', + description: 'Node type as string. Example: "nodes-base.slack"', + }, + config: { + type: 'object', + description: 'Configuration as object. For simple nodes use {}. For complex nodes include fields like {resource:"channel",operation:"create"}', + }, + mode: { + type: 'string', + enum: ['full', 'minimal'], + description: 'Validation mode. full=comprehensive validation with errors/warnings/suggestions, minimal=quick required fields check only. Default is "full"', + default: 'full', + }, + profile: { + type: 'string', + enum: ['strict', 'runtime', 'ai-friendly', 'minimal'], + description: 'Profile for mode=full: "minimal", "runtime", "ai-friendly", or "strict". Default is "ai-friendly"', + default: 'ai-friendly', + }, + }, + required: ['nodeType', 'config'], + additionalProperties: false, + }, + outputSchema: { + type: 'object', + properties: { + nodeType: { type: 'string' }, + workflowNodeType: { type: 'string' }, + displayName: { type: 'string' }, + valid: { type: 'boolean' }, + errors: { + type: 'array', + items: { + type: 'object', + properties: { + type: { type: 'string' }, + property: { type: 'string' }, + message: { type: 'string' }, + fix: { type: 'string' } + } + } + }, + warnings: { + type: 'array', + items: { + type: 'object', + properties: { + type: { type: 'string' }, + property: { type: 'string' }, + message: { type: 'string' }, + suggestion: { type: 'string' } + } + } + }, + suggestions: { type: 'array', items: { type: 'string' } }, + missingRequiredFields: { + type: 'array', + items: { type: 'string' }, + description: 'Only present in mode=minimal' + }, + summary: { + type: 'object', + properties: { + hasErrors: { type: 'boolean' }, + errorCount: { type: 'number' }, + warningCount: { type: 'number' }, + suggestionCount: { type: 'number' } + } + } + }, + required: ['nodeType', 'displayName', 'valid'] + }, + }, + { + name: 'get_template', + description: `Get template by ID. Use mode to control response size: nodes_only (minimal), structure (nodes+connections), full (complete workflow).`, + inputSchema: { + type: 'object', + properties: { + templateId: { + type: 'number', + description: 'The template ID to retrieve', + }, + mode: { + type: 'string', + enum: ['nodes_only', 'structure', 'full'], + description: 'Response detail level. nodes_only: just node list, structure: nodes+connections, full: complete workflow JSON.', + default: 'full', + }, + }, + required: ['templateId'], + }, + }, + { + name: 'search_templates', + description: `Search templates with multiple modes. Use searchMode='keyword' for text search, 'by_nodes' to find templates using specific nodes, 'by_task' for curated task-based templates, 'by_metadata' for filtering by complexity/setup time/services.`, + inputSchema: { + type: 'object', + properties: { + searchMode: { + type: 'string', + enum: ['keyword', 'by_nodes', 'by_task', 'by_metadata'], + description: 'Search mode. keyword=text search (default), by_nodes=find by node types, by_task=curated task templates, by_metadata=filter by complexity/services', + default: 'keyword', + }, + query: { + type: 'string', + description: 'For searchMode=keyword: search keyword (e.g., "chatbot")', + }, + fields: { + type: 'array', + items: { + type: 'string', + enum: ['id', 'name', 'description', 'author', 'nodes', 'views', 'created', 'url', 'metadata'], + }, + description: 'For searchMode=keyword: fields to include in response. Default: all fields.', + }, + nodeTypes: { + type: 'array', + items: { type: 'string' }, + description: 'For searchMode=by_nodes: array of node types (e.g., ["n8n-nodes-base.httpRequest", "n8n-nodes-base.slack"])', + }, + task: { + type: 'string', + enum: [ + 'ai_automation', + 'data_sync', + 'webhook_processing', + 'email_automation', + 'slack_integration', + 'data_transformation', + 'file_processing', + 'scheduling', + 'api_integration', + 'database_operations' + ], + description: 'For searchMode=by_task: the type of task', + }, + category: { + type: 'string', + description: 'For searchMode=by_metadata: filter by category (e.g., "automation", "integration")', + }, + complexity: { + type: 'string', + enum: ['simple', 'medium', 'complex'], + description: 'For searchMode=by_metadata: filter by complexity level', + }, + maxSetupMinutes: { + type: 'number', + description: 'For searchMode=by_metadata: maximum setup time in minutes', + minimum: 5, + maximum: 480, + }, + minSetupMinutes: { + type: 'number', + description: 'For searchMode=by_metadata: minimum setup time in minutes', + minimum: 5, + maximum: 480, + }, + requiredService: { + type: 'string', + description: 'For searchMode=by_metadata: filter by required service (e.g., "openai", "slack")', + }, + targetAudience: { + type: 'string', + description: 'For searchMode=by_metadata: filter by target audience (e.g., "developers", "marketers")', + }, + limit: { + type: 'number', + description: 'Maximum number of results. Default 20.', + default: 20, + minimum: 1, + maximum: 100, + }, + offset: { + type: 'number', + description: 'Pagination offset. Default 0.', + default: 0, + minimum: 0, + }, + }, + }, + }, + { + name: 'validate_workflow', + description: `Full workflow validation: structure, connections, expressions, AI tools. Returns errors/warnings/fixes. Essential before deploy.`, + inputSchema: { + type: 'object', + properties: { + workflow: { + type: 'object', + description: 'The complete workflow JSON to validate. Must include nodes array and connections object.', + }, + options: { + type: 'object', + properties: { + validateNodes: { + type: 'boolean', + description: 'Validate individual node configurations. Default true.', + default: true, + }, + validateConnections: { + type: 'boolean', + description: 'Validate node connections and flow. Default true.', + default: true, + }, + validateExpressions: { + type: 'boolean', + description: 'Validate n8n expressions syntax and references. Default true.', + default: true, + }, + profile: { + type: 'string', + enum: ['minimal', 'runtime', 'ai-friendly', 'strict'], + description: 'Validation profile for node validation. Default "runtime".', + default: 'runtime', + }, + }, + description: 'Optional validation settings', + }, + }, + required: ['workflow'], + additionalProperties: false, + }, + outputSchema: { + type: 'object', + properties: { + valid: { type: 'boolean' }, + summary: { + type: 'object', + properties: { + totalNodes: { type: 'number' }, + enabledNodes: { type: 'number' }, + triggerNodes: { type: 'number' }, + validConnections: { type: 'number' }, + invalidConnections: { type: 'number' }, + expressionsValidated: { type: 'number' }, + errorCount: { type: 'number' }, + warningCount: { type: 'number' } + } + }, + errors: { + type: 'array', + items: { + type: 'object', + properties: { + node: { type: 'string' }, + message: { type: 'string' }, + details: { type: 'string' } + } + } + }, + warnings: { + type: 'array', + items: { + type: 'object', + properties: { + node: { type: 'string' }, + message: { type: 'string' }, + details: { type: 'string' } + } + } + }, + suggestions: { type: 'array', items: { type: 'string' } } + }, + required: ['valid', 'summary'] + }, + }, +]; +//# sourceMappingURL=tools.js.map \ No newline at end of file diff --git a/dist/mcp/tools.js.map b/dist/mcp/tools.js.map new file mode 100644 index 0000000..58ef7b9 --- /dev/null +++ b/dist/mcp/tools.js.map @@ -0,0 +1 @@ +{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/mcp/workflow-examples.d.ts b/dist/mcp/workflow-examples.d.ts new file mode 100644 index 0000000..e361d8a --- /dev/null +++ b/dist/mcp/workflow-examples.d.ts @@ -0,0 +1,76 @@ +export declare const MINIMAL_WORKFLOW_EXAMPLE: { + nodes: { + name: string; + type: string; + typeVersion: number; + position: number[]; + parameters: { + httpMethod: string; + path: string; + }; + }[]; + connections: {}; +}; +export declare const SIMPLE_WORKFLOW_EXAMPLE: { + nodes: ({ + name: string; + type: string; + typeVersion: number; + position: number[]; + parameters: { + httpMethod: string; + path: string; + mode?: undefined; + assignments?: undefined; + respondWith?: undefined; + }; + } | { + name: string; + type: string; + typeVersion: number; + position: number[]; + parameters: { + mode: string; + assignments: { + assignments: { + name: string; + type: string; + value: string; + }[]; + }; + httpMethod?: undefined; + path?: undefined; + respondWith?: undefined; + }; + } | { + name: string; + type: string; + typeVersion: number; + position: number[]; + parameters: { + respondWith: string; + httpMethod?: undefined; + path?: undefined; + mode?: undefined; + assignments?: undefined; + }; + })[]; + connections: { + Webhook: { + main: { + node: string; + type: string; + index: number; + }[][]; + }; + Set: { + main: { + node: string; + type: string; + index: number; + }[][]; + }; + }; +}; +export declare function getWorkflowExampleString(): string; +//# sourceMappingURL=workflow-examples.d.ts.map \ No newline at end of file diff --git a/dist/mcp/workflow-examples.d.ts.map b/dist/mcp/workflow-examples.d.ts.map new file mode 100644 index 0000000..46ee237 --- /dev/null +++ b/dist/mcp/workflow-examples.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"workflow-examples.d.ts","sourceRoot":"","sources":["../../src/mcp/workflow-examples.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,wBAAwB;;;;;;;;;;;;CAcpC,CAAC;AAEF,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgEnC,CAAC;AAEF,wBAAgB,wBAAwB,IAAI,MAAM,CAyBjD"} \ No newline at end of file diff --git a/dist/mcp/workflow-examples.js b/dist/mcp/workflow-examples.js new file mode 100644 index 0000000..62a0aa6 --- /dev/null +++ b/dist/mcp/workflow-examples.js @@ -0,0 +1,111 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.SIMPLE_WORKFLOW_EXAMPLE = exports.MINIMAL_WORKFLOW_EXAMPLE = void 0; +exports.getWorkflowExampleString = getWorkflowExampleString; +exports.MINIMAL_WORKFLOW_EXAMPLE = { + nodes: [ + { + name: "Webhook", + type: "n8n-nodes-base.webhook", + typeVersion: 2, + position: [250, 300], + parameters: { + httpMethod: "POST", + path: "webhook" + } + } + ], + connections: {} +}; +exports.SIMPLE_WORKFLOW_EXAMPLE = { + nodes: [ + { + name: "Webhook", + type: "n8n-nodes-base.webhook", + typeVersion: 2, + position: [250, 300], + parameters: { + httpMethod: "POST", + path: "webhook" + } + }, + { + name: "Set", + type: "n8n-nodes-base.set", + typeVersion: 2, + position: [450, 300], + parameters: { + mode: "manual", + assignments: { + assignments: [ + { + name: "message", + type: "string", + value: "Hello" + } + ] + } + } + }, + { + name: "Respond to Webhook", + type: "n8n-nodes-base.respondToWebhook", + typeVersion: 1, + position: [650, 300], + parameters: { + respondWith: "firstIncomingItem" + } + } + ], + connections: { + "Webhook": { + "main": [ + [ + { + "node": "Set", + "type": "main", + "index": 0 + } + ] + ] + }, + "Set": { + "main": [ + [ + { + "node": "Respond to Webhook", + "type": "main", + "index": 0 + } + ] + ] + } + } +}; +function getWorkflowExampleString() { + return `Example workflow structure: +${JSON.stringify(exports.MINIMAL_WORKFLOW_EXAMPLE, null, 2)} + +Each node MUST have: +- name: unique string identifier +- type: full node type with prefix (e.g., "n8n-nodes-base.webhook") +- typeVersion: number (usually 1 or 2) +- position: [x, y] coordinates array +- parameters: object with node-specific settings + +Connections format: +{ + "SourceNodeName": { + "main": [ + [ + { + "node": "TargetNodeName", + "type": "main", + "index": 0 + } + ] + ] + } +}`; +} +//# sourceMappingURL=workflow-examples.js.map \ No newline at end of file diff --git a/dist/mcp/workflow-examples.js.map b/dist/mcp/workflow-examples.js.map new file mode 100644 index 0000000..852d8ec --- /dev/null +++ b/dist/mcp/workflow-examples.js.map @@ -0,0 +1 @@ +{"version":3,"file":"workflow-examples.js","sourceRoot":"","sources":["../../src/mcp/workflow-examples.ts"],"names":[],"mappings":";;;AAsFA,4DAyBC;AA3GY,QAAA,wBAAwB,GAAG;IACtC,KAAK,EAAE;QACL;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,wBAAwB;YAC9B,WAAW,EAAE,CAAC;YACd,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;YACpB,UAAU,EAAE;gBACV,UAAU,EAAE,MAAM;gBAClB,IAAI,EAAE,SAAS;aAChB;SACF;KACF;IACD,WAAW,EAAE,EAAE;CAChB,CAAC;AAEW,QAAA,uBAAuB,GAAG;IACrC,KAAK,EAAE;QACL;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,wBAAwB;YAC9B,WAAW,EAAE,CAAC;YACd,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;YACpB,UAAU,EAAE;gBACV,UAAU,EAAE,MAAM;gBAClB,IAAI,EAAE,SAAS;aAChB;SACF;QACD;YACE,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,oBAAoB;YAC1B,WAAW,EAAE,CAAC;YACd,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;YACpB,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE;oBACX,WAAW,EAAE;wBACX;4BACE,IAAI,EAAE,SAAS;4BACf,IAAI,EAAE,QAAQ;4BACd,KAAK,EAAE,OAAO;yBACf;qBACF;iBACF;aACF;SACF;QACD;YACE,IAAI,EAAE,oBAAoB;YAC1B,IAAI,EAAE,iCAAiC;YACvC,WAAW,EAAE,CAAC;YACd,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;YACpB,UAAU,EAAE;gBACV,WAAW,EAAE,mBAAmB;aACjC;SACF;KACF;IACD,WAAW,EAAE;QACX,SAAS,EAAE;YACT,MAAM,EAAE;gBACN;oBACE;wBACE,MAAM,EAAE,KAAK;wBACb,MAAM,EAAE,MAAM;wBACd,OAAO,EAAE,CAAC;qBACX;iBACF;aACF;SACF;QACD,KAAK,EAAE;YACL,MAAM,EAAE;gBACN;oBACE;wBACE,MAAM,EAAE,oBAAoB;wBAC5B,MAAM,EAAE,MAAM;wBACd,OAAO,EAAE,CAAC;qBACX;iBACF;aACF;SACF;KACF;CACF,CAAC;AAEF,SAAgB,wBAAwB;IACtC,OAAO;EACP,IAAI,CAAC,SAAS,CAAC,gCAAwB,EAAE,IAAI,EAAE,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;EAsBjD,CAAC;AACH,CAAC"} \ No newline at end of file diff --git a/dist/n8n/MCPApi.credentials.d.ts b/dist/n8n/MCPApi.credentials.d.ts new file mode 100644 index 0000000..0f448cf --- /dev/null +++ b/dist/n8n/MCPApi.credentials.d.ts @@ -0,0 +1,8 @@ +import { ICredentialType, INodeProperties } from 'n8n-workflow'; +export declare class MCPApi implements ICredentialType { + name: string; + displayName: string; + documentationUrl: string; + properties: INodeProperties[]; +} +//# sourceMappingURL=MCPApi.credentials.d.ts.map \ No newline at end of file diff --git a/dist/n8n/MCPApi.credentials.d.ts.map b/dist/n8n/MCPApi.credentials.d.ts.map new file mode 100644 index 0000000..048398c --- /dev/null +++ b/dist/n8n/MCPApi.credentials.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"MCPApi.credentials.d.ts","sourceRoot":"","sources":["../../src/n8n/MCPApi.credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,eAAe,EAChB,MAAM,cAAc,CAAC;AAEtB,qBAAa,MAAO,YAAW,eAAe;IAC5C,IAAI,SAAY;IAChB,WAAW,SAAa;IACxB,gBAAgB,SAAS;IACzB,UAAU,EAAE,eAAe,EAAE,CAwC3B;CACH"} \ No newline at end of file diff --git a/dist/n8n/MCPApi.credentials.js b/dist/n8n/MCPApi.credentials.js new file mode 100644 index 0000000..f61a499 --- /dev/null +++ b/dist/n8n/MCPApi.credentials.js @@ -0,0 +1,53 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.MCPApi = void 0; +class MCPApi { + constructor() { + this.name = 'mcpApi'; + this.displayName = 'MCP API'; + this.documentationUrl = 'mcp'; + this.properties = [ + { + displayName: 'Server URL', + name: 'serverUrl', + type: 'string', + default: 'http://localhost:3000', + placeholder: 'http://localhost:3000', + description: 'The URL of the MCP server', + }, + { + displayName: 'Authentication Token', + name: 'authToken', + type: 'string', + typeOptions: { + password: true, + }, + default: '', + description: 'Authentication token for the MCP server (if required)', + }, + { + displayName: 'Connection Type', + name: 'connectionType', + type: 'options', + options: [ + { + name: 'HTTP', + value: 'http', + }, + { + name: 'WebSocket', + value: 'websocket', + }, + { + name: 'STDIO', + value: 'stdio', + }, + ], + default: 'http', + description: 'How to connect to the MCP server', + }, + ]; + } +} +exports.MCPApi = MCPApi; +//# sourceMappingURL=MCPApi.credentials.js.map \ No newline at end of file diff --git a/dist/n8n/MCPApi.credentials.js.map b/dist/n8n/MCPApi.credentials.js.map new file mode 100644 index 0000000..85e5071 --- /dev/null +++ b/dist/n8n/MCPApi.credentials.js.map @@ -0,0 +1 @@ +{"version":3,"file":"MCPApi.credentials.js","sourceRoot":"","sources":["../../src/n8n/MCPApi.credentials.ts"],"names":[],"mappings":";;;AAKA,MAAa,MAAM;IAAnB;QACE,SAAI,GAAG,QAAQ,CAAC;QAChB,gBAAW,GAAG,SAAS,CAAC;QACxB,qBAAgB,GAAG,KAAK,CAAC;QACzB,eAAU,GAAsB;YAC9B;gBACE,WAAW,EAAE,YAAY;gBACzB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,uBAAuB;gBAChC,WAAW,EAAE,uBAAuB;gBACpC,WAAW,EAAE,2BAA2B;aACzC;YACD;gBACE,WAAW,EAAE,sBAAsB;gBACnC,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE;oBACX,QAAQ,EAAE,IAAI;iBACf;gBACD,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,uDAAuD;aACrE;YACD;gBACE,WAAW,EAAE,iBAAiB;gBAC9B,IAAI,EAAE,gBAAgB;gBACtB,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,KAAK,EAAE,MAAM;qBACd;oBACD;wBACE,IAAI,EAAE,WAAW;wBACjB,KAAK,EAAE,WAAW;qBACnB;oBACD;wBACE,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,OAAO;qBACf;iBACF;gBACD,OAAO,EAAE,MAAM;gBACf,WAAW,EAAE,kCAAkC;aAChD;SACF,CAAC;IACJ,CAAC;CAAA;AA7CD,wBA6CC"} \ No newline at end of file diff --git a/dist/n8n/MCPNode.node.d.ts b/dist/n8n/MCPNode.node.d.ts new file mode 100644 index 0000000..053b8ee --- /dev/null +++ b/dist/n8n/MCPNode.node.d.ts @@ -0,0 +1,13 @@ +import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow'; +export declare class MCPNode implements INodeType { + description: INodeTypeDescription; + execute(this: IExecuteFunctions): Promise; + private getMCPClient; + private callMCPTool; + private listMCPTools; + private readMCPResource; + private listMCPResources; + private getMCPPrompt; + private listMCPPrompts; +} +//# sourceMappingURL=MCPNode.node.d.ts.map \ No newline at end of file diff --git a/dist/n8n/MCPNode.node.d.ts.map b/dist/n8n/MCPNode.node.d.ts.map new file mode 100644 index 0000000..78588db --- /dev/null +++ b/dist/n8n/MCPNode.node.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"MCPNode.node.d.ts","sourceRoot":"","sources":["../../src/n8n/MCPNode.node.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,SAAS,EACT,oBAAoB,EAErB,MAAM,cAAc,CAAC;AAItB,qBAAa,OAAQ,YAAW,SAAS;IACvC,WAAW,EAAE,oBAAoB,CA+H/B;IAEI,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;YAwEzD,YAAY;YAUZ,WAAW;YAUX,YAAY;YASZ,eAAe;YAUf,gBAAgB;YAShB,YAAY;YAUZ,cAAc;CAQ7B"} \ No newline at end of file diff --git a/dist/n8n/MCPNode.node.js b/dist/n8n/MCPNode.node.js new file mode 100644 index 0000000..58c2d2e --- /dev/null +++ b/dist/n8n/MCPNode.node.js @@ -0,0 +1,260 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.MCPNode = void 0; +const n8n_workflow_1 = require("n8n-workflow"); +const mcp_client_1 = require("../utils/mcp-client"); +const bridge_1 = require("../utils/bridge"); +class MCPNode { + constructor() { + this.description = { + displayName: 'MCP', + name: 'mcp', + icon: 'file:mcp.svg', + group: ['transform'], + version: 1, + description: 'Interact with Model Context Protocol (MCP) servers', + defaults: { + name: 'MCP', + }, + inputs: ['main'], + outputs: ['main'], + credentials: [ + { + name: 'mcpApi', + required: true, + }, + ], + properties: [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + noDataExpression: true, + options: [ + { + name: 'Call Tool', + value: 'callTool', + description: 'Execute an MCP tool', + }, + { + name: 'List Tools', + value: 'listTools', + description: 'List available MCP tools', + }, + { + name: 'Read Resource', + value: 'readResource', + description: 'Read an MCP resource', + }, + { + name: 'List Resources', + value: 'listResources', + description: 'List available MCP resources', + }, + { + name: 'Get Prompt', + value: 'getPrompt', + description: 'Get an MCP prompt', + }, + { + name: 'List Prompts', + value: 'listPrompts', + description: 'List available MCP prompts', + }, + ], + default: 'callTool', + }, + { + displayName: 'Tool Name', + name: 'toolName', + type: 'string', + required: true, + displayOptions: { + show: { + operation: ['callTool'], + }, + }, + default: '', + description: 'Name of the MCP tool to execute', + }, + { + displayName: 'Tool Arguments', + name: 'toolArguments', + type: 'json', + required: false, + displayOptions: { + show: { + operation: ['callTool'], + }, + }, + default: '{}', + description: 'Arguments to pass to the MCP tool', + }, + { + displayName: 'Resource URI', + name: 'resourceUri', + type: 'string', + required: true, + displayOptions: { + show: { + operation: ['readResource'], + }, + }, + default: '', + description: 'URI of the MCP resource to read', + }, + { + displayName: 'Prompt Name', + name: 'promptName', + type: 'string', + required: true, + displayOptions: { + show: { + operation: ['getPrompt'], + }, + }, + default: '', + description: 'Name of the MCP prompt to retrieve', + }, + { + displayName: 'Prompt Arguments', + name: 'promptArguments', + type: 'json', + required: false, + displayOptions: { + show: { + operation: ['getPrompt'], + }, + }, + default: '{}', + description: 'Arguments to pass to the MCP prompt', + }, + ], + }; + } + async execute() { + const items = this.getInputData(); + const returnData = []; + const operation = this.getNodeParameter('operation', 0); + const credentials = await this.getCredentials('mcpApi'); + for (let itemIndex = 0; itemIndex < items.length; itemIndex++) { + try { + let result; + switch (operation) { + case 'callTool': + const toolName = this.getNodeParameter('toolName', itemIndex); + const toolArgumentsJson = this.getNodeParameter('toolArguments', itemIndex); + const toolArguments = JSON.parse(toolArgumentsJson); + result = await this.callMCPTool(credentials, toolName, toolArguments); + break; + case 'listTools': + result = await this.listMCPTools(credentials); + break; + case 'readResource': + const resourceUri = this.getNodeParameter('resourceUri', itemIndex); + result = await this.readMCPResource(credentials, resourceUri); + break; + case 'listResources': + result = await this.listMCPResources(credentials); + break; + case 'getPrompt': + const promptName = this.getNodeParameter('promptName', itemIndex); + const promptArgumentsJson = this.getNodeParameter('promptArguments', itemIndex); + const promptArguments = JSON.parse(promptArgumentsJson); + result = await this.getMCPPrompt(credentials, promptName, promptArguments); + break; + case 'listPrompts': + result = await this.listMCPPrompts(credentials); + break; + default: + throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`); + } + returnData.push({ + json: result, + pairedItem: itemIndex, + }); + } + catch (error) { + if (this.continueOnFail()) { + returnData.push({ + json: { + error: error instanceof Error ? error.message : 'Unknown error', + }, + pairedItem: itemIndex, + }); + continue; + } + throw error; + } + } + return [returnData]; + } + async getMCPClient(credentials) { + const client = new mcp_client_1.MCPClient({ + serverUrl: credentials.serverUrl, + authToken: credentials.authToken, + connectionType: credentials.connectionType || 'websocket', + }); + await client.connect(); + return client; + } + async callMCPTool(credentials, toolName, args) { + const client = await this.getMCPClient(credentials); + try { + const result = await client.callTool(toolName, args); + return bridge_1.N8NMCPBridge.mcpToN8NExecutionData(result).json; + } + finally { + await client.disconnect(); + } + } + async listMCPTools(credentials) { + const client = await this.getMCPClient(credentials); + try { + return await client.listTools(); + } + finally { + await client.disconnect(); + } + } + async readMCPResource(credentials, uri) { + const client = await this.getMCPClient(credentials); + try { + const result = await client.readResource(uri); + return bridge_1.N8NMCPBridge.mcpToN8NExecutionData(result).json; + } + finally { + await client.disconnect(); + } + } + async listMCPResources(credentials) { + const client = await this.getMCPClient(credentials); + try { + return await client.listResources(); + } + finally { + await client.disconnect(); + } + } + async getMCPPrompt(credentials, promptName, args) { + const client = await this.getMCPClient(credentials); + try { + const result = await client.getPrompt(promptName, args); + return bridge_1.N8NMCPBridge.mcpPromptArgsToN8N(result); + } + finally { + await client.disconnect(); + } + } + async listMCPPrompts(credentials) { + const client = await this.getMCPClient(credentials); + try { + return await client.listPrompts(); + } + finally { + await client.disconnect(); + } + } +} +exports.MCPNode = MCPNode; +//# sourceMappingURL=MCPNode.node.js.map \ No newline at end of file diff --git a/dist/n8n/MCPNode.node.js.map b/dist/n8n/MCPNode.node.js.map new file mode 100644 index 0000000..e036277 --- /dev/null +++ b/dist/n8n/MCPNode.node.js.map @@ -0,0 +1 @@ +{"version":3,"file":"MCPNode.node.js","sourceRoot":"","sources":["../../src/n8n/MCPNode.node.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/parsers/node-parser.d.ts b/dist/parsers/node-parser.d.ts new file mode 100644 index 0000000..c042285 --- /dev/null +++ b/dist/parsers/node-parser.d.ts @@ -0,0 +1,35 @@ +import type { NodeClass } from '../types/node-types'; +export interface ParsedNode { + style: 'declarative' | 'programmatic'; + nodeType: string; + displayName: string; + description?: string; + category?: string; + properties: any[]; + credentials: any[]; + isAITool: boolean; + isTrigger: boolean; + isWebhook: boolean; + operations: any[]; + version?: string; + isVersioned: boolean; + packageName: string; + documentation?: string; + outputs?: any[]; + outputNames?: string[]; +} +export declare class NodeParser { + private propertyExtractor; + private currentNodeClass; + parse(nodeClass: NodeClass, packageName: string): ParsedNode; + private getNodeDescription; + private detectStyle; + private extractNodeType; + private extractCategory; + private detectTrigger; + private detectWebhook; + private extractVersion; + private detectVersioned; + private extractOutputs; +} +//# sourceMappingURL=node-parser.d.ts.map \ No newline at end of file diff --git a/dist/parsers/node-parser.d.ts.map b/dist/parsers/node-parser.d.ts.map new file mode 100644 index 0000000..9fb6b68 --- /dev/null +++ b/dist/parsers/node-parser.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"node-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/node-parser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,SAAS,EAEV,MAAM,qBAAqB,CAAC;AAQ7B,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,aAAa,GAAG,cAAc,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,GAAG,EAAE,CAAC;IAClB,WAAW,EAAE,GAAG,EAAE,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,GAAG,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,iBAAiB,CAA2B;IACpD,OAAO,CAAC,gBAAgB,CAA0B;IAElD,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,GAAG,UAAU;IA0B5D,OAAO,CAAC,kBAAkB;IAoD1B,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,aAAa;IAyBrB,OAAO,CAAC,cAAc;IA0FtB,OAAO,CAAC,eAAe;IA2CvB,OAAO,CAAC,cAAc;CAsDvB"} \ No newline at end of file diff --git a/dist/parsers/node-parser.js b/dist/parsers/node-parser.js new file mode 100644 index 0000000..d555cdd --- /dev/null +++ b/dist/parsers/node-parser.js @@ -0,0 +1,250 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.NodeParser = void 0; +const property_extractor_1 = require("./property-extractor"); +const node_types_1 = require("../types/node-types"); +class NodeParser { + constructor() { + this.propertyExtractor = new property_extractor_1.PropertyExtractor(); + this.currentNodeClass = null; + } + parse(nodeClass, packageName) { + this.currentNodeClass = nodeClass; + const description = this.getNodeDescription(nodeClass); + const outputInfo = this.extractOutputs(description); + return { + style: this.detectStyle(nodeClass), + nodeType: this.extractNodeType(description, packageName), + displayName: description.displayName || description.name, + description: description.description, + category: this.extractCategory(description), + properties: this.propertyExtractor.extractProperties(nodeClass), + credentials: this.propertyExtractor.extractCredentials(nodeClass), + isAITool: this.propertyExtractor.detectAIToolCapability(nodeClass), + isTrigger: this.detectTrigger(description), + isWebhook: this.detectWebhook(description), + operations: this.propertyExtractor.extractOperations(nodeClass), + version: this.extractVersion(nodeClass), + isVersioned: this.detectVersioned(nodeClass), + packageName: packageName, + outputs: outputInfo.outputs, + outputNames: outputInfo.outputNames + }; + } + getNodeDescription(nodeClass) { + let description; + if ((0, node_types_1.isVersionedNodeClass)(nodeClass)) { + try { + const instance = new nodeClass(); + const inst = instance; + description = inst.description || (inst.nodeVersions ? inst.baseDescription : undefined); + } + catch (e) { + } + } + else if (typeof nodeClass === 'function') { + try { + const instance = new nodeClass(); + description = instance.description; + if (!description || !description.name) { + const inst = instance; + if (inst.baseDescription?.name) { + description = inst.baseDescription; + } + } + } + catch (e) { + description = nodeClass.description; + } + } + else { + description = nodeClass.description; + if (!description || !description.name) { + const inst = nodeClass; + if (inst.baseDescription?.name) { + description = inst.baseDescription; + } + } + } + return description || {}; + } + detectStyle(nodeClass) { + const desc = this.getNodeDescription(nodeClass); + return desc.routing ? 'declarative' : 'programmatic'; + } + extractNodeType(description, packageName) { + const name = description.name; + if (!name) { + throw new Error('Node is missing name property'); + } + if (name.includes('.')) { + return name; + } + const packagePrefix = packageName.replace('@n8n/', '').replace('n8n-', ''); + return `${packagePrefix}.${name}`; + } + extractCategory(description) { + return description.group?.[0] || + description.categories?.[0] || + description.category || + 'misc'; + } + detectTrigger(description) { + const desc = description; + if (description.group && Array.isArray(description.group)) { + if (description.group.includes('trigger')) { + return true; + } + } + return desc.polling === true || + desc.trigger === true || + desc.eventTrigger === true || + description.name?.toLowerCase().includes('trigger'); + } + detectWebhook(description) { + const desc = description; + return (desc.webhooks?.length > 0) || + desc.webhook === true || + description.name?.toLowerCase().includes('webhook'); + } + extractVersion(nodeClass) { + try { + const instance = typeof nodeClass === 'function' ? new nodeClass() : nodeClass; + const inst = instance; + if (inst?.currentVersion !== undefined) { + return inst.currentVersion.toString(); + } + if (inst?.description?.defaultVersion) { + return inst.description.defaultVersion.toString(); + } + if (inst?.nodeVersions) { + const versions = Object.keys(inst.nodeVersions).map(Number); + if (versions.length > 0) { + const maxVersion = Math.max(...versions); + if (!isNaN(maxVersion)) { + return maxVersion.toString(); + } + } + } + if (inst?.description?.version) { + const version = inst.description.version; + if (Array.isArray(version)) { + const numericVersions = version.map((v) => parseFloat(v.toString())); + if (numericVersions.length > 0) { + const maxVersion = Math.max(...numericVersions); + if (!isNaN(maxVersion)) { + return maxVersion.toString(); + } + } + } + else if (typeof version === 'number' || typeof version === 'string') { + return version.toString(); + } + } + } + catch (e) { + } + const nodeClassAny = nodeClass; + if (nodeClassAny.description?.defaultVersion) { + return nodeClassAny.description.defaultVersion.toString(); + } + if (nodeClassAny.nodeVersions) { + const versions = Object.keys(nodeClassAny.nodeVersions).map(Number); + if (versions.length > 0) { + const maxVersion = Math.max(...versions); + if (!isNaN(maxVersion)) { + return maxVersion.toString(); + } + } + } + const description = this.getNodeDescription(nodeClass); + const desc = description; + if (desc?.version) { + if (Array.isArray(desc.version)) { + const numericVersions = desc.version.map((v) => parseFloat(v.toString())); + if (numericVersions.length > 0) { + const maxVersion = Math.max(...numericVersions); + if (!isNaN(maxVersion)) { + return maxVersion.toString(); + } + } + } + else if (typeof desc.version === 'number' || typeof desc.version === 'string') { + return desc.version.toString(); + } + } + return '1'; + } + detectVersioned(nodeClass) { + try { + const instance = typeof nodeClass === 'function' ? new nodeClass() : nodeClass; + const inst = instance; + if (inst?.baseDescription?.defaultVersion) { + return true; + } + if (inst?.nodeVersions) { + return true; + } + if (inst?.description?.version && Array.isArray(inst.description.version)) { + return true; + } + } + catch (e) { + } + const nodeClassAny = nodeClass; + if (nodeClassAny.nodeVersions || nodeClassAny.baseDescription?.defaultVersion) { + return true; + } + const description = this.getNodeDescription(nodeClass); + const desc = description; + if (desc?.version && Array.isArray(desc.version)) { + return true; + } + return false; + } + extractOutputs(description) { + const result = {}; + const desc = description; + if (desc.outputs) { + result.outputs = Array.isArray(desc.outputs) ? desc.outputs : [desc.outputs]; + } + if (desc.outputNames) { + result.outputNames = Array.isArray(desc.outputNames) ? desc.outputNames : [desc.outputNames]; + } + if (!result.outputs && !result.outputNames) { + const nodeClass = this.currentNodeClass; + if (nodeClass) { + try { + const instance = typeof nodeClass === 'function' ? new nodeClass() : nodeClass; + const inst = instance; + if (inst.nodeVersions) { + const versions = Object.keys(inst.nodeVersions).map(Number); + if (versions.length > 0) { + const latestVersion = Math.max(...versions); + if (!isNaN(latestVersion)) { + const versionedDescription = inst.nodeVersions[latestVersion]?.description; + if (versionedDescription) { + if (versionedDescription.outputs) { + result.outputs = Array.isArray(versionedDescription.outputs) + ? versionedDescription.outputs + : [versionedDescription.outputs]; + } + if (versionedDescription.outputNames) { + result.outputNames = Array.isArray(versionedDescription.outputNames) + ? versionedDescription.outputNames + : [versionedDescription.outputNames]; + } + } + } + } + } + } + catch (e) { + } + } + } + return result; + } +} +exports.NodeParser = NodeParser; +//# sourceMappingURL=node-parser.js.map \ No newline at end of file diff --git a/dist/parsers/node-parser.js.map b/dist/parsers/node-parser.js.map new file mode 100644 index 0000000..fe39c96 --- /dev/null +++ b/dist/parsers/node-parser.js.map @@ -0,0 +1 @@ +{"version":3,"file":"node-parser.js","sourceRoot":"","sources":["../../src/parsers/node-parser.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/parsers/property-extractor.d.ts b/dist/parsers/property-extractor.d.ts new file mode 100644 index 0000000..6040d98 --- /dev/null +++ b/dist/parsers/property-extractor.d.ts @@ -0,0 +1,11 @@ +import type { NodeClass } from '../types/node-types'; +export declare class PropertyExtractor { + extractProperties(nodeClass: NodeClass): any[]; + private getNodeDescription; + extractOperations(nodeClass: NodeClass): any[]; + private extractOperationsFromDescription; + detectAIToolCapability(nodeClass: NodeClass): boolean; + extractCredentials(nodeClass: NodeClass): any[]; + private normalizeProperties; +} +//# sourceMappingURL=property-extractor.d.ts.map \ No newline at end of file diff --git a/dist/parsers/property-extractor.d.ts.map b/dist/parsers/property-extractor.d.ts.map new file mode 100644 index 0000000..daf5e46 --- /dev/null +++ b/dist/parsers/property-extractor.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"property-extractor.d.ts","sourceRoot":"","sources":["../../src/parsers/property-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,qBAAa,iBAAiB;IAI5B,iBAAiB,CAAC,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;IAqC9C,OAAO,CAAC,kBAAkB;IA6B1B,iBAAiB,CAAC,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;IAiC9C,OAAO,CAAC,gCAAgC;IAmDxC,sBAAsB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO;IA4BrD,kBAAkB,CAAC,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;IAqC/C,OAAO,CAAC,mBAAmB;CAgB5B"} \ No newline at end of file diff --git a/dist/parsers/property-extractor.js b/dist/parsers/property-extractor.js new file mode 100644 index 0000000..10eac03 --- /dev/null +++ b/dist/parsers/property-extractor.js @@ -0,0 +1,172 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.PropertyExtractor = void 0; +class PropertyExtractor { + extractProperties(nodeClass) { + const properties = []; + let instance; + try { + instance = typeof nodeClass === 'function' ? new nodeClass() : nodeClass; + } + catch (e) { + } + if (instance?.nodeVersions) { + const versions = Object.keys(instance.nodeVersions).map(Number); + if (versions.length > 0) { + const latestVersion = Math.max(...versions); + if (!isNaN(latestVersion)) { + const versionedNode = instance.nodeVersions[latestVersion]; + if (versionedNode?.description?.properties) { + return this.normalizeProperties(versionedNode.description.properties); + } + } + } + } + const description = instance?.description || instance?.baseDescription || + this.getNodeDescription(nodeClass); + if (description?.properties) { + return this.normalizeProperties(description.properties); + } + return properties; + } + getNodeDescription(nodeClass) { + let description; + if (typeof nodeClass === 'function') { + try { + const instance = new nodeClass(); + const inst = instance; + description = inst.description || inst.baseDescription || {}; + } + catch (e) { + const nodeClassAny = nodeClass; + description = nodeClassAny.description || {}; + } + } + else { + const inst = nodeClass; + description = inst.description || {}; + } + return description; + } + extractOperations(nodeClass) { + const operations = []; + let instance; + try { + instance = typeof nodeClass === 'function' ? new nodeClass() : nodeClass; + } + catch (e) { + } + if (instance?.nodeVersions) { + const versions = Object.keys(instance.nodeVersions).map(Number); + if (versions.length > 0) { + const latestVersion = Math.max(...versions); + if (!isNaN(latestVersion)) { + const versionedNode = instance.nodeVersions[latestVersion]; + if (versionedNode?.description) { + return this.extractOperationsFromDescription(versionedNode.description); + } + } + } + } + const description = instance?.description || instance?.baseDescription || + this.getNodeDescription(nodeClass); + return this.extractOperationsFromDescription(description); + } + extractOperationsFromDescription(description) { + const operations = []; + if (!description) + return operations; + if (description.routing) { + const routing = description.routing; + if (routing.request?.resource) { + const resources = routing.request.resource.options || []; + const operationOptions = routing.request.operation?.options || {}; + resources.forEach((resource) => { + const resourceOps = operationOptions[resource.value] || []; + resourceOps.forEach((op) => { + operations.push({ + resource: resource.value, + operation: op.value, + name: `${resource.name} - ${op.name}`, + action: op.action + }); + }); + }); + } + } + if (description.properties && Array.isArray(description.properties)) { + const operationProp = description.properties.find((p) => p.name === 'operation' || p.name === 'action'); + if (operationProp?.options) { + operationProp.options.forEach((op) => { + operations.push({ + operation: op.value, + name: op.name, + description: op.description + }); + }); + } + } + return operations; + } + detectAIToolCapability(nodeClass) { + const description = this.getNodeDescription(nodeClass); + if (description?.usableAsTool === true) + return true; + if (description?.actions?.some((a) => a.usableAsTool === true)) + return true; + const nodeClassAny = nodeClass; + if (nodeClassAny.nodeVersions) { + for (const version of Object.values(nodeClassAny.nodeVersions)) { + if (version.description?.usableAsTool === true) + return true; + } + } + const aiIndicators = ['openai', 'anthropic', 'huggingface', 'cohere', 'ai']; + const nodeName = description?.name?.toLowerCase() || ''; + return aiIndicators.some(indicator => nodeName.includes(indicator)); + } + extractCredentials(nodeClass) { + const credentials = []; + let instance; + try { + instance = typeof nodeClass === 'function' ? new nodeClass() : nodeClass; + } + catch (e) { + } + if (instance?.nodeVersions) { + const versions = Object.keys(instance.nodeVersions).map(Number); + if (versions.length > 0) { + const latestVersion = Math.max(...versions); + if (!isNaN(latestVersion)) { + const versionedNode = instance.nodeVersions[latestVersion]; + if (versionedNode?.description?.credentials) { + return versionedNode.description.credentials; + } + } + } + } + const description = instance?.description || instance?.baseDescription || + this.getNodeDescription(nodeClass); + if (description?.credentials) { + return description.credentials; + } + return credentials; + } + normalizeProperties(properties) { + return properties.map(prop => ({ + displayName: prop.displayName, + name: prop.name, + type: prop.type, + default: prop.default, + description: prop.description, + options: prop.options, + required: prop.required, + displayOptions: prop.displayOptions, + typeOptions: prop.typeOptions, + modes: prop.modes, + noDataExpression: prop.noDataExpression + })); + } +} +exports.PropertyExtractor = PropertyExtractor; +//# sourceMappingURL=property-extractor.js.map \ No newline at end of file diff --git a/dist/parsers/property-extractor.js.map b/dist/parsers/property-extractor.js.map new file mode 100644 index 0000000..e0ba242 --- /dev/null +++ b/dist/parsers/property-extractor.js.map @@ -0,0 +1 @@ +{"version":3,"file":"property-extractor.js","sourceRoot":"","sources":["../../src/parsers/property-extractor.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/parsers/simple-parser.d.ts b/dist/parsers/simple-parser.d.ts new file mode 100644 index 0000000..a9abef8 --- /dev/null +++ b/dist/parsers/simple-parser.d.ts @@ -0,0 +1,25 @@ +import type { NodeClass } from '../types/node-types'; +export interface ParsedNode { + style: 'declarative' | 'programmatic'; + nodeType: string; + displayName: string; + description?: string; + category?: string; + properties: any[]; + credentials: string[]; + isAITool: boolean; + isTrigger: boolean; + isWebhook: boolean; + operations: any[]; + version?: string; + isVersioned: boolean; +} +export declare class SimpleParser { + parse(nodeClass: NodeClass): ParsedNode; + private detectTrigger; + private extractOperations; + private extractProgrammaticOperations; + private extractVersion; + private isVersionedNode; +} +//# sourceMappingURL=simple-parser.d.ts.map \ No newline at end of file diff --git a/dist/parsers/simple-parser.d.ts.map b/dist/parsers/simple-parser.d.ts.map new file mode 100644 index 0000000..e1110b1 --- /dev/null +++ b/dist/parsers/simple-parser.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"simple-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/simple-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EAEV,MAAM,qBAAqB,CAAC;AAO7B,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,aAAa,GAAG,cAAc,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,GAAG,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,GAAG,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,qBAAa,YAAY;IACvB,KAAK,CAAC,SAAS,EAAE,SAAS,GAAG,UAAU;IA0FvC,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,iBAAiB;IAsCzB,OAAO,CAAC,6BAA6B;IA+DrC,OAAO,CAAC,cAAc;IA2DtB,OAAO,CAAC,eAAe;CAqCxB"} \ No newline at end of file diff --git a/dist/parsers/simple-parser.js b/dist/parsers/simple-parser.js new file mode 100644 index 0000000..37b2490 --- /dev/null +++ b/dist/parsers/simple-parser.js @@ -0,0 +1,212 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.SimpleParser = void 0; +const node_types_1 = require("../types/node-types"); +class SimpleParser { + parse(nodeClass) { + let description; + let isVersioned = false; + try { + if ((0, node_types_1.isVersionedNodeClass)(nodeClass)) { + const instance = new nodeClass(); + const inst = instance; + description = inst.description || (inst.nodeVersions ? inst.baseDescription : undefined); + if (!description) { + description = {}; + } + isVersioned = true; + if (inst.nodeVersions && inst.currentVersion) { + const currentVersionNode = inst.nodeVersions[inst.currentVersion]; + if (currentVersionNode && currentVersionNode.description) { + description = { ...description, ...currentVersionNode.description }; + } + } + } + else if (typeof nodeClass === 'function') { + try { + const instance = new nodeClass(); + description = instance.description; + if (!description || !description.name) { + const inst = instance; + if (inst.baseDescription?.name) { + description = inst.baseDescription; + } + } + } + catch (e) { + description = {}; + } + } + else { + description = nodeClass.description; + if (!description || !description.name) { + const inst = nodeClass; + if (inst.baseDescription?.name) { + description = inst.baseDescription; + } + } + } + } + catch (error) { + description = nodeClass.description || {}; + } + const desc = description; + const isDeclarative = !!desc.routing; + if (!description.name) { + throw new Error('Node is missing name property'); + } + return { + style: isDeclarative ? 'declarative' : 'programmatic', + nodeType: description.name, + displayName: description.displayName || description.name, + description: description.description, + category: description.group?.[0] || desc.categories?.[0], + properties: desc.properties || [], + credentials: desc.credentials || [], + isAITool: desc.usableAsTool === true, + isTrigger: this.detectTrigger(description), + isWebhook: desc.webhooks?.length > 0, + operations: isDeclarative ? this.extractOperations(desc.routing) : this.extractProgrammaticOperations(desc), + version: this.extractVersion(nodeClass), + isVersioned: isVersioned || this.isVersionedNode(nodeClass) || Array.isArray(desc.version) || desc.defaultVersion !== undefined + }; + } + detectTrigger(description) { + if (description.group && Array.isArray(description.group)) { + if (description.group.includes('trigger')) { + return true; + } + } + const desc = description; + return desc.polling === true || + desc.trigger === true || + desc.eventTrigger === true || + description.name?.toLowerCase().includes('trigger'); + } + extractOperations(routing) { + const operations = []; + if (routing?.request) { + const resources = routing.request.resource?.options || []; + resources.forEach((resource) => { + operations.push({ + resource: resource.value, + name: resource.name + }); + }); + const operationOptions = routing.request.operation?.options || []; + operationOptions.forEach((operation) => { + operations.push({ + operation: operation.value, + name: operation.name || operation.displayName + }); + }); + } + if (routing?.operations) { + Object.entries(routing.operations).forEach(([key, value]) => { + operations.push({ + operation: key, + name: value.displayName || key + }); + }); + } + return operations; + } + extractProgrammaticOperations(description) { + const operations = []; + if (!description.properties || !Array.isArray(description.properties)) { + return operations; + } + const resourceProp = description.properties.find((p) => p.name === 'resource' && p.type === 'options'); + if (resourceProp && resourceProp.options) { + resourceProp.options.forEach((resource) => { + operations.push({ + type: 'resource', + resource: resource.value, + name: resource.name + }); + }); + } + const operationProps = description.properties.filter((p) => p.name === 'operation' && p.type === 'options' && p.displayOptions); + operationProps.forEach((opProp) => { + if (opProp.options) { + opProp.options.forEach((operation) => { + const resourceCondition = opProp.displayOptions?.show?.resource; + const resources = Array.isArray(resourceCondition) ? resourceCondition : [resourceCondition]; + operations.push({ + type: 'operation', + operation: operation.value, + name: operation.name, + action: operation.action, + resources: resources + }); + }); + } + }); + return operations; + } + extractVersion(nodeClass) { + try { + const instance = typeof nodeClass === 'function' ? new nodeClass() : nodeClass; + const inst = instance; + if (inst?.currentVersion !== undefined) { + return inst.currentVersion.toString(); + } + if (inst?.description?.defaultVersion) { + return inst.description.defaultVersion.toString(); + } + if (inst?.nodeVersions) { + const versions = Object.keys(inst.nodeVersions).map(Number); + if (versions.length > 0) { + const maxVersion = Math.max(...versions); + if (!isNaN(maxVersion)) { + return maxVersion.toString(); + } + } + } + if (inst?.description?.version) { + return inst.description.version.toString(); + } + } + catch (e) { + } + const nodeClassAny = nodeClass; + if (nodeClassAny.description?.defaultVersion) { + return nodeClassAny.description.defaultVersion.toString(); + } + if (nodeClassAny.nodeVersions) { + const versions = Object.keys(nodeClassAny.nodeVersions).map(Number); + if (versions.length > 0) { + const maxVersion = Math.max(...versions); + if (!isNaN(maxVersion)) { + return maxVersion.toString(); + } + } + } + return nodeClassAny.description?.version || '1'; + } + isVersionedNode(nodeClass) { + const nodeClassAny = nodeClass; + if (nodeClassAny.baseDescription && nodeClassAny.nodeVersions) { + return true; + } + try { + const instance = typeof nodeClass === 'function' ? new nodeClass() : nodeClass; + const inst = instance; + if (inst.baseDescription && inst.nodeVersions) { + return true; + } + const description = inst.description || {}; + if (Array.isArray(description.version)) { + return true; + } + if (description.defaultVersion !== undefined) { + return true; + } + } + catch (e) { + } + return false; + } +} +exports.SimpleParser = SimpleParser; +//# sourceMappingURL=simple-parser.js.map \ No newline at end of file diff --git a/dist/parsers/simple-parser.js.map b/dist/parsers/simple-parser.js.map new file mode 100644 index 0000000..6cacd3a --- /dev/null +++ b/dist/parsers/simple-parser.js.map @@ -0,0 +1 @@ +{"version":3,"file":"simple-parser.js","sourceRoot":"","sources":["../../src/parsers/simple-parser.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/scripts/debug-http-search.d.ts b/dist/scripts/debug-http-search.d.ts new file mode 100644 index 0000000..73fa46d --- /dev/null +++ b/dist/scripts/debug-http-search.d.ts @@ -0,0 +1,3 @@ +#!/usr/bin/env npx tsx +export {}; +//# sourceMappingURL=debug-http-search.d.ts.map \ No newline at end of file diff --git a/dist/scripts/debug-http-search.d.ts.map b/dist/scripts/debug-http-search.d.ts.map new file mode 100644 index 0000000..ac442a9 --- /dev/null +++ b/dist/scripts/debug-http-search.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"debug-http-search.d.ts","sourceRoot":"","sources":["../../src/scripts/debug-http-search.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/scripts/debug-http-search.js b/dist/scripts/debug-http-search.js new file mode 100644 index 0000000..52f17f4 --- /dev/null +++ b/dist/scripts/debug-http-search.js @@ -0,0 +1,57 @@ +#!/usr/bin/env npx tsx +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const database_adapter_1 = require("../database/database-adapter"); +const node_repository_1 = require("../database/node-repository"); +const node_similarity_service_1 = require("../services/node-similarity-service"); +const path_1 = __importDefault(require("path")); +async function debugHttpSearch() { + const dbPath = path_1.default.join(process.cwd(), 'data/nodes.db'); + const db = await (0, database_adapter_1.createDatabaseAdapter)(dbPath); + const repository = new node_repository_1.NodeRepository(db); + const service = new node_similarity_service_1.NodeSimilarityService(repository); + console.log('Testing "http" search...\n'); + const httpNode = repository.getNode('nodes-base.httpRequest'); + console.log('HTTP Request node exists:', httpNode ? 'Yes' : 'No'); + if (httpNode) { + console.log(' Display name:', httpNode.displayName); + } + const suggestions = await service.findSimilarNodes('http', 5); + console.log('\nSuggestions for "http":', suggestions.length); + suggestions.forEach(s => { + console.log(` - ${s.nodeType} (${Math.round(s.confidence * 100)}%)`); + }); + console.log('\nManual score calculation for httpRequest:'); + const testNode = { + nodeType: 'nodes-base.httpRequest', + displayName: 'HTTP Request', + category: 'Core Nodes' + }; + const cleanInvalid = 'http'; + const cleanValid = 'nodesbasehttprequest'; + const displayNameClean = 'httprequest'; + const hasSubstring = cleanValid.includes(cleanInvalid) || displayNameClean.includes(cleanInvalid); + console.log(` Substring match: ${hasSubstring}`); + const patternScore = hasSubstring ? 35 : 0; + console.log(` Pattern score: ${patternScore}`); + console.log(` Total score would need to be >= 50 to appear`); + const allNodes = repository.getAllNodes(); + const httpNodes = allNodes.filter(n => n.nodeType.toLowerCase().includes('http') || + (n.displayName && n.displayName.toLowerCase().includes('http'))); + console.log('\n\nNodes containing "http" in name:'); + httpNodes.slice(0, 5).forEach(n => { + console.log(` - ${n.nodeType} (${n.displayName})`); + const normalizedSearch = 'http'; + const normalizedType = n.nodeType.toLowerCase().replace(/[^a-z0-9]/g, ''); + const normalizedDisplay = (n.displayName || '').toLowerCase().replace(/[^a-z0-9]/g, ''); + const containsInType = normalizedType.includes(normalizedSearch); + const containsInDisplay = normalizedDisplay.includes(normalizedSearch); + console.log(` Type check: "${normalizedType}" includes "${normalizedSearch}" = ${containsInType}`); + console.log(` Display check: "${normalizedDisplay}" includes "${normalizedSearch}" = ${containsInDisplay}`); + }); +} +debugHttpSearch().catch(console.error); +//# sourceMappingURL=debug-http-search.js.map \ No newline at end of file diff --git a/dist/scripts/debug-http-search.js.map b/dist/scripts/debug-http-search.js.map new file mode 100644 index 0000000..24473a1 --- /dev/null +++ b/dist/scripts/debug-http-search.js.map @@ -0,0 +1 @@ +{"version":3,"file":"debug-http-search.js","sourceRoot":"","sources":["../../src/scripts/debug-http-search.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/scripts/extract-from-docker.d.ts b/dist/scripts/extract-from-docker.d.ts new file mode 100644 index 0000000..9c6c584 --- /dev/null +++ b/dist/scripts/extract-from-docker.d.ts @@ -0,0 +1,3 @@ +#!/usr/bin/env node +export {}; +//# sourceMappingURL=extract-from-docker.d.ts.map \ No newline at end of file diff --git a/dist/scripts/extract-from-docker.d.ts.map b/dist/scripts/extract-from-docker.d.ts.map new file mode 100644 index 0000000..b1eee41 --- /dev/null +++ b/dist/scripts/extract-from-docker.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"extract-from-docker.d.ts","sourceRoot":"","sources":["../../src/scripts/extract-from-docker.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/scripts/extract-from-docker.js b/dist/scripts/extract-from-docker.js new file mode 100644 index 0000000..80852ac --- /dev/null +++ b/dist/scripts/extract-from-docker.js @@ -0,0 +1,210 @@ +#!/usr/bin/env node +"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 }); +const dotenv = __importStar(require("dotenv")); +const node_documentation_service_1 = require("../services/node-documentation-service"); +const node_source_extractor_1 = require("../utils/node-source-extractor"); +const logger_1 = require("../utils/logger"); +const fs = __importStar(require("fs/promises")); +const path = __importStar(require("path")); +dotenv.config(); +async function extractNodesFromDocker() { + logger_1.logger.info('🐳 Starting Docker-based node extraction...'); + const dockerVolumePaths = [ + process.env.N8N_MODULES_PATH || '/n8n-modules', + process.env.N8N_CUSTOM_PATH || '/n8n-custom', + ]; + logger_1.logger.info(`Docker volume paths: ${dockerVolumePaths.join(', ')}`); + for (const volumePath of dockerVolumePaths) { + try { + await fs.access(volumePath); + logger_1.logger.info(`✅ Volume mounted: ${volumePath}`); + const entries = await fs.readdir(volumePath); + logger_1.logger.info(`Contents of ${volumePath}: ${entries.slice(0, 10).join(', ')}${entries.length > 10 ? '...' : ''}`); + } + catch (error) { + logger_1.logger.warn(`❌ Volume not accessible: ${volumePath}`); + } + } + const docService = new node_documentation_service_1.NodeDocumentationService(); + const extractor = new node_source_extractor_1.NodeSourceExtractor(); + extractor.n8nBasePaths.unshift(...dockerVolumePaths); + logger_1.logger.info('🧹 Clearing existing nodes...'); + const db = docService.db; + db.prepare('DELETE FROM nodes').run(); + logger_1.logger.info('🔍 Searching for n8n nodes in Docker volumes...'); + const n8nPackages = [ + 'n8n-nodes-base', + '@n8n/n8n-nodes-langchain', + 'n8n-nodes-extras', + ]; + let totalExtracted = 0; + let ifNodeVersion = null; + for (const packageName of n8nPackages) { + logger_1.logger.info(`\n📦 Processing package: ${packageName}`); + try { + let packagePath = null; + for (const volumePath of dockerVolumePaths) { + const possiblePaths = [ + path.join(volumePath, packageName), + path.join(volumePath, '.pnpm', `${packageName}@*`, 'node_modules', packageName), + ]; + for (const testPath of possiblePaths) { + try { + if (testPath.includes('*')) { + const baseDir = path.dirname(testPath.split('*')[0]); + const entries = await fs.readdir(baseDir); + for (const entry of entries) { + if (entry.includes(packageName.replace('/', '+'))) { + const fullPath = path.join(baseDir, entry, 'node_modules', packageName); + try { + await fs.access(fullPath); + packagePath = fullPath; + break; + } + catch { } + } + } + } + else { + await fs.access(testPath); + packagePath = testPath; + break; + } + } + catch { } + } + if (packagePath) + break; + } + if (!packagePath) { + logger_1.logger.warn(`Package ${packageName} not found in Docker volumes`); + continue; + } + logger_1.logger.info(`Found package at: ${packagePath}`); + try { + const packageJsonPath = path.join(packagePath, 'package.json'); + const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8')); + logger_1.logger.info(`Package version: ${packageJson.version}`); + } + catch { } + const nodesPath = path.join(packagePath, 'dist', 'nodes'); + try { + await fs.access(nodesPath); + logger_1.logger.info(`Scanning nodes directory: ${nodesPath}`); + const nodeEntries = await scanForNodes(nodesPath); + logger_1.logger.info(`Found ${nodeEntries.length} nodes in ${packageName}`); + for (const nodeEntry of nodeEntries) { + try { + const nodeName = nodeEntry.name.replace('.node.js', ''); + const nodeType = `${packageName}.${nodeName}`; + logger_1.logger.info(`Extracting: ${nodeType}`); + const sourceInfo = await extractor.extractNodeSource(nodeType); + if (nodeName === 'If') { + const versionMatch = sourceInfo.sourceCode.match(/version:\s*(\d+)/); + if (versionMatch) { + ifNodeVersion = versionMatch[1]; + logger_1.logger.info(`📍 Found If node version: ${ifNodeVersion}`); + } + } + await docService.storeNode({ + nodeType: nodeType, + name: nodeName, + displayName: nodeName, + description: `${nodeName} node from ${packageName}`, + sourceCode: sourceInfo.sourceCode, + credentialCode: sourceInfo.credentialCode, + packageName: packageName, + version: ifNodeVersion || '1', + hasCredentials: !!sourceInfo.credentialCode, + isTrigger: sourceInfo.sourceCode.includes('trigger: true') || nodeName.toLowerCase().includes('trigger'), + isWebhook: sourceInfo.sourceCode.includes('webhook: true') || nodeName.toLowerCase().includes('webhook'), + }); + totalExtracted++; + } + catch (error) { + logger_1.logger.error(`Failed to extract ${nodeEntry.name}: ${error}`); + } + } + } + catch (error) { + logger_1.logger.error(`Failed to scan nodes directory: ${error}`); + } + } + catch (error) { + logger_1.logger.error(`Failed to process package ${packageName}: ${error}`); + } + } + logger_1.logger.info(`\n✅ Extraction complete!`); + logger_1.logger.info(`📊 Total nodes extracted: ${totalExtracted}`); + if (ifNodeVersion) { + logger_1.logger.info(`📍 If node version: ${ifNodeVersion}`); + if (ifNodeVersion === '2' || ifNodeVersion === '2.2') { + logger_1.logger.info('✅ Successfully extracted latest If node (v2+)!'); + } + else { + logger_1.logger.warn(`⚠️ If node version is ${ifNodeVersion}, expected v2 or higher`); + } + } + await docService.close(); +} +async function scanForNodes(dirPath) { + const nodes = []; + async function scan(currentPath) { + try { + const entries = await fs.readdir(currentPath, { withFileTypes: true }); + for (const entry of entries) { + const fullPath = path.join(currentPath, entry.name); + if (entry.isFile() && entry.name.endsWith('.node.js')) { + nodes.push({ name: entry.name, path: fullPath }); + } + else if (entry.isDirectory() && entry.name !== 'node_modules') { + await scan(fullPath); + } + } + } + catch (error) { + logger_1.logger.debug(`Failed to scan directory ${currentPath}: ${error}`); + } + } + await scan(dirPath); + return nodes; +} +extractNodesFromDocker().catch(error => { + logger_1.logger.error('Extraction failed:', error); + process.exit(1); +}); +//# sourceMappingURL=extract-from-docker.js.map \ No newline at end of file diff --git a/dist/scripts/extract-from-docker.js.map b/dist/scripts/extract-from-docker.js.map new file mode 100644 index 0000000..e320ba6 --- /dev/null +++ b/dist/scripts/extract-from-docker.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extract-from-docker.js","sourceRoot":"","sources":["../../src/scripts/extract-from-docker.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/scripts/fetch-templates-robust.d.ts b/dist/scripts/fetch-templates-robust.d.ts new file mode 100644 index 0000000..16926ef --- /dev/null +++ b/dist/scripts/fetch-templates-robust.d.ts @@ -0,0 +1,4 @@ +#!/usr/bin/env node +declare function fetchTemplatesRobust(): Promise; +export { fetchTemplatesRobust }; +//# sourceMappingURL=fetch-templates-robust.d.ts.map \ No newline at end of file diff --git a/dist/scripts/fetch-templates-robust.d.ts.map b/dist/scripts/fetch-templates-robust.d.ts.map new file mode 100644 index 0000000..fea1039 --- /dev/null +++ b/dist/scripts/fetch-templates-robust.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"fetch-templates-robust.d.ts","sourceRoot":"","sources":["../../src/scripts/fetch-templates-robust.ts"],"names":[],"mappings":";AAOA,iBAAe,oBAAoB,kBAwHlC;AAOD,OAAO,EAAE,oBAAoB,EAAE,CAAC"} \ No newline at end of file diff --git a/dist/scripts/fetch-templates-robust.js b/dist/scripts/fetch-templates-robust.js new file mode 100644 index 0000000..db55f51 --- /dev/null +++ b/dist/scripts/fetch-templates-robust.js @@ -0,0 +1,132 @@ +#!/usr/bin/env node +"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.fetchTemplatesRobust = fetchTemplatesRobust; +const database_adapter_1 = require("../database/database-adapter"); +const template_repository_1 = require("../templates/template-repository"); +const template_fetcher_1 = require("../templates/template-fetcher"); +const fs = __importStar(require("fs")); +const path = __importStar(require("path")); +async function fetchTemplatesRobust() { + console.log('🌐 Fetching n8n workflow templates (last year)...\n'); + const dataDir = './data'; + if (!fs.existsSync(dataDir)) { + fs.mkdirSync(dataDir, { recursive: true }); + } + const db = await (0, database_adapter_1.createDatabaseAdapter)('./data/nodes.db'); + try { + db.exec('DROP TABLE IF EXISTS templates'); + db.exec('DROP TABLE IF EXISTS templates_fts'); + console.log('🗑️ Dropped existing templates tables\n'); + } + catch (error) { + } + const schema = fs.readFileSync(path.join(__dirname, '../../src/database/schema.sql'), 'utf8'); + db.exec(schema); + const repository = new template_repository_1.TemplateRepository(db); + const fetcher = new template_fetcher_1.TemplateFetcher(); + let lastMessage = ''; + const startTime = Date.now(); + try { + console.log('📋 Phase 1: Fetching template list from n8n.io API\n'); + const templates = await fetcher.fetchTemplates((current, total) => { + if (lastMessage) { + process.stdout.write('\r' + ' '.repeat(lastMessage.length) + '\r'); + } + const progress = Math.round((current / total) * 100); + lastMessage = `📊 Fetching template list: ${current}/${total} (${progress}%)`; + process.stdout.write(lastMessage); + }); + console.log('\n'); + console.log(`✅ Found ${templates.length} templates from last year\n`); + console.log('📥 Phase 2: Fetching details and saving to database\n'); + let saved = 0; + let errors = 0; + for (let i = 0; i < templates.length; i++) { + const template = templates[i]; + try { + if (lastMessage) { + process.stdout.write('\r' + ' '.repeat(lastMessage.length) + '\r'); + } + const progress = Math.round(((i + 1) / templates.length) * 100); + lastMessage = `📊 Processing: ${i + 1}/${templates.length} (${progress}%) - Saved: ${saved}, Errors: ${errors}`; + process.stdout.write(lastMessage); + const detail = await fetcher.fetchTemplateDetail(template.id); + if (detail !== null) { + repository.saveTemplate(template, detail); + saved++; + } + else { + errors++; + console.error(`\n❌ Failed to fetch template ${template.id} (${template.name}) after retries`); + } + await new Promise(resolve => setTimeout(resolve, 200)); + } + catch (error) { + errors++; + console.error(`\n❌ Error processing template ${template.id} (${template.name}): ${error.message}`); + } + } + console.log('\n'); + const elapsed = Math.round((Date.now() - startTime) / 1000); + const stats = await repository.getTemplateStats(); + console.log('✅ Template fetch complete!\n'); + console.log('📈 Statistics:'); + console.log(` - Templates found: ${templates.length}`); + console.log(` - Templates saved: ${saved}`); + console.log(` - Errors: ${errors}`); + console.log(` - Success rate: ${Math.round((saved / templates.length) * 100)}%`); + console.log(` - Time elapsed: ${elapsed} seconds`); + console.log(` - Average time per template: ${(elapsed / saved).toFixed(2)} seconds`); + if (stats.topUsedNodes && stats.topUsedNodes.length > 0) { + console.log('\n🔝 Top used nodes:'); + stats.topUsedNodes.slice(0, 10).forEach((node, index) => { + console.log(` ${index + 1}. ${node.node} (${node.count} templates)`); + }); + } + } + catch (error) { + console.error('\n❌ Fatal error:', error); + process.exit(1); + } + if ('close' in db && typeof db.close === 'function') { + db.close(); + } +} +if (require.main === module) { + fetchTemplatesRobust().catch(console.error); +} +//# sourceMappingURL=fetch-templates-robust.js.map \ No newline at end of file diff --git a/dist/scripts/fetch-templates-robust.js.map b/dist/scripts/fetch-templates-robust.js.map new file mode 100644 index 0000000..b4ec739 --- /dev/null +++ b/dist/scripts/fetch-templates-robust.js.map @@ -0,0 +1 @@ +{"version":3,"file":"fetch-templates-robust.js","sourceRoot":"","sources":["../../src/scripts/fetch-templates-robust.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/scripts/fetch-templates.d.ts b/dist/scripts/fetch-templates.d.ts new file mode 100644 index 0000000..e13480d --- /dev/null +++ b/dist/scripts/fetch-templates.d.ts @@ -0,0 +1,4 @@ +#!/usr/bin/env node +declare function fetchTemplates(mode?: 'rebuild' | 'update', generateMetadata?: boolean, metadataOnly?: boolean, extractOnly?: boolean): Promise; +export { fetchTemplates }; +//# sourceMappingURL=fetch-templates.d.ts.map \ No newline at end of file diff --git a/dist/scripts/fetch-templates.d.ts.map b/dist/scripts/fetch-templates.d.ts.map new file mode 100644 index 0000000..6b138c2 --- /dev/null +++ b/dist/scripts/fetch-templates.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"fetch-templates.d.ts","sourceRoot":"","sources":["../../src/scripts/fetch-templates.ts"],"names":[],"mappings":";AA4LA,iBAAe,cAAc,CAC3B,IAAI,GAAE,SAAS,GAAG,QAAoB,EACtC,gBAAgB,GAAE,OAAe,EACjC,YAAY,GAAE,OAAe,EAC7B,WAAW,GAAE,OAAe,iBAgL7B;AA6KD,OAAO,EAAE,cAAc,EAAE,CAAC"} \ No newline at end of file diff --git a/dist/scripts/fetch-templates.js b/dist/scripts/fetch-templates.js new file mode 100644 index 0000000..2232b17 --- /dev/null +++ b/dist/scripts/fetch-templates.js @@ -0,0 +1,411 @@ +#!/usr/bin/env node +"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.fetchTemplates = fetchTemplates; +const database_adapter_1 = require("../database/database-adapter"); +const template_service_1 = require("../templates/template-service"); +const fs = __importStar(require("fs")); +const path = __importStar(require("path")); +const zlib = __importStar(require("zlib")); +const dotenv = __importStar(require("dotenv")); +dotenv.config(); +function extractNodeConfigs(templateId, templateName, templateViews, workflowCompressed, metadata) { + try { + const decompressed = zlib.gunzipSync(Buffer.from(workflowCompressed, 'base64')); + const workflow = JSON.parse(decompressed.toString('utf-8')); + const configs = []; + for (const node of workflow.nodes || []) { + if (node.type.includes('stickyNote') || !node.parameters) { + continue; + } + configs.push({ + node_type: node.type, + template_id: templateId, + template_name: templateName, + template_views: templateViews, + node_name: node.name, + parameters_json: JSON.stringify(node.parameters), + credentials_json: node.credentials ? JSON.stringify(node.credentials) : null, + has_credentials: node.credentials ? 1 : 0, + has_expressions: detectExpressions(node.parameters) ? 1 : 0, + complexity: metadata?.complexity || 'medium', + use_cases: JSON.stringify(metadata?.use_cases || []) + }); + } + return configs; + } + catch (error) { + console.error(`Error extracting configs from template ${templateId}:`, error); + return []; + } +} +function detectExpressions(params) { + if (!params) + return false; + const json = JSON.stringify(params); + return json.includes('={{') || json.includes('$json') || json.includes('$node'); +} +function insertAndRankConfigs(db, configs) { + if (configs.length === 0) { + console.log('No configs to insert'); + return; + } + const templateIds = [...new Set(configs.map(c => c.template_id))]; + const placeholders = templateIds.map(() => '?').join(','); + db.prepare(`DELETE FROM template_node_configs WHERE template_id IN (${placeholders})`).run(...templateIds); + const insertStmt = db.prepare(` + INSERT INTO template_node_configs ( + node_type, template_id, template_name, template_views, + node_name, parameters_json, credentials_json, + has_credentials, has_expressions, complexity, use_cases + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `); + for (const config of configs) { + insertStmt.run(config.node_type, config.template_id, config.template_name, config.template_views, config.node_name, config.parameters_json, config.credentials_json, config.has_credentials, config.has_expressions, config.complexity, config.use_cases); + } + db.exec(` + UPDATE template_node_configs + SET rank = ( + SELECT COUNT(*) + 1 + FROM template_node_configs AS t2 + WHERE t2.node_type = template_node_configs.node_type + AND t2.template_views > template_node_configs.template_views + ) + `); + db.exec(` + DELETE FROM template_node_configs + WHERE id NOT IN ( + SELECT id FROM template_node_configs + WHERE rank <= 10 + ORDER BY node_type, rank + ) + `); + console.log(`✅ Extracted and ranked ${configs.length} node configurations`); +} +async function extractTemplateConfigs(db, service) { + console.log('📦 Extracting node configurations from templates...'); + const repository = service.repository; + const allTemplates = repository.getAllTemplates(); + const allConfigs = []; + let configsExtracted = 0; + for (const template of allTemplates) { + if (template.workflow_json_compressed) { + const metadata = template.metadata_json ? JSON.parse(template.metadata_json) : null; + const configs = extractNodeConfigs(template.id, template.name, template.views, template.workflow_json_compressed, metadata); + allConfigs.push(...configs); + configsExtracted += configs.length; + } + } + if (allConfigs.length > 0) { + insertAndRankConfigs(db, allConfigs); + const configStats = db.prepare(` + SELECT + COUNT(DISTINCT node_type) as node_types, + COUNT(*) as total_configs, + AVG(rank) as avg_rank + FROM template_node_configs + `).get(); + console.log(`📊 Node config stats:`); + console.log(` - Unique node types: ${configStats.node_types}`); + console.log(` - Total configs stored: ${configStats.total_configs}`); + console.log(` - Average rank: ${configStats.avg_rank?.toFixed(1) || 'N/A'}`); + } + else { + console.log('⚠️ No node configurations extracted'); + } +} +async function fetchTemplates(mode = 'rebuild', generateMetadata = false, metadataOnly = false, extractOnly = false) { + if (extractOnly) { + console.log('📦 Extract-only mode: Extracting node configurations from existing templates...\n'); + const db = await (0, database_adapter_1.createDatabaseAdapter)('./data/nodes.db'); + try { + const tableExists = db.prepare(` + SELECT name FROM sqlite_master + WHERE type='table' AND name='template_node_configs' + `).get(); + if (!tableExists) { + console.log('📋 Creating template_node_configs table...'); + const migrationPath = path.join(__dirname, '../../src/database/migrations/add-template-node-configs.sql'); + const migration = fs.readFileSync(migrationPath, 'utf8'); + db.exec(migration); + console.log('✅ Table created successfully\n'); + } + } + catch (error) { + console.error('❌ Error checking/creating template_node_configs table:', error); + if ('close' in db && typeof db.close === 'function') { + db.close(); + } + process.exit(1); + } + const service = new template_service_1.TemplateService(db); + await extractTemplateConfigs(db, service); + if ('close' in db && typeof db.close === 'function') { + db.close(); + } + return; + } + if (metadataOnly) { + console.log('🤖 Metadata-only mode: Generating metadata for existing templates...\n'); + if (!process.env.OPENAI_API_KEY) { + console.error('❌ OPENAI_API_KEY not set in environment'); + process.exit(1); + } + const db = await (0, database_adapter_1.createDatabaseAdapter)('./data/nodes.db'); + const service = new template_service_1.TemplateService(db); + await generateTemplateMetadata(db, service); + if ('close' in db && typeof db.close === 'function') { + db.close(); + } + return; + } + const modeEmoji = mode === 'rebuild' ? '🔄' : '⬆️'; + const modeText = mode === 'rebuild' ? 'Rebuilding' : 'Updating'; + console.log(`${modeEmoji} ${modeText} n8n workflow templates...\n`); + if (generateMetadata) { + console.log('🤖 Metadata generation enabled (using OpenAI)\n'); + } + const dataDir = './data'; + if (!fs.existsSync(dataDir)) { + fs.mkdirSync(dataDir, { recursive: true }); + } + const db = await (0, database_adapter_1.createDatabaseAdapter)('./data/nodes.db'); + if (mode === 'rebuild') { + try { + db.exec('DROP TABLE IF EXISTS templates'); + db.exec('DROP TABLE IF EXISTS templates_fts'); + console.log('🗑️ Dropped existing templates tables (rebuild mode)\n'); + const schema = fs.readFileSync(path.join(__dirname, '../../src/database/schema.sql'), 'utf8'); + db.exec(schema); + console.log('📋 Applied database schema\n'); + } + catch (error) { + console.error('❌ Error setting up database schema:', error); + throw error; + } + } + else { + console.log('📊 Update mode: Keeping existing templates and schema\n'); + try { + const columns = db.prepare("PRAGMA table_info(templates)").all(); + const hasMetadataColumn = columns.some((col) => col.name === 'metadata_json'); + if (!hasMetadataColumn) { + console.log('📋 Adding metadata columns to existing schema...'); + db.exec(` + ALTER TABLE templates ADD COLUMN metadata_json TEXT; + ALTER TABLE templates ADD COLUMN metadata_generated_at DATETIME; + `); + console.log('✅ Metadata columns added\n'); + } + } + catch (error) { + console.log('📋 Schema is up to date\n'); + } + } + const service = new template_service_1.TemplateService(db); + let lastMessage = ''; + const startTime = Date.now(); + try { + await service.fetchAndUpdateTemplates((message, current, total) => { + if (lastMessage) { + process.stdout.write('\r' + ' '.repeat(lastMessage.length) + '\r'); + } + const progress = total > 0 ? Math.round((current / total) * 100) : 0; + lastMessage = `📊 ${message}: ${current}/${total} (${progress}%)`; + process.stdout.write(lastMessage); + }, mode); + console.log('\n'); + const stats = await service.getTemplateStats(); + const elapsed = Math.round((Date.now() - startTime) / 1000); + console.log('✅ Template fetch complete!\n'); + console.log('📈 Statistics:'); + console.log(` - Total templates: ${stats.totalTemplates}`); + console.log(` - Average views: ${stats.averageViews}`); + console.log(` - Time elapsed: ${elapsed} seconds`); + console.log('\n🔝 Top used nodes:'); + stats.topUsedNodes.forEach((node, index) => { + console.log(` ${index + 1}. ${node.node} (${node.count} templates)`); + }); + console.log(''); + await extractTemplateConfigs(db, service); + if (generateMetadata && process.env.OPENAI_API_KEY) { + console.log('\n🤖 Generating metadata for templates...'); + await generateTemplateMetadata(db, service); + } + else if (generateMetadata && !process.env.OPENAI_API_KEY) { + console.log('\n⚠️ Metadata generation requested but OPENAI_API_KEY not set'); + } + } + catch (error) { + console.error('\n❌ Error fetching templates:', error); + process.exit(1); + } + if ('close' in db && typeof db.close === 'function') { + db.close(); + } +} +async function generateTemplateMetadata(db, service) { + try { + const { BatchProcessor } = await Promise.resolve().then(() => __importStar(require('../templates/batch-processor'))); + const repository = service.repository; + const limit = parseInt(process.env.METADATA_LIMIT || '0'); + const templatesWithoutMetadata = limit > 0 + ? repository.getTemplatesWithoutMetadata(limit) + : repository.getTemplatesWithoutMetadata(999999); + if (templatesWithoutMetadata.length === 0) { + console.log('✅ All templates already have metadata'); + return; + } + console.log(`Found ${templatesWithoutMetadata.length} templates without metadata`); + const batchSize = parseInt(process.env.OPENAI_BATCH_SIZE || '50'); + console.log(`Processing in batches of ${batchSize} templates each`); + if (batchSize > 100) { + console.log(`⚠️ Large batch size (${batchSize}) may take longer to process`); + console.log(` Consider using OPENAI_BATCH_SIZE=50 for faster results`); + } + const processor = new BatchProcessor({ + apiKey: process.env.OPENAI_API_KEY, + model: process.env.OPENAI_MODEL || 'gpt-4o-mini', + batchSize: batchSize, + outputDir: './temp/batch' + }); + const requests = templatesWithoutMetadata.map((t) => { + let workflow = undefined; + try { + if (t.workflow_json_compressed) { + const decompressed = zlib.gunzipSync(Buffer.from(t.workflow_json_compressed, 'base64')); + workflow = JSON.parse(decompressed.toString()); + } + else if (t.workflow_json) { + workflow = JSON.parse(t.workflow_json); + } + } + catch (error) { + console.warn(`Failed to parse workflow for template ${t.id}:`, error); + } + let nodes = []; + try { + if (t.nodes_used) { + nodes = JSON.parse(t.nodes_used); + if (!Array.isArray(nodes)) { + console.warn(`Template ${t.id} has invalid nodes_used (not an array), using empty array`); + nodes = []; + } + } + } + catch (error) { + console.warn(`Failed to parse nodes_used for template ${t.id}:`, error); + nodes = []; + } + return { + templateId: t.id, + name: t.name, + description: t.description, + nodes: nodes, + workflow + }; + }); + const results = await processor.processTemplates(requests, (message, current, total) => { + process.stdout.write(`\r📊 ${message}: ${current}/${total}`); + }); + console.log('\n'); + const metadataMap = new Map(); + for (const [templateId, result] of results) { + if (!result.error) { + metadataMap.set(templateId, result.metadata); + } + } + if (metadataMap.size > 0) { + repository.batchUpdateMetadata(metadataMap); + console.log(`✅ Updated metadata for ${metadataMap.size} templates`); + } + const stats = repository.getMetadataStats(); + console.log('\n📈 Metadata Statistics:'); + console.log(` - Total templates: ${stats.total}`); + console.log(` - With metadata: ${stats.withMetadata}`); + console.log(` - Without metadata: ${stats.withoutMetadata}`); + console.log(` - Outdated (>30 days): ${stats.outdated}`); + } + catch (error) { + console.error('\n❌ Error generating metadata:', error); + } +} +function parseArgs() { + const args = process.argv.slice(2); + let mode = 'rebuild'; + let generateMetadata = false; + let metadataOnly = false; + let extractOnly = false; + const modeIndex = args.findIndex(arg => arg.startsWith('--mode')); + if (modeIndex !== -1) { + const modeArg = args[modeIndex]; + const modeValue = modeArg.includes('=') ? modeArg.split('=')[1] : args[modeIndex + 1]; + if (modeValue === 'update') { + mode = 'update'; + } + } + if (args.includes('--update')) { + mode = 'update'; + } + if (args.includes('--generate-metadata') || args.includes('--metadata')) { + generateMetadata = true; + } + if (args.includes('--metadata-only')) { + metadataOnly = true; + } + if (args.includes('--extract-only') || args.includes('--extract')) { + extractOnly = true; + } + if (args.includes('--help') || args.includes('-h')) { + console.log('Usage: npm run fetch:templates [options]\n'); + console.log('Options:'); + console.log(' --mode=rebuild|update Rebuild from scratch or update existing (default: rebuild)'); + console.log(' --update Shorthand for --mode=update'); + console.log(' --generate-metadata Generate AI metadata after fetching templates'); + console.log(' --metadata Shorthand for --generate-metadata'); + console.log(' --metadata-only Only generate metadata, skip template fetching'); + console.log(' --extract-only Only extract node configs, skip template fetching'); + console.log(' --extract Shorthand for --extract-only'); + console.log(' --help, -h Show this help message'); + process.exit(0); + } + return { mode, generateMetadata, metadataOnly, extractOnly }; +} +if (require.main === module) { + const { mode, generateMetadata, metadataOnly, extractOnly } = parseArgs(); + fetchTemplates(mode, generateMetadata, metadataOnly, extractOnly).catch(console.error); +} +//# sourceMappingURL=fetch-templates.js.map \ No newline at end of file diff --git a/dist/scripts/fetch-templates.js.map b/dist/scripts/fetch-templates.js.map new file mode 100644 index 0000000..c54c3f9 --- /dev/null +++ b/dist/scripts/fetch-templates.js.map @@ -0,0 +1 @@ +{"version":3,"file":"fetch-templates.js","sourceRoot":"","sources":["../../src/scripts/fetch-templates.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/scripts/rebuild-database.d.ts b/dist/scripts/rebuild-database.d.ts new file mode 100644 index 0000000..199f6c6 --- /dev/null +++ b/dist/scripts/rebuild-database.d.ts @@ -0,0 +1,4 @@ +#!/usr/bin/env node +declare function rebuildDocumentationDatabase(): Promise; +export { rebuildDocumentationDatabase }; +//# sourceMappingURL=rebuild-database.d.ts.map \ No newline at end of file diff --git a/dist/scripts/rebuild-database.d.ts.map b/dist/scripts/rebuild-database.d.ts.map new file mode 100644 index 0000000..516efbd --- /dev/null +++ b/dist/scripts/rebuild-database.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"rebuild-database.d.ts","sourceRoot":"","sources":["../../src/scripts/rebuild-database.ts"],"names":[],"mappings":";AAYA,iBAAe,4BAA4B,kBA4D1C;AAUD,OAAO,EAAE,4BAA4B,EAAE,CAAC"} \ No newline at end of file diff --git a/dist/scripts/rebuild-database.js b/dist/scripts/rebuild-database.js new file mode 100644 index 0000000..1c5f6b9 --- /dev/null +++ b/dist/scripts/rebuild-database.js @@ -0,0 +1,95 @@ +#!/usr/bin/env node +"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.rebuildDocumentationDatabase = rebuildDocumentationDatabase; +const dotenv = __importStar(require("dotenv")); +const node_documentation_service_1 = require("../services/node-documentation-service"); +dotenv.config(); +async function rebuildDocumentationDatabase() { + console.log('🔄 Starting enhanced documentation database rebuild...\n'); + const startTime = Date.now(); + const service = new node_documentation_service_1.NodeDocumentationService(); + try { + const results = await service.rebuildDatabase(); + const duration = ((Date.now() - startTime) / 1000).toFixed(2); + console.log('\n✅ Enhanced documentation database rebuild completed!\n'); + console.log('📊 Results:'); + console.log(` Total nodes found: ${results.total}`); + console.log(` Successfully processed: ${results.successful}`); + console.log(` Failed: ${results.failed}`); + console.log(` Duration: ${duration}s`); + if (results.errors.length > 0) { + console.log(`\n⚠️ First ${Math.min(5, results.errors.length)} errors:`); + results.errors.slice(0, 5).forEach(err => { + console.log(` - ${err}`); + }); + if (results.errors.length > 5) { + console.log(` ... and ${results.errors.length - 5} more errors`); + } + } + const stats = await service.getStatistics(); + console.log('\n📈 Database Statistics:'); + console.log(` Total nodes: ${stats.totalNodes}`); + console.log(` Nodes with documentation: ${stats.nodesWithDocs}`); + console.log(` Nodes with examples: ${stats.nodesWithExamples}`); + console.log(` Nodes with credentials: ${stats.nodesWithCredentials}`); + console.log(` Trigger nodes: ${stats.triggerNodes}`); + console.log(` Webhook nodes: ${stats.webhookNodes}`); + console.log('\n📦 Package distribution:'); + stats.packageDistribution.slice(0, 10).forEach((pkg) => { + console.log(` ${pkg.package}: ${pkg.count} nodes`); + }); + await service.close(); + console.log('\n✨ Enhanced documentation database is ready!'); + console.log('💡 The database now includes:'); + console.log(' - Complete node source code'); + console.log(' - Enhanced documentation with operations and API methods'); + console.log(' - Code examples and templates'); + console.log(' - Related resources and required scopes'); + } + catch (error) { + console.error('\n❌ Documentation database rebuild failed:', error); + service.close(); + process.exit(1); + } +} +if (require.main === module) { + rebuildDocumentationDatabase().catch(error => { + console.error('Fatal error:', error); + process.exit(1); + }); +} +//# sourceMappingURL=rebuild-database.js.map \ No newline at end of file diff --git a/dist/scripts/rebuild-database.js.map b/dist/scripts/rebuild-database.js.map new file mode 100644 index 0000000..775dcf9 --- /dev/null +++ b/dist/scripts/rebuild-database.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rebuild-database.js","sourceRoot":"","sources":["../../src/scripts/rebuild-database.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/scripts/rebuild-optimized.d.ts b/dist/scripts/rebuild-optimized.d.ts new file mode 100644 index 0000000..080dfc4 --- /dev/null +++ b/dist/scripts/rebuild-optimized.d.ts @@ -0,0 +1,3 @@ +#!/usr/bin/env node +export {}; +//# sourceMappingURL=rebuild-optimized.d.ts.map \ No newline at end of file diff --git a/dist/scripts/rebuild-optimized.d.ts.map b/dist/scripts/rebuild-optimized.d.ts.map new file mode 100644 index 0000000..932f48d --- /dev/null +++ b/dist/scripts/rebuild-optimized.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"rebuild-optimized.d.ts","sourceRoot":"","sources":["../../src/scripts/rebuild-optimized.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/scripts/rebuild-optimized.js b/dist/scripts/rebuild-optimized.js new file mode 100644 index 0000000..c2ad091 --- /dev/null +++ b/dist/scripts/rebuild-optimized.js @@ -0,0 +1,198 @@ +#!/usr/bin/env node +"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 }); +const database_adapter_1 = require("../database/database-adapter"); +const node_loader_1 = require("../loaders/node-loader"); +const node_parser_1 = require("../parsers/node-parser"); +const docs_mapper_1 = require("../mappers/docs-mapper"); +const node_repository_1 = require("../database/node-repository"); +const fs = __importStar(require("fs")); +const path = __importStar(require("path")); +async function extractNodeSource(NodeClass, packageName, nodeName) { + try { + const possiblePaths = [ + `${packageName}/dist/nodes/${nodeName}.node.js`, + `${packageName}/dist/nodes/${nodeName}/${nodeName}.node.js`, + `${packageName}/nodes/${nodeName}.node.js`, + `${packageName}/nodes/${nodeName}/${nodeName}.node.js` + ]; + let nodeFilePath = null; + let nodeSourceCode = '// Source code not found'; + for (const path of possiblePaths) { + try { + nodeFilePath = require.resolve(path); + nodeSourceCode = await fs.promises.readFile(nodeFilePath, 'utf8'); + break; + } + catch (e) { + } + } + if (nodeSourceCode === '// Source code not found' && NodeClass.toString) { + nodeSourceCode = `// Extracted from NodeClass\n${NodeClass.toString()}`; + nodeFilePath = 'extracted-from-class'; + } + let credentialSourceCode; + try { + const credName = nodeName.replace(/Node$/, ''); + const credentialPaths = [ + `${packageName}/dist/credentials/${credName}.credentials.js`, + `${packageName}/dist/credentials/${credName}/${credName}.credentials.js`, + `${packageName}/credentials/${credName}.credentials.js` + ]; + for (const path of credentialPaths) { + try { + const credFilePath = require.resolve(path); + credentialSourceCode = await fs.promises.readFile(credFilePath, 'utf8'); + break; + } + catch (e) { + } + } + } + catch (error) { + } + return { + nodeSourceCode, + credentialSourceCode, + sourceLocation: nodeFilePath || 'unknown' + }; + } + catch (error) { + console.warn(`Could not extract source for ${nodeName}: ${error.message}`); + return { + nodeSourceCode: '// Source code extraction failed', + sourceLocation: 'unknown' + }; + } +} +async function rebuildOptimized() { + console.log('🔄 Building optimized n8n node database with embedded source code...\n'); + const dbPath = process.env.BUILD_DB_PATH || './data/nodes.db'; + const db = await (0, database_adapter_1.createDatabaseAdapter)(dbPath); + const loader = new node_loader_1.N8nNodeLoader(); + const parser = new node_parser_1.NodeParser(); + const mapper = new docs_mapper_1.DocsMapper(); + const repository = new node_repository_1.NodeRepository(db); + const schemaPath = path.join(__dirname, '../../src/database/schema-optimized.sql'); + const schema = fs.readFileSync(schemaPath, 'utf8'); + db.exec(schema); + db.exec('DELETE FROM nodes'); + console.log('🗑️ Cleared existing data\n'); + const nodes = await loader.loadAllNodes(); + console.log(`📦 Loaded ${nodes.length} nodes from packages\n`); + const stats = { + successful: 0, + failed: 0, + aiTools: 0, + triggers: 0, + webhooks: 0, + withProperties: 0, + withOperations: 0, + withDocs: 0, + withSource: 0 + }; + for (const { packageName, nodeName, NodeClass } of nodes) { + try { + const parsed = parser.parse(NodeClass, packageName); + if (!parsed.nodeType || !parsed.displayName) { + throw new Error('Missing required fields'); + } + const docs = await mapper.fetchDocumentation(parsed.nodeType); + parsed.documentation = docs || undefined; + console.log(`📄 Extracting source code for ${parsed.nodeType}...`); + const sourceInfo = await extractNodeSource(NodeClass, packageName, nodeName); + const nodeData = { + ...parsed, + developmentStyle: parsed.style, + credentialsRequired: parsed.credentials || [], + nodeSourceCode: sourceInfo.nodeSourceCode, + credentialSourceCode: sourceInfo.credentialSourceCode, + sourceLocation: sourceInfo.sourceLocation, + sourceExtractedAt: new Date().toISOString() + }; + const stmt = db.prepare(` + INSERT INTO nodes ( + node_type, package_name, display_name, description, category, + development_style, is_ai_tool, is_trigger, is_webhook, is_versioned, + version, documentation, properties_schema, operations, credentials_required, + node_source_code, credential_source_code, source_location, source_extracted_at + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `); + stmt.run(nodeData.nodeType, nodeData.packageName, nodeData.displayName, nodeData.description, nodeData.category, nodeData.developmentStyle, nodeData.isAITool ? 1 : 0, nodeData.isTrigger ? 1 : 0, nodeData.isWebhook ? 1 : 0, nodeData.isVersioned ? 1 : 0, nodeData.version, nodeData.documentation, JSON.stringify(nodeData.properties), JSON.stringify(nodeData.operations), JSON.stringify(nodeData.credentialsRequired), nodeData.nodeSourceCode, nodeData.credentialSourceCode, nodeData.sourceLocation, nodeData.sourceExtractedAt); + stats.successful++; + if (parsed.isAITool) + stats.aiTools++; + if (parsed.isTrigger) + stats.triggers++; + if (parsed.isWebhook) + stats.webhooks++; + if (parsed.properties.length > 0) + stats.withProperties++; + if (parsed.operations.length > 0) + stats.withOperations++; + if (docs) + stats.withDocs++; + if (sourceInfo.nodeSourceCode !== '// Source code extraction failed') + stats.withSource++; + console.log(`✅ ${parsed.nodeType} [Props: ${parsed.properties.length}, Ops: ${parsed.operations.length}, Source: ${sourceInfo.nodeSourceCode.length} bytes]`); + } + catch (error) { + stats.failed++; + console.error(`❌ Failed to process ${nodeName}: ${error.message}`); + } + } + console.log('\n🔍 Building full-text search index...'); + db.exec('INSERT INTO nodes_fts(nodes_fts) VALUES("rebuild")'); + console.log('\n📊 Summary:'); + console.log(` Total nodes: ${nodes.length}`); + console.log(` Successful: ${stats.successful}`); + console.log(` Failed: ${stats.failed}`); + console.log(` AI Tools: ${stats.aiTools}`); + console.log(` Triggers: ${stats.triggers}`); + console.log(` Webhooks: ${stats.webhooks}`); + console.log(` With Properties: ${stats.withProperties}`); + console.log(` With Operations: ${stats.withOperations}`); + console.log(` With Documentation: ${stats.withDocs}`); + console.log(` With Source Code: ${stats.withSource}`); + const dbStats = db.prepare('SELECT page_count * page_size as size FROM pragma_page_count(), pragma_page_size()').get(); + console.log(`\n💾 Database size: ${(dbStats.size / 1024 / 1024).toFixed(2)} MB`); + console.log('\n✨ Optimized rebuild complete!'); + db.close(); +} +if (require.main === module) { + rebuildOptimized().catch(console.error); +} +//# sourceMappingURL=rebuild-optimized.js.map \ No newline at end of file diff --git a/dist/scripts/rebuild-optimized.js.map b/dist/scripts/rebuild-optimized.js.map new file mode 100644 index 0000000..dc24de9 --- /dev/null +++ b/dist/scripts/rebuild-optimized.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rebuild-optimized.js","sourceRoot":"","sources":["../../src/scripts/rebuild-optimized.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/scripts/rebuild.d.ts b/dist/scripts/rebuild.d.ts new file mode 100644 index 0000000..00333d4 --- /dev/null +++ b/dist/scripts/rebuild.d.ts @@ -0,0 +1,3 @@ +#!/usr/bin/env node +export {}; +//# sourceMappingURL=rebuild.d.ts.map \ No newline at end of file diff --git a/dist/scripts/rebuild.d.ts.map b/dist/scripts/rebuild.d.ts.map new file mode 100644 index 0000000..50ed748 --- /dev/null +++ b/dist/scripts/rebuild.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"rebuild.d.ts","sourceRoot":"","sources":["../../src/scripts/rebuild.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/scripts/rebuild.js b/dist/scripts/rebuild.js new file mode 100644 index 0000000..0bb3d15 --- /dev/null +++ b/dist/scripts/rebuild.js @@ -0,0 +1,234 @@ +#!/usr/bin/env node +"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 }); +const database_adapter_1 = require("../database/database-adapter"); +const node_loader_1 = require("../loaders/node-loader"); +const node_parser_1 = require("../parsers/node-parser"); +const docs_mapper_1 = require("../mappers/docs-mapper"); +const node_repository_1 = require("../database/node-repository"); +const template_sanitizer_1 = require("../utils/template-sanitizer"); +const fs = __importStar(require("fs")); +const path = __importStar(require("path")); +async function rebuild() { + console.log('🔄 Rebuilding n8n node database...\n'); + const dbPath = process.env.NODE_DB_PATH || './data/nodes.db'; + const db = await (0, database_adapter_1.createDatabaseAdapter)(dbPath); + const loader = new node_loader_1.N8nNodeLoader(); + const parser = new node_parser_1.NodeParser(); + const mapper = new docs_mapper_1.DocsMapper(); + const repository = new node_repository_1.NodeRepository(db); + const schema = fs.readFileSync(path.join(__dirname, '../../src/database/schema.sql'), 'utf8'); + db.exec(schema); + db.exec('DELETE FROM nodes'); + console.log('🗑️ Cleared existing data\n'); + const nodes = await loader.loadAllNodes(); + console.log(`📦 Loaded ${nodes.length} nodes from packages\n`); + const stats = { + successful: 0, + failed: 0, + aiTools: 0, + triggers: 0, + webhooks: 0, + withProperties: 0, + withOperations: 0, + withDocs: 0 + }; + console.log('🔄 Processing nodes...'); + const processedNodes = []; + for (const { packageName, nodeName, NodeClass } of nodes) { + try { + const parsed = parser.parse(NodeClass, packageName); + if (!parsed.nodeType || !parsed.displayName) { + throw new Error(`Missing required fields - nodeType: ${parsed.nodeType}, displayName: ${parsed.displayName}, packageName: ${parsed.packageName}`); + } + if (!parsed.packageName) { + throw new Error(`Missing packageName for node ${nodeName}`); + } + const docs = await mapper.fetchDocumentation(parsed.nodeType); + parsed.documentation = docs || undefined; + processedNodes.push({ parsed, docs: docs || undefined, nodeName }); + } + catch (error) { + stats.failed++; + const errorMessage = error.message; + console.error(`❌ Failed to process ${nodeName}: ${errorMessage}`); + } + } + console.log(`\n💾 Saving ${processedNodes.length} processed nodes to database...`); + let saved = 0; + for (const { parsed, docs, nodeName } of processedNodes) { + try { + repository.saveNode(parsed); + saved++; + stats.successful++; + if (parsed.isAITool) + stats.aiTools++; + if (parsed.isTrigger) + stats.triggers++; + if (parsed.isWebhook) + stats.webhooks++; + if (parsed.properties.length > 0) + stats.withProperties++; + if (parsed.operations.length > 0) + stats.withOperations++; + if (docs) + stats.withDocs++; + console.log(`✅ ${parsed.nodeType} [Props: ${parsed.properties.length}, Ops: ${parsed.operations.length}]`); + } + catch (error) { + stats.failed++; + const errorMessage = error.message; + console.error(`❌ Failed to save ${nodeName}: ${errorMessage}`); + } + } + console.log(`💾 Save completed: ${saved} nodes saved successfully`); + console.log('\n🔍 Running validation checks...'); + try { + const validationResults = validateDatabase(repository); + if (!validationResults.passed) { + console.log('⚠️ Validation Issues:'); + validationResults.issues.forEach(issue => console.log(` - ${issue}`)); + } + else { + console.log('✅ All validation checks passed'); + } + } + catch (validationError) { + console.error('❌ Validation failed:', validationError.message); + console.log('⚠️ Skipping validation due to database compatibility issues'); + } + console.log('\n📊 Summary:'); + console.log(` Total nodes: ${nodes.length}`); + console.log(` Successful: ${stats.successful}`); + console.log(` Failed: ${stats.failed}`); + console.log(` AI Tools: ${stats.aiTools}`); + console.log(` Triggers: ${stats.triggers}`); + console.log(` Webhooks: ${stats.webhooks}`); + console.log(` With Properties: ${stats.withProperties}`); + console.log(` With Operations: ${stats.withOperations}`); + console.log(` With Documentation: ${stats.withDocs}`); + console.log('\n🧹 Checking for templates to sanitize...'); + const templateCount = db.prepare('SELECT COUNT(*) as count FROM templates').get(); + if (templateCount && templateCount.count > 0) { + console.log(` Found ${templateCount.count} templates, sanitizing...`); + const sanitizer = new template_sanitizer_1.TemplateSanitizer(); + let sanitizedCount = 0; + const templates = db.prepare('SELECT id, name, workflow_json FROM templates').all(); + for (const template of templates) { + const originalWorkflow = JSON.parse(template.workflow_json); + const { sanitized: sanitizedWorkflow, wasModified } = sanitizer.sanitizeWorkflow(originalWorkflow); + if (wasModified) { + const stmt = db.prepare('UPDATE templates SET workflow_json = ? WHERE id = ?'); + stmt.run(JSON.stringify(sanitizedWorkflow), template.id); + sanitizedCount++; + console.log(` ✅ Sanitized template ${template.id}: ${template.name}`); + } + } + console.log(` Sanitization complete: ${sanitizedCount} templates cleaned`); + } + else { + console.log(' No templates found in database'); + } + console.log('\n✨ Rebuild complete!'); + db.close(); +} +function validateDatabase(repository) { + const issues = []; + try { + const db = repository.db; + const nodeCount = db.prepare('SELECT COUNT(*) as count FROM nodes').get(); + if (nodeCount.count === 0) { + issues.push('CRITICAL: Database is empty - no nodes found! Rebuild failed or was interrupted.'); + return { passed: false, issues }; + } + if (nodeCount.count < 500) { + issues.push(`WARNING: Only ${nodeCount.count} nodes found - expected at least 500 (both n8n packages)`); + } + const criticalNodes = ['nodes-base.httpRequest', 'nodes-base.code', 'nodes-base.webhook', 'nodes-base.slack']; + for (const nodeType of criticalNodes) { + const node = repository.getNode(nodeType); + if (!node) { + issues.push(`Critical node ${nodeType} not found`); + continue; + } + if (node.properties.length === 0) { + issues.push(`Node ${nodeType} has no properties`); + } + } + const aiTools = repository.getAITools(); + if (aiTools.length === 0) { + issues.push('No AI tools found - check detection logic'); + } + const ftsTableCheck = db.prepare(` + SELECT name FROM sqlite_master + WHERE type='table' AND name='nodes_fts' + `).get(); + if (!ftsTableCheck) { + issues.push('CRITICAL: FTS5 table (nodes_fts) does not exist - searches will fail or be very slow'); + } + else { + const ftsCount = db.prepare('SELECT COUNT(*) as count FROM nodes_fts').get(); + if (ftsCount.count === 0) { + issues.push('CRITICAL: FTS5 index is empty - searches will return zero results'); + } + else if (nodeCount.count !== ftsCount.count) { + issues.push(`FTS5 index out of sync: ${nodeCount.count} nodes but ${ftsCount.count} FTS5 entries`); + } + const searchableNodes = ['webhook', 'merge', 'split']; + for (const searchTerm of searchableNodes) { + const searchResult = db.prepare(` + SELECT COUNT(*) as count FROM nodes_fts + WHERE nodes_fts MATCH ? + `).get(searchTerm); + if (searchResult.count === 0) { + issues.push(`CRITICAL: Search for "${searchTerm}" returns zero results in FTS5 index`); + } + } + } + } + catch (error) { + const errorMessage = error.message; + issues.push(`Validation error: ${errorMessage}`); + } + return { + passed: issues.length === 0, + issues + }; +} +if (require.main === module) { + rebuild().catch(console.error); +} +//# sourceMappingURL=rebuild.js.map \ No newline at end of file diff --git a/dist/scripts/rebuild.js.map b/dist/scripts/rebuild.js.map new file mode 100644 index 0000000..505bf4b --- /dev/null +++ b/dist/scripts/rebuild.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rebuild.js","sourceRoot":"","sources":["../../src/scripts/rebuild.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/scripts/sanitize-templates.d.ts b/dist/scripts/sanitize-templates.d.ts new file mode 100644 index 0000000..6babf6f --- /dev/null +++ b/dist/scripts/sanitize-templates.d.ts @@ -0,0 +1,3 @@ +#!/usr/bin/env node +export {}; +//# sourceMappingURL=sanitize-templates.d.ts.map \ No newline at end of file diff --git a/dist/scripts/sanitize-templates.d.ts.map b/dist/scripts/sanitize-templates.d.ts.map new file mode 100644 index 0000000..1cc28b0 --- /dev/null +++ b/dist/scripts/sanitize-templates.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"sanitize-templates.d.ts","sourceRoot":"","sources":["../../src/scripts/sanitize-templates.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/scripts/sanitize-templates.js b/dist/scripts/sanitize-templates.js new file mode 100644 index 0000000..1354fd6 --- /dev/null +++ b/dist/scripts/sanitize-templates.js @@ -0,0 +1,88 @@ +#!/usr/bin/env node +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const database_adapter_1 = require("../database/database-adapter"); +const template_sanitizer_1 = require("../utils/template-sanitizer"); +const zlib_1 = require("zlib"); +async function sanitizeTemplates() { + console.log('🧹 Sanitizing workflow templates in database...\n'); + const db = await (0, database_adapter_1.createDatabaseAdapter)('./data/nodes.db'); + const sanitizer = new template_sanitizer_1.TemplateSanitizer(); + try { + const templates = db.prepare('SELECT id, name, workflow_json, workflow_json_compressed FROM templates').all(); + console.log(`Found ${templates.length} templates to check\n`); + let sanitizedCount = 0; + const problematicTemplates = []; + for (const template of templates) { + let originalWorkflow = null; + let useCompressed = false; + if (template.workflow_json_compressed) { + try { + const buffer = Buffer.from(template.workflow_json_compressed, 'base64'); + const decompressed = (0, zlib_1.gunzipSync)(buffer).toString('utf-8'); + originalWorkflow = JSON.parse(decompressed); + useCompressed = true; + } + catch (e) { + console.log(`⚠️ Failed to decompress template ${template.id}, trying uncompressed`); + } + } + if (!originalWorkflow && template.workflow_json) { + try { + originalWorkflow = JSON.parse(template.workflow_json); + } + catch (e) { + console.log(`⚠️ Skipping template ${template.id}: Invalid JSON in both formats`); + continue; + } + } + if (!originalWorkflow) { + continue; + } + const { sanitized: sanitizedWorkflow, wasModified } = sanitizer.sanitizeWorkflow(originalWorkflow); + if (wasModified) { + const detectedTokens = sanitizer.detectTokens(originalWorkflow); + if (useCompressed) { + const compressed = (0, zlib_1.gzipSync)(JSON.stringify(sanitizedWorkflow)).toString('base64'); + const stmt = db.prepare('UPDATE templates SET workflow_json_compressed = ? WHERE id = ?'); + stmt.run(compressed, template.id); + } + else { + const stmt = db.prepare('UPDATE templates SET workflow_json = ? WHERE id = ?'); + stmt.run(JSON.stringify(sanitizedWorkflow), template.id); + } + sanitizedCount++; + problematicTemplates.push({ + id: template.id, + name: template.name, + tokens: detectedTokens + }); + console.log(`✅ Sanitized template ${template.id}: ${template.name}`); + detectedTokens.forEach(token => { + console.log(` - Found: ${token.substring(0, 20)}...`); + }); + } + } + console.log(`\n📊 Summary:`); + console.log(` Total templates: ${templates.length}`); + console.log(` Sanitized: ${sanitizedCount}`); + if (problematicTemplates.length > 0) { + console.log(`\n⚠️ Templates that contained API tokens:`); + problematicTemplates.forEach(t => { + console.log(` - ${t.id}: ${t.name}`); + }); + } + console.log('\n✨ Sanitization complete!'); + } + catch (error) { + console.error('❌ Error sanitizing templates:', error); + process.exit(1); + } + finally { + db.close(); + } +} +if (require.main === module) { + sanitizeTemplates().catch(console.error); +} +//# sourceMappingURL=sanitize-templates.js.map \ No newline at end of file diff --git a/dist/scripts/sanitize-templates.js.map b/dist/scripts/sanitize-templates.js.map new file mode 100644 index 0000000..0942a6a --- /dev/null +++ b/dist/scripts/sanitize-templates.js.map @@ -0,0 +1 @@ +{"version":3,"file":"sanitize-templates.js","sourceRoot":"","sources":["../../src/scripts/sanitize-templates.ts"],"names":[],"mappings":";;;AACA,mEAAqE;AAErE,oEAAgE;AAChE,+BAA4C;AAE5C,KAAK,UAAU,iBAAiB;IAC9B,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IAEjE,MAAM,EAAE,GAAG,MAAM,IAAA,wCAAqB,EAAC,iBAAiB,CAAC,CAAC;IAC1D,MAAM,SAAS,GAAG,IAAI,sCAAiB,EAAE,CAAC;IAE1C,IAAI,CAAC;QAEH,MAAM,SAAS,GAAG,EAAE,CAAC,OAAO,CAAC,yEAAyE,CAAC,CAAC,GAAG,EAAW,CAAC;QACvH,OAAO,CAAC,GAAG,CAAC,SAAS,SAAS,CAAC,MAAM,uBAAuB,CAAC,CAAC;QAE9D,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,MAAM,oBAAoB,GAAU,EAAE,CAAC;QAEvC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,gBAAgB,GAAQ,IAAI,CAAC;YACjC,IAAI,aAAa,GAAG,KAAK,CAAC;YAG1B,IAAI,QAAQ,CAAC,wBAAwB,EAAE,CAAC;gBACtC,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,wBAAwB,EAAE,QAAQ,CAAC,CAAC;oBACxE,MAAM,YAAY,GAAG,IAAA,iBAAU,EAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;oBAC1D,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;oBAC5C,aAAa,GAAG,IAAI,CAAC;gBACvB,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,OAAO,CAAC,GAAG,CAAC,oCAAoC,QAAQ,CAAC,EAAE,uBAAuB,CAAC,CAAC;gBACtF,CAAC;YACH,CAAC;YAGD,IAAI,CAAC,gBAAgB,IAAI,QAAQ,CAAC,aAAa,EAAE,CAAC;gBAChD,IAAI,CAAC;oBACH,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;gBACxD,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,OAAO,CAAC,GAAG,CAAC,wBAAwB,QAAQ,CAAC,EAAE,gCAAgC,CAAC,CAAC;oBACjF,SAAS;gBACX,CAAC;YACH,CAAC;YAED,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACtB,SAAS;YACX,CAAC;YAED,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;YAEnG,IAAI,WAAW,EAAE,CAAC;gBAEhB,MAAM,cAAc,GAAG,SAAS,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;gBAGhE,IAAI,aAAa,EAAE,CAAC;oBAClB,MAAM,UAAU,GAAG,IAAA,eAAQ,EAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;oBAClF,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,gEAAgE,CAAC,CAAC;oBAC1F,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACpC,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,qDAAqD,CAAC,CAAC;oBAC/E,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;gBAC3D,CAAC;gBAED,cAAc,EAAE,CAAC;gBACjB,oBAAoB,CAAC,IAAI,CAAC;oBACxB,EAAE,EAAE,QAAQ,CAAC,EAAE;oBACf,IAAI,EAAE,QAAQ,CAAC,IAAI;oBACnB,MAAM,EAAE,cAAc;iBACvB,CAAC,CAAC;gBAEH,OAAO,CAAC,GAAG,CAAC,wBAAwB,QAAQ,CAAC,EAAE,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;gBACrE,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;oBAC7B,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;gBAC1D,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,uBAAuB,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,iBAAiB,cAAc,EAAE,CAAC,CAAC;QAE/C,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;YAC1D,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;gBAC/B,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACzC,CAAC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAGD,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,iBAAiB,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC3C,CAAC"} \ No newline at end of file diff --git a/dist/scripts/seed-canonical-ai-examples.d.ts b/dist/scripts/seed-canonical-ai-examples.d.ts new file mode 100644 index 0000000..c2ac065 --- /dev/null +++ b/dist/scripts/seed-canonical-ai-examples.d.ts @@ -0,0 +1,4 @@ +#!/usr/bin/env node +declare function seedCanonicalExamples(): Promise; +export { seedCanonicalExamples }; +//# sourceMappingURL=seed-canonical-ai-examples.d.ts.map \ No newline at end of file diff --git a/dist/scripts/seed-canonical-ai-examples.d.ts.map b/dist/scripts/seed-canonical-ai-examples.d.ts.map new file mode 100644 index 0000000..b670b41 --- /dev/null +++ b/dist/scripts/seed-canonical-ai-examples.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"seed-canonical-ai-examples.d.ts","sourceRoot":"","sources":["../../src/scripts/seed-canonical-ai-examples.ts"],"names":[],"mappings":";AAmCA,iBAAe,qBAAqB,kBAsHnC;AAOD,OAAO,EAAE,qBAAqB,EAAE,CAAC"} \ No newline at end of file diff --git a/dist/scripts/seed-canonical-ai-examples.js b/dist/scripts/seed-canonical-ai-examples.js new file mode 100644 index 0000000..a2be05f --- /dev/null +++ b/dist/scripts/seed-canonical-ai-examples.js @@ -0,0 +1,121 @@ +#!/usr/bin/env node +"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.seedCanonicalExamples = seedCanonicalExamples; +const fs = __importStar(require("fs")); +const path = __importStar(require("path")); +const database_adapter_1 = require("../database/database-adapter"); +const logger_1 = require("../utils/logger"); +async function seedCanonicalExamples() { + try { + const examplesPath = path.join(__dirname, '../data/canonical-ai-tool-examples.json'); + const examplesData = fs.readFileSync(examplesPath, 'utf-8'); + const canonicalExamples = JSON.parse(examplesData); + logger_1.logger.info('Loading canonical AI tool examples', { + version: canonicalExamples.version, + tools: canonicalExamples.examples.length + }); + const db = await (0, database_adapter_1.createDatabaseAdapter)('./data/nodes.db'); + const templateStmt = db.prepare(` + INSERT OR IGNORE INTO templates ( + id, + workflow_id, + name, + description, + views, + created_at, + updated_at + ) VALUES (?, ?, ?, ?, ?, datetime('now'), datetime('now')) + `); + const canonicalTemplateId = -1000; + templateStmt.run(canonicalTemplateId, canonicalTemplateId, 'Canonical AI Tool Examples', 'Hand-crafted examples demonstrating best practices for AI tools', 99999); + const stmt = db.prepare(` + INSERT OR REPLACE INTO template_node_configs ( + node_type, + template_id, + template_name, + template_views, + node_name, + parameters_json, + credentials_json, + has_credentials, + has_expressions, + complexity, + use_cases + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `); + let totalInserted = 0; + for (const toolExamples of canonicalExamples.examples) { + const { node_type, display_name, examples } = toolExamples; + logger_1.logger.info(`Seeding examples for ${display_name}`, { + nodeType: node_type, + exampleCount: examples.length + }); + for (let i = 0; i < examples.length; i++) { + const example = examples[i]; + const templateId = canonicalTemplateId; + const templateName = `Canonical: ${display_name} - ${example.name}`; + const paramsStr = JSON.stringify(example.parameters); + const hasExpressions = paramsStr.includes('={{') || paramsStr.includes('$json') || paramsStr.includes('$node') ? 1 : 0; + stmt.run(node_type, templateId, templateName, 99999, example.name, JSON.stringify(example.parameters), example.credentials ? JSON.stringify(example.credentials) : null, example.credentials ? 1 : 0, hasExpressions, example.complexity, example.use_case); + totalInserted++; + logger_1.logger.info(` ✓ Seeded: ${example.name}`, { + complexity: example.complexity, + hasCredentials: !!example.credentials, + hasExpressions: hasExpressions === 1 + }); + } + } + db.close(); + logger_1.logger.info('Canonical examples seeding complete', { + totalExamples: totalInserted, + tools: canonicalExamples.examples.length + }); + console.log('\n✅ Successfully seeded', totalInserted, 'canonical AI tool examples'); + console.log('\nExamples are now available via:'); + console.log(' • search_nodes({query: "HTTP Request Tool", includeExamples: true})'); + console.log(' • get_node_essentials({nodeType: "nodes-langchain.toolCode", includeExamples: true})'); + } + catch (error) { + logger_1.logger.error('Failed to seed canonical examples', { error }); + console.error('❌ Error:', error); + process.exit(1); + } +} +if (require.main === module) { + seedCanonicalExamples().catch(console.error); +} +//# sourceMappingURL=seed-canonical-ai-examples.js.map \ No newline at end of file diff --git a/dist/scripts/seed-canonical-ai-examples.js.map b/dist/scripts/seed-canonical-ai-examples.js.map new file mode 100644 index 0000000..e07c1cd --- /dev/null +++ b/dist/scripts/seed-canonical-ai-examples.js.map @@ -0,0 +1 @@ +{"version":3,"file":"seed-canonical-ai-examples.js","sourceRoot":"","sources":["../../src/scripts/seed-canonical-ai-examples.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgKS,sDAAqB;AAxJ9B,uCAAyB;AACzB,2CAA6B;AAC7B,mEAAqE;AACrE,4CAAyC;AAwBzC,KAAK,UAAU,qBAAqB;IAClC,IAAI,CAAC;QAEH,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,yCAAyC,CAAC,CAAC;QACrF,MAAM,YAAY,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAC5D,MAAM,iBAAiB,GAA0B,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAE1E,eAAM,CAAC,IAAI,CAAC,oCAAoC,EAAE;YAChD,OAAO,EAAE,iBAAiB,CAAC,OAAO;YAClC,KAAK,EAAE,iBAAiB,CAAC,QAAQ,CAAC,MAAM;SACzC,CAAC,CAAC;QAGH,MAAM,EAAE,GAAG,MAAM,IAAA,wCAAqB,EAAC,iBAAiB,CAAC,CAAC;QAG1D,MAAM,YAAY,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;;;;KAU/B,CAAC,CAAC;QAGH,MAAM,mBAAmB,GAAG,CAAC,IAAI,CAAC;QAClC,YAAY,CAAC,GAAG,CACd,mBAAmB,EACnB,mBAAmB,EACnB,4BAA4B,EAC5B,iEAAiE,EACjE,KAAK,CACN,CAAC;QAGF,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;;;;;;;;KAcvB,CAAC,CAAC;QAEH,IAAI,aAAa,GAAG,CAAC,CAAC;QAGtB,KAAK,MAAM,YAAY,IAAI,iBAAiB,CAAC,QAAQ,EAAE,CAAC;YACtD,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,GAAG,YAAY,CAAC;YAE3D,eAAM,CAAC,IAAI,CAAC,wBAAwB,YAAY,EAAE,EAAE;gBAClD,QAAQ,EAAE,SAAS;gBACnB,YAAY,EAAE,QAAQ,CAAC,MAAM;aAC9B,CAAC,CAAC;YAEH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAG5B,MAAM,UAAU,GAAG,mBAAmB,CAAC;gBACvC,MAAM,YAAY,GAAG,cAAc,YAAY,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;gBAGpE,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBACrD,MAAM,cAAc,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAGvH,IAAI,CAAC,GAAG,CACN,SAAS,EACT,UAAU,EACV,YAAY,EACZ,KAAK,EACL,OAAO,CAAC,IAAI,EACZ,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,EAClC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,EAChE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAC3B,cAAc,EACd,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,QAAQ,CACjB,CAAC;gBAEF,aAAa,EAAE,CAAC;gBAChB,eAAM,CAAC,IAAI,CAAC,eAAe,OAAO,CAAC,IAAI,EAAE,EAAE;oBACzC,UAAU,EAAE,OAAO,CAAC,UAAU;oBAC9B,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW;oBACrC,cAAc,EAAE,cAAc,KAAK,CAAC;iBACrC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,EAAE,CAAC,KAAK,EAAE,CAAC;QAEX,eAAM,CAAC,IAAI,CAAC,qCAAqC,EAAE;YACjD,aAAa,EAAE,aAAa;YAC5B,KAAK,EAAE,iBAAiB,CAAC,QAAQ,CAAC,MAAM;SACzC,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,yBAAyB,EAAE,aAAa,EAAE,4BAA4B,CAAC,CAAC;QACpF,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAC;QACrF,OAAO,CAAC,GAAG,CAAC,wFAAwF,CAAC,CAAC;IAExG,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7D,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAGD,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,qBAAqB,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC/C,CAAC"} \ No newline at end of file diff --git a/dist/scripts/test-autofix-documentation.d.ts b/dist/scripts/test-autofix-documentation.d.ts new file mode 100644 index 0000000..4532f3e --- /dev/null +++ b/dist/scripts/test-autofix-documentation.d.ts @@ -0,0 +1,3 @@ +#!/usr/bin/env npx tsx +export {}; +//# sourceMappingURL=test-autofix-documentation.d.ts.map \ No newline at end of file diff --git a/dist/scripts/test-autofix-documentation.d.ts.map b/dist/scripts/test-autofix-documentation.d.ts.map new file mode 100644 index 0000000..981a076 --- /dev/null +++ b/dist/scripts/test-autofix-documentation.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"test-autofix-documentation.d.ts","sourceRoot":"","sources":["../../src/scripts/test-autofix-documentation.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/scripts/test-autofix-documentation.js b/dist/scripts/test-autofix-documentation.js new file mode 100644 index 0000000..5c7651f --- /dev/null +++ b/dist/scripts/test-autofix-documentation.js @@ -0,0 +1,103 @@ +#!/usr/bin/env npx tsx +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tool_docs_1 = require("../mcp/tool-docs"); +const tools_documentation_1 = require("../mcp/tools-documentation"); +const logger_1 = require("../utils/logger"); +const logger = new logger_1.Logger({ prefix: '[AutofixDoc Test]' }); +async function testAutofixDocumentation() { + logger.info('Testing n8n_autofix_workflow documentation...\n'); + logger.info('Test 1: Checking documentation registry'); + const hasDoc = 'n8n_autofix_workflow' in tool_docs_1.toolsDocumentation; + if (hasDoc) { + logger.info('✅ Documentation found in registry'); + } + else { + logger.error('❌ Documentation NOT found in registry'); + logger.info('Available tools:', Object.keys(tool_docs_1.toolsDocumentation).filter(k => k.includes('autofix'))); + } + if (hasDoc) { + logger.info('\nTest 2: Checking documentation structure'); + const doc = tool_docs_1.toolsDocumentation['n8n_autofix_workflow']; + const hasEssentials = doc.essentials && + doc.essentials.description && + doc.essentials.keyParameters && + doc.essentials.example; + const hasFull = doc.full && + doc.full.description && + doc.full.parameters && + doc.full.examples; + if (hasEssentials) { + logger.info('✅ Essentials documentation complete'); + logger.info(` Description: ${doc.essentials.description.substring(0, 80)}...`); + logger.info(` Key params: ${doc.essentials.keyParameters.join(', ')}`); + } + else { + logger.error('❌ Essentials documentation incomplete'); + } + if (hasFull) { + logger.info('✅ Full documentation complete'); + logger.info(` Parameters: ${Object.keys(doc.full.parameters).join(', ')}`); + logger.info(` Examples: ${doc.full.examples.length} provided`); + } + else { + logger.error('❌ Full documentation incomplete'); + } + } + logger.info('\nTest 3: Testing getToolDocumentation function'); + try { + const essentialsDoc = (0, tools_documentation_1.getToolDocumentation)('n8n_autofix_workflow', 'essentials'); + if (essentialsDoc.includes("Tool 'n8n_autofix_workflow' not found")) { + logger.error('❌ Essentials documentation retrieval failed'); + } + else { + logger.info('✅ Essentials documentation retrieved'); + const lines = essentialsDoc.split('\n').slice(0, 3); + lines.forEach(line => logger.info(` ${line}`)); + } + } + catch (error) { + logger.error('❌ Error retrieving essentials documentation:', error); + } + try { + const fullDoc = (0, tools_documentation_1.getToolDocumentation)('n8n_autofix_workflow', 'full'); + if (fullDoc.includes("Tool 'n8n_autofix_workflow' not found")) { + logger.error('❌ Full documentation retrieval failed'); + } + else { + logger.info('✅ Full documentation retrieved'); + const lines = fullDoc.split('\n').slice(0, 3); + lines.forEach(line => logger.info(` ${line}`)); + } + } + catch (error) { + logger.error('❌ Error retrieving full documentation:', error); + } + logger.info('\nTest 4: Checking workflow management tools listing'); + const workflowTools = Object.keys(tool_docs_1.toolsDocumentation).filter(k => k.startsWith('n8n_')); + const hasAutofix = workflowTools.includes('n8n_autofix_workflow'); + if (hasAutofix) { + logger.info('✅ n8n_autofix_workflow is listed in workflow management tools'); + logger.info(` Total workflow tools: ${workflowTools.length}`); + const relatedTools = workflowTools.filter(t => t.includes('validate') || t.includes('update') || t.includes('fix')); + logger.info(` Related tools: ${relatedTools.join(', ')}`); + } + else { + logger.error('❌ n8n_autofix_workflow NOT listed in workflow management tools'); + } + logger.info('\n' + '='.repeat(60)); + logger.info('Summary:'); + if (hasDoc && hasAutofix) { + logger.info('✨ Documentation integration successful!'); + logger.info('The n8n_autofix_workflow tool documentation is properly integrated.'); + logger.info('\nTo use in MCP:'); + logger.info(' - Essentials: tools_documentation({topic: "n8n_autofix_workflow"})'); + logger.info(' - Full: tools_documentation({topic: "n8n_autofix_workflow", depth: "full"})'); + } + else { + logger.error('⚠️ Documentation integration incomplete'); + logger.info('Please check the implementation and rebuild the project.'); + } +} +testAutofixDocumentation().catch(console.error); +//# sourceMappingURL=test-autofix-documentation.js.map \ No newline at end of file diff --git a/dist/scripts/test-autofix-documentation.js.map b/dist/scripts/test-autofix-documentation.js.map new file mode 100644 index 0000000..b37a3bf --- /dev/null +++ b/dist/scripts/test-autofix-documentation.js.map @@ -0,0 +1 @@ +{"version":3,"file":"test-autofix-documentation.js","sourceRoot":"","sources":["../../src/scripts/test-autofix-documentation.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/scripts/test-autofix-workflow.d.ts b/dist/scripts/test-autofix-workflow.d.ts new file mode 100644 index 0000000..005ac22 --- /dev/null +++ b/dist/scripts/test-autofix-workflow.d.ts @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=test-autofix-workflow.d.ts.map \ No newline at end of file diff --git a/dist/scripts/test-autofix-workflow.d.ts.map b/dist/scripts/test-autofix-workflow.d.ts.map new file mode 100644 index 0000000..4d15a00 --- /dev/null +++ b/dist/scripts/test-autofix-workflow.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"test-autofix-workflow.d.ts","sourceRoot":"","sources":["../../src/scripts/test-autofix-workflow.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/scripts/test-autofix-workflow.js b/dist/scripts/test-autofix-workflow.js new file mode 100644 index 0000000..e96c0e0 --- /dev/null +++ b/dist/scripts/test-autofix-workflow.js @@ -0,0 +1,223 @@ +"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 }); +const workflow_auto_fixer_1 = require("../services/workflow-auto-fixer"); +const workflow_validator_1 = require("../services/workflow-validator"); +const enhanced_config_validator_1 = require("../services/enhanced-config-validator"); +const expression_format_validator_1 = require("../services/expression-format-validator"); +const node_repository_1 = require("../database/node-repository"); +const logger_1 = require("../utils/logger"); +const database_adapter_1 = require("../database/database-adapter"); +const path = __importStar(require("path")); +const logger = new logger_1.Logger({ prefix: '[TestAutofix]' }); +async function testAutofix() { + const dbPath = path.join(__dirname, '../../data/nodes.db'); + const dbAdapter = await (0, database_adapter_1.createDatabaseAdapter)(dbPath); + const repository = new node_repository_1.NodeRepository(dbAdapter); + const testWorkflow = { + id: 'test_workflow_1', + name: 'Test Workflow for Autofix', + nodes: [ + { + id: 'webhook_1', + name: 'Webhook', + type: 'n8n-nodes-base.webhook', + typeVersion: 1.1, + position: [250, 300], + parameters: { + httpMethod: 'GET', + path: 'test-webhook', + responseMode: 'onReceived', + responseData: 'firstEntryJson' + } + }, + { + id: 'http_1', + name: 'HTTP Request', + type: 'n8n-nodes-base.httpRequest', + typeVersion: 5.0, + position: [450, 300], + parameters: { + method: 'GET', + url: '{{ $json.webhookUrl }}', + sendHeaders: true, + headerParameters: { + parameters: [ + { + name: 'Authorization', + value: '{{ $json.token }}' + } + ] + } + }, + onError: 'continueErrorOutput' + }, + { + id: 'set_1', + name: 'Set', + type: 'n8n-nodes-base.set', + typeVersion: 3.5, + position: [650, 300], + parameters: { + mode: 'manual', + duplicateItem: false, + values: { + values: [ + { + name: 'status', + value: '{{ $json.success }}' + } + ] + } + } + } + ], + connections: { + 'Webhook': { + main: [ + [ + { + node: 'HTTP Request', + type: 'main', + index: 0 + } + ] + ] + }, + 'HTTP Request': { + main: [ + [ + { + node: 'Set', + type: 'main', + index: 0 + } + ] + ] + } + } + }; + logger.info('=== Testing Workflow Auto-Fixer ===\n'); + logger.info('Step 1: Validating workflow to identify issues...'); + const validator = new workflow_validator_1.WorkflowValidator(repository, enhanced_config_validator_1.EnhancedConfigValidator); + const validationResult = await validator.validateWorkflow(testWorkflow, { + validateNodes: true, + validateConnections: true, + validateExpressions: true, + profile: 'ai-friendly' + }); + logger.info(`Found ${validationResult.errors.length} errors and ${validationResult.warnings.length} warnings`); + logger.info('\nStep 2: Checking for expression format issues...'); + const allFormatIssues = []; + for (const node of testWorkflow.nodes) { + const formatContext = { + nodeType: node.type, + nodeName: node.name, + nodeId: node.id + }; + const nodeFormatIssues = expression_format_validator_1.ExpressionFormatValidator.validateNodeParameters(node.parameters, formatContext); + const enrichedIssues = nodeFormatIssues.map(issue => ({ + ...issue, + nodeName: node.name, + nodeId: node.id + })); + allFormatIssues.push(...enrichedIssues); + } + logger.info(`Found ${allFormatIssues.length} expression format issues`); + if (allFormatIssues.length > 0) { + logger.info('\nExpression format issues found:'); + for (const issue of allFormatIssues) { + logger.info(` - ${issue.fieldPath}: ${issue.issueType} (${issue.severity})`); + logger.info(` Current: ${JSON.stringify(issue.currentValue)}`); + logger.info(` Fixed: ${JSON.stringify(issue.correctedValue)}`); + } + } + logger.info('\nStep 3: Generating fixes (preview mode)...'); + const autoFixer = new workflow_auto_fixer_1.WorkflowAutoFixer(); + const previewResult = await autoFixer.generateFixes(testWorkflow, validationResult, allFormatIssues, { + applyFixes: false, + confidenceThreshold: 'medium' + }); + logger.info(`\nGenerated ${previewResult.fixes.length} fixes:`); + logger.info(`Summary: ${previewResult.summary}`); + logger.info('\nFixes by type:'); + for (const [type, count] of Object.entries(previewResult.stats.byType)) { + if (count > 0) { + logger.info(` - ${type}: ${count}`); + } + } + logger.info('\nFixes by confidence:'); + for (const [confidence, count] of Object.entries(previewResult.stats.byConfidence)) { + if (count > 0) { + logger.info(` - ${confidence}: ${count}`); + } + } + logger.info('\nDetailed fixes:'); + for (const fix of previewResult.fixes) { + logger.info(`\n[${fix.confidence.toUpperCase()}] ${fix.node}.${fix.field} (${fix.type})`); + logger.info(` Before: ${JSON.stringify(fix.before)}`); + logger.info(` After: ${JSON.stringify(fix.after)}`); + logger.info(` Description: ${fix.description}`); + } + logger.info('\n\nGenerated diff operations:'); + for (const op of previewResult.operations) { + logger.info(`\nOperation: ${op.type}`); + logger.info(` Details: ${JSON.stringify(op, null, 2)}`); + } + logger.info('\n\n=== Testing Different Confidence Thresholds ==='); + for (const threshold of ['high', 'medium', 'low']) { + const result = await autoFixer.generateFixes(testWorkflow, validationResult, allFormatIssues, { + applyFixes: false, + confidenceThreshold: threshold + }); + logger.info(`\nThreshold "${threshold}": ${result.fixes.length} fixes`); + } + logger.info('\n\n=== Testing Specific Fix Types ==='); + const fixTypes = ['expression-format', 'typeversion-correction', 'error-output-config']; + for (const fixType of fixTypes) { + const result = await autoFixer.generateFixes(testWorkflow, validationResult, allFormatIssues, { + applyFixes: false, + fixTypes: [fixType] + }); + logger.info(`\nFix type "${fixType}": ${result.fixes.length} fixes`); + } + logger.info('\n\n✅ Autofix test completed successfully!'); + await dbAdapter.close(); +} +testAutofix().catch(error => { + logger.error('Test failed:', error); + process.exit(1); +}); +//# sourceMappingURL=test-autofix-workflow.js.map \ No newline at end of file diff --git a/dist/scripts/test-autofix-workflow.js.map b/dist/scripts/test-autofix-workflow.js.map new file mode 100644 index 0000000..7616e6a --- /dev/null +++ b/dist/scripts/test-autofix-workflow.js.map @@ -0,0 +1 @@ +{"version":3,"file":"test-autofix-workflow.js","sourceRoot":"","sources":["../../src/scripts/test-autofix-workflow.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/scripts/test-execution-filtering.d.ts b/dist/scripts/test-execution-filtering.d.ts new file mode 100644 index 0000000..914ac84 --- /dev/null +++ b/dist/scripts/test-execution-filtering.d.ts @@ -0,0 +1,3 @@ +#!/usr/bin/env node +export {}; +//# sourceMappingURL=test-execution-filtering.d.ts.map \ No newline at end of file diff --git a/dist/scripts/test-execution-filtering.d.ts.map b/dist/scripts/test-execution-filtering.d.ts.map new file mode 100644 index 0000000..45ac11b --- /dev/null +++ b/dist/scripts/test-execution-filtering.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"test-execution-filtering.d.ts","sourceRoot":"","sources":["../../src/scripts/test-execution-filtering.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/scripts/test-execution-filtering.js b/dist/scripts/test-execution-filtering.js new file mode 100644 index 0000000..0e657cd --- /dev/null +++ b/dist/scripts/test-execution-filtering.js @@ -0,0 +1,206 @@ +#!/usr/bin/env node +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const execution_processor_1 = require("../services/execution-processor"); +const n8n_api_1 = require("../types/n8n-api"); +console.log('='.repeat(80)); +console.log('Execution Filtering Feature - Manual Test Suite'); +console.log('='.repeat(80)); +console.log(''); +function createTestExecution(itemCount) { + const items = Array.from({ length: itemCount }, (_, i) => ({ + json: { + id: i + 1, + name: `Item ${i + 1}`, + email: `user${i}@example.com`, + value: Math.random() * 1000, + metadata: { + createdAt: new Date().toISOString(), + tags: ['tag1', 'tag2'], + }, + }, + })); + return { + id: `test-exec-${Date.now()}`, + workflowId: 'workflow-test', + status: n8n_api_1.ExecutionStatus.SUCCESS, + mode: 'manual', + finished: true, + startedAt: '2024-01-01T10:00:00.000Z', + stoppedAt: '2024-01-01T10:00:05.000Z', + data: { + resultData: { + runData: { + 'HTTP Request': [ + { + startTime: Date.now(), + executionTime: 234, + data: { + main: [items], + }, + }, + ], + 'Filter': [ + { + startTime: Date.now(), + executionTime: 45, + data: { + main: [items.slice(0, Math.floor(itemCount / 2))], + }, + }, + ], + 'Set': [ + { + startTime: Date.now(), + executionTime: 12, + data: { + main: [items.slice(0, 5)], + }, + }, + ], + }, + }, + }, + }; +} +console.log('📊 TEST 1: Preview Mode (No Data, Just Structure)'); +console.log('-'.repeat(80)); +const execution1 = createTestExecution(50); +const { preview, recommendation } = (0, execution_processor_1.generatePreview)(execution1); +console.log('Preview:', JSON.stringify(preview, null, 2)); +console.log('\nRecommendation:', JSON.stringify(recommendation, null, 2)); +console.log('\n✅ Preview mode shows structure without consuming tokens for data\n'); +console.log('📝 TEST 2: Summary Mode (2 items per node)'); +console.log('-'.repeat(80)); +const execution2 = createTestExecution(50); +const summaryResult = (0, execution_processor_1.filterExecutionData)(execution2, { mode: 'summary' }); +console.log('Summary Mode Result:'); +console.log('- Mode:', summaryResult.mode); +console.log('- Summary:', JSON.stringify(summaryResult.summary, null, 2)); +console.log('- HTTP Request items shown:', summaryResult.nodes?.['HTTP Request']?.data?.metadata.itemsShown); +console.log('- HTTP Request truncated:', summaryResult.nodes?.['HTTP Request']?.data?.metadata.truncated); +console.log('\n✅ Summary mode returns 2 items per node (safe default)\n'); +console.log('🎯 TEST 3: Filtered Mode (Custom itemsLimit: 5)'); +console.log('-'.repeat(80)); +const execution3 = createTestExecution(100); +const filteredResult = (0, execution_processor_1.filterExecutionData)(execution3, { + mode: 'filtered', + itemsLimit: 5, +}); +console.log('Filtered Mode Result:'); +console.log('- Items shown per node:', filteredResult.nodes?.['HTTP Request']?.data?.metadata.itemsShown); +console.log('- Total items available:', filteredResult.nodes?.['HTTP Request']?.data?.metadata.totalItems); +console.log('- More data available:', filteredResult.summary?.hasMoreData); +console.log('\n✅ Filtered mode allows custom item limits\n'); +console.log('🔍 TEST 4: Filter to Specific Nodes'); +console.log('-'.repeat(80)); +const execution4 = createTestExecution(30); +const nodeFilterResult = (0, execution_processor_1.filterExecutionData)(execution4, { + mode: 'filtered', + nodeNames: ['HTTP Request'], + itemsLimit: 3, +}); +console.log('Node Filter Result:'); +console.log('- Nodes in result:', Object.keys(nodeFilterResult.nodes || {})); +console.log('- Expected: ["HTTP Request"]'); +console.log('- Executed nodes:', nodeFilterResult.summary?.executedNodes); +console.log('- Total nodes:', nodeFilterResult.summary?.totalNodes); +console.log('\n✅ Can filter to specific nodes only\n'); +console.log('🏗️ TEST 5: Structure-Only Mode (itemsLimit: 0)'); +console.log('-'.repeat(80)); +const execution5 = createTestExecution(100); +const structureResult = (0, execution_processor_1.filterExecutionData)(execution5, { + mode: 'filtered', + itemsLimit: 0, +}); +console.log('Structure-Only Result:'); +console.log('- Items shown:', structureResult.nodes?.['HTTP Request']?.data?.metadata.itemsShown); +console.log('- First item (structure):', JSON.stringify(structureResult.nodes?.['HTTP Request']?.data?.output?.[0]?.[0], null, 2)); +console.log('\n✅ Structure-only mode shows data shape without values\n'); +console.log('💾 TEST 6: Full Mode (All Data)'); +console.log('-'.repeat(80)); +const execution6 = createTestExecution(5); +const fullResult = (0, execution_processor_1.filterExecutionData)(execution6, { mode: 'full' }); +console.log('Full Mode Result:'); +console.log('- Items shown:', fullResult.nodes?.['HTTP Request']?.data?.metadata.itemsShown); +console.log('- Total items:', fullResult.nodes?.['HTTP Request']?.data?.metadata.totalItems); +console.log('- Truncated:', fullResult.nodes?.['HTTP Request']?.data?.metadata.truncated); +console.log('\n✅ Full mode returns all data (use with caution)\n'); +console.log('🔄 TEST 7: Backward Compatibility (No Filtering)'); +console.log('-'.repeat(80)); +const execution7 = createTestExecution(10); +const legacyResult = (0, execution_processor_1.processExecution)(execution7, {}); +console.log('Legacy Result:'); +console.log('- Returns original execution:', legacyResult === execution7); +console.log('- Type:', typeof legacyResult); +console.log('\n✅ Backward compatible - no options returns original execution\n'); +console.log('🔗 TEST 8: Include Input Data'); +console.log('-'.repeat(80)); +const execution8 = createTestExecution(5); +const inputDataResult = (0, execution_processor_1.filterExecutionData)(execution8, { + mode: 'filtered', + itemsLimit: 2, + includeInputData: true, +}); +console.log('Input Data Result:'); +console.log('- Has input data:', !!inputDataResult.nodes?.['HTTP Request']?.data?.input); +console.log('- Has output data:', !!inputDataResult.nodes?.['HTTP Request']?.data?.output); +console.log('\n✅ Can include input data for debugging\n'); +console.log('⚠️ TEST 9: itemsLimit Validation'); +console.log('-'.repeat(80)); +const execution9 = createTestExecution(50); +const negativeResult = (0, execution_processor_1.filterExecutionData)(execution9, { + mode: 'filtered', + itemsLimit: -5, +}); +console.log('- Negative itemsLimit (-5) handled:', negativeResult.nodes?.['HTTP Request']?.data?.metadata.itemsShown === 2); +const largeResult = (0, execution_processor_1.filterExecutionData)(execution9, { + mode: 'filtered', + itemsLimit: 999999, +}); +console.log('- Large itemsLimit (999999) capped:', (largeResult.nodes?.['HTTP Request']?.data?.metadata.itemsShown || 0) <= 1000); +const unlimitedResult = (0, execution_processor_1.filterExecutionData)(execution9, { + mode: 'filtered', + itemsLimit: -1, +}); +console.log('- Unlimited itemsLimit (-1) works:', unlimitedResult.nodes?.['HTTP Request']?.data?.metadata.itemsShown === 50); +console.log('\n✅ itemsLimit validation works correctly\n'); +console.log('🎯 TEST 10: Follow Recommendation Workflow'); +console.log('-'.repeat(80)); +const execution10 = createTestExecution(100); +const { preview: preview10, recommendation: rec10 } = (0, execution_processor_1.generatePreview)(execution10); +console.log('1. Preview shows:', { + totalItems: preview10.nodes['HTTP Request']?.itemCounts.output, + sizeKB: preview10.estimatedSizeKB, +}); +console.log('\n2. Recommendation:', { + canFetchFull: rec10.canFetchFull, + suggestedMode: rec10.suggestedMode, + suggestedItemsLimit: rec10.suggestedItemsLimit, + reason: rec10.reason, +}); +const options = { + mode: rec10.suggestedMode, + itemsLimit: rec10.suggestedItemsLimit, +}; +const recommendedResult = (0, execution_processor_1.filterExecutionData)(execution10, options); +console.log('\n3. Following recommendation gives:', { + mode: recommendedResult.mode, + itemsShown: recommendedResult.nodes?.['HTTP Request']?.data?.metadata.itemsShown, + hasMoreData: recommendedResult.summary?.hasMoreData, +}); +console.log('\n✅ Recommendation workflow helps make optimal choices\n'); +console.log('='.repeat(80)); +console.log('✨ All Tests Completed Successfully!'); +console.log('='.repeat(80)); +console.log('\n🎉 Execution Filtering Feature is Working!\n'); +console.log('Key Takeaways:'); +console.log('1. Always use preview mode first for unknown datasets'); +console.log('2. Follow the recommendation for optimal token usage'); +console.log('3. Use nodeNames to filter to relevant nodes'); +console.log('4. itemsLimit: 0 shows structure without data'); +console.log('5. itemsLimit: -1 returns unlimited items (use with caution)'); +console.log('6. Summary mode (2 items) is a safe default'); +console.log('7. Full mode should only be used for small datasets'); +console.log(''); +//# sourceMappingURL=test-execution-filtering.js.map \ No newline at end of file diff --git a/dist/scripts/test-execution-filtering.js.map b/dist/scripts/test-execution-filtering.js.map new file mode 100644 index 0000000..9972159 --- /dev/null +++ b/dist/scripts/test-execution-filtering.js.map @@ -0,0 +1 @@ +{"version":3,"file":"test-execution-filtering.js","sourceRoot":"","sources":["../../src/scripts/test-execution-filtering.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/scripts/test-node-suggestions.d.ts b/dist/scripts/test-node-suggestions.d.ts new file mode 100644 index 0000000..ade8fd3 --- /dev/null +++ b/dist/scripts/test-node-suggestions.d.ts @@ -0,0 +1,3 @@ +#!/usr/bin/env npx tsx +export {}; +//# sourceMappingURL=test-node-suggestions.d.ts.map \ No newline at end of file diff --git a/dist/scripts/test-node-suggestions.d.ts.map b/dist/scripts/test-node-suggestions.d.ts.map new file mode 100644 index 0000000..8958e90 --- /dev/null +++ b/dist/scripts/test-node-suggestions.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"test-node-suggestions.d.ts","sourceRoot":"","sources":["../../src/scripts/test-node-suggestions.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/scripts/test-node-suggestions.js b/dist/scripts/test-node-suggestions.js new file mode 100644 index 0000000..6095ce0 --- /dev/null +++ b/dist/scripts/test-node-suggestions.js @@ -0,0 +1,165 @@ +#!/usr/bin/env npx tsx +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const database_adapter_1 = require("../database/database-adapter"); +const node_repository_1 = require("../database/node-repository"); +const node_similarity_service_1 = require("../services/node-similarity-service"); +const workflow_validator_1 = require("../services/workflow-validator"); +const enhanced_config_validator_1 = require("../services/enhanced-config-validator"); +const workflow_auto_fixer_1 = require("../services/workflow-auto-fixer"); +const logger_1 = require("../utils/logger"); +const path_1 = __importDefault(require("path")); +const logger = new logger_1.Logger({ prefix: '[NodeSuggestions Test]' }); +const console = { + log: (msg) => logger.info(msg), + error: (msg, err) => logger.error(msg, err) +}; +async function testNodeSimilarity() { + console.log('🔍 Testing Enhanced Node Type Suggestions\n'); + const dbPath = path_1.default.join(process.cwd(), 'data/nodes.db'); + const db = await (0, database_adapter_1.createDatabaseAdapter)(dbPath); + const repository = new node_repository_1.NodeRepository(db); + const similarityService = new node_similarity_service_1.NodeSimilarityService(repository); + const validator = new workflow_validator_1.WorkflowValidator(repository, enhanced_config_validator_1.EnhancedConfigValidator); + const testCases = [ + { invalid: 'HttpRequest', expected: 'nodes-base.httpRequest' }, + { invalid: 'HTTPRequest', expected: 'nodes-base.httpRequest' }, + { invalid: 'Webhook', expected: 'nodes-base.webhook' }, + { invalid: 'WebHook', expected: 'nodes-base.webhook' }, + { invalid: 'slack', expected: 'nodes-base.slack' }, + { invalid: 'googleSheets', expected: 'nodes-base.googleSheets' }, + { invalid: 'telegram', expected: 'nodes-base.telegram' }, + { invalid: 'htpRequest', expected: 'nodes-base.httpRequest' }, + { invalid: 'webook', expected: 'nodes-base.webhook' }, + { invalid: 'slak', expected: 'nodes-base.slack' }, + { invalid: 'http', expected: 'nodes-base.httpRequest' }, + { invalid: 'sheet', expected: 'nodes-base.googleSheets' }, + { invalid: 'nodes-base.openai', expected: 'nodes-langchain.openAi' }, + { invalid: 'n8n-nodes-base.httpRequest', expected: 'nodes-base.httpRequest' }, + { invalid: 'foobar', expected: null }, + { invalid: 'xyz123', expected: null }, + ]; + console.log('Testing individual node type suggestions:'); + console.log('='.repeat(60)); + for (const testCase of testCases) { + const suggestions = await similarityService.findSimilarNodes(testCase.invalid, 3); + console.log(`\n❌ Invalid type: "${testCase.invalid}"`); + if (suggestions.length > 0) { + console.log('✨ Suggestions:'); + for (const suggestion of suggestions) { + const confidence = Math.round(suggestion.confidence * 100); + const marker = suggestion.nodeType === testCase.expected ? '✅' : ' '; + console.log(`${marker} ${suggestion.nodeType} (${confidence}% match) - ${suggestion.reason}`); + if (suggestion.confidence >= 0.9) { + console.log(' 💡 Can be auto-fixed!'); + } + } + if (testCase.expected) { + const found = suggestions.some(s => s.nodeType === testCase.expected); + if (!found) { + console.log(` ⚠️ Expected "${testCase.expected}" was not suggested!`); + } + } + } + else { + console.log(' No suggestions found'); + if (testCase.expected) { + console.log(` ⚠️ Expected "${testCase.expected}" was not suggested!`); + } + } + } + console.log('\n' + '='.repeat(60)); + console.log('\n📋 Testing workflow validation with unknown nodes:'); + console.log('='.repeat(60)); + const testWorkflow = { + id: 'test-workflow', + name: 'Test Workflow', + nodes: [ + { + id: '1', + name: 'Start', + type: 'nodes-base.manualTrigger', + position: [100, 100], + parameters: {}, + typeVersion: 1 + }, + { + id: '2', + name: 'HTTP Request', + type: 'HTTPRequest', + position: [300, 100], + parameters: {}, + typeVersion: 1 + }, + { + id: '3', + name: 'Slack', + type: 'slack', + position: [500, 100], + parameters: {}, + typeVersion: 1 + }, + { + id: '4', + name: 'Unknown', + type: 'foobar', + position: [700, 100], + parameters: {}, + typeVersion: 1 + } + ], + connections: { + 'Start': { + main: [[{ node: 'HTTP Request', type: 'main', index: 0 }]] + }, + 'HTTP Request': { + main: [[{ node: 'Slack', type: 'main', index: 0 }]] + }, + 'Slack': { + main: [[{ node: 'Unknown', type: 'main', index: 0 }]] + } + }, + settings: {} + }; + const validationResult = await validator.validateWorkflow(testWorkflow, { + validateNodes: true, + validateConnections: false, + validateExpressions: false, + profile: 'runtime' + }); + console.log('\nValidation Results:'); + for (const error of validationResult.errors) { + if (error.message?.includes('Unknown node type:')) { + console.log(`\n🔴 ${error.nodeName}: ${error.message}`); + } + } + console.log('\n' + '='.repeat(60)); + console.log('\n🔧 Testing AutoFixer with node type corrections:'); + console.log('='.repeat(60)); + const autoFixer = new workflow_auto_fixer_1.WorkflowAutoFixer(repository); + const fixResult = await autoFixer.generateFixes(testWorkflow, validationResult, [], { + applyFixes: false, + fixTypes: ['node-type-correction'], + confidenceThreshold: 'high' + }); + if (fixResult.fixes.length > 0) { + console.log('\n✅ Auto-fixable issues found:'); + for (const fix of fixResult.fixes) { + console.log(` • ${fix.description}`); + } + console.log(`\nSummary: ${fixResult.summary}`); + } + else { + console.log('\n❌ No auto-fixable node type issues found (only high-confidence fixes are applied)'); + } + console.log('\n' + '='.repeat(60)); + console.log('\n✨ Test complete!'); +} +testNodeSimilarity().catch(error => { + console.error('Test failed:', error); + process.exit(1); +}); +//# sourceMappingURL=test-node-suggestions.js.map \ No newline at end of file diff --git a/dist/scripts/test-node-suggestions.js.map b/dist/scripts/test-node-suggestions.js.map new file mode 100644 index 0000000..268d1fd --- /dev/null +++ b/dist/scripts/test-node-suggestions.js.map @@ -0,0 +1 @@ +{"version":3,"file":"test-node-suggestions.js","sourceRoot":"","sources":["../../src/scripts/test-node-suggestions.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/scripts/test-protocol-negotiation.d.ts b/dist/scripts/test-protocol-negotiation.d.ts new file mode 100644 index 0000000..b634a5d --- /dev/null +++ b/dist/scripts/test-protocol-negotiation.d.ts @@ -0,0 +1,3 @@ +#!/usr/bin/env node +export {}; +//# sourceMappingURL=test-protocol-negotiation.d.ts.map \ No newline at end of file diff --git a/dist/scripts/test-protocol-negotiation.d.ts.map b/dist/scripts/test-protocol-negotiation.d.ts.map new file mode 100644 index 0000000..29778b6 --- /dev/null +++ b/dist/scripts/test-protocol-negotiation.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"test-protocol-negotiation.d.ts","sourceRoot":"","sources":["../../src/scripts/test-protocol-negotiation.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/scripts/test-protocol-negotiation.js b/dist/scripts/test-protocol-negotiation.js new file mode 100644 index 0000000..124bf90 --- /dev/null +++ b/dist/scripts/test-protocol-negotiation.js @@ -0,0 +1,154 @@ +#!/usr/bin/env node +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const protocol_version_1 = require("../utils/protocol-version"); +const testCases = [ + { + name: 'Standard MCP client (Claude Desktop)', + clientVersion: '2025-03-26', + clientInfo: { name: 'Claude Desktop', version: '1.0.0' }, + expectedVersion: '2025-03-26', + expectedIsN8nClient: false + }, + { + name: 'n8n client with specific client info', + clientVersion: '2025-03-26', + clientInfo: { name: 'n8n', version: '1.0.0' }, + expectedVersion: protocol_version_1.N8N_PROTOCOL_VERSION, + expectedIsN8nClient: true + }, + { + name: 'LangChain client', + clientVersion: '2025-03-26', + clientInfo: { name: 'langchain-js', version: '0.1.0' }, + expectedVersion: protocol_version_1.N8N_PROTOCOL_VERSION, + expectedIsN8nClient: true + }, + { + name: 'n8n client via user agent', + clientVersion: '2025-03-26', + userAgent: 'n8n/1.0.0', + expectedVersion: protocol_version_1.N8N_PROTOCOL_VERSION, + expectedIsN8nClient: true + }, + { + name: 'n8n mode environment variable', + clientVersion: '2025-03-26', + expectedVersion: protocol_version_1.N8N_PROTOCOL_VERSION, + expectedIsN8nClient: true + }, + { + name: 'Client requesting older version', + clientVersion: '2024-06-25', + clientInfo: { name: 'Some Client', version: '1.0.0' }, + expectedVersion: '2024-06-25', + expectedIsN8nClient: false + }, + { + name: 'Client requesting unsupported version', + clientVersion: '2020-01-01', + clientInfo: { name: 'Old Client', version: '1.0.0' }, + expectedVersion: protocol_version_1.STANDARD_PROTOCOL_VERSION, + expectedIsN8nClient: false + }, + { + name: 'No client info provided', + expectedVersion: protocol_version_1.STANDARD_PROTOCOL_VERSION, + expectedIsN8nClient: false + }, + { + name: 'n8n headers detection', + clientVersion: '2025-03-26', + headers: { 'x-n8n-version': '1.0.0' }, + expectedVersion: protocol_version_1.N8N_PROTOCOL_VERSION, + expectedIsN8nClient: true + } +]; +async function runTests() { + console.log('🧪 Testing Protocol Version Negotiation\n'); + let passed = 0; + let failed = 0; + const originalN8nMode = process.env.N8N_MODE; + for (const testCase of testCases) { + try { + if (testCase.name.includes('environment variable')) { + process.env.N8N_MODE = 'true'; + } + else { + delete process.env.N8N_MODE; + } + const detectedAsN8n = (0, protocol_version_1.isN8nClient)(testCase.clientInfo, testCase.userAgent, testCase.headers); + const result = (0, protocol_version_1.negotiateProtocolVersion)(testCase.clientVersion, testCase.clientInfo, testCase.userAgent, testCase.headers); + const versionCorrect = result.version === testCase.expectedVersion; + const n8nDetectionCorrect = result.isN8nClient === testCase.expectedIsN8nClient; + const isN8nFunctionCorrect = detectedAsN8n === testCase.expectedIsN8nClient; + if (versionCorrect && n8nDetectionCorrect && isN8nFunctionCorrect) { + console.log(`✅ ${testCase.name}`); + console.log(` Version: ${result.version}, n8n client: ${result.isN8nClient}`); + console.log(` Reasoning: ${result.reasoning}\n`); + passed++; + } + else { + console.log(`❌ ${testCase.name}`); + console.log(` Expected: version=${testCase.expectedVersion}, isN8n=${testCase.expectedIsN8nClient}`); + console.log(` Got: version=${result.version}, isN8n=${result.isN8nClient}`); + console.log(` isN8nClient function: ${detectedAsN8n} (expected: ${testCase.expectedIsN8nClient})`); + console.log(` Reasoning: ${result.reasoning}\n`); + failed++; + } + } + catch (error) { + console.log(`💥 ${testCase.name} - ERROR`); + console.log(` ${error instanceof Error ? error.message : String(error)}\n`); + failed++; + } + } + if (originalN8nMode) { + process.env.N8N_MODE = originalN8nMode; + } + else { + delete process.env.N8N_MODE; + } + console.log(`\n📊 Test Results:`); + console.log(` ✅ Passed: ${passed}`); + console.log(` ❌ Failed: ${failed}`); + console.log(` Total: ${passed + failed}`); + if (failed > 0) { + console.log(`\n❌ Some tests failed!`); + process.exit(1); + } + else { + console.log(`\n🎉 All tests passed!`); + } +} +async function testIntegration() { + console.log('\n🔧 Integration Test - MCP Server Protocol Negotiation\n'); + const scenarios = [ + { + name: 'Claude Desktop connecting', + clientInfo: { name: 'Claude Desktop', version: '1.0.0' }, + clientVersion: '2025-03-26' + }, + { + name: 'n8n connecting via HTTP', + headers: { 'user-agent': 'n8n/1.52.0' }, + clientVersion: '2025-03-26' + } + ]; + for (const scenario of scenarios) { + const result = (0, protocol_version_1.negotiateProtocolVersion)(scenario.clientVersion, scenario.clientInfo, scenario.headers?.['user-agent'], scenario.headers); + console.log(`🔍 ${scenario.name}:`); + console.log(` Negotiated version: ${result.version}`); + console.log(` Is n8n client: ${result.isN8nClient}`); + console.log(` Reasoning: ${result.reasoning}\n`); + } +} +if (require.main === module) { + runTests() + .then(() => testIntegration()) + .catch(error => { + console.error('Test execution failed:', error); + process.exit(1); + }); +} +//# sourceMappingURL=test-protocol-negotiation.js.map \ No newline at end of file diff --git a/dist/scripts/test-protocol-negotiation.js.map b/dist/scripts/test-protocol-negotiation.js.map new file mode 100644 index 0000000..942a00c --- /dev/null +++ b/dist/scripts/test-protocol-negotiation.js.map @@ -0,0 +1 @@ +{"version":3,"file":"test-protocol-negotiation.js","sourceRoot":"","sources":["../../src/scripts/test-protocol-negotiation.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/scripts/test-summary.d.ts b/dist/scripts/test-summary.d.ts new file mode 100644 index 0000000..2ca09ae --- /dev/null +++ b/dist/scripts/test-summary.d.ts @@ -0,0 +1,3 @@ +#!/usr/bin/env npx tsx +export {}; +//# sourceMappingURL=test-summary.d.ts.map \ No newline at end of file diff --git a/dist/scripts/test-summary.d.ts.map b/dist/scripts/test-summary.d.ts.map new file mode 100644 index 0000000..8be35e0 --- /dev/null +++ b/dist/scripts/test-summary.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"test-summary.d.ts","sourceRoot":"","sources":["../../src/scripts/test-summary.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/scripts/test-summary.js b/dist/scripts/test-summary.js new file mode 100644 index 0000000..32544f1 --- /dev/null +++ b/dist/scripts/test-summary.js @@ -0,0 +1,77 @@ +#!/usr/bin/env npx tsx +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const database_adapter_1 = require("../database/database-adapter"); +const node_repository_1 = require("../database/node-repository"); +const node_similarity_service_1 = require("../services/node-similarity-service"); +const path_1 = __importDefault(require("path")); +async function testSummary() { + const dbPath = path_1.default.join(process.cwd(), 'data/nodes.db'); + const db = await (0, database_adapter_1.createDatabaseAdapter)(dbPath); + const repository = new node_repository_1.NodeRepository(db); + const similarityService = new node_similarity_service_1.NodeSimilarityService(repository); + const testCases = [ + { invalid: 'HttpRequest', expected: 'nodes-base.httpRequest' }, + { invalid: 'HTTPRequest', expected: 'nodes-base.httpRequest' }, + { invalid: 'Webhook', expected: 'nodes-base.webhook' }, + { invalid: 'WebHook', expected: 'nodes-base.webhook' }, + { invalid: 'slack', expected: 'nodes-base.slack' }, + { invalid: 'googleSheets', expected: 'nodes-base.googleSheets' }, + { invalid: 'telegram', expected: 'nodes-base.telegram' }, + { invalid: 'htpRequest', expected: 'nodes-base.httpRequest' }, + { invalid: 'webook', expected: 'nodes-base.webhook' }, + { invalid: 'slak', expected: 'nodes-base.slack' }, + { invalid: 'http', expected: 'nodes-base.httpRequest' }, + { invalid: 'sheet', expected: 'nodes-base.googleSheets' }, + { invalid: 'nodes-base.openai', expected: 'nodes-langchain.openAi' }, + { invalid: 'n8n-nodes-base.httpRequest', expected: 'nodes-base.httpRequest' }, + { invalid: 'foobar', expected: null }, + { invalid: 'xyz123', expected: null }, + ]; + let passed = 0; + let failed = 0; + console.log('Test Results Summary:'); + console.log('='.repeat(60)); + for (const testCase of testCases) { + const suggestions = await similarityService.findSimilarNodes(testCase.invalid, 3); + let result = '❌'; + let status = 'FAILED'; + if (testCase.expected === null) { + if (suggestions.length === 0) { + result = '✅'; + status = 'PASSED'; + passed++; + } + else { + failed++; + } + } + else { + const found = suggestions.some(s => s.nodeType === testCase.expected); + if (found) { + const suggestion = suggestions.find(s => s.nodeType === testCase.expected); + const isAutoFixable = suggestion && suggestion.confidence >= 0.9; + result = '✅'; + status = isAutoFixable ? 'PASSED (auto-fixable)' : 'PASSED'; + passed++; + } + else { + failed++; + } + } + console.log(`${result} "${testCase.invalid}" → ${testCase.expected || 'no suggestions'}: ${status}`); + } + console.log('='.repeat(60)); + console.log(`\nTotal: ${passed}/${testCases.length} tests passed`); + if (failed === 0) { + console.log('🎉 All tests passed!'); + } + else { + console.log(`⚠️ ${failed} tests failed`); + } +} +testSummary().catch(console.error); +//# sourceMappingURL=test-summary.js.map \ No newline at end of file diff --git a/dist/scripts/test-summary.js.map b/dist/scripts/test-summary.js.map new file mode 100644 index 0000000..c577576 --- /dev/null +++ b/dist/scripts/test-summary.js.map @@ -0,0 +1 @@ +{"version":3,"file":"test-summary.js","sourceRoot":"","sources":["../../src/scripts/test-summary.ts"],"names":[],"mappings":";;;;;;AAEA,mEAAqE;AACrE,iEAA6D;AAC7D,iFAA4E;AAC5E,gDAAwB;AAExB,KAAK,UAAU,WAAW;IACxB,MAAM,MAAM,GAAG,cAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC,CAAC;IACzD,MAAM,EAAE,GAAG,MAAM,IAAA,wCAAqB,EAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,IAAI,gCAAc,CAAC,EAAE,CAAC,CAAC;IAC1C,MAAM,iBAAiB,GAAG,IAAI,+CAAqB,CAAC,UAAU,CAAC,CAAC;IAEhE,MAAM,SAAS,GAAG;QAChB,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,wBAAwB,EAAE;QAC9D,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,wBAAwB,EAAE;QAC9D,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,oBAAoB,EAAE;QACtD,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,oBAAoB,EAAE;QACtD,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE;QAClD,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,yBAAyB,EAAE;QAChE,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,qBAAqB,EAAE;QACxD,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,wBAAwB,EAAE;QAC7D,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,oBAAoB,EAAE;QACrD,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,kBAAkB,EAAE;QACjD,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,wBAAwB,EAAE;QACvD,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,yBAAyB,EAAE;QACzD,EAAE,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,wBAAwB,EAAE;QACpE,EAAE,OAAO,EAAE,4BAA4B,EAAE,QAAQ,EAAE,wBAAwB,EAAE;QAC7E,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;QACrC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;KACtC,CAAC;IAEF,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,gBAAgB,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAElF,IAAI,MAAM,GAAG,GAAG,CAAC;QACjB,IAAI,MAAM,GAAG,QAAQ,CAAC;QAEtB,IAAI,QAAQ,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YAE/B,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC7B,MAAM,GAAG,GAAG,CAAC;gBACb,MAAM,GAAG,QAAQ,CAAC;gBAClB,MAAM,EAAE,CAAC;YACX,CAAC;iBAAM,CAAC;gBACN,MAAM,EAAE,CAAC;YACX,CAAC;QACH,CAAC;aAAM,CAAC;YAEN,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACtE,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAC3E,MAAM,aAAa,GAAG,UAAU,IAAI,UAAU,CAAC,UAAU,IAAI,GAAG,CAAC;gBACjE,MAAM,GAAG,GAAG,CAAC;gBACb,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,QAAQ,CAAC;gBAC5D,MAAM,EAAE,CAAC;YACX,CAAC;iBAAM,CAAC;gBACN,MAAM,EAAE,CAAC;YACX,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,KAAK,QAAQ,CAAC,OAAO,OAAO,QAAQ,CAAC,QAAQ,IAAI,gBAAgB,KAAK,MAAM,EAAE,CAAC,CAAC;IACvG,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,IAAI,SAAS,CAAC,MAAM,eAAe,CAAC,CAAC;IAEnE,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACtC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,OAAO,MAAM,eAAe,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED,WAAW,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"} \ No newline at end of file diff --git a/dist/scripts/test-telemetry-mutations-verbose.d.ts b/dist/scripts/test-telemetry-mutations-verbose.d.ts new file mode 100644 index 0000000..4beb88b --- /dev/null +++ b/dist/scripts/test-telemetry-mutations-verbose.d.ts @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=test-telemetry-mutations-verbose.d.ts.map \ No newline at end of file diff --git a/dist/scripts/test-telemetry-mutations-verbose.d.ts.map b/dist/scripts/test-telemetry-mutations-verbose.d.ts.map new file mode 100644 index 0000000..c2d881b --- /dev/null +++ b/dist/scripts/test-telemetry-mutations-verbose.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"test-telemetry-mutations-verbose.d.ts","sourceRoot":"","sources":["../../src/scripts/test-telemetry-mutations-verbose.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/scripts/test-telemetry-mutations-verbose.js b/dist/scripts/test-telemetry-mutations-verbose.js new file mode 100644 index 0000000..2dc8a14 --- /dev/null +++ b/dist/scripts/test-telemetry-mutations-verbose.js @@ -0,0 +1,133 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const telemetry_manager_js_1 = require("../telemetry/telemetry-manager.js"); +const config_manager_js_1 = require("../telemetry/config-manager.js"); +async function testMutations() { + console.log('Starting verbose telemetry mutation test...\n'); + const configManager = config_manager_js_1.TelemetryConfigManager.getInstance(); + console.log('Telemetry config is enabled:', configManager.isEnabled()); + console.log('Telemetry config file:', configManager['configPath']); + const testMutation = { + sessionId: 'test_session_' + Date.now(), + toolName: 'n8n_update_partial_workflow', + userIntent: 'Add a Merge node for data consolidation', + operations: [ + { + type: 'addNode', + nodeId: 'Merge1', + node: { + id: 'Merge1', + type: 'n8n-nodes-base.merge', + name: 'Merge', + position: [600, 200], + parameters: {} + } + }, + { + type: 'addConnection', + source: 'previous_node', + target: 'Merge1' + } + ], + workflowBefore: { + id: 'test-workflow', + name: 'Test Workflow', + active: true, + nodes: [ + { + id: 'previous_node', + type: 'n8n-nodes-base.manualTrigger', + name: 'When called', + position: [300, 200], + parameters: {} + } + ], + connections: {}, + nodeIds: [] + }, + workflowAfter: { + id: 'test-workflow', + name: 'Test Workflow', + active: true, + nodes: [ + { + id: 'previous_node', + type: 'n8n-nodes-base.manualTrigger', + name: 'When called', + position: [300, 200], + parameters: {} + }, + { + id: 'Merge1', + type: 'n8n-nodes-base.merge', + name: 'Merge', + position: [600, 200], + parameters: {} + } + ], + connections: { + 'previous_node': [ + { + node: 'Merge1', + type: 'main', + index: 0, + source: 0, + destination: 0 + } + ] + }, + nodeIds: [] + }, + mutationSuccess: true, + durationMs: 125 + }; + console.log('\nTest Mutation Data:'); + console.log('=================='); + console.log(JSON.stringify({ + intent: testMutation.userIntent, + tool: testMutation.toolName, + operationCount: testMutation.operations.length, + sessionId: testMutation.sessionId + }, null, 2)); + console.log('\n'); + console.log('Calling telemetry.trackWorkflowMutation...'); + try { + await telemetry_manager_js_1.telemetry.trackWorkflowMutation(testMutation); + console.log('✓ trackWorkflowMutation completed successfully\n'); + } + catch (error) { + console.error('✗ trackWorkflowMutation failed:', error); + console.error('\n'); + } + const metricsBeforeFlush = telemetry_manager_js_1.telemetry.getMetrics(); + console.log('Metrics before flush:'); + console.log('- mutationQueueSize:', metricsBeforeFlush.tracking.mutationQueueSize); + console.log('- eventsTracked:', metricsBeforeFlush.processing.eventsTracked); + console.log('- eventsFailed:', metricsBeforeFlush.processing.eventsFailed); + console.log('\n'); + console.log('Flushing telemetry (waiting 10 seconds for Supabase)...'); + try { + await telemetry_manager_js_1.telemetry.flush(); + console.log('✓ Telemetry flush completed\n'); + } + catch (error) { + console.error('✗ Flush failed:', error); + console.error('\n'); + } + await new Promise(resolve => setTimeout(resolve, 2000)); + const metricsAfterFlush = telemetry_manager_js_1.telemetry.getMetrics(); + console.log('Metrics after flush:'); + console.log('- mutationQueueSize:', metricsAfterFlush.tracking.mutationQueueSize); + console.log('- eventsTracked:', metricsAfterFlush.processing.eventsTracked); + console.log('- eventsFailed:', metricsAfterFlush.processing.eventsFailed); + console.log('- batchesSent:', metricsAfterFlush.processing.batchesSent); + console.log('- batchesFailed:', metricsAfterFlush.processing.batchesFailed); + console.log('- circuitBreakerState:', metricsAfterFlush.processing.circuitBreakerState); + console.log('\n'); + console.log('Test completed. Check workflow_mutations table in Supabase.'); +} +testMutations().catch(error => { + console.error('Test failed:', error); + process.exit(1); +}); +//# sourceMappingURL=test-telemetry-mutations-verbose.js.map \ No newline at end of file diff --git a/dist/scripts/test-telemetry-mutations-verbose.js.map b/dist/scripts/test-telemetry-mutations-verbose.js.map new file mode 100644 index 0000000..c3835be --- /dev/null +++ b/dist/scripts/test-telemetry-mutations-verbose.js.map @@ -0,0 +1 @@ +{"version":3,"file":"test-telemetry-mutations-verbose.js","sourceRoot":"","sources":["../../src/scripts/test-telemetry-mutations-verbose.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/scripts/test-telemetry-mutations.d.ts b/dist/scripts/test-telemetry-mutations.d.ts new file mode 100644 index 0000000..933ac95 --- /dev/null +++ b/dist/scripts/test-telemetry-mutations.d.ts @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=test-telemetry-mutations.d.ts.map \ No newline at end of file diff --git a/dist/scripts/test-telemetry-mutations.d.ts.map b/dist/scripts/test-telemetry-mutations.d.ts.map new file mode 100644 index 0000000..ce4f37f --- /dev/null +++ b/dist/scripts/test-telemetry-mutations.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"test-telemetry-mutations.d.ts","sourceRoot":"","sources":["../../src/scripts/test-telemetry-mutations.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/scripts/test-telemetry-mutations.js b/dist/scripts/test-telemetry-mutations.js new file mode 100644 index 0000000..c905a49 --- /dev/null +++ b/dist/scripts/test-telemetry-mutations.js @@ -0,0 +1,129 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const telemetry_manager_js_1 = require("../telemetry/telemetry-manager.js"); +const config_manager_js_1 = require("../telemetry/config-manager.js"); +async function testMutations() { + console.log('Starting telemetry mutation test...\n'); + const configManager = config_manager_js_1.TelemetryConfigManager.getInstance(); + console.log('Telemetry Status:'); + console.log('================'); + console.log(configManager.getStatus()); + console.log('\n'); + const metricsAfterInit = telemetry_manager_js_1.telemetry.getMetrics(); + console.log('Telemetry Metrics (After Init):'); + console.log('================================'); + console.log(JSON.stringify(metricsAfterInit, null, 2)); + console.log('\n'); + const testMutation = { + sessionId: 'test_session_' + Date.now(), + toolName: 'n8n_update_partial_workflow', + userIntent: 'Add a Merge node for data consolidation', + operations: [ + { + type: 'addNode', + nodeId: 'Merge1', + node: { + id: 'Merge1', + type: 'n8n-nodes-base.merge', + name: 'Merge', + position: [600, 200], + parameters: {} + } + }, + { + type: 'addConnection', + source: 'previous_node', + target: 'Merge1' + } + ], + workflowBefore: { + id: 'test-workflow', + name: 'Test Workflow', + active: true, + nodes: [ + { + id: 'previous_node', + type: 'n8n-nodes-base.manualTrigger', + name: 'When called', + position: [300, 200], + parameters: {} + } + ], + connections: {}, + nodeIds: [] + }, + workflowAfter: { + id: 'test-workflow', + name: 'Test Workflow', + active: true, + nodes: [ + { + id: 'previous_node', + type: 'n8n-nodes-base.manualTrigger', + name: 'When called', + position: [300, 200], + parameters: {} + }, + { + id: 'Merge1', + type: 'n8n-nodes-base.merge', + name: 'Merge', + position: [600, 200], + parameters: {} + } + ], + connections: { + 'previous_node': [ + { + node: 'Merge1', + type: 'main', + index: 0, + source: 0, + destination: 0 + } + ] + }, + nodeIds: [] + }, + mutationSuccess: true, + durationMs: 125 + }; + console.log('Test Mutation Data:'); + console.log('=================='); + console.log(JSON.stringify({ + intent: testMutation.userIntent, + tool: testMutation.toolName, + operationCount: testMutation.operations.length, + sessionId: testMutation.sessionId + }, null, 2)); + console.log('\n'); + console.log('Calling telemetry.trackWorkflowMutation...'); + try { + await telemetry_manager_js_1.telemetry.trackWorkflowMutation(testMutation); + console.log('✓ trackWorkflowMutation completed successfully\n'); + } + catch (error) { + console.error('✗ trackWorkflowMutation failed:', error); + console.error('\n'); + } + console.log('Flushing telemetry...'); + try { + await telemetry_manager_js_1.telemetry.flush(); + console.log('✓ Telemetry flushed successfully\n'); + } + catch (error) { + console.error('✗ Flush failed:', error); + console.error('\n'); + } + const metricsAfterFlush = telemetry_manager_js_1.telemetry.getMetrics(); + console.log('Telemetry Metrics (After Flush):'); + console.log('=================================='); + console.log(JSON.stringify(metricsAfterFlush, null, 2)); + console.log('\n'); + console.log('Test completed. Check workflow_mutations table in Supabase.'); +} +testMutations().catch(error => { + console.error('Test failed:', error); + process.exit(1); +}); +//# sourceMappingURL=test-telemetry-mutations.js.map \ No newline at end of file diff --git a/dist/scripts/test-telemetry-mutations.js.map b/dist/scripts/test-telemetry-mutations.js.map new file mode 100644 index 0000000..6725348 --- /dev/null +++ b/dist/scripts/test-telemetry-mutations.js.map @@ -0,0 +1 @@ +{"version":3,"file":"test-telemetry-mutations.js","sourceRoot":"","sources":["../../src/scripts/test-telemetry-mutations.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/scripts/test-webhook-autofix.d.ts b/dist/scripts/test-webhook-autofix.d.ts new file mode 100644 index 0000000..351a198 --- /dev/null +++ b/dist/scripts/test-webhook-autofix.d.ts @@ -0,0 +1,3 @@ +#!/usr/bin/env node +export {}; +//# sourceMappingURL=test-webhook-autofix.d.ts.map \ No newline at end of file diff --git a/dist/scripts/test-webhook-autofix.d.ts.map b/dist/scripts/test-webhook-autofix.d.ts.map new file mode 100644 index 0000000..0df4c2d --- /dev/null +++ b/dist/scripts/test-webhook-autofix.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"test-webhook-autofix.d.ts","sourceRoot":"","sources":["../../src/scripts/test-webhook-autofix.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/scripts/test-webhook-autofix.js b/dist/scripts/test-webhook-autofix.js new file mode 100644 index 0000000..22e3aa5 --- /dev/null +++ b/dist/scripts/test-webhook-autofix.js @@ -0,0 +1,117 @@ +#!/usr/bin/env node +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const node_repository_1 = require("../database/node-repository"); +const database_adapter_1 = require("../database/database-adapter"); +const workflow_auto_fixer_1 = require("../services/workflow-auto-fixer"); +const workflow_validator_1 = require("../services/workflow-validator"); +const enhanced_config_validator_1 = require("../services/enhanced-config-validator"); +const logger_1 = require("../utils/logger"); +const path_1 = require("path"); +const logger = new logger_1.Logger({ prefix: '[TestWebhookAutofix]' }); +const testWorkflow = { + id: 'test_webhook_fix', + name: 'Test Webhook Autofix', + active: false, + nodes: [ + { + id: '1', + name: 'Webhook', + type: 'n8n-nodes-base.webhook', + typeVersion: 2.1, + position: [250, 300], + parameters: {}, + }, + { + id: '2', + name: 'HTTP Request', + type: 'n8n-nodes-base.httpRequest', + typeVersion: 4.2, + position: [450, 300], + parameters: { + url: 'https://api.example.com/data', + method: 'GET' + } + } + ], + connections: { + 'Webhook': { + main: [[{ + node: 'HTTP Request', + type: 'main', + index: 0 + }]] + } + }, + settings: { + executionOrder: 'v1' + }, + staticData: undefined +}; +async function testWebhookAutofix() { + logger.info('Testing webhook path autofixer...'); + const dbPath = (0, path_1.join)(process.cwd(), 'data', 'nodes.db'); + const adapter = await (0, database_adapter_1.createDatabaseAdapter)(dbPath); + const repository = new node_repository_1.NodeRepository(adapter); + const validator = new workflow_validator_1.WorkflowValidator(repository, enhanced_config_validator_1.EnhancedConfigValidator); + const autoFixer = new workflow_auto_fixer_1.WorkflowAutoFixer(repository); + logger.info('Step 1: Validating workflow to identify issues...'); + const validationResult = await validator.validateWorkflow(testWorkflow); + console.log('\n📋 Validation Summary:'); + console.log(`- Valid: ${validationResult.valid}`); + console.log(`- Errors: ${validationResult.errors.length}`); + console.log(`- Warnings: ${validationResult.warnings.length}`); + if (validationResult.errors.length > 0) { + console.log('\n❌ Errors found:'); + validationResult.errors.forEach(error => { + console.log(` - [${error.nodeName || error.nodeId}] ${error.message}`); + }); + } + logger.info('\nStep 2: Generating fixes in preview mode...'); + const fixResult = await autoFixer.generateFixes(testWorkflow, validationResult, [], { + applyFixes: false, + fixTypes: ['webhook-missing-path'] + }); + console.log('\n🔧 Fix Results:'); + console.log(`- Summary: ${fixResult.summary}`); + console.log(`- Total fixes: ${fixResult.stats.total}`); + console.log(`- Webhook path fixes: ${fixResult.stats.byType['webhook-missing-path']}`); + if (fixResult.fixes.length > 0) { + console.log('\n📝 Detailed Fixes:'); + fixResult.fixes.forEach(fix => { + console.log(` - Node: ${fix.node}`); + console.log(` Field: ${fix.field}`); + console.log(` Type: ${fix.type}`); + console.log(` Before: ${fix.before || 'undefined'}`); + console.log(` After: ${fix.after}`); + console.log(` Confidence: ${fix.confidence}`); + console.log(` Description: ${fix.description}`); + }); + } + if (fixResult.operations.length > 0) { + console.log('\n🔄 Operations to Apply:'); + fixResult.operations.forEach(op => { + if (op.type === 'updateNode') { + console.log(` - Update Node: ${op.nodeId}`); + console.log(` Updates: ${JSON.stringify(op.updates, null, 2)}`); + } + }); + } + if (fixResult.fixes.length > 0) { + const webhookFix = fixResult.fixes.find(f => f.type === 'webhook-missing-path'); + if (webhookFix) { + const uuid = webhookFix.after; + const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; + const isValidUUID = uuidRegex.test(uuid); + console.log('\n✅ UUID Validation:'); + console.log(` - Generated UUID: ${uuid}`); + console.log(` - Valid format: ${isValidUUID ? 'Yes' : 'No'}`); + } + } + logger.info('\n✨ Webhook autofix test completed successfully!'); +} +testWebhookAutofix().catch(error => { + logger.error('Test failed:', error); + process.exit(1); +}); +//# sourceMappingURL=test-webhook-autofix.js.map \ No newline at end of file diff --git a/dist/scripts/test-webhook-autofix.js.map b/dist/scripts/test-webhook-autofix.js.map new file mode 100644 index 0000000..ab158d3 --- /dev/null +++ b/dist/scripts/test-webhook-autofix.js.map @@ -0,0 +1 @@ +{"version":3,"file":"test-webhook-autofix.js","sourceRoot":"","sources":["../../src/scripts/test-webhook-autofix.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/scripts/validate.d.ts b/dist/scripts/validate.d.ts new file mode 100644 index 0000000..21930b2 --- /dev/null +++ b/dist/scripts/validate.d.ts @@ -0,0 +1,3 @@ +#!/usr/bin/env node +export {}; +//# sourceMappingURL=validate.d.ts.map \ No newline at end of file diff --git a/dist/scripts/validate.d.ts.map b/dist/scripts/validate.d.ts.map new file mode 100644 index 0000000..c3e6c1d --- /dev/null +++ b/dist/scripts/validate.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/scripts/validate.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/scripts/validate.js b/dist/scripts/validate.js new file mode 100644 index 0000000..08c6b3b --- /dev/null +++ b/dist/scripts/validate.js @@ -0,0 +1,121 @@ +#!/usr/bin/env node +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const database_adapter_1 = require("../database/database-adapter"); +async function validate() { + const db = await (0, database_adapter_1.createDatabaseAdapter)('./data/nodes.db'); + console.log('🔍 Validating critical nodes...\n'); + const criticalChecks = [ + { + type: 'nodes-base.httpRequest', + checks: { + hasDocumentation: true, + documentationContains: 'HTTP Request', + style: 'programmatic' + } + }, + { + type: 'nodes-base.code', + checks: { + hasDocumentation: true, + documentationContains: 'Code' + } + }, + { + type: 'nodes-base.slack', + checks: { + hasOperations: true, + style: 'programmatic' + } + }, + { + type: 'nodes-langchain.agent', + checks: { + isAITool: false, + packageName: '@n8n/n8n-nodes-langchain' + } + } + ]; + let passed = 0; + let failed = 0; + for (const check of criticalChecks) { + const node = db.prepare('SELECT * FROM nodes WHERE node_type = ?').get(check.type); + if (!node) { + console.log(`❌ ${check.type}: NOT FOUND`); + failed++; + continue; + } + let nodeOk = true; + const issues = []; + if (check.checks.hasDocumentation && !node.documentation) { + nodeOk = false; + issues.push('missing documentation'); + } + if (check.checks.documentationContains && + !node.documentation?.includes(check.checks.documentationContains)) { + nodeOk = false; + issues.push(`documentation doesn't contain "${check.checks.documentationContains}"`); + } + if (check.checks.style && node.development_style !== check.checks.style) { + nodeOk = false; + issues.push(`wrong style: ${node.development_style}`); + } + if (check.checks.hasOperations) { + const operations = JSON.parse(node.operations || '[]'); + if (!operations.length) { + nodeOk = false; + issues.push('no operations found'); + } + } + if (check.checks.isAITool !== undefined && !!node.is_ai_tool !== check.checks.isAITool) { + nodeOk = false; + issues.push(`AI tool flag mismatch: expected ${check.checks.isAITool}, got ${!!node.is_ai_tool}`); + } + if ('isVersioned' in check.checks && check.checks.isVersioned && !node.is_versioned) { + nodeOk = false; + issues.push('not marked as versioned'); + } + if (check.checks.packageName && node.package_name !== check.checks.packageName) { + nodeOk = false; + issues.push(`wrong package: ${node.package_name}`); + } + if (nodeOk) { + console.log(`✅ ${check.type}`); + passed++; + } + else { + console.log(`❌ ${check.type}: ${issues.join(', ')}`); + failed++; + } + } + console.log(`\n📊 Results: ${passed} passed, ${failed} failed`); + const stats = db.prepare(` + SELECT + COUNT(*) as total, + SUM(is_ai_tool) as ai_tools, + SUM(is_trigger) as triggers, + SUM(is_versioned) as versioned, + COUNT(DISTINCT package_name) as packages + FROM nodes + `).get(); + console.log('\n📈 Database Statistics:'); + console.log(` Total nodes: ${stats.total}`); + console.log(` AI tools: ${stats.ai_tools}`); + console.log(` Triggers: ${stats.triggers}`); + console.log(` Versioned: ${stats.versioned}`); + console.log(` Packages: ${stats.packages}`); + const docStats = db.prepare(` + SELECT + COUNT(*) as total, + SUM(CASE WHEN documentation IS NOT NULL THEN 1 ELSE 0 END) as with_docs + FROM nodes + `).get(); + console.log(`\n📚 Documentation Coverage:`); + console.log(` Nodes with docs: ${docStats.with_docs}/${docStats.total} (${Math.round(docStats.with_docs / docStats.total * 100)}%)`); + db.close(); + process.exit(failed > 0 ? 1 : 0); +} +if (require.main === module) { + validate().catch(console.error); +} +//# sourceMappingURL=validate.js.map \ No newline at end of file diff --git a/dist/scripts/validate.js.map b/dist/scripts/validate.js.map new file mode 100644 index 0000000..754da9b --- /dev/null +++ b/dist/scripts/validate.js.map @@ -0,0 +1 @@ +{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/scripts/validate.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/scripts/validation-summary.d.ts b/dist/scripts/validation-summary.d.ts new file mode 100644 index 0000000..6026110 --- /dev/null +++ b/dist/scripts/validation-summary.d.ts @@ -0,0 +1,3 @@ +#!/usr/bin/env node +export {}; +//# sourceMappingURL=validation-summary.d.ts.map \ No newline at end of file diff --git a/dist/scripts/validation-summary.d.ts.map b/dist/scripts/validation-summary.d.ts.map new file mode 100644 index 0000000..7ad7311 --- /dev/null +++ b/dist/scripts/validation-summary.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"validation-summary.d.ts","sourceRoot":"","sources":["../../src/scripts/validation-summary.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/scripts/validation-summary.js b/dist/scripts/validation-summary.js new file mode 100644 index 0000000..0d07702 --- /dev/null +++ b/dist/scripts/validation-summary.js @@ -0,0 +1,135 @@ +#!/usr/bin/env node +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const fs_1 = require("fs"); +const path_1 = __importDefault(require("path")); +const node_repository_1 = require("../database/node-repository"); +const database_adapter_1 = require("../database/database-adapter"); +const workflow_validator_1 = require("../services/workflow-validator"); +const enhanced_config_validator_1 = require("../services/enhanced-config-validator"); +const template_repository_1 = require("../templates/template-repository"); +const logger_1 = require("../utils/logger"); +const logger = new logger_1.Logger({ prefix: '[validation-summary]' }); +async function runValidationSummary() { + const dbPath = path_1.default.join(process.cwd(), 'data', 'nodes.db'); + if (!(0, fs_1.existsSync)(dbPath)) { + logger.error('Database not found. Run npm run rebuild first.'); + process.exit(1); + } + const db = await (0, database_adapter_1.createDatabaseAdapter)(dbPath); + const repository = new node_repository_1.NodeRepository(db); + const templateRepository = new template_repository_1.TemplateRepository(db); + const validator = new workflow_validator_1.WorkflowValidator(repository, enhanced_config_validator_1.EnhancedConfigValidator); + try { + const templates = await templateRepository.getAllTemplates(50); + const results = { + total: templates.length, + valid: 0, + invalid: 0, + noErrors: 0, + errorCategories: { + unknownNodes: 0, + missingRequired: 0, + expressionErrors: 0, + connectionErrors: 0, + cycles: 0, + other: 0 + }, + commonUnknownNodes: new Map(), + stickyNoteIssues: 0 + }; + for (const template of templates) { + try { + const workflow = JSON.parse(template.workflow_json || '{}'); + const validationResult = await validator.validateWorkflow(workflow, { + profile: 'minimal' + }); + if (validationResult.valid) { + results.valid++; + } + else { + results.invalid++; + } + if (validationResult.errors.length === 0) { + results.noErrors++; + } + validationResult.errors.forEach((error) => { + const errorMsg = typeof error.message === 'string' ? error.message : JSON.stringify(error.message); + if (errorMsg.includes('Unknown node type')) { + results.errorCategories.unknownNodes++; + const match = errorMsg.match(/Unknown node type: (.+)/); + if (match) { + const nodeType = match[1]; + results.commonUnknownNodes.set(nodeType, (results.commonUnknownNodes.get(nodeType) || 0) + 1); + } + } + else if (errorMsg.includes('missing_required')) { + results.errorCategories.missingRequired++; + if (error.nodeName?.includes('Sticky Note')) { + results.stickyNoteIssues++; + } + } + else if (errorMsg.includes('Expression error')) { + results.errorCategories.expressionErrors++; + } + else if (errorMsg.includes('connection') || errorMsg.includes('Connection')) { + results.errorCategories.connectionErrors++; + } + else if (errorMsg.includes('cycle')) { + results.errorCategories.cycles++; + } + else { + results.errorCategories.other++; + } + }); + } + catch (error) { + results.invalid++; + } + } + console.log('\n' + '='.repeat(80)); + console.log('WORKFLOW VALIDATION SUMMARY'); + console.log('='.repeat(80)); + console.log(`\nTemplates analyzed: ${results.total}`); + console.log(`Valid workflows: ${results.valid} (${((results.valid / results.total) * 100).toFixed(1)}%)`); + console.log(`Workflows without errors: ${results.noErrors} (${((results.noErrors / results.total) * 100).toFixed(1)}%)`); + console.log('\nError Categories:'); + console.log(` - Unknown nodes: ${results.errorCategories.unknownNodes}`); + console.log(` - Missing required properties: ${results.errorCategories.missingRequired}`); + console.log(` (Sticky note issues: ${results.stickyNoteIssues})`); + console.log(` - Expression errors: ${results.errorCategories.expressionErrors}`); + console.log(` - Connection errors: ${results.errorCategories.connectionErrors}`); + console.log(` - Workflow cycles: ${results.errorCategories.cycles}`); + console.log(` - Other errors: ${results.errorCategories.other}`); + if (results.commonUnknownNodes.size > 0) { + console.log('\nTop Unknown Node Types:'); + const sortedNodes = Array.from(results.commonUnknownNodes.entries()) + .sort((a, b) => b[1] - a[1]) + .slice(0, 10); + sortedNodes.forEach(([nodeType, count]) => { + console.log(` - ${nodeType} (${count} occurrences)`); + }); + } + console.log('\nKey Insights:'); + const stickyNotePercent = ((results.stickyNoteIssues / results.errorCategories.missingRequired) * 100).toFixed(1); + console.log(` - ${stickyNotePercent}% of missing required property errors are from Sticky Notes`); + console.log(` - Most workflows have some validation warnings (best practices)`); + console.log(` - Expression validation is working well`); + console.log(` - Node type normalization is handling most cases correctly`); + } + catch (error) { + logger.error('Failed to run validation summary:', error); + process.exit(1); + } + finally { + db.close(); + } +} +runValidationSummary().catch(error => { + logger.error('Summary failed:', error); + process.exit(1); +}); +//# sourceMappingURL=validation-summary.js.map \ No newline at end of file diff --git a/dist/scripts/validation-summary.js.map b/dist/scripts/validation-summary.js.map new file mode 100644 index 0000000..bd6a776 --- /dev/null +++ b/dist/scripts/validation-summary.js.map @@ -0,0 +1 @@ +{"version":3,"file":"validation-summary.js","sourceRoot":"","sources":["../../src/scripts/validation-summary.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/ai-node-validator.d.ts b/dist/services/ai-node-validator.d.ts new file mode 100644 index 0000000..c318383 --- /dev/null +++ b/dist/services/ai-node-validator.d.ts @@ -0,0 +1,12 @@ +import { WorkflowNode, WorkflowJson, ReverseConnection, ValidationIssue } from './ai-tool-validators'; +export type { WorkflowNode, WorkflowJson, ReverseConnection, ValidationIssue } from './ai-tool-validators'; +export declare const AI_CONNECTION_TYPES: readonly ["ai_languageModel", "ai_memory", "ai_tool", "ai_embedding", "ai_vectorStore", "ai_document", "ai_textSplitter", "ai_outputParser"]; +export declare function buildReverseConnectionMap(workflow: WorkflowJson): Map; +export declare function getAIConnections(nodeName: string, reverseConnections: Map, connectionType?: string): ReverseConnection[]; +export declare function validateAIAgent(node: WorkflowNode, reverseConnections: Map, workflow: WorkflowJson): ValidationIssue[]; +export declare function validateChatTrigger(node: WorkflowNode, workflow: WorkflowJson, reverseConnections: Map): ValidationIssue[]; +export declare function validateBasicLLMChain(node: WorkflowNode, reverseConnections: Map): ValidationIssue[]; +export declare function validateAISpecificNodes(workflow: WorkflowJson): ValidationIssue[]; +export declare function hasAINodes(workflow: WorkflowJson): boolean; +export declare function getAINodeCategory(nodeType: string): string | null; +//# sourceMappingURL=ai-node-validator.d.ts.map \ No newline at end of file diff --git a/dist/services/ai-node-validator.d.ts.map b/dist/services/ai-node-validator.d.ts.map new file mode 100644 index 0000000..1fe892f --- /dev/null +++ b/dist/services/ai-node-validator.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"ai-node-validator.d.ts","sourceRoot":"","sources":["../../src/services/ai-node-validator.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,eAAe,EAGhB,MAAM,sBAAsB,CAAC;AAG9B,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,eAAe,EAChB,MAAM,sBAAsB,CAAC;AAU9B,eAAO,MAAM,mBAAmB,8IAStB,CAAC;AAmBX,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,YAAY,GACrB,GAAG,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,CA4ClC;AAKD,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,EACpD,cAAc,CAAC,EAAE,MAAM,GACtB,iBAAiB,EAAE,CAQrB;AAgBD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,YAAY,EAClB,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,EACpD,QAAQ,EAAE,YAAY,GACrB,eAAe,EAAE,CAqLnB;AAyCD,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,YAAY,EAClB,QAAQ,EAAE,YAAY,EACtB,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,GACnD,eAAe,EAAE,CA8EnB;AAYD,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,YAAY,EAClB,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,GACnD,eAAe,EAAE,CAiEnB;AAOD,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,YAAY,GACrB,eAAe,EAAE,CA0CnB;AAMD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAW1D;AAKD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA0BjE"} \ No newline at end of file diff --git a/dist/services/ai-node-validator.js b/dist/services/ai-node-validator.js new file mode 100644 index 0000000..0a67806 --- /dev/null +++ b/dist/services/ai-node-validator.js @@ -0,0 +1,429 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.AI_CONNECTION_TYPES = void 0; +exports.buildReverseConnectionMap = buildReverseConnectionMap; +exports.getAIConnections = getAIConnections; +exports.validateAIAgent = validateAIAgent; +exports.validateChatTrigger = validateChatTrigger; +exports.validateBasicLLMChain = validateBasicLLMChain; +exports.validateAISpecificNodes = validateAISpecificNodes; +exports.hasAINodes = hasAINodes; +exports.getAINodeCategory = getAINodeCategory; +const node_type_normalizer_1 = require("../utils/node-type-normalizer"); +const ai_tool_validators_1 = require("./ai-tool-validators"); +const MIN_SYSTEM_MESSAGE_LENGTH = 20; +const MAX_ITERATIONS_WARNING_THRESHOLD = 50; +exports.AI_CONNECTION_TYPES = [ + 'ai_languageModel', + 'ai_memory', + 'ai_tool', + 'ai_embedding', + 'ai_vectorStore', + 'ai_document', + 'ai_textSplitter', + 'ai_outputParser' +]; +function buildReverseConnectionMap(workflow) { + const map = new Map(); + for (const [sourceName, outputs] of Object.entries(workflow.connections)) { + if (!sourceName || typeof sourceName !== 'string' || sourceName.trim() === '') { + continue; + } + if (!outputs || typeof outputs !== 'object') + continue; + for (const [outputType, connections] of Object.entries(outputs)) { + if (!Array.isArray(connections)) + continue; + const connArray = connections.flat().filter(c => c); + for (const conn of connArray) { + if (!conn || !conn.node) + continue; + if (typeof conn.node !== 'string' || conn.node.trim() === '') { + continue; + } + if (!map.has(conn.node)) { + map.set(conn.node, []); + } + map.get(conn.node).push({ + sourceName: sourceName, + sourceType: outputType, + type: outputType, + index: conn.index ?? 0 + }); + } + } + } + return map; +} +function getAIConnections(nodeName, reverseConnections, connectionType) { + const incoming = reverseConnections.get(nodeName) || []; + if (connectionType) { + return incoming.filter(c => c.type === connectionType); + } + return incoming.filter(c => exports.AI_CONNECTION_TYPES.includes(c.type)); +} +function validateAIAgent(node, reverseConnections, workflow) { + const issues = []; + const incoming = reverseConnections.get(node.name) || []; + const languageModelConnections = incoming.filter(c => c.type === 'ai_languageModel'); + if (languageModelConnections.length === 0) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `AI Agent "${node.name}" requires an ai_languageModel connection. Connect a language model node (e.g., OpenAI Chat Model, Anthropic Chat Model).`, + code: 'MISSING_LANGUAGE_MODEL' + }); + } + else if (languageModelConnections.length > 2) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `AI Agent "${node.name}" has ${languageModelConnections.length} ai_languageModel connections. Maximum is 2 (for fallback model support).`, + code: 'TOO_MANY_LANGUAGE_MODELS' + }); + } + else if (languageModelConnections.length === 2) { + if (!node.parameters.needsFallback) { + issues.push({ + severity: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `AI Agent "${node.name}" has 2 language models but needsFallback is not enabled. Set needsFallback=true or remove the second model.` + }); + } + } + else if (languageModelConnections.length === 1 && node.parameters.needsFallback === true) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `AI Agent "${node.name}" has needsFallback=true but only 1 language model connected. Connect a second model for fallback or disable needsFallback.`, + code: 'FALLBACK_MISSING_SECOND_MODEL' + }); + } + const outputParserConnections = incoming.filter(c => c.type === 'ai_outputParser'); + if (node.parameters.hasOutputParser === true) { + if (outputParserConnections.length === 0) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `AI Agent "${node.name}" has hasOutputParser=true but no ai_outputParser connection. Connect an output parser or set hasOutputParser=false.`, + code: 'MISSING_OUTPUT_PARSER' + }); + } + } + else if (outputParserConnections.length > 0) { + issues.push({ + severity: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `AI Agent "${node.name}" has an output parser connected but hasOutputParser is not true. Set hasOutputParser=true to enable output parsing.` + }); + } + if (outputParserConnections.length > 1) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `AI Agent "${node.name}" has ${outputParserConnections.length} output parsers. Only 1 is allowed.`, + code: 'MULTIPLE_OUTPUT_PARSERS' + }); + } + if (node.parameters.promptType === 'define') { + if (!node.parameters.text || node.parameters.text.trim() === '') { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `AI Agent "${node.name}" has promptType="define" but the text field is empty. Provide a custom prompt or switch to promptType="auto".`, + code: 'MISSING_PROMPT_TEXT' + }); + } + } + if (!node.parameters.systemMessage) { + issues.push({ + severity: 'info', + nodeId: node.id, + nodeName: node.name, + message: `AI Agent "${node.name}" has no systemMessage. Consider adding one to define the agent's role, capabilities, and constraints.` + }); + } + else if (node.parameters.systemMessage.trim().length < MIN_SYSTEM_MESSAGE_LENGTH) { + issues.push({ + severity: 'info', + nodeId: node.id, + nodeName: node.name, + message: `AI Agent "${node.name}" systemMessage is very short (minimum ${MIN_SYSTEM_MESSAGE_LENGTH} characters recommended). Provide more detail about the agent's role and capabilities.` + }); + } + const isStreamingTarget = checkIfStreamingTarget(node, workflow, reverseConnections); + const hasOwnStreamingEnabled = node.parameters?.options?.streamResponse === true; + if (isStreamingTarget || hasOwnStreamingEnabled) { + const agentMainOutput = workflow.connections[node.name]?.main; + if (agentMainOutput && agentMainOutput.flat().some((c) => c)) { + const streamSource = isStreamingTarget + ? 'connected from Chat Trigger with responseMode="streaming"' + : 'has streamResponse=true in options'; + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `AI Agent "${node.name}" is in streaming mode (${streamSource}) but has outgoing main connections. Remove all main output connections - streaming responses flow back through the Chat Trigger.`, + code: 'STREAMING_WITH_MAIN_OUTPUT' + }); + } + } + const memoryConnections = incoming.filter(c => c.type === 'ai_memory'); + if (memoryConnections.length > 1) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `AI Agent "${node.name}" has ${memoryConnections.length} ai_memory connections. Only 1 memory is allowed.`, + code: 'MULTIPLE_MEMORY_CONNECTIONS' + }); + } + const toolConnections = incoming.filter(c => c.type === 'ai_tool'); + if (toolConnections.length === 0) { + issues.push({ + severity: 'info', + nodeId: node.id, + nodeName: node.name, + message: `AI Agent "${node.name}" has no ai_tool connections. Consider adding tools to enhance the agent's capabilities.` + }); + } + if (node.parameters.maxIterations !== undefined) { + if (typeof node.parameters.maxIterations !== 'number') { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `AI Agent "${node.name}" has invalid maxIterations type. Must be a number.`, + code: 'INVALID_MAX_ITERATIONS_TYPE' + }); + } + else if (node.parameters.maxIterations < 1) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `AI Agent "${node.name}" has maxIterations=${node.parameters.maxIterations}. Must be at least 1.`, + code: 'MAX_ITERATIONS_TOO_LOW' + }); + } + else if (node.parameters.maxIterations > MAX_ITERATIONS_WARNING_THRESHOLD) { + issues.push({ + severity: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `AI Agent "${node.name}" has maxIterations=${node.parameters.maxIterations}. Very high iteration counts (>${MAX_ITERATIONS_WARNING_THRESHOLD}) may cause long execution times and high costs.` + }); + } + } + return issues; +} +function checkIfStreamingTarget(node, workflow, reverseConnections) { + const incoming = reverseConnections.get(node.name) || []; + const mainConnections = incoming.filter(c => c.type === 'main'); + for (const conn of mainConnections) { + const sourceNode = workflow.nodes.find(n => n.name === conn.sourceName); + if (!sourceNode) + continue; + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(sourceNode.type); + if (normalizedType === 'nodes-langchain.chatTrigger') { + const responseMode = sourceNode.parameters?.options?.responseMode || 'lastNode'; + if (responseMode === 'streaming') { + return true; + } + } + } + return false; +} +function validateChatTrigger(node, workflow, reverseConnections) { + const issues = []; + const responseMode = node.parameters?.options?.responseMode || 'lastNode'; + const outgoingMain = workflow.connections[node.name]?.main; + if (!outgoingMain || outgoingMain.length === 0 || !outgoingMain[0] || outgoingMain[0].length === 0) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Chat Trigger "${node.name}" has no outgoing connections. Connect it to an AI Agent or workflow.`, + code: 'MISSING_CONNECTIONS' + }); + return issues; + } + const firstConnection = outgoingMain[0][0]; + if (!firstConnection) { + return issues; + } + const targetNode = workflow.nodes.find(n => n.name === firstConnection.node); + if (!targetNode) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Chat Trigger "${node.name}" connects to non-existent node "${firstConnection.node}".`, + code: 'INVALID_TARGET_NODE' + }); + return issues; + } + const targetType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(targetNode.type); + if (responseMode === 'streaming') { + if (targetType !== 'nodes-langchain.agent') { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Chat Trigger "${node.name}" has responseMode="streaming" but connects to "${targetNode.name}" (${targetType}). Streaming mode only works with AI Agent. Change responseMode to "lastNode" or connect to an AI Agent.`, + code: 'STREAMING_WRONG_TARGET' + }); + } + else { + const agentMainOutput = workflow.connections[targetNode.name]?.main; + if (agentMainOutput && agentMainOutput.flat().some((c) => c)) { + issues.push({ + severity: 'error', + nodeId: targetNode.id, + nodeName: targetNode.name, + message: `AI Agent "${targetNode.name}" is in streaming mode but has outgoing main connections. In streaming mode, the AI Agent must NOT have main output connections - responses stream back through the Chat Trigger.`, + code: 'STREAMING_AGENT_HAS_OUTPUT' + }); + } + } + } + if (responseMode === 'lastNode') { + if (targetType === 'nodes-langchain.agent') { + issues.push({ + severity: 'info', + nodeId: node.id, + nodeName: node.name, + message: `Chat Trigger "${node.name}" uses responseMode="lastNode" with AI Agent. Consider using responseMode="streaming" for better user experience with real-time responses.` + }); + } + } + return issues; +} +function validateBasicLLMChain(node, reverseConnections) { + const issues = []; + const incoming = reverseConnections.get(node.name) || []; + const languageModelConnections = incoming.filter(c => c.type === 'ai_languageModel'); + if (languageModelConnections.length === 0) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Basic LLM Chain "${node.name}" requires an ai_languageModel connection. Connect a language model node.`, + code: 'MISSING_LANGUAGE_MODEL' + }); + } + else if (languageModelConnections.length > 1) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Basic LLM Chain "${node.name}" has ${languageModelConnections.length} ai_languageModel connections. Basic LLM Chain only supports 1 language model (no fallback).`, + code: 'MULTIPLE_LANGUAGE_MODELS' + }); + } + const memoryConnections = incoming.filter(c => c.type === 'ai_memory'); + if (memoryConnections.length > 1) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Basic LLM Chain "${node.name}" has ${memoryConnections.length} ai_memory connections. Only 1 memory is allowed.`, + code: 'MULTIPLE_MEMORY_CONNECTIONS' + }); + } + const toolConnections = incoming.filter(c => c.type === 'ai_tool'); + if (toolConnections.length > 0) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Basic LLM Chain "${node.name}" has ai_tool connections. Basic LLM Chain does not support tools. Use AI Agent if you need tool support.`, + code: 'TOOLS_NOT_SUPPORTED' + }); + } + if (node.parameters.promptType === 'define') { + if (!node.parameters.text || node.parameters.text.trim() === '') { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Basic LLM Chain "${node.name}" has promptType="define" but the text field is empty.`, + code: 'MISSING_PROMPT_TEXT' + }); + } + } + return issues; +} +function validateAISpecificNodes(workflow) { + const issues = []; + const reverseConnectionMap = buildReverseConnectionMap(workflow); + for (const node of workflow.nodes) { + if (node.disabled) + continue; + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(node.type); + if (normalizedType === 'nodes-langchain.agent') { + const nodeIssues = validateAIAgent(node, reverseConnectionMap, workflow); + issues.push(...nodeIssues); + } + if (normalizedType === 'nodes-langchain.chatTrigger') { + const nodeIssues = validateChatTrigger(node, workflow, reverseConnectionMap); + issues.push(...nodeIssues); + } + if (normalizedType === 'nodes-langchain.chainLlm') { + const nodeIssues = validateBasicLLMChain(node, reverseConnectionMap); + issues.push(...nodeIssues); + } + if ((0, ai_tool_validators_1.isAIToolSubNode)(normalizedType)) { + const nodeIssues = (0, ai_tool_validators_1.validateAIToolSubNode)(node, normalizedType, reverseConnectionMap, workflow); + issues.push(...nodeIssues); + } + } + return issues; +} +function hasAINodes(workflow) { + const aiNodeTypes = [ + 'nodes-langchain.agent', + 'nodes-langchain.chatTrigger', + 'nodes-langchain.chainLlm', + ]; + return workflow.nodes.some(node => { + const normalized = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(node.type); + return aiNodeTypes.includes(normalized) || (0, ai_tool_validators_1.isAIToolSubNode)(normalized); + }); +} +function getAINodeCategory(nodeType) { + const normalized = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + if (normalized === 'nodes-langchain.agent') + return 'AI Agent'; + if (normalized === 'nodes-langchain.chatTrigger') + return 'Chat Trigger'; + if (normalized === 'nodes-langchain.chainLlm') + return 'Basic LLM Chain'; + if ((0, ai_tool_validators_1.isAIToolSubNode)(normalized)) + return 'AI Tool'; + if (normalized.startsWith('nodes-langchain.')) { + if (normalized.includes('openAi') || normalized.includes('anthropic') || normalized.includes('googleGemini')) { + return 'Language Model'; + } + if (normalized.includes('memory') || normalized.includes('buffer')) { + return 'Memory'; + } + if (normalized.includes('vectorStore') || normalized.includes('pinecone') || normalized.includes('qdrant')) { + return 'Vector Store'; + } + if (normalized.includes('embedding')) { + return 'Embeddings'; + } + return 'AI Component'; + } + return null; +} +//# sourceMappingURL=ai-node-validator.js.map \ No newline at end of file diff --git a/dist/services/ai-node-validator.js.map b/dist/services/ai-node-validator.js.map new file mode 100644 index 0000000..100da89 --- /dev/null +++ b/dist/services/ai-node-validator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ai-node-validator.js","sourceRoot":"","sources":["../../src/services/ai-node-validator.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/ai-tool-validators.d.ts b/dist/services/ai-tool-validators.d.ts new file mode 100644 index 0000000..cf06dea --- /dev/null +++ b/dist/services/ai-tool-validators.d.ts @@ -0,0 +1,58 @@ +export interface WorkflowNode { + id: string; + name: string; + type: string; + position: [number, number]; + parameters: any; + credentials?: any; + disabled?: boolean; + typeVersion?: number; +} +export interface WorkflowJson { + name?: string; + nodes: WorkflowNode[]; + connections: Record; + settings?: any; +} +export interface ReverseConnection { + sourceName: string; + sourceType: string; + type: string; + index: number; +} +export interface ValidationIssue { + severity: 'error' | 'warning' | 'info'; + nodeId?: string; + nodeName?: string; + message: string; + code?: string; +} +export declare function validateHTTPRequestTool(node: WorkflowNode): ValidationIssue[]; +export declare function validateCodeTool(node: WorkflowNode): ValidationIssue[]; +export declare function validateVectorStoreTool(node: WorkflowNode, reverseConnections: Map, workflow: WorkflowJson): ValidationIssue[]; +export declare function validateWorkflowTool(node: WorkflowNode, reverseConnections?: Map): ValidationIssue[]; +export declare function validateAIAgentTool(node: WorkflowNode, reverseConnections: Map): ValidationIssue[]; +export declare function validateMCPClientTool(node: WorkflowNode): ValidationIssue[]; +export declare function validateCalculatorTool(node: WorkflowNode): ValidationIssue[]; +export declare function validateThinkTool(node: WorkflowNode): ValidationIssue[]; +export declare function validateSerpApiTool(node: WorkflowNode): ValidationIssue[]; +export declare function validateWikipediaTool(node: WorkflowNode): ValidationIssue[]; +export declare function validateSearXngTool(node: WorkflowNode): ValidationIssue[]; +export declare function validateWolframAlphaTool(node: WorkflowNode): ValidationIssue[]; +export declare const AI_TOOL_VALIDATORS: { + readonly 'nodes-langchain.toolHttpRequest': typeof validateHTTPRequestTool; + readonly 'nodes-langchain.toolCode': typeof validateCodeTool; + readonly 'nodes-langchain.toolVectorStore': typeof validateVectorStoreTool; + readonly 'nodes-langchain.toolWorkflow': typeof validateWorkflowTool; + readonly 'nodes-langchain.agentTool': typeof validateAIAgentTool; + readonly 'nodes-langchain.mcpClientTool': typeof validateMCPClientTool; + readonly 'nodes-langchain.toolCalculator': typeof validateCalculatorTool; + readonly 'nodes-langchain.toolThink': typeof validateThinkTool; + readonly 'nodes-langchain.toolSerpApi': typeof validateSerpApiTool; + readonly 'nodes-langchain.toolWikipedia': typeof validateWikipediaTool; + readonly 'nodes-langchain.toolSearXng': typeof validateSearXngTool; + readonly 'nodes-langchain.toolWolframAlpha': typeof validateWolframAlphaTool; +}; +export declare function isAIToolSubNode(nodeType: string): boolean; +export declare function validateAIToolSubNode(node: WorkflowNode, nodeType: string, reverseConnections: Map, workflow: WorkflowJson): ValidationIssue[]; +//# sourceMappingURL=ai-tool-validators.d.ts.map \ No newline at end of file diff --git a/dist/services/ai-tool-validators.d.ts.map b/dist/services/ai-tool-validators.d.ts.map new file mode 100644 index 0000000..15f0c1b --- /dev/null +++ b/dist/services/ai-tool-validators.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"ai-tool-validators.d.ts","sourceRoot":"","sources":["../../src/services/ai-tool-validators.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,UAAU,EAAE,GAAG,CAAC;IAChB,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,QAAQ,CAAC,EAAE,GAAG,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAMD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,YAAY,GAAG,eAAe,EAAE,CAuJ7E;AAMD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,YAAY,GAAG,eAAe,EAAE,CAoCtE;AAMD,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,YAAY,EAClB,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,EACpD,QAAQ,EAAE,YAAY,GACrB,eAAe,EAAE,CAmCnB;AAMD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,GAAG,eAAe,EAAE,CA0BjI;AAMD,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,YAAY,EAClB,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,GACnD,eAAe,EAAE,CAmCnB;AAMD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,YAAY,GAAG,eAAe,EAAE,CA0B3E;AAMD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,eAAe,EAAE,CAM5E;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG,eAAe,EAAE,CAMvE;AAMD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,YAAY,GAAG,eAAe,EAAE,CAyBzE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,YAAY,GAAG,eAAe,EAAE,CA4B3E;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,YAAY,GAAG,eAAe,EAAE,CA0BzE;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,YAAY,GAAG,eAAe,EAAE,CAyB9E;AAKD,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;CAarB,CAAC;AAKX,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGzD;AAKD,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,YAAY,EAClB,QAAQ,EAAE,MAAM,EAChB,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,EACpD,QAAQ,EAAE,YAAY,GACrB,eAAe,EAAE,CAgCnB"} \ No newline at end of file diff --git a/dist/services/ai-tool-validators.js b/dist/services/ai-tool-validators.js new file mode 100644 index 0000000..38a9e2f --- /dev/null +++ b/dist/services/ai-tool-validators.js @@ -0,0 +1,438 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.AI_TOOL_VALIDATORS = void 0; +exports.validateHTTPRequestTool = validateHTTPRequestTool; +exports.validateCodeTool = validateCodeTool; +exports.validateVectorStoreTool = validateVectorStoreTool; +exports.validateWorkflowTool = validateWorkflowTool; +exports.validateAIAgentTool = validateAIAgentTool; +exports.validateMCPClientTool = validateMCPClientTool; +exports.validateCalculatorTool = validateCalculatorTool; +exports.validateThinkTool = validateThinkTool; +exports.validateSerpApiTool = validateSerpApiTool; +exports.validateWikipediaTool = validateWikipediaTool; +exports.validateSearXngTool = validateSearXngTool; +exports.validateWolframAlphaTool = validateWolframAlphaTool; +exports.isAIToolSubNode = isAIToolSubNode; +exports.validateAIToolSubNode = validateAIToolSubNode; +const node_type_normalizer_1 = require("../utils/node-type-normalizer"); +const MIN_DESCRIPTION_LENGTH_SHORT = 10; +const MIN_DESCRIPTION_LENGTH_MEDIUM = 15; +const MIN_DESCRIPTION_LENGTH_LONG = 20; +const MAX_ITERATIONS_WARNING_THRESHOLD = 50; +const MAX_TOPK_WARNING_THRESHOLD = 20; +function validateHTTPRequestTool(node) { + const issues = []; + if (!node.parameters.toolDescription) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `HTTP Request Tool "${node.name}" has no toolDescription. Add a clear description to help the LLM know when to use this API.`, + code: 'MISSING_TOOL_DESCRIPTION' + }); + } + else if (node.parameters.toolDescription.trim().length < MIN_DESCRIPTION_LENGTH_MEDIUM) { + issues.push({ + severity: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `HTTP Request Tool "${node.name}" toolDescription is too short (minimum ${MIN_DESCRIPTION_LENGTH_MEDIUM} characters). Explain what API this calls and when to use it.` + }); + } + if (!node.parameters.url) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `HTTP Request Tool "${node.name}" has no URL. Add the API endpoint URL.`, + code: 'MISSING_URL' + }); + } + else { + try { + const urlObj = new URL(node.parameters.url); + if (urlObj.protocol !== 'http:' && urlObj.protocol !== 'https:') { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `HTTP Request Tool "${node.name}" has invalid URL protocol "${urlObj.protocol}". Use http:// or https:// only.`, + code: 'INVALID_URL_PROTOCOL' + }); + } + } + catch (e) { + if (!node.parameters.url.includes('{{')) { + issues.push({ + severity: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `HTTP Request Tool "${node.name}" has potentially invalid URL format. Ensure it's a valid URL or n8n expression.` + }); + } + } + } + if (node.parameters.url || node.parameters.body || node.parameters.headers) { + const placeholderRegex = /\{([^}]+)\}/g; + const placeholders = new Set(); + [node.parameters.url, node.parameters.body, JSON.stringify(node.parameters.headers || {})].forEach(text => { + if (text) { + let match; + while ((match = placeholderRegex.exec(text)) !== null) { + placeholders.add(match[1]); + } + } + }); + if (placeholders.size > 0) { + const definitions = node.parameters.placeholderDefinitions?.values || []; + const definedNames = new Set(definitions.map((d) => d.name)); + if (!node.parameters.placeholderDefinitions) { + issues.push({ + severity: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `HTTP Request Tool "${node.name}" uses placeholders but has no placeholderDefinitions. Add definitions to describe the expected inputs.` + }); + } + else { + for (const placeholder of placeholders) { + if (!definedNames.has(placeholder)) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `HTTP Request Tool "${node.name}" Placeholder "${placeholder}" in URL but it's not defined in placeholderDefinitions.`, + code: 'UNDEFINED_PLACEHOLDER' + }); + } + } + for (const def of definitions) { + if (!placeholders.has(def.name)) { + issues.push({ + severity: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `HTTP Request Tool "${node.name}" defines placeholder "${def.name}" but doesn't use it.` + }); + } + } + } + } + } + if (node.parameters.authentication === 'predefinedCredentialType' && + (!node.credentials || Object.keys(node.credentials).length === 0)) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `HTTP Request Tool "${node.name}" requires credentials but none are configured.`, + code: 'MISSING_CREDENTIALS' + }); + } + const validMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS']; + if (node.parameters.method && !validMethods.includes(node.parameters.method.toUpperCase())) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `HTTP Request Tool "${node.name}" has invalid HTTP method "${node.parameters.method}". Use one of: ${validMethods.join(', ')}.`, + code: 'INVALID_HTTP_METHOD' + }); + } + if (['POST', 'PUT', 'PATCH'].includes(node.parameters.method?.toUpperCase())) { + if (!node.parameters.body && !node.parameters.jsonBody) { + issues.push({ + severity: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `HTTP Request Tool "${node.name}" uses ${node.parameters.method} but has no body. Consider adding a body or using GET instead.` + }); + } + } + return issues; +} +function validateCodeTool(node) { + const issues = []; + if (!node.parameters.toolDescription) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Code Tool "${node.name}" has no toolDescription. Add one to help the LLM understand the tool's purpose.`, + code: 'MISSING_TOOL_DESCRIPTION' + }); + } + if (!node.parameters.jsCode || node.parameters.jsCode.trim().length === 0) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Code Tool "${node.name}" code is empty. Add the JavaScript code to execute.`, + code: 'MISSING_CODE' + }); + } + if (!node.parameters.inputSchema && !node.parameters.specifyInputSchema) { + issues.push({ + severity: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `Code Tool "${node.name}" has no input schema. Consider adding one to validate LLM inputs.` + }); + } + return issues; +} +function validateVectorStoreTool(node, reverseConnections, workflow) { + const issues = []; + if (!node.parameters.toolDescription) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Vector Store Tool "${node.name}" has no toolDescription. Add one to explain what data it searches.`, + code: 'MISSING_TOOL_DESCRIPTION' + }); + } + if (node.parameters.topK !== undefined) { + if (typeof node.parameters.topK !== 'number' || node.parameters.topK < 1) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Vector Store Tool "${node.name}" has invalid topK value. Must be a positive number.`, + code: 'INVALID_TOPK' + }); + } + else if (node.parameters.topK > MAX_TOPK_WARNING_THRESHOLD) { + issues.push({ + severity: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `Vector Store Tool "${node.name}" has topK=${node.parameters.topK}. Large values (>${MAX_TOPK_WARNING_THRESHOLD}) may overwhelm the LLM context. Consider reducing to 10 or less.` + }); + } + } + return issues; +} +function validateWorkflowTool(node, reverseConnections) { + const issues = []; + if (!node.parameters.toolDescription) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Workflow Tool "${node.name}" has no toolDescription. Add one to help the LLM know when to use this tool.`, + code: 'MISSING_TOOL_DESCRIPTION' + }); + } + if (!node.parameters.workflowId) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Workflow Tool "${node.name}" has no workflowId. Select a workflow to execute.`, + code: 'MISSING_WORKFLOW_ID' + }); + } + return issues; +} +function validateAIAgentTool(node, reverseConnections) { + const issues = []; + if (!node.parameters.toolDescription) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `AI Agent Tool "${node.name}" has no toolDescription. Add one to help the LLM know when to use this tool.`, + code: 'MISSING_TOOL_DESCRIPTION' + }); + } + if (node.parameters.maxIterations !== undefined) { + if (typeof node.parameters.maxIterations !== 'number' || node.parameters.maxIterations < 1) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `AI Agent Tool "${node.name}" has invalid maxIterations. Must be a positive number.`, + code: 'INVALID_MAX_ITERATIONS' + }); + } + else if (node.parameters.maxIterations > MAX_ITERATIONS_WARNING_THRESHOLD) { + issues.push({ + severity: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `AI Agent Tool "${node.name}" has maxIterations=${node.parameters.maxIterations}. Large values (>${MAX_ITERATIONS_WARNING_THRESHOLD}) may lead to long execution times.` + }); + } + } + return issues; +} +function validateMCPClientTool(node) { + const issues = []; + if (!node.parameters.toolDescription) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `MCP Client Tool "${node.name}" has no toolDescription. Add one to help the LLM know when to use this tool.`, + code: 'MISSING_TOOL_DESCRIPTION' + }); + } + if (!node.parameters.serverUrl) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `MCP Client Tool "${node.name}" has no serverUrl. Configure the MCP server URL.`, + code: 'MISSING_SERVER_URL' + }); + } + return issues; +} +function validateCalculatorTool(node) { + const issues = []; + return issues; +} +function validateThinkTool(node) { + const issues = []; + return issues; +} +function validateSerpApiTool(node) { + const issues = []; + if (!node.parameters.toolDescription) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `SerpApi Tool "${node.name}" has no toolDescription. Add one to explain when to use Google search.`, + code: 'MISSING_TOOL_DESCRIPTION' + }); + } + if (!node.credentials || !node.credentials.serpApiApi) { + issues.push({ + severity: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `SerpApi Tool "${node.name}" requires SerpApi credentials. Configure your API key.` + }); + } + return issues; +} +function validateWikipediaTool(node) { + const issues = []; + if (!node.parameters.toolDescription) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Wikipedia Tool "${node.name}" has no toolDescription. Add one to explain when to use Wikipedia.`, + code: 'MISSING_TOOL_DESCRIPTION' + }); + } + if (node.parameters.language) { + const validLanguageCodes = /^[a-z]{2,3}$/; + if (!validLanguageCodes.test(node.parameters.language)) { + issues.push({ + severity: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `Wikipedia Tool "${node.name}" has potentially invalid language code "${node.parameters.language}". Use ISO 639 codes (e.g., "en", "es", "fr").` + }); + } + } + return issues; +} +function validateSearXngTool(node) { + const issues = []; + if (!node.parameters.toolDescription) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `SearXNG Tool "${node.name}" has no toolDescription. Add one to explain when to use SearXNG.`, + code: 'MISSING_TOOL_DESCRIPTION' + }); + } + if (!node.parameters.baseUrl) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `SearXNG Tool "${node.name}" has no baseUrl. Configure your SearXNG instance URL.`, + code: 'MISSING_BASE_URL' + }); + } + return issues; +} +function validateWolframAlphaTool(node) { + const issues = []; + if (!node.credentials || (!node.credentials.wolframAlpha && !node.credentials.wolframAlphaApi)) { + issues.push({ + severity: 'error', + nodeId: node.id, + nodeName: node.name, + message: `WolframAlpha Tool "${node.name}" requires Wolfram|Alpha API credentials. Configure your App ID.`, + code: 'MISSING_CREDENTIALS' + }); + } + if (!node.parameters.description && !node.parameters.toolDescription) { + issues.push({ + severity: 'info', + nodeId: node.id, + nodeName: node.name, + message: `WolframAlpha Tool "${node.name}" has no custom description. Add one to explain when to use Wolfram|Alpha for computational queries.` + }); + } + return issues; +} +exports.AI_TOOL_VALIDATORS = { + 'nodes-langchain.toolHttpRequest': validateHTTPRequestTool, + 'nodes-langchain.toolCode': validateCodeTool, + 'nodes-langchain.toolVectorStore': validateVectorStoreTool, + 'nodes-langchain.toolWorkflow': validateWorkflowTool, + 'nodes-langchain.agentTool': validateAIAgentTool, + 'nodes-langchain.mcpClientTool': validateMCPClientTool, + 'nodes-langchain.toolCalculator': validateCalculatorTool, + 'nodes-langchain.toolThink': validateThinkTool, + 'nodes-langchain.toolSerpApi': validateSerpApiTool, + 'nodes-langchain.toolWikipedia': validateWikipediaTool, + 'nodes-langchain.toolSearXng': validateSearXngTool, + 'nodes-langchain.toolWolframAlpha': validateWolframAlphaTool, +}; +function isAIToolSubNode(nodeType) { + const normalized = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + return normalized in exports.AI_TOOL_VALIDATORS; +} +function validateAIToolSubNode(node, nodeType, reverseConnections, workflow) { + const normalized = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + switch (normalized) { + case 'nodes-langchain.toolHttpRequest': + return validateHTTPRequestTool(node); + case 'nodes-langchain.toolCode': + return validateCodeTool(node); + case 'nodes-langchain.toolVectorStore': + return validateVectorStoreTool(node, reverseConnections, workflow); + case 'nodes-langchain.toolWorkflow': + return validateWorkflowTool(node); + case 'nodes-langchain.agentTool': + return validateAIAgentTool(node, reverseConnections); + case 'nodes-langchain.mcpClientTool': + return validateMCPClientTool(node); + case 'nodes-langchain.toolCalculator': + return validateCalculatorTool(node); + case 'nodes-langchain.toolThink': + return validateThinkTool(node); + case 'nodes-langchain.toolSerpApi': + return validateSerpApiTool(node); + case 'nodes-langchain.toolWikipedia': + return validateWikipediaTool(node); + case 'nodes-langchain.toolSearXng': + return validateSearXngTool(node); + case 'nodes-langchain.toolWolframAlpha': + return validateWolframAlphaTool(node); + default: + return []; + } +} +//# sourceMappingURL=ai-tool-validators.js.map \ No newline at end of file diff --git a/dist/services/ai-tool-validators.js.map b/dist/services/ai-tool-validators.js.map new file mode 100644 index 0000000..2b4b46f --- /dev/null +++ b/dist/services/ai-tool-validators.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ai-tool-validators.js","sourceRoot":"","sources":["../../src/services/ai-tool-validators.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/breaking-change-detector.d.ts b/dist/services/breaking-change-detector.d.ts new file mode 100644 index 0000000..afa0691 --- /dev/null +++ b/dist/services/breaking-change-detector.d.ts @@ -0,0 +1,38 @@ +import { NodeRepository } from '../database/node-repository'; +export interface DetectedChange { + propertyName: string; + changeType: 'added' | 'removed' | 'renamed' | 'type_changed' | 'requirement_changed' | 'default_changed'; + isBreaking: boolean; + oldValue?: any; + newValue?: any; + migrationHint: string; + autoMigratable: boolean; + migrationStrategy?: any; + severity: 'LOW' | 'MEDIUM' | 'HIGH'; + source: 'registry' | 'dynamic'; +} +export interface VersionUpgradeAnalysis { + nodeType: string; + fromVersion: string; + toVersion: string; + hasBreakingChanges: boolean; + changes: DetectedChange[]; + autoMigratableCount: number; + manualRequiredCount: number; + overallSeverity: 'LOW' | 'MEDIUM' | 'HIGH'; + recommendations: string[]; +} +export declare class BreakingChangeDetector { + private nodeRepository; + constructor(nodeRepository: NodeRepository); + analyzeVersionUpgrade(nodeType: string, fromVersion: string, toVersion: string): Promise; + private getRegistryChanges; + private detectDynamicChanges; + private flattenProperties; + private mergeChanges; + private calculateOverallSeverity; + private generateRecommendations; + hasBreakingChanges(nodeType: string, fromVersion: string, toVersion: string): boolean; + getChangedProperties(nodeType: string, fromVersion: string, toVersion: string): string[]; +} +//# sourceMappingURL=breaking-change-detector.d.ts.map \ No newline at end of file diff --git a/dist/services/breaking-change-detector.d.ts.map b/dist/services/breaking-change-detector.d.ts.map new file mode 100644 index 0000000..dcec4a8 --- /dev/null +++ b/dist/services/breaking-change-detector.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"breaking-change-detector.d.ts","sourceRoot":"","sources":["../../src/services/breaking-change-detector.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAQ7D,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,cAAc,GAAG,qBAAqB,GAAG,iBAAiB,CAAC;IACzG,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE,GAAG,CAAC;IACxB,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;CAChC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC3C,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,qBAAa,sBAAsB;IACrB,OAAO,CAAC,cAAc;gBAAd,cAAc,EAAE,cAAc;IAK5C,qBAAqB,CACzB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,sBAAsB,CAAC;IAqClC,OAAO,CAAC,kBAAkB;IAwB1B,OAAO,CAAC,oBAAoB;IA+F5B,OAAO,CAAC,iBAAiB;IAuBzB,OAAO,CAAC,YAAY;IA4BpB,OAAO,CAAC,wBAAwB;IAShC,OAAO,CAAC,uBAAuB;IAsC/B,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAQrF,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE;CAIzF"} \ No newline at end of file diff --git a/dist/services/breaking-change-detector.js b/dist/services/breaking-change-detector.js new file mode 100644 index 0000000..56218e7 --- /dev/null +++ b/dist/services/breaking-change-detector.js @@ -0,0 +1,184 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BreakingChangeDetector = void 0; +const breaking_changes_registry_1 = require("./breaking-changes-registry"); +class BreakingChangeDetector { + constructor(nodeRepository) { + this.nodeRepository = nodeRepository; + } + async analyzeVersionUpgrade(nodeType, fromVersion, toVersion) { + const registryChanges = this.getRegistryChanges(nodeType, fromVersion, toVersion); + const dynamicChanges = this.detectDynamicChanges(nodeType, fromVersion, toVersion); + const allChanges = this.mergeChanges(registryChanges, dynamicChanges); + const hasBreakingChanges = allChanges.some(c => c.isBreaking); + const autoMigratableCount = allChanges.filter(c => c.autoMigratable).length; + const manualRequiredCount = allChanges.filter(c => !c.autoMigratable).length; + const overallSeverity = this.calculateOverallSeverity(allChanges); + const recommendations = this.generateRecommendations(allChanges); + return { + nodeType, + fromVersion, + toVersion, + hasBreakingChanges, + changes: allChanges, + autoMigratableCount, + manualRequiredCount, + overallSeverity, + recommendations + }; + } + getRegistryChanges(nodeType, fromVersion, toVersion) { + const registryChanges = (0, breaking_changes_registry_1.getAllChangesForNode)(nodeType, fromVersion, toVersion); + return registryChanges.map(change => ({ + propertyName: change.propertyName, + changeType: change.changeType, + isBreaking: change.isBreaking, + oldValue: change.oldValue, + newValue: change.newValue, + migrationHint: change.migrationHint, + autoMigratable: change.autoMigratable, + migrationStrategy: change.migrationStrategy, + severity: change.severity, + source: 'registry' + })); + } + detectDynamicChanges(nodeType, fromVersion, toVersion) { + const oldVersionData = this.nodeRepository.getNodeVersion(nodeType, fromVersion); + const newVersionData = this.nodeRepository.getNodeVersion(nodeType, toVersion); + if (!oldVersionData || !newVersionData) { + return []; + } + const changes = []; + const oldProps = this.flattenProperties(oldVersionData.propertiesSchema || []); + const newProps = this.flattenProperties(newVersionData.propertiesSchema || []); + for (const propName of Object.keys(newProps)) { + if (!oldProps[propName]) { + const prop = newProps[propName]; + const isRequired = prop.required === true; + changes.push({ + propertyName: propName, + changeType: 'added', + isBreaking: isRequired, + newValue: prop.type || 'unknown', + migrationHint: isRequired + ? `Property "${propName}" is now required in v${toVersion}. Provide a value to prevent validation errors.` + : `Property "${propName}" was added in v${toVersion}. Optional parameter, safe to ignore if not needed.`, + autoMigratable: !isRequired, + migrationStrategy: !isRequired + ? { + type: 'add_property', + defaultValue: prop.default || null + } + : undefined, + severity: isRequired ? 'HIGH' : 'LOW', + source: 'dynamic' + }); + } + } + for (const propName of Object.keys(oldProps)) { + if (!newProps[propName]) { + changes.push({ + propertyName: propName, + changeType: 'removed', + isBreaking: true, + oldValue: oldProps[propName].type || 'unknown', + migrationHint: `Property "${propName}" was removed in v${toVersion}. Remove this property from your configuration.`, + autoMigratable: true, + migrationStrategy: { + type: 'remove_property' + }, + severity: 'MEDIUM', + source: 'dynamic' + }); + } + } + for (const propName of Object.keys(newProps)) { + if (oldProps[propName]) { + const oldRequired = oldProps[propName].required === true; + const newRequired = newProps[propName].required === true; + if (oldRequired !== newRequired) { + changes.push({ + propertyName: propName, + changeType: 'requirement_changed', + isBreaking: newRequired && !oldRequired, + oldValue: oldRequired ? 'required' : 'optional', + newValue: newRequired ? 'required' : 'optional', + migrationHint: newRequired + ? `Property "${propName}" is now required in v${toVersion}. Ensure a value is provided.` + : `Property "${propName}" is now optional in v${toVersion}.`, + autoMigratable: false, + severity: newRequired ? 'HIGH' : 'LOW', + source: 'dynamic' + }); + } + } + } + return changes; + } + flattenProperties(properties, prefix = '') { + const flat = {}; + for (const prop of properties) { + if (!prop.name && !prop.displayName) + continue; + const propName = prop.name || prop.displayName; + const fullPath = prefix ? `${prefix}.${propName}` : propName; + flat[fullPath] = prop; + if (prop.options && Array.isArray(prop.options)) { + Object.assign(flat, this.flattenProperties(prop.options, fullPath)); + } + } + return flat; + } + mergeChanges(registryChanges, dynamicChanges) { + const merged = [...registryChanges]; + for (const dynamicChange of dynamicChanges) { + const existsInRegistry = registryChanges.some(rc => rc.propertyName === dynamicChange.propertyName && + rc.changeType === dynamicChange.changeType); + if (!existsInRegistry) { + merged.push(dynamicChange); + } + } + const severityOrder = { HIGH: 0, MEDIUM: 1, LOW: 2 }; + merged.sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]); + return merged; + } + calculateOverallSeverity(changes) { + if (changes.some(c => c.severity === 'HIGH')) + return 'HIGH'; + if (changes.some(c => c.severity === 'MEDIUM')) + return 'MEDIUM'; + return 'LOW'; + } + generateRecommendations(changes) { + const recommendations = []; + const breakingChanges = changes.filter(c => c.isBreaking); + const autoMigratable = changes.filter(c => c.autoMigratable); + const manualRequired = changes.filter(c => !c.autoMigratable); + if (breakingChanges.length === 0) { + recommendations.push('✓ No breaking changes detected. This upgrade should be safe.'); + } + else { + recommendations.push(`⚠ ${breakingChanges.length} breaking change(s) detected. Review carefully before applying.`); + } + if (autoMigratable.length > 0) { + recommendations.push(`✓ ${autoMigratable.length} change(s) can be automatically migrated.`); + } + if (manualRequired.length > 0) { + recommendations.push(`✋ ${manualRequired.length} change(s) require manual intervention.`); + for (const change of manualRequired) { + recommendations.push(` - ${change.propertyName}: ${change.migrationHint}`); + } + } + return recommendations; + } + hasBreakingChanges(nodeType, fromVersion, toVersion) { + const registryChanges = (0, breaking_changes_registry_1.getBreakingChangesForNode)(nodeType, fromVersion, toVersion); + return registryChanges.length > 0; + } + getChangedProperties(nodeType, fromVersion, toVersion) { + const registryChanges = (0, breaking_changes_registry_1.getAllChangesForNode)(nodeType, fromVersion, toVersion); + return registryChanges.map(c => c.propertyName); + } +} +exports.BreakingChangeDetector = BreakingChangeDetector; +//# sourceMappingURL=breaking-change-detector.js.map \ No newline at end of file diff --git a/dist/services/breaking-change-detector.js.map b/dist/services/breaking-change-detector.js.map new file mode 100644 index 0000000..ebc7ae8 --- /dev/null +++ b/dist/services/breaking-change-detector.js.map @@ -0,0 +1 @@ +{"version":3,"file":"breaking-change-detector.js","sourceRoot":"","sources":["../../src/services/breaking-change-detector.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/breaking-changes-registry.d.ts b/dist/services/breaking-changes-registry.d.ts new file mode 100644 index 0000000..5a354e9 --- /dev/null +++ b/dist/services/breaking-changes-registry.d.ts @@ -0,0 +1,28 @@ +export interface BreakingChange { + nodeType: string; + fromVersion: string; + toVersion: string; + propertyName: string; + changeType: 'added' | 'removed' | 'renamed' | 'type_changed' | 'requirement_changed' | 'default_changed'; + isBreaking: boolean; + oldValue?: string; + newValue?: string; + migrationHint: string; + autoMigratable: boolean; + migrationStrategy?: { + type: 'add_property' | 'remove_property' | 'rename_property' | 'set_default'; + defaultValue?: any; + sourceProperty?: string; + targetProperty?: string; + }; + severity: 'LOW' | 'MEDIUM' | 'HIGH'; +} +export declare const BREAKING_CHANGES_REGISTRY: BreakingChange[]; +export declare function getBreakingChangesForNode(nodeType: string, fromVersion: string, toVersion: string): BreakingChange[]; +export declare function getAllChangesForNode(nodeType: string, fromVersion: string, toVersion: string): BreakingChange[]; +export declare function getAutoMigratableChanges(nodeType: string, fromVersion: string, toVersion: string): BreakingChange[]; +export declare function hasBreakingChanges(nodeType: string, fromVersion: string, toVersion: string): boolean; +export declare function getMigrationHints(nodeType: string, fromVersion: string, toVersion: string): string[]; +export declare function getNodesWithVersionMigrations(): string[]; +export declare function getTrackedVersionsForNode(nodeType: string): string[]; +//# sourceMappingURL=breaking-changes-registry.d.ts.map \ No newline at end of file diff --git a/dist/services/breaking-changes-registry.d.ts.map b/dist/services/breaking-changes-registry.d.ts.map new file mode 100644 index 0000000..6891980 --- /dev/null +++ b/dist/services/breaking-changes-registry.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"breaking-changes-registry.d.ts","sourceRoot":"","sources":["../../src/services/breaking-changes-registry.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,cAAc,GAAG,qBAAqB,GAAG,iBAAiB,CAAC;IACzG,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE;QAClB,IAAI,EAAE,cAAc,GAAG,iBAAiB,GAAG,iBAAiB,GAAG,aAAa,CAAC;QAC7E,YAAY,CAAC,EAAE,GAAG,CAAC;QACnB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CACrC;AAKD,eAAO,MAAM,yBAAyB,EAAE,cAAc,EAyJrD,CAAC;AAKF,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,cAAc,EAAE,CAYlB;AAKD,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,cAAc,EAAE,CASlB;AAKD,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,cAAc,EAAE,CAIlB;AAKD,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAET;AAKD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,MAAM,EAAE,CAGV;AAwBD,wBAAgB,6BAA6B,IAAI,MAAM,EAAE,CAUxD;AAKD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAWpE"} \ No newline at end of file diff --git a/dist/services/breaking-changes-registry.js b/dist/services/breaking-changes-registry.js new file mode 100644 index 0000000..37d9b6e --- /dev/null +++ b/dist/services/breaking-changes-registry.js @@ -0,0 +1,200 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BREAKING_CHANGES_REGISTRY = void 0; +exports.getBreakingChangesForNode = getBreakingChangesForNode; +exports.getAllChangesForNode = getAllChangesForNode; +exports.getAutoMigratableChanges = getAutoMigratableChanges; +exports.hasBreakingChanges = hasBreakingChanges; +exports.getMigrationHints = getMigrationHints; +exports.getNodesWithVersionMigrations = getNodesWithVersionMigrations; +exports.getTrackedVersionsForNode = getTrackedVersionsForNode; +exports.BREAKING_CHANGES_REGISTRY = [ + { + nodeType: 'n8n-nodes-base.executeWorkflow', + fromVersion: '1.0', + toVersion: '1.1', + propertyName: 'parameters.inputFieldMapping', + changeType: 'added', + isBreaking: true, + migrationHint: 'In v1.1+, the Execute Workflow node requires explicit field mapping to pass data to sub-workflows. Add an "inputFieldMapping" object with "mappings" array defining how to map fields from parent to child workflow.', + autoMigratable: true, + migrationStrategy: { + type: 'add_property', + defaultValue: { + mappings: [] + } + }, + severity: 'HIGH' + }, + { + nodeType: 'n8n-nodes-base.executeWorkflow', + fromVersion: '1.0', + toVersion: '1.1', + propertyName: 'parameters.mode', + changeType: 'requirement_changed', + isBreaking: false, + migrationHint: 'The "mode" parameter behavior changed in v1.1. Default is now "static" instead of "list". Ensure your workflow ID specification matches the selected mode.', + autoMigratable: false, + severity: 'MEDIUM' + }, + { + nodeType: 'n8n-nodes-base.webhook', + fromVersion: '2.0', + toVersion: '2.1', + propertyName: 'webhookId', + changeType: 'added', + isBreaking: true, + migrationHint: 'In v2.1+, webhooks require a unique "webhookId" field in addition to the path. This ensures webhook persistence across workflow updates. A UUID will be auto-generated if not provided.', + autoMigratable: true, + migrationStrategy: { + type: 'add_property', + defaultValue: null + }, + severity: 'HIGH' + }, + { + nodeType: 'n8n-nodes-base.webhook', + fromVersion: '1.0', + toVersion: '2.0', + propertyName: 'parameters.path', + changeType: 'requirement_changed', + isBreaking: true, + migrationHint: 'In v2.0+, the webhook path must be explicitly defined and cannot be empty. Ensure a valid path is set.', + autoMigratable: false, + severity: 'HIGH' + }, + { + nodeType: 'n8n-nodes-base.webhook', + fromVersion: '1.0', + toVersion: '2.0', + propertyName: 'parameters.responseMode', + changeType: 'added', + isBreaking: false, + migrationHint: 'v2.0 introduces a "responseMode" parameter to control how the webhook responds. Default is "onReceived" (immediate response). Use "lastNode" to wait for workflow completion.', + autoMigratable: true, + migrationStrategy: { + type: 'add_property', + defaultValue: 'onReceived' + }, + severity: 'LOW' + }, + { + nodeType: 'n8n-nodes-base.httpRequest', + fromVersion: '4.1', + toVersion: '4.2', + propertyName: 'parameters.sendBody', + changeType: 'requirement_changed', + isBreaking: false, + migrationHint: 'In v4.2+, "sendBody" must be explicitly set to true for POST/PUT/PATCH requests to include a body. Previous versions had implicit body sending.', + autoMigratable: true, + migrationStrategy: { + type: 'add_property', + defaultValue: true + }, + severity: 'MEDIUM' + }, + { + nodeType: 'n8n-nodes-base.code', + fromVersion: '1.0', + toVersion: '2.0', + propertyName: 'parameters.mode', + changeType: 'added', + isBreaking: false, + migrationHint: 'v2.0 introduces execution modes: "runOnceForAllItems" (default) and "runOnceForEachItem". The default mode processes all items at once, which may differ from v1.0 behavior.', + autoMigratable: true, + migrationStrategy: { + type: 'add_property', + defaultValue: 'runOnceForAllItems' + }, + severity: 'MEDIUM' + }, + { + nodeType: 'n8n-nodes-base.scheduleTrigger', + fromVersion: '1.0', + toVersion: '1.1', + propertyName: 'parameters.rule.interval', + changeType: 'type_changed', + isBreaking: true, + oldValue: 'string', + newValue: 'array', + migrationHint: 'In v1.1+, the interval parameter changed from a single string to an array of interval objects. Convert your single interval to an array format: [{field: "hours", value: 1}]', + autoMigratable: false, + severity: 'HIGH' + }, + { + nodeType: '*', + fromVersion: '1.0', + toVersion: '2.0', + propertyName: 'continueOnFail', + changeType: 'removed', + isBreaking: false, + migrationHint: 'The "continueOnFail" property is deprecated. Use "onError" instead with value "continueErrorOutput" or "continueRegularOutput".', + autoMigratable: true, + migrationStrategy: { + type: 'rename_property', + sourceProperty: 'continueOnFail', + targetProperty: 'onError', + defaultValue: 'continueErrorOutput' + }, + severity: 'MEDIUM' + } +]; +function getBreakingChangesForNode(nodeType, fromVersion, toVersion) { + return exports.BREAKING_CHANGES_REGISTRY.filter(change => { + const nodeMatches = change.nodeType === nodeType || change.nodeType === '*'; + const versionMatches = compareVersions(fromVersion, change.fromVersion) >= 0 && + compareVersions(toVersion, change.toVersion) <= 0; + return nodeMatches && versionMatches && change.isBreaking; + }); +} +function getAllChangesForNode(nodeType, fromVersion, toVersion) { + return exports.BREAKING_CHANGES_REGISTRY.filter(change => { + const nodeMatches = change.nodeType === nodeType || change.nodeType === '*'; + const versionMatches = compareVersions(fromVersion, change.fromVersion) >= 0 && + compareVersions(toVersion, change.toVersion) <= 0; + return nodeMatches && versionMatches; + }); +} +function getAutoMigratableChanges(nodeType, fromVersion, toVersion) { + return getAllChangesForNode(nodeType, fromVersion, toVersion).filter(change => change.autoMigratable); +} +function hasBreakingChanges(nodeType, fromVersion, toVersion) { + return getBreakingChangesForNode(nodeType, fromVersion, toVersion).length > 0; +} +function getMigrationHints(nodeType, fromVersion, toVersion) { + const changes = getAllChangesForNode(nodeType, fromVersion, toVersion); + return changes.map(change => change.migrationHint); +} +function compareVersions(v1, v2) { + const parts1 = v1.split('.').map(Number); + const parts2 = v2.split('.').map(Number); + 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 getNodesWithVersionMigrations() { + const nodeTypes = new Set(); + exports.BREAKING_CHANGES_REGISTRY.forEach(change => { + if (change.nodeType !== '*') { + nodeTypes.add(change.nodeType); + } + }); + return Array.from(nodeTypes); +} +function getTrackedVersionsForNode(nodeType) { + const versions = new Set(); + exports.BREAKING_CHANGES_REGISTRY + .filter(change => change.nodeType === nodeType || change.nodeType === '*') + .forEach(change => { + versions.add(change.fromVersion); + versions.add(change.toVersion); + }); + return Array.from(versions).sort((a, b) => compareVersions(a, b)); +} +//# sourceMappingURL=breaking-changes-registry.js.map \ No newline at end of file diff --git a/dist/services/breaking-changes-registry.js.map b/dist/services/breaking-changes-registry.js.map new file mode 100644 index 0000000..21f1e6a --- /dev/null +++ b/dist/services/breaking-changes-registry.js.map @@ -0,0 +1 @@ +{"version":3,"file":"breaking-changes-registry.js","sourceRoot":"","sources":["../../src/services/breaking-changes-registry.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/confidence-scorer.d.ts b/dist/services/confidence-scorer.d.ts new file mode 100644 index 0000000..2a276e0 --- /dev/null +++ b/dist/services/confidence-scorer.d.ts @@ -0,0 +1,24 @@ +export interface ConfidenceScore { + value: number; + reason: string; + factors: ConfidenceFactor[]; +} +export interface ConfidenceFactor { + name: string; + weight: number; + matched: boolean; + description: string; +} +export declare class ConfidenceScorer { + static scoreResourceLocatorRecommendation(fieldName: string, nodeType: string, value: string): ConfidenceScore; + private static readonly EXACT_FIELD_MAPPINGS; + private static checkExactFieldMatch; + private static readonly FIELD_PATTERNS; + private static checkFieldPattern; + private static checkValuePattern; + private static readonly RESOURCE_HEAVY_NODES; + private static checkNodeCategory; + static getConfidenceLevel(score: number): 'high' | 'medium' | 'low' | 'very-low'; + static shouldApplyRecommendation(score: number, threshold?: 'strict' | 'normal' | 'relaxed'): boolean; +} +//# sourceMappingURL=confidence-scorer.d.ts.map \ No newline at end of file diff --git a/dist/services/confidence-scorer.d.ts.map b/dist/services/confidence-scorer.d.ts.map new file mode 100644 index 0000000..2ee2d06 --- /dev/null +++ b/dist/services/confidence-scorer.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"confidence-scorer.d.ts","sourceRoot":"","sources":["../../src/services/confidence-scorer.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,gBAAgB;IAI3B,MAAM,CAAC,kCAAkC,CACvC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,eAAe;IAyElB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAO1C;IAEF,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAenC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CASpC;IAEF,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAOhC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAsBhC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAU1C;IAEF,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAWhC,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,UAAU;IAUhF,MAAM,CAAC,yBAAyB,CAC9B,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,QAAQ,GAAG,QAAQ,GAAG,SAAoB,GACpD,OAAO;CASX"} \ No newline at end of file diff --git a/dist/services/confidence-scorer.js b/dist/services/confidence-scorer.js new file mode 100644 index 0000000..68f258d --- /dev/null +++ b/dist/services/confidence-scorer.js @@ -0,0 +1,139 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ConfidenceScorer = void 0; +class ConfidenceScorer { + static scoreResourceLocatorRecommendation(fieldName, nodeType, value) { + const factors = []; + let totalWeight = 0; + let matchedWeight = 0; + const exactFieldMatch = this.checkExactFieldMatch(fieldName, nodeType); + factors.push({ + name: 'exact-field-match', + weight: 0.5, + matched: exactFieldMatch, + description: `Field name '${fieldName}' is known to use resource locator in ${nodeType}` + }); + const patternMatch = this.checkFieldPattern(fieldName); + factors.push({ + name: 'field-pattern', + weight: 0.3, + matched: patternMatch, + description: `Field name '${fieldName}' matches common resource locator patterns` + }); + const valuePattern = this.checkValuePattern(value); + factors.push({ + name: 'value-pattern', + weight: 0.1, + matched: valuePattern, + description: 'Value contains patterns typical of resource identifiers' + }); + const nodeCategory = this.checkNodeCategory(nodeType); + factors.push({ + name: 'node-category', + weight: 0.1, + matched: nodeCategory, + description: `Node type '${nodeType}' typically uses resource locators` + }); + for (const factor of factors) { + totalWeight += factor.weight; + if (factor.matched) { + matchedWeight += factor.weight; + } + } + const score = totalWeight > 0 ? matchedWeight / totalWeight : 0; + let reason; + if (score >= 0.8) { + reason = 'High confidence: Multiple strong indicators suggest resource locator format'; + } + else if (score >= 0.5) { + reason = 'Medium confidence: Some indicators suggest resource locator format'; + } + else if (score >= 0.3) { + reason = 'Low confidence: Weak indicators for resource locator format'; + } + else { + reason = 'Very low confidence: Minimal evidence for resource locator format'; + } + return { + value: score, + reason, + factors + }; + } + static checkExactFieldMatch(fieldName, nodeType) { + const nodeBase = nodeType.split('.').pop()?.toLowerCase() || ''; + for (const [pattern, fields] of Object.entries(this.EXACT_FIELD_MAPPINGS)) { + if (nodeBase === pattern || nodeBase.startsWith(`${pattern}-`)) { + return fields.includes(fieldName); + } + } + return false; + } + static checkFieldPattern(fieldName) { + return this.FIELD_PATTERNS.some(pattern => pattern.test(fieldName)); + } + static checkValuePattern(value) { + const content = value.startsWith('=') ? value.substring(1) : value; + if (!content.includes('{{') || !content.includes('}}')) { + return false; + } + const patterns = [ + /\{\{.*\.(id|Id|ID|key|Key|name|Name|path|Path|url|Url|uri|Uri).*\}\}/i, + /\{\{.*_(id|Id|ID|key|Key|name|Name|path|Path|url|Url|uri|Uri).*\}\}/i, + /\{\{.*(id|Id|ID|key|Key|name|Name|path|Path|url|Url|uri|Uri).*\}\}/i + ]; + return patterns.some(pattern => pattern.test(content)); + } + static checkNodeCategory(nodeType) { + const nodeBase = nodeType.split('.').pop()?.toLowerCase() || ''; + return this.RESOURCE_HEAVY_NODES.some(category => nodeBase.includes(category)); + } + static getConfidenceLevel(score) { + if (score >= 0.8) + return 'high'; + if (score >= 0.5) + return 'medium'; + if (score >= 0.3) + return 'low'; + return 'very-low'; + } + static shouldApplyRecommendation(score, threshold = 'normal') { + const thresholds = { + strict: 0.8, + normal: 0.5, + relaxed: 0.3 + }; + return score >= thresholds[threshold]; + } +} +exports.ConfidenceScorer = ConfidenceScorer; +ConfidenceScorer.EXACT_FIELD_MAPPINGS = { + 'github': ['owner', 'repository', 'user', 'organization'], + 'googlesheets': ['sheetId', 'documentId', 'spreadsheetId'], + 'googledrive': ['fileId', 'folderId', 'driveId'], + 'slack': ['channel', 'user', 'channelId', 'userId'], + 'notion': ['databaseId', 'pageId', 'blockId'], + 'airtable': ['baseId', 'tableId', 'viewId'] +}; +ConfidenceScorer.FIELD_PATTERNS = [ + /^.*Id$/i, + /^.*Ids$/i, + /^.*Key$/i, + /^.*Name$/i, + /^.*Path$/i, + /^.*Url$/i, + /^.*Uri$/i, + /^(table|database|collection|bucket|folder|file|document|sheet|board|project|issue|user|channel|team|organization|repository|owner)$/i +]; +ConfidenceScorer.RESOURCE_HEAVY_NODES = [ + 'github', 'gitlab', 'bitbucket', + 'googlesheets', 'googledrive', 'dropbox', + 'slack', 'discord', 'telegram', + 'notion', 'airtable', 'baserow', + 'jira', 'asana', 'trello', 'monday', + 'salesforce', 'hubspot', 'pipedrive', + 'stripe', 'paypal', 'square', + 'aws', 'gcp', 'azure', + 'mysql', 'postgres', 'mongodb', 'redis' +]; +//# sourceMappingURL=confidence-scorer.js.map \ No newline at end of file diff --git a/dist/services/confidence-scorer.js.map b/dist/services/confidence-scorer.js.map new file mode 100644 index 0000000..bff629e --- /dev/null +++ b/dist/services/confidence-scorer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"confidence-scorer.js","sourceRoot":"","sources":["../../src/services/confidence-scorer.ts"],"names":[],"mappings":";;;AAoBA,MAAa,gBAAgB;IAI3B,MAAM,CAAC,kCAAkC,CACvC,SAAiB,EACjB,QAAgB,EAChB,KAAa;QAEb,MAAM,OAAO,GAAuB,EAAE,CAAC;QACvC,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,IAAI,aAAa,GAAG,CAAC,CAAC;QAGtB,MAAM,eAAe,GAAG,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,mBAAmB;YACzB,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,eAAe;YACxB,WAAW,EAAE,eAAe,SAAS,yCAAyC,QAAQ,EAAE;SACzF,CAAC,CAAC;QAGH,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,eAAe;YACrB,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,YAAY;YACrB,WAAW,EAAE,eAAe,SAAS,4CAA4C;SAClF,CAAC,CAAC;QAGH,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,eAAe;YACrB,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,YAAY;YACrB,WAAW,EAAE,yDAAyD;SACvE,CAAC,CAAC;QAGH,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,eAAe;YACrB,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,YAAY;YACrB,WAAW,EAAE,cAAc,QAAQ,oCAAoC;SACxE,CAAC,CAAC;QAGH,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC;YAC7B,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,aAAa,IAAI,MAAM,CAAC,MAAM,CAAC;YACjC,CAAC;QACH,CAAC;QAED,MAAM,KAAK,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QAGhE,IAAI,MAAc,CAAC;QACnB,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;YACjB,MAAM,GAAG,6EAA6E,CAAC;QACzF,CAAC;aAAM,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;YACxB,MAAM,GAAG,oEAAoE,CAAC;QAChF,CAAC;aAAM,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;YACxB,MAAM,GAAG,6DAA6D,CAAC;QACzE,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,mEAAmE,CAAC;QAC/E,CAAC;QAED,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,MAAM;YACN,OAAO;SACR,CAAC;IACJ,CAAC;IAcO,MAAM,CAAC,oBAAoB,CAAC,SAAiB,EAAE,QAAgB;QACrE,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;QAEhE,KAAK,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,EAAE,CAAC;YAC1E,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,OAAO,GAAG,CAAC,EAAE,CAAC;gBAC/D,OAAO,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAgBO,MAAM,CAAC,iBAAiB,CAAC,SAAiB;QAChD,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACtE,CAAC;IAKO,MAAM,CAAC,iBAAiB,CAAC,KAAa;QAE5C,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAGnE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACvD,OAAO,KAAK,CAAC;QACf,CAAC;QAGD,MAAM,QAAQ,GAAG;YACf,uEAAuE;YACvE,sEAAsE;YACtE,qEAAqE;SACtE,CAAC;QAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACzD,CAAC;IAiBO,MAAM,CAAC,iBAAiB,CAAC,QAAgB;QAC/C,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;QAEhE,OAAO,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAC/C,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAC5B,CAAC;IACJ,CAAC;IAKD,MAAM,CAAC,kBAAkB,CAAC,KAAa;QACrC,IAAI,KAAK,IAAI,GAAG;YAAE,OAAO,MAAM,CAAC;QAChC,IAAI,KAAK,IAAI,GAAG;YAAE,OAAO,QAAQ,CAAC;QAClC,IAAI,KAAK,IAAI,GAAG;YAAE,OAAO,KAAK,CAAC;QAC/B,OAAO,UAAU,CAAC;IACpB,CAAC;IAKD,MAAM,CAAC,yBAAyB,CAC9B,KAAa,EACb,YAA6C,QAAQ;QAErD,MAAM,UAAU,GAAG;YACjB,MAAM,EAAE,GAAG;YACX,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,GAAG;SACb,CAAC;QAEF,OAAO,KAAK,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;;AA7LH,4CA8LC;AA7GyB,qCAAoB,GAA6B;IACvE,QAAQ,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,cAAc,CAAC;IACzD,cAAc,EAAE,CAAC,SAAS,EAAE,YAAY,EAAE,eAAe,CAAC;IAC1D,aAAa,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC;IAChD,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC;IACnD,QAAQ,EAAE,CAAC,YAAY,EAAE,QAAQ,EAAE,SAAS,CAAC;IAC7C,UAAU,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC;CAC5C,CAAC;AAiBsB,+BAAc,GAAG;IACvC,SAAS;IACT,UAAU;IACV,UAAU;IACV,WAAW;IACX,WAAW;IACX,UAAU;IACV,UAAU;IACV,sIAAsI;CACvI,CAAC;AA+BsB,qCAAoB,GAAG;IAC7C,QAAQ,EAAE,QAAQ,EAAE,WAAW;IAC/B,cAAc,EAAE,aAAa,EAAE,SAAS;IACxC,OAAO,EAAE,SAAS,EAAE,UAAU;IAC9B,QAAQ,EAAE,UAAU,EAAE,SAAS;IAC/B,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ;IACnC,YAAY,EAAE,SAAS,EAAE,WAAW;IACpC,QAAQ,EAAE,QAAQ,EAAE,QAAQ;IAC5B,KAAK,EAAE,KAAK,EAAE,OAAO;IACrB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO;CACxC,CAAC"} \ No newline at end of file diff --git a/dist/services/config-validator.d.ts b/dist/services/config-validator.d.ts new file mode 100644 index 0000000..a915bde --- /dev/null +++ b/dist/services/config-validator.d.ts @@ -0,0 +1,47 @@ +export interface ValidationResult { + valid: boolean; + errors: ValidationError[]; + warnings: ValidationWarning[]; + suggestions: string[]; + visibleProperties: string[]; + hiddenProperties: string[]; + autofix?: Record; +} +export interface ValidationError { + type: 'missing_required' | 'invalid_type' | 'invalid_value' | 'incompatible' | 'invalid_configuration' | 'syntax_error'; + property: string; + message: string; + fix?: string; + suggestion?: string; +} +export interface ValidationWarning { + type: 'missing_common' | 'deprecated' | 'inefficient' | 'security' | 'best_practice' | 'invalid_value'; + property?: string; + message: string; + suggestion?: string; +} +export declare class ConfigValidator { + private static readonly UI_ONLY_TYPES; + static validate(nodeType: string, config: Record, properties: any[], userProvidedKeys?: Set): ValidationResult; + static validateBatch(configs: Array<{ + nodeType: string; + config: Record; + properties: any[]; + }>): ValidationResult[]; + private static checkRequiredProperties; + private static getPropertyVisibility; + protected static isPropertyVisible(prop: any, config: Record): boolean; + private static validatePropertyTypes; + private static performNodeSpecificValidation; + private static validateHttpRequest; + private static validateWebhook; + private static validateDatabase; + private static validateCode; + private static checkCommonIssues; + private static performSecurityChecks; + private static getVisibilityRequirement; + private static validateJavaScriptSyntax; + private static validatePythonSyntax; + private static validateN8nCodePatterns; +} +//# sourceMappingURL=config-validator.d.ts.map \ No newline at end of file diff --git a/dist/services/config-validator.d.ts.map b/dist/services/config-validator.d.ts.map new file mode 100644 index 0000000..585df0d --- /dev/null +++ b/dist/services/config-validator.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"config-validator.d.ts","sourceRoot":"","sources":["../../src/services/config-validator.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,kBAAkB,GAAG,cAAc,GAAG,eAAe,GAAG,cAAc,GAAG,uBAAuB,GAAG,cAAc,CAAC;IACxH,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,gBAAgB,GAAG,YAAY,GAAG,aAAa,GAAG,UAAU,GAAG,eAAe,GAAG,eAAe,CAAC;IACvG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,eAAe;IAI1B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAA4C;IAKjF,MAAM,CAAC,QAAQ,CACb,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,UAAU,EAAE,GAAG,EAAE,EACjB,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAC7B,gBAAgB;IAsDnB,MAAM,CAAC,aAAa,CAClB,OAAO,EAAE,KAAK,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC5B,UAAU,EAAE,GAAG,EAAE,CAAC;KACnB,CAAC,GACD,gBAAgB,EAAE;IASrB,OAAO,CAAC,MAAM,CAAC,uBAAuB;IA0CtC,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAqBpC,SAAS,CAAC,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO;IAiCnF,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAoIpC,OAAO,CAAC,MAAM,CAAC,6BAA6B;IA+B5C,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAoElC,OAAO,CAAC,MAAM,CAAC,eAAe;IAc9B,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAoC/B,OAAO,CAAC,MAAM,CAAC,YAAY;IAyC3B,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAgEhC,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAmCpC,OAAO,CAAC,MAAM,CAAC,wBAAwB;IA6BvC,OAAO,CAAC,MAAM,CAAC,wBAAwB;IA4CvC,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAgEnC,OAAO,CAAC,MAAM,CAAC,uBAAuB;CAmOvC"} \ No newline at end of file diff --git a/dist/services/config-validator.js b/dist/services/config-validator.js new file mode 100644 index 0000000..aca0ae4 --- /dev/null +++ b/dist/services/config-validator.js @@ -0,0 +1,671 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ConfigValidator = void 0; +const expression_utils_js_1 = require("../utils/expression-utils.js"); +class ConfigValidator { + static validate(nodeType, config, properties, userProvidedKeys) { + if (!config || typeof config !== 'object') { + throw new TypeError('Config must be a non-null object'); + } + if (!properties || !Array.isArray(properties)) { + throw new TypeError('Properties must be a non-null array'); + } + const errors = []; + const warnings = []; + const suggestions = []; + const visibleProperties = []; + const hiddenProperties = []; + const autofix = {}; + this.checkRequiredProperties(properties, config, errors); + const { visible, hidden } = this.getPropertyVisibility(properties, config); + visibleProperties.push(...visible); + hiddenProperties.push(...hidden); + this.validatePropertyTypes(properties, config, errors); + this.performNodeSpecificValidation(nodeType, config, errors, warnings, suggestions, autofix); + this.checkCommonIssues(nodeType, config, properties, warnings, suggestions, userProvidedKeys); + this.performSecurityChecks(nodeType, config, warnings); + return { + valid: errors.length === 0, + errors, + warnings, + suggestions, + visibleProperties, + hiddenProperties, + autofix: Object.keys(autofix).length > 0 ? autofix : undefined + }; + } + static validateBatch(configs) { + return configs.map(({ nodeType, config, properties }) => this.validate(nodeType, config, properties)); + } + static checkRequiredProperties(properties, config, errors) { + for (const prop of properties) { + if (!prop || !prop.name) + continue; + if (prop.required) { + const value = config[prop.name]; + if (!(prop.name in config)) { + errors.push({ + type: 'missing_required', + property: prop.name, + message: `Required property '${prop.displayName || prop.name}' is missing`, + fix: `Add ${prop.name} to your configuration` + }); + } + else if (value === null || value === undefined) { + errors.push({ + type: 'invalid_type', + property: prop.name, + message: `Required property '${prop.displayName || prop.name}' cannot be null or undefined`, + fix: `Provide a valid value for ${prop.name}` + }); + } + else if (typeof value === 'string' && value.trim() === '') { + errors.push({ + type: 'missing_required', + property: prop.name, + message: `Required property '${prop.displayName || prop.name}' cannot be empty`, + fix: `Provide a valid value for ${prop.name}` + }); + } + } + } + } + static getPropertyVisibility(properties, config) { + const visible = []; + const hidden = []; + for (const prop of properties) { + if (this.isPropertyVisible(prop, config)) { + visible.push(prop.name); + } + else { + hidden.push(prop.name); + } + } + return { visible, hidden }; + } + static isPropertyVisible(prop, config) { + if (!prop.displayOptions) + return true; + if (prop.displayOptions.show) { + for (const [key, values] of Object.entries(prop.displayOptions.show)) { + const configValue = config[key]; + const expectedValues = Array.isArray(values) ? values : [values]; + if (!expectedValues.includes(configValue)) { + return false; + } + } + } + if (prop.displayOptions.hide) { + for (const [key, values] of Object.entries(prop.displayOptions.hide)) { + const configValue = config[key]; + const expectedValues = Array.isArray(values) ? values : [values]; + if (expectedValues.includes(configValue)) { + return false; + } + } + } + return true; + } + static validatePropertyTypes(properties, config, errors) { + for (const [key, value] of Object.entries(config)) { + const prop = properties.find(p => p.name === key); + if (!prop) + continue; + if (prop.type === 'string' && typeof value !== 'string') { + errors.push({ + type: 'invalid_type', + property: key, + message: `Property '${key}' must be a string, got ${typeof value}`, + fix: `Change ${key} to a string value` + }); + } + else if (prop.type === 'number' && typeof value !== 'number') { + errors.push({ + type: 'invalid_type', + property: key, + message: `Property '${key}' must be a number, got ${typeof value}`, + fix: `Change ${key} to a number` + }); + } + else if (prop.type === 'boolean' && typeof value !== 'boolean') { + errors.push({ + type: 'invalid_type', + property: key, + message: `Property '${key}' must be a boolean, got ${typeof value}`, + fix: `Change ${key} to true or false` + }); + } + else if (prop.type === 'resourceLocator') { + if (typeof value !== 'object' || value === null || Array.isArray(value)) { + const fixValue = typeof value === 'string' ? value : JSON.stringify(value); + errors.push({ + type: 'invalid_type', + property: key, + message: `Property '${key}' is a resourceLocator and must be an object with 'mode' and 'value' properties, got ${typeof value}`, + fix: `Change ${key} to { mode: "list", value: ${JSON.stringify(fixValue)} } or { mode: "id", value: ${JSON.stringify(fixValue)} }` + }); + } + else { + if (!value.mode) { + errors.push({ + type: 'missing_required', + property: `${key}.mode`, + message: `resourceLocator '${key}' is missing required property 'mode'`, + fix: `Add mode property: { mode: "list", value: ${JSON.stringify(value.value || '')} }` + }); + } + else if (typeof value.mode !== 'string') { + errors.push({ + type: 'invalid_type', + property: `${key}.mode`, + message: `resourceLocator '${key}.mode' must be a string, got ${typeof value.mode}`, + fix: `Set mode to a valid string value` + }); + } + else if (prop.modes) { + const modes = prop.modes; + if (!modes || typeof modes !== 'object') { + continue; + } + let allowedModes = []; + if (Array.isArray(modes)) { + allowedModes = modes + .map(m => (typeof m === 'object' && m !== null) ? m.name : m) + .filter(m => typeof m === 'string' && m.length > 0); + } + else { + allowedModes = Object.keys(modes).filter(k => k.length > 0); + } + if (allowedModes.length > 0 && !allowedModes.includes(value.mode)) { + errors.push({ + type: 'invalid_value', + property: `${key}.mode`, + message: `resourceLocator '${key}.mode' must be one of [${allowedModes.join(', ')}], got '${value.mode}'`, + fix: `Change mode to one of: ${allowedModes.join(', ')}` + }); + } + } + if (value.value === undefined) { + errors.push({ + type: 'missing_required', + property: `${key}.value`, + message: `resourceLocator '${key}' is missing required property 'value'`, + fix: `Add value property to specify the ${prop.displayName || key}` + }); + } + } + } + if (prop.type === 'options' && prop.options) { + const validValues = prop.options.map((opt) => typeof opt === 'string' ? opt : opt.value); + if (!validValues.includes(value)) { + errors.push({ + type: 'invalid_value', + property: key, + message: `Invalid value for '${key}'. Must be one of: ${validValues.join(', ')}`, + fix: `Change ${key} to one of the valid options` + }); + } + } + } + } + static performNodeSpecificValidation(nodeType, config, errors, warnings, suggestions, autofix) { + switch (nodeType) { + case 'nodes-base.httpRequest': + this.validateHttpRequest(config, errors, warnings, suggestions, autofix); + break; + case 'nodes-base.webhook': + this.validateWebhook(config, warnings, suggestions); + break; + case 'nodes-base.postgres': + case 'nodes-base.mysql': + this.validateDatabase(config, warnings, suggestions); + break; + case 'nodes-base.code': + this.validateCode(config, errors, warnings); + break; + } + } + static validateHttpRequest(config, errors, warnings, suggestions, autofix) { + if (config.url && typeof config.url === 'string') { + if (!(0, expression_utils_js_1.shouldSkipLiteralValidation)(config.url)) { + if (!config.url.startsWith('http://') && !config.url.startsWith('https://')) { + errors.push({ + type: 'invalid_value', + property: 'url', + message: 'URL must start with http:// or https://', + fix: 'Add https:// to the beginning of your URL' + }); + } + } + } + if (['POST', 'PUT', 'PATCH'].includes(config.method) && !config.sendBody) { + warnings.push({ + type: 'missing_common', + property: 'sendBody', + message: `${config.method} requests typically send a body`, + suggestion: 'Set sendBody=true and configure the body content' + }); + autofix.sendBody = true; + autofix.contentType = 'json'; + } + if (!config.authentication || config.authentication === 'none') { + if (config.url?.includes('api.') || config.url?.includes('/api/')) { + warnings.push({ + type: 'security', + message: 'API endpoints typically require authentication', + suggestion: 'Consider setting authentication if the API requires it' + }); + } + } + if (config.sendBody && config.contentType === 'json' && config.jsonBody) { + if (!(0, expression_utils_js_1.shouldSkipLiteralValidation)(config.jsonBody)) { + try { + JSON.parse(config.jsonBody); + } + catch (e) { + const errorMsg = e instanceof Error ? e.message : 'Unknown parsing error'; + errors.push({ + type: 'invalid_value', + property: 'jsonBody', + message: `jsonBody contains invalid JSON: ${errorMsg}`, + fix: 'Fix JSON syntax error and ensure valid JSON format' + }); + } + } + } + } + static validateWebhook(config, warnings, suggestions) { + if (config.responseMode === 'responseNode' && !config.responseData) { + suggestions.push('When using responseMode=responseNode, add a "Respond to Webhook" node to send custom responses'); + } + } + static validateDatabase(config, warnings, suggestions) { + if (config.query) { + const query = config.query.toLowerCase(); + if (query.includes('${') || query.includes('{{')) { + warnings.push({ + type: 'security', + message: 'Query contains template expressions that might be vulnerable to SQL injection', + suggestion: 'Use parameterized queries with additionalFields.queryParams instead' + }); + } + if (query.includes('delete') && !query.includes('where')) { + warnings.push({ + type: 'security', + message: 'DELETE query without WHERE clause will delete all records', + suggestion: 'Add a WHERE clause to limit the deletion' + }); + } + if (query.includes('select *')) { + suggestions.push('Consider selecting specific columns instead of * for better performance'); + } + } + } + static validateCode(config, errors, warnings) { + const codeField = config.language === 'python' ? 'pythonCode' : 'jsCode'; + const code = config[codeField]; + if (!code || code.trim() === '') { + errors.push({ + type: 'missing_required', + property: codeField, + message: 'Code cannot be empty', + fix: 'Add your code logic' + }); + return; + } + if (code?.includes('eval(') || code?.includes('exec(')) { + warnings.push({ + type: 'security', + message: 'Code contains eval/exec which can be a security risk', + suggestion: 'Avoid using eval/exec with untrusted input' + }); + } + if (config.language === 'python') { + this.validatePythonSyntax(code, errors, warnings); + } + else { + this.validateJavaScriptSyntax(code, errors, warnings); + } + this.validateN8nCodePatterns(code, config.language || 'javascript', errors, warnings); + } + static checkCommonIssues(nodeType, config, properties, warnings, suggestions, userProvidedKeys) { + if (nodeType === 'nodes-base.code') { + return; + } + const visibleProps = properties.filter(p => this.isPropertyVisible(p, config)); + const configuredKeys = Object.keys(config); + for (const key of configuredKeys) { + if (key === '@version' || key.startsWith('_')) { + continue; + } + if (userProvidedKeys && !userProvidedKeys.has(key)) { + continue; + } + const prop = properties.find(p => p.name === key); + if (prop && this.UI_ONLY_TYPES.includes(prop.type)) { + continue; + } + if (!visibleProps.find(p => p.name === key)) { + const visibilityReq = this.getVisibilityRequirement(prop, config); + warnings.push({ + type: 'inefficient', + property: key, + message: `Property '${prop?.displayName || key}' won't be used - not visible with current settings`, + suggestion: visibilityReq || 'Remove this property or adjust other settings to make it visible' + }); + } + } + const commonProps = ['authentication', 'errorHandling', 'timeout']; + for (const prop of commonProps) { + const propDef = properties.find(p => p.name === prop); + if (propDef && this.isPropertyVisible(propDef, config) && !(prop in config)) { + suggestions.push(`Consider setting '${prop}' for better control`); + } + } + } + static performSecurityChecks(nodeType, config, warnings) { + const sensitivePatterns = [ + /api[_-]?key/i, + /password/i, + /secret/i, + /token/i, + /credential/i + ]; + for (const [key, value] of Object.entries(config)) { + if (typeof value === 'string') { + for (const pattern of sensitivePatterns) { + if (pattern.test(key) && value.length > 0 && !value.includes('{{')) { + warnings.push({ + type: 'security', + property: key, + message: `Hardcoded ${key} detected`, + suggestion: 'Use n8n credentials or expressions instead of hardcoding sensitive values' + }); + break; + } + } + } + } + } + static getVisibilityRequirement(prop, config) { + if (!prop || !prop.displayOptions?.show) { + return undefined; + } + const requirements = []; + for (const [field, values] of Object.entries(prop.displayOptions.show)) { + const expectedValues = Array.isArray(values) ? values : [values]; + const currentValue = config[field]; + if (!expectedValues.includes(currentValue)) { + const valueStr = expectedValues.length === 1 + ? `"${expectedValues[0]}"` + : expectedValues.map(v => `"${v}"`).join(' or '); + requirements.push(`${field}=${valueStr}`); + } + } + if (requirements.length === 0) { + return undefined; + } + return `Requires: ${requirements.join(', ')}`; + } + static validateJavaScriptSyntax(code, errors, warnings) { + const openBraces = (code.match(/\{/g) || []).length; + const closeBraces = (code.match(/\}/g) || []).length; + if (openBraces !== closeBraces) { + errors.push({ + type: 'invalid_value', + property: 'jsCode', + message: 'Unbalanced braces detected', + fix: 'Check that all { have matching }' + }); + } + const openParens = (code.match(/\(/g) || []).length; + const closeParens = (code.match(/\)/g) || []).length; + if (openParens !== closeParens) { + errors.push({ + type: 'invalid_value', + property: 'jsCode', + message: 'Unbalanced parentheses detected', + fix: 'Check that all ( have matching )' + }); + } + const stringMatches = code.match(/(["'`])(?:(?=(\\?))\2.)*?\1/g) || []; + const quotesInStrings = stringMatches.join('').match(/["'`]/g)?.length || 0; + const totalQuotes = (code.match(/["'`]/g) || []).length; + if ((totalQuotes - quotesInStrings) % 2 !== 0) { + warnings.push({ + type: 'inefficient', + message: 'Possible unterminated string detected', + suggestion: 'Check that all strings are properly closed' + }); + } + } + static validatePythonSyntax(code, errors, warnings) { + const lines = code.split('\n'); + const indentTypes = new Set(); + lines.forEach(line => { + const indent = line.match(/^(\s+)/); + if (indent) { + if (indent[1].includes('\t')) + indentTypes.add('tabs'); + if (indent[1].includes(' ')) + indentTypes.add('spaces'); + } + }); + if (indentTypes.size > 1) { + errors.push({ + type: 'syntax_error', + property: 'pythonCode', + message: 'Mixed indentation (tabs and spaces)', + fix: 'Use either tabs or spaces consistently, not both' + }); + } + const openSquare = (code.match(/\[/g) || []).length; + const closeSquare = (code.match(/\]/g) || []).length; + if (openSquare !== closeSquare) { + errors.push({ + type: 'syntax_error', + property: 'pythonCode', + message: 'Unmatched bracket - missing ] or extra [', + fix: 'Check that all [ have matching ]' + }); + } + const openCurly = (code.match(/\{/g) || []).length; + const closeCurly = (code.match(/\}/g) || []).length; + if (openCurly !== closeCurly) { + errors.push({ + type: 'syntax_error', + property: 'pythonCode', + message: 'Unmatched bracket - missing } or extra {', + fix: 'Check that all { have matching }' + }); + } + const controlStructures = /^\s*(if|elif|else|for|while|def|class|try|except|finally|with)\s+.*[^:]\s*$/gm; + if (controlStructures.test(code)) { + warnings.push({ + type: 'inefficient', + message: 'Missing colon after control structure', + suggestion: 'Add : at the end of if/for/def/class statements' + }); + } + } + static validateN8nCodePatterns(code, language, errors, warnings) { + const hasReturn = language === 'python' + ? /return\s+/.test(code) + : /return\s+/.test(code); + if (!hasReturn) { + warnings.push({ + type: 'missing_common', + message: 'No return statement found', + suggestion: 'Code node must return data. Example: return [{json: {result: "success"}}]' + }); + } + if (language === 'javascript' && hasReturn) { + if (/return\s+items\s*;/.test(code) && !code.includes('.map') && !code.includes('json:')) { + warnings.push({ + type: 'best_practice', + message: 'Returning items directly - ensure each item has {json: ...} structure', + suggestion: 'If modifying items, use: return items.map(item => ({json: {...item.json, newField: "value"}}))' + }); + } + if (/return\s+{[^}]+}\s*;/.test(code) && !code.includes('[') && !code.includes(']')) { + warnings.push({ + type: 'invalid_value', + message: 'Return value must be an array', + suggestion: 'Wrap your return object in an array: return [{json: {your: "data"}}]' + }); + } + if (/return\s+\[['"`]/.test(code) || /return\s+\[\d/.test(code)) { + warnings.push({ + type: 'invalid_value', + message: 'Items must be objects with json property', + suggestion: 'Use format: return [{json: {value: "data"}}] not return ["data"]' + }); + } + } + if (language === 'python' && hasReturn) { + if (code.includes('result = {"data": "value"}')) { + console.log('DEBUG: Processing Python code with result variable'); + console.log('DEBUG: Language:', language); + console.log('DEBUG: Has return:', hasReturn); + } + if (/return\s+items\s*$/.test(code) && !code.includes('json') && !code.includes('dict')) { + warnings.push({ + type: 'best_practice', + message: 'Returning items directly - ensure each item is a dict with "json" key', + suggestion: 'Use: return [{"json": item.json} for item in items]' + }); + } + if (/return\s+{['"]/.test(code) && !code.includes('[') && !code.includes(']')) { + warnings.push({ + type: 'invalid_value', + message: 'Return value must be a list', + suggestion: 'Wrap your return dict in a list: return [{"json": {"your": "data"}}]' + }); + } + if (/return\s+(?!.*\[).*{(?!.*["']json["'])/.test(code)) { + warnings.push({ + type: 'invalid_value', + message: 'Must return array of objects with json key', + suggestion: 'Use format: return [{"json": {"data": "value"}}]' + }); + } + const returnMatch = code.match(/return\s+(\w+)\s*(?:#|$)/m); + if (returnMatch) { + const varName = returnMatch[1]; + const assignmentRegex = new RegExp(`${varName}\\s*=\\s*{[^}]+}`, 'm'); + if (assignmentRegex.test(code) && !new RegExp(`${varName}\\s*=\\s*\\[`).test(code)) { + warnings.push({ + type: 'invalid_value', + message: 'Must return array of objects with json key', + suggestion: `Wrap ${varName} in a list with json key: return [{"json": ${varName}}]` + }); + } + } + } + if (language === 'javascript') { + if (!code.includes('items') && !code.includes('$input') && !code.includes('$json')) { + warnings.push({ + type: 'missing_common', + message: 'Code doesn\'t reference input data', + suggestion: 'Access input with: items, $input.all(), or $json (in single-item mode)' + }); + } + if (code.includes('$json') && !code.includes('mode')) { + warnings.push({ + type: 'best_practice', + message: '$json only works in "Run Once for Each Item" mode', + suggestion: 'For all items mode, use: items[0].json or loop through items' + }); + } + const commonVars = ['$node', '$workflow', '$execution', '$prevNode', 'DateTime', 'jmespath']; + const usedVars = commonVars.filter(v => code.includes(v)); + if (code.includes('$helpers.getWorkflowStaticData')) { + if (/\$helpers\.getWorkflowStaticData(?!\s*\()/.test(code)) { + errors.push({ + type: 'invalid_value', + property: 'jsCode', + message: 'getWorkflowStaticData requires parentheses: $helpers.getWorkflowStaticData()', + fix: 'Add parentheses: $helpers.getWorkflowStaticData()' + }); + } + else { + warnings.push({ + type: 'invalid_value', + message: '$helpers.getWorkflowStaticData() is incorrect - causes "$helpers is not defined" error', + suggestion: 'Use $getWorkflowStaticData() as a standalone function (no $helpers prefix)' + }); + } + } + if (code.includes('$helpers') && !code.includes('typeof $helpers')) { + warnings.push({ + type: 'best_practice', + message: '$helpers is only available in Code nodes with mode="runOnceForEachItem"', + suggestion: 'Check availability first: if (typeof $helpers !== "undefined" && $helpers.httpRequest) { ... }' + }); + } + if ((code.includes('fetch(') || code.includes('Promise') || code.includes('.then(')) && !code.includes('await')) { + warnings.push({ + type: 'best_practice', + message: 'Async operation without await - will return a Promise instead of actual data', + suggestion: 'Use await with async operations: const result = await fetch(...);' + }); + } + if ((code.includes('crypto.') || code.includes('randomBytes') || code.includes('randomUUID')) && !code.includes('require')) { + warnings.push({ + type: 'invalid_value', + message: 'Using crypto without require statement', + suggestion: 'Add: const crypto = require("crypto"); at the beginning (ignore editor warnings)' + }); + } + if (code.includes('console.log')) { + warnings.push({ + type: 'best_practice', + message: 'console.log output appears in n8n execution logs', + suggestion: 'Remove console.log statements in production or use them sparingly' + }); + } + } + else if (language === 'python') { + if (!code.includes('items') && !code.includes('_input')) { + warnings.push({ + type: 'missing_common', + message: 'Code doesn\'t reference input items', + suggestion: 'Access input data with: items variable' + }); + } + if (code.includes('print(')) { + warnings.push({ + type: 'best_practice', + message: 'print() output appears in n8n execution logs', + suggestion: 'Remove print statements in production or use them sparingly' + }); + } + if (code.includes('import requests') || code.includes('import pandas')) { + warnings.push({ + type: 'invalid_value', + message: 'External libraries not available in Code node', + suggestion: 'Only Python standard library is available. For HTTP requests, use JavaScript with $helpers.httpRequest' + }); + } + } + if (/while\s*\(\s*true\s*\)|while\s+True:/.test(code)) { + warnings.push({ + type: 'security', + message: 'Infinite loop detected', + suggestion: 'Add a break condition or use a for loop with limits' + }); + } + if (!code.includes('try') && !code.includes('catch') && !code.includes('except')) { + if (code.length > 200) { + warnings.push({ + type: 'best_practice', + message: 'No error handling found', + suggestion: 'Consider adding try/catch (JavaScript) or try/except (Python) for robust error handling' + }); + } + } + } +} +exports.ConfigValidator = ConfigValidator; +ConfigValidator.UI_ONLY_TYPES = ['notice', 'callout', 'infoBox', 'info']; +//# sourceMappingURL=config-validator.js.map \ No newline at end of file diff --git a/dist/services/config-validator.js.map b/dist/services/config-validator.js.map new file mode 100644 index 0000000..021227c --- /dev/null +++ b/dist/services/config-validator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"config-validator.js","sourceRoot":"","sources":["../../src/services/config-validator.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/enhanced-config-validator.d.ts b/dist/services/enhanced-config-validator.d.ts new file mode 100644 index 0000000..4fa8fa4 --- /dev/null +++ b/dist/services/enhanced-config-validator.d.ts @@ -0,0 +1,54 @@ +import { ConfigValidator, ValidationResult } from './config-validator'; +import { NodeRepository } from '../database/node-repository'; +export type ValidationMode = 'full' | 'operation' | 'minimal'; +export type ValidationProfile = 'strict' | 'runtime' | 'ai-friendly' | 'minimal'; +export interface EnhancedValidationResult extends ValidationResult { + mode: ValidationMode; + profile?: ValidationProfile; + operation?: { + resource?: string; + operation?: string; + action?: string; + }; + examples?: Array<{ + description: string; + config: Record; + }>; + nextSteps?: string[]; +} +export interface OperationContext { + resource?: string; + operation?: string; + action?: string; + mode?: string; +} +export declare class EnhancedConfigValidator extends ConfigValidator { + private static operationSimilarityService; + private static resourceSimilarityService; + private static nodeRepository; + static initializeSimilarityServices(repository: NodeRepository): void; + static validateWithMode(nodeType: string, config: Record, properties: any[], mode?: ValidationMode, profile?: ValidationProfile): EnhancedValidationResult; + private static extractOperationContext; + private static filterPropertiesByMode; + private static applyNodeDefaults; + private static isPropertyRelevantToOperation; + private static addOperationSpecificEnhancements; + private static enhanceSlackValidation; + private static enhanceGoogleSheetsValidation; + private static enhanceHttpRequestValidation; + private static generateNextSteps; + private static deduplicateErrors; + private static shouldFilterCredentialWarning; + private static applyProfileFilters; + private static enforceErrorHandlingForProfile; + private static addErrorHandlingSuggestions; + private static validateFixedCollectionStructures; + private static validateSwitchNodeStructure; + private static validateIfNodeStructure; + private static validateFilterNodeStructure; + private static validateResourceAndOperation; + private static validateSpecialTypeStructures; + private static validateComplexTypeStructure; + private static validateFilterOperations; +} +//# sourceMappingURL=enhanced-config-validator.d.ts.map \ No newline at end of file diff --git a/dist/services/enhanced-config-validator.d.ts.map b/dist/services/enhanced-config-validator.d.ts.map new file mode 100644 index 0000000..3eab317 --- /dev/null +++ b/dist/services/enhanced-config-validator.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"enhanced-config-validator.d.ts","sourceRoot":"","sources":["../../src/services/enhanced-config-validator.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAsC,MAAM,oBAAoB,CAAC;AAK3G,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAM7D,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;AAC9D,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAAC;AAEjF,MAAM,WAAW,wBAAyB,SAAQ,gBAAgB;IAChE,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,SAAS,CAAC,EAAE;QACV,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,QAAQ,CAAC,EAAE,KAAK,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KAC7B,CAAC,CAAC;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,uBAAwB,SAAQ,eAAe;IAC1D,OAAO,CAAC,MAAM,CAAC,0BAA0B,CAA2C;IACpF,OAAO,CAAC,MAAM,CAAC,yBAAyB,CAA0C;IAClF,OAAO,CAAC,MAAM,CAAC,cAAc,CAA+B;IAK5D,MAAM,CAAC,4BAA4B,CAAC,UAAU,EAAE,cAAc,GAAG,IAAI;IAQrE,MAAM,CAAC,gBAAgB,CACrB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,UAAU,EAAE,GAAG,EAAE,EACjB,IAAI,GAAE,cAA4B,EAClC,OAAO,GAAE,iBAAiC,GACzC,wBAAwB;IAqE3B,OAAO,CAAC,MAAM,CAAC,uBAAuB;IAatC,OAAO,CAAC,MAAM,CAAC,sBAAsB;IAsCrC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAehC,OAAO,CAAC,MAAM,CAAC,6BAA6B;IAgD5C,OAAO,CAAC,MAAM,CAAC,gCAAgC;IAgH/C,OAAO,CAAC,MAAM,CAAC,sBAAsB;IAyBrC,OAAO,CAAC,MAAM,CAAC,6BAA6B;IAwB5C,OAAO,CAAC,MAAM,CAAC,4BAA4B;IA8D3C,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAoChC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IA0BhC,OAAO,CAAC,MAAM,CAAC,6BAA6B;IAS5C,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAsFlC,OAAO,CAAC,MAAM,CAAC,8BAA8B;IAyB7C,OAAO,CAAC,MAAM,CAAC,2BAA2B;IA+B1C,OAAO,CAAC,MAAM,CAAC,iCAAiC;IA+ChD,OAAO,CAAC,MAAM,CAAC,2BAA2B;IAuC1C,OAAO,CAAC,MAAM,CAAC,uBAAuB;IAmBtC,OAAO,CAAC,MAAM,CAAC,2BAA2B;IAmB1C,OAAO,CAAC,MAAM,CAAC,4BAA4B;IAiM3C,OAAO,CAAC,MAAM,CAAC,6BAA6B;IA4E5C,OAAO,CAAC,MAAM,CAAC,4BAA4B;IAyH3C,OAAO,CAAC,MAAM,CAAC,wBAAwB;CAoExC"} \ No newline at end of file diff --git a/dist/services/enhanced-config-validator.js b/dist/services/enhanced-config-validator.js new file mode 100644 index 0000000..9fada29 --- /dev/null +++ b/dist/services/enhanced-config-validator.js @@ -0,0 +1,789 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.EnhancedConfigValidator = void 0; +const config_validator_1 = require("./config-validator"); +const node_specific_validators_1 = require("./node-specific-validators"); +const fixed_collection_validator_1 = require("../utils/fixed-collection-validator"); +const operation_similarity_service_1 = require("./operation-similarity-service"); +const resource_similarity_service_1 = require("./resource-similarity-service"); +const node_type_normalizer_1 = require("../utils/node-type-normalizer"); +const type_structure_service_1 = require("./type-structure-service"); +class EnhancedConfigValidator extends config_validator_1.ConfigValidator { + static initializeSimilarityServices(repository) { + this.nodeRepository = repository; + this.operationSimilarityService = new operation_similarity_service_1.OperationSimilarityService(repository); + this.resourceSimilarityService = new resource_similarity_service_1.ResourceSimilarityService(repository); + } + static validateWithMode(nodeType, config, properties, mode = 'operation', profile = 'ai-friendly') { + if (typeof nodeType !== 'string') { + throw new Error(`Invalid nodeType: expected string, got ${typeof nodeType}`); + } + if (!config || typeof config !== 'object') { + throw new Error(`Invalid config: expected object, got ${typeof config}`); + } + if (!Array.isArray(properties)) { + throw new Error(`Invalid properties: expected array, got ${typeof properties}`); + } + const operationContext = this.extractOperationContext(config); + const userProvidedKeys = new Set(Object.keys(config)); + const { properties: filteredProperties, configWithDefaults } = this.filterPropertiesByMode(properties, config, mode, operationContext); + const baseResult = super.validate(nodeType, configWithDefaults, filteredProperties, userProvidedKeys); + const enhancedResult = { + ...baseResult, + mode, + profile, + operation: operationContext, + examples: [], + nextSteps: [], + errors: baseResult.errors || [], + warnings: baseResult.warnings || [], + suggestions: baseResult.suggestions || [] + }; + this.applyProfileFilters(enhancedResult, profile); + this.addOperationSpecificEnhancements(nodeType, config, filteredProperties, enhancedResult); + enhancedResult.errors = this.deduplicateErrors(enhancedResult.errors); + enhancedResult.nextSteps = this.generateNextSteps(enhancedResult); + enhancedResult.valid = enhancedResult.errors.length === 0; + return enhancedResult; + } + static extractOperationContext(config) { + return { + resource: config.resource, + operation: config.operation, + action: config.action, + mode: config.mode + }; + } + static filterPropertiesByMode(properties, config, mode, operation) { + const configWithDefaults = this.applyNodeDefaults(properties, config); + let filteredProperties; + switch (mode) { + case 'minimal': + filteredProperties = properties.filter(prop => prop.required && this.isPropertyVisible(prop, configWithDefaults)); + break; + case 'operation': + filteredProperties = properties.filter(prop => this.isPropertyRelevantToOperation(prop, configWithDefaults, operation)); + break; + case 'full': + default: + filteredProperties = properties; + break; + } + return { properties: filteredProperties, configWithDefaults }; + } + static applyNodeDefaults(properties, config) { + const result = { ...config }; + for (const prop of properties) { + if (prop.name && prop.default !== undefined && result[prop.name] === undefined) { + result[prop.name] = prop.default; + } + } + return result; + } + static isPropertyRelevantToOperation(prop, config, operation) { + if (!this.isPropertyVisible(prop, config)) { + return false; + } + if (!operation.resource && !operation.operation && !operation.action) { + return true; + } + if (prop.displayOptions?.show) { + const show = prop.displayOptions.show; + if (operation.resource && show.resource) { + const expectedResources = Array.isArray(show.resource) ? show.resource : [show.resource]; + if (!expectedResources.includes(operation.resource)) { + return false; + } + } + if (operation.operation && show.operation) { + const expectedOps = Array.isArray(show.operation) ? show.operation : [show.operation]; + if (!expectedOps.includes(operation.operation)) { + return false; + } + } + if (operation.action && show.action) { + const expectedActions = Array.isArray(show.action) ? show.action : [show.action]; + if (!expectedActions.includes(operation.action)) { + return false; + } + } + } + return true; + } + static addOperationSpecificEnhancements(nodeType, config, properties, result) { + if (typeof nodeType !== 'string') { + result.errors.push({ + type: 'invalid_type', + property: 'nodeType', + message: `Invalid nodeType: expected string, got ${typeof nodeType}`, + fix: 'Provide a valid node type string (e.g., "nodes-base.webhook")' + }); + return; + } + this.validateResourceAndOperation(nodeType, config, result); + this.validateSpecialTypeStructures(config, properties, result); + this.validateFixedCollectionStructures(nodeType, config, result); + const context = { + config, + errors: result.errors, + warnings: result.warnings, + suggestions: result.suggestions, + autofix: result.autofix || {} + }; + const normalizedNodeType = nodeType.replace('n8n-nodes-base.', 'nodes-base.'); + switch (normalizedNodeType) { + case 'nodes-base.slack': + node_specific_validators_1.NodeSpecificValidators.validateSlack(context); + this.enhanceSlackValidation(config, result); + break; + case 'nodes-base.googleSheets': + node_specific_validators_1.NodeSpecificValidators.validateGoogleSheets(context); + this.enhanceGoogleSheetsValidation(config, result); + break; + case 'nodes-base.httpRequest': + this.enhanceHttpRequestValidation(config, result); + break; + case 'nodes-base.code': + node_specific_validators_1.NodeSpecificValidators.validateCode(context); + break; + case 'nodes-base.openAi': + node_specific_validators_1.NodeSpecificValidators.validateOpenAI(context); + break; + case 'nodes-base.mongoDb': + node_specific_validators_1.NodeSpecificValidators.validateMongoDB(context); + break; + case 'nodes-base.webhook': + node_specific_validators_1.NodeSpecificValidators.validateWebhook(context); + break; + case 'nodes-base.postgres': + node_specific_validators_1.NodeSpecificValidators.validatePostgres(context); + break; + case 'nodes-base.mysql': + node_specific_validators_1.NodeSpecificValidators.validateMySQL(context); + break; + case 'nodes-langchain.agent': + node_specific_validators_1.NodeSpecificValidators.validateAIAgent(context); + break; + case 'nodes-base.set': + node_specific_validators_1.NodeSpecificValidators.validateSet(context); + break; + case 'nodes-base.switch': + this.validateSwitchNodeStructure(config, result); + break; + case 'nodes-base.if': + this.validateIfNodeStructure(config, result); + break; + case 'nodes-base.filter': + this.validateFilterNodeStructure(config, result); + break; + } + if (Object.keys(context.autofix).length > 0) { + result.autofix = context.autofix; + } + } + static enhanceSlackValidation(config, result) { + const { resource, operation } = result.operation || {}; + if (resource === 'message' && operation === 'send') { + if (!config.channel && !config.channelId) { + const channelError = result.errors.find(e => e.property === 'channel' || e.property === 'channelId'); + if (channelError) { + channelError.message = 'To send a Slack message, specify either a channel name (e.g., "#general") or channel ID'; + channelError.fix = 'Add channel: "#general" or use a channel ID like "C1234567890"'; + } + } + } + } + static enhanceGoogleSheetsValidation(config, result) { + const { operation } = result.operation || {}; + if (operation === 'append') { + if (config.range && !config.range.includes('!')) { + result.warnings.push({ + type: 'inefficient', + property: 'range', + message: 'Range should include sheet name (e.g., "Sheet1!A:B")', + suggestion: 'Format: "SheetName!A1:B10" or "SheetName!A:B" for entire columns' + }); + } + } + } + static enhanceHttpRequestValidation(config, result) { + const url = String(config.url || ''); + const options = config.options || {}; + if (!result.suggestions.some(s => typeof s === 'string' && s.includes('alwaysOutputData'))) { + result.suggestions.push('Consider adding alwaysOutputData: true at node level (not in parameters) for better error handling. ' + + 'This ensures the node produces output even when HTTP requests fail, allowing downstream error handling.'); + } + const lowerUrl = url.toLowerCase(); + const isApiEndpoint = /^https?:\/\/api\./i.test(url) || + /\/api[\/\?]|\/api$/i.test(url) || + /\/rest[\/\?]|\/rest$/i.test(url) || + lowerUrl.includes('supabase.co') || + lowerUrl.includes('firebase') || + lowerUrl.includes('googleapis.com') || + /\.com\/v\d+/i.test(url); + if (isApiEndpoint && !options.response?.response?.responseFormat) { + result.suggestions.push('API endpoints should explicitly set options.response.response.responseFormat to "json" or "text" ' + + 'to prevent confusion about response parsing. Example: ' + + '{ "options": { "response": { "response": { "responseFormat": "json" } } } }'); + } + if (url && url.startsWith('=')) { + const expressionContent = url.slice(1); + const lowerExpression = expressionContent.toLowerCase(); + if (expressionContent.startsWith('www.') || + (expressionContent.includes('{{') && !lowerExpression.includes('http'))) { + result.warnings.push({ + type: 'invalid_value', + property: 'url', + message: 'URL expression appears to be missing http:// or https:// protocol', + suggestion: 'Include protocol in your expression. Example: ={{ "https://" + $json.domain + ".com" }}' + }); + } + } + } + static generateNextSteps(result) { + const steps = []; + const requiredErrors = result.errors.filter(e => e.type === 'missing_required'); + const typeErrors = result.errors.filter(e => e.type === 'invalid_type'); + const valueErrors = result.errors.filter(e => e.type === 'invalid_value'); + if (requiredErrors.length > 0) { + steps.push(`Add required fields: ${requiredErrors.map(e => e.property).join(', ')}`); + } + if (typeErrors.length > 0) { + steps.push(`Fix type mismatches: ${typeErrors.map(e => `${e.property} should be ${e.fix}`).join(', ')}`); + } + if (valueErrors.length > 0) { + steps.push(`Correct invalid values: ${valueErrors.map(e => e.property).join(', ')}`); + } + if (result.warnings.length > 0 && result.errors.length === 0) { + steps.push('Consider addressing warnings for better reliability'); + } + if (result.errors.length > 0) { + steps.push('Fix the errors above following the provided suggestions'); + } + return steps; + } + static deduplicateErrors(errors) { + const seen = new Map(); + for (const error of errors) { + const key = `${error.property}-${error.type}`; + const existing = seen.get(key); + if (!existing) { + seen.set(key, error); + } + else { + const existingLength = (existing.message?.length || 0) + (existing.fix?.length || 0); + const newLength = (error.message?.length || 0) + (error.fix?.length || 0); + if (newLength > existingLength) { + seen.set(key, error); + } + } + } + return Array.from(seen.values()); + } + static shouldFilterCredentialWarning(warning) { + return warning.type === 'security' && + warning.message !== undefined && + warning.message.includes('Hardcoded nodeCredentialType'); + } + static applyProfileFilters(result, profile) { + switch (profile) { + case 'minimal': + result.errors = result.errors.filter(e => e.type === 'missing_required'); + result.warnings = result.warnings.filter(w => { + if (this.shouldFilterCredentialWarning(w)) { + return false; + } + return w.type === 'security' || w.type === 'deprecated'; + }); + result.suggestions = []; + break; + case 'runtime': + result.errors = result.errors.filter(e => e.type === 'missing_required' || + e.type === 'invalid_value' || + (e.type === 'invalid_type' && e.message.includes('undefined'))); + result.warnings = result.warnings.filter(w => { + if (this.shouldFilterCredentialWarning(w)) { + return false; + } + if (w.type === 'security' || w.type === 'deprecated') + return true; + if (w.type === 'inefficient' && w.message && w.message.includes('not visible')) { + return false; + } + return false; + }); + result.suggestions = []; + break; + case 'strict': + if (result.warnings.length === 0 && result.errors.length === 0) { + result.suggestions.push('Consider adding error handling with onError property and timeout configuration'); + result.suggestions.push('Add authentication if connecting to external services'); + } + this.enforceErrorHandlingForProfile(result, profile); + break; + case 'ai-friendly': + default: + result.warnings = result.warnings.filter(w => { + if (this.shouldFilterCredentialWarning(w)) { + return false; + } + if (w.type === 'security' || w.type === 'deprecated') + return true; + if (w.type === 'missing_common') + return true; + if (w.type === 'best_practice') + return true; + if (w.type === 'inefficient' && w.message && w.message.includes('not visible')) { + return false; + } + if (w.type === 'inefficient' && w.property?.startsWith('_')) { + return false; + } + return true; + }); + this.addErrorHandlingSuggestions(result); + break; + } + } + static enforceErrorHandlingForProfile(result, profile) { + if (profile !== 'strict') + return; + const nodeType = result.operation?.resource || ''; + const errorProneTypes = ['httpRequest', 'webhook', 'database', 'api', 'slack', 'email', 'openai']; + if (errorProneTypes.some(type => nodeType.toLowerCase().includes(type))) { + result.warnings.push({ + type: 'best_practice', + property: 'errorHandling', + message: 'External service nodes should have error handling configured', + suggestion: 'Add onError: "continueRegularOutput" or "stopWorkflow" with retryOnFail: true for resilience' + }); + } + } + static addErrorHandlingSuggestions(result) { + const hasNetworkErrors = result.errors.some(e => e.message.toLowerCase().includes('url') || + e.message.toLowerCase().includes('endpoint') || + e.message.toLowerCase().includes('api')); + if (hasNetworkErrors) { + result.suggestions.push('For API calls, consider adding onError: "continueRegularOutput" with retryOnFail: true and maxTries: 3'); + } + const isWebhook = result.operation?.resource === 'webhook' || + result.errors.some(e => e.message.toLowerCase().includes('webhook')); + if (isWebhook) { + result.suggestions.push('Webhooks should use onError: "continueRegularOutput" to ensure responses are always sent'); + } + } + static validateFixedCollectionStructures(nodeType, config, result) { + const validationResult = fixed_collection_validator_1.FixedCollectionValidator.validate(nodeType, config); + if (!validationResult.isValid) { + for (const error of validationResult.errors) { + result.errors.push({ + type: 'invalid_value', + property: error.pattern.split('.')[0], + message: error.message, + fix: error.fix + }); + } + if (validationResult.autofix) { + if (typeof validationResult.autofix === 'object' && !Array.isArray(validationResult.autofix)) { + result.autofix = { + ...result.autofix, + ...validationResult.autofix + }; + } + else { + const firstError = validationResult.errors[0]; + if (firstError) { + const rootProperty = firstError.pattern.split('.')[0]; + result.autofix = { + ...result.autofix, + [rootProperty]: validationResult.autofix + }; + } + } + } + } + } + static validateSwitchNodeStructure(config, result) { + if (!config.rules) + return; + const hasFixedCollectionError = result.errors.some(e => e.property === 'rules' && e.message.includes('propertyValues[itemName] is not iterable')); + if (hasFixedCollectionError) + return; + if (config.rules.values && Array.isArray(config.rules.values)) { + config.rules.values.forEach((rule, index) => { + if (!rule.conditions) { + result.warnings.push({ + type: 'missing_common', + property: 'rules', + message: `Switch rule ${index + 1} is missing "conditions" property`, + suggestion: 'Each rule in the values array should have a "conditions" property' + }); + } + if (!rule.outputKey && rule.renameOutput !== false) { + result.warnings.push({ + type: 'missing_common', + property: 'rules', + message: `Switch rule ${index + 1} is missing "outputKey" property`, + suggestion: 'Add "outputKey" to specify which output to use when this rule matches' + }); + } + }); + } + } + static validateIfNodeStructure(config, result) { + if (!config.conditions) + return; + const hasFixedCollectionError = result.errors.some(e => e.property === 'conditions' && e.message.includes('propertyValues[itemName] is not iterable')); + if (hasFixedCollectionError) + return; + } + static validateFilterNodeStructure(config, result) { + if (!config.conditions) + return; + const hasFixedCollectionError = result.errors.some(e => e.property === 'conditions' && e.message.includes('propertyValues[itemName] is not iterable')); + if (hasFixedCollectionError) + return; + } + static validateResourceAndOperation(nodeType, config, result) { + if (!this.operationSimilarityService || !this.resourceSimilarityService || !this.nodeRepository) { + return; + } + const normalizedNodeType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType); + const configWithDefaults = { ...config }; + if (configWithDefaults.operation === undefined && configWithDefaults.resource !== undefined) { + const defaultOperation = this.nodeRepository.getDefaultOperationForResource(normalizedNodeType, configWithDefaults.resource); + if (defaultOperation !== undefined) { + configWithDefaults.operation = defaultOperation; + } + } + if (config.resource !== undefined) { + result.errors = result.errors.filter(e => e.property !== 'resource'); + const validResources = this.nodeRepository.getNodeResources(normalizedNodeType); + const resourceIsValid = validResources.some(r => { + const resourceValue = typeof r === 'string' ? r : r.value; + return resourceValue === config.resource; + }); + if (!resourceIsValid && config.resource !== '') { + let suggestions = []; + try { + suggestions = this.resourceSimilarityService.findSimilarResources(normalizedNodeType, config.resource, 3); + } + catch (error) { + console.error('Resource similarity service error:', error); + } + let errorMessage = `Invalid resource "${config.resource}" for node ${nodeType}.`; + let fix = ''; + if (suggestions.length > 0) { + const topSuggestion = suggestions[0]; + errorMessage += ` Did you mean "${topSuggestion.value}"?`; + if (topSuggestion.confidence >= 0.8) { + fix = `Change resource to "${topSuggestion.value}". ${topSuggestion.reason}`; + } + else { + fix = `Valid resources: ${validResources.slice(0, 5).map(r => { + const val = typeof r === 'string' ? r : r.value; + return `"${val}"`; + }).join(', ')}${validResources.length > 5 ? '...' : ''}`; + } + } + else { + fix = `Valid resources: ${validResources.slice(0, 5).map(r => { + const val = typeof r === 'string' ? r : r.value; + return `"${val}"`; + }).join(', ')}${validResources.length > 5 ? '...' : ''}`; + } + const error = { + type: 'invalid_value', + property: 'resource', + message: errorMessage, + fix + }; + if (suggestions.length > 0 && suggestions[0].confidence >= 0.5) { + error.suggestion = `Did you mean "${suggestions[0].value}"? ${suggestions[0].reason}`; + } + result.errors.push(error); + if (suggestions.length > 0) { + for (const suggestion of suggestions) { + result.suggestions.push(`Resource "${config.resource}" not found. Did you mean "${suggestion.value}"? ${suggestion.reason}`); + } + } + } + } + if (config.operation !== undefined || configWithDefaults.operation !== undefined) { + result.errors = result.errors.filter(e => e.property !== 'operation'); + const operationToValidate = configWithDefaults.operation || config.operation; + const validOperations = this.nodeRepository.getNodeOperations(normalizedNodeType, config.resource); + const operationIsValid = validOperations.some(op => { + const opValue = op.operation || op.value || op; + return opValue === operationToValidate; + }); + if (!operationIsValid && config.operation !== undefined && config.operation !== '') { + let suggestions = []; + try { + suggestions = this.operationSimilarityService.findSimilarOperations(normalizedNodeType, config.operation, config.resource, 3); + } + catch (error) { + console.error('Operation similarity service error:', error); + } + let errorMessage = `Invalid operation "${config.operation}" for node ${nodeType}`; + if (config.resource) { + errorMessage += ` with resource "${config.resource}"`; + } + errorMessage += '.'; + let fix = ''; + if (suggestions.length > 0) { + const topSuggestion = suggestions[0]; + if (topSuggestion.confidence >= 0.8) { + errorMessage += ` Did you mean "${topSuggestion.value}"?`; + fix = `Change operation to "${topSuggestion.value}". ${topSuggestion.reason}`; + } + else { + errorMessage += ` Similar operations: ${suggestions.map(s => `"${s.value}"`).join(', ')}`; + fix = `Valid operations${config.resource ? ` for resource "${config.resource}"` : ''}: ${validOperations.slice(0, 5).map(op => { + const val = op.operation || op.value || op; + return `"${val}"`; + }).join(', ')}${validOperations.length > 5 ? '...' : ''}`; + } + } + else { + fix = `Valid operations${config.resource ? ` for resource "${config.resource}"` : ''}: ${validOperations.slice(0, 5).map(op => { + const val = op.operation || op.value || op; + return `"${val}"`; + }).join(', ')}${validOperations.length > 5 ? '...' : ''}`; + } + const error = { + type: 'invalid_value', + property: 'operation', + message: errorMessage, + fix + }; + if (suggestions.length > 0 && suggestions[0].confidence >= 0.5) { + error.suggestion = `Did you mean "${suggestions[0].value}"? ${suggestions[0].reason}`; + } + result.errors.push(error); + if (suggestions.length > 0) { + for (const suggestion of suggestions) { + result.suggestions.push(`Operation "${config.operation}" not found. Did you mean "${suggestion.value}"? ${suggestion.reason}`); + } + } + } + } + } + static validateSpecialTypeStructures(config, properties, result) { + for (const [key, value] of Object.entries(config)) { + if (value === undefined || value === null) + continue; + const propDef = properties.find(p => p.name === key); + if (!propDef) + continue; + let structureType = null; + if (propDef.type === 'filter') { + structureType = 'filter'; + } + else if (propDef.type === 'resourceMapper') { + structureType = 'resourceMapper'; + } + else if (propDef.type === 'assignmentCollection') { + structureType = 'assignmentCollection'; + } + else if (propDef.type === 'resourceLocator') { + structureType = 'resourceLocator'; + } + if (!structureType) + continue; + const structure = type_structure_service_1.TypeStructureService.getStructure(structureType); + if (!structure) { + console.warn(`No structure definition found for type: ${structureType}`); + continue; + } + const validationResult = type_structure_service_1.TypeStructureService.validateTypeCompatibility(value, structureType); + if (!validationResult.valid) { + for (const error of validationResult.errors) { + result.errors.push({ + type: 'invalid_configuration', + property: key, + message: error, + fix: `Ensure ${key} follows the expected structure for ${structureType} type. Example: ${JSON.stringify(structure.example)}` + }); + } + } + for (const warning of validationResult.warnings) { + result.warnings.push({ + type: 'best_practice', + property: key, + message: warning + }); + } + if (typeof value === 'object' && value !== null) { + this.validateComplexTypeStructure(key, value, structureType, structure, result); + } + if (structureType === 'filter' && value.conditions) { + this.validateFilterOperations(value.conditions, key, result); + } + } + } + static validateComplexTypeStructure(propertyName, value, type, structure, result) { + switch (type) { + case 'filter': + if (!value.combinator) { + result.errors.push({ + type: 'invalid_configuration', + property: `${propertyName}.combinator`, + message: 'Filter must have a combinator field', + fix: 'Add combinator: "and" or combinator: "or" to the filter configuration' + }); + } + else if (value.combinator !== 'and' && value.combinator !== 'or') { + result.errors.push({ + type: 'invalid_configuration', + property: `${propertyName}.combinator`, + message: `Invalid combinator value: ${value.combinator}. Must be "and" or "or"`, + fix: 'Set combinator to either "and" or "or"' + }); + } + if (!value.conditions) { + result.errors.push({ + type: 'invalid_configuration', + property: `${propertyName}.conditions`, + message: 'Filter must have a conditions field', + fix: 'Add conditions array to the filter configuration' + }); + } + else if (!Array.isArray(value.conditions)) { + result.errors.push({ + type: 'invalid_configuration', + property: `${propertyName}.conditions`, + message: 'Filter conditions must be an array', + fix: 'Ensure conditions is an array of condition objects' + }); + } + break; + case 'resourceLocator': + if (!value.mode) { + result.errors.push({ + type: 'invalid_configuration', + property: `${propertyName}.mode`, + message: 'ResourceLocator must have a mode field', + fix: 'Add mode: "id", mode: "url", or mode: "list" to the resourceLocator configuration' + }); + } + else if (!['id', 'url', 'list', 'name'].includes(value.mode)) { + result.errors.push({ + type: 'invalid_configuration', + property: `${propertyName}.mode`, + message: `Invalid mode value: ${value.mode}. Must be "id", "url", "list", or "name"`, + fix: 'Set mode to one of: "id", "url", "list", "name"' + }); + } + if (!value.hasOwnProperty('value')) { + result.errors.push({ + type: 'invalid_configuration', + property: `${propertyName}.value`, + message: 'ResourceLocator must have a value field', + fix: 'Add value field to the resourceLocator configuration' + }); + } + break; + case 'assignmentCollection': + if (!value.assignments) { + result.errors.push({ + type: 'invalid_configuration', + property: `${propertyName}.assignments`, + message: 'AssignmentCollection must have an assignments field', + fix: 'Add assignments array to the assignmentCollection configuration' + }); + } + else if (!Array.isArray(value.assignments)) { + result.errors.push({ + type: 'invalid_configuration', + property: `${propertyName}.assignments`, + message: 'AssignmentCollection assignments must be an array', + fix: 'Ensure assignments is an array of assignment objects' + }); + } + break; + case 'resourceMapper': + if (!value.mappingMode) { + result.errors.push({ + type: 'invalid_configuration', + property: `${propertyName}.mappingMode`, + message: 'ResourceMapper must have a mappingMode field', + fix: 'Add mappingMode: "defineBelow" or mappingMode: "autoMapInputData"' + }); + } + else if (!['defineBelow', 'autoMapInputData'].includes(value.mappingMode)) { + result.errors.push({ + type: 'invalid_configuration', + property: `${propertyName}.mappingMode`, + message: `Invalid mappingMode: ${value.mappingMode}. Must be "defineBelow" or "autoMapInputData"`, + fix: 'Set mappingMode to either "defineBelow" or "autoMapInputData"' + }); + } + break; + } + } + static validateFilterOperations(conditions, propertyName, result) { + if (!Array.isArray(conditions)) + return; + const VALID_OPERATIONS_BY_TYPE = { + string: [ + 'empty', 'notEmpty', 'equals', 'notEquals', + 'contains', 'notContains', 'startsWith', 'notStartsWith', + 'endsWith', 'notEndsWith', 'regex', 'notRegex', + 'exists', 'notExists', 'isNotEmpty' + ], + number: [ + 'empty', 'notEmpty', 'equals', 'notEquals', 'gt', 'lt', 'gte', 'lte', + 'exists', 'notExists', 'isNotEmpty' + ], + dateTime: [ + 'empty', 'notEmpty', 'equals', 'notEquals', 'after', 'before', 'afterOrEquals', 'beforeOrEquals', + 'exists', 'notExists', 'isNotEmpty' + ], + boolean: [ + 'empty', 'notEmpty', 'true', 'false', 'equals', 'notEquals', + 'exists', 'notExists', 'isNotEmpty' + ], + array: [ + 'contains', 'notContains', 'lengthEquals', 'lengthNotEquals', + 'lengthGt', 'lengthLt', 'lengthGte', 'lengthLte', 'empty', 'notEmpty', + 'exists', 'notExists', 'isNotEmpty' + ], + object: [ + 'empty', 'notEmpty', + 'exists', 'notExists', 'isNotEmpty' + ], + any: ['exists', 'notExists', 'isNotEmpty'] + }; + for (let i = 0; i < conditions.length; i++) { + const condition = conditions[i]; + if (!condition.operator || typeof condition.operator !== 'object') + continue; + const { type, operation } = condition.operator; + if (!type || !operation) + continue; + const validOperations = VALID_OPERATIONS_BY_TYPE[type]; + if (!validOperations) { + result.warnings.push({ + type: 'best_practice', + property: `${propertyName}.conditions[${i}].operator.type`, + message: `Unknown operator type: ${type}` + }); + continue; + } + if (!validOperations.includes(operation)) { + result.errors.push({ + type: 'invalid_value', + property: `${propertyName}.conditions[${i}].operator.operation`, + message: `Operation '${operation}' is not valid for type '${type}'`, + fix: `Use one of the valid operations for ${type}: ${validOperations.join(', ')}` + }); + } + } + } +} +exports.EnhancedConfigValidator = EnhancedConfigValidator; +EnhancedConfigValidator.operationSimilarityService = null; +EnhancedConfigValidator.resourceSimilarityService = null; +EnhancedConfigValidator.nodeRepository = null; +//# sourceMappingURL=enhanced-config-validator.js.map \ No newline at end of file diff --git a/dist/services/enhanced-config-validator.js.map b/dist/services/enhanced-config-validator.js.map new file mode 100644 index 0000000..31187e7 --- /dev/null +++ b/dist/services/enhanced-config-validator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"enhanced-config-validator.js","sourceRoot":"","sources":["../../src/services/enhanced-config-validator.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/example-generator.d.ts b/dist/services/example-generator.d.ts new file mode 100644 index 0000000..3c6e716 --- /dev/null +++ b/dist/services/example-generator.d.ts @@ -0,0 +1,14 @@ +export interface NodeExamples { + minimal: Record; + common?: Record; + advanced?: Record; +} +export declare class ExampleGenerator { + private static NODE_EXAMPLES; + static getExamples(nodeType: string, essentials?: any): NodeExamples; + private static generateBasicExamples; + private static getDefaultValue; + private static getStringDefault; + static getTaskExample(nodeType: string, task: string): Record | undefined; +} +//# sourceMappingURL=example-generator.d.ts.map \ No newline at end of file diff --git a/dist/services/example-generator.d.ts.map b/dist/services/example-generator.d.ts.map new file mode 100644 index 0000000..76ea474 --- /dev/null +++ b/dist/services/example-generator.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"example-generator.d.ts","sourceRoot":"","sources":["../../src/services/example-generator.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED,qBAAa,gBAAgB;IAK3B,OAAO,CAAC,MAAM,CAAC,aAAa,CA87B1B;IAKF,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,GAAG,GAAG,YAAY;IAcpE,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAsBpC,OAAO,CAAC,MAAM,CAAC,eAAe;IAsC9B,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAiD/B,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS;CAiBvF"} \ No newline at end of file diff --git a/dist/services/example-generator.js b/dist/services/example-generator.js new file mode 100644 index 0000000..b8b2c09 --- /dev/null +++ b/dist/services/example-generator.js @@ -0,0 +1,970 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ExampleGenerator = void 0; +class ExampleGenerator { + static getExamples(nodeType, essentials) { + const examples = this.NODE_EXAMPLES[nodeType]; + if (examples) { + return examples; + } + return this.generateBasicExamples(nodeType, essentials); + } + static generateBasicExamples(nodeType, essentials) { + const minimal = {}; + if (essentials?.required) { + for (const prop of essentials.required) { + minimal[prop.name] = this.getDefaultValue(prop); + } + } + if (Object.keys(minimal).length === 0 && essentials?.common?.length > 0) { + const firstCommon = essentials.common[0]; + minimal[firstCommon.name] = this.getDefaultValue(firstCommon); + } + return { minimal }; + } + static getDefaultValue(prop) { + if (prop.default !== undefined) { + return prop.default; + } + switch (prop.type) { + case 'string': + return this.getStringDefault(prop); + case 'number': + return prop.name.includes('port') ? 80 : + prop.name.includes('timeout') ? 30000 : + prop.name.includes('limit') ? 10 : 0; + case 'boolean': + return false; + case 'options': + case 'multiOptions': + return prop.options?.[0]?.value || ''; + case 'json': + return '{\n "key": "value"\n}'; + case 'collection': + case 'fixedCollection': + return {}; + default: + return ''; + } + } + static getStringDefault(prop) { + const name = prop.name.toLowerCase(); + if (name.includes('url') || name === 'endpoint') { + return 'https://api.example.com'; + } + if (name.includes('email')) { + return name.includes('from') ? 'sender@example.com' : 'recipient@example.com'; + } + if (name.includes('path')) { + return name.includes('webhook') ? 'my-webhook' : '/path/to/file'; + } + if (name === 'name' || name.includes('username')) { + return 'John Doe'; + } + if (name.includes('key')) { + return 'myKey'; + } + if (name === 'query' || name.includes('sql')) { + return 'SELECT * FROM table_name LIMIT 10'; + } + if (name === 'collection' || name === 'table') { + return 'users'; + } + if (prop.placeholder) { + return prop.placeholder; + } + return ''; + } + static getTaskExample(nodeType, task) { + const examples = this.NODE_EXAMPLES[nodeType]; + if (!examples) + return undefined; + const taskMap = { + 'basic': 'minimal', + 'simple': 'minimal', + 'typical': 'common', + 'standard': 'common', + 'complex': 'advanced', + 'full': 'advanced' + }; + const exampleType = taskMap[task] || 'common'; + return examples[exampleType] || examples.minimal; + } +} +exports.ExampleGenerator = ExampleGenerator; +ExampleGenerator.NODE_EXAMPLES = { + 'nodes-base.httpRequest': { + minimal: { + url: 'https://api.example.com/data' + }, + common: { + method: 'POST', + url: 'https://api.example.com/users', + sendBody: true, + contentType: 'json', + specifyBody: 'json', + jsonBody: '{\n "name": "John Doe",\n "email": "john@example.com"\n}' + }, + advanced: { + method: 'POST', + url: 'https://api.example.com/protected/resource', + authentication: 'genericCredentialType', + genericAuthType: 'headerAuth', + sendHeaders: true, + headerParameters: { + parameters: [ + { + name: 'X-API-Version', + value: 'v2' + } + ] + }, + sendBody: true, + contentType: 'json', + specifyBody: 'json', + jsonBody: '{\n "action": "update",\n "data": {}\n}', + onError: 'continueRegularOutput', + retryOnFail: true, + maxTries: 3, + waitBetweenTries: 1000, + alwaysOutputData: true + } + }, + 'nodes-base.webhook': { + minimal: { + path: 'my-webhook', + httpMethod: 'POST' + }, + common: { + path: 'webhook-endpoint', + httpMethod: 'POST', + responseMode: 'lastNode', + responseData: 'allEntries', + responseCode: 200, + onError: 'continueRegularOutput', + alwaysOutputData: true + } + }, + 'nodes-base.code.webhookProcessing': { + minimal: { + language: 'javaScript', + jsCode: `// ⚠️ CRITICAL: Webhook data is nested under 'body' property! +// This Code node should be connected after a Webhook node + +// ❌ WRONG - This will be undefined: +// const command = items[0].json.testCommand; + +// ✅ CORRECT - Access webhook data through body: +const webhookData = items[0].json.body; +const headers = items[0].json.headers; +const query = items[0].json.query; + +// Process webhook payload +return [{ + json: { + // Extract data from webhook body + command: webhookData.testCommand, + userId: webhookData.userId, + data: webhookData.data, + + // Add metadata + timestamp: DateTime.now().toISO(), + requestId: headers['x-request-id'] || crypto.randomUUID(), + source: query.source || 'webhook', + + // Original webhook info + httpMethod: items[0].json.httpMethod, + webhookPath: items[0].json.webhookPath + } +}];` + } + }, + 'nodes-base.code': { + minimal: { + language: 'javaScript', + jsCode: 'return [{json: {result: "success"}}];' + }, + common: { + language: 'javaScript', + jsCode: `// Process each item and add timestamp +return items.map(item => ({ + json: { + ...item.json, + processed: true, + timestamp: DateTime.now().toISO() + } +}));`, + onError: 'continueRegularOutput' + }, + advanced: { + language: 'javaScript', + jsCode: `// Advanced data processing with proper helper checks +const crypto = require('crypto'); +const results = []; + +for (const item of items) { + try { + // Validate required fields + if (!item.json.email || !item.json.name) { + throw new Error('Missing required fields: email or name'); + } + + // Generate secure API key + const apiKey = crypto.randomBytes(16).toString('hex'); + + // Check if $helpers is available before using + let response; + if (typeof $helpers !== 'undefined' && $helpers.httpRequest) { + response = await $helpers.httpRequest({ + method: 'POST', + url: 'https://api.example.com/process', + body: { + email: item.json.email, + name: item.json.name, + apiKey + }, + headers: { + 'Content-Type': 'application/json' + } + }); + } else { + // Fallback if $helpers not available + response = { message: 'HTTP requests not available in this n8n version' }; + } + + // Add to results with response data + results.push({ + json: { + ...item.json, + apiResponse: response, + processedAt: DateTime.now().toISO(), + status: 'success' + } + }); + + } catch (error) { + // Include failed items with error info + results.push({ + json: { + ...item.json, + error: error.message, + status: 'failed', + processedAt: DateTime.now().toISO() + } + }); + } +} + +return results;`, + onError: 'continueRegularOutput', + retryOnFail: true, + maxTries: 2 + } + }, + 'nodes-base.code.dataTransform': { + minimal: { + language: 'javaScript', + jsCode: `// Transform CSV-like data to JSON +return items.map(item => { + const lines = item.json.data.split('\\n'); + const headers = lines[0].split(','); + const rows = lines.slice(1).map(line => { + const values = line.split(','); + return headers.reduce((obj, header, i) => { + obj[header.trim()] = values[i]?.trim() || ''; + return obj; + }, {}); + }); + + return {json: {rows, count: rows.length}}; +});` + } + }, + 'nodes-base.code.aggregation': { + minimal: { + language: 'javaScript', + jsCode: `// Aggregate data from all items +const totals = items.reduce((acc, item) => { + acc.count++; + acc.sum += item.json.amount || 0; + acc.categories[item.json.category] = (acc.categories[item.json.category] || 0) + 1; + return acc; +}, {count: 0, sum: 0, categories: {}}); + +return [{ + json: { + totalItems: totals.count, + totalAmount: totals.sum, + averageAmount: totals.sum / totals.count, + categoryCounts: totals.categories, + processedAt: DateTime.now().toISO() + } +}];` + } + }, + 'nodes-base.code.filtering': { + minimal: { + language: 'javaScript', + jsCode: `// Filter items based on conditions +return items + .filter(item => { + const amount = item.json.amount || 0; + const status = item.json.status || ''; + return amount > 100 && status === 'active'; + }) + .map(item => ({json: item.json}));` + } + }, + 'nodes-base.code.jmespathFiltering': { + minimal: { + language: 'javaScript', + jsCode: `// JMESPath filtering - IMPORTANT: Use backticks for numeric literals! +const allItems = items.map(item => item.json); + +// ✅ CORRECT - Filter with numeric literals using backticks +const expensiveItems = $jmespath(allItems, '[?price >= \`100\`]'); +const lowStock = $jmespath(allItems, '[?inventory < \`10\`]'); +const highPriority = $jmespath(allItems, '[?priority == \`1\`]'); + +// Combine multiple conditions +const urgentExpensive = $jmespath(allItems, '[?price >= \`100\` && priority == \`1\`]'); + +// String comparisons don't need backticks +const activeItems = $jmespath(allItems, '[?status == "active"]'); + +// Return filtered results +return expensiveItems.map(item => ({json: item}));` + } + }, + 'nodes-base.code.pythonExample': { + minimal: { + language: 'python', + pythonCode: `# Python data processing - use underscore prefix for built-in variables +import json +from datetime import datetime +import re + +results = [] + +# Use _input.all() to get items in Python +for item in _input.all(): + # Convert JsProxy to Python dict to avoid issues with null values + item_data = item.json.to_py() + + # Clean email addresses + email = item_data.get('email', '') + if email and re.match(r'^[\\w\\.-]+@[\\w\\.-]+\\.\\w+$', email): + cleaned_data = { + 'email': email.lower(), + 'name': item_data.get('name', '').title(), + 'validated': True, + 'timestamp': datetime.now().isoformat() + } + else: + # Spread operator doesn't work with JsProxy, use dict() + cleaned_data = dict(item_data) + cleaned_data['validated'] = False + cleaned_data['error'] = 'Invalid email format' + + results.append({'json': cleaned_data}) + +return results` + } + }, + 'nodes-base.code.aiTool': { + minimal: { + language: 'javaScript', + mode: 'runOnceForEachItem', + jsCode: `// Code node as AI tool - calculate discount +const quantity = $json.quantity || 1; +const price = $json.price || 0; + +let discountRate = 0; +if (quantity >= 100) discountRate = 0.20; +else if (quantity >= 50) discountRate = 0.15; +else if (quantity >= 20) discountRate = 0.10; +else if (quantity >= 10) discountRate = 0.05; + +const subtotal = price * quantity; +const discount = subtotal * discountRate; +const total = subtotal - discount; + +return [{ + json: { + quantity, + price, + subtotal, + discountRate: discountRate * 100, + discountAmount: discount, + total, + savings: discount + } +}];` + } + }, + 'nodes-base.code.crypto': { + minimal: { + language: 'javaScript', + jsCode: `// Using crypto in Code nodes - it IS available! +const crypto = require('crypto'); + +// Generate secure tokens +const token = crypto.randomBytes(32).toString('hex'); +const uuid = crypto.randomUUID(); + +// Create hashes +const hash = crypto.createHash('sha256') + .update(items[0].json.data || 'test') + .digest('hex'); + +return [{ + json: { + token, + uuid, + hash, + timestamp: DateTime.now().toISO() + } +}];` + } + }, + 'nodes-base.code.staticData': { + minimal: { + language: 'javaScript', + jsCode: `// Using workflow static data correctly +// IMPORTANT: $getWorkflowStaticData is a standalone function! +const staticData = $getWorkflowStaticData('global'); + +// Initialize counter if not exists +if (!staticData.processCount) { + staticData.processCount = 0; + staticData.firstRun = DateTime.now().toISO(); +} + +// Update counter +staticData.processCount++; +staticData.lastRun = DateTime.now().toISO(); + +// Process items +const results = items.map(item => ({ + json: { + ...item.json, + runNumber: staticData.processCount, + processed: true + } +})); + +return results;` + } + }, + 'nodes-base.set': { + minimal: { + mode: 'manual', + assignments: { + assignments: [ + { + id: '1', + name: 'status', + value: 'active', + type: 'string' + } + ] + } + }, + common: { + mode: 'manual', + includeOtherFields: true, + assignments: { + assignments: [ + { + id: '1', + name: 'status', + value: 'processed', + type: 'string' + }, + { + id: '2', + name: 'processedAt', + value: '={{ $now.toISO() }}', + type: 'string' + }, + { + id: '3', + name: 'itemCount', + value: '={{ $items().length }}', + type: 'number' + } + ] + } + } + }, + 'nodes-base.if': { + minimal: { + conditions: { + conditions: [ + { + id: '1', + leftValue: '={{ $json.status }}', + rightValue: 'active', + operator: { + type: 'string', + operation: 'equals' + } + } + ] + } + }, + common: { + conditions: { + conditions: [ + { + id: '1', + leftValue: '={{ $json.status }}', + rightValue: 'active', + operator: { + type: 'string', + operation: 'equals' + } + }, + { + id: '2', + leftValue: '={{ $json.count }}', + rightValue: 10, + operator: { + type: 'number', + operation: 'gt' + } + } + ] + }, + combineOperation: 'all' + } + }, + 'nodes-base.postgres': { + minimal: { + operation: 'executeQuery', + query: 'SELECT * FROM users LIMIT 10' + }, + common: { + operation: 'insert', + table: 'users', + columns: 'name,email,created_at', + additionalFields: {} + }, + advanced: { + operation: 'executeQuery', + query: `INSERT INTO users (name, email, status) +VALUES ($1, $2, $3) +ON CONFLICT (email) +DO UPDATE SET + name = EXCLUDED.name, + updated_at = NOW() +RETURNING *;`, + additionalFields: { + queryParams: '={{ $json.name }},{{ $json.email }},active' + }, + retryOnFail: true, + maxTries: 3, + waitBetweenTries: 2000, + onError: 'continueErrorOutput' + } + }, + 'nodes-base.openAi': { + minimal: { + resource: 'chat', + operation: 'message', + modelId: 'gpt-3.5-turbo', + messages: { + values: [ + { + role: 'user', + content: 'Hello, how can you help me?' + } + ] + } + }, + common: { + resource: 'chat', + operation: 'message', + modelId: 'gpt-4', + messages: { + values: [ + { + role: 'system', + content: 'You are a helpful assistant that summarizes text concisely.' + }, + { + role: 'user', + content: '={{ $json.text }}' + } + ] + }, + options: { + maxTokens: 150, + temperature: 0.7 + }, + retryOnFail: true, + maxTries: 3, + waitBetweenTries: 5000, + onError: 'continueRegularOutput', + alwaysOutputData: true + } + }, + 'nodes-base.googleSheets': { + minimal: { + operation: 'read', + documentId: { + __rl: true, + value: 'https://docs.google.com/spreadsheets/d/your-sheet-id', + mode: 'url' + }, + sheetName: 'Sheet1' + }, + common: { + operation: 'append', + documentId: { + __rl: true, + value: 'your-sheet-id', + mode: 'id' + }, + sheetName: 'Sheet1', + dataStartRow: 2, + columns: { + mappingMode: 'defineBelow', + value: { + 'Name': '={{ $json.name }}', + 'Email': '={{ $json.email }}', + 'Date': '={{ $now.toISO() }}' + } + } + } + }, + 'nodes-base.slack': { + minimal: { + resource: 'message', + operation: 'post', + channel: '#general', + text: 'Hello from n8n!' + }, + common: { + resource: 'message', + operation: 'post', + channel: '#notifications', + text: 'New order received!', + attachments: [ + { + color: '#36a64f', + title: 'Order #{{ $json.orderId }}', + fields: { + item: [ + { + title: 'Customer', + value: '{{ $json.customerName }}', + short: true + }, + { + title: 'Amount', + value: '${{ $json.amount }}', + short: true + } + ] + } + } + ], + retryOnFail: true, + maxTries: 2, + waitBetweenTries: 3000, + onError: 'continueRegularOutput' + } + }, + 'nodes-base.emailSend': { + minimal: { + fromEmail: 'sender@example.com', + toEmail: 'recipient@example.com', + subject: 'Test Email', + text: 'This is a test email from n8n.' + }, + common: { + fromEmail: 'notifications@company.com', + toEmail: '={{ $json.email }}', + subject: 'Welcome to our service, {{ $json.name }}!', + html: `

Welcome!

+

Hi {{ $json.name }},

+

Thank you for signing up. We're excited to have you on board!

+

Best regards,
The Team

`, + options: { + ccEmail: 'admin@company.com' + }, + retryOnFail: true, + maxTries: 3, + waitBetweenTries: 2000, + onError: 'continueRegularOutput' + } + }, + 'nodes-base.merge': { + minimal: { + mode: 'append' + }, + common: { + mode: 'mergeByKey', + propertyName1: 'id', + propertyName2: 'userId' + } + }, + 'nodes-base.function': { + minimal: { + functionCode: 'return items;' + }, + common: { + functionCode: `// Add a timestamp to each item +const processedItems = items.map(item => { + return { + ...item, + json: { + ...item.json, + processedAt: new Date().toISOString() + } + }; +}); + +return processedItems;` + } + }, + 'nodes-base.splitInBatches': { + minimal: { + batchSize: 10 + }, + common: { + batchSize: 100, + options: { + reset: false + } + } + }, + 'nodes-base.redis': { + minimal: { + operation: 'set', + key: 'myKey', + value: 'myValue' + }, + common: { + operation: 'set', + key: 'user:{{ $json.userId }}', + value: '={{ JSON.stringify($json) }}', + expire: true, + ttl: 3600 + } + }, + 'nodes-base.mongoDb': { + minimal: { + operation: 'find', + collection: 'users' + }, + common: { + operation: 'findOneAndUpdate', + collection: 'users', + query: '{ "email": "{{ $json.email }}" }', + update: '{ "$set": { "lastLogin": "{{ $now.toISO() }}" } }', + options: { + upsert: true, + returnNewDocument: true + }, + retryOnFail: true, + maxTries: 3, + waitBetweenTries: 1000, + onError: 'continueErrorOutput' + } + }, + 'nodes-base.mySql': { + minimal: { + operation: 'executeQuery', + query: 'SELECT * FROM products WHERE active = 1' + }, + common: { + operation: 'insert', + table: 'orders', + columns: 'customer_id,product_id,quantity,order_date', + options: { + queryBatching: 'independently' + }, + retryOnFail: true, + maxTries: 3, + waitBetweenTries: 2000, + onError: 'stopWorkflow' + } + }, + 'nodes-base.ftp': { + minimal: { + operation: 'download', + path: '/files/data.csv' + }, + common: { + operation: 'upload', + path: '/uploads/', + fileName: 'report_{{ $now.format("yyyy-MM-dd") }}.csv', + binaryData: true, + binaryPropertyName: 'data' + } + }, + 'nodes-base.ssh': { + minimal: { + resource: 'command', + operation: 'execute', + command: 'ls -la' + }, + common: { + resource: 'command', + operation: 'execute', + command: 'cd /var/logs && tail -n 100 app.log | grep ERROR', + cwd: '/home/user' + } + }, + 'nodes-base.executeCommand': { + minimal: { + command: 'echo "Hello from n8n"' + }, + common: { + command: 'node process-data.js --input "{{ $json.filename }}"', + cwd: '/app/scripts' + } + }, + 'nodes-base.github': { + minimal: { + resource: 'issue', + operation: 'get', + owner: 'n8n-io', + repository: 'n8n', + issueNumber: 123 + }, + common: { + resource: 'issue', + operation: 'create', + owner: '={{ $json.organization }}', + repository: '={{ $json.repo }}', + title: 'Bug: {{ $json.title }}', + body: `## Description +{{ $json.description }} + +## Steps to Reproduce +{{ $json.steps }} + +## Expected Behavior +{{ $json.expected }}`, + assignees: ['maintainer'], + labels: ['bug', 'needs-triage'] + } + }, + 'error-handling.modern-patterns': { + minimal: { + onError: 'continueRegularOutput' + }, + common: { + onError: 'continueErrorOutput', + alwaysOutputData: true + }, + advanced: { + onError: 'stopWorkflow', + retryOnFail: true, + maxTries: 3, + waitBetweenTries: 2000 + } + }, + 'error-handling.api-with-retry': { + minimal: { + url: 'https://api.example.com/data', + retryOnFail: true, + maxTries: 3, + waitBetweenTries: 1000 + }, + common: { + method: 'GET', + url: 'https://api.example.com/users/{{ $json.userId }}', + retryOnFail: true, + maxTries: 5, + waitBetweenTries: 2000, + alwaysOutputData: true, + sendHeaders: true, + headerParameters: { + parameters: [ + { + name: 'X-Request-ID', + value: '={{ $workflow.id }}-{{ $execution.id }}' + } + ] + } + }, + advanced: { + method: 'POST', + url: 'https://api.example.com/critical-operation', + sendBody: true, + contentType: 'json', + specifyBody: 'json', + jsonBody: '{{ JSON.stringify($json) }}', + retryOnFail: true, + maxTries: 5, + waitBetweenTries: 1000, + alwaysOutputData: true, + onError: 'stopWorkflow' + } + }, + 'error-handling.fault-tolerant': { + minimal: { + onError: 'continueRegularOutput' + }, + common: { + onError: 'continueRegularOutput', + alwaysOutputData: true + }, + advanced: { + onError: 'continueRegularOutput', + retryOnFail: true, + maxTries: 2, + waitBetweenTries: 500, + alwaysOutputData: true + } + }, + 'error-handling.database-patterns': { + minimal: { + onError: 'continueRegularOutput', + alwaysOutputData: true + }, + common: { + retryOnFail: true, + maxTries: 3, + waitBetweenTries: 2000, + onError: 'stopWorkflow' + }, + advanced: { + onError: 'continueErrorOutput', + retryOnFail: false, + alwaysOutputData: true + } + }, + 'error-handling.webhook-patterns': { + minimal: { + onError: 'continueRegularOutput', + alwaysOutputData: true + }, + common: { + onError: 'continueErrorOutput', + alwaysOutputData: true, + responseCode: 200, + responseData: 'allEntries' + } + }, + 'error-handling.ai-patterns': { + minimal: { + retryOnFail: true, + maxTries: 3, + waitBetweenTries: 5000, + onError: 'continueRegularOutput' + }, + common: { + retryOnFail: true, + maxTries: 5, + waitBetweenTries: 2000, + onError: 'continueRegularOutput', + alwaysOutputData: true + } + } +}; +//# sourceMappingURL=example-generator.js.map \ No newline at end of file diff --git a/dist/services/example-generator.js.map b/dist/services/example-generator.js.map new file mode 100644 index 0000000..20501c9 --- /dev/null +++ b/dist/services/example-generator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"example-generator.js","sourceRoot":"","sources":["../../src/services/example-generator.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/execution-processor.d.ts b/dist/services/execution-processor.d.ts new file mode 100644 index 0000000..0702206 --- /dev/null +++ b/dist/services/execution-processor.d.ts @@ -0,0 +1,8 @@ +import { Execution, ExecutionPreview, ExecutionRecommendation, ExecutionFilterOptions, FilteredExecutionResponse } from '../types/n8n-api'; +export declare function generatePreview(execution: Execution): { + preview: ExecutionPreview; + recommendation: ExecutionRecommendation; +}; +export declare function filterExecutionData(execution: Execution, options: ExecutionFilterOptions): FilteredExecutionResponse; +export declare function processExecution(execution: Execution, options?: ExecutionFilterOptions): FilteredExecutionResponse | Execution; +//# sourceMappingURL=execution-processor.d.ts.map \ No newline at end of file diff --git a/dist/services/execution-processor.d.ts.map b/dist/services/execution-processor.d.ts.map new file mode 100644 index 0000000..6d62e75 --- /dev/null +++ b/dist/services/execution-processor.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"execution-processor.d.ts","sourceRoot":"","sources":["../../src/services/execution-processor.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,SAAS,EAET,gBAAgB,EAEhB,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EAG1B,MAAM,kBAAkB,CAAC;AA+G1B,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG;IACrD,OAAO,EAAE,gBAAgB,CAAC;IAC1B,cAAc,EAAE,uBAAuB,CAAC;CACzC,CA2EA;AAoID,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,sBAAsB,GAC9B,yBAAyB,CA2J3B;AAMD,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,SAAS,EACpB,OAAO,GAAE,sBAA2B,GACnC,yBAAyB,GAAG,SAAS,CAOvC"} \ No newline at end of file diff --git a/dist/services/execution-processor.js b/dist/services/execution-processor.js new file mode 100644 index 0000000..83d510b --- /dev/null +++ b/dist/services/execution-processor.js @@ -0,0 +1,359 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.generatePreview = generatePreview; +exports.filterExecutionData = filterExecutionData; +exports.processExecution = processExecution; +const logger_1 = require("../utils/logger"); +const THRESHOLDS = { + CHAR_SIZE_BYTES: 2, + OVERHEAD_PER_OBJECT: 50, + MAX_RECOMMENDED_SIZE_KB: 100, + SMALL_DATASET_ITEMS: 20, + MODERATE_DATASET_ITEMS: 50, + MODERATE_DATASET_SIZE_KB: 200, + MAX_DEPTH: 3, + MAX_ITEMS_LIMIT: 1000, +}; +function extractErrorMessage(error) { + if (typeof error === 'string') { + return error; + } + if (error && typeof error === 'object') { + if ('message' in error && typeof error.message === 'string') { + return error.message; + } + if ('error' in error && typeof error.error === 'string') { + return error.error; + } + } + return 'Unknown error'; +} +function extractStructure(data, maxDepth = THRESHOLDS.MAX_DEPTH, currentDepth = 0) { + if (currentDepth >= maxDepth) { + return typeof data; + } + if (data === null || data === undefined) { + return 'null'; + } + if (Array.isArray(data)) { + if (data.length === 0) { + return []; + } + return [extractStructure(data[0], maxDepth, currentDepth + 1)]; + } + if (typeof data === 'object') { + const structure = {}; + for (const key in data) { + if (Object.prototype.hasOwnProperty.call(data, key)) { + structure[key] = extractStructure(data[key], maxDepth, currentDepth + 1); + } + } + return structure; + } + return typeof data; +} +function estimateDataSize(data) { + try { + const jsonString = JSON.stringify(data); + const sizeBytes = jsonString.length * THRESHOLDS.CHAR_SIZE_BYTES; + return Math.ceil(sizeBytes / 1024); + } + catch (error) { + logger_1.logger.warn('Failed to estimate data size', { error }); + return 0; + } +} +function countItems(nodeData) { + const counts = { input: 0, output: 0 }; + if (!nodeData || !Array.isArray(nodeData)) { + return counts; + } + for (const run of nodeData) { + if (run?.data?.main) { + const mainData = run.data.main; + if (Array.isArray(mainData)) { + for (const output of mainData) { + if (Array.isArray(output)) { + counts.output += output.length; + } + } + } + } + } + return counts; +} +function generatePreview(execution) { + const preview = { + totalNodes: 0, + executedNodes: 0, + estimatedSizeKB: 0, + nodes: {}, + }; + if (!execution.data?.resultData?.runData) { + return { + preview, + recommendation: { + canFetchFull: true, + suggestedMode: 'summary', + reason: 'No execution data available', + }, + }; + } + const runData = execution.data.resultData.runData; + const nodeNames = Object.keys(runData); + preview.totalNodes = nodeNames.length; + let totalItemsOutput = 0; + let largestNodeItems = 0; + for (const nodeName of nodeNames) { + const nodeData = runData[nodeName]; + const itemCounts = countItems(nodeData); + let dataStructure = {}; + if (Array.isArray(nodeData) && nodeData.length > 0) { + const firstRun = nodeData[0]; + const firstItem = firstRun?.data?.main?.[0]?.[0]; + if (firstItem) { + dataStructure = extractStructure(firstItem); + } + } + const nodeSize = estimateDataSize(nodeData); + const nodePreview = { + status: 'success', + itemCounts, + dataStructure, + estimatedSizeKB: nodeSize, + }; + if (Array.isArray(nodeData)) { + for (const run of nodeData) { + if (run.error) { + nodePreview.status = 'error'; + nodePreview.error = extractErrorMessage(run.error); + break; + } + } + } + preview.nodes[nodeName] = nodePreview; + preview.estimatedSizeKB += nodeSize; + preview.executedNodes++; + totalItemsOutput += itemCounts.output; + largestNodeItems = Math.max(largestNodeItems, itemCounts.output); + } + const recommendation = generateRecommendation(preview.estimatedSizeKB, totalItemsOutput, largestNodeItems); + return { preview, recommendation }; +} +function generateRecommendation(totalSizeKB, totalItems, largestNodeItems) { + if (totalSizeKB <= THRESHOLDS.MAX_RECOMMENDED_SIZE_KB && totalItems <= THRESHOLDS.SMALL_DATASET_ITEMS) { + return { + canFetchFull: true, + suggestedMode: 'full', + reason: `Small dataset (${totalSizeKB}KB, ${totalItems} items). Safe to fetch full data.`, + }; + } + if (totalSizeKB <= THRESHOLDS.MODERATE_DATASET_SIZE_KB && totalItems <= THRESHOLDS.MODERATE_DATASET_ITEMS) { + return { + canFetchFull: false, + suggestedMode: 'summary', + suggestedItemsLimit: 2, + reason: `Moderate dataset (${totalSizeKB}KB, ${totalItems} items). Summary mode recommended.`, + }; + } + const suggestedLimit = Math.max(1, Math.min(5, Math.floor(100 / largestNodeItems))); + return { + canFetchFull: false, + suggestedMode: 'filtered', + suggestedItemsLimit: suggestedLimit, + reason: `Large dataset (${totalSizeKB}KB, ${totalItems} items). Use filtered mode with itemsLimit: ${suggestedLimit}.`, + }; +} +function truncateItems(items, limit) { + if (!Array.isArray(items) || items.length === 0) { + return { + truncated: items || [], + metadata: { + totalItems: 0, + itemsShown: 0, + truncated: false, + }, + }; + } + let totalItems = 0; + for (const output of items) { + if (Array.isArray(output)) { + totalItems += output.length; + } + } + if (limit === 0) { + const structureOnly = items.map(output => { + if (!Array.isArray(output) || output.length === 0) { + return []; + } + return [extractStructure(output[0])]; + }); + return { + truncated: structureOnly, + metadata: { + totalItems, + itemsShown: 0, + truncated: true, + }, + }; + } + if (limit < 0) { + return { + truncated: items, + metadata: { + totalItems, + itemsShown: totalItems, + truncated: false, + }, + }; + } + const result = []; + let itemsShown = 0; + for (const output of items) { + if (!Array.isArray(output)) { + result.push(output); + continue; + } + if (itemsShown >= limit) { + break; + } + const remaining = limit - itemsShown; + const toTake = Math.min(remaining, output.length); + result.push(output.slice(0, toTake)); + itemsShown += toTake; + } + return { + truncated: result, + metadata: { + totalItems, + itemsShown, + truncated: itemsShown < totalItems, + }, + }; +} +function filterExecutionData(execution, options) { + const mode = options.mode || 'summary'; + let itemsLimit = options.itemsLimit !== undefined ? options.itemsLimit : 2; + if (itemsLimit !== -1) { + if (itemsLimit < 0) { + logger_1.logger.warn('Invalid itemsLimit, defaulting to 2', { provided: itemsLimit }); + itemsLimit = 2; + } + if (itemsLimit > THRESHOLDS.MAX_ITEMS_LIMIT) { + logger_1.logger.warn(`itemsLimit capped at ${THRESHOLDS.MAX_ITEMS_LIMIT}`, { provided: itemsLimit }); + itemsLimit = THRESHOLDS.MAX_ITEMS_LIMIT; + } + } + const includeInputData = options.includeInputData || false; + const nodeNamesFilter = options.nodeNames; + const duration = execution.stoppedAt && execution.startedAt + ? new Date(execution.stoppedAt).getTime() - new Date(execution.startedAt).getTime() + : undefined; + const response = { + id: execution.id, + workflowId: execution.workflowId, + status: execution.status, + mode, + startedAt: execution.startedAt, + stoppedAt: execution.stoppedAt, + duration, + finished: execution.finished, + }; + if (mode === 'preview') { + const { preview, recommendation } = generatePreview(execution); + response.preview = preview; + response.recommendation = recommendation; + return response; + } + if (!execution.data?.resultData?.runData) { + response.summary = { + totalNodes: 0, + executedNodes: 0, + totalItems: 0, + hasMoreData: false, + }; + response.nodes = {}; + if (execution.data?.resultData?.error) { + response.error = execution.data.resultData.error; + } + return response; + } + const runData = execution.data.resultData.runData; + let nodeNames = Object.keys(runData); + if (nodeNamesFilter && nodeNamesFilter.length > 0) { + nodeNames = nodeNames.filter(name => nodeNamesFilter.includes(name)); + } + const processedNodes = {}; + let totalItems = 0; + let hasMoreData = false; + for (const nodeName of nodeNames) { + const nodeData = runData[nodeName]; + if (!Array.isArray(nodeData) || nodeData.length === 0) { + processedNodes[nodeName] = { + itemsInput: 0, + itemsOutput: 0, + status: 'success', + }; + continue; + } + const firstRun = nodeData[0]; + const itemCounts = countItems(nodeData); + totalItems += itemCounts.output; + const nodeResult = { + executionTime: firstRun.executionTime, + itemsInput: itemCounts.input, + itemsOutput: itemCounts.output, + status: 'success', + }; + if (firstRun.error) { + nodeResult.status = 'error'; + nodeResult.error = extractErrorMessage(firstRun.error); + } + if (mode === 'full') { + nodeResult.data = { + output: firstRun.data?.main || [], + metadata: { + totalItems: itemCounts.output, + itemsShown: itemCounts.output, + truncated: false, + }, + }; + if (includeInputData && firstRun.inputData) { + nodeResult.data.input = firstRun.inputData; + } + } + else { + const outputData = firstRun.data?.main || []; + const { truncated, metadata } = truncateItems(outputData, itemsLimit); + if (metadata.truncated) { + hasMoreData = true; + } + nodeResult.data = { + output: truncated, + metadata, + }; + if (includeInputData && firstRun.inputData) { + nodeResult.data.input = firstRun.inputData; + } + } + processedNodes[nodeName] = nodeResult; + } + response.summary = { + totalNodes: Object.keys(runData).length, + executedNodes: nodeNames.length, + totalItems, + hasMoreData, + }; + response.nodes = processedNodes; + if (execution.data?.resultData?.error) { + response.error = execution.data.resultData.error; + } + return response; +} +function processExecution(execution, options = {}) { + if (!options.mode && !options.nodeNames && options.itemsLimit === undefined) { + return execution; + } + return filterExecutionData(execution, options); +} +//# sourceMappingURL=execution-processor.js.map \ No newline at end of file diff --git a/dist/services/execution-processor.js.map b/dist/services/execution-processor.js.map new file mode 100644 index 0000000..0e830d4 --- /dev/null +++ b/dist/services/execution-processor.js.map @@ -0,0 +1 @@ +{"version":3,"file":"execution-processor.js","sourceRoot":"","sources":["../../src/services/execution-processor.ts"],"names":[],"mappings":";;AAsIA,0CA8EC;AAoID,kDA8JC;AAMD,4CAUC;AA9eD,4CAAyC;AAKzC,MAAM,UAAU,GAAG;IACjB,eAAe,EAAE,CAAC;IAClB,mBAAmB,EAAE,EAAE;IACvB,uBAAuB,EAAE,GAAG;IAC5B,mBAAmB,EAAE,EAAE;IACvB,sBAAsB,EAAE,EAAE;IAC1B,wBAAwB,EAAE,GAAG;IAC7B,SAAS,EAAE,CAAC;IACZ,eAAe,EAAE,IAAI;CACb,CAAC;AAKX,SAAS,mBAAmB,CAAC,KAAc;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,IAAI,SAAS,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC5D,OAAO,KAAK,CAAC,OAAO,CAAC;QACvB,CAAC;QACD,IAAI,OAAO,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACxD,OAAO,KAAK,CAAC,KAAK,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC;AAKD,SAAS,gBAAgB,CAAC,IAAa,EAAE,QAAQ,GAAG,UAAU,CAAC,SAAS,EAAE,YAAY,GAAG,CAAC;IACxF,IAAI,YAAY,IAAI,QAAQ,EAAE,CAAC;QAC7B,OAAO,OAAO,IAAI,CAAC;IACrB,CAAC;IAED,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACxC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,MAAM,SAAS,GAA4B,EAAE,CAAC;QAC9C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;gBACpD,SAAS,CAAC,GAAG,CAAC,GAAG,gBAAgB,CAAE,IAAgC,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,YAAY,GAAG,CAAC,CAAC,CAAC;YACxG,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,OAAO,IAAI,CAAC;AACrB,CAAC;AAKD,SAAS,gBAAgB,CAAC,IAAa;IACrC,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,GAAG,UAAU,CAAC,eAAe,CAAC;QACjE,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAM,CAAC,IAAI,CAAC,8BAA8B,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACvD,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAKD,SAAS,UAAU,CAAC,QAAiB;IACnC,MAAM,MAAM,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAEvC,IAAI,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1C,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YACpB,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5B,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;oBAC9B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;wBAC1B,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC;oBACjC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAKD,SAAgB,eAAe,CAAC,SAAoB;IAIlD,MAAM,OAAO,GAAqB;QAChC,UAAU,EAAE,CAAC;QACb,aAAa,EAAE,CAAC;QAChB,eAAe,EAAE,CAAC;QAClB,KAAK,EAAE,EAAE;KACV,CAAC;IAEF,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;QACzC,OAAO;YACL,OAAO;YACP,cAAc,EAAE;gBACd,YAAY,EAAE,IAAI;gBAClB,aAAa,EAAE,SAAS;gBACxB,MAAM,EAAE,6BAA6B;aACtC;SACF,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;IAClD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvC,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC;IAEtC,IAAI,gBAAgB,GAAG,CAAC,CAAC;IACzB,IAAI,gBAAgB,GAAG,CAAC,CAAC;IAEzB,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,UAAU,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QAGxC,IAAI,aAAa,GAA4B,EAAE,CAAC;QAChD,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnD,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC7B,MAAM,SAAS,GAAG,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACjD,IAAI,SAAS,EAAE,CAAC;gBACd,aAAa,GAAG,gBAAgB,CAAC,SAAS,CAA4B,CAAC;YACzE,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAE5C,MAAM,WAAW,GAAgB;YAC/B,MAAM,EAAE,SAAS;YACjB,UAAU;YACV,aAAa;YACb,eAAe,EAAE,QAAQ;SAC1B,CAAC;QAGF,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;oBACd,WAAW,CAAC,MAAM,GAAG,OAAO,CAAC;oBAC7B,WAAW,CAAC,KAAK,GAAG,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;oBACnD,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,WAAW,CAAC;QACtC,OAAO,CAAC,eAAe,IAAI,QAAQ,CAAC;QACpC,OAAO,CAAC,aAAa,EAAE,CAAC;QACxB,gBAAgB,IAAI,UAAU,CAAC,MAAM,CAAC;QACtC,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IACnE,CAAC;IAGD,MAAM,cAAc,GAAG,sBAAsB,CAC3C,OAAO,CAAC,eAAe,EACvB,gBAAgB,EAChB,gBAAgB,CACjB,CAAC;IAEF,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC;AACrC,CAAC;AAKD,SAAS,sBAAsB,CAC7B,WAAmB,EACnB,UAAkB,EAClB,gBAAwB;IAGxB,IAAI,WAAW,IAAI,UAAU,CAAC,uBAAuB,IAAI,UAAU,IAAI,UAAU,CAAC,mBAAmB,EAAE,CAAC;QACtG,OAAO;YACL,YAAY,EAAE,IAAI;YAClB,aAAa,EAAE,MAAM;YACrB,MAAM,EAAE,kBAAkB,WAAW,OAAO,UAAU,mCAAmC;SAC1F,CAAC;IACJ,CAAC;IAGD,IAAI,WAAW,IAAI,UAAU,CAAC,wBAAwB,IAAI,UAAU,IAAI,UAAU,CAAC,sBAAsB,EAAE,CAAC;QAC1G,OAAO;YACL,YAAY,EAAE,KAAK;YACnB,aAAa,EAAE,SAAS;YACxB,mBAAmB,EAAE,CAAC;YACtB,MAAM,EAAE,qBAAqB,WAAW,OAAO,UAAU,oCAAoC;SAC9F,CAAC;IACJ,CAAC;IAGD,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAEpF,OAAO;QACL,YAAY,EAAE,KAAK;QACnB,aAAa,EAAE,UAAU;QACzB,mBAAmB,EAAE,cAAc;QACnC,MAAM,EAAE,kBAAkB,WAAW,OAAO,UAAU,+CAA+C,cAAc,GAAG;KACvH,CAAC;AACJ,CAAC;AAKD,SAAS,aAAa,CACpB,KAAkB,EAClB,KAAa;IAKb,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChD,OAAO;YACL,SAAS,EAAE,KAAK,IAAI,EAAE;YACtB,QAAQ,EAAE;gBACR,UAAU,EAAE,CAAC;gBACb,UAAU,EAAE,CAAC;gBACb,SAAS,EAAE,KAAK;aACjB;SACF,CAAC;IACJ,CAAC;IAED,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC;QAC9B,CAAC;IACH,CAAC;IAGD,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,MAAM,aAAa,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;YACvC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAClD,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,OAAO;YACL,SAAS,EAAE,aAAa;YACxB,QAAQ,EAAE;gBACR,UAAU;gBACV,UAAU,EAAE,CAAC;gBACb,SAAS,EAAE,IAAI;aAChB;SACF,CAAC;IACJ,CAAC;IAGD,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,OAAO;YACL,SAAS,EAAE,KAAK;YAChB,QAAQ,EAAE;gBACR,UAAU;gBACV,UAAU,EAAE,UAAU;gBACtB,SAAS,EAAE,KAAK;aACjB;SACF,CAAC;IACJ,CAAC;IAGD,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACpB,SAAS;QACX,CAAC;QAED,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;YACxB,MAAM;QACR,CAAC;QAED,MAAM,SAAS,GAAG,KAAK,GAAG,UAAU,CAAC;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACrC,UAAU,IAAI,MAAM,CAAC;IACvB,CAAC;IAED,OAAO;QACL,SAAS,EAAE,MAAM;QACjB,QAAQ,EAAE;YACR,UAAU;YACV,UAAU;YACV,SAAS,EAAE,UAAU,GAAG,UAAU;SACnC;KACF,CAAC;AACJ,CAAC;AAKD,SAAgB,mBAAmB,CACjC,SAAoB,EACpB,OAA+B;IAE/B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC;IAGvC,IAAI,UAAU,GAAG,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;QACtB,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YACnB,eAAM,CAAC,IAAI,CAAC,qCAAqC,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;YAC7E,UAAU,GAAG,CAAC,CAAC;QACjB,CAAC;QACD,IAAI,UAAU,GAAG,UAAU,CAAC,eAAe,EAAE,CAAC;YAC5C,eAAM,CAAC,IAAI,CAAC,wBAAwB,UAAU,CAAC,eAAe,EAAE,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;YAC5F,UAAU,GAAG,UAAU,CAAC,eAAe,CAAC;QAC1C,CAAC;IACH,CAAC;IAED,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,KAAK,CAAC;IAC3D,MAAM,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC;IAG1C,MAAM,QAAQ,GAAG,SAAS,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS;QACzD,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE;QACnF,CAAC,CAAC,SAAS,CAAC;IAEd,MAAM,QAAQ,GAA8B;QAC1C,EAAE,EAAE,SAAS,CAAC,EAAE;QAChB,UAAU,EAAE,SAAS,CAAC,UAAU;QAChC,MAAM,EAAE,SAAS,CAAC,MAAM;QACxB,IAAI;QACJ,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,QAAQ;QACR,QAAQ,EAAE,SAAS,CAAC,QAAQ;KAC7B,CAAC;IAGF,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;QAC/D,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAC;QAC3B,QAAQ,CAAC,cAAc,GAAG,cAAc,CAAC;QACzC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAGD,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;QACzC,QAAQ,CAAC,OAAO,GAAG;YACjB,UAAU,EAAE,CAAC;YACb,aAAa,EAAE,CAAC;YAChB,UAAU,EAAE,CAAC;YACb,WAAW,EAAE,KAAK;SACnB,CAAC;QACF,QAAQ,CAAC,KAAK,GAAG,EAAE,CAAC;QAEpB,IAAI,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;YACtC,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QACnD,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;IAClD,IAAI,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAGrC,IAAI,eAAe,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IACvE,CAAC;IAGD,MAAM,cAAc,GAAqC,EAAE,CAAC;IAC5D,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,WAAW,GAAG,KAAK,CAAC;IAExB,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QAEnC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtD,cAAc,CAAC,QAAQ,CAAC,GAAG;gBACzB,UAAU,EAAE,CAAC;gBACb,WAAW,EAAE,CAAC;gBACd,MAAM,EAAE,SAAS;aAClB,CAAC;YACF,SAAS;QACX,CAAC;QAGD,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,UAAU,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QACxC,UAAU,IAAI,UAAU,CAAC,MAAM,CAAC;QAEhC,MAAM,UAAU,GAAqB;YACnC,aAAa,EAAE,QAAQ,CAAC,aAAa;YACrC,UAAU,EAAE,UAAU,CAAC,KAAK;YAC5B,WAAW,EAAE,UAAU,CAAC,MAAM;YAC9B,MAAM,EAAE,SAAS;SAClB,CAAC;QAGF,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnB,UAAU,CAAC,MAAM,GAAG,OAAO,CAAC;YAC5B,UAAU,CAAC,KAAK,GAAG,mBAAmB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACzD,CAAC;QAGD,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACpB,UAAU,CAAC,IAAI,GAAG;gBAChB,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE;gBACjC,QAAQ,EAAE;oBACR,UAAU,EAAE,UAAU,CAAC,MAAM;oBAC7B,UAAU,EAAE,UAAU,CAAC,MAAM;oBAC7B,SAAS,EAAE,KAAK;iBACjB;aACF,CAAC;YAEF,IAAI,gBAAgB,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;gBAC3C,UAAU,CAAC,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC;YAC7C,CAAC;QACH,CAAC;aAAM,CAAC;YAEN,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;YAC7C,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YAEtE,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;gBACvB,WAAW,GAAG,IAAI,CAAC;YACrB,CAAC;YAED,UAAU,CAAC,IAAI,GAAG;gBAChB,MAAM,EAAE,SAAS;gBACjB,QAAQ;aACT,CAAC;YAEF,IAAI,gBAAgB,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;gBAC3C,UAAU,CAAC,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC;YAC7C,CAAC;QACH,CAAC;QAED,cAAc,CAAC,QAAQ,CAAC,GAAG,UAAU,CAAC;IACxC,CAAC;IAGD,QAAQ,CAAC,OAAO,GAAG;QACjB,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM;QACvC,aAAa,EAAE,SAAS,CAAC,MAAM;QAC/B,UAAU;QACV,WAAW;KACZ,CAAC;IAEF,QAAQ,CAAC,KAAK,GAAG,cAAc,CAAC;IAGhC,IAAI,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;QACtC,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;IACnD,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAMD,SAAgB,gBAAgB,CAC9B,SAAoB,EACpB,UAAkC,EAAE;IAGpC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QAC5E,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,mBAAmB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AACjD,CAAC"} \ No newline at end of file diff --git a/dist/services/expression-format-validator.d.ts b/dist/services/expression-format-validator.d.ts new file mode 100644 index 0000000..4a6a711 --- /dev/null +++ b/dist/services/expression-format-validator.d.ts @@ -0,0 +1,33 @@ +export interface ExpressionFormatIssue { + fieldPath: string; + currentValue: any; + correctedValue: any; + issueType: 'missing-prefix' | 'needs-resource-locator' | 'invalid-rl-structure' | 'mixed-format'; + explanation: string; + severity: 'error' | 'warning'; + confidence?: number; +} +export interface ResourceLocatorField { + __rl: true; + value: string; + mode: string; +} +export interface ValidationContext { + nodeType: string; + nodeName: string; + nodeId?: string; +} +export declare class ExpressionFormatValidator { + private static readonly VALID_RL_MODES; + private static readonly MAX_RECURSION_DEPTH; + private static readonly EXPRESSION_PREFIX; + private static readonly RESOURCE_LOCATOR_FIELDS; + private static shouldUseResourceLocator; + private static isResourceLocator; + private static generateCorrection; + static validateAndFix(value: any, fieldPath: string, context: ValidationContext): ExpressionFormatIssue | null; + static validateNodeParameters(parameters: any, context: ValidationContext): ExpressionFormatIssue[]; + private static validateRecursive; + static formatErrorMessage(issue: ExpressionFormatIssue, context: ValidationContext): string; +} +//# sourceMappingURL=expression-format-validator.d.ts.map \ No newline at end of file diff --git a/dist/services/expression-format-validator.d.ts.map b/dist/services/expression-format-validator.d.ts.map new file mode 100644 index 0000000..34ea44f --- /dev/null +++ b/dist/services/expression-format-validator.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"expression-format-validator.d.ts","sourceRoot":"","sources":["../../src/services/expression-format-validator.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,GAAG,CAAC;IAClB,cAAc,EAAE,GAAG,CAAC;IACpB,SAAS,EAAE,gBAAgB,GAAG,wBAAwB,GAAG,sBAAsB,GAAG,cAAc,CAAC;IACjG,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,yBAAyB;IACpC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAwD;IAC9F,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAO;IAClD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAO;IAMhD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAmB7C;IAMF,OAAO,CAAC,MAAM,CAAC,wBAAwB;IAoBvC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAoBhC,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAsBjC,MAAM,CAAC,cAAc,CACnB,KAAK,EAAE,GAAG,EACV,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,iBAAiB,GACzB,qBAAqB,GAAG,IAAI;IAgH/B,MAAM,CAAC,sBAAsB,CAC3B,UAAU,EAAE,GAAG,EACf,OAAO,EAAE,iBAAiB,GACzB,qBAAqB,EAAE;IAY1B,OAAO,CAAC,MAAM,CAAC,iBAAiB;IA0DhC,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,qBAAqB,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM;CAoB5F"} \ No newline at end of file diff --git a/dist/services/expression-format-validator.js b/dist/services/expression-format-validator.js new file mode 100644 index 0000000..84d0fa8 --- /dev/null +++ b/dist/services/expression-format-validator.js @@ -0,0 +1,209 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ExpressionFormatValidator = void 0; +const universal_expression_validator_1 = require("./universal-expression-validator"); +const confidence_scorer_1 = require("./confidence-scorer"); +class ExpressionFormatValidator { + static shouldUseResourceLocator(fieldName, nodeType) { + const nodeBase = nodeType.split('.').pop()?.toLowerCase() || ''; + for (const [pattern, fields] of Object.entries(this.RESOURCE_LOCATOR_FIELDS)) { + if ((nodeBase === pattern || nodeBase.startsWith(`${pattern}-`)) && fields.includes(fieldName)) { + return true; + } + } + return false; + } + static isResourceLocator(value) { + if (typeof value !== 'object' || value === null || value.__rl !== true) { + return false; + } + if (!('value' in value) || !('mode' in value)) { + return false; + } + if (typeof value.mode !== 'string' || !this.VALID_RL_MODES.includes(value.mode)) { + return false; + } + return true; + } + static generateCorrection(value, needsResourceLocator) { + const correctedValue = value.startsWith(this.EXPRESSION_PREFIX) + ? value + : `${this.EXPRESSION_PREFIX}${value}`; + if (needsResourceLocator) { + return { + __rl: true, + value: correctedValue, + mode: 'expression' + }; + } + return correctedValue; + } + static validateAndFix(value, fieldPath, context) { + if (typeof value !== 'string' && !this.isResourceLocator(value)) { + return null; + } + if (this.isResourceLocator(value)) { + const universalResults = universal_expression_validator_1.UniversalExpressionValidator.validate(value.value); + const invalidResult = universalResults.find(r => !r.isValid && r.needsPrefix); + if (invalidResult) { + return { + fieldPath, + currentValue: value, + correctedValue: { + ...value, + value: universal_expression_validator_1.UniversalExpressionValidator.getCorrectedValue(value.value) + }, + issueType: 'missing-prefix', + explanation: `Resource locator value: ${invalidResult.explanation}`, + severity: 'error' + }; + } + return null; + } + const universalResults = universal_expression_validator_1.UniversalExpressionValidator.validate(value); + const invalidResults = universalResults.filter(r => !r.isValid); + if (invalidResults.length > 0) { + const prefixIssue = invalidResults.find(r => r.needsPrefix); + if (prefixIssue) { + const fieldName = fieldPath.split('.').pop() || ''; + const confidenceScore = confidence_scorer_1.ConfidenceScorer.scoreResourceLocatorRecommendation(fieldName, context.nodeType, value); + if (confidenceScore.value >= 0.8) { + return { + fieldPath, + currentValue: value, + correctedValue: this.generateCorrection(value, true), + issueType: 'needs-resource-locator', + explanation: `Field '${fieldName}' contains expression but needs resource locator format with '${this.EXPRESSION_PREFIX}' prefix for evaluation.`, + severity: 'error', + confidence: confidenceScore.value + }; + } + else { + return { + fieldPath, + currentValue: value, + correctedValue: universal_expression_validator_1.UniversalExpressionValidator.getCorrectedValue(value), + issueType: 'missing-prefix', + explanation: prefixIssue.explanation, + severity: 'error' + }; + } + } + const firstIssue = invalidResults[0]; + return { + fieldPath, + currentValue: value, + correctedValue: value, + issueType: 'mixed-format', + explanation: firstIssue.explanation, + severity: 'error' + }; + } + const hasExpression = universalResults.some(r => r.hasExpression); + if (hasExpression && typeof value === 'string') { + const fieldName = fieldPath.split('.').pop() || ''; + const confidenceScore = confidence_scorer_1.ConfidenceScorer.scoreResourceLocatorRecommendation(fieldName, context.nodeType, value); + if (confidenceScore.value >= 0.5) { + return { + fieldPath, + currentValue: value, + correctedValue: this.generateCorrection(value, true), + issueType: 'needs-resource-locator', + explanation: `Field '${fieldName}' should use resource locator format for better compatibility. (Confidence: ${Math.round(confidenceScore.value * 100)}%)`, + severity: 'warning', + confidence: confidenceScore.value + }; + } + } + return null; + } + static validateNodeParameters(parameters, context) { + const issues = []; + const visited = new WeakSet(); + this.validateRecursive(parameters, '', context, issues, visited); + return issues; + } + static validateRecursive(obj, path, context, issues, visited, depth = 0) { + if (depth > this.MAX_RECURSION_DEPTH) { + issues.push({ + fieldPath: path, + currentValue: obj, + correctedValue: obj, + issueType: 'mixed-format', + explanation: `Maximum recursion depth (${this.MAX_RECURSION_DEPTH}) exceeded. Object may have circular references or be too deeply nested.`, + severity: 'warning' + }); + return; + } + if (obj && typeof obj === 'object') { + if (visited.has(obj)) + return; + visited.add(obj); + } + const issue = this.validateAndFix(obj, path, context); + if (issue) { + issues.push(issue); + } + if (Array.isArray(obj)) { + obj.forEach((item, index) => { + const newPath = path ? `${path}[${index}]` : `[${index}]`; + this.validateRecursive(item, newPath, context, issues, visited, depth + 1); + }); + } + else if (obj && typeof obj === 'object') { + if (this.isResourceLocator(obj)) { + return; + } + Object.entries(obj).forEach(([key, value]) => { + if (key.startsWith('__')) + return; + const newPath = path ? `${path}.${key}` : key; + this.validateRecursive(value, newPath, context, issues, visited, depth + 1); + }); + } + } + static formatErrorMessage(issue, context) { + let message = `Expression format ${issue.severity} in node '${context.nodeName}':\n`; + message += `Field '${issue.fieldPath}' ${issue.explanation}\n\n`; + message += `Current (incorrect):\n`; + if (typeof issue.currentValue === 'string') { + message += `"${issue.fieldPath}": "${issue.currentValue}"\n\n`; + } + else { + message += `"${issue.fieldPath}": ${JSON.stringify(issue.currentValue, null, 2)}\n\n`; + } + message += `Fixed (correct):\n`; + if (typeof issue.correctedValue === 'string') { + message += `"${issue.fieldPath}": "${issue.correctedValue}"`; + } + else { + message += `"${issue.fieldPath}": ${JSON.stringify(issue.correctedValue, null, 2)}`; + } + return message; + } +} +exports.ExpressionFormatValidator = ExpressionFormatValidator; +ExpressionFormatValidator.VALID_RL_MODES = ['id', 'url', 'expression', 'name', 'list']; +ExpressionFormatValidator.MAX_RECURSION_DEPTH = 100; +ExpressionFormatValidator.EXPRESSION_PREFIX = '='; +ExpressionFormatValidator.RESOURCE_LOCATOR_FIELDS = { + 'github': ['owner', 'repository', 'user', 'organization'], + 'googleSheets': ['sheetId', 'documentId', 'spreadsheetId', 'rangeDefinition'], + 'googleDrive': ['fileId', 'folderId', 'driveId'], + 'slack': ['channel', 'user', 'channelId', 'userId', 'teamId'], + 'notion': ['databaseId', 'pageId', 'blockId'], + 'airtable': ['baseId', 'tableId', 'viewId'], + 'monday': ['boardId', 'itemId', 'groupId'], + 'hubspot': ['contactId', 'companyId', 'dealId'], + 'salesforce': ['recordId', 'objectName'], + 'jira': ['projectKey', 'issueKey', 'boardId'], + 'gitlab': ['projectId', 'mergeRequestId', 'issueId'], + 'mysql': ['table', 'database', 'schema'], + 'postgres': ['table', 'database', 'schema'], + 'mongodb': ['collection', 'database'], + 's3': ['bucketName', 'key', 'fileName'], + 'ftp': ['path', 'fileName'], + 'ssh': ['path', 'fileName'], + 'redis': ['key'], +}; +//# sourceMappingURL=expression-format-validator.js.map \ No newline at end of file diff --git a/dist/services/expression-format-validator.js.map b/dist/services/expression-format-validator.js.map new file mode 100644 index 0000000..9f600f5 --- /dev/null +++ b/dist/services/expression-format-validator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"expression-format-validator.js","sourceRoot":"","sources":["../../src/services/expression-format-validator.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/expression-validator.d.ts b/dist/services/expression-validator.d.ts new file mode 100644 index 0000000..c482ebd --- /dev/null +++ b/dist/services/expression-validator.d.ts @@ -0,0 +1,27 @@ +interface ExpressionValidationResult { + valid: boolean; + errors: string[]; + warnings: string[]; + usedVariables: Set; + usedNodes: Set; +} +interface ExpressionContext { + availableNodes: string[]; + currentNodeName?: string; + isInLoop?: boolean; + hasInputData?: boolean; +} +export declare class ExpressionValidator { + private static readonly EXPRESSION_PATTERN; + private static readonly VARIABLE_PATTERNS; + static validateExpression(expression: string, context: ExpressionContext): ExpressionValidationResult; + private static checkSyntaxErrors; + private static extractExpressions; + private static validateSingleExpression; + private static checkCommonMistakes; + private static checkNodeReferences; + static validateNodeExpressions(parameters: any, context: ExpressionContext): ExpressionValidationResult; + private static validateParametersRecursive; +} +export {}; +//# sourceMappingURL=expression-validator.d.ts.map \ No newline at end of file diff --git a/dist/services/expression-validator.d.ts.map b/dist/services/expression-validator.d.ts.map new file mode 100644 index 0000000..b887791 --- /dev/null +++ b/dist/services/expression-validator.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"expression-validator.d.ts","sourceRoot":"","sources":["../../src/services/expression-validator.ts"],"names":[],"mappings":"AAKA,UAAU,0BAA0B;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACxB;AAED,UAAU,iBAAiB;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,qBAAa,mBAAmB;IAE9B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAyB;IACnE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAcvC;IAKF,MAAM,CAAC,kBAAkB,CACvB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,iBAAiB,GACzB,0BAA0B;IA2C7B,OAAO,CAAC,MAAM,CAAC,iBAAiB;IA+BhC,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAcjC,OAAO,CAAC,MAAM,CAAC,wBAAwB;IAwEvC,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAkDlC,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAgBlC,MAAM,CAAC,uBAAuB,CAC5B,UAAU,EAAE,GAAG,EACf,OAAO,EAAE,iBAAiB,GACzB,0BAA0B;IAmB7B,OAAO,CAAC,MAAM,CAAC,2BAA2B;CAiD3C"} \ No newline at end of file diff --git a/dist/services/expression-validator.js b/dist/services/expression-validator.js new file mode 100644 index 0000000..049bff5 --- /dev/null +++ b/dist/services/expression-validator.js @@ -0,0 +1,187 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ExpressionValidator = void 0; +class ExpressionValidator { + static validateExpression(expression, context) { + const result = { + valid: true, + errors: [], + warnings: [], + usedVariables: new Set(), + usedNodes: new Set(), + }; + if (!expression) { + return result; + } + if (!context) { + result.valid = false; + result.errors.push('Validation context is required'); + return result; + } + const syntaxErrors = this.checkSyntaxErrors(expression); + result.errors.push(...syntaxErrors); + const expressions = this.extractExpressions(expression); + for (const expr of expressions) { + this.validateSingleExpression(expr, context, result); + } + this.checkNodeReferences(result, context); + result.valid = result.errors.length === 0; + return result; + } + static checkSyntaxErrors(expression) { + const errors = []; + const openBrackets = (expression.match(/\{\{/g) || []).length; + const closeBrackets = (expression.match(/\}\}/g) || []).length; + if (openBrackets !== closeBrackets) { + errors.push('Unmatched expression brackets {{ }}'); + } + const nestedPattern = /\{\{[^}]*\{\{/; + if (nestedPattern.test(expression)) { + errors.push('Nested expressions are not supported (expression inside another expression)'); + } + const emptyExpressionPattern = /\{\{\s*\}\}/; + if (emptyExpressionPattern.test(expression)) { + errors.push('Empty expression found'); + } + return errors; + } + static extractExpressions(text) { + const expressions = []; + let match; + while ((match = this.EXPRESSION_PATTERN.exec(text)) !== null) { + expressions.push(match[1].trim()); + } + return expressions; + } + static validateSingleExpression(expr, context, result) { + let match; + const jsonPattern = new RegExp(this.VARIABLE_PATTERNS.json.source, this.VARIABLE_PATTERNS.json.flags); + while ((match = jsonPattern.exec(expr)) !== null) { + result.usedVariables.add('$json'); + if (!context.hasInputData && !context.isInLoop) { + result.warnings.push('Using $json but node might not have input data'); + } + const fullMatch = match[0]; + if (fullMatch.includes('.invalid') || fullMatch.includes('.undefined') || + fullMatch.includes('.null') || fullMatch.includes('.test')) { + result.warnings.push(`Property access '${fullMatch}' looks suspicious - verify this property exists in your data`); + } + } + const nodePattern = new RegExp(this.VARIABLE_PATTERNS.node.source, this.VARIABLE_PATTERNS.node.flags); + while ((match = nodePattern.exec(expr)) !== null) { + const nodeName = match[1]; + result.usedNodes.add(nodeName); + result.usedVariables.add('$node'); + } + const inputPattern = new RegExp(this.VARIABLE_PATTERNS.input.source, this.VARIABLE_PATTERNS.input.flags); + while ((match = inputPattern.exec(expr)) !== null) { + result.usedVariables.add('$input'); + if (!context.hasInputData) { + result.warnings.push('$input is only available when the node has input data'); + } + } + const itemsPattern = new RegExp(this.VARIABLE_PATTERNS.items.source, this.VARIABLE_PATTERNS.items.flags); + while ((match = itemsPattern.exec(expr)) !== null) { + const nodeName = match[1]; + result.usedNodes.add(nodeName); + result.usedVariables.add('$items'); + } + for (const [varName, pattern] of Object.entries(this.VARIABLE_PATTERNS)) { + if (['json', 'node', 'input', 'items'].includes(varName)) + continue; + const testPattern = new RegExp(pattern.source, pattern.flags); + if (testPattern.test(expr)) { + result.usedVariables.add(`$${varName}`); + } + } + this.checkCommonMistakes(expr, result); + } + static checkCommonMistakes(expr, result) { + const missingPrefixPattern = /(? { + result.errors.push(path ? `${path}: ${error}` : error); + }); + validation.warnings.forEach(warning => { + result.warnings.push(path ? `${path}: ${warning}` : warning); + }); + validation.usedVariables.forEach(v => result.usedVariables.add(v)); + validation.usedNodes.forEach(n => result.usedNodes.add(n)); + } + } + else if (Array.isArray(obj)) { + obj.forEach((item, index) => { + this.validateParametersRecursive(item, context, result, `${path}[${index}]`, visited); + }); + } + else if (obj && typeof obj === 'object') { + Object.entries(obj).forEach(([key, value]) => { + const newPath = path ? `${path}.${key}` : key; + this.validateParametersRecursive(value, context, result, newPath, visited); + }); + } + } +} +exports.ExpressionValidator = ExpressionValidator; +ExpressionValidator.EXPRESSION_PATTERN = /\{\{([\s\S]+?)\}\}/g; +ExpressionValidator.VARIABLE_PATTERNS = { + json: /\$json(\.[a-zA-Z_][\w]*|\["[^"]+"\]|\['[^']+'\]|\[\d+\])*/g, + node: /\$node\["([^"]+)"\]\.json/g, + input: /\$input\.item(\.[a-zA-Z_][\w]*|\["[^"]+"\]|\['[^']+'\]|\[\d+\])*/g, + items: /\$items\("([^"]+)"(?:,\s*(-?\d+))?\)/g, + parameter: /\$parameter\["([^"]+)"\]/g, + env: /\$env\.([a-zA-Z_][\w]*)/g, + workflow: /\$workflow\.(id|name|active)/g, + execution: /\$execution\.(id|mode|resumeUrl)/g, + prevNode: /\$prevNode\.(name|outputIndex|runIndex)/g, + itemIndex: /\$itemIndex/g, + runIndex: /\$runIndex/g, + now: /\$now/g, + today: /\$today/g, +}; +//# sourceMappingURL=expression-validator.js.map \ No newline at end of file diff --git a/dist/services/expression-validator.js.map b/dist/services/expression-validator.js.map new file mode 100644 index 0000000..85381b9 --- /dev/null +++ b/dist/services/expression-validator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"expression-validator.js","sourceRoot":"","sources":["../../src/services/expression-validator.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/n8n-api-client.d.ts b/dist/services/n8n-api-client.d.ts new file mode 100644 index 0000000..1041411 --- /dev/null +++ b/dist/services/n8n-api-client.d.ts @@ -0,0 +1,47 @@ +import { Workflow, WorkflowListParams, WorkflowListResponse, Execution, ExecutionListParams, ExecutionListResponse, Credential, CredentialListParams, CredentialListResponse, Tag, TagListParams, TagListResponse, HealthCheckResponse, N8nVersionInfo, Variable, WebhookRequest, SourceControlStatus, SourceControlPullResult, SourceControlPushResult } from '../types/n8n-api'; +export interface N8nApiClientConfig { + baseUrl: string; + apiKey: string; + timeout?: number; + maxRetries?: number; +} +export declare class N8nApiClient { + private client; + private maxRetries; + private baseUrl; + private versionInfo; + private versionFetched; + constructor(config: N8nApiClientConfig); + getVersion(): Promise; + getCachedVersionInfo(): N8nVersionInfo | null; + healthCheck(): Promise; + createWorkflow(workflow: Partial): Promise; + getWorkflow(id: string): Promise; + updateWorkflow(id: string, workflow: Partial): Promise; + deleteWorkflow(id: string): Promise; + activateWorkflow(id: string): Promise; + deactivateWorkflow(id: string): Promise; + listWorkflows(params?: WorkflowListParams): Promise; + getExecution(id: string, includeData?: boolean): Promise; + listExecutions(params?: ExecutionListParams): Promise; + deleteExecution(id: string): Promise; + triggerWebhook(request: WebhookRequest): Promise; + listCredentials(params?: CredentialListParams): Promise; + getCredential(id: string): Promise; + createCredential(credential: Partial): Promise; + updateCredential(id: string, credential: Partial): Promise; + deleteCredential(id: string): Promise; + listTags(params?: TagListParams): Promise; + createTag(tag: Partial): Promise; + updateTag(id: string, tag: Partial): Promise; + deleteTag(id: string): Promise; + getSourceControlStatus(): Promise; + pullSourceControl(force?: boolean): Promise; + pushSourceControl(message: string, fileNames?: string[]): Promise; + getVariables(): Promise; + createVariable(variable: Partial): Promise; + updateVariable(id: string, variable: Partial): Promise; + deleteVariable(id: string): Promise; + private validateListResponse; +} +//# sourceMappingURL=n8n-api-client.d.ts.map \ No newline at end of file diff --git a/dist/services/n8n-api-client.d.ts.map b/dist/services/n8n-api-client.d.ts.map new file mode 100644 index 0000000..df33f27 --- /dev/null +++ b/dist/services/n8n-api-client.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-api-client.d.ts","sourceRoot":"","sources":["../../src/services/n8n-api-client.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/n8n-api-client.js b/dist/services/n8n-api-client.js new file mode 100644 index 0000000..1a85a49 --- /dev/null +++ b/dist/services/n8n-api-client.js @@ -0,0 +1,445 @@ +"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; + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.N8nApiClient = void 0; +const axios_1 = __importDefault(require("axios")); +const logger_1 = require("../utils/logger"); +const n8n_errors_1 = require("../utils/n8n-errors"); +const n8n_validation_1 = require("./n8n-validation"); +const n8n_version_1 = require("./n8n-version"); +class N8nApiClient { + constructor(config) { + this.versionInfo = null; + this.versionFetched = false; + const { baseUrl, apiKey, timeout = 30000, maxRetries = 3 } = config; + this.maxRetries = maxRetries; + this.baseUrl = baseUrl; + const apiUrl = baseUrl.endsWith('/api/v1') + ? baseUrl + : `${baseUrl.replace(/\/$/, '')}/api/v1`; + this.client = axios_1.default.create({ + baseURL: apiUrl, + timeout, + headers: { + 'X-N8N-API-KEY': apiKey, + 'Content-Type': 'application/json', + }, + }); + this.client.interceptors.request.use((config) => { + logger_1.logger.debug(`n8n API Request: ${config.method?.toUpperCase()} ${config.url}`, { + params: config.params, + data: config.data, + }); + return config; + }, (error) => { + logger_1.logger.error('n8n API Request Error:', error); + return Promise.reject(error); + }); + this.client.interceptors.response.use((response) => { + logger_1.logger.debug(`n8n API Response: ${response.status} ${response.config.url}`); + return response; + }, (error) => { + const n8nError = (0, n8n_errors_1.handleN8nApiError)(error); + (0, n8n_errors_1.logN8nError)(n8nError, 'n8n API Response'); + return Promise.reject(n8nError); + }); + } + async getVersion() { + if (!this.versionFetched) { + this.versionInfo = (0, n8n_version_1.getCachedVersion)(this.baseUrl); + if (!this.versionInfo) { + this.versionInfo = await (0, n8n_version_1.fetchN8nVersion)(this.baseUrl); + } + this.versionFetched = true; + } + return this.versionInfo; + } + getCachedVersionInfo() { + return this.versionInfo; + } + async healthCheck() { + try { + const baseUrl = this.client.defaults.baseURL || ''; + const healthzUrl = baseUrl.replace(/\/api\/v\d+\/?$/, '') + '/healthz'; + const response = await axios_1.default.get(healthzUrl, { + timeout: 5000, + validateStatus: (status) => status < 500 + }); + const versionInfo = await this.getVersion(); + if (response.status === 200 && response.data?.status === 'ok') { + return { + status: 'ok', + n8nVersion: versionInfo?.version, + features: {} + }; + } + throw new Error('healthz endpoint not available'); + } + catch (error) { + try { + await this.client.get('/workflows', { params: { limit: 1 } }); + const versionInfo = await this.getVersion(); + return { + status: 'ok', + n8nVersion: versionInfo?.version, + features: {} + }; + } + catch (fallbackError) { + throw (0, n8n_errors_1.handleN8nApiError)(fallbackError); + } + } + } + async createWorkflow(workflow) { + try { + const cleanedWorkflow = (0, n8n_validation_1.cleanWorkflowForCreate)(workflow); + const response = await this.client.post('/workflows', cleanedWorkflow); + return response.data; + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async getWorkflow(id) { + try { + const response = await this.client.get(`/workflows/${id}`); + return response.data; + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async updateWorkflow(id, workflow) { + try { + const cleanedWorkflow = (0, n8n_validation_1.cleanWorkflowForUpdate)(workflow); + const versionInfo = await this.getVersion(); + if (versionInfo) { + logger_1.logger.debug(`Updating workflow with n8n version ${versionInfo.version}`); + cleanedWorkflow.settings = (0, n8n_version_1.cleanSettingsForVersion)(cleanedWorkflow.settings, versionInfo); + } + else { + logger_1.logger.warn('Could not determine n8n version, sending all known settings properties'); + } + try { + const response = await this.client.put(`/workflows/${id}`, cleanedWorkflow); + return response.data; + } + catch (putError) { + if (putError.response?.status === 405) { + logger_1.logger.debug('PUT method not supported, falling back to PATCH'); + const response = await this.client.patch(`/workflows/${id}`, cleanedWorkflow); + return response.data; + } + throw putError; + } + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async deleteWorkflow(id) { + try { + const response = await this.client.delete(`/workflows/${id}`); + return response.data; + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async activateWorkflow(id) { + try { + const response = await this.client.post(`/workflows/${id}/activate`); + return response.data; + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async deactivateWorkflow(id) { + try { + const response = await this.client.post(`/workflows/${id}/deactivate`); + return response.data; + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async listWorkflows(params = {}) { + try { + const response = await this.client.get('/workflows', { params }); + return this.validateListResponse(response.data, 'workflows'); + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async getExecution(id, includeData = false) { + try { + const response = await this.client.get(`/executions/${id}`, { + params: { includeData }, + }); + return response.data; + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async listExecutions(params = {}) { + try { + const response = await this.client.get('/executions', { params }); + return this.validateListResponse(response.data, 'executions'); + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async deleteExecution(id) { + try { + await this.client.delete(`/executions/${id}`); + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async triggerWebhook(request) { + try { + const { webhookUrl, httpMethod, data, headers, waitForResponse = true } = request; + const { SSRFProtection } = await Promise.resolve().then(() => __importStar(require('../utils/ssrf-protection'))); + const validation = await SSRFProtection.validateWebhookUrl(webhookUrl); + if (!validation.valid) { + throw new Error(`SSRF protection: ${validation.reason}`); + } + const url = new URL(webhookUrl); + const webhookPath = url.pathname; + const config = { + method: httpMethod, + url: webhookPath, + headers: { + ...headers, + 'X-N8N-API-KEY': undefined, + }, + data: httpMethod !== 'GET' ? data : undefined, + params: httpMethod === 'GET' ? data : undefined, + timeout: waitForResponse ? 120000 : 30000, + }; + const webhookClient = axios_1.default.create({ + baseURL: new URL('/', webhookUrl).toString(), + validateStatus: (status) => status < 500, + }); + const response = await webhookClient.request(config); + return { + status: response.status, + statusText: response.statusText, + data: response.data, + headers: response.headers, + }; + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async listCredentials(params = {}) { + try { + const response = await this.client.get('/credentials', { params }); + return this.validateListResponse(response.data, 'credentials'); + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async getCredential(id) { + try { + const response = await this.client.get(`/credentials/${id}`); + return response.data; + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async createCredential(credential) { + try { + const response = await this.client.post('/credentials', credential); + return response.data; + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async updateCredential(id, credential) { + try { + const response = await this.client.patch(`/credentials/${id}`, credential); + return response.data; + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async deleteCredential(id) { + try { + await this.client.delete(`/credentials/${id}`); + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async listTags(params = {}) { + try { + const response = await this.client.get('/tags', { params }); + return this.validateListResponse(response.data, 'tags'); + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async createTag(tag) { + try { + const response = await this.client.post('/tags', tag); + return response.data; + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async updateTag(id, tag) { + try { + const response = await this.client.patch(`/tags/${id}`, tag); + return response.data; + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async deleteTag(id) { + try { + await this.client.delete(`/tags/${id}`); + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async getSourceControlStatus() { + try { + const response = await this.client.get('/source-control/status'); + return response.data; + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async pullSourceControl(force = false) { + try { + const response = await this.client.post('/source-control/pull', { force }); + return response.data; + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async pushSourceControl(message, fileNames) { + try { + const response = await this.client.post('/source-control/push', { + message, + fileNames, + }); + return response.data; + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async getVariables() { + try { + const response = await this.client.get('/variables'); + return response.data.data || []; + } + catch (error) { + logger_1.logger.warn('Variables API not available, returning empty array'); + return []; + } + } + async createVariable(variable) { + try { + const response = await this.client.post('/variables', variable); + return response.data; + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async updateVariable(id, variable) { + try { + const response = await this.client.patch(`/variables/${id}`, variable); + return response.data; + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + async deleteVariable(id) { + try { + await this.client.delete(`/variables/${id}`); + } + catch (error) { + throw (0, n8n_errors_1.handleN8nApiError)(error); + } + } + validateListResponse(responseData, resourceType) { + if (!responseData || typeof responseData !== 'object') { + throw new Error(`Invalid response from n8n API for ${resourceType}: response is not an object`); + } + if (Array.isArray(responseData)) { + logger_1.logger.warn(`n8n API returned array directly instead of {data, nextCursor} object for ${resourceType}. ` + + 'Wrapping in expected format for backwards compatibility.'); + return { + data: responseData, + nextCursor: null + }; + } + if (!Array.isArray(responseData.data)) { + const keys = Object.keys(responseData).slice(0, 5); + const keysPreview = keys.length < Object.keys(responseData).length + ? `${keys.join(', ')}...` + : keys.join(', '); + throw new Error(`Invalid response from n8n API for ${resourceType}: expected {data: [], nextCursor?: string}, ` + + `got object with keys: [${keysPreview}]`); + } + return responseData; + } +} +exports.N8nApiClient = N8nApiClient; +//# sourceMappingURL=n8n-api-client.js.map \ No newline at end of file diff --git a/dist/services/n8n-api-client.js.map b/dist/services/n8n-api-client.js.map new file mode 100644 index 0000000..e2dbfee --- /dev/null +++ b/dist/services/n8n-api-client.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-api-client.js","sourceRoot":"","sources":["../../src/services/n8n-api-client.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/n8n-validation.d.ts b/dist/services/n8n-validation.d.ts new file mode 100644 index 0000000..c5eb889 --- /dev/null +++ b/dist/services/n8n-validation.d.ts @@ -0,0 +1,273 @@ +import { z } from 'zod'; +import { WorkflowNode, WorkflowConnection, Workflow } from '../types/n8n-api'; +export declare const workflowNodeSchema: z.ZodObject<{ + id: z.ZodString; + name: z.ZodString; + type: z.ZodString; + typeVersion: z.ZodNumber; + position: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>; + parameters: z.ZodRecord; + credentials: z.ZodOptional>; + disabled: z.ZodOptional; + notes: z.ZodOptional; + notesInFlow: z.ZodOptional; + continueOnFail: z.ZodOptional; + retryOnFail: z.ZodOptional; + maxTries: z.ZodOptional; + waitBetweenTries: z.ZodOptional; + alwaysOutputData: z.ZodOptional; + executeOnce: z.ZodOptional; +}, "strip", z.ZodTypeAny, { + type: string; + id: string; + name: string; + typeVersion: number; + position: [number, number]; + parameters: Record; + credentials?: Record | undefined; + retryOnFail?: boolean | undefined; + maxTries?: number | undefined; + waitBetweenTries?: number | undefined; + alwaysOutputData?: boolean | undefined; + continueOnFail?: boolean | undefined; + executeOnce?: boolean | undefined; + disabled?: boolean | undefined; + notes?: string | undefined; + notesInFlow?: boolean | undefined; +}, { + type: string; + id: string; + name: string; + typeVersion: number; + position: [number, number]; + parameters: Record; + credentials?: Record | undefined; + retryOnFail?: boolean | undefined; + maxTries?: number | undefined; + waitBetweenTries?: number | undefined; + alwaysOutputData?: boolean | undefined; + continueOnFail?: boolean | undefined; + executeOnce?: boolean | undefined; + disabled?: boolean | undefined; + notes?: string | undefined; + notesInFlow?: boolean | undefined; +}>; +export declare const workflowConnectionSchema: z.ZodRecord, "many">, "many">>; + error: z.ZodOptional, "many">, "many">>; + ai_tool: z.ZodOptional, "many">, "many">>; + ai_languageModel: z.ZodOptional, "many">, "many">>; + ai_memory: z.ZodOptional, "many">, "many">>; + ai_embedding: z.ZodOptional, "many">, "many">>; + ai_vectorStore: z.ZodOptional, "many">, "many">>; +}, "strip", z.ZodTypeAny, { + error?: { + type: string; + node: string; + index: number; + }[][] | undefined; + main?: { + type: string; + node: string; + index: number; + }[][] | undefined; + ai_languageModel?: { + type: string; + node: string; + index: number; + }[][] | undefined; + ai_memory?: { + type: string; + node: string; + index: number; + }[][] | undefined; + ai_tool?: { + type: string; + node: string; + index: number; + }[][] | undefined; + ai_embedding?: { + type: string; + node: string; + index: number; + }[][] | undefined; + ai_vectorStore?: { + type: string; + node: string; + index: number; + }[][] | undefined; +}, { + error?: { + type: string; + node: string; + index: number; + }[][] | undefined; + main?: { + type: string; + node: string; + index: number; + }[][] | undefined; + ai_languageModel?: { + type: string; + node: string; + index: number; + }[][] | undefined; + ai_memory?: { + type: string; + node: string; + index: number; + }[][] | undefined; + ai_tool?: { + type: string; + node: string; + index: number; + }[][] | undefined; + ai_embedding?: { + type: string; + node: string; + index: number; + }[][] | undefined; + ai_vectorStore?: { + type: string; + node: string; + index: number; + }[][] | undefined; +}>>; +export declare const workflowSettingsSchema: z.ZodObject<{ + executionOrder: z.ZodDefault>; + timezone: z.ZodOptional; + saveDataErrorExecution: z.ZodDefault>; + saveDataSuccessExecution: z.ZodDefault>; + saveManualExecutions: z.ZodDefault; + saveExecutionProgress: z.ZodDefault; + executionTimeout: z.ZodOptional; + errorWorkflow: z.ZodOptional; + callerPolicy: z.ZodOptional>; + availableInMCP: z.ZodOptional; +}, "strip", z.ZodTypeAny, { + executionOrder: "v0" | "v1"; + saveDataErrorExecution: "all" | "none"; + saveDataSuccessExecution: "all" | "none"; + saveManualExecutions: boolean; + saveExecutionProgress: boolean; + timezone?: string | undefined; + executionTimeout?: number | undefined; + errorWorkflow?: string | undefined; + callerPolicy?: "any" | "workflowsFromSameOwner" | "workflowsFromAList" | undefined; + availableInMCP?: boolean | undefined; +}, { + timezone?: string | undefined; + executionOrder?: "v0" | "v1" | undefined; + saveDataErrorExecution?: "all" | "none" | undefined; + saveDataSuccessExecution?: "all" | "none" | undefined; + saveManualExecutions?: boolean | undefined; + saveExecutionProgress?: boolean | undefined; + executionTimeout?: number | undefined; + errorWorkflow?: string | undefined; + callerPolicy?: "any" | "workflowsFromSameOwner" | "workflowsFromAList" | undefined; + availableInMCP?: boolean | undefined; +}>; +export declare const defaultWorkflowSettings: { + executionOrder: "v1"; + saveDataErrorExecution: "all"; + saveDataSuccessExecution: "all"; + saveManualExecutions: boolean; + saveExecutionProgress: boolean; +}; +export declare function validateWorkflowNode(node: unknown): WorkflowNode; +export declare function validateWorkflowConnections(connections: unknown): WorkflowConnection; +export declare function validateWorkflowSettings(settings: unknown): z.infer; +export declare function cleanWorkflowForCreate(workflow: Partial): Partial; +export declare function cleanWorkflowForUpdate(workflow: Workflow): Partial; +export declare function validateWorkflowStructure(workflow: Partial): string[]; +export declare function hasWebhookTrigger(workflow: Workflow): boolean; +export declare function validateFilterBasedNodeMetadata(node: WorkflowNode): string[]; +export declare function validateOperatorStructure(operator: any, path: string): string[]; +export declare function getWebhookUrl(workflow: Workflow): string | null; +export declare function getWorkflowStructureExample(): string; +export declare function getWorkflowFixSuggestions(errors: string[]): string[]; +//# sourceMappingURL=n8n-validation.d.ts.map \ No newline at end of file diff --git a/dist/services/n8n-validation.d.ts.map b/dist/services/n8n-validation.d.ts.map new file mode 100644 index 0000000..9575894 --- /dev/null +++ b/dist/services/n8n-validation.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-validation.d.ts","sourceRoot":"","sources":["../../src/services/n8n-validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAM9E,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiB7B,CAAC;AAkBH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAUpC,CAAC;AAEF,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWjC,CAAC;AAGH,eAAO,MAAM,uBAAuB;;;;;;CAMnC,CAAC;AAGF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,CAEhE;AAED,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,OAAO,GAAG,kBAAkB,CAEpF;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAElG;AAGD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAsBrF;AAiBD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CA4D5E;AAGD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAAE,CAyP/E;AAGD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAK7D;AAMD,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,EAAE,CA+F5E;AAMD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA0D/E;AAGD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAmB/D;AAGD,wBAAgB,2BAA2B,IAAI,MAAM,CA6CpD;AAGD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAmBpE"} \ No newline at end of file diff --git a/dist/services/n8n-validation.js b/dist/services/n8n-validation.js new file mode 100644 index 0000000..5c84cb5 --- /dev/null +++ b/dist/services/n8n-validation.js @@ -0,0 +1,481 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.defaultWorkflowSettings = exports.workflowSettingsSchema = exports.workflowConnectionSchema = exports.workflowNodeSchema = void 0; +exports.validateWorkflowNode = validateWorkflowNode; +exports.validateWorkflowConnections = validateWorkflowConnections; +exports.validateWorkflowSettings = validateWorkflowSettings; +exports.cleanWorkflowForCreate = cleanWorkflowForCreate; +exports.cleanWorkflowForUpdate = cleanWorkflowForUpdate; +exports.validateWorkflowStructure = validateWorkflowStructure; +exports.hasWebhookTrigger = hasWebhookTrigger; +exports.validateFilterBasedNodeMetadata = validateFilterBasedNodeMetadata; +exports.validateOperatorStructure = validateOperatorStructure; +exports.getWebhookUrl = getWebhookUrl; +exports.getWorkflowStructureExample = getWorkflowStructureExample; +exports.getWorkflowFixSuggestions = getWorkflowFixSuggestions; +const zod_1 = require("zod"); +const node_type_utils_1 = require("../utils/node-type-utils"); +const node_classification_1 = require("../utils/node-classification"); +exports.workflowNodeSchema = zod_1.z.object({ + id: zod_1.z.string(), + name: zod_1.z.string(), + type: zod_1.z.string(), + typeVersion: zod_1.z.number(), + position: zod_1.z.tuple([zod_1.z.number(), zod_1.z.number()]), + parameters: zod_1.z.record(zod_1.z.unknown()), + credentials: zod_1.z.record(zod_1.z.unknown()).optional(), + disabled: zod_1.z.boolean().optional(), + notes: zod_1.z.string().optional(), + notesInFlow: zod_1.z.boolean().optional(), + continueOnFail: zod_1.z.boolean().optional(), + retryOnFail: zod_1.z.boolean().optional(), + maxTries: zod_1.z.number().optional(), + waitBetweenTries: zod_1.z.number().optional(), + alwaysOutputData: zod_1.z.boolean().optional(), + executeOnce: zod_1.z.boolean().optional(), +}); +const connectionArraySchema = zod_1.z.array(zod_1.z.array(zod_1.z.object({ + node: zod_1.z.string(), + type: zod_1.z.string(), + index: zod_1.z.number(), +}))); +exports.workflowConnectionSchema = zod_1.z.record(zod_1.z.object({ + main: connectionArraySchema.optional(), + error: connectionArraySchema.optional(), + ai_tool: connectionArraySchema.optional(), + ai_languageModel: connectionArraySchema.optional(), + ai_memory: connectionArraySchema.optional(), + ai_embedding: connectionArraySchema.optional(), + ai_vectorStore: connectionArraySchema.optional(), +})); +exports.workflowSettingsSchema = zod_1.z.object({ + executionOrder: zod_1.z.enum(['v0', 'v1']).default('v1'), + timezone: zod_1.z.string().optional(), + saveDataErrorExecution: zod_1.z.enum(['all', 'none']).default('all'), + saveDataSuccessExecution: zod_1.z.enum(['all', 'none']).default('all'), + saveManualExecutions: zod_1.z.boolean().default(true), + saveExecutionProgress: zod_1.z.boolean().default(true), + executionTimeout: zod_1.z.number().optional(), + errorWorkflow: zod_1.z.string().optional(), + callerPolicy: zod_1.z.enum(['any', 'workflowsFromSameOwner', 'workflowsFromAList']).optional(), + availableInMCP: zod_1.z.boolean().optional(), +}); +exports.defaultWorkflowSettings = { + executionOrder: 'v1', + saveDataErrorExecution: 'all', + saveDataSuccessExecution: 'all', + saveManualExecutions: true, + saveExecutionProgress: true, +}; +function validateWorkflowNode(node) { + return exports.workflowNodeSchema.parse(node); +} +function validateWorkflowConnections(connections) { + return exports.workflowConnectionSchema.parse(connections); +} +function validateWorkflowSettings(settings) { + return exports.workflowSettingsSchema.parse(settings); +} +function cleanWorkflowForCreate(workflow) { + const { id, createdAt, updatedAt, versionId, meta, active, tags, ...cleanedWorkflow } = workflow; + if (!cleanedWorkflow.settings || Object.keys(cleanedWorkflow.settings).length === 0) { + cleanedWorkflow.settings = exports.defaultWorkflowSettings; + } + return cleanedWorkflow; +} +function cleanWorkflowForUpdate(workflow) { + const { id, createdAt, updatedAt, versionId, versionCounter, meta, staticData, pinData, tags, description, isArchived, usedCredentials, sharedWithProjects, triggerCount, shared, active, activeVersionId, activeVersion, ...cleanedWorkflow } = workflow; + const ALL_KNOWN_SETTINGS_PROPERTIES = new Set([ + 'saveExecutionProgress', + 'saveManualExecutions', + 'saveDataErrorExecution', + 'saveDataSuccessExecution', + 'executionTimeout', + 'errorWorkflow', + 'timezone', + 'executionOrder', + 'callerPolicy', + 'callerIds', + 'timeSavedPerExecution', + 'availableInMCP', + ]); + if (cleanedWorkflow.settings && typeof cleanedWorkflow.settings === 'object') { + const filteredSettings = {}; + for (const [key, value] of Object.entries(cleanedWorkflow.settings)) { + if (ALL_KNOWN_SETTINGS_PROPERTIES.has(key)) { + filteredSettings[key] = value; + } + } + cleanedWorkflow.settings = filteredSettings; + } + else { + cleanedWorkflow.settings = {}; + } + return cleanedWorkflow; +} +function validateWorkflowStructure(workflow) { + const errors = []; + if (!workflow.name) { + errors.push('Workflow name is required'); + } + if (!workflow.nodes || workflow.nodes.length === 0) { + errors.push('Workflow must have at least one node'); + } + if (workflow.nodes && workflow.nodes.length > 0) { + const hasExecutableNodes = workflow.nodes.some(node => !(0, node_classification_1.isNonExecutableNode)(node.type)); + if (!hasExecutableNodes) { + errors.push('Workflow must have at least one executable node. Sticky notes alone cannot form a valid workflow.'); + } + } + if (!workflow.connections) { + errors.push('Workflow connections are required'); + } + if (workflow.nodes && workflow.nodes.length === 1) { + const singleNode = workflow.nodes[0]; + const isWebhookOnly = singleNode.type === 'n8n-nodes-base.webhook' || + singleNode.type === 'n8n-nodes-base.webhookTrigger'; + if (!isWebhookOnly) { + errors.push(`Single non-webhook node workflow is invalid. Current node: "${singleNode.name}" (${singleNode.type}). Add another node using: {type: 'addNode', node: {name: 'Process Data', type: 'n8n-nodes-base.set', typeVersion: 3.4, position: [450, 300], parameters: {}}}`); + } + } + if (workflow.nodes && workflow.nodes.length > 1 && workflow.connections) { + const executableNodes = workflow.nodes.filter(node => !(0, node_classification_1.isNonExecutableNode)(node.type)); + const connectionCount = Object.keys(workflow.connections).length; + if (connectionCount === 0 && executableNodes.length > 1) { + const nodeNames = executableNodes.slice(0, 2).map(n => n.name); + errors.push(`Multi-node workflow has no connections between nodes. Add a connection using: {type: 'addConnection', source: '${nodeNames[0]}', target: '${nodeNames[1]}', sourcePort: 'main', targetPort: 'main'}`); + } + else if (connectionCount > 0 || executableNodes.length > 1) { + const connectedNodes = new Set(); + Object.entries(workflow.connections).forEach(([sourceName, connection]) => { + connectedNodes.add(sourceName); + if (connection.main && Array.isArray(connection.main)) { + connection.main.forEach((outputs) => { + if (Array.isArray(outputs)) { + outputs.forEach((target) => { + connectedNodes.add(target.node); + }); + } + }); + } + }); + const disconnectedNodes = workflow.nodes.filter(node => { + if ((0, node_classification_1.isNonExecutableNode)(node.type)) { + return false; + } + const isConnected = connectedNodes.has(node.name); + const isNodeTrigger = (0, node_type_utils_1.isTriggerNode)(node.type); + if (isNodeTrigger) { + return !workflow.connections?.[node.name]; + } + return !isConnected; + }); + if (disconnectedNodes.length > 0) { + const disconnectedList = disconnectedNodes.map(n => `"${n.name}" (${n.type})`).join(', '); + const firstDisconnected = disconnectedNodes[0]; + const suggestedSource = workflow.nodes.find(n => connectedNodes.has(n.name))?.name || workflow.nodes[0].name; + errors.push(`Disconnected nodes detected: ${disconnectedList}. Each node must have at least one connection. Add a connection: {type: 'addConnection', source: '${suggestedSource}', target: '${firstDisconnected.name}', sourcePort: 'main', targetPort: 'main'}`); + } + } + } + if (workflow.nodes) { + workflow.nodes.forEach((node, index) => { + try { + validateWorkflowNode(node); + if (node.type.startsWith('nodes-base.')) { + errors.push(`Invalid node type "${node.type}" at index ${index}. Use "n8n-nodes-base.${node.type.substring(11)}" instead.`); + } + else if (!node.type.includes('.')) { + errors.push(`Invalid node type "${node.type}" at index ${index}. Node types must include package prefix (e.g., "n8n-nodes-base.webhook").`); + } + } + catch (error) { + errors.push(`Invalid node at index ${index}: ${error instanceof Error ? error.message : 'Unknown error'}`); + } + }); + } + if (workflow.nodes) { + workflow.nodes.forEach((node, index) => { + const filterErrors = validateFilterBasedNodeMetadata(node); + if (filterErrors.length > 0) { + errors.push(...filterErrors.map(err => `Node "${node.name}" (index ${index}): ${err}`)); + } + }); + } + if (workflow.connections) { + try { + validateWorkflowConnections(workflow.connections); + } + catch (error) { + errors.push(`Invalid connections: ${error instanceof Error ? error.message : 'Unknown error'}`); + } + } + if (workflow.active === true && workflow.nodes && workflow.nodes.length > 0) { + const activatableTriggers = workflow.nodes.filter(node => !node.disabled && (0, node_type_utils_1.isActivatableTrigger)(node.type)); + const executeWorkflowTriggers = workflow.nodes.filter(node => !node.disabled && node.type.toLowerCase().includes('executeworkflow')); + if (activatableTriggers.length === 0 && executeWorkflowTriggers.length > 0) { + const triggerNames = executeWorkflowTriggers.map(n => n.name).join(', '); + errors.push(`Cannot activate workflow with only Execute Workflow Trigger nodes (${triggerNames}). ` + + 'Execute Workflow Trigger can only be invoked by other workflows, not activated. ' + + 'Either deactivate the workflow or add a webhook/schedule/polling trigger.'); + } + } + if (workflow.nodes && workflow.connections) { + const switchNodes = workflow.nodes.filter(n => { + if (n.type !== 'n8n-nodes-base.switch') + return false; + const mode = n.parameters?.mode; + return !mode || mode === 'rules'; + }); + for (const switchNode of switchNodes) { + const params = switchNode.parameters; + const rules = params?.rules?.rules || []; + const nodeConnections = workflow.connections[switchNode.name]; + if (rules.length > 0 && nodeConnections?.main) { + const outputBranches = nodeConnections.main.length; + if (outputBranches !== rules.length) { + const ruleNames = rules.map((r, i) => r.outputKey ? `"${r.outputKey}" (index ${i})` : `Rule ${i}`).join(', '); + errors.push(`Switch node "${switchNode.name}" has ${rules.length} rules [${ruleNames}] ` + + `but only ${outputBranches} output branch${outputBranches !== 1 ? 'es' : ''} in connections. ` + + `Each rule needs its own output branch. When connecting to Switch outputs, specify sourceIndex: ` + + rules.map((_, i) => i).join(', ') + + ` (or use case parameter for clarity).`); + } + const nonEmptyBranches = nodeConnections.main.filter((branch) => branch.length > 0).length; + if (nonEmptyBranches < rules.length) { + const emptyIndices = nodeConnections.main + .map((branch, i) => branch.length === 0 ? i : -1) + .filter((i) => i !== -1 && i < rules.length); + if (emptyIndices.length > 0) { + const ruleInfo = emptyIndices.map((i) => { + const rule = rules[i]; + return rule.outputKey ? `"${rule.outputKey}" (index ${i})` : `Rule ${i}`; + }).join(', '); + errors.push(`Switch node "${switchNode.name}" has unconnected output${emptyIndices.length !== 1 ? 's' : ''}: ${ruleInfo}. ` + + `Add connection${emptyIndices.length !== 1 ? 's' : ''} using sourceIndex: ${emptyIndices.join(' or ')}.`); + } + } + } + } + } + if (workflow.nodes && workflow.connections) { + const nodeNames = new Set(workflow.nodes.map(node => node.name)); + const nodeIds = new Set(workflow.nodes.map(node => node.id)); + const nodeIdToName = new Map(workflow.nodes.map(node => [node.id, node.name])); + Object.entries(workflow.connections).forEach(([sourceName, connection]) => { + if (!nodeNames.has(sourceName)) { + if (nodeIds.has(sourceName)) { + const correctName = nodeIdToName.get(sourceName); + errors.push(`Connection uses node ID '${sourceName}' but must use node name '${correctName}'. Change connections.${sourceName} to connections['${correctName}']`); + } + else { + errors.push(`Connection references non-existent node: ${sourceName}`); + } + } + if (connection.main && Array.isArray(connection.main)) { + connection.main.forEach((outputs, outputIndex) => { + if (Array.isArray(outputs)) { + outputs.forEach((target, targetIndex) => { + if (!nodeNames.has(target.node)) { + if (nodeIds.has(target.node)) { + const correctName = nodeIdToName.get(target.node); + errors.push(`Connection target uses node ID '${target.node}' but must use node name '${correctName}' (from ${sourceName}[${outputIndex}][${targetIndex}])`); + } + else { + errors.push(`Connection references non-existent target node: ${target.node} (from ${sourceName}[${outputIndex}][${targetIndex}])`); + } + } + }); + } + }); + } + }); + } + return errors; +} +function hasWebhookTrigger(workflow) { + return workflow.nodes.some(node => node.type === 'n8n-nodes-base.webhook' || + node.type === 'n8n-nodes-base.webhookTrigger'); +} +function validateFilterBasedNodeMetadata(node) { + const errors = []; + const isIFNode = node.type === 'n8n-nodes-base.if' && node.typeVersion >= 2.2; + const isSwitchNode = node.type === 'n8n-nodes-base.switch' && node.typeVersion >= 3.2; + if (!isIFNode && !isSwitchNode) { + return errors; + } + if (isIFNode) { + const conditions = node.parameters.conditions; + if (!conditions?.options) { + errors.push('Missing required "conditions.options". ' + + 'IF v2.2+ requires: {version: 2, leftValue: "", caseSensitive: true, typeValidation: "strict"}'); + } + else { + const requiredFields = { + version: 2, + leftValue: '', + caseSensitive: 'boolean', + typeValidation: 'strict' + }; + for (const [field, expectedValue] of Object.entries(requiredFields)) { + if (!(field in conditions.options)) { + errors.push(`Missing required field "conditions.options.${field}". ` + + `Expected value: ${typeof expectedValue === 'string' ? `"${expectedValue}"` : expectedValue}`); + } + } + } + if (conditions?.conditions && Array.isArray(conditions.conditions)) { + conditions.conditions.forEach((condition, i) => { + const operatorErrors = validateOperatorStructure(condition.operator, `conditions.conditions[${i}].operator`); + errors.push(...operatorErrors); + }); + } + } + if (isSwitchNode) { + const rules = node.parameters.rules; + if (rules?.rules && Array.isArray(rules.rules)) { + rules.rules.forEach((rule, ruleIndex) => { + if (!rule.conditions?.options) { + errors.push(`Missing required "rules.rules[${ruleIndex}].conditions.options". ` + + 'Switch v3.2+ requires: {version: 2, leftValue: "", caseSensitive: true, typeValidation: "strict"}'); + } + else { + const requiredFields = { + version: 2, + leftValue: '', + caseSensitive: 'boolean', + typeValidation: 'strict' + }; + for (const [field, expectedValue] of Object.entries(requiredFields)) { + if (!(field in rule.conditions.options)) { + errors.push(`Missing required field "rules.rules[${ruleIndex}].conditions.options.${field}". ` + + `Expected value: ${typeof expectedValue === 'string' ? `"${expectedValue}"` : expectedValue}`); + } + } + } + if (rule.conditions?.conditions && Array.isArray(rule.conditions.conditions)) { + rule.conditions.conditions.forEach((condition, condIndex) => { + const operatorErrors = validateOperatorStructure(condition.operator, `rules.rules[${ruleIndex}].conditions.conditions[${condIndex}].operator`); + errors.push(...operatorErrors); + }); + } + }); + } + } + return errors; +} +function validateOperatorStructure(operator, path) { + const errors = []; + if (!operator || typeof operator !== 'object') { + errors.push(`${path}: operator is missing or not an object`); + return errors; + } + if (!operator.type) { + errors.push(`${path}: missing required field "type". ` + + 'Must be a data type: "string", "number", "boolean", "dateTime", "array", or "object"'); + } + else { + const validTypes = ['string', 'number', 'boolean', 'dateTime', 'array', 'object']; + if (!validTypes.includes(operator.type)) { + errors.push(`${path}: invalid type "${operator.type}". ` + + `Type must be a data type (${validTypes.join(', ')}), not an operation name. ` + + 'Did you mean to use the "operation" field?'); + } + } + if (!operator.operation) { + errors.push(`${path}: missing required field "operation". ` + + 'Operation specifies the comparison type (e.g., "equals", "contains", "isNotEmpty")'); + } + if (operator.operation) { + const unaryOperators = ['isEmpty', 'isNotEmpty', 'true', 'false', 'isNumeric']; + const isUnary = unaryOperators.includes(operator.operation); + if (isUnary) { + if (operator.singleValue !== true) { + errors.push(`${path}: unary operator "${operator.operation}" requires "singleValue: true". ` + + 'Unary operators do not use rightValue.'); + } + } + else { + if (operator.singleValue === true) { + errors.push(`${path}: binary operator "${operator.operation}" should not have "singleValue: true". ` + + 'Only unary operators (isEmpty, isNotEmpty, true, false, isNumeric) need this property.'); + } + } + } + return errors; +} +function getWebhookUrl(workflow) { + const webhookNode = workflow.nodes.find(node => node.type === 'n8n-nodes-base.webhook' || + node.type === 'n8n-nodes-base.webhookTrigger'); + if (!webhookNode || !webhookNode.parameters) { + return null; + } + const path = webhookNode.parameters.path; + if (!path) { + return null; + } + return path; +} +function getWorkflowStructureExample() { + return ` +Minimal Workflow Example: +{ + "name": "My Workflow", + "nodes": [ + { + "id": "manual-trigger-1", + "name": "Manual Trigger", + "type": "n8n-nodes-base.manualTrigger", + "typeVersion": 1, + "position": [250, 300], + "parameters": {} + }, + { + "id": "set-1", + "name": "Set Data", + "type": "n8n-nodes-base.set", + "typeVersion": 3.4, + "position": [450, 300], + "parameters": { + "mode": "manual", + "assignments": { + "assignments": [{ + "id": "1", + "name": "message", + "value": "Hello World", + "type": "string" + }] + } + } + } + ], + "connections": { + "Manual Trigger": { + "main": [[{ + "node": "Set Data", + "type": "main", + "index": 0 + }]] + } + } +} + +IMPORTANT: In connections, use the node NAME (e.g., "Manual Trigger"), NOT the node ID or type!`; +} +function getWorkflowFixSuggestions(errors) { + const suggestions = []; + if (errors.some(e => e.includes('empty connections'))) { + suggestions.push('Add connections between your nodes. Each node (except endpoints) should connect to another node.'); + suggestions.push('Connection format: connections: { "Source Node Name": { "main": [[{ "node": "Target Node Name", "type": "main", "index": 0 }]] } }'); + } + if (errors.some(e => e.includes('Single-node workflows'))) { + suggestions.push('Add at least one more node to process data. Common patterns: Trigger → Process → Output'); + suggestions.push('Examples: Manual Trigger → Set, Webhook → HTTP Request, Schedule Trigger → Database Query'); + } + if (errors.some(e => e.includes('node ID') && e.includes('instead of node name'))) { + suggestions.push('Replace node IDs with node names in connections. The name is what appears in the node header.'); + suggestions.push('Wrong: connections: { "set-1": {...} }, Right: connections: { "Set Data": {...} }'); + } + return suggestions; +} +//# sourceMappingURL=n8n-validation.js.map \ No newline at end of file diff --git a/dist/services/n8n-validation.js.map b/dist/services/n8n-validation.js.map new file mode 100644 index 0000000..8f34a3b --- /dev/null +++ b/dist/services/n8n-validation.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-validation.js","sourceRoot":"","sources":["../../src/services/n8n-validation.ts"],"names":[],"mappings":";;;AA6EA,oDAEC;AAED,kEAEC;AAED,4DAEC;AAGD,wDAsBC;AAiBD,wDA4DC;AAGD,8DAyPC;AAGD,8CAKC;AAMD,0EA+FC;AAMD,8DA0DC;AAGD,sCAmBC;AAGD,kEA6CC;AAGD,8DAmBC;AAlsBD,6BAAwB;AAExB,8DAA+E;AAC/E,sEAAmE;AAItD,QAAA,kBAAkB,GAAG,OAAC,CAAC,MAAM,CAAC;IACzC,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;IAChB,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;IAChB,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE;IACvB,QAAQ,EAAE,OAAC,CAAC,KAAK,CAAC,CAAC,OAAC,CAAC,MAAM,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3C,UAAU,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,OAAO,EAAE,CAAC;IACjC,WAAW,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC7C,QAAQ,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAChC,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,WAAW,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACnC,cAAc,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACtC,WAAW,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACnC,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,gBAAgB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACvC,gBAAgB,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACxC,WAAW,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACpC,CAAC,CAAC;AAGH,MAAM,qBAAqB,GAAG,OAAC,CAAC,KAAK,CACnC,OAAC,CAAC,KAAK,CACL,OAAC,CAAC,MAAM,CAAC;IACP,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;IAChB,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;IAChB,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE;CAClB,CAAC,CACH,CACF,CAAC;AAOW,QAAA,wBAAwB,GAAG,OAAC,CAAC,MAAM,CAC9C,OAAC,CAAC,MAAM,CAAC;IACP,IAAI,EAAE,qBAAqB,CAAC,QAAQ,EAAE;IACtC,KAAK,EAAE,qBAAqB,CAAC,QAAQ,EAAE;IACvC,OAAO,EAAE,qBAAqB,CAAC,QAAQ,EAAE;IACzC,gBAAgB,EAAE,qBAAqB,CAAC,QAAQ,EAAE;IAClD,SAAS,EAAE,qBAAqB,CAAC,QAAQ,EAAE;IAC3C,YAAY,EAAE,qBAAqB,CAAC,QAAQ,EAAE;IAC9C,cAAc,EAAE,qBAAqB,CAAC,QAAQ,EAAE;CACjD,CAAC,CACH,CAAC;AAEW,QAAA,sBAAsB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC7C,cAAc,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IAClD,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,sBAAsB,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IAC9D,wBAAwB,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IAChE,oBAAoB,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC/C,qBAAqB,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAChD,gBAAgB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACvC,aAAa,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,YAAY,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,wBAAwB,EAAE,oBAAoB,CAAC,CAAC,CAAC,QAAQ,EAAE;IACxF,cAAc,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACvC,CAAC,CAAC;AAGU,QAAA,uBAAuB,GAAG;IACrC,cAAc,EAAE,IAAa;IAC7B,sBAAsB,EAAE,KAAc;IACtC,wBAAwB,EAAE,KAAc;IACxC,oBAAoB,EAAE,IAAI;IAC1B,qBAAqB,EAAE,IAAI;CAC5B,CAAC;AAGF,SAAgB,oBAAoB,CAAC,IAAa;IAChD,OAAO,0BAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC;AAED,SAAgB,2BAA2B,CAAC,WAAoB;IAC9D,OAAO,gCAAwB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AACrD,CAAC;AAED,SAAgB,wBAAwB,CAAC,QAAiB;IACxD,OAAO,8BAAsB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;AAChD,CAAC;AAGD,SAAgB,sBAAsB,CAAC,QAA2B;IAChE,MAAM,EAEJ,EAAE,EACF,SAAS,EACT,SAAS,EACT,SAAS,EACT,IAAI,EAEJ,MAAM,EACN,IAAI,EAEJ,GAAG,eAAe,EACnB,GAAG,QAAQ,CAAC;IAIb,IAAI,CAAC,eAAe,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpF,eAAe,CAAC,QAAQ,GAAG,+BAAuB,CAAC;IACrD,CAAC;IAED,OAAO,eAAe,CAAC;AACzB,CAAC;AAiBD,SAAgB,sBAAsB,CAAC,QAAkB;IACvD,MAAM,EAEJ,EAAE,EACF,SAAS,EACT,SAAS,EACT,SAAS,EACT,cAAc,EACd,IAAI,EACJ,UAAU,EACV,OAAO,EACP,IAAI,EACJ,WAAW,EACX,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,MAAM,EACN,MAAM,EACN,eAAe,EACf,aAAa,EAEb,GAAG,eAAe,EACnB,GAAG,QAAe,CAAC;IAKpB,MAAM,6BAA6B,GAAG,IAAI,GAAG,CAAC;QAE5C,uBAAuB;QACvB,sBAAsB;QACtB,wBAAwB;QACxB,0BAA0B;QAC1B,kBAAkB;QAClB,eAAe;QACf,UAAU;QAEV,gBAAgB;QAEhB,cAAc;QACd,WAAW;QACX,uBAAuB;QACvB,gBAAgB;KACjB,CAAC,CAAC;IAEH,IAAI,eAAe,CAAC,QAAQ,IAAI,OAAO,eAAe,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAE7E,MAAM,gBAAgB,GAA4B,EAAE,CAAC;QACrD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpE,IAAI,6BAA6B,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC3C,gBAAgB,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YAChC,CAAC;QACH,CAAC;QACD,eAAe,CAAC,QAAQ,GAAG,gBAAgB,CAAC;IAC9C,CAAC;SAAM,CAAC;QACN,eAAe,CAAC,QAAQ,GAAG,EAAE,CAAC;IAChC,CAAC;IAED,OAAO,eAAe,CAAC;AACzB,CAAC;AAGD,SAAgB,yBAAyB,CAAC,QAA2B;IACnE,MAAM,MAAM,GAAa,EAAE,CAAC;IAG5B,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnB,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnD,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;IACtD,CAAC;IAGD,IAAI,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,MAAM,kBAAkB,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAA,yCAAmB,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACxF,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACxB,MAAM,CAAC,IAAI,CAAC,mGAAmG,CAAC,CAAC;QACnH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IACnD,CAAC;IAGD,IAAI,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClD,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,aAAa,GAAG,UAAU,CAAC,IAAI,KAAK,wBAAwB;YAC7C,UAAU,CAAC,IAAI,KAAK,+BAA+B,CAAC;QAEzE,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,CAAC,IAAI,CAAC,+DAA+D,UAAU,CAAC,IAAI,MAAM,UAAU,CAAC,IAAI,gKAAgK,CAAC,CAAC;QACnR,CAAC;IACH,CAAC;IAGD,IAAI,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;QAExE,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAA,yCAAmB,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACvF,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;QAGjE,IAAI,eAAe,KAAK,CAAC,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxD,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC/D,MAAM,CAAC,IAAI,CAAC,kHAAkH,SAAS,CAAC,CAAC,CAAC,eAAe,SAAS,CAAC,CAAC,CAAC,4CAA4C,CAAC,CAAC;QACrN,CAAC;aAAM,IAAI,eAAe,GAAG,CAAC,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAE7D,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;YAGzC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,EAAE,EAAE;gBACxE,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBAE/B,IAAI,UAAU,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;oBACtD,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;wBAClC,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;4BAC3B,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;gCACzB,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;4BAClC,CAAC,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;YAKH,MAAM,iBAAiB,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;gBAErD,IAAI,IAAA,yCAAmB,EAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACnC,OAAO,KAAK,CAAC;gBACf,CAAC;gBAED,MAAM,WAAW,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAClD,MAAM,aAAa,GAAG,IAAA,+BAAa,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAG/C,IAAI,aAAa,EAAE,CAAC;oBAClB,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC5C,CAAC;gBAGD,OAAO,CAAC,WAAW,CAAC;YACtB,CAAC,CAAC,CAAC;YAEH,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACjC,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC1F,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;gBAC/C,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBAE7G,MAAM,CAAC,IAAI,CAAC,gCAAgC,gBAAgB,qGAAqG,eAAe,eAAe,iBAAiB,CAAC,IAAI,4CAA4C,CAAC,CAAC;YACrQ,CAAC;QACH,CAAC;IACH,CAAC;IAGD,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnB,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YACrC,IAAI,CAAC;gBACH,oBAAoB,CAAC,IAAI,CAAC,CAAC;gBAG3B,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;oBACxC,MAAM,CAAC,IAAI,CAAC,sBAAsB,IAAI,CAAC,IAAI,cAAc,KAAK,yBAAyB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;gBAC9H,CAAC;qBAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBACpC,MAAM,CAAC,IAAI,CAAC,sBAAsB,IAAI,CAAC,IAAI,cAAc,KAAK,4EAA4E,CAAC,CAAC;gBAC9I,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,CAAC,yBAAyB,KAAK,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;YAC7G,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAGD,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnB,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YACrC,MAAM,YAAY,GAAG,+BAA+B,CAAC,IAAI,CAAC,CAAC;YAC3D,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC5B,MAAM,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,IAAI,CAAC,IAAI,YAAY,KAAK,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC;YAC1F,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAGD,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,2BAA2B,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,wBAAwB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;QAClG,CAAC;IACH,CAAC;IAKD,IAAK,QAAgB,CAAC,MAAM,KAAK,IAAI,IAAI,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrF,MAAM,mBAAmB,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CACvD,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAA,sCAAoB,EAAC,IAAI,CAAC,IAAI,CAAC,CAClD,CAAC;QAEF,MAAM,uBAAuB,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAC3D,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CACtE,CAAC;QAEF,IAAI,mBAAmB,CAAC,MAAM,KAAK,CAAC,IAAI,uBAAuB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAE3E,MAAM,YAAY,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzE,MAAM,CAAC,IAAI,CACT,sEAAsE,YAAY,KAAK;gBACvF,kFAAkF;gBAClF,2EAA2E,CAC5E,CAAC;QACJ,CAAC;IACH,CAAC;IAGD,IAAI,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;YAC5C,IAAI,CAAC,CAAC,IAAI,KAAK,uBAAuB;gBAAE,OAAO,KAAK,CAAC;YACrD,MAAM,IAAI,GAAI,CAAC,CAAC,UAAkB,EAAE,IAAI,CAAC;YACzC,OAAO,CAAC,IAAI,IAAI,IAAI,KAAK,OAAO,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACrC,MAAM,MAAM,GAAG,UAAU,CAAC,UAAiB,CAAC;YAC5C,MAAM,KAAK,GAAG,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC;YACzC,MAAM,eAAe,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAE9D,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,eAAe,EAAE,IAAI,EAAE,CAAC;gBAC9C,MAAM,cAAc,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC;gBAGnD,IAAI,cAAc,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;oBACpC,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,CAAS,EAAE,EAAE,CAChD,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAC5D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAEb,MAAM,CAAC,IAAI,CACT,gBAAgB,UAAU,CAAC,IAAI,SAAS,KAAK,CAAC,MAAM,WAAW,SAAS,IAAI;wBAC5E,YAAY,cAAc,iBAAiB,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,mBAAmB;wBAC9F,iGAAiG;wBACjG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;wBAC9C,uCAAuC,CACxC,CAAC;gBACJ,CAAC;gBAGD,MAAM,gBAAgB,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAa,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;gBAClG,IAAI,gBAAgB,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;oBACpC,MAAM,YAAY,GAAG,eAAe,CAAC,IAAI;yBACtC,GAAG,CAAC,CAAC,MAAa,EAAE,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;yBAC/D,MAAM,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;oBAEvD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC5B,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE;4BAC9C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;4BACtB,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;wBAC3E,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBAEd,MAAM,CAAC,IAAI,CACT,gBAAgB,UAAU,CAAC,IAAI,2BAA2B,YAAY,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,IAAI;4BAC/G,iBAAiB,YAAY,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,uBAAuB,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CACzG,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAGD,IAAI,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACjE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7D,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE/E,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,EAAE,EAAE;YAExE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;gBAE/B,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC5B,MAAM,WAAW,GAAG,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;oBACjD,MAAM,CAAC,IAAI,CAAC,4BAA4B,UAAU,6BAA6B,WAAW,yBAAyB,UAAU,oBAAoB,WAAW,IAAI,CAAC,CAAC;gBACpK,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,IAAI,CAAC,4CAA4C,UAAU,EAAE,CAAC,CAAC;gBACxE,CAAC;YACH,CAAC;YAED,IAAI,UAAU,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACtD,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE;oBAC/C,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;wBAC3B,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE;4BAEtC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gCAEhC,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;oCAC7B,MAAM,WAAW,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;oCAClD,MAAM,CAAC,IAAI,CAAC,mCAAmC,MAAM,CAAC,IAAI,6BAA6B,WAAW,WAAW,UAAU,IAAI,WAAW,KAAK,WAAW,IAAI,CAAC,CAAC;gCAC9J,CAAC;qCAAM,CAAC;oCACN,MAAM,CAAC,IAAI,CAAC,mDAAmD,MAAM,CAAC,IAAI,UAAU,UAAU,IAAI,WAAW,KAAK,WAAW,IAAI,CAAC,CAAC;gCACrI,CAAC;4BACH,CAAC;wBACH,CAAC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAGD,SAAgB,iBAAiB,CAAC,QAAkB;IAClD,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAChC,IAAI,CAAC,IAAI,KAAK,wBAAwB;QACtC,IAAI,CAAC,IAAI,KAAK,+BAA+B,CAC9C,CAAC;AACJ,CAAC;AAMD,SAAgB,+BAA+B,CAAC,IAAkB;IAChE,MAAM,MAAM,GAAa,EAAE,CAAC;IAG5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,KAAK,mBAAmB,IAAI,IAAI,CAAC,WAAW,IAAI,GAAG,CAAC;IAC9E,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,KAAK,uBAAuB,IAAI,IAAI,CAAC,WAAW,IAAI,GAAG,CAAC;IAEtF,IAAI,CAAC,QAAQ,IAAI,CAAC,YAAY,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IAGD,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,UAAU,GAAI,IAAI,CAAC,UAAU,CAAC,UAAkB,CAAC;QAGvD,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC;YACzB,MAAM,CAAC,IAAI,CACT,yCAAyC;gBACzC,+FAA+F,CAChG,CAAC;QACJ,CAAC;aAAM,CAAC;YAEN,MAAM,cAAc,GAAG;gBACrB,OAAO,EAAE,CAAC;gBACV,SAAS,EAAE,EAAE;gBACb,aAAa,EAAE,SAAS;gBACxB,cAAc,EAAE,QAAQ;aACzB,CAAC;YAEF,KAAK,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;gBACpE,IAAI,CAAC,CAAC,KAAK,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;oBACnC,MAAM,CAAC,IAAI,CACT,8CAA8C,KAAK,KAAK;wBACxD,mBAAmB,OAAO,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,aAAa,GAAG,CAAC,CAAC,CAAC,aAAa,EAAE,CAC9F,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAGD,IAAI,UAAU,EAAE,UAAU,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACnE,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,SAAc,EAAE,CAAS,EAAE,EAAE;gBAC1D,MAAM,cAAc,GAAG,yBAAyB,CAAC,SAAS,CAAC,QAAQ,EAAE,yBAAyB,CAAC,YAAY,CAAC,CAAC;gBAC7G,MAAM,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC;YACjC,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAGD,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,KAAK,GAAI,IAAI,CAAC,UAAU,CAAC,KAAa,CAAC;QAE7C,IAAI,KAAK,EAAE,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/C,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAS,EAAE,SAAiB,EAAE,EAAE;gBAEnD,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC;oBAC9B,MAAM,CAAC,IAAI,CACT,iCAAiC,SAAS,yBAAyB;wBACnE,mGAAmG,CACpG,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBAEN,MAAM,cAAc,GAAG;wBACrB,OAAO,EAAE,CAAC;wBACV,SAAS,EAAE,EAAE;wBACb,aAAa,EAAE,SAAS;wBACxB,cAAc,EAAE,QAAQ;qBACzB,CAAC;oBAEF,KAAK,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;wBACpE,IAAI,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;4BACxC,MAAM,CAAC,IAAI,CACT,uCAAuC,SAAS,wBAAwB,KAAK,KAAK;gCAClF,mBAAmB,OAAO,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,aAAa,GAAG,CAAC,CAAC,CAAC,aAAa,EAAE,CAC9F,CAAC;wBACJ,CAAC;oBACH,CAAC;gBACH,CAAC;gBAGD,IAAI,IAAI,CAAC,UAAU,EAAE,UAAU,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC7E,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,SAAc,EAAE,SAAiB,EAAE,EAAE;wBACvE,MAAM,cAAc,GAAG,yBAAyB,CAC9C,SAAS,CAAC,QAAQ,EAClB,eAAe,SAAS,2BAA2B,SAAS,YAAY,CACzE,CAAC;wBACF,MAAM,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC;oBACjC,CAAC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAMD,SAAgB,yBAAyB,CAAC,QAAa,EAAE,IAAY;IACnE,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,wCAAwC,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC;IAChB,CAAC;IAGD,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnB,MAAM,CAAC,IAAI,CACT,GAAG,IAAI,mCAAmC;YAC1C,sFAAsF,CACvF,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,UAAU,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAClF,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CACT,GAAG,IAAI,mBAAmB,QAAQ,CAAC,IAAI,KAAK;gBAC5C,6BAA6B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,4BAA4B;gBAC9E,4CAA4C,CAC7C,CAAC;QACJ,CAAC;IACH,CAAC;IAGD,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,CACT,GAAG,IAAI,wCAAwC;YAC/C,oFAAoF,CACrF,CAAC;IACJ,CAAC;IAGD,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;QACvB,MAAM,cAAc,GAAG,CAAC,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;QAC/E,MAAM,OAAO,GAAG,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAE5D,IAAI,OAAO,EAAE,CAAC;YAEZ,IAAI,QAAQ,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;gBAClC,MAAM,CAAC,IAAI,CACT,GAAG,IAAI,qBAAqB,QAAQ,CAAC,SAAS,kCAAkC;oBAChF,wCAAwC,CACzC,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,CAAC;YAEN,IAAI,QAAQ,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;gBAClC,MAAM,CAAC,IAAI,CACT,GAAG,IAAI,sBAAsB,QAAQ,CAAC,SAAS,yCAAyC;oBACxF,wFAAwF,CACzF,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAGD,SAAgB,aAAa,CAAC,QAAkB;IAC9C,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC7C,IAAI,CAAC,IAAI,KAAK,wBAAwB;QACtC,IAAI,CAAC,IAAI,KAAK,+BAA+B,CAC9C,CAAC;IAEF,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;IAGD,MAAM,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC,IAA0B,CAAC;IAC/D,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IAID,OAAO,IAAI,CAAC;AACd,CAAC;AAGD,SAAgB,2BAA2B;IACzC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gGA2CuF,CAAC;AACjG,CAAC;AAGD,SAAgB,yBAAyB,CAAC,MAAgB;IACxD,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC;QACtD,WAAW,CAAC,IAAI,CAAC,kGAAkG,CAAC,CAAC;QACrH,WAAW,CAAC,IAAI,CAAC,oIAAoI,CAAC,CAAC;IACzJ,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC,EAAE,CAAC;QAC1D,WAAW,CAAC,IAAI,CAAC,yFAAyF,CAAC,CAAC;QAC5G,WAAW,CAAC,IAAI,CAAC,2FAA2F,CAAC,CAAC;IAChH,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC,EAAE,CAAC;QAClF,WAAW,CAAC,IAAI,CAAC,+FAA+F,CAAC,CAAC;QAClH,WAAW,CAAC,IAAI,CAAC,mFAAmF,CAAC,CAAC;IACxG,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC"} \ No newline at end of file diff --git a/dist/services/n8n-version.d.ts b/dist/services/n8n-version.d.ts new file mode 100644 index 0000000..916ea64 --- /dev/null +++ b/dist/services/n8n-version.d.ts @@ -0,0 +1,23 @@ +import { N8nVersionInfo } from '../types/n8n-api'; +export declare function parseVersion(versionString: string): N8nVersionInfo | null; +export declare function compareVersions(a: N8nVersionInfo, b: N8nVersionInfo): number; +export declare function versionAtLeast(version: N8nVersionInfo, major: number, minor: number, patch?: number): boolean; +export declare function getSupportedSettingsProperties(version: N8nVersionInfo): Set; +export declare function fetchN8nVersion(baseUrl: string): Promise; +export declare function clearVersionCache(): void; +export declare function getCachedVersion(baseUrl: string): N8nVersionInfo | null; +export declare function setCachedVersion(baseUrl: string, version: N8nVersionInfo): void; +export declare function cleanSettingsForVersion(settings: Record | undefined, version: N8nVersionInfo | null): Record; +export declare const VERSION_THRESHOLDS: { + EXECUTION_ORDER: { + major: number; + minor: number; + patch: number; + }; + CALLER_POLICY: { + major: number; + minor: number; + patch: number; + }; +}; +//# sourceMappingURL=n8n-version.d.ts.map \ No newline at end of file diff --git a/dist/services/n8n-version.d.ts.map b/dist/services/n8n-version.d.ts.map new file mode 100644 index 0000000..4ad45f1 --- /dev/null +++ b/dist/services/n8n-version.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-version.d.ts","sourceRoot":"","sources":["../../src/services/n8n-version.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,cAAc,EAAuB,MAAM,kBAAkB,CAAC;AAkCvE,wBAAgB,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAazE;AAKD,wBAAgB,eAAe,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,cAAc,GAAG,MAAM,CAI5E;AAKD,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,OAAO,CAGxG;AAKD,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,cAAc,GAAG,GAAG,CAAC,MAAM,CAAC,CAcnF;AASD,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAgDrF;AAKD,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAKD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAEvE;AAKD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAE/E;AAYD,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC7C,OAAO,EAAE,cAAc,GAAG,IAAI,GAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAsBzB;AAGD,eAAO,MAAM,kBAAkB;;;;;;;;;;;CAG9B,CAAC"} \ No newline at end of file diff --git a/dist/services/n8n-version.js b/dist/services/n8n-version.js new file mode 100644 index 0000000..6bf5d5d --- /dev/null +++ b/dist/services/n8n-version.js @@ -0,0 +1,142 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.VERSION_THRESHOLDS = void 0; +exports.parseVersion = parseVersion; +exports.compareVersions = compareVersions; +exports.versionAtLeast = versionAtLeast; +exports.getSupportedSettingsProperties = getSupportedSettingsProperties; +exports.fetchN8nVersion = fetchN8nVersion; +exports.clearVersionCache = clearVersionCache; +exports.getCachedVersion = getCachedVersion; +exports.setCachedVersion = setCachedVersion; +exports.cleanSettingsForVersion = cleanSettingsForVersion; +const axios_1 = __importDefault(require("axios")); +const logger_1 = require("../utils/logger"); +const versionCache = new Map(); +const SETTINGS_BY_VERSION = { + core: [ + 'saveExecutionProgress', + 'saveManualExecutions', + 'saveDataErrorExecution', + 'saveDataSuccessExecution', + 'executionTimeout', + 'errorWorkflow', + 'timezone', + ], + v1_37_0: [ + 'executionOrder', + ], + v1_119_0: [ + 'callerPolicy', + 'callerIds', + 'timeSavedPerExecution', + 'availableInMCP', + ], +}; +function parseVersion(versionString) { + const match = versionString.match(/^(\d+)\.(\d+)\.(\d+)/); + if (!match) { + return null; + } + return { + version: versionString, + major: parseInt(match[1], 10), + minor: parseInt(match[2], 10), + patch: parseInt(match[3], 10), + }; +} +function compareVersions(a, b) { + if (a.major !== b.major) + return a.major - b.major; + if (a.minor !== b.minor) + return a.minor - b.minor; + return a.patch - b.patch; +} +function versionAtLeast(version, major, minor, patch = 0) { + const target = { version: '', major, minor, patch }; + return compareVersions(version, target) >= 0; +} +function getSupportedSettingsProperties(version) { + const supported = new Set(SETTINGS_BY_VERSION.core); + if (versionAtLeast(version, 1, 37, 0)) { + SETTINGS_BY_VERSION.v1_37_0.forEach(prop => supported.add(prop)); + } + if (versionAtLeast(version, 1, 119, 0)) { + SETTINGS_BY_VERSION.v1_119_0.forEach(prop => supported.add(prop)); + } + return supported; +} +async function fetchN8nVersion(baseUrl) { + const cached = versionCache.get(baseUrl); + if (cached) { + logger_1.logger.debug(`Using cached n8n version for ${baseUrl}: ${cached.version}`); + return cached; + } + try { + const cleanBaseUrl = baseUrl.replace(/\/api\/v\d+\/?$/, '').replace(/\/$/, ''); + const settingsUrl = `${cleanBaseUrl}/rest/settings`; + logger_1.logger.debug(`Fetching n8n version from ${settingsUrl}`); + const response = await axios_1.default.get(settingsUrl, { + timeout: 5000, + validateStatus: (status) => status < 500, + }); + if (response.status === 200 && response.data) { + const settings = response.data.data; + if (!settings) { + logger_1.logger.warn('No data in settings response'); + return null; + } + const versionString = settings.n8nVersion || settings.versionCli; + if (versionString) { + const versionInfo = parseVersion(versionString); + if (versionInfo) { + versionCache.set(baseUrl, versionInfo); + logger_1.logger.debug(`Detected n8n version: ${versionInfo.version}`); + return versionInfo; + } + } + } + logger_1.logger.warn(`Could not determine n8n version from ${settingsUrl}`); + return null; + } + catch (error) { + logger_1.logger.warn(`Failed to fetch n8n version: ${error instanceof Error ? error.message : 'Unknown error'}`); + return null; + } +} +function clearVersionCache() { + versionCache.clear(); +} +function getCachedVersion(baseUrl) { + return versionCache.get(baseUrl) || null; +} +function setCachedVersion(baseUrl, version) { + versionCache.set(baseUrl, version); +} +function cleanSettingsForVersion(settings, version) { + if (!settings || typeof settings !== 'object') { + return {}; + } + if (!version) { + return settings; + } + const supportedProperties = getSupportedSettingsProperties(version); + const cleaned = {}; + for (const [key, value] of Object.entries(settings)) { + if (supportedProperties.has(key)) { + cleaned[key] = value; + } + else { + logger_1.logger.debug(`Filtered out unsupported settings property: ${key} (n8n ${version.version})`); + } + } + return cleaned; +} +exports.VERSION_THRESHOLDS = { + EXECUTION_ORDER: { major: 1, minor: 37, patch: 0 }, + CALLER_POLICY: { major: 1, minor: 119, patch: 0 }, +}; +//# sourceMappingURL=n8n-version.js.map \ No newline at end of file diff --git a/dist/services/n8n-version.js.map b/dist/services/n8n-version.js.map new file mode 100644 index 0000000..3f9c475 --- /dev/null +++ b/dist/services/n8n-version.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-version.js","sourceRoot":"","sources":["../../src/services/n8n-version.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/node-documentation-service.d.ts b/dist/services/node-documentation-service.d.ts new file mode 100644 index 0000000..c740856 --- /dev/null +++ b/dist/services/node-documentation-service.d.ts @@ -0,0 +1,70 @@ +import { OperationInfo, ApiMethodMapping, CodeExample, TemplateInfo, RelatedResource } from '../utils/enhanced-documentation-fetcher'; +interface NodeInfo { + nodeType: string; + name: string; + displayName: string; + description: string; + category?: string; + subcategory?: string; + icon?: string; + sourceCode: string; + credentialCode?: string; + documentationMarkdown?: string; + documentationUrl?: string; + documentationTitle?: string; + operations?: OperationInfo[]; + apiMethods?: ApiMethodMapping[]; + documentationExamples?: CodeExample[]; + templates?: TemplateInfo[]; + relatedResources?: RelatedResource[]; + requiredScopes?: string[]; + exampleWorkflow?: any; + exampleParameters?: any; + propertiesSchema?: any; + packageName: string; + version?: string; + codexData?: any; + aliases?: string[]; + hasCredentials: boolean; + isTrigger: boolean; + isWebhook: boolean; +} +interface SearchOptions { + query?: string; + nodeType?: string; + packageName?: string; + category?: string; + hasCredentials?: boolean; + isTrigger?: boolean; + limit?: number; +} +export declare class NodeDocumentationService { + private db; + private extractor; + private docsFetcher; + private dbPath; + private initialized; + constructor(dbPath?: string); + private findDatabasePath; + private initializeAsync; + private ensureInitialized; + private initializeDatabase; + storeNode(nodeInfo: NodeInfo): Promise; + getNodeInfo(nodeType: string): Promise; + searchNodes(options: SearchOptions): Promise; + listNodes(): Promise; + rebuildDatabase(): Promise<{ + total: number; + successful: number; + failed: number; + errors: string[]; + }>; + private parseNodeDefinition; + private rowToNodeInfo; + private generateHash; + private storeStatistics; + getStatistics(): Promise; + close(): Promise; +} +export {}; +//# sourceMappingURL=node-documentation-service.d.ts.map \ No newline at end of file diff --git a/dist/services/node-documentation-service.d.ts.map b/dist/services/node-documentation-service.d.ts.map new file mode 100644 index 0000000..2a5251a --- /dev/null +++ b/dist/services/node-documentation-service.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"node-documentation-service.d.ts","sourceRoot":"","sources":["../../src/services/node-documentation-service.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/node-documentation-service.js b/dist/services/node-documentation-service.js new file mode 100644 index 0000000..b6dc092 --- /dev/null +++ b/dist/services/node-documentation-service.js @@ -0,0 +1,518 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.NodeDocumentationService = void 0; +const crypto_1 = require("crypto"); +const path_1 = __importDefault(require("path")); +const logger_1 = require("../utils/logger"); +const node_source_extractor_1 = require("../utils/node-source-extractor"); +const enhanced_documentation_fetcher_1 = require("../utils/enhanced-documentation-fetcher"); +const example_generator_1 = require("../utils/example-generator"); +const database_adapter_1 = require("../database/database-adapter"); +class NodeDocumentationService { + constructor(dbPath) { + this.db = null; + this.dbPath = dbPath || process.env.NODE_DB_PATH || this.findDatabasePath(); + const dbDir = path_1.default.dirname(this.dbPath); + if (!require('fs').existsSync(dbDir)) { + require('fs').mkdirSync(dbDir, { recursive: true }); + } + this.extractor = new node_source_extractor_1.NodeSourceExtractor(); + this.docsFetcher = new enhanced_documentation_fetcher_1.EnhancedDocumentationFetcher(); + this.initialized = this.initializeAsync(); + } + findDatabasePath() { + const fs = require('fs'); + const localPath = path_1.default.join(process.cwd(), 'data', 'nodes.db'); + if (fs.existsSync(localPath)) { + return localPath; + } + const packagePath = path_1.default.join(__dirname, '..', '..', 'data', 'nodes.db'); + if (fs.existsSync(packagePath)) { + return packagePath; + } + const globalPath = path_1.default.join(__dirname, '..', '..', '..', 'data', 'nodes.db'); + if (fs.existsSync(globalPath)) { + return globalPath; + } + return localPath; + } + async initializeAsync() { + try { + this.db = await (0, database_adapter_1.createDatabaseAdapter)(this.dbPath); + this.initializeDatabase(); + logger_1.logger.info('Node Documentation Service initialized'); + } + catch (error) { + logger_1.logger.error('Failed to initialize database adapter', error); + throw error; + } + } + async ensureInitialized() { + await this.initialized; + if (!this.db) { + throw new Error('Database not initialized'); + } + } + initializeDatabase() { + if (!this.db) + throw new Error('Database not initialized'); + const schema = ` +-- Main nodes table with documentation and examples +CREATE TABLE IF NOT EXISTS nodes ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + node_type TEXT UNIQUE NOT NULL, + name TEXT NOT NULL, + display_name TEXT, + description TEXT, + category TEXT, + subcategory TEXT, + icon TEXT, + + -- Source code + source_code TEXT NOT NULL, + credential_code TEXT, + code_hash TEXT NOT NULL, + code_length INTEGER NOT NULL, + + -- Documentation + documentation_markdown TEXT, + documentation_url TEXT, + documentation_title TEXT, + + -- Enhanced documentation fields (stored as JSON) + operations TEXT, + api_methods TEXT, + documentation_examples TEXT, + templates TEXT, + related_resources TEXT, + required_scopes TEXT, + + -- Example usage + example_workflow TEXT, + example_parameters TEXT, + properties_schema TEXT, + + -- Metadata + package_name TEXT NOT NULL, + version TEXT, + codex_data TEXT, + aliases TEXT, + + -- Flags + has_credentials INTEGER DEFAULT 0, + is_trigger INTEGER DEFAULT 0, + is_webhook INTEGER DEFAULT 0, + + -- Timestamps + extracted_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP +); + +-- Indexes +CREATE INDEX IF NOT EXISTS idx_nodes_package_name ON nodes(package_name); +CREATE INDEX IF NOT EXISTS idx_nodes_category ON nodes(category); +CREATE INDEX IF NOT EXISTS idx_nodes_code_hash ON nodes(code_hash); +CREATE INDEX IF NOT EXISTS idx_nodes_name ON nodes(name); +CREATE INDEX IF NOT EXISTS idx_nodes_is_trigger ON nodes(is_trigger); + +-- Full Text Search +CREATE VIRTUAL TABLE IF NOT EXISTS nodes_fts USING fts5( + node_type, + name, + display_name, + description, + category, + documentation_markdown, + aliases, + content=nodes, + content_rowid=id +); + +-- Triggers for FTS +CREATE TRIGGER IF NOT EXISTS nodes_ai AFTER INSERT ON nodes +BEGIN + INSERT INTO nodes_fts(rowid, node_type, name, display_name, description, category, documentation_markdown, aliases) + VALUES (new.id, new.node_type, new.name, new.display_name, new.description, new.category, new.documentation_markdown, new.aliases); +END; + +CREATE TRIGGER IF NOT EXISTS nodes_ad AFTER DELETE ON nodes +BEGIN + DELETE FROM nodes_fts WHERE rowid = old.id; +END; + +CREATE TRIGGER IF NOT EXISTS nodes_au AFTER UPDATE ON nodes +BEGIN + DELETE FROM nodes_fts WHERE rowid = old.id; + INSERT INTO nodes_fts(rowid, node_type, name, display_name, description, category, documentation_markdown, aliases) + VALUES (new.id, new.node_type, new.name, new.display_name, new.description, new.category, new.documentation_markdown, new.aliases); +END; + +-- Documentation sources table +CREATE TABLE IF NOT EXISTS documentation_sources ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + source TEXT NOT NULL, + commit_hash TEXT, + fetched_at DATETIME DEFAULT CURRENT_TIMESTAMP +); + +-- Statistics table +CREATE TABLE IF NOT EXISTS extraction_stats ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + total_nodes INTEGER NOT NULL, + nodes_with_docs INTEGER NOT NULL, + nodes_with_examples INTEGER NOT NULL, + total_code_size INTEGER NOT NULL, + total_docs_size INTEGER NOT NULL, + extraction_date DATETIME DEFAULT CURRENT_TIMESTAMP +); + `; + this.db.exec(schema); + } + async storeNode(nodeInfo) { + await this.ensureInitialized(); + const hash = this.generateHash(nodeInfo.sourceCode); + const stmt = this.db.prepare(` + INSERT OR REPLACE INTO nodes ( + node_type, name, display_name, description, category, subcategory, icon, + source_code, credential_code, code_hash, code_length, + documentation_markdown, documentation_url, documentation_title, + operations, api_methods, documentation_examples, templates, related_resources, required_scopes, + example_workflow, example_parameters, properties_schema, + package_name, version, codex_data, aliases, + has_credentials, is_trigger, is_webhook + ) VALUES ( + @nodeType, @name, @displayName, @description, @category, @subcategory, @icon, + @sourceCode, @credentialCode, @hash, @codeLength, + @documentation, @documentationUrl, @documentationTitle, + @operations, @apiMethods, @documentationExamples, @templates, @relatedResources, @requiredScopes, + @exampleWorkflow, @exampleParameters, @propertiesSchema, + @packageName, @version, @codexData, @aliases, + @hasCredentials, @isTrigger, @isWebhook + ) + `); + stmt.run({ + nodeType: nodeInfo.nodeType, + name: nodeInfo.name, + displayName: nodeInfo.displayName || nodeInfo.name, + description: nodeInfo.description || '', + category: nodeInfo.category || 'Other', + subcategory: nodeInfo.subcategory || null, + icon: nodeInfo.icon || null, + sourceCode: nodeInfo.sourceCode, + credentialCode: nodeInfo.credentialCode || null, + hash, + codeLength: nodeInfo.sourceCode.length, + documentation: nodeInfo.documentationMarkdown || null, + documentationUrl: nodeInfo.documentationUrl || null, + documentationTitle: nodeInfo.documentationTitle || null, + operations: nodeInfo.operations ? JSON.stringify(nodeInfo.operations) : null, + apiMethods: nodeInfo.apiMethods ? JSON.stringify(nodeInfo.apiMethods) : null, + documentationExamples: nodeInfo.documentationExamples ? JSON.stringify(nodeInfo.documentationExamples) : null, + templates: nodeInfo.templates ? JSON.stringify(nodeInfo.templates) : null, + relatedResources: nodeInfo.relatedResources ? JSON.stringify(nodeInfo.relatedResources) : null, + requiredScopes: nodeInfo.requiredScopes ? JSON.stringify(nodeInfo.requiredScopes) : null, + exampleWorkflow: nodeInfo.exampleWorkflow ? JSON.stringify(nodeInfo.exampleWorkflow) : null, + exampleParameters: nodeInfo.exampleParameters ? JSON.stringify(nodeInfo.exampleParameters) : null, + propertiesSchema: nodeInfo.propertiesSchema ? JSON.stringify(nodeInfo.propertiesSchema) : null, + packageName: nodeInfo.packageName, + version: nodeInfo.version || null, + codexData: nodeInfo.codexData ? JSON.stringify(nodeInfo.codexData) : null, + aliases: nodeInfo.aliases ? JSON.stringify(nodeInfo.aliases) : null, + hasCredentials: nodeInfo.hasCredentials ? 1 : 0, + isTrigger: nodeInfo.isTrigger ? 1 : 0, + isWebhook: nodeInfo.isWebhook ? 1 : 0 + }); + } + async getNodeInfo(nodeType) { + await this.ensureInitialized(); + const stmt = this.db.prepare(` + SELECT * FROM nodes WHERE node_type = ? OR name = ? COLLATE NOCASE + `); + const row = stmt.get(nodeType, nodeType); + if (!row) + return null; + return this.rowToNodeInfo(row); + } + async searchNodes(options) { + await this.ensureInitialized(); + let query = 'SELECT * FROM nodes WHERE 1=1'; + const params = {}; + if (options.query) { + query += ` AND id IN ( + SELECT rowid FROM nodes_fts + WHERE nodes_fts MATCH @query + )`; + params.query = options.query; + } + if (options.nodeType) { + query += ' AND node_type LIKE @nodeType'; + params.nodeType = `%${options.nodeType}%`; + } + if (options.packageName) { + query += ' AND package_name = @packageName'; + params.packageName = options.packageName; + } + if (options.category) { + query += ' AND category = @category'; + params.category = options.category; + } + if (options.hasCredentials !== undefined) { + query += ' AND has_credentials = @hasCredentials'; + params.hasCredentials = options.hasCredentials ? 1 : 0; + } + if (options.isTrigger !== undefined) { + query += ' AND is_trigger = @isTrigger'; + params.isTrigger = options.isTrigger ? 1 : 0; + } + query += ' ORDER BY name LIMIT @limit'; + params.limit = options.limit || 20; + const stmt = this.db.prepare(query); + const rows = stmt.all(params); + return rows.map(row => this.rowToNodeInfo(row)); + } + async listNodes() { + await this.ensureInitialized(); + const stmt = this.db.prepare('SELECT * FROM nodes ORDER BY name'); + const rows = stmt.all(); + return rows.map(row => this.rowToNodeInfo(row)); + } + async rebuildDatabase() { + await this.ensureInitialized(); + logger_1.logger.info('Starting complete database rebuild...'); + this.db.exec('DELETE FROM nodes'); + this.db.exec('DELETE FROM extraction_stats'); + await this.docsFetcher.ensureDocsRepository(); + const stats = { + total: 0, + successful: 0, + failed: 0, + errors: [] + }; + try { + const availableNodes = await this.extractor.listAvailableNodes(); + stats.total = availableNodes.length; + logger_1.logger.info(`Found ${stats.total} nodes to process`); + const batchSize = 10; + for (let i = 0; i < availableNodes.length; i += batchSize) { + const batch = availableNodes.slice(i, i + batchSize); + await Promise.all(batch.map(async (node) => { + try { + const nodeType = `n8n-nodes-base.${node.name}`; + const nodeData = await this.extractor.extractNodeSource(nodeType); + if (!nodeData || !nodeData.sourceCode) { + throw new Error('Failed to extract node source'); + } + const nodeDefinition = this.parseNodeDefinition(nodeData.sourceCode); + const enhancedDocs = await this.docsFetcher.getEnhancedNodeDocumentation(nodeType); + const example = example_generator_1.ExampleGenerator.generateFromNodeDefinition(nodeDefinition); + const nodeInfo = { + nodeType: nodeType, + name: node.name, + displayName: nodeDefinition.displayName || node.displayName || node.name, + description: nodeDefinition.description || node.description || '', + category: nodeDefinition.category || 'Other', + subcategory: nodeDefinition.subcategory, + icon: nodeDefinition.icon, + sourceCode: nodeData.sourceCode, + credentialCode: nodeData.credentialCode, + documentationMarkdown: enhancedDocs?.markdown, + documentationUrl: enhancedDocs?.url, + documentationTitle: enhancedDocs?.title, + operations: enhancedDocs?.operations, + apiMethods: enhancedDocs?.apiMethods, + documentationExamples: enhancedDocs?.examples, + templates: enhancedDocs?.templates, + relatedResources: enhancedDocs?.relatedResources, + requiredScopes: enhancedDocs?.requiredScopes, + exampleWorkflow: example, + exampleParameters: example.nodes[0]?.parameters, + propertiesSchema: nodeDefinition.properties, + packageName: nodeData.packageInfo?.name || 'n8n-nodes-base', + version: nodeDefinition.version, + codexData: nodeDefinition.codex, + aliases: nodeDefinition.alias, + hasCredentials: !!nodeData.credentialCode, + isTrigger: node.name.toLowerCase().includes('trigger'), + isWebhook: node.name.toLowerCase().includes('webhook') + }; + await this.storeNode(nodeInfo); + stats.successful++; + logger_1.logger.debug(`Processed node: ${nodeType}`); + } + catch (error) { + stats.failed++; + const errorMsg = `Failed to process ${node.name}: ${error instanceof Error ? error.message : String(error)}`; + stats.errors.push(errorMsg); + logger_1.logger.error(errorMsg); + } + })); + logger_1.logger.info(`Progress: ${Math.min(i + batchSize, availableNodes.length)}/${stats.total} nodes processed`); + } + this.storeStatistics(stats); + logger_1.logger.info(`Database rebuild complete: ${stats.successful} successful, ${stats.failed} failed`); + } + catch (error) { + logger_1.logger.error('Database rebuild failed:', error); + throw error; + } + return stats; + } + parseNodeDefinition(sourceCode) { + const result = { + displayName: '', + description: '', + properties: [], + category: null, + subcategory: null, + icon: null, + version: null, + codex: null, + alias: null + }; + try { + const displayNameMatch = sourceCode.match(/displayName\s*[:=]\s*['"`]([^'"`]+)['"`]/); + if (displayNameMatch) { + result.displayName = displayNameMatch[1]; + } + const descriptionMatch = sourceCode.match(/description\s*[:=]\s*['"`]([^'"`]+)['"`]/); + if (descriptionMatch) { + result.description = descriptionMatch[1]; + } + const iconMatch = sourceCode.match(/icon\s*[:=]\s*['"`]([^'"`]+)['"`]/); + if (iconMatch) { + result.icon = iconMatch[1]; + } + const groupMatch = sourceCode.match(/group\s*[:=]\s*\[['"`]([^'"`]+)['"`]\]/); + if (groupMatch) { + result.category = groupMatch[1]; + } + const versionMatch = sourceCode.match(/version\s*[:=]\s*(\d+)/); + if (versionMatch) { + result.version = parseInt(versionMatch[1]); + } + const subtitleMatch = sourceCode.match(/subtitle\s*[:=]\s*['"`]([^'"`]+)['"`]/); + if (subtitleMatch) { + result.subtitle = subtitleMatch[1]; + } + const propsMatch = sourceCode.match(/properties\s*[:=]\s*(\[[\s\S]*?\])\s*[,}]/); + if (propsMatch) { + try { + result.properties = []; + } + catch (e) { + } + } + if (sourceCode.includes('implements.*ITrigger') || + sourceCode.includes('polling:.*true') || + sourceCode.includes('webhook:.*true') || + result.displayName.toLowerCase().includes('trigger')) { + result.isTrigger = true; + } + if (sourceCode.includes('webhooks:') || + sourceCode.includes('webhook:.*true') || + result.displayName.toLowerCase().includes('webhook')) { + result.isWebhook = true; + } + } + catch (error) { + logger_1.logger.debug('Error parsing node definition:', error); + } + return result; + } + rowToNodeInfo(row) { + return { + nodeType: row.node_type, + name: row.name, + displayName: row.display_name, + description: row.description, + category: row.category, + subcategory: row.subcategory, + icon: row.icon, + sourceCode: row.source_code, + credentialCode: row.credential_code, + documentationMarkdown: row.documentation_markdown, + documentationUrl: row.documentation_url, + documentationTitle: row.documentation_title, + operations: row.operations ? JSON.parse(row.operations) : null, + apiMethods: row.api_methods ? JSON.parse(row.api_methods) : null, + documentationExamples: row.documentation_examples ? JSON.parse(row.documentation_examples) : null, + templates: row.templates ? JSON.parse(row.templates) : null, + relatedResources: row.related_resources ? JSON.parse(row.related_resources) : null, + requiredScopes: row.required_scopes ? JSON.parse(row.required_scopes) : null, + exampleWorkflow: row.example_workflow ? JSON.parse(row.example_workflow) : null, + exampleParameters: row.example_parameters ? JSON.parse(row.example_parameters) : null, + propertiesSchema: row.properties_schema ? JSON.parse(row.properties_schema) : null, + packageName: row.package_name, + version: row.version, + codexData: row.codex_data ? JSON.parse(row.codex_data) : null, + aliases: row.aliases ? JSON.parse(row.aliases) : null, + hasCredentials: row.has_credentials === 1, + isTrigger: row.is_trigger === 1, + isWebhook: row.is_webhook === 1 + }; + } + generateHash(content) { + return (0, crypto_1.createHash)('sha256').update(content).digest('hex'); + } + storeStatistics(stats) { + if (!this.db) + throw new Error('Database not initialized'); + const stmt = this.db.prepare(` + INSERT INTO extraction_stats ( + total_nodes, nodes_with_docs, nodes_with_examples, + total_code_size, total_docs_size + ) VALUES (?, ?, ?, ?, ?) + `); + const sizeStats = this.db.prepare(` + SELECT + COUNT(*) as total, + SUM(CASE WHEN documentation_markdown IS NOT NULL THEN 1 ELSE 0 END) as with_docs, + SUM(CASE WHEN example_workflow IS NOT NULL THEN 1 ELSE 0 END) as with_examples, + SUM(code_length) as code_size, + SUM(LENGTH(documentation_markdown)) as docs_size + FROM nodes + `).get(); + stmt.run(stats.successful, sizeStats?.with_docs || 0, sizeStats?.with_examples || 0, sizeStats?.code_size || 0, sizeStats?.docs_size || 0); + } + async getStatistics() { + await this.ensureInitialized(); + const stats = this.db.prepare(` + SELECT + COUNT(*) as totalNodes, + COUNT(DISTINCT package_name) as totalPackages, + SUM(code_length) as totalCodeSize, + SUM(CASE WHEN documentation_markdown IS NOT NULL THEN 1 ELSE 0 END) as nodesWithDocs, + SUM(CASE WHEN example_workflow IS NOT NULL THEN 1 ELSE 0 END) as nodesWithExamples, + SUM(has_credentials) as nodesWithCredentials, + SUM(is_trigger) as triggerNodes, + SUM(is_webhook) as webhookNodes + FROM nodes + `).get(); + const packages = this.db.prepare(` + SELECT package_name as package, COUNT(*) as count + FROM nodes + GROUP BY package_name + ORDER BY count DESC + `).all(); + return { + totalNodes: stats?.totalNodes || 0, + totalPackages: stats?.totalPackages || 0, + totalCodeSize: stats?.totalCodeSize || 0, + nodesWithDocs: stats?.nodesWithDocs || 0, + nodesWithExamples: stats?.nodesWithExamples || 0, + nodesWithCredentials: stats?.nodesWithCredentials || 0, + triggerNodes: stats?.triggerNodes || 0, + webhookNodes: stats?.webhookNodes || 0, + packageDistribution: packages + }; + } + async close() { + await this.ensureInitialized(); + this.db.close(); + } +} +exports.NodeDocumentationService = NodeDocumentationService; +//# sourceMappingURL=node-documentation-service.js.map \ No newline at end of file diff --git a/dist/services/node-documentation-service.js.map b/dist/services/node-documentation-service.js.map new file mode 100644 index 0000000..bca0fe5 --- /dev/null +++ b/dist/services/node-documentation-service.js.map @@ -0,0 +1 @@ +{"version":3,"file":"node-documentation-service.js","sourceRoot":"","sources":["../../src/services/node-documentation-service.ts"],"names":[],"mappings":";;;;;;AAAA,mCAAoC;AACpC,gDAAwB;AAExB,4CAAyC;AACzC,0EAAqE;AACrE,4FAQiD;AACjD,kEAA8D;AAC9D,mEAAsF;AA2CtF,MAAa,wBAAwB;IAOnC,YAAY,MAAe;QANnB,OAAE,GAA2B,IAAI,CAAC;QAQxC,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAG5E,MAAM,KAAK,GAAG,cAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YACrC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,IAAI,CAAC,SAAS,GAAG,IAAI,2CAAmB,EAAE,CAAC;QAC3C,IAAI,CAAC,WAAW,GAAG,IAAI,6DAA4B,EAAE,CAAC;QAGtD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;IAC5C,CAAC;IAEO,gBAAgB;QACtB,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAIzB,MAAM,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QAC/D,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,OAAO,SAAS,CAAC;QACnB,CAAC;QAGD,MAAM,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACzE,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/B,OAAO,WAAW,CAAC;QACrB,CAAC;QAGD,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QAC9E,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,OAAO,UAAU,CAAC;QACpB,CAAC;QAGD,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,KAAK,CAAC,eAAe;QAC3B,IAAI,CAAC;YACH,IAAI,CAAC,EAAE,GAAG,MAAM,IAAA,wCAAqB,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAGnD,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAE1B,eAAM,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;QACxD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAM,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAC;YAC7D,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,iBAAiB;QAC7B,MAAM,IAAI,CAAC,WAAW,CAAC;QACvB,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAE1D,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA6Gd,CAAC;QAEF,IAAI,CAAC,EAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;IAKD,KAAK,CAAC,SAAS,CAAC,QAAkB;QAChC,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAEpD,MAAM,IAAI,GAAG,IAAI,CAAC,EAAG,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;KAkB7B,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC;YACP,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,WAAW,EAAE,QAAQ,CAAC,WAAW,IAAI,QAAQ,CAAC,IAAI;YAClD,WAAW,EAAE,QAAQ,CAAC,WAAW,IAAI,EAAE;YACvC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,IAAI,OAAO;YACtC,WAAW,EAAE,QAAQ,CAAC,WAAW,IAAI,IAAI;YACzC,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,IAAI;YAC3B,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,cAAc,EAAE,QAAQ,CAAC,cAAc,IAAI,IAAI;YAC/C,IAAI;YACJ,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC,MAAM;YACtC,aAAa,EAAE,QAAQ,CAAC,qBAAqB,IAAI,IAAI;YACrD,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB,IAAI,IAAI;YACnD,kBAAkB,EAAE,QAAQ,CAAC,kBAAkB,IAAI,IAAI;YACvD,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI;YAC5E,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI;YAC5E,qBAAqB,EAAE,QAAQ,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,IAAI;YAC7G,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI;YACzE,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI;YAC9F,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI;YACxF,eAAe,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI;YAC3F,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI;YACjG,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI;YAC9F,WAAW,EAAE,QAAQ,CAAC,WAAW;YACjC,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,IAAI;YACjC,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI;YACzE,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI;YACnE,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/C,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACrC,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACtC,CAAC,CAAC;IACL,CAAC;IAKD,KAAK,CAAC,WAAW,CAAC,QAAgB;QAChC,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,EAAG,CAAC,OAAO,CAAC;;KAE7B,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACzC,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QAEtB,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAKD,KAAK,CAAC,WAAW,CAAC,OAAsB;QACtC,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/B,IAAI,KAAK,GAAG,+BAA+B,CAAC;QAC5C,MAAM,MAAM,GAAQ,EAAE,CAAC;QAEvB,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,KAAK,IAAI;;;QAGP,CAAC;YACH,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC/B,CAAC;QAED,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,KAAK,IAAI,+BAA+B,CAAC;YACzC,MAAM,CAAC,QAAQ,GAAG,IAAI,OAAO,CAAC,QAAQ,GAAG,CAAC;QAC5C,CAAC;QAED,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YACxB,KAAK,IAAI,kCAAkC,CAAC;YAC5C,MAAM,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QAC3C,CAAC;QAED,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,KAAK,IAAI,2BAA2B,CAAC;YACrC,MAAM,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACrC,CAAC;QAED,IAAI,OAAO,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;YACzC,KAAK,IAAI,wCAAwC,CAAC;YAClD,MAAM,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,CAAC;QAED,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACpC,KAAK,IAAI,8BAA8B,CAAC;YACxC,MAAM,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/C,CAAC;QAED,KAAK,IAAI,6BAA6B,CAAC;QACvC,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;QAEnC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAE9B,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;IAClD,CAAC;IAKD,KAAK,CAAC,SAAS;QACb,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,EAAG,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC;QACnE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;IAClD,CAAC;IAKD,KAAK,CAAC,eAAe;QAMnB,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/B,eAAM,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;QAGrD,IAAI,CAAC,EAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACnC,IAAI,CAAC,EAAG,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;QAG9C,MAAM,IAAI,CAAC,WAAW,CAAC,oBAAoB,EAAE,CAAC;QAE9C,MAAM,KAAK,GAAG;YACZ,KAAK,EAAE,CAAC;YACR,UAAU,EAAE,CAAC;YACb,MAAM,EAAE,CAAC;YACT,MAAM,EAAE,EAAc;SACvB,CAAC;QAEF,IAAI,CAAC;YAEH,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE,CAAC;YACjE,KAAK,CAAC,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC;YAEpC,eAAM,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,KAAK,mBAAmB,CAAC,CAAC;YAGrD,MAAM,SAAS,GAAG,EAAE,CAAC;YACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;gBAC1D,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC;gBAErD,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;oBACzC,IAAI,CAAC;wBAEH,MAAM,QAAQ,GAAG,kBAAkB,IAAI,CAAC,IAAI,EAAE,CAAC;wBAG/C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;wBAClE,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;4BACtC,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;wBACnD,CAAC;wBAGD,MAAM,cAAc,GAAG,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;wBAGrE,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,4BAA4B,CAAC,QAAQ,CAAC,CAAC;wBAGnF,MAAM,OAAO,GAAG,oCAAgB,CAAC,0BAA0B,CAAC,cAAc,CAAC,CAAC;wBAG5E,MAAM,QAAQ,GAAa;4BACzB,QAAQ,EAAE,QAAQ;4BAClB,IAAI,EAAE,IAAI,CAAC,IAAI;4BACf,WAAW,EAAE,cAAc,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,IAAI;4BACxE,WAAW,EAAE,cAAc,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE;4BACjE,QAAQ,EAAE,cAAc,CAAC,QAAQ,IAAI,OAAO;4BAC5C,WAAW,EAAE,cAAc,CAAC,WAAW;4BACvC,IAAI,EAAE,cAAc,CAAC,IAAI;4BACzB,UAAU,EAAE,QAAQ,CAAC,UAAU;4BAC/B,cAAc,EAAE,QAAQ,CAAC,cAAc;4BACvC,qBAAqB,EAAE,YAAY,EAAE,QAAQ;4BAC7C,gBAAgB,EAAE,YAAY,EAAE,GAAG;4BACnC,kBAAkB,EAAE,YAAY,EAAE,KAAK;4BACvC,UAAU,EAAE,YAAY,EAAE,UAAU;4BACpC,UAAU,EAAE,YAAY,EAAE,UAAU;4BACpC,qBAAqB,EAAE,YAAY,EAAE,QAAQ;4BAC7C,SAAS,EAAE,YAAY,EAAE,SAAS;4BAClC,gBAAgB,EAAE,YAAY,EAAE,gBAAgB;4BAChD,cAAc,EAAE,YAAY,EAAE,cAAc;4BAC5C,eAAe,EAAE,OAAO;4BACxB,iBAAiB,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,UAAU;4BAC/C,gBAAgB,EAAE,cAAc,CAAC,UAAU;4BAC3C,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,IAAI,gBAAgB;4BAC3D,OAAO,EAAE,cAAc,CAAC,OAAO;4BAC/B,SAAS,EAAE,cAAc,CAAC,KAAK;4BAC/B,OAAO,EAAE,cAAc,CAAC,KAAK;4BAC7B,cAAc,EAAE,CAAC,CAAC,QAAQ,CAAC,cAAc;4BACzC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;4BACtD,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;yBACvD,CAAC;wBAGF,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;wBAE/B,KAAK,CAAC,UAAU,EAAE,CAAC;wBACnB,eAAM,CAAC,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;oBAC9C,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,KAAK,CAAC,MAAM,EAAE,CAAC;wBACf,MAAM,QAAQ,GAAG,qBAAqB,IAAI,CAAC,IAAI,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;wBAC7G,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;wBAC5B,eAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;oBACzB,CAAC;gBACH,CAAC,CAAC,CAAC,CAAC;gBAEJ,eAAM,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,EAAE,cAAc,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,kBAAkB,CAAC,CAAC;YAC5G,CAAC;YAGD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAE5B,eAAM,CAAC,IAAI,CAAC,8BAA8B,KAAK,CAAC,UAAU,gBAAgB,KAAK,CAAC,MAAM,SAAS,CAAC,CAAC;QAEnG,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAM,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;YAChD,MAAM,KAAK,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAKO,mBAAmB,CAAC,UAAkB;QAC5C,MAAM,MAAM,GAAQ;YAClB,WAAW,EAAE,EAAE;YACf,WAAW,EAAE,EAAE;YACf,UAAU,EAAE,EAAE;YACd,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE,IAAI;YACjB,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,IAAI;YACX,KAAK,EAAE,IAAI;SACZ,CAAC;QAEF,IAAI,CAAC;YAIH,MAAM,gBAAgB,GAAG,UAAU,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;YACtF,IAAI,gBAAgB,EAAE,CAAC;gBACrB,MAAM,CAAC,WAAW,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;YAC3C,CAAC;YAGD,MAAM,gBAAgB,GAAG,UAAU,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;YACtF,IAAI,gBAAgB,EAAE,CAAC;gBACrB,MAAM,CAAC,WAAW,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;YAC3C,CAAC;YAGD,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;YACxE,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YAC7B,CAAC;YAGD,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;YAC9E,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,CAAC,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YAClC,CAAC;YAGD,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;YAChE,IAAI,YAAY,EAAE,CAAC;gBACjB,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7C,CAAC;YAGD,MAAM,aAAa,GAAG,UAAU,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;YAChF,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,CAAC,QAAQ,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;YACrC,CAAC;YAGD,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;YACjF,IAAI,UAAU,EAAE,CAAC;gBACf,IAAI,CAAC;oBAEH,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC;gBACzB,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;gBAEb,CAAC;YACH,CAAC;YAGD,IAAI,UAAU,CAAC,QAAQ,CAAC,sBAAsB,CAAC;gBAC3C,UAAU,CAAC,QAAQ,CAAC,gBAAgB,CAAC;gBACrC,UAAU,CAAC,QAAQ,CAAC,gBAAgB,CAAC;gBACrC,MAAM,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBACzD,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC;YAC1B,CAAC;YAGD,IAAI,UAAU,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAChC,UAAU,CAAC,QAAQ,CAAC,gBAAgB,CAAC;gBACrC,MAAM,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBACzD,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC;YAC1B,CAAC;QAEH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;QACxD,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAKO,aAAa,CAAC,GAAQ;QAC5B,OAAO;YACL,QAAQ,EAAE,GAAG,CAAC,SAAS;YACvB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,WAAW,EAAE,GAAG,CAAC,YAAY;YAC7B,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,UAAU,EAAE,GAAG,CAAC,WAAW;YAC3B,cAAc,EAAE,GAAG,CAAC,eAAe;YACnC,qBAAqB,EAAE,GAAG,CAAC,sBAAsB;YACjD,gBAAgB,EAAE,GAAG,CAAC,iBAAiB;YACvC,kBAAkB,EAAE,GAAG,CAAC,mBAAmB;YAC3C,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI;YAC9D,UAAU,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI;YAChE,qBAAqB,EAAE,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,IAAI;YACjG,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI;YAC3D,gBAAgB,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI;YAClF,cAAc,EAAE,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI;YAC5E,eAAe,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI;YAC/E,iBAAiB,EAAE,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,IAAI;YACrF,gBAAgB,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI;YAClF,WAAW,EAAE,GAAG,CAAC,YAAY;YAC7B,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,SAAS,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI;YAC7D,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI;YACrD,cAAc,EAAE,GAAG,CAAC,eAAe,KAAK,CAAC;YACzC,SAAS,EAAE,GAAG,CAAC,UAAU,KAAK,CAAC;YAC/B,SAAS,EAAE,GAAG,CAAC,UAAU,KAAK,CAAC;SAChC,CAAC;IACJ,CAAC;IAKO,YAAY,CAAC,OAAe;QAClC,OAAO,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5D,CAAC;IAKO,eAAe,CAAC,KAAU;QAChC,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;;;;;KAK5B,CAAC,CAAC;QAGH,MAAM,SAAS,GAAG,IAAI,CAAC,EAAG,CAAC,OAAO,CAAC;;;;;;;;KAQlC,CAAC,CAAC,GAAG,EAAS,CAAC;QAEhB,IAAI,CAAC,GAAG,CACN,KAAK,CAAC,UAAU,EAChB,SAAS,EAAE,SAAS,IAAI,CAAC,EACzB,SAAS,EAAE,aAAa,IAAI,CAAC,EAC7B,SAAS,EAAE,SAAS,IAAI,CAAC,EACzB,SAAS,EAAE,SAAS,IAAI,CAAC,CAC1B,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,aAAa;QACjB,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,EAAG,CAAC,OAAO,CAAC;;;;;;;;;;;KAW9B,CAAC,CAAC,GAAG,EAAS,CAAC;QAEhB,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAG,CAAC,OAAO,CAAC;;;;;KAKjC,CAAC,CAAC,GAAG,EAAE,CAAC;QAET,OAAO;YACL,UAAU,EAAE,KAAK,EAAE,UAAU,IAAI,CAAC;YAClC,aAAa,EAAE,KAAK,EAAE,aAAa,IAAI,CAAC;YACxC,aAAa,EAAE,KAAK,EAAE,aAAa,IAAI,CAAC;YACxC,aAAa,EAAE,KAAK,EAAE,aAAa,IAAI,CAAC;YACxC,iBAAiB,EAAE,KAAK,EAAE,iBAAiB,IAAI,CAAC;YAChD,oBAAoB,EAAE,KAAK,EAAE,oBAAoB,IAAI,CAAC;YACtD,YAAY,EAAE,KAAK,EAAE,YAAY,IAAI,CAAC;YACtC,YAAY,EAAE,KAAK,EAAE,YAAY,IAAI,CAAC;YACtC,mBAAmB,EAAE,QAAQ;SAC9B,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/B,IAAI,CAAC,EAAG,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;CACF;AA3oBD,4DA2oBC"} \ No newline at end of file diff --git a/dist/services/node-migration-service.d.ts b/dist/services/node-migration-service.d.ts new file mode 100644 index 0000000..489608e --- /dev/null +++ b/dist/services/node-migration-service.d.ts @@ -0,0 +1,44 @@ +import { BreakingChangeDetector } from './breaking-change-detector'; +import { NodeVersionService } from './node-version-service'; +export interface MigrationResult { + success: boolean; + nodeId: string; + nodeName: string; + fromVersion: string; + toVersion: string; + appliedMigrations: AppliedMigration[]; + remainingIssues: string[]; + confidence: 'HIGH' | 'MEDIUM' | 'LOW'; + updatedNode: any; +} +export interface AppliedMigration { + propertyName: string; + action: string; + oldValue?: any; + newValue?: any; + description: string; +} +export declare class NodeMigrationService { + private versionService; + private breakingChangeDetector; + constructor(versionService: NodeVersionService, breakingChangeDetector: BreakingChangeDetector); + migrateNode(node: any, fromVersion: string, toVersion: string): Promise; + private applyMigration; + private addProperty; + private removeProperty; + private renameProperty; + private setDefault; + private resolveDefaultValue; + private parseVersion; + validateMigratedNode(node: any, nodeType: string): Promise<{ + valid: boolean; + errors: string[]; + warnings: string[]; + }>; + migrateWorkflowNodes(workflow: any, targetVersions: Record): Promise<{ + success: boolean; + results: MigrationResult[]; + overallConfidence: 'HIGH' | 'MEDIUM' | 'LOW'; + }>; +} +//# sourceMappingURL=node-migration-service.d.ts.map \ No newline at end of file diff --git a/dist/services/node-migration-service.d.ts.map b/dist/services/node-migration-service.d.ts.map new file mode 100644 index 0000000..7431277 --- /dev/null +++ b/dist/services/node-migration-service.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"node-migration-service.d.ts","sourceRoot":"","sources":["../../src/services/node-migration-service.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,sBAAsB,EAAkB,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;IACtC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,WAAW,EAAE,GAAG,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,oBAAoB;IAE7B,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,sBAAsB;gBADtB,cAAc,EAAE,kBAAkB,EAClC,sBAAsB,EAAE,sBAAsB;IAMlD,WAAW,CACf,IAAI,EAAE,GAAG,EACT,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC;IA4D3B,OAAO,CAAC,cAAc;IA0BtB,OAAO,CAAC,WAAW;IAkCnB,OAAO,CAAC,cAAc;IAkCtB,OAAO,CAAC,cAAc;IAiDtB,OAAO,CAAC,UAAU;IAqClB,OAAO,CAAC,mBAAmB;IAoB3B,OAAO,CAAC,YAAY;IAcd,oBAAoB,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAC/D,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;IAuCI,oBAAoB,CACxB,QAAQ,EAAE,GAAG,EACb,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACrC,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,eAAe,EAAE,CAAC;QAC3B,iBAAiB,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;KAC9C,CAAC;CAmCH"} \ No newline at end of file diff --git a/dist/services/node-migration-service.js b/dist/services/node-migration-service.js new file mode 100644 index 0000000..242478e --- /dev/null +++ b/dist/services/node-migration-service.js @@ -0,0 +1,231 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.NodeMigrationService = void 0; +const uuid_1 = require("uuid"); +class NodeMigrationService { + constructor(versionService, breakingChangeDetector) { + this.versionService = versionService; + this.breakingChangeDetector = breakingChangeDetector; + } + async migrateNode(node, fromVersion, toVersion) { + const nodeId = node.id || 'unknown'; + const nodeName = node.name || 'Unknown Node'; + const nodeType = node.type; + const analysis = await this.breakingChangeDetector.analyzeVersionUpgrade(nodeType, fromVersion, toVersion); + const migratedNode = JSON.parse(JSON.stringify(node)); + migratedNode.typeVersion = this.parseVersion(toVersion); + const appliedMigrations = []; + const remainingIssues = []; + for (const change of analysis.changes.filter(c => c.autoMigratable)) { + const migration = this.applyMigration(migratedNode, change); + if (migration) { + appliedMigrations.push(migration); + } + } + for (const change of analysis.changes.filter(c => !c.autoMigratable)) { + remainingIssues.push(`Manual action required for "${change.propertyName}": ${change.migrationHint}`); + } + let confidence = 'HIGH'; + if (remainingIssues.length > 0) { + confidence = remainingIssues.length > 3 ? 'LOW' : 'MEDIUM'; + } + return { + success: remainingIssues.length === 0, + nodeId, + nodeName, + fromVersion, + toVersion, + appliedMigrations, + remainingIssues, + confidence, + updatedNode: migratedNode + }; + } + applyMigration(node, change) { + if (!change.migrationStrategy) + return null; + const { type, defaultValue, sourceProperty, targetProperty } = change.migrationStrategy; + switch (type) { + case 'add_property': + return this.addProperty(node, change.propertyName, defaultValue, change); + case 'remove_property': + return this.removeProperty(node, change.propertyName, change); + case 'rename_property': + return this.renameProperty(node, sourceProperty, targetProperty, change); + case 'set_default': + return this.setDefault(node, change.propertyName, defaultValue, change); + default: + return null; + } + } + addProperty(node, propertyPath, defaultValue, change) { + const value = this.resolveDefaultValue(propertyPath, defaultValue, node); + const parts = propertyPath.split('.'); + let target = node; + for (let i = 0; i < parts.length - 1; i++) { + const part = parts[i]; + if (!target[part]) { + target[part] = {}; + } + target = target[part]; + } + const finalKey = parts[parts.length - 1]; + target[finalKey] = value; + return { + propertyName: propertyPath, + action: 'Added property', + newValue: value, + description: `Added "${propertyPath}" with default value` + }; + } + removeProperty(node, propertyPath, change) { + const parts = propertyPath.split('.'); + let target = node; + for (let i = 0; i < parts.length - 1; i++) { + const part = parts[i]; + if (!target[part]) + return null; + target = target[part]; + } + const finalKey = parts[parts.length - 1]; + const oldValue = target[finalKey]; + if (oldValue !== undefined) { + delete target[finalKey]; + return { + propertyName: propertyPath, + action: 'Removed property', + oldValue, + description: `Removed deprecated property "${propertyPath}"` + }; + } + return null; + } + renameProperty(node, sourcePath, targetPath, change) { + const sourceParts = sourcePath.split('.'); + let sourceTarget = node; + for (let i = 0; i < sourceParts.length - 1; i++) { + if (!sourceTarget[sourceParts[i]]) + return null; + sourceTarget = sourceTarget[sourceParts[i]]; + } + const sourceKey = sourceParts[sourceParts.length - 1]; + const oldValue = sourceTarget[sourceKey]; + if (oldValue === undefined) + return null; + const targetParts = targetPath.split('.'); + let targetTarget = node; + for (let i = 0; i < targetParts.length - 1; i++) { + if (!targetTarget[targetParts[i]]) { + targetTarget[targetParts[i]] = {}; + } + targetTarget = targetTarget[targetParts[i]]; + } + const targetKey = targetParts[targetParts.length - 1]; + targetTarget[targetKey] = oldValue; + delete sourceTarget[sourceKey]; + return { + propertyName: targetPath, + action: 'Renamed property', + oldValue: `${sourcePath}: ${JSON.stringify(oldValue)}`, + newValue: `${targetPath}: ${JSON.stringify(oldValue)}`, + description: `Renamed "${sourcePath}" to "${targetPath}"` + }; + } + setDefault(node, propertyPath, defaultValue, change) { + const parts = propertyPath.split('.'); + let target = node; + for (let i = 0; i < parts.length - 1; i++) { + if (!target[parts[i]]) { + target[parts[i]] = {}; + } + target = target[parts[i]]; + } + const finalKey = parts[parts.length - 1]; + if (target[finalKey] === undefined) { + const value = this.resolveDefaultValue(propertyPath, defaultValue, node); + target[finalKey] = value; + return { + propertyName: propertyPath, + action: 'Set default value', + newValue: value, + description: `Set default value for "${propertyPath}"` + }; + } + return null; + } + resolveDefaultValue(propertyPath, defaultValue, node) { + if (propertyPath === 'webhookId' || propertyPath.endsWith('.webhookId')) { + return (0, uuid_1.v4)(); + } + if (propertyPath === 'path' || propertyPath.endsWith('.path')) { + if (node.type === 'n8n-nodes-base.webhook') { + return `/webhook-${Date.now()}`; + } + } + return defaultValue !== null && defaultValue !== undefined ? defaultValue : null; + } + parseVersion(version) { + const parts = version.split('.').map(Number); + if (parts.length === 1) + return parts[0]; + if (parts.length === 2) + return parts[0] + parts[1] / 10; + return parts[0]; + } + async validateMigratedNode(node, nodeType) { + const errors = []; + const warnings = []; + if (!node.typeVersion) { + errors.push('Missing typeVersion after migration'); + } + if (!node.parameters) { + errors.push('Missing parameters object'); + } + if (nodeType === 'n8n-nodes-base.webhook') { + if (!node.parameters?.path) { + errors.push('Webhook node missing required "path" parameter'); + } + if (node.typeVersion >= 2.1 && !node.webhookId) { + warnings.push('Webhook v2.1+ typically requires webhookId'); + } + } + if (nodeType === 'n8n-nodes-base.executeWorkflow') { + if (node.typeVersion >= 1.1 && !node.parameters?.inputFieldMapping) { + errors.push('Execute Workflow v1.1+ requires inputFieldMapping'); + } + } + return { + valid: errors.length === 0, + errors, + warnings + }; + } + async migrateWorkflowNodes(workflow, targetVersions) { + const results = []; + for (const node of workflow.nodes || []) { + const targetVersion = targetVersions[node.id]; + if (targetVersion && node.typeVersion) { + const currentVersion = node.typeVersion.toString(); + const result = await this.migrateNode(node, currentVersion, targetVersion); + results.push(result); + Object.assign(node, result.updatedNode); + } + } + const confidences = results.map(r => r.confidence); + let overallConfidence = 'HIGH'; + if (confidences.includes('LOW')) { + overallConfidence = 'LOW'; + } + else if (confidences.includes('MEDIUM')) { + overallConfidence = 'MEDIUM'; + } + const success = results.every(r => r.success); + return { + success, + results, + overallConfidence + }; + } +} +exports.NodeMigrationService = NodeMigrationService; +//# sourceMappingURL=node-migration-service.js.map \ No newline at end of file diff --git a/dist/services/node-migration-service.js.map b/dist/services/node-migration-service.js.map new file mode 100644 index 0000000..45be291 --- /dev/null +++ b/dist/services/node-migration-service.js.map @@ -0,0 +1 @@ +{"version":3,"file":"node-migration-service.js","sourceRoot":"","sources":["../../src/services/node-migration-service.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/node-sanitizer.d.ts b/dist/services/node-sanitizer.d.ts new file mode 100644 index 0000000..0c3eeb2 --- /dev/null +++ b/dist/services/node-sanitizer.d.ts @@ -0,0 +1,5 @@ +import { WorkflowNode } from '../types/n8n-api'; +export declare function sanitizeNode(node: WorkflowNode): WorkflowNode; +export declare function sanitizeWorkflowNodes(workflow: any): any; +export declare function validateNodeMetadata(node: WorkflowNode): string[]; +//# sourceMappingURL=node-sanitizer.d.ts.map \ No newline at end of file diff --git a/dist/services/node-sanitizer.d.ts.map b/dist/services/node-sanitizer.d.ts.map new file mode 100644 index 0000000..3a8bd7d --- /dev/null +++ b/dist/services/node-sanitizer.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"node-sanitizer.d.ts","sourceRoot":"","sources":["../../src/services/node-sanitizer.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAKhD,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,YAAY,CAa7D;AAKD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG,CASxD;AAoND,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,EAAE,CAgEjE"} \ No newline at end of file diff --git a/dist/services/node-sanitizer.js b/dist/services/node-sanitizer.js new file mode 100644 index 0000000..428a82d --- /dev/null +++ b/dist/services/node-sanitizer.js @@ -0,0 +1,225 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sanitizeNode = sanitizeNode; +exports.sanitizeWorkflowNodes = sanitizeWorkflowNodes; +exports.validateNodeMetadata = validateNodeMetadata; +const logger_1 = require("../utils/logger"); +function sanitizeNode(node) { + const sanitized = { ...node }; + if (isFilterBasedNode(node.type, node.typeVersion)) { + sanitized.parameters = sanitizeFilterBasedNode(sanitized.parameters, node.type, node.typeVersion); + } + return sanitized; +} +function sanitizeWorkflowNodes(workflow) { + if (!workflow.nodes || !Array.isArray(workflow.nodes)) { + return workflow; + } + return { + ...workflow, + nodes: workflow.nodes.map((node) => sanitizeNode(node)) + }; +} +function isFilterBasedNode(nodeType, typeVersion) { + if (nodeType === 'n8n-nodes-base.if') { + return typeVersion >= 2.2; + } + if (nodeType === 'n8n-nodes-base.switch') { + return typeVersion >= 3.2; + } + return false; +} +function sanitizeFilterBasedNode(parameters, nodeType, typeVersion) { + const sanitized = { ...parameters }; + if (nodeType === 'n8n-nodes-base.if' && typeVersion >= 2.2) { + sanitized.conditions = sanitizeFilterConditions(sanitized.conditions); + } + if (nodeType === 'n8n-nodes-base.switch' && typeVersion >= 3.2) { + if (sanitized.rules && typeof sanitized.rules === 'object') { + const rules = sanitized.rules; + if (rules.rules && Array.isArray(rules.rules)) { + rules.rules = rules.rules.map((rule) => ({ + ...rule, + conditions: sanitizeFilterConditions(rule.conditions) + })); + } + } + } + return sanitized; +} +function sanitizeFilterConditions(conditions) { + if (!conditions || typeof conditions !== 'object') { + return conditions; + } + const sanitized = { ...conditions }; + if (!sanitized.options) { + sanitized.options = {}; + } + const requiredOptions = { + version: 2, + leftValue: '', + caseSensitive: true, + typeValidation: 'strict' + }; + sanitized.options = { + ...requiredOptions, + ...sanitized.options + }; + if (sanitized.conditions && Array.isArray(sanitized.conditions)) { + sanitized.conditions = sanitized.conditions.map((condition) => sanitizeCondition(condition)); + } + return sanitized; +} +function sanitizeCondition(condition) { + if (!condition || typeof condition !== 'object') { + return condition; + } + const sanitized = { ...condition }; + if (!sanitized.id) { + sanitized.id = generateConditionId(); + } + if (sanitized.operator) { + sanitized.operator = sanitizeOperator(sanitized.operator); + } + return sanitized; +} +function sanitizeOperator(operator) { + if (!operator || typeof operator !== 'object') { + return operator; + } + const sanitized = { ...operator }; + if (sanitized.type && !sanitized.operation) { + const typeValue = sanitized.type; + if (isOperationName(typeValue)) { + logger_1.logger.debug(`Fixing operator structure: converting type="${typeValue}" to operation`); + const dataType = inferDataType(typeValue); + sanitized.type = dataType; + sanitized.operation = typeValue; + } + } + if (sanitized.operation) { + if (isUnaryOperator(sanitized.operation)) { + sanitized.singleValue = true; + } + else { + delete sanitized.singleValue; + } + } + return sanitized; +} +function isOperationName(value) { + const dataTypes = ['string', 'number', 'boolean', 'dateTime', 'array', 'object']; + return !dataTypes.includes(value) && /^[a-z][a-zA-Z]*$/.test(value); +} +function inferDataType(operation) { + const booleanOps = ['true', 'false', 'isEmpty', 'isNotEmpty']; + if (booleanOps.includes(operation)) { + return 'boolean'; + } + const numberOps = ['isNumeric', 'gt', 'gte', 'lt', 'lte']; + if (numberOps.some(op => operation.includes(op))) { + return 'number'; + } + const dateOps = ['after', 'before', 'afterDate', 'beforeDate']; + if (dateOps.some(op => operation.includes(op))) { + return 'dateTime'; + } + return 'string'; +} +function isUnaryOperator(operation) { + const unaryOps = [ + 'isEmpty', + 'isNotEmpty', + 'true', + 'false', + 'isNumeric' + ]; + return unaryOps.includes(operation); +} +function generateConditionId() { + return `condition-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; +} +function validateNodeMetadata(node) { + const issues = []; + if (!isFilterBasedNode(node.type, node.typeVersion)) { + return issues; + } + if (node.type === 'n8n-nodes-base.if') { + const conditions = node.parameters.conditions; + if (!conditions?.options) { + issues.push('Missing conditions.options'); + } + else { + const required = ['version', 'leftValue', 'typeValidation', 'caseSensitive']; + for (const field of required) { + if (!(field in conditions.options)) { + issues.push(`Missing conditions.options.${field}`); + } + } + } + if (conditions?.conditions && Array.isArray(conditions.conditions)) { + for (let i = 0; i < conditions.conditions.length; i++) { + const condition = conditions.conditions[i]; + const operatorIssues = validateOperator(condition.operator, `conditions.conditions[${i}].operator`); + issues.push(...operatorIssues); + } + } + } + if (node.type === 'n8n-nodes-base.switch') { + const rules = node.parameters.rules; + if (rules?.rules && Array.isArray(rules.rules)) { + for (let i = 0; i < rules.rules.length; i++) { + const rule = rules.rules[i]; + if (!rule.conditions?.options) { + issues.push(`Missing rules.rules[${i}].conditions.options`); + } + else { + const required = ['version', 'leftValue', 'typeValidation', 'caseSensitive']; + for (const field of required) { + if (!(field in rule.conditions.options)) { + issues.push(`Missing rules.rules[${i}].conditions.options.${field}`); + } + } + } + if (rule.conditions?.conditions && Array.isArray(rule.conditions.conditions)) { + for (let j = 0; j < rule.conditions.conditions.length; j++) { + const condition = rule.conditions.conditions[j]; + const operatorIssues = validateOperator(condition.operator, `rules.rules[${i}].conditions.conditions[${j}].operator`); + issues.push(...operatorIssues); + } + } + } + } + } + return issues; +} +function validateOperator(operator, path) { + const issues = []; + if (!operator || typeof operator !== 'object') { + issues.push(`${path}: operator is missing or not an object`); + return issues; + } + if (!operator.type) { + issues.push(`${path}: missing required field 'type'`); + } + else if (!['string', 'number', 'boolean', 'dateTime', 'array', 'object'].includes(operator.type)) { + issues.push(`${path}: invalid type "${operator.type}" (must be data type, not operation)`); + } + if (!operator.operation) { + issues.push(`${path}: missing required field 'operation'`); + } + if (operator.operation) { + if (isUnaryOperator(operator.operation)) { + if (operator.singleValue !== true) { + issues.push(`${path}: unary operator "${operator.operation}" requires singleValue: true`); + } + } + else { + if (operator.singleValue === true) { + issues.push(`${path}: binary operator "${operator.operation}" should not have singleValue: true (only unary operators need this)`); + } + } + } + return issues; +} +//# sourceMappingURL=node-sanitizer.js.map \ No newline at end of file diff --git a/dist/services/node-sanitizer.js.map b/dist/services/node-sanitizer.js.map new file mode 100644 index 0000000..0a601f2 --- /dev/null +++ b/dist/services/node-sanitizer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"node-sanitizer.js","sourceRoot":"","sources":["../../src/services/node-sanitizer.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/node-similarity-service.d.ts b/dist/services/node-similarity-service.d.ts new file mode 100644 index 0000000..7d11edc --- /dev/null +++ b/dist/services/node-similarity-service.d.ts @@ -0,0 +1,51 @@ +import { NodeRepository } from '../database/node-repository'; +export interface NodeSuggestion { + nodeType: string; + displayName: string; + confidence: number; + reason: string; + category?: string; + description?: string; +} +export interface SimilarityScore { + nameSimilarity: number; + categoryMatch: number; + packageMatch: number; + patternMatch: number; + totalScore: number; +} +export interface CommonMistakePattern { + pattern: string; + suggestion: string; + confidence: number; + reason: string; +} +export declare class NodeSimilarityService { + private static readonly SCORING_THRESHOLD; + private static readonly TYPO_EDIT_DISTANCE; + private static readonly SHORT_SEARCH_LENGTH; + private static readonly CACHE_DURATION_MS; + private static readonly AUTO_FIX_CONFIDENCE; + private repository; + private commonMistakes; + private nodeCache; + private cacheExpiry; + private cacheVersion; + constructor(repository: NodeRepository); + private initializeCommonMistakes; + private isCommonNodeWithoutPrefix; + findSimilarNodes(invalidType: string, limit?: number): Promise; + private checkCommonMistakes; + private calculateSimilarityScore; + private createSuggestion; + private normalizeNodeType; + private getStringSimilarity; + private getEditDistance; + private getCachedNodes; + invalidateCache(): void; + refreshCache(): Promise; + formatSuggestionMessage(suggestions: NodeSuggestion[], invalidType: string): string; + isAutoFixable(suggestion: NodeSuggestion): boolean; + clearCache(): void; +} +//# sourceMappingURL=node-similarity-service.d.ts.map \ No newline at end of file diff --git a/dist/services/node-similarity-service.d.ts.map b/dist/services/node-similarity-service.d.ts.map new file mode 100644 index 0000000..e24c580 --- /dev/null +++ b/dist/services/node-similarity-service.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"node-similarity-service.d.ts","sourceRoot":"","sources":["../../src/services/node-similarity-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAG7D,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,qBAAqB;IAEhC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAM;IAC/C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAK;IAC/C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAK;IAChD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAiB;IAC1D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAO;IAElD,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,cAAc,CAAsC;IAC5D,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,YAAY,CAAa;gBAErB,UAAU,EAAE,cAAc;IAStC,OAAO,CAAC,wBAAwB;IAkDhC,OAAO,CAAC,yBAAyB;IAuB3B,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IA8CzF,OAAO,CAAC,mBAAmB;IA0E3B,OAAO,CAAC,wBAAwB;IAuEhC,OAAO,CAAC,gBAAgB;IA2BxB,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,mBAAmB;IAgB3B,OAAO,CAAC,eAAe;YAgDT,cAAc;IAqCrB,eAAe,IAAI,IAAI;IAUjB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ1C,uBAAuB,CAAC,WAAW,EAAE,cAAc,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;IA8BnF,aAAa,CAAC,UAAU,EAAE,cAAc,GAAG,OAAO;IAQlD,UAAU,IAAI,IAAI;CAGnB"} \ No newline at end of file diff --git a/dist/services/node-similarity-service.js b/dist/services/node-similarity-service.js new file mode 100644 index 0000000..4885484 --- /dev/null +++ b/dist/services/node-similarity-service.js @@ -0,0 +1,335 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.NodeSimilarityService = void 0; +const logger_1 = require("../utils/logger"); +class NodeSimilarityService { + constructor(repository) { + this.nodeCache = null; + this.cacheExpiry = 0; + this.cacheVersion = 0; + this.repository = repository; + this.commonMistakes = this.initializeCommonMistakes(); + } + initializeCommonMistakes() { + const patterns = new Map(); + patterns.set('case_variations', [ + { pattern: 'httprequest', suggestion: 'nodes-base.httpRequest', confidence: 0.95, reason: 'Incorrect capitalization' }, + { pattern: 'webhook', suggestion: 'nodes-base.webhook', confidence: 0.95, reason: 'Incorrect capitalization' }, + { pattern: 'slack', suggestion: 'nodes-base.slack', confidence: 0.9, reason: 'Missing package prefix' }, + { pattern: 'gmail', suggestion: 'nodes-base.gmail', confidence: 0.9, reason: 'Missing package prefix' }, + { pattern: 'googlesheets', suggestion: 'nodes-base.googleSheets', confidence: 0.9, reason: 'Missing package prefix' }, + { pattern: 'telegram', suggestion: 'nodes-base.telegram', confidence: 0.9, reason: 'Missing package prefix' }, + ]); + patterns.set('specific_variations', [ + { pattern: 'HttpRequest', suggestion: 'nodes-base.httpRequest', confidence: 0.95, reason: 'Incorrect capitalization' }, + { pattern: 'HTTPRequest', suggestion: 'nodes-base.httpRequest', confidence: 0.95, reason: 'Common capitalization mistake' }, + { pattern: 'Webhook', suggestion: 'nodes-base.webhook', confidence: 0.95, reason: 'Incorrect capitalization' }, + { pattern: 'WebHook', suggestion: 'nodes-base.webhook', confidence: 0.95, reason: 'Common capitalization mistake' }, + ]); + patterns.set('deprecated_prefixes', [ + { pattern: 'n8n-nodes-base.', suggestion: 'nodes-base.', confidence: 0.95, reason: 'Full package name used instead of short form' }, + { pattern: '@n8n/n8n-nodes-langchain.', suggestion: 'nodes-langchain.', confidence: 0.95, reason: 'Full package name used instead of short form' }, + ]); + patterns.set('typos', [ + { pattern: 'htprequest', suggestion: 'nodes-base.httpRequest', confidence: 0.8, reason: 'Likely typo' }, + { pattern: 'httpreqest', suggestion: 'nodes-base.httpRequest', confidence: 0.8, reason: 'Likely typo' }, + { pattern: 'webook', suggestion: 'nodes-base.webhook', confidence: 0.8, reason: 'Likely typo' }, + { pattern: 'slak', suggestion: 'nodes-base.slack', confidence: 0.8, reason: 'Likely typo' }, + { pattern: 'googlesheets', suggestion: 'nodes-base.googleSheets', confidence: 0.8, reason: 'Likely typo' }, + ]); + patterns.set('ai_nodes', [ + { pattern: 'openai', suggestion: 'nodes-langchain.openAi', confidence: 0.85, reason: 'AI node - incorrect package' }, + { pattern: 'nodes-base.openai', suggestion: 'nodes-langchain.openAi', confidence: 0.9, reason: 'Wrong package - OpenAI is in LangChain package' }, + { pattern: 'chatopenai', suggestion: 'nodes-langchain.lmChatOpenAi', confidence: 0.85, reason: 'LangChain node naming convention' }, + { pattern: 'vectorstore', suggestion: 'nodes-langchain.vectorStoreInMemory', confidence: 0.7, reason: 'Generic vector store reference' }, + ]); + return patterns; + } + isCommonNodeWithoutPrefix(type) { + const commonNodes = { + 'httprequest': 'nodes-base.httpRequest', + 'webhook': 'nodes-base.webhook', + 'slack': 'nodes-base.slack', + 'gmail': 'nodes-base.gmail', + 'googlesheets': 'nodes-base.googleSheets', + 'telegram': 'nodes-base.telegram', + 'discord': 'nodes-base.discord', + 'notion': 'nodes-base.notion', + 'airtable': 'nodes-base.airtable', + 'postgres': 'nodes-base.postgres', + 'mysql': 'nodes-base.mySql', + 'mongodb': 'nodes-base.mongoDb', + }; + const normalized = type.toLowerCase(); + return commonNodes[normalized] || null; + } + async findSimilarNodes(invalidType, limit = 5) { + if (!invalidType || invalidType.trim() === '') { + return []; + } + const suggestions = []; + const mistakeSuggestion = this.checkCommonMistakes(invalidType); + if (mistakeSuggestion) { + suggestions.push(mistakeSuggestion); + } + const allNodes = await this.getCachedNodes(); + const scores = allNodes.map(node => ({ + node, + score: this.calculateSimilarityScore(invalidType, node) + })); + scores.sort((a, b) => b.score.totalScore - a.score.totalScore); + for (const { node, score } of scores) { + if (suggestions.some(s => s.nodeType === node.nodeType)) { + continue; + } + if (score.totalScore >= NodeSimilarityService.SCORING_THRESHOLD) { + suggestions.push(this.createSuggestion(node, score)); + } + if (suggestions.length >= limit) { + break; + } + } + return suggestions; + } + checkCommonMistakes(invalidType) { + const cleanType = invalidType.trim(); + const lowerType = cleanType.toLowerCase(); + const commonNodeSuggestion = this.isCommonNodeWithoutPrefix(cleanType); + if (commonNodeSuggestion) { + const node = this.repository.getNode(commonNodeSuggestion); + if (node) { + return { + nodeType: commonNodeSuggestion, + displayName: node.displayName, + confidence: 0.9, + reason: 'Missing package prefix', + category: node.category, + description: node.description + }; + } + } + for (const [category, patterns] of this.commonMistakes) { + if (category === 'deprecated_prefixes') { + for (const pattern of patterns) { + if (cleanType.startsWith(pattern.pattern)) { + const actualSuggestion = cleanType.replace(pattern.pattern, pattern.suggestion); + const node = this.repository.getNode(actualSuggestion); + if (node) { + return { + nodeType: actualSuggestion, + displayName: node.displayName, + confidence: pattern.confidence, + reason: pattern.reason, + category: node.category, + description: node.description + }; + } + } + } + } + } + for (const [category, patterns] of this.commonMistakes) { + if (category === 'deprecated_prefixes') + continue; + for (const pattern of patterns) { + const match = category === 'specific_variations' + ? cleanType === pattern.pattern + : lowerType === pattern.pattern.toLowerCase(); + if (match && pattern.suggestion) { + const node = this.repository.getNode(pattern.suggestion); + if (node) { + return { + nodeType: pattern.suggestion, + displayName: node.displayName, + confidence: pattern.confidence, + reason: pattern.reason, + category: node.category, + description: node.description + }; + } + } + } + } + return null; + } + calculateSimilarityScore(invalidType, node) { + const cleanInvalid = this.normalizeNodeType(invalidType); + const cleanValid = this.normalizeNodeType(node.nodeType); + const displayNameClean = this.normalizeNodeType(node.displayName); + const isShortSearch = invalidType.length <= NodeSimilarityService.SHORT_SEARCH_LENGTH; + let nameSimilarity = Math.max(this.getStringSimilarity(cleanInvalid, cleanValid), this.getStringSimilarity(cleanInvalid, displayNameClean)) * 40; + if (isShortSearch && (cleanValid.includes(cleanInvalid) || displayNameClean.includes(cleanInvalid))) { + nameSimilarity = Math.max(nameSimilarity, 10); + } + let categoryMatch = 0; + if (node.category) { + const categoryClean = this.normalizeNodeType(node.category); + if (cleanInvalid.includes(categoryClean) || categoryClean.includes(cleanInvalid)) { + categoryMatch = 20; + } + } + let packageMatch = 0; + const invalidParts = cleanInvalid.split(/[.-]/); + const validParts = cleanValid.split(/[.-]/); + if (invalidParts[0] === validParts[0]) { + packageMatch = 15; + } + let patternMatch = 0; + if (cleanValid.includes(cleanInvalid) || displayNameClean.includes(cleanInvalid)) { + patternMatch = isShortSearch ? 45 : 25; + } + else if (this.getEditDistance(cleanInvalid, cleanValid) <= NodeSimilarityService.TYPO_EDIT_DISTANCE) { + patternMatch = 20; + } + else if (this.getEditDistance(cleanInvalid, displayNameClean) <= NodeSimilarityService.TYPO_EDIT_DISTANCE) { + patternMatch = 18; + } + if (isShortSearch && (cleanValid.startsWith(cleanInvalid) || displayNameClean.startsWith(cleanInvalid))) { + patternMatch = Math.max(patternMatch, 40); + } + const totalScore = nameSimilarity + categoryMatch + packageMatch + patternMatch; + return { + nameSimilarity, + categoryMatch, + packageMatch, + patternMatch, + totalScore + }; + } + createSuggestion(node, score) { + let reason = 'Similar node'; + if (score.patternMatch >= 20) { + reason = 'Name similarity'; + } + else if (score.categoryMatch >= 15) { + reason = 'Same category'; + } + else if (score.packageMatch >= 10) { + reason = 'Same package'; + } + const confidence = Math.min(score.totalScore / 100, 1); + return { + nodeType: node.nodeType, + displayName: node.displayName, + confidence, + reason, + category: node.category, + description: node.description + }; + } + normalizeNodeType(type) { + return type + .toLowerCase() + .replace(/[^a-z0-9]/g, '') + .trim(); + } + getStringSimilarity(s1, s2) { + if (s1 === s2) + return 1; + if (!s1 || !s2) + return 0; + const distance = this.getEditDistance(s1, s2); + const maxLen = Math.max(s1.length, s2.length); + return 1 - (distance / maxLen); + } + getEditDistance(s1, s2, maxDistance = 5) { + if (s1 === s2) + return 0; + const m = s1.length; + const n = s2.length; + const lengthDiff = Math.abs(m - n); + if (lengthDiff > maxDistance) + return maxDistance + 1; + if (m === 0) + return n; + if (n === 0) + return m; + let prev = Array(n + 1).fill(0).map((_, i) => i); + for (let i = 1; i <= m; i++) { + const curr = [i]; + let minInRow = i; + for (let j = 1; j <= n; j++) { + const cost = s1[i - 1] === s2[j - 1] ? 0 : 1; + const val = Math.min(curr[j - 1] + 1, prev[j] + 1, prev[j - 1] + cost); + curr.push(val); + minInRow = Math.min(minInRow, val); + } + if (minInRow > maxDistance) { + return maxDistance + 1; + } + prev = curr; + } + return prev[n]; + } + async getCachedNodes() { + const now = Date.now(); + if (!this.nodeCache || now > this.cacheExpiry) { + try { + const newNodes = this.repository.getAllNodes(); + if (newNodes && newNodes.length > 0) { + this.nodeCache = newNodes; + this.cacheExpiry = now + NodeSimilarityService.CACHE_DURATION_MS; + this.cacheVersion++; + logger_1.logger.debug('Node cache refreshed', { + count: newNodes.length, + version: this.cacheVersion + }); + } + else if (this.nodeCache) { + logger_1.logger.warn('Node fetch returned empty, using stale cache'); + } + } + catch (error) { + logger_1.logger.error('Failed to fetch nodes for similarity service', error); + if (this.nodeCache) { + logger_1.logger.info('Using stale cache due to fetch error'); + return this.nodeCache; + } + return []; + } + } + return this.nodeCache || []; + } + invalidateCache() { + this.nodeCache = null; + this.cacheExpiry = 0; + this.cacheVersion++; + logger_1.logger.debug('Node cache invalidated', { version: this.cacheVersion }); + } + async refreshCache() { + this.invalidateCache(); + await this.getCachedNodes(); + } + formatSuggestionMessage(suggestions, invalidType) { + if (suggestions.length === 0) { + return `Unknown node type: "${invalidType}". No similar nodes found.`; + } + let message = `Unknown node type: "${invalidType}"\n\nDid you mean one of these?\n`; + for (const suggestion of suggestions) { + const confidence = Math.round(suggestion.confidence * 100); + message += `• ${suggestion.nodeType} (${confidence}% match)`; + if (suggestion.displayName) { + message += ` - ${suggestion.displayName}`; + } + message += `\n → ${suggestion.reason}`; + if (suggestion.confidence >= 0.9) { + message += ' (can be auto-fixed)'; + } + message += '\n'; + } + return message; + } + isAutoFixable(suggestion) { + return suggestion.confidence >= NodeSimilarityService.AUTO_FIX_CONFIDENCE; + } + clearCache() { + this.invalidateCache(); + } +} +exports.NodeSimilarityService = NodeSimilarityService; +NodeSimilarityService.SCORING_THRESHOLD = 50; +NodeSimilarityService.TYPO_EDIT_DISTANCE = 2; +NodeSimilarityService.SHORT_SEARCH_LENGTH = 5; +NodeSimilarityService.CACHE_DURATION_MS = 5 * 60 * 1000; +NodeSimilarityService.AUTO_FIX_CONFIDENCE = 0.9; +//# sourceMappingURL=node-similarity-service.js.map \ No newline at end of file diff --git a/dist/services/node-similarity-service.js.map b/dist/services/node-similarity-service.js.map new file mode 100644 index 0000000..b673cd5 --- /dev/null +++ b/dist/services/node-similarity-service.js.map @@ -0,0 +1 @@ +{"version":3,"file":"node-similarity-service.js","sourceRoot":"","sources":["../../src/services/node-similarity-service.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/node-specific-validators.d.ts b/dist/services/node-specific-validators.d.ts new file mode 100644 index 0000000..b342ed8 --- /dev/null +++ b/dist/services/node-specific-validators.d.ts @@ -0,0 +1,37 @@ +import { ValidationError, ValidationWarning } from './config-validator'; +export interface NodeValidationContext { + config: Record; + errors: ValidationError[]; + warnings: ValidationWarning[]; + suggestions: string[]; + autofix: Record; +} +export declare class NodeSpecificValidators { + static validateSlack(context: NodeValidationContext): void; + private static validateSlackSendMessage; + private static validateSlackUpdateMessage; + private static validateSlackDeleteMessage; + private static validateSlackCreateChannel; + static validateGoogleSheets(context: NodeValidationContext): void; + private static validateGoogleSheetsAppend; + private static validateGoogleSheetsRead; + private static validateGoogleSheetsUpdate; + private static validateGoogleSheetsDelete; + private static validateGoogleSheetsRange; + static validateOpenAI(context: NodeValidationContext): void; + static validateMongoDB(context: NodeValidationContext): void; + static validatePostgres(context: NodeValidationContext): void; + static validateAIAgent(context: NodeValidationContext): void; + static validateMySQL(context: NodeValidationContext): void; + private static validateSQLQuery; + static validateHttpRequest(context: NodeValidationContext): void; + static validateWebhook(context: NodeValidationContext): void; + static validateCode(context: NodeValidationContext): void; + private static validateJavaScriptCode; + private static validatePythonCode; + private static validateReturnStatement; + private static validateN8nVariables; + private static validateCodeSecurity; + static validateSet(context: NodeValidationContext): void; +} +//# sourceMappingURL=node-specific-validators.d.ts.map \ No newline at end of file diff --git a/dist/services/node-specific-validators.d.ts.map b/dist/services/node-specific-validators.d.ts.map new file mode 100644 index 0000000..766c226 --- /dev/null +++ b/dist/services/node-specific-validators.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"node-specific-validators.d.ts","sourceRoot":"","sources":["../../src/services/node-specific-validators.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAExE,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B;AAED,qBAAa,sBAAsB;IAIjC,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI;IAqE1D,OAAO,CAAC,MAAM,CAAC,wBAAwB;IAkDvC,OAAO,CAAC,MAAM,CAAC,0BAA0B;IAsBzC,OAAO,CAAC,MAAM,CAAC,0BAA0B;IA4BzC,OAAO,CAAC,MAAM,CAAC,0BAA0B;IA2CzC,MAAM,CAAC,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI;IAiDjE,OAAO,CAAC,MAAM,CAAC,0BAA0B;IA0BzC,OAAO,CAAC,MAAM,CAAC,wBAAwB;IAkBvC,OAAO,CAAC,MAAM,CAAC,0BAA0B;IAsBzC,OAAO,CAAC,MAAM,CAAC,0BAA0B;IA4BzC,OAAO,CAAC,MAAM,CAAC,yBAAyB;IAwCxC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI;IAwF3D,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI;IAyG5D,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI;IAkI7D,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI;IAmG5D,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI;IA6F1D,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAkF/B,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI;IAiGhE,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI;IA6D5D,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI;IA8DzD,OAAO,CAAC,MAAM,CAAC,sBAAsB;IAuDrC,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAuDjC,OAAO,CAAC,MAAM,CAAC,uBAAuB;IAsFtC,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAuKnC,OAAO,CAAC,MAAM,CAAC,oBAAoB;IA2EnC,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI;CAoDzD"} \ No newline at end of file diff --git a/dist/services/node-specific-validators.js b/dist/services/node-specific-validators.js new file mode 100644 index 0000000..9af2c78 --- /dev/null +++ b/dist/services/node-specific-validators.js @@ -0,0 +1,1331 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.NodeSpecificValidators = void 0; +class NodeSpecificValidators { + static validateSlack(context) { + const { config, errors, warnings, suggestions, autofix } = context; + const { resource, operation } = config; + if (resource === 'message') { + switch (operation) { + case 'send': + this.validateSlackSendMessage(context); + break; + case 'update': + this.validateSlackUpdateMessage(context); + break; + case 'delete': + this.validateSlackDeleteMessage(context); + break; + } + } + else if (resource === 'channel') { + switch (operation) { + case 'create': + this.validateSlackCreateChannel(context); + break; + case 'get': + case 'getAll': + break; + } + } + else if (resource === 'user') { + if (operation === 'get' && !config.user) { + errors.push({ + type: 'missing_required', + property: 'user', + message: 'User identifier required - use email, user ID, or username', + fix: 'Set user to an email like "john@example.com" or user ID like "U1234567890"' + }); + } + } + if (!config.onError && !config.retryOnFail && !config.continueOnFail) { + warnings.push({ + type: 'best_practice', + property: 'errorHandling', + message: 'Slack API can have rate limits and transient failures', + suggestion: 'Add onError: "continueRegularOutput" with retryOnFail for resilience' + }); + autofix.onError = 'continueRegularOutput'; + autofix.retryOnFail = true; + autofix.maxTries = 2; + autofix.waitBetweenTries = 3000; + } + if (config.continueOnFail !== undefined) { + warnings.push({ + type: 'deprecated', + property: 'continueOnFail', + message: 'continueOnFail is deprecated. Use onError instead', + suggestion: 'Replace with onError: "continueRegularOutput"' + }); + } + } + static validateSlackSendMessage(context) { + const { config, errors, warnings, suggestions, autofix } = context; + if (!config.channel && !config.channelId) { + errors.push({ + type: 'missing_required', + property: 'channel', + message: 'Channel is required to send a message', + fix: 'Set channel to a channel name (e.g., "#general") or ID (e.g., "C1234567890")' + }); + } + if (!config.text && !config.blocks && !config.attachments) { + errors.push({ + type: 'missing_required', + property: 'text', + message: 'Message content is required - provide text, blocks, or attachments', + fix: 'Add text field with your message content' + }); + } + if (config.text && config.text.length > 40000) { + warnings.push({ + type: 'inefficient', + property: 'text', + message: 'Message text exceeds Slack\'s 40,000 character limit', + suggestion: 'Split into multiple messages or use a file upload' + }); + } + if (config.replyToThread && !config.threadTs) { + warnings.push({ + type: 'missing_common', + property: 'threadTs', + message: 'Thread timestamp required when replying to thread', + suggestion: 'Set threadTs to the timestamp of the thread parent message' + }); + } + if (config.text?.includes('@') && !config.linkNames) { + suggestions.push('Set linkNames=true to convert @mentions to user links'); + autofix.linkNames = true; + } + } + static validateSlackUpdateMessage(context) { + const { config, errors } = context; + if (!config.ts) { + errors.push({ + type: 'missing_required', + property: 'ts', + message: 'Message timestamp (ts) is required to update a message', + fix: 'Provide the timestamp of the message to update' + }); + } + if (!config.channel && !config.channelId) { + errors.push({ + type: 'missing_required', + property: 'channel', + message: 'Channel is required to update a message', + fix: 'Provide the channel where the message exists' + }); + } + } + static validateSlackDeleteMessage(context) { + const { config, errors, warnings } = context; + if (!config.ts) { + errors.push({ + type: 'missing_required', + property: 'ts', + message: 'Message timestamp (ts) is required to delete a message', + fix: 'Provide the timestamp of the message to delete' + }); + } + if (!config.channel && !config.channelId) { + errors.push({ + type: 'missing_required', + property: 'channel', + message: 'Channel is required to delete a message', + fix: 'Provide the channel where the message exists' + }); + } + warnings.push({ + type: 'security', + message: 'Message deletion is permanent and cannot be undone', + suggestion: 'Consider archiving or updating the message instead if you need to preserve history' + }); + } + static validateSlackCreateChannel(context) { + const { config, errors, warnings } = context; + if (!config.name) { + errors.push({ + type: 'missing_required', + property: 'name', + message: 'Channel name is required', + fix: 'Provide a channel name (lowercase, no spaces, 1-80 characters)' + }); + } + else { + const name = config.name; + if (name.includes(' ')) { + errors.push({ + type: 'invalid_value', + property: 'name', + message: 'Channel names cannot contain spaces', + fix: 'Use hyphens or underscores instead of spaces' + }); + } + if (name !== name.toLowerCase()) { + errors.push({ + type: 'invalid_value', + property: 'name', + message: 'Channel names must be lowercase', + fix: 'Convert the channel name to lowercase' + }); + } + if (name.length > 80) { + errors.push({ + type: 'invalid_value', + property: 'name', + message: 'Channel name exceeds 80 character limit', + fix: 'Shorten the channel name' + }); + } + } + } + static validateGoogleSheets(context) { + const { config, errors, warnings, suggestions } = context; + const { operation } = config; + switch (operation) { + case 'append': + this.validateGoogleSheetsAppend(context); + break; + case 'read': + this.validateGoogleSheetsRead(context); + break; + case 'update': + this.validateGoogleSheetsUpdate(context); + break; + case 'delete': + this.validateGoogleSheetsDelete(context); + break; + } + if (config.range) { + this.validateGoogleSheetsRange(config.range, errors, warnings); + } + const filteredErrors = []; + for (const error of errors) { + if (error.property === 'sheetId' && error.type === 'missing_required') { + continue; + } + if (error.property && error.property.includes('sheetId') && error.type === 'missing_required') { + continue; + } + filteredErrors.push(error); + } + errors.length = 0; + errors.push(...filteredErrors); + } + static validateGoogleSheetsAppend(context) { + const { config, errors, warnings, autofix } = context; + if (!config.range && !config.columns) { + errors.push({ + type: 'missing_required', + property: 'range', + message: 'Range or columns mapping is required for append operation', + fix: 'Specify range like "Sheet1!A:B" OR use columns with mappingMode' + }); + } + if (!config.options?.valueInputMode) { + warnings.push({ + type: 'missing_common', + property: 'options.valueInputMode', + message: 'Consider setting valueInputMode for proper data formatting', + suggestion: 'Use "USER_ENTERED" to parse formulas and dates, or "RAW" for literal values' + }); + autofix.options = { ...config.options, valueInputMode: 'USER_ENTERED' }; + } + } + static validateGoogleSheetsRead(context) { + const { config, errors, suggestions } = context; + if (!config.range) { + errors.push({ + type: 'missing_required', + property: 'range', + message: 'Range is required for read operation', + fix: 'Specify range like "Sheet1!A:B" or "Sheet1!A1:B10"' + }); + } + if (!config.options?.dataStructure) { + suggestions.push('Consider setting options.dataStructure to "object" for easier data manipulation'); + } + } + static validateGoogleSheetsUpdate(context) { + const { config, errors } = context; + if (!config.range) { + errors.push({ + type: 'missing_required', + property: 'range', + message: 'Range is required for update operation', + fix: 'Specify the exact range to update like "Sheet1!A1:B10"' + }); + } + if (!config.values && !config.rawData) { + errors.push({ + type: 'missing_required', + property: 'values', + message: 'Values are required for update operation', + fix: 'Provide the data to write to the spreadsheet' + }); + } + } + static validateGoogleSheetsDelete(context) { + const { config, errors, warnings } = context; + if (!config.toDelete) { + errors.push({ + type: 'missing_required', + property: 'toDelete', + message: 'Specify what to delete (rows or columns)', + fix: 'Set toDelete to "rows" or "columns"' + }); + } + if (config.toDelete === 'rows' && !config.startIndex && config.startIndex !== 0) { + errors.push({ + type: 'missing_required', + property: 'startIndex', + message: 'Start index is required when deleting rows', + fix: 'Specify the starting row index (0-based)' + }); + } + warnings.push({ + type: 'security', + message: 'Deletion is permanent. Consider backing up data first', + suggestion: 'Read the data before deletion to create a backup' + }); + } + static validateGoogleSheetsRange(range, errors, warnings) { + if (!range.includes('!')) { + warnings.push({ + type: 'inefficient', + property: 'range', + message: 'Range should include sheet name for clarity', + suggestion: 'Format: "SheetName!A1:B10" or "SheetName!A:B"' + }); + } + if (range.includes(' ') && !range.match(/^'[^']+'/)) { + errors.push({ + type: 'invalid_value', + property: 'range', + message: 'Sheet names with spaces must be quoted', + fix: 'Use single quotes around sheet name: \'Sheet Name\'!A1:B10' + }); + } + const a1Pattern = /^('[^']+'|[^!]+)!([A-Z]+\d*:?[A-Z]*\d*|[A-Z]+:[A-Z]+|\d+:\d+)$/i; + if (!a1Pattern.test(range)) { + warnings.push({ + type: 'inefficient', + property: 'range', + message: 'Range may not be in valid A1 notation', + suggestion: 'Examples: "Sheet1!A1:B10", "Sheet1!A:B", "Sheet1!1:10"' + }); + } + } + static validateOpenAI(context) { + const { config, errors, warnings, suggestions, autofix } = context; + const { resource, operation } = config; + if (resource === 'chat' && operation === 'create') { + if (!config.model) { + errors.push({ + type: 'missing_required', + property: 'model', + message: 'Model selection is required', + fix: 'Choose a model like "gpt-4", "gpt-3.5-turbo", etc.' + }); + } + else { + const deprecatedModels = ['text-davinci-003', 'text-davinci-002']; + if (deprecatedModels.includes(config.model)) { + warnings.push({ + type: 'deprecated', + property: 'model', + message: `Model ${config.model} is deprecated`, + suggestion: 'Use "gpt-3.5-turbo" or "gpt-4" instead' + }); + } + } + if (!config.messages && !config.prompt) { + errors.push({ + type: 'missing_required', + property: 'messages', + message: 'Messages or prompt required for chat completion', + fix: 'Add messages array or use the prompt field' + }); + } + if (config.maxTokens && config.maxTokens > 4000) { + warnings.push({ + type: 'inefficient', + property: 'maxTokens', + message: 'High token limit may increase costs significantly', + suggestion: 'Consider if you really need more than 4000 tokens' + }); + } + if (config.temperature !== undefined) { + if (config.temperature < 0 || config.temperature > 2) { + errors.push({ + type: 'invalid_value', + property: 'temperature', + message: 'Temperature must be between 0 and 2', + fix: 'Set temperature between 0 (deterministic) and 2 (creative)' + }); + } + } + } + if (!config.onError && !config.retryOnFail && !config.continueOnFail) { + warnings.push({ + type: 'best_practice', + property: 'errorHandling', + message: 'AI APIs have rate limits and can return errors', + suggestion: 'Add onError: "continueRegularOutput" with retryOnFail and longer wait times' + }); + autofix.onError = 'continueRegularOutput'; + autofix.retryOnFail = true; + autofix.maxTries = 3; + autofix.waitBetweenTries = 5000; + autofix.alwaysOutputData = true; + } + if (config.continueOnFail !== undefined) { + warnings.push({ + type: 'deprecated', + property: 'continueOnFail', + message: 'continueOnFail is deprecated. Use onError instead', + suggestion: 'Replace with onError: "continueRegularOutput"' + }); + } + } + static validateMongoDB(context) { + const { config, errors, warnings, autofix } = context; + const { operation } = config; + if (!config.collection) { + errors.push({ + type: 'missing_required', + property: 'collection', + message: 'Collection name is required', + fix: 'Specify the MongoDB collection to work with' + }); + } + switch (operation) { + case 'find': + if (config.query) { + try { + JSON.parse(config.query); + } + catch (e) { + errors.push({ + type: 'invalid_value', + property: 'query', + message: 'Query must be valid JSON', + fix: 'Ensure query is valid JSON like: {"name": "John"}' + }); + } + } + break; + case 'insert': + if (!config.fields && !config.documents) { + errors.push({ + type: 'missing_required', + property: 'fields', + message: 'Document data is required for insert', + fix: 'Provide the data to insert' + }); + } + break; + case 'update': + if (!config.query) { + warnings.push({ + type: 'security', + message: 'Update without query will affect all documents', + suggestion: 'Add a query to target specific documents' + }); + } + break; + case 'delete': + if (!config.query || config.query === '{}') { + errors.push({ + type: 'invalid_value', + property: 'query', + message: 'Delete without query would remove all documents - this is a critical security issue', + fix: 'Add a query to specify which documents to delete' + }); + } + break; + } + if (!config.onError && !config.retryOnFail && !config.continueOnFail) { + if (operation === 'find') { + warnings.push({ + type: 'best_practice', + property: 'errorHandling', + message: 'MongoDB queries can fail due to connection issues', + suggestion: 'Add onError: "continueRegularOutput" with retryOnFail' + }); + autofix.onError = 'continueRegularOutput'; + autofix.retryOnFail = true; + autofix.maxTries = 3; + } + else if (['insert', 'update', 'delete'].includes(operation)) { + warnings.push({ + type: 'best_practice', + property: 'errorHandling', + message: 'MongoDB write operations should handle errors carefully', + suggestion: 'Add onError: "continueErrorOutput" to handle write failures separately' + }); + autofix.onError = 'continueErrorOutput'; + autofix.retryOnFail = true; + autofix.maxTries = 2; + autofix.waitBetweenTries = 1000; + } + } + if (config.continueOnFail !== undefined) { + warnings.push({ + type: 'deprecated', + property: 'continueOnFail', + message: 'continueOnFail is deprecated. Use onError instead', + suggestion: 'Replace with onError: "continueRegularOutput" or "continueErrorOutput"' + }); + } + } + static validatePostgres(context) { + const { config, errors, warnings, suggestions, autofix } = context; + const { operation } = config; + if (['execute', 'select', 'insert', 'update', 'delete'].includes(operation)) { + this.validateSQLQuery(context, 'postgres'); + } + switch (operation) { + case 'insert': + if (!config.table) { + errors.push({ + type: 'missing_required', + property: 'table', + message: 'Table name is required for insert operation', + fix: 'Specify the table to insert data into' + }); + } + if (!config.columns && !config.dataMode) { + warnings.push({ + type: 'missing_common', + property: 'columns', + message: 'No columns specified for insert', + suggestion: 'Define which columns to insert data into' + }); + } + break; + case 'update': + if (!config.table) { + errors.push({ + type: 'missing_required', + property: 'table', + message: 'Table name is required for update operation', + fix: 'Specify the table to update' + }); + } + if (!config.updateKey) { + warnings.push({ + type: 'missing_common', + property: 'updateKey', + message: 'No update key specified', + suggestion: 'Set updateKey to identify which rows to update (e.g., "id")' + }); + } + break; + case 'delete': + if (!config.table) { + errors.push({ + type: 'missing_required', + property: 'table', + message: 'Table name is required for delete operation', + fix: 'Specify the table to delete from' + }); + } + if (!config.deleteKey) { + errors.push({ + type: 'missing_required', + property: 'deleteKey', + message: 'Delete key is required to identify rows', + fix: 'Set deleteKey (e.g., "id") to specify which rows to delete' + }); + } + break; + case 'execute': + if (!config.query) { + errors.push({ + type: 'missing_required', + property: 'query', + message: 'SQL query is required', + fix: 'Provide the SQL query to execute' + }); + } + break; + } + if (config.connectionTimeout === undefined) { + suggestions.push('Consider setting connectionTimeout to handle slow connections'); + } + if (!config.onError && !config.retryOnFail && !config.continueOnFail) { + if (operation === 'execute' && config.query?.toLowerCase().includes('select')) { + warnings.push({ + type: 'best_practice', + property: 'errorHandling', + message: 'Database reads can fail due to connection issues', + suggestion: 'Add onError: "continueRegularOutput" and retryOnFail: true' + }); + autofix.onError = 'continueRegularOutput'; + autofix.retryOnFail = true; + autofix.maxTries = 3; + } + else if (['insert', 'update', 'delete'].includes(operation)) { + warnings.push({ + type: 'best_practice', + property: 'errorHandling', + message: 'Database writes should handle errors carefully', + suggestion: 'Add onError: "stopWorkflow" with retryOnFail for transient failures' + }); + autofix.onError = 'stopWorkflow'; + autofix.retryOnFail = true; + autofix.maxTries = 2; + autofix.waitBetweenTries = 2000; + } + } + if (config.continueOnFail !== undefined) { + warnings.push({ + type: 'deprecated', + property: 'continueOnFail', + message: 'continueOnFail is deprecated. Use onError instead', + suggestion: 'Replace with onError: "continueRegularOutput" or "stopWorkflow"' + }); + } + } + static validateAIAgent(context) { + const { config, errors, warnings, suggestions, autofix } = context; + if (config.promptType === 'define') { + if (!config.text || (typeof config.text === 'string' && config.text.trim() === '')) { + errors.push({ + type: 'missing_required', + property: 'text', + message: 'Custom prompt text is required when promptType is "define"', + fix: 'Provide a custom prompt in the text field, or change promptType to "auto"' + }); + } + } + if (!config.systemMessage || (typeof config.systemMessage === 'string' && config.systemMessage.trim() === '')) { + suggestions.push('AI Agent works best with a system message that defines the agent\'s role, capabilities, and constraints. Set systemMessage to provide context.'); + } + else if (typeof config.systemMessage === 'string' && config.systemMessage.trim().length < 20) { + warnings.push({ + type: 'inefficient', + property: 'systemMessage', + message: 'System message is very short (< 20 characters)', + suggestion: 'Consider a more detailed system message to guide the agent\'s behavior' + }); + } + if (config.hasOutputParser === true) { + warnings.push({ + type: 'best_practice', + property: 'hasOutputParser', + message: 'Output parser is enabled. Ensure an ai_outputParser connection is configured in the workflow.', + suggestion: 'Connect an output parser node (e.g., Structured Output Parser) via ai_outputParser connection type' + }); + } + if (config.needsFallback === true) { + warnings.push({ + type: 'best_practice', + property: 'needsFallback', + message: 'Fallback model is enabled. Ensure 2 language models are connected via ai_languageModel connections.', + suggestion: 'Connect a primary model and a fallback model to handle failures gracefully' + }); + } + if (config.maxIterations !== undefined) { + const maxIter = Number(config.maxIterations); + if (isNaN(maxIter) || maxIter < 1) { + errors.push({ + type: 'invalid_value', + property: 'maxIterations', + message: 'maxIterations must be a positive number', + fix: 'Set maxIterations to a value >= 1 (e.g., 10)' + }); + } + else if (maxIter > 50) { + warnings.push({ + type: 'inefficient', + property: 'maxIterations', + message: `maxIterations is set to ${maxIter}. High values can lead to long execution times and high costs.`, + suggestion: 'Consider reducing maxIterations to 10-20 for most use cases' + }); + } + } + if (!config.onError && !config.retryOnFail && !config.continueOnFail) { + warnings.push({ + type: 'best_practice', + property: 'errorHandling', + message: 'AI models can fail due to API limits, rate limits, or invalid responses', + suggestion: 'Add onError: "continueRegularOutput" with retryOnFail for resilience' + }); + autofix.onError = 'continueRegularOutput'; + autofix.retryOnFail = true; + autofix.maxTries = 2; + autofix.waitBetweenTries = 5000; + } + if (config.continueOnFail !== undefined) { + warnings.push({ + type: 'deprecated', + property: 'continueOnFail', + message: 'continueOnFail is deprecated. Use onError instead', + suggestion: 'Replace with onError: "continueRegularOutput" or "stopWorkflow"' + }); + } + } + static validateMySQL(context) { + const { config, errors, warnings, suggestions } = context; + const { operation } = config; + if (['execute', 'insert', 'update', 'delete'].includes(operation)) { + this.validateSQLQuery(context, 'mysql'); + } + switch (operation) { + case 'insert': + if (!config.table) { + errors.push({ + type: 'missing_required', + property: 'table', + message: 'Table name is required for insert operation', + fix: 'Specify the table to insert data into' + }); + } + break; + case 'update': + if (!config.table) { + errors.push({ + type: 'missing_required', + property: 'table', + message: 'Table name is required for update operation', + fix: 'Specify the table to update' + }); + } + if (!config.updateKey) { + warnings.push({ + type: 'missing_common', + property: 'updateKey', + message: 'No update key specified', + suggestion: 'Set updateKey to identify which rows to update' + }); + } + break; + case 'delete': + if (!config.table) { + errors.push({ + type: 'missing_required', + property: 'table', + message: 'Table name is required for delete operation', + fix: 'Specify the table to delete from' + }); + } + break; + case 'execute': + if (!config.query) { + errors.push({ + type: 'missing_required', + property: 'query', + message: 'SQL query is required', + fix: 'Provide the SQL query to execute' + }); + } + break; + } + if (config.timezone === undefined) { + suggestions.push('Consider setting timezone to ensure consistent date/time handling'); + } + if (!config.onError && !config.retryOnFail && !config.continueOnFail) { + if (operation === 'execute' && config.query?.toLowerCase().includes('select')) { + warnings.push({ + type: 'best_practice', + property: 'errorHandling', + message: 'Database queries can fail due to connection issues', + suggestion: 'Add onError: "continueRegularOutput" and retryOnFail: true' + }); + } + else if (['insert', 'update', 'delete'].includes(operation)) { + warnings.push({ + type: 'best_practice', + property: 'errorHandling', + message: 'Database modifications should handle errors carefully', + suggestion: 'Add onError: "stopWorkflow" with retryOnFail for transient failures' + }); + } + } + } + static validateSQLQuery(context, dbType = 'generic') { + const { config, errors, warnings, suggestions } = context; + const query = config.query || config.deleteQuery || config.updateQuery || ''; + if (!query) + return; + const lowerQuery = query.toLowerCase(); + if (query.includes('${') || query.includes('{{')) { + warnings.push({ + type: 'security', + message: 'Query contains template expressions that might be vulnerable to SQL injection', + suggestion: 'Use parameterized queries with query parameters instead of string interpolation' + }); + suggestions.push('Example: Use "SELECT * FROM users WHERE id = $1" with queryParams: [userId]'); + } + if (lowerQuery.includes('delete') && !lowerQuery.includes('where')) { + errors.push({ + type: 'invalid_value', + property: 'query', + message: 'DELETE query without WHERE clause will delete all records', + fix: 'Add a WHERE clause to specify which records to delete' + }); + } + if (lowerQuery.includes('update') && !lowerQuery.includes('where')) { + warnings.push({ + type: 'security', + message: 'UPDATE query without WHERE clause will update all records', + suggestion: 'Add a WHERE clause to specify which records to update' + }); + } + if (lowerQuery.includes('truncate')) { + warnings.push({ + type: 'security', + message: 'TRUNCATE will remove all data from the table', + suggestion: 'Consider using DELETE with WHERE clause if you need to keep some data' + }); + } + if (lowerQuery.includes('drop')) { + errors.push({ + type: 'invalid_value', + property: 'query', + message: 'DROP operations are extremely dangerous and will permanently delete database objects', + fix: 'Use this only if you really intend to delete tables/databases permanently' + }); + } + if (lowerQuery.includes('select *')) { + suggestions.push('Consider selecting specific columns instead of * for better performance'); + } + if (dbType === 'postgres') { + if (query.includes('$$')) { + suggestions.push('Dollar-quoted strings detected - ensure they are properly closed'); + } + } + else if (dbType === 'mysql') { + if (query.includes('`')) { + suggestions.push('Using backticks for identifiers - ensure they are properly paired'); + } + } + } + static validateHttpRequest(context) { + const { config, errors, warnings, suggestions, autofix } = context; + const { method = 'GET', url, sendBody, authentication } = config; + if (!url) { + errors.push({ + type: 'missing_required', + property: 'url', + message: 'URL is required for HTTP requests', + fix: 'Provide the full URL including protocol (https://...)' + }); + } + else if (!url.startsWith('http://') && !url.startsWith('https://') && !url.includes('{{')) { + warnings.push({ + type: 'invalid_value', + property: 'url', + message: 'URL should start with http:// or https://', + suggestion: 'Use https:// for secure connections' + }); + } + if (['POST', 'PUT', 'PATCH'].includes(method) && !sendBody) { + warnings.push({ + type: 'missing_common', + property: 'sendBody', + message: `${method} requests typically include a body`, + suggestion: 'Set sendBody: true and configure the body content' + }); + } + if (!config.retryOnFail && !config.onError && !config.continueOnFail) { + warnings.push({ + type: 'best_practice', + property: 'errorHandling', + message: 'HTTP requests can fail due to network issues or server errors', + suggestion: 'Add onError: "continueRegularOutput" and retryOnFail: true for resilience' + }); + autofix.onError = 'continueRegularOutput'; + autofix.retryOnFail = true; + autofix.maxTries = 3; + autofix.waitBetweenTries = 1000; + } + if (config.continueOnFail !== undefined) { + warnings.push({ + type: 'deprecated', + property: 'continueOnFail', + message: 'continueOnFail is deprecated. Use onError instead', + suggestion: 'Replace with onError: "continueRegularOutput"' + }); + autofix.onError = config.continueOnFail ? 'continueRegularOutput' : 'stopWorkflow'; + delete autofix.continueOnFail; + } + if (config.retryOnFail) { + if (!['GET', 'HEAD', 'OPTIONS'].includes(method) && (!config.maxTries || config.maxTries > 3)) { + warnings.push({ + type: 'best_practice', + property: 'maxTries', + message: `${method} requests might not be idempotent. Use fewer retries.`, + suggestion: 'Set maxTries: 2 for non-idempotent operations' + }); + } + if (!config.alwaysOutputData) { + suggestions.push('Enable alwaysOutputData to capture error responses for debugging'); + autofix.alwaysOutputData = true; + } + } + if (url && url.includes('api') && !authentication) { + warnings.push({ + type: 'security', + property: 'authentication', + message: 'API endpoints typically require authentication', + suggestion: 'Configure authentication method (Bearer token, API key, etc.)' + }); + } + if (!config.timeout) { + suggestions.push('Consider setting a timeout to prevent hanging requests'); + } + } + static validateWebhook(context) { + const { config, errors, warnings, suggestions, autofix } = context; + const { path, httpMethod = 'POST', responseMode } = config; + if (!path) { + errors.push({ + type: 'missing_required', + property: 'path', + message: 'Webhook path is required', + fix: 'Provide a unique path like "my-webhook" or "github-events"' + }); + } + else if (path.startsWith('/')) { + warnings.push({ + type: 'invalid_value', + property: 'path', + message: 'Webhook path should not start with /', + suggestion: 'Use "webhook-name" instead of "/webhook-name"' + }); + } + if (!config.onError && !config.continueOnFail) { + warnings.push({ + type: 'best_practice', + property: 'onError', + message: 'Webhooks should always send a response, even on error', + suggestion: 'Set onError: "continueRegularOutput" to ensure webhook responses' + }); + autofix.onError = 'continueRegularOutput'; + } + if (config.continueOnFail !== undefined) { + warnings.push({ + type: 'deprecated', + property: 'continueOnFail', + message: 'continueOnFail is deprecated. Use onError instead', + suggestion: 'Replace with onError: "continueRegularOutput"' + }); + autofix.onError = 'continueRegularOutput'; + delete autofix.continueOnFail; + } + if (!config.alwaysOutputData) { + suggestions.push('Enable alwaysOutputData to debug webhook payloads'); + autofix.alwaysOutputData = true; + } + suggestions.push('Consider adding webhook validation (HMAC signature verification)'); + suggestions.push('Implement rate limiting for public webhooks'); + } + static validateCode(context) { + const { config, errors, warnings, suggestions, autofix } = context; + const language = config.language || 'javaScript'; + const codeField = language === 'python' ? 'pythonCode' : 'jsCode'; + const code = config[codeField] || ''; + if (!code || code.trim() === '') { + errors.push({ + type: 'missing_required', + property: codeField, + message: 'Code cannot be empty', + fix: 'Add your code logic. Start with: return [{json: {result: "success"}}]' + }); + return; + } + if (language === 'javaScript') { + this.validateJavaScriptCode(code, errors, warnings, suggestions); + } + else if (language === 'python') { + this.validatePythonCode(code, errors, warnings, suggestions); + } + this.validateReturnStatement(code, language, errors, warnings, suggestions); + this.validateN8nVariables(code, language, warnings, suggestions, errors); + this.validateCodeSecurity(code, language, warnings); + if (!config.onError && code.length > 100) { + warnings.push({ + type: 'best_practice', + property: 'errorHandling', + message: 'Code nodes can throw errors - consider error handling', + suggestion: 'Add onError: "continueRegularOutput" to handle errors gracefully' + }); + autofix.onError = 'continueRegularOutput'; + } + if (config.mode === 'runOnceForEachItem' && code.includes('items')) { + warnings.push({ + type: 'best_practice', + message: 'In "Run Once for Each Item" mode, use $json instead of items array', + suggestion: 'Access current item data with $json.fieldName' + }); + } + if (!config.mode && code.includes('$json')) { + warnings.push({ + type: 'best_practice', + message: '$json only works in "Run Once for Each Item" mode', + suggestion: 'Either set mode: "runOnceForEachItem" or use items[0].json' + }); + } + } + static validateJavaScriptCode(code, errors, warnings, suggestions) { + const syntaxPatterns = [ + { pattern: /const\s+const/, message: 'Duplicate const declaration' }, + { pattern: /let\s+let/, message: 'Duplicate let declaration' }, + { pattern: /}\s*}\s*}\s*}$/, message: 'Multiple closing braces at end - check your nesting' } + ]; + syntaxPatterns.forEach(({ pattern, message }) => { + if (pattern.test(code)) { + errors.push({ + type: 'invalid_value', + property: 'jsCode', + message: `Syntax error: ${message}`, + fix: 'Check your JavaScript syntax' + }); + } + }); + const functionWithAwait = /function\s+\w*\s*\([^)]*\)\s*{[^}]*await/; + const arrowWithAwait = /\([^)]*\)\s*=>\s*{[^}]*await/; + if ((functionWithAwait.test(code) || arrowWithAwait.test(code)) && !code.includes('async')) { + warnings.push({ + type: 'best_practice', + message: 'Using await inside a non-async function', + suggestion: 'Add async keyword to the function, or use top-level await (Code nodes support it)' + }); + } + if (code.includes('$helpers.httpRequest')) { + suggestions.push('$helpers.httpRequest is async - use: const response = await $helpers.httpRequest(...)'); + } + if (code.includes('DateTime') && !code.includes('DateTime.')) { + warnings.push({ + type: 'best_practice', + message: 'DateTime is from Luxon library', + suggestion: 'Use DateTime.now() or DateTime.fromISO() for date operations' + }); + } + } + static validatePythonCode(code, errors, warnings, suggestions) { + const lines = code.split('\n'); + if (code.includes('__name__') && code.includes('__main__')) { + warnings.push({ + type: 'inefficient', + message: 'if __name__ == "__main__" is not needed in Code nodes', + suggestion: 'Code node Python runs directly - remove the main check' + }); + } + const unavailableImports = [ + { module: 'requests', suggestion: 'Use JavaScript Code node with $helpers.httpRequest for HTTP requests' }, + { module: 'pandas', suggestion: 'Use built-in list/dict operations or JavaScript for data manipulation' }, + { module: 'numpy', suggestion: 'Use standard Python math operations' }, + { module: 'pip', suggestion: 'External packages cannot be installed in Code nodes' } + ]; + unavailableImports.forEach(({ module, suggestion }) => { + if (code.includes(`import ${module}`) || code.includes(`from ${module}`)) { + errors.push({ + type: 'invalid_value', + property: 'pythonCode', + message: `Module '${module}' is not available in Code nodes`, + fix: suggestion + }); + } + }); + lines.forEach((line, i) => { + if (line.trim().endsWith(':') && i < lines.length - 1) { + const nextLine = lines[i + 1]; + if (nextLine.trim() && !nextLine.startsWith(' ') && !nextLine.startsWith('\t')) { + errors.push({ + type: 'invalid_value', + property: 'pythonCode', + message: `Missing indentation after line ${i + 1}`, + fix: 'Indent the line after the colon' + }); + } + } + }); + } + static validateReturnStatement(code, language, errors, warnings, suggestions) { + const hasReturn = /return\s+/.test(code); + if (!hasReturn) { + errors.push({ + type: 'missing_required', + property: language === 'python' ? 'pythonCode' : 'jsCode', + message: 'Code must return data for the next node', + fix: language === 'python' + ? 'Add: return [{"json": {"result": "success"}}]' + : 'Add: return [{json: {result: "success"}}]' + }); + return; + } + if (language === 'javaScript') { + if (/return\s+{(?!.*\[).*}\s*;?$/s.test(code) && !code.includes('json:')) { + errors.push({ + type: 'invalid_value', + property: 'jsCode', + message: 'Return value must be an array of objects', + fix: 'Wrap in array: return [{json: yourObject}]' + }); + } + if (/return\s+(true|false|null|undefined|\d+|['"`])/m.test(code)) { + errors.push({ + type: 'invalid_value', + property: 'jsCode', + message: 'Cannot return primitive values directly', + fix: 'Return array of objects: return [{json: {value: yourData}}]' + }); + } + if (/return\s+\[[\s\n]*['"`\d]/.test(code)) { + errors.push({ + type: 'invalid_value', + property: 'jsCode', + message: 'Array items must be objects with json property', + fix: 'Use: return [{json: {value: "data"}}] not return ["data"]' + }); + } + if (/return\s+items\s*;?$/.test(code) && !code.includes('map')) { + suggestions.push('Returning items directly is fine if they already have {json: ...} structure. ' + + 'To modify: return items.map(item => ({json: {...item.json, newField: "value"}}))'); + } + } + if (language === 'python') { + if (/return\s+{(?!.*\[).*}$/s.test(code)) { + errors.push({ + type: 'invalid_value', + property: 'pythonCode', + message: 'Return value must be a list of dicts', + fix: 'Wrap in list: return [{"json": your_dict}]' + }); + } + if (/return\s+(True|False|None|\d+|['"`])/m.test(code)) { + errors.push({ + type: 'invalid_value', + property: 'pythonCode', + message: 'Cannot return primitive values directly', + fix: 'Return list of dicts: return [{"json": {"value": your_data}}]' + }); + } + } + } + static validateN8nVariables(code, language, warnings, suggestions, errors) { + const inputPatterns = language === 'javaScript' + ? ['items', '$input', '$json', '$node', '$prevNode'] + : ['items', '_input']; + const usesInput = inputPatterns.some(pattern => code.includes(pattern)); + if (!usesInput && code.length > 50) { + warnings.push({ + type: 'missing_common', + message: 'Code doesn\'t reference input data', + suggestion: language === 'javaScript' + ? 'Access input with: items, $input.all(), or $json (single-item mode)' + : 'Access input with: items variable' + }); + } + if (code.includes('{{') && code.includes('}}')) { + errors.push({ + type: 'invalid_value', + property: language === 'python' ? 'pythonCode' : 'jsCode', + message: 'Expression syntax {{...}} is not valid in Code nodes', + fix: 'Use regular JavaScript/Python syntax without double curly braces' + }); + } + if (code.includes('$node[')) { + warnings.push({ + type: 'invalid_value', + property: language === 'python' ? 'pythonCode' : 'jsCode', + message: 'Use $(\'Node Name\') instead of $node[\'Node Name\'] in Code nodes', + suggestion: 'Replace $node[\'NodeName\'] with $(\'NodeName\')' + }); + } + const expressionOnlyFunctions = ['$now()', '$today()', '$tomorrow()', '.unique()', '.pluck(', '.keys()', '.hash(']; + expressionOnlyFunctions.forEach(func => { + if (code.includes(func)) { + warnings.push({ + type: 'invalid_value', + property: language === 'python' ? 'pythonCode' : 'jsCode', + message: `${func} is an expression-only function not available in Code nodes`, + suggestion: 'See Code node documentation for alternatives' + }); + } + }); + if (language === 'javaScript') { + if (/\$(?![a-zA-Z])/.test(code) && !code.includes('${')) { + warnings.push({ + type: 'best_practice', + message: 'Invalid $ usage detected', + suggestion: 'n8n variables start with $: $json, $input, $node, $workflow, $execution' + }); + } + if (code.includes('helpers.') && !code.includes('$helpers')) { + warnings.push({ + type: 'invalid_value', + property: 'jsCode', + message: 'Use $helpers not helpers', + suggestion: 'Change helpers. to $helpers.' + }); + } + if (code.includes('$helpers') && !code.includes('typeof $helpers')) { + warnings.push({ + type: 'best_practice', + message: '$helpers availability varies by n8n version', + suggestion: 'Check availability first: if (typeof $helpers !== "undefined" && $helpers.httpRequest) { ... }' + }); + } + if (code.includes('$helpers')) { + suggestions.push('Common $helpers methods: httpRequest(), prepareBinaryData(). Note: getWorkflowStaticData is a standalone function - use $getWorkflowStaticData() instead'); + } + if (code.includes('$helpers.getWorkflowStaticData')) { + errors.push({ + type: 'invalid_value', + property: 'jsCode', + message: '$helpers.getWorkflowStaticData() will cause "$helpers is not defined" error', + fix: 'Use $getWorkflowStaticData("global") or $getWorkflowStaticData("node") directly' + }); + } + if (code.includes('$jmespath(') && /\$jmespath\s*\(\s*['"`]/.test(code)) { + warnings.push({ + type: 'invalid_value', + property: 'jsCode', + message: 'Code node $jmespath has reversed parameter order: $jmespath(data, query)', + suggestion: 'Use: $jmespath(dataObject, "query.path") not $jmespath("query.path", dataObject)' + }); + } + if (code.includes('items[0].json') && !code.includes('.json.body')) { + if (code.includes('Webhook') || code.includes('webhook') || + code.includes('$("Webhook")') || code.includes("$('Webhook')")) { + warnings.push({ + type: 'invalid_value', + property: 'jsCode', + message: 'Webhook data is nested under .body property', + suggestion: 'Use items[0].json.body.fieldName instead of items[0].json.fieldName for webhook data' + }); + } + else if (/items\[0\]\.json\.(payload|data|command|action|event|message)\b/.test(code)) { + warnings.push({ + type: 'best_practice', + message: 'If processing webhook data, remember it\'s nested under .body', + suggestion: 'Webhook payloads are at items[0].json.body, not items[0].json' + }); + } + } + } + const jmespathFunction = language === 'javaScript' ? '$jmespath' : '_jmespath'; + if (code.includes(jmespathFunction + '(')) { + const filterPattern = /\[?\?[^[\]]*(?:>=?|<=?|==|!=)\s*(\d+(?:\.\d+)?)\s*\]/g; + let match; + while ((match = filterPattern.exec(code)) !== null) { + const number = match[1]; + const beforeNumber = code.substring(match.index, match.index + match[0].indexOf(number)); + const afterNumber = code.substring(match.index + match[0].indexOf(number) + number.length); + if (!beforeNumber.includes('`') || !afterNumber.startsWith('`')) { + errors.push({ + type: 'invalid_value', + property: language === 'python' ? 'pythonCode' : 'jsCode', + message: `JMESPath numeric literal ${number} must be wrapped in backticks`, + fix: `Change [?field >= ${number}] to [?field >= \`${number}\`]` + }); + } + } + suggestions.push('JMESPath in n8n requires backticks around numeric literals in filters: [?age >= `18`]'); + } + } + static validateCodeSecurity(code, language, warnings) { + const dangerousPatterns = [ + { pattern: /eval\s*\(/, message: 'Avoid eval() - it\'s a security risk' }, + { pattern: /Function\s*\(/, message: 'Avoid Function constructor - use regular functions' }, + { pattern: language === 'python' ? /exec\s*\(/ : /exec\s*\(/, message: 'Avoid exec() - it\'s a security risk' }, + { pattern: /process\.env/, message: 'Limited environment access in Code nodes' }, + { pattern: /import\s+\*/, message: 'Avoid import * - be specific about imports' } + ]; + dangerousPatterns.forEach(({ pattern, message }) => { + if (pattern.test(code)) { + warnings.push({ + type: 'security', + message, + suggestion: 'Use safer alternatives or built-in functions' + }); + } + }); + if (code.includes('require(')) { + const builtinModules = ['crypto', 'util', 'querystring', 'url', 'buffer']; + const requirePattern = /require\s*\(\s*['"`](\w+)['"`]\s*\)/g; + let match; + while ((match = requirePattern.exec(code)) !== null) { + const moduleName = match[1]; + if (!builtinModules.includes(moduleName)) { + warnings.push({ + type: 'security', + message: `Cannot require('${moduleName}') - only built-in Node.js modules are available`, + suggestion: `Available modules: ${builtinModules.join(', ')}` + }); + } + } + if (/require\s*\([^'"`]/.test(code)) { + warnings.push({ + type: 'security', + message: 'Dynamic require() not supported', + suggestion: 'Use static require with string literals: require("crypto")' + }); + } + } + if ((code.includes('crypto.') || code.includes('randomBytes') || code.includes('randomUUID')) && + !code.includes('require') && language === 'javaScript') { + warnings.push({ + type: 'invalid_value', + message: 'Using crypto without require statement', + suggestion: 'Add: const crypto = require("crypto"); at the beginning (ignore editor warnings)' + }); + } + if (/\b(fs|path|child_process)\b/.test(code)) { + warnings.push({ + type: 'security', + message: 'File system and process access not available in Code nodes', + suggestion: 'Use other n8n nodes for file operations (e.g., Read/Write Files node)' + }); + } + } + static validateSet(context) { + const { config, errors, warnings } = context; + if (config.jsonOutput !== undefined && config.jsonOutput !== null && config.jsonOutput !== '') { + try { + const parsed = JSON.parse(config.jsonOutput); + if (Array.isArray(parsed)) { + errors.push({ + type: 'invalid_value', + property: 'jsonOutput', + message: 'Set node expects a JSON object {}, not an array []', + fix: 'Either wrap array items as object properties: {"items": [...]}, OR use a different approach for multiple items' + }); + } + if (typeof parsed === 'object' && !Array.isArray(parsed) && Object.keys(parsed).length === 0) { + warnings.push({ + type: 'inefficient', + property: 'jsonOutput', + message: 'jsonOutput is an empty object - this node will output no data', + suggestion: 'Add properties to the object or remove this node if not needed' + }); + } + } + catch (e) { + errors.push({ + type: 'syntax_error', + property: 'jsonOutput', + message: `Invalid JSON in jsonOutput: ${e instanceof Error ? e.message : 'Syntax error'}`, + fix: 'Ensure jsonOutput contains valid JSON syntax' + }); + } + } + if (config.mode === 'manual') { + const hasFields = config.values && Object.keys(config.values).length > 0; + if (!hasFields && !config.jsonOutput) { + warnings.push({ + type: 'missing_common', + message: 'Set node has no fields configured - will output empty items', + suggestion: 'Add fields in the Values section or use JSON mode' + }); + } + } + } +} +exports.NodeSpecificValidators = NodeSpecificValidators; +//# sourceMappingURL=node-specific-validators.js.map \ No newline at end of file diff --git a/dist/services/node-specific-validators.js.map b/dist/services/node-specific-validators.js.map new file mode 100644 index 0000000..997deaf --- /dev/null +++ b/dist/services/node-specific-validators.js.map @@ -0,0 +1 @@ +{"version":3,"file":"node-specific-validators.js","sourceRoot":"","sources":["../../src/services/node-specific-validators.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/node-version-service.d.ts b/dist/services/node-version-service.d.ts new file mode 100644 index 0000000..db866cb --- /dev/null +++ b/dist/services/node-version-service.d.ts @@ -0,0 +1,63 @@ +import { NodeRepository } from '../database/node-repository'; +import { BreakingChangeDetector } from './breaking-change-detector'; +export interface NodeVersion { + nodeType: string; + version: string; + packageName: string; + displayName: string; + isCurrentMax: boolean; + minimumN8nVersion?: string; + breakingChanges: any[]; + deprecatedProperties: string[]; + addedProperties: string[]; + releasedAt?: Date; +} +export interface VersionComparison { + nodeType: string; + currentVersion: string; + latestVersion: string; + isOutdated: boolean; + versionGap: number; + hasBreakingChanges: boolean; + recommendUpgrade: boolean; + confidence: 'HIGH' | 'MEDIUM' | 'LOW'; + reason: string; +} +export interface UpgradePath { + nodeType: string; + fromVersion: string; + toVersion: string; + direct: boolean; + intermediateVersions: string[]; + totalBreakingChanges: number; + autoMigratableChanges: number; + manualRequiredChanges: number; + estimatedEffort: 'LOW' | 'MEDIUM' | 'HIGH'; + steps: UpgradeStep[]; +} +export interface UpgradeStep { + fromVersion: string; + toVersion: string; + breakingChanges: number; + migrationHints: string[]; +} +export declare class NodeVersionService { + private nodeRepository; + private breakingChangeDetector; + private versionCache; + private cacheTTL; + private cacheTimestamps; + constructor(nodeRepository: NodeRepository, breakingChangeDetector: BreakingChangeDetector); + getAvailableVersions(nodeType: string): NodeVersion[]; + getLatestVersion(nodeType: string): string | null; + compareVersions(currentVersion: string, latestVersion: string): number; + analyzeVersion(nodeType: string, currentVersion: string): VersionComparison; + private calculateVersionGap; + suggestUpgradePath(nodeType: string, currentVersion: string): Promise; + versionExists(nodeType: string, version: string): boolean; + getVersionMetadata(nodeType: string, version: string): NodeVersion | null; + clearCache(nodeType?: string): void; + private getCachedVersions; + private cacheVersions; +} +//# sourceMappingURL=node-version-service.d.ts.map \ No newline at end of file diff --git a/dist/services/node-version-service.d.ts.map b/dist/services/node-version-service.d.ts.map new file mode 100644 index 0000000..11bb5c3 --- /dev/null +++ b/dist/services/node-version-service.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"node-version-service.d.ts","sourceRoot":"","sources":["../../src/services/node-version-service.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAEpE,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,GAAG,EAAE,CAAC;IACvB,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,UAAU,CAAC,EAAE,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,eAAe,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC3C,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAKD,qBAAa,kBAAkB;IAM3B,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,sBAAsB;IANhC,OAAO,CAAC,YAAY,CAAyC;IAC7D,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,eAAe,CAAkC;gBAG/C,cAAc,EAAE,cAAc,EAC9B,sBAAsB,EAAE,sBAAsB;IAMxD,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE;IAiBrD,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAqBjD,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM;IAkBtE,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,iBAAiB;IA6E3E,OAAO,CAAC,mBAAmB;IAmBrB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAuG/F,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;IAQzD,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAQzE,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAanC,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,aAAa;CAItB"} \ No newline at end of file diff --git a/dist/services/node-version-service.js b/dist/services/node-version-service.js new file mode 100644 index 0000000..7d8db82 --- /dev/null +++ b/dist/services/node-version-service.js @@ -0,0 +1,215 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.NodeVersionService = void 0; +class NodeVersionService { + constructor(nodeRepository, breakingChangeDetector) { + this.nodeRepository = nodeRepository; + this.breakingChangeDetector = breakingChangeDetector; + this.versionCache = new Map(); + this.cacheTTL = 5 * 60 * 1000; + this.cacheTimestamps = new Map(); + } + getAvailableVersions(nodeType) { + const cached = this.getCachedVersions(nodeType); + if (cached) + return cached; + const versions = this.nodeRepository.getNodeVersions(nodeType); + this.cacheVersions(nodeType, versions); + return versions; + } + getLatestVersion(nodeType) { + const versions = this.getAvailableVersions(nodeType); + if (versions.length === 0) { + const node = this.nodeRepository.getNode(nodeType); + return node?.version || null; + } + const maxVersion = versions.find(v => v.isCurrentMax); + if (maxVersion) + return maxVersion.version; + const sorted = versions.sort((a, b) => this.compareVersions(b.version, a.version)); + return sorted[0]?.version || null; + } + compareVersions(currentVersion, latestVersion) { + const parts1 = currentVersion.split('.').map(Number); + const parts2 = latestVersion.split('.').map(Number); + 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; + } + analyzeVersion(nodeType, currentVersion) { + const latestVersion = this.getLatestVersion(nodeType); + if (!latestVersion) { + return { + nodeType, + currentVersion, + latestVersion: currentVersion, + isOutdated: false, + versionGap: 0, + hasBreakingChanges: false, + recommendUpgrade: false, + confidence: 'HIGH', + reason: 'No version information available. Using current version.' + }; + } + const comparison = this.compareVersions(currentVersion, latestVersion); + const isOutdated = comparison < 0; + if (!isOutdated) { + return { + nodeType, + currentVersion, + latestVersion, + isOutdated: false, + versionGap: 0, + hasBreakingChanges: false, + recommendUpgrade: false, + confidence: 'HIGH', + reason: 'Node is already at the latest version.' + }; + } + const versionGap = this.calculateVersionGap(currentVersion, latestVersion); + const hasBreakingChanges = this.breakingChangeDetector.hasBreakingChanges(nodeType, currentVersion, latestVersion); + let recommendUpgrade = true; + let confidence = 'HIGH'; + let reason = `Version ${latestVersion} available. `; + if (hasBreakingChanges) { + confidence = 'MEDIUM'; + reason += 'Contains breaking changes. Review before upgrading.'; + } + else { + reason += 'Safe to upgrade (no breaking changes detected).'; + } + if (versionGap > 2) { + confidence = 'LOW'; + reason += ` Version gap is large (${versionGap} versions). Consider incremental upgrade.`; + } + return { + nodeType, + currentVersion, + latestVersion, + isOutdated, + versionGap, + hasBreakingChanges, + recommendUpgrade, + confidence, + reason + }; + } + calculateVersionGap(fromVersion, toVersion) { + const from = fromVersion.split('.').map(Number); + const to = toVersion.split('.').map(Number); + let gap = 0; + for (let i = 0; i < Math.max(from.length, to.length); i++) { + const f = from[i] || 0; + const t = to[i] || 0; + gap += Math.abs(t - f); + } + return gap; + } + async suggestUpgradePath(nodeType, currentVersion) { + const latestVersion = this.getLatestVersion(nodeType); + if (!latestVersion) + return null; + const comparison = this.compareVersions(currentVersion, latestVersion); + if (comparison >= 0) + return null; + const allVersions = this.getAvailableVersions(nodeType); + const intermediateVersions = allVersions + .filter(v => this.compareVersions(v.version, currentVersion) > 0 && + this.compareVersions(v.version, latestVersion) < 0) + .map(v => v.version) + .sort((a, b) => this.compareVersions(a, b)); + const analysis = await this.breakingChangeDetector.analyzeVersionUpgrade(nodeType, currentVersion, latestVersion); + const versionGap = this.calculateVersionGap(currentVersion, latestVersion); + const direct = versionGap <= 1 || !analysis.hasBreakingChanges; + const steps = []; + if (direct || intermediateVersions.length === 0) { + steps.push({ + fromVersion: currentVersion, + toVersion: latestVersion, + breakingChanges: analysis.changes.filter(c => c.isBreaking).length, + migrationHints: analysis.recommendations + }); + } + else { + let stepFrom = currentVersion; + for (const intermediateVersion of intermediateVersions) { + const stepAnalysis = await this.breakingChangeDetector.analyzeVersionUpgrade(nodeType, stepFrom, intermediateVersion); + steps.push({ + fromVersion: stepFrom, + toVersion: intermediateVersion, + breakingChanges: stepAnalysis.changes.filter(c => c.isBreaking).length, + migrationHints: stepAnalysis.recommendations + }); + stepFrom = intermediateVersion; + } + const finalStepAnalysis = await this.breakingChangeDetector.analyzeVersionUpgrade(nodeType, stepFrom, latestVersion); + steps.push({ + fromVersion: stepFrom, + toVersion: latestVersion, + breakingChanges: finalStepAnalysis.changes.filter(c => c.isBreaking).length, + migrationHints: finalStepAnalysis.recommendations + }); + } + const totalBreakingChanges = steps.reduce((sum, step) => sum + step.breakingChanges, 0); + let estimatedEffort = 'LOW'; + if (totalBreakingChanges > 5 || steps.length > 3) { + estimatedEffort = 'HIGH'; + } + else if (totalBreakingChanges > 2 || steps.length > 1) { + estimatedEffort = 'MEDIUM'; + } + return { + nodeType, + fromVersion: currentVersion, + toVersion: latestVersion, + direct, + intermediateVersions, + totalBreakingChanges, + autoMigratableChanges: analysis.autoMigratableCount, + manualRequiredChanges: analysis.manualRequiredCount, + estimatedEffort, + steps + }; + } + versionExists(nodeType, version) { + const versions = this.getAvailableVersions(nodeType); + return versions.some(v => v.version === version); + } + getVersionMetadata(nodeType, version) { + const versionData = this.nodeRepository.getNodeVersion(nodeType, version); + return versionData; + } + clearCache(nodeType) { + if (nodeType) { + this.versionCache.delete(nodeType); + this.cacheTimestamps.delete(nodeType); + } + else { + this.versionCache.clear(); + this.cacheTimestamps.clear(); + } + } + getCachedVersions(nodeType) { + const cached = this.versionCache.get(nodeType); + const timestamp = this.cacheTimestamps.get(nodeType); + if (cached && timestamp) { + const age = Date.now() - timestamp; + if (age < this.cacheTTL) { + return cached; + } + } + return null; + } + cacheVersions(nodeType, versions) { + this.versionCache.set(nodeType, versions); + this.cacheTimestamps.set(nodeType, Date.now()); + } +} +exports.NodeVersionService = NodeVersionService; +//# sourceMappingURL=node-version-service.js.map \ No newline at end of file diff --git a/dist/services/node-version-service.js.map b/dist/services/node-version-service.js.map new file mode 100644 index 0000000..d65b7b3 --- /dev/null +++ b/dist/services/node-version-service.js.map @@ -0,0 +1 @@ +{"version":3,"file":"node-version-service.js","sourceRoot":"","sources":["../../src/services/node-version-service.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/operation-similarity-service.d.ts b/dist/services/operation-similarity-service.d.ts new file mode 100644 index 0000000..2f61881 --- /dev/null +++ b/dist/services/operation-similarity-service.d.ts @@ -0,0 +1,32 @@ +import { NodeRepository } from '../database/node-repository'; +export interface OperationSuggestion { + value: string; + confidence: number; + reason: string; + resource?: string; + description?: string; +} +export declare class OperationSimilarityService { + private static readonly CACHE_DURATION_MS; + private static readonly MIN_CONFIDENCE; + private static readonly MAX_SUGGESTIONS; + private static readonly CONFIDENCE_THRESHOLDS; + private repository; + private operationCache; + private suggestionCache; + private commonPatterns; + constructor(repository: NodeRepository); + private cleanupExpiredEntries; + private initializeCommonPatterns; + findSimilarOperations(nodeType: string, invalidOperation: string, resource?: string, maxSuggestions?: number): OperationSuggestion[]; + private getOperationValue; + private getResourceValue; + private getNodeOperations; + private getNodePatterns; + private calculateSimilarity; + private levenshteinDistance; + private areCommonVariations; + private getSimilarityReason; + clearCache(): void; +} +//# sourceMappingURL=operation-similarity-service.d.ts.map \ No newline at end of file diff --git a/dist/services/operation-similarity-service.d.ts.map b/dist/services/operation-similarity-service.d.ts.map new file mode 100644 index 0000000..7d14ec6 --- /dev/null +++ b/dist/services/operation-similarity-service.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"operation-similarity-service.d.ts","sourceRoot":"","sources":["../../src/services/operation-similarity-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAI7D,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AASD,qBAAa,0BAA0B;IACrC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAiB;IAC1D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAO;IAC7C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAK;IAG5C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAMlC;IAEX,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,cAAc,CAAoE;IAC1F,OAAO,CAAC,eAAe,CAAiD;IACxE,OAAO,CAAC,cAAc,CAAkC;gBAE5C,UAAU,EAAE,cAAc;IAStC,OAAO,CAAC,qBAAqB;IAwB7B,OAAO,CAAC,wBAAwB;IAmEhC,qBAAqB,CACnB,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,MAAM,EACxB,QAAQ,CAAC,EAAE,MAAM,EACjB,cAAc,GAAE,MAAmD,GAClE,mBAAmB,EAAE;IA0FxB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,iBAAiB;IA+EzB,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,mBAAmB;IAuC3B,OAAO,CAAC,mBAAmB;IA4B3B,OAAO,CAAC,mBAAmB;IAgD3B,OAAO,CAAC,mBAAmB;IAmB3B,UAAU,IAAI,IAAI;CAInB"} \ No newline at end of file diff --git a/dist/services/operation-similarity-service.js b/dist/services/operation-similarity-service.js new file mode 100644 index 0000000..581438a --- /dev/null +++ b/dist/services/operation-similarity-service.js @@ -0,0 +1,341 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.OperationSimilarityService = void 0; +const logger_1 = require("../utils/logger"); +const validation_service_error_1 = require("../errors/validation-service-error"); +class OperationSimilarityService { + constructor(repository) { + this.operationCache = new Map(); + this.suggestionCache = new Map(); + this.repository = repository; + this.commonPatterns = this.initializeCommonPatterns(); + } + cleanupExpiredEntries() { + const now = Date.now(); + for (const [key, value] of this.operationCache.entries()) { + if (now - value.timestamp >= OperationSimilarityService.CACHE_DURATION_MS) { + this.operationCache.delete(key); + } + } + if (this.suggestionCache.size > 100) { + const entries = Array.from(this.suggestionCache.entries()); + this.suggestionCache.clear(); + entries.slice(-50).forEach(([key, value]) => { + this.suggestionCache.set(key, value); + }); + } + } + initializeCommonPatterns() { + const patterns = new Map(); + patterns.set('googleDrive', [ + { pattern: 'listFiles', suggestion: 'search', confidence: 0.85, reason: 'Use "search" with resource: "fileFolder" to list files' }, + { pattern: 'uploadFile', suggestion: 'upload', confidence: 0.95, reason: 'Use "upload" instead of "uploadFile"' }, + { pattern: 'deleteFile', suggestion: 'deleteFile', confidence: 1.0, reason: 'Exact match' }, + { pattern: 'downloadFile', suggestion: 'download', confidence: 0.95, reason: 'Use "download" instead of "downloadFile"' }, + { pattern: 'getFile', suggestion: 'download', confidence: 0.8, reason: 'Use "download" to retrieve file content' }, + { pattern: 'listFolders', suggestion: 'search', confidence: 0.85, reason: 'Use "search" with resource: "fileFolder"' }, + ]); + patterns.set('slack', [ + { pattern: 'sendMessage', suggestion: 'send', confidence: 0.95, reason: 'Use "send" instead of "sendMessage"' }, + { pattern: 'getMessage', suggestion: 'get', confidence: 0.9, reason: 'Use "get" to retrieve messages' }, + { pattern: 'postMessage', suggestion: 'send', confidence: 0.9, reason: 'Use "send" to post messages' }, + { pattern: 'deleteMessage', suggestion: 'delete', confidence: 0.95, reason: 'Use "delete" instead of "deleteMessage"' }, + { pattern: 'createChannel', suggestion: 'create', confidence: 0.9, reason: 'Use "create" with resource: "channel"' }, + ]); + patterns.set('database', [ + { pattern: 'selectData', suggestion: 'select', confidence: 0.95, reason: 'Use "select" instead of "selectData"' }, + { pattern: 'insertData', suggestion: 'insert', confidence: 0.95, reason: 'Use "insert" instead of "insertData"' }, + { pattern: 'updateData', suggestion: 'update', confidence: 0.95, reason: 'Use "update" instead of "updateData"' }, + { pattern: 'deleteData', suggestion: 'delete', confidence: 0.95, reason: 'Use "delete" instead of "deleteData"' }, + { pattern: 'query', suggestion: 'select', confidence: 0.7, reason: 'Use "select" for queries' }, + { pattern: 'fetch', suggestion: 'select', confidence: 0.7, reason: 'Use "select" to fetch data' }, + ]); + patterns.set('httpRequest', [ + { pattern: 'fetch', suggestion: 'GET', confidence: 0.8, reason: 'Use "GET" method for fetching data' }, + { pattern: 'send', suggestion: 'POST', confidence: 0.7, reason: 'Use "POST" method for sending data' }, + { pattern: 'create', suggestion: 'POST', confidence: 0.8, reason: 'Use "POST" method for creating resources' }, + { pattern: 'update', suggestion: 'PUT', confidence: 0.8, reason: 'Use "PUT" method for updating resources' }, + { pattern: 'delete', suggestion: 'DELETE', confidence: 0.9, reason: 'Use "DELETE" method' }, + ]); + patterns.set('generic', [ + { pattern: 'list', suggestion: 'get', confidence: 0.6, reason: 'Consider using "get" or "search"' }, + { pattern: 'retrieve', suggestion: 'get', confidence: 0.8, reason: 'Use "get" to retrieve data' }, + { pattern: 'fetch', suggestion: 'get', confidence: 0.8, reason: 'Use "get" to fetch data' }, + { pattern: 'remove', suggestion: 'delete', confidence: 0.85, reason: 'Use "delete" to remove items' }, + { pattern: 'add', suggestion: 'create', confidence: 0.7, reason: 'Use "create" to add new items' }, + ]); + return patterns; + } + findSimilarOperations(nodeType, invalidOperation, resource, maxSuggestions = OperationSimilarityService.MAX_SUGGESTIONS) { + if (Math.random() < 0.1) { + this.cleanupExpiredEntries(); + } + const cacheKey = `${nodeType}:${invalidOperation}:${resource || ''}`; + if (this.suggestionCache.has(cacheKey)) { + return this.suggestionCache.get(cacheKey); + } + const suggestions = []; + let nodeInfo; + try { + nodeInfo = this.repository.getNode(nodeType); + if (!nodeInfo) { + return []; + } + } + catch (error) { + logger_1.logger.warn(`Error getting node ${nodeType}:`, error); + return []; + } + const validOperations = this.getNodeOperations(nodeType, resource); + for (const op of validOperations) { + const opValue = this.getOperationValue(op); + if (opValue.toLowerCase() === invalidOperation.toLowerCase()) { + return []; + } + } + const nodePatterns = this.getNodePatterns(nodeType); + for (const pattern of nodePatterns) { + if (pattern.pattern.toLowerCase() === invalidOperation.toLowerCase()) { + const exists = validOperations.some(op => { + const opValue = this.getOperationValue(op); + return opValue === pattern.suggestion; + }); + if (exists) { + suggestions.push({ + value: pattern.suggestion, + confidence: pattern.confidence, + reason: pattern.reason, + resource + }); + } + } + } + for (const op of validOperations) { + const opValue = this.getOperationValue(op); + const similarity = this.calculateSimilarity(invalidOperation, opValue); + if (similarity >= OperationSimilarityService.MIN_CONFIDENCE) { + if (!suggestions.some(s => s.value === opValue)) { + suggestions.push({ + value: opValue, + confidence: similarity, + reason: this.getSimilarityReason(similarity, invalidOperation, opValue), + resource: typeof op === 'object' ? op.resource : undefined, + description: typeof op === 'object' ? (op.description || op.name) : undefined + }); + } + } + } + suggestions.sort((a, b) => b.confidence - a.confidence); + const topSuggestions = suggestions.slice(0, maxSuggestions); + this.suggestionCache.set(cacheKey, topSuggestions); + return topSuggestions; + } + getOperationValue(op) { + if (typeof op === 'string') { + return op; + } + if (typeof op === 'object' && op !== null) { + return op.operation || op.value || ''; + } + return ''; + } + getResourceValue(resource) { + if (typeof resource === 'string') { + return resource; + } + if (typeof resource === 'object' && resource !== null) { + return resource.value || ''; + } + return ''; + } + getNodeOperations(nodeType, resource) { + if (Math.random() < 0.05) { + this.cleanupExpiredEntries(); + } + const cacheKey = `${nodeType}:${resource || 'all'}`; + const cached = this.operationCache.get(cacheKey); + if (cached && Date.now() - cached.timestamp < OperationSimilarityService.CACHE_DURATION_MS) { + return cached.operations; + } + const nodeInfo = this.repository.getNode(nodeType); + if (!nodeInfo) + return []; + let operations = []; + try { + const opsData = nodeInfo.operations; + if (typeof opsData === 'string') { + try { + operations = JSON.parse(opsData); + } + catch (parseError) { + logger_1.logger.error(`JSON parse error for operations in ${nodeType}:`, parseError); + throw validation_service_error_1.ValidationServiceError.jsonParseError(nodeType, parseError); + } + } + else if (Array.isArray(opsData)) { + operations = opsData; + } + else if (opsData && typeof opsData === 'object') { + operations = Object.values(opsData).flat(); + } + } + catch (error) { + if (error instanceof validation_service_error_1.ValidationServiceError) { + throw error; + } + logger_1.logger.warn(`Failed to process operations for ${nodeType}:`, error); + } + try { + const properties = nodeInfo.properties || []; + for (const prop of properties) { + if (prop.name === 'operation' && prop.options) { + if (prop.displayOptions?.show?.resource) { + const allowedResources = Array.isArray(prop.displayOptions.show.resource) + ? prop.displayOptions.show.resource + : [prop.displayOptions.show.resource]; + if (resource && !allowedResources.includes(resource)) { + continue; + } + } + operations.push(...prop.options.map((opt) => ({ + operation: opt.value, + name: opt.name, + description: opt.description, + resource + }))); + } + } + } + catch (error) { + logger_1.logger.warn(`Failed to extract operations from properties for ${nodeType}:`, error); + } + this.operationCache.set(cacheKey, { operations, timestamp: Date.now() }); + return operations; + } + getNodePatterns(nodeType) { + const patterns = []; + if (nodeType.includes('googleDrive')) { + patterns.push(...(this.commonPatterns.get('googleDrive') || [])); + } + else if (nodeType.includes('slack')) { + patterns.push(...(this.commonPatterns.get('slack') || [])); + } + else if (nodeType.includes('postgres') || nodeType.includes('mysql') || nodeType.includes('mongodb')) { + patterns.push(...(this.commonPatterns.get('database') || [])); + } + else if (nodeType.includes('httpRequest')) { + patterns.push(...(this.commonPatterns.get('httpRequest') || [])); + } + patterns.push(...(this.commonPatterns.get('generic') || [])); + return patterns; + } + calculateSimilarity(str1, str2) { + const s1 = str1.toLowerCase(); + const s2 = str2.toLowerCase(); + if (s1 === s2) + return 1.0; + if (s1.includes(s2) || s2.includes(s1)) { + const ratio = Math.min(s1.length, s2.length) / Math.max(s1.length, s2.length); + return Math.max(OperationSimilarityService.CONFIDENCE_THRESHOLDS.MIN_SUBSTRING, ratio); + } + const distance = this.levenshteinDistance(s1, s2); + const maxLength = Math.max(s1.length, s2.length); + let similarity = 1 - (distance / maxLength); + if (distance === 1 && maxLength <= 5) { + similarity = Math.max(similarity, 0.75); + } + else if (distance === 2 && maxLength <= 5) { + similarity = Math.max(similarity, 0.72); + } + if (this.areCommonVariations(s1, s2)) { + return Math.min(1.0, similarity + 0.2); + } + return similarity; + } + levenshteinDistance(str1, str2) { + const m = str1.length; + const n = str2.length; + const dp = Array(m + 1).fill(null).map(() => Array(n + 1).fill(0)); + for (let i = 0; i <= m; i++) + dp[i][0] = i; + for (let j = 0; j <= n; j++) + dp[0][j] = j; + for (let i = 1; i <= m; i++) { + for (let j = 1; j <= n; j++) { + if (str1[i - 1] === str2[j - 1]) { + dp[i][j] = dp[i - 1][j - 1]; + } + else { + dp[i][j] = Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + 1); + } + } + } + return dp[m][n]; + } + areCommonVariations(str1, str2) { + if (str1 === '' || str2 === '' || str1 === str2) { + return false; + } + const commonPrefixes = ['get', 'set', 'create', 'delete', 'update', 'send', 'fetch']; + const commonSuffixes = ['data', 'item', 'record', 'message', 'file', 'folder']; + for (const prefix of commonPrefixes) { + if ((str1.startsWith(prefix) && !str2.startsWith(prefix)) || + (!str1.startsWith(prefix) && str2.startsWith(prefix))) { + const s1Clean = str1.startsWith(prefix) ? str1.slice(prefix.length) : str1; + const s2Clean = str2.startsWith(prefix) ? str2.slice(prefix.length) : str2; + if ((str1.startsWith(prefix) && s1Clean !== str1) || (str2.startsWith(prefix) && s2Clean !== str2)) { + if (s1Clean === s2Clean || this.levenshteinDistance(s1Clean, s2Clean) <= 2) { + return true; + } + } + } + } + for (const suffix of commonSuffixes) { + if ((str1.endsWith(suffix) && !str2.endsWith(suffix)) || + (!str1.endsWith(suffix) && str2.endsWith(suffix))) { + const s1Clean = str1.endsWith(suffix) ? str1.slice(0, -suffix.length) : str1; + const s2Clean = str2.endsWith(suffix) ? str2.slice(0, -suffix.length) : str2; + if ((str1.endsWith(suffix) && s1Clean !== str1) || (str2.endsWith(suffix) && s2Clean !== str2)) { + if (s1Clean === s2Clean || this.levenshteinDistance(s1Clean, s2Clean) <= 2) { + return true; + } + } + } + } + return false; + } + getSimilarityReason(confidence, invalid, valid) { + const { VERY_HIGH, HIGH, MEDIUM } = OperationSimilarityService.CONFIDENCE_THRESHOLDS; + if (confidence >= VERY_HIGH) { + return 'Almost exact match - likely a typo'; + } + else if (confidence >= HIGH) { + return 'Very similar - common variation'; + } + else if (confidence >= MEDIUM) { + return 'Similar operation'; + } + else if (invalid.includes(valid) || valid.includes(invalid)) { + return 'Partial match'; + } + else { + return 'Possibly related operation'; + } + } + clearCache() { + this.operationCache.clear(); + this.suggestionCache.clear(); + } +} +exports.OperationSimilarityService = OperationSimilarityService; +OperationSimilarityService.CACHE_DURATION_MS = 5 * 60 * 1000; +OperationSimilarityService.MIN_CONFIDENCE = 0.3; +OperationSimilarityService.MAX_SUGGESTIONS = 5; +OperationSimilarityService.CONFIDENCE_THRESHOLDS = { + EXACT: 1.0, + VERY_HIGH: 0.95, + HIGH: 0.8, + MEDIUM: 0.6, + MIN_SUBSTRING: 0.7 +}; +//# sourceMappingURL=operation-similarity-service.js.map \ No newline at end of file diff --git a/dist/services/operation-similarity-service.js.map b/dist/services/operation-similarity-service.js.map new file mode 100644 index 0000000..045c350 --- /dev/null +++ b/dist/services/operation-similarity-service.js.map @@ -0,0 +1 @@ +{"version":3,"file":"operation-similarity-service.js","sourceRoot":"","sources":["../../src/services/operation-similarity-service.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/post-update-validator.d.ts b/dist/services/post-update-validator.d.ts new file mode 100644 index 0000000..42eae20 --- /dev/null +++ b/dist/services/post-update-validator.d.ts @@ -0,0 +1,59 @@ +import { BreakingChangeDetector } from './breaking-change-detector'; +import { MigrationResult } from './node-migration-service'; +import { NodeVersionService } from './node-version-service'; +export interface PostUpdateGuidance { + nodeId: string; + nodeName: string; + nodeType: string; + oldVersion: string; + newVersion: string; + migrationStatus: 'complete' | 'partial' | 'manual_required'; + requiredActions: RequiredAction[]; + deprecatedProperties: DeprecatedProperty[]; + behaviorChanges: BehaviorChange[]; + migrationSteps: string[]; + confidence: 'HIGH' | 'MEDIUM' | 'LOW'; + estimatedTime: string; +} +export interface RequiredAction { + type: 'ADD_PROPERTY' | 'UPDATE_PROPERTY' | 'CONFIGURE_OPTION' | 'REVIEW_CONFIGURATION'; + property: string; + reason: string; + suggestedValue?: any; + currentValue?: any; + documentation?: string; + priority: 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW'; +} +export interface DeprecatedProperty { + property: string; + status: 'removed' | 'deprecated'; + replacement?: string; + action: 'remove' | 'replace' | 'ignore'; + impact: 'breaking' | 'warning'; +} +export interface BehaviorChange { + aspect: string; + oldBehavior: string; + newBehavior: string; + impact: 'HIGH' | 'MEDIUM' | 'LOW'; + actionRequired: boolean; + recommendation: string; +} +export declare class PostUpdateValidator { + private versionService; + private breakingChangeDetector; + constructor(versionService: NodeVersionService, breakingChangeDetector: BreakingChangeDetector); + generateGuidance(nodeId: string, nodeName: string, nodeType: string, oldVersion: string, newVersion: string, migrationResult: MigrationResult): Promise; + private determineMigrationStatus; + private generateRequiredActions; + private identifyDeprecatedProperties; + private documentBehaviorChanges; + private generateMigrationSteps; + private mapChangeTypeToActionType; + private mapSeverityToPriority; + private getPropertyDocumentation; + private calculateConfidence; + private estimateTime; + generateSummary(guidance: PostUpdateGuidance): string; +} +//# sourceMappingURL=post-update-validator.d.ts.map \ No newline at end of file diff --git a/dist/services/post-update-validator.d.ts.map b/dist/services/post-update-validator.d.ts.map new file mode 100644 index 0000000..2a37be6 --- /dev/null +++ b/dist/services/post-update-validator.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"post-update-validator.d.ts","sourceRoot":"","sources":["../../src/services/post-update-validator.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,sBAAsB,EAAkB,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,UAAU,GAAG,SAAS,GAAG,iBAAiB,CAAC;IAC5D,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,oBAAoB,EAAE,kBAAkB,EAAE,CAAC;IAC3C,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,cAAc,GAAG,iBAAiB,GAAG,kBAAkB,GAAG,sBAAsB,CAAC;IACvF,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,GAAG,CAAC;IACrB,YAAY,CAAC,EAAE,GAAG,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;CAClD;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,YAAY,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACxC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;CAChC;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IAClC,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,mBAAmB;IAE5B,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,sBAAsB;gBADtB,cAAc,EAAE,kBAAkB,EAClC,sBAAsB,EAAE,sBAAsB;IAMlD,gBAAgB,CACpB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,eAAe,GAC/B,OAAO,CAAC,kBAAkB,CAAC;IAsD9B,OAAO,CAAC,wBAAwB;IAoBhC,OAAO,CAAC,uBAAuB;IA4B/B,OAAO,CAAC,4BAA4B;IAqBpC,OAAO,CAAC,uBAAuB;IAuD/B,OAAO,CAAC,sBAAsB;IAmE9B,OAAO,CAAC,yBAAyB;IAmBjC,OAAO,CAAC,qBAAqB;IAU7B,OAAO,CAAC,wBAAwB;IAQhC,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,YAAY;IAoBpB,eAAe,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM;CA2BtD"} \ No newline at end of file diff --git a/dist/services/post-update-validator.js b/dist/services/post-update-validator.js new file mode 100644 index 0000000..256d022 --- /dev/null +++ b/dist/services/post-update-validator.js @@ -0,0 +1,231 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.PostUpdateValidator = void 0; +class PostUpdateValidator { + constructor(versionService, breakingChangeDetector) { + this.versionService = versionService; + this.breakingChangeDetector = breakingChangeDetector; + } + async generateGuidance(nodeId, nodeName, nodeType, oldVersion, newVersion, migrationResult) { + const analysis = await this.breakingChangeDetector.analyzeVersionUpgrade(nodeType, oldVersion, newVersion); + const migrationStatus = this.determineMigrationStatus(migrationResult, analysis.changes); + const requiredActions = this.generateRequiredActions(migrationResult, analysis.changes, nodeType); + const deprecatedProperties = this.identifyDeprecatedProperties(analysis.changes); + const behaviorChanges = this.documentBehaviorChanges(nodeType, oldVersion, newVersion); + const migrationSteps = this.generateMigrationSteps(requiredActions, deprecatedProperties, behaviorChanges); + const confidence = this.calculateConfidence(requiredActions, migrationStatus); + const estimatedTime = this.estimateTime(requiredActions, behaviorChanges); + return { + nodeId, + nodeName, + nodeType, + oldVersion, + newVersion, + migrationStatus, + requiredActions, + deprecatedProperties, + behaviorChanges, + migrationSteps, + confidence, + estimatedTime + }; + } + determineMigrationStatus(migrationResult, changes) { + if (migrationResult.remainingIssues.length === 0) { + return 'complete'; + } + const criticalIssues = changes.filter(c => c.isBreaking && !c.autoMigratable); + if (criticalIssues.length > 0) { + return 'manual_required'; + } + return 'partial'; + } + generateRequiredActions(migrationResult, changes, nodeType) { + const actions = []; + const manualChanges = changes.filter(c => !c.autoMigratable); + for (const change of manualChanges) { + actions.push({ + type: this.mapChangeTypeToActionType(change.changeType), + property: change.propertyName, + reason: change.migrationHint, + suggestedValue: change.newValue, + currentValue: change.oldValue, + documentation: this.getPropertyDocumentation(nodeType, change.propertyName), + priority: this.mapSeverityToPriority(change.severity) + }); + } + return actions; + } + identifyDeprecatedProperties(changes) { + const deprecated = []; + for (const change of changes) { + if (change.changeType === 'removed') { + deprecated.push({ + property: change.propertyName, + status: 'removed', + replacement: change.migrationStrategy?.targetProperty, + action: change.autoMigratable ? 'remove' : 'replace', + impact: change.isBreaking ? 'breaking' : 'warning' + }); + } + } + return deprecated; + } + documentBehaviorChanges(nodeType, oldVersion, newVersion) { + const changes = []; + if (nodeType === 'n8n-nodes-base.executeWorkflow') { + if (this.versionService.compareVersions(oldVersion, '1.1') < 0 && + this.versionService.compareVersions(newVersion, '1.1') >= 0) { + changes.push({ + aspect: 'Data passing to sub-workflows', + oldBehavior: 'Automatic data passing - all data from parent workflow automatically available', + newBehavior: 'Explicit field mapping required - must define inputFieldMapping to pass specific fields', + impact: 'HIGH', + actionRequired: true, + recommendation: 'Define inputFieldMapping with specific field mappings between parent and child workflows. Review data dependencies.' + }); + } + } + if (nodeType === 'n8n-nodes-base.webhook') { + if (this.versionService.compareVersions(oldVersion, '2.1') < 0 && + this.versionService.compareVersions(newVersion, '2.1') >= 0) { + changes.push({ + aspect: 'Webhook persistence', + oldBehavior: 'Webhook URL changes on workflow updates', + newBehavior: 'Stable webhook URL via webhookId field', + impact: 'MEDIUM', + actionRequired: false, + recommendation: 'Webhook URLs now remain stable across workflow updates. Update external systems if needed.' + }); + } + if (this.versionService.compareVersions(oldVersion, '2.0') < 0 && + this.versionService.compareVersions(newVersion, '2.0') >= 0) { + changes.push({ + aspect: 'Response handling', + oldBehavior: 'Automatic response after webhook trigger', + newBehavior: 'Configurable response mode (onReceived vs lastNode)', + impact: 'MEDIUM', + actionRequired: true, + recommendation: 'Review responseMode setting. Use "onReceived" for immediate responses or "lastNode" to wait for workflow completion.' + }); + } + } + return changes; + } + generateMigrationSteps(requiredActions, deprecatedProperties, behaviorChanges) { + const steps = []; + let stepNumber = 1; + if (deprecatedProperties.length > 0) { + steps.push(`Step ${stepNumber++}: Remove deprecated properties`); + for (const dep of deprecatedProperties) { + steps.push(` - Remove "${dep.property}" ${dep.replacement ? `(use "${dep.replacement}" instead)` : ''}`); + } + } + const criticalActions = requiredActions.filter(a => a.priority === 'CRITICAL'); + if (criticalActions.length > 0) { + steps.push(`Step ${stepNumber++}: Address critical configuration requirements`); + for (const action of criticalActions) { + steps.push(` - ${action.property}: ${action.reason}`); + if (action.suggestedValue !== undefined) { + steps.push(` Suggested value: ${JSON.stringify(action.suggestedValue)}`); + } + } + } + const highActions = requiredActions.filter(a => a.priority === 'HIGH'); + if (highActions.length > 0) { + steps.push(`Step ${stepNumber++}: Configure required properties`); + for (const action of highActions) { + steps.push(` - ${action.property}: ${action.reason}`); + } + } + const actionRequiredChanges = behaviorChanges.filter(c => c.actionRequired); + if (actionRequiredChanges.length > 0) { + steps.push(`Step ${stepNumber++}: Adapt to behavior changes`); + for (const change of actionRequiredChanges) { + steps.push(` - ${change.aspect}: ${change.recommendation}`); + } + } + const otherActions = requiredActions.filter(a => a.priority === 'MEDIUM' || a.priority === 'LOW'); + if (otherActions.length > 0) { + steps.push(`Step ${stepNumber++}: Review optional configurations`); + for (const action of otherActions) { + steps.push(` - ${action.property}: ${action.reason}`); + } + } + steps.push(`Step ${stepNumber}: Test workflow execution`); + steps.push(' - Validate all node configurations'); + steps.push(' - Run a test execution'); + steps.push(' - Verify expected behavior'); + return steps; + } + mapChangeTypeToActionType(changeType) { + switch (changeType) { + case 'added': + return 'ADD_PROPERTY'; + case 'requirement_changed': + case 'type_changed': + return 'UPDATE_PROPERTY'; + case 'default_changed': + return 'CONFIGURE_OPTION'; + default: + return 'REVIEW_CONFIGURATION'; + } + } + mapSeverityToPriority(severity) { + if (severity === 'HIGH') + return 'CRITICAL'; + return severity; + } + getPropertyDocumentation(nodeType, propertyName) { + return `See n8n documentation for ${nodeType} - ${propertyName}`; + } + calculateConfidence(requiredActions, migrationStatus) { + if (migrationStatus === 'complete') + return 'HIGH'; + const criticalActions = requiredActions.filter(a => a.priority === 'CRITICAL'); + if (migrationStatus === 'manual_required' || criticalActions.length > 3) { + return 'LOW'; + } + return 'MEDIUM'; + } + estimateTime(requiredActions, behaviorChanges) { + const criticalCount = requiredActions.filter(a => a.priority === 'CRITICAL').length; + const highCount = requiredActions.filter(a => a.priority === 'HIGH').length; + const behaviorCount = behaviorChanges.filter(c => c.actionRequired).length; + const totalComplexity = criticalCount * 5 + highCount * 3 + behaviorCount * 2; + if (totalComplexity === 0) + return '< 1 minute'; + if (totalComplexity <= 5) + return '2-5 minutes'; + if (totalComplexity <= 10) + return '5-10 minutes'; + if (totalComplexity <= 20) + return '10-20 minutes'; + return '20+ minutes'; + } + generateSummary(guidance) { + const lines = []; + lines.push(`Node "${guidance.nodeName}" upgraded from v${guidance.oldVersion} to v${guidance.newVersion}`); + lines.push(`Status: ${guidance.migrationStatus.toUpperCase()}`); + lines.push(`Confidence: ${guidance.confidence}`); + lines.push(`Estimated time: ${guidance.estimatedTime}`); + if (guidance.requiredActions.length > 0) { + lines.push(`\nRequired actions: ${guidance.requiredActions.length}`); + for (const action of guidance.requiredActions.slice(0, 3)) { + lines.push(` - [${action.priority}] ${action.property}: ${action.reason}`); + } + if (guidance.requiredActions.length > 3) { + lines.push(` ... and ${guidance.requiredActions.length - 3} more`); + } + } + if (guidance.behaviorChanges.length > 0) { + lines.push(`\nBehavior changes: ${guidance.behaviorChanges.length}`); + for (const change of guidance.behaviorChanges) { + lines.push(` - ${change.aspect}: ${change.newBehavior}`); + } + } + return lines.join('\n'); + } +} +exports.PostUpdateValidator = PostUpdateValidator; +//# sourceMappingURL=post-update-validator.js.map \ No newline at end of file diff --git a/dist/services/post-update-validator.js.map b/dist/services/post-update-validator.js.map new file mode 100644 index 0000000..2e5acbf --- /dev/null +++ b/dist/services/post-update-validator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"post-update-validator.js","sourceRoot":"","sources":["../../src/services/post-update-validator.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/property-dependencies.d.ts b/dist/services/property-dependencies.d.ts new file mode 100644 index 0000000..fffea9f --- /dev/null +++ b/dist/services/property-dependencies.d.ts @@ -0,0 +1,36 @@ +export interface PropertyDependency { + property: string; + displayName: string; + dependsOn: DependencyCondition[]; + showWhen?: Record; + hideWhen?: Record; + enablesProperties?: string[]; + disablesProperties?: string[]; + notes?: string[]; +} +export interface DependencyCondition { + property: string; + values: any[]; + condition: 'equals' | 'not_equals' | 'includes' | 'not_includes'; + description?: string; +} +export interface DependencyAnalysis { + totalProperties: number; + propertiesWithDependencies: number; + dependencies: PropertyDependency[]; + dependencyGraph: Record; + suggestions: string[]; +} +export declare class PropertyDependencies { + static analyze(properties: any[]): DependencyAnalysis; + private static extractDependency; + private static generateConditionDescription; + private static generateSuggestions; + static getVisibilityImpact(properties: any[], config: Record): { + visible: string[]; + hidden: string[]; + reasons: Record; + }; + private static checkVisibility; +} +//# sourceMappingURL=property-dependencies.d.ts.map \ No newline at end of file diff --git a/dist/services/property-dependencies.d.ts.map b/dist/services/property-dependencies.d.ts.map new file mode 100644 index 0000000..c49d74d --- /dev/null +++ b/dist/services/property-dependencies.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"property-dependencies.d.ts","sourceRoot":"","sources":["../../src/services/property-dependencies.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,GAAG,EAAE,CAAC;IACd,SAAS,EAAE,QAAQ,GAAG,YAAY,GAAG,UAAU,GAAG,cAAc,CAAC;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,0BAA0B,EAAE,MAAM,CAAC;IACnC,YAAY,EAAE,kBAAkB,EAAE,CAAC;IACnC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1C,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,qBAAa,oBAAoB;IAI/B,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,kBAAkB;IAyCrD,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAmDhC,OAAO,CAAC,MAAM,CAAC,4BAA4B;IA2B3C,OAAO,CAAC,MAAM,CAAC,mBAAmB;IA4ClC,MAAM,CAAC,mBAAmB,CACxB,UAAU,EAAE,GAAG,EAAE,EACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC1B;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE;IAyB3E,OAAO,CAAC,MAAM,CAAC,eAAe;CAwC/B"} \ No newline at end of file diff --git a/dist/services/property-dependencies.js b/dist/services/property-dependencies.js new file mode 100644 index 0000000..8293a1a --- /dev/null +++ b/dist/services/property-dependencies.js @@ -0,0 +1,168 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.PropertyDependencies = void 0; +class PropertyDependencies { + static analyze(properties) { + const dependencies = []; + const dependencyGraph = {}; + const suggestions = []; + for (const prop of properties) { + if (prop.displayOptions?.show || prop.displayOptions?.hide) { + const dependency = this.extractDependency(prop, properties); + dependencies.push(dependency); + for (const condition of dependency.dependsOn) { + if (!dependencyGraph[condition.property]) { + dependencyGraph[condition.property] = []; + } + dependencyGraph[condition.property].push(prop.name); + } + } + } + for (const dep of dependencies) { + dep.enablesProperties = dependencyGraph[dep.property] || []; + } + this.generateSuggestions(dependencies, suggestions); + return { + totalProperties: properties.length, + propertiesWithDependencies: dependencies.length, + dependencies, + dependencyGraph, + suggestions + }; + } + static extractDependency(prop, allProperties) { + const dependency = { + property: prop.name, + displayName: prop.displayName || prop.name, + dependsOn: [], + showWhen: prop.displayOptions?.show, + hideWhen: prop.displayOptions?.hide, + notes: [] + }; + if (prop.displayOptions?.show) { + for (const [key, values] of Object.entries(prop.displayOptions.show)) { + const valuesArray = Array.isArray(values) ? values : [values]; + dependency.dependsOn.push({ + property: key, + values: valuesArray, + condition: 'equals', + description: this.generateConditionDescription(key, valuesArray, 'show', allProperties) + }); + } + } + if (prop.displayOptions?.hide) { + for (const [key, values] of Object.entries(prop.displayOptions.hide)) { + const valuesArray = Array.isArray(values) ? values : [values]; + dependency.dependsOn.push({ + property: key, + values: valuesArray, + condition: 'not_equals', + description: this.generateConditionDescription(key, valuesArray, 'hide', allProperties) + }); + } + } + if (prop.type === 'collection' || prop.type === 'fixedCollection') { + dependency.notes?.push('This property contains nested properties that may have their own dependencies'); + } + if (dependency.dependsOn.length > 1) { + dependency.notes?.push('Multiple conditions must be met for this property to be visible'); + } + return dependency; + } + static generateConditionDescription(property, values, type, allProperties) { + const prop = allProperties.find(p => p.name === property); + const propName = prop?.displayName || property; + if (type === 'show') { + if (values.length === 1) { + return `Visible when ${propName} is set to "${values[0]}"`; + } + else { + return `Visible when ${propName} is one of: ${values.map(v => `"${v}"`).join(', ')}`; + } + } + else { + if (values.length === 1) { + return `Hidden when ${propName} is set to "${values[0]}"`; + } + else { + return `Hidden when ${propName} is one of: ${values.map(v => `"${v}"`).join(', ')}`; + } + } + } + static generateSuggestions(dependencies, suggestions) { + const controllers = new Map(); + for (const dep of dependencies) { + for (const condition of dep.dependsOn) { + controllers.set(condition.property, (controllers.get(condition.property) || 0) + 1); + } + } + const sortedControllers = Array.from(controllers.entries()) + .sort((a, b) => b[1] - a[1]) + .slice(0, 3); + if (sortedControllers.length > 0) { + suggestions.push(`Key properties to configure first: ${sortedControllers.map(([prop]) => prop).join(', ')}`); + } + const complexDeps = dependencies.filter(d => d.dependsOn.length > 1); + if (complexDeps.length > 0) { + suggestions.push(`${complexDeps.length} properties have multiple dependencies - check their conditions carefully`); + } + for (const dep of dependencies) { + for (const condition of dep.dependsOn) { + const targetDep = dependencies.find(d => d.property === condition.property); + if (targetDep?.dependsOn.some(c => c.property === dep.property)) { + suggestions.push(`Circular dependency detected between ${dep.property} and ${condition.property}`); + } + } + } + } + static getVisibilityImpact(properties, config) { + const visible = []; + const hidden = []; + const reasons = {}; + for (const prop of properties) { + const { isVisible, reason } = this.checkVisibility(prop, config); + if (isVisible) { + visible.push(prop.name); + } + else { + hidden.push(prop.name); + } + if (reason) { + reasons[prop.name] = reason; + } + } + return { visible, hidden, reasons }; + } + static checkVisibility(prop, config) { + if (!prop.displayOptions) { + return { isVisible: true }; + } + if (prop.displayOptions.show) { + for (const [key, values] of Object.entries(prop.displayOptions.show)) { + const configValue = config[key]; + const expectedValues = Array.isArray(values) ? values : [values]; + if (!expectedValues.includes(configValue)) { + return { + isVisible: false, + reason: `Hidden because ${key} is "${configValue}" (needs to be ${expectedValues.join(' or ')})` + }; + } + } + } + if (prop.displayOptions.hide) { + for (const [key, values] of Object.entries(prop.displayOptions.hide)) { + const configValue = config[key]; + const expectedValues = Array.isArray(values) ? values : [values]; + if (expectedValues.includes(configValue)) { + return { + isVisible: false, + reason: `Hidden because ${key} is "${configValue}"` + }; + } + } + } + return { isVisible: true }; + } +} +exports.PropertyDependencies = PropertyDependencies; +//# sourceMappingURL=property-dependencies.js.map \ No newline at end of file diff --git a/dist/services/property-dependencies.js.map b/dist/services/property-dependencies.js.map new file mode 100644 index 0000000..31780ff --- /dev/null +++ b/dist/services/property-dependencies.js.map @@ -0,0 +1 @@ +{"version":3,"file":"property-dependencies.js","sourceRoot":"","sources":["../../src/services/property-dependencies.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/property-filter.d.ts b/dist/services/property-filter.d.ts new file mode 100644 index 0000000..1856611 --- /dev/null +++ b/dist/services/property-filter.d.ts @@ -0,0 +1,44 @@ +export interface SimplifiedProperty { + name: string; + displayName: string; + type: string; + description: string; + default?: any; + options?: Array<{ + value: string; + label: string; + }>; + required?: boolean; + placeholder?: string; + showWhen?: Record; + usageHint?: string; + expectedFormat?: { + structure: Record; + modes?: string[]; + example: Record; + }; +} +export interface EssentialConfig { + required: string[]; + common: string[]; + categoryPriority?: string[]; +} +export interface FilteredProperties { + required: SimplifiedProperty[]; + common: SimplifiedProperty[]; +} +export declare class PropertyFilter { + private static ESSENTIAL_PROPERTIES; + static deduplicateProperties(properties: any[]): any[]; + static getEssentials(allProperties: any[], nodeType: string): FilteredProperties; + private static extractProperties; + private static findPropertyByName; + private static simplifyProperty; + private static generateUsageHint; + private static extractDescription; + private static generateDescription; + private static inferEssentials; + static searchProperties(allProperties: any[], query: string, maxResults?: number): SimplifiedProperty[]; + private static searchPropertiesRecursive; +} +//# sourceMappingURL=property-filter.d.ts.map \ No newline at end of file diff --git a/dist/services/property-filter.d.ts.map b/dist/services/property-filter.d.ts.map new file mode 100644 index 0000000..d737e82 --- /dev/null +++ b/dist/services/property-filter.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"property-filter.d.ts","sourceRoot":"","sources":["../../src/services/property-filter.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE;QACf,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAClC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KAC9B,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,MAAM,EAAE,kBAAkB,EAAE,CAAC;CAC9B;AAED,qBAAa,cAAc;IAKzB,OAAO,CAAC,MAAM,CAAC,oBAAoB,CA4IjC;IAKF,MAAM,CAAC,qBAAqB,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE;IAyBtD,MAAM,CAAC,aAAa,CAAC,aAAa,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,kBAAkB;IA6BhF,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAwBhC,OAAO,CAAC,MAAM,CAAC,kBAAkB;IA6BjC,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAiE/B,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAgChC,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAmBjC,OAAO,CAAC,MAAM,CAAC,mBAAmB;IA+DlC,OAAO,CAAC,MAAM,CAAC,eAAe;IAuD9B,MAAM,CAAC,gBAAgB,CACrB,aAAa,EAAE,GAAG,EAAE,EACpB,KAAK,EAAE,MAAM,EACb,UAAU,GAAE,MAAW,GACtB,kBAAkB,EAAE;IAwBvB,OAAO,CAAC,MAAM,CAAC,yBAAyB;CAkDzC"} \ No newline at end of file diff --git a/dist/services/property-filter.js b/dist/services/property-filter.js new file mode 100644 index 0000000..a61dd8d --- /dev/null +++ b/dist/services/property-filter.js @@ -0,0 +1,395 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.PropertyFilter = void 0; +class PropertyFilter { + static deduplicateProperties(properties) { + const seen = new Map(); + return properties.filter(prop => { + if (!prop || !prop.name) { + return false; + } + const conditions = JSON.stringify(prop.displayOptions || {}); + const key = `${prop.name}_${conditions}`; + if (seen.has(key)) { + return false; + } + seen.set(key, prop); + return true; + }); + } + static getEssentials(allProperties, nodeType) { + if (!allProperties) { + return { required: [], common: [] }; + } + const uniqueProperties = this.deduplicateProperties(allProperties); + const config = this.ESSENTIAL_PROPERTIES[nodeType]; + if (!config) { + return this.inferEssentials(uniqueProperties); + } + const required = this.extractProperties(uniqueProperties, config.required, true); + const requiredNames = new Set(required.map(p => p.name)); + const common = this.extractProperties(uniqueProperties, config.common, false) + .filter(p => !requiredNames.has(p.name)); + return { required, common }; + } + static extractProperties(allProperties, propertyNames, markAsRequired) { + const extracted = []; + for (const name of propertyNames) { + const property = this.findPropertyByName(allProperties, name); + if (property) { + const simplified = this.simplifyProperty(property); + if (markAsRequired) { + simplified.required = true; + } + extracted.push(simplified); + } + } + return extracted; + } + static findPropertyByName(properties, name) { + for (const prop of properties) { + if (prop.name === name) { + return prop; + } + if (prop.type === 'collection' && prop.options) { + const found = this.findPropertyByName(prop.options, name); + if (found) + return found; + } + if (prop.type === 'fixedCollection' && prop.options) { + for (const option of prop.options) { + if (option.values) { + const found = this.findPropertyByName(option.values, name); + if (found) + return found; + } + } + } + } + return undefined; + } + static simplifyProperty(prop) { + const simplified = { + name: prop.name, + displayName: prop.displayName || prop.name, + type: prop.type || 'string', + description: this.extractDescription(prop), + required: prop.required || false + }; + if (prop.default !== undefined && + typeof prop.default !== 'object' || + prop.type === 'options' || + prop.type === 'multiOptions') { + simplified.default = prop.default; + } + if (prop.placeholder) { + simplified.placeholder = prop.placeholder; + } + if (prop.options && Array.isArray(prop.options)) { + const limitedOptions = prop.options.slice(0, 20); + simplified.options = limitedOptions.map((opt) => { + if (typeof opt === 'string') { + return { value: opt, label: opt }; + } + return { + value: opt.value || opt.name, + label: opt.name || opt.value || opt.displayName + }; + }); + } + if (prop.type === 'resourceLocator') { + const modes = prop.modes?.map((m) => m.name || m) || ['list', 'id']; + const defaultValue = prop.default?.value || 'your-resource-id'; + simplified.expectedFormat = { + structure: { mode: 'string', value: 'string' }, + modes, + example: { mode: 'id', value: defaultValue } + }; + } + if (prop.displayOptions?.show) { + const conditions = Object.keys(prop.displayOptions.show); + if (conditions.length <= 2) { + simplified.showWhen = prop.displayOptions.show; + } + } + simplified.usageHint = this.generateUsageHint(prop); + return simplified; + } + static generateUsageHint(prop) { + if (prop.name.toLowerCase().includes('url') || prop.name === 'endpoint') { + return 'Enter the full URL including https://'; + } + if (prop.name.includes('auth') || prop.name.includes('credential')) { + return 'Select authentication method or credentials'; + } + if (prop.type === 'json' || prop.name.includes('json')) { + return 'Enter valid JSON data'; + } + if (prop.type === 'code' || prop.name.includes('code')) { + return 'Enter your code here'; + } + if (prop.type === 'boolean' && prop.displayOptions) { + return 'Enabling this will show additional options'; + } + return undefined; + } + static extractDescription(prop) { + const description = prop.description || + prop.hint || + prop.placeholder || + prop.displayName || + ''; + if (!description) { + return this.generateDescription(prop); + } + return description; + } + static generateDescription(prop) { + const name = prop.name.toLowerCase(); + const type = prop.type; + const commonDescriptions = { + 'url': 'The URL to make the request to', + 'method': 'HTTP method to use for the request', + 'authentication': 'Authentication method to use', + 'sendbody': 'Whether to send a request body', + 'contenttype': 'Content type of the request body', + 'sendheaders': 'Whether to send custom headers', + 'jsonbody': 'JSON data to send in the request body', + 'headers': 'Custom headers to send with the request', + 'timeout': 'Request timeout in milliseconds', + 'query': 'SQL query to execute', + 'table': 'Database table name', + 'operation': 'Operation to perform', + 'path': 'Webhook path or file path', + 'httpmethod': 'HTTP method to accept', + 'responsemode': 'How to respond to the webhook', + 'responsecode': 'HTTP response code to return', + 'channel': 'Slack channel to send message to', + 'text': 'Text content of the message', + 'subject': 'Email subject line', + 'fromemail': 'Sender email address', + 'toemail': 'Recipient email address', + 'language': 'Programming language to use', + 'jscode': 'JavaScript code to execute', + 'pythoncode': 'Python code to execute' + }; + if (commonDescriptions[name]) { + return commonDescriptions[name]; + } + for (const [key, desc] of Object.entries(commonDescriptions)) { + if (name.includes(key)) { + return desc; + } + } + if (type === 'boolean') { + return `Enable or disable ${prop.displayName || name}`; + } + else if (type === 'options') { + return `Select ${prop.displayName || name}`; + } + else if (type === 'string') { + return `Enter ${prop.displayName || name}`; + } + else if (type === 'number') { + return `Number value for ${prop.displayName || name}`; + } + else if (type === 'json') { + return `JSON data for ${prop.displayName || name}`; + } + return `Configure ${prop.displayName || name}`; + } + static inferEssentials(properties) { + const required = properties + .filter(p => p.name && p.required === true) + .slice(0, 10) + .map(p => this.simplifyProperty(p)); + const common = properties + .filter(p => { + return p.name && + !p.required && + !p.displayOptions && + p.type !== 'hidden' && + p.type !== 'notice' && + !p.name.startsWith('options') && + !p.name.startsWith('_'); + }) + .slice(0, 10) + .map(p => this.simplifyProperty(p)); + if (required.length + common.length < 10) { + const additional = properties + .filter(p => { + return p.name && + !p.required && + p.type !== 'hidden' && + p.displayOptions && + Object.keys(p.displayOptions.show || {}).length === 1; + }) + .slice(0, 10 - (required.length + common.length)) + .map(p => this.simplifyProperty(p)); + common.push(...additional); + } + const totalLimit = 30; + if (required.length + common.length > totalLimit) { + const requiredCount = Math.min(required.length, 15); + const commonCount = totalLimit - requiredCount; + return { + required: required.slice(0, requiredCount), + common: common.slice(0, commonCount) + }; + } + return { required, common }; + } + static searchProperties(allProperties, query, maxResults = 20) { + if (!query || query.trim() === '') { + return []; + } + const lowerQuery = query.toLowerCase(); + const matches = []; + this.searchPropertiesRecursive(allProperties, lowerQuery, matches); + return matches + .sort((a, b) => b.score - a.score) + .slice(0, maxResults) + .map(match => ({ + ...this.simplifyProperty(match.property), + path: match.path + })); + } + static searchPropertiesRecursive(properties, query, matches, path = '') { + for (const prop of properties) { + const currentPath = path ? `${path}.${prop.name}` : prop.name; + let score = 0; + if (prop.name.toLowerCase() === query) { + score = 10; + } + else if (prop.name.toLowerCase().startsWith(query)) { + score = 8; + } + else if (prop.name.toLowerCase().includes(query)) { + score = 5; + } + if (prop.displayName?.toLowerCase().includes(query)) { + score = Math.max(score, 4); + } + if (prop.description?.toLowerCase().includes(query)) { + score = Math.max(score, 3); + } + if (score > 0) { + matches.push({ property: prop, score, path: currentPath }); + } + if (prop.type === 'collection' && prop.options) { + this.searchPropertiesRecursive(prop.options, query, matches, currentPath); + } + else if (prop.type === 'fixedCollection' && prop.options) { + for (const option of prop.options) { + if (option.values) { + this.searchPropertiesRecursive(option.values, query, matches, `${currentPath}.${option.name}`); + } + } + } + } + } +} +exports.PropertyFilter = PropertyFilter; +PropertyFilter.ESSENTIAL_PROPERTIES = { + 'nodes-base.httpRequest': { + required: ['url'], + common: ['method', 'authentication', 'sendBody', 'contentType', 'sendHeaders'], + categoryPriority: ['basic', 'authentication', 'request', 'response', 'advanced'] + }, + 'nodes-base.webhook': { + required: [], + common: ['httpMethod', 'path', 'responseMode', 'responseData', 'responseCode'], + categoryPriority: ['basic', 'response', 'advanced'] + }, + 'nodes-base.code': { + required: [], + common: ['language', 'jsCode', 'pythonCode', 'mode'], + categoryPriority: ['basic', 'code', 'advanced'] + }, + 'nodes-base.set': { + required: [], + common: ['mode', 'assignments', 'includeOtherFields', 'options'], + categoryPriority: ['basic', 'data', 'advanced'] + }, + 'nodes-base.if': { + required: [], + common: ['conditions', 'combineOperation'], + categoryPriority: ['basic', 'conditions', 'advanced'] + }, + 'nodes-base.postgres': { + required: [], + common: ['operation', 'table', 'query', 'additionalFields', 'returnAll'], + categoryPriority: ['basic', 'query', 'options', 'advanced'] + }, + 'nodes-base.openAi': { + required: [], + common: ['resource', 'operation', 'modelId', 'prompt', 'messages', 'maxTokens'], + categoryPriority: ['basic', 'model', 'input', 'options', 'advanced'] + }, + 'nodes-base.googleSheets': { + required: [], + common: ['operation', 'documentId', 'sheetName', 'range', 'dataStartRow'], + categoryPriority: ['basic', 'location', 'data', 'options', 'advanced'] + }, + 'nodes-base.slack': { + required: [], + common: ['resource', 'operation', 'channel', 'text', 'attachments', 'blocks'], + categoryPriority: ['basic', 'message', 'formatting', 'advanced'] + }, + 'nodes-base.email': { + required: [], + common: ['resource', 'operation', 'fromEmail', 'toEmail', 'subject', 'text', 'html'], + categoryPriority: ['basic', 'recipients', 'content', 'advanced'] + }, + 'nodes-base.merge': { + required: [], + common: ['mode', 'joinMode', 'propertyName1', 'propertyName2', 'outputDataFrom'], + categoryPriority: ['basic', 'merge', 'advanced'] + }, + 'nodes-base.function': { + required: [], + common: ['functionCode'], + categoryPriority: ['basic', 'code', 'advanced'] + }, + 'nodes-base.splitInBatches': { + required: [], + common: ['batchSize', 'options'], + categoryPriority: ['basic', 'options', 'advanced'] + }, + 'nodes-base.redis': { + required: [], + common: ['operation', 'key', 'value', 'keyType', 'expire'], + categoryPriority: ['basic', 'data', 'options', 'advanced'] + }, + 'nodes-base.mongoDb': { + required: [], + common: ['operation', 'collection', 'query', 'fields', 'limit'], + categoryPriority: ['basic', 'query', 'options', 'advanced'] + }, + 'nodes-base.mySql': { + required: [], + common: ['operation', 'table', 'query', 'columns', 'additionalFields'], + categoryPriority: ['basic', 'query', 'options', 'advanced'] + }, + 'nodes-base.ftp': { + required: [], + common: ['operation', 'path', 'fileName', 'binaryData'], + categoryPriority: ['basic', 'file', 'options', 'advanced'] + }, + 'nodes-base.ssh': { + required: [], + common: ['resource', 'operation', 'command', 'path', 'cwd'], + categoryPriority: ['basic', 'command', 'options', 'advanced'] + }, + 'nodes-base.executeCommand': { + required: [], + common: ['command', 'cwd'], + categoryPriority: ['basic', 'advanced'] + }, + 'nodes-base.github': { + required: [], + common: ['resource', 'operation', 'owner', 'repository', 'title', 'body'], + categoryPriority: ['basic', 'repository', 'content', 'advanced'] + } +}; +//# sourceMappingURL=property-filter.js.map \ No newline at end of file diff --git a/dist/services/property-filter.js.map b/dist/services/property-filter.js.map new file mode 100644 index 0000000..e3ebe8c --- /dev/null +++ b/dist/services/property-filter.js.map @@ -0,0 +1 @@ +{"version":3,"file":"property-filter.js","sourceRoot":"","sources":["../../src/services/property-filter.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/resource-similarity-service.d.ts b/dist/services/resource-similarity-service.d.ts new file mode 100644 index 0000000..fe7a338 --- /dev/null +++ b/dist/services/resource-similarity-service.d.ts @@ -0,0 +1,33 @@ +import { NodeRepository } from '../database/node-repository'; +export interface ResourceSuggestion { + value: string; + confidence: number; + reason: string; + availableOperations?: string[]; +} +export declare class ResourceSimilarityService { + private static readonly CACHE_DURATION_MS; + private static readonly MIN_CONFIDENCE; + private static readonly MAX_SUGGESTIONS; + private static readonly CONFIDENCE_THRESHOLDS; + private repository; + private resourceCache; + private suggestionCache; + private commonPatterns; + constructor(repository: NodeRepository); + private cleanupExpiredEntries; + private initializeCommonPatterns; + findSimilarResources(nodeType: string, invalidResource: string, maxSuggestions?: number): ResourceSuggestion[]; + private getResourceValue; + private getNodeResources; + private extractImplicitResources; + private inferResourceFromOperations; + private getNodePatterns; + private toSingular; + private toPlural; + private calculateSimilarity; + private levenshteinDistance; + private getSimilarityReason; + clearCache(): void; +} +//# sourceMappingURL=resource-similarity-service.d.ts.map \ No newline at end of file diff --git a/dist/services/resource-similarity-service.d.ts.map b/dist/services/resource-similarity-service.d.ts.map new file mode 100644 index 0000000..5652128 --- /dev/null +++ b/dist/services/resource-similarity-service.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"resource-similarity-service.d.ts","sourceRoot":"","sources":["../../src/services/resource-similarity-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAI7D,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC;AASD,qBAAa,yBAAyB;IACpC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAiB;IAC1D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAO;IAC7C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAK;IAG5C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAMlC;IAEX,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,aAAa,CAAmE;IACxF,OAAO,CAAC,eAAe,CAAgD;IACvE,OAAO,CAAC,cAAc,CAAiC;gBAE3C,UAAU,EAAE,cAAc;IAQtC,OAAO,CAAC,qBAAqB;IAwB7B,OAAO,CAAC,wBAAwB;IA2EhC,oBAAoB,CAClB,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,EACvB,cAAc,GAAE,MAAkD,GACjE,kBAAkB,EAAE;IA6FvB,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,gBAAgB;IA0ExB,OAAO,CAAC,wBAAwB;IAwBhC,OAAO,CAAC,2BAA2B;IA2BnC,OAAO,CAAC,eAAe;IAyBvB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,QAAQ;IAchB,OAAO,CAAC,mBAAmB;IAkC3B,OAAO,CAAC,mBAAmB;IAgC3B,OAAO,CAAC,mBAAmB;IAmB3B,UAAU,IAAI,IAAI;CAInB"} \ No newline at end of file diff --git a/dist/services/resource-similarity-service.js b/dist/services/resource-similarity-service.js new file mode 100644 index 0000000..50ccde7 --- /dev/null +++ b/dist/services/resource-similarity-service.js @@ -0,0 +1,358 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ResourceSimilarityService = void 0; +const logger_1 = require("../utils/logger"); +class ResourceSimilarityService { + constructor(repository) { + this.resourceCache = new Map(); + this.suggestionCache = new Map(); + this.repository = repository; + this.commonPatterns = this.initializeCommonPatterns(); + } + cleanupExpiredEntries() { + const now = Date.now(); + for (const [key, value] of this.resourceCache.entries()) { + if (now - value.timestamp >= ResourceSimilarityService.CACHE_DURATION_MS) { + this.resourceCache.delete(key); + } + } + if (this.suggestionCache.size > 100) { + const entries = Array.from(this.suggestionCache.entries()); + this.suggestionCache.clear(); + entries.slice(-50).forEach(([key, value]) => { + this.suggestionCache.set(key, value); + }); + } + } + initializeCommonPatterns() { + const patterns = new Map(); + patterns.set('googleDrive', [ + { pattern: 'files', suggestion: 'file', confidence: 0.95, reason: 'Use singular "file" not plural' }, + { pattern: 'folders', suggestion: 'folder', confidence: 0.95, reason: 'Use singular "folder" not plural' }, + { pattern: 'permissions', suggestion: 'permission', confidence: 0.9, reason: 'Use singular form' }, + { pattern: 'fileAndFolder', suggestion: 'fileFolder', confidence: 0.9, reason: 'Use "fileFolder" for combined operations' }, + { pattern: 'driveFiles', suggestion: 'file', confidence: 0.8, reason: 'Use "file" for file operations' }, + { pattern: 'sharedDrives', suggestion: 'drive', confidence: 0.85, reason: 'Use "drive" for shared drive operations' }, + ]); + patterns.set('slack', [ + { pattern: 'messages', suggestion: 'message', confidence: 0.95, reason: 'Use singular "message" not plural' }, + { pattern: 'channels', suggestion: 'channel', confidence: 0.95, reason: 'Use singular "channel" not plural' }, + { pattern: 'users', suggestion: 'user', confidence: 0.95, reason: 'Use singular "user" not plural' }, + { pattern: 'msg', suggestion: 'message', confidence: 0.85, reason: 'Use full "message" not abbreviation' }, + { pattern: 'dm', suggestion: 'message', confidence: 0.7, reason: 'Use "message" for direct messages' }, + { pattern: 'conversation', suggestion: 'channel', confidence: 0.7, reason: 'Use "channel" for conversations' }, + ]); + patterns.set('database', [ + { pattern: 'tables', suggestion: 'table', confidence: 0.95, reason: 'Use singular "table" not plural' }, + { pattern: 'queries', suggestion: 'query', confidence: 0.95, reason: 'Use singular "query" not plural' }, + { pattern: 'collections', suggestion: 'collection', confidence: 0.95, reason: 'Use singular "collection" not plural' }, + { pattern: 'documents', suggestion: 'document', confidence: 0.95, reason: 'Use singular "document" not plural' }, + { pattern: 'records', suggestion: 'record', confidence: 0.85, reason: 'Use "record" or "document"' }, + { pattern: 'rows', suggestion: 'row', confidence: 0.9, reason: 'Use singular "row"' }, + ]); + patterns.set('googleSheets', [ + { pattern: 'sheets', suggestion: 'sheet', confidence: 0.95, reason: 'Use singular "sheet" not plural' }, + { pattern: 'spreadsheets', suggestion: 'spreadsheet', confidence: 0.95, reason: 'Use singular "spreadsheet"' }, + { pattern: 'cells', suggestion: 'cell', confidence: 0.9, reason: 'Use singular "cell"' }, + { pattern: 'ranges', suggestion: 'range', confidence: 0.9, reason: 'Use singular "range"' }, + { pattern: 'worksheets', suggestion: 'sheet', confidence: 0.8, reason: 'Use "sheet" for worksheet operations' }, + ]); + patterns.set('email', [ + { pattern: 'emails', suggestion: 'email', confidence: 0.95, reason: 'Use singular "email" not plural' }, + { pattern: 'messages', suggestion: 'message', confidence: 0.9, reason: 'Use "message" for email operations' }, + { pattern: 'mails', suggestion: 'email', confidence: 0.9, reason: 'Use "email" not "mail"' }, + { pattern: 'attachments', suggestion: 'attachment', confidence: 0.95, reason: 'Use singular "attachment"' }, + ]); + patterns.set('generic', [ + { pattern: 'items', suggestion: 'item', confidence: 0.9, reason: 'Use singular form' }, + { pattern: 'objects', suggestion: 'object', confidence: 0.9, reason: 'Use singular form' }, + { pattern: 'entities', suggestion: 'entity', confidence: 0.9, reason: 'Use singular form' }, + { pattern: 'resources', suggestion: 'resource', confidence: 0.9, reason: 'Use singular form' }, + { pattern: 'elements', suggestion: 'element', confidence: 0.9, reason: 'Use singular form' }, + ]); + return patterns; + } + findSimilarResources(nodeType, invalidResource, maxSuggestions = ResourceSimilarityService.MAX_SUGGESTIONS) { + if (Math.random() < 0.1) { + this.cleanupExpiredEntries(); + } + const cacheKey = `${nodeType}:${invalidResource}`; + if (this.suggestionCache.has(cacheKey)) { + return this.suggestionCache.get(cacheKey); + } + const suggestions = []; + const validResources = this.getNodeResources(nodeType); + for (const resource of validResources) { + const resourceValue = this.getResourceValue(resource); + if (resourceValue.toLowerCase() === invalidResource.toLowerCase()) { + return []; + } + } + const nodePatterns = this.getNodePatterns(nodeType); + for (const pattern of nodePatterns) { + if (pattern.pattern.toLowerCase() === invalidResource.toLowerCase()) { + const exists = validResources.some(r => { + const resourceValue = this.getResourceValue(r); + return resourceValue === pattern.suggestion; + }); + if (exists) { + suggestions.push({ + value: pattern.suggestion, + confidence: pattern.confidence, + reason: pattern.reason + }); + } + } + } + const singularForm = this.toSingular(invalidResource); + const pluralForm = this.toPlural(invalidResource); + for (const resource of validResources) { + const resourceValue = this.getResourceValue(resource); + if (resourceValue === singularForm || resourceValue === pluralForm) { + if (!suggestions.some(s => s.value === resourceValue)) { + suggestions.push({ + value: resourceValue, + confidence: 0.9, + reason: invalidResource.endsWith('s') ? + 'Use singular form for resources' : + 'Incorrect plural/singular form', + availableOperations: typeof resource === 'object' ? resource.operations : undefined + }); + } + } + const similarity = this.calculateSimilarity(invalidResource, resourceValue); + if (similarity >= ResourceSimilarityService.MIN_CONFIDENCE) { + if (!suggestions.some(s => s.value === resourceValue)) { + suggestions.push({ + value: resourceValue, + confidence: similarity, + reason: this.getSimilarityReason(similarity, invalidResource, resourceValue), + availableOperations: typeof resource === 'object' ? resource.operations : undefined + }); + } + } + } + suggestions.sort((a, b) => b.confidence - a.confidence); + const topSuggestions = suggestions.slice(0, maxSuggestions); + this.suggestionCache.set(cacheKey, topSuggestions); + return topSuggestions; + } + getResourceValue(resource) { + if (typeof resource === 'string') { + return resource; + } + if (typeof resource === 'object' && resource !== null) { + return resource.value || ''; + } + return ''; + } + getNodeResources(nodeType) { + if (Math.random() < 0.05) { + this.cleanupExpiredEntries(); + } + const cacheKey = nodeType; + const cached = this.resourceCache.get(cacheKey); + if (cached && Date.now() - cached.timestamp < ResourceSimilarityService.CACHE_DURATION_MS) { + return cached.resources; + } + const nodeInfo = this.repository.getNode(nodeType); + if (!nodeInfo) + return []; + const resources = []; + const resourceMap = new Map(); + try { + const properties = nodeInfo.properties || []; + for (const prop of properties) { + if (prop.name === 'resource' && prop.options) { + for (const option of prop.options) { + resources.push({ + value: option.value, + name: option.name, + operations: [] + }); + resourceMap.set(option.value, []); + } + } + if (prop.name === 'operation' && prop.displayOptions?.show?.resource) { + const resourceValues = Array.isArray(prop.displayOptions.show.resource) + ? prop.displayOptions.show.resource + : [prop.displayOptions.show.resource]; + for (const resourceValue of resourceValues) { + if (resourceMap.has(resourceValue) && prop.options) { + const ops = prop.options.map((op) => op.value); + resourceMap.get(resourceValue).push(...ops); + } + } + } + } + for (const resource of resources) { + if (resourceMap.has(resource.value)) { + resource.operations = resourceMap.get(resource.value); + } + } + if (resources.length === 0) { + const implicitResources = this.extractImplicitResources(properties); + resources.push(...implicitResources); + } + } + catch (error) { + logger_1.logger.warn(`Failed to extract resources for ${nodeType}:`, error); + } + this.resourceCache.set(cacheKey, { resources, timestamp: Date.now() }); + return resources; + } + extractImplicitResources(properties) { + const resources = []; + for (const prop of properties) { + if (prop.name === 'operation' && prop.options) { + const resourceFromOps = this.inferResourceFromOperations(prop.options); + if (resourceFromOps) { + resources.push({ + value: resourceFromOps, + name: resourceFromOps.charAt(0).toUpperCase() + resourceFromOps.slice(1), + operations: prop.options.map((op) => op.value) + }); + } + } + } + return resources; + } + inferResourceFromOperations(operations) { + const patterns = [ + { keywords: ['file', 'upload', 'download'], resource: 'file' }, + { keywords: ['folder', 'directory'], resource: 'folder' }, + { keywords: ['message', 'send', 'reply'], resource: 'message' }, + { keywords: ['channel', 'broadcast'], resource: 'channel' }, + { keywords: ['user', 'member'], resource: 'user' }, + { keywords: ['table', 'row', 'column'], resource: 'table' }, + { keywords: ['document', 'doc'], resource: 'document' }, + ]; + for (const pattern of patterns) { + for (const op of operations) { + const opName = (op.value || op).toLowerCase(); + if (pattern.keywords.some(keyword => opName.includes(keyword))) { + return pattern.resource; + } + } + } + return null; + } + getNodePatterns(nodeType) { + const patterns = []; + if (nodeType.includes('googleDrive')) { + patterns.push(...(this.commonPatterns.get('googleDrive') || [])); + } + else if (nodeType.includes('slack')) { + patterns.push(...(this.commonPatterns.get('slack') || [])); + } + else if (nodeType.includes('postgres') || nodeType.includes('mysql') || nodeType.includes('mongodb')) { + patterns.push(...(this.commonPatterns.get('database') || [])); + } + else if (nodeType.includes('googleSheets')) { + patterns.push(...(this.commonPatterns.get('googleSheets') || [])); + } + else if (nodeType.includes('gmail') || nodeType.includes('email')) { + patterns.push(...(this.commonPatterns.get('email') || [])); + } + patterns.push(...(this.commonPatterns.get('generic') || [])); + return patterns; + } + toSingular(word) { + if (word.endsWith('ies')) { + return word.slice(0, -3) + 'y'; + } + else if (word.endsWith('es')) { + return word.slice(0, -2); + } + else if (word.endsWith('s') && !word.endsWith('ss')) { + return word.slice(0, -1); + } + return word; + } + toPlural(word) { + if (word.endsWith('y') && !['ay', 'ey', 'iy', 'oy', 'uy'].includes(word.slice(-2))) { + return word.slice(0, -1) + 'ies'; + } + else if (word.endsWith('s') || word.endsWith('x') || word.endsWith('z') || + word.endsWith('ch') || word.endsWith('sh')) { + return word + 'es'; + } + else { + return word + 's'; + } + } + calculateSimilarity(str1, str2) { + const s1 = str1.toLowerCase(); + const s2 = str2.toLowerCase(); + if (s1 === s2) + return 1.0; + if (s1.includes(s2) || s2.includes(s1)) { + const ratio = Math.min(s1.length, s2.length) / Math.max(s1.length, s2.length); + return Math.max(ResourceSimilarityService.CONFIDENCE_THRESHOLDS.MIN_SUBSTRING, ratio); + } + const distance = this.levenshteinDistance(s1, s2); + const maxLength = Math.max(s1.length, s2.length); + let similarity = 1 - (distance / maxLength); + if (distance === 1 && maxLength <= 5) { + similarity = Math.max(similarity, 0.75); + } + else if (distance === 2 && maxLength <= 5) { + similarity = Math.max(similarity, 0.72); + } + return similarity; + } + levenshteinDistance(str1, str2) { + const m = str1.length; + const n = str2.length; + const dp = Array(m + 1).fill(null).map(() => Array(n + 1).fill(0)); + for (let i = 0; i <= m; i++) + dp[i][0] = i; + for (let j = 0; j <= n; j++) + dp[0][j] = j; + for (let i = 1; i <= m; i++) { + for (let j = 1; j <= n; j++) { + if (str1[i - 1] === str2[j - 1]) { + dp[i][j] = dp[i - 1][j - 1]; + } + else { + dp[i][j] = Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + 1); + } + } + } + return dp[m][n]; + } + getSimilarityReason(confidence, invalid, valid) { + const { VERY_HIGH, HIGH, MEDIUM } = ResourceSimilarityService.CONFIDENCE_THRESHOLDS; + if (confidence >= VERY_HIGH) { + return 'Almost exact match - likely a typo'; + } + else if (confidence >= HIGH) { + return 'Very similar - common variation'; + } + else if (confidence >= MEDIUM) { + return 'Similar resource name'; + } + else if (invalid.includes(valid) || valid.includes(invalid)) { + return 'Partial match'; + } + else { + return 'Possibly related resource'; + } + } + clearCache() { + this.resourceCache.clear(); + this.suggestionCache.clear(); + } +} +exports.ResourceSimilarityService = ResourceSimilarityService; +ResourceSimilarityService.CACHE_DURATION_MS = 5 * 60 * 1000; +ResourceSimilarityService.MIN_CONFIDENCE = 0.3; +ResourceSimilarityService.MAX_SUGGESTIONS = 5; +ResourceSimilarityService.CONFIDENCE_THRESHOLDS = { + EXACT: 1.0, + VERY_HIGH: 0.95, + HIGH: 0.8, + MEDIUM: 0.6, + MIN_SUBSTRING: 0.7 +}; +//# sourceMappingURL=resource-similarity-service.js.map \ No newline at end of file diff --git a/dist/services/resource-similarity-service.js.map b/dist/services/resource-similarity-service.js.map new file mode 100644 index 0000000..d7e9f07 --- /dev/null +++ b/dist/services/resource-similarity-service.js.map @@ -0,0 +1 @@ +{"version":3,"file":"resource-similarity-service.js","sourceRoot":"","sources":["../../src/services/resource-similarity-service.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/sqlite-storage-service.d.ts b/dist/services/sqlite-storage-service.d.ts new file mode 100644 index 0000000..8e9d89b --- /dev/null +++ b/dist/services/sqlite-storage-service.d.ts @@ -0,0 +1,11 @@ +import { DatabaseAdapter } from '../database/database-adapter'; +export declare class SQLiteStorageService { + private adapter; + private dbPath; + constructor(dbPath?: string); + private initSync; + private initializeSchema; + get db(): DatabaseAdapter; + close(): void; +} +//# sourceMappingURL=sqlite-storage-service.d.ts.map \ No newline at end of file diff --git a/dist/services/sqlite-storage-service.d.ts.map b/dist/services/sqlite-storage-service.d.ts.map new file mode 100644 index 0000000..c043198 --- /dev/null +++ b/dist/services/sqlite-storage-service.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"sqlite-storage-service.d.ts","sourceRoot":"","sources":["../../src/services/sqlite-storage-service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAyB,MAAM,8BAA8B,CAAC;AAEtF,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,GAAE,MAAmB;IAKvC,OAAO,CAAC,QAAQ;IA6BhB,OAAO,CAAC,gBAAgB;IA6BxB,IAAI,EAAE,IAAI,eAAe,CAKxB;IAED,KAAK;CAMN"} \ No newline at end of file diff --git a/dist/services/sqlite-storage-service.js b/dist/services/sqlite-storage-service.js new file mode 100644 index 0000000..f0a3a35 --- /dev/null +++ b/dist/services/sqlite-storage-service.js @@ -0,0 +1,74 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.SQLiteStorageService = void 0; +class SQLiteStorageService { + constructor(dbPath = ':memory:') { + this.adapter = null; + this.dbPath = dbPath; + this.initSync(); + } + initSync() { + const Database = require('better-sqlite3'); + const db = new Database(this.dbPath); + this.adapter = { + prepare: (sql) => db.prepare(sql), + exec: (sql) => db.exec(sql), + close: () => db.close(), + pragma: (key, value) => db.pragma(`${key}${value !== undefined ? ` = ${value}` : ''}`), + inTransaction: db.inTransaction, + transaction: (fn) => db.transaction(fn)(), + checkFTS5Support: () => { + try { + db.exec("CREATE VIRTUAL TABLE test_fts USING fts5(content)"); + db.exec("DROP TABLE test_fts"); + return true; + } + catch { + return false; + } + } + }; + this.initializeSchema(); + } + initializeSchema() { + const schema = ` + CREATE TABLE IF NOT EXISTS nodes ( + node_type TEXT PRIMARY KEY, + package_name TEXT NOT NULL, + display_name TEXT NOT NULL, + description TEXT, + category TEXT, + development_style TEXT CHECK(development_style IN ('declarative', 'programmatic')), + is_ai_tool INTEGER DEFAULT 0, + is_trigger INTEGER DEFAULT 0, + is_webhook INTEGER DEFAULT 0, + is_versioned INTEGER DEFAULT 0, + version TEXT, + documentation TEXT, + properties_schema TEXT, + operations TEXT, + credentials_required TEXT, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP + ); + + CREATE INDEX IF NOT EXISTS idx_package ON nodes(package_name); + CREATE INDEX IF NOT EXISTS idx_ai_tool ON nodes(is_ai_tool); + CREATE INDEX IF NOT EXISTS idx_category ON nodes(category); + `; + this.adapter.exec(schema); + } + get db() { + if (!this.adapter) { + throw new Error('Database not initialized'); + } + return this.adapter; + } + close() { + if (this.adapter) { + this.adapter.close(); + this.adapter = null; + } + } +} +exports.SQLiteStorageService = SQLiteStorageService; +//# sourceMappingURL=sqlite-storage-service.js.map \ No newline at end of file diff --git a/dist/services/sqlite-storage-service.js.map b/dist/services/sqlite-storage-service.js.map new file mode 100644 index 0000000..db29558 --- /dev/null +++ b/dist/services/sqlite-storage-service.js.map @@ -0,0 +1 @@ +{"version":3,"file":"sqlite-storage-service.js","sourceRoot":"","sources":["../../src/services/sqlite-storage-service.ts"],"names":[],"mappings":";;;AAKA,MAAa,oBAAoB;IAI/B,YAAY,SAAiB,UAAU;QAH/B,YAAO,GAA2B,IAAI,CAAC;QAI7C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;IAEO,QAAQ;QAGd,MAAM,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAC3C,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAGrC,IAAI,CAAC,OAAO,GAAG;YACb,OAAO,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;YACzC,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;YACnC,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE;YACvB,MAAM,EAAE,CAAC,GAAW,EAAE,KAAW,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,GAAG,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACpG,aAAa,EAAE,EAAE,CAAC,aAAa;YAC/B,WAAW,EAAE,CAAC,EAAa,EAAE,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE;YACpD,gBAAgB,EAAE,GAAG,EAAE;gBACrB,IAAI,CAAC;oBACH,EAAE,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;oBAC7D,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;oBAC/B,OAAO,IAAI,CAAC;gBACd,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,KAAK,CAAC;gBACf,CAAC;YACH,CAAC;SACF,CAAC;QAGF,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC1B,CAAC;IAEO,gBAAgB;QACtB,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;KAuBd,CAAC;QAEF,IAAI,CAAC,OAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED,IAAI,EAAE;QACJ,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACrB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC;IACH,CAAC;CACF;AAhFD,oDAgFC"} \ No newline at end of file diff --git a/dist/services/task-templates.d.ts b/dist/services/task-templates.d.ts new file mode 100644 index 0000000..eaa437e --- /dev/null +++ b/dist/services/task-templates.d.ts @@ -0,0 +1,27 @@ +export interface TaskTemplate { + task: string; + description: string; + nodeType: string; + configuration: Record; + userMustProvide: Array<{ + property: string; + description: string; + example?: any; + }>; + optionalEnhancements?: Array<{ + property: string; + description: string; + when?: string; + }>; + notes?: string[]; +} +export declare class TaskTemplates { + private static templates; + static getAllTasks(): string[]; + static getTasksForNode(nodeType: string): string[]; + static getTaskTemplate(task: string): TaskTemplate | undefined; + static getTemplate(task: string): TaskTemplate | undefined; + static searchTasks(keyword: string): string[]; + static getTaskCategories(): Record; +} +//# sourceMappingURL=task-templates.d.ts.map \ No newline at end of file diff --git a/dist/services/task-templates.d.ts.map b/dist/services/task-templates.d.ts.map new file mode 100644 index 0000000..90fbd59 --- /dev/null +++ b/dist/services/task-templates.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"task-templates.d.ts","sourceRoot":"","sources":["../../src/services/task-templates.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnC,eAAe,EAAE,KAAK,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,GAAG,CAAC;KACf,CAAC,CAAC;IACH,oBAAoB,CAAC,EAAE,KAAK,CAAC;QAC3B,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,SAAS,CAm4CtB;IAKF,MAAM,CAAC,WAAW,IAAI,MAAM,EAAE;IAO9B,MAAM,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IASlD,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAO9D,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAO1D,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE;IAc7C,MAAM,CAAC,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;CAYrD"} \ No newline at end of file diff --git a/dist/services/task-templates.js b/dist/services/task-templates.js new file mode 100644 index 0000000..268afbd --- /dev/null +++ b/dist/services/task-templates.js @@ -0,0 +1,1397 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TaskTemplates = void 0; +class TaskTemplates { + static getAllTasks() { + return Object.keys(this.templates); + } + static getTasksForNode(nodeType) { + return Object.entries(this.templates) + .filter(([_, template]) => template.nodeType === nodeType) + .map(([task, _]) => task); + } + static getTaskTemplate(task) { + return this.templates[task]; + } + static getTemplate(task) { + return this.getTaskTemplate(task); + } + static searchTasks(keyword) { + const lower = keyword.toLowerCase(); + return Object.entries(this.templates) + .filter(([task, template]) => task.toLowerCase().includes(lower) || + template.description.toLowerCase().includes(lower) || + template.nodeType.toLowerCase().includes(lower)) + .map(([task, _]) => task); + } + static getTaskCategories() { + return { + 'HTTP/API': ['get_api_data', 'post_json_request', 'call_api_with_auth', 'api_call_with_retry'], + 'Webhooks': ['receive_webhook', 'webhook_with_response', 'webhook_with_error_handling', 'process_webhook_data'], + 'Database': ['query_postgres', 'insert_postgres_data', 'database_transaction_safety'], + 'AI/LangChain': ['chat_with_ai', 'ai_agent_workflow', 'multi_tool_ai_agent', 'ai_rate_limit_handling'], + 'Data Processing': ['transform_data', 'filter_data', 'fault_tolerant_processing', 'process_webhook_data'], + 'Communication': ['send_slack_message', 'send_email'], + 'AI Tool Usage': ['use_google_sheets_as_tool', 'use_slack_as_tool', 'multi_tool_ai_agent'], + 'Error Handling': ['modern_error_handling_patterns', 'api_call_with_retry', 'fault_tolerant_processing', 'webhook_with_error_handling', 'database_transaction_safety', 'ai_rate_limit_handling'] + }; + } +} +exports.TaskTemplates = TaskTemplates; +TaskTemplates.templates = { + 'get_api_data': { + task: 'get_api_data', + description: 'Make a simple GET request to retrieve data from an API', + nodeType: 'nodes-base.httpRequest', + configuration: { + method: 'GET', + url: '', + authentication: 'none', + onError: 'continueRegularOutput', + retryOnFail: true, + maxTries: 3, + waitBetweenTries: 1000, + alwaysOutputData: true + }, + userMustProvide: [ + { + property: 'url', + description: 'The API endpoint URL', + example: 'https://api.example.com/users' + } + ], + optionalEnhancements: [ + { + property: 'authentication', + description: 'Add authentication if the API requires it', + when: 'API requires authentication' + }, + { + property: 'sendHeaders', + description: 'Add custom headers if needed', + when: 'API requires specific headers' + }, + { + property: 'alwaysOutputData', + description: 'Set to true to capture error responses', + when: 'Need to debug API errors' + } + ] + }, + 'post_json_request': { + task: 'post_json_request', + description: 'Send JSON data to an API endpoint', + nodeType: 'nodes-base.httpRequest', + configuration: { + method: 'POST', + url: '', + sendBody: true, + contentType: 'json', + specifyBody: 'json', + jsonBody: '', + onError: 'continueRegularOutput', + retryOnFail: true, + maxTries: 2, + waitBetweenTries: 1000, + alwaysOutputData: true + }, + userMustProvide: [ + { + property: 'url', + description: 'The API endpoint URL', + example: 'https://api.example.com/users' + }, + { + property: 'jsonBody', + description: 'The JSON data to send', + example: '{\n "name": "John Doe",\n "email": "john@example.com"\n}' + } + ], + optionalEnhancements: [ + { + property: 'authentication', + description: 'Add authentication if required' + }, + { + property: 'onError', + description: 'Set to "continueRegularOutput" for non-critical operations', + when: 'Failure should not stop the workflow' + } + ], + notes: [ + 'Make sure jsonBody contains valid JSON', + 'Content-Type header is automatically set to application/json', + 'Be careful with retries on non-idempotent operations' + ] + }, + 'call_api_with_auth': { + task: 'call_api_with_auth', + description: 'Make an authenticated API request', + nodeType: 'nodes-base.httpRequest', + configuration: { + method: 'GET', + url: '', + authentication: 'genericCredentialType', + genericAuthType: 'headerAuth', + sendHeaders: true, + onError: 'continueErrorOutput', + retryOnFail: true, + maxTries: 3, + waitBetweenTries: 2000, + alwaysOutputData: true, + headerParameters: { + parameters: [ + { + name: '', + value: '' + } + ] + } + }, + userMustProvide: [ + { + property: 'url', + description: 'The API endpoint URL' + }, + { + property: 'headerParameters.parameters[0].name', + description: 'The header name for authentication', + example: 'Authorization' + }, + { + property: 'headerParameters.parameters[0].value', + description: 'The authentication value', + example: 'Bearer YOUR_API_KEY' + } + ], + optionalEnhancements: [ + { + property: 'method', + description: 'Change to POST/PUT/DELETE as needed' + } + ] + }, + 'receive_webhook': { + task: 'receive_webhook', + description: 'Set up a webhook to receive data from external services', + nodeType: 'nodes-base.webhook', + configuration: { + httpMethod: 'POST', + path: 'webhook', + responseMode: 'lastNode', + responseData: 'allEntries', + onError: 'continueRegularOutput', + alwaysOutputData: true + }, + userMustProvide: [ + { + property: 'path', + description: 'The webhook path (will be appended to your n8n URL)', + example: 'github-webhook' + } + ], + optionalEnhancements: [ + { + property: 'httpMethod', + description: 'Change if the service sends GET/PUT/etc' + }, + { + property: 'responseCode', + description: 'Set custom response code (default 200)' + } + ], + notes: [ + 'The full webhook URL will be: https://your-n8n.com/webhook/[path]', + 'Test URL will be different from production URL' + ] + }, + 'webhook_with_response': { + task: 'webhook_with_response', + description: 'Receive webhook and send custom response', + nodeType: 'nodes-base.webhook', + configuration: { + httpMethod: 'POST', + path: 'webhook', + responseMode: 'responseNode', + responseData: 'firstEntryJson', + responseCode: 200, + onError: 'continueRegularOutput', + alwaysOutputData: true + }, + userMustProvide: [ + { + property: 'path', + description: 'The webhook path' + } + ], + notes: [ + 'Use with a Respond to Webhook node to send custom response', + 'responseMode: responseNode requires a Respond to Webhook node' + ] + }, + 'process_webhook_data': { + task: 'process_webhook_data', + description: 'Process incoming webhook data with Code node (shows correct data access)', + nodeType: 'nodes-base.code', + configuration: { + language: 'javaScript', + jsCode: `// ⚠️ CRITICAL: Webhook data is nested under 'body' property! +// Connect this Code node after a Webhook node + +// Access webhook payload data - it's under .body, not directly under .json +const webhookData = items[0].json.body; // ✅ CORRECT +const headers = items[0].json.headers; // HTTP headers +const query = items[0].json.query; // Query parameters + +// Common mistake to avoid: +// const command = items[0].json.testCommand; // ❌ WRONG - will be undefined! +// const command = items[0].json.body.testCommand; // ✅ CORRECT + +// Process the webhook data +try { + // Validate required fields + if (!webhookData.command) { + throw new Error('Missing required field: command'); + } + + // Process based on command + let result = {}; + switch (webhookData.command) { + case 'process': + result = { + status: 'processed', + data: webhookData.data, + processedAt: DateTime.now().toISO() + }; + break; + + case 'validate': + result = { + status: 'validated', + isValid: true, + validatedFields: Object.keys(webhookData.data || {}) + }; + break; + + default: + result = { + status: 'unknown_command', + command: webhookData.command + }; + } + + // Return processed data + return [{ + json: { + ...result, + requestId: headers['x-request-id'] || crypto.randomUUID(), + source: query.source || 'webhook', + originalCommand: webhookData.command, + metadata: { + httpMethod: items[0].json.httpMethod, + webhookPath: items[0].json.webhookPath, + timestamp: DateTime.now().toISO() + } + } + }]; + +} catch (error) { + // Return error response + return [{ + json: { + status: 'error', + error: error.message, + timestamp: DateTime.now().toISO() + } + }]; +}`, + onError: 'continueRegularOutput' + }, + userMustProvide: [], + notes: [ + '⚠️ WEBHOOK DATA IS AT items[0].json.body, NOT items[0].json', + 'This is the most common webhook processing mistake', + 'Headers are at items[0].json.headers', + 'Query parameters are at items[0].json.query', + 'Connect this Code node directly after a Webhook node' + ] + }, + 'query_postgres': { + task: 'query_postgres', + description: 'Query data from PostgreSQL database', + nodeType: 'nodes-base.postgres', + configuration: { + operation: 'executeQuery', + query: '', + onError: 'continueRegularOutput', + retryOnFail: true, + maxTries: 3, + waitBetweenTries: 1000 + }, + userMustProvide: [ + { + property: 'query', + description: 'The SQL query to execute', + example: 'SELECT * FROM users WHERE active = true LIMIT 10' + } + ], + optionalEnhancements: [ + { + property: 'additionalFields.queryParams', + description: 'Use parameterized queries for security', + when: 'Using dynamic values' + } + ], + notes: [ + 'Always use parameterized queries to prevent SQL injection', + 'Configure PostgreSQL credentials in n8n' + ] + }, + 'insert_postgres_data': { + task: 'insert_postgres_data', + description: 'Insert data into PostgreSQL table', + nodeType: 'nodes-base.postgres', + configuration: { + operation: 'insert', + table: '', + columns: '', + returnFields: '*', + onError: 'stopWorkflow', + retryOnFail: true, + maxTries: 2, + waitBetweenTries: 1000 + }, + userMustProvide: [ + { + property: 'table', + description: 'The table name', + example: 'users' + }, + { + property: 'columns', + description: 'Comma-separated column names', + example: 'name,email,created_at' + } + ], + notes: [ + 'Input data should match the column structure', + 'Use expressions like {{ $json.fieldName }} to map data' + ] + }, + 'chat_with_ai': { + task: 'chat_with_ai', + description: 'Send a message to an AI model and get response', + nodeType: 'nodes-base.openAi', + configuration: { + resource: 'chat', + operation: 'message', + modelId: 'gpt-3.5-turbo', + messages: { + values: [ + { + role: 'user', + content: '' + } + ] + }, + onError: 'continueRegularOutput', + retryOnFail: true, + maxTries: 3, + waitBetweenTries: 5000, + alwaysOutputData: true + }, + userMustProvide: [ + { + property: 'messages.values[0].content', + description: 'The message to send to the AI', + example: '{{ $json.userMessage }}' + } + ], + optionalEnhancements: [ + { + property: 'modelId', + description: 'Change to gpt-4 for better results' + }, + { + property: 'options.temperature', + description: 'Adjust creativity (0-1)' + }, + { + property: 'options.maxTokens', + description: 'Limit response length' + } + ] + }, + 'ai_agent_workflow': { + task: 'ai_agent_workflow', + description: 'Create an AI agent that can use tools', + nodeType: 'nodes-langchain.agent', + configuration: { + text: '', + outputType: 'output', + systemMessage: 'You are a helpful assistant.' + }, + userMustProvide: [ + { + property: 'text', + description: 'The input prompt for the agent', + example: '{{ $json.query }}' + } + ], + optionalEnhancements: [ + { + property: 'systemMessage', + description: 'Customize the agent\'s behavior' + } + ], + notes: [ + 'Connect tool nodes to give the agent capabilities', + 'Configure the AI model credentials' + ] + }, + 'transform_data': { + task: 'transform_data', + description: 'Transform data structure using JavaScript', + nodeType: 'nodes-base.code', + configuration: { + language: 'javaScript', + jsCode: `// Transform each item +const results = []; + +for (const item of items) { + results.push({ + json: { + // Transform your data here + id: item.json.id, + processedAt: new Date().toISOString() + } + }); +} + +return results;` + }, + userMustProvide: [], + notes: [ + 'Access input data via items array', + 'Each item has a json property with the data', + 'Return array of objects with json property' + ] + }, + 'filter_data': { + task: 'filter_data', + description: 'Filter items based on conditions', + nodeType: 'nodes-base.if', + configuration: { + conditions: { + conditions: [ + { + leftValue: '', + rightValue: '', + operator: { + type: 'string', + operation: 'equals' + } + } + ] + } + }, + userMustProvide: [ + { + property: 'conditions.conditions[0].leftValue', + description: 'The value to check', + example: '{{ $json.status }}' + }, + { + property: 'conditions.conditions[0].rightValue', + description: 'The value to compare against', + example: 'active' + } + ], + notes: [ + 'True output contains matching items', + 'False output contains non-matching items' + ] + }, + 'send_slack_message': { + task: 'send_slack_message', + description: 'Send a message to Slack channel', + nodeType: 'nodes-base.slack', + configuration: { + resource: 'message', + operation: 'post', + channel: '', + text: '', + onError: 'continueRegularOutput', + retryOnFail: true, + maxTries: 2, + waitBetweenTries: 2000 + }, + userMustProvide: [ + { + property: 'channel', + description: 'The Slack channel', + example: '#general' + }, + { + property: 'text', + description: 'The message text', + example: 'New order received: {{ $json.orderId }}' + } + ], + optionalEnhancements: [ + { + property: 'attachments', + description: 'Add rich message attachments' + }, + { + property: 'blocks', + description: 'Use Block Kit for advanced formatting' + } + ] + }, + 'send_email': { + task: 'send_email', + description: 'Send an email notification', + nodeType: 'nodes-base.emailSend', + configuration: { + fromEmail: '', + toEmail: '', + subject: '', + text: '', + onError: 'continueRegularOutput', + retryOnFail: true, + maxTries: 3, + waitBetweenTries: 3000, + alwaysOutputData: true + }, + userMustProvide: [ + { + property: 'fromEmail', + description: 'Sender email address', + example: 'notifications@company.com' + }, + { + property: 'toEmail', + description: 'Recipient email address', + example: '{{ $json.customerEmail }}' + }, + { + property: 'subject', + description: 'Email subject', + example: 'Order Confirmation #{{ $json.orderId }}' + }, + { + property: 'text', + description: 'Email body (plain text)', + example: 'Thank you for your order!' + } + ], + optionalEnhancements: [ + { + property: 'html', + description: 'Use HTML for rich formatting' + }, + { + property: 'attachments', + description: 'Attach files to the email' + } + ] + }, + 'use_google_sheets_as_tool': { + task: 'use_google_sheets_as_tool', + description: 'Use Google Sheets as an AI tool for reading/writing data', + nodeType: 'nodes-base.googleSheets', + configuration: { + operation: 'append', + sheetId: '={{ $fromAI("sheetId", "The Google Sheets ID") }}', + range: '={{ $fromAI("range", "The range to append to, e.g. A:Z") }}', + dataMode: 'autoMap' + }, + userMustProvide: [ + { + property: 'Google Sheets credentials', + description: 'Configure Google Sheets API credentials in n8n' + }, + { + property: 'Tool name in AI Agent', + description: 'Give it a descriptive name like "Log Results to Sheet"' + }, + { + property: 'Tool description', + description: 'Describe when and how the AI should use this tool' + } + ], + notes: [ + 'Connect this node to the ai_tool port of an AI Agent node', + 'The AI can dynamically determine sheetId and range using $fromAI', + 'Works great for logging AI analysis results or reading data for processing' + ] + }, + 'use_slack_as_tool': { + task: 'use_slack_as_tool', + description: 'Use Slack as an AI tool for sending notifications', + nodeType: 'nodes-base.slack', + configuration: { + resource: 'message', + operation: 'post', + channel: '={{ $fromAI("channel", "The Slack channel, e.g. #general") }}', + text: '={{ $fromAI("message", "The message to send") }}', + attachments: [] + }, + userMustProvide: [ + { + property: 'Slack credentials', + description: 'Configure Slack OAuth2 credentials in n8n' + }, + { + property: 'Tool configuration in AI Agent', + description: 'Name it something like "Send Slack Notification"' + } + ], + notes: [ + 'Perfect for AI agents that need to notify teams', + 'The AI determines channel and message content dynamically', + 'Can be enhanced with blocks for rich formatting' + ] + }, + 'multi_tool_ai_agent': { + task: 'multi_tool_ai_agent', + description: 'AI agent with multiple tools for complex automation', + nodeType: 'nodes-langchain.agent', + configuration: { + text: '={{ $json.query }}', + outputType: 'output', + systemMessage: 'You are an intelligent assistant with access to multiple tools. Use them wisely to complete tasks.' + }, + userMustProvide: [ + { + property: 'AI model credentials', + description: 'OpenAI, Anthropic, or other LLM credentials' + }, + { + property: 'Multiple tool nodes', + description: 'Connect various nodes to the ai_tool port' + }, + { + property: 'Tool descriptions', + description: 'Clear descriptions for each connected tool' + } + ], + optionalEnhancements: [ + { + property: 'Memory', + description: 'Add memory nodes for conversation context' + }, + { + property: 'Custom tools', + description: 'Create Code nodes as custom tools' + } + ], + notes: [ + 'Connect multiple nodes: HTTP Request, Slack, Google Sheets, etc.', + 'Each tool should have a clear, specific purpose', + 'Test each tool individually before combining', + 'Set N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true for community nodes' + ] + }, + 'api_call_with_retry': { + task: 'api_call_with_retry', + description: 'Resilient API call with automatic retry on failure', + nodeType: 'nodes-base.httpRequest', + configuration: { + method: 'GET', + url: '', + retryOnFail: true, + maxTries: 5, + waitBetweenTries: 2000, + alwaysOutputData: true, + sendHeaders: true, + headerParameters: { + parameters: [ + { + name: 'X-Request-ID', + value: '={{ $workflow.id }}-{{ $itemIndex }}' + } + ] + } + }, + userMustProvide: [ + { + property: 'url', + description: 'The API endpoint to call', + example: 'https://api.example.com/resource/{{ $json.id }}' + } + ], + optionalEnhancements: [ + { + property: 'authentication', + description: 'Add API authentication' + }, + { + property: 'onError', + description: 'Change to "stopWorkflow" for critical API calls', + when: 'This is a critical API call that must succeed' + } + ], + notes: [ + 'Retries help with rate limits and transient network issues', + 'waitBetweenTries prevents hammering the API', + 'alwaysOutputData captures error responses for debugging', + 'Consider exponential backoff for production use' + ] + }, + 'fault_tolerant_processing': { + task: 'fault_tolerant_processing', + description: 'Data processing that continues despite individual item failures', + nodeType: 'nodes-base.code', + configuration: { + language: 'javaScript', + jsCode: `// Process items with error handling +const results = []; + +for (const item of items) { + try { + // Your processing logic here + const processed = { + ...item.json, + processed: true, + timestamp: new Date().toISOString() + }; + + results.push({ json: processed }); + } catch (error) { + // Log error but continue processing + console.error('Processing failed for item:', item.json.id, error); + + // Add error item to results + results.push({ + json: { + ...item.json, + error: error.message, + processed: false + } + }); + } +} + +return results;`, + onError: 'continueRegularOutput', + alwaysOutputData: true + }, + userMustProvide: [ + { + property: 'Processing logic', + description: 'Replace the comment with your data transformation logic' + } + ], + optionalEnhancements: [ + { + property: 'Error notification', + description: 'Add IF node after to handle error items separately' + } + ], + notes: [ + 'Individual item failures won\'t stop processing of other items', + 'Error items are marked and can be handled separately', + 'continueOnFail ensures workflow continues even on total failure' + ] + }, + 'webhook_with_error_handling': { + task: 'webhook_with_error_handling', + description: 'Webhook that gracefully handles processing errors', + nodeType: 'nodes-base.webhook', + configuration: { + httpMethod: 'POST', + path: 'resilient-webhook', + responseMode: 'responseNode', + responseData: 'firstEntryJson', + onError: 'continueRegularOutput', + alwaysOutputData: true + }, + userMustProvide: [ + { + property: 'path', + description: 'Unique webhook path', + example: 'order-processor' + }, + { + property: 'Respond to Webhook node', + description: 'Add node to send appropriate success/error responses' + } + ], + optionalEnhancements: [ + { + property: 'Validation', + description: 'Add IF node to validate webhook payload' + }, + { + property: 'Error logging', + description: 'Add error handler node for failed requests' + } + ], + notes: [ + 'onError: continueRegularOutput ensures webhook always sends a response', + 'Use Respond to Webhook node to send appropriate status codes', + 'Log errors but don\'t expose internal errors to webhook callers', + 'Consider rate limiting for public webhooks' + ] + }, + 'modern_error_handling_patterns': { + task: 'modern_error_handling_patterns', + description: 'Examples of modern error handling using onError property', + nodeType: 'nodes-base.httpRequest', + configuration: { + method: 'GET', + url: '', + onError: 'continueRegularOutput', + retryOnFail: true, + maxTries: 3, + waitBetweenTries: 2000, + alwaysOutputData: true + }, + userMustProvide: [ + { + property: 'url', + description: 'The API endpoint' + }, + { + property: 'onError', + description: 'Choose error handling strategy', + example: 'continueRegularOutput' + } + ], + notes: [ + 'onError replaces the deprecated continueOnFail property', + 'continueRegularOutput: Continue with normal output on error', + 'continueErrorOutput: Route errors to error output for special handling', + 'stopWorkflow: Stop the entire workflow on error', + 'Combine with retryOnFail for resilient workflows' + ] + }, + 'database_transaction_safety': { + task: 'database_transaction_safety', + description: 'Database operations with proper error handling', + nodeType: 'nodes-base.postgres', + configuration: { + operation: 'executeQuery', + query: 'BEGIN; INSERT INTO orders ...; COMMIT;', + onError: 'continueErrorOutput', + retryOnFail: false, + alwaysOutputData: true + }, + userMustProvide: [ + { + property: 'query', + description: 'Your SQL query or transaction' + } + ], + notes: [ + 'Transactions should not be retried automatically', + 'Use continueErrorOutput to handle errors separately', + 'Consider implementing compensating transactions', + 'Always log transaction failures for audit' + ] + }, + 'ai_rate_limit_handling': { + task: 'ai_rate_limit_handling', + description: 'AI API calls with rate limit handling', + nodeType: 'nodes-base.openAi', + configuration: { + resource: 'chat', + operation: 'message', + modelId: 'gpt-4', + messages: { + values: [ + { + role: 'user', + content: '' + } + ] + }, + onError: 'continueRegularOutput', + retryOnFail: true, + maxTries: 5, + waitBetweenTries: 5000, + alwaysOutputData: true + }, + userMustProvide: [ + { + property: 'messages.values[0].content', + description: 'The prompt for the AI' + } + ], + notes: [ + 'AI APIs often have rate limits', + 'Longer wait times help avoid hitting limits', + 'Consider implementing exponential backoff in Code node', + 'Monitor usage to stay within quotas' + ] + }, + 'custom_ai_tool': { + task: 'custom_ai_tool', + description: 'Create a custom tool for AI agents using Code node', + nodeType: 'nodes-base.code', + configuration: { + language: 'javaScript', + mode: 'runOnceForEachItem', + jsCode: `// Custom AI Tool - Example: Text Analysis +// This code will be called by AI agents with $json containing the input + +// Access the input from the AI agent +const text = $json.text || ''; +const operation = $json.operation || 'analyze'; + +// Perform the requested operation +let result = {}; + +switch (operation) { + case 'wordCount': + result = { + wordCount: text.split(/\\s+/).filter(word => word.length > 0).length, + characterCount: text.length, + lineCount: text.split('\\n').length + }; + break; + + case 'extract': + // Extract specific patterns (emails, URLs, etc.) + result = { + emails: text.match(/[\\w.-]+@[\\w.-]+\\.\\w+/g) || [], + urls: text.match(/https?:\\/\\/[^\\s]+/g) || [], + numbers: text.match(/\\b\\d+\\b/g) || [] + }; + break; + + default: + result = { + error: 'Unknown operation', + availableOperations: ['wordCount', 'extract'] + }; +} + +return [{ + json: { + ...result, + originalText: text, + operation: operation, + processedAt: DateTime.now().toISO() + } +}];`, + onError: 'continueRegularOutput' + }, + userMustProvide: [], + notes: [ + 'Connect this to AI Agent node\'s tool input', + 'AI will pass data in $json', + 'Use "Run Once for Each Item" mode for AI tools', + 'Return structured data the AI can understand' + ] + }, + 'aggregate_data': { + task: 'aggregate_data', + description: 'Aggregate data from multiple items into summary statistics', + nodeType: 'nodes-base.code', + configuration: { + language: 'javaScript', + jsCode: `// Aggregate data from all items +const stats = { + count: 0, + sum: 0, + min: Infinity, + max: -Infinity, + values: [], + categories: {}, + errors: [] +}; + +// Process each item +for (const item of items) { + try { + const value = item.json.value || item.json.amount || 0; + const category = item.json.category || 'uncategorized'; + + stats.count++; + stats.sum += value; + stats.min = Math.min(stats.min, value); + stats.max = Math.max(stats.max, value); + stats.values.push(value); + + // Count by category + stats.categories[category] = (stats.categories[category] || 0) + 1; + + } catch (error) { + stats.errors.push({ + item: item.json, + error: error.message + }); + } +} + +// Calculate additional statistics +const average = stats.count > 0 ? stats.sum / stats.count : 0; +const sorted = [...stats.values].sort((a, b) => a - b); +const median = sorted.length > 0 + ? sorted[Math.floor(sorted.length / 2)] + : 0; + +return [{ + json: { + totalItems: stats.count, + sum: stats.sum, + average: average, + median: median, + min: stats.min === Infinity ? 0 : stats.min, + max: stats.max === -Infinity ? 0 : stats.max, + categoryCounts: stats.categories, + errorCount: stats.errors.length, + errors: stats.errors, + processedAt: DateTime.now().toISO() + } +}];`, + onError: 'continueRegularOutput' + }, + userMustProvide: [], + notes: [ + 'Assumes items have "value" or "amount" field', + 'Groups by "category" field if present', + 'Returns single item with all statistics', + 'Handles errors gracefully' + ] + }, + 'batch_process_with_api': { + task: 'batch_process_with_api', + description: 'Process items in batches with API calls', + nodeType: 'nodes-base.code', + configuration: { + language: 'javaScript', + jsCode: `// Batch process items with API calls +const BATCH_SIZE = 10; +const API_URL = 'https://api.example.com/batch-process'; // USER MUST UPDATE +const results = []; + +// Process items in batches +for (let i = 0; i < items.length; i += BATCH_SIZE) { + const batch = items.slice(i, i + BATCH_SIZE); + + try { + // Prepare batch data + const batchData = batch.map(item => ({ + id: item.json.id, + data: item.json + })); + + // Make API request for batch + const response = await $helpers.httpRequest({ + method: 'POST', + url: API_URL, + body: { + items: batchData + }, + headers: { + 'Content-Type': 'application/json' + } + }); + + // Add results + if (response.results && Array.isArray(response.results)) { + response.results.forEach((result, index) => { + results.push({ + json: { + ...batch[index].json, + ...result, + batchNumber: Math.floor(i / BATCH_SIZE) + 1, + processedAt: DateTime.now().toISO() + } + }); + }); + } + + // Add delay between batches to avoid rate limits + if (i + BATCH_SIZE < items.length) { + await new Promise(resolve => setTimeout(resolve, 1000)); + } + + } catch (error) { + // Add failed batch items with error + batch.forEach(item => { + results.push({ + json: { + ...item.json, + error: error.message, + status: 'failed', + batchNumber: Math.floor(i / BATCH_SIZE) + 1 + } + }); + }); + } +} + +return results;`, + onError: 'continueRegularOutput', + retryOnFail: true, + maxTries: 2 + }, + userMustProvide: [ + { + property: 'jsCode', + description: 'Update API_URL in the code', + example: 'https://your-api.com/batch' + } + ], + notes: [ + 'Processes items in batches of 10', + 'Includes delay between batches', + 'Handles batch failures gracefully', + 'Update API_URL and adjust BATCH_SIZE as needed' + ] + }, + 'error_safe_transform': { + task: 'error_safe_transform', + description: 'Transform data with comprehensive error handling', + nodeType: 'nodes-base.code', + configuration: { + language: 'javaScript', + jsCode: `// Safe data transformation with validation +const results = []; +const errors = []; + +for (const item of items) { + try { + // Validate required fields + const required = ['id', 'name']; // USER SHOULD UPDATE + const missing = required.filter(field => !item.json[field]); + + if (missing.length > 0) { + throw new Error(\`Missing required fields: \${missing.join(', ')}\`); + } + + // Transform data with type checking + const transformed = { + // Ensure ID is string + id: String(item.json.id), + + // Clean and validate name + name: String(item.json.name).trim(), + + // Parse numbers safely + amount: parseFloat(item.json.amount) || 0, + + // Parse dates safely + date: item.json.date + ? DateTime.fromISO(item.json.date).isValid + ? DateTime.fromISO(item.json.date).toISO() + : null + : null, + + // Boolean conversion + isActive: Boolean(item.json.active || item.json.isActive), + + // Array handling + tags: Array.isArray(item.json.tags) + ? item.json.tags.filter(tag => typeof tag === 'string') + : [], + + // Nested object handling + metadata: typeof item.json.metadata === 'object' + ? item.json.metadata + : {}, + + // Add processing info + processedAt: DateTime.now().toISO(), + originalIndex: items.indexOf(item) + }; + + results.push({ + json: transformed + }); + + } catch (error) { + errors.push({ + json: { + error: error.message, + originalData: item.json, + index: items.indexOf(item), + status: 'failed' + } + }); + } +} + +// Add summary at the end +results.push({ + json: { + _summary: { + totalProcessed: results.length - errors.length, + totalErrors: errors.length, + successRate: ((results.length - errors.length) / items.length * 100).toFixed(2) + '%', + timestamp: DateTime.now().toISO() + } + } +}); + +// Include errors at the end +return [...results, ...errors];`, + onError: 'continueRegularOutput' + }, + userMustProvide: [ + { + property: 'jsCode', + description: 'Update required fields array', + example: "const required = ['id', 'email', 'name'];" + } + ], + notes: [ + 'Validates all data types', + 'Handles missing/invalid data gracefully', + 'Returns both successful and failed items', + 'Includes processing summary' + ] + }, + 'async_data_processing': { + task: 'async_data_processing', + description: 'Process data with async operations and proper error handling', + nodeType: 'nodes-base.code', + configuration: { + language: 'javaScript', + jsCode: `// Async processing with concurrent limits +const CONCURRENT_LIMIT = 5; +const results = []; + +// Process items with concurrency control +async function processItem(item, index) { + try { + // Simulate async operation (replace with actual logic) + // Example: API call, database query, file operation + await new Promise(resolve => setTimeout(resolve, 100)); + + // Actual processing logic here + const processed = { + ...item.json, + processed: true, + index: index, + timestamp: DateTime.now().toISO() + }; + + // Example async operation - external API call + if (item.json.needsEnrichment) { + const enrichment = await $helpers.httpRequest({ + method: 'GET', + url: \`https://api.example.com/enrich/\${item.json.id}\` + }); + processed.enrichment = enrichment; + } + + return { json: processed }; + + } catch (error) { + return { + json: { + ...item.json, + error: error.message, + status: 'failed', + index: index + } + }; + } +} + +// Process in batches with concurrency limit +for (let i = 0; i < items.length; i += CONCURRENT_LIMIT) { + const batch = items.slice(i, i + CONCURRENT_LIMIT); + const batchPromises = batch.map((item, batchIndex) => + processItem(item, i + batchIndex) + ); + + const batchResults = await Promise.all(batchPromises); + results.push(...batchResults); +} + +return results;`, + onError: 'continueRegularOutput', + retryOnFail: true, + maxTries: 2 + }, + userMustProvide: [], + notes: [ + 'Processes 5 items concurrently', + 'Prevents overwhelming external services', + 'Each item processed independently', + 'Errors don\'t affect other items' + ] + }, + 'python_data_analysis': { + task: 'python_data_analysis', + description: 'Analyze data using Python with statistics', + nodeType: 'nodes-base.code', + configuration: { + language: 'python', + pythonCode: `# Python data analysis - use underscore prefix for built-in variables +import json +from datetime import datetime +import statistics + +# Collect data for analysis +values = [] +categories = {} +dates = [] + +# Use _input.all() to get items in Python +for item in _input.all(): + # Convert JsProxy to Python dict for safe access + item_data = item.json.to_py() + + # Extract numeric values + if 'value' in item_data or 'amount' in item_data: + value = item_data.get('value', item_data.get('amount', 0)) + if isinstance(value, (int, float)): + values.append(value) + + # Count categories + category = item_data.get('category', 'uncategorized') + categories[category] = categories.get(category, 0) + 1 + + # Collect dates + if 'date' in item_data: + dates.append(item_data['date']) + +# Calculate statistics +result = { + 'itemCount': len(_input.all()), + 'values': { + 'count': len(values), + 'sum': sum(values) if values else 0, + 'mean': statistics.mean(values) if values else 0, + 'median': statistics.median(values) if values else 0, + 'min': min(values) if values else 0, + 'max': max(values) if values else 0, + 'stdev': statistics.stdev(values) if len(values) > 1 else 0 + }, + 'categories': categories, + 'dateRange': { + 'earliest': min(dates) if dates else None, + 'latest': max(dates) if dates else None, + 'count': len(dates) + }, + 'analysis': { + 'hasNumericData': len(values) > 0, + 'hasCategoricalData': len(categories) > 0, + 'hasTemporalData': len(dates) > 0, + 'dataQuality': 'good' if len(values) > len(items) * 0.8 else 'partial' + }, + 'processedAt': datetime.now().isoformat() +} + +# Return single summary item +return [{'json': result}]`, + onError: 'continueRegularOutput' + }, + userMustProvide: [], + notes: [ + 'Uses Python statistics module', + 'Analyzes numeric, categorical, and date data', + 'Returns comprehensive summary', + 'Handles missing data gracefully' + ] + } +}; +//# sourceMappingURL=task-templates.js.map \ No newline at end of file diff --git a/dist/services/task-templates.js.map b/dist/services/task-templates.js.map new file mode 100644 index 0000000..8c92fd4 --- /dev/null +++ b/dist/services/task-templates.js.map @@ -0,0 +1 @@ +{"version":3,"file":"task-templates.js","sourceRoot":"","sources":["../../src/services/task-templates.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/type-structure-service.d.ts b/dist/services/type-structure-service.d.ts new file mode 100644 index 0000000..5e106a8 --- /dev/null +++ b/dist/services/type-structure-service.d.ts @@ -0,0 +1,23 @@ +import type { NodePropertyTypes } from 'n8n-workflow'; +import type { TypeStructure } from '../types/type-structures'; +export interface TypeValidationResult { + valid: boolean; + errors: string[]; + warnings: string[]; +} +export declare class TypeStructureService { + static getStructure(type: NodePropertyTypes): TypeStructure | null; + static getAllStructures(): Record; + static getExample(type: NodePropertyTypes): any; + static getExamples(type: NodePropertyTypes): any[]; + static isComplexType(type: NodePropertyTypes): boolean; + static isPrimitiveType(type: NodePropertyTypes): boolean; + static getComplexTypes(): NodePropertyTypes[]; + static getPrimitiveTypes(): NodePropertyTypes[]; + static getComplexExamples(type: 'collection' | 'fixedCollection' | 'filter' | 'resourceMapper' | 'assignmentCollection'): Record | null; + static validateTypeCompatibility(value: any, type: NodePropertyTypes): TypeValidationResult; + static getDescription(type: NodePropertyTypes): string | null; + static getNotes(type: NodePropertyTypes): string[]; + static getJavaScriptType(type: NodePropertyTypes): 'string' | 'number' | 'boolean' | 'object' | 'array' | 'any' | null; +} +//# sourceMappingURL=type-structure-service.d.ts.map \ No newline at end of file diff --git a/dist/services/type-structure-service.d.ts.map b/dist/services/type-structure-service.d.ts.map new file mode 100644 index 0000000..fb4f0e4 --- /dev/null +++ b/dist/services/type-structure-service.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"type-structure-service.d.ts","sourceRoot":"","sources":["../../src/services/type-structure-service.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAU9D,MAAM,WAAW,oBAAoB;IAIpC,KAAK,EAAE,OAAO,CAAC;IAKf,MAAM,EAAE,MAAM,EAAE,CAAC;IAKjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACnB;AA2BD,qBAAa,oBAAoB;IAqBhC,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,iBAAiB,GAAG,aAAa,GAAG,IAAI;IAkBlE,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,iBAAiB,EAAE,aAAa,CAAC;IAuBnE,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,GAAG;IAuB/C,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,iBAAiB,GAAG,GAAG,EAAE;IAyBlD,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO;IAqBtD,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO;IAmBxD,MAAM,CAAC,eAAe,IAAI,iBAAiB,EAAE;IAsB7C,MAAM,CAAC,iBAAiB,IAAI,iBAAiB,EAAE;IAsB/C,MAAM,CAAC,kBAAkB,CACxB,IAAI,EAAE,YAAY,GAAG,iBAAiB,GAAG,QAAQ,GAAG,gBAAgB,GAAG,sBAAsB,GAC3F,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IA+B7B,MAAM,CAAC,yBAAyB,CAC/B,KAAK,EAAE,GAAG,EACV,IAAI,EAAE,iBAAiB,GACrB,oBAAoB;IAoFvB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,GAAG,IAAI;IAqB7D,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,EAAE;IAqBlD,MAAM,CAAC,iBAAiB,CACvB,IAAI,EAAE,iBAAiB,GACrB,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,IAAI;CAItE"} \ No newline at end of file diff --git a/dist/services/type-structure-service.js b/dist/services/type-structure-service.js new file mode 100644 index 0000000..6af008b --- /dev/null +++ b/dist/services/type-structure-service.js @@ -0,0 +1,109 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TypeStructureService = void 0; +const type_structures_1 = require("../types/type-structures"); +const type_structures_2 = require("../constants/type-structures"); +class TypeStructureService { + static getStructure(type) { + return type_structures_2.TYPE_STRUCTURES[type] || null; + } + static getAllStructures() { + return { ...type_structures_2.TYPE_STRUCTURES }; + } + static getExample(type) { + const structure = this.getStructure(type); + return structure ? structure.example : null; + } + static getExamples(type) { + const structure = this.getStructure(type); + if (!structure) + return []; + return structure.examples || [structure.example]; + } + static isComplexType(type) { + return (0, type_structures_1.isComplexType)(type); + } + static isPrimitiveType(type) { + return (0, type_structures_1.isPrimitiveType)(type); + } + static getComplexTypes() { + return Object.entries(type_structures_2.TYPE_STRUCTURES) + .filter(([, structure]) => structure.type === 'collection' || structure.type === 'special') + .filter(([type]) => this.isComplexType(type)) + .map(([type]) => type); + } + static getPrimitiveTypes() { + return Object.keys(type_structures_2.TYPE_STRUCTURES).filter((type) => this.isPrimitiveType(type)); + } + static getComplexExamples(type) { + return type_structures_2.COMPLEX_TYPE_EXAMPLES[type] || null; + } + static validateTypeCompatibility(value, type) { + const structure = this.getStructure(type); + if (!structure) { + return { + valid: false, + errors: [`Unknown property type: ${type}`], + warnings: [], + }; + } + const errors = []; + const warnings = []; + if (value === null || value === undefined) { + if (!structure.validation?.allowEmpty) { + errors.push(`Value is required for type ${type}`); + } + return { valid: errors.length === 0, errors, warnings }; + } + const actualType = Array.isArray(value) ? 'array' : typeof value; + const expectedType = structure.jsType; + if (expectedType !== 'any' && actualType !== expectedType) { + const isExpression = typeof value === 'string' && value.includes('{{'); + if (isExpression && structure.validation?.allowExpressions) { + warnings.push(`Value contains n8n expression - cannot validate type until runtime`); + } + else { + errors.push(`Expected ${expectedType} but got ${actualType}`); + } + } + if (type === 'dateTime' && typeof value === 'string') { + const pattern = structure.validation?.pattern; + if (pattern && !new RegExp(pattern).test(value)) { + errors.push(`Invalid dateTime format. Expected ISO 8601 format.`); + } + } + if (type === 'color' && typeof value === 'string') { + const pattern = structure.validation?.pattern; + if (pattern && !new RegExp(pattern).test(value)) { + errors.push(`Invalid color format. Expected 6-digit hex color (e.g., #FF5733).`); + } + } + if (type === 'json' && typeof value === 'string') { + try { + JSON.parse(value); + } + catch { + errors.push(`Invalid JSON string. Must be valid JSON when parsed.`); + } + } + return { + valid: errors.length === 0, + errors, + warnings, + }; + } + static getDescription(type) { + const structure = this.getStructure(type); + return structure ? structure.description : null; + } + static getNotes(type) { + const structure = this.getStructure(type); + return structure?.notes || []; + } + static getJavaScriptType(type) { + const structure = this.getStructure(type); + return structure ? structure.jsType : null; + } +} +exports.TypeStructureService = TypeStructureService; +//# sourceMappingURL=type-structure-service.js.map \ No newline at end of file diff --git a/dist/services/type-structure-service.js.map b/dist/services/type-structure-service.js.map new file mode 100644 index 0000000..7e2adcc --- /dev/null +++ b/dist/services/type-structure-service.js.map @@ -0,0 +1 @@ +{"version":3,"file":"type-structure-service.js","sourceRoot":"","sources":["../../src/services/type-structure-service.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/universal-expression-validator.d.ts b/dist/services/universal-expression-validator.d.ts new file mode 100644 index 0000000..8fe96bb --- /dev/null +++ b/dist/services/universal-expression-validator.d.ts @@ -0,0 +1,20 @@ +export interface UniversalValidationResult { + isValid: boolean; + hasExpression: boolean; + needsPrefix: boolean; + isMixedContent: boolean; + confidence: 1.0; + suggestion?: string; + explanation: string; +} +export declare class UniversalExpressionValidator { + private static readonly EXPRESSION_PATTERN; + private static readonly EXPRESSION_PREFIX; + static validateExpressionPrefix(value: any): UniversalValidationResult; + private static hasMixedContent; + static validateExpressionSyntax(value: string): UniversalValidationResult; + static validateCommonPatterns(value: string): UniversalValidationResult; + static validate(value: any): UniversalValidationResult[]; + static getCorrectedValue(value: string): string; +} +//# sourceMappingURL=universal-expression-validator.d.ts.map \ No newline at end of file diff --git a/dist/services/universal-expression-validator.d.ts.map b/dist/services/universal-expression-validator.d.ts.map new file mode 100644 index 0000000..b986baa --- /dev/null +++ b/dist/services/universal-expression-validator.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"universal-expression-validator.d.ts","sourceRoot":"","sources":["../../src/services/universal-expression-validator.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,GAAG,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,4BAA4B;IACvC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAsB;IAChE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAO;IAgBhD,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,GAAG,GAAG,yBAAyB;IAgEtE,OAAO,CAAC,MAAM,CAAC,eAAe;IAe9B,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,yBAAyB;IA8DzE,MAAM,CAAC,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,yBAAyB;IAwDvE,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,GAAG,yBAAyB,EAAE;IAyCxD,MAAM,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;CAWhD"} \ No newline at end of file diff --git a/dist/services/universal-expression-validator.js b/dist/services/universal-expression-validator.js new file mode 100644 index 0000000..74409ce --- /dev/null +++ b/dist/services/universal-expression-validator.js @@ -0,0 +1,192 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.UniversalExpressionValidator = void 0; +class UniversalExpressionValidator { + static validateExpressionPrefix(value) { + if (typeof value !== 'string') { + return { + isValid: true, + hasExpression: false, + needsPrefix: false, + isMixedContent: false, + confidence: 1.0, + explanation: 'Not a string value' + }; + } + const hasExpression = this.EXPRESSION_PATTERN.test(value); + if (!hasExpression) { + return { + isValid: true, + hasExpression: false, + needsPrefix: false, + isMixedContent: false, + confidence: 1.0, + explanation: 'No n8n expression found' + }; + } + const hasPrefix = value.startsWith(this.EXPRESSION_PREFIX); + const isMixedContent = this.hasMixedContent(value); + if (!hasPrefix) { + return { + isValid: false, + hasExpression: true, + needsPrefix: true, + isMixedContent, + confidence: 1.0, + suggestion: `${this.EXPRESSION_PREFIX}${value}`, + explanation: isMixedContent + ? 'Mixed literal text and expression requires = prefix for expression evaluation' + : 'Expression requires = prefix to be evaluated' + }; + } + return { + isValid: true, + hasExpression: true, + needsPrefix: false, + isMixedContent, + confidence: 1.0, + explanation: 'Expression is properly formatted with = prefix' + }; + } + static hasMixedContent(value) { + const content = value.startsWith(this.EXPRESSION_PREFIX) + ? value.substring(1) + : value; + const withoutExpressions = content.replace(/\{\{[\s\S]+?\}\}/g, ''); + return withoutExpressions.trim().length > 0; + } + static validateExpressionSyntax(value) { + const hasAnyBrackets = value.includes('{{') || value.includes('}}'); + if (!hasAnyBrackets) { + return { + isValid: true, + hasExpression: false, + needsPrefix: false, + isMixedContent: false, + confidence: 1.0, + explanation: 'No expression to validate' + }; + } + const openCount = (value.match(/\{\{/g) || []).length; + const closeCount = (value.match(/\}\}/g) || []).length; + if (openCount !== closeCount) { + return { + isValid: false, + hasExpression: true, + needsPrefix: false, + isMixedContent: false, + confidence: 1.0, + explanation: `Unmatched expression brackets: ${openCount} opening, ${closeCount} closing` + }; + } + const expressions = value.match(/\{\{[\s\S]+?\}\}/g) || []; + for (const expr of expressions) { + const content = expr.slice(2, -2).trim(); + if (!content) { + return { + isValid: false, + hasExpression: true, + needsPrefix: false, + isMixedContent: false, + confidence: 1.0, + explanation: 'Empty expression {{ }} is not valid' + }; + } + } + return { + isValid: true, + hasExpression: expressions.length > 0, + needsPrefix: false, + isMixedContent: this.hasMixedContent(value), + confidence: 1.0, + explanation: 'Expression syntax is valid' + }; + } + static validateCommonPatterns(value) { + if (!this.EXPRESSION_PATTERN.test(value)) { + return { + isValid: true, + hasExpression: false, + needsPrefix: false, + isMixedContent: false, + confidence: 1.0, + explanation: 'No expression to validate' + }; + } + const expressions = value.match(/\{\{[\s\S]+?\}\}/g) || []; + const warnings = []; + for (const expr of expressions) { + const content = expr.slice(2, -2).trim(); + if (content.includes('${') && content.includes('}')) { + warnings.push(`Template literal syntax \${} found - use n8n syntax instead: ${expr}`); + } + if (content.startsWith('=')) { + warnings.push(`Double prefix detected in expression: ${expr}`); + } + if (content.includes('{{') || content.includes('}}')) { + warnings.push(`Nested brackets detected: ${expr}`); + } + } + if (warnings.length > 0) { + return { + isValid: false, + hasExpression: true, + needsPrefix: false, + isMixedContent: false, + confidence: 1.0, + explanation: warnings.join('; ') + }; + } + return { + isValid: true, + hasExpression: true, + needsPrefix: false, + isMixedContent: this.hasMixedContent(value), + confidence: 1.0, + explanation: 'Expression patterns are valid' + }; + } + static validate(value) { + const results = []; + const prefixResult = this.validateExpressionPrefix(value); + if (!prefixResult.isValid) { + results.push(prefixResult); + } + if (typeof value === 'string') { + const syntaxResult = this.validateExpressionSyntax(value); + if (!syntaxResult.isValid) { + results.push(syntaxResult); + } + const patternResult = this.validateCommonPatterns(value); + if (!patternResult.isValid) { + results.push(patternResult); + } + } + if (results.length === 0) { + results.push({ + isValid: true, + hasExpression: prefixResult.hasExpression, + needsPrefix: false, + isMixedContent: prefixResult.isMixedContent, + confidence: 1.0, + explanation: prefixResult.hasExpression + ? 'Expression is valid' + : 'No expression found' + }); + } + return results; + } + static getCorrectedValue(value) { + if (!this.EXPRESSION_PATTERN.test(value)) { + return value; + } + if (!value.startsWith(this.EXPRESSION_PREFIX)) { + return `${this.EXPRESSION_PREFIX}${value}`; + } + return value; + } +} +exports.UniversalExpressionValidator = UniversalExpressionValidator; +UniversalExpressionValidator.EXPRESSION_PATTERN = /\{\{[\s\S]+?\}\}/; +UniversalExpressionValidator.EXPRESSION_PREFIX = '='; +//# sourceMappingURL=universal-expression-validator.js.map \ No newline at end of file diff --git a/dist/services/universal-expression-validator.js.map b/dist/services/universal-expression-validator.js.map new file mode 100644 index 0000000..0fd537c --- /dev/null +++ b/dist/services/universal-expression-validator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"universal-expression-validator.js","sourceRoot":"","sources":["../../src/services/universal-expression-validator.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/workflow-auto-fixer.d.ts b/dist/services/workflow-auto-fixer.d.ts new file mode 100644 index 0000000..1d6d719 --- /dev/null +++ b/dist/services/workflow-auto-fixer.d.ts @@ -0,0 +1,73 @@ +import { WorkflowValidationResult } from './workflow-validator'; +import { ExpressionFormatIssue } from './expression-format-validator'; +import { NodeRepository } from '../database/node-repository'; +import { WorkflowDiffOperation } from '../types/workflow-diff'; +import { Workflow } from '../types/n8n-api'; +import { PostUpdateGuidance } from './post-update-validator'; +export type FixConfidenceLevel = 'high' | 'medium' | 'low'; +export type FixType = 'expression-format' | 'typeversion-correction' | 'error-output-config' | 'node-type-correction' | 'webhook-missing-path' | 'typeversion-upgrade' | 'version-migration'; +export interface AutoFixConfig { + applyFixes: boolean; + fixTypes?: FixType[]; + confidenceThreshold?: FixConfidenceLevel; + maxFixes?: number; +} +export interface FixOperation { + node: string; + field: string; + type: FixType; + before: any; + after: any; + confidence: FixConfidenceLevel; + description: string; +} +export interface AutoFixResult { + operations: WorkflowDiffOperation[]; + fixes: FixOperation[]; + summary: string; + stats: { + total: number; + byType: Record; + byConfidence: Record; + }; + postUpdateGuidance?: PostUpdateGuidance[]; +} +export interface NodeFormatIssue extends ExpressionFormatIssue { + nodeName: string; + nodeId: string; +} +export declare function isNodeFormatIssue(issue: ExpressionFormatIssue): issue is NodeFormatIssue; +export interface NodeTypeError { + type: 'error'; + nodeId?: string; + nodeName?: string; + message: string; + suggestions?: Array<{ + nodeType: string; + confidence: number; + reason: string; + }>; +} +export declare class WorkflowAutoFixer { + private readonly defaultConfig; + private similarityService; + private versionService; + private breakingChangeDetector; + private migrationService; + private postUpdateValidator; + constructor(repository?: NodeRepository); + generateFixes(workflow: Workflow, validationResult: WorkflowValidationResult, formatIssues?: ExpressionFormatIssue[], config?: Partial): Promise; + private processExpressionFormatFixes; + private processTypeVersionFixes; + private processErrorOutputFixes; + private processNodeTypeFixes; + private processWebhookPathFixes; + private setNestedValue; + private filterByConfidence; + private filterOperationsByFixes; + private calculateStats; + private generateSummary; + private processVersionUpgradeFixes; + private processVersionMigrationFixes; +} +//# sourceMappingURL=workflow-auto-fixer.d.ts.map \ No newline at end of file diff --git a/dist/services/workflow-auto-fixer.d.ts.map b/dist/services/workflow-auto-fixer.d.ts.map new file mode 100644 index 0000000..2cee5f8 --- /dev/null +++ b/dist/services/workflow-auto-fixer.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"workflow-auto-fixer.d.ts","sourceRoot":"","sources":["../../src/services/workflow-auto-fixer.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/workflow-auto-fixer.js b/dist/services/workflow-auto-fixer.js new file mode 100644 index 0000000..8339316 --- /dev/null +++ b/dist/services/workflow-auto-fixer.js @@ -0,0 +1,515 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.WorkflowAutoFixer = void 0; +exports.isNodeFormatIssue = isNodeFormatIssue; +const crypto_1 = __importDefault(require("crypto")); +const node_similarity_service_1 = require("./node-similarity-service"); +const logger_1 = require("../utils/logger"); +const node_version_service_1 = require("./node-version-service"); +const breaking_change_detector_1 = require("./breaking-change-detector"); +const node_migration_service_1 = require("./node-migration-service"); +const post_update_validator_1 = require("./post-update-validator"); +const logger = new logger_1.Logger({ prefix: '[WorkflowAutoFixer]' }); +function isNodeFormatIssue(issue) { + return 'nodeName' in issue && 'nodeId' in issue && + typeof issue.nodeName === 'string' && + typeof issue.nodeId === 'string'; +} +class WorkflowAutoFixer { + constructor(repository) { + this.defaultConfig = { + applyFixes: false, + confidenceThreshold: 'medium', + maxFixes: 50 + }; + this.similarityService = null; + this.versionService = null; + this.breakingChangeDetector = null; + this.migrationService = null; + this.postUpdateValidator = null; + if (repository) { + this.similarityService = new node_similarity_service_1.NodeSimilarityService(repository); + this.breakingChangeDetector = new breaking_change_detector_1.BreakingChangeDetector(repository); + this.versionService = new node_version_service_1.NodeVersionService(repository, this.breakingChangeDetector); + this.migrationService = new node_migration_service_1.NodeMigrationService(this.versionService, this.breakingChangeDetector); + this.postUpdateValidator = new post_update_validator_1.PostUpdateValidator(this.versionService, this.breakingChangeDetector); + } + } + async generateFixes(workflow, validationResult, formatIssues = [], config = {}) { + const fullConfig = { ...this.defaultConfig, ...config }; + const operations = []; + const fixes = []; + const postUpdateGuidance = []; + const nodeMap = new Map(); + workflow.nodes.forEach(node => { + nodeMap.set(node.name, node); + nodeMap.set(node.id, node); + }); + if (!fullConfig.fixTypes || fullConfig.fixTypes.includes('expression-format')) { + this.processExpressionFormatFixes(formatIssues, nodeMap, operations, fixes); + } + if (!fullConfig.fixTypes || fullConfig.fixTypes.includes('typeversion-correction')) { + this.processTypeVersionFixes(validationResult, nodeMap, operations, fixes); + } + if (!fullConfig.fixTypes || fullConfig.fixTypes.includes('error-output-config')) { + this.processErrorOutputFixes(validationResult, nodeMap, workflow, operations, fixes); + } + if (!fullConfig.fixTypes || fullConfig.fixTypes.includes('node-type-correction')) { + this.processNodeTypeFixes(validationResult, nodeMap, operations, fixes); + } + if (!fullConfig.fixTypes || fullConfig.fixTypes.includes('webhook-missing-path')) { + this.processWebhookPathFixes(validationResult, nodeMap, operations, fixes); + } + if (!fullConfig.fixTypes || fullConfig.fixTypes.includes('typeversion-upgrade')) { + await this.processVersionUpgradeFixes(workflow, nodeMap, operations, fixes, postUpdateGuidance); + } + if (!fullConfig.fixTypes || fullConfig.fixTypes.includes('version-migration')) { + await this.processVersionMigrationFixes(workflow, nodeMap, operations, fixes, postUpdateGuidance); + } + const filteredFixes = this.filterByConfidence(fixes, fullConfig.confidenceThreshold); + const filteredOperations = this.filterOperationsByFixes(operations, filteredFixes, fixes); + const limitedFixes = filteredFixes.slice(0, fullConfig.maxFixes); + const limitedOperations = this.filterOperationsByFixes(filteredOperations, limitedFixes, filteredFixes); + const stats = this.calculateStats(limitedFixes); + const summary = this.generateSummary(stats); + return { + operations: limitedOperations, + fixes: limitedFixes, + summary, + stats, + postUpdateGuidance: postUpdateGuidance.length > 0 ? postUpdateGuidance : undefined + }; + } + processExpressionFormatFixes(formatIssues, nodeMap, operations, fixes) { + const fixesByNode = new Map(); + for (const issue of formatIssues) { + if (issue.issueType === 'missing-prefix') { + if (!isNodeFormatIssue(issue)) { + logger.warn('Expression format issue missing node information', { + fieldPath: issue.fieldPath, + issueType: issue.issueType + }); + continue; + } + const nodeName = issue.nodeName; + if (!fixesByNode.has(nodeName)) { + fixesByNode.set(nodeName, []); + } + fixesByNode.get(nodeName).push(issue); + } + } + for (const [nodeName, nodeIssues] of fixesByNode) { + const node = nodeMap.get(nodeName); + if (!node) + continue; + const updatedParameters = JSON.parse(JSON.stringify(node.parameters || {})); + for (const issue of nodeIssues) { + const fieldPath = issue.fieldPath.split('.'); + this.setNestedValue(updatedParameters, fieldPath, issue.correctedValue); + fixes.push({ + node: nodeName, + field: issue.fieldPath, + type: 'expression-format', + before: issue.currentValue, + after: issue.correctedValue, + confidence: 'high', + description: issue.explanation + }); + } + const operation = { + type: 'updateNode', + nodeId: nodeName, + updates: { + parameters: updatedParameters + } + }; + operations.push(operation); + } + } + processTypeVersionFixes(validationResult, nodeMap, operations, fixes) { + for (const error of validationResult.errors) { + if (error.message.includes('typeVersion') && error.message.includes('exceeds maximum')) { + const versionMatch = error.message.match(/typeVersion (\d+(?:\.\d+)?) exceeds maximum supported version (\d+(?:\.\d+)?)/); + if (versionMatch) { + const currentVersion = parseFloat(versionMatch[1]); + const maxVersion = parseFloat(versionMatch[2]); + const nodeName = error.nodeName || error.nodeId; + if (!nodeName) + continue; + const node = nodeMap.get(nodeName); + if (!node) + continue; + fixes.push({ + node: nodeName, + field: 'typeVersion', + type: 'typeversion-correction', + before: currentVersion, + after: maxVersion, + confidence: 'medium', + description: `Corrected typeVersion from ${currentVersion} to maximum supported ${maxVersion}` + }); + const operation = { + type: 'updateNode', + nodeId: nodeName, + updates: { + typeVersion: maxVersion + } + }; + operations.push(operation); + } + } + } + } + processErrorOutputFixes(validationResult, nodeMap, workflow, operations, fixes) { + for (const error of validationResult.errors) { + if (error.message.includes('onError: \'continueErrorOutput\'') && + error.message.includes('no error output connections')) { + const nodeName = error.nodeName || error.nodeId; + if (!nodeName) + continue; + const node = nodeMap.get(nodeName); + if (!node) + continue; + fixes.push({ + node: nodeName, + field: 'onError', + type: 'error-output-config', + before: 'continueErrorOutput', + after: undefined, + confidence: 'medium', + description: 'Removed onError setting due to missing error output connections' + }); + const operation = { + type: 'updateNode', + nodeId: nodeName, + updates: { + onError: undefined + } + }; + operations.push(operation); + } + } + } + processNodeTypeFixes(validationResult, nodeMap, operations, fixes) { + if (!this.similarityService) { + return; + } + for (const error of validationResult.errors) { + const nodeError = error; + if (error.message?.includes('Unknown node type:') && nodeError.suggestions) { + const highConfidenceSuggestion = nodeError.suggestions.find(s => s.confidence >= 0.9); + if (highConfidenceSuggestion && nodeError.nodeId) { + const node = nodeMap.get(nodeError.nodeId) || nodeMap.get(nodeError.nodeName || ''); + if (node) { + fixes.push({ + node: node.name, + field: 'type', + type: 'node-type-correction', + before: node.type, + after: highConfidenceSuggestion.nodeType, + confidence: 'high', + description: `Fix node type: "${node.type}" → "${highConfidenceSuggestion.nodeType}" (${highConfidenceSuggestion.reason})` + }); + const operation = { + type: 'updateNode', + nodeId: node.name, + updates: { + type: highConfidenceSuggestion.nodeType + } + }; + operations.push(operation); + } + } + } + } + } + processWebhookPathFixes(validationResult, nodeMap, operations, fixes) { + for (const error of validationResult.errors) { + if (error.message === 'Webhook path is required') { + const nodeName = error.nodeName || error.nodeId; + if (!nodeName) + continue; + const node = nodeMap.get(nodeName); + if (!node) + continue; + if (!node.type?.includes('webhook')) + continue; + const webhookId = crypto_1.default.randomUUID(); + const currentTypeVersion = node.typeVersion || 1; + const needsVersionUpdate = currentTypeVersion < 2.1; + fixes.push({ + node: nodeName, + field: 'path', + type: 'webhook-missing-path', + before: undefined, + after: webhookId, + confidence: 'high', + description: needsVersionUpdate + ? `Generated webhook path and ID: ${webhookId} (also updating typeVersion to 2.1)` + : `Generated webhook path and ID: ${webhookId}` + }); + const updates = { + 'parameters.path': webhookId, + 'webhookId': webhookId + }; + if (needsVersionUpdate) { + updates['typeVersion'] = 2.1; + } + const operation = { + type: 'updateNode', + nodeId: nodeName, + updates + }; + operations.push(operation); + } + } + } + setNestedValue(obj, path, value) { + if (!obj || typeof obj !== 'object') { + throw new Error('Cannot set value on non-object'); + } + if (path.length === 0) { + throw new Error('Cannot set value with empty path'); + } + try { + let current = obj; + for (let i = 0; i < path.length - 1; i++) { + const key = path[i]; + if (key.includes('[')) { + const matches = key.match(/^([^[]+)\[(\d+)\]$/); + if (!matches) { + throw new Error(`Invalid array notation: ${key}`); + } + const [, arrayKey, indexStr] = matches; + const index = parseInt(indexStr, 10); + if (isNaN(index) || index < 0) { + throw new Error(`Invalid array index: ${indexStr}`); + } + if (!current[arrayKey]) { + current[arrayKey] = []; + } + if (!Array.isArray(current[arrayKey])) { + throw new Error(`Expected array at ${arrayKey}, got ${typeof current[arrayKey]}`); + } + while (current[arrayKey].length <= index) { + current[arrayKey].push({}); + } + current = current[arrayKey][index]; + } + else { + if (current[key] === null || current[key] === undefined) { + current[key] = {}; + } + if (typeof current[key] !== 'object' || Array.isArray(current[key])) { + throw new Error(`Cannot traverse through ${typeof current[key]} at ${key}`); + } + current = current[key]; + } + } + const lastKey = path[path.length - 1]; + if (lastKey.includes('[')) { + const matches = lastKey.match(/^([^[]+)\[(\d+)\]$/); + if (!matches) { + throw new Error(`Invalid array notation: ${lastKey}`); + } + const [, arrayKey, indexStr] = matches; + const index = parseInt(indexStr, 10); + if (isNaN(index) || index < 0) { + throw new Error(`Invalid array index: ${indexStr}`); + } + if (!current[arrayKey]) { + current[arrayKey] = []; + } + if (!Array.isArray(current[arrayKey])) { + throw new Error(`Expected array at ${arrayKey}, got ${typeof current[arrayKey]}`); + } + while (current[arrayKey].length <= index) { + current[arrayKey].push(null); + } + current[arrayKey][index] = value; + } + else { + current[lastKey] = value; + } + } + catch (error) { + logger.error('Failed to set nested value', { + path: path.join('.'), + error: error instanceof Error ? error.message : String(error) + }); + throw error; + } + } + filterByConfidence(fixes, threshold) { + if (!threshold) + return fixes; + const levels = ['high', 'medium', 'low']; + const thresholdIndex = levels.indexOf(threshold); + return fixes.filter(fix => { + const fixIndex = levels.indexOf(fix.confidence); + return fixIndex <= thresholdIndex; + }); + } + filterOperationsByFixes(operations, filteredFixes, allFixes) { + const fixedNodes = new Set(filteredFixes.map(f => f.node)); + return operations.filter(op => { + if (op.type === 'updateNode') { + return fixedNodes.has(op.nodeId || ''); + } + return true; + }); + } + calculateStats(fixes) { + const stats = { + total: fixes.length, + byType: { + 'expression-format': 0, + 'typeversion-correction': 0, + 'error-output-config': 0, + 'node-type-correction': 0, + 'webhook-missing-path': 0, + 'typeversion-upgrade': 0, + 'version-migration': 0 + }, + byConfidence: { + 'high': 0, + 'medium': 0, + 'low': 0 + } + }; + for (const fix of fixes) { + stats.byType[fix.type]++; + stats.byConfidence[fix.confidence]++; + } + return stats; + } + generateSummary(stats) { + if (stats.total === 0) { + return 'No fixes available'; + } + const parts = []; + if (stats.byType['expression-format'] > 0) { + parts.push(`${stats.byType['expression-format']} expression format ${stats.byType['expression-format'] === 1 ? 'error' : 'errors'}`); + } + if (stats.byType['typeversion-correction'] > 0) { + parts.push(`${stats.byType['typeversion-correction']} version ${stats.byType['typeversion-correction'] === 1 ? 'issue' : 'issues'}`); + } + if (stats.byType['error-output-config'] > 0) { + parts.push(`${stats.byType['error-output-config']} error output ${stats.byType['error-output-config'] === 1 ? 'configuration' : 'configurations'}`); + } + if (stats.byType['node-type-correction'] > 0) { + parts.push(`${stats.byType['node-type-correction']} node type ${stats.byType['node-type-correction'] === 1 ? 'correction' : 'corrections'}`); + } + if (stats.byType['webhook-missing-path'] > 0) { + parts.push(`${stats.byType['webhook-missing-path']} webhook ${stats.byType['webhook-missing-path'] === 1 ? 'path' : 'paths'}`); + } + if (stats.byType['typeversion-upgrade'] > 0) { + parts.push(`${stats.byType['typeversion-upgrade']} version ${stats.byType['typeversion-upgrade'] === 1 ? 'upgrade' : 'upgrades'}`); + } + if (stats.byType['version-migration'] > 0) { + parts.push(`${stats.byType['version-migration']} version ${stats.byType['version-migration'] === 1 ? 'migration' : 'migrations'}`); + } + if (parts.length === 0) { + return `Fixed ${stats.total} ${stats.total === 1 ? 'issue' : 'issues'}`; + } + return `Fixed ${parts.join(', ')}`; + } + async processVersionUpgradeFixes(workflow, nodeMap, operations, fixes, postUpdateGuidance) { + if (!this.versionService || !this.migrationService || !this.postUpdateValidator) { + logger.warn('Version services not initialized. Skipping version upgrade fixes.'); + return; + } + for (const node of workflow.nodes) { + if (!node.typeVersion || !node.type) + continue; + const currentVersion = node.typeVersion.toString(); + const analysis = this.versionService.analyzeVersion(node.type, currentVersion); + if (!analysis.isOutdated || !analysis.recommendUpgrade) + continue; + if (analysis.confidence === 'LOW') + continue; + const latestVersion = analysis.latestVersion; + try { + const migrationResult = await this.migrationService.migrateNode(node, currentVersion, latestVersion); + fixes.push({ + node: node.name, + field: 'typeVersion', + type: 'typeversion-upgrade', + before: currentVersion, + after: latestVersion, + confidence: analysis.hasBreakingChanges ? 'medium' : 'high', + description: `Upgrade ${node.name} from v${currentVersion} to v${latestVersion}. ${analysis.reason}` + }); + const operation = { + type: 'updateNode', + nodeId: node.id, + updates: { + typeVersion: parseFloat(latestVersion), + parameters: migrationResult.updatedNode.parameters, + ...(migrationResult.updatedNode.webhookId && { webhookId: migrationResult.updatedNode.webhookId }) + } + }; + operations.push(operation); + const guidance = await this.postUpdateValidator.generateGuidance(node.id, node.name, node.type, currentVersion, latestVersion, migrationResult); + postUpdateGuidance.push(guidance); + logger.info(`Generated version upgrade fix for ${node.name}: ${currentVersion} → ${latestVersion}`, { + appliedMigrations: migrationResult.appliedMigrations.length, + remainingIssues: migrationResult.remainingIssues.length + }); + } + catch (error) { + logger.error(`Failed to process version upgrade for ${node.name}`, { error }); + } + } + } + async processVersionMigrationFixes(workflow, nodeMap, operations, fixes, postUpdateGuidance) { + if (!this.versionService || !this.breakingChangeDetector || !this.postUpdateValidator) { + logger.warn('Version services not initialized. Skipping version migration fixes.'); + return; + } + for (const node of workflow.nodes) { + if (!node.typeVersion || !node.type) + continue; + const currentVersion = node.typeVersion.toString(); + const latestVersion = this.versionService.getLatestVersion(node.type); + if (!latestVersion || currentVersion === latestVersion) + continue; + const hasBreaking = this.breakingChangeDetector.hasBreakingChanges(node.type, currentVersion, latestVersion); + if (!hasBreaking) + continue; + const analysis = await this.breakingChangeDetector.analyzeVersionUpgrade(node.type, currentVersion, latestVersion); + if (analysis.autoMigratableCount === analysis.changes.length) + continue; + const guidance = await this.postUpdateValidator.generateGuidance(node.id, node.name, node.type, currentVersion, latestVersion, { + success: false, + nodeId: node.id, + nodeName: node.name, + fromVersion: currentVersion, + toVersion: latestVersion, + appliedMigrations: [], + remainingIssues: analysis.recommendations, + confidence: analysis.overallSeverity === 'HIGH' ? 'LOW' : 'MEDIUM', + updatedNode: node + }); + fixes.push({ + node: node.name, + field: 'typeVersion', + type: 'version-migration', + before: currentVersion, + after: latestVersion, + confidence: guidance.confidence === 'HIGH' ? 'medium' : 'low', + description: `Version migration required: ${node.name} v${currentVersion} → v${latestVersion}. ${analysis.manualRequiredCount} manual action(s) required.` + }); + postUpdateGuidance.push(guidance); + logger.info(`Documented version migration for ${node.name}`, { + breakingChanges: analysis.changes.filter(c => c.isBreaking).length, + manualRequired: analysis.manualRequiredCount + }); + } + } +} +exports.WorkflowAutoFixer = WorkflowAutoFixer; +//# sourceMappingURL=workflow-auto-fixer.js.map \ No newline at end of file diff --git a/dist/services/workflow-auto-fixer.js.map b/dist/services/workflow-auto-fixer.js.map new file mode 100644 index 0000000..ba8b100 --- /dev/null +++ b/dist/services/workflow-auto-fixer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"workflow-auto-fixer.js","sourceRoot":"","sources":["../../src/services/workflow-auto-fixer.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/workflow-diff-engine.d.ts b/dist/services/workflow-diff-engine.d.ts new file mode 100644 index 0000000..1c85b85 --- /dev/null +++ b/dist/services/workflow-diff-engine.d.ts @@ -0,0 +1,45 @@ +import { WorkflowDiffRequest, WorkflowDiffResult } from '../types/workflow-diff'; +import { Workflow } from '../types/n8n-api'; +export declare class WorkflowDiffEngine { + private renameMap; + private warnings; + applyDiff(workflow: Workflow, request: WorkflowDiffRequest): Promise; + private validateOperation; + private applyOperation; + private validateAddNode; + private validateRemoveNode; + private validateUpdateNode; + private validateMoveNode; + private validateToggleNode; + private validateAddConnection; + private validateRemoveConnection; + private validateRewireConnection; + private applyAddNode; + private applyRemoveNode; + private applyUpdateNode; + private applyMoveNode; + private applyEnableNode; + private applyDisableNode; + private resolveSmartParameters; + private applyAddConnection; + private applyRemoveConnection; + private applyRewireConnection; + private applyUpdateSettings; + private applyUpdateName; + private applyAddTag; + private applyRemoveTag; + private validateActivateWorkflow; + private validateDeactivateWorkflow; + private applyActivateWorkflow; + private applyDeactivateWorkflow; + private validateCleanStaleConnections; + private validateReplaceConnections; + private applyCleanStaleConnections; + private applyReplaceConnections; + private updateConnectionReferences; + private normalizeNodeName; + private findNode; + private formatNodeNotFoundError; + private setNestedProperty; +} +//# sourceMappingURL=workflow-diff-engine.d.ts.map \ No newline at end of file diff --git a/dist/services/workflow-diff-engine.d.ts.map b/dist/services/workflow-diff-engine.d.ts.map new file mode 100644 index 0000000..fa24afd --- /dev/null +++ b/dist/services/workflow-diff-engine.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"workflow-diff-engine.d.ts","sourceRoot":"","sources":["../../src/services/workflow-diff-engine.ts"],"names":[],"mappings":"AAMA,OAAO,EAEL,mBAAmB,EACnB,kBAAkB,EAsBnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAoC,MAAM,kBAAkB,CAAC;AAQ9E,qBAAa,kBAAkB;IAE7B,OAAO,CAAC,SAAS,CAAkC;IAEnD,OAAO,CAAC,QAAQ,CAAqC;IAK/C,SAAS,CACb,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC;IA0M9B,OAAO,CAAC,iBAAiB;IAwCzB,OAAO,CAAC,cAAc;IAyDtB,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,kBAAkB;IAuB1B,OAAO,CAAC,kBAAkB;IAoC1B,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,qBAAqB;IAkD7B,OAAO,CAAC,wBAAwB;IAuChC,OAAO,CAAC,wBAAwB;IAmDhC,OAAO,CAAC,YAAY;IA2BpB,OAAO,CAAC,eAAe;IAkCvB,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,sBAAsB;IAgD9B,OAAO,CAAC,kBAAkB;IA4C1B,OAAO,CAAC,qBAAqB;IA2C7B,OAAO,CAAC,qBAAqB;IA0B7B,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,wBAAwB;IAchC,OAAO,CAAC,0BAA0B;IAMlC,OAAO,CAAC,qBAAqB;IAM7B,OAAO,CAAC,uBAAuB;IAO/B,OAAO,CAAC,6BAA6B;IAKrC,OAAO,CAAC,0BAA0B;IA0BlC,OAAO,CAAC,0BAA0B;IA0ElC,OAAO,CAAC,uBAAuB;IAe/B,OAAO,CAAC,0BAA0B;IAkElC,OAAO,CAAC,iBAAiB;IAkBzB,OAAO,CAAC,QAAQ;IAsChB,OAAO,CAAC,uBAAuB;IAW/B,OAAO,CAAC,iBAAiB;CAc1B"} \ No newline at end of file diff --git a/dist/services/workflow-diff-engine.js b/dist/services/workflow-diff-engine.js new file mode 100644 index 0000000..2488283 --- /dev/null +++ b/dist/services/workflow-diff-engine.js @@ -0,0 +1,830 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.WorkflowDiffEngine = void 0; +const uuid_1 = require("uuid"); +const logger_1 = require("../utils/logger"); +const node_sanitizer_1 = require("./node-sanitizer"); +const node_type_utils_1 = require("../utils/node-type-utils"); +const logger = new logger_1.Logger({ prefix: '[WorkflowDiffEngine]' }); +class WorkflowDiffEngine { + constructor() { + this.renameMap = new Map(); + this.warnings = []; + } + async applyDiff(workflow, request) { + try { + this.renameMap.clear(); + this.warnings = []; + const workflowCopy = JSON.parse(JSON.stringify(workflow)); + const nodeOperationTypes = ['addNode', 'removeNode', 'updateNode', 'moveNode', 'enableNode', 'disableNode']; + const nodeOperations = []; + const otherOperations = []; + request.operations.forEach((operation, index) => { + if (nodeOperationTypes.includes(operation.type)) { + nodeOperations.push({ operation, index }); + } + else { + otherOperations.push({ operation, index }); + } + }); + const allOperations = [...nodeOperations, ...otherOperations]; + const errors = []; + const appliedIndices = []; + const failedIndices = []; + if (request.continueOnError) { + for (const { operation, index } of allOperations) { + const error = this.validateOperation(workflowCopy, operation); + if (error) { + errors.push({ + operation: index, + message: error, + details: operation + }); + failedIndices.push(index); + continue; + } + try { + this.applyOperation(workflowCopy, operation); + appliedIndices.push(index); + } + catch (error) { + const errorMsg = `Failed to apply operation: ${error instanceof Error ? error.message : 'Unknown error'}`; + errors.push({ + operation: index, + message: errorMsg, + details: operation + }); + failedIndices.push(index); + } + } + if (this.renameMap.size > 0 && appliedIndices.length > 0) { + this.updateConnectionReferences(workflowCopy); + logger.debug(`Auto-updated ${this.renameMap.size} node name references in connections (continueOnError mode)`); + } + if (request.validateOnly) { + return { + success: errors.length === 0, + message: errors.length === 0 + ? 'Validation successful. All operations are valid.' + : `Validation completed with ${errors.length} errors.`, + errors: errors.length > 0 ? errors : undefined, + warnings: this.warnings.length > 0 ? this.warnings : undefined, + applied: appliedIndices, + failed: failedIndices + }; + } + const success = appliedIndices.length > 0; + return { + success, + workflow: workflowCopy, + operationsApplied: appliedIndices.length, + message: `Applied ${appliedIndices.length} operations, ${failedIndices.length} failed (continueOnError mode)`, + errors: errors.length > 0 ? errors : undefined, + warnings: this.warnings.length > 0 ? this.warnings : undefined, + applied: appliedIndices, + failed: failedIndices + }; + } + else { + for (const { operation, index } of nodeOperations) { + const error = this.validateOperation(workflowCopy, operation); + if (error) { + return { + success: false, + errors: [{ + operation: index, + message: error, + details: operation + }] + }; + } + try { + this.applyOperation(workflowCopy, operation); + } + catch (error) { + return { + success: false, + errors: [{ + operation: index, + message: `Failed to apply operation: ${error instanceof Error ? error.message : 'Unknown error'}`, + details: operation + }] + }; + } + } + if (this.renameMap.size > 0) { + this.updateConnectionReferences(workflowCopy); + logger.debug(`Auto-updated ${this.renameMap.size} node name references in connections`); + } + for (const { operation, index } of otherOperations) { + const error = this.validateOperation(workflowCopy, operation); + if (error) { + return { + success: false, + errors: [{ + operation: index, + message: error, + details: operation + }] + }; + } + try { + this.applyOperation(workflowCopy, operation); + } + catch (error) { + return { + success: false, + errors: [{ + operation: index, + message: `Failed to apply operation: ${error instanceof Error ? error.message : 'Unknown error'}`, + details: operation + }] + }; + } + } + workflowCopy.nodes = workflowCopy.nodes.map((node) => (0, node_sanitizer_1.sanitizeNode)(node)); + logger.debug('Applied full-workflow sanitization to all nodes'); + if (request.validateOnly) { + return { + success: true, + message: 'Validation successful. Operations are valid but not applied.' + }; + } + const operationsApplied = request.operations.length; + const shouldActivate = workflowCopy._shouldActivate === true; + const shouldDeactivate = workflowCopy._shouldDeactivate === true; + delete workflowCopy._shouldActivate; + delete workflowCopy._shouldDeactivate; + return { + success: true, + workflow: workflowCopy, + operationsApplied, + message: `Successfully applied ${operationsApplied} operations (${nodeOperations.length} node ops, ${otherOperations.length} other ops)`, + warnings: this.warnings.length > 0 ? this.warnings : undefined, + shouldActivate: shouldActivate || undefined, + shouldDeactivate: shouldDeactivate || undefined + }; + } + } + catch (error) { + logger.error('Failed to apply diff', error); + return { + success: false, + errors: [{ + operation: -1, + message: `Diff engine error: ${error instanceof Error ? error.message : 'Unknown error'}` + }] + }; + } + } + validateOperation(workflow, operation) { + switch (operation.type) { + case 'addNode': + return this.validateAddNode(workflow, operation); + case 'removeNode': + return this.validateRemoveNode(workflow, operation); + case 'updateNode': + return this.validateUpdateNode(workflow, operation); + case 'moveNode': + return this.validateMoveNode(workflow, operation); + case 'enableNode': + case 'disableNode': + return this.validateToggleNode(workflow, operation); + case 'addConnection': + return this.validateAddConnection(workflow, operation); + case 'removeConnection': + return this.validateRemoveConnection(workflow, operation); + case 'rewireConnection': + return this.validateRewireConnection(workflow, operation); + case 'updateSettings': + case 'updateName': + case 'addTag': + case 'removeTag': + return null; + case 'activateWorkflow': + return this.validateActivateWorkflow(workflow, operation); + case 'deactivateWorkflow': + return this.validateDeactivateWorkflow(workflow, operation); + case 'cleanStaleConnections': + return this.validateCleanStaleConnections(workflow, operation); + case 'replaceConnections': + return this.validateReplaceConnections(workflow, operation); + default: + return `Unknown operation type: ${operation.type}`; + } + } + applyOperation(workflow, operation) { + switch (operation.type) { + case 'addNode': + this.applyAddNode(workflow, operation); + break; + case 'removeNode': + this.applyRemoveNode(workflow, operation); + break; + case 'updateNode': + this.applyUpdateNode(workflow, operation); + break; + case 'moveNode': + this.applyMoveNode(workflow, operation); + break; + case 'enableNode': + this.applyEnableNode(workflow, operation); + break; + case 'disableNode': + this.applyDisableNode(workflow, operation); + break; + case 'addConnection': + this.applyAddConnection(workflow, operation); + break; + case 'removeConnection': + this.applyRemoveConnection(workflow, operation); + break; + case 'rewireConnection': + this.applyRewireConnection(workflow, operation); + break; + case 'updateSettings': + this.applyUpdateSettings(workflow, operation); + break; + case 'updateName': + this.applyUpdateName(workflow, operation); + break; + case 'addTag': + this.applyAddTag(workflow, operation); + break; + case 'removeTag': + this.applyRemoveTag(workflow, operation); + break; + case 'activateWorkflow': + this.applyActivateWorkflow(workflow, operation); + break; + case 'deactivateWorkflow': + this.applyDeactivateWorkflow(workflow, operation); + break; + case 'cleanStaleConnections': + this.applyCleanStaleConnections(workflow, operation); + break; + case 'replaceConnections': + this.applyReplaceConnections(workflow, operation); + break; + } + } + validateAddNode(workflow, operation) { + const { node } = operation; + const normalizedNewName = this.normalizeNodeName(node.name); + const duplicate = workflow.nodes.find(n => this.normalizeNodeName(n.name) === normalizedNewName); + if (duplicate) { + return `Node with name "${node.name}" already exists (normalized name matches existing node "${duplicate.name}")`; + } + if (!node.type.includes('.')) { + return `Invalid node type "${node.type}". Must include package prefix (e.g., "n8n-nodes-base.webhook")`; + } + if (node.type.startsWith('nodes-base.')) { + return `Invalid node type "${node.type}". Use "n8n-nodes-base.${node.type.substring(11)}" instead`; + } + return null; + } + validateRemoveNode(workflow, operation) { + const node = this.findNode(workflow, operation.nodeId, operation.nodeName); + if (!node) { + return this.formatNodeNotFoundError(workflow, operation.nodeId || operation.nodeName || '', 'removeNode'); + } + const hasConnections = Object.values(workflow.connections).some(conn => { + return Object.values(conn).some(outputs => outputs.some(connections => connections.some(c => c.node === node.name))); + }); + if (hasConnections || workflow.connections[node.name]) { + logger.warn(`Removing node "${node.name}" will break existing connections`); + } + return null; + } + validateUpdateNode(workflow, operation) { + const operationAny = operation; + if (operationAny.changes && !operation.updates) { + return `Invalid parameter 'changes'. The updateNode operation requires 'updates' (not 'changes'). Example: {type: "updateNode", nodeId: "abc", updates: {name: "New Name", "parameters.url": "https://example.com"}}`; + } + if (!operation.updates) { + return `Missing required parameter 'updates'. The updateNode operation requires an 'updates' object containing properties to modify. Example: {type: "updateNode", nodeId: "abc", updates: {name: "New Name"}}`; + } + const node = this.findNode(workflow, operation.nodeId, operation.nodeName); + if (!node) { + return this.formatNodeNotFoundError(workflow, operation.nodeId || operation.nodeName || '', 'updateNode'); + } + if (operation.updates.name && operation.updates.name !== node.name) { + const normalizedNewName = this.normalizeNodeName(operation.updates.name); + const normalizedCurrentName = this.normalizeNodeName(node.name); + if (normalizedNewName !== normalizedCurrentName) { + const collision = workflow.nodes.find(n => n.id !== node.id && this.normalizeNodeName(n.name) === normalizedNewName); + if (collision) { + return `Cannot rename node "${node.name}" to "${operation.updates.name}": A node with that name already exists (id: ${collision.id.substring(0, 8)}...). Please choose a different name.`; + } + } + } + return null; + } + validateMoveNode(workflow, operation) { + const node = this.findNode(workflow, operation.nodeId, operation.nodeName); + if (!node) { + return this.formatNodeNotFoundError(workflow, operation.nodeId || operation.nodeName || '', 'moveNode'); + } + return null; + } + validateToggleNode(workflow, operation) { + const node = this.findNode(workflow, operation.nodeId, operation.nodeName); + if (!node) { + const operationType = operation.type === 'enableNode' ? 'enableNode' : 'disableNode'; + return this.formatNodeNotFoundError(workflow, operation.nodeId || operation.nodeName || '', operationType); + } + return null; + } + validateAddConnection(workflow, operation) { + const operationAny = operation; + if (operationAny.sourceNodeId || operationAny.targetNodeId) { + const wrongParams = []; + if (operationAny.sourceNodeId) + wrongParams.push('sourceNodeId'); + if (operationAny.targetNodeId) + wrongParams.push('targetNodeId'); + return `Invalid parameter(s): ${wrongParams.join(', ')}. Use 'source' and 'target' instead. Example: {type: "addConnection", source: "Node Name", target: "Target Name"}`; + } + if (!operation.source) { + return `Missing required parameter 'source'. The addConnection operation requires both 'source' and 'target' parameters. Check that you're using 'source' (not 'sourceNodeId').`; + } + if (!operation.target) { + return `Missing required parameter 'target'. The addConnection operation requires both 'source' and 'target' parameters. Check that you're using 'target' (not 'targetNodeId').`; + } + const sourceNode = this.findNode(workflow, operation.source, operation.source); + const targetNode = this.findNode(workflow, operation.target, operation.target); + if (!sourceNode) { + const availableNodes = workflow.nodes + .map(n => `"${n.name}" (id: ${n.id.substring(0, 8)}...)`) + .join(', '); + return `Source node not found: "${operation.source}". Available nodes: ${availableNodes}. Tip: Use node ID for names with special characters (apostrophes, quotes).`; + } + if (!targetNode) { + const availableNodes = workflow.nodes + .map(n => `"${n.name}" (id: ${n.id.substring(0, 8)}...)`) + .join(', '); + return `Target node not found: "${operation.target}". Available nodes: ${availableNodes}. Tip: Use node ID for names with special characters (apostrophes, quotes).`; + } + const sourceOutput = operation.sourceOutput || 'main'; + const existing = workflow.connections[sourceNode.name]?.[sourceOutput]; + if (existing) { + const hasConnection = existing.some(connections => connections.some(c => c.node === targetNode.name)); + if (hasConnection) { + return `Connection already exists from "${sourceNode.name}" to "${targetNode.name}"`; + } + } + return null; + } + validateRemoveConnection(workflow, operation) { + if (operation.ignoreErrors) { + return null; + } + const sourceNode = this.findNode(workflow, operation.source, operation.source); + const targetNode = this.findNode(workflow, operation.target, operation.target); + if (!sourceNode) { + const availableNodes = workflow.nodes + .map(n => `"${n.name}" (id: ${n.id.substring(0, 8)}...)`) + .join(', '); + return `Source node not found: "${operation.source}". Available nodes: ${availableNodes}. Tip: Use node ID for names with special characters.`; + } + if (!targetNode) { + const availableNodes = workflow.nodes + .map(n => `"${n.name}" (id: ${n.id.substring(0, 8)}...)`) + .join(', '); + return `Target node not found: "${operation.target}". Available nodes: ${availableNodes}. Tip: Use node ID for names with special characters.`; + } + const sourceOutput = operation.sourceOutput || 'main'; + const connections = workflow.connections[sourceNode.name]?.[sourceOutput]; + if (!connections) { + return `No connections found from "${sourceNode.name}"`; + } + const hasConnection = connections.some(conns => conns.some(c => c.node === targetNode.name)); + if (!hasConnection) { + return `No connection exists from "${sourceNode.name}" to "${targetNode.name}"`; + } + return null; + } + validateRewireConnection(workflow, operation) { + const sourceNode = this.findNode(workflow, operation.source, operation.source); + if (!sourceNode) { + const availableNodes = workflow.nodes + .map(n => `"${n.name}" (id: ${n.id.substring(0, 8)}...)`) + .join(', '); + return `Source node not found: "${operation.source}". Available nodes: ${availableNodes}. Tip: Use node ID for names with special characters.`; + } + const fromNode = this.findNode(workflow, operation.from, operation.from); + if (!fromNode) { + const availableNodes = workflow.nodes + .map(n => `"${n.name}" (id: ${n.id.substring(0, 8)}...)`) + .join(', '); + return `"From" node not found: "${operation.from}". Available nodes: ${availableNodes}. Tip: Use node ID for names with special characters.`; + } + const toNode = this.findNode(workflow, operation.to, operation.to); + if (!toNode) { + const availableNodes = workflow.nodes + .map(n => `"${n.name}" (id: ${n.id.substring(0, 8)}...)`) + .join(', '); + return `"To" node not found: "${operation.to}". Available nodes: ${availableNodes}. Tip: Use node ID for names with special characters.`; + } + const { sourceOutput, sourceIndex } = this.resolveSmartParameters(workflow, operation); + const connections = workflow.connections[sourceNode.name]?.[sourceOutput]; + if (!connections) { + return `No connections found from "${sourceNode.name}" on output "${sourceOutput}"`; + } + if (!connections[sourceIndex]) { + return `No connections found from "${sourceNode.name}" on output "${sourceOutput}" at index ${sourceIndex}`; + } + const hasConnection = connections[sourceIndex].some(c => c.node === fromNode.name); + if (!hasConnection) { + return `No connection exists from "${sourceNode.name}" to "${fromNode.name}" on output "${sourceOutput}" at index ${sourceIndex}"`; + } + return null; + } + applyAddNode(workflow, operation) { + const newNode = { + id: operation.node.id || (0, uuid_1.v4)(), + name: operation.node.name, + type: operation.node.type, + typeVersion: operation.node.typeVersion || 1, + position: operation.node.position, + parameters: operation.node.parameters || {}, + credentials: operation.node.credentials, + disabled: operation.node.disabled, + notes: operation.node.notes, + notesInFlow: operation.node.notesInFlow, + continueOnFail: operation.node.continueOnFail, + onError: operation.node.onError, + retryOnFail: operation.node.retryOnFail, + maxTries: operation.node.maxTries, + waitBetweenTries: operation.node.waitBetweenTries, + alwaysOutputData: operation.node.alwaysOutputData, + executeOnce: operation.node.executeOnce + }; + const sanitizedNode = (0, node_sanitizer_1.sanitizeNode)(newNode); + workflow.nodes.push(sanitizedNode); + } + applyRemoveNode(workflow, operation) { + const node = this.findNode(workflow, operation.nodeId, operation.nodeName); + if (!node) + return; + const index = workflow.nodes.findIndex(n => n.id === node.id); + if (index !== -1) { + workflow.nodes.splice(index, 1); + } + delete workflow.connections[node.name]; + Object.keys(workflow.connections).forEach(sourceName => { + const sourceConnections = workflow.connections[sourceName]; + Object.keys(sourceConnections).forEach(outputName => { + sourceConnections[outputName] = sourceConnections[outputName].map(connections => connections.filter(conn => conn.node !== node.name)).filter(connections => connections.length > 0); + if (sourceConnections[outputName].length === 0) { + delete sourceConnections[outputName]; + } + }); + if (Object.keys(sourceConnections).length === 0) { + delete workflow.connections[sourceName]; + } + }); + } + applyUpdateNode(workflow, operation) { + const node = this.findNode(workflow, operation.nodeId, operation.nodeName); + if (!node) + return; + if (operation.updates.name && operation.updates.name !== node.name) { + const oldName = node.name; + const newName = operation.updates.name; + this.renameMap.set(oldName, newName); + logger.debug(`Tracking rename: "${oldName}" → "${newName}"`); + } + Object.entries(operation.updates).forEach(([path, value]) => { + this.setNestedProperty(node, path, value); + }); + const sanitized = (0, node_sanitizer_1.sanitizeNode)(node); + Object.assign(node, sanitized); + } + applyMoveNode(workflow, operation) { + const node = this.findNode(workflow, operation.nodeId, operation.nodeName); + if (!node) + return; + node.position = operation.position; + } + applyEnableNode(workflow, operation) { + const node = this.findNode(workflow, operation.nodeId, operation.nodeName); + if (!node) + return; + node.disabled = false; + } + applyDisableNode(workflow, operation) { + const node = this.findNode(workflow, operation.nodeId, operation.nodeName); + if (!node) + return; + node.disabled = true; + } + resolveSmartParameters(workflow, operation) { + const sourceNode = this.findNode(workflow, operation.source, operation.source); + let sourceOutput = operation.sourceOutput ?? 'main'; + let sourceIndex = operation.sourceIndex ?? 0; + if (operation.branch !== undefined && operation.sourceIndex === undefined) { + if (sourceNode?.type === 'n8n-nodes-base.if') { + sourceIndex = operation.branch === 'true' ? 0 : 1; + } + } + if (operation.case !== undefined && operation.sourceIndex === undefined) { + sourceIndex = operation.case; + } + if (sourceNode && operation.sourceIndex !== undefined && operation.branch === undefined && operation.case === undefined) { + if (sourceNode.type === 'n8n-nodes-base.if') { + this.warnings.push({ + operation: -1, + message: `Connection to If node "${operation.source}" uses sourceIndex=${operation.sourceIndex}. ` + + `Consider using branch="true" or branch="false" for better clarity. ` + + `If node outputs: main[0]=TRUE branch, main[1]=FALSE branch.` + }); + } + else if (sourceNode.type === 'n8n-nodes-base.switch') { + this.warnings.push({ + operation: -1, + message: `Connection to Switch node "${operation.source}" uses sourceIndex=${operation.sourceIndex}. ` + + `Consider using case=N for better clarity (case=0 for first output, case=1 for second, etc.).` + }); + } + } + return { sourceOutput, sourceIndex }; + } + applyAddConnection(workflow, operation) { + const sourceNode = this.findNode(workflow, operation.source, operation.source); + const targetNode = this.findNode(workflow, operation.target, operation.target); + if (!sourceNode || !targetNode) + return; + const { sourceOutput, sourceIndex } = this.resolveSmartParameters(workflow, operation); + const targetInput = operation.targetInput ?? sourceOutput; + const targetIndex = operation.targetIndex ?? 0; + if (!workflow.connections[sourceNode.name]) { + workflow.connections[sourceNode.name] = {}; + } + if (!workflow.connections[sourceNode.name][sourceOutput]) { + workflow.connections[sourceNode.name][sourceOutput] = []; + } + const outputArray = workflow.connections[sourceNode.name][sourceOutput]; + while (outputArray.length <= sourceIndex) { + outputArray.push([]); + } + if (!Array.isArray(outputArray[sourceIndex])) { + outputArray[sourceIndex] = []; + } + outputArray[sourceIndex].push({ + node: targetNode.name, + type: targetInput, + index: targetIndex + }); + } + applyRemoveConnection(workflow, operation) { + const sourceNode = this.findNode(workflow, operation.source, operation.source); + const targetNode = this.findNode(workflow, operation.target, operation.target); + if (!sourceNode || !targetNode) { + if (operation.ignoreErrors) { + return; + } + return; + } + const sourceOutput = operation.sourceOutput || 'main'; + const connections = workflow.connections[sourceNode.name]?.[sourceOutput]; + if (!connections) + return; + workflow.connections[sourceNode.name][sourceOutput] = connections.map(conns => conns.filter(conn => conn.node !== targetNode.name)); + const outputConnections = workflow.connections[sourceNode.name][sourceOutput]; + while (outputConnections.length > 0 && outputConnections[outputConnections.length - 1].length === 0) { + outputConnections.pop(); + } + if (outputConnections.length === 0) { + delete workflow.connections[sourceNode.name][sourceOutput]; + } + if (Object.keys(workflow.connections[sourceNode.name]).length === 0) { + delete workflow.connections[sourceNode.name]; + } + } + applyRewireConnection(workflow, operation) { + const { sourceOutput, sourceIndex } = this.resolveSmartParameters(workflow, operation); + this.applyRemoveConnection(workflow, { + type: 'removeConnection', + source: operation.source, + target: operation.from, + sourceOutput: sourceOutput, + targetInput: operation.targetInput + }); + this.applyAddConnection(workflow, { + type: 'addConnection', + source: operation.source, + target: operation.to, + sourceOutput: sourceOutput, + targetInput: operation.targetInput, + sourceIndex: sourceIndex, + targetIndex: 0 + }); + } + applyUpdateSettings(workflow, operation) { + if (operation.settings && Object.keys(operation.settings).length > 0) { + if (!workflow.settings) { + workflow.settings = {}; + } + Object.assign(workflow.settings, operation.settings); + } + } + applyUpdateName(workflow, operation) { + workflow.name = operation.name; + } + applyAddTag(workflow, operation) { + if (!workflow.tags) { + workflow.tags = []; + } + if (!workflow.tags.includes(operation.tag)) { + workflow.tags.push(operation.tag); + } + } + applyRemoveTag(workflow, operation) { + if (!workflow.tags) + return; + const index = workflow.tags.indexOf(operation.tag); + if (index !== -1) { + workflow.tags.splice(index, 1); + } + } + validateActivateWorkflow(workflow, operation) { + const activatableTriggers = workflow.nodes.filter(node => !node.disabled && (0, node_type_utils_1.isActivatableTrigger)(node.type)); + if (activatableTriggers.length === 0) { + return 'Cannot activate workflow: No activatable trigger nodes found. Workflows must have at least one enabled trigger node (webhook, schedule, email, etc.). Note: executeWorkflowTrigger cannot activate workflows as they can only be invoked by other workflows.'; + } + return null; + } + validateDeactivateWorkflow(workflow, operation) { + return null; + } + applyActivateWorkflow(workflow, operation) { + workflow._shouldActivate = true; + } + applyDeactivateWorkflow(workflow, operation) { + workflow._shouldDeactivate = true; + } + validateCleanStaleConnections(workflow, operation) { + return null; + } + validateReplaceConnections(workflow, operation) { + const nodeNames = new Set(workflow.nodes.map(n => n.name)); + for (const [sourceName, outputs] of Object.entries(operation.connections)) { + if (!nodeNames.has(sourceName)) { + return `Source node not found in connections: ${sourceName}`; + } + for (const outputName of Object.keys(outputs)) { + const connections = outputs[outputName]; + for (const conns of connections) { + for (const conn of conns) { + if (!nodeNames.has(conn.node)) { + return `Target node not found in connections: ${conn.node}`; + } + } + } + } + } + return null; + } + applyCleanStaleConnections(workflow, operation) { + const nodeNames = new Set(workflow.nodes.map(n => n.name)); + const staleConnections = []; + if (operation.dryRun) { + for (const [sourceName, outputs] of Object.entries(workflow.connections)) { + if (!nodeNames.has(sourceName)) { + for (const [outputName, connections] of Object.entries(outputs)) { + for (const conns of connections) { + for (const conn of conns) { + staleConnections.push({ from: sourceName, to: conn.node }); + } + } + } + } + else { + for (const [outputName, connections] of Object.entries(outputs)) { + for (const conns of connections) { + for (const conn of conns) { + if (!nodeNames.has(conn.node)) { + staleConnections.push({ from: sourceName, to: conn.node }); + } + } + } + } + } + } + logger.info(`[DryRun] Would remove ${staleConnections.length} stale connections:`, staleConnections); + return; + } + for (const [sourceName, outputs] of Object.entries(workflow.connections)) { + if (!nodeNames.has(sourceName)) { + for (const [outputName, connections] of Object.entries(outputs)) { + for (const conns of connections) { + for (const conn of conns) { + staleConnections.push({ from: sourceName, to: conn.node }); + } + } + } + delete workflow.connections[sourceName]; + continue; + } + for (const [outputName, connections] of Object.entries(outputs)) { + const filteredConnections = connections.map(conns => conns.filter(conn => { + if (!nodeNames.has(conn.node)) { + staleConnections.push({ from: sourceName, to: conn.node }); + return false; + } + return true; + })).filter(conns => conns.length > 0); + if (filteredConnections.length === 0) { + delete outputs[outputName]; + } + else { + outputs[outputName] = filteredConnections; + } + } + if (Object.keys(outputs).length === 0) { + delete workflow.connections[sourceName]; + } + } + logger.info(`Removed ${staleConnections.length} stale connections`); + } + applyReplaceConnections(workflow, operation) { + workflow.connections = operation.connections; + } + updateConnectionReferences(workflow) { + if (this.renameMap.size === 0) + return; + logger.debug(`Updating connection references for ${this.renameMap.size} renamed nodes`); + const renames = new Map(this.renameMap); + const updatedConnections = {}; + for (const [sourceName, outputs] of Object.entries(workflow.connections)) { + const newSourceName = renames.get(sourceName) || sourceName; + updatedConnections[newSourceName] = outputs; + } + for (const [sourceName, outputs] of Object.entries(updatedConnections)) { + for (const [outputType, connections] of Object.entries(outputs)) { + for (let outputIndex = 0; outputIndex < connections.length; outputIndex++) { + const connectionsAtIndex = connections[outputIndex]; + for (let connIndex = 0; connIndex < connectionsAtIndex.length; connIndex++) { + const connection = connectionsAtIndex[connIndex]; + if (renames.has(connection.node)) { + const newTargetName = renames.get(connection.node); + connection.node = newTargetName; + logger.debug(`Updated connection: ${sourceName}[${outputType}][${outputIndex}][${connIndex}].node: "${connection.node}" → "${newTargetName}"`); + } + } + } + } + } + workflow.connections = updatedConnections; + logger.info(`Auto-updated ${this.renameMap.size} node name references in connections`); + } + normalizeNodeName(name) { + return name + .trim() + .replace(/\\\\/g, '\\') + .replace(/\\'/g, "'") + .replace(/\\"/g, '"') + .replace(/\s+/g, ' '); + } + findNode(workflow, nodeId, nodeName) { + if (nodeId) { + const nodeById = workflow.nodes.find(n => n.id === nodeId); + if (nodeById) + return nodeById; + } + if (nodeName) { + const normalizedSearch = this.normalizeNodeName(nodeName); + const nodeByName = workflow.nodes.find(n => this.normalizeNodeName(n.name) === normalizedSearch); + if (nodeByName) + return nodeByName; + } + if (nodeId && !nodeName) { + const normalizedSearch = this.normalizeNodeName(nodeId); + const nodeByName = workflow.nodes.find(n => this.normalizeNodeName(n.name) === normalizedSearch); + if (nodeByName) + return nodeByName; + } + return null; + } + formatNodeNotFoundError(workflow, nodeIdentifier, operationType) { + const availableNodes = workflow.nodes + .map(n => `"${n.name}" (id: ${n.id.substring(0, 8)}...)`) + .join(', '); + return `Node not found for ${operationType}: "${nodeIdentifier}". Available nodes: ${availableNodes}. Tip: Use node ID for names with special characters (apostrophes, quotes).`; + } + setNestedProperty(obj, path, value) { + const keys = path.split('.'); + let current = obj; + for (let i = 0; i < keys.length - 1; i++) { + const key = keys[i]; + if (!(key in current) || typeof current[key] !== 'object') { + current[key] = {}; + } + current = current[key]; + } + current[keys[keys.length - 1]] = value; + } +} +exports.WorkflowDiffEngine = WorkflowDiffEngine; +//# sourceMappingURL=workflow-diff-engine.js.map \ No newline at end of file diff --git a/dist/services/workflow-diff-engine.js.map b/dist/services/workflow-diff-engine.js.map new file mode 100644 index 0000000..60dcea7 --- /dev/null +++ b/dist/services/workflow-diff-engine.js.map @@ -0,0 +1 @@ +{"version":3,"file":"workflow-diff-engine.js","sourceRoot":"","sources":["../../src/services/workflow-diff-engine.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/workflow-validator.d.ts b/dist/services/workflow-validator.d.ts new file mode 100644 index 0000000..cef5a5d --- /dev/null +++ b/dist/services/workflow-validator.d.ts @@ -0,0 +1,104 @@ +import { NodeRepository } from '../database/node-repository'; +import { EnhancedConfigValidator } from './enhanced-config-validator'; +interface WorkflowNode { + id: string; + name: string; + type: string; + position: [number, number]; + parameters: any; + credentials?: any; + disabled?: boolean; + notes?: string; + notesInFlow?: boolean; + typeVersion?: number; + continueOnFail?: boolean; + onError?: 'continueRegularOutput' | 'continueErrorOutput' | 'stopWorkflow'; + retryOnFail?: boolean; + maxTries?: number; + waitBetweenTries?: number; + alwaysOutputData?: boolean; + executeOnce?: boolean; +} +interface WorkflowConnection { + [sourceNode: string]: { + main?: Array>; + error?: Array>; + ai_tool?: Array>; + }; +} +interface WorkflowJson { + name?: string; + nodes: WorkflowNode[]; + connections: WorkflowConnection; + settings?: any; + staticData?: any; + pinData?: any; + meta?: any; +} +interface ValidationIssue { + type: 'error' | 'warning'; + nodeId?: string; + nodeName?: string; + message: string; + details?: any; +} +export interface WorkflowValidationResult { + valid: boolean; + errors: ValidationIssue[]; + warnings: ValidationIssue[]; + statistics: { + totalNodes: number; + enabledNodes: number; + triggerNodes: number; + validConnections: number; + invalidConnections: number; + expressionsValidated: number; + }; + suggestions: string[]; +} +export declare class WorkflowValidator { + private nodeRepository; + private nodeValidator; + private currentWorkflow; + private similarityService; + constructor(nodeRepository: NodeRepository, nodeValidator: typeof EnhancedConfigValidator); + validateWorkflow(workflow: WorkflowJson, options?: { + validateNodes?: boolean; + validateConnections?: boolean; + validateExpressions?: boolean; + profile?: 'minimal' | 'runtime' | 'ai-friendly' | 'strict'; + }): Promise; + private validateWorkflowStructure; + private validateAllNodes; + private validateConnections; + private validateConnectionOutputs; + private validateErrorOutputConfiguration; + private validateAIToolConnection; + private hasCycle; + private validateExpressions; + private countExpressionsInObject; + private nodeHasInput; + private checkWorkflowPatterns; + private getLongestLinearChain; + private generateSuggestions; + private checkNodeErrorHandling; + private checkWebhookErrorHandling; + private generateErrorHandlingSuggestions; + private validateSplitInBatchesConnection; + private checkForLoopBack; + private addErrorRecoverySuggestions; +} +export {}; +//# sourceMappingURL=workflow-validator.d.ts.map \ No newline at end of file diff --git a/dist/services/workflow-validator.d.ts.map b/dist/services/workflow-validator.d.ts.map new file mode 100644 index 0000000..871ecd0 --- /dev/null +++ b/dist/services/workflow-validator.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"workflow-validator.d.ts","sourceRoot":"","sources":["../../src/services/workflow-validator.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/workflow-validator.js b/dist/services/workflow-validator.js new file mode 100644 index 0000000..88ef0f2 --- /dev/null +++ b/dist/services/workflow-validator.js @@ -0,0 +1,1249 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.WorkflowValidator = void 0; +const crypto_1 = __importDefault(require("crypto")); +const expression_validator_1 = require("./expression-validator"); +const expression_format_validator_1 = require("./expression-format-validator"); +const node_similarity_service_1 = require("./node-similarity-service"); +const node_type_normalizer_1 = require("../utils/node-type-normalizer"); +const logger_1 = require("../utils/logger"); +const ai_node_validator_1 = require("./ai-node-validator"); +const node_type_utils_1 = require("../utils/node-type-utils"); +const node_classification_1 = require("../utils/node-classification"); +const logger = new logger_1.Logger({ prefix: '[WorkflowValidator]' }); +class WorkflowValidator { + constructor(nodeRepository, nodeValidator) { + this.nodeRepository = nodeRepository; + this.nodeValidator = nodeValidator; + this.currentWorkflow = null; + this.similarityService = new node_similarity_service_1.NodeSimilarityService(nodeRepository); + } + async validateWorkflow(workflow, options = {}) { + this.currentWorkflow = workflow; + const { validateNodes = true, validateConnections = true, validateExpressions = true, profile = 'runtime' } = options; + const result = { + valid: true, + errors: [], + warnings: [], + statistics: { + totalNodes: 0, + enabledNodes: 0, + triggerNodes: 0, + validConnections: 0, + invalidConnections: 0, + expressionsValidated: 0, + }, + suggestions: [] + }; + try { + if (!workflow) { + result.errors.push({ + type: 'error', + message: 'Invalid workflow structure: workflow is null or undefined' + }); + result.valid = false; + return result; + } + const executableNodes = Array.isArray(workflow.nodes) ? workflow.nodes.filter(n => !(0, node_classification_1.isNonExecutableNode)(n.type)) : []; + result.statistics.totalNodes = executableNodes.length; + result.statistics.enabledNodes = executableNodes.filter(n => !n.disabled).length; + this.validateWorkflowStructure(workflow, result); + if (workflow.nodes && Array.isArray(workflow.nodes) && workflow.connections && typeof workflow.connections === 'object') { + if (validateNodes && workflow.nodes.length > 0) { + await this.validateAllNodes(workflow, result, profile); + } + if (validateConnections) { + this.validateConnections(workflow, result, profile); + } + if (validateExpressions && workflow.nodes.length > 0) { + this.validateExpressions(workflow, result, profile); + } + if (workflow.nodes.length > 0) { + this.checkWorkflowPatterns(workflow, result, profile); + } + if (workflow.nodes.length > 0 && (0, ai_node_validator_1.hasAINodes)(workflow)) { + const aiIssues = (0, ai_node_validator_1.validateAISpecificNodes)(workflow); + for (const issue of aiIssues) { + const validationIssue = { + type: issue.severity === 'error' ? 'error' : 'warning', + nodeId: issue.nodeId, + nodeName: issue.nodeName, + message: issue.message, + details: issue.code ? { code: issue.code } : undefined + }; + if (issue.severity === 'error') { + result.errors.push(validationIssue); + } + else { + result.warnings.push(validationIssue); + } + } + } + this.generateSuggestions(workflow, result); + if (result.errors.length > 0) { + this.addErrorRecoverySuggestions(result); + } + } + } + catch (error) { + logger.error('Error validating workflow:', error); + result.errors.push({ + type: 'error', + message: `Workflow validation failed: ${error instanceof Error ? error.message : 'Unknown error'}` + }); + } + result.valid = result.errors.length === 0; + return result; + } + validateWorkflowStructure(workflow, result) { + if (!workflow.nodes) { + result.errors.push({ + type: 'error', + message: workflow.nodes === null ? 'nodes must be an array' : 'Workflow must have a nodes array' + }); + return; + } + if (!Array.isArray(workflow.nodes)) { + result.errors.push({ + type: 'error', + message: 'nodes must be an array' + }); + return; + } + if (!workflow.connections) { + result.errors.push({ + type: 'error', + message: workflow.connections === null ? 'connections must be an object' : 'Workflow must have a connections object' + }); + return; + } + if (typeof workflow.connections !== 'object' || Array.isArray(workflow.connections)) { + result.errors.push({ + type: 'error', + message: 'connections must be an object' + }); + return; + } + if (workflow.nodes.length === 0) { + result.warnings.push({ + type: 'warning', + message: 'Workflow is empty - no nodes defined' + }); + return; + } + if (workflow.nodes.length === 1) { + const singleNode = workflow.nodes[0]; + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(singleNode.type); + const isWebhook = normalizedType === 'nodes-base.webhook' || + normalizedType === 'nodes-base.webhookTrigger'; + const isLangchainNode = normalizedType.startsWith('nodes-langchain.'); + if (!isWebhook && !isLangchainNode) { + result.errors.push({ + type: 'error', + message: 'Single-node workflows are only valid for webhook endpoints. Add at least one more connected node to create a functional workflow.' + }); + } + else if (isWebhook && Object.keys(workflow.connections).length === 0) { + result.warnings.push({ + type: 'warning', + message: 'Webhook node has no connections. Consider adding nodes to process the webhook data.' + }); + } + } + if (workflow.nodes.length > 1) { + const hasEnabledNodes = workflow.nodes.some(n => !n.disabled); + const hasConnections = Object.keys(workflow.connections).length > 0; + if (hasEnabledNodes && !hasConnections) { + result.errors.push({ + type: 'error', + message: 'Multi-node workflow has no connections. Nodes must be connected to create a workflow. Use connections: { "Source Node Name": { "main": [[{ "node": "Target Node Name", "type": "main", "index": 0 }]] } }' + }); + } + } + const nodeNames = new Set(); + const nodeIds = new Set(); + const nodeIdToIndex = new Map(); + for (let i = 0; i < workflow.nodes.length; i++) { + const node = workflow.nodes[i]; + if (nodeNames.has(node.name)) { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Duplicate node name: "${node.name}"` + }); + } + nodeNames.add(node.name); + if (nodeIds.has(node.id)) { + const firstNodeIndex = nodeIdToIndex.get(node.id); + const firstNode = firstNodeIndex !== undefined ? workflow.nodes[firstNodeIndex] : undefined; + result.errors.push({ + type: 'error', + nodeId: node.id, + message: `Duplicate node ID: "${node.id}". Node at index ${i} (name: "${node.name}", type: "${node.type}") conflicts with node at index ${firstNodeIndex} (name: "${firstNode?.name || 'unknown'}", type: "${firstNode?.type || 'unknown'}"). Each node must have a unique ID. Generate a new UUID using crypto.randomUUID() - Example: {id: "${crypto_1.default.randomUUID()}", name: "${node.name}", type: "${node.type}", ...}` + }); + } + else { + nodeIds.add(node.id); + nodeIdToIndex.set(node.id, i); + } + } + const triggerNodes = workflow.nodes.filter(n => (0, node_type_utils_1.isTriggerNode)(n.type)); + result.statistics.triggerNodes = triggerNodes.length; + if (triggerNodes.length === 0 && workflow.nodes.filter(n => !n.disabled).length > 0) { + result.warnings.push({ + type: 'warning', + message: 'Workflow has no trigger nodes. It can only be executed manually.' + }); + } + } + async validateAllNodes(workflow, result, profile) { + for (const node of workflow.nodes) { + if (node.disabled || (0, node_classification_1.isNonExecutableNode)(node.type)) + continue; + try { + if (node.name && node.name.length > 255) { + result.warnings.push({ + type: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `Node name is very long (${node.name.length} characters). Consider using a shorter name for better readability.` + }); + } + if (!Array.isArray(node.position) || node.position.length !== 2) { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: 'Node position must be an array with exactly 2 numbers [x, y]' + }); + } + else { + const [x, y] = node.position; + if (typeof x !== 'number' || typeof y !== 'number' || + !isFinite(x) || !isFinite(y)) { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: 'Node position values must be finite numbers' + }); + } + } + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(node.type); + const nodeInfo = this.nodeRepository.getNode(normalizedType); + if (!nodeInfo) { + const suggestions = await this.similarityService.findSimilarNodes(node.type, 3); + let message = `Unknown node type: "${node.type}".`; + if (suggestions.length > 0) { + message += '\n\nDid you mean one of these?'; + for (const suggestion of suggestions) { + const confidence = Math.round(suggestion.confidence * 100); + message += `\n• ${suggestion.nodeType} (${confidence}% match)`; + if (suggestion.displayName) { + message += ` - ${suggestion.displayName}`; + } + message += `\n → ${suggestion.reason}`; + if (suggestion.confidence >= 0.9) { + message += ' (can be auto-fixed)'; + } + } + } + else { + message += ' No similar nodes found. Node types must include the package prefix (e.g., "n8n-nodes-base.webhook").'; + } + const error = { + type: 'error', + nodeId: node.id, + nodeName: node.name, + message + }; + if (suggestions.length > 0) { + error.suggestions = suggestions.map(s => ({ + nodeType: s.nodeType, + confidence: s.confidence, + reason: s.reason + })); + } + result.errors.push(error); + continue; + } + if (nodeInfo.isVersioned) { + if (!node.typeVersion) { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Missing required property 'typeVersion'. Add typeVersion: ${nodeInfo.version || 1}` + }); + } + else if (typeof node.typeVersion !== 'number' || node.typeVersion < 0) { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Invalid typeVersion: ${node.typeVersion}. Must be a non-negative number` + }); + } + else if (nodeInfo.version && node.typeVersion < nodeInfo.version) { + result.warnings.push({ + type: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `Outdated typeVersion: ${node.typeVersion}. Latest is ${nodeInfo.version}` + }); + } + else if (nodeInfo.version && node.typeVersion > nodeInfo.version) { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: `typeVersion ${node.typeVersion} exceeds maximum supported version ${nodeInfo.version}` + }); + } + } + if (normalizedType.startsWith('nodes-langchain.')) { + continue; + } + const nodeValidation = this.nodeValidator.validateWithMode(node.type, node.parameters, nodeInfo.properties || [], 'operation', profile); + nodeValidation.errors.forEach((error) => { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: typeof error === 'string' ? error : error.message || String(error) + }); + }); + nodeValidation.warnings.forEach((warning) => { + result.warnings.push({ + type: 'warning', + nodeId: node.id, + nodeName: node.name, + message: typeof warning === 'string' ? warning : warning.message || String(warning) + }); + }); + } + catch (error) { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Failed to validate node: ${error instanceof Error ? error.message : 'Unknown error'}` + }); + } + } + } + validateConnections(workflow, result, profile = 'runtime') { + const nodeMap = new Map(workflow.nodes.map(n => [n.name, n])); + const nodeIdMap = new Map(workflow.nodes.map(n => [n.id, n])); + for (const [sourceName, outputs] of Object.entries(workflow.connections)) { + const sourceNode = nodeMap.get(sourceName); + if (!sourceNode) { + const nodeById = nodeIdMap.get(sourceName); + if (nodeById) { + result.errors.push({ + type: 'error', + nodeId: nodeById.id, + nodeName: nodeById.name, + message: `Connection uses node ID '${sourceName}' instead of node name '${nodeById.name}'. In n8n, connections must use node names, not IDs.` + }); + } + else { + result.errors.push({ + type: 'error', + message: `Connection from non-existent node: "${sourceName}"` + }); + } + result.statistics.invalidConnections++; + continue; + } + if (outputs.main) { + this.validateConnectionOutputs(sourceName, outputs.main, nodeMap, nodeIdMap, result, 'main'); + } + if (outputs.error) { + this.validateConnectionOutputs(sourceName, outputs.error, nodeMap, nodeIdMap, result, 'error'); + } + if (outputs.ai_tool) { + this.validateConnectionOutputs(sourceName, outputs.ai_tool, nodeMap, nodeIdMap, result, 'ai_tool'); + } + } + const connectedNodes = new Set(); + Object.keys(workflow.connections).forEach(name => connectedNodes.add(name)); + Object.values(workflow.connections).forEach(outputs => { + if (outputs.main) { + outputs.main.flat().forEach(conn => { + if (conn) + connectedNodes.add(conn.node); + }); + } + if (outputs.error) { + outputs.error.flat().forEach(conn => { + if (conn) + connectedNodes.add(conn.node); + }); + } + if (outputs.ai_tool) { + outputs.ai_tool.flat().forEach(conn => { + if (conn) + connectedNodes.add(conn.node); + }); + } + }); + for (const node of workflow.nodes) { + if (node.disabled || (0, node_classification_1.isNonExecutableNode)(node.type)) + continue; + const isNodeTrigger = (0, node_type_utils_1.isTriggerNode)(node.type); + if (!connectedNodes.has(node.name) && !isNodeTrigger) { + result.warnings.push({ + type: 'warning', + nodeId: node.id, + nodeName: node.name, + message: 'Node is not connected to any other nodes' + }); + } + } + if (profile !== 'minimal' && this.hasCycle(workflow)) { + result.errors.push({ + type: 'error', + message: 'Workflow contains a cycle (infinite loop)' + }); + } + } + validateConnectionOutputs(sourceName, outputs, nodeMap, nodeIdMap, result, outputType) { + const sourceNode = nodeMap.get(sourceName); + if (outputType === 'main' && sourceNode) { + this.validateErrorOutputConfiguration(sourceName, sourceNode, outputs, nodeMap, result); + } + outputs.forEach((outputConnections, outputIndex) => { + if (!outputConnections) + return; + outputConnections.forEach(connection => { + if (connection.index < 0) { + result.errors.push({ + type: 'error', + message: `Invalid connection index ${connection.index} from "${sourceName}". Connection indices must be non-negative.` + }); + result.statistics.invalidConnections++; + return; + } + const isSplitInBatches = sourceNode && (sourceNode.type === 'n8n-nodes-base.splitInBatches' || + sourceNode.type === 'nodes-base.splitInBatches'); + if (isSplitInBatches) { + this.validateSplitInBatchesConnection(sourceNode, outputIndex, connection, nodeMap, result); + } + if (connection.node === sourceName) { + if (sourceNode && !isSplitInBatches) { + result.warnings.push({ + type: 'warning', + message: `Node "${sourceName}" has a self-referencing connection. This can cause infinite loops.` + }); + } + } + const targetNode = nodeMap.get(connection.node); + if (!targetNode) { + const nodeById = nodeIdMap.get(connection.node); + if (nodeById) { + result.errors.push({ + type: 'error', + nodeId: nodeById.id, + nodeName: nodeById.name, + message: `Connection target uses node ID '${connection.node}' instead of node name '${nodeById.name}' (from ${sourceName}). In n8n, connections must use node names, not IDs.` + }); + } + else { + result.errors.push({ + type: 'error', + message: `Connection to non-existent node: "${connection.node}" from "${sourceName}"` + }); + } + result.statistics.invalidConnections++; + } + else if (targetNode.disabled) { + result.warnings.push({ + type: 'warning', + message: `Connection to disabled node: "${connection.node}" from "${sourceName}"` + }); + } + else { + result.statistics.validConnections++; + if (outputType === 'ai_tool') { + this.validateAIToolConnection(sourceName, targetNode, result); + } + } + }); + }); + } + validateErrorOutputConfiguration(sourceName, sourceNode, outputs, nodeMap, result) { + const hasErrorOutputSetting = sourceNode.onError === 'continueErrorOutput'; + const hasErrorConnections = outputs.length > 1 && outputs[1] && outputs[1].length > 0; + if (hasErrorOutputSetting && !hasErrorConnections) { + result.errors.push({ + type: 'error', + nodeId: sourceNode.id, + nodeName: sourceNode.name, + message: `Node has onError: 'continueErrorOutput' but no error output connections in main[1]. Add error handler connections to main[1] or change onError to 'continueRegularOutput' or 'stopWorkflow'.` + }); + } + if (!hasErrorOutputSetting && hasErrorConnections) { + result.warnings.push({ + type: 'warning', + nodeId: sourceNode.id, + nodeName: sourceNode.name, + message: `Node has error output connections in main[1] but missing onError: 'continueErrorOutput'. Add this property to properly handle errors.` + }); + } + if (outputs.length >= 1 && outputs[0] && outputs[0].length > 1) { + const potentialErrorHandlers = outputs[0].filter(conn => { + const targetNode = nodeMap.get(conn.node); + if (!targetNode) + return false; + const nodeName = targetNode.name.toLowerCase(); + const nodeType = targetNode.type.toLowerCase(); + return nodeName.includes('error') || + nodeName.includes('fail') || + nodeName.includes('catch') || + nodeName.includes('exception') || + nodeType.includes('respondtowebhook') || + nodeType.includes('emailsend'); + }); + if (potentialErrorHandlers.length > 0) { + const errorHandlerNames = potentialErrorHandlers.map(conn => `"${conn.node}"`).join(', '); + result.errors.push({ + type: 'error', + nodeId: sourceNode.id, + nodeName: sourceNode.name, + message: `Incorrect error output configuration. Nodes ${errorHandlerNames} appear to be error handlers but are in main[0] (success output) along with other nodes.\n\n` + + `INCORRECT (current):\n` + + `"${sourceName}": {\n` + + ` "main": [\n` + + ` [ // main[0] has multiple nodes mixed together\n` + + outputs[0].map(conn => ` {"node": "${conn.node}", "type": "${conn.type}", "index": ${conn.index}}`).join(',\n') + '\n' + + ` ]\n` + + ` ]\n` + + `}\n\n` + + `CORRECT (should be):\n` + + `"${sourceName}": {\n` + + ` "main": [\n` + + ` [ // main[0] = success output\n` + + outputs[0].filter(conn => !potentialErrorHandlers.includes(conn)).map(conn => ` {"node": "${conn.node}", "type": "${conn.type}", "index": ${conn.index}}`).join(',\n') + '\n' + + ` ],\n` + + ` [ // main[1] = error output\n` + + potentialErrorHandlers.map(conn => ` {"node": "${conn.node}", "type": "${conn.type}", "index": ${conn.index}}`).join(',\n') + '\n' + + ` ]\n` + + ` ]\n` + + `}\n\n` + + `Also add: "onError": "continueErrorOutput" to the "${sourceName}" node.` + }); + } + } + } + validateAIToolConnection(sourceName, targetNode, result) { + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(targetNode.type); + let targetNodeInfo = this.nodeRepository.getNode(normalizedType); + if (!targetNodeInfo && normalizedType !== targetNode.type) { + targetNodeInfo = this.nodeRepository.getNode(targetNode.type); + } + if (targetNodeInfo && !targetNodeInfo.isAITool && targetNodeInfo.package !== 'n8n-nodes-base') { + result.warnings.push({ + type: 'warning', + nodeId: targetNode.id, + nodeName: targetNode.name, + message: `Community node "${targetNode.name}" is being used as an AI tool. Ensure N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true is set.` + }); + } + } + hasCycle(workflow) { + const visited = new Set(); + const recursionStack = new Set(); + const nodeTypeMap = new Map(); + workflow.nodes.forEach(node => { + if (!(0, node_classification_1.isNonExecutableNode)(node.type)) { + nodeTypeMap.set(node.name, node.type); + } + }); + const loopNodeTypes = [ + 'n8n-nodes-base.splitInBatches', + 'nodes-base.splitInBatches', + 'n8n-nodes-base.itemLists', + 'nodes-base.itemLists', + 'n8n-nodes-base.loop', + 'nodes-base.loop' + ]; + const hasCycleDFS = (nodeName, pathFromLoopNode = false) => { + visited.add(nodeName); + recursionStack.add(nodeName); + const connections = workflow.connections[nodeName]; + if (connections) { + const allTargets = []; + if (connections.main) { + connections.main.flat().forEach(conn => { + if (conn) + allTargets.push(conn.node); + }); + } + if (connections.error) { + connections.error.flat().forEach(conn => { + if (conn) + allTargets.push(conn.node); + }); + } + if (connections.ai_tool) { + connections.ai_tool.flat().forEach(conn => { + if (conn) + allTargets.push(conn.node); + }); + } + const currentNodeType = nodeTypeMap.get(nodeName); + const isLoopNode = loopNodeTypes.includes(currentNodeType || ''); + for (const target of allTargets) { + if (!visited.has(target)) { + if (hasCycleDFS(target, pathFromLoopNode || isLoopNode)) + return true; + } + else if (recursionStack.has(target)) { + const targetNodeType = nodeTypeMap.get(target); + const isTargetLoopNode = loopNodeTypes.includes(targetNodeType || ''); + if (isTargetLoopNode || pathFromLoopNode || isLoopNode) { + continue; + } + return true; + } + } + } + recursionStack.delete(nodeName); + return false; + }; + for (const node of workflow.nodes) { + if (!(0, node_classification_1.isNonExecutableNode)(node.type) && !visited.has(node.name)) { + if (hasCycleDFS(node.name)) + return true; + } + } + return false; + } + validateExpressions(workflow, result, profile = 'runtime') { + const nodeNames = workflow.nodes.map(n => n.name); + for (const node of workflow.nodes) { + if (node.disabled || (0, node_classification_1.isNonExecutableNode)(node.type)) + continue; + const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(node.type); + if (normalizedType.startsWith('nodes-langchain.')) { + continue; + } + const context = { + availableNodes: nodeNames.filter(n => n !== node.name), + currentNodeName: node.name, + hasInputData: this.nodeHasInput(node.name, workflow), + isInLoop: false + }; + const exprValidation = expression_validator_1.ExpressionValidator.validateNodeExpressions(node.parameters, context); + const expressionCount = this.countExpressionsInObject(node.parameters); + result.statistics.expressionsValidated += expressionCount; + exprValidation.errors.forEach(error => { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Expression error: ${error}` + }); + }); + exprValidation.warnings.forEach(warning => { + result.warnings.push({ + type: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `Expression warning: ${warning}` + }); + }); + const formatContext = { + nodeType: node.type, + nodeName: node.name, + nodeId: node.id + }; + const formatIssues = expression_format_validator_1.ExpressionFormatValidator.validateNodeParameters(node.parameters, formatContext); + formatIssues.forEach(issue => { + const formattedMessage = expression_format_validator_1.ExpressionFormatValidator.formatErrorMessage(issue, formatContext); + if (issue.severity === 'error') { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: formattedMessage + }); + } + else { + result.warnings.push({ + type: 'warning', + nodeId: node.id, + nodeName: node.name, + message: formattedMessage + }); + } + }); + } + } + countExpressionsInObject(obj) { + let count = 0; + if (typeof obj === 'string') { + const matches = obj.match(/\{\{[\s\S]+?\}\}/g); + if (matches) { + count += matches.length; + } + } + else if (Array.isArray(obj)) { + for (const item of obj) { + count += this.countExpressionsInObject(item); + } + } + else if (obj && typeof obj === 'object') { + for (const value of Object.values(obj)) { + count += this.countExpressionsInObject(value); + } + } + return count; + } + nodeHasInput(nodeName, workflow) { + for (const [sourceName, outputs] of Object.entries(workflow.connections)) { + if (outputs.main) { + for (const outputConnections of outputs.main) { + if (outputConnections?.some(conn => conn.node === nodeName)) { + return true; + } + } + } + } + return false; + } + checkWorkflowPatterns(workflow, result, profile = 'runtime') { + const hasErrorHandling = Object.values(workflow.connections).some(outputs => outputs.main && outputs.main.length > 1 && outputs.main[1] && outputs.main[1].length > 0); + if (!hasErrorHandling && workflow.nodes.length > 3 && profile !== 'minimal') { + result.warnings.push({ + type: 'warning', + message: 'Consider adding error handling to your workflow' + }); + } + for (const node of workflow.nodes) { + if (!(0, node_classification_1.isNonExecutableNode)(node.type)) { + this.checkNodeErrorHandling(node, workflow, result); + } + } + const linearChainLength = this.getLongestLinearChain(workflow); + if (linearChainLength > 10) { + result.warnings.push({ + type: 'warning', + message: `Long linear chain detected (${linearChainLength} nodes). Consider breaking into sub-workflows.` + }); + } + this.generateErrorHandlingSuggestions(workflow, result); + for (const node of workflow.nodes) { + if (node.credentials && Object.keys(node.credentials).length > 0) { + for (const [credType, credConfig] of Object.entries(node.credentials)) { + if (!credConfig || (typeof credConfig === 'object' && !('id' in credConfig))) { + result.warnings.push({ + type: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `Missing credentials configuration for ${credType}` + }); + } + } + } + } + const aiAgentNodes = workflow.nodes.filter(n => n.type.toLowerCase().includes('agent') || + n.type.includes('langchain.agent')); + if (aiAgentNodes.length > 0) { + for (const agentNode of aiAgentNodes) { + const hasToolConnected = Object.values(workflow.connections).some(sourceOutputs => { + const aiToolConnections = sourceOutputs.ai_tool; + if (!aiToolConnections) + return false; + return aiToolConnections.flat().some(conn => conn && conn.node === agentNode.name); + }); + if (!hasToolConnected) { + result.warnings.push({ + type: 'warning', + nodeId: agentNode.id, + nodeName: agentNode.name, + message: 'AI Agent has no tools connected. Consider adding tools to enhance agent capabilities.' + }); + } + } + const hasAIToolConnections = Object.values(workflow.connections).some(outputs => outputs.ai_tool && outputs.ai_tool.length > 0); + if (hasAIToolConnections) { + result.suggestions.push('For community nodes used as AI tools, ensure N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true is set'); + } + } + } + getLongestLinearChain(workflow) { + const memo = new Map(); + const visiting = new Set(); + const getChainLength = (nodeName) => { + if (visiting.has(nodeName)) + return 0; + if (memo.has(nodeName)) + return memo.get(nodeName); + visiting.add(nodeName); + let maxLength = 0; + const connections = workflow.connections[nodeName]; + if (connections?.main) { + for (const outputConnections of connections.main) { + if (outputConnections) { + for (const conn of outputConnections) { + const length = getChainLength(conn.node); + maxLength = Math.max(maxLength, length); + } + } + } + } + visiting.delete(nodeName); + const result = maxLength + 1; + memo.set(nodeName, result); + return result; + }; + let maxChain = 0; + for (const node of workflow.nodes) { + if (!this.nodeHasInput(node.name, workflow)) { + maxChain = Math.max(maxChain, getChainLength(node.name)); + } + } + return maxChain; + } + generateSuggestions(workflow, result) { + if (result.statistics.triggerNodes === 0) { + result.suggestions.push('Add a trigger node (e.g., Webhook, Schedule Trigger) to automate workflow execution'); + } + const hasConnectionErrors = result.errors.some(e => typeof e.message === 'string' && (e.message.includes('connection') || + e.message.includes('Connection') || + e.message.includes('Multi-node workflow has no connections'))); + if (hasConnectionErrors) { + result.suggestions.push('Example connection structure: connections: { "Manual Trigger": { "main": [[{ "node": "Set", "type": "main", "index": 0 }]] } }'); + result.suggestions.push('Remember: Use node NAMES (not IDs) in connections. The name is what you see in the UI, not the node type.'); + } + if (!Object.values(workflow.connections).some(o => o.error)) { + result.suggestions.push('Add error handling using the error output of nodes or an Error Trigger node'); + } + if (workflow.nodes.length > 20) { + result.suggestions.push('Consider breaking this workflow into smaller sub-workflows for better maintainability'); + } + const complexExpressionNodes = workflow.nodes.filter(node => { + const jsonString = JSON.stringify(node.parameters); + const expressionCount = (jsonString.match(/\{\{/g) || []).length; + return expressionCount > 5; + }); + if (complexExpressionNodes.length > 0) { + result.suggestions.push('Consider using a Code node for complex data transformations instead of multiple expressions'); + } + if (workflow.nodes.length === 1 && Object.keys(workflow.connections).length === 0) { + result.suggestions.push('A minimal workflow needs: 1) A trigger node (e.g., Manual Trigger), 2) An action node (e.g., Set, HTTP Request), 3) A connection between them'); + } + } + checkNodeErrorHandling(node, workflow, result) { + if (node.disabled === true) + return; + const errorProneNodeTypes = [ + 'httprequest', + 'webhook', + 'emailsend', + 'slack', + 'discord', + 'telegram', + 'postgres', + 'mysql', + 'mongodb', + 'redis', + 'github', + 'gitlab', + 'jira', + 'salesforce', + 'hubspot', + 'airtable', + 'googlesheets', + 'googledrive', + 'dropbox', + 's3', + 'ftp', + 'ssh', + 'mqtt', + 'kafka', + 'rabbitmq', + 'graphql', + 'openai', + 'anthropic' + ]; + const normalizedType = node.type.toLowerCase(); + const isErrorProne = errorProneNodeTypes.some(type => normalizedType.includes(type)); + const nodeLevelProps = [ + 'onError', 'continueOnFail', 'retryOnFail', 'maxTries', 'waitBetweenTries', 'alwaysOutputData', + 'executeOnce', 'disabled', 'notes', 'notesInFlow', 'credentials' + ]; + const misplacedProps = []; + if (node.parameters) { + for (const prop of nodeLevelProps) { + if (node.parameters[prop] !== undefined) { + misplacedProps.push(prop); + } + } + } + if (misplacedProps.length > 0) { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Node-level properties ${misplacedProps.join(', ')} are in the wrong location. They must be at the node level, not inside parameters.`, + details: { + fix: `Move these properties from node.parameters to the node level. Example:\n` + + `{\n` + + ` "name": "${node.name}",\n` + + ` "type": "${node.type}",\n` + + ` "parameters": { /* operation-specific params */ },\n` + + ` "onError": "continueErrorOutput", // ✅ Correct location\n` + + ` "retryOnFail": true, // ✅ Correct location\n` + + ` "executeOnce": true, // ✅ Correct location\n` + + ` "disabled": false, // ✅ Correct location\n` + + ` "credentials": { /* ... */ } // ✅ Correct location\n` + + `}` + } + }); + } + if (node.onError !== undefined) { + const validOnErrorValues = ['continueRegularOutput', 'continueErrorOutput', 'stopWorkflow']; + if (!validOnErrorValues.includes(node.onError)) { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: `Invalid onError value: "${node.onError}". Must be one of: ${validOnErrorValues.join(', ')}` + }); + } + } + if (node.continueOnFail !== undefined) { + if (typeof node.continueOnFail !== 'boolean') { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: 'continueOnFail must be a boolean value' + }); + } + else if (node.continueOnFail === true) { + result.warnings.push({ + type: 'warning', + nodeId: node.id, + nodeName: node.name, + message: 'Using deprecated "continueOnFail: true". Use "onError: \'continueRegularOutput\'" instead for better control and UI compatibility.' + }); + } + } + if (node.continueOnFail !== undefined && node.onError !== undefined) { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: 'Cannot use both "continueOnFail" and "onError" properties. Use only "onError" for modern workflows.' + }); + } + if (node.retryOnFail !== undefined) { + if (typeof node.retryOnFail !== 'boolean') { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: 'retryOnFail must be a boolean value' + }); + } + if (node.retryOnFail === true) { + if (node.maxTries !== undefined) { + if (typeof node.maxTries !== 'number' || node.maxTries < 1) { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: 'maxTries must be a positive number when retryOnFail is enabled' + }); + } + else if (node.maxTries > 10) { + result.warnings.push({ + type: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `maxTries is set to ${node.maxTries}. Consider if this many retries is necessary.` + }); + } + } + else { + result.warnings.push({ + type: 'warning', + nodeId: node.id, + nodeName: node.name, + message: 'retryOnFail is enabled but maxTries is not specified. Default is 3 attempts.' + }); + } + if (node.waitBetweenTries !== undefined) { + if (typeof node.waitBetweenTries !== 'number' || node.waitBetweenTries < 0) { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: 'waitBetweenTries must be a non-negative number (milliseconds)' + }); + } + else if (node.waitBetweenTries > 300000) { + result.warnings.push({ + type: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `waitBetweenTries is set to ${node.waitBetweenTries}ms (${(node.waitBetweenTries / 1000).toFixed(1)}s). This seems excessive.` + }); + } + } + } + } + if (node.alwaysOutputData !== undefined && typeof node.alwaysOutputData !== 'boolean') { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: 'alwaysOutputData must be a boolean value' + }); + } + const hasErrorHandling = node.onError || node.continueOnFail || node.retryOnFail; + if (isErrorProne && !hasErrorHandling) { + const nodeTypeSimple = normalizedType.split('.').pop() || normalizedType; + if (normalizedType.includes('httprequest')) { + result.warnings.push({ + type: 'warning', + nodeId: node.id, + nodeName: node.name, + message: 'HTTP Request node without error handling. Consider adding "onError: \'continueRegularOutput\'" for non-critical requests or "retryOnFail: true" for transient failures.' + }); + } + else if (normalizedType.includes('webhook')) { + this.checkWebhookErrorHandling(node, normalizedType, result); + } + else if (errorProneNodeTypes.some(db => normalizedType.includes(db) && ['postgres', 'mysql', 'mongodb'].includes(db))) { + result.warnings.push({ + type: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `Database operation without error handling. Consider adding "retryOnFail: true" for connection issues or "onError: \'continueRegularOutput\'" for non-critical queries.` + }); + } + else { + result.warnings.push({ + type: 'warning', + nodeId: node.id, + nodeName: node.name, + message: `${nodeTypeSimple} node without error handling. Consider using "onError" property for better error management.` + }); + } + } + if (node.continueOnFail && node.retryOnFail) { + result.warnings.push({ + type: 'warning', + nodeId: node.id, + nodeName: node.name, + message: 'Both continueOnFail and retryOnFail are enabled. The node will retry first, then continue on failure.' + }); + } + if (node.executeOnce !== undefined && typeof node.executeOnce !== 'boolean') { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: 'executeOnce must be a boolean value' + }); + } + if (node.disabled !== undefined && typeof node.disabled !== 'boolean') { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: 'disabled must be a boolean value' + }); + } + if (node.notesInFlow !== undefined && typeof node.notesInFlow !== 'boolean') { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: 'notesInFlow must be a boolean value' + }); + } + if (node.notes !== undefined && typeof node.notes !== 'string') { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: 'notes must be a string value' + }); + } + if (node.executeOnce === true) { + result.warnings.push({ + type: 'warning', + nodeId: node.id, + nodeName: node.name, + message: 'executeOnce is enabled. This node will execute only once regardless of input items.' + }); + } + if ((node.continueOnFail || node.retryOnFail) && !node.alwaysOutputData) { + if (normalizedType.includes('httprequest') || normalizedType.includes('webhook')) { + result.suggestions.push(`Consider enabling alwaysOutputData on "${node.name}" to capture error responses for debugging`); + } + } + } + checkWebhookErrorHandling(node, normalizedType, result) { + if (normalizedType.includes('respondtowebhook')) { + return; + } + if (node.parameters?.responseMode === 'responseNode') { + if (!node.onError && !node.continueOnFail) { + result.errors.push({ + type: 'error', + nodeId: node.id, + nodeName: node.name, + message: 'responseNode mode requires onError: "continueRegularOutput"' + }); + } + return; + } + result.warnings.push({ + type: 'warning', + nodeId: node.id, + nodeName: node.name, + message: 'Webhook node without error handling. Consider adding "onError: \'continueRegularOutput\'" to prevent workflow failures from blocking webhook responses.' + }); + } + generateErrorHandlingSuggestions(workflow, result) { + const nodesWithoutErrorHandling = workflow.nodes.filter(n => !n.disabled && !n.onError && !n.continueOnFail && !n.retryOnFail).length; + if (nodesWithoutErrorHandling > 5 && workflow.nodes.length > 5) { + result.suggestions.push('Most nodes lack error handling. Use "onError" property for modern error handling: "continueRegularOutput" (continue on error), "continueErrorOutput" (use error output), or "stopWorkflow" (stop execution).'); + } + const nodesWithDeprecatedErrorHandling = workflow.nodes.filter(n => !n.disabled && n.continueOnFail === true).length; + if (nodesWithDeprecatedErrorHandling > 0) { + result.suggestions.push('Replace "continueOnFail: true" with "onError: \'continueRegularOutput\'" for better UI compatibility and control.'); + } + } + validateSplitInBatchesConnection(sourceNode, outputIndex, connection, nodeMap, result) { + const targetNode = nodeMap.get(connection.node); + if (!targetNode) + return; + if (outputIndex === 0) { + const targetType = targetNode.type.toLowerCase(); + const targetName = targetNode.name.toLowerCase(); + if (targetType.includes('function') || + targetType.includes('code') || + targetType.includes('item') || + targetName.includes('process') || + targetName.includes('transform') || + targetName.includes('handle')) { + const hasLoopBack = this.checkForLoopBack(targetNode.name, sourceNode.name, nodeMap); + if (hasLoopBack) { + result.errors.push({ + type: 'error', + nodeId: sourceNode.id, + nodeName: sourceNode.name, + message: `SplitInBatches outputs appear reversed! Node "${targetNode.name}" is connected to output 0 ("done") but connects back to the loop. It should be connected to output 1 ("loop") instead. Remember: Output 0 = "done" (post-loop), Output 1 = "loop" (inside loop).` + }); + } + else { + result.warnings.push({ + type: 'warning', + nodeId: sourceNode.id, + nodeName: sourceNode.name, + message: `Node "${targetNode.name}" is connected to the "done" output (index 0) but appears to be a processing node. Consider connecting it to the "loop" output (index 1) if it should process items inside the loop.` + }); + } + } + } + else if (outputIndex === 1) { + const targetType = targetNode.type.toLowerCase(); + const targetName = targetNode.name.toLowerCase(); + if (targetType.includes('aggregate') || + targetType.includes('merge') || + targetType.includes('email') || + targetType.includes('slack') || + targetName.includes('final') || + targetName.includes('complete') || + targetName.includes('summary') || + targetName.includes('report')) { + result.warnings.push({ + type: 'warning', + nodeId: sourceNode.id, + nodeName: sourceNode.name, + message: `Node "${targetNode.name}" is connected to the "loop" output (index 1) but appears to be a post-processing node. Consider connecting it to the "done" output (index 0) if it should run after all iterations complete.` + }); + } + const hasLoopBack = this.checkForLoopBack(targetNode.name, sourceNode.name, nodeMap); + if (!hasLoopBack) { + result.warnings.push({ + type: 'warning', + nodeId: sourceNode.id, + nodeName: sourceNode.name, + message: `The "loop" output connects to "${targetNode.name}" but doesn't connect back to the SplitInBatches node. The last node in the loop should connect back to complete the iteration.` + }); + } + } + } + checkForLoopBack(startNode, targetNode, nodeMap, visited = new Set(), maxDepth = 50) { + if (maxDepth <= 0) + return false; + if (visited.has(startNode)) + return false; + visited.add(startNode); + const node = nodeMap.get(startNode); + if (!node) + return false; + const connections = this.currentWorkflow?.connections[startNode]; + if (!connections) + return false; + for (const [outputType, outputs] of Object.entries(connections)) { + if (!Array.isArray(outputs)) + continue; + for (const outputConnections of outputs) { + if (!Array.isArray(outputConnections)) + continue; + for (const conn of outputConnections) { + if (conn.node === targetNode) { + return true; + } + if (this.checkForLoopBack(conn.node, targetNode, nodeMap, visited, maxDepth - 1)) { + return true; + } + } + } + } + return false; + } + addErrorRecoverySuggestions(result) { + const errorTypes = { + nodeType: result.errors.filter(e => e.message.includes('node type') || e.message.includes('Node type')), + connection: result.errors.filter(e => e.message.includes('connection') || e.message.includes('Connection')), + structure: result.errors.filter(e => e.message.includes('structure') || e.message.includes('nodes must be')), + configuration: result.errors.filter(e => e.message.includes('property') || e.message.includes('field')), + typeVersion: result.errors.filter(e => e.message.includes('typeVersion')) + }; + if (errorTypes.nodeType.length > 0) { + result.suggestions.unshift('🔧 RECOVERY: Invalid node types detected. Use these patterns:', ' • For core nodes: "n8n-nodes-base.nodeName" (e.g., "n8n-nodes-base.webhook")', ' • For AI nodes: "@n8n/n8n-nodes-langchain.nodeName"', ' • Never use just the node name without package prefix'); + } + if (errorTypes.connection.length > 0) { + result.suggestions.unshift('🔧 RECOVERY: Connection errors detected. Fix with:', ' • Use node NAMES in connections, not IDs or types', ' • Structure: { "Source Node Name": { "main": [[{ "node": "Target Node Name", "type": "main", "index": 0 }]] } }', ' • Ensure all referenced nodes exist in the workflow'); + } + if (errorTypes.structure.length > 0) { + result.suggestions.unshift('🔧 RECOVERY: Workflow structure errors. Fix with:', ' • Ensure "nodes" is an array: "nodes": [...]', ' • Ensure "connections" is an object: "connections": {...}', ' • Add at least one node to create a valid workflow'); + } + if (errorTypes.configuration.length > 0) { + result.suggestions.unshift('🔧 RECOVERY: Node configuration errors. Fix with:', ' • Check required fields using validate_node_minimal first', ' • Use get_node_essentials to see what fields are needed', ' • Ensure operation-specific fields match the node\'s requirements'); + } + if (errorTypes.typeVersion.length > 0) { + result.suggestions.unshift('🔧 RECOVERY: TypeVersion errors. Fix with:', ' • Add "typeVersion": 1 (or latest version) to each node', ' • Use get_node_info to check the correct version for each node type'); + } + if (result.errors.length > 3) { + result.suggestions.push('📋 SUGGESTED WORKFLOW: Too many errors detected. Try this approach:', ' 1. Fix structural issues first (nodes array, connections object)', ' 2. Validate node types and fix invalid ones', ' 3. Add required typeVersion to all nodes', ' 4. Test connections step by step', ' 5. Use validate_node_minimal on individual nodes to verify configuration'); + } + } +} +exports.WorkflowValidator = WorkflowValidator; +//# sourceMappingURL=workflow-validator.js.map \ No newline at end of file diff --git a/dist/services/workflow-validator.js.map b/dist/services/workflow-validator.js.map new file mode 100644 index 0000000..fc64913 --- /dev/null +++ b/dist/services/workflow-validator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"workflow-validator.js","sourceRoot":"","sources":["../../src/services/workflow-validator.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/workflow-versioning-service.d.ts b/dist/services/workflow-versioning-service.d.ts new file mode 100644 index 0000000..59b22b7 --- /dev/null +++ b/dist/services/workflow-versioning-service.d.ts @@ -0,0 +1,102 @@ +import { NodeRepository } from '../database/node-repository'; +import { N8nApiClient } from './n8n-api-client'; +export interface WorkflowVersion { + id: number; + workflowId: string; + versionNumber: number; + workflowName: string; + workflowSnapshot: any; + trigger: 'partial_update' | 'full_update' | 'autofix'; + operations?: any[]; + fixTypes?: string[]; + metadata?: any; + createdAt: string; +} +export interface VersionInfo { + id: number; + workflowId: string; + versionNumber: number; + workflowName: string; + trigger: string; + operationCount?: number; + fixTypesApplied?: string[]; + createdAt: string; + size: number; +} +export interface RestoreResult { + success: boolean; + message: string; + workflowId: string; + fromVersion?: number; + toVersionId: number; + backupCreated: boolean; + backupVersionId?: number; + validationErrors?: string[]; +} +export interface BackupResult { + versionId: number; + versionNumber: number; + pruned: number; + message: string; +} +export interface StorageStats { + totalVersions: number; + totalSize: number; + totalSizeFormatted: string; + byWorkflow: WorkflowStorageInfo[]; +} +export interface WorkflowStorageInfo { + workflowId: string; + workflowName: string; + versionCount: number; + totalSize: number; + totalSizeFormatted: string; + lastBackup: string; +} +export interface VersionDiff { + versionId1: number; + versionId2: number; + version1Number: number; + version2Number: number; + addedNodes: string[]; + removedNodes: string[]; + modifiedNodes: string[]; + connectionChanges: number; + settingChanges: any; +} +export declare class WorkflowVersioningService { + private nodeRepository; + private apiClient?; + private readonly DEFAULT_MAX_VERSIONS; + constructor(nodeRepository: NodeRepository, apiClient?: N8nApiClient | undefined); + createBackup(workflowId: string, workflow: any, context: { + trigger: 'partial_update' | 'full_update' | 'autofix'; + operations?: any[]; + fixTypes?: string[]; + metadata?: any; + }): Promise; + getVersionHistory(workflowId: string, limit?: number): Promise; + getVersion(versionId: number): Promise; + restoreVersion(workflowId: string, versionId?: number, validateBefore?: boolean): Promise; + deleteVersion(versionId: number): Promise<{ + success: boolean; + message: string; + }>; + deleteAllVersions(workflowId: string): Promise<{ + deleted: number; + message: string; + }>; + pruneVersions(workflowId: string, maxVersions?: number): Promise<{ + pruned: number; + remaining: number; + }>; + truncateAllVersions(confirm: boolean): Promise<{ + deleted: number; + message: string; + }>; + getStorageStats(): Promise; + compareVersions(versionId1: number, versionId2: number): Promise; + private formatBytes; + private diffObjects; +} +//# sourceMappingURL=workflow-versioning-service.d.ts.map \ No newline at end of file diff --git a/dist/services/workflow-versioning-service.d.ts.map b/dist/services/workflow-versioning-service.d.ts.map new file mode 100644 index 0000000..0bb7f28 --- /dev/null +++ b/dist/services/workflow-versioning-service.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"workflow-versioning-service.d.ts","sourceRoot":"","sources":["../../src/services/workflow-versioning-service.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAIhD,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,GAAG,CAAC;IACtB,OAAO,EAAE,gBAAgB,GAAG,aAAa,GAAG,SAAS,CAAC;IACtD,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,mBAAmB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,GAAG,CAAC;CACrB;AAKD,qBAAa,yBAAyB;IAIlC,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,SAAS,CAAC;IAJpB,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAM;gBAGjC,cAAc,EAAE,cAAc,EAC9B,SAAS,CAAC,EAAE,YAAY,YAAA;IAO5B,YAAY,CAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,GAAG,EACb,OAAO,EAAE;QACP,OAAO,EAAE,gBAAgB,GAAG,aAAa,GAAG,SAAS,CAAC;QACtD,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,QAAQ,CAAC,EAAE,GAAG,CAAC;KAChB,GACA,OAAO,CAAC,YAAY,CAAC;IAoClB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAmBjF,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAQ9D,cAAc,CAClB,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,EAClB,cAAc,GAAE,OAAc,GAC7B,OAAO,CAAC,aAAa,CAAC;IA2GnB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAqBhF,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAqBpF,aAAa,CACjB,UAAU,EAAE,MAAM,EAClB,WAAW,GAAE,MAAW,GACvB,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAW3C,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAmBpF,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC;IAqBxC,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAqDnF,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,WAAW;CAgBpB"} \ No newline at end of file diff --git a/dist/services/workflow-versioning-service.js b/dist/services/workflow-versioning-service.js new file mode 100644 index 0000000..93351b9 --- /dev/null +++ b/dist/services/workflow-versioning-service.js @@ -0,0 +1,264 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.WorkflowVersioningService = void 0; +const workflow_validator_1 = require("./workflow-validator"); +const enhanced_config_validator_1 = require("./enhanced-config-validator"); +class WorkflowVersioningService { + constructor(nodeRepository, apiClient) { + this.nodeRepository = nodeRepository; + this.apiClient = apiClient; + this.DEFAULT_MAX_VERSIONS = 10; + } + async createBackup(workflowId, workflow, context) { + const versions = this.nodeRepository.getWorkflowVersions(workflowId, 1); + const nextVersion = versions.length > 0 ? versions[0].versionNumber + 1 : 1; + const versionId = this.nodeRepository.createWorkflowVersion({ + workflowId, + versionNumber: nextVersion, + workflowName: workflow.name || 'Unnamed Workflow', + workflowSnapshot: workflow, + trigger: context.trigger, + operations: context.operations, + fixTypes: context.fixTypes, + metadata: context.metadata + }); + const pruned = this.nodeRepository.pruneWorkflowVersions(workflowId, this.DEFAULT_MAX_VERSIONS); + return { + versionId, + versionNumber: nextVersion, + pruned, + message: pruned > 0 + ? `Backup created (version ${nextVersion}), pruned ${pruned} old version(s)` + : `Backup created (version ${nextVersion})` + }; + } + async getVersionHistory(workflowId, limit = 10) { + const versions = this.nodeRepository.getWorkflowVersions(workflowId, limit); + return versions.map(v => ({ + id: v.id, + workflowId: v.workflowId, + versionNumber: v.versionNumber, + workflowName: v.workflowName, + trigger: v.trigger, + operationCount: v.operations ? v.operations.length : undefined, + fixTypesApplied: v.fixTypes || undefined, + createdAt: v.createdAt, + size: JSON.stringify(v.workflowSnapshot).length + })); + } + async getVersion(versionId) { + return this.nodeRepository.getWorkflowVersion(versionId); + } + async restoreVersion(workflowId, versionId, validateBefore = true) { + if (!this.apiClient) { + return { + success: false, + message: 'API client not configured - cannot restore workflow', + workflowId, + toVersionId: versionId || 0, + backupCreated: false + }; + } + let versionToRestore = null; + if (versionId) { + versionToRestore = this.nodeRepository.getWorkflowVersion(versionId); + } + else { + versionToRestore = this.nodeRepository.getLatestWorkflowVersion(workflowId); + } + if (!versionToRestore) { + return { + success: false, + message: versionId + ? `Version ${versionId} not found` + : `No backup versions found for workflow ${workflowId}`, + workflowId, + toVersionId: versionId || 0, + backupCreated: false + }; + } + if (validateBefore) { + const validator = new workflow_validator_1.WorkflowValidator(this.nodeRepository, enhanced_config_validator_1.EnhancedConfigValidator); + const validationResult = await validator.validateWorkflow(versionToRestore.workflowSnapshot, { + validateNodes: true, + validateConnections: true, + validateExpressions: false, + profile: 'runtime' + }); + if (validationResult.errors.length > 0) { + return { + success: false, + message: `Cannot restore - version ${versionToRestore.versionNumber} has validation errors`, + workflowId, + toVersionId: versionToRestore.id, + backupCreated: false, + validationErrors: validationResult.errors.map(e => e.message || 'Unknown error') + }; + } + } + let backupResult; + try { + const currentWorkflow = await this.apiClient.getWorkflow(workflowId); + backupResult = await this.createBackup(workflowId, currentWorkflow, { + trigger: 'partial_update', + metadata: { + reason: 'Backup before rollback', + restoringToVersion: versionToRestore.versionNumber + } + }); + } + catch (error) { + return { + success: false, + message: `Failed to create backup before restore: ${error.message}`, + workflowId, + toVersionId: versionToRestore.id, + backupCreated: false + }; + } + try { + await this.apiClient.updateWorkflow(workflowId, versionToRestore.workflowSnapshot); + return { + success: true, + message: `Successfully restored workflow to version ${versionToRestore.versionNumber}`, + workflowId, + fromVersion: backupResult.versionNumber, + toVersionId: versionToRestore.id, + backupCreated: true, + backupVersionId: backupResult.versionId + }; + } + catch (error) { + return { + success: false, + message: `Failed to restore workflow: ${error.message}`, + workflowId, + toVersionId: versionToRestore.id, + backupCreated: true, + backupVersionId: backupResult.versionId + }; + } + } + async deleteVersion(versionId) { + const version = this.nodeRepository.getWorkflowVersion(versionId); + if (!version) { + return { + success: false, + message: `Version ${versionId} not found` + }; + } + this.nodeRepository.deleteWorkflowVersion(versionId); + return { + success: true, + message: `Deleted version ${version.versionNumber} for workflow ${version.workflowId}` + }; + } + async deleteAllVersions(workflowId) { + const count = this.nodeRepository.getWorkflowVersionCount(workflowId); + if (count === 0) { + return { + deleted: 0, + message: `No versions found for workflow ${workflowId}` + }; + } + const deleted = this.nodeRepository.deleteWorkflowVersionsByWorkflowId(workflowId); + return { + deleted, + message: `Deleted ${deleted} version(s) for workflow ${workflowId}` + }; + } + async pruneVersions(workflowId, maxVersions = 10) { + const pruned = this.nodeRepository.pruneWorkflowVersions(workflowId, maxVersions); + const remaining = this.nodeRepository.getWorkflowVersionCount(workflowId); + return { pruned, remaining }; + } + async truncateAllVersions(confirm) { + if (!confirm) { + return { + deleted: 0, + message: 'Truncate operation not confirmed - no action taken' + }; + } + const deleted = this.nodeRepository.truncateWorkflowVersions(); + return { + deleted, + message: `Truncated workflow_versions table - deleted ${deleted} version(s)` + }; + } + async getStorageStats() { + const stats = this.nodeRepository.getVersionStorageStats(); + return { + totalVersions: stats.totalVersions, + totalSize: stats.totalSize, + totalSizeFormatted: this.formatBytes(stats.totalSize), + byWorkflow: stats.byWorkflow.map((w) => ({ + workflowId: w.workflowId, + workflowName: w.workflowName, + versionCount: w.versionCount, + totalSize: w.totalSize, + totalSizeFormatted: this.formatBytes(w.totalSize), + lastBackup: w.lastBackup + })) + }; + } + async compareVersions(versionId1, versionId2) { + const v1 = this.nodeRepository.getWorkflowVersion(versionId1); + const v2 = this.nodeRepository.getWorkflowVersion(versionId2); + if (!v1 || !v2) { + throw new Error(`One or both versions not found: ${versionId1}, ${versionId2}`); + } + const nodes1 = new Set(v1.workflowSnapshot.nodes?.map((n) => n.id) || []); + const nodes2 = new Set(v2.workflowSnapshot.nodes?.map((n) => n.id) || []); + const addedNodes = [...nodes2].filter(id => !nodes1.has(id)); + const removedNodes = [...nodes1].filter(id => !nodes2.has(id)); + const commonNodes = [...nodes1].filter(id => nodes2.has(id)); + const modifiedNodes = []; + for (const nodeId of commonNodes) { + const node1 = v1.workflowSnapshot.nodes?.find((n) => n.id === nodeId); + const node2 = v2.workflowSnapshot.nodes?.find((n) => n.id === nodeId); + if (JSON.stringify(node1) !== JSON.stringify(node2)) { + modifiedNodes.push(nodeId); + } + } + const conn1Str = JSON.stringify(v1.workflowSnapshot.connections || {}); + const conn2Str = JSON.stringify(v2.workflowSnapshot.connections || {}); + const connectionChanges = conn1Str !== conn2Str ? 1 : 0; + const settings1 = v1.workflowSnapshot.settings || {}; + const settings2 = v2.workflowSnapshot.settings || {}; + const settingChanges = this.diffObjects(settings1, settings2); + return { + versionId1, + versionId2, + version1Number: v1.versionNumber, + version2Number: v2.versionNumber, + addedNodes, + removedNodes, + modifiedNodes, + connectionChanges, + settingChanges + }; + } + formatBytes(bytes) { + if (bytes === 0) + return '0 Bytes'; + const k = 1024; + const sizes = ['Bytes', 'KB', 'MB', 'GB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i]; + } + diffObjects(obj1, obj2) { + const changes = {}; + const allKeys = new Set([...Object.keys(obj1), ...Object.keys(obj2)]); + for (const key of allKeys) { + if (JSON.stringify(obj1[key]) !== JSON.stringify(obj2[key])) { + changes[key] = { + before: obj1[key], + after: obj2[key] + }; + } + } + return changes; + } +} +exports.WorkflowVersioningService = WorkflowVersioningService; +//# sourceMappingURL=workflow-versioning-service.js.map \ No newline at end of file diff --git a/dist/services/workflow-versioning-service.js.map b/dist/services/workflow-versioning-service.js.map new file mode 100644 index 0000000..5ad3bbb --- /dev/null +++ b/dist/services/workflow-versioning-service.js.map @@ -0,0 +1 @@ +{"version":3,"file":"workflow-versioning-service.js","sourceRoot":"","sources":["../../src/services/workflow-versioning-service.ts"],"names":[],"mappings":";;;AASA,6DAAyD;AACzD,2EAAsE;AA4EtE,MAAa,yBAAyB;IAGpC,YACU,cAA8B,EAC9B,SAAwB;QADxB,mBAAc,GAAd,cAAc,CAAgB;QAC9B,cAAS,GAAT,SAAS,CAAe;QAJjB,yBAAoB,GAAG,EAAE,CAAC;IAKxC,CAAC;IAMJ,KAAK,CAAC,YAAY,CAChB,UAAkB,EAClB,QAAa,EACb,OAKC;QAGD,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;QACxE,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAG5E,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,qBAAqB,CAAC;YAC1D,UAAU;YACV,aAAa,EAAE,WAAW;YAC1B,YAAY,EAAE,QAAQ,CAAC,IAAI,IAAI,kBAAkB;YACjD,gBAAgB,EAAE,QAAQ;YAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;SAC3B,CAAC,CAAC;QAGH,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,qBAAqB,CACtD,UAAU,EACV,IAAI,CAAC,oBAAoB,CAC1B,CAAC;QAEF,OAAO;YACL,SAAS;YACT,aAAa,EAAE,WAAW;YAC1B,MAAM;YACN,OAAO,EAAE,MAAM,GAAG,CAAC;gBACjB,CAAC,CAAC,2BAA2B,WAAW,aAAa,MAAM,iBAAiB;gBAC5E,CAAC,CAAC,2BAA2B,WAAW,GAAG;SAC9C,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,iBAAiB,CAAC,UAAkB,EAAE,QAAgB,EAAE;QAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAE5E,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACxB,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,UAAU,EAAE,CAAC,CAAC,UAAU;YACxB,aAAa,EAAE,CAAC,CAAC,aAAa;YAC9B,YAAY,EAAE,CAAC,CAAC,YAAY;YAC5B,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,cAAc,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;YAC9D,eAAe,EAAE,CAAC,CAAC,QAAQ,IAAI,SAAS;YACxC,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,MAAM;SAChD,CAAC,CAAC,CAAC;IACN,CAAC;IAKD,KAAK,CAAC,UAAU,CAAC,SAAiB;QAChC,OAAO,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC3D,CAAC;IAMD,KAAK,CAAC,cAAc,CAClB,UAAkB,EAClB,SAAkB,EAClB,iBAA0B,IAAI;QAE9B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,qDAAqD;gBAC9D,UAAU;gBACV,WAAW,EAAE,SAAS,IAAI,CAAC;gBAC3B,aAAa,EAAE,KAAK;aACrB,CAAC;QACJ,CAAC;QAGD,IAAI,gBAAgB,GAA2B,IAAI,CAAC;QAEpD,IAAI,SAAS,EAAE,CAAC;YACd,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;QACvE,CAAC;aAAM,CAAC;YAEN,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,wBAAwB,CAAC,UAAU,CAAC,CAAC;QAC9E,CAAC;QAED,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,SAAS;oBAChB,CAAC,CAAC,WAAW,SAAS,YAAY;oBAClC,CAAC,CAAC,yCAAyC,UAAU,EAAE;gBACzD,UAAU;gBACV,WAAW,EAAE,SAAS,IAAI,CAAC;gBAC3B,aAAa,EAAE,KAAK;aACrB,CAAC;QACJ,CAAC;QAGD,IAAI,cAAc,EAAE,CAAC;YACnB,MAAM,SAAS,GAAG,IAAI,sCAAiB,CAAC,IAAI,CAAC,cAAc,EAAE,mDAAuB,CAAC,CAAC;YACtF,MAAM,gBAAgB,GAAG,MAAM,SAAS,CAAC,gBAAgB,CACvD,gBAAgB,CAAC,gBAAgB,EACjC;gBACE,aAAa,EAAE,IAAI;gBACnB,mBAAmB,EAAE,IAAI;gBACzB,mBAAmB,EAAE,KAAK;gBAC1B,OAAO,EAAE,SAAS;aACnB,CACF,CAAC;YAEF,IAAI,gBAAgB,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvC,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE,4BAA4B,gBAAgB,CAAC,aAAa,wBAAwB;oBAC3F,UAAU;oBACV,WAAW,EAAE,gBAAgB,CAAC,EAAE;oBAChC,aAAa,EAAE,KAAK;oBACpB,gBAAgB,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,eAAe,CAAC;iBACjF,CAAC;YACJ,CAAC;QACH,CAAC;QAGD,IAAI,YAAsC,CAAC;QAC3C,IAAI,CAAC;YACH,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;YACrE,YAAY,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,eAAe,EAAE;gBAClE,OAAO,EAAE,gBAAgB;gBACzB,QAAQ,EAAE;oBACR,MAAM,EAAE,wBAAwB;oBAChC,kBAAkB,EAAE,gBAAgB,CAAC,aAAa;iBACnD;aACF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,2CAA2C,KAAK,CAAC,OAAO,EAAE;gBACnE,UAAU;gBACV,WAAW,EAAE,gBAAgB,CAAC,EAAE;gBAChC,aAAa,EAAE,KAAK;aACrB,CAAC;QACJ,CAAC;QAGD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,UAAU,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;YAEnF,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,6CAA6C,gBAAgB,CAAC,aAAa,EAAE;gBACtF,UAAU;gBACV,WAAW,EAAE,YAAY,CAAC,aAAa;gBACvC,WAAW,EAAE,gBAAgB,CAAC,EAAE;gBAChC,aAAa,EAAE,IAAI;gBACnB,eAAe,EAAE,YAAY,CAAC,SAAS;aACxC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,+BAA+B,KAAK,CAAC,OAAO,EAAE;gBACvD,UAAU;gBACV,WAAW,EAAE,gBAAgB,CAAC,EAAE;gBAChC,aAAa,EAAE,IAAI;gBACnB,eAAe,EAAE,YAAY,CAAC,SAAS;aACxC,CAAC;QACJ,CAAC;IACH,CAAC;IAKD,KAAK,CAAC,aAAa,CAAC,SAAiB;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;QAElE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,WAAW,SAAS,YAAY;aAC1C,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,cAAc,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;QAErD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,mBAAmB,OAAO,CAAC,aAAa,iBAAiB,OAAO,CAAC,UAAU,EAAE;SACvF,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,iBAAiB,CAAC,UAAkB;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;QAEtE,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAChB,OAAO;gBACL,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,kCAAkC,UAAU,EAAE;aACxD,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,kCAAkC,CAAC,UAAU,CAAC,CAAC;QAEnF,OAAO;YACL,OAAO;YACP,OAAO,EAAE,WAAW,OAAO,4BAA4B,UAAU,EAAE;SACpE,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,aAAa,CACjB,UAAkB,EAClB,cAAsB,EAAE;QAExB,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,qBAAqB,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QAClF,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;QAE1E,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC/B,CAAC;IAMD,KAAK,CAAC,mBAAmB,CAAC,OAAgB;QACxC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,oDAAoD;aAC9D,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,wBAAwB,EAAE,CAAC;QAE/D,OAAO;YACL,OAAO;YACP,OAAO,EAAE,+CAA+C,OAAO,aAAa;SAC7E,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,eAAe;QACnB,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,sBAAsB,EAAE,CAAC;QAE3D,OAAO;YACL,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,kBAAkB,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC;YACrD,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;gBAC5C,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB,YAAY,EAAE,CAAC,CAAC,YAAY;gBAC5B,YAAY,EAAE,CAAC,CAAC,YAAY;gBAC5B,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,kBAAkB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;gBACjD,UAAU,EAAE,CAAC,CAAC,UAAU;aACzB,CAAC,CAAC;SACJ,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,eAAe,CAAC,UAAkB,EAAE,UAAkB;QAC1D,MAAM,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;QAC9D,MAAM,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;QAE9D,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,mCAAmC,UAAU,KAAK,UAAU,EAAE,CAAC,CAAC;QAClF,CAAC;QAGD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAS,EAAE,CAAC,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAY,CAAC,IAAI,EAAE,CAAC,CAAC;QACjG,MAAM,MAAM,GAAG,IAAI,GAAG,CAAS,EAAE,CAAC,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAY,CAAC,IAAI,EAAE,CAAC,CAAC;QAEjG,MAAM,UAAU,GAAa,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACvE,MAAM,YAAY,GAAa,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACzE,MAAM,WAAW,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAG7D,MAAM,aAAa,GAAa,EAAE,CAAC;QACnC,KAAK,MAAM,MAAM,IAAI,WAAW,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;YAC3E,MAAM,KAAK,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;YAE3E,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpD,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAGD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,gBAAgB,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;QACvE,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,gBAAgB,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;QACvE,MAAM,iBAAiB,GAAG,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAGxD,MAAM,SAAS,GAAG,EAAE,CAAC,gBAAgB,CAAC,QAAQ,IAAI,EAAE,CAAC;QACrD,MAAM,SAAS,GAAG,EAAE,CAAC,gBAAgB,CAAC,QAAQ,IAAI,EAAE,CAAC;QACrD,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAE9D,OAAO;YACL,UAAU;YACV,UAAU;YACV,cAAc,EAAE,EAAE,CAAC,aAAa;YAChC,cAAc,EAAE,EAAE,CAAC,aAAa;YAChC,UAAU;YACV,YAAY;YACZ,aAAa;YACb,iBAAiB;YACjB,cAAc;SACf,CAAC;IACJ,CAAC;IAKO,WAAW,CAAC,KAAa;QAC/B,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAElC,MAAM,CAAC,GAAG,IAAI,CAAC;QACf,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAEpD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3E,CAAC;IAKO,WAAW,CAAC,IAAS,EAAE,IAAS;QACtC,MAAM,OAAO,GAAQ,EAAE,CAAC;QAExB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAEtE,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBAC5D,OAAO,CAAC,GAAG,CAAC,GAAG;oBACb,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC;oBACjB,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC;iBACjB,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AArXD,8DAqXC"} \ No newline at end of file diff --git a/dist/telemetry/batch-processor.d.ts b/dist/telemetry/batch-processor.d.ts new file mode 100644 index 0000000..d8ded77 --- /dev/null +++ b/dist/telemetry/batch-processor.d.ts @@ -0,0 +1,34 @@ +import { SupabaseClient } from '@supabase/supabase-js'; +import { TelemetryEvent, WorkflowTelemetry, WorkflowMutationRecord, TelemetryMetrics } from './telemetry-types'; +export declare class TelemetryBatchProcessor { + private supabase; + private isEnabled; + private flushTimer?; + private isFlushingEvents; + private isFlushingWorkflows; + private isFlushingMutations; + private circuitBreaker; + private metrics; + private flushTimes; + private deadLetterQueue; + private readonly maxDeadLetterSize; + constructor(supabase: SupabaseClient | null, isEnabled: () => boolean); + start(): void; + stop(): void; + flush(events?: TelemetryEvent[], workflows?: WorkflowTelemetry[], mutations?: WorkflowMutationRecord[]): Promise; + private flushEvents; + private flushWorkflows; + private flushMutations; + private executeWithRetry; + private createBatches; + private deduplicateWorkflows; + private addToDeadLetterQueue; + private processDeadLetterQueue; + private recordFlushTime; + getMetrics(): TelemetryMetrics & { + circuitBreakerState: any; + deadLetterQueueSize: number; + }; + resetMetrics(): void; +} +//# sourceMappingURL=batch-processor.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/batch-processor.d.ts.map b/dist/telemetry/batch-processor.d.ts.map new file mode 100644 index 0000000..a91be74 --- /dev/null +++ b/dist/telemetry/batch-processor.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"batch-processor.d.ts","sourceRoot":"","sources":["../../src/telemetry/batch-processor.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,sBAAsB,EAAoB,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAyBlI,qBAAa,uBAAuB;IAoBhC,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,SAAS;IApBnB,OAAO,CAAC,UAAU,CAAC,CAAiB;IACpC,OAAO,CAAC,gBAAgB,CAAkB;IAC1C,OAAO,CAAC,mBAAmB,CAAkB;IAC7C,OAAO,CAAC,mBAAmB,CAAkB;IAC7C,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,OAAO,CAQb;IACF,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,eAAe,CAAuE;IAC9F,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAO;gBAG/B,QAAQ,EAAE,cAAc,GAAG,IAAI,EAC/B,SAAS,EAAE,MAAM,OAAO;IAQlC,KAAK,IAAI,IAAI;IA+Bb,IAAI,IAAI,IAAI;IAWN,KAAK,CAAC,MAAM,CAAC,EAAE,cAAc,EAAE,EAAE,SAAS,CAAC,EAAE,iBAAiB,EAAE,EAAE,SAAS,CAAC,EAAE,sBAAsB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAgD9G,WAAW;YAmDX,cAAc;YAuDd,cAAc;YAiEd,gBAAgB;IAgD9B,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,oBAAoB;IAiB5B,OAAO,CAAC,oBAAoB;YAmBd,sBAAsB;IAgCpC,OAAO,CAAC,eAAe;IAiBvB,UAAU,IAAI,gBAAgB,GAAG;QAAE,mBAAmB,EAAE,GAAG,CAAC;QAAC,mBAAmB,EAAE,MAAM,CAAA;KAAE;IAW1F,YAAY,IAAI,IAAI;CAarB"} \ No newline at end of file diff --git a/dist/telemetry/batch-processor.js b/dist/telemetry/batch-processor.js new file mode 100644 index 0000000..9a4cef3 --- /dev/null +++ b/dist/telemetry/batch-processor.js @@ -0,0 +1,343 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TelemetryBatchProcessor = void 0; +const telemetry_types_1 = require("./telemetry-types"); +const telemetry_error_1 = require("./telemetry-error"); +const logger_1 = require("../utils/logger"); +function toSnakeCase(obj) { + if (obj === null || obj === undefined) + return obj; + if (Array.isArray(obj)) + return obj.map(toSnakeCase); + if (typeof obj !== 'object') + return obj; + const result = {}; + for (const key in obj) { + if (obj.hasOwnProperty(key)) { + const snakeKey = key.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`); + result[snakeKey] = toSnakeCase(obj[key]); + } + } + return result; +} +class TelemetryBatchProcessor { + constructor(supabase, isEnabled) { + this.supabase = supabase; + this.isEnabled = isEnabled; + this.isFlushingEvents = false; + this.isFlushingWorkflows = false; + this.isFlushingMutations = false; + this.metrics = { + eventsTracked: 0, + eventsDropped: 0, + eventsFailed: 0, + batchesSent: 0, + batchesFailed: 0, + averageFlushTime: 0, + rateLimitHits: 0 + }; + this.flushTimes = []; + this.deadLetterQueue = []; + this.maxDeadLetterSize = 100; + this.circuitBreaker = new telemetry_error_1.TelemetryCircuitBreaker(); + } + start() { + if (!this.isEnabled() || !this.supabase) + return; + this.flushTimer = setInterval(() => { + this.flush(); + }, telemetry_types_1.TELEMETRY_CONFIG.BATCH_FLUSH_INTERVAL); + if (typeof this.flushTimer === 'object' && 'unref' in this.flushTimer) { + this.flushTimer.unref(); + } + process.on('beforeExit', () => this.flush()); + process.on('SIGINT', () => { + this.flush(); + process.exit(0); + }); + process.on('SIGTERM', () => { + this.flush(); + process.exit(0); + }); + logger_1.logger.debug('Telemetry batch processor started'); + } + stop() { + if (this.flushTimer) { + clearInterval(this.flushTimer); + this.flushTimer = undefined; + } + logger_1.logger.debug('Telemetry batch processor stopped'); + } + async flush(events, workflows, mutations) { + if (!this.isEnabled() || !this.supabase) + return; + if (!this.circuitBreaker.shouldAllow()) { + logger_1.logger.debug('Circuit breaker open - skipping flush'); + this.metrics.eventsDropped += (events?.length || 0) + (workflows?.length || 0) + (mutations?.length || 0); + return; + } + const startTime = Date.now(); + let hasErrors = false; + if (events && events.length > 0) { + hasErrors = !(await this.flushEvents(events)) || hasErrors; + } + if (workflows && workflows.length > 0) { + hasErrors = !(await this.flushWorkflows(workflows)) || hasErrors; + } + if (mutations && mutations.length > 0) { + hasErrors = !(await this.flushMutations(mutations)) || hasErrors; + } + const flushTime = Date.now() - startTime; + this.recordFlushTime(flushTime); + if (hasErrors) { + this.circuitBreaker.recordFailure(); + } + else { + this.circuitBreaker.recordSuccess(); + } + if (!hasErrors && this.deadLetterQueue.length > 0) { + await this.processDeadLetterQueue(); + } + } + async flushEvents(events) { + if (this.isFlushingEvents || events.length === 0) + return true; + this.isFlushingEvents = true; + try { + const batches = this.createBatches(events, telemetry_types_1.TELEMETRY_CONFIG.MAX_BATCH_SIZE); + for (const batch of batches) { + const result = await this.executeWithRetry(async () => { + const { error } = await this.supabase + .from('telemetry_events') + .insert(batch); + if (error) { + throw error; + } + logger_1.logger.debug(`Flushed batch of ${batch.length} telemetry events`); + return true; + }, 'Flush telemetry events'); + if (result) { + this.metrics.eventsTracked += batch.length; + this.metrics.batchesSent++; + } + else { + this.metrics.eventsFailed += batch.length; + this.metrics.batchesFailed++; + this.addToDeadLetterQueue(batch); + return false; + } + } + return true; + } + catch (error) { + logger_1.logger.debug('Failed to flush events:', error); + throw new telemetry_error_1.TelemetryError(telemetry_error_1.TelemetryErrorType.NETWORK_ERROR, 'Failed to flush events', { error: error instanceof Error ? error.message : String(error) }, true); + } + finally { + this.isFlushingEvents = false; + } + } + async flushWorkflows(workflows) { + if (this.isFlushingWorkflows || workflows.length === 0) + return true; + this.isFlushingWorkflows = true; + try { + const uniqueWorkflows = this.deduplicateWorkflows(workflows); + logger_1.logger.debug(`Deduplicating workflows: ${workflows.length} -> ${uniqueWorkflows.length}`); + const batches = this.createBatches(uniqueWorkflows, telemetry_types_1.TELEMETRY_CONFIG.MAX_BATCH_SIZE); + for (const batch of batches) { + const result = await this.executeWithRetry(async () => { + const { error } = await this.supabase + .from('telemetry_workflows') + .insert(batch); + if (error) { + throw error; + } + logger_1.logger.debug(`Flushed batch of ${batch.length} telemetry workflows`); + return true; + }, 'Flush telemetry workflows'); + if (result) { + this.metrics.eventsTracked += batch.length; + this.metrics.batchesSent++; + } + else { + this.metrics.eventsFailed += batch.length; + this.metrics.batchesFailed++; + this.addToDeadLetterQueue(batch); + return false; + } + } + return true; + } + catch (error) { + logger_1.logger.debug('Failed to flush workflows:', error); + throw new telemetry_error_1.TelemetryError(telemetry_error_1.TelemetryErrorType.NETWORK_ERROR, 'Failed to flush workflows', { error: error instanceof Error ? error.message : String(error) }, true); + } + finally { + this.isFlushingWorkflows = false; + } + } + async flushMutations(mutations) { + if (this.isFlushingMutations || mutations.length === 0) + return true; + this.isFlushingMutations = true; + try { + const batches = this.createBatches(mutations, telemetry_types_1.TELEMETRY_CONFIG.MAX_BATCH_SIZE); + for (const batch of batches) { + const result = await this.executeWithRetry(async () => { + const snakeCaseBatch = batch.map(mutation => toSnakeCase(mutation)); + const { error } = await this.supabase + .from('workflow_mutations') + .insert(snakeCaseBatch); + if (error) { + logger_1.logger.error('Mutation insert error details:', { + code: error.code, + message: error.message, + details: error.details, + hint: error.hint, + fullError: String(error) + }); + throw error; + } + logger_1.logger.debug(`Flushed batch of ${batch.length} workflow mutations`); + return true; + }, 'Flush workflow mutations'); + if (result) { + this.metrics.eventsTracked += batch.length; + this.metrics.batchesSent++; + } + else { + this.metrics.eventsFailed += batch.length; + this.metrics.batchesFailed++; + this.addToDeadLetterQueue(batch); + return false; + } + } + return true; + } + catch (error) { + logger_1.logger.error('Failed to flush mutations with details:', { + errorMsg: error instanceof Error ? error.message : String(error), + errorType: error instanceof Error ? error.constructor.name : typeof error + }); + throw new telemetry_error_1.TelemetryError(telemetry_error_1.TelemetryErrorType.NETWORK_ERROR, 'Failed to flush workflow mutations', { error: error instanceof Error ? error.message : String(error) }, true); + } + finally { + this.isFlushingMutations = false; + } + } + async executeWithRetry(operation, operationName) { + let lastError = null; + let delay = telemetry_types_1.TELEMETRY_CONFIG.RETRY_DELAY; + for (let attempt = 1; attempt <= telemetry_types_1.TELEMETRY_CONFIG.MAX_RETRIES; attempt++) { + try { + if (process.env.NODE_ENV === 'test' && process.env.VITEST) { + const result = await operation(); + return result; + } + const timeoutPromise = new Promise((_, reject) => { + setTimeout(() => reject(new Error('Operation timed out')), telemetry_types_1.TELEMETRY_CONFIG.OPERATION_TIMEOUT); + }); + const result = await Promise.race([operation(), timeoutPromise]); + return result; + } + catch (error) { + lastError = error; + logger_1.logger.debug(`${operationName} attempt ${attempt} failed:`, error); + if (attempt < telemetry_types_1.TELEMETRY_CONFIG.MAX_RETRIES) { + if (!(process.env.NODE_ENV === 'test' && process.env.VITEST)) { + const jitter = Math.random() * 0.3 * delay; + const waitTime = delay + jitter; + await new Promise(resolve => setTimeout(resolve, waitTime)); + delay *= 2; + } + } + } + } + logger_1.logger.debug(`${operationName} failed after ${telemetry_types_1.TELEMETRY_CONFIG.MAX_RETRIES} attempts:`, lastError); + return null; + } + createBatches(items, batchSize) { + const batches = []; + for (let i = 0; i < items.length; i += batchSize) { + batches.push(items.slice(i, i + batchSize)); + } + return batches; + } + deduplicateWorkflows(workflows) { + const seen = new Set(); + const unique = []; + for (const workflow of workflows) { + if (!seen.has(workflow.workflow_hash)) { + seen.add(workflow.workflow_hash); + unique.push(workflow); + } + } + return unique; + } + addToDeadLetterQueue(items) { + for (const item of items) { + this.deadLetterQueue.push(item); + if (this.deadLetterQueue.length > this.maxDeadLetterSize) { + const dropped = this.deadLetterQueue.shift(); + if (dropped) { + this.metrics.eventsDropped++; + } + } + } + logger_1.logger.debug(`Added ${items.length} items to dead letter queue`); + } + async processDeadLetterQueue() { + if (this.deadLetterQueue.length === 0) + return; + logger_1.logger.debug(`Processing ${this.deadLetterQueue.length} items from dead letter queue`); + const events = []; + const workflows = []; + for (const item of this.deadLetterQueue) { + if ('workflow_hash' in item) { + workflows.push(item); + } + else { + events.push(item); + } + } + this.deadLetterQueue = []; + if (events.length > 0) { + await this.flushEvents(events); + } + if (workflows.length > 0) { + await this.flushWorkflows(workflows); + } + } + recordFlushTime(time) { + this.flushTimes.push(time); + if (this.flushTimes.length > 100) { + this.flushTimes.shift(); + } + const sum = this.flushTimes.reduce((a, b) => a + b, 0); + this.metrics.averageFlushTime = Math.round(sum / this.flushTimes.length); + this.metrics.lastFlushTime = time; + } + getMetrics() { + return { + ...this.metrics, + circuitBreakerState: this.circuitBreaker.getState(), + deadLetterQueueSize: this.deadLetterQueue.length + }; + } + resetMetrics() { + this.metrics = { + eventsTracked: 0, + eventsDropped: 0, + eventsFailed: 0, + batchesSent: 0, + batchesFailed: 0, + averageFlushTime: 0, + rateLimitHits: 0 + }; + this.flushTimes = []; + this.circuitBreaker.reset(); + } +} +exports.TelemetryBatchProcessor = TelemetryBatchProcessor; +//# sourceMappingURL=batch-processor.js.map \ No newline at end of file diff --git a/dist/telemetry/batch-processor.js.map b/dist/telemetry/batch-processor.js.map new file mode 100644 index 0000000..679451d --- /dev/null +++ b/dist/telemetry/batch-processor.js.map @@ -0,0 +1 @@ +{"version":3,"file":"batch-processor.js","sourceRoot":"","sources":["../../src/telemetry/batch-processor.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/telemetry/config-manager.d.ts b/dist/telemetry/config-manager.d.ts new file mode 100644 index 0000000..ba86e3b --- /dev/null +++ b/dist/telemetry/config-manager.d.ts @@ -0,0 +1,32 @@ +export interface TelemetryConfig { + enabled: boolean; + userId: string; + firstRun?: string; + lastModified?: string; + version?: string; +} +export declare class TelemetryConfigManager { + private static instance; + private readonly configDir; + private readonly configPath; + private config; + private constructor(); + static getInstance(): TelemetryConfigManager; + private generateUserId; + private generateDockerStableId; + private readBootId; + private generateCombinedFingerprint; + private isCloudEnvironment; + loadConfig(): TelemetryConfig; + private saveConfig; + isEnabled(): boolean; + private isDisabledByEnvironment; + getUserId(): string; + isFirstRun(): boolean; + enable(): void; + disable(): void; + getStatus(): string; + private showFirstRunNotice; + private getPackageVersion; +} +//# sourceMappingURL=config-manager.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/config-manager.d.ts.map b/dist/telemetry/config-manager.d.ts.map new file mode 100644 index 0000000..fff3e99 --- /dev/null +++ b/dist/telemetry/config-manager.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"config-manager.d.ts","sourceRoot":"","sources":["../../src/telemetry/config-manager.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,sBAAsB;IACjC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAyB;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,MAAM,CAAgC;IAE9C,OAAO;IAKP,MAAM,CAAC,WAAW,IAAI,sBAAsB;IAW5C,OAAO,CAAC,cAAc;IAetB,OAAO,CAAC,sBAAsB;IAuB9B,OAAO,CAAC,UAAU;IA2BlB,OAAO,CAAC,2BAA2B;IAiDnC,OAAO,CAAC,kBAAkB;IAgB1B,UAAU,IAAI,eAAe;IAqD7B,OAAO,CAAC,UAAU;IAmBlB,SAAS,IAAI,OAAO;IAapB,OAAO,CAAC,uBAAuB;IAiC/B,SAAS,IAAI,MAAM;IAQnB,UAAU,IAAI,OAAO;IAOrB,MAAM,IAAI,IAAI;IAWd,OAAO,IAAI,IAAI;IAWf,SAAS,IAAI,MAAM;IA2BnB,OAAO,CAAC,kBAAkB;IA0C1B,OAAO,CAAC,iBAAiB;CA+B1B"} \ No newline at end of file diff --git a/dist/telemetry/config-manager.js b/dist/telemetry/config-manager.js new file mode 100644 index 0000000..b7dd445 --- /dev/null +++ b/dist/telemetry/config-manager.js @@ -0,0 +1,289 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TelemetryConfigManager = void 0; +const fs_1 = require("fs"); +const path_1 = require("path"); +const os_1 = require("os"); +const crypto_1 = require("crypto"); +const os_2 = require("os"); +class TelemetryConfigManager { + constructor() { + this.config = null; + this.configDir = (0, path_1.join)((0, os_1.homedir)(), '.n8n-mcp'); + this.configPath = (0, path_1.join)(this.configDir, 'telemetry.json'); + } + static getInstance() { + if (!TelemetryConfigManager.instance) { + TelemetryConfigManager.instance = new TelemetryConfigManager(); + } + return TelemetryConfigManager.instance; + } + generateUserId() { + if (process.env.IS_DOCKER === 'true' || this.isCloudEnvironment()) { + return this.generateDockerStableId(); + } + const machineId = `${(0, os_2.hostname)()}-${(0, os_2.platform)()}-${(0, os_2.arch)()}-${(0, os_1.homedir)()}`; + return (0, crypto_1.createHash)('sha256').update(machineId).digest('hex').substring(0, 16); + } + generateDockerStableId() { + const bootId = this.readBootId(); + if (bootId) { + const fingerprint = `${bootId}-${(0, os_2.platform)()}-${(0, os_2.arch)()}`; + return (0, crypto_1.createHash)('sha256').update(fingerprint).digest('hex').substring(0, 16); + } + const combinedFingerprint = this.generateCombinedFingerprint(); + if (combinedFingerprint) { + return combinedFingerprint; + } + const genericId = `docker-${(0, os_2.platform)()}-${(0, os_2.arch)()}`; + return (0, crypto_1.createHash)('sha256').update(genericId).digest('hex').substring(0, 16); + } + readBootId() { + try { + const bootIdPath = '/proc/sys/kernel/random/boot_id'; + if (!(0, fs_1.existsSync)(bootIdPath)) { + return null; + } + const bootId = (0, fs_1.readFileSync)(bootIdPath, 'utf-8').trim(); + const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; + if (!uuidRegex.test(bootId)) { + return null; + } + return bootId; + } + catch (error) { + return null; + } + } + generateCombinedFingerprint() { + try { + const signals = []; + if ((0, fs_1.existsSync)('/proc/cpuinfo')) { + const cpuinfo = (0, fs_1.readFileSync)('/proc/cpuinfo', 'utf-8'); + const cores = (cpuinfo.match(/processor\s*:/g) || []).length; + if (cores > 0) { + signals.push(`cores:${cores}`); + } + } + if ((0, fs_1.existsSync)('/proc/meminfo')) { + const meminfo = (0, fs_1.readFileSync)('/proc/meminfo', 'utf-8'); + const totalMatch = meminfo.match(/MemTotal:\s+(\d+)/); + if (totalMatch) { + signals.push(`mem:${totalMatch[1]}`); + } + } + if ((0, fs_1.existsSync)('/proc/version')) { + const version = (0, fs_1.readFileSync)('/proc/version', 'utf-8'); + const kernelMatch = version.match(/Linux version ([\d.]+)/); + if (kernelMatch) { + signals.push(`kernel:${kernelMatch[1]}`); + } + } + signals.push((0, os_2.platform)(), (0, os_2.arch)()); + if (signals.length < 3) { + return null; + } + const fingerprint = signals.join('-'); + return (0, crypto_1.createHash)('sha256').update(fingerprint).digest('hex').substring(0, 16); + } + catch (error) { + return null; + } + } + isCloudEnvironment() { + return !!(process.env.RAILWAY_ENVIRONMENT || + process.env.RENDER || + process.env.FLY_APP_NAME || + process.env.HEROKU_APP_NAME || + process.env.AWS_EXECUTION_ENV || + process.env.KUBERNETES_SERVICE_HOST || + process.env.GOOGLE_CLOUD_PROJECT || + process.env.AZURE_FUNCTIONS_ENVIRONMENT); + } + loadConfig() { + if (this.config) { + return this.config; + } + if (!(0, fs_1.existsSync)(this.configPath)) { + const version = this.getPackageVersion(); + const envDisabled = this.isDisabledByEnvironment(); + this.config = { + enabled: !envDisabled, + userId: this.generateUserId(), + firstRun: new Date().toISOString(), + version + }; + this.saveConfig(); + if (!envDisabled) { + this.showFirstRunNotice(); + } + return this.config; + } + try { + const rawConfig = (0, fs_1.readFileSync)(this.configPath, 'utf-8'); + this.config = JSON.parse(rawConfig); + if (!this.config.userId) { + this.config.userId = this.generateUserId(); + this.saveConfig(); + } + return this.config; + } + catch (error) { + console.error('Failed to load telemetry config, using defaults:', error); + this.config = { + enabled: false, + userId: this.generateUserId() + }; + return this.config; + } + } + saveConfig() { + if (!this.config) + return; + try { + if (!(0, fs_1.existsSync)(this.configDir)) { + (0, fs_1.mkdirSync)(this.configDir, { recursive: true }); + } + this.config.lastModified = new Date().toISOString(); + (0, fs_1.writeFileSync)(this.configPath, JSON.stringify(this.config, null, 2)); + } + catch (error) { + console.error('Failed to save telemetry config:', error); + } + } + isEnabled() { + if (this.isDisabledByEnvironment()) { + return false; + } + const config = this.loadConfig(); + return config.enabled; + } + isDisabledByEnvironment() { + const envVars = [ + 'N8N_MCP_TELEMETRY_DISABLED', + 'TELEMETRY_DISABLED', + 'DISABLE_TELEMETRY' + ]; + for (const varName of envVars) { + const value = process.env[varName]; + if (value !== undefined) { + const normalized = value.toLowerCase().trim(); + if (!['true', 'false', '1', '0', ''].includes(normalized)) { + console.warn(`⚠️ Invalid telemetry environment variable value: ${varName}="${value}"\n` + + ` Use "true" to disable or "false" to enable telemetry.`); + } + if (normalized === 'true' || normalized === '1') { + return true; + } + } + } + return false; + } + getUserId() { + const config = this.loadConfig(); + return config.userId; + } + isFirstRun() { + return !(0, fs_1.existsSync)(this.configPath); + } + enable() { + const config = this.loadConfig(); + config.enabled = true; + this.config = config; + this.saveConfig(); + console.log('✓ Anonymous telemetry enabled'); + } + disable() { + const config = this.loadConfig(); + config.enabled = false; + this.config = config; + this.saveConfig(); + console.log('✓ Anonymous telemetry disabled'); + } + getStatus() { + const config = this.loadConfig(); + const envDisabled = this.isDisabledByEnvironment(); + let status = config.enabled ? 'ENABLED' : 'DISABLED'; + if (envDisabled) { + status = 'DISABLED (via environment variable)'; + } + return ` +Telemetry Status: ${status} +Anonymous ID: ${config.userId} +First Run: ${config.firstRun || 'Unknown'} +Config Path: ${this.configPath} + +To opt-out: npx n8n-mcp telemetry disable +To opt-in: npx n8n-mcp telemetry enable + +For Docker: Set N8N_MCP_TELEMETRY_DISABLED=true +`; + } + showFirstRunNotice() { + console.log(` +╔════════════════════════════════════════════════════════════╗ +║ Anonymous Usage Statistics ║ +╠════════════════════════════════════════════════════════════╣ +║ ║ +║ n8n-mcp collects anonymous usage data to improve the ║ +║ tool and understand how it's being used. ║ +║ ║ +║ We track: ║ +║ • Which MCP tools are used (no parameters) ║ +║ • Workflow structures (sanitized, no sensitive data) ║ +║ • Error patterns (hashed, no details) ║ +║ • Performance metrics (timing, success rates) ║ +║ ║ +║ We NEVER collect: ║ +║ • URLs, API keys, or credentials ║ +║ • Workflow content or actual data ║ +║ • Personal or identifiable information ║ +║ • n8n instance details or locations ║ +║ ║ +║ Your anonymous ID: ${this.config?.userId || 'generating...'} ║ +║ ║ +║ This helps me understand usage patterns and improve ║ +║ n8n-mcp for everyone. Thank you for your support! ║ +║ ║ +║ To opt-out at any time: ║ +║ npx n8n-mcp telemetry disable ║ +║ ║ +║ Data deletion requests: ║ +║ Email romuald@n8n-mcp.com with your anonymous ID ║ +║ ║ +║ Learn more: ║ +║ https://github.com/czlonkowski/n8n-mcp/blob/main/PRIVACY.md ║ +║ ║ +╚════════════════════════════════════════════════════════════╝ +`); + } + getPackageVersion() { + try { + const possiblePaths = [ + (0, path_1.resolve)(__dirname, '..', '..', 'package.json'), + (0, path_1.resolve)(process.cwd(), 'package.json'), + (0, path_1.resolve)(__dirname, '..', '..', '..', 'package.json') + ]; + for (const packagePath of possiblePaths) { + if ((0, fs_1.existsSync)(packagePath)) { + const packageJson = JSON.parse((0, fs_1.readFileSync)(packagePath, 'utf-8')); + if (packageJson.version) { + return packageJson.version; + } + } + } + try { + const packageJson = require('../../package.json'); + return packageJson.version || 'unknown'; + } + catch { + } + return 'unknown'; + } + catch (error) { + return 'unknown'; + } + } +} +exports.TelemetryConfigManager = TelemetryConfigManager; +//# sourceMappingURL=config-manager.js.map \ No newline at end of file diff --git a/dist/telemetry/config-manager.js.map b/dist/telemetry/config-manager.js.map new file mode 100644 index 0000000..af78eae --- /dev/null +++ b/dist/telemetry/config-manager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../../src/telemetry/config-manager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/telemetry/early-error-logger.d.ts b/dist/telemetry/early-error-logger.d.ts new file mode 100644 index 0000000..5e74a7a --- /dev/null +++ b/dist/telemetry/early-error-logger.d.ts @@ -0,0 +1,26 @@ +import { StartupCheckpoint } from './startup-checkpoints'; +export declare class EarlyErrorLogger { + private static instance; + private enabled; + private supabase; + private userId; + private checkpoints; + private startTime; + private initPromise; + private constructor(); + static getInstance(): EarlyErrorLogger; + private initialize; + waitForInit(): Promise; + logCheckpoint(checkpoint: StartupCheckpoint): void; + logStartupError(checkpoint: StartupCheckpoint, error: unknown): void; + private logStartupErrorAsync; + logStartupSuccess(checkpoints: StartupCheckpoint[], durationMs: number): void; + getCheckpoints(): StartupCheckpoint[]; + getStartupDuration(): number; + getStartupData(): { + durationMs: number; + checkpoints: StartupCheckpoint[]; + } | null; + isEnabled(): boolean; +} +//# sourceMappingURL=early-error-logger.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/early-error-logger.d.ts.map b/dist/telemetry/early-error-logger.d.ts.map new file mode 100644 index 0000000..6d78c0f --- /dev/null +++ b/dist/telemetry/early-error-logger.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"early-error-logger.d.ts","sourceRoot":"","sources":["../../src/telemetry/early-error-logger.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,iBAAiB,EAA+C,MAAM,uBAAuB,CAAC;AAqBvG,qBAAa,gBAAgB;IAE3B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAiC;IAIxD,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,WAAW,CAAgB;IAMnC,OAAO;IASP,MAAM,CAAC,WAAW,IAAI,gBAAgB;YAWxB,UAAU;IAmDlB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAQlC,aAAa,CAAC,UAAU,EAAE,iBAAiB,GAAG,IAAI;IA2BlD,eAAe,CAAC,UAAU,EAAE,iBAAiB,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;YAetD,oBAAoB;IAuElC,iBAAiB,CAAC,WAAW,EAAE,iBAAiB,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAqB7E,cAAc,IAAI,iBAAiB,EAAE;IAOrC,kBAAkB,IAAI,MAAM;IAO5B,cAAc,IAAI;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,iBAAiB,EAAE,CAAA;KAAE,GAAG,IAAI;IAcjF,SAAS,IAAI,OAAO;CAGrB"} \ No newline at end of file diff --git a/dist/telemetry/early-error-logger.js b/dist/telemetry/early-error-logger.js new file mode 100644 index 0000000..8a83c75 --- /dev/null +++ b/dist/telemetry/early-error-logger.js @@ -0,0 +1,187 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.EarlyErrorLogger = void 0; +const supabase_js_1 = require("@supabase/supabase-js"); +const config_manager_1 = require("./config-manager"); +const telemetry_types_1 = require("./telemetry-types"); +const startup_checkpoints_1 = require("./startup-checkpoints"); +const error_sanitization_utils_1 = require("./error-sanitization-utils"); +const logger_1 = require("../utils/logger"); +async function withTimeout(promise, timeoutMs, operation) { + try { + const timeoutPromise = new Promise((_, reject) => { + setTimeout(() => reject(new Error(`${operation} timeout after ${timeoutMs}ms`)), timeoutMs); + }); + return await Promise.race([promise, timeoutPromise]); + } + catch (error) { + logger_1.logger.debug(`${operation} failed or timed out:`, error); + return null; + } +} +class EarlyErrorLogger { + constructor() { + this.enabled = false; + this.supabase = null; + this.userId = null; + this.checkpoints = []; + this.startTime = Date.now(); + this.initPromise = this.initialize(); + } + static getInstance() { + if (!EarlyErrorLogger.instance) { + EarlyErrorLogger.instance = new EarlyErrorLogger(); + } + return EarlyErrorLogger.instance; + } + async initialize() { + try { + if (!telemetry_types_1.TELEMETRY_BACKEND.URL || !telemetry_types_1.TELEMETRY_BACKEND.ANON_KEY) { + logger_1.logger.debug('Telemetry backend not configured, early error logger disabled'); + this.enabled = false; + return; + } + const configManager = config_manager_1.TelemetryConfigManager.getInstance(); + const isEnabled = configManager.isEnabled(); + if (!isEnabled) { + logger_1.logger.debug('Telemetry disabled by user, early error logger will not send events'); + this.enabled = false; + return; + } + this.supabase = (0, supabase_js_1.createClient)(telemetry_types_1.TELEMETRY_BACKEND.URL, telemetry_types_1.TELEMETRY_BACKEND.ANON_KEY, { + auth: { + persistSession: false, + autoRefreshToken: false, + }, + }); + this.userId = configManager.getUserId(); + this.enabled = true; + logger_1.logger.debug('Early error logger initialized successfully'); + } + catch (error) { + logger_1.logger.debug('Early error logger initialization failed:', error); + this.enabled = false; + this.supabase = null; + this.userId = null; + } + } + async waitForInit() { + await this.initPromise; + } + logCheckpoint(checkpoint) { + if (!this.enabled) { + return; + } + try { + if (!(0, startup_checkpoints_1.isValidCheckpoint)(checkpoint)) { + logger_1.logger.warn(`Invalid checkpoint: ${checkpoint}`); + return; + } + this.checkpoints.push(checkpoint); + logger_1.logger.debug(`Checkpoint passed: ${checkpoint} (${(0, startup_checkpoints_1.getCheckpointDescription)(checkpoint)})`); + } + catch (error) { + logger_1.logger.debug('Failed to log checkpoint:', error); + } + } + logStartupError(checkpoint, error) { + if (!this.enabled || !this.supabase || !this.userId) { + return; + } + this.logStartupErrorAsync(checkpoint, error).catch((logError) => { + logger_1.logger.debug('Failed to log startup error:', logError); + }); + } + async logStartupErrorAsync(checkpoint, error) { + try { + let errorMessage = 'Unknown error'; + if (error instanceof Error) { + errorMessage = error.message; + if (error.stack) { + errorMessage = error.stack; + } + } + else if (typeof error === 'string') { + errorMessage = error; + } + else { + errorMessage = String(error); + } + const sanitizedError = (0, error_sanitization_utils_1.sanitizeErrorMessageCore)(errorMessage); + let errorType = 'unknown'; + if (error instanceof Error) { + errorType = error.name || 'Error'; + } + else if (typeof error === 'string') { + errorType = 'string_error'; + } + const event = { + user_id: this.userId, + event: 'startup_error', + properties: { + checkpoint, + errorMessage: sanitizedError, + errorType, + checkpointsPassed: this.checkpoints, + checkpointsPassedCount: this.checkpoints.length, + startupDuration: Date.now() - this.startTime, + platform: process.platform, + arch: process.arch, + nodeVersion: process.version, + isDocker: process.env.IS_DOCKER === 'true', + }, + created_at: new Date().toISOString(), + }; + const insertOperation = async () => { + return await this.supabase + .from('events') + .insert(event) + .select() + .single(); + }; + const result = await withTimeout(insertOperation(), 5000, 'Startup error insert'); + if (result && 'error' in result && result.error) { + logger_1.logger.debug('Failed to insert startup error event:', result.error); + } + else if (result) { + logger_1.logger.debug(`Startup error logged for checkpoint: ${checkpoint}`); + } + } + catch (logError) { + logger_1.logger.debug('Failed to log startup error:', logError); + } + } + logStartupSuccess(checkpoints, durationMs) { + if (!this.enabled) { + return; + } + try { + this.checkpoints = checkpoints; + logger_1.logger.debug(`Startup successful: ${checkpoints.length} checkpoints passed in ${durationMs}ms`); + } + catch (error) { + logger_1.logger.debug('Failed to log startup success:', error); + } + } + getCheckpoints() { + return [...this.checkpoints]; + } + getStartupDuration() { + return Date.now() - this.startTime; + } + getStartupData() { + if (!this.enabled) { + return null; + } + return { + durationMs: this.getStartupDuration(), + checkpoints: this.getCheckpoints(), + }; + } + isEnabled() { + return this.enabled && this.supabase !== null && this.userId !== null; + } +} +exports.EarlyErrorLogger = EarlyErrorLogger; +EarlyErrorLogger.instance = null; +//# sourceMappingURL=early-error-logger.js.map \ No newline at end of file diff --git a/dist/telemetry/early-error-logger.js.map b/dist/telemetry/early-error-logger.js.map new file mode 100644 index 0000000..c2b441a --- /dev/null +++ b/dist/telemetry/early-error-logger.js.map @@ -0,0 +1 @@ +{"version":3,"file":"early-error-logger.js","sourceRoot":"","sources":["../../src/telemetry/early-error-logger.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/telemetry/error-sanitization-utils.d.ts b/dist/telemetry/error-sanitization-utils.d.ts new file mode 100644 index 0000000..44f9866 --- /dev/null +++ b/dist/telemetry/error-sanitization-utils.d.ts @@ -0,0 +1,2 @@ +export declare function sanitizeErrorMessageCore(errorMessage: string): string; +//# sourceMappingURL=error-sanitization-utils.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/error-sanitization-utils.d.ts.map b/dist/telemetry/error-sanitization-utils.d.ts.map new file mode 100644 index 0000000..69909db --- /dev/null +++ b/dist/telemetry/error-sanitization-utils.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"error-sanitization-utils.d.ts","sourceRoot":"","sources":["../../src/telemetry/error-sanitization-utils.ts"],"names":[],"mappings":"AAyBA,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAiDrE"} \ No newline at end of file diff --git a/dist/telemetry/error-sanitization-utils.js b/dist/telemetry/error-sanitization-utils.js new file mode 100644 index 0000000..7df55c1 --- /dev/null +++ b/dist/telemetry/error-sanitization-utils.js @@ -0,0 +1,37 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sanitizeErrorMessageCore = sanitizeErrorMessageCore; +const logger_1 = require("../utils/logger"); +function sanitizeErrorMessageCore(errorMessage) { + try { + const maxLength = 1500; + const trimmed = errorMessage.length > maxLength + ? errorMessage.substring(0, maxLength) + : errorMessage; + const lines = trimmed.split('\n'); + let sanitized = lines.slice(0, 3).join('\n'); + sanitized = sanitized.replace(/https?:\/\/\S+/gi, '[URL]'); + sanitized = sanitized + .replace(/AKIA[A-Z0-9]{16}/g, '[AWS_KEY]') + .replace(/ghp_[a-zA-Z0-9]{36,}/g, '[GITHUB_TOKEN]') + .replace(/eyJ[a-zA-Z0-9_-]+\.eyJ[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+/g, '[JWT]') + .replace(/Bearer\s+[^\s]+/gi, 'Bearer [TOKEN]'); + sanitized = sanitized.replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g, '[EMAIL]'); + sanitized = sanitized + .replace(/\b[a-zA-Z0-9_-]{32,}\b/g, '[KEY]') + .replace(/(['"])[a-zA-Z0-9_-]{16,}\1/g, '$1[TOKEN]$1'); + sanitized = sanitized + .replace(/password\s*[=:]\s*\S+/gi, 'password=[REDACTED]') + .replace(/api[_-]?key\s*[=:]\s*\S+/gi, 'api_key=[REDACTED]') + .replace(/\btoken\s*[=:]\s*[^\s;,)]+/gi, 'token=[REDACTED]'); + if (sanitized.length > 500) { + sanitized = sanitized.substring(0, 500) + '...'; + } + return sanitized; + } + catch (error) { + logger_1.logger.debug('Error message sanitization failed:', error); + return '[SANITIZATION_FAILED]'; + } +} +//# sourceMappingURL=error-sanitization-utils.js.map \ No newline at end of file diff --git a/dist/telemetry/error-sanitization-utils.js.map b/dist/telemetry/error-sanitization-utils.js.map new file mode 100644 index 0000000..c7268ed --- /dev/null +++ b/dist/telemetry/error-sanitization-utils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"error-sanitization-utils.js","sourceRoot":"","sources":["../../src/telemetry/error-sanitization-utils.ts"],"names":[],"mappings":";;AAyBA,4DAiDC;AAnED,4CAAyC;AAkBzC,SAAgB,wBAAwB,CAAC,YAAoB;IAC3D,IAAI,CAAC;QAEH,MAAM,SAAS,GAAG,IAAI,CAAC;QACvB,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,GAAG,SAAS;YAC7C,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC;YACtC,CAAC,CAAC,YAAY,CAAC;QAGjB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAK7C,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;QAG3D,SAAS,GAAG,SAAS;aAClB,OAAO,CAAC,mBAAmB,EAAE,WAAW,CAAC;aACzC,OAAO,CAAC,uBAAuB,EAAE,gBAAgB,CAAC;aAClD,OAAO,CAAC,uDAAuD,EAAE,OAAO,CAAC;aACzE,OAAO,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,CAAC;QAGlD,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,iDAAiD,EAAE,SAAS,CAAC,CAAC;QAG5F,SAAS,GAAG,SAAS;aAClB,OAAO,CAAC,yBAAyB,EAAE,OAAO,CAAC;aAC3C,OAAO,CAAC,6BAA6B,EAAE,aAAa,CAAC,CAAC;QAIzD,SAAS,GAAG,SAAS;aAClB,OAAO,CAAC,yBAAyB,EAAE,qBAAqB,CAAC;aACzD,OAAO,CAAC,4BAA4B,EAAE,oBAAoB,CAAC;aAC3D,OAAO,CAAC,8BAA8B,EAAE,kBAAkB,CAAC,CAAC;QAG/D,IAAI,SAAS,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YAC3B,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC;QAClD,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAM,CAAC,KAAK,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;QAC1D,OAAO,uBAAuB,CAAC;IACjC,CAAC;AACH,CAAC"} \ No newline at end of file diff --git a/dist/telemetry/error-sanitizer.d.ts b/dist/telemetry/error-sanitizer.d.ts new file mode 100644 index 0000000..9ec5349 --- /dev/null +++ b/dist/telemetry/error-sanitizer.d.ts @@ -0,0 +1,4 @@ +export declare function extractErrorMessage(error: unknown): string; +export declare function sanitizeStartupError(errorMessage: string): string; +export declare function processStartupError(error: unknown): string; +//# sourceMappingURL=error-sanitizer.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/error-sanitizer.d.ts.map b/dist/telemetry/error-sanitizer.d.ts.map new file mode 100644 index 0000000..4f2c912 --- /dev/null +++ b/dist/telemetry/error-sanitizer.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"error-sanitizer.d.ts","sourceRoot":"","sources":["../../src/telemetry/error-sanitizer.ts"],"names":[],"mappings":"AAaA,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAiC1D;AAOD,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAEjE;AAMD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAG1D"} \ No newline at end of file diff --git a/dist/telemetry/error-sanitizer.js b/dist/telemetry/error-sanitizer.js new file mode 100644 index 0000000..7780175 --- /dev/null +++ b/dist/telemetry/error-sanitizer.js @@ -0,0 +1,45 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.extractErrorMessage = extractErrorMessage; +exports.sanitizeStartupError = sanitizeStartupError; +exports.processStartupError = processStartupError; +const logger_1 = require("../utils/logger"); +const error_sanitization_utils_1 = require("./error-sanitization-utils"); +function extractErrorMessage(error) { + try { + if (error instanceof Error) { + return error.stack || error.message || 'Unknown error'; + } + if (typeof error === 'string') { + return error; + } + if (error && typeof error === 'object') { + const errorObj = error; + if (errorObj.message) { + return String(errorObj.message); + } + if (errorObj.error) { + return String(errorObj.error); + } + try { + return JSON.stringify(error).substring(0, 500); + } + catch { + return 'Error object (unstringifiable)'; + } + } + return String(error); + } + catch (extractError) { + logger_1.logger.debug('Error during message extraction:', extractError); + return 'Error message extraction failed'; + } +} +function sanitizeStartupError(errorMessage) { + return (0, error_sanitization_utils_1.sanitizeErrorMessageCore)(errorMessage); +} +function processStartupError(error) { + const message = extractErrorMessage(error); + return sanitizeStartupError(message); +} +//# sourceMappingURL=error-sanitizer.js.map \ No newline at end of file diff --git a/dist/telemetry/error-sanitizer.js.map b/dist/telemetry/error-sanitizer.js.map new file mode 100644 index 0000000..e842517 --- /dev/null +++ b/dist/telemetry/error-sanitizer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"error-sanitizer.js","sourceRoot":"","sources":["../../src/telemetry/error-sanitizer.ts"],"names":[],"mappings":";;AAaA,kDAiCC;AAOD,oDAEC;AAMD,kDAGC;AA1DD,4CAAyC;AACzC,yEAAsE;AAMtE,SAAgB,mBAAmB,CAAC,KAAc;IAChD,IAAI,CAAC;QACH,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAE3B,OAAO,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,IAAI,eAAe,CAAC;QACzD,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAEvC,MAAM,QAAQ,GAAG,KAAY,CAAC;YAC9B,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACrB,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAClC,CAAC;YACD,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;gBACnB,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAChC,CAAC;YAED,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YACjD,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,gCAAgC,CAAC;YAC1C,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAAC,OAAO,YAAY,EAAE,CAAC;QACtB,eAAM,CAAC,KAAK,CAAC,kCAAkC,EAAE,YAAY,CAAC,CAAC;QAC/D,OAAO,iCAAiC,CAAC;IAC3C,CAAC;AACH,CAAC;AAOD,SAAgB,oBAAoB,CAAC,YAAoB;IACvD,OAAO,IAAA,mDAAwB,EAAC,YAAY,CAAC,CAAC;AAChD,CAAC;AAMD,SAAgB,mBAAmB,CAAC,KAAc;IAChD,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC3C,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;AACvC,CAAC"} \ No newline at end of file diff --git a/dist/telemetry/event-tracker.d.ts b/dist/telemetry/event-tracker.d.ts new file mode 100644 index 0000000..d3a6a43 --- /dev/null +++ b/dist/telemetry/event-tracker.d.ts @@ -0,0 +1,71 @@ +import { TelemetryEvent, WorkflowTelemetry, WorkflowMutationRecord } from './telemetry-types'; +export declare class TelemetryEventTracker { + private getUserId; + private isEnabled; + private rateLimiter; + private validator; + private eventQueue; + private workflowQueue; + private mutationQueue; + private previousTool?; + private previousToolTimestamp; + private performanceMetrics; + constructor(getUserId: () => string, isEnabled: () => boolean); + trackToolUsage(toolName: string, success: boolean, duration?: number): void; + trackWorkflowCreation(workflow: any, validationPassed: boolean): Promise; + trackError(errorType: string, context: string, toolName?: string, errorMessage?: string): void; + trackEvent(eventName: string, properties: Record, checkRateLimit?: boolean): void; + trackSessionStart(startupData?: { + durationMs?: number; + checkpoints?: string[]; + errorCount?: number; + }): void; + trackStartupComplete(): void; + private detectCloudPlatform; + trackSearchQuery(query: string, resultsFound: number, searchType: string): void; + trackValidationDetails(nodeType: string, errorType: string, details: Record): void; + trackToolSequence(previousTool: string, currentTool: string, timeDelta: number): void; + trackNodeConfiguration(nodeType: string, propertiesSet: number, usedDefaults: boolean): void; + trackPerformanceMetric(operation: string, duration: number, metadata?: Record): void; + updateToolSequence(toolName: string): void; + getEventQueue(): TelemetryEvent[]; + getWorkflowQueue(): WorkflowTelemetry[]; + getMutationQueue(): WorkflowMutationRecord[]; + clearEventQueue(): void; + clearWorkflowQueue(): void; + clearMutationQueue(): void; + enqueueMutation(mutation: WorkflowMutationRecord): void; + getMutationQueueSize(): number; + getStats(): { + rateLimiter: { + currentEvents: number; + maxEvents: number; + windowMs: number; + droppedEvents: number; + utilizationPercent: number; + remainingCapacity: number; + arraySize: number; + maxArraySize: number; + memoryUsagePercent: number; + }; + validator: { + errors: number; + successes: number; + total: number; + errorRate: number; + }; + eventQueueSize: number; + workflowQueueSize: number; + mutationQueueSize: number; + performanceMetrics: Record; + }; + private recordPerformanceMetric; + private getPerformanceStats; + private categorizeError; + private categorizeConfigComplexity; + private getPackageVersion; + private sanitizeErrorType; + private sanitizeContext; + private sanitizeErrorMessage; +} +//# sourceMappingURL=event-tracker.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/event-tracker.d.ts.map b/dist/telemetry/event-tracker.d.ts.map new file mode 100644 index 0000000..f64972f --- /dev/null +++ b/dist/telemetry/event-tracker.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"event-tracker.d.ts","sourceRoot":"","sources":["../../src/telemetry/event-tracker.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAU9F,qBAAa,qBAAqB;IAW9B,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,SAAS;IAXnB,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,aAAa,CAA2B;IAChD,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,qBAAqB,CAAa;IAC1C,OAAO,CAAC,kBAAkB,CAAoC;gBAGpD,SAAS,EAAE,MAAM,MAAM,EACvB,SAAS,EAAE,MAAM,OAAO;IASlC,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAkCrE,qBAAqB,CAAC,QAAQ,EAAE,GAAG,EAAE,gBAAgB,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA6DpF,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI;IAkB9F,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,cAAc,GAAE,OAAc,GAAG,IAAI;IAyBpG,iBAAiB,CAAC,WAAW,CAAC,EAAE;QAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;QACvB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,IAAI;IAsBR,oBAAoB,IAAI,IAAI;IAY5B,OAAO,CAAC,mBAAmB;IAe3B,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAe/E,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAc/F,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAerF,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,IAAI;IAc5F,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAkBjG,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAa1C,aAAa,IAAI,cAAc,EAAE;IAOjC,gBAAgB,IAAI,iBAAiB,EAAE;IAOvC,gBAAgB,IAAI,sBAAsB,EAAE;IAO5C,eAAe,IAAI,IAAI;IAOvB,kBAAkB,IAAI,IAAI;IAO1B,kBAAkB,IAAI,IAAI;IAO1B,eAAe,CAAC,QAAQ,EAAE,sBAAsB,GAAG,IAAI;IAQvD,oBAAoB,IAAI,MAAM;IAO9B,QAAQ;;;;;;;;;;;;;;;;;;;;;;;IAcR,OAAO,CAAC,uBAAuB;IAiB/B,OAAO,CAAC,mBAAmB;IA0B3B,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,iBAAiB;IA2BzB,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,oBAAoB;CAG7B"} \ No newline at end of file diff --git a/dist/telemetry/event-tracker.js b/dist/telemetry/event-tracker.js new file mode 100644 index 0000000..2dd22d4 --- /dev/null +++ b/dist/telemetry/event-tracker.js @@ -0,0 +1,356 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TelemetryEventTracker = void 0; +const workflow_sanitizer_1 = require("./workflow-sanitizer"); +const rate_limiter_1 = require("./rate-limiter"); +const event_validator_1 = require("./event-validator"); +const telemetry_error_1 = require("./telemetry-error"); +const logger_1 = require("../utils/logger"); +const fs_1 = require("fs"); +const path_1 = require("path"); +const error_sanitization_utils_1 = require("./error-sanitization-utils"); +class TelemetryEventTracker { + constructor(getUserId, isEnabled) { + this.getUserId = getUserId; + this.isEnabled = isEnabled; + this.eventQueue = []; + this.workflowQueue = []; + this.mutationQueue = []; + this.previousToolTimestamp = 0; + this.performanceMetrics = new Map(); + this.rateLimiter = new rate_limiter_1.TelemetryRateLimiter(); + this.validator = new event_validator_1.TelemetryEventValidator(); + } + trackToolUsage(toolName, success, duration) { + if (!this.isEnabled()) + return; + if (!this.rateLimiter.allow()) { + logger_1.logger.debug(`Rate limited: tool_used event for ${toolName}`); + return; + } + if (duration !== undefined) { + this.recordPerformanceMetric(toolName, duration); + } + const event = { + user_id: this.getUserId(), + event: 'tool_used', + properties: { + tool: toolName.replace(/[^a-zA-Z0-9_-]/g, '_'), + success, + duration: duration || 0, + } + }; + const validated = this.validator.validateEvent(event); + if (validated) { + this.eventQueue.push(validated); + } + } + async trackWorkflowCreation(workflow, validationPassed) { + if (!this.isEnabled()) + return; + if (!this.rateLimiter.allow()) { + logger_1.logger.debug('Rate limited: workflow creation event'); + return; + } + if (!validationPassed) { + this.trackEvent('workflow_validation_failed', { + nodeCount: workflow.nodes?.length || 0, + }); + return; + } + try { + const sanitized = workflow_sanitizer_1.WorkflowSanitizer.sanitizeWorkflow(workflow); + const telemetryData = { + user_id: this.getUserId(), + workflow_hash: sanitized.workflowHash, + node_count: sanitized.nodeCount, + node_types: sanitized.nodeTypes, + has_trigger: sanitized.hasTrigger, + has_webhook: sanitized.hasWebhook, + complexity: sanitized.complexity, + sanitized_workflow: { + nodes: sanitized.nodes, + connections: sanitized.connections, + }, + }; + const validated = this.validator.validateWorkflow(telemetryData); + if (validated) { + this.workflowQueue.push(validated); + this.trackEvent('workflow_created', { + nodeCount: sanitized.nodeCount, + nodeTypes: sanitized.nodeTypes.length, + complexity: sanitized.complexity, + hasTrigger: sanitized.hasTrigger, + hasWebhook: sanitized.hasWebhook, + }); + } + } + catch (error) { + logger_1.logger.debug('Failed to track workflow creation:', error); + throw new telemetry_error_1.TelemetryError(telemetry_error_1.TelemetryErrorType.VALIDATION_ERROR, 'Failed to sanitize workflow', { error: error instanceof Error ? error.message : String(error) }); + } + } + trackError(errorType, context, toolName, errorMessage) { + if (!this.isEnabled()) + return; + this.trackEvent('error_occurred', { + errorType: this.sanitizeErrorType(errorType), + context: this.sanitizeContext(context), + tool: toolName ? toolName.replace(/[^a-zA-Z0-9_-]/g, '_') : undefined, + error: errorMessage ? this.sanitizeErrorMessage(errorMessage) : undefined, + mcpMode: process.env.MCP_MODE || 'stdio', + platform: process.platform + }, false); + } + trackEvent(eventName, properties, checkRateLimit = true) { + if (!this.isEnabled()) + return; + if (checkRateLimit && !this.rateLimiter.allow()) { + logger_1.logger.debug(`Rate limited: ${eventName} event`); + return; + } + const event = { + user_id: this.getUserId(), + event: eventName, + properties, + }; + const validated = this.validator.validateEvent(event); + if (validated) { + this.eventQueue.push(validated); + } + } + trackSessionStart(startupData) { + if (!this.isEnabled()) + return; + this.trackEvent('session_start', { + version: this.getPackageVersion(), + platform: process.platform, + arch: process.arch, + nodeVersion: process.version, + isDocker: process.env.IS_DOCKER === 'true', + cloudPlatform: this.detectCloudPlatform(), + mcpMode: process.env.MCP_MODE || 'stdio', + startupDurationMs: startupData?.durationMs, + checkpointsPassed: startupData?.checkpoints, + startupErrorCount: startupData?.errorCount || 0, + }); + } + trackStartupComplete() { + if (!this.isEnabled()) + return; + this.trackEvent('startup_completed', { + version: this.getPackageVersion(), + }); + } + detectCloudPlatform() { + if (process.env.RAILWAY_ENVIRONMENT) + return 'railway'; + if (process.env.RENDER) + return 'render'; + if (process.env.FLY_APP_NAME) + return 'fly'; + if (process.env.HEROKU_APP_NAME) + return 'heroku'; + if (process.env.AWS_EXECUTION_ENV) + return 'aws'; + if (process.env.KUBERNETES_SERVICE_HOST) + return 'kubernetes'; + if (process.env.GOOGLE_CLOUD_PROJECT) + return 'gcp'; + if (process.env.AZURE_FUNCTIONS_ENVIRONMENT) + return 'azure'; + return null; + } + trackSearchQuery(query, resultsFound, searchType) { + if (!this.isEnabled()) + return; + this.trackEvent('search_query', { + query: query.substring(0, 100), + resultsFound, + searchType, + hasResults: resultsFound > 0, + isZeroResults: resultsFound === 0 + }); + } + trackValidationDetails(nodeType, errorType, details) { + if (!this.isEnabled()) + return; + this.trackEvent('validation_details', { + nodeType: nodeType.replace(/[^a-zA-Z0-9_.-]/g, '_'), + errorType: this.sanitizeErrorType(errorType), + errorCategory: this.categorizeError(errorType), + details + }); + } + trackToolSequence(previousTool, currentTool, timeDelta) { + if (!this.isEnabled()) + return; + this.trackEvent('tool_sequence', { + previousTool: previousTool.replace(/[^a-zA-Z0-9_-]/g, '_'), + currentTool: currentTool.replace(/[^a-zA-Z0-9_-]/g, '_'), + timeDelta: Math.min(timeDelta, 300000), + isSlowTransition: timeDelta > 10000, + sequence: `${previousTool}->${currentTool}` + }); + } + trackNodeConfiguration(nodeType, propertiesSet, usedDefaults) { + if (!this.isEnabled()) + return; + this.trackEvent('node_configuration', { + nodeType: nodeType.replace(/[^a-zA-Z0-9_.-]/g, '_'), + propertiesSet, + usedDefaults, + complexity: this.categorizeConfigComplexity(propertiesSet) + }); + } + trackPerformanceMetric(operation, duration, metadata) { + if (!this.isEnabled()) + return; + this.recordPerformanceMetric(operation, duration); + this.trackEvent('performance_metric', { + operation: operation.replace(/[^a-zA-Z0-9_-]/g, '_'), + duration, + isSlow: duration > 1000, + isVerySlow: duration > 5000, + metadata + }); + } + updateToolSequence(toolName) { + if (this.previousTool) { + const timeDelta = Date.now() - this.previousToolTimestamp; + this.trackToolSequence(this.previousTool, toolName, timeDelta); + } + this.previousTool = toolName; + this.previousToolTimestamp = Date.now(); + } + getEventQueue() { + return [...this.eventQueue]; + } + getWorkflowQueue() { + return [...this.workflowQueue]; + } + getMutationQueue() { + return [...this.mutationQueue]; + } + clearEventQueue() { + this.eventQueue = []; + } + clearWorkflowQueue() { + this.workflowQueue = []; + } + clearMutationQueue() { + this.mutationQueue = []; + } + enqueueMutation(mutation) { + if (!this.isEnabled()) + return; + this.mutationQueue.push(mutation); + } + getMutationQueueSize() { + return this.mutationQueue.length; + } + getStats() { + return { + rateLimiter: this.rateLimiter.getStats(), + validator: this.validator.getStats(), + eventQueueSize: this.eventQueue.length, + workflowQueueSize: this.workflowQueue.length, + mutationQueueSize: this.mutationQueue.length, + performanceMetrics: this.getPerformanceStats() + }; + } + recordPerformanceMetric(operation, duration) { + if (!this.performanceMetrics.has(operation)) { + this.performanceMetrics.set(operation, []); + } + const metrics = this.performanceMetrics.get(operation); + metrics.push(duration); + if (metrics.length > 100) { + metrics.shift(); + } + } + getPerformanceStats() { + const stats = {}; + for (const [operation, durations] of this.performanceMetrics.entries()) { + if (durations.length === 0) + continue; + const sorted = [...durations].sort((a, b) => a - b); + const sum = sorted.reduce((a, b) => a + b, 0); + stats[operation] = { + count: sorted.length, + min: sorted[0], + max: sorted[sorted.length - 1], + avg: Math.round(sum / sorted.length), + p50: sorted[Math.floor(sorted.length * 0.5)], + p95: sorted[Math.floor(sorted.length * 0.95)], + p99: sorted[Math.floor(sorted.length * 0.99)] + }; + } + return stats; + } + categorizeError(errorType) { + const lowerError = errorType.toLowerCase(); + if (lowerError.includes('type')) + return 'type_error'; + if (lowerError.includes('validation')) + return 'validation_error'; + if (lowerError.includes('required')) + return 'required_field_error'; + if (lowerError.includes('connection')) + return 'connection_error'; + if (lowerError.includes('expression')) + return 'expression_error'; + return 'other_error'; + } + categorizeConfigComplexity(propertiesSet) { + if (propertiesSet === 0) + return 'defaults_only'; + if (propertiesSet <= 3) + return 'simple'; + if (propertiesSet <= 10) + return 'moderate'; + return 'complex'; + } + getPackageVersion() { + try { + const possiblePaths = [ + (0, path_1.resolve)(__dirname, '..', '..', 'package.json'), + (0, path_1.resolve)(process.cwd(), 'package.json'), + (0, path_1.resolve)(__dirname, '..', '..', '..', 'package.json') + ]; + for (const packagePath of possiblePaths) { + if ((0, fs_1.existsSync)(packagePath)) { + const packageJson = JSON.parse((0, fs_1.readFileSync)(packagePath, 'utf-8')); + if (packageJson.version) { + return packageJson.version; + } + } + } + return 'unknown'; + } + catch (error) { + logger_1.logger.debug('Failed to get package version:', error); + return 'unknown'; + } + } + sanitizeErrorType(errorType) { + return errorType.replace(/[^a-zA-Z0-9_-]/g, '_').substring(0, 50); + } + sanitizeContext(context) { + let sanitized = context + .replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g, '[EMAIL]') + .replace(/\b[a-zA-Z0-9_-]{32,}/g, '[KEY]') + .replace(/(https?:\/\/)([^\s\/]+)(\/[^\s]*)?/gi, (match, protocol, domain, path) => { + return '[URL]' + (path || ''); + }); + if (sanitized.length > 100) { + sanitized = sanitized.substring(0, 100); + } + return sanitized; + } + sanitizeErrorMessage(errorMessage) { + return (0, error_sanitization_utils_1.sanitizeErrorMessageCore)(errorMessage); + } +} +exports.TelemetryEventTracker = TelemetryEventTracker; +//# sourceMappingURL=event-tracker.js.map \ No newline at end of file diff --git a/dist/telemetry/event-tracker.js.map b/dist/telemetry/event-tracker.js.map new file mode 100644 index 0000000..9f74aa5 --- /dev/null +++ b/dist/telemetry/event-tracker.js.map @@ -0,0 +1 @@ +{"version":3,"file":"event-tracker.js","sourceRoot":"","sources":["../../src/telemetry/event-tracker.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/telemetry/event-validator.d.ts b/dist/telemetry/event-validator.d.ts new file mode 100644 index 0000000..02edbc7 --- /dev/null +++ b/dist/telemetry/event-validator.d.ts @@ -0,0 +1,78 @@ +import { z } from 'zod'; +import { TelemetryEvent, WorkflowTelemetry } from './telemetry-types'; +export declare const telemetryEventSchema: z.ZodObject<{ + user_id: z.ZodString; + event: z.ZodString; + properties: z.ZodEffects, Record, Record>; + created_at: z.ZodOptional; +}, "strip", z.ZodTypeAny, { + properties: Record; + user_id: string; + event: string; + created_at?: string | undefined; +}, { + properties: Record; + user_id: string; + event: string; + created_at?: string | undefined; +}>; +export declare const workflowTelemetrySchema: z.ZodObject<{ + user_id: z.ZodString; + workflow_hash: z.ZodString; + node_count: z.ZodNumber; + node_types: z.ZodArray; + has_trigger: z.ZodBoolean; + has_webhook: z.ZodBoolean; + complexity: z.ZodEnum<["simple", "medium", "complex"]>; + sanitized_workflow: z.ZodObject<{ + nodes: z.ZodArray; + connections: z.ZodRecord; + }, "strip", z.ZodTypeAny, { + nodes: any[]; + connections: Record; + }, { + nodes: any[]; + connections: Record; + }>; + created_at: z.ZodOptional; +}, "strip", z.ZodTypeAny, { + complexity: "simple" | "medium" | "complex"; + user_id: string; + workflow_hash: string; + node_count: number; + node_types: string[]; + has_trigger: boolean; + has_webhook: boolean; + sanitized_workflow: { + nodes: any[]; + connections: Record; + }; + created_at?: string | undefined; +}, { + complexity: "simple" | "medium" | "complex"; + user_id: string; + workflow_hash: string; + node_count: number; + node_types: string[]; + has_trigger: boolean; + has_webhook: boolean; + sanitized_workflow: { + nodes: any[]; + connections: Record; + }; + created_at?: string | undefined; +}>; +export declare class TelemetryEventValidator { + private validationErrors; + private validationSuccesses; + validateEvent(event: TelemetryEvent): TelemetryEvent | null; + validateWorkflow(workflow: WorkflowTelemetry): WorkflowTelemetry | null; + getStats(): { + errors: number; + successes: number; + total: number; + errorRate: number; + }; + resetStats(): void; +} +//# sourceMappingURL=event-validator.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/event-validator.d.ts.map b/dist/telemetry/event-validator.d.ts.map new file mode 100644 index 0000000..3c1b0fc --- /dev/null +++ b/dist/telemetry/event-validator.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"event-validator.d.ts","sourceRoot":"","sources":["../../src/telemetry/event-validator.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAyCtE,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;EAK/B,CAAC;AAGH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAalC,CAAC;AA0JH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,mBAAmB,CAAa;IAKxC,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,cAAc,GAAG,IAAI;IAkC3D,gBAAgB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,iBAAiB,GAAG,IAAI;IAmBvE,QAAQ;;;;;;IAYR,UAAU,IAAI,IAAI;CAInB"} \ No newline at end of file diff --git a/dist/telemetry/event-validator.js b/dist/telemetry/event-validator.js new file mode 100644 index 0000000..4f1e017 --- /dev/null +++ b/dist/telemetry/event-validator.js @@ -0,0 +1,227 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TelemetryEventValidator = exports.workflowTelemetrySchema = exports.telemetryEventSchema = void 0; +const zod_1 = require("zod"); +const logger_1 = require("../utils/logger"); +const sanitizedString = zod_1.z.string().transform(val => { + let sanitized = val.replace(/https?:\/\/[^\s]+/gi, '[URL]'); + sanitized = sanitized.replace(/[a-zA-Z0-9_-]{32,}/g, '[KEY]'); + sanitized = sanitized.replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g, '[EMAIL]'); + return sanitized; +}); +const eventPropertiesSchema = zod_1.z.record(zod_1.z.unknown()).transform(obj => { + const sanitized = {}; + for (const [key, value] of Object.entries(obj)) { + if (isSensitiveKey(key)) { + continue; + } + if (typeof value === 'string') { + sanitized[key] = sanitizedString.parse(value); + } + else if (typeof value === 'number' || typeof value === 'boolean') { + sanitized[key] = value; + } + else if (value === null || value === undefined) { + sanitized[key] = null; + } + else if (typeof value === 'object') { + sanitized[key] = sanitizeNestedObject(value, 3); + } + } + return sanitized; +}); +exports.telemetryEventSchema = zod_1.z.object({ + user_id: zod_1.z.string().min(1).max(64), + event: zod_1.z.string().min(1).max(100).regex(/^[a-zA-Z0-9_-]+$/), + properties: eventPropertiesSchema, + created_at: zod_1.z.string().datetime().optional() +}); +exports.workflowTelemetrySchema = zod_1.z.object({ + user_id: zod_1.z.string().min(1).max(64), + workflow_hash: zod_1.z.string().min(1).max(64), + node_count: zod_1.z.number().int().min(0).max(1000), + node_types: zod_1.z.array(zod_1.z.string()).max(100), + has_trigger: zod_1.z.boolean(), + has_webhook: zod_1.z.boolean(), + complexity: zod_1.z.enum(['simple', 'medium', 'complex']), + sanitized_workflow: zod_1.z.object({ + nodes: zod_1.z.array(zod_1.z.any()).max(1000), + connections: zod_1.z.record(zod_1.z.any()) + }), + created_at: zod_1.z.string().datetime().optional() +}); +const toolUsagePropertiesSchema = zod_1.z.object({ + tool: zod_1.z.string().max(100), + success: zod_1.z.boolean(), + duration: zod_1.z.number().min(0).max(3600000), +}); +const searchQueryPropertiesSchema = zod_1.z.object({ + query: zod_1.z.string().max(100).transform(val => { + let sanitized = val.replace(/https?:\/\/[^\s]+/gi, '[URL]'); + sanitized = sanitized.replace(/[a-zA-Z0-9_-]{32,}/g, '[KEY]'); + sanitized = sanitized.replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g, '[EMAIL]'); + return sanitized; + }), + resultsFound: zod_1.z.number().int().min(0), + searchType: zod_1.z.string().max(50), + hasResults: zod_1.z.boolean(), + isZeroResults: zod_1.z.boolean() +}); +const validationDetailsPropertiesSchema = zod_1.z.object({ + nodeType: zod_1.z.string().max(100), + errorType: zod_1.z.string().max(100), + errorCategory: zod_1.z.string().max(50), + details: zod_1.z.record(zod_1.z.any()).optional() +}); +const performanceMetricPropertiesSchema = zod_1.z.object({ + operation: zod_1.z.string().max(100), + duration: zod_1.z.number().min(0).max(3600000), + isSlow: zod_1.z.boolean(), + isVerySlow: zod_1.z.boolean(), + metadata: zod_1.z.record(zod_1.z.any()).optional() +}); +const startupErrorPropertiesSchema = zod_1.z.object({ + checkpoint: zod_1.z.string().max(100), + errorMessage: zod_1.z.string().max(500), + errorType: zod_1.z.string().max(100), + checkpointsPassed: zod_1.z.array(zod_1.z.string()).max(20), + checkpointsPassedCount: zod_1.z.number().int().min(0).max(20), + startupDuration: zod_1.z.number().min(0).max(300000), + platform: zod_1.z.string().max(50), + arch: zod_1.z.string().max(50), + nodeVersion: zod_1.z.string().max(50), + isDocker: zod_1.z.boolean() +}); +const startupCompletedPropertiesSchema = zod_1.z.object({ + version: zod_1.z.string().max(50) +}); +const EVENT_SCHEMAS = { + 'tool_used': toolUsagePropertiesSchema, + 'search_query': searchQueryPropertiesSchema, + 'validation_details': validationDetailsPropertiesSchema, + 'performance_metric': performanceMetricPropertiesSchema, + 'startup_error': startupErrorPropertiesSchema, + 'startup_completed': startupCompletedPropertiesSchema, +}; +function isSensitiveKey(key) { + const sensitivePatterns = [ + 'password', 'passwd', 'pwd', + 'token', 'jwt', 'bearer', + 'apikey', 'api_key', 'api-key', + 'secret', 'private', + 'credential', 'cred', 'auth', + 'url', 'uri', 'endpoint', 'host', 'hostname', + 'database', 'db', 'connection', 'conn', + 'slack', 'discord', 'telegram', + 'oauth', 'client_secret', 'client-secret', 'clientsecret', + 'access_token', 'access-token', 'accesstoken', + 'refresh_token', 'refresh-token', 'refreshtoken' + ]; + const lowerKey = key.toLowerCase(); + if (sensitivePatterns.includes(lowerKey)) { + return true; + } + if (lowerKey.includes('key') && lowerKey !== 'key') { + const keyPatterns = ['apikey', 'api_key', 'api-key', 'secretkey', 'secret_key', 'privatekey', 'private_key']; + if (keyPatterns.some(pattern => lowerKey.includes(pattern))) { + return true; + } + } + return sensitivePatterns.some(pattern => { + const regex = new RegExp(`(?:^|[_-])${pattern}(?:[_-]|$)`, 'i'); + return regex.test(key) || lowerKey.includes(pattern); + }); +} +function sanitizeNestedObject(obj, maxDepth) { + if (maxDepth <= 0 || !obj || typeof obj !== 'object') { + return '[NESTED]'; + } + if (Array.isArray(obj)) { + return obj.slice(0, 10).map(item => typeof item === 'object' ? sanitizeNestedObject(item, maxDepth - 1) : item); + } + const sanitized = {}; + let keyCount = 0; + for (const [key, value] of Object.entries(obj)) { + if (keyCount++ >= 20) { + sanitized['...'] = 'truncated'; + break; + } + if (isSensitiveKey(key)) { + continue; + } + if (typeof value === 'string') { + sanitized[key] = sanitizedString.parse(value); + } + else if (typeof value === 'object' && value !== null) { + sanitized[key] = sanitizeNestedObject(value, maxDepth - 1); + } + else { + sanitized[key] = value; + } + } + return sanitized; +} +class TelemetryEventValidator { + constructor() { + this.validationErrors = 0; + this.validationSuccesses = 0; + } + validateEvent(event) { + try { + const specificSchema = EVENT_SCHEMAS[event.event]; + if (specificSchema) { + const validatedProperties = specificSchema.safeParse(event.properties); + if (!validatedProperties.success) { + logger_1.logger.debug(`Event validation failed for ${event.event}:`, validatedProperties.error.errors); + this.validationErrors++; + return null; + } + event.properties = validatedProperties.data; + } + const validated = exports.telemetryEventSchema.parse(event); + this.validationSuccesses++; + return validated; + } + catch (error) { + if (error instanceof zod_1.z.ZodError) { + logger_1.logger.debug('Event validation error:', error.errors); + } + else { + logger_1.logger.debug('Unexpected validation error:', error); + } + this.validationErrors++; + return null; + } + } + validateWorkflow(workflow) { + try { + const validated = exports.workflowTelemetrySchema.parse(workflow); + this.validationSuccesses++; + return validated; + } + catch (error) { + if (error instanceof zod_1.z.ZodError) { + logger_1.logger.debug('Workflow validation error:', error.errors); + } + else { + logger_1.logger.debug('Unexpected workflow validation error:', error); + } + this.validationErrors++; + return null; + } + } + getStats() { + return { + errors: this.validationErrors, + successes: this.validationSuccesses, + total: this.validationErrors + this.validationSuccesses, + errorRate: this.validationErrors / (this.validationErrors + this.validationSuccesses) || 0 + }; + } + resetStats() { + this.validationErrors = 0; + this.validationSuccesses = 0; + } +} +exports.TelemetryEventValidator = TelemetryEventValidator; +//# sourceMappingURL=event-validator.js.map \ No newline at end of file diff --git a/dist/telemetry/event-validator.js.map b/dist/telemetry/event-validator.js.map new file mode 100644 index 0000000..b3c4f1b --- /dev/null +++ b/dist/telemetry/event-validator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"event-validator.js","sourceRoot":"","sources":["../../src/telemetry/event-validator.ts"],"names":[],"mappings":";;;AAKA,6BAAwB;AAExB,4CAAyC;AAGzC,MAAM,eAAe,GAAG,OAAC,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE;IAEjD,IAAI,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,qBAAqB,EAAE,OAAO,CAAC,CAAC;IAE5D,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,qBAAqB,EAAE,OAAO,CAAC,CAAC;IAE9D,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,iDAAiD,EAAE,SAAS,CAAC,CAAC;IAC5F,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC,CAAC;AAGH,MAAM,qBAAqB,GAAG,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE;IAClE,MAAM,SAAS,GAAwB,EAAE,CAAC;IAE1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAE/C,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,SAAS;QACX,CAAC;QAGD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,SAAS,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAChD,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;YACnE,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACzB,CAAC;aAAM,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACjD,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;QACxB,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAErC,SAAS,CAAC,GAAG,CAAC,GAAG,oBAAoB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC,CAAC;AAGU,QAAA,oBAAoB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC3C,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IAClC,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC;IAC3D,UAAU,EAAE,qBAAqB;IACjC,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAC7C,CAAC,CAAC;AAGU,QAAA,uBAAuB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC9C,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IAClC,aAAa,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IACxC,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;IAC7C,UAAU,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACxC,WAAW,EAAE,OAAC,CAAC,OAAO,EAAE;IACxB,WAAW,EAAE,OAAC,CAAC,OAAO,EAAE;IACxB,UAAU,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IACnD,kBAAkB,EAAE,OAAC,CAAC,MAAM,CAAC;QAC3B,KAAK,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;QACjC,WAAW,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,GAAG,EAAE,CAAC;KAC/B,CAAC;IACF,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAC7C,CAAC,CAAC;AAGH,MAAM,yBAAyB,GAAG,OAAC,CAAC,MAAM,CAAC;IACzC,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;IACzB,OAAO,EAAE,OAAC,CAAC,OAAO,EAAE;IACpB,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;CACzC,CAAC,CAAC;AAEH,MAAM,2BAA2B,GAAG,OAAC,CAAC,MAAM,CAAC;IAC3C,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE;QAEzC,IAAI,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,qBAAqB,EAAE,OAAO,CAAC,CAAC;QAC5D,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,qBAAqB,EAAE,OAAO,CAAC,CAAC;QAC9D,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,iDAAiD,EAAE,SAAS,CAAC,CAAC;QAC5F,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IACF,YAAY,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrC,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IAC9B,UAAU,EAAE,OAAC,CAAC,OAAO,EAAE;IACvB,aAAa,EAAE,OAAC,CAAC,OAAO,EAAE;CAC3B,CAAC,CAAC;AAEH,MAAM,iCAAiC,GAAG,OAAC,CAAC,MAAM,CAAC;IACjD,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;IAC7B,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;IAC9B,aAAa,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IACjC,OAAO,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE;CACtC,CAAC,CAAC;AAEH,MAAM,iCAAiC,GAAG,OAAC,CAAC,MAAM,CAAC;IACjD,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;IAC9B,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;IACxC,MAAM,EAAE,OAAC,CAAC,OAAO,EAAE;IACnB,UAAU,EAAE,OAAC,CAAC,OAAO,EAAE;IACvB,QAAQ,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE;CACvC,CAAC,CAAC;AAGH,MAAM,4BAA4B,GAAG,OAAC,CAAC,MAAM,CAAC;IAC5C,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;IAC/B,YAAY,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;IACjC,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;IAC9B,iBAAiB,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IAC9C,sBAAsB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IACvD,eAAe,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;IAC9C,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IAC5B,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IACxB,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IAC/B,QAAQ,EAAE,OAAC,CAAC,OAAO,EAAE;CACtB,CAAC,CAAC;AAGH,MAAM,gCAAgC,GAAG,OAAC,CAAC,MAAM,CAAC;IAChD,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;CAC5B,CAAC,CAAC;AAGH,MAAM,aAAa,GAAqC;IACtD,WAAW,EAAE,yBAAyB;IACtC,cAAc,EAAE,2BAA2B;IAC3C,oBAAoB,EAAE,iCAAiC;IACvD,oBAAoB,EAAE,iCAAiC;IACvD,eAAe,EAAE,4BAA4B;IAC7C,mBAAmB,EAAE,gCAAgC;CACtD,CAAC;AAMF,SAAS,cAAc,CAAC,GAAW;IACjC,MAAM,iBAAiB,GAAG;QAExB,UAAU,EAAE,QAAQ,EAAE,KAAK;QAC3B,OAAO,EAAE,KAAK,EAAE,QAAQ;QACxB,QAAQ,EAAE,SAAS,EAAE,SAAS;QAC9B,QAAQ,EAAE,SAAS;QACnB,YAAY,EAAE,MAAM,EAAE,MAAM;QAG5B,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU;QAC5C,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM;QAGtC,OAAO,EAAE,SAAS,EAAE,UAAU;QAC9B,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc;QACzD,cAAc,EAAE,cAAc,EAAE,aAAa;QAC7C,eAAe,EAAE,eAAe,EAAE,cAAc;KACjD,CAAC;IAEF,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAGnC,IAAI,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAGD,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;QAEnD,MAAM,WAAW,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;QAC7G,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;YAC5D,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAGD,OAAO,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;QAEtC,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,aAAa,OAAO,YAAY,EAAE,GAAG,CAAC,CAAC;QAChE,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC;AAKD,SAAS,oBAAoB,CAAC,GAAQ,EAAE,QAAgB;IACtD,IAAI,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACrD,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CACjC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,oBAAoB,CAAC,IAAI,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAC3E,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAwB,EAAE,CAAC;IAC1C,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC;YACrB,SAAS,CAAC,KAAK,CAAC,GAAG,WAAW,CAAC;YAC/B,MAAM;QACR,CAAC;QAED,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,SAAS;QACX,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,SAAS,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAChD,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACvD,SAAS,CAAC,GAAG,CAAC,GAAG,oBAAoB,CAAC,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC;QAC7D,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACzB,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAa,uBAAuB;IAApC;QACU,qBAAgB,GAAW,CAAC,CAAC;QAC7B,wBAAmB,GAAW,CAAC,CAAC;IA0E1C,CAAC;IArEC,aAAa,CAAC,KAAqB;QACjC,IAAI,CAAC;YAEH,MAAM,cAAc,GAAG,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAElD,IAAI,cAAc,EAAE,CAAC;gBAEnB,MAAM,mBAAmB,GAAG,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBACvE,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC;oBACjC,eAAM,CAAC,KAAK,CAAC,+BAA+B,KAAK,CAAC,KAAK,GAAG,EAAE,mBAAmB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;oBAC9F,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACxB,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,KAAK,CAAC,UAAU,GAAG,mBAAmB,CAAC,IAAI,CAAC;YAC9C,CAAC;YAGD,MAAM,SAAS,GAAG,4BAAoB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACpD,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;gBAChC,eAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YACxD,CAAC;iBAAM,CAAC;gBACN,eAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YACtD,CAAC;YACD,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAKD,gBAAgB,CAAC,QAA2B;QAC1C,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,+BAAuB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC1D,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;gBAChC,eAAM,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAC3D,CAAC;iBAAM,CAAC;gBACN,eAAM,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAC;YAC/D,CAAC;YACD,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAKD,QAAQ;QACN,OAAO;YACL,MAAM,EAAE,IAAI,CAAC,gBAAgB;YAC7B,SAAS,EAAE,IAAI,CAAC,mBAAmB;YACnC,KAAK,EAAE,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,mBAAmB;YACvD,SAAS,EAAE,IAAI,CAAC,gBAAgB,GAAG,CAAC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC;SAC3F,CAAC;IACJ,CAAC;IAKD,UAAU;QACR,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;IAC/B,CAAC;CACF;AA5ED,0DA4EC"} \ No newline at end of file diff --git a/dist/telemetry/index.d.ts b/dist/telemetry/index.d.ts new file mode 100644 index 0000000..4382079 --- /dev/null +++ b/dist/telemetry/index.d.ts @@ -0,0 +1,5 @@ +export { TelemetryManager, telemetry } from './telemetry-manager'; +export { TelemetryConfigManager } from './config-manager'; +export { WorkflowSanitizer } from './workflow-sanitizer'; +export type { TelemetryConfig } from './config-manager'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/index.d.ts.map b/dist/telemetry/index.d.ts.map new file mode 100644 index 0000000..e5a545b --- /dev/null +++ b/dist/telemetry/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/telemetry/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC"} \ No newline at end of file diff --git a/dist/telemetry/index.js b/dist/telemetry/index.js new file mode 100644 index 0000000..9f49dcd --- /dev/null +++ b/dist/telemetry/index.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.WorkflowSanitizer = exports.TelemetryConfigManager = exports.telemetry = exports.TelemetryManager = void 0; +var telemetry_manager_1 = require("./telemetry-manager"); +Object.defineProperty(exports, "TelemetryManager", { enumerable: true, get: function () { return telemetry_manager_1.TelemetryManager; } }); +Object.defineProperty(exports, "telemetry", { enumerable: true, get: function () { return telemetry_manager_1.telemetry; } }); +var config_manager_1 = require("./config-manager"); +Object.defineProperty(exports, "TelemetryConfigManager", { enumerable: true, get: function () { return config_manager_1.TelemetryConfigManager; } }); +var workflow_sanitizer_1 = require("./workflow-sanitizer"); +Object.defineProperty(exports, "WorkflowSanitizer", { enumerable: true, get: function () { return workflow_sanitizer_1.WorkflowSanitizer; } }); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/telemetry/index.js.map b/dist/telemetry/index.js.map new file mode 100644 index 0000000..d786dd1 --- /dev/null +++ b/dist/telemetry/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/telemetry/index.ts"],"names":[],"mappings":";;;AAKA,yDAAkE;AAAzD,qHAAA,gBAAgB,OAAA;AAAE,8GAAA,SAAS,OAAA;AACpC,mDAA0D;AAAjD,wHAAA,sBAAsB,OAAA;AAC/B,2DAAyD;AAAhD,uHAAA,iBAAiB,OAAA"} \ No newline at end of file diff --git a/dist/telemetry/intent-classifier.d.ts b/dist/telemetry/intent-classifier.d.ts new file mode 100644 index 0000000..4830f30 --- /dev/null +++ b/dist/telemetry/intent-classifier.d.ts @@ -0,0 +1,11 @@ +import { DiffOperation } from '../types/workflow-diff.js'; +import { IntentClassification } from './mutation-types.js'; +export declare class IntentClassifier { + classify(operations: DiffOperation[], userIntent?: string): IntentClassification; + private classifyFromText; + private classifyFromOperations; + getConfidence(classification: IntentClassification, operations: DiffOperation[], userIntent?: string): number; + getDescription(classification: IntentClassification): string; +} +export declare const intentClassifier: IntentClassifier; +//# sourceMappingURL=intent-classifier.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/intent-classifier.d.ts.map b/dist/telemetry/intent-classifier.d.ts.map new file mode 100644 index 0000000..28be02a --- /dev/null +++ b/dist/telemetry/intent-classifier.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"intent-classifier.d.ts","sourceRoot":"","sources":["../../src/telemetry/intent-classifier.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAK3D,qBAAa,gBAAgB;IAI3B,QAAQ,CAAC,UAAU,EAAE,aAAa,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,oBAAoB;IAoBhF,OAAO,CAAC,gBAAgB;IA8DxB,OAAO,CAAC,sBAAsB;IA2E9B,aAAa,CACX,cAAc,EAAE,oBAAoB,EACpC,UAAU,EAAE,aAAa,EAAE,EAC3B,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM;IA2CT,cAAc,CAAC,cAAc,EAAE,oBAAoB,GAAG,MAAM;CAkB7D;AAKD,eAAO,MAAM,gBAAgB,kBAAyB,CAAC"} \ No newline at end of file diff --git a/dist/telemetry/intent-classifier.js b/dist/telemetry/intent-classifier.js new file mode 100644 index 0000000..074b67c --- /dev/null +++ b/dist/telemetry/intent-classifier.js @@ -0,0 +1,141 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.intentClassifier = exports.IntentClassifier = void 0; +const mutation_types_js_1 = require("./mutation-types.js"); +class IntentClassifier { + classify(operations, userIntent) { + if (operations.length === 0) { + return mutation_types_js_1.IntentClassification.UNKNOWN; + } + if (userIntent) { + const textClassification = this.classifyFromText(userIntent); + if (textClassification !== mutation_types_js_1.IntentClassification.UNKNOWN) { + return textClassification; + } + } + return this.classifyFromOperations(operations); + } + classifyFromText(intent) { + const lowerIntent = intent.toLowerCase(); + if (lowerIntent.includes('fix') || + lowerIntent.includes('resolve') || + lowerIntent.includes('correct') || + lowerIntent.includes('repair') || + lowerIntent.includes('error')) { + return mutation_types_js_1.IntentClassification.FIX_VALIDATION; + } + if (lowerIntent.includes('add') || + lowerIntent.includes('create') || + lowerIntent.includes('insert') || + lowerIntent.includes('new node')) { + return mutation_types_js_1.IntentClassification.ADD_FUNCTIONALITY; + } + if (lowerIntent.includes('update') || + lowerIntent.includes('change') || + lowerIntent.includes('modify') || + lowerIntent.includes('configure') || + lowerIntent.includes('set')) { + return mutation_types_js_1.IntentClassification.MODIFY_CONFIGURATION; + } + if (lowerIntent.includes('connect') || + lowerIntent.includes('reconnect') || + lowerIntent.includes('rewire') || + lowerIntent.includes('reroute') || + lowerIntent.includes('link')) { + return mutation_types_js_1.IntentClassification.REWIRE_LOGIC; + } + if (lowerIntent.includes('remove') || + lowerIntent.includes('delete') || + lowerIntent.includes('clean') || + lowerIntent.includes('disable')) { + return mutation_types_js_1.IntentClassification.CLEANUP; + } + return mutation_types_js_1.IntentClassification.UNKNOWN; + } + classifyFromOperations(operations) { + const opTypes = operations.map((op) => op.type); + const opTypeSet = new Set(opTypes); + if (opTypeSet.has('addNode') && opTypeSet.has('addConnection')) { + return mutation_types_js_1.IntentClassification.ADD_FUNCTIONALITY; + } + if (opTypeSet.has('addNode') && !opTypeSet.has('removeNode')) { + return mutation_types_js_1.IntentClassification.ADD_FUNCTIONALITY; + } + if (opTypeSet.has('removeNode') || opTypeSet.has('removeConnection')) { + return mutation_types_js_1.IntentClassification.CLEANUP; + } + if (opTypeSet.has('disableNode')) { + return mutation_types_js_1.IntentClassification.CLEANUP; + } + if (opTypeSet.has('rewireConnection') || + opTypeSet.has('replaceConnections') || + (opTypeSet.has('addConnection') && opTypeSet.has('removeConnection'))) { + return mutation_types_js_1.IntentClassification.REWIRE_LOGIC; + } + if (opTypeSet.has('updateNode') && opTypes.every((t) => t === 'updateNode')) { + return mutation_types_js_1.IntentClassification.MODIFY_CONFIGURATION; + } + if (opTypeSet.has('updateSettings') || + opTypeSet.has('updateName') || + opTypeSet.has('addTag') || + opTypeSet.has('removeTag')) { + return mutation_types_js_1.IntentClassification.MODIFY_CONFIGURATION; + } + if (opTypeSet.has('updateNode')) { + return mutation_types_js_1.IntentClassification.MODIFY_CONFIGURATION; + } + if (opTypeSet.has('moveNode')) { + return mutation_types_js_1.IntentClassification.MODIFY_CONFIGURATION; + } + if (opTypeSet.has('enableNode')) { + return mutation_types_js_1.IntentClassification.FIX_VALIDATION; + } + if (opTypeSet.has('cleanStaleConnections')) { + return mutation_types_js_1.IntentClassification.CLEANUP; + } + return mutation_types_js_1.IntentClassification.UNKNOWN; + } + getConfidence(classification, operations, userIntent) { + if (userIntent && this.classifyFromText(userIntent) === classification) { + return 0.9; + } + if (classification !== mutation_types_js_1.IntentClassification.UNKNOWN) { + const opTypes = new Set(operations.map((op) => op.type)); + if (classification === mutation_types_js_1.IntentClassification.ADD_FUNCTIONALITY && + opTypes.has('addNode')) { + return 0.8; + } + if (classification === mutation_types_js_1.IntentClassification.CLEANUP && + (opTypes.has('removeNode') || opTypes.has('removeConnection'))) { + return 0.8; + } + if (classification === mutation_types_js_1.IntentClassification.REWIRE_LOGIC && + opTypes.has('rewireConnection')) { + return 0.8; + } + return 0.6; + } + return 0.3; + } + getDescription(classification) { + switch (classification) { + case mutation_types_js_1.IntentClassification.ADD_FUNCTIONALITY: + return 'Adding new nodes or functionality to the workflow'; + case mutation_types_js_1.IntentClassification.MODIFY_CONFIGURATION: + return 'Modifying configuration of existing nodes'; + case mutation_types_js_1.IntentClassification.REWIRE_LOGIC: + return 'Changing workflow execution flow by rewiring connections'; + case mutation_types_js_1.IntentClassification.FIX_VALIDATION: + return 'Fixing validation errors or issues'; + case mutation_types_js_1.IntentClassification.CLEANUP: + return 'Removing or disabling nodes and connections'; + case mutation_types_js_1.IntentClassification.UNKNOWN: + return 'Unknown or complex mutation pattern'; + default: + return 'Unclassified mutation'; + } + } +} +exports.IntentClassifier = IntentClassifier; +exports.intentClassifier = new IntentClassifier(); +//# sourceMappingURL=intent-classifier.js.map \ No newline at end of file diff --git a/dist/telemetry/intent-classifier.js.map b/dist/telemetry/intent-classifier.js.map new file mode 100644 index 0000000..44f3b0a --- /dev/null +++ b/dist/telemetry/intent-classifier.js.map @@ -0,0 +1 @@ +{"version":3,"file":"intent-classifier.js","sourceRoot":"","sources":["../../src/telemetry/intent-classifier.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/telemetry/intent-sanitizer.d.ts b/dist/telemetry/intent-sanitizer.d.ts new file mode 100644 index 0000000..5690366 --- /dev/null +++ b/dist/telemetry/intent-sanitizer.d.ts @@ -0,0 +1,9 @@ +export declare class IntentSanitizer { + sanitize(intent: string): string; + containsPII(intent: string): boolean; + detectPIITypes(intent: string): string[]; + truncate(intent: string, maxLength?: number): string; + isSafeForTelemetry(intent: string): boolean; +} +export declare const intentSanitizer: IntentSanitizer; +//# sourceMappingURL=intent-sanitizer.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/intent-sanitizer.d.ts.map b/dist/telemetry/intent-sanitizer.d.ts.map new file mode 100644 index 0000000..9552554 --- /dev/null +++ b/dist/telemetry/intent-sanitizer.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"intent-sanitizer.d.ts","sourceRoot":"","sources":["../../src/telemetry/intent-sanitizer.ts"],"names":[],"mappings":"AAoDA,qBAAa,eAAe;IAI1B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IA+ChC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAWpC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IA4BxC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,GAAE,MAAa,GAAG,MAAM;IAsB1D,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;CAiB5C;AAKD,eAAO,MAAM,eAAe,iBAAwB,CAAC"} \ No newline at end of file diff --git a/dist/telemetry/intent-sanitizer.js b/dist/telemetry/intent-sanitizer.js new file mode 100644 index 0000000..f3df398 --- /dev/null +++ b/dist/telemetry/intent-sanitizer.js @@ -0,0 +1,103 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.intentSanitizer = exports.IntentSanitizer = void 0; +const PII_PATTERNS = { + email: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/gi, + url: /https?:\/\/[^\s]+/gi, + ip: /\b(?:\d{1,3}\.){3}\d{1,3}\b/g, + phone: /\b(?:\+?\d{1,3}[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g, + creditCard: /\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/g, + apiKey: /\b[A-Za-z0-9_-]{32,}\b/g, + uuid: /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi, + filePath: /(?:\/[\w.-]+)+\/?|(?:[A-Z]:\\(?:[\w.-]+\\)*[\w.-]+)/g, + secret: /\b(?:password|passwd|pwd|secret|token|key)[:=\s]+[^\s]+/gi, +}; +const COMPANY_PATTERNS = { + companySuffix: /\b\w+(?:\s+(?:Inc|LLC|Corp|Corporation|Ltd|Limited|GmbH|AG)\.?)\b/gi, + businessContext: /\b(?:company|organization|client|customer)\s+(?:named?|called)\s+\w+/gi, +}; +class IntentSanitizer { + sanitize(intent) { + if (!intent) { + return intent; + } + let sanitized = intent; + sanitized = sanitized.replace(PII_PATTERNS.email, '[EMAIL]'); + sanitized = sanitized.replace(PII_PATTERNS.url, '[URL]'); + sanitized = sanitized.replace(PII_PATTERNS.ip, '[IP_ADDRESS]'); + sanitized = sanitized.replace(PII_PATTERNS.phone, '[PHONE]'); + sanitized = sanitized.replace(PII_PATTERNS.creditCard, '[CARD_NUMBER]'); + sanitized = sanitized.replace(PII_PATTERNS.apiKey, '[API_KEY]'); + sanitized = sanitized.replace(PII_PATTERNS.uuid, '[UUID]'); + sanitized = sanitized.replace(PII_PATTERNS.filePath, '[FILE_PATH]'); + sanitized = sanitized.replace(PII_PATTERNS.secret, '[SECRET]'); + sanitized = sanitized.replace(COMPANY_PATTERNS.companySuffix, '[COMPANY]'); + sanitized = sanitized.replace(COMPANY_PATTERNS.businessContext, '[COMPANY_CONTEXT]'); + sanitized = sanitized.replace(/\s{2,}/g, ' ').trim(); + return sanitized; + } + containsPII(intent) { + if (!intent) { + return false; + } + return Object.values(PII_PATTERNS).some((pattern) => pattern.test(intent)); + } + detectPIITypes(intent) { + if (!intent) { + return []; + } + const detected = []; + if (PII_PATTERNS.email.test(intent)) + detected.push('email'); + if (PII_PATTERNS.url.test(intent)) + detected.push('url'); + if (PII_PATTERNS.ip.test(intent)) + detected.push('ip_address'); + if (PII_PATTERNS.phone.test(intent)) + detected.push('phone'); + if (PII_PATTERNS.creditCard.test(intent)) + detected.push('credit_card'); + if (PII_PATTERNS.apiKey.test(intent)) + detected.push('api_key'); + if (PII_PATTERNS.uuid.test(intent)) + detected.push('uuid'); + if (PII_PATTERNS.filePath.test(intent)) + detected.push('file_path'); + if (PII_PATTERNS.secret.test(intent)) + detected.push('secret'); + Object.values(PII_PATTERNS).forEach((pattern) => { + pattern.lastIndex = 0; + }); + return detected; + } + truncate(intent, maxLength = 1000) { + if (!intent || intent.length <= maxLength) { + return intent; + } + const truncated = intent.substring(0, maxLength); + const lastSentence = truncated.lastIndexOf('.'); + const lastSpace = truncated.lastIndexOf(' '); + if (lastSentence > maxLength * 0.8) { + return truncated.substring(0, lastSentence + 1); + } + else if (lastSpace > maxLength * 0.9) { + return truncated.substring(0, lastSpace) + '...'; + } + return truncated + '...'; + } + isSafeForTelemetry(intent) { + if (!intent) { + return true; + } + if (intent.length > 5000) { + return false; + } + if (/[\x00-\x08\x0B\x0C\x0E-\x1F]/.test(intent)) { + return false; + } + return true; + } +} +exports.IntentSanitizer = IntentSanitizer; +exports.intentSanitizer = new IntentSanitizer(); +//# sourceMappingURL=intent-sanitizer.js.map \ No newline at end of file diff --git a/dist/telemetry/intent-sanitizer.js.map b/dist/telemetry/intent-sanitizer.js.map new file mode 100644 index 0000000..e2b6633 --- /dev/null +++ b/dist/telemetry/intent-sanitizer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"intent-sanitizer.js","sourceRoot":"","sources":["../../src/telemetry/intent-sanitizer.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/telemetry/mutation-tracker.d.ts b/dist/telemetry/mutation-tracker.d.ts new file mode 100644 index 0000000..56eac5b --- /dev/null +++ b/dist/telemetry/mutation-tracker.d.ts @@ -0,0 +1,15 @@ +import { WorkflowMutationData, WorkflowMutationRecord } from './mutation-types.js'; +export declare class MutationTracker { + private recentMutations; + private readonly RECENT_MUTATIONS_LIMIT; + processMutation(data: WorkflowMutationData, userId: string): Promise; + private validateMutationData; + private calculateChangeMetrics; + private calculateValidationMetrics; + private extractOperationTypes; + private addToRecentMutations; + clearRecentMutations(): void; + getRecentMutationsCount(): number; +} +export declare const mutationTracker: MutationTracker; +//# sourceMappingURL=mutation-tracker.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/mutation-tracker.d.ts.map b/dist/telemetry/mutation-tracker.d.ts.map new file mode 100644 index 0000000..689ef06 --- /dev/null +++ b/dist/telemetry/mutation-tracker.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"mutation-tracker.d.ts","sourceRoot":"","sources":["../../src/telemetry/mutation-tracker.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EAIvB,MAAM,qBAAqB,CAAC;AAU7B,qBAAa,eAAe;IAC1B,OAAO,CAAC,eAAe,CAIf;IAER,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAO;IAKxC,eAAe,CAAC,IAAI,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC;IA0FzG,OAAO,CAAC,oBAAoB;IAkB5B,OAAO,CAAC,sBAAsB;IAsE9B,OAAO,CAAC,0BAA0B;IA+BlC,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,oBAAoB;IAgB5B,oBAAoB,IAAI,IAAI;IAO5B,uBAAuB,IAAI,MAAM;CAGlC;AAKD,eAAO,MAAM,eAAe,iBAAwB,CAAC"} \ No newline at end of file diff --git a/dist/telemetry/mutation-tracker.js b/dist/telemetry/mutation-tracker.js new file mode 100644 index 0000000..8e799c8 --- /dev/null +++ b/dist/telemetry/mutation-tracker.js @@ -0,0 +1,177 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.mutationTracker = exports.MutationTracker = void 0; +const intent_classifier_js_1 = require("./intent-classifier.js"); +const mutation_validator_js_1 = require("./mutation-validator.js"); +const intent_sanitizer_js_1 = require("./intent-sanitizer.js"); +const workflow_sanitizer_js_1 = require("./workflow-sanitizer.js"); +const logger_js_1 = require("../utils/logger.js"); +class MutationTracker { + constructor() { + this.recentMutations = []; + this.RECENT_MUTATIONS_LIMIT = 100; + } + async processMutation(data, userId) { + try { + if (!this.validateMutationData(data)) { + logger_js_1.logger.debug('Mutation data validation failed'); + return null; + } + const workflowBefore = workflow_sanitizer_js_1.WorkflowSanitizer.sanitizeWorkflowRaw(data.workflowBefore); + const workflowAfter = workflow_sanitizer_js_1.WorkflowSanitizer.sanitizeWorkflowRaw(data.workflowAfter); + const sanitizedIntent = intent_sanitizer_js_1.intentSanitizer.sanitize(data.userIntent); + if (mutation_validator_js_1.mutationValidator.shouldExclude(data)) { + logger_js_1.logger.debug('Mutation excluded from tracking based on quality criteria'); + return null; + } + if (mutation_validator_js_1.mutationValidator.isDuplicate(workflowBefore, workflowAfter, data.operations, this.recentMutations)) { + logger_js_1.logger.debug('Duplicate mutation detected, skipping tracking'); + return null; + } + const hashBefore = mutation_validator_js_1.mutationValidator.hashWorkflow(workflowBefore); + const hashAfter = mutation_validator_js_1.mutationValidator.hashWorkflow(workflowAfter); + const structureHashBefore = workflow_sanitizer_js_1.WorkflowSanitizer.generateWorkflowHash(workflowBefore); + const structureHashAfter = workflow_sanitizer_js_1.WorkflowSanitizer.generateWorkflowHash(workflowAfter); + const intentClassification = intent_classifier_js_1.intentClassifier.classify(data.operations, sanitizedIntent); + const changeMetrics = this.calculateChangeMetrics(data.operations); + const validationMetrics = this.calculateValidationMetrics(data.validationBefore, data.validationAfter); + const record = { + userId, + sessionId: data.sessionId, + workflowBefore, + workflowAfter, + workflowHashBefore: hashBefore, + workflowHashAfter: hashAfter, + workflowStructureHashBefore: structureHashBefore, + workflowStructureHashAfter: structureHashAfter, + userIntent: sanitizedIntent, + intentClassification, + toolName: data.toolName, + operations: data.operations, + operationCount: data.operations.length, + operationTypes: this.extractOperationTypes(data.operations), + validationBefore: data.validationBefore, + validationAfter: data.validationAfter, + ...validationMetrics, + ...changeMetrics, + mutationSuccess: data.mutationSuccess, + mutationError: data.mutationError, + durationMs: data.durationMs, + }; + this.addToRecentMutations(hashBefore, hashAfter, data.operations); + return record; + } + catch (error) { + logger_js_1.logger.error('Error processing mutation:', error); + return null; + } + } + validateMutationData(data) { + const validationResult = mutation_validator_js_1.mutationValidator.validate(data); + if (!validationResult.valid) { + logger_js_1.logger.warn('Mutation data validation failed:', validationResult.errors); + return false; + } + if (validationResult.warnings.length > 0) { + logger_js_1.logger.debug('Mutation data validation warnings:', validationResult.warnings); + } + return true; + } + calculateChangeMetrics(operations) { + const metrics = { + nodesAdded: 0, + nodesRemoved: 0, + nodesModified: 0, + connectionsAdded: 0, + connectionsRemoved: 0, + propertiesChanged: 0, + }; + for (const op of operations) { + switch (op.type) { + case 'addNode': + metrics.nodesAdded++; + break; + case 'removeNode': + metrics.nodesRemoved++; + break; + case 'updateNode': + metrics.nodesModified++; + if ('updates' in op && op.updates) { + metrics.propertiesChanged += Object.keys(op.updates).length; + } + break; + case 'addConnection': + metrics.connectionsAdded++; + break; + case 'removeConnection': + metrics.connectionsRemoved++; + break; + case 'rewireConnection': + metrics.connectionsRemoved++; + metrics.connectionsAdded++; + break; + case 'replaceConnections': + if ('connections' in op && op.connections) { + metrics.connectionsRemoved++; + metrics.connectionsAdded++; + } + break; + case 'updateSettings': + if ('settings' in op && op.settings) { + metrics.propertiesChanged += Object.keys(op.settings).length; + } + break; + case 'moveNode': + case 'enableNode': + case 'disableNode': + case 'updateName': + case 'addTag': + case 'removeTag': + case 'activateWorkflow': + case 'deactivateWorkflow': + case 'cleanStaleConnections': + metrics.propertiesChanged++; + break; + } + } + return metrics; + } + calculateValidationMetrics(validationBefore, validationAfter) { + if (!validationBefore || !validationAfter) { + return { + validationImproved: null, + errorsResolved: 0, + errorsIntroduced: 0, + }; + } + const errorsBefore = validationBefore.errors?.length || 0; + const errorsAfter = validationAfter.errors?.length || 0; + const errorsResolved = Math.max(0, errorsBefore - errorsAfter); + const errorsIntroduced = Math.max(0, errorsAfter - errorsBefore); + const validationImproved = errorsBefore > errorsAfter; + return { + validationImproved, + errorsResolved, + errorsIntroduced, + }; + } + extractOperationTypes(operations) { + const types = new Set(operations.map((op) => op.type)); + return Array.from(types); + } + addToRecentMutations(hashBefore, hashAfter, operations) { + this.recentMutations.push({ hashBefore, hashAfter, operations }); + if (this.recentMutations.length > this.RECENT_MUTATIONS_LIMIT) { + this.recentMutations.shift(); + } + } + clearRecentMutations() { + this.recentMutations = []; + } + getRecentMutationsCount() { + return this.recentMutations.length; + } +} +exports.MutationTracker = MutationTracker; +exports.mutationTracker = new MutationTracker(); +//# sourceMappingURL=mutation-tracker.js.map \ No newline at end of file diff --git a/dist/telemetry/mutation-tracker.js.map b/dist/telemetry/mutation-tracker.js.map new file mode 100644 index 0000000..f6365cb --- /dev/null +++ b/dist/telemetry/mutation-tracker.js.map @@ -0,0 +1 @@ +{"version":3,"file":"mutation-tracker.js","sourceRoot":"","sources":["../../src/telemetry/mutation-tracker.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/telemetry/mutation-types.d.ts b/dist/telemetry/mutation-types.d.ts new file mode 100644 index 0000000..8ff3695 --- /dev/null +++ b/dist/telemetry/mutation-types.d.ts @@ -0,0 +1,106 @@ +import { DiffOperation } from '../types/workflow-diff.js'; +export declare enum IntentClassification { + ADD_FUNCTIONALITY = "add_functionality", + MODIFY_CONFIGURATION = "modify_configuration", + REWIRE_LOGIC = "rewire_logic", + FIX_VALIDATION = "fix_validation", + CLEANUP = "cleanup", + UNKNOWN = "unknown" +} +export declare enum MutationToolName { + UPDATE_PARTIAL = "n8n_update_partial_workflow", + UPDATE_FULL = "n8n_update_full_workflow" +} +export interface ValidationResult { + valid: boolean; + errors: Array<{ + type: string; + message: string; + severity?: string; + location?: string; + }>; + warnings?: Array<{ + type: string; + message: string; + }>; +} +export interface MutationChangeMetrics { + nodesAdded: number; + nodesRemoved: number; + nodesModified: number; + connectionsAdded: number; + connectionsRemoved: number; + propertiesChanged: number; +} +export interface MutationValidationMetrics { + validationImproved: boolean | null; + errorsResolved: number; + errorsIntroduced: number; +} +export interface WorkflowMutationData { + sessionId: string; + toolName: MutationToolName; + userIntent: string; + operations: DiffOperation[]; + workflowBefore: any; + workflowAfter: any; + validationBefore?: ValidationResult; + validationAfter?: ValidationResult; + mutationSuccess: boolean; + mutationError?: string; + durationMs: number; +} +export interface WorkflowMutationRecord { + id?: string; + userId: string; + sessionId: string; + workflowBefore: any; + workflowAfter: any; + workflowHashBefore: string; + workflowHashAfter: string; + workflowStructureHashBefore?: string; + workflowStructureHashAfter?: string; + isTrulySuccessful?: boolean; + userIntent: string; + intentClassification: IntentClassification; + toolName: MutationToolName; + operations: DiffOperation[]; + operationCount: number; + operationTypes: string[]; + validationBefore?: ValidationResult; + validationAfter?: ValidationResult; + validationImproved: boolean | null; + errorsResolved: number; + errorsIntroduced: number; + nodesAdded: number; + nodesRemoved: number; + nodesModified: number; + connectionsAdded: number; + connectionsRemoved: number; + propertiesChanged: number; + mutationSuccess: boolean; + mutationError?: string; + durationMs: number; + createdAt?: Date; +} +export interface MutationTrackingOptions { + enabled?: boolean; + maxWorkflowSizeKb?: number; + validateQuality?: boolean; + sanitize?: boolean; +} +export interface MutationTrackingStats { + totalMutationsTracked: number; + successfulMutations: number; + failedMutations: number; + mutationsWithValidationImprovement: number; + averageDurationMs: number; + intentClassificationBreakdown: Record; + operationTypeBreakdown: Record; +} +export interface MutationDataQualityResult { + valid: boolean; + errors: string[]; + warnings: string[]; +} +//# sourceMappingURL=mutation-types.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/mutation-types.d.ts.map b/dist/telemetry/mutation-types.d.ts.map new file mode 100644 index 0000000..9913d4f --- /dev/null +++ b/dist/telemetry/mutation-types.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"mutation-types.d.ts","sourceRoot":"","sources":["../../src/telemetry/mutation-types.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/telemetry/mutation-types.js b/dist/telemetry/mutation-types.js new file mode 100644 index 0000000..7f2e83f --- /dev/null +++ b/dist/telemetry/mutation-types.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.MutationToolName = exports.IntentClassification = void 0; +var IntentClassification; +(function (IntentClassification) { + IntentClassification["ADD_FUNCTIONALITY"] = "add_functionality"; + IntentClassification["MODIFY_CONFIGURATION"] = "modify_configuration"; + IntentClassification["REWIRE_LOGIC"] = "rewire_logic"; + IntentClassification["FIX_VALIDATION"] = "fix_validation"; + IntentClassification["CLEANUP"] = "cleanup"; + IntentClassification["UNKNOWN"] = "unknown"; +})(IntentClassification || (exports.IntentClassification = IntentClassification = {})); +var MutationToolName; +(function (MutationToolName) { + MutationToolName["UPDATE_PARTIAL"] = "n8n_update_partial_workflow"; + MutationToolName["UPDATE_FULL"] = "n8n_update_full_workflow"; +})(MutationToolName || (exports.MutationToolName = MutationToolName = {})); +//# sourceMappingURL=mutation-types.js.map \ No newline at end of file diff --git a/dist/telemetry/mutation-types.js.map b/dist/telemetry/mutation-types.js.map new file mode 100644 index 0000000..daae0f2 --- /dev/null +++ b/dist/telemetry/mutation-types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"mutation-types.js","sourceRoot":"","sources":["../../src/telemetry/mutation-types.ts"],"names":[],"mappings":";;;AAUA,IAAY,oBAOX;AAPD,WAAY,oBAAoB;IAC9B,+DAAuC,CAAA;IACvC,qEAA6C,CAAA;IAC7C,qDAA6B,CAAA;IAC7B,yDAAiC,CAAA;IACjC,2CAAmB,CAAA;IACnB,2CAAmB,CAAA;AACrB,CAAC,EAPW,oBAAoB,oCAApB,oBAAoB,QAO/B;AAKD,IAAY,gBAGX;AAHD,WAAY,gBAAgB;IAC1B,kEAA8C,CAAA;IAC9C,4DAAwC,CAAA;AAC1C,CAAC,EAHW,gBAAgB,gCAAhB,gBAAgB,QAG3B"} \ No newline at end of file diff --git a/dist/telemetry/mutation-validator.d.ts b/dist/telemetry/mutation-validator.d.ts new file mode 100644 index 0000000..02601a1 --- /dev/null +++ b/dist/telemetry/mutation-validator.d.ts @@ -0,0 +1,20 @@ +import { WorkflowMutationData, MutationDataQualityResult, MutationTrackingOptions } from './mutation-types.js'; +export declare const DEFAULT_MUTATION_TRACKING_OPTIONS: Required; +export declare class MutationValidator { + private options; + constructor(options?: MutationTrackingOptions); + validate(data: WorkflowMutationData): MutationDataQualityResult; + private isValidWorkflow; + private getWorkflowSizeKb; + private hasMeaningfulChange; + hashWorkflow(workflow: any): string; + shouldExclude(data: WorkflowMutationData): boolean; + isDuplicate(workflowBefore: any, workflowAfter: any, operations: any[], recentMutations: Array<{ + hashBefore: string; + hashAfter: string; + operations: any[]; + }>): boolean; + private hashOperations; +} +export declare const mutationValidator: MutationValidator; +//# sourceMappingURL=mutation-validator.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/mutation-validator.d.ts.map b/dist/telemetry/mutation-validator.d.ts.map new file mode 100644 index 0000000..52903b9 --- /dev/null +++ b/dist/telemetry/mutation-validator.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"mutation-validator.d.ts","sourceRoot":"","sources":["../../src/telemetry/mutation-validator.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,uBAAuB,EACxB,MAAM,qBAAqB,CAAC;AAK7B,eAAO,MAAM,iCAAiC,EAAE,QAAQ,CAAC,uBAAuB,CAK/E,CAAC;AAKF,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAoC;gBAEvC,OAAO,GAAE,uBAA4B;IAOjD,QAAQ,CAAC,IAAI,EAAE,oBAAoB,GAAG,yBAAyB;IA+E/D,OAAO,CAAC,eAAe;IAqBvB,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,mBAAmB;IAe3B,YAAY,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM;IAYnC,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO;IA4BlD,WAAW,CACT,cAAc,EAAE,GAAG,EACnB,aAAa,EAAE,GAAG,EAClB,UAAU,EAAE,GAAG,EAAE,EACjB,eAAe,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC,GACnF,OAAO;IAgBV,OAAO,CAAC,cAAc;CAQvB;AAKD,eAAO,MAAM,iBAAiB,mBAA0B,CAAC"} \ No newline at end of file diff --git a/dist/telemetry/mutation-validator.js b/dist/telemetry/mutation-validator.js new file mode 100644 index 0000000..4fff689 --- /dev/null +++ b/dist/telemetry/mutation-validator.js @@ -0,0 +1,144 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.mutationValidator = exports.MutationValidator = exports.DEFAULT_MUTATION_TRACKING_OPTIONS = void 0; +const crypto_1 = require("crypto"); +exports.DEFAULT_MUTATION_TRACKING_OPTIONS = { + enabled: true, + maxWorkflowSizeKb: 500, + validateQuality: true, + sanitize: true, +}; +class MutationValidator { + constructor(options = {}) { + this.options = { ...exports.DEFAULT_MUTATION_TRACKING_OPTIONS, ...options }; + } + validate(data) { + const errors = []; + const warnings = []; + if (!this.isValidWorkflow(data.workflowBefore)) { + errors.push('Invalid workflow_before structure'); + } + if (!this.isValidWorkflow(data.workflowAfter)) { + errors.push('Invalid workflow_after structure'); + } + const beforeSizeKb = this.getWorkflowSizeKb(data.workflowBefore); + const afterSizeKb = this.getWorkflowSizeKb(data.workflowAfter); + if (beforeSizeKb > this.options.maxWorkflowSizeKb) { + errors.push(`workflow_before size (${beforeSizeKb}KB) exceeds maximum (${this.options.maxWorkflowSizeKb}KB)`); + } + if (afterSizeKb > this.options.maxWorkflowSizeKb) { + errors.push(`workflow_after size (${afterSizeKb}KB) exceeds maximum (${this.options.maxWorkflowSizeKb}KB)`); + } + if (!this.hasMeaningfulChange(data.workflowBefore, data.workflowAfter)) { + warnings.push('No meaningful change detected between before and after workflows'); + } + if (!data.userIntent || data.userIntent.trim().length === 0) { + warnings.push('User intent is empty'); + } + else if (data.userIntent.trim().length < 5) { + warnings.push('User intent is too short (less than 5 characters)'); + } + else if (data.userIntent.length > 1000) { + warnings.push('User intent is very long (over 1000 characters)'); + } + if (!data.operations || data.operations.length === 0) { + errors.push('No operations provided'); + } + if (data.validationBefore && data.validationAfter) { + if (typeof data.validationBefore.valid !== 'boolean') { + warnings.push('Invalid validation_before structure'); + } + if (typeof data.validationAfter.valid !== 'boolean') { + warnings.push('Invalid validation_after structure'); + } + } + if (data.durationMs !== undefined) { + if (data.durationMs < 0) { + errors.push('Duration cannot be negative'); + } + if (data.durationMs > 300000) { + warnings.push('Duration is very long (over 5 minutes)'); + } + } + return { + valid: errors.length === 0, + errors, + warnings, + }; + } + isValidWorkflow(workflow) { + if (!workflow || typeof workflow !== 'object') { + return false; + } + if (!Array.isArray(workflow.nodes)) { + return false; + } + if (!workflow.connections || typeof workflow.connections !== 'object') { + return false; + } + return true; + } + getWorkflowSizeKb(workflow) { + try { + const json = JSON.stringify(workflow); + return json.length / 1024; + } + catch { + return 0; + } + } + hasMeaningfulChange(workflowBefore, workflowAfter) { + try { + const hashBefore = this.hashWorkflow(workflowBefore); + const hashAfter = this.hashWorkflow(workflowAfter); + return hashBefore !== hashAfter; + } + catch { + return false; + } + } + hashWorkflow(workflow) { + try { + const json = JSON.stringify(workflow); + return (0, crypto_1.createHash)('sha256').update(json).digest('hex').substring(0, 16); + } + catch { + return ''; + } + } + shouldExclude(data) { + if (!data.mutationSuccess && !data.mutationError) { + return true; + } + if (!this.hasMeaningfulChange(data.workflowBefore, data.workflowAfter)) { + return true; + } + const beforeSizeKb = this.getWorkflowSizeKb(data.workflowBefore); + const afterSizeKb = this.getWorkflowSizeKb(data.workflowAfter); + if (beforeSizeKb > this.options.maxWorkflowSizeKb || + afterSizeKb > this.options.maxWorkflowSizeKb) { + return true; + } + return false; + } + isDuplicate(workflowBefore, workflowAfter, operations, recentMutations) { + const hashBefore = this.hashWorkflow(workflowBefore); + const hashAfter = this.hashWorkflow(workflowAfter); + const operationsHash = this.hashOperations(operations); + return recentMutations.some((m) => m.hashBefore === hashBefore && + m.hashAfter === hashAfter && + this.hashOperations(m.operations) === operationsHash); + } + hashOperations(operations) { + try { + const json = JSON.stringify(operations); + return (0, crypto_1.createHash)('sha256').update(json).digest('hex').substring(0, 16); + } + catch { + return ''; + } + } +} +exports.MutationValidator = MutationValidator; +exports.mutationValidator = new MutationValidator(); +//# sourceMappingURL=mutation-validator.js.map \ No newline at end of file diff --git a/dist/telemetry/mutation-validator.js.map b/dist/telemetry/mutation-validator.js.map new file mode 100644 index 0000000..0a9b391 --- /dev/null +++ b/dist/telemetry/mutation-validator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"mutation-validator.js","sourceRoot":"","sources":["../../src/telemetry/mutation-validator.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/telemetry/performance-monitor.d.ts b/dist/telemetry/performance-monitor.d.ts new file mode 100644 index 0000000..029981f --- /dev/null +++ b/dist/telemetry/performance-monitor.d.ts @@ -0,0 +1,113 @@ +export declare class TelemetryPerformanceMonitor { + private metrics; + private operationTimers; + private readonly maxMetrics; + private startupTime; + private operationCounts; + startOperation(operation: string): void; + endOperation(operation: string): number; + private recordMetric; + private captureMemoryUsage; + getStatistics(): { + totalOperations: number; + averageDuration: number; + slowOperations: number; + operationsByType: {}; + memoryUsage: { + heapUsed: number; + heapTotal: number; + external: number; + } | undefined; + uptimeMs: number; + overhead: { + percentage: number; + totalMs: number; + }; + operationsInLastMinute?: undefined; + } | { + totalOperations: number; + operationsInLastMinute: number; + averageDuration: number; + slowOperations: number; + operationsByType: Record; + memoryUsage: { + heapUsed: number; + heapTotal: number; + external: number; + } | undefined; + uptimeMs: number; + overhead: { + percentage: number; + totalMs: number; + }; + }; + getDetailedReport(): { + summary: { + totalOperations: number; + averageDuration: number; + slowOperations: number; + operationsByType: {}; + memoryUsage: { + heapUsed: number; + heapTotal: number; + external: number; + } | undefined; + uptimeMs: number; + overhead: { + percentage: number; + totalMs: number; + }; + operationsInLastMinute?: undefined; + } | { + totalOperations: number; + operationsInLastMinute: number; + averageDuration: number; + slowOperations: number; + operationsByType: Record; + memoryUsage: { + heapUsed: number; + heapTotal: number; + external: number; + } | undefined; + uptimeMs: number; + overhead: { + percentage: number; + totalMs: number; + }; + }; + percentiles: { + p50: number; + p75: number; + p90: number; + p95: number; + p99: number; + }; + topSlowOperations: { + operation: string; + duration: number; + timestamp: number; + }[]; + memoryTrend: { + trend: string; + delta: number; + }; + recommendations: string[]; + }; + private calculatePercentiles; + private percentile; + private getTopSlowOperations; + private getMemoryTrend; + private generateRecommendations; + reset(): void; + getTelemetryOverhead(): { + percentage: number; + impact: 'minimal' | 'low' | 'moderate' | 'high'; + }; +} +//# sourceMappingURL=performance-monitor.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/performance-monitor.d.ts.map b/dist/telemetry/performance-monitor.d.ts.map new file mode 100644 index 0000000..45b71ee --- /dev/null +++ b/dist/telemetry/performance-monitor.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"performance-monitor.d.ts","sourceRoot":"","sources":["../../src/telemetry/performance-monitor.ts"],"names":[],"mappings":"AAkBA,qBAAa,2BAA2B;IACtC,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,eAAe,CAAkC;IACzD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,eAAe,CAAkC;IAKzD,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAOvC,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IA8BvC,OAAO,CAAC,YAAY;IAiBpB,OAAO,CAAC,kBAAkB;IAe1B,aAAa;;;;;;;;;;;;;;;;;;;;;;mBA0BqC,MAAM;yBAAe,MAAM;;;;;;;;;;;;;IAwC7E,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;uBAxCiC,MAAM;6BAAe,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAwD7E,OAAO,CAAC,oBAAoB;IAsB5B,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,oBAAoB;IAc5B,OAAO,CAAC,cAAc;IAsBtB,OAAO,CAAC,uBAAuB;IAmC/B,KAAK,IAAI,IAAI;IAUb,oBAAoB,IAAI;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,SAAS,GAAG,KAAK,GAAG,UAAU,GAAG,MAAM,CAAA;KAAE;CAYhG"} \ No newline at end of file diff --git a/dist/telemetry/performance-monitor.js b/dist/telemetry/performance-monitor.js new file mode 100644 index 0000000..59320db --- /dev/null +++ b/dist/telemetry/performance-monitor.js @@ -0,0 +1,208 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TelemetryPerformanceMonitor = void 0; +const logger_1 = require("../utils/logger"); +class TelemetryPerformanceMonitor { + constructor() { + this.metrics = []; + this.operationTimers = new Map(); + this.maxMetrics = 1000; + this.startupTime = Date.now(); + this.operationCounts = new Map(); + } + startOperation(operation) { + this.operationTimers.set(operation, performance.now()); + } + endOperation(operation) { + const startTime = this.operationTimers.get(operation); + if (!startTime) { + logger_1.logger.debug(`No start time found for operation: ${operation}`); + return 0; + } + const duration = performance.now() - startTime; + this.operationTimers.delete(operation); + const metric = { + operation, + duration, + timestamp: Date.now(), + memory: this.captureMemoryUsage() + }; + this.recordMetric(metric); + const count = this.operationCounts.get(operation) || 0; + this.operationCounts.set(operation, count + 1); + return duration; + } + recordMetric(metric) { + this.metrics.push(metric); + if (this.metrics.length > this.maxMetrics) { + this.metrics.shift(); + } + if (metric.duration > 100) { + logger_1.logger.debug(`Slow telemetry operation: ${metric.operation} took ${metric.duration.toFixed(2)}ms`); + } + } + captureMemoryUsage() { + if (typeof process !== 'undefined' && process.memoryUsage) { + const usage = process.memoryUsage(); + return { + heapUsed: Math.round(usage.heapUsed / 1024 / 1024), + heapTotal: Math.round(usage.heapTotal / 1024 / 1024), + external: Math.round(usage.external / 1024 / 1024) + }; + } + return undefined; + } + getStatistics() { + const now = Date.now(); + const recentMetrics = this.metrics.filter(m => now - m.timestamp < 60000); + if (recentMetrics.length === 0) { + return { + totalOperations: 0, + averageDuration: 0, + slowOperations: 0, + operationsByType: {}, + memoryUsage: this.captureMemoryUsage(), + uptimeMs: now - this.startupTime, + overhead: { + percentage: 0, + totalMs: 0 + } + }; + } + const durations = recentMetrics.map(m => m.duration); + const totalDuration = durations.reduce((a, b) => a + b, 0); + const avgDuration = totalDuration / durations.length; + const slowOps = durations.filter(d => d > 50).length; + const operationsByType = {}; + const typeGroups = new Map(); + for (const metric of recentMetrics) { + const type = metric.operation; + if (!typeGroups.has(type)) { + typeGroups.set(type, []); + } + typeGroups.get(type).push(metric.duration); + } + for (const [type, durations] of typeGroups.entries()) { + const sum = durations.reduce((a, b) => a + b, 0); + operationsByType[type] = { + count: durations.length, + avgDuration: Math.round(sum / durations.length * 100) / 100 + }; + } + const estimatedOverheadPercentage = Math.min(5, avgDuration / 10); + return { + totalOperations: this.operationCounts.size, + operationsInLastMinute: recentMetrics.length, + averageDuration: Math.round(avgDuration * 100) / 100, + slowOperations: slowOps, + operationsByType, + memoryUsage: this.captureMemoryUsage(), + uptimeMs: now - this.startupTime, + overhead: { + percentage: estimatedOverheadPercentage, + totalMs: totalDuration + } + }; + } + getDetailedReport() { + const stats = this.getStatistics(); + const percentiles = this.calculatePercentiles(); + return { + summary: stats, + percentiles, + topSlowOperations: this.getTopSlowOperations(5), + memoryTrend: this.getMemoryTrend(), + recommendations: this.generateRecommendations(stats, percentiles) + }; + } + calculatePercentiles() { + const recentDurations = this.metrics + .filter(m => Date.now() - m.timestamp < 60000) + .map(m => m.duration) + .sort((a, b) => a - b); + if (recentDurations.length === 0) { + return { p50: 0, p75: 0, p90: 0, p95: 0, p99: 0 }; + } + return { + p50: this.percentile(recentDurations, 0.5), + p75: this.percentile(recentDurations, 0.75), + p90: this.percentile(recentDurations, 0.9), + p95: this.percentile(recentDurations, 0.95), + p99: this.percentile(recentDurations, 0.99) + }; + } + percentile(sorted, p) { + const index = Math.ceil(sorted.length * p) - 1; + return Math.round(sorted[Math.max(0, index)] * 100) / 100; + } + getTopSlowOperations(n) { + return [...this.metrics] + .sort((a, b) => b.duration - a.duration) + .slice(0, n) + .map(m => ({ + operation: m.operation, + duration: Math.round(m.duration * 100) / 100, + timestamp: m.timestamp + })); + } + getMemoryTrend() { + const metricsWithMemory = this.metrics.filter(m => m.memory); + if (metricsWithMemory.length < 2) { + return { trend: 'stable', delta: 0 }; + } + const recent = metricsWithMemory.slice(-10); + const first = recent[0].memory; + const last = recent[recent.length - 1].memory; + const delta = last.heapUsed - first.heapUsed; + let trend; + if (delta > 5) + trend = 'increasing'; + else if (delta < -5) + trend = 'decreasing'; + else + trend = 'stable'; + return { trend, delta }; + } + generateRecommendations(stats, percentiles) { + const recommendations = []; + if (stats.averageDuration > 50) { + recommendations.push('Consider batching more events to reduce overhead'); + } + if (stats.slowOperations > stats.operationsInLastMinute * 0.1) { + recommendations.push('Many slow operations detected - investigate network latency'); + } + if (percentiles.p99 > 200) { + recommendations.push('P99 latency is high - consider implementing local queue persistence'); + } + const memoryTrend = this.getMemoryTrend(); + if (memoryTrend.trend === 'increasing' && memoryTrend.delta > 10) { + recommendations.push('Memory usage is increasing - check for memory leaks'); + } + if (stats.operationsInLastMinute > 1000) { + recommendations.push('High telemetry volume - ensure rate limiting is effective'); + } + return recommendations; + } + reset() { + this.metrics = []; + this.operationTimers.clear(); + this.operationCounts.clear(); + this.startupTime = Date.now(); + } + getTelemetryOverhead() { + const stats = this.getStatistics(); + const percentage = stats.overhead.percentage; + let impact; + if (percentage < 1) + impact = 'minimal'; + else if (percentage < 3) + impact = 'low'; + else if (percentage < 5) + impact = 'moderate'; + else + impact = 'high'; + return { percentage, impact }; + } +} +exports.TelemetryPerformanceMonitor = TelemetryPerformanceMonitor; +//# sourceMappingURL=performance-monitor.js.map \ No newline at end of file diff --git a/dist/telemetry/performance-monitor.js.map b/dist/telemetry/performance-monitor.js.map new file mode 100644 index 0000000..0217859 --- /dev/null +++ b/dist/telemetry/performance-monitor.js.map @@ -0,0 +1 @@ +{"version":3,"file":"performance-monitor.js","sourceRoot":"","sources":["../../src/telemetry/performance-monitor.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/telemetry/rate-limiter.d.ts b/dist/telemetry/rate-limiter.d.ts new file mode 100644 index 0000000..d86220b --- /dev/null +++ b/dist/telemetry/rate-limiter.d.ts @@ -0,0 +1,30 @@ +export declare class TelemetryRateLimiter { + private eventTimestamps; + private windowMs; + private maxEvents; + private droppedEventsCount; + private lastWarningTime; + private readonly WARNING_INTERVAL; + private readonly MAX_ARRAY_SIZE; + constructor(windowMs?: number, maxEvents?: number); + allow(): boolean; + wouldAllow(): boolean; + getStats(): { + currentEvents: number; + maxEvents: number; + windowMs: number; + droppedEvents: number; + utilizationPercent: number; + remainingCapacity: number; + arraySize: number; + maxArraySize: number; + memoryUsagePercent: number; + }; + reset(): void; + private cleanupOldTimestamps; + private handleRateLimitHit; + getDroppedEventsCount(): number; + getTimeUntilCapacity(): number; + updateLimits(windowMs?: number, maxEvents?: number): void; +} +//# sourceMappingURL=rate-limiter.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/rate-limiter.d.ts.map b/dist/telemetry/rate-limiter.d.ts.map new file mode 100644 index 0000000..895a3ec --- /dev/null +++ b/dist/telemetry/rate-limiter.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../src/telemetry/rate-limiter.ts"],"names":[],"mappings":"AAQA,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,eAAe,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;gBAGrC,QAAQ,GAAE,MAA2C,EACrD,SAAS,GAAE,MAA+C;IAU5D,KAAK,IAAI,OAAO;IAqBhB,UAAU,IAAI,OAAO;IASrB,QAAQ;;;;;;;;;;;IAoBR,KAAK,IAAI,IAAI;IASb,OAAO,CAAC,oBAAoB;IA+B5B,OAAO,CAAC,kBAAkB;IAiB1B,qBAAqB,IAAI,MAAM;IAQ/B,oBAAoB,IAAI,MAAM;IAkB9B,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;CAU1D"} \ No newline at end of file diff --git a/dist/telemetry/rate-limiter.js b/dist/telemetry/rate-limiter.js new file mode 100644 index 0000000..dc7e9ce --- /dev/null +++ b/dist/telemetry/rate-limiter.js @@ -0,0 +1,103 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TelemetryRateLimiter = void 0; +const telemetry_types_1 = require("./telemetry-types"); +const logger_1 = require("../utils/logger"); +class TelemetryRateLimiter { + constructor(windowMs = telemetry_types_1.TELEMETRY_CONFIG.RATE_LIMIT_WINDOW, maxEvents = telemetry_types_1.TELEMETRY_CONFIG.RATE_LIMIT_MAX_EVENTS) { + this.eventTimestamps = []; + this.droppedEventsCount = 0; + this.lastWarningTime = 0; + this.WARNING_INTERVAL = 60000; + this.MAX_ARRAY_SIZE = 1000; + this.windowMs = windowMs; + this.maxEvents = maxEvents; + } + allow() { + const now = Date.now(); + this.cleanupOldTimestamps(now); + if (this.eventTimestamps.length >= this.maxEvents) { + this.handleRateLimitHit(now); + return false; + } + this.eventTimestamps.push(now); + return true; + } + wouldAllow() { + const now = Date.now(); + this.cleanupOldTimestamps(now); + return this.eventTimestamps.length < this.maxEvents; + } + getStats() { + const now = Date.now(); + this.cleanupOldTimestamps(now); + return { + currentEvents: this.eventTimestamps.length, + maxEvents: this.maxEvents, + windowMs: this.windowMs, + droppedEvents: this.droppedEventsCount, + utilizationPercent: Math.round((this.eventTimestamps.length / this.maxEvents) * 100), + remainingCapacity: Math.max(0, this.maxEvents - this.eventTimestamps.length), + arraySize: this.eventTimestamps.length, + maxArraySize: this.MAX_ARRAY_SIZE, + memoryUsagePercent: Math.round((this.eventTimestamps.length / this.MAX_ARRAY_SIZE) * 100) + }; + } + reset() { + this.eventTimestamps = []; + this.droppedEventsCount = 0; + this.lastWarningTime = 0; + } + cleanupOldTimestamps(now) { + const windowStart = now - this.windowMs; + let i = 0; + while (i < this.eventTimestamps.length && this.eventTimestamps[i] < windowStart) { + i++; + } + if (i > 0) { + this.eventTimestamps.splice(0, i); + } + if (this.eventTimestamps.length > this.MAX_ARRAY_SIZE) { + const excess = this.eventTimestamps.length - this.MAX_ARRAY_SIZE; + this.eventTimestamps.splice(0, excess); + if (now - this.lastWarningTime > this.WARNING_INTERVAL) { + logger_1.logger.debug(`Telemetry rate limiter array trimmed: removed ${excess} oldest timestamps to prevent memory leak. ` + + `Array size: ${this.eventTimestamps.length}/${this.MAX_ARRAY_SIZE}`); + this.lastWarningTime = now; + } + } + } + handleRateLimitHit(now) { + this.droppedEventsCount++; + if (now - this.lastWarningTime > this.WARNING_INTERVAL) { + const stats = this.getStats(); + logger_1.logger.debug(`Telemetry rate limit reached: ${stats.currentEvents}/${stats.maxEvents} events in ${stats.windowMs}ms window. ` + + `Total dropped: ${stats.droppedEvents}`); + this.lastWarningTime = now; + } + } + getDroppedEventsCount() { + return this.droppedEventsCount; + } + getTimeUntilCapacity() { + const now = Date.now(); + this.cleanupOldTimestamps(now); + if (this.eventTimestamps.length < this.maxEvents) { + return 0; + } + const oldestRelevant = this.eventTimestamps[this.eventTimestamps.length - this.maxEvents]; + const timeUntilExpiry = Math.max(0, (oldestRelevant + this.windowMs) - now); + return timeUntilExpiry; + } + updateLimits(windowMs, maxEvents) { + if (windowMs !== undefined && windowMs > 0) { + this.windowMs = windowMs; + } + if (maxEvents !== undefined && maxEvents > 0) { + this.maxEvents = maxEvents; + } + logger_1.logger.debug(`Rate limiter updated: ${this.maxEvents} events per ${this.windowMs}ms`); + } +} +exports.TelemetryRateLimiter = TelemetryRateLimiter; +//# sourceMappingURL=rate-limiter.js.map \ No newline at end of file diff --git a/dist/telemetry/rate-limiter.js.map b/dist/telemetry/rate-limiter.js.map new file mode 100644 index 0000000..3675f44 --- /dev/null +++ b/dist/telemetry/rate-limiter.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../src/telemetry/rate-limiter.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/telemetry/startup-checkpoints.d.ts b/dist/telemetry/startup-checkpoints.d.ts new file mode 100644 index 0000000..e99408b --- /dev/null +++ b/dist/telemetry/startup-checkpoints.d.ts @@ -0,0 +1,26 @@ +export declare const STARTUP_CHECKPOINTS: { + readonly PROCESS_STARTED: "process_started"; + readonly DATABASE_CONNECTING: "database_connecting"; + readonly DATABASE_CONNECTED: "database_connected"; + readonly N8N_API_CHECKING: "n8n_api_checking"; + readonly N8N_API_READY: "n8n_api_ready"; + readonly TELEMETRY_INITIALIZING: "telemetry_initializing"; + readonly TELEMETRY_READY: "telemetry_ready"; + readonly MCP_HANDSHAKE_STARTING: "mcp_handshake_starting"; + readonly MCP_HANDSHAKE_COMPLETE: "mcp_handshake_complete"; + readonly SERVER_READY: "server_ready"; +}; +export type StartupCheckpoint = typeof STARTUP_CHECKPOINTS[keyof typeof STARTUP_CHECKPOINTS]; +export interface CheckpointData { + name: StartupCheckpoint; + timestamp: number; + success: boolean; + error?: string; +} +export declare function getAllCheckpoints(): StartupCheckpoint[]; +export declare function findFailedCheckpoint(passedCheckpoints: string[]): StartupCheckpoint; +export declare function isValidCheckpoint(checkpoint: string): checkpoint is StartupCheckpoint; +export declare function getCheckpointDescription(checkpoint: StartupCheckpoint): string; +export declare function getNextCheckpoint(current: StartupCheckpoint): StartupCheckpoint | null; +export declare function getCompletionPercentage(passedCheckpoints: string[]): number; +//# sourceMappingURL=startup-checkpoints.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/startup-checkpoints.d.ts.map b/dist/telemetry/startup-checkpoints.d.ts.map new file mode 100644 index 0000000..7f7f301 --- /dev/null +++ b/dist/telemetry/startup-checkpoints.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"startup-checkpoints.d.ts","sourceRoot":"","sources":["../../src/telemetry/startup-checkpoints.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,mBAAmB;;;;;;;;;;;CA8BtB,CAAC;AAKX,MAAM,MAAM,iBAAiB,GAAG,OAAO,mBAAmB,CAAC,MAAM,OAAO,mBAAmB,CAAC,CAAC;AAK7F,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,iBAAiB,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,wBAAgB,iBAAiB,IAAI,iBAAiB,EAAE,CAEvD;AAMD,wBAAgB,oBAAoB,CAAC,iBAAiB,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAYnF;AAKD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,IAAI,iBAAiB,CAErF;AAKD,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,iBAAiB,GAAG,MAAM,CAe9E;AAMD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,GAAG,iBAAiB,GAAG,IAAI,CAStF;AAKD,wBAAgB,uBAAuB,CAAC,iBAAiB,EAAE,MAAM,EAAE,GAAG,MAAM,CAK3E"} \ No newline at end of file diff --git a/dist/telemetry/startup-checkpoints.js b/dist/telemetry/startup-checkpoints.js new file mode 100644 index 0000000..c7b195f --- /dev/null +++ b/dist/telemetry/startup-checkpoints.js @@ -0,0 +1,65 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.STARTUP_CHECKPOINTS = void 0; +exports.getAllCheckpoints = getAllCheckpoints; +exports.findFailedCheckpoint = findFailedCheckpoint; +exports.isValidCheckpoint = isValidCheckpoint; +exports.getCheckpointDescription = getCheckpointDescription; +exports.getNextCheckpoint = getNextCheckpoint; +exports.getCompletionPercentage = getCompletionPercentage; +exports.STARTUP_CHECKPOINTS = { + PROCESS_STARTED: 'process_started', + DATABASE_CONNECTING: 'database_connecting', + DATABASE_CONNECTED: 'database_connected', + N8N_API_CHECKING: 'n8n_api_checking', + N8N_API_READY: 'n8n_api_ready', + TELEMETRY_INITIALIZING: 'telemetry_initializing', + TELEMETRY_READY: 'telemetry_ready', + MCP_HANDSHAKE_STARTING: 'mcp_handshake_starting', + MCP_HANDSHAKE_COMPLETE: 'mcp_handshake_complete', + SERVER_READY: 'server_ready', +}; +function getAllCheckpoints() { + return Object.values(exports.STARTUP_CHECKPOINTS); +} +function findFailedCheckpoint(passedCheckpoints) { + const allCheckpoints = getAllCheckpoints(); + for (const checkpoint of allCheckpoints) { + if (!passedCheckpoints.includes(checkpoint)) { + return checkpoint; + } + } + return exports.STARTUP_CHECKPOINTS.SERVER_READY; +} +function isValidCheckpoint(checkpoint) { + return getAllCheckpoints().includes(checkpoint); +} +function getCheckpointDescription(checkpoint) { + const descriptions = { + [exports.STARTUP_CHECKPOINTS.PROCESS_STARTED]: 'Process initialization started', + [exports.STARTUP_CHECKPOINTS.DATABASE_CONNECTING]: 'Connecting to database', + [exports.STARTUP_CHECKPOINTS.DATABASE_CONNECTED]: 'Database connection established', + [exports.STARTUP_CHECKPOINTS.N8N_API_CHECKING]: 'Checking n8n API configuration', + [exports.STARTUP_CHECKPOINTS.N8N_API_READY]: 'n8n API ready', + [exports.STARTUP_CHECKPOINTS.TELEMETRY_INITIALIZING]: 'Initializing telemetry system', + [exports.STARTUP_CHECKPOINTS.TELEMETRY_READY]: 'Telemetry system ready', + [exports.STARTUP_CHECKPOINTS.MCP_HANDSHAKE_STARTING]: 'Starting MCP protocol handshake', + [exports.STARTUP_CHECKPOINTS.MCP_HANDSHAKE_COMPLETE]: 'MCP handshake completed', + [exports.STARTUP_CHECKPOINTS.SERVER_READY]: 'Server fully initialized and ready', + }; + return descriptions[checkpoint] || 'Unknown checkpoint'; +} +function getNextCheckpoint(current) { + const allCheckpoints = getAllCheckpoints(); + const currentIndex = allCheckpoints.indexOf(current); + if (currentIndex === -1 || currentIndex === allCheckpoints.length - 1) { + return null; + } + return allCheckpoints[currentIndex + 1]; +} +function getCompletionPercentage(passedCheckpoints) { + const totalCheckpoints = getAllCheckpoints().length; + const passedCount = passedCheckpoints.length; + return Math.round((passedCount / totalCheckpoints) * 100); +} +//# sourceMappingURL=startup-checkpoints.js.map \ No newline at end of file diff --git a/dist/telemetry/startup-checkpoints.js.map b/dist/telemetry/startup-checkpoints.js.map new file mode 100644 index 0000000..75967a8 --- /dev/null +++ b/dist/telemetry/startup-checkpoints.js.map @@ -0,0 +1 @@ +{"version":3,"file":"startup-checkpoints.js","sourceRoot":"","sources":["../../src/telemetry/startup-checkpoints.ts"],"names":[],"mappings":";;;AA4DA,8CAEC;AAMD,oDAYC;AAKD,8CAEC;AAKD,4DAeC;AAMD,8CASC;AAKD,0DAKC;AA1HY,QAAA,mBAAmB,GAAG;IAEjC,eAAe,EAAE,iBAAiB;IAGlC,mBAAmB,EAAE,qBAAqB;IAG1C,kBAAkB,EAAE,oBAAoB;IAGxC,gBAAgB,EAAE,kBAAkB;IAGpC,aAAa,EAAE,eAAe;IAG9B,sBAAsB,EAAE,wBAAwB;IAGhD,eAAe,EAAE,iBAAiB;IAGlC,sBAAsB,EAAE,wBAAwB;IAGhD,sBAAsB,EAAE,wBAAwB;IAGhD,YAAY,EAAE,cAAc;CACpB,CAAC;AAoBX,SAAgB,iBAAiB;IAC/B,OAAO,MAAM,CAAC,MAAM,CAAC,2BAAmB,CAAC,CAAC;AAC5C,CAAC;AAMD,SAAgB,oBAAoB,CAAC,iBAA2B;IAC9D,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;IAE3C,KAAK,MAAM,UAAU,IAAI,cAAc,EAAE,CAAC;QACxC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5C,OAAO,UAAU,CAAC;QACpB,CAAC;IACH,CAAC;IAID,OAAO,2BAAmB,CAAC,YAAY,CAAC;AAC1C,CAAC;AAKD,SAAgB,iBAAiB,CAAC,UAAkB;IAClD,OAAO,iBAAiB,EAAE,CAAC,QAAQ,CAAC,UAA+B,CAAC,CAAC;AACvE,CAAC;AAKD,SAAgB,wBAAwB,CAAC,UAA6B;IACpE,MAAM,YAAY,GAAsC;QACtD,CAAC,2BAAmB,CAAC,eAAe,CAAC,EAAE,gCAAgC;QACvE,CAAC,2BAAmB,CAAC,mBAAmB,CAAC,EAAE,wBAAwB;QACnE,CAAC,2BAAmB,CAAC,kBAAkB,CAAC,EAAE,iCAAiC;QAC3E,CAAC,2BAAmB,CAAC,gBAAgB,CAAC,EAAE,gCAAgC;QACxE,CAAC,2BAAmB,CAAC,aAAa,CAAC,EAAE,eAAe;QACpD,CAAC,2BAAmB,CAAC,sBAAsB,CAAC,EAAE,+BAA+B;QAC7E,CAAC,2BAAmB,CAAC,eAAe,CAAC,EAAE,wBAAwB;QAC/D,CAAC,2BAAmB,CAAC,sBAAsB,CAAC,EAAE,iCAAiC;QAC/E,CAAC,2BAAmB,CAAC,sBAAsB,CAAC,EAAE,yBAAyB;QACvE,CAAC,2BAAmB,CAAC,YAAY,CAAC,EAAE,oCAAoC;KACzE,CAAC;IAEF,OAAO,YAAY,CAAC,UAAU,CAAC,IAAI,oBAAoB,CAAC;AAC1D,CAAC;AAMD,SAAgB,iBAAiB,CAAC,OAA0B;IAC1D,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;IAC3C,MAAM,YAAY,GAAG,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAErD,IAAI,YAAY,KAAK,CAAC,CAAC,IAAI,YAAY,KAAK,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,cAAc,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;AAC1C,CAAC;AAKD,SAAgB,uBAAuB,CAAC,iBAA2B;IACjE,MAAM,gBAAgB,GAAG,iBAAiB,EAAE,CAAC,MAAM,CAAC;IACpD,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,CAAC;IAE7C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,GAAG,gBAAgB,CAAC,GAAG,GAAG,CAAC,CAAC;AAC5D,CAAC"} \ No newline at end of file diff --git a/dist/telemetry/telemetry-error.d.ts b/dist/telemetry/telemetry-error.d.ts new file mode 100644 index 0000000..c06f6f0 --- /dev/null +++ b/dist/telemetry/telemetry-error.d.ts @@ -0,0 +1,44 @@ +import { TelemetryErrorType, TelemetryErrorContext } from './telemetry-types'; +export { TelemetryErrorType, TelemetryErrorContext } from './telemetry-types'; +export declare class TelemetryError extends Error { + readonly type: TelemetryErrorType; + readonly context?: Record; + readonly timestamp: number; + readonly retryable: boolean; + constructor(type: TelemetryErrorType, message: string, context?: Record, retryable?: boolean); + toContext(): TelemetryErrorContext; + log(): void; +} +export declare class TelemetryCircuitBreaker { + private failureCount; + private lastFailureTime; + private state; + private readonly failureThreshold; + private readonly resetTimeout; + private readonly halfOpenRequests; + private halfOpenCount; + constructor(failureThreshold?: number, resetTimeout?: number, halfOpenRequests?: number); + shouldAllow(): boolean; + recordSuccess(): void; + recordFailure(error?: Error): void; + getState(): { + state: string; + failureCount: number; + canRetry: boolean; + }; + reset(): void; +} +export declare class TelemetryErrorAggregator { + private errors; + private errorDetails; + private readonly maxDetails; + record(error: TelemetryError): void; + getStats(): { + totalErrors: number; + errorsByType: Record; + mostCommonError?: string; + recentErrors: TelemetryErrorContext[]; + }; + reset(): void; +} +//# sourceMappingURL=telemetry-error.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/telemetry-error.d.ts.map b/dist/telemetry/telemetry-error.d.ts.map new file mode 100644 index 0000000..2434976 --- /dev/null +++ b/dist/telemetry/telemetry-error.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"telemetry-error.d.ts","sourceRoot":"","sources":["../../src/telemetry/telemetry-error.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAI9E,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE9E,qBAAa,cAAe,SAAQ,KAAK;IACvC,SAAgB,IAAI,EAAE,kBAAkB,CAAC;IACzC,SAAgB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9C,SAAgB,SAAS,EAAE,MAAM,CAAC;IAClC,SAAgB,SAAS,EAAE,OAAO,CAAC;gBAGjC,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7B,SAAS,GAAE,OAAe;IAgB5B,SAAS,IAAI,qBAAqB;IAalC,GAAG,IAAI,IAAI;CAaZ;AAKD,qBAAa,uBAAuB;IAClC,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,KAAK,CAA6C;IAE1D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,aAAa,CAAa;gBAGhC,gBAAgB,GAAE,MAAU,EAC5B,YAAY,GAAE,MAAc,EAC5B,gBAAgB,GAAE,MAAU;IAU9B,WAAW,IAAI,OAAO;IAiCtB,aAAa,IAAI,IAAI;IAiBrB,aAAa,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI;IAqBlC,QAAQ,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE;IAWtE,KAAK,IAAI,IAAI;CAMd;AAKD,qBAAa,wBAAwB;IACnC,OAAO,CAAC,MAAM,CAA8C;IAC5D,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAe;IAK1C,MAAM,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAenC,QAAQ,IAAI;QACV,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,YAAY,EAAE,qBAAqB,EAAE,CAAC;KACvC;IA2BD,KAAK,IAAI,IAAI;CAId"} \ No newline at end of file diff --git a/dist/telemetry/telemetry-error.js b/dist/telemetry/telemetry-error.js new file mode 100644 index 0000000..0b1cd29 --- /dev/null +++ b/dist/telemetry/telemetry-error.js @@ -0,0 +1,153 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TelemetryErrorAggregator = exports.TelemetryCircuitBreaker = exports.TelemetryError = exports.TelemetryErrorType = void 0; +const logger_1 = require("../utils/logger"); +var telemetry_types_1 = require("./telemetry-types"); +Object.defineProperty(exports, "TelemetryErrorType", { enumerable: true, get: function () { return telemetry_types_1.TelemetryErrorType; } }); +class TelemetryError extends Error { + constructor(type, message, context, retryable = false) { + super(message); + this.name = 'TelemetryError'; + this.type = type; + this.context = context; + this.timestamp = Date.now(); + this.retryable = retryable; + Object.setPrototypeOf(this, TelemetryError.prototype); + } + toContext() { + return { + type: this.type, + message: this.message, + context: this.context, + timestamp: this.timestamp, + retryable: this.retryable + }; + } + log() { + const logContext = { + type: this.type, + message: this.message, + ...this.context + }; + if (this.retryable) { + logger_1.logger.debug('Retryable telemetry error:', logContext); + } + else { + logger_1.logger.debug('Non-retryable telemetry error:', logContext); + } + } +} +exports.TelemetryError = TelemetryError; +class TelemetryCircuitBreaker { + constructor(failureThreshold = 5, resetTimeout = 60000, halfOpenRequests = 3) { + this.failureCount = 0; + this.lastFailureTime = 0; + this.state = 'closed'; + this.halfOpenCount = 0; + this.failureThreshold = failureThreshold; + this.resetTimeout = resetTimeout; + this.halfOpenRequests = halfOpenRequests; + } + shouldAllow() { + const now = Date.now(); + switch (this.state) { + case 'closed': + return true; + case 'open': + if (now - this.lastFailureTime > this.resetTimeout) { + this.state = 'half-open'; + this.halfOpenCount = 0; + logger_1.logger.debug('Circuit breaker transitioning to half-open'); + return true; + } + return false; + case 'half-open': + if (this.halfOpenCount < this.halfOpenRequests) { + this.halfOpenCount++; + return true; + } + return false; + default: + return false; + } + } + recordSuccess() { + if (this.state === 'half-open') { + if (this.halfOpenCount >= this.halfOpenRequests) { + this.state = 'closed'; + this.failureCount = 0; + logger_1.logger.debug('Circuit breaker closed after successful recovery'); + } + } + else if (this.state === 'closed') { + this.failureCount = 0; + } + } + recordFailure(error) { + this.failureCount++; + this.lastFailureTime = Date.now(); + if (this.state === 'half-open') { + this.state = 'open'; + logger_1.logger.debug('Circuit breaker opened from half-open state', { error: error?.message }); + } + else if (this.state === 'closed' && this.failureCount >= this.failureThreshold) { + this.state = 'open'; + logger_1.logger.debug(`Circuit breaker opened after ${this.failureCount} failures`, { error: error?.message }); + } + } + getState() { + return { + state: this.state, + failureCount: this.failureCount, + canRetry: this.shouldAllow() + }; + } + reset() { + this.state = 'closed'; + this.failureCount = 0; + this.lastFailureTime = 0; + this.halfOpenCount = 0; + } +} +exports.TelemetryCircuitBreaker = TelemetryCircuitBreaker; +class TelemetryErrorAggregator { + constructor() { + this.errors = new Map(); + this.errorDetails = []; + this.maxDetails = 100; + } + record(error) { + const count = this.errors.get(error.type) || 0; + this.errors.set(error.type, count + 1); + this.errorDetails.push(error.toContext()); + if (this.errorDetails.length > this.maxDetails) { + this.errorDetails.shift(); + } + } + getStats() { + const errorsByType = {}; + let totalErrors = 0; + let mostCommonError; + let maxCount = 0; + for (const [type, count] of this.errors.entries()) { + errorsByType[type] = count; + totalErrors += count; + if (count > maxCount) { + maxCount = count; + mostCommonError = type; + } + } + return { + totalErrors, + errorsByType, + mostCommonError, + recentErrors: this.errorDetails.slice(-10) + }; + } + reset() { + this.errors.clear(); + this.errorDetails = []; + } +} +exports.TelemetryErrorAggregator = TelemetryErrorAggregator; +//# sourceMappingURL=telemetry-error.js.map \ No newline at end of file diff --git a/dist/telemetry/telemetry-error.js.map b/dist/telemetry/telemetry-error.js.map new file mode 100644 index 0000000..7ac1b5c --- /dev/null +++ b/dist/telemetry/telemetry-error.js.map @@ -0,0 +1 @@ +{"version":3,"file":"telemetry-error.js","sourceRoot":"","sources":["../../src/telemetry/telemetry-error.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/telemetry/telemetry-manager.d.ts b/dist/telemetry/telemetry-manager.d.ts new file mode 100644 index 0000000..3988dd1 --- /dev/null +++ b/dist/telemetry/telemetry-manager.d.ts @@ -0,0 +1,130 @@ +export declare class TelemetryManager { + private static instance; + private supabase; + private configManager; + private eventTracker; + private batchProcessor; + private performanceMonitor; + private errorAggregator; + private isInitialized; + private constructor(); + static getInstance(): TelemetryManager; + private ensureInitialized; + private initialize; + trackToolUsage(toolName: string, success: boolean, duration?: number): void; + trackWorkflowCreation(workflow: any, validationPassed: boolean): Promise; + trackWorkflowMutation(data: any): Promise; + trackError(errorType: string, context: string, toolName?: string, errorMessage?: string): void; + trackEvent(eventName: string, properties: Record): void; + trackSessionStart(): void; + trackSearchQuery(query: string, resultsFound: number, searchType: string): void; + trackValidationDetails(nodeType: string, errorType: string, details: Record): void; + trackToolSequence(previousTool: string, currentTool: string, timeDelta: number): void; + trackNodeConfiguration(nodeType: string, propertiesSet: number, usedDefaults: boolean): void; + trackPerformanceMetric(operation: string, duration: number, metadata?: Record): void; + flush(): Promise; + flushMutations(): Promise; + private isEnabled; + disable(): void; + enable(): void; + getStatus(): string; + getMetrics(): { + status: string; + initialized: boolean; + tracking: { + rateLimiter: { + currentEvents: number; + maxEvents: number; + windowMs: number; + droppedEvents: number; + utilizationPercent: number; + remainingCapacity: number; + arraySize: number; + maxArraySize: number; + memoryUsagePercent: number; + }; + validator: { + errors: number; + successes: number; + total: number; + errorRate: number; + }; + eventQueueSize: number; + workflowQueueSize: number; + mutationQueueSize: number; + performanceMetrics: Record; + }; + processing: import("./telemetry-types").TelemetryMetrics & { + circuitBreakerState: any; + deadLetterQueueSize: number; + }; + errors: { + totalErrors: number; + errorsByType: Record; + mostCommonError?: string; + recentErrors: import("./telemetry-types").TelemetryErrorContext[]; + }; + performance: { + summary: { + totalOperations: number; + averageDuration: number; + slowOperations: number; + operationsByType: {}; + memoryUsage: { + heapUsed: number; + heapTotal: number; + external: number; + } | undefined; + uptimeMs: number; + overhead: { + percentage: number; + totalMs: number; + }; + operationsInLastMinute?: undefined; + } | { + totalOperations: number; + operationsInLastMinute: number; + averageDuration: number; + slowOperations: number; + operationsByType: Record; + memoryUsage: { + heapUsed: number; + heapTotal: number; + external: number; + } | undefined; + uptimeMs: number; + overhead: { + percentage: number; + totalMs: number; + }; + }; + percentiles: { + p50: number; + p75: number; + p90: number; + p95: number; + p99: number; + }; + topSlowOperations: { + operation: string; + duration: number; + timestamp: number; + }[]; + memoryTrend: { + trend: string; + delta: number; + }; + recommendations: string[]; + }; + overhead: { + percentage: number; + impact: "minimal" | "low" | "moderate" | "high"; + }; + }; + static resetInstance(): void; +} +export declare const telemetry: TelemetryManager; +//# sourceMappingURL=telemetry-manager.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/telemetry-manager.d.ts.map b/dist/telemetry/telemetry-manager.d.ts.map new file mode 100644 index 0000000..3a9f5b2 --- /dev/null +++ b/dist/telemetry/telemetry-manager.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"telemetry-manager.d.ts","sourceRoot":"","sources":["../../src/telemetry/telemetry-manager.ts"],"names":[],"mappings":"AAcA,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,aAAa,CAAyB;IAC9C,OAAO,CAAC,YAAY,CAAwB;IAC5C,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,kBAAkB,CAA8B;IACxD,OAAO,CAAC,eAAe,CAA2B;IAClD,OAAO,CAAC,aAAa,CAAkB;IAEvC,OAAO;IA0BP,MAAM,CAAC,WAAW,IAAI,gBAAgB;IAUtC,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,UAAU;IAiDlB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAWrE,qBAAqB,CAAC,QAAQ,EAAE,GAAG,EAAE,gBAAgB,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB9E,qBAAqB,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IA6CrD,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI;IAQ9F,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAQpE,iBAAiB,IAAI,IAAI;IAQzB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAO/E,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAO/F,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAOrF,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,IAAI;IAO5F,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAQ3F,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAyCtB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBrC,OAAO,CAAC,SAAS;IAOjB,OAAO,IAAI,IAAI;IAUf,MAAM,IAAI,IAAI;IAQd,SAAS,IAAI,MAAM;IAOnB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAeV,MAAM,CAAC,aAAa,IAAI,IAAI;CAI7B;AAUD,eAAO,MAAM,SAAS,EAAmC,gBAAgB,CAAC"} \ No newline at end of file diff --git a/dist/telemetry/telemetry-manager.js b/dist/telemetry/telemetry-manager.js new file mode 100644 index 0000000..32013af --- /dev/null +++ b/dist/telemetry/telemetry-manager.js @@ -0,0 +1,257 @@ +"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.telemetry = exports.TelemetryManager = void 0; +const supabase_js_1 = require("@supabase/supabase-js"); +const config_manager_1 = require("./config-manager"); +const event_tracker_1 = require("./event-tracker"); +const batch_processor_1 = require("./batch-processor"); +const performance_monitor_1 = require("./performance-monitor"); +const telemetry_types_1 = require("./telemetry-types"); +const telemetry_error_1 = require("./telemetry-error"); +const logger_1 = require("../utils/logger"); +class TelemetryManager { + constructor() { + this.supabase = null; + this.isInitialized = false; + if (TelemetryManager.instance) { + throw new Error('Use TelemetryManager.getInstance() instead of new TelemetryManager()'); + } + this.configManager = config_manager_1.TelemetryConfigManager.getInstance(); + this.errorAggregator = new telemetry_error_1.TelemetryErrorAggregator(); + this.performanceMonitor = new performance_monitor_1.TelemetryPerformanceMonitor(); + this.eventTracker = new event_tracker_1.TelemetryEventTracker(() => this.configManager.getUserId(), () => this.isEnabled()); + this.batchProcessor = new batch_processor_1.TelemetryBatchProcessor(null, () => this.isEnabled()); + } + static getInstance() { + if (!TelemetryManager.instance) { + TelemetryManager.instance = new TelemetryManager(); + } + return TelemetryManager.instance; + } + ensureInitialized() { + if (!this.isInitialized && this.configManager.isEnabled()) { + this.initialize(); + } + } + initialize() { + if (!this.configManager.isEnabled()) { + logger_1.logger.debug('Telemetry disabled by user preference'); + return; + } + const supabaseUrl = process.env.SUPABASE_URL || telemetry_types_1.TELEMETRY_BACKEND.URL; + const supabaseAnonKey = process.env.SUPABASE_ANON_KEY || telemetry_types_1.TELEMETRY_BACKEND.ANON_KEY; + try { + this.supabase = (0, supabase_js_1.createClient)(supabaseUrl, supabaseAnonKey, { + auth: { + persistSession: false, + autoRefreshToken: false, + }, + realtime: { + params: { + eventsPerSecond: 1, + }, + }, + }); + this.batchProcessor = new batch_processor_1.TelemetryBatchProcessor(this.supabase, () => this.isEnabled()); + this.batchProcessor.start(); + this.isInitialized = true; + logger_1.logger.debug('Telemetry initialized successfully'); + } + catch (error) { + const telemetryError = new telemetry_error_1.TelemetryError(telemetry_error_1.TelemetryErrorType.INITIALIZATION_ERROR, 'Failed to initialize telemetry', { error: error instanceof Error ? error.message : String(error) }); + this.errorAggregator.record(telemetryError); + telemetryError.log(); + this.isInitialized = false; + } + } + trackToolUsage(toolName, success, duration) { + this.ensureInitialized(); + this.performanceMonitor.startOperation('trackToolUsage'); + this.eventTracker.trackToolUsage(toolName, success, duration); + this.eventTracker.updateToolSequence(toolName); + this.performanceMonitor.endOperation('trackToolUsage'); + } + async trackWorkflowCreation(workflow, validationPassed) { + this.ensureInitialized(); + this.performanceMonitor.startOperation('trackWorkflowCreation'); + try { + await this.eventTracker.trackWorkflowCreation(workflow, validationPassed); + await this.flush(); + } + catch (error) { + const telemetryError = error instanceof telemetry_error_1.TelemetryError + ? error + : new telemetry_error_1.TelemetryError(telemetry_error_1.TelemetryErrorType.UNKNOWN_ERROR, 'Failed to track workflow', { error: String(error) }); + this.errorAggregator.record(telemetryError); + } + finally { + this.performanceMonitor.endOperation('trackWorkflowCreation'); + } + } + async trackWorkflowMutation(data) { + this.ensureInitialized(); + if (!this.isEnabled()) { + logger_1.logger.debug('Telemetry disabled, skipping mutation tracking'); + return; + } + this.performanceMonitor.startOperation('trackWorkflowMutation'); + try { + const { mutationTracker } = await Promise.resolve().then(() => __importStar(require('./mutation-tracker.js'))); + const userId = this.configManager.getUserId(); + const mutationRecord = await mutationTracker.processMutation(data, userId); + if (mutationRecord) { + this.eventTracker.enqueueMutation(mutationRecord); + const queueSize = this.eventTracker.getMutationQueueSize(); + if (queueSize >= 2) { + await this.flushMutations(); + } + } + } + catch (error) { + const telemetryError = error instanceof telemetry_error_1.TelemetryError + ? error + : new telemetry_error_1.TelemetryError(telemetry_error_1.TelemetryErrorType.UNKNOWN_ERROR, 'Failed to track workflow mutation', { error: String(error) }); + this.errorAggregator.record(telemetryError); + logger_1.logger.debug('Error tracking workflow mutation:', error); + } + finally { + this.performanceMonitor.endOperation('trackWorkflowMutation'); + } + } + trackError(errorType, context, toolName, errorMessage) { + this.ensureInitialized(); + this.eventTracker.trackError(errorType, context, toolName, errorMessage); + } + trackEvent(eventName, properties) { + this.ensureInitialized(); + this.eventTracker.trackEvent(eventName, properties); + } + trackSessionStart() { + this.ensureInitialized(); + this.eventTracker.trackSessionStart(); + } + trackSearchQuery(query, resultsFound, searchType) { + this.eventTracker.trackSearchQuery(query, resultsFound, searchType); + } + trackValidationDetails(nodeType, errorType, details) { + this.eventTracker.trackValidationDetails(nodeType, errorType, details); + } + trackToolSequence(previousTool, currentTool, timeDelta) { + this.eventTracker.trackToolSequence(previousTool, currentTool, timeDelta); + } + trackNodeConfiguration(nodeType, propertiesSet, usedDefaults) { + this.eventTracker.trackNodeConfiguration(nodeType, propertiesSet, usedDefaults); + } + trackPerformanceMetric(operation, duration, metadata) { + this.eventTracker.trackPerformanceMetric(operation, duration, metadata); + } + async flush() { + this.ensureInitialized(); + if (!this.isEnabled() || !this.supabase) + return; + this.performanceMonitor.startOperation('flush'); + const events = this.eventTracker.getEventQueue(); + const workflows = this.eventTracker.getWorkflowQueue(); + const mutations = this.eventTracker.getMutationQueue(); + this.eventTracker.clearEventQueue(); + this.eventTracker.clearWorkflowQueue(); + this.eventTracker.clearMutationQueue(); + try { + await this.batchProcessor.flush(events, workflows, mutations); + } + catch (error) { + const telemetryError = error instanceof telemetry_error_1.TelemetryError + ? error + : new telemetry_error_1.TelemetryError(telemetry_error_1.TelemetryErrorType.NETWORK_ERROR, 'Failed to flush telemetry', { error: String(error) }, true); + this.errorAggregator.record(telemetryError); + telemetryError.log(); + } + finally { + const duration = this.performanceMonitor.endOperation('flush'); + if (duration > 100) { + logger_1.logger.debug(`Telemetry flush took ${duration.toFixed(2)}ms`); + } + } + } + async flushMutations() { + this.ensureInitialized(); + if (!this.isEnabled() || !this.supabase) + return; + const mutations = this.eventTracker.getMutationQueue(); + this.eventTracker.clearMutationQueue(); + if (mutations.length > 0) { + await this.batchProcessor.flush([], [], mutations); + } + } + isEnabled() { + return this.isInitialized && this.configManager.isEnabled(); + } + disable() { + this.configManager.disable(); + this.batchProcessor.stop(); + this.isInitialized = false; + this.supabase = null; + } + enable() { + this.configManager.enable(); + this.initialize(); + } + getStatus() { + return this.configManager.getStatus(); + } + getMetrics() { + return { + status: this.isEnabled() ? 'enabled' : 'disabled', + initialized: this.isInitialized, + tracking: this.eventTracker.getStats(), + processing: this.batchProcessor.getMetrics(), + errors: this.errorAggregator.getStats(), + performance: this.performanceMonitor.getDetailedReport(), + overhead: this.performanceMonitor.getTelemetryOverhead() + }; + } + static resetInstance() { + TelemetryManager.instance = undefined; + global.__telemetryManager = undefined; + } +} +exports.TelemetryManager = TelemetryManager; +const globalAny = global; +if (!globalAny.__telemetryManager) { + globalAny.__telemetryManager = TelemetryManager.getInstance(); +} +exports.telemetry = globalAny.__telemetryManager; +//# sourceMappingURL=telemetry-manager.js.map \ No newline at end of file diff --git a/dist/telemetry/telemetry-manager.js.map b/dist/telemetry/telemetry-manager.js.map new file mode 100644 index 0000000..45d0612 --- /dev/null +++ b/dist/telemetry/telemetry-manager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"telemetry-manager.js","sourceRoot":"","sources":["../../src/telemetry/telemetry-manager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/telemetry/telemetry-types.d.ts b/dist/telemetry/telemetry-types.d.ts new file mode 100644 index 0000000..3cd5d66 --- /dev/null +++ b/dist/telemetry/telemetry-types.d.ts @@ -0,0 +1,103 @@ +import { StartupCheckpoint } from './startup-checkpoints'; +export interface TelemetryEvent { + user_id: string; + event: string; + properties: Record; + created_at?: string; +} +export interface StartupErrorEvent extends TelemetryEvent { + event: 'startup_error'; + properties: { + checkpoint: StartupCheckpoint; + errorMessage: string; + errorType: string; + checkpointsPassed: StartupCheckpoint[]; + checkpointsPassedCount: number; + startupDuration: number; + platform: string; + arch: string; + nodeVersion: string; + isDocker: boolean; + }; +} +export interface StartupCompletedEvent extends TelemetryEvent { + event: 'startup_completed'; + properties: { + version: string; + }; +} +export interface SessionStartProperties { + version: string; + platform: string; + arch: string; + nodeVersion: string; + isDocker: boolean; + cloudPlatform: string | null; + startupDurationMs?: number; + checkpointsPassed?: StartupCheckpoint[]; + startupErrorCount?: number; +} +export interface WorkflowTelemetry { + user_id: string; + workflow_hash: string; + node_count: number; + node_types: string[]; + has_trigger: boolean; + has_webhook: boolean; + complexity: 'simple' | 'medium' | 'complex'; + sanitized_workflow: any; + created_at?: string; +} +export interface SanitizedWorkflow { + nodes: any[]; + connections: any; + nodeCount: number; + nodeTypes: string[]; + hasTrigger: boolean; + hasWebhook: boolean; + complexity: 'simple' | 'medium' | 'complex'; + workflowHash: string; +} +export declare const TELEMETRY_CONFIG: { + readonly BATCH_FLUSH_INTERVAL: 5000; + readonly EVENT_QUEUE_THRESHOLD: 10; + readonly WORKFLOW_QUEUE_THRESHOLD: 5; + readonly MAX_RETRIES: 3; + readonly RETRY_DELAY: 1000; + readonly OPERATION_TIMEOUT: 5000; + readonly RATE_LIMIT_WINDOW: 60000; + readonly RATE_LIMIT_MAX_EVENTS: 100; + readonly MAX_QUEUE_SIZE: 1000; + readonly MAX_BATCH_SIZE: 50; +}; +export declare const TELEMETRY_BACKEND: { + readonly URL: "https://ydyufsohxdfpopqbubwk.supabase.co"; + readonly ANON_KEY: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InlkeXVmc29oeGRmcG9wcWJ1YndrIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTg3OTYyMDAsImV4cCI6MjA3NDM3MjIwMH0.xESphg6h5ozaDsm4Vla3QnDJGc6Nc_cpfoqTHRynkCk"; +}; +export interface TelemetryMetrics { + eventsTracked: number; + eventsDropped: number; + eventsFailed: number; + batchesSent: number; + batchesFailed: number; + averageFlushTime: number; + lastFlushTime?: number; + rateLimitHits: number; +} +export declare enum TelemetryErrorType { + VALIDATION_ERROR = "VALIDATION_ERROR", + NETWORK_ERROR = "NETWORK_ERROR", + RATE_LIMIT_ERROR = "RATE_LIMIT_ERROR", + QUEUE_OVERFLOW_ERROR = "QUEUE_OVERFLOW_ERROR", + INITIALIZATION_ERROR = "INITIALIZATION_ERROR", + UNKNOWN_ERROR = "UNKNOWN_ERROR" +} +export interface TelemetryErrorContext { + type: TelemetryErrorType; + message: string; + context?: Record; + timestamp: number; + retryable: boolean; +} +export type { WorkflowMutationRecord, WorkflowMutationData } from './mutation-types.js'; +//# sourceMappingURL=telemetry-types.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/telemetry-types.d.ts.map b/dist/telemetry/telemetry-types.d.ts.map new file mode 100644 index 0000000..7376d00 --- /dev/null +++ b/dist/telemetry/telemetry-types.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"telemetry-types.d.ts","sourceRoot":"","sources":["../../src/telemetry/telemetry-types.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/telemetry/telemetry-types.js b/dist/telemetry/telemetry-types.js new file mode 100644 index 0000000..b7f26d0 --- /dev/null +++ b/dist/telemetry/telemetry-types.js @@ -0,0 +1,29 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TelemetryErrorType = exports.TELEMETRY_BACKEND = exports.TELEMETRY_CONFIG = void 0; +exports.TELEMETRY_CONFIG = { + BATCH_FLUSH_INTERVAL: 5000, + EVENT_QUEUE_THRESHOLD: 10, + WORKFLOW_QUEUE_THRESHOLD: 5, + MAX_RETRIES: 3, + RETRY_DELAY: 1000, + OPERATION_TIMEOUT: 5000, + RATE_LIMIT_WINDOW: 60000, + RATE_LIMIT_MAX_EVENTS: 100, + MAX_QUEUE_SIZE: 1000, + MAX_BATCH_SIZE: 50, +}; +exports.TELEMETRY_BACKEND = { + URL: 'https://ydyufsohxdfpopqbubwk.supabase.co', + ANON_KEY: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InlkeXVmc29oeGRmcG9wcWJ1YndrIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTg3OTYyMDAsImV4cCI6MjA3NDM3MjIwMH0.xESphg6h5ozaDsm4Vla3QnDJGc6Nc_cpfoqTHRynkCk' +}; +var TelemetryErrorType; +(function (TelemetryErrorType) { + TelemetryErrorType["VALIDATION_ERROR"] = "VALIDATION_ERROR"; + TelemetryErrorType["NETWORK_ERROR"] = "NETWORK_ERROR"; + TelemetryErrorType["RATE_LIMIT_ERROR"] = "RATE_LIMIT_ERROR"; + TelemetryErrorType["QUEUE_OVERFLOW_ERROR"] = "QUEUE_OVERFLOW_ERROR"; + TelemetryErrorType["INITIALIZATION_ERROR"] = "INITIALIZATION_ERROR"; + TelemetryErrorType["UNKNOWN_ERROR"] = "UNKNOWN_ERROR"; +})(TelemetryErrorType || (exports.TelemetryErrorType = TelemetryErrorType = {})); +//# sourceMappingURL=telemetry-types.js.map \ No newline at end of file diff --git a/dist/telemetry/telemetry-types.js.map b/dist/telemetry/telemetry-types.js.map new file mode 100644 index 0000000..88f4227 --- /dev/null +++ b/dist/telemetry/telemetry-types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"telemetry-types.js","sourceRoot":"","sources":["../../src/telemetry/telemetry-types.ts"],"names":[],"mappings":";;;AAkFa,QAAA,gBAAgB,GAAG;IAE9B,oBAAoB,EAAE,IAAI;IAC1B,qBAAqB,EAAE,EAAE;IACzB,wBAAwB,EAAE,CAAC;IAG3B,WAAW,EAAE,CAAC;IACd,WAAW,EAAE,IAAI;IACjB,iBAAiB,EAAE,IAAI;IAGvB,iBAAiB,EAAE,KAAK;IACxB,qBAAqB,EAAE,GAAG;IAG1B,cAAc,EAAE,IAAI;IACpB,cAAc,EAAE,EAAE;CACV,CAAC;AAEE,QAAA,iBAAiB,GAAG;IAC/B,GAAG,EAAE,0CAA0C;IAC/C,QAAQ,EAAE,kNAAkN;CACpN,CAAC;AAaX,IAAY,kBAOX;AAPD,WAAY,kBAAkB;IAC5B,2DAAqC,CAAA;IACrC,qDAA+B,CAAA;IAC/B,2DAAqC,CAAA;IACrC,mEAA6C,CAAA;IAC7C,mEAA6C,CAAA;IAC7C,qDAA+B,CAAA;AACjC,CAAC,EAPW,kBAAkB,kCAAlB,kBAAkB,QAO7B"} \ No newline at end of file diff --git a/dist/telemetry/workflow-sanitizer.d.ts b/dist/telemetry/workflow-sanitizer.d.ts new file mode 100644 index 0000000..e9490db --- /dev/null +++ b/dist/telemetry/workflow-sanitizer.d.ts @@ -0,0 +1,34 @@ +interface WorkflowNode { + id: string; + name: string; + type: string; + position: [number, number]; + parameters: any; + credentials?: any; + disabled?: boolean; + typeVersion?: number; +} +interface SanitizedWorkflow { + nodes: WorkflowNode[]; + connections: any; + nodeCount: number; + nodeTypes: string[]; + hasTrigger: boolean; + hasWebhook: boolean; + complexity: 'simple' | 'medium' | 'complex'; + workflowHash: string; +} +export declare class WorkflowSanitizer { + private static readonly SENSITIVE_PATTERNS; + private static readonly SENSITIVE_FIELDS; + static sanitizeWorkflow(workflow: any): SanitizedWorkflow; + private static sanitizeNode; + private static sanitizeObject; + private static sanitizeString; + private static isSensitiveField; + private static sanitizeConnections; + static generateWorkflowHash(workflow: any): string; + static sanitizeWorkflowRaw(workflow: any): any; +} +export {}; +//# sourceMappingURL=workflow-sanitizer.d.ts.map \ No newline at end of file diff --git a/dist/telemetry/workflow-sanitizer.d.ts.map b/dist/telemetry/workflow-sanitizer.d.ts.map new file mode 100644 index 0000000..22e9dc7 --- /dev/null +++ b/dist/telemetry/workflow-sanitizer.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"workflow-sanitizer.d.ts","sourceRoot":"","sources":["../../src/telemetry/workflow-sanitizer.ts"],"names":[],"mappings":"AAOA,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,UAAU,EAAE,GAAG,CAAC;IAChB,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,iBAAiB;IACzB,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,WAAW,EAAE,GAAG,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC5C,YAAY,EAAE,MAAM,CAAC;CACtB;AAQD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAmBxC;IAEF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAoBtC;IAKF,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,GAAG,iBAAiB;IAwEzD,OAAO,CAAC,MAAM,CAAC,YAAY;IAiB3B,OAAO,CAAC,MAAM,CAAC,cAAc;IAqD7B,OAAO,CAAC,MAAM,CAAC,cAAc;IAyE7B,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAU/B,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAsClC,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM;IASlD,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG;CA4B/C"} \ No newline at end of file diff --git a/dist/telemetry/workflow-sanitizer.js b/dist/telemetry/workflow-sanitizer.js new file mode 100644 index 0000000..2f73b7a --- /dev/null +++ b/dist/telemetry/workflow-sanitizer.js @@ -0,0 +1,242 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.WorkflowSanitizer = void 0; +const crypto_1 = require("crypto"); +class WorkflowSanitizer { + static sanitizeWorkflow(workflow) { + const sanitized = JSON.parse(JSON.stringify(workflow)); + if (sanitized.nodes && Array.isArray(sanitized.nodes)) { + sanitized.nodes = sanitized.nodes.map((node) => this.sanitizeNode(node)); + } + if (sanitized.connections) { + sanitized.connections = this.sanitizeConnections(sanitized.connections); + } + delete sanitized.settings?.errorWorkflow; + delete sanitized.staticData; + delete sanitized.pinData; + delete sanitized.credentials; + delete sanitized.sharedWorkflows; + delete sanitized.ownedBy; + delete sanitized.createdBy; + delete sanitized.updatedBy; + const nodeTypes = sanitized.nodes?.map((n) => n.type) || []; + const uniqueNodeTypes = [...new Set(nodeTypes)]; + const hasTrigger = nodeTypes.some((type) => type.includes('trigger') || type.includes('webhook')); + const hasWebhook = nodeTypes.some((type) => type.includes('webhook')); + const nodeCount = sanitized.nodes?.length || 0; + let complexity = 'simple'; + if (nodeCount > 20) { + complexity = 'complex'; + } + else if (nodeCount > 10) { + complexity = 'medium'; + } + const workflowStructure = JSON.stringify({ + nodeTypes: uniqueNodeTypes.sort(), + connections: sanitized.connections + }); + const workflowHash = (0, crypto_1.createHash)('sha256') + .update(workflowStructure) + .digest('hex') + .substring(0, 16); + return { + nodes: sanitized.nodes || [], + connections: sanitized.connections || {}, + nodeCount, + nodeTypes: uniqueNodeTypes, + hasTrigger, + hasWebhook, + complexity, + workflowHash + }; + } + static sanitizeNode(node) { + const sanitized = { ...node }; + delete sanitized.credentials; + if (sanitized.parameters) { + sanitized.parameters = this.sanitizeObject(sanitized.parameters); + } + return sanitized; + } + static sanitizeObject(obj) { + if (!obj || typeof obj !== 'object') { + return obj; + } + if (Array.isArray(obj)) { + return obj.map(item => this.sanitizeObject(item)); + } + const sanitized = {}; + for (const [key, value] of Object.entries(obj)) { + const isSensitive = this.isSensitiveField(key); + const isUrlField = key.toLowerCase().includes('url') || + key.toLowerCase().includes('endpoint') || + key.toLowerCase().includes('webhook'); + if (typeof value === 'object' && value !== null) { + if (isSensitive && !isUrlField) { + sanitized[key] = '[REDACTED]'; + } + else { + sanitized[key] = this.sanitizeObject(value); + } + } + else if (typeof value === 'string') { + if (isSensitive && !isUrlField) { + sanitized[key] = '[REDACTED]'; + } + else { + sanitized[key] = this.sanitizeString(value, key); + } + } + else if (isSensitive) { + sanitized[key] = '[REDACTED]'; + } + else { + sanitized[key] = value; + } + } + return sanitized; + } + static sanitizeString(value, fieldName) { + if (value.includes('/webhook/') || value.includes('/hook/')) { + return 'https://[webhook-url]'; + } + let sanitized = value; + for (const patternDef of this.SENSITIVE_PATTERNS) { + if (patternDef.placeholder.includes('WEBHOOK')) { + continue; + } + if (sanitized.includes('[REDACTED')) { + break; + } + if (patternDef.placeholder === '[REDACTED_URL_WITH_AUTH]') { + const matches = value.match(patternDef.pattern); + if (matches) { + for (const match of matches) { + const fullUrlMatch = value.indexOf(match); + if (fullUrlMatch !== -1) { + const afterUrl = value.substring(fullUrlMatch + match.length); + if (afterUrl && afterUrl.startsWith('/')) { + const pathPart = afterUrl.split(/[\s?&#]/)[0]; + sanitized = sanitized.replace(match + pathPart, patternDef.placeholder + pathPart); + } + else { + sanitized = sanitized.replace(match, patternDef.placeholder); + } + } + } + } + continue; + } + sanitized = sanitized.replace(patternDef.pattern, patternDef.placeholder); + } + if (fieldName.toLowerCase().includes('url') || + fieldName.toLowerCase().includes('endpoint')) { + if (sanitized.startsWith('http://') || sanitized.startsWith('https://')) { + if (sanitized.includes('[REDACTED_URL_WITH_AUTH]')) { + return sanitized; + } + if (sanitized.includes('[REDACTED]')) { + return sanitized; + } + const urlParts = sanitized.split('/'); + if (urlParts.length > 2) { + urlParts[2] = '[domain]'; + sanitized = urlParts.join('/'); + } + } + } + return sanitized; + } + static isSensitiveField(fieldName) { + const lowerFieldName = fieldName.toLowerCase(); + return this.SENSITIVE_FIELDS.some(sensitive => lowerFieldName.includes(sensitive.toLowerCase())); + } + static sanitizeConnections(connections) { + if (!connections || typeof connections !== 'object') { + return connections; + } + const sanitized = {}; + for (const [nodeId, nodeConnections] of Object.entries(connections)) { + if (typeof nodeConnections === 'object' && nodeConnections !== null) { + sanitized[nodeId] = {}; + for (const [connType, connArray] of Object.entries(nodeConnections)) { + if (Array.isArray(connArray)) { + sanitized[nodeId][connType] = connArray.map((conns) => { + if (Array.isArray(conns)) { + return conns.map((conn) => ({ + node: conn.node, + type: conn.type, + index: conn.index + })); + } + return conns; + }); + } + else { + sanitized[nodeId][connType] = connArray; + } + } + } + else { + sanitized[nodeId] = nodeConnections; + } + } + return sanitized; + } + static generateWorkflowHash(workflow) { + const sanitized = this.sanitizeWorkflow(workflow); + return sanitized.workflowHash; + } + static sanitizeWorkflowRaw(workflow) { + const sanitized = JSON.parse(JSON.stringify(workflow)); + if (sanitized.nodes && Array.isArray(sanitized.nodes)) { + sanitized.nodes = sanitized.nodes.map((node) => this.sanitizeNode(node)); + } + if (sanitized.connections) { + sanitized.connections = this.sanitizeConnections(sanitized.connections); + } + delete sanitized.settings?.errorWorkflow; + delete sanitized.staticData; + delete sanitized.pinData; + delete sanitized.credentials; + delete sanitized.sharedWorkflows; + delete sanitized.ownedBy; + delete sanitized.createdBy; + delete sanitized.updatedBy; + return sanitized; + } +} +exports.WorkflowSanitizer = WorkflowSanitizer; +WorkflowSanitizer.SENSITIVE_PATTERNS = [ + { pattern: /https?:\/\/[^\s/]+\/webhook\/[^\s]+/g, placeholder: '[REDACTED_WEBHOOK]' }, + { pattern: /https?:\/\/[^\s/]+\/hook\/[^\s]+/g, placeholder: '[REDACTED_WEBHOOK]' }, + { pattern: /https?:\/\/[^:]+:[^@]+@[^\s/]+/g, placeholder: '[REDACTED_URL_WITH_AUTH]' }, + { pattern: /wss?:\/\/[^:]+:[^@]+@[^\s/]+/g, placeholder: '[REDACTED_URL_WITH_AUTH]' }, + { pattern: /(?:postgres|mysql|mongodb|redis):\/\/[^:]+:[^@]+@[^\s]+/g, placeholder: '[REDACTED_URL_WITH_AUTH]' }, + { pattern: /sk-[a-zA-Z0-9]{16,}/g, placeholder: '[REDACTED_APIKEY]' }, + { pattern: /Bearer\s+[^\s]+/gi, placeholder: 'Bearer [REDACTED]', preservePrefix: true }, + { pattern: /\b[a-zA-Z0-9_-]{32,}\b/g, placeholder: '[REDACTED_TOKEN]' }, + { pattern: /\b[a-zA-Z0-9_-]{20,31}\b/g, placeholder: '[REDACTED]' }, +]; +WorkflowSanitizer.SENSITIVE_FIELDS = [ + 'apiKey', + 'api_key', + 'token', + 'secret', + 'password', + 'credential', + 'auth', + 'authorization', + 'webhook', + 'webhookUrl', + 'url', + 'endpoint', + 'host', + 'server', + 'database', + 'connectionString', + 'privateKey', + 'publicKey', + 'certificate', +]; +//# sourceMappingURL=workflow-sanitizer.js.map \ No newline at end of file diff --git a/dist/telemetry/workflow-sanitizer.js.map b/dist/telemetry/workflow-sanitizer.js.map new file mode 100644 index 0000000..eb31092 --- /dev/null +++ b/dist/telemetry/workflow-sanitizer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"workflow-sanitizer.js","sourceRoot":"","sources":["../../src/telemetry/workflow-sanitizer.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/templates/batch-processor.d.ts b/dist/templates/batch-processor.d.ts new file mode 100644 index 0000000..961f5d0 --- /dev/null +++ b/dist/templates/batch-processor.d.ts @@ -0,0 +1,35 @@ +import { MetadataRequest, MetadataResult } from './metadata-generator'; +export interface BatchProcessorOptions { + apiKey: string; + model?: string; + batchSize?: number; + outputDir?: string; +} +export interface BatchJob { + id: string; + status: 'validating' | 'in_progress' | 'finalizing' | 'completed' | 'failed' | 'expired' | 'cancelled'; + created_at: number; + completed_at?: number; + input_file_id: string; + output_file_id?: string; + error?: any; +} +export declare class BatchProcessor { + private client; + private generator; + private batchSize; + private outputDir; + constructor(options: BatchProcessorOptions); + processTemplates(templates: MetadataRequest[], progressCallback?: (message: string, current: number, total: number) => void): Promise>; + private submitBatch; + private processBatch; + private createBatches; + private createBatchFile; + private uploadFile; + private createBatchJob; + private monitorBatchJob; + private retrieveResults; + private cleanup; + private sleep; +} +//# sourceMappingURL=batch-processor.d.ts.map \ No newline at end of file diff --git a/dist/templates/batch-processor.d.ts.map b/dist/templates/batch-processor.d.ts.map new file mode 100644 index 0000000..a72d198 --- /dev/null +++ b/dist/templates/batch-processor.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"batch-processor.d.ts","sourceRoot":"","sources":["../../src/templates/batch-processor.ts"],"names":[],"mappings":"AAIA,OAAO,EAAqB,eAAe,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE1F,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,YAAY,GAAG,aAAa,GAAG,YAAY,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;IACvG,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAoB;IACrC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;gBAEd,OAAO,EAAE,qBAAqB;IAepC,gBAAgB,CACpB,SAAS,EAAE,eAAe,EAAE,EAC5B,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GAC3E,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;YAwEzB,WAAW;YA6CX,YAAY;IAiC1B,OAAO,CAAC,aAAa;YAaP,eAAe;YAwBf,UAAU;YAcV,cAAc;YAcd,eAAe;YAiDf,eAAe;YAiFf,OAAO;IA8BrB,OAAO,CAAC,KAAK;CAGd"} \ No newline at end of file diff --git a/dist/templates/batch-processor.js b/dist/templates/batch-processor.js new file mode 100644 index 0000000..29a0509 --- /dev/null +++ b/dist/templates/batch-processor.js @@ -0,0 +1,320 @@ +"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; + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BatchProcessor = void 0; +const fs = __importStar(require("fs")); +const path = __importStar(require("path")); +const openai_1 = __importDefault(require("openai")); +const logger_1 = require("../utils/logger"); +const metadata_generator_1 = require("./metadata-generator"); +class BatchProcessor { + constructor(options) { + this.client = new openai_1.default({ apiKey: options.apiKey }); + this.generator = new metadata_generator_1.MetadataGenerator(options.apiKey, options.model); + this.batchSize = options.batchSize || 100; + this.outputDir = options.outputDir || './temp'; + if (!fs.existsSync(this.outputDir)) { + fs.mkdirSync(this.outputDir, { recursive: true }); + } + } + async processTemplates(templates, progressCallback) { + const results = new Map(); + const batches = this.createBatches(templates); + logger_1.logger.info(`Processing ${templates.length} templates in ${batches.length} batches`); + console.log(`\n📤 Submitting ${batches.length} batch${batches.length > 1 ? 'es' : ''} to OpenAI...`); + const batchJobs = []; + for (let i = 0; i < batches.length; i++) { + const batch = batches[i]; + const batchNum = i + 1; + try { + progressCallback?.(`Submitting batch ${batchNum}/${batches.length}`, i * this.batchSize, templates.length); + const jobPromise = this.submitBatch(batch, `batch_${batchNum}`); + batchJobs.push({ batchNum, jobPromise, templates: batch }); + console.log(` 📨 Submitted batch ${batchNum}/${batches.length} (${batch.length} templates)`); + } + catch (error) { + logger_1.logger.error(`Error submitting batch ${batchNum}:`, error); + console.error(` ❌ Failed to submit batch ${batchNum}`); + } + } + console.log(`\n⏳ All batches submitted. Waiting for completion...`); + console.log(` (Batches process in parallel - this is much faster than sequential processing)`); + const batchPromises = batchJobs.map(async ({ batchNum, jobPromise, templates: batchTemplates }) => { + try { + const completedJob = await jobPromise; + console.log(`\n📦 Retrieving results for batch ${batchNum}/${batches.length}...`); + const batchResults = await this.retrieveResults(completedJob); + logger_1.logger.info(`Retrieved ${batchResults.length} results from batch ${batchNum}`); + progressCallback?.(`Retrieved batch ${batchNum}/${batches.length}`, Math.min(batchNum * this.batchSize, templates.length), templates.length); + return { batchNum, results: batchResults }; + } + catch (error) { + logger_1.logger.error(`Error processing batch ${batchNum}:`, error); + console.error(` ❌ Batch ${batchNum} failed:`, error); + return { batchNum, results: [] }; + } + }); + const allBatchResults = await Promise.all(batchPromises); + for (const { batchNum, results: batchResults } of allBatchResults) { + for (const result of batchResults) { + results.set(result.templateId, result); + } + if (batchResults.length > 0) { + console.log(` ✅ Merged ${batchResults.length} results from batch ${batchNum}`); + } + } + logger_1.logger.info(`Batch processing complete: ${results.size} results`); + return results; + } + async submitBatch(templates, batchName) { + const inputFile = await this.createBatchFile(templates, batchName); + try { + const uploadedFile = await this.uploadFile(inputFile); + const batchJob = await this.createBatchJob(uploadedFile.id); + const monitoringPromise = this.monitorBatchJob(batchJob.id); + try { + fs.unlinkSync(inputFile); + } + catch { } + monitoringPromise.then(async (completedJob) => { + try { + await this.client.files.del(uploadedFile.id); + if (completedJob.output_file_id) { + } + } + catch (error) { + logger_1.logger.warn(`Failed to cleanup files for batch ${batchName}`, error); + } + }); + return monitoringPromise; + } + catch (error) { + try { + fs.unlinkSync(inputFile); + } + catch { } + throw error; + } + } + async processBatch(templates, batchName) { + const inputFile = await this.createBatchFile(templates, batchName); + try { + const uploadedFile = await this.uploadFile(inputFile); + const batchJob = await this.createBatchJob(uploadedFile.id); + const completedJob = await this.monitorBatchJob(batchJob.id); + const results = await this.retrieveResults(completedJob); + await this.cleanup(inputFile, uploadedFile.id, completedJob.output_file_id); + return results; + } + catch (error) { + try { + fs.unlinkSync(inputFile); + } + catch { } + throw error; + } + } + createBatches(templates) { + const batches = []; + for (let i = 0; i < templates.length; i += this.batchSize) { + batches.push(templates.slice(i, i + this.batchSize)); + } + return batches; + } + async createBatchFile(templates, batchName) { + const filename = path.join(this.outputDir, `${batchName}_${Date.now()}.jsonl`); + const stream = fs.createWriteStream(filename); + for (const template of templates) { + const request = this.generator.createBatchRequest(template); + stream.write(JSON.stringify(request) + '\n'); + } + stream.end(); + await new Promise((resolve, reject) => { + stream.on('finish', () => resolve()); + stream.on('error', reject); + }); + logger_1.logger.debug(`Created batch file: ${filename} with ${templates.length} requests`); + return filename; + } + async uploadFile(filepath) { + const file = fs.createReadStream(filepath); + const uploadedFile = await this.client.files.create({ + file, + purpose: 'batch' + }); + logger_1.logger.debug(`Uploaded file: ${uploadedFile.id}`); + return uploadedFile; + } + async createBatchJob(fileId) { + const batchJob = await this.client.batches.create({ + input_file_id: fileId, + endpoint: '/v1/chat/completions', + completion_window: '24h' + }); + logger_1.logger.info(`Created batch job: ${batchJob.id}`); + return batchJob; + } + async monitorBatchJob(batchId) { + const pollInterval = 60; + let attempts = 0; + const maxAttempts = 120; + const startTime = Date.now(); + let lastStatus = ''; + while (attempts < maxAttempts) { + const batchJob = await this.client.batches.retrieve(batchId); + const elapsedMinutes = Math.floor((Date.now() - startTime) / 60000); + const statusSymbol = batchJob.status === 'in_progress' ? '⚙️' : + batchJob.status === 'finalizing' ? '📦' : + batchJob.status === 'validating' ? '🔍' : + batchJob.status === 'completed' ? '✅' : + batchJob.status === 'failed' ? '❌' : '⏳'; + console.log(` ${statusSymbol} Batch ${batchId.slice(-8)}: ${batchJob.status} (${elapsedMinutes} min, check ${attempts + 1})`); + if (batchJob.status !== lastStatus) { + logger_1.logger.info(`Batch ${batchId} status changed: ${lastStatus} -> ${batchJob.status}`); + lastStatus = batchJob.status; + } + if (batchJob.status === 'completed') { + console.log(` ✅ Batch ${batchId.slice(-8)} completed successfully in ${elapsedMinutes} minutes`); + logger_1.logger.info(`Batch job ${batchId} completed successfully`); + return batchJob; + } + if (['failed', 'expired', 'cancelled'].includes(batchJob.status)) { + logger_1.logger.error(`Batch job ${batchId} failed with status: ${batchJob.status}`); + throw new Error(`Batch job failed with status: ${batchJob.status}`); + } + logger_1.logger.debug(`Waiting ${pollInterval} seconds before next check...`); + await this.sleep(pollInterval * 1000); + attempts++; + } + throw new Error(`Batch job monitoring timed out after ${maxAttempts} minutes`); + } + async retrieveResults(batchJob) { + const results = []; + if (batchJob.output_file_id) { + const fileResponse = await this.client.files.content(batchJob.output_file_id); + const fileContent = await fileResponse.text(); + const lines = fileContent.trim().split('\n'); + for (const line of lines) { + if (!line) + continue; + try { + const result = JSON.parse(line); + const parsed = this.generator.parseResult(result); + results.push(parsed); + } + catch (error) { + logger_1.logger.error('Error parsing result line:', error); + } + } + logger_1.logger.info(`Retrieved ${results.length} successful results from batch job`); + } + if (batchJob.error_file_id) { + logger_1.logger.warn(`Batch job has error file: ${batchJob.error_file_id}`); + try { + const errorResponse = await this.client.files.content(batchJob.error_file_id); + const errorContent = await errorResponse.text(); + const errorFilePath = path.join(this.outputDir, `batch_${batchJob.id}_error.jsonl`); + fs.writeFileSync(errorFilePath, errorContent); + logger_1.logger.warn(`Error file saved to: ${errorFilePath}`); + const errorLines = errorContent.trim().split('\n'); + logger_1.logger.warn(`Found ${errorLines.length} failed requests in error file`); + for (const line of errorLines) { + if (!line) + continue; + try { + const errorResult = JSON.parse(line); + const templateId = parseInt(errorResult.custom_id?.replace('template-', '') || '0'); + if (templateId > 0) { + const errorMessage = errorResult.response?.body?.error?.message || + errorResult.error?.message || + 'Unknown error'; + logger_1.logger.debug(`Template ${templateId} failed: ${errorMessage}`); + const defaultMeta = this.generator.getDefaultMetadata(); + results.push({ + templateId, + metadata: defaultMeta, + error: errorMessage + }); + } + } + catch (parseError) { + logger_1.logger.error('Error parsing error line:', parseError); + } + } + } + catch (error) { + logger_1.logger.error('Failed to process error file:', error); + } + } + if (results.length === 0 && !batchJob.output_file_id && !batchJob.error_file_id) { + throw new Error('No output file or error file available for batch job'); + } + logger_1.logger.info(`Total results (successful + failed): ${results.length}`); + return results; + } + async cleanup(localFile, inputFileId, outputFileId) { + try { + fs.unlinkSync(localFile); + logger_1.logger.debug(`Deleted local file: ${localFile}`); + } + catch (error) { + logger_1.logger.warn(`Failed to delete local file: ${localFile}`, error); + } + try { + await this.client.files.del(inputFileId); + logger_1.logger.debug(`Deleted input file from OpenAI: ${inputFileId}`); + } + catch (error) { + logger_1.logger.warn(`Failed to delete input file from OpenAI: ${inputFileId}`, error); + } + if (outputFileId) { + try { + await this.client.files.del(outputFileId); + logger_1.logger.debug(`Deleted output file from OpenAI: ${outputFileId}`); + } + catch (error) { + logger_1.logger.warn(`Failed to delete output file from OpenAI: ${outputFileId}`, error); + } + } + } + sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); + } +} +exports.BatchProcessor = BatchProcessor; +//# sourceMappingURL=batch-processor.js.map \ No newline at end of file diff --git a/dist/templates/batch-processor.js.map b/dist/templates/batch-processor.js.map new file mode 100644 index 0000000..a136c17 --- /dev/null +++ b/dist/templates/batch-processor.js.map @@ -0,0 +1 @@ +{"version":3,"file":"batch-processor.js","sourceRoot":"","sources":["../../src/templates/batch-processor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAC7B,oDAA4B;AAC5B,4CAAyC;AACzC,6DAA0F;AAmB1F,MAAa,cAAc;IAMzB,YAAY,OAA8B;QACxC,IAAI,CAAC,MAAM,GAAG,IAAI,gBAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,SAAS,GAAG,IAAI,sCAAiB,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QACtE,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,GAAG,CAAC;QAC1C,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,QAAQ,CAAC;QAG/C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACnC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAKD,KAAK,CAAC,gBAAgB,CACpB,SAA4B,EAC5B,gBAA4E;QAE5E,MAAM,OAAO,GAAG,IAAI,GAAG,EAA0B,CAAC;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAE9C,eAAM,CAAC,IAAI,CAAC,cAAc,SAAS,CAAC,MAAM,iBAAiB,OAAO,CAAC,MAAM,UAAU,CAAC,CAAC;QAGrF,OAAO,CAAC,GAAG,CAAC,mBAAmB,OAAO,CAAC,MAAM,SAAS,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC;QACrG,MAAM,SAAS,GAAwF,EAAE,CAAC;QAE1G,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YACzB,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC;YAEvB,IAAI,CAAC;gBACH,gBAAgB,EAAE,CAAC,oBAAoB,QAAQ,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;gBAG3G,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC,CAAC;gBAChE,SAAS,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;gBAE3D,OAAO,CAAC,GAAG,CAAC,yBAAyB,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,aAAa,CAAC,CAAC;YACjG,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,eAAM,CAAC,KAAK,CAAC,0BAA0B,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC;gBAC3D,OAAO,CAAC,KAAK,CAAC,+BAA+B,QAAQ,EAAE,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,mFAAmF,CAAC,CAAC;QAGjG,MAAM,aAAa,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,EAAE,EAAE;YAChG,IAAI,CAAC;gBACH,MAAM,YAAY,GAAG,MAAM,UAAU,CAAC;gBACtC,OAAO,CAAC,GAAG,CAAC,qCAAqC,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC;gBAGlF,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;gBAE9D,eAAM,CAAC,IAAI,CAAC,aAAa,YAAY,CAAC,MAAM,uBAAuB,QAAQ,EAAE,CAAC,CAAC;gBAC/E,gBAAgB,EAAE,CAAC,mBAAmB,QAAQ,IAAI,OAAO,CAAC,MAAM,EAAE,EAChE,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;gBAE3E,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;YAC7C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,eAAM,CAAC,KAAK,CAAC,0BAA0B,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC;gBAC3D,OAAO,CAAC,KAAK,CAAC,cAAc,QAAQ,UAAU,EAAE,KAAK,CAAC,CAAC;gBACvD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;YACnC,CAAC;QACH,CAAC,CAAC,CAAC;QAGH,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAGzD,KAAK,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,eAAe,EAAE,CAAC;YAClE,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;gBAClC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YACzC,CAAC;YACD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC5B,OAAO,CAAC,GAAG,CAAC,eAAe,YAAY,CAAC,MAAM,uBAAuB,QAAQ,EAAE,CAAC,CAAC;YACnF,CAAC;QACH,CAAC;QAED,eAAM,CAAC,IAAI,CAAC,8BAA8B,OAAO,CAAC,IAAI,UAAU,CAAC,CAAC;QAClE,OAAO,OAAO,CAAC;IACjB,CAAC;IAKO,KAAK,CAAC,WAAW,CAAC,SAA4B,EAAE,SAAiB;QAEvE,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAEnE,IAAI,CAAC;YAEH,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YAGtD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YAG5D,MAAM,iBAAiB,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAG5D,IAAI,CAAC;gBACH,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YAC3B,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YAGV,iBAAiB,CAAC,IAAI,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE;gBAE5C,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;oBAC7C,IAAI,YAAY,CAAC,cAAc,EAAE,CAAC;oBAElC,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,eAAM,CAAC,IAAI,CAAC,qCAAqC,SAAS,EAAE,EAAE,KAAK,CAAC,CAAC;gBACvE,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,OAAO,iBAAiB,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAEf,IAAI,CAAC;gBACH,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YAC3B,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YACV,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAKO,KAAK,CAAC,YAAY,CAAC,SAA4B,EAAE,SAAiB;QAExE,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAEnE,IAAI,CAAC;YAEH,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YAGtD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YAG5D,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAG7D,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;YAGzD,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC;YAE5E,OAAO,OAAO,CAAC;QACjB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAEf,IAAI,CAAC;gBACH,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YAC3B,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YACV,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAKO,aAAa,CAAC,SAA4B;QAChD,MAAM,OAAO,GAAwB,EAAE,CAAC;QAExC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC1D,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QACvD,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAKO,KAAK,CAAC,eAAe,CAAC,SAA4B,EAAE,SAAiB;QAC3E,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC/E,MAAM,MAAM,GAAG,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAE9C,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YAC5D,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;QAC/C,CAAC;QAED,MAAM,CAAC,GAAG,EAAE,CAAC;QAGb,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1C,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;YACrC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,eAAM,CAAC,KAAK,CAAC,uBAAuB,QAAQ,SAAS,SAAS,CAAC,MAAM,WAAW,CAAC,CAAC;QAClF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAKO,KAAK,CAAC,UAAU,CAAC,QAAgB;QACvC,MAAM,IAAI,GAAG,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAC3C,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;YAClD,IAAI;YACJ,OAAO,EAAE,OAAO;SACjB,CAAC,CAAC;QAEH,eAAM,CAAC,KAAK,CAAC,kBAAkB,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC;QAClD,OAAO,YAAY,CAAC;IACtB,CAAC;IAKO,KAAK,CAAC,cAAc,CAAC,MAAc;QACzC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;YAChD,aAAa,EAAE,MAAM;YACrB,QAAQ,EAAE,sBAAsB;YAChC,iBAAiB,EAAE,KAAK;SACzB,CAAC,CAAC;QAEH,eAAM,CAAC,IAAI,CAAC,sBAAsB,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;QACjD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAKO,KAAK,CAAC,eAAe,CAAC,OAAe;QAC3C,MAAM,YAAY,GAAG,EAAE,CAAC;QACxB,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,MAAM,WAAW,GAAG,GAAG,CAAC;QACxB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,IAAI,UAAU,GAAG,EAAE,CAAC;QAEpB,OAAO,QAAQ,GAAG,WAAW,EAAE,CAAC;YAC9B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC7D,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,KAAK,CAAC,CAAC;YAGpE,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBAC3C,QAAQ,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;oBACzC,QAAQ,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;wBACzC,QAAQ,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;4BACvC,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAE7D,OAAO,CAAC,GAAG,CAAC,MAAM,YAAY,UAAU,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,KAAK,cAAc,eAAe,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC;YAEhI,IAAI,QAAQ,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;gBACnC,eAAM,CAAC,IAAI,CAAC,SAAS,OAAO,oBAAoB,UAAU,OAAO,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;gBACpF,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC;YAC/B,CAAC;YAED,IAAI,QAAQ,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBACpC,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,8BAA8B,cAAc,UAAU,CAAC,CAAC;gBACnG,eAAM,CAAC,IAAI,CAAC,aAAa,OAAO,yBAAyB,CAAC,CAAC;gBAC3D,OAAO,QAAQ,CAAC;YAClB,CAAC;YAED,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBACjE,eAAM,CAAC,KAAK,CAAC,aAAa,OAAO,wBAAwB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC5E,MAAM,IAAI,KAAK,CAAC,iCAAiC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACtE,CAAC;YAGD,eAAM,CAAC,KAAK,CAAC,WAAW,YAAY,+BAA+B,CAAC,CAAC;YACrE,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;YAEtC,QAAQ,EAAE,CAAC;QACb,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,wCAAwC,WAAW,UAAU,CAAC,CAAC;IACjF,CAAC;IAKO,KAAK,CAAC,eAAe,CAAC,QAAa;QACzC,MAAM,OAAO,GAAqB,EAAE,CAAC;QAGrC,IAAI,QAAQ,CAAC,cAAc,EAAE,CAAC;YAC5B,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;YAC9E,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,CAAC;YAE9C,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC,IAAI;oBAAE,SAAS;gBACpB,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAChC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;oBAClD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACvB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,eAAM,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;gBACpD,CAAC;YACH,CAAC;YACD,eAAM,CAAC,IAAI,CAAC,aAAa,OAAO,CAAC,MAAM,oCAAoC,CAAC,CAAC;QAC/E,CAAC;QAGD,IAAI,QAAQ,CAAC,aAAa,EAAE,CAAC;YAC3B,eAAM,CAAC,IAAI,CAAC,6BAA6B,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;YAEnE,IAAI,CAAC;gBACH,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;gBAC9E,MAAM,YAAY,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC;gBAGhD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,QAAQ,CAAC,EAAE,cAAc,CAAC,CAAC;gBACpF,EAAE,CAAC,aAAa,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;gBAC9C,eAAM,CAAC,IAAI,CAAC,wBAAwB,aAAa,EAAE,CAAC,CAAC;gBAGrD,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACnD,eAAM,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,MAAM,gCAAgC,CAAC,CAAC;gBAExE,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;oBAC9B,IAAI,CAAC,IAAI;wBAAE,SAAS;oBACpB,IAAI,CAAC;wBACH,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBACrC,MAAM,UAAU,GAAG,QAAQ,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC;wBAEpF,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;4BACnB,MAAM,YAAY,GAAG,WAAW,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO;gCAC3C,WAAW,CAAC,KAAK,EAAE,OAAO;gCAC1B,eAAe,CAAC;4BAEpC,eAAM,CAAC,KAAK,CAAC,YAAY,UAAU,YAAY,YAAY,EAAE,CAAC,CAAC;4BAG/D,MAAM,WAAW,GAAI,IAAI,CAAC,SAAiB,CAAC,kBAAkB,EAAE,CAAC;4BACjE,OAAO,CAAC,IAAI,CAAC;gCACX,UAAU;gCACV,QAAQ,EAAE,WAAW;gCACrB,KAAK,EAAE,YAAY;6BACpB,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;oBAAC,OAAO,UAAU,EAAE,CAAC;wBACpB,eAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE,UAAU,CAAC,CAAC;oBACxD,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,eAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;QAGD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;YAChF,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC1E,CAAC;QAED,eAAM,CAAC,IAAI,CAAC,wCAAwC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACtE,OAAO,OAAO,CAAC;IACjB,CAAC;IAKO,KAAK,CAAC,OAAO,CAAC,SAAiB,EAAE,WAAmB,EAAE,YAAqB;QAEjF,IAAI,CAAC;YACH,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YACzB,eAAM,CAAC,KAAK,CAAC,uBAAuB,SAAS,EAAE,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAM,CAAC,IAAI,CAAC,gCAAgC,SAAS,EAAE,EAAE,KAAK,CAAC,CAAC;QAClE,CAAC;QAGD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACzC,eAAM,CAAC,KAAK,CAAC,mCAAmC,WAAW,EAAE,CAAC,CAAC;QACjE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAM,CAAC,IAAI,CAAC,4CAA4C,WAAW,EAAE,EAAE,KAAK,CAAC,CAAC;QAChF,CAAC;QAED,IAAI,YAAY,EAAE,CAAC;YACjB,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;gBAC1C,eAAM,CAAC,KAAK,CAAC,oCAAoC,YAAY,EAAE,CAAC,CAAC;YACnE,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,eAAM,CAAC,IAAI,CAAC,6CAA6C,YAAY,EAAE,EAAE,KAAK,CAAC,CAAC;YAClF,CAAC;QACH,CAAC;IACH,CAAC;IAKO,KAAK,CAAC,EAAU;QACtB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IACzD,CAAC;CACF;AAlZD,wCAkZC"} \ No newline at end of file diff --git a/dist/templates/metadata-generator.d.ts b/dist/templates/metadata-generator.d.ts new file mode 100644 index 0000000..f90b9b9 --- /dev/null +++ b/dist/templates/metadata-generator.d.ts @@ -0,0 +1,52 @@ +import { z } from 'zod'; +export declare const TemplateMetadataSchema: z.ZodObject<{ + categories: z.ZodArray; + complexity: z.ZodEnum<["simple", "medium", "complex"]>; + use_cases: z.ZodArray; + estimated_setup_minutes: z.ZodNumber; + required_services: z.ZodArray; + key_features: z.ZodArray; + target_audience: z.ZodArray; +}, "strip", z.ZodTypeAny, { + complexity: "simple" | "medium" | "complex"; + categories: string[]; + use_cases: string[]; + estimated_setup_minutes: number; + required_services: string[]; + key_features: string[]; + target_audience: string[]; +}, { + complexity: "simple" | "medium" | "complex"; + categories: string[]; + use_cases: string[]; + estimated_setup_minutes: number; + required_services: string[]; + key_features: string[]; + target_audience: string[]; +}>; +export type TemplateMetadata = z.infer; +export interface MetadataRequest { + templateId: number; + name: string; + description?: string; + nodes: string[]; + workflow?: any; +} +export interface MetadataResult { + templateId: number; + metadata: TemplateMetadata; + error?: string; +} +export declare class MetadataGenerator { + private client; + private model; + constructor(apiKey: string, model?: string); + private getJsonSchema; + createBatchRequest(template: MetadataRequest): any; + private sanitizeInput; + private summarizeNodes; + parseResult(result: any): MetadataResult; + private getDefaultMetadata; + generateSingle(template: MetadataRequest): Promise; +} +//# sourceMappingURL=metadata-generator.d.ts.map \ No newline at end of file diff --git a/dist/templates/metadata-generator.d.ts.map b/dist/templates/metadata-generator.d.ts.map new file mode 100644 index 0000000..88aab53 --- /dev/null +++ b/dist/templates/metadata-generator.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"metadata-generator.d.ts","sourceRoot":"","sources":["../../src/templates/metadata-generator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;EAQjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,GAAG,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;gBAEV,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,MAAgC;IAQnE,OAAO,CAAC,aAAa;IAiErB,kBAAkB,CAAC,QAAQ,EAAE,eAAe,GAAG,GAAG;IA+ClD,OAAO,CAAC,aAAa;IAqBrB,OAAO,CAAC,cAAc;IAwDtB,WAAW,CAAC,MAAM,EAAE,GAAG,GAAG,cAAc;IAsCxC,OAAO,CAAC,kBAAkB;IAepB,cAAc,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAmC3E"} \ No newline at end of file diff --git a/dist/templates/metadata-generator.js b/dist/templates/metadata-generator.js new file mode 100644 index 0000000..726bd30 --- /dev/null +++ b/dist/templates/metadata-generator.js @@ -0,0 +1,252 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.MetadataGenerator = exports.TemplateMetadataSchema = void 0; +const openai_1 = __importDefault(require("openai")); +const zod_1 = require("zod"); +const logger_1 = require("../utils/logger"); +exports.TemplateMetadataSchema = zod_1.z.object({ + categories: zod_1.z.array(zod_1.z.string()).max(5).describe('Main categories (max 5)'), + complexity: zod_1.z.enum(['simple', 'medium', 'complex']).describe('Implementation complexity'), + use_cases: zod_1.z.array(zod_1.z.string()).max(5).describe('Primary use cases'), + estimated_setup_minutes: zod_1.z.number().min(5).max(480).describe('Setup time in minutes'), + required_services: zod_1.z.array(zod_1.z.string()).describe('External services needed'), + key_features: zod_1.z.array(zod_1.z.string()).max(5).describe('Main capabilities'), + target_audience: zod_1.z.array(zod_1.z.string()).max(3).describe('Target users') +}); +class MetadataGenerator { + constructor(apiKey, model = 'gpt-5-mini-2025-08-07') { + this.client = new openai_1.default({ apiKey }); + this.model = model; + } + getJsonSchema() { + return { + name: 'template_metadata', + strict: true, + schema: { + type: 'object', + properties: { + categories: { + type: 'array', + items: { type: 'string' }, + maxItems: 5, + description: 'Main categories like automation, integration, data processing' + }, + complexity: { + type: 'string', + enum: ['simple', 'medium', 'complex'], + description: 'Implementation complexity level' + }, + use_cases: { + type: 'array', + items: { type: 'string' }, + maxItems: 5, + description: 'Primary use cases for this template' + }, + estimated_setup_minutes: { + type: 'number', + minimum: 5, + maximum: 480, + description: 'Estimated setup time in minutes' + }, + required_services: { + type: 'array', + items: { type: 'string' }, + description: 'External services or APIs required' + }, + key_features: { + type: 'array', + items: { type: 'string' }, + maxItems: 5, + description: 'Main capabilities or features' + }, + target_audience: { + type: 'array', + items: { type: 'string' }, + maxItems: 3, + description: 'Target users like developers, marketers, analysts' + } + }, + required: [ + 'categories', + 'complexity', + 'use_cases', + 'estimated_setup_minutes', + 'required_services', + 'key_features', + 'target_audience' + ], + additionalProperties: false + } + }; + } + createBatchRequest(template) { + const nodesSummary = this.summarizeNodes(template.nodes); + const sanitizedName = this.sanitizeInput(template.name, Math.max(200, template.name.length)); + const sanitizedDescription = template.description ? + this.sanitizeInput(template.description, 500) : ''; + const context = [ + `Template: ${sanitizedName}`, + sanitizedDescription ? `Description: ${sanitizedDescription}` : '', + `Nodes Used (${template.nodes.length}): ${nodesSummary}`, + template.workflow ? `Workflow has ${template.workflow.nodes?.length || 0} nodes with ${Object.keys(template.workflow.connections || {}).length} connections` : '' + ].filter(Boolean).join('\n'); + return { + custom_id: `template-${template.templateId}`, + method: 'POST', + url: '/v1/chat/completions', + body: { + model: this.model, + max_completion_tokens: 3000, + response_format: { + type: 'json_schema', + json_schema: this.getJsonSchema() + }, + messages: [ + { + role: 'system', + content: `Analyze n8n workflow templates and extract metadata. Be concise.` + }, + { + role: 'user', + content: context + } + ] + } + }; + } + sanitizeInput(input, maxLength) { + let sanitized = input.slice(0, maxLength); + sanitized = sanitized.replace(/[\x00-\x1F\x7F-\x9F]/g, ''); + sanitized = sanitized.replace(/\s+/g, ' ').trim(); + sanitized = sanitized.replace(/\b(system|assistant|user|human|ai):/gi, ''); + sanitized = sanitized.replace(/```[\s\S]*?```/g, ''); + sanitized = sanitized.replace(/\[INST\]|\[\/INST\]/g, ''); + return sanitized; + } + summarizeNodes(nodes) { + const nodeGroups = {}; + for (const node of nodes) { + const baseName = node.split('.').pop() || node; + if (baseName.includes('webhook') || baseName.includes('http')) { + nodeGroups['HTTP/Webhooks'] = (nodeGroups['HTTP/Webhooks'] || 0) + 1; + } + else if (baseName.includes('database') || baseName.includes('postgres') || baseName.includes('mysql')) { + nodeGroups['Database'] = (nodeGroups['Database'] || 0) + 1; + } + else if (baseName.includes('slack') || baseName.includes('email') || baseName.includes('gmail')) { + nodeGroups['Communication'] = (nodeGroups['Communication'] || 0) + 1; + } + else if (baseName.includes('ai') || baseName.includes('openai') || baseName.includes('langchain') || + baseName.toLowerCase().includes('openai') || baseName.includes('agent')) { + nodeGroups['AI/ML'] = (nodeGroups['AI/ML'] || 0) + 1; + } + else if (baseName.includes('sheet') || baseName.includes('csv') || baseName.includes('excel') || + baseName.toLowerCase().includes('googlesheets')) { + nodeGroups['Spreadsheets'] = (nodeGroups['Spreadsheets'] || 0) + 1; + } + else { + let displayName; + if (node.includes('.with.') && node.includes('@')) { + displayName = node.split('/').pop() || baseName; + } + else { + if (baseName.endsWith('Trigger') && baseName.length > 7) { + displayName = baseName.slice(0, -7); + } + else if (baseName.endsWith('Node') && baseName.length > 4 && baseName !== 'unknownNode') { + displayName = baseName.slice(0, -4); + } + else { + displayName = baseName; + } + } + nodeGroups[displayName] = (nodeGroups[displayName] || 0) + 1; + } + } + const summary = Object.entries(nodeGroups) + .sort((a, b) => b[1] - a[1]) + .slice(0, 10) + .map(([name, count]) => count > 1 ? `${name} (${count})` : name) + .join(', '); + return summary; + } + parseResult(result) { + try { + if (result.error) { + return { + templateId: parseInt(result.custom_id.replace('template-', '')), + metadata: this.getDefaultMetadata(), + error: result.error.message + }; + } + const response = result.response; + if (!response?.body?.choices?.[0]?.message?.content) { + throw new Error('Invalid response structure'); + } + const content = response.body.choices[0].message.content; + const metadata = JSON.parse(content); + const validated = exports.TemplateMetadataSchema.parse(metadata); + return { + templateId: parseInt(result.custom_id.replace('template-', '')), + metadata: validated + }; + } + catch (error) { + logger_1.logger.error(`Error parsing result for ${result.custom_id}:`, error); + return { + templateId: parseInt(result.custom_id.replace('template-', '')), + metadata: this.getDefaultMetadata(), + error: error instanceof Error ? error.message : 'Unknown error' + }; + } + } + getDefaultMetadata() { + return { + categories: ['automation'], + complexity: 'medium', + use_cases: ['Process automation'], + estimated_setup_minutes: 30, + required_services: [], + key_features: ['Workflow automation'], + target_audience: ['developers'] + }; + } + async generateSingle(template) { + try { + const completion = await this.client.chat.completions.create({ + model: this.model, + max_completion_tokens: 3000, + response_format: { + type: 'json_schema', + json_schema: this.getJsonSchema() + }, + messages: [ + { + role: 'system', + content: `Analyze n8n workflow templates and extract metadata. Be concise.` + }, + { + role: 'user', + content: `Template: ${template.name}\nNodes: ${template.nodes.slice(0, 10).join(', ')}` + } + ] + }); + const content = completion.choices[0].message.content; + if (!content) { + logger_1.logger.error('No content in OpenAI response'); + throw new Error('No content in response'); + } + const metadata = JSON.parse(content); + return exports.TemplateMetadataSchema.parse(metadata); + } + catch (error) { + logger_1.logger.error('Error generating single metadata:', error); + return this.getDefaultMetadata(); + } + } +} +exports.MetadataGenerator = MetadataGenerator; +//# sourceMappingURL=metadata-generator.js.map \ No newline at end of file diff --git a/dist/templates/metadata-generator.js.map b/dist/templates/metadata-generator.js.map new file mode 100644 index 0000000..c2aeb38 --- /dev/null +++ b/dist/templates/metadata-generator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"metadata-generator.js","sourceRoot":"","sources":["../../src/templates/metadata-generator.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/templates/template-fetcher.d.ts b/dist/templates/template-fetcher.d.ts new file mode 100644 index 0000000..55e9436 --- /dev/null +++ b/dist/templates/template-fetcher.d.ts @@ -0,0 +1,45 @@ +export interface TemplateNode { + id: number; + name: string; + icon: string; +} +export interface TemplateUser { + id: number; + name: string; + username: string; + verified: boolean; +} +export interface TemplateWorkflow { + id: number; + name: string; + description: string; + totalViews: number; + createdAt: string; + user: TemplateUser; + nodes: TemplateNode[]; +} +export interface TemplateDetail { + id: number; + name: string; + description: string; + views: number; + createdAt: string; + workflow: { + nodes: any[]; + connections: any; + settings?: any; + }; +} +export declare class TemplateFetcher { + private readonly baseUrl; + private readonly pageSize; + private readonly maxRetries; + private readonly retryDelay; + private retryWithBackoff; + fetchTemplates(progressCallback?: (current: number, total: number) => void, sinceDate?: Date): Promise; + fetchAllTemplates(progressCallback?: (current: number, total: number) => void): Promise; + fetchTemplateDetail(workflowId: number): Promise; + fetchAllTemplateDetails(workflows: TemplateWorkflow[], progressCallback?: (current: number, total: number) => void): Promise>; + private sleep; +} +//# sourceMappingURL=template-fetcher.d.ts.map \ No newline at end of file diff --git a/dist/templates/template-fetcher.d.ts.map b/dist/templates/template-fetcher.d.ts.map new file mode 100644 index 0000000..86ea569 --- /dev/null +++ b/dist/templates/template-fetcher.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"template-fetcher.d.ts","sourceRoot":"","sources":["../../src/templates/template-fetcher.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE;QACR,KAAK,EAAE,GAAG,EAAE,CAAC;QACb,WAAW,EAAE,GAAG,CAAC;QACjB,QAAQ,CAAC,EAAE,GAAG,CAAC;KAChB,CAAC;CACH;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsC;IAC9D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAO;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAK;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;YAKrB,gBAAgB;IA6BxB,cAAc,CAAC,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,EAAE,SAAS,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAuB1H,iBAAiB,CAAC,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IA8D3G,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAYvE,uBAAuB,CAC3B,SAAS,EAAE,gBAAgB,EAAE,EAC7B,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GAC1D,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IA8BvC,OAAO,CAAC,KAAK;CAGd"} \ No newline at end of file diff --git a/dist/templates/template-fetcher.js b/dist/templates/template-fetcher.js new file mode 100644 index 0000000..4217409 --- /dev/null +++ b/dist/templates/template-fetcher.js @@ -0,0 +1,122 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TemplateFetcher = void 0; +const axios_1 = __importDefault(require("axios")); +const logger_1 = require("../utils/logger"); +class TemplateFetcher { + constructor() { + this.baseUrl = 'https://api.n8n.io/api/templates'; + this.pageSize = 250; + this.maxRetries = 3; + this.retryDelay = 1000; + } + async retryWithBackoff(fn, context, maxRetries = this.maxRetries) { + let lastError; + for (let attempt = 1; attempt <= maxRetries; attempt++) { + try { + return await fn(); + } + catch (error) { + lastError = error; + if (attempt < maxRetries) { + const delay = this.retryDelay * attempt; + logger_1.logger.warn(`${context} - Attempt ${attempt}/${maxRetries} failed, retrying in ${delay}ms...`); + await this.sleep(delay); + } + } + } + logger_1.logger.error(`${context} - All ${maxRetries} attempts failed, skipping`, lastError); + return null; + } + async fetchTemplates(progressCallback, sinceDate) { + const allTemplates = await this.fetchAllTemplates(progressCallback); + const cutoffDate = sinceDate || (() => { + const oneYearAgo = new Date(); + oneYearAgo.setMonth(oneYearAgo.getMonth() - 12); + return oneYearAgo; + })(); + const recentTemplates = allTemplates.filter((w) => { + const createdDate = new Date(w.createdAt); + return createdDate >= cutoffDate; + }); + logger_1.logger.info(`Filtered to ${recentTemplates.length} templates since ${cutoffDate.toISOString().split('T')[0]} (out of ${allTemplates.length} total)`); + return recentTemplates; + } + async fetchAllTemplates(progressCallback) { + const allTemplates = []; + let page = 1; + let hasMore = true; + let totalWorkflows = 0; + logger_1.logger.info('Starting complete template fetch from n8n.io API'); + while (hasMore) { + const result = await this.retryWithBackoff(async () => { + const response = await axios_1.default.get(`${this.baseUrl}/search`, { + params: { + page, + rows: this.pageSize + } + }); + return response.data; + }, `Fetching templates page ${page}`); + if (result === null) { + logger_1.logger.warn(`Skipping page ${page} after ${this.maxRetries} failed attempts`); + page++; + continue; + } + const { workflows } = result; + totalWorkflows = result.totalWorkflows || totalWorkflows; + allTemplates.push(...workflows); + const totalPages = Math.ceil(totalWorkflows / this.pageSize); + if (progressCallback) { + progressCallback(allTemplates.length, totalWorkflows); + } + logger_1.logger.debug(`Fetched page ${page}/${totalPages}: ${workflows.length} templates (total so far: ${allTemplates.length}/${totalWorkflows})`); + if (workflows.length < this.pageSize) { + hasMore = false; + } + page++; + if (hasMore) { + await this.sleep(300); + } + } + logger_1.logger.info(`Fetched all ${allTemplates.length} templates from n8n.io`); + return allTemplates; + } + async fetchTemplateDetail(workflowId) { + const result = await this.retryWithBackoff(async () => { + const response = await axios_1.default.get(`${this.baseUrl}/workflows/${workflowId}`); + return response.data.workflow; + }, `Fetching template detail for workflow ${workflowId}`); + return result; + } + async fetchAllTemplateDetails(workflows, progressCallback) { + const details = new Map(); + let skipped = 0; + logger_1.logger.info(`Fetching details for ${workflows.length} templates`); + for (let i = 0; i < workflows.length; i++) { + const workflow = workflows[i]; + const detail = await this.fetchTemplateDetail(workflow.id); + if (detail !== null) { + details.set(workflow.id, detail); + } + else { + skipped++; + logger_1.logger.warn(`Skipped workflow ${workflow.id} after ${this.maxRetries} failed attempts`); + } + if (progressCallback) { + progressCallback(i + 1, workflows.length); + } + await this.sleep(150); + } + logger_1.logger.info(`Successfully fetched ${details.size} template details (${skipped} skipped)`); + return details; + } + sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); + } +} +exports.TemplateFetcher = TemplateFetcher; +//# sourceMappingURL=template-fetcher.js.map \ No newline at end of file diff --git a/dist/templates/template-fetcher.js.map b/dist/templates/template-fetcher.js.map new file mode 100644 index 0000000..a00637f --- /dev/null +++ b/dist/templates/template-fetcher.js.map @@ -0,0 +1 @@ +{"version":3,"file":"template-fetcher.js","sourceRoot":"","sources":["../../src/templates/template-fetcher.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/templates/template-repository.d.ts b/dist/templates/template-repository.d.ts new file mode 100644 index 0000000..2857c57 --- /dev/null +++ b/dist/templates/template-repository.d.ts @@ -0,0 +1,93 @@ +import { DatabaseAdapter } from '../database/database-adapter'; +import { TemplateWorkflow, TemplateDetail } from './template-fetcher'; +export interface StoredTemplate { + id: number; + workflow_id: number; + name: string; + description: string; + author_name: string; + author_username: string; + author_verified: number; + nodes_used: string; + workflow_json?: string; + workflow_json_compressed?: string; + categories: string; + views: number; + created_at: string; + updated_at: string; + url: string; + scraped_at: string; + metadata_json?: string; + metadata_generated_at?: string; +} +export declare class TemplateRepository { + private db; + private sanitizer; + private hasFTS5Support; + constructor(db: DatabaseAdapter); + private initializeFTS5; + saveTemplate(workflow: TemplateWorkflow, detail: TemplateDetail, categories?: string[]): void; + getTemplatesByNodes(nodeTypes: string[], limit?: number, offset?: number): StoredTemplate[]; + getTemplate(templateId: number): StoredTemplate | null; + private decompressWorkflow; + searchTemplates(query: string, limit?: number, offset?: number): StoredTemplate[]; + private searchTemplatesLIKE; + getTemplatesForTask(task: string, limit?: number, offset?: number): StoredTemplate[]; + getAllTemplates(limit?: number, offset?: number, sortBy?: 'views' | 'created_at' | 'name'): StoredTemplate[]; + getTemplateCount(): number; + getSearchCount(query: string): number; + getNodeTemplatesCount(nodeTypes: string[]): number; + getTaskTemplatesCount(task: string): number; + getExistingTemplateIds(): Set; + getMostRecentTemplateDate(): Date | null; + hasTemplate(templateId: number): boolean; + getTemplateMetadata(): Map; + getTemplateStats(): Record; + clearTemplates(): void; + rebuildTemplateFTS(): void; + updateTemplateMetadata(templateId: number, metadata: any): void; + batchUpdateMetadata(metadataMap: Map): void; + getTemplatesWithoutMetadata(limit?: number): StoredTemplate[]; + getTemplatesWithOutdatedMetadata(daysOld?: number, limit?: number): StoredTemplate[]; + getMetadataStats(): { + total: number; + withMetadata: number; + withoutMetadata: number; + outdated: number; + }; + private buildMetadataFilterConditions; + searchTemplatesByMetadata(filters: { + category?: string; + complexity?: 'simple' | 'medium' | 'complex'; + maxSetupMinutes?: number; + minSetupMinutes?: number; + requiredService?: string; + targetAudience?: string; + }, limit?: number, offset?: number): StoredTemplate[]; + getMetadataSearchCount(filters: { + category?: string; + complexity?: 'simple' | 'medium' | 'complex'; + maxSetupMinutes?: number; + minSetupMinutes?: number; + requiredService?: string; + targetAudience?: string; + }): number; + getAvailableCategories(): string[]; + getAvailableTargetAudiences(): string[]; + getTemplatesByCategory(category: string, limit?: number, offset?: number): StoredTemplate[]; + getTemplatesByComplexity(complexity: 'simple' | 'medium' | 'complex', limit?: number, offset?: number): StoredTemplate[]; + getSearchTemplatesByMetadataCount(filters: { + category?: string; + complexity?: 'simple' | 'medium' | 'complex'; + maxSetupMinutes?: number; + minSetupMinutes?: number; + requiredService?: string; + targetAudience?: string; + }): number; + getUniqueCategories(): string[]; + getUniqueTargetAudiences(): string[]; +} +//# sourceMappingURL=template-repository.d.ts.map \ No newline at end of file diff --git a/dist/templates/template-repository.d.ts.map b/dist/templates/template-repository.d.ts.map new file mode 100644 index 0000000..f3a359d --- /dev/null +++ b/dist/templates/template-repository.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"template-repository.d.ts","sourceRoot":"","sources":["../../src/templates/template-repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAMtE,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,qBAAa,kBAAkB;IAIjB,OAAO,CAAC,EAAE;IAHtB,OAAO,CAAC,SAAS,CAAoB;IACrC,OAAO,CAAC,cAAc,CAAkB;gBAEpB,EAAE,EAAE,eAAe;IAQvC,OAAO,CAAC,cAAc;IAuEtB,YAAY,CAAC,QAAQ,EAAE,gBAAgB,EAAE,MAAM,EAAE,cAAc,EAAE,UAAU,GAAE,MAAM,EAAO,GAAG,IAAI;IAmEjG,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,GAAE,MAAW,EAAE,MAAM,GAAE,MAAU,GAAG,cAAc,EAAE;IAiClG,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAyBtD,OAAO,CAAC,kBAAkB;IAgB1B,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,EAAE,MAAM,GAAE,MAAU,GAAG,cAAc,EAAE;IA0CxF,OAAO,CAAC,mBAAmB;IAkB3B,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,EAAE,MAAM,GAAE,MAAU,GAAG,cAAc,EAAE;IA0B3F,eAAe,CAAC,KAAK,GAAE,MAAW,EAAE,MAAM,GAAE,MAAU,EAAE,MAAM,GAAE,OAAO,GAAG,YAAY,GAAG,MAAgB,GAAG,cAAc,EAAE;IAe5H,gBAAgB,IAAI,MAAM;IAQ1B,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAmCrC,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM;IAkBlD,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IA0B3C,sBAAsB,IAAI,GAAG,CAAC,MAAM,CAAC;IASrC,yBAAyB,IAAI,IAAI,GAAG,IAAI;IAWxC,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IASxC,mBAAmB,IAAI,GAAG,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAiBxE,gBAAgB,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAyCvC,cAAc,IAAI,IAAI;IAStB,kBAAkB,IAAI,IAAI;IA2B1B,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,IAAI;IAc/D,mBAAmB,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAmBxD,2BAA2B,CAAC,KAAK,GAAE,MAAY,GAAG,cAAc,EAAE;IAclE,gCAAgC,CAAC,OAAO,GAAE,MAAW,EAAE,KAAK,GAAE,MAAY,GAAG,cAAc,EAAE;IAc7F,gBAAgB,IAAI;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;QACxB,QAAQ,EAAE,MAAM,CAAC;KAClB;IAuBD,OAAO,CAAC,6BAA6B;IAwDrC,yBAAyB,CAAC,OAAO,EAAE;QACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;QAC7C,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,EAAE,KAAK,GAAE,MAAW,EAAE,MAAM,GAAE,MAAU,GAAG,cAAc,EAAE;IAyE5D,sBAAsB,CAAC,OAAO,EAAE;QAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;QAC7C,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GAAG,MAAM;IAaV,sBAAsB,IAAI,MAAM,EAAE;IAclC,2BAA2B,IAAI,MAAM,EAAE;IAcvC,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,EAAE,MAAM,GAAE,MAAU,GAAG,cAAc,EAAE;IAkBlG,wBAAwB,CAAC,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,EAAE,KAAK,GAAE,MAAW,EAAE,MAAM,GAAE,MAAU,GAAG,cAAc,EAAE;IAgB/H,iCAAiC,CAAC,OAAO,EAAE;QACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;QAC7C,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GAAG,MAAM;IA4CV,mBAAmB,IAAI,MAAM,EAAE;IAe/B,wBAAwB,IAAI,MAAM,EAAE;CAWrC"} \ No newline at end of file diff --git a/dist/templates/template-repository.js b/dist/templates/template-repository.js new file mode 100644 index 0000000..ad39085 --- /dev/null +++ b/dist/templates/template-repository.js @@ -0,0 +1,644 @@ +"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.TemplateRepository = void 0; +const logger_1 = require("../utils/logger"); +const template_sanitizer_1 = require("../utils/template-sanitizer"); +const zlib = __importStar(require("zlib")); +const template_node_resolver_1 = require("../utils/template-node-resolver"); +class TemplateRepository { + constructor(db) { + this.db = db; + this.hasFTS5Support = false; + this.sanitizer = new template_sanitizer_1.TemplateSanitizer(); + this.initializeFTS5(); + } + initializeFTS5() { + this.hasFTS5Support = this.db.checkFTS5Support(); + if (this.hasFTS5Support) { + try { + const ftsExists = this.db.prepare(` + SELECT name FROM sqlite_master + WHERE type='table' AND name='templates_fts' + `).get(); + if (ftsExists) { + logger_1.logger.info('FTS5 table already exists for templates'); + try { + const testCount = this.db.prepare('SELECT COUNT(*) as count FROM templates_fts').get(); + logger_1.logger.info(`FTS5 enabled with ${testCount.count} indexed entries`); + } + catch (testError) { + logger_1.logger.warn('FTS5 table exists but query failed:', testError); + this.hasFTS5Support = false; + return; + } + } + else { + logger_1.logger.info('Creating FTS5 virtual table for templates...'); + this.db.exec(` + CREATE VIRTUAL TABLE IF NOT EXISTS templates_fts USING fts5( + name, description, content=templates + ); + `); + this.db.exec(` + CREATE TRIGGER IF NOT EXISTS templates_ai AFTER INSERT ON templates BEGIN + INSERT INTO templates_fts(rowid, name, description) + VALUES (new.id, new.name, new.description); + END; + `); + this.db.exec(` + CREATE TRIGGER IF NOT EXISTS templates_au AFTER UPDATE ON templates BEGIN + UPDATE templates_fts SET name = new.name, description = new.description + WHERE rowid = new.id; + END; + `); + this.db.exec(` + CREATE TRIGGER IF NOT EXISTS templates_ad AFTER DELETE ON templates BEGIN + DELETE FROM templates_fts WHERE rowid = old.id; + END; + `); + logger_1.logger.info('FTS5 support enabled for template search'); + } + } + catch (error) { + logger_1.logger.warn('Failed to initialize FTS5 for templates:', { + message: error.message, + code: error.code, + stack: error.stack + }); + this.hasFTS5Support = false; + } + } + else { + logger_1.logger.info('FTS5 not available, using LIKE search for templates'); + } + } + saveTemplate(workflow, detail, categories = []) { + if ((workflow.totalViews || 0) <= 10) { + logger_1.logger.debug(`Skipping template ${workflow.id}: ${workflow.name} (only ${workflow.totalViews} views)`); + return; + } + const stmt = this.db.prepare(` + INSERT OR REPLACE INTO templates ( + id, workflow_id, name, description, author_name, author_username, + author_verified, nodes_used, workflow_json_compressed, categories, views, + created_at, updated_at, url + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `); + const nodeTypes = detail.workflow.nodes.map(n => n.type); + const url = `https://n8n.io/workflows/${workflow.id}`; + const { sanitized: sanitizedWorkflow, wasModified } = this.sanitizer.sanitizeWorkflow(detail.workflow); + if (wasModified) { + const detectedTokens = this.sanitizer.detectTokens(detail.workflow); + logger_1.logger.warn(`Sanitized API tokens in template ${workflow.id}: ${workflow.name}`, { + templateId: workflow.id, + templateName: workflow.name, + tokensFound: detectedTokens.length, + tokenPreviews: detectedTokens.map(t => t.substring(0, 20) + '...') + }); + } + const workflowJsonStr = JSON.stringify(sanitizedWorkflow); + const compressed = zlib.gzipSync(workflowJsonStr); + const compressedBase64 = compressed.toString('base64'); + const originalSize = Buffer.byteLength(workflowJsonStr); + const compressedSize = compressed.length; + const ratio = Math.round((1 - compressedSize / originalSize) * 100); + logger_1.logger.debug(`Template ${workflow.id} compression: ${originalSize} → ${compressedSize} bytes (${ratio}% reduction)`); + stmt.run(workflow.id, workflow.id, workflow.name, workflow.description || '', workflow.user.name, workflow.user.username, workflow.user.verified ? 1 : 0, JSON.stringify(nodeTypes), compressedBase64, JSON.stringify(categories), workflow.totalViews || 0, workflow.createdAt, workflow.createdAt, url); + } + getTemplatesByNodes(nodeTypes, limit = 10, offset = 0) { + const resolvedTypes = (0, template_node_resolver_1.resolveTemplateNodeTypes)(nodeTypes); + if (resolvedTypes.length === 0) { + logger_1.logger.debug('No resolved types for template search', { input: nodeTypes }); + return []; + } + const conditions = resolvedTypes.map(() => "nodes_used LIKE ?").join(" OR "); + const query = ` + SELECT * FROM templates + WHERE ${conditions} + ORDER BY views DESC, created_at DESC + LIMIT ? OFFSET ? + `; + const params = [...resolvedTypes.map(n => `%"${n}"%`), limit, offset]; + const results = this.db.prepare(query).all(...params); + logger_1.logger.debug(`Template search found ${results.length} results`, { + input: nodeTypes, + resolved: resolvedTypes, + found: results.length + }); + return results.map(t => this.decompressWorkflow(t)); + } + getTemplate(templateId) { + const row = this.db.prepare(` + SELECT * FROM templates WHERE id = ? + `).get(templateId); + if (!row) + return null; + if (row.workflow_json_compressed && !row.workflow_json) { + try { + const compressed = Buffer.from(row.workflow_json_compressed, 'base64'); + const decompressed = zlib.gunzipSync(compressed); + row.workflow_json = decompressed.toString(); + } + catch (error) { + logger_1.logger.error(`Failed to decompress workflow for template ${templateId}:`, error); + return null; + } + } + return row; + } + decompressWorkflow(template) { + if (template.workflow_json_compressed && !template.workflow_json) { + try { + const compressed = Buffer.from(template.workflow_json_compressed, 'base64'); + const decompressed = zlib.gunzipSync(compressed); + template.workflow_json = decompressed.toString(); + } + catch (error) { + logger_1.logger.error(`Failed to decompress workflow for template ${template.id}:`, error); + } + } + return template; + } + searchTemplates(query, limit = 20, offset = 0) { + logger_1.logger.debug(`Searching templates for: "${query}" (FTS5: ${this.hasFTS5Support})`); + if (!this.hasFTS5Support) { + logger_1.logger.debug('Using LIKE search (FTS5 not available)'); + return this.searchTemplatesLIKE(query, limit, offset); + } + try { + const ftsQuery = query.split(' ').map(term => { + const escaped = term.replace(/"/g, '""'); + return `"${escaped}"`; + }).join(' OR '); + logger_1.logger.debug(`FTS5 query: ${ftsQuery}`); + const results = this.db.prepare(` + SELECT t.* FROM templates t + JOIN templates_fts ON t.id = templates_fts.rowid + WHERE templates_fts MATCH ? + ORDER BY rank, t.views DESC + LIMIT ? OFFSET ? + `).all(ftsQuery, limit, offset); + logger_1.logger.debug(`FTS5 search returned ${results.length} results`); + return results.map(t => this.decompressWorkflow(t)); + } + catch (error) { + logger_1.logger.warn('FTS5 template search failed, using LIKE fallback:', { + message: error.message, + query: query, + ftsQuery: query.split(' ').map(term => `"${term}"`).join(' OR ') + }); + return this.searchTemplatesLIKE(query, limit, offset); + } + } + searchTemplatesLIKE(query, limit = 20, offset = 0) { + const likeQuery = `%${query}%`; + logger_1.logger.debug(`Using LIKE search with pattern: ${likeQuery}`); + const results = this.db.prepare(` + SELECT * FROM templates + WHERE name LIKE ? OR description LIKE ? + ORDER BY views DESC, created_at DESC + LIMIT ? OFFSET ? + `).all(likeQuery, likeQuery, limit, offset); + logger_1.logger.debug(`LIKE search returned ${results.length} results`); + return results.map(t => this.decompressWorkflow(t)); + } + getTemplatesForTask(task, limit = 10, offset = 0) { + const taskNodeMap = { + 'ai_automation': ['@n8n/n8n-nodes-langchain.openAi', '@n8n/n8n-nodes-langchain.agent', 'n8n-nodes-base.openAi'], + 'data_sync': ['n8n-nodes-base.googleSheets', 'n8n-nodes-base.postgres', 'n8n-nodes-base.mysql'], + 'webhook_processing': ['n8n-nodes-base.webhook', 'n8n-nodes-base.httpRequest'], + 'email_automation': ['n8n-nodes-base.gmail', 'n8n-nodes-base.emailSend', 'n8n-nodes-base.emailReadImap'], + 'slack_integration': ['n8n-nodes-base.slack', 'n8n-nodes-base.slackTrigger'], + 'data_transformation': ['n8n-nodes-base.code', 'n8n-nodes-base.set', 'n8n-nodes-base.merge'], + 'file_processing': ['n8n-nodes-base.readBinaryFile', 'n8n-nodes-base.writeBinaryFile', 'n8n-nodes-base.googleDrive'], + 'scheduling': ['n8n-nodes-base.scheduleTrigger', 'n8n-nodes-base.cron'], + 'api_integration': ['n8n-nodes-base.httpRequest', 'n8n-nodes-base.graphql'], + 'database_operations': ['n8n-nodes-base.postgres', 'n8n-nodes-base.mysql', 'n8n-nodes-base.mongodb'] + }; + const nodes = taskNodeMap[task]; + if (!nodes) { + return []; + } + return this.getTemplatesByNodes(nodes, limit, offset); + } + getAllTemplates(limit = 10, offset = 0, sortBy = 'views') { + const orderClause = sortBy === 'name' ? 'name ASC' : + sortBy === 'created_at' ? 'created_at DESC' : + 'views DESC, created_at DESC'; + const results = this.db.prepare(` + SELECT * FROM templates + ORDER BY ${orderClause} + LIMIT ? OFFSET ? + `).all(limit, offset); + return results.map(t => this.decompressWorkflow(t)); + } + getTemplateCount() { + const result = this.db.prepare('SELECT COUNT(*) as count FROM templates').get(); + return result.count; + } + getSearchCount(query) { + if (!this.hasFTS5Support) { + const likeQuery = `%${query}%`; + const result = this.db.prepare(` + SELECT COUNT(*) as count FROM templates + WHERE name LIKE ? OR description LIKE ? + `).get(likeQuery, likeQuery); + return result.count; + } + try { + const ftsQuery = query.split(' ').map(term => { + const escaped = term.replace(/"/g, '""'); + return `"${escaped}"`; + }).join(' OR '); + const result = this.db.prepare(` + SELECT COUNT(*) as count FROM templates t + JOIN templates_fts ON t.id = templates_fts.rowid + WHERE templates_fts MATCH ? + `).get(ftsQuery); + return result.count; + } + catch { + const likeQuery = `%${query}%`; + const result = this.db.prepare(` + SELECT COUNT(*) as count FROM templates + WHERE name LIKE ? OR description LIKE ? + `).get(likeQuery, likeQuery); + return result.count; + } + } + getNodeTemplatesCount(nodeTypes) { + const resolvedTypes = (0, template_node_resolver_1.resolveTemplateNodeTypes)(nodeTypes); + if (resolvedTypes.length === 0) { + return 0; + } + const conditions = resolvedTypes.map(() => "nodes_used LIKE ?").join(" OR "); + const query = `SELECT COUNT(*) as count FROM templates WHERE ${conditions}`; + const params = resolvedTypes.map(n => `%"${n}"%`); + const result = this.db.prepare(query).get(...params); + return result.count; + } + getTaskTemplatesCount(task) { + const taskNodeMap = { + 'ai_automation': ['@n8n/n8n-nodes-langchain.openAi', '@n8n/n8n-nodes-langchain.agent', 'n8n-nodes-base.openAi'], + 'data_sync': ['n8n-nodes-base.googleSheets', 'n8n-nodes-base.postgres', 'n8n-nodes-base.mysql'], + 'webhook_processing': ['n8n-nodes-base.webhook', 'n8n-nodes-base.httpRequest'], + 'email_automation': ['n8n-nodes-base.gmail', 'n8n-nodes-base.emailSend', 'n8n-nodes-base.emailReadImap'], + 'slack_integration': ['n8n-nodes-base.slack', 'n8n-nodes-base.slackTrigger'], + 'data_transformation': ['n8n-nodes-base.code', 'n8n-nodes-base.set', 'n8n-nodes-base.merge'], + 'file_processing': ['n8n-nodes-base.readBinaryFile', 'n8n-nodes-base.writeBinaryFile', 'n8n-nodes-base.googleDrive'], + 'scheduling': ['n8n-nodes-base.scheduleTrigger', 'n8n-nodes-base.cron'], + 'api_integration': ['n8n-nodes-base.httpRequest', 'n8n-nodes-base.graphql'], + 'database_operations': ['n8n-nodes-base.postgres', 'n8n-nodes-base.mysql', 'n8n-nodes-base.mongodb'] + }; + const nodes = taskNodeMap[task]; + if (!nodes) { + return 0; + } + return this.getNodeTemplatesCount(nodes); + } + getExistingTemplateIds() { + const rows = this.db.prepare('SELECT id FROM templates').all(); + return new Set(rows.map(r => r.id)); + } + getMostRecentTemplateDate() { + const result = this.db.prepare('SELECT MAX(created_at) as max_date FROM templates').get(); + if (!result || !result.max_date) { + return null; + } + return new Date(result.max_date); + } + hasTemplate(templateId) { + const result = this.db.prepare('SELECT 1 FROM templates WHERE id = ?').get(templateId); + return result !== undefined; + } + getTemplateMetadata() { + const rows = this.db.prepare('SELECT id, name, updated_at FROM templates').all(); + const metadata = new Map(); + for (const row of rows) { + metadata.set(row.id, { name: row.name, updated_at: row.updated_at }); + } + return metadata; + } + getTemplateStats() { + const count = this.getTemplateCount(); + const avgViews = this.db.prepare('SELECT AVG(views) as avg FROM templates').get(); + const topNodes = this.db.prepare(` + SELECT nodes_used FROM templates + ORDER BY views DESC + LIMIT 100 + `).all(); + const nodeCount = {}; + topNodes.forEach(t => { + if (!t.nodes_used) + return; + try { + const nodes = JSON.parse(t.nodes_used); + if (Array.isArray(nodes)) { + nodes.forEach((n) => { + nodeCount[n] = (nodeCount[n] || 0) + 1; + }); + } + } + catch (error) { + logger_1.logger.warn(`Failed to parse nodes_used for template stats:`, error); + } + }); + const topUsedNodes = Object.entries(nodeCount) + .sort(([, a], [, b]) => b - a) + .slice(0, 10) + .map(([node, count]) => ({ node, count })); + return { + totalTemplates: count, + averageViews: Math.round(avgViews.avg || 0), + topUsedNodes + }; + } + clearTemplates() { + this.db.exec('DELETE FROM templates'); + logger_1.logger.info('Cleared all templates from database'); + } + rebuildTemplateFTS() { + if (!this.hasFTS5Support) { + return; + } + try { + this.db.exec('DELETE FROM templates_fts'); + this.db.exec(` + INSERT INTO templates_fts(rowid, name, description) + SELECT id, name, description FROM templates + `); + const count = this.getTemplateCount(); + logger_1.logger.info(`Rebuilt FTS5 index for ${count} templates`); + } + catch (error) { + logger_1.logger.warn('Failed to rebuild template FTS5 index:', error); + } + } + updateTemplateMetadata(templateId, metadata) { + const stmt = this.db.prepare(` + UPDATE templates + SET metadata_json = ?, metadata_generated_at = CURRENT_TIMESTAMP + WHERE id = ? + `); + stmt.run(JSON.stringify(metadata), templateId); + logger_1.logger.debug(`Updated metadata for template ${templateId}`); + } + batchUpdateMetadata(metadataMap) { + const stmt = this.db.prepare(` + UPDATE templates + SET metadata_json = ?, metadata_generated_at = CURRENT_TIMESTAMP + WHERE id = ? + `); + for (const [templateId, metadata] of metadataMap.entries()) { + stmt.run(JSON.stringify(metadata), templateId); + } + logger_1.logger.info(`Updated metadata for ${metadataMap.size} templates`); + } + getTemplatesWithoutMetadata(limit = 100) { + const stmt = this.db.prepare(` + SELECT * FROM templates + WHERE metadata_json IS NULL OR metadata_generated_at IS NULL + ORDER BY views DESC + LIMIT ? + `); + return stmt.all(limit); + } + getTemplatesWithOutdatedMetadata(daysOld = 30, limit = 100) { + const stmt = this.db.prepare(` + SELECT * FROM templates + WHERE metadata_generated_at < datetime('now', '-' || ? || ' days') + ORDER BY views DESC + LIMIT ? + `); + return stmt.all(daysOld, limit); + } + getMetadataStats() { + const total = this.getTemplateCount(); + const withMetadata = this.db.prepare(` + SELECT COUNT(*) as count FROM templates + WHERE metadata_json IS NOT NULL + `).get().count; + const withoutMetadata = total - withMetadata; + const outdated = this.db.prepare(` + SELECT COUNT(*) as count FROM templates + WHERE metadata_generated_at < datetime('now', '-30 days') + `).get().count; + return { total, withMetadata, withoutMetadata, outdated }; + } + buildMetadataFilterConditions(filters) { + const conditions = ['metadata_json IS NOT NULL']; + const params = []; + if (filters.category !== undefined) { + conditions.push("json_extract(metadata_json, '$.categories') LIKE '%' || ? || '%'"); + const sanitizedCategory = JSON.stringify(filters.category).slice(1, -1); + params.push(sanitizedCategory); + } + if (filters.complexity) { + conditions.push("json_extract(metadata_json, '$.complexity') = ?"); + params.push(filters.complexity); + } + if (filters.maxSetupMinutes !== undefined) { + conditions.push("CAST(json_extract(metadata_json, '$.estimated_setup_minutes') AS INTEGER) <= ?"); + params.push(filters.maxSetupMinutes); + } + if (filters.minSetupMinutes !== undefined) { + conditions.push("CAST(json_extract(metadata_json, '$.estimated_setup_minutes') AS INTEGER) >= ?"); + params.push(filters.minSetupMinutes); + } + if (filters.requiredService !== undefined) { + conditions.push("json_extract(metadata_json, '$.required_services') LIKE '%' || ? || '%'"); + const sanitizedService = JSON.stringify(filters.requiredService).slice(1, -1); + params.push(sanitizedService); + } + if (filters.targetAudience !== undefined) { + conditions.push("json_extract(metadata_json, '$.target_audience') LIKE '%' || ? || '%'"); + const sanitizedAudience = JSON.stringify(filters.targetAudience).slice(1, -1); + params.push(sanitizedAudience); + } + return { conditions, params }; + } + searchTemplatesByMetadata(filters, limit = 20, offset = 0) { + const startTime = Date.now(); + const { conditions, params } = this.buildMetadataFilterConditions(filters); + const idsQuery = ` + SELECT id FROM templates + WHERE ${conditions.join(' AND ')} + ORDER BY views DESC, created_at DESC, id ASC + LIMIT ? OFFSET ? + `; + params.push(limit, offset); + const ids = this.db.prepare(idsQuery).all(...params); + const phase1Time = Date.now() - startTime; + if (ids.length === 0) { + logger_1.logger.debug('Metadata search found 0 results', { filters, phase1Ms: phase1Time }); + return []; + } + const idValues = ids.map(r => r.id).filter(id => typeof id === 'number' && id > 0 && Number.isInteger(id)); + if (idValues.length === 0) { + logger_1.logger.warn('No valid IDs after filtering', { filters, originalCount: ids.length }); + return []; + } + if (idValues.length !== ids.length) { + logger_1.logger.warn('Some IDs were filtered out as invalid', { + original: ids.length, + valid: idValues.length, + filtered: ids.length - idValues.length + }); + } + const phase2Start = Date.now(); + const orderedQuery = ` + WITH ordered_ids(id, sort_order) AS ( + VALUES ${idValues.map((id, idx) => `(${id}, ${idx})`).join(', ')} + ) + SELECT t.* FROM templates t + INNER JOIN ordered_ids o ON t.id = o.id + ORDER BY o.sort_order + `; + const results = this.db.prepare(orderedQuery).all(); + const phase2Time = Date.now() - phase2Start; + logger_1.logger.debug(`Metadata search found ${results.length} results`, { + filters, + count: results.length, + phase1Ms: phase1Time, + phase2Ms: phase2Time, + totalMs: Date.now() - startTime, + optimization: 'two-phase-with-ordering' + }); + return results.map(t => this.decompressWorkflow(t)); + } + getMetadataSearchCount(filters) { + const { conditions, params } = this.buildMetadataFilterConditions(filters); + const query = `SELECT COUNT(*) as count FROM templates WHERE ${conditions.join(' AND ')}`; + const result = this.db.prepare(query).get(...params); + return result.count; + } + getAvailableCategories() { + const results = this.db.prepare(` + SELECT DISTINCT json_extract(value, '$') as category + FROM templates, json_each(json_extract(metadata_json, '$.categories')) + WHERE metadata_json IS NOT NULL + ORDER BY category + `).all(); + return results.map(r => r.category); + } + getAvailableTargetAudiences() { + const results = this.db.prepare(` + SELECT DISTINCT json_extract(value, '$') as audience + FROM templates, json_each(json_extract(metadata_json, '$.target_audience')) + WHERE metadata_json IS NOT NULL + ORDER BY audience + `).all(); + return results.map(r => r.audience); + } + getTemplatesByCategory(category, limit = 10, offset = 0) { + const query = ` + SELECT * FROM templates + WHERE metadata_json IS NOT NULL + AND json_extract(metadata_json, '$.categories') LIKE '%' || ? || '%' + ORDER BY views DESC, created_at DESC + LIMIT ? OFFSET ? + `; + const sanitizedCategory = JSON.stringify(category).slice(1, -1); + const results = this.db.prepare(query).all(sanitizedCategory, limit, offset); + return results.map(t => this.decompressWorkflow(t)); + } + getTemplatesByComplexity(complexity, limit = 10, offset = 0) { + const query = ` + SELECT * FROM templates + WHERE metadata_json IS NOT NULL + AND json_extract(metadata_json, '$.complexity') = ? + ORDER BY views DESC, created_at DESC + LIMIT ? OFFSET ? + `; + const results = this.db.prepare(query).all(complexity, limit, offset); + return results.map(t => this.decompressWorkflow(t)); + } + getSearchTemplatesByMetadataCount(filters) { + let sql = ` + SELECT COUNT(*) as count FROM templates + WHERE metadata_json IS NOT NULL + `; + const params = []; + if (filters.category) { + sql += ` AND json_extract(metadata_json, '$.categories') LIKE ?`; + params.push(`%"${filters.category}"%`); + } + if (filters.complexity) { + sql += ` AND json_extract(metadata_json, '$.complexity') = ?`; + params.push(filters.complexity); + } + if (filters.maxSetupMinutes !== undefined) { + sql += ` AND CAST(json_extract(metadata_json, '$.estimated_setup_minutes') AS INTEGER) <= ?`; + params.push(filters.maxSetupMinutes); + } + if (filters.minSetupMinutes !== undefined) { + sql += ` AND CAST(json_extract(metadata_json, '$.estimated_setup_minutes') AS INTEGER) >= ?`; + params.push(filters.minSetupMinutes); + } + if (filters.requiredService) { + sql += ` AND json_extract(metadata_json, '$.required_services') LIKE ?`; + params.push(`%"${filters.requiredService}"%`); + } + if (filters.targetAudience) { + sql += ` AND json_extract(metadata_json, '$.target_audience') LIKE ?`; + params.push(`%"${filters.targetAudience}"%`); + } + const result = this.db.prepare(sql).get(...params); + return result?.count || 0; + } + getUniqueCategories() { + const sql = ` + SELECT DISTINCT value as category + FROM templates, json_each(metadata_json, '$.categories') + WHERE metadata_json IS NOT NULL + ORDER BY category + `; + const results = this.db.prepare(sql).all(); + return results.map(r => r.category); + } + getUniqueTargetAudiences() { + const sql = ` + SELECT DISTINCT value as audience + FROM templates, json_each(metadata_json, '$.target_audience') + WHERE metadata_json IS NOT NULL + ORDER BY audience + `; + const results = this.db.prepare(sql).all(); + return results.map(r => r.audience); + } +} +exports.TemplateRepository = TemplateRepository; +//# sourceMappingURL=template-repository.js.map \ No newline at end of file diff --git a/dist/templates/template-repository.js.map b/dist/templates/template-repository.js.map new file mode 100644 index 0000000..924ac5f --- /dev/null +++ b/dist/templates/template-repository.js.map @@ -0,0 +1 @@ +{"version":3,"file":"template-repository.js","sourceRoot":"","sources":["../../src/templates/template-repository.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/templates/template-service.d.ts b/dist/templates/template-service.d.ts new file mode 100644 index 0000000..6b0f3e7 --- /dev/null +++ b/dist/templates/template-service.d.ts @@ -0,0 +1,79 @@ +import { DatabaseAdapter } from '../database/database-adapter'; +export interface TemplateInfo { + id: number; + name: string; + description: string; + author: { + name: string; + username: string; + verified: boolean; + }; + nodes: string[]; + views: number; + created: string; + url: string; + metadata?: { + categories: string[]; + complexity: 'simple' | 'medium' | 'complex'; + use_cases: string[]; + estimated_setup_minutes: number; + required_services: string[]; + key_features: string[]; + target_audience: string[]; + }; +} +export interface TemplateWithWorkflow extends TemplateInfo { + workflow: any; +} +export interface PaginatedResponse { + items: T[]; + total: number; + limit: number; + offset: number; + hasMore: boolean; +} +export interface TemplateMinimal { + id: number; + name: string; + description: string; + views: number; + nodeCount: number; + metadata?: { + categories: string[]; + complexity: 'simple' | 'medium' | 'complex'; + use_cases: string[]; + estimated_setup_minutes: number; + required_services: string[]; + key_features: string[]; + target_audience: string[]; + }; +} +export type TemplateField = 'id' | 'name' | 'description' | 'author' | 'nodes' | 'views' | 'created' | 'url' | 'metadata'; +export type PartialTemplateInfo = Partial; +export declare class TemplateService { + private repository; + constructor(db: DatabaseAdapter); + listNodeTemplates(nodeTypes: string[], limit?: number, offset?: number): Promise>; + getTemplate(templateId: number, mode?: 'nodes_only' | 'structure' | 'full'): Promise; + searchTemplates(query: string, limit?: number, offset?: number, fields?: string[]): Promise>; + getTemplatesForTask(task: string, limit?: number, offset?: number): Promise>; + listTemplates(limit?: number, offset?: number, sortBy?: 'views' | 'created_at' | 'name', includeMetadata?: boolean): Promise>; + listAvailableTasks(): string[]; + searchTemplatesByMetadata(filters: { + category?: string; + complexity?: 'simple' | 'medium' | 'complex'; + maxSetupMinutes?: number; + minSetupMinutes?: number; + requiredService?: string; + targetAudience?: string; + }, limit?: number, offset?: number): Promise>; + getAvailableCategories(): Promise; + getAvailableTargetAudiences(): Promise; + getTemplatesByCategory(category: string, limit?: number, offset?: number): Promise>; + getTemplatesByComplexity(complexity: 'simple' | 'medium' | 'complex', limit?: number, offset?: number): Promise>; + getTemplateStats(): Promise>; + fetchAndUpdateTemplates(progressCallback?: (message: string, current: number, total: number) => void, mode?: 'rebuild' | 'update'): Promise; + private formatTemplateInfo; + private formatTemplateWithFields; +} +//# sourceMappingURL=template-service.d.ts.map \ No newline at end of file diff --git a/dist/templates/template-service.d.ts.map b/dist/templates/template-service.d.ts.map new file mode 100644 index 0000000..4101e61 --- /dev/null +++ b/dist/templates/template-service.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"template-service.d.ts","sourceRoot":"","sources":["../../src/templates/template-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAI/D,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;KACnB,CAAC;IACF,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE;QACT,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;QAC5C,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,uBAAuB,EAAE,MAAM,CAAC;QAChC,iBAAiB,EAAE,MAAM,EAAE,CAAC;QAC5B,YAAY,EAAE,MAAM,EAAE,CAAC;QACvB,eAAe,EAAE,MAAM,EAAE,CAAC;KAC3B,CAAC;CACH;AAED,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD,QAAQ,EAAE,GAAG,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE;QACT,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;QAC5C,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,uBAAuB,EAAE,MAAM,CAAC;QAChC,iBAAiB,EAAE,MAAM,EAAE,CAAC;QAC5B,YAAY,EAAE,MAAM,EAAE,CAAC;QACvB,eAAe,EAAE,MAAM,EAAE,CAAC;KAC3B,CAAC;CACH;AAED,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,MAAM,GAAG,aAAa,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,KAAK,GAAG,UAAU,CAAC;AAC1H,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAExD,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAAqB;gBAE3B,EAAE,EAAE,eAAe;IAOzB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,GAAE,MAAW,EAAE,MAAM,GAAE,MAAU,GAAG,OAAO,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAgBxH,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,GAAE,YAAY,GAAG,WAAW,GAAG,MAAe,GAAG,OAAO,CAAC,GAAG,CAAC;IA2CjG,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,EAAE,MAAM,GAAE,MAAU,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,CAAC;IAqB1I,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,EAAE,MAAM,GAAE,MAAU,GAAG,OAAO,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAgBnH,aAAa,CAAC,KAAK,GAAE,MAAW,EAAE,MAAM,GAAE,MAAU,EAAE,MAAM,GAAE,OAAO,GAAG,YAAY,GAAG,MAAgB,EAAE,eAAe,GAAE,OAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC;IAqC7L,kBAAkB,IAAI,MAAM,EAAE;IAkBxB,yBAAyB,CAC7B,OAAO,EAAE;QACP,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;QAC7C,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,EACD,KAAK,GAAE,MAAW,EAClB,MAAM,GAAE,MAAU,GACjB,OAAO,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAgBrC,sBAAsB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAO3C,2BAA2B,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAOhD,sBAAsB,CAC1B,QAAQ,EAAE,MAAM,EAChB,KAAK,GAAE,MAAW,EAClB,MAAM,GAAE,MAAU,GACjB,OAAO,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAgBrC,wBAAwB,CAC5B,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,EAC3C,KAAK,GAAE,MAAW,EAClB,MAAM,GAAE,MAAU,GACjB,OAAO,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAgBrC,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAQhD,uBAAuB,CAC3B,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,EAC5E,IAAI,GAAE,SAAS,GAAG,QAAoB,GACrC,OAAO,CAAC,IAAI,CAAC;IAyFhB,OAAO,CAAC,kBAAkB;IA+B1B,OAAO,CAAC,wBAAwB;CAajC"} \ No newline at end of file diff --git a/dist/templates/template-service.js b/dist/templates/template-service.js new file mode 100644 index 0000000..40957e3 --- /dev/null +++ b/dist/templates/template-service.js @@ -0,0 +1,300 @@ +"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.TemplateService = void 0; +const template_repository_1 = require("./template-repository"); +const logger_1 = require("../utils/logger"); +class TemplateService { + constructor(db) { + this.repository = new template_repository_1.TemplateRepository(db); + } + async listNodeTemplates(nodeTypes, limit = 10, offset = 0) { + const templates = this.repository.getTemplatesByNodes(nodeTypes, limit, offset); + const total = this.repository.getNodeTemplatesCount(nodeTypes); + return { + items: templates.map(this.formatTemplateInfo), + total, + limit, + offset, + hasMore: offset + limit < total + }; + } + async getTemplate(templateId, mode = 'full') { + const template = this.repository.getTemplate(templateId); + if (!template) { + return null; + } + const workflow = JSON.parse(template.workflow_json || '{}'); + if (mode === 'nodes_only') { + return { + id: template.id, + name: template.name, + nodes: workflow.nodes?.map((n) => ({ + type: n.type, + name: n.name + })) || [] + }; + } + if (mode === 'structure') { + return { + id: template.id, + name: template.name, + nodes: workflow.nodes?.map((n) => ({ + id: n.id, + type: n.type, + name: n.name, + position: n.position + })) || [], + connections: workflow.connections || {} + }; + } + return { + ...this.formatTemplateInfo(template), + workflow + }; + } + async searchTemplates(query, limit = 20, offset = 0, fields) { + const templates = this.repository.searchTemplates(query, limit, offset); + const total = this.repository.getSearchCount(query); + const items = fields + ? templates.map(t => this.formatTemplateWithFields(t, fields)) + : templates.map(t => this.formatTemplateInfo(t)); + return { + items, + total, + limit, + offset, + hasMore: offset + limit < total + }; + } + async getTemplatesForTask(task, limit = 10, offset = 0) { + const templates = this.repository.getTemplatesForTask(task, limit, offset); + const total = this.repository.getTaskTemplatesCount(task); + return { + items: templates.map(this.formatTemplateInfo), + total, + limit, + offset, + hasMore: offset + limit < total + }; + } + async listTemplates(limit = 10, offset = 0, sortBy = 'views', includeMetadata = false) { + const templates = this.repository.getAllTemplates(limit, offset, sortBy); + const total = this.repository.getTemplateCount(); + const items = templates.map(t => { + const item = { + id: t.id, + name: t.name, + description: t.description, + views: t.views, + nodeCount: JSON.parse(t.nodes_used).length + }; + if (includeMetadata && t.metadata_json) { + try { + item.metadata = JSON.parse(t.metadata_json); + } + catch (error) { + logger_1.logger.warn(`Failed to parse metadata for template ${t.id}:`, error); + } + } + return item; + }); + return { + items, + total, + limit, + offset, + hasMore: offset + limit < total + }; + } + listAvailableTasks() { + return [ + 'ai_automation', + 'data_sync', + 'webhook_processing', + 'email_automation', + 'slack_integration', + 'data_transformation', + 'file_processing', + 'scheduling', + 'api_integration', + 'database_operations' + ]; + } + async searchTemplatesByMetadata(filters, limit = 20, offset = 0) { + const templates = this.repository.searchTemplatesByMetadata(filters, limit, offset); + const total = this.repository.getMetadataSearchCount(filters); + return { + items: templates.map(this.formatTemplateInfo.bind(this)), + total, + limit, + offset, + hasMore: offset + limit < total + }; + } + async getAvailableCategories() { + return this.repository.getAvailableCategories(); + } + async getAvailableTargetAudiences() { + return this.repository.getAvailableTargetAudiences(); + } + async getTemplatesByCategory(category, limit = 10, offset = 0) { + const templates = this.repository.getTemplatesByCategory(category, limit, offset); + const total = this.repository.getMetadataSearchCount({ category }); + return { + items: templates.map(this.formatTemplateInfo.bind(this)), + total, + limit, + offset, + hasMore: offset + limit < total + }; + } + async getTemplatesByComplexity(complexity, limit = 10, offset = 0) { + const templates = this.repository.getTemplatesByComplexity(complexity, limit, offset); + const total = this.repository.getMetadataSearchCount({ complexity }); + return { + items: templates.map(this.formatTemplateInfo.bind(this)), + total, + limit, + offset, + hasMore: offset + limit < total + }; + } + async getTemplateStats() { + return this.repository.getTemplateStats(); + } + async fetchAndUpdateTemplates(progressCallback, mode = 'rebuild') { + try { + const { TemplateFetcher } = await Promise.resolve().then(() => __importStar(require('./template-fetcher'))); + const fetcher = new TemplateFetcher(); + let existingIds = new Set(); + let sinceDate; + if (mode === 'update') { + existingIds = this.repository.getExistingTemplateIds(); + logger_1.logger.info(`Update mode: Found ${existingIds.size} existing templates in database`); + const mostRecentDate = this.repository.getMostRecentTemplateDate(); + if (mostRecentDate) { + sinceDate = new Date(mostRecentDate); + sinceDate.setDate(sinceDate.getDate() - 14); + logger_1.logger.info(`Update mode: Fetching templates since ${sinceDate.toISOString().split('T')[0]} (2 weeks before most recent)`); + } + else { + sinceDate = new Date(); + sinceDate.setDate(sinceDate.getDate() - 14); + logger_1.logger.info(`Update mode: No existing templates, fetching from last 2 weeks`); + } + } + else { + this.repository.clearTemplates(); + logger_1.logger.info('Rebuild mode: Cleared existing templates'); + } + logger_1.logger.info(`Fetching template list from n8n.io (mode: ${mode})`); + const templates = await fetcher.fetchTemplates((current, total) => { + progressCallback?.('Fetching template list', current, total); + }, sinceDate); + logger_1.logger.info(`Found ${templates.length} templates matching date criteria`); + let templatesToFetch = templates; + if (mode === 'update') { + templatesToFetch = templates.filter(t => !existingIds.has(t.id)); + logger_1.logger.info(`Update mode: ${templatesToFetch.length} new templates to fetch (skipping ${templates.length - templatesToFetch.length} existing)`); + if (templatesToFetch.length === 0) { + logger_1.logger.info('No new templates to fetch'); + progressCallback?.('No new templates', 0, 0); + return; + } + } + logger_1.logger.info(`Fetching details for ${templatesToFetch.length} templates`); + const details = await fetcher.fetchAllTemplateDetails(templatesToFetch, (current, total) => { + progressCallback?.('Fetching template details', current, total); + }); + logger_1.logger.info('Saving templates to database'); + let saved = 0; + for (const template of templatesToFetch) { + const detail = details.get(template.id); + if (detail) { + this.repository.saveTemplate(template, detail); + saved++; + } + } + logger_1.logger.info(`Successfully saved ${saved} templates to database`); + if (saved > 0) { + logger_1.logger.info('Rebuilding FTS5 index for templates'); + this.repository.rebuildTemplateFTS(); + } + progressCallback?.('Complete', saved, saved); + } + catch (error) { + logger_1.logger.error('Error fetching templates:', error); + throw error; + } + } + formatTemplateInfo(template) { + const info = { + id: template.id, + name: template.name, + description: template.description, + author: { + name: template.author_name, + username: template.author_username, + verified: template.author_verified === 1 + }, + nodes: JSON.parse(template.nodes_used), + views: template.views, + created: template.created_at, + url: template.url + }; + if (template.metadata_json) { + try { + info.metadata = JSON.parse(template.metadata_json); + } + catch (error) { + logger_1.logger.warn(`Failed to parse metadata for template ${template.id}:`, error); + } + } + return info; + } + formatTemplateWithFields(template, fields) { + const fullInfo = this.formatTemplateInfo(template); + const result = {}; + for (const field of fields) { + if (field in fullInfo) { + result[field] = fullInfo[field]; + } + } + return result; + } +} +exports.TemplateService = TemplateService; +//# sourceMappingURL=template-service.js.map \ No newline at end of file diff --git a/dist/templates/template-service.js.map b/dist/templates/template-service.js.map new file mode 100644 index 0000000..360895c --- /dev/null +++ b/dist/templates/template-service.js.map @@ -0,0 +1 @@ +{"version":3,"file":"template-service.js","sourceRoot":"","sources":["../../src/templates/template-service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,+DAA2E;AAC3E,4CAAyC;AA0DzC,MAAa,eAAe;IAG1B,YAAY,EAAmB;QAC7B,IAAI,CAAC,UAAU,GAAG,IAAI,wCAAkB,CAAC,EAAE,CAAC,CAAC;IAC/C,CAAC;IAKD,KAAK,CAAC,iBAAiB,CAAC,SAAmB,EAAE,QAAgB,EAAE,EAAE,SAAiB,CAAC;QACjF,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAChF,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;QAE/D,OAAO;YACL,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC;YAC7C,KAAK;YACL,KAAK;YACL,MAAM;YACN,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK;SAChC,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,WAAW,CAAC,UAAkB,EAAE,OAA4C,MAAM;QACtF,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QACzD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC;QAE5D,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;YAC1B,OAAO;gBACL,EAAE,EAAE,QAAQ,CAAC,EAAE;gBACf,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;oBACtC,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,IAAI,EAAE,CAAC,CAAC,IAAI;iBACb,CAAC,CAAC,IAAI,EAAE;aACV,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YACzB,OAAO;gBACL,EAAE,EAAE,QAAQ,CAAC,EAAE;gBACf,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;oBACtC,EAAE,EAAE,CAAC,CAAC,EAAE;oBACR,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ;iBACrB,CAAC,CAAC,IAAI,EAAE;gBACT,WAAW,EAAE,QAAQ,CAAC,WAAW,IAAI,EAAE;aACxC,CAAC;QACJ,CAAC;QAGD,OAAO;YACL,GAAG,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC;YACpC,QAAQ;SACT,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,eAAe,CAAC,KAAa,EAAE,QAAgB,EAAE,EAAE,SAAiB,CAAC,EAAE,MAAiB;QAC5F,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACxE,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAGpD,MAAM,KAAK,GAAG,MAAM;YAClB,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;YAC9D,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;QAEnD,OAAO;YACL,KAAK;YACL,KAAK;YACL,KAAK;YACL,MAAM;YACN,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK;SAChC,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,mBAAmB,CAAC,IAAY,EAAE,QAAgB,EAAE,EAAE,SAAiB,CAAC;QAC5E,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAC3E,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;QAE1D,OAAO;YACL,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC;YAC7C,KAAK;YACL,KAAK;YACL,MAAM;YACN,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK;SAChC,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,aAAa,CAAC,QAAgB,EAAE,EAAE,SAAiB,CAAC,EAAE,SAA0C,OAAO,EAAE,kBAA2B,KAAK;QAC7I,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACzE,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC;QAEjD,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;YAC9B,MAAM,IAAI,GAAoB;gBAC5B,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,WAAW,EAAE,CAAC,CAAC,WAAW;gBAC1B,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM;aAC3C,CAAC;YAGF,IAAI,eAAe,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;gBACvC,IAAI,CAAC;oBACH,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;gBAC9C,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,eAAM,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;gBACvE,CAAC;YACH,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,OAAO;YACL,KAAK;YACL,KAAK;YACL,KAAK;YACL,MAAM;YACN,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK;SAChC,CAAC;IACJ,CAAC;IAKD,kBAAkB;QAChB,OAAO;YACL,eAAe;YACf,WAAW;YACX,oBAAoB;YACpB,kBAAkB;YAClB,mBAAmB;YACnB,qBAAqB;YACrB,iBAAiB;YACjB,YAAY;YACZ,iBAAiB;YACjB,qBAAqB;SACtB,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,yBAAyB,CAC7B,OAOC,EACD,QAAgB,EAAE,EAClB,SAAiB,CAAC;QAElB,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,yBAAyB,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACpF,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAE9D,OAAO;YACL,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxD,KAAK;YACL,KAAK;YACL,MAAM;YACN,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK;SAChC,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,sBAAsB;QAC1B,OAAO,IAAI,CAAC,UAAU,CAAC,sBAAsB,EAAE,CAAC;IAClD,CAAC;IAKD,KAAK,CAAC,2BAA2B;QAC/B,OAAO,IAAI,CAAC,UAAU,CAAC,2BAA2B,EAAE,CAAC;IACvD,CAAC;IAKD,KAAK,CAAC,sBAAsB,CAC1B,QAAgB,EAChB,QAAgB,EAAE,EAClB,SAAiB,CAAC;QAElB,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAClF,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QAEnE,OAAO;YACL,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxD,KAAK;YACL,KAAK;YACL,MAAM;YACN,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK;SAChC,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,wBAAwB,CAC5B,UAA2C,EAC3C,QAAgB,EAAE,EAClB,SAAiB,CAAC;QAElB,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,wBAAwB,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACtF,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;QAErE,OAAO;YACL,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxD,KAAK;YACL,KAAK;YACL,MAAM;YACN,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK;SAChC,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,gBAAgB;QACpB,OAAO,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC;IAC5C,CAAC;IAMD,KAAK,CAAC,uBAAuB,CAC3B,gBAA4E,EAC5E,OAA6B,SAAS;QAEtC,IAAI,CAAC;YAEH,MAAM,EAAE,eAAe,EAAE,GAAG,wDAAa,oBAAoB,GAAC,CAAC;YAC/D,MAAM,OAAO,GAAG,IAAI,eAAe,EAAE,CAAC;YAGtC,IAAI,WAAW,GAAgB,IAAI,GAAG,EAAE,CAAC;YACzC,IAAI,SAA2B,CAAC;YAEhC,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,sBAAsB,EAAE,CAAC;gBACvD,eAAM,CAAC,IAAI,CAAC,sBAAsB,WAAW,CAAC,IAAI,iCAAiC,CAAC,CAAC;gBAGrF,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,yBAAyB,EAAE,CAAC;gBACnE,IAAI,cAAc,EAAE,CAAC;oBAEnB,SAAS,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,CAAC;oBACrC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;oBAC5C,eAAM,CAAC,IAAI,CAAC,yCAAyC,SAAS,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC;gBAC7H,CAAC;qBAAM,CAAC;oBAEN,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;oBAC5C,eAAM,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC;gBAChF,CAAC;YACH,CAAC;iBAAM,CAAC;gBAEN,IAAI,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC;gBACjC,eAAM,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;YAC1D,CAAC;YAGD,eAAM,CAAC,IAAI,CAAC,6CAA6C,IAAI,GAAG,CAAC,CAAC;YAClE,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;gBAChE,gBAAgB,EAAE,CAAC,wBAAwB,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;YAC/D,CAAC,EAAE,SAAS,CAAC,CAAC;YAEd,eAAM,CAAC,IAAI,CAAC,SAAS,SAAS,CAAC,MAAM,mCAAmC,CAAC,CAAC;YAG1E,IAAI,gBAAgB,GAAG,SAAS,CAAC;YACjC,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,gBAAgB,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBACjE,eAAM,CAAC,IAAI,CAAC,gBAAgB,gBAAgB,CAAC,MAAM,qCAAqC,SAAS,CAAC,MAAM,GAAG,gBAAgB,CAAC,MAAM,YAAY,CAAC,CAAC;gBAEhJ,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAClC,eAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;oBACzC,gBAAgB,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;oBAC7C,OAAO;gBACT,CAAC;YACH,CAAC;YAGD,eAAM,CAAC,IAAI,CAAC,wBAAwB,gBAAgB,CAAC,MAAM,YAAY,CAAC,CAAC;YACzE,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,uBAAuB,CAAC,gBAAgB,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;gBACzF,gBAAgB,EAAE,CAAC,2BAA2B,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;YAClE,CAAC,CAAC,CAAC;YAGH,eAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;YAC5C,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,KAAK,MAAM,QAAQ,IAAI,gBAAgB,EAAE,CAAC;gBACxC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACxC,IAAI,MAAM,EAAE,CAAC;oBACX,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;oBAC/C,KAAK,EAAE,CAAC;gBACV,CAAC;YACH,CAAC;YAED,eAAM,CAAC,IAAI,CAAC,sBAAsB,KAAK,wBAAwB,CAAC,CAAC;YAGjE,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;gBACd,eAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;gBACnD,IAAI,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC;YACvC,CAAC;YAED,gBAAgB,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;YACjD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAKO,kBAAkB,CAAC,QAAwB;QACjD,MAAM,IAAI,GAAiB;YACzB,EAAE,EAAE,QAAQ,CAAC,EAAE;YACf,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,WAAW,EAAE,QAAQ,CAAC,WAAW;YACjC,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ,CAAC,WAAW;gBAC1B,QAAQ,EAAE,QAAQ,CAAC,eAAe;gBAClC,QAAQ,EAAE,QAAQ,CAAC,eAAe,KAAK,CAAC;aACzC;YACD,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;YACtC,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,OAAO,EAAE,QAAQ,CAAC,UAAU;YAC5B,GAAG,EAAE,QAAQ,CAAC,GAAG;SAClB,CAAC;QAGF,IAAI,QAAQ,CAAC,aAAa,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;YACrD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,eAAM,CAAC,IAAI,CAAC,yCAAyC,QAAQ,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;YAC9E,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAKO,wBAAwB,CAAC,QAAwB,EAAE,MAAgB;QACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QACnD,MAAM,MAAM,GAAwB,EAAE,CAAC;QAGvC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,KAAK,IAAI,QAAQ,EAAE,CAAC;gBACrB,MAAc,CAAC,KAAK,CAAC,GAAI,QAAgB,CAAC,KAAK,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAlYD,0CAkYC"} \ No newline at end of file diff --git a/dist/triggers/handlers/base-handler.d.ts b/dist/triggers/handlers/base-handler.d.ts new file mode 100644 index 0000000..9bc9e8d --- /dev/null +++ b/dist/triggers/handlers/base-handler.d.ts @@ -0,0 +1,21 @@ +import { z } from 'zod'; +import { Workflow } from '../../types/n8n-api'; +import { InstanceContext } from '../../types/instance-context'; +import { N8nApiClient } from '../../services/n8n-api-client'; +import { TriggerType, TriggerResponse, TriggerHandlerCapabilities, DetectedTrigger, BaseTriggerInput } from '../types'; +export type TriggerHandlerConstructor = new (client: N8nApiClient, context?: InstanceContext) => BaseTriggerHandler; +export declare abstract class BaseTriggerHandler { + protected client: N8nApiClient; + protected context?: InstanceContext; + abstract readonly triggerType: TriggerType; + abstract readonly capabilities: TriggerHandlerCapabilities; + abstract readonly inputSchema: z.ZodSchema; + constructor(client: N8nApiClient, context?: InstanceContext); + validate(input: unknown): T; + abstract execute(input: T, workflow: Workflow, triggerInfo?: DetectedTrigger): Promise; + protected getBaseUrl(): string | undefined; + protected getApiKey(): string | undefined; + protected normalizeResponse(result: unknown, input: T, startTime: number, extra?: Partial): TriggerResponse; + protected errorResponse(input: BaseTriggerInput, error: string, startTime: number, extra?: Partial): TriggerResponse; +} +//# sourceMappingURL=base-handler.d.ts.map \ No newline at end of file diff --git a/dist/triggers/handlers/base-handler.d.ts.map b/dist/triggers/handlers/base-handler.d.ts.map new file mode 100644 index 0000000..10f07e5 --- /dev/null +++ b/dist/triggers/handlers/base-handler.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"base-handler.d.ts","sourceRoot":"","sources":["../../../src/triggers/handlers/base-handler.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,OAAO,EACL,WAAW,EACX,eAAe,EACf,0BAA0B,EAC1B,eAAe,EACf,gBAAgB,EACjB,MAAM,UAAU,CAAC;AAKlB,MAAM,MAAM,yBAAyB,GAAG,KACtC,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE,eAAe,KACtB,kBAAkB,CAAC;AAUxB,8BAAsB,kBAAkB,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB;IACpF,SAAS,CAAC,MAAM,EAAE,YAAY,CAAC;IAC/B,SAAS,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC;IAGpC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAG3C,QAAQ,CAAC,QAAQ,CAAC,YAAY,EAAE,0BAA0B,CAAC;IAG3D,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;gBAElC,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,eAAe;IAS3D,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,CAAC;IAW3B,QAAQ,CAAC,OAAO,CACd,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,QAAQ,EAClB,WAAW,CAAC,EAAE,eAAe,GAC5B,OAAO,CAAC,eAAe,CAAC;IAK3B,SAAS,CAAC,UAAU,IAAI,MAAM,GAAG,SAAS;IAgB1C,SAAS,CAAC,SAAS,IAAI,MAAM,GAAG,SAAS;IAazC,SAAS,CAAC,iBAAiB,CACzB,MAAM,EAAE,OAAO,EACf,KAAK,EAAE,CAAC,EACR,SAAS,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAC/B,eAAe;IAmBlB,SAAS,CAAC,aAAa,CACrB,KAAK,EAAE,gBAAgB,EACvB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAC/B,eAAe;CAenB"} \ No newline at end of file diff --git a/dist/triggers/handlers/base-handler.js b/dist/triggers/handlers/base-handler.js new file mode 100644 index 0000000..8ac12f7 --- /dev/null +++ b/dist/triggers/handlers/base-handler.js @@ -0,0 +1,60 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BaseTriggerHandler = void 0; +const n8n_api_1 = require("../../config/n8n-api"); +class BaseTriggerHandler { + constructor(client, context) { + this.client = client; + this.context = context; + } + validate(input) { + return this.inputSchema.parse(input); + } + getBaseUrl() { + if (this.context?.n8nApiUrl) { + return this.context.n8nApiUrl.replace(/\/api\/v1\/?$/, ''); + } + const config = (0, n8n_api_1.getN8nApiConfig)(); + if (config?.baseUrl) { + return config.baseUrl.replace(/\/api\/v1\/?$/, ''); + } + return undefined; + } + getApiKey() { + if (this.context?.n8nApiKey) { + return this.context.n8nApiKey; + } + const config = (0, n8n_api_1.getN8nApiConfig)(); + return config?.apiKey; + } + normalizeResponse(result, input, startTime, extra) { + const endTime = Date.now(); + const duration = endTime - startTime; + return { + success: true, + triggerType: this.triggerType, + workflowId: input.workflowId, + data: result, + metadata: { + duration, + }, + ...extra, + }; + } + errorResponse(input, error, startTime, extra) { + const endTime = Date.now(); + const duration = endTime - startTime; + return { + success: false, + triggerType: this.triggerType, + workflowId: input.workflowId, + error, + metadata: { + duration, + }, + ...extra, + }; + } +} +exports.BaseTriggerHandler = BaseTriggerHandler; +//# sourceMappingURL=base-handler.js.map \ No newline at end of file diff --git a/dist/triggers/handlers/base-handler.js.map b/dist/triggers/handlers/base-handler.js.map new file mode 100644 index 0000000..cd81491 --- /dev/null +++ b/dist/triggers/handlers/base-handler.js.map @@ -0,0 +1 @@ +{"version":3,"file":"base-handler.js","sourceRoot":"","sources":["../../../src/triggers/handlers/base-handler.ts"],"names":[],"mappings":";;;AAQA,kDAAuD;AAyBvD,MAAsB,kBAAkB;IAatC,YAAY,MAAoB,EAAE,OAAyB;QACzD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAMD,QAAQ,CAAC,KAAc;QACrB,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC;IAkBS,UAAU;QAElB,IAAI,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QAC7D,CAAC;QAED,MAAM,MAAM,GAAG,IAAA,yBAAe,GAAE,CAAC;QACjC,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;YACpB,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAKS,SAAS;QAEjB,IAAI,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;QAChC,CAAC;QAED,MAAM,MAAM,GAAG,IAAA,yBAAe,GAAE,CAAC;QACjC,OAAO,MAAM,EAAE,MAAM,CAAC;IACxB,CAAC;IAKS,iBAAiB,CACzB,MAAe,EACf,KAAQ,EACR,SAAiB,EACjB,KAAgC;QAEhC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;QAErC,OAAO;YACL,OAAO,EAAE,IAAI;YACb,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE;gBACR,QAAQ;aACT;YACD,GAAG,KAAK;SACT,CAAC;IACJ,CAAC;IAKS,aAAa,CACrB,KAAuB,EACvB,KAAa,EACb,SAAiB,EACjB,KAAgC;QAEhC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;QAErC,OAAO;YACL,OAAO,EAAE,KAAK;YACd,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,KAAK;YACL,QAAQ,EAAE;gBACR,QAAQ;aACT;YACD,GAAG,KAAK;SACT,CAAC;IACJ,CAAC;CACF;AAnHD,gDAmHC"} \ No newline at end of file diff --git a/dist/triggers/handlers/chat-handler.d.ts b/dist/triggers/handlers/chat-handler.d.ts new file mode 100644 index 0000000..093adf4 --- /dev/null +++ b/dist/triggers/handlers/chat-handler.d.ts @@ -0,0 +1,38 @@ +import { z } from 'zod'; +import { Workflow } from '../../types/n8n-api'; +import { TriggerType, TriggerResponse, TriggerHandlerCapabilities, DetectedTrigger, ChatTriggerInput } from '../types'; +import { BaseTriggerHandler } from './base-handler'; +export declare class ChatHandler extends BaseTriggerHandler { + readonly triggerType: TriggerType; + readonly capabilities: TriggerHandlerCapabilities; + readonly inputSchema: z.ZodObject<{ + workflowId: z.ZodString; + triggerType: z.ZodLiteral<"chat">; + message: z.ZodString; + sessionId: z.ZodOptional; + data: z.ZodOptional>; + headers: z.ZodOptional>; + timeout: z.ZodOptional; + waitForResponse: z.ZodOptional; + }, "strip", z.ZodTypeAny, { + workflowId: string; + triggerType: "chat"; + message: string; + sessionId?: string | undefined; + data?: Record | undefined; + headers?: Record | undefined; + timeout?: number | undefined; + waitForResponse?: boolean | undefined; + }, { + workflowId: string; + triggerType: "chat"; + message: string; + sessionId?: string | undefined; + data?: Record | undefined; + headers?: Record | undefined; + timeout?: number | undefined; + waitForResponse?: boolean | undefined; + }>; + execute(input: ChatTriggerInput, workflow: Workflow, triggerInfo?: DetectedTrigger): Promise; +} +//# sourceMappingURL=chat-handler.d.ts.map \ No newline at end of file diff --git a/dist/triggers/handlers/chat-handler.d.ts.map b/dist/triggers/handlers/chat-handler.d.ts.map new file mode 100644 index 0000000..32c8610 --- /dev/null +++ b/dist/triggers/handlers/chat-handler.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"chat-handler.d.ts","sourceRoot":"","sources":["../../../src/triggers/handlers/chat-handler.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EACL,WAAW,EACX,eAAe,EACf,0BAA0B,EAC1B,eAAe,EACf,gBAAgB,EACjB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AA2BpD,qBAAa,WAAY,SAAQ,kBAAkB,CAAC,gBAAgB,CAAC;IACnE,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAU;IAE3C,QAAQ,CAAC,YAAY,EAAE,0BAA0B,CAG/C;IAEF,QAAQ,CAAC,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;OAAmB;IAEjC,OAAO,CACX,KAAK,EAAE,gBAAgB,EACvB,QAAQ,EAAE,QAAQ,EAClB,WAAW,CAAC,EAAE,eAAe,GAC5B,OAAO,CAAC,eAAe,CAAC;CAgF5B"} \ No newline at end of file diff --git a/dist/triggers/handlers/chat-handler.js b/dist/triggers/handlers/chat-handler.js new file mode 100644 index 0000000..a603961 --- /dev/null +++ b/dist/triggers/handlers/chat-handler.js @@ -0,0 +1,129 @@ +"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; + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ChatHandler = void 0; +const zod_1 = require("zod"); +const axios_1 = __importDefault(require("axios")); +const base_handler_1 = require("./base-handler"); +const trigger_detector_1 = require("../trigger-detector"); +const chatInputSchema = zod_1.z.object({ + workflowId: zod_1.z.string(), + triggerType: zod_1.z.literal('chat'), + message: zod_1.z.string(), + sessionId: zod_1.z.string().optional(), + data: zod_1.z.record(zod_1.z.unknown()).optional(), + headers: zod_1.z.record(zod_1.z.string()).optional(), + timeout: zod_1.z.number().optional(), + waitForResponse: zod_1.z.boolean().optional(), +}); +function generateSessionId() { + return `session_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`; +} +class ChatHandler extends base_handler_1.BaseTriggerHandler { + constructor() { + super(...arguments); + this.triggerType = 'chat'; + this.capabilities = { + requiresActiveWorkflow: true, + canPassInputData: true, + }; + this.inputSchema = chatInputSchema; + } + async execute(input, workflow, triggerInfo) { + const startTime = Date.now(); + try { + const baseUrl = this.getBaseUrl(); + if (!baseUrl) { + return this.errorResponse(input, 'Cannot determine n8n base URL', startTime); + } + let chatUrl; + if (triggerInfo?.webhookPath) { + chatUrl = (0, trigger_detector_1.buildTriggerUrl)(baseUrl, triggerInfo, 'production'); + } + else { + chatUrl = `${baseUrl.replace(/\/+$/, '')}/webhook/${input.workflowId}`; + } + const { SSRFProtection } = await Promise.resolve().then(() => __importStar(require('../../utils/ssrf-protection'))); + const validation = await SSRFProtection.validateWebhookUrl(chatUrl); + if (!validation.valid) { + return this.errorResponse(input, `SSRF protection: ${validation.reason}`, startTime); + } + const sessionId = input.sessionId || generateSessionId(); + const chatPayload = { + action: 'sendMessage', + sessionId, + chatInput: input.message, + ...input.data, + }; + const config = { + method: 'POST', + url: chatUrl, + headers: { + 'Content-Type': 'application/json', + ...input.headers, + }, + data: chatPayload, + timeout: input.timeout || (input.waitForResponse !== false ? 120000 : 30000), + validateStatus: (status) => status < 500, + }; + const response = await axios_1.default.request(config); + const chatResponse = response.data; + return this.normalizeResponse(chatResponse, input, startTime, { + status: response.status, + statusText: response.statusText, + metadata: { + duration: Date.now() - startTime, + sessionId, + webhookPath: triggerInfo?.webhookPath, + }, + }); + } + catch (error) { + const errorMessage = error instanceof Error ? error.message : 'Unknown error'; + const errorDetails = error?.response?.data; + const executionId = errorDetails?.executionId || errorDetails?.id; + return this.errorResponse(input, errorMessage, startTime, { + executionId, + code: error?.code, + details: errorDetails, + }); + } + } +} +exports.ChatHandler = ChatHandler; +//# sourceMappingURL=chat-handler.js.map \ No newline at end of file diff --git a/dist/triggers/handlers/chat-handler.js.map b/dist/triggers/handlers/chat-handler.js.map new file mode 100644 index 0000000..8f5f5a7 --- /dev/null +++ b/dist/triggers/handlers/chat-handler.js.map @@ -0,0 +1 @@ +{"version":3,"file":"chat-handler.js","sourceRoot":"","sources":["../../../src/triggers/handlers/chat-handler.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/triggers/handlers/form-handler.d.ts b/dist/triggers/handlers/form-handler.d.ts new file mode 100644 index 0000000..4919f9e --- /dev/null +++ b/dist/triggers/handlers/form-handler.d.ts @@ -0,0 +1,35 @@ +import { z } from 'zod'; +import { Workflow } from '../../types/n8n-api'; +import { TriggerType, TriggerResponse, TriggerHandlerCapabilities, DetectedTrigger, FormTriggerInput } from '../types'; +import { BaseTriggerHandler } from './base-handler'; +export declare class FormHandler extends BaseTriggerHandler { + readonly triggerType: TriggerType; + readonly capabilities: TriggerHandlerCapabilities; + readonly inputSchema: z.ZodObject<{ + workflowId: z.ZodString; + triggerType: z.ZodLiteral<"form">; + formData: z.ZodOptional>; + data: z.ZodOptional>; + headers: z.ZodOptional>; + timeout: z.ZodOptional; + waitForResponse: z.ZodOptional; + }, "strip", z.ZodTypeAny, { + workflowId: string; + triggerType: "form"; + data?: Record | undefined; + headers?: Record | undefined; + timeout?: number | undefined; + waitForResponse?: boolean | undefined; + formData?: Record | undefined; + }, { + workflowId: string; + triggerType: "form"; + data?: Record | undefined; + headers?: Record | undefined; + timeout?: number | undefined; + waitForResponse?: boolean | undefined; + formData?: Record | undefined; + }>; + execute(input: FormTriggerInput, workflow: Workflow, triggerInfo?: DetectedTrigger): Promise; +} +//# sourceMappingURL=form-handler.d.ts.map \ No newline at end of file diff --git a/dist/triggers/handlers/form-handler.d.ts.map b/dist/triggers/handlers/form-handler.d.ts.map new file mode 100644 index 0000000..b9121c5 --- /dev/null +++ b/dist/triggers/handlers/form-handler.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"form-handler.d.ts","sourceRoot":"","sources":["../../../src/triggers/handlers/form-handler.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,QAAQ,EAAgB,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EACL,WAAW,EACX,eAAe,EACf,0BAA0B,EAC1B,eAAe,EACf,gBAAgB,EACjB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAwMpD,qBAAa,WAAY,SAAQ,kBAAkB,CAAC,gBAAgB,CAAC;IACnE,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAU;IAE3C,QAAQ,CAAC,YAAY,EAAE,0BAA0B,CAG/C;IAEF,QAAQ,CAAC,WAAW;;;;;;;;;;;;;;;;;;;;;;;;OAAmB;IAEjC,OAAO,CACX,KAAK,EAAE,gBAAgB,EACvB,QAAQ,EAAE,QAAQ,EAClB,WAAW,CAAC,EAAE,eAAe,GAC5B,OAAO,CAAC,eAAe,CAAC;CAiO5B"} \ No newline at end of file diff --git a/dist/triggers/handlers/form-handler.js b/dist/triggers/handlers/form-handler.js new file mode 100644 index 0000000..38cb067 --- /dev/null +++ b/dist/triggers/handlers/form-handler.js @@ -0,0 +1,362 @@ +"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; + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.FormHandler = void 0; +const zod_1 = require("zod"); +const axios_1 = __importDefault(require("axios")); +const form_data_1 = __importDefault(require("form-data")); +const base_handler_1 = require("./base-handler"); +const formInputSchema = zod_1.z.object({ + workflowId: zod_1.z.string(), + triggerType: zod_1.z.literal('form'), + formData: zod_1.z.record(zod_1.z.unknown()).optional(), + data: zod_1.z.record(zod_1.z.unknown()).optional(), + headers: zod_1.z.record(zod_1.z.string()).optional(), + timeout: zod_1.z.number().optional(), + waitForResponse: zod_1.z.boolean().optional(), +}); +const FORM_FIELD_TYPES = { + TEXT: 'text', + TEXTAREA: 'textarea', + EMAIL: 'email', + NUMBER: 'number', + PASSWORD: 'password', + DATE: 'date', + DROPDOWN: 'dropdown', + CHECKBOX: 'checkbox', + FILE: 'file', + HIDDEN: 'hiddenField', + HTML: 'html', +}; +const MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024; +function isValidBase64(str) { + if (!str || str.length === 0) { + return false; + } + const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/; + if (!base64Regex.test(str)) { + return false; + } + try { + const decoded = Buffer.from(str, 'base64'); + return decoded.toString('base64') === str; + } + catch { + return false; + } +} +function extractFormFields(workflow, triggerNode) { + const node = triggerNode || workflow.nodes.find(n => n.type.toLowerCase().includes('formtrigger')); + const params = node?.parameters; + const formFields = params?.formFields; + if (!formFields?.values) { + return []; + } + const fields = []; + let fieldIndex = 0; + for (const rawField of formFields.values) { + const field = rawField; + const fieldType = field.fieldType || FORM_FIELD_TYPES.TEXT; + const def = { + index: fieldIndex, + fieldName: `field-${fieldIndex}`, + label: field.fieldLabel || field.fieldName || field.elementName || `field-${fieldIndex}`, + type: fieldType, + required: field.requiredField === true, + }; + if (field.fieldOptions?.values) { + def.options = field.fieldOptions.values.map((v) => v.option); + } + fields.push(def); + fieldIndex++; + } + return fields; +} +function generateFormUsageHint(fields) { + if (fields.length === 0) { + return 'No form fields detected in workflow.'; + } + const lines = ['Form fields (use these keys in data parameter):']; + for (const field of fields) { + let hint = ` "${field.fieldName}": `; + switch (field.type) { + case FORM_FIELD_TYPES.CHECKBOX: + hint += `["${field.options?.[0] || 'option1'}", ...]`; + if (field.options) { + hint += ` (options: ${field.options.join(', ')})`; + } + break; + case FORM_FIELD_TYPES.DROPDOWN: + hint += `"${field.options?.[0] || 'value'}"`; + if (field.options) { + hint += ` (options: ${field.options.join(', ')})`; + } + break; + case FORM_FIELD_TYPES.DATE: + hint += '"YYYY-MM-DD"'; + break; + case FORM_FIELD_TYPES.EMAIL: + hint += '"user@example.com"'; + break; + case FORM_FIELD_TYPES.NUMBER: + hint += '123'; + break; + case FORM_FIELD_TYPES.FILE: + hint += '{ filename: "test.txt", content: "base64..." } or skip (sends empty file)'; + break; + case FORM_FIELD_TYPES.PASSWORD: + hint += '"secret"'; + break; + case FORM_FIELD_TYPES.TEXTAREA: + hint += '"multi-line text..."'; + break; + case FORM_FIELD_TYPES.HTML: + hint += '"" (display-only, can be omitted)'; + break; + case FORM_FIELD_TYPES.HIDDEN: + hint += '"value" (hidden field)'; + break; + default: + hint += '"text value"'; + } + hint += field.required ? ' [REQUIRED]' : ''; + hint += ` // ${field.label}`; + lines.push(hint); + } + return lines.join('\n'); +} +class FormHandler extends base_handler_1.BaseTriggerHandler { + constructor() { + super(...arguments); + this.triggerType = 'form'; + this.capabilities = { + requiresActiveWorkflow: true, + canPassInputData: true, + }; + this.inputSchema = formInputSchema; + } + async execute(input, workflow, triggerInfo) { + const startTime = Date.now(); + const formFieldDefs = extractFormFields(workflow, triggerInfo?.node); + try { + const baseUrl = this.getBaseUrl(); + if (!baseUrl) { + return this.errorResponse(input, 'Cannot determine n8n base URL', startTime, { + details: { + formFields: formFieldDefs, + hint: generateFormUsageHint(formFieldDefs), + }, + }); + } + const formPath = triggerInfo?.webhookPath || triggerInfo?.node?.parameters?.path || input.workflowId; + const formUrl = `${baseUrl.replace(/\/+$/, '')}/form/${formPath}`; + const inputFields = { + ...input.data, + ...input.formData, + }; + const { SSRFProtection } = await Promise.resolve().then(() => __importStar(require('../../utils/ssrf-protection'))); + const validation = await SSRFProtection.validateWebhookUrl(formUrl); + if (!validation.valid) { + return this.errorResponse(input, `SSRF protection: ${validation.reason}`, startTime); + } + const formData = new form_data_1.default(); + const warnings = []; + for (const fieldDef of formFieldDefs) { + const value = inputFields[fieldDef.fieldName]; + switch (fieldDef.type) { + case FORM_FIELD_TYPES.CHECKBOX: + if (Array.isArray(value)) { + for (const item of value) { + formData.append(`${fieldDef.fieldName}[]`, String(item ?? '')); + } + } + else if (value !== undefined && value !== null) { + formData.append(`${fieldDef.fieldName}[]`, String(value)); + } + else if (fieldDef.required) { + warnings.push(`Required checkbox field "${fieldDef.fieldName}" (${fieldDef.label}) not provided`); + } + break; + case FORM_FIELD_TYPES.FILE: + if (value && typeof value === 'object' && 'content' in value) { + const fileObj = value; + let buffer; + if (typeof fileObj.content === 'string') { + if (!isValidBase64(fileObj.content)) { + warnings.push(`Invalid base64 encoding for file field "${fieldDef.fieldName}" (${fieldDef.label})`); + buffer = Buffer.from(''); + } + else { + buffer = Buffer.from(fileObj.content, 'base64'); + if (buffer.length > MAX_FILE_SIZE_BYTES) { + warnings.push(`File too large for "${fieldDef.fieldName}" (${fieldDef.label}): ${Math.round(buffer.length / 1024 / 1024)}MB exceeds ${MAX_FILE_SIZE_BYTES / 1024 / 1024}MB limit`); + buffer = Buffer.from(''); + } + } + } + else { + buffer = fileObj.content; + if (buffer.length > MAX_FILE_SIZE_BYTES) { + warnings.push(`File too large for "${fieldDef.fieldName}" (${fieldDef.label}): ${Math.round(buffer.length / 1024 / 1024)}MB exceeds ${MAX_FILE_SIZE_BYTES / 1024 / 1024}MB limit`); + buffer = Buffer.from(''); + } + } + formData.append(fieldDef.fieldName, buffer, { + filename: fileObj.filename || 'file.txt', + contentType: 'application/octet-stream', + }); + } + else if (value && typeof value === 'string') { + if (!isValidBase64(value)) { + warnings.push(`Invalid base64 encoding for file field "${fieldDef.fieldName}" (${fieldDef.label})`); + formData.append(fieldDef.fieldName, Buffer.from(''), { + filename: 'empty.txt', + contentType: 'text/plain', + }); + } + else { + const buffer = Buffer.from(value, 'base64'); + if (buffer.length > MAX_FILE_SIZE_BYTES) { + warnings.push(`File too large for "${fieldDef.fieldName}" (${fieldDef.label}): ${Math.round(buffer.length / 1024 / 1024)}MB exceeds ${MAX_FILE_SIZE_BYTES / 1024 / 1024}MB limit`); + formData.append(fieldDef.fieldName, Buffer.from(''), { + filename: 'empty.txt', + contentType: 'text/plain', + }); + } + else { + formData.append(fieldDef.fieldName, buffer, { + filename: 'file.txt', + contentType: 'application/octet-stream', + }); + } + } + } + else { + formData.append(fieldDef.fieldName, Buffer.from(''), { + filename: 'empty.txt', + contentType: 'text/plain', + }); + if (fieldDef.required) { + warnings.push(`Required file field "${fieldDef.fieldName}" (${fieldDef.label}) not provided - sending empty placeholder`); + } + } + break; + case FORM_FIELD_TYPES.HTML: + formData.append(fieldDef.fieldName, String(value ?? '')); + break; + case FORM_FIELD_TYPES.HIDDEN: + formData.append(fieldDef.fieldName, String(value ?? '')); + break; + default: + if (value !== undefined && value !== null) { + formData.append(fieldDef.fieldName, String(value)); + } + else if (fieldDef.required) { + warnings.push(`Required field "${fieldDef.fieldName}" (${fieldDef.label}) not provided`); + } + break; + } + } + const definedFieldNames = new Set(formFieldDefs.map(f => f.fieldName)); + for (const [key, value] of Object.entries(inputFields)) { + if (!definedFieldNames.has(key)) { + if (Array.isArray(value)) { + for (const item of value) { + formData.append(`${key}[]`, String(item ?? '')); + } + } + else { + formData.append(key, String(value ?? '')); + } + } + } + const config = { + method: 'POST', + url: formUrl, + headers: { + ...formData.getHeaders(), + ...input.headers, + }, + data: formData, + timeout: input.timeout || (input.waitForResponse !== false ? 120000 : 30000), + validateStatus: (status) => status < 500, + }; + const response = await axios_1.default.request(config); + const result = this.normalizeResponse(response.data, input, startTime, { + status: response.status, + statusText: response.statusText, + metadata: { + duration: Date.now() - startTime, + }, + }); + result.details = { + ...result.details, + fieldsSubmitted: formFieldDefs.length, + }; + if (warnings.length > 0) { + result.details = { + ...result.details, + warnings, + }; + } + return result; + } + catch (error) { + const errorMessage = error instanceof Error ? error.message : 'Unknown error'; + const errorDetails = error?.response?.data; + const executionId = errorDetails?.executionId || errorDetails?.id; + return this.errorResponse(input, errorMessage, startTime, { + executionId, + code: error?.code, + details: { + ...errorDetails, + formFields: formFieldDefs.map(f => ({ + name: f.fieldName, + label: f.label, + type: f.type, + required: f.required, + options: f.options, + })), + hint: generateFormUsageHint(formFieldDefs), + }, + }); + } + } +} +exports.FormHandler = FormHandler; +//# sourceMappingURL=form-handler.js.map \ No newline at end of file diff --git a/dist/triggers/handlers/form-handler.js.map b/dist/triggers/handlers/form-handler.js.map new file mode 100644 index 0000000..6d4fd65 --- /dev/null +++ b/dist/triggers/handlers/form-handler.js.map @@ -0,0 +1 @@ +{"version":3,"file":"form-handler.js","sourceRoot":"","sources":["../../../src/triggers/handlers/form-handler.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/triggers/handlers/webhook-handler.d.ts b/dist/triggers/handlers/webhook-handler.d.ts new file mode 100644 index 0000000..1ce4098 --- /dev/null +++ b/dist/triggers/handlers/webhook-handler.d.ts @@ -0,0 +1,38 @@ +import { z } from 'zod'; +import { Workflow } from '../../types/n8n-api'; +import { TriggerType, TriggerResponse, TriggerHandlerCapabilities, DetectedTrigger, WebhookTriggerInput } from '../types'; +import { BaseTriggerHandler } from './base-handler'; +export declare class WebhookHandler extends BaseTriggerHandler { + readonly triggerType: TriggerType; + readonly capabilities: TriggerHandlerCapabilities; + readonly inputSchema: z.ZodObject<{ + workflowId: z.ZodString; + triggerType: z.ZodLiteral<"webhook">; + httpMethod: z.ZodOptional>; + webhookPath: z.ZodOptional; + data: z.ZodOptional>; + headers: z.ZodOptional>; + timeout: z.ZodOptional; + waitForResponse: z.ZodOptional; + }, "strip", z.ZodTypeAny, { + workflowId: string; + triggerType: "webhook"; + httpMethod?: "GET" | "POST" | "PUT" | "DELETE" | undefined; + webhookPath?: string | undefined; + data?: Record | undefined; + headers?: Record | undefined; + timeout?: number | undefined; + waitForResponse?: boolean | undefined; + }, { + workflowId: string; + triggerType: "webhook"; + httpMethod?: "GET" | "POST" | "PUT" | "DELETE" | undefined; + webhookPath?: string | undefined; + data?: Record | undefined; + headers?: Record | undefined; + timeout?: number | undefined; + waitForResponse?: boolean | undefined; + }>; + execute(input: WebhookTriggerInput, workflow: Workflow, triggerInfo?: DetectedTrigger): Promise; +} +//# sourceMappingURL=webhook-handler.d.ts.map \ No newline at end of file diff --git a/dist/triggers/handlers/webhook-handler.d.ts.map b/dist/triggers/handlers/webhook-handler.d.ts.map new file mode 100644 index 0000000..4fcf9c5 --- /dev/null +++ b/dist/triggers/handlers/webhook-handler.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"webhook-handler.d.ts","sourceRoot":"","sources":["../../../src/triggers/handlers/webhook-handler.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAkB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EACL,WAAW,EACX,eAAe,EACf,0BAA0B,EAC1B,eAAe,EACf,mBAAmB,EACpB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAoBpD,qBAAa,cAAe,SAAQ,kBAAkB,CAAC,mBAAmB,CAAC;IACzE,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAa;IAE9C,QAAQ,CAAC,YAAY,EAAE,0BAA0B,CAI/C;IAEF,QAAQ,CAAC,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;OAAsB;IAEpC,OAAO,CACX,KAAK,EAAE,mBAAmB,EAC1B,QAAQ,EAAE,QAAQ,EAClB,WAAW,CAAC,EAAE,eAAe,GAC5B,OAAO,CAAC,eAAe,CAAC;CAuE5B"} \ No newline at end of file diff --git a/dist/triggers/handlers/webhook-handler.js b/dist/triggers/handlers/webhook-handler.js new file mode 100644 index 0000000..753c88c --- /dev/null +++ b/dist/triggers/handlers/webhook-handler.js @@ -0,0 +1,115 @@ +"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.WebhookHandler = void 0; +const zod_1 = require("zod"); +const base_handler_1 = require("./base-handler"); +const trigger_detector_1 = require("../trigger-detector"); +const webhookInputSchema = zod_1.z.object({ + workflowId: zod_1.z.string(), + triggerType: zod_1.z.literal('webhook'), + httpMethod: zod_1.z.enum(['GET', 'POST', 'PUT', 'DELETE']).optional(), + webhookPath: zod_1.z.string().optional(), + data: zod_1.z.record(zod_1.z.unknown()).optional(), + headers: zod_1.z.record(zod_1.z.string()).optional(), + timeout: zod_1.z.number().optional(), + waitForResponse: zod_1.z.boolean().optional(), +}); +class WebhookHandler extends base_handler_1.BaseTriggerHandler { + constructor() { + super(...arguments); + this.triggerType = 'webhook'; + this.capabilities = { + requiresActiveWorkflow: true, + supportedMethods: ['GET', 'POST', 'PUT', 'DELETE'], + canPassInputData: true, + }; + this.inputSchema = webhookInputSchema; + } + async execute(input, workflow, triggerInfo) { + const startTime = Date.now(); + try { + const baseUrl = this.getBaseUrl(); + if (!baseUrl) { + return this.errorResponse(input, 'Cannot determine n8n base URL', startTime); + } + let webhookUrl; + if (input.webhookPath) { + webhookUrl = `${baseUrl.replace(/\/+$/, '')}/webhook/${input.webhookPath}`; + } + else if (triggerInfo?.webhookPath) { + webhookUrl = (0, trigger_detector_1.buildTriggerUrl)(baseUrl, triggerInfo, 'production'); + } + else { + return this.errorResponse(input, 'No webhook path available. Provide webhookPath parameter or ensure workflow has a webhook trigger.', startTime); + } + const httpMethod = input.httpMethod || triggerInfo?.httpMethod || 'POST'; + const { SSRFProtection } = await Promise.resolve().then(() => __importStar(require('../../utils/ssrf-protection'))); + const validation = await SSRFProtection.validateWebhookUrl(webhookUrl); + if (!validation.valid) { + return this.errorResponse(input, `SSRF protection: ${validation.reason}`, startTime); + } + const webhookRequest = { + webhookUrl, + httpMethod: httpMethod, + data: input.data, + headers: input.headers, + waitForResponse: input.waitForResponse ?? true, + }; + const response = await this.client.triggerWebhook(webhookRequest); + return this.normalizeResponse(response, input, startTime, { + status: response.status, + statusText: response.statusText, + metadata: { + duration: Date.now() - startTime, + webhookPath: input.webhookPath || triggerInfo?.webhookPath, + httpMethod, + }, + }); + } + catch (error) { + const errorMessage = error instanceof Error ? error.message : 'Unknown error'; + const errorDetails = error?.details; + const executionId = errorDetails?.executionId || errorDetails?.id; + return this.errorResponse(input, errorMessage, startTime, { + executionId, + code: error?.code, + details: errorDetails, + }); + } + } +} +exports.WebhookHandler = WebhookHandler; +//# sourceMappingURL=webhook-handler.js.map \ No newline at end of file diff --git a/dist/triggers/handlers/webhook-handler.js.map b/dist/triggers/handlers/webhook-handler.js.map new file mode 100644 index 0000000..3659802 --- /dev/null +++ b/dist/triggers/handlers/webhook-handler.js.map @@ -0,0 +1 @@ +{"version":3,"file":"webhook-handler.js","sourceRoot":"","sources":["../../../src/triggers/handlers/webhook-handler.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/triggers/index.d.ts b/dist/triggers/index.d.ts new file mode 100644 index 0000000..daf904f --- /dev/null +++ b/dist/triggers/index.d.ts @@ -0,0 +1,5 @@ +export { TriggerType, BaseTriggerInput, WebhookTriggerInput, FormTriggerInput, ChatTriggerInput, TriggerInput, TriggerResponse, TriggerHandlerCapabilities, DetectedTrigger, TriggerDetectionResult, TestWorkflowInput, } from './types'; +export { detectTriggerFromWorkflow, buildTriggerUrl, describeTrigger, } from './trigger-detector'; +export { TriggerRegistry, initializeTriggerRegistry, ensureRegistryInitialized, } from './trigger-registry'; +export { BaseTriggerHandler, TriggerHandlerConstructor, } from './handlers/base-handler'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/triggers/index.d.ts.map b/dist/triggers/index.d.ts.map new file mode 100644 index 0000000..447723f --- /dev/null +++ b/dist/triggers/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/triggers/index.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,0BAA0B,EAC1B,eAAe,EACf,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,yBAAyB,EACzB,eAAe,EACf,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,eAAe,EACf,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC"} \ No newline at end of file diff --git a/dist/triggers/index.js b/dist/triggers/index.js new file mode 100644 index 0000000..df8da92 --- /dev/null +++ b/dist/triggers/index.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BaseTriggerHandler = exports.ensureRegistryInitialized = exports.initializeTriggerRegistry = exports.TriggerRegistry = exports.describeTrigger = exports.buildTriggerUrl = exports.detectTriggerFromWorkflow = void 0; +var trigger_detector_1 = require("./trigger-detector"); +Object.defineProperty(exports, "detectTriggerFromWorkflow", { enumerable: true, get: function () { return trigger_detector_1.detectTriggerFromWorkflow; } }); +Object.defineProperty(exports, "buildTriggerUrl", { enumerable: true, get: function () { return trigger_detector_1.buildTriggerUrl; } }); +Object.defineProperty(exports, "describeTrigger", { enumerable: true, get: function () { return trigger_detector_1.describeTrigger; } }); +var trigger_registry_1 = require("./trigger-registry"); +Object.defineProperty(exports, "TriggerRegistry", { enumerable: true, get: function () { return trigger_registry_1.TriggerRegistry; } }); +Object.defineProperty(exports, "initializeTriggerRegistry", { enumerable: true, get: function () { return trigger_registry_1.initializeTriggerRegistry; } }); +Object.defineProperty(exports, "ensureRegistryInitialized", { enumerable: true, get: function () { return trigger_registry_1.ensureRegistryInitialized; } }); +var base_handler_1 = require("./handlers/base-handler"); +Object.defineProperty(exports, "BaseTriggerHandler", { enumerable: true, get: function () { return base_handler_1.BaseTriggerHandler; } }); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/triggers/index.js.map b/dist/triggers/index.js.map new file mode 100644 index 0000000..bf8c482 --- /dev/null +++ b/dist/triggers/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/triggers/index.ts"],"names":[],"mappings":";;;AA4BA,uDAI4B;AAH1B,6HAAA,yBAAyB,OAAA;AACzB,mHAAA,eAAe,OAAA;AACf,mHAAA,eAAe,OAAA;AAIjB,uDAI4B;AAH1B,mHAAA,eAAe,OAAA;AACf,6HAAA,yBAAyB,OAAA;AACzB,6HAAA,yBAAyB,OAAA;AAI3B,wDAGiC;AAF/B,kHAAA,kBAAkB,OAAA"} \ No newline at end of file diff --git a/dist/triggers/trigger-detector.d.ts b/dist/triggers/trigger-detector.d.ts new file mode 100644 index 0000000..6e85456 --- /dev/null +++ b/dist/triggers/trigger-detector.d.ts @@ -0,0 +1,6 @@ +import { Workflow } from '../types/n8n-api'; +import { DetectedTrigger, TriggerDetectionResult } from './types'; +export declare function detectTriggerFromWorkflow(workflow: Workflow): TriggerDetectionResult; +export declare function buildTriggerUrl(baseUrl: string, trigger: DetectedTrigger, mode?: 'production' | 'test'): string; +export declare function describeTrigger(trigger: DetectedTrigger): string; +//# sourceMappingURL=trigger-detector.d.ts.map \ No newline at end of file diff --git a/dist/triggers/trigger-detector.d.ts.map b/dist/triggers/trigger-detector.d.ts.map new file mode 100644 index 0000000..23e1d77 --- /dev/null +++ b/dist/triggers/trigger-detector.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"trigger-detector.d.ts","sourceRoot":"","sources":["../../src/triggers/trigger-detector.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAgB,MAAM,kBAAkB,CAAC;AAE1D,OAAO,EAAe,eAAe,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AA8B/E,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,QAAQ,GAAG,sBAAsB,CAsDpF;AAmLD,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,eAAe,EACxB,IAAI,GAAE,YAAY,GAAG,MAAqB,GACzC,MAAM,CA2BR;AAKD,wBAAgB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CAehE"} \ No newline at end of file diff --git a/dist/triggers/trigger-detector.js b/dist/triggers/trigger-detector.js new file mode 100644 index 0000000..e33be46 --- /dev/null +++ b/dist/triggers/trigger-detector.js @@ -0,0 +1,201 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.detectTriggerFromWorkflow = detectTriggerFromWorkflow; +exports.buildTriggerUrl = buildTriggerUrl; +exports.describeTrigger = describeTrigger; +const node_type_utils_1 = require("../utils/node-type-utils"); +const WEBHOOK_PATTERNS = [ + 'webhook', + 'webhooktrigger', +]; +const FORM_PATTERNS = [ + 'formtrigger', + 'form', +]; +const CHAT_PATTERNS = [ + 'chattrigger', +]; +function detectTriggerFromWorkflow(workflow) { + if (!workflow.nodes || workflow.nodes.length === 0) { + return { + detected: false, + reason: 'Workflow has no nodes', + }; + } + const triggerNodes = workflow.nodes.filter(node => !node.disabled && isTriggerNodeType(node.type)); + if (triggerNodes.length === 0) { + return { + detected: false, + reason: 'No trigger nodes found in workflow', + }; + } + for (const node of triggerNodes) { + const webhookTrigger = detectWebhookTrigger(node); + if (webhookTrigger) { + return { + detected: true, + trigger: webhookTrigger, + }; + } + } + for (const node of triggerNodes) { + const chatTrigger = detectChatTrigger(node); + if (chatTrigger) { + return { + detected: true, + trigger: chatTrigger, + }; + } + } + for (const node of triggerNodes) { + const formTrigger = detectFormTrigger(node); + if (formTrigger) { + return { + detected: true, + trigger: formTrigger, + }; + } + } + return { + detected: false, + reason: `Workflow has trigger nodes but none support external triggering (found: ${triggerNodes.map(n => n.type).join(', ')}). Only webhook, form, and chat triggers can be triggered via the API.`, + }; +} +function isTriggerNodeType(nodeType) { + const normalized = (0, node_type_utils_1.normalizeNodeType)(nodeType).toLowerCase(); + return (normalized.includes('trigger') || + normalized.includes('webhook') || + normalized === 'nodes-base.start'); +} +function detectWebhookTrigger(node) { + const normalized = (0, node_type_utils_1.normalizeNodeType)(node.type).toLowerCase(); + const nodeName = normalized.split('.').pop() || ''; + const isWebhook = WEBHOOK_PATTERNS.some(pattern => nodeName === pattern || nodeName.includes(pattern)); + if (!isWebhook) { + return null; + } + const params = node.parameters || {}; + const webhookPath = extractWebhookPath(params, node.id, node.webhookId); + const httpMethod = extractHttpMethod(params); + return { + type: 'webhook', + node, + webhookPath, + httpMethod, + }; +} +function detectFormTrigger(node) { + const normalized = (0, node_type_utils_1.normalizeNodeType)(node.type).toLowerCase(); + const nodeName = normalized.split('.').pop() || ''; + const isForm = FORM_PATTERNS.some(pattern => nodeName === pattern || nodeName.includes(pattern)); + if (!isForm) { + return null; + } + const params = node.parameters || {}; + const formFields = extractFormFields(params); + const webhookPath = extractWebhookPath(params, node.id, node.webhookId); + return { + type: 'form', + node, + webhookPath, + formFields, + }; +} +function detectChatTrigger(node) { + const normalized = (0, node_type_utils_1.normalizeNodeType)(node.type).toLowerCase(); + const nodeName = normalized.split('.').pop() || ''; + const isChat = CHAT_PATTERNS.some(pattern => nodeName === pattern || nodeName.includes(pattern)); + if (!isChat) { + return null; + } + const params = node.parameters || {}; + const responseMode = params.options?.responseMode || 'lastNode'; + const webhookPath = extractWebhookPath(params, node.id, node.webhookId); + return { + type: 'chat', + node, + webhookPath, + chatConfig: { + responseMode, + }, + }; +} +function extractWebhookPath(params, nodeId, webhookId) { + if (typeof params.path === 'string' && params.path) { + return params.path; + } + if (typeof params.httpMethod === 'string') { + const methodPath = params[`path_${params.httpMethod.toLowerCase()}`]; + if (typeof methodPath === 'string' && methodPath) { + return methodPath; + } + } + if (typeof webhookId === 'string' && webhookId) { + return webhookId; + } + return nodeId; +} +function extractHttpMethod(params) { + if (typeof params.httpMethod === 'string') { + return params.httpMethod.toUpperCase(); + } + return 'POST'; +} +function extractFormFields(params) { + const fields = []; + if (Array.isArray(params.formFields)) { + for (const field of params.formFields) { + if (field && typeof field.fieldLabel === 'string') { + fields.push(field.fieldLabel); + } + else if (field && typeof field.fieldName === 'string') { + fields.push(field.fieldName); + } + } + } + const options = params.options; + if (options && Array.isArray(options.formFields)) { + for (const field of options.formFields) { + if (field && typeof field.fieldLabel === 'string') { + fields.push(field.fieldLabel); + } + } + } + return fields; +} +function buildTriggerUrl(baseUrl, trigger, mode = 'production') { + const cleanBaseUrl = baseUrl.replace(/\/+$/, ''); + switch (trigger.type) { + case 'webhook': { + const prefix = mode === 'test' ? 'webhook-test' : 'webhook'; + const path = trigger.webhookPath || trigger.node.id; + return `${cleanBaseUrl}/${prefix}/${path}`; + } + case 'chat': { + const prefix = mode === 'test' ? 'webhook-test' : 'webhook'; + const path = trigger.webhookPath || trigger.node.id; + return `${cleanBaseUrl}/${prefix}/${path}/chat`; + } + case 'form': { + const prefix = mode === 'test' ? 'form-test' : 'form'; + const path = trigger.webhookPath || trigger.node.id; + return `${cleanBaseUrl}/${prefix}/${path}`; + } + default: + throw new Error(`Cannot build URL for trigger type: ${trigger.type}`); + } +} +function describeTrigger(trigger) { + switch (trigger.type) { + case 'webhook': + return `Webhook trigger (${trigger.httpMethod || 'POST'} /${trigger.webhookPath || trigger.node.id})`; + case 'form': + const fieldCount = trigger.formFields?.length || 0; + return `Form trigger (${fieldCount} fields)`; + case 'chat': + return `Chat trigger (${trigger.chatConfig?.responseMode || 'lastNode'} mode)`; + default: + return 'Unknown trigger'; + } +} +//# sourceMappingURL=trigger-detector.js.map \ No newline at end of file diff --git a/dist/triggers/trigger-detector.js.map b/dist/triggers/trigger-detector.js.map new file mode 100644 index 0000000..487e0e7 --- /dev/null +++ b/dist/triggers/trigger-detector.js.map @@ -0,0 +1 @@ +{"version":3,"file":"trigger-detector.js","sourceRoot":"","sources":["../../src/triggers/trigger-detector.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/triggers/trigger-registry.d.ts b/dist/triggers/trigger-registry.d.ts new file mode 100644 index 0000000..e24dcbe --- /dev/null +++ b/dist/triggers/trigger-registry.d.ts @@ -0,0 +1,18 @@ +import { N8nApiClient } from '../services/n8n-api-client'; +import { InstanceContext } from '../types/instance-context'; +import { TriggerType } from './types'; +import { BaseTriggerHandler, TriggerHandlerConstructor } from './handlers/base-handler'; +export declare class TriggerRegistry { + private static handlers; + private static initialized; + static register(type: TriggerType, HandlerClass: TriggerHandlerConstructor): void; + static getHandler(type: TriggerType, client: N8nApiClient, context?: InstanceContext): BaseTriggerHandler | undefined; + static hasHandler(type: TriggerType): boolean; + static getRegisteredTypes(): TriggerType[]; + static clear(): void; + static isInitialized(): boolean; + static markInitialized(): void; +} +export declare function initializeTriggerRegistry(): Promise; +export declare function ensureRegistryInitialized(): Promise; +//# sourceMappingURL=trigger-registry.d.ts.map \ No newline at end of file diff --git a/dist/triggers/trigger-registry.d.ts.map b/dist/triggers/trigger-registry.d.ts.map new file mode 100644 index 0000000..1bfd992 --- /dev/null +++ b/dist/triggers/trigger-registry.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"trigger-registry.d.ts","sourceRoot":"","sources":["../../src/triggers/trigger-registry.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAKxF,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA0D;IACjF,OAAO,CAAC,MAAM,CAAC,WAAW,CAAS;IAQnC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,yBAAyB,GAAG,IAAI;IAYjF,MAAM,CAAC,UAAU,CACf,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE,eAAe,GACxB,kBAAkB,GAAG,SAAS;IAWjC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO;IAO7C,MAAM,CAAC,kBAAkB,IAAI,WAAW,EAAE;IAO1C,MAAM,CAAC,KAAK,IAAI,IAAI;IAQpB,MAAM,CAAC,aAAa,IAAI,OAAO;IAO/B,MAAM,CAAC,eAAe,IAAI,IAAI;CAG/B;AAMD,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC,CAgB/D;AAKD,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC,CAI/D"} \ No newline at end of file diff --git a/dist/triggers/trigger-registry.js b/dist/triggers/trigger-registry.js new file mode 100644 index 0000000..2a71ae9 --- /dev/null +++ b/dist/triggers/trigger-registry.js @@ -0,0 +1,87 @@ +"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.TriggerRegistry = void 0; +exports.initializeTriggerRegistry = initializeTriggerRegistry; +exports.ensureRegistryInitialized = ensureRegistryInitialized; +class TriggerRegistry { + static register(type, HandlerClass) { + this.handlers.set(type, HandlerClass); + } + static getHandler(type, client, context) { + const HandlerClass = this.handlers.get(type); + if (!HandlerClass) { + return undefined; + } + return new HandlerClass(client, context); + } + static hasHandler(type) { + return this.handlers.has(type); + } + static getRegisteredTypes() { + return Array.from(this.handlers.keys()); + } + static clear() { + this.handlers.clear(); + this.initialized = false; + } + static isInitialized() { + return this.initialized; + } + static markInitialized() { + this.initialized = true; + } +} +exports.TriggerRegistry = TriggerRegistry; +TriggerRegistry.handlers = new Map(); +TriggerRegistry.initialized = false; +async function initializeTriggerRegistry() { + if (TriggerRegistry.isInitialized()) { + return; + } + const { WebhookHandler } = await Promise.resolve().then(() => __importStar(require('./handlers/webhook-handler'))); + const { FormHandler } = await Promise.resolve().then(() => __importStar(require('./handlers/form-handler'))); + const { ChatHandler } = await Promise.resolve().then(() => __importStar(require('./handlers/chat-handler'))); + TriggerRegistry.register('webhook', WebhookHandler); + TriggerRegistry.register('form', FormHandler); + TriggerRegistry.register('chat', ChatHandler); + TriggerRegistry.markInitialized(); +} +async function ensureRegistryInitialized() { + if (!TriggerRegistry.isInitialized()) { + await initializeTriggerRegistry(); + } +} +//# sourceMappingURL=trigger-registry.js.map \ No newline at end of file diff --git a/dist/triggers/trigger-registry.js.map b/dist/triggers/trigger-registry.js.map new file mode 100644 index 0000000..a6cc214 --- /dev/null +++ b/dist/triggers/trigger-registry.js.map @@ -0,0 +1 @@ +{"version":3,"file":"trigger-registry.js","sourceRoot":"","sources":["../../src/triggers/trigger-registry.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4FA,8DAgBC;AAKD,8DAIC;AApGD,MAAa,eAAe;IAU1B,MAAM,CAAC,QAAQ,CAAC,IAAiB,EAAE,YAAuC;QACxE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACxC,CAAC;IAUD,MAAM,CAAC,UAAU,CACf,IAAiB,EACjB,MAAoB,EACpB,OAAyB;QAEzB,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,IAAI,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAKD,MAAM,CAAC,UAAU,CAAC,IAAiB;QACjC,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAKD,MAAM,CAAC,kBAAkB;QACvB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1C,CAAC;IAKD,MAAM,CAAC,KAAK;QACV,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC3B,CAAC;IAKD,MAAM,CAAC,aAAa;QAClB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAKD,MAAM,CAAC,eAAe;QACpB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC1B,CAAC;;AApEH,0CAqEC;AApEgB,wBAAQ,GAAgD,IAAI,GAAG,EAAE,CAAC;AAClE,2BAAW,GAAG,KAAK,CAAC;AAyE9B,KAAK,UAAU,yBAAyB;IAC7C,IAAI,eAAe,CAAC,aAAa,EAAE,EAAE,CAAC;QACpC,OAAO;IACT,CAAC;IAGD,MAAM,EAAE,cAAc,EAAE,GAAG,wDAAa,4BAA4B,GAAC,CAAC;IACtE,MAAM,EAAE,WAAW,EAAE,GAAG,wDAAa,yBAAyB,GAAC,CAAC;IAChE,MAAM,EAAE,WAAW,EAAE,GAAG,wDAAa,yBAAyB,GAAC,CAAC;IAGhE,eAAe,CAAC,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACpD,eAAe,CAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC9C,eAAe,CAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAE9C,eAAe,CAAC,eAAe,EAAE,CAAC;AACpC,CAAC;AAKM,KAAK,UAAU,yBAAyB;IAC7C,IAAI,CAAC,eAAe,CAAC,aAAa,EAAE,EAAE,CAAC;QACrC,MAAM,yBAAyB,EAAE,CAAC;IACpC,CAAC;AACH,CAAC"} \ No newline at end of file diff --git a/dist/triggers/types.d.ts b/dist/triggers/types.d.ts new file mode 100644 index 0000000..02b281c --- /dev/null +++ b/dist/triggers/types.d.ts @@ -0,0 +1,76 @@ +import { WorkflowNode } from '../types/n8n-api'; +export type TriggerType = 'webhook' | 'form' | 'chat'; +export interface BaseTriggerInput { + workflowId: string; + triggerType?: TriggerType; + data?: Record; + headers?: Record; + timeout?: number; + waitForResponse?: boolean; +} +export interface WebhookTriggerInput extends BaseTriggerInput { + triggerType: 'webhook'; + httpMethod?: 'GET' | 'POST' | 'PUT' | 'DELETE'; + webhookPath?: string; +} +export interface FormTriggerInput extends BaseTriggerInput { + triggerType: 'form'; + formData?: Record; +} +export interface ChatTriggerInput extends BaseTriggerInput { + triggerType: 'chat'; + message: string; + sessionId?: string; +} +export type TriggerInput = WebhookTriggerInput | FormTriggerInput | ChatTriggerInput; +export interface TriggerResponse { + success: boolean; + triggerType: TriggerType; + workflowId: string; + executionId?: string; + status?: number; + statusText?: string; + data?: unknown; + error?: string; + code?: string; + details?: Record; + metadata: { + duration: number; + webhookPath?: string; + sessionId?: string; + httpMethod?: string; + }; +} +export interface TriggerHandlerCapabilities { + requiresActiveWorkflow: boolean; + supportedMethods?: string[]; + canPassInputData: boolean; +} +export interface DetectedTrigger { + type: TriggerType; + node: WorkflowNode; + webhookPath?: string; + httpMethod?: string; + formFields?: string[]; + chatConfig?: { + responseMode?: string; + }; +} +export interface TriggerDetectionResult { + detected: boolean; + trigger?: DetectedTrigger; + reason?: string; +} +export interface TestWorkflowInput { + workflowId: string; + triggerType?: TriggerType; + httpMethod?: 'GET' | 'POST' | 'PUT' | 'DELETE'; + webhookPath?: string; + message?: string; + sessionId?: string; + data?: Record; + headers?: Record; + timeout?: number; + waitForResponse?: boolean; +} +//# sourceMappingURL=types.d.ts.map \ No newline at end of file diff --git a/dist/triggers/types.d.ts.map b/dist/triggers/types.d.ts.map new file mode 100644 index 0000000..dcd1949 --- /dev/null +++ b/dist/triggers/types.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/triggers/types.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/triggers/types.js b/dist/triggers/types.js new file mode 100644 index 0000000..11e638d --- /dev/null +++ b/dist/triggers/types.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/dist/triggers/types.js.map b/dist/triggers/types.js.map new file mode 100644 index 0000000..10e60f4 --- /dev/null +++ b/dist/triggers/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/triggers/types.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/types/index.d.ts b/dist/types/index.d.ts new file mode 100644 index 0000000..42219e2 --- /dev/null +++ b/dist/types/index.d.ts @@ -0,0 +1,41 @@ +export * from './node-types'; +export * from './type-structures'; +export * from './instance-context'; +export * from './session-state'; +export interface MCPServerConfig { + port: number; + host: string; + authToken?: string; +} +export interface ToolDefinition { + name: string; + description: string; + inputSchema: { + type: string; + properties: Record; + required?: string[]; + additionalProperties?: boolean | Record; + }; + outputSchema?: { + type: string; + properties: Record; + required?: string[]; + additionalProperties?: boolean | Record; + }; +} +export interface ResourceDefinition { + uri: string; + name: string; + description?: string; + mimeType?: string; +} +export interface PromptDefinition { + name: string; + description?: string; + arguments?: Array<{ + name: string; + description?: string; + required?: boolean; + }>; +} +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/types/index.d.ts.map b/dist/types/index.d.ts.map new file mode 100644 index 0000000..81d0fd8 --- /dev/null +++ b/dist/types/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAEhC,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,oBAAoB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KACtD,CAAC;IACF,YAAY,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,oBAAoB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KACtD,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,KAAK,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC,CAAC;CACJ"} \ No newline at end of file diff --git a/dist/types/index.js b/dist/types/index.js new file mode 100644 index 0000000..558eb3c --- /dev/null +++ b/dist/types/index.js @@ -0,0 +1,21 @@ +"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("./node-types"), exports); +__exportStar(require("./type-structures"), exports); +__exportStar(require("./instance-context"), exports); +__exportStar(require("./session-state"), exports); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/types/index.js.map b/dist/types/index.js.map new file mode 100644 index 0000000..3499702 --- /dev/null +++ b/dist/types/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,+CAA6B;AAC7B,oDAAkC;AAClC,qDAAmC;AACnC,kDAAgC"} \ No newline at end of file diff --git a/dist/types/instance-context.d.ts b/dist/types/instance-context.d.ts new file mode 100644 index 0000000..9036602 --- /dev/null +++ b/dist/types/instance-context.d.ts @@ -0,0 +1,15 @@ +export interface InstanceContext { + n8nApiUrl?: string; + n8nApiKey?: string; + n8nApiTimeout?: number; + n8nApiMaxRetries?: number; + instanceId?: string; + sessionId?: string; + metadata?: Record; +} +export declare function isInstanceContext(obj: any): obj is InstanceContext; +export declare function validateInstanceContext(context: InstanceContext): { + valid: boolean; + errors?: string[]; +}; +//# sourceMappingURL=instance-context.d.ts.map \ No newline at end of file diff --git a/dist/types/instance-context.d.ts.map b/dist/types/instance-context.d.ts.map new file mode 100644 index 0000000..03d5dcd --- /dev/null +++ b/dist/types/instance-context.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"instance-context.d.ts","sourceRoot":"","sources":["../../src/types/instance-context.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,eAAe;IAK9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAM1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IAMnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAsED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,eAAe,CAuBlE;AAMD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,eAAe,GAAG;IACjE,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAClB,CAgEA"} \ No newline at end of file diff --git a/dist/types/instance-context.js b/dist/types/instance-context.js new file mode 100644 index 0000000..43c94c3 --- /dev/null +++ b/dist/types/instance-context.js @@ -0,0 +1,127 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isInstanceContext = isInstanceContext; +exports.validateInstanceContext = validateInstanceContext; +function isValidUrl(url) { + try { + const parsed = new URL(url); + if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') { + return false; + } + if (!parsed.hostname || parsed.hostname.length === 0) { + return false; + } + if (parsed.port && (isNaN(Number(parsed.port)) || Number(parsed.port) < 1 || Number(parsed.port) > 65535)) { + return false; + } + const hostname = parsed.hostname.toLowerCase(); + if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1') { + return true; + } + const ipv4Pattern = /^(\d{1,3}\.){3}\d{1,3}$/; + if (ipv4Pattern.test(hostname)) { + const parts = hostname.split('.'); + return parts.every(part => { + const num = parseInt(part, 10); + return num >= 0 && num <= 255; + }); + } + if (hostname.includes(':') || hostname.startsWith('[') && hostname.endsWith(']')) { + return true; + } + const domainPattern = /^([a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?\.)*[a-zA-Z]([a-zA-Z0-9-]*[a-zA-Z0-9])?$/; + return domainPattern.test(hostname); + } + catch { + return false; + } +} +function isValidApiKey(key) { + return key.length > 0 && + !key.toLowerCase().includes('your_api_key') && + !key.toLowerCase().includes('placeholder') && + !key.toLowerCase().includes('example'); +} +function isInstanceContext(obj) { + if (!obj || typeof obj !== 'object') + return false; + const hasValidUrl = obj.n8nApiUrl === undefined || + (typeof obj.n8nApiUrl === 'string' && isValidUrl(obj.n8nApiUrl)); + const hasValidKey = obj.n8nApiKey === undefined || + (typeof obj.n8nApiKey === 'string' && isValidApiKey(obj.n8nApiKey)); + const hasValidTimeout = obj.n8nApiTimeout === undefined || + (typeof obj.n8nApiTimeout === 'number' && obj.n8nApiTimeout > 0); + const hasValidRetries = obj.n8nApiMaxRetries === undefined || + (typeof obj.n8nApiMaxRetries === 'number' && obj.n8nApiMaxRetries >= 0); + const hasValidInstanceId = obj.instanceId === undefined || typeof obj.instanceId === 'string'; + const hasValidSessionId = obj.sessionId === undefined || typeof obj.sessionId === 'string'; + const hasValidMetadata = obj.metadata === undefined || + (typeof obj.metadata === 'object' && obj.metadata !== null); + return hasValidUrl && hasValidKey && hasValidTimeout && hasValidRetries && + hasValidInstanceId && hasValidSessionId && hasValidMetadata; +} +function validateInstanceContext(context) { + const errors = []; + if (context.n8nApiUrl !== undefined) { + if (context.n8nApiUrl === '') { + errors.push(`Invalid n8nApiUrl: empty string - URL is required when field is provided`); + } + else if (!isValidUrl(context.n8nApiUrl)) { + try { + const parsed = new URL(context.n8nApiUrl); + if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') { + errors.push(`Invalid n8nApiUrl: URL must use HTTP or HTTPS protocol, got ${parsed.protocol}`); + } + } + catch { + errors.push(`Invalid n8nApiUrl: URL format is malformed or incomplete`); + } + } + } + if (context.n8nApiKey !== undefined) { + if (context.n8nApiKey === '') { + errors.push(`Invalid n8nApiKey: empty string - API key is required when field is provided`); + } + else if (!isValidApiKey(context.n8nApiKey)) { + if (context.n8nApiKey.toLowerCase().includes('your_api_key')) { + errors.push(`Invalid n8nApiKey: contains placeholder 'your_api_key' - Please provide actual API key`); + } + else if (context.n8nApiKey.toLowerCase().includes('placeholder')) { + errors.push(`Invalid n8nApiKey: contains placeholder text - Please provide actual API key`); + } + else if (context.n8nApiKey.toLowerCase().includes('example')) { + errors.push(`Invalid n8nApiKey: contains example text - Please provide actual API key`); + } + else { + errors.push(`Invalid n8nApiKey: format validation failed - Ensure key is valid`); + } + } + } + if (context.n8nApiTimeout !== undefined) { + if (typeof context.n8nApiTimeout !== 'number') { + errors.push(`Invalid n8nApiTimeout: ${context.n8nApiTimeout} - Must be a number, got ${typeof context.n8nApiTimeout}`); + } + else if (context.n8nApiTimeout <= 0) { + errors.push(`Invalid n8nApiTimeout: ${context.n8nApiTimeout} - Must be positive (greater than 0)`); + } + else if (!isFinite(context.n8nApiTimeout)) { + errors.push(`Invalid n8nApiTimeout: ${context.n8nApiTimeout} - Must be a finite number (not Infinity or NaN)`); + } + } + if (context.n8nApiMaxRetries !== undefined) { + if (typeof context.n8nApiMaxRetries !== 'number') { + errors.push(`Invalid n8nApiMaxRetries: ${context.n8nApiMaxRetries} - Must be a number, got ${typeof context.n8nApiMaxRetries}`); + } + else if (context.n8nApiMaxRetries < 0) { + errors.push(`Invalid n8nApiMaxRetries: ${context.n8nApiMaxRetries} - Must be non-negative (0 or greater)`); + } + else if (!isFinite(context.n8nApiMaxRetries)) { + errors.push(`Invalid n8nApiMaxRetries: ${context.n8nApiMaxRetries} - Must be a finite number (not Infinity or NaN)`); + } + } + return { + valid: errors.length === 0, + errors: errors.length > 0 ? errors : undefined + }; +} +//# sourceMappingURL=instance-context.js.map \ No newline at end of file diff --git a/dist/types/instance-context.js.map b/dist/types/instance-context.js.map new file mode 100644 index 0000000..a694a78 --- /dev/null +++ b/dist/types/instance-context.js.map @@ -0,0 +1 @@ +{"version":3,"file":"instance-context.js","sourceRoot":"","sources":["../../src/types/instance-context.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/types/n8n-api.d.ts b/dist/types/n8n-api.d.ts new file mode 100644 index 0000000..8978a7a --- /dev/null +++ b/dist/types/n8n-api.d.ts @@ -0,0 +1,336 @@ +export interface ResourceLocatorValue { + __rl: true; + value: string; + mode: 'id' | 'url' | 'expression' | string; +} +export type ExpressionValue = string | ResourceLocatorValue; +export interface WorkflowNode { + id: string; + name: string; + type: string; + typeVersion: number; + position: [number, number]; + parameters: Record; + credentials?: Record; + disabled?: boolean; + notes?: string; + notesInFlow?: boolean; + continueOnFail?: boolean; + onError?: 'continueRegularOutput' | 'continueErrorOutput' | 'stopWorkflow'; + retryOnFail?: boolean; + maxTries?: number; + waitBetweenTries?: number; + alwaysOutputData?: boolean; + executeOnce?: boolean; + webhookId?: string; +} +export interface WorkflowConnection { + [sourceNodeId: string]: { + [outputType: string]: Array>; + }; +} +export interface WorkflowSettings { + executionOrder?: 'v0' | 'v1'; + timezone?: string; + saveDataErrorExecution?: 'all' | 'none'; + saveDataSuccessExecution?: 'all' | 'none'; + saveManualExecutions?: boolean; + saveExecutionProgress?: boolean; + executionTimeout?: number; + errorWorkflow?: string; +} +export interface Workflow { + id?: string; + name: string; + description?: string; + nodes: WorkflowNode[]; + connections: WorkflowConnection; + active?: boolean; + isArchived?: boolean; + settings?: WorkflowSettings; + staticData?: Record; + tags?: string[]; + updatedAt?: string; + createdAt?: string; + versionId?: string; + versionCounter?: number; + meta?: { + instanceId?: string; + }; +} +export declare enum ExecutionStatus { + SUCCESS = "success", + ERROR = "error", + WAITING = "waiting" +} +export interface ExecutionSummary { + id: string; + finished: boolean; + mode: string; + retryOf?: string; + retrySuccessId?: string; + status: ExecutionStatus; + startedAt: string; + stoppedAt?: string; + workflowId: string; + workflowName?: string; + waitTill?: string; +} +export interface ExecutionData { + startData?: Record; + resultData: { + runData: Record; + lastNodeExecuted?: string; + error?: Record; + }; + executionData?: Record; +} +export interface Execution extends ExecutionSummary { + data?: ExecutionData; +} +export interface Credential { + id?: string; + name: string; + type: string; + data?: Record; + nodesAccess?: Array<{ + nodeType: string; + date?: string; + }>; + createdAt?: string; + updatedAt?: string; +} +export interface Tag { + id?: string; + name: string; + workflowIds?: string[]; + createdAt?: string; + updatedAt?: string; +} +export interface Variable { + id?: string; + key: string; + value: string; + type?: 'string'; +} +export interface WorkflowExport { + id: string; + name: string; + active: boolean; + createdAt: string; + updatedAt: string; + nodes: WorkflowNode[]; + connections: WorkflowConnection; + settings?: WorkflowSettings; + staticData?: Record; + tags?: string[]; + pinData?: Record; + versionId?: string; + versionCounter?: number; + meta?: Record; +} +export interface WorkflowImport { + name: string; + nodes: WorkflowNode[]; + connections: WorkflowConnection; + settings?: WorkflowSettings; + staticData?: Record; + tags?: string[]; + pinData?: Record; +} +export interface SourceControlStatus { + ahead: number; + behind: number; + conflicted: string[]; + created: string[]; + current: string; + deleted: string[]; + detached: boolean; + files: Array<{ + path: string; + status: string; + }>; + modified: string[]; + notAdded: string[]; + renamed: Array<{ + from: string; + to: string; + }>; + staged: string[]; + tracking: string; +} +export interface SourceControlPullResult { + conflicts: string[]; + files: Array<{ + path: string; + status: string; + }>; + mergeConflicts: boolean; + pullResult: 'success' | 'conflict' | 'error'; +} +export interface SourceControlPushResult { + ahead: number; + conflicts: string[]; + files: Array<{ + path: string; + status: string; + }>; + pushResult: 'success' | 'conflict' | 'error'; +} +export interface HealthCheckResponse { + status: 'ok' | 'error'; + instanceId?: string; + n8nVersion?: string; + features?: { + sourceControl?: boolean; + externalHooks?: boolean; + workers?: boolean; + [key: string]: boolean | undefined; + }; +} +export interface N8nVersionInfo { + version: string; + major: number; + minor: number; + patch: number; +} +export interface N8nSettingsData { + n8nVersion?: string; + versionCli?: string; + instanceId?: string; + [key: string]: unknown; +} +export interface N8nSettingsResponse { + data?: N8nSettingsData; +} +export interface WorkflowListParams { + limit?: number; + cursor?: string; + active?: boolean; + tags?: string | null; + projectId?: string; + excludePinnedData?: boolean; + instance?: string; +} +export interface WorkflowListResponse { + data: Workflow[]; + nextCursor?: string | null; +} +export interface ExecutionListParams { + limit?: number; + cursor?: string; + workflowId?: string; + projectId?: string; + status?: ExecutionStatus; + includeData?: boolean; +} +export interface ExecutionListResponse { + data: Execution[]; + nextCursor?: string | null; +} +export interface CredentialListParams { + limit?: number; + cursor?: string; + filter?: Record; +} +export interface CredentialListResponse { + data: Credential[]; + nextCursor?: string | null; +} +export interface TagListParams { + limit?: number; + cursor?: string; + withUsageCount?: boolean; +} +export interface TagListResponse { + data: Tag[]; + nextCursor?: string | null; +} +export interface WebhookRequest { + webhookUrl: string; + httpMethod: 'GET' | 'POST' | 'PUT' | 'DELETE'; + data?: Record; + headers?: Record; + waitForResponse?: boolean; +} +export interface McpToolResponse { + success: boolean; + data?: unknown; + error?: string; + message?: string; + code?: string; + details?: Record; + executionId?: string; + workflowId?: string; +} +export type ExecutionMode = 'preview' | 'summary' | 'filtered' | 'full'; +export interface ExecutionPreview { + totalNodes: number; + executedNodes: number; + estimatedSizeKB: number; + nodes: Record; +} +export interface NodePreview { + status: 'success' | 'error'; + itemCounts: { + input: number; + output: number; + }; + dataStructure: Record; + estimatedSizeKB: number; + error?: string; +} +export interface ExecutionRecommendation { + canFetchFull: boolean; + suggestedMode: ExecutionMode; + suggestedItemsLimit?: number; + reason: string; +} +export interface ExecutionFilterOptions { + mode?: ExecutionMode; + nodeNames?: string[]; + itemsLimit?: number; + includeInputData?: boolean; + fieldsToInclude?: string[]; +} +export interface FilteredExecutionResponse { + id: string; + workflowId: string; + status: ExecutionStatus; + mode: ExecutionMode; + startedAt: string; + stoppedAt?: string; + duration?: number; + finished: boolean; + preview?: ExecutionPreview; + recommendation?: ExecutionRecommendation; + summary?: { + totalNodes: number; + executedNodes: number; + totalItems: number; + hasMoreData: boolean; + }; + nodes?: Record; + error?: Record; +} +export interface FilteredNodeData { + executionTime?: number; + itemsInput: number; + itemsOutput: number; + status: 'success' | 'error'; + error?: string; + data?: { + input?: any[][]; + output?: any[][]; + metadata: { + totalItems: number; + itemsShown: number; + truncated: boolean; + }; + }; +} +//# sourceMappingURL=n8n-api.d.ts.map \ No newline at end of file diff --git a/dist/types/n8n-api.d.ts.map b/dist/types/n8n-api.d.ts.map new file mode 100644 index 0000000..8f68fd9 --- /dev/null +++ b/dist/types/n8n-api.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-api.d.ts","sourceRoot":"","sources":["../../src/types/n8n-api.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/types/n8n-api.js b/dist/types/n8n-api.js new file mode 100644 index 0000000..875ef4b --- /dev/null +++ b/dist/types/n8n-api.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ExecutionStatus = void 0; +var ExecutionStatus; +(function (ExecutionStatus) { + ExecutionStatus["SUCCESS"] = "success"; + ExecutionStatus["ERROR"] = "error"; + ExecutionStatus["WAITING"] = "waiting"; +})(ExecutionStatus || (exports.ExecutionStatus = ExecutionStatus = {})); +//# sourceMappingURL=n8n-api.js.map \ No newline at end of file diff --git a/dist/types/n8n-api.js.map b/dist/types/n8n-api.js.map new file mode 100644 index 0000000..95dc576 --- /dev/null +++ b/dist/types/n8n-api.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-api.js","sourceRoot":"","sources":["../../src/types/n8n-api.ts"],"names":[],"mappings":";;;AA6EA,IAAY,eAKX;AALD,WAAY,eAAe;IACzB,sCAAmB,CAAA;IACnB,kCAAe,CAAA;IACf,sCAAmB,CAAA;AAErB,CAAC,EALW,eAAe,+BAAf,eAAe,QAK1B"} \ No newline at end of file diff --git a/dist/types/node-types.d.ts b/dist/types/node-types.d.ts new file mode 100644 index 0000000..d081c38 --- /dev/null +++ b/dist/types/node-types.d.ts @@ -0,0 +1,19 @@ +import type { IVersionedNodeType, INodeType, INodeTypeBaseDescription, INodeTypeDescription } from 'n8n-workflow'; +export type NodeClass = (new () => INodeType) | (new () => IVersionedNodeType) | INodeType | IVersionedNodeType; +export interface VersionedNodeInstance extends IVersionedNodeType { + currentVersion: number; + description: INodeTypeBaseDescription; + nodeVersions: { + [version: number]: INodeType; + }; +} +export interface RegularNodeInstance extends INodeType { + description: INodeTypeDescription; +} +export type NodeInstance = VersionedNodeInstance | RegularNodeInstance; +export declare function isVersionedNodeInstance(node: any): node is VersionedNodeInstance; +export declare function isVersionedNodeClass(nodeClass: any): boolean; +export declare function instantiateNode(nodeClass: NodeClass): NodeInstance | null; +export declare function getNodeInstance(nodeClass: NodeClass): NodeInstance | undefined; +export declare function getNodeDescription(nodeClass: NodeClass): INodeTypeBaseDescription | INodeTypeDescription; +//# sourceMappingURL=node-types.d.ts.map \ No newline at end of file diff --git a/dist/types/node-types.d.ts.map b/dist/types/node-types.d.ts.map new file mode 100644 index 0000000..4d27f2b --- /dev/null +++ b/dist/types/node-types.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"node-types.d.ts","sourceRoot":"","sources":["../../src/types/node-types.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,kBAAkB,EAClB,SAAS,EACT,wBAAwB,EACxB,oBAAoB,EACrB,MAAM,cAAc,CAAC;AAUtB,MAAM,MAAM,SAAS,GACjB,CAAC,UAAU,SAAS,CAAC,GACrB,CAAC,UAAU,kBAAkB,CAAC,GAC9B,SAAS,GACT,kBAAkB,CAAC;AAoBvB,MAAM,WAAW,qBAAsB,SAAQ,kBAAkB;IAC/D,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,wBAAwB,CAAC;IACtC,YAAY,EAAE;QACZ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;KAC9B,CAAC;CACH;AAQD,MAAM,WAAW,mBAAoB,SAAQ,SAAS;IACpD,WAAW,EAAE,oBAAoB,CAAC;CACnC;AAOD,MAAM,MAAM,YAAY,GAAG,qBAAqB,GAAG,mBAAmB,CAAC;AAqBvE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,IAAI,qBAAqB,CAShF;AAkBD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAK5D;AAsBD,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,YAAY,GAAG,IAAI,CAWzE;AAUD,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,CAG9E;AAUD,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,SAAS,GACnB,wBAAwB,GAAG,oBAAoB,CAkCjD"} \ No newline at end of file diff --git a/dist/types/node-types.js b/dist/types/node-types.js new file mode 100644 index 0000000..484d785 --- /dev/null +++ b/dist/types/node-types.js @@ -0,0 +1,62 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isVersionedNodeInstance = isVersionedNodeInstance; +exports.isVersionedNodeClass = isVersionedNodeClass; +exports.instantiateNode = instantiateNode; +exports.getNodeInstance = getNodeInstance; +exports.getNodeDescription = getNodeDescription; +function isVersionedNodeInstance(node) { + return (node !== null && + typeof node === 'object' && + 'nodeVersions' in node && + 'currentVersion' in node && + 'description' in node && + typeof node.currentVersion === 'number'); +} +function isVersionedNodeClass(nodeClass) { + return (typeof nodeClass === 'function' && + nodeClass.prototype?.constructor?.name === 'VersionedNodeType'); +} +function instantiateNode(nodeClass) { + try { + if (typeof nodeClass === 'function') { + return new nodeClass(); + } + return nodeClass; + } + catch (e) { + return null; + } +} +function getNodeInstance(nodeClass) { + const instance = instantiateNode(nodeClass); + return instance ?? undefined; +} +function getNodeDescription(nodeClass) { + try { + const instance = instantiateNode(nodeClass); + if (instance) { + if (isVersionedNodeInstance(instance)) { + return instance.description; + } + return instance.description; + } + } + catch (e) { + } + if (typeof nodeClass === 'object' && 'description' in nodeClass) { + return nodeClass.description; + } + return { + displayName: '', + name: '', + group: [], + description: '', + version: 1, + defaults: { name: '', color: '' }, + inputs: [], + outputs: [], + properties: [] + }; +} +//# sourceMappingURL=node-types.js.map \ No newline at end of file diff --git a/dist/types/node-types.js.map b/dist/types/node-types.js.map new file mode 100644 index 0000000..c38a799 --- /dev/null +++ b/dist/types/node-types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"node-types.js","sourceRoot":"","sources":["../../src/types/node-types.ts"],"names":[],"mappings":";;AA+FA,0DASC;AAkBD,oDAKC;AAsBD,0CAWC;AAUD,0CAGC;AAUD,gDAoCC;AA5HD,SAAgB,uBAAuB,CAAC,IAAS;IAC/C,OAAO,CACL,IAAI,KAAK,IAAI;QACb,OAAO,IAAI,KAAK,QAAQ;QACxB,cAAc,IAAI,IAAI;QACtB,gBAAgB,IAAI,IAAI;QACxB,aAAa,IAAI,IAAI;QACrB,OAAO,IAAI,CAAC,cAAc,KAAK,QAAQ,CACxC,CAAC;AACJ,CAAC;AAkBD,SAAgB,oBAAoB,CAAC,SAAc;IACjD,OAAO,CACL,OAAO,SAAS,KAAK,UAAU;QAC/B,SAAS,CAAC,SAAS,EAAE,WAAW,EAAE,IAAI,KAAK,mBAAmB,CAC/D,CAAC;AACJ,CAAC;AAsBD,SAAgB,eAAe,CAAC,SAAoB;IAClD,IAAI,CAAC;QACH,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;YACpC,OAAO,IAAI,SAAS,EAAE,CAAC;QACzB,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QAEX,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAUD,SAAgB,eAAe,CAAC,SAAoB;IAClD,MAAM,QAAQ,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IAC5C,OAAO,QAAQ,IAAI,SAAS,CAAC;AAC/B,CAAC;AAUD,SAAgB,kBAAkB,CAChC,SAAoB;IAGpB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;QAE5C,IAAI,QAAQ,EAAE,CAAC;YAEb,IAAI,uBAAuB,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACtC,OAAO,QAAQ,CAAC,WAAW,CAAC;YAC9B,CAAC;YAED,OAAO,QAAQ,CAAC,WAAW,CAAC;QAC9B,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;IAEb,CAAC;IAGD,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,aAAa,IAAI,SAAS,EAAE,CAAC;QAChE,OAAO,SAAS,CAAC,WAAW,CAAC;IAC/B,CAAC;IAGD,OAAO;QACL,WAAW,EAAE,EAAE;QACf,IAAI,EAAE,EAAE;QACR,KAAK,EAAE,EAAE;QACT,WAAW,EAAE,EAAE;QACf,OAAO,EAAE,CAAC;QACV,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QACjC,MAAM,EAAE,EAAE;QACV,OAAO,EAAE,EAAE;QACX,UAAU,EAAE,EAAE;KACR,CAAC;AACX,CAAC"} \ No newline at end of file diff --git a/dist/types/session-state.d.ts b/dist/types/session-state.d.ts new file mode 100644 index 0000000..24506a2 --- /dev/null +++ b/dist/types/session-state.d.ts @@ -0,0 +1,15 @@ +export interface SessionState { + sessionId: string; + metadata: { + createdAt: string; + lastAccess: string; + }; + context: { + n8nApiUrl: string; + n8nApiKey: string; + instanceId?: string; + sessionId?: string; + metadata?: Record; + }; +} +//# sourceMappingURL=session-state.d.ts.map \ No newline at end of file diff --git a/dist/types/session-state.d.ts.map b/dist/types/session-state.d.ts.map new file mode 100644 index 0000000..3c4e51b --- /dev/null +++ b/dist/types/session-state.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"session-state.d.ts","sourceRoot":"","sources":["../../src/types/session-state.ts"],"names":[],"mappings":"AA2BA,MAAM,WAAW,YAAY;IAK3B,SAAS,EAAE,MAAM,CAAC;IAKlB,QAAQ,EAAE;QAKR,SAAS,EAAE,MAAM,CAAC;QAMlB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IAWF,OAAO,EAAE;QAKP,SAAS,EAAE,MAAM,CAAC;QAMlB,SAAS,EAAE,MAAM,CAAC;QAMlB,UAAU,CAAC,EAAE,MAAM,CAAC;QAMpB,SAAS,CAAC,EAAE,MAAM,CAAC;QAMnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KAChC,CAAC;CACH"} \ No newline at end of file diff --git a/dist/types/session-state.js b/dist/types/session-state.js new file mode 100644 index 0000000..95627e8 --- /dev/null +++ b/dist/types/session-state.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=session-state.js.map \ No newline at end of file diff --git a/dist/types/session-state.js.map b/dist/types/session-state.js.map new file mode 100644 index 0000000..e1cfeab --- /dev/null +++ b/dist/types/session-state.js.map @@ -0,0 +1 @@ +{"version":3,"file":"session-state.js","sourceRoot":"","sources":["../../src/types/session-state.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/types/type-structures.d.ts b/dist/types/type-structures.d.ts new file mode 100644 index 0000000..d1f419b --- /dev/null +++ b/dist/types/type-structures.d.ts @@ -0,0 +1,42 @@ +import type { NodePropertyTypes } from 'n8n-workflow'; +export interface TypeStructure { + type: 'primitive' | 'object' | 'array' | 'collection' | 'special'; + jsType: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'any'; + description: string; + structure?: { + properties?: Record; + items?: TypePropertyDefinition; + flexible?: boolean; + required?: string[]; + }; + example: any; + examples?: any[]; + validation?: { + allowEmpty?: boolean; + allowExpressions?: boolean; + min?: number; + max?: number; + pattern?: string; + customValidator?: string; + }; + introducedIn?: string; + deprecatedIn?: string; + replacedBy?: NodePropertyTypes; + notes?: string[]; +} +export interface TypePropertyDefinition { + type: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'any'; + description?: string; + required?: boolean; + properties?: Record; + items?: TypePropertyDefinition; + example?: any; + enum?: Array; + flexible?: boolean; +} +export type ComplexPropertyType = 'collection' | 'fixedCollection' | 'resourceLocator' | 'resourceMapper' | 'filter' | 'assignmentCollection'; +export type PrimitivePropertyType = 'string' | 'number' | 'boolean' | 'dateTime' | 'color' | 'json'; +export declare function isComplexType(type: NodePropertyTypes): type is ComplexPropertyType; +export declare function isPrimitiveType(type: NodePropertyTypes): type is PrimitivePropertyType; +export declare function isTypeStructure(value: any): value is TypeStructure; +//# sourceMappingURL=type-structures.d.ts.map \ No newline at end of file diff --git a/dist/types/type-structures.d.ts.map b/dist/types/type-structures.d.ts.map new file mode 100644 index 0000000..e8cd50b --- /dev/null +++ b/dist/types/type-structures.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"type-structures.d.ts","sourceRoot":"","sources":["../../src/types/type-structures.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAwBtD,MAAM,WAAW,aAAa;IAS7B,IAAI,EAAE,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,YAAY,GAAG,SAAS,CAAC;IAKlE,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC;IAKrE,WAAW,EAAE,MAAM,CAAC;IAMpB,SAAS,CAAC,EAAE;QAIX,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;QAKpD,KAAK,CAAC,EAAE,sBAAsB,CAAC;QAK/B,QAAQ,CAAC,EAAE,OAAO,CAAC;QAKnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;IAKF,OAAO,EAAE,GAAG,CAAC;IAKb,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC;IAKjB,UAAU,CAAC,EAAE;QAIZ,UAAU,CAAC,EAAE,OAAO,CAAC;QAKrB,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAK3B,GAAG,CAAC,EAAE,MAAM,CAAC;QAKb,GAAG,CAAC,EAAE,MAAM,CAAC;QAKb,OAAO,CAAC,EAAE,MAAM,CAAC;QAKjB,eAAe,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IAKF,YAAY,CAAC,EAAE,MAAM,CAAC;IAKtB,YAAY,CAAC,EAAE,MAAM,CAAC;IAKtB,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAK/B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAKD,MAAM,WAAW,sBAAsB;IAItC,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC;IAKnE,WAAW,CAAC,EAAE,MAAM,CAAC;IAKrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAKnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAKpD,KAAK,CAAC,EAAE,sBAAsB,CAAC;IAK/B,OAAO,CAAC,EAAE,GAAG,CAAC;IAKd,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IAKxC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAQD,MAAM,MAAM,mBAAmB,GAC5B,YAAY,GACZ,iBAAiB,GACjB,iBAAiB,GACjB,gBAAgB,GAChB,QAAQ,GACR,sBAAsB,CAAC;AAQ1B,MAAM,MAAM,qBAAqB,GAC9B,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,UAAU,GACV,OAAO,GACP,MAAM,CAAC;AAkBV,wBAAgB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,IAAI,mBAAmB,CASlF;AAkBD,wBAAgB,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,IAAI,qBAAqB,CAStF;AAgBD,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,IAAI,aAAa,CAWlE"} \ No newline at end of file diff --git a/dist/types/type-structures.js b/dist/types/type-structures.js new file mode 100644 index 0000000..25083e3 --- /dev/null +++ b/dist/types/type-structures.js @@ -0,0 +1,32 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isComplexType = isComplexType; +exports.isPrimitiveType = isPrimitiveType; +exports.isTypeStructure = isTypeStructure; +function isComplexType(type) { + return (type === 'collection' || + type === 'fixedCollection' || + type === 'resourceLocator' || + type === 'resourceMapper' || + type === 'filter' || + type === 'assignmentCollection'); +} +function isPrimitiveType(type) { + return (type === 'string' || + type === 'number' || + type === 'boolean' || + type === 'dateTime' || + type === 'color' || + type === 'json'); +} +function isTypeStructure(value) { + return (value !== null && + typeof value === 'object' && + 'type' in value && + 'jsType' in value && + 'description' in value && + 'example' in value && + ['primitive', 'object', 'array', 'collection', 'special'].includes(value.type) && + ['string', 'number', 'boolean', 'object', 'array', 'any'].includes(value.jsType)); +} +//# sourceMappingURL=type-structures.js.map \ No newline at end of file diff --git a/dist/types/type-structures.js.map b/dist/types/type-structures.js.map new file mode 100644 index 0000000..56866a8 --- /dev/null +++ b/dist/types/type-structures.js.map @@ -0,0 +1 @@ +{"version":3,"file":"type-structures.js","sourceRoot":"","sources":["../../src/types/type-structures.ts"],"names":[],"mappings":";;AA6OA,sCASC;AAkBD,0CASC;AAgBD,0CAWC;AA/DD,SAAgB,aAAa,CAAC,IAAuB;IACpD,OAAO,CACN,IAAI,KAAK,YAAY;QACrB,IAAI,KAAK,iBAAiB;QAC1B,IAAI,KAAK,iBAAiB;QAC1B,IAAI,KAAK,gBAAgB;QACzB,IAAI,KAAK,QAAQ;QACjB,IAAI,KAAK,sBAAsB,CAC/B,CAAC;AACH,CAAC;AAkBD,SAAgB,eAAe,CAAC,IAAuB;IACtD,OAAO,CACN,IAAI,KAAK,QAAQ;QACjB,IAAI,KAAK,QAAQ;QACjB,IAAI,KAAK,SAAS;QAClB,IAAI,KAAK,UAAU;QACnB,IAAI,KAAK,OAAO;QAChB,IAAI,KAAK,MAAM,CACf,CAAC;AACH,CAAC;AAgBD,SAAgB,eAAe,CAAC,KAAU;IACzC,OAAO,CACN,KAAK,KAAK,IAAI;QACd,OAAO,KAAK,KAAK,QAAQ;QACzB,MAAM,IAAI,KAAK;QACf,QAAQ,IAAI,KAAK;QACjB,aAAa,IAAI,KAAK;QACtB,SAAS,IAAI,KAAK;QAClB,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;QAC9E,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAChF,CAAC;AACH,CAAC"} \ No newline at end of file diff --git a/dist/types/workflow-diff.d.ts b/dist/types/workflow-diff.d.ts new file mode 100644 index 0000000..31f5a1c --- /dev/null +++ b/dist/types/workflow-diff.d.ts @@ -0,0 +1,148 @@ +import { WorkflowNode } from './n8n-api'; +export interface DiffOperation { + type: string; + description?: string; +} +export interface AddNodeOperation extends DiffOperation { + type: 'addNode'; + node: Partial & { + name: string; + type: string; + position: [number, number]; + }; +} +export interface RemoveNodeOperation extends DiffOperation { + type: 'removeNode'; + nodeId?: string; + nodeName?: string; +} +export interface UpdateNodeOperation extends DiffOperation { + type: 'updateNode'; + nodeId?: string; + nodeName?: string; + updates: { + [path: string]: any; + }; +} +export interface MoveNodeOperation extends DiffOperation { + type: 'moveNode'; + nodeId?: string; + nodeName?: string; + position: [number, number]; +} +export interface EnableNodeOperation extends DiffOperation { + type: 'enableNode'; + nodeId?: string; + nodeName?: string; +} +export interface DisableNodeOperation extends DiffOperation { + type: 'disableNode'; + nodeId?: string; + nodeName?: string; +} +export interface AddConnectionOperation extends DiffOperation { + type: 'addConnection'; + source: string; + target: string; + sourceOutput?: string; + targetInput?: string; + sourceIndex?: number; + targetIndex?: number; + branch?: 'true' | 'false'; + case?: number; +} +export interface RemoveConnectionOperation extends DiffOperation { + type: 'removeConnection'; + source: string; + target: string; + sourceOutput?: string; + targetInput?: string; + ignoreErrors?: boolean; +} +export interface RewireConnectionOperation extends DiffOperation { + type: 'rewireConnection'; + source: string; + from: string; + to: string; + sourceOutput?: string; + targetInput?: string; + sourceIndex?: number; + branch?: 'true' | 'false'; + case?: number; +} +export interface UpdateSettingsOperation extends DiffOperation { + type: 'updateSettings'; + settings: { + [key: string]: any; + }; +} +export interface UpdateNameOperation extends DiffOperation { + type: 'updateName'; + name: string; +} +export interface AddTagOperation extends DiffOperation { + type: 'addTag'; + tag: string; +} +export interface RemoveTagOperation extends DiffOperation { + type: 'removeTag'; + tag: string; +} +export interface ActivateWorkflowOperation extends DiffOperation { + type: 'activateWorkflow'; +} +export interface DeactivateWorkflowOperation extends DiffOperation { + type: 'deactivateWorkflow'; +} +export interface CleanStaleConnectionsOperation extends DiffOperation { + type: 'cleanStaleConnections'; + dryRun?: boolean; +} +export interface ReplaceConnectionsOperation extends DiffOperation { + type: 'replaceConnections'; + connections: { + [nodeName: string]: { + [outputName: string]: Array>; + }; + }; +} +export type WorkflowDiffOperation = AddNodeOperation | RemoveNodeOperation | UpdateNodeOperation | MoveNodeOperation | EnableNodeOperation | DisableNodeOperation | AddConnectionOperation | RemoveConnectionOperation | RewireConnectionOperation | UpdateSettingsOperation | UpdateNameOperation | AddTagOperation | RemoveTagOperation | ActivateWorkflowOperation | DeactivateWorkflowOperation | CleanStaleConnectionsOperation | ReplaceConnectionsOperation; +export interface WorkflowDiffRequest { + id: string; + operations: WorkflowDiffOperation[]; + validateOnly?: boolean; + continueOnError?: boolean; +} +export interface WorkflowDiffValidationError { + operation: number; + message: string; + details?: any; +} +export interface WorkflowDiffResult { + success: boolean; + workflow?: any; + errors?: WorkflowDiffValidationError[]; + warnings?: WorkflowDiffValidationError[]; + operationsApplied?: number; + message?: string; + applied?: number[]; + failed?: number[]; + staleConnectionsRemoved?: Array<{ + from: string; + to: string; + }>; + shouldActivate?: boolean; + shouldDeactivate?: boolean; +} +export interface NodeReference { + id?: string; + name?: string; +} +export declare function isNodeOperation(op: WorkflowDiffOperation): op is AddNodeOperation | RemoveNodeOperation | UpdateNodeOperation | MoveNodeOperation | EnableNodeOperation | DisableNodeOperation; +export declare function isConnectionOperation(op: WorkflowDiffOperation): op is AddConnectionOperation | RemoveConnectionOperation | RewireConnectionOperation | CleanStaleConnectionsOperation | ReplaceConnectionsOperation; +export declare function isMetadataOperation(op: WorkflowDiffOperation): op is UpdateSettingsOperation | UpdateNameOperation | AddTagOperation | RemoveTagOperation; +//# sourceMappingURL=workflow-diff.d.ts.map \ No newline at end of file diff --git a/dist/types/workflow-diff.d.ts.map b/dist/types/workflow-diff.d.ts.map new file mode 100644 index 0000000..f70843a --- /dev/null +++ b/dist/types/workflow-diff.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"workflow-diff.d.ts","sourceRoot":"","sources":["../../src/types/workflow-diff.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/types/workflow-diff.js b/dist/types/workflow-diff.js new file mode 100644 index 0000000..59416f5 --- /dev/null +++ b/dist/types/workflow-diff.js @@ -0,0 +1,15 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isNodeOperation = isNodeOperation; +exports.isConnectionOperation = isConnectionOperation; +exports.isMetadataOperation = isMetadataOperation; +function isNodeOperation(op) { + return ['addNode', 'removeNode', 'updateNode', 'moveNode', 'enableNode', 'disableNode'].includes(op.type); +} +function isConnectionOperation(op) { + return ['addConnection', 'removeConnection', 'rewireConnection', 'cleanStaleConnections', 'replaceConnections'].includes(op.type); +} +function isMetadataOperation(op) { + return ['updateSettings', 'updateName', 'addTag', 'removeTag'].includes(op.type); +} +//# sourceMappingURL=workflow-diff.js.map \ No newline at end of file diff --git a/dist/types/workflow-diff.js.map b/dist/types/workflow-diff.js.map new file mode 100644 index 0000000..f127d99 --- /dev/null +++ b/dist/types/workflow-diff.js.map @@ -0,0 +1 @@ +{"version":3,"file":"workflow-diff.js","sourceRoot":"","sources":["../../src/types/workflow-diff.ts"],"names":[],"mappings":";;AAyMA,0CAIC;AAED,sDAGC;AAED,kDAGC;AAdD,SAAgB,eAAe,CAAC,EAAyB;IAGvD,OAAO,CAAC,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;AAC5G,CAAC;AAED,SAAgB,qBAAqB,CAAC,EAAyB;IAE7D,OAAO,CAAC,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,oBAAoB,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;AACpI,CAAC;AAED,SAAgB,mBAAmB,CAAC,EAAyB;IAE3D,OAAO,CAAC,gBAAgB,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;AACnF,CAAC"} \ No newline at end of file diff --git a/dist/utils/auth.d.ts b/dist/utils/auth.d.ts new file mode 100644 index 0000000..f63b3d9 --- /dev/null +++ b/dist/utils/auth.d.ts @@ -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 \ No newline at end of file diff --git a/dist/utils/auth.d.ts.map b/dist/utils/auth.d.ts.map new file mode 100644 index 0000000..15c0a06 --- /dev/null +++ b/dist/utils/auth.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/auth.js b/dist/utils/auth.js new file mode 100644 index 0000000..9ff4383 --- /dev/null +++ b/dist/utils/auth.js @@ -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 \ No newline at end of file diff --git a/dist/utils/auth.js.map b/dist/utils/auth.js.map new file mode 100644 index 0000000..f18f824 --- /dev/null +++ b/dist/utils/auth.js.map @@ -0,0 +1 @@ +{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/bridge.d.ts b/dist/utils/bridge.d.ts new file mode 100644 index 0000000..65c5ffb --- /dev/null +++ b/dist/utils/bridge.d.ts @@ -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 \ No newline at end of file diff --git a/dist/utils/bridge.d.ts.map b/dist/utils/bridge.d.ts.map new file mode 100644 index 0000000..ae65d74 --- /dev/null +++ b/dist/utils/bridge.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/bridge.js b/dist/utils/bridge.js new file mode 100644 index 0000000..b66daf7 --- /dev/null +++ b/dist/utils/bridge.js @@ -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 \ No newline at end of file diff --git a/dist/utils/bridge.js.map b/dist/utils/bridge.js.map new file mode 100644 index 0000000..5481990 --- /dev/null +++ b/dist/utils/bridge.js.map @@ -0,0 +1 @@ +{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../src/utils/bridge.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/cache-utils.d.ts b/dist/utils/cache-utils.d.ts new file mode 100644 index 0000000..87f4ff1 --- /dev/null +++ b/dist/utils/cache-utils.d.ts @@ -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(onDispose?: (value: T, key: string) => void): LRUCache; +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(fn: () => Promise, config?: RetryConfig, context?: string): Promise; +export declare function getCacheStatistics(): string; +export {}; +//# sourceMappingURL=cache-utils.d.ts.map \ No newline at end of file diff --git a/dist/utils/cache-utils.d.ts.map b/dist/utils/cache-utils.d.ts.map new file mode 100644 index 0000000..acb5ed8 --- /dev/null +++ b/dist/utils/cache-utils.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/cache-utils.js b/dist/utils/cache-utils.js new file mode 100644 index 0000000..3d700d1 --- /dev/null +++ b/dist/utils/cache-utils.js @@ -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 \ No newline at end of file diff --git a/dist/utils/cache-utils.js.map b/dist/utils/cache-utils.js.map new file mode 100644 index 0000000..545ee06 --- /dev/null +++ b/dist/utils/cache-utils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"cache-utils.js","sourceRoot":"","sources":["../../src/utils/cache-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/console-manager.d.ts b/dist/utils/console-manager.d.ts new file mode 100644 index 0000000..6e15df2 --- /dev/null +++ b/dist/utils/console-manager.d.ts @@ -0,0 +1,10 @@ +export declare class ConsoleManager { + private originalConsole; + private isSilenced; + silence(): void; + restore(): void; + wrapOperation(operation: () => T | Promise): Promise; + get isActive(): boolean; +} +export declare const consoleManager: ConsoleManager; +//# sourceMappingURL=console-manager.d.ts.map \ No newline at end of file diff --git a/dist/utils/console-manager.d.ts.map b/dist/utils/console-manager.d.ts.map new file mode 100644 index 0000000..a85b0d9 --- /dev/null +++ b/dist/utils/console-manager.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/console-manager.js b/dist/utils/console-manager.js new file mode 100644 index 0000000..b0ea250 --- /dev/null +++ b/dist/utils/console-manager.js @@ -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 \ No newline at end of file diff --git a/dist/utils/console-manager.js.map b/dist/utils/console-manager.js.map new file mode 100644 index 0000000..da49c09 --- /dev/null +++ b/dist/utils/console-manager.js.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/documentation-fetcher.d.ts b/dist/utils/documentation-fetcher.d.ts new file mode 100644 index 0000000..bc1bd90 --- /dev/null +++ b/dist/utils/documentation-fetcher.d.ts @@ -0,0 +1,2 @@ +export * from './enhanced-documentation-fetcher'; +//# sourceMappingURL=documentation-fetcher.d.ts.map \ No newline at end of file diff --git a/dist/utils/documentation-fetcher.d.ts.map b/dist/utils/documentation-fetcher.d.ts.map new file mode 100644 index 0000000..490ad11 --- /dev/null +++ b/dist/utils/documentation-fetcher.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"documentation-fetcher.d.ts","sourceRoot":"","sources":["../../src/utils/documentation-fetcher.ts"],"names":[],"mappings":"AACA,cAAc,kCAAkC,CAAC"} \ No newline at end of file diff --git a/dist/utils/documentation-fetcher.js b/dist/utils/documentation-fetcher.js new file mode 100644 index 0000000..94f3e46 --- /dev/null +++ b/dist/utils/documentation-fetcher.js @@ -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 \ No newline at end of file diff --git a/dist/utils/documentation-fetcher.js.map b/dist/utils/documentation-fetcher.js.map new file mode 100644 index 0000000..6e3aa3e --- /dev/null +++ b/dist/utils/documentation-fetcher.js.map @@ -0,0 +1 @@ +{"version":3,"file":"documentation-fetcher.js","sourceRoot":"","sources":["../../src/utils/documentation-fetcher.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,mEAAiD"} \ No newline at end of file diff --git a/dist/utils/enhanced-documentation-fetcher.d.ts b/dist/utils/enhanced-documentation-fetcher.d.ts new file mode 100644 index 0000000..bd4166f --- /dev/null +++ b/dist/utils/enhanced-documentation-fetcher.d.ts @@ -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; + getEnhancedNodeDocumentation(nodeType: string): Promise; + 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; +} +//# sourceMappingURL=enhanced-documentation-fetcher.d.ts.map \ No newline at end of file diff --git a/dist/utils/enhanced-documentation-fetcher.d.ts.map b/dist/utils/enhanced-documentation-fetcher.d.ts.map new file mode 100644 index 0000000..ee3465a --- /dev/null +++ b/dist/utils/enhanced-documentation-fetcher.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/enhanced-documentation-fetcher.js b/dist/utils/enhanced-documentation-fetcher.js new file mode 100644 index 0000000..1dd3478 --- /dev/null +++ b/dist/utils/enhanced-documentation-fetcher.js @@ -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 \ No newline at end of file diff --git a/dist/utils/enhanced-documentation-fetcher.js.map b/dist/utils/enhanced-documentation-fetcher.js.map new file mode 100644 index 0000000..3138d89 --- /dev/null +++ b/dist/utils/enhanced-documentation-fetcher.js.map @@ -0,0 +1 @@ +{"version":3,"file":"enhanced-documentation-fetcher.js","sourceRoot":"","sources":["../../src/utils/enhanced-documentation-fetcher.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/error-handler.d.ts b/dist/utils/error-handler.d.ts new file mode 100644 index 0000000..0f85c78 --- /dev/null +++ b/dist/utils/error-handler.d.ts @@ -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(operation: () => Promise, context: string): Promise; +//# sourceMappingURL=error-handler.d.ts.map \ No newline at end of file diff --git a/dist/utils/error-handler.d.ts.map b/dist/utils/error-handler.d.ts.map new file mode 100644 index 0000000..de6d272 --- /dev/null +++ b/dist/utils/error-handler.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/error-handler.js b/dist/utils/error-handler.js new file mode 100644 index 0000000..5e24094 --- /dev/null +++ b/dist/utils/error-handler.js @@ -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 \ No newline at end of file diff --git a/dist/utils/error-handler.js.map b/dist/utils/error-handler.js.map new file mode 100644 index 0000000..90f2015 --- /dev/null +++ b/dist/utils/error-handler.js.map @@ -0,0 +1 @@ +{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/utils/error-handler.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/example-generator.d.ts b/dist/utils/example-generator.d.ts new file mode 100644 index 0000000..8beadeb --- /dev/null +++ b/dist/utils/example-generator.d.ts @@ -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 \ No newline at end of file diff --git a/dist/utils/example-generator.d.ts.map b/dist/utils/example-generator.d.ts.map new file mode 100644 index 0000000..0fe7c79 --- /dev/null +++ b/dist/utils/example-generator.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/example-generator.js b/dist/utils/example-generator.js new file mode 100644 index 0000000..c7f4a84 --- /dev/null +++ b/dist/utils/example-generator.js @@ -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 \ No newline at end of file diff --git a/dist/utils/example-generator.js.map b/dist/utils/example-generator.js.map new file mode 100644 index 0000000..ca9b13d --- /dev/null +++ b/dist/utils/example-generator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"example-generator.js","sourceRoot":"","sources":["../../src/utils/example-generator.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/expression-utils.d.ts b/dist/utils/expression-utils.d.ts new file mode 100644 index 0000000..af7f645 --- /dev/null +++ b/dist/utils/expression-utils.d.ts @@ -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 \ No newline at end of file diff --git a/dist/utils/expression-utils.d.ts.map b/dist/utils/expression-utils.d.ts.map new file mode 100644 index 0000000..3db7780 --- /dev/null +++ b/dist/utils/expression-utils.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/expression-utils.js b/dist/utils/expression-utils.js new file mode 100644 index 0000000..09c405e --- /dev/null +++ b/dist/utils/expression-utils.js @@ -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 \ No newline at end of file diff --git a/dist/utils/expression-utils.js.map b/dist/utils/expression-utils.js.map new file mode 100644 index 0000000..cc0c42f --- /dev/null +++ b/dist/utils/expression-utils.js.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/fixed-collection-validator.d.ts b/dist/utils/fixed-collection-validator.d.ts new file mode 100644 index 0000000..416b84a --- /dev/null +++ b/dist/utils/fixed-collection-validator.d.ts @@ -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 \ No newline at end of file diff --git a/dist/utils/fixed-collection-validator.d.ts.map b/dist/utils/fixed-collection-validator.d.ts.map new file mode 100644 index 0000000..5057f28 --- /dev/null +++ b/dist/utils/fixed-collection-validator.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/fixed-collection-validator.js b/dist/utils/fixed-collection-validator.js new file mode 100644 index 0000000..19e4cf3 --- /dev/null +++ b/dist/utils/fixed-collection-validator.js @@ -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 \ No newline at end of file diff --git a/dist/utils/fixed-collection-validator.js.map b/dist/utils/fixed-collection-validator.js.map new file mode 100644 index 0000000..11f2d3d --- /dev/null +++ b/dist/utils/fixed-collection-validator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"fixed-collection-validator.js","sourceRoot":"","sources":["../../src/utils/fixed-collection-validator.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/logger.d.ts b/dist/utils/logger.d.ts new file mode 100644 index 0000000..64ac541 --- /dev/null +++ b/dist/utils/logger.d.ts @@ -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); + static getInstance(config?: Partial): 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 \ No newline at end of file diff --git a/dist/utils/logger.d.ts.map b/dist/utils/logger.d.ts.map new file mode 100644 index 0000000..a520959 --- /dev/null +++ b/dist/utils/logger.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/logger.js b/dist/utils/logger.js new file mode 100644 index 0000000..8337dd1 --- /dev/null +++ b/dist/utils/logger.js @@ -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 \ No newline at end of file diff --git a/dist/utils/logger.js.map b/dist/utils/logger.js.map new file mode 100644 index 0000000..efccfdc --- /dev/null +++ b/dist/utils/logger.js.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/mcp-client.d.ts b/dist/utils/mcp-client.d.ts new file mode 100644 index 0000000..53404ea --- /dev/null +++ b/dist/utils/mcp-client.d.ts @@ -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; + disconnect(): Promise; + listTools(): Promise; + callTool(name: string, args: any): Promise; + listResources(): Promise; + readResource(uri: string): Promise; + listPrompts(): Promise; + getPrompt(name: string, args?: any): Promise; + private ensureConnected; +} +//# sourceMappingURL=mcp-client.d.ts.map \ No newline at end of file diff --git a/dist/utils/mcp-client.d.ts.map b/dist/utils/mcp-client.d.ts.map new file mode 100644 index 0000000..abf5d76 --- /dev/null +++ b/dist/utils/mcp-client.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/mcp-client.js b/dist/utils/mcp-client.js new file mode 100644 index 0000000..fe4fbce --- /dev/null +++ b/dist/utils/mcp-client.js @@ -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 \ No newline at end of file diff --git a/dist/utils/mcp-client.js.map b/dist/utils/mcp-client.js.map new file mode 100644 index 0000000..c84be49 --- /dev/null +++ b/dist/utils/mcp-client.js.map @@ -0,0 +1 @@ +{"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../../src/utils/mcp-client.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/n8n-errors.d.ts b/dist/utils/n8n-errors.d.ts new file mode 100644 index 0000000..df9d90c --- /dev/null +++ b/dist/utils/n8n-errors.d.ts @@ -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 \ No newline at end of file diff --git a/dist/utils/n8n-errors.d.ts.map b/dist/utils/n8n-errors.d.ts.map new file mode 100644 index 0000000..72a4bcb --- /dev/null +++ b/dist/utils/n8n-errors.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/n8n-errors.js b/dist/utils/n8n-errors.js new file mode 100644 index 0000000..85cb82b --- /dev/null +++ b/dist/utils/n8n-errors.js @@ -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 \ No newline at end of file diff --git a/dist/utils/n8n-errors.js.map b/dist/utils/n8n-errors.js.map new file mode 100644 index 0000000..5c1da9a --- /dev/null +++ b/dist/utils/n8n-errors.js.map @@ -0,0 +1 @@ +{"version":3,"file":"n8n-errors.js","sourceRoot":"","sources":["../../src/utils/n8n-errors.ts"],"names":[],"mappings":";;;AAwDA,8CAuCC;AAQD,oDAGC;AAMD,wDAEC;AAGD,kEAmBC;AAGD,kCAiBC;AA5JD,qCAAkC;AAIlC,MAAa,WAAY,SAAQ,KAAK;IACpC,YACE,OAAe,EACR,UAAmB,EACnB,IAAa,EACb,OAAiB;QAExB,KAAK,CAAC,OAAO,CAAC,CAAC;QAJR,eAAU,GAAV,UAAU,CAAS;QACnB,SAAI,GAAJ,IAAI,CAAS;QACb,YAAO,GAAP,OAAO,CAAU;QAGxB,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAVD,kCAUC;AAED,MAAa,sBAAuB,SAAQ,WAAW;IACrD,YAAY,OAAO,GAAG,uBAAuB;QAC3C,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,sBAAsB,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AALD,wDAKC;AAED,MAAa,gBAAiB,SAAQ,WAAW;IAC/C,YAAY,QAAgB,EAAE,EAAW;QACvC,MAAM,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,QAAQ,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,QAAQ,YAAY,CAAC;QACrF,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAND,4CAMC;AAED,MAAa,kBAAmB,SAAQ,WAAW;IACjD,YAAY,OAAe,EAAE,OAAiB;QAC5C,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,kBAAkB,EAAE,OAAO,CAAC,CAAC;QACjD,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AALD,gDAKC;AAED,MAAa,iBAAkB,SAAQ,WAAW;IAChD,YAAY,UAAmB;QAC7B,MAAM,OAAO,GAAG,UAAU;YACxB,CAAC,CAAC,oCAAoC,UAAU,UAAU;YAC1D,CAAC,CAAC,qBAAqB,CAAC;QAC1B,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,kBAAkB,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AARD,8CAQC;AAED,MAAa,cAAe,SAAQ,WAAW;IAC7C,YAAY,OAAO,GAAG,uBAAuB,EAAE,UAAU,GAAG,GAAG;QAC7D,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AALD,wCAKC;AAGD,SAAgB,iBAAiB,CAAC,KAAc;IAC9C,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAE3B,MAAM,UAAU,GAAG,KAAY,CAAC;QAChC,IAAI,UAAU,CAAC,QAAQ,EAAE,CAAC;YACxB,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,QAAQ,CAAC;YAC7C,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC;YAEpD,QAAQ,MAAM,EAAE,CAAC;gBACf,KAAK,GAAG;oBACN,OAAO,IAAI,sBAAsB,CAAC,OAAO,CAAC,CAAC;gBAC7C,KAAK,GAAG;oBACN,OAAO,IAAI,gBAAgB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBACnD,KAAK,GAAG;oBACN,OAAO,IAAI,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;gBAC/C,KAAK,GAAG;oBACN,MAAM,UAAU,GAAG,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;oBAC9D,OAAO,IAAI,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;gBAC9E;oBACE,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;wBAClB,OAAO,IAAI,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;oBAC7C,CAAC;oBACD,OAAO,IAAI,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC;aAAM,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;YAE9B,OAAO,IAAI,WAAW,CAAC,6BAA6B,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;QAClF,CAAC;aAAM,CAAC;YAEN,OAAO,IAAI,WAAW,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IAGD,OAAO,IAAI,WAAW,CAAC,wBAAwB,EAAE,SAAS,EAAE,eAAe,EAAE,KAAK,CAAC,CAAC;AACtF,CAAC;AAQD,SAAgB,oBAAoB,CAAC,WAAmB,EAAE,UAAmB;IAC3E,MAAM,cAAc,GAAG,UAAU,CAAC,CAAC,CAAC,YAAY,UAAU,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC;IACvF,OAAO,GAAG,cAAc,GAAG,WAAW,wCAAwC,WAAW,gDAAgD,CAAC;AAC5I,CAAC;AAMD,SAAgB,sBAAsB;IACpC,OAAO,2IAA2I,CAAC;AACrJ,CAAC;AAGD,SAAgB,2BAA2B,CAAC,KAAkB;IAC5D,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,sBAAsB;YACzB,OAAO,6DAA6D,CAAC;QACvE,KAAK,WAAW;YACd,OAAO,KAAK,CAAC,OAAO,CAAC;QACvB,KAAK,kBAAkB;YACrB,OAAO,oBAAoB,KAAK,CAAC,OAAO,EAAE,CAAC;QAC7C,KAAK,kBAAkB;YACrB,OAAO,wDAAwD,CAAC;QAClE,KAAK,aAAa;YAChB,OAAO,kFAAkF,CAAC;QAC5F,KAAK,cAAc;YAGjB,OAAO,KAAK,CAAC,OAAO,IAAI,2BAA2B,CAAC;QACtD;YACE,OAAO,KAAK,CAAC,OAAO,IAAI,8BAA8B,CAAC;IAC3D,CAAC;AACH,CAAC;AAGD,SAAgB,WAAW,CAAC,KAAkB,EAAE,OAAgB;IAC9D,MAAM,SAAS,GAAG;QAChB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,OAAO;KACR,CAAC;IAEF,IAAI,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,IAAI,GAAG,EAAE,CAAC;QAChD,eAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE,SAAS,CAAC,CAAC;IAClD,CAAC;SAAM,IAAI,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,IAAI,GAAG,EAAE,CAAC;QACvD,eAAM,CAAC,IAAI,CAAC,sBAAsB,EAAE,SAAS,CAAC,CAAC;IACjD,CAAC;SAAM,CAAC;QACN,eAAM,CAAC,KAAK,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC"} \ No newline at end of file diff --git a/dist/utils/node-classification.d.ts b/dist/utils/node-classification.d.ts new file mode 100644 index 0000000..5dc2e2f --- /dev/null +++ b/dist/utils/node-classification.d.ts @@ -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 \ No newline at end of file diff --git a/dist/utils/node-classification.d.ts.map b/dist/utils/node-classification.d.ts.map new file mode 100644 index 0000000..72f3364 --- /dev/null +++ b/dist/utils/node-classification.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/node-classification.js b/dist/utils/node-classification.js new file mode 100644 index 0000000..7e53e9e --- /dev/null +++ b/dist/utils/node-classification.js @@ -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 \ No newline at end of file diff --git a/dist/utils/node-classification.js.map b/dist/utils/node-classification.js.map new file mode 100644 index 0000000..acd73eb --- /dev/null +++ b/dist/utils/node-classification.js.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/node-source-extractor.d.ts b/dist/utils/node-source-extractor.d.ts new file mode 100644 index 0000000..a5dd72a --- /dev/null +++ b/dist/utils/node-source-extractor.d.ts @@ -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; + private parseNodeType; + private searchNodeInPath; + private searchInPnpm; + private searchWithGlobPattern; + private tryLoadNodeFile; + listAvailableNodes(category?: string, search?: string): Promise; + private scanDirectoryForNodes; + private scanPnpmDirectory; + extractAIAgentNode(): Promise; +} +//# sourceMappingURL=node-source-extractor.d.ts.map \ No newline at end of file diff --git a/dist/utils/node-source-extractor.d.ts.map b/dist/utils/node-source-extractor.d.ts.map new file mode 100644 index 0000000..5293d43 --- /dev/null +++ b/dist/utils/node-source-extractor.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/node-source-extractor.js b/dist/utils/node-source-extractor.js new file mode 100644 index 0000000..81e185b --- /dev/null +++ b/dist/utils/node-source-extractor.js @@ -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 \ No newline at end of file diff --git a/dist/utils/node-source-extractor.js.map b/dist/utils/node-source-extractor.js.map new file mode 100644 index 0000000..6960d45 --- /dev/null +++ b/dist/utils/node-source-extractor.js.map @@ -0,0 +1 @@ +{"version":3,"file":"node-source-extractor.js","sourceRoot":"","sources":["../../src/utils/node-source-extractor.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/node-type-normalizer.d.ts b/dist/utils/node-type-normalizer.d.ts new file mode 100644 index 0000000..29d3ecc --- /dev/null +++ b/dist/utils/node-type-normalizer.d.ts @@ -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; + static normalizeWorkflowNodeTypes(workflow: any): any; + static isFullForm(type: string): boolean; + static isShortForm(type: string): boolean; +} +//# sourceMappingURL=node-type-normalizer.d.ts.map \ No newline at end of file diff --git a/dist/utils/node-type-normalizer.d.ts.map b/dist/utils/node-type-normalizer.d.ts.map new file mode 100644 index 0000000..1c12031 --- /dev/null +++ b/dist/utils/node-type-normalizer.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/node-type-normalizer.js b/dist/utils/node-type-normalizer.js new file mode 100644 index 0000000..9be209b --- /dev/null +++ b/dist/utils/node-type-normalizer.js @@ -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 \ No newline at end of file diff --git a/dist/utils/node-type-normalizer.js.map b/dist/utils/node-type-normalizer.js.map new file mode 100644 index 0000000..2e37809 --- /dev/null +++ b/dist/utils/node-type-normalizer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"node-type-normalizer.js","sourceRoot":"","sources":["../../src/utils/node-type-normalizer.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/node-type-utils.d.ts b/dist/utils/node-type-utils.d.ts new file mode 100644 index 0000000..43bdcb4 --- /dev/null +++ b/dist/utils/node-type-utils.d.ts @@ -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 \ No newline at end of file diff --git a/dist/utils/node-type-utils.d.ts.map b/dist/utils/node-type-utils.d.ts.map new file mode 100644 index 0000000..a9b3de7 --- /dev/null +++ b/dist/utils/node-type-utils.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/node-type-utils.js b/dist/utils/node-type-utils.js new file mode 100644 index 0000000..7ba64c6 --- /dev/null +++ b/dist/utils/node-type-utils.js @@ -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 \ No newline at end of file diff --git a/dist/utils/node-type-utils.js.map b/dist/utils/node-type-utils.js.map new file mode 100644 index 0000000..d7c1ed7 --- /dev/null +++ b/dist/utils/node-type-utils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"node-type-utils.js","sourceRoot":"","sources":["../../src/utils/node-type-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/node-utils.d.ts b/dist/utils/node-utils.d.ts new file mode 100644 index 0000000..32ca483 --- /dev/null +++ b/dist/utils/node-utils.d.ts @@ -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 \ No newline at end of file diff --git a/dist/utils/node-utils.d.ts.map b/dist/utils/node-utils.d.ts.map new file mode 100644 index 0000000..cb780bf --- /dev/null +++ b/dist/utils/node-utils.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/node-utils.js b/dist/utils/node-utils.js new file mode 100644 index 0000000..436deab --- /dev/null +++ b/dist/utils/node-utils.js @@ -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 \ No newline at end of file diff --git a/dist/utils/node-utils.js.map b/dist/utils/node-utils.js.map new file mode 100644 index 0000000..c118045 --- /dev/null +++ b/dist/utils/node-utils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"node-utils.js","sourceRoot":"","sources":["../../src/utils/node-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/npm-version-checker.d.ts b/dist/utils/npm-version-checker.d.ts new file mode 100644 index 0000000..0ebf435 --- /dev/null +++ b/dist/utils/npm-version-checker.d.ts @@ -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; +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 \ No newline at end of file diff --git a/dist/utils/npm-version-checker.d.ts.map b/dist/utils/npm-version-checker.d.ts.map new file mode 100644 index 0000000..b4f258c --- /dev/null +++ b/dist/utils/npm-version-checker.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/npm-version-checker.js b/dist/utils/npm-version-checker.js new file mode 100644 index 0000000..71e7bd1 --- /dev/null +++ b/dist/utils/npm-version-checker.js @@ -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 \ No newline at end of file diff --git a/dist/utils/npm-version-checker.js.map b/dist/utils/npm-version-checker.js.map new file mode 100644 index 0000000..ad36518 --- /dev/null +++ b/dist/utils/npm-version-checker.js.map @@ -0,0 +1 @@ +{"version":3,"file":"npm-version-checker.js","sourceRoot":"","sources":["../../src/utils/npm-version-checker.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/protocol-version.d.ts b/dist/utils/protocol-version.d.ts new file mode 100644 index 0000000..929227a --- /dev/null +++ b/dist/utils/protocol-version.d.ts @@ -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): boolean; +export declare function negotiateProtocolVersion(clientRequestedVersion?: string, clientInfo?: ClientInfo, userAgent?: string, headers?: Record): 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 \ No newline at end of file diff --git a/dist/utils/protocol-version.d.ts.map b/dist/utils/protocol-version.d.ts.map new file mode 100644 index 0000000..872f0b9 --- /dev/null +++ b/dist/utils/protocol-version.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/protocol-version.js b/dist/utils/protocol-version.js new file mode 100644 index 0000000..d19321a --- /dev/null +++ b/dist/utils/protocol-version.js @@ -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 \ No newline at end of file diff --git a/dist/utils/protocol-version.js.map b/dist/utils/protocol-version.js.map new file mode 100644 index 0000000..cce37f8 --- /dev/null +++ b/dist/utils/protocol-version.js.map @@ -0,0 +1 @@ +{"version":3,"file":"protocol-version.js","sourceRoot":"","sources":["../../src/utils/protocol-version.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/simple-cache.d.ts b/dist/utils/simple-cache.d.ts new file mode 100644 index 0000000..b13aff4 --- /dev/null +++ b/dist/utils/simple-cache.d.ts @@ -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 \ No newline at end of file diff --git a/dist/utils/simple-cache.d.ts.map b/dist/utils/simple-cache.d.ts.map new file mode 100644 index 0000000..c56861a --- /dev/null +++ b/dist/utils/simple-cache.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/simple-cache.js b/dist/utils/simple-cache.js new file mode 100644 index 0000000..63187ff --- /dev/null +++ b/dist/utils/simple-cache.js @@ -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 \ No newline at end of file diff --git a/dist/utils/simple-cache.js.map b/dist/utils/simple-cache.js.map new file mode 100644 index 0000000..3f3f9e4 --- /dev/null +++ b/dist/utils/simple-cache.js.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/ssrf-protection.d.ts b/dist/utils/ssrf-protection.d.ts new file mode 100644 index 0000000..da10b77 --- /dev/null +++ b/dist/utils/ssrf-protection.d.ts @@ -0,0 +1,7 @@ +export declare class SSRFProtection { + static validateWebhookUrl(urlString: string): Promise<{ + valid: boolean; + reason?: string; + }>; +} +//# sourceMappingURL=ssrf-protection.d.ts.map \ No newline at end of file diff --git a/dist/utils/ssrf-protection.d.ts.map b/dist/utils/ssrf-protection.d.ts.map new file mode 100644 index 0000000..22b147c --- /dev/null +++ b/dist/utils/ssrf-protection.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/ssrf-protection.js b/dist/utils/ssrf-protection.js new file mode 100644 index 0000000..61c449c --- /dev/null +++ b/dist/utils/ssrf-protection.js @@ -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 \ No newline at end of file diff --git a/dist/utils/ssrf-protection.js.map b/dist/utils/ssrf-protection.js.map new file mode 100644 index 0000000..6ebfa98 --- /dev/null +++ b/dist/utils/ssrf-protection.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ssrf-protection.js","sourceRoot":"","sources":["../../src/utils/ssrf-protection.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/template-node-resolver.d.ts b/dist/utils/template-node-resolver.d.ts new file mode 100644 index 0000000..a82d239 --- /dev/null +++ b/dist/utils/template-node-resolver.d.ts @@ -0,0 +1,2 @@ +export declare function resolveTemplateNodeTypes(nodeTypes: string[]): string[]; +//# sourceMappingURL=template-node-resolver.d.ts.map \ No newline at end of file diff --git a/dist/utils/template-node-resolver.d.ts.map b/dist/utils/template-node-resolver.d.ts.map new file mode 100644 index 0000000..7dab10a --- /dev/null +++ b/dist/utils/template-node-resolver.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/template-node-resolver.js b/dist/utils/template-node-resolver.js new file mode 100644 index 0000000..6fb0074 --- /dev/null +++ b/dist/utils/template-node-resolver.js @@ -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 \ No newline at end of file diff --git a/dist/utils/template-node-resolver.js.map b/dist/utils/template-node-resolver.js.map new file mode 100644 index 0000000..00ae200 --- /dev/null +++ b/dist/utils/template-node-resolver.js.map @@ -0,0 +1 @@ +{"version":3,"file":"template-node-resolver.js","sourceRoot":"","sources":["../../src/utils/template-node-resolver.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/template-sanitizer.d.ts b/dist/utils/template-sanitizer.d.ts new file mode 100644 index 0000000..6f17297 --- /dev/null +++ b/dist/utils/template-sanitizer.d.ts @@ -0,0 +1,21 @@ +export interface SanitizerConfig { + problematicTokens: string[]; + tokenPatterns: RegExp[]; + replacements: Map; +} +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 \ No newline at end of file diff --git a/dist/utils/template-sanitizer.d.ts.map b/dist/utils/template-sanitizer.d.ts.map new file mode 100644 index 0000000..3bc161e --- /dev/null +++ b/dist/utils/template-sanitizer.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/template-sanitizer.js b/dist/utils/template-sanitizer.js new file mode 100644 index 0000000..51b6a3e --- /dev/null +++ b/dist/utils/template-sanitizer.js @@ -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 \ No newline at end of file diff --git a/dist/utils/template-sanitizer.js.map b/dist/utils/template-sanitizer.js.map new file mode 100644 index 0000000..1386d16 --- /dev/null +++ b/dist/utils/template-sanitizer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"template-sanitizer.js","sourceRoot":"","sources":["../../src/utils/template-sanitizer.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/url-detector.d.ts b/dist/utils/url-detector.d.ts new file mode 100644 index 0000000..9ce0963 --- /dev/null +++ b/dist/utils/url-detector.d.ts @@ -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 \ No newline at end of file diff --git a/dist/utils/url-detector.d.ts.map b/dist/utils/url-detector.d.ts.map new file mode 100644 index 0000000..8302d03 --- /dev/null +++ b/dist/utils/url-detector.d.ts.map @@ -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"} \ No newline at end of file diff --git a/dist/utils/url-detector.js b/dist/utils/url-detector.js new file mode 100644 index 0000000..993de59 --- /dev/null +++ b/dist/utils/url-detector.js @@ -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 \ No newline at end of file diff --git a/dist/utils/url-detector.js.map b/dist/utils/url-detector.js.map new file mode 100644 index 0000000..a107e42 --- /dev/null +++ b/dist/utils/url-detector.js.map @@ -0,0 +1 @@ +{"version":3,"file":"url-detector.js","sourceRoot":"","sources":["../../src/utils/url-detector.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/validation-schemas.d.ts b/dist/utils/validation-schemas.d.ts new file mode 100644 index 0000000..30b3fcd --- /dev/null +++ b/dist/utils/validation-schemas.d.ts @@ -0,0 +1,32 @@ +export declare class ValidationError extends Error { + field?: string | undefined; + value?: any | undefined; + constructor(message: string, field?: string | undefined, value?: any | undefined); +} +export interface ValidationResult { + valid: boolean; + errors: Array<{ + field: string; + message: string; + value?: any; + }>; +} +export declare class Validator { + static validateString(value: any, fieldName: string, required?: boolean): ValidationResult; + static validateObject(value: any, fieldName: string, required?: boolean): ValidationResult; + static validateArray(value: any, fieldName: string, required?: boolean): ValidationResult; + static validateNumber(value: any, fieldName: string, required?: boolean, min?: number, max?: number): ValidationResult; + static validateEnum(value: any, fieldName: string, allowedValues: T[], required?: boolean): ValidationResult; + static combineResults(...results: ValidationResult[]): ValidationResult; + static formatErrors(result: ValidationResult, toolName?: string): string; +} +export declare class ToolValidation { + static validateNodeOperation(args: any): ValidationResult; + static validateNodeMinimal(args: any): ValidationResult; + static validateWorkflow(args: any): ValidationResult; + static validateSearchNodes(args: any): ValidationResult; + static validateListNodeTemplates(args: any): ValidationResult; + static validateWorkflowId(args: any): ValidationResult; + static validateCreateWorkflow(args: any): ValidationResult; +} +//# sourceMappingURL=validation-schemas.d.ts.map \ No newline at end of file diff --git a/dist/utils/validation-schemas.d.ts.map b/dist/utils/validation-schemas.d.ts.map new file mode 100644 index 0000000..84ddc7e --- /dev/null +++ b/dist/utils/validation-schemas.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"validation-schemas.d.ts","sourceRoot":"","sources":["../../src/utils/validation-schemas.ts"],"names":[],"mappings":"AAQA,qBAAa,eAAgB,SAAQ,KAAK;IACJ,KAAK,CAAC,EAAE,MAAM;IAAS,KAAK,CAAC,EAAE,GAAG;gBAA1D,OAAO,EAAE,MAAM,EAAS,KAAK,CAAC,EAAE,MAAM,YAAA,EAAS,KAAK,CAAC,EAAE,GAAG,YAAA;CAIvE;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,KAAK,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,GAAG,CAAC;KACb,CAAC,CAAC;CACJ;AAKD,qBAAa,SAAS;IAIpB,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,GAAE,OAAc,GAAG,gBAAgB;IAgChG,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,GAAE,OAAc,GAAG,gBAAgB;IAkChG,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,GAAE,OAAc,GAAG,gBAAgB;IA0B/F,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,GAAE,OAAc,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,gBAAgB;IA2C5H,MAAM,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,EAAE,EAAE,QAAQ,GAAE,OAAc,GAAG,gBAAgB;IA0BrH,MAAM,CAAC,cAAc,CAAC,GAAG,OAAO,EAAE,gBAAgB,EAAE,GAAG,gBAAgB;IAWvE,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,gBAAgB,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM;CAQzE;AAKD,qBAAa,cAAc;IAIzB,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,GAAG,GAAG,gBAAgB;IAgBzD,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,GAAG,GAAG,gBAAgB;IAUvD,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,GAAG,GAAG,gBAAgB;IAsBpD,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,GAAG,GAAG,gBAAgB;IAgBvD,MAAM,CAAC,yBAAyB,CAAC,IAAI,EAAE,GAAG,GAAG,gBAAgB;IAU7D,MAAM,CAAC,kBAAkB,CAAC,IAAI,EAAE,GAAG,GAAG,gBAAgB;IAOtD,MAAM,CAAC,sBAAsB,CAAC,IAAI,EAAE,GAAG,GAAG,gBAAgB;CAU3D"} \ No newline at end of file diff --git a/dist/utils/validation-schemas.js b/dist/utils/validation-schemas.js new file mode 100644 index 0000000..8275359 --- /dev/null +++ b/dist/utils/validation-schemas.js @@ -0,0 +1,219 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ToolValidation = exports.Validator = exports.ValidationError = void 0; +class ValidationError extends Error { + constructor(message, field, value) { + super(message); + this.field = field; + this.value = value; + this.name = 'ValidationError'; + } +} +exports.ValidationError = ValidationError; +class Validator { + static validateString(value, fieldName, required = true) { + const errors = []; + if (required && (value === undefined || value === null)) { + errors.push({ + field: fieldName, + message: `${fieldName} is required`, + value + }); + } + else if (value !== undefined && value !== null && typeof value !== 'string') { + errors.push({ + field: fieldName, + message: `${fieldName} must be a string, got ${typeof value}`, + value + }); + } + else if (required && typeof value === 'string' && value.trim().length === 0) { + errors.push({ + field: fieldName, + message: `${fieldName} cannot be empty`, + value + }); + } + return { + valid: errors.length === 0, + errors + }; + } + static validateObject(value, fieldName, required = true) { + const errors = []; + if (required && (value === undefined || value === null)) { + errors.push({ + field: fieldName, + message: `${fieldName} is required`, + value + }); + } + else if (value !== undefined && value !== null) { + if (typeof value !== 'object') { + errors.push({ + field: fieldName, + message: `${fieldName} must be an object, got ${typeof value}`, + value + }); + } + else if (Array.isArray(value)) { + errors.push({ + field: fieldName, + message: `${fieldName} must be an object, not an array`, + value + }); + } + } + return { + valid: errors.length === 0, + errors + }; + } + static validateArray(value, fieldName, required = true) { + const errors = []; + if (required && (value === undefined || value === null)) { + errors.push({ + field: fieldName, + message: `${fieldName} is required`, + value + }); + } + else if (value !== undefined && value !== null && !Array.isArray(value)) { + errors.push({ + field: fieldName, + message: `${fieldName} must be an array, got ${typeof value}`, + value + }); + } + return { + valid: errors.length === 0, + errors + }; + } + static validateNumber(value, fieldName, required = true, min, max) { + const errors = []; + if (required && (value === undefined || value === null)) { + errors.push({ + field: fieldName, + message: `${fieldName} is required`, + value + }); + } + else if (value !== undefined && value !== null) { + if (typeof value !== 'number' || isNaN(value)) { + errors.push({ + field: fieldName, + message: `${fieldName} must be a number, got ${typeof value}`, + value + }); + } + else { + if (min !== undefined && value < min) { + errors.push({ + field: fieldName, + message: `${fieldName} must be at least ${min}, got ${value}`, + value + }); + } + if (max !== undefined && value > max) { + errors.push({ + field: fieldName, + message: `${fieldName} must be at most ${max}, got ${value}`, + value + }); + } + } + } + return { + valid: errors.length === 0, + errors + }; + } + static validateEnum(value, fieldName, allowedValues, required = true) { + const errors = []; + if (required && (value === undefined || value === null)) { + errors.push({ + field: fieldName, + message: `${fieldName} is required`, + value + }); + } + else if (value !== undefined && value !== null && !allowedValues.includes(value)) { + errors.push({ + field: fieldName, + message: `${fieldName} must be one of: ${allowedValues.join(', ')}, got "${value}"`, + value + }); + } + return { + valid: errors.length === 0, + errors + }; + } + static combineResults(...results) { + const allErrors = results.flatMap(r => r.errors); + return { + valid: allErrors.length === 0, + errors: allErrors + }; + } + static formatErrors(result, toolName) { + if (result.valid) + return ''; + const prefix = toolName ? `${toolName}: ` : ''; + const errors = result.errors.map(e => ` • ${e.field}: ${e.message}`).join('\n'); + return `${prefix}Validation failed:\n${errors}`; + } +} +exports.Validator = Validator; +class ToolValidation { + static validateNodeOperation(args) { + const nodeTypeResult = Validator.validateString(args.nodeType, 'nodeType'); + const configResult = Validator.validateObject(args.config, 'config'); + const profileResult = Validator.validateEnum(args.profile, 'profile', ['minimal', 'runtime', 'ai-friendly', 'strict'], false); + return Validator.combineResults(nodeTypeResult, configResult, profileResult); + } + static validateNodeMinimal(args) { + const nodeTypeResult = Validator.validateString(args.nodeType, 'nodeType'); + const configResult = Validator.validateObject(args.config, 'config'); + return Validator.combineResults(nodeTypeResult, configResult); + } + static validateWorkflow(args) { + const workflowResult = Validator.validateObject(args.workflow, 'workflow'); + let nodesResult = { valid: true, errors: [] }; + let connectionsResult = { valid: true, errors: [] }; + if (workflowResult.valid && args.workflow) { + nodesResult = Validator.validateArray(args.workflow.nodes, 'workflow.nodes'); + connectionsResult = Validator.validateObject(args.workflow.connections, 'workflow.connections'); + } + const optionsResult = args.options ? + Validator.validateObject(args.options, 'options', false) : + { valid: true, errors: [] }; + return Validator.combineResults(workflowResult, nodesResult, connectionsResult, optionsResult); + } + static validateSearchNodes(args) { + const queryResult = Validator.validateString(args.query, 'query'); + const limitResult = Validator.validateNumber(args.limit, 'limit', false, 1, 200); + const modeResult = Validator.validateEnum(args.mode, 'mode', ['OR', 'AND', 'FUZZY'], false); + return Validator.combineResults(queryResult, limitResult, modeResult); + } + static validateListNodeTemplates(args) { + const nodeTypesResult = Validator.validateArray(args.nodeTypes, 'nodeTypes'); + const limitResult = Validator.validateNumber(args.limit, 'limit', false, 1, 50); + return Validator.combineResults(nodeTypesResult, limitResult); + } + static validateWorkflowId(args) { + return Validator.validateString(args.id, 'id'); + } + static validateCreateWorkflow(args) { + const nameResult = Validator.validateString(args.name, 'name'); + const nodesResult = Validator.validateArray(args.nodes, 'nodes'); + const connectionsResult = Validator.validateObject(args.connections, 'connections'); + const settingsResult = args.settings ? + Validator.validateObject(args.settings, 'settings', false) : + { valid: true, errors: [] }; + return Validator.combineResults(nameResult, nodesResult, connectionsResult, settingsResult); + } +} +exports.ToolValidation = ToolValidation; +//# sourceMappingURL=validation-schemas.js.map \ No newline at end of file diff --git a/dist/utils/validation-schemas.js.map b/dist/utils/validation-schemas.js.map new file mode 100644 index 0000000..ad7f0e7 --- /dev/null +++ b/dist/utils/validation-schemas.js.map @@ -0,0 +1 @@ +{"version":3,"file":"validation-schemas.js","sourceRoot":"","sources":["../../src/utils/validation-schemas.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/version.d.ts b/dist/utils/version.d.ts new file mode 100644 index 0000000..6ff78e6 --- /dev/null +++ b/dist/utils/version.d.ts @@ -0,0 +1,2 @@ +export declare const PROJECT_VERSION: string; +//# sourceMappingURL=version.d.ts.map \ No newline at end of file diff --git a/dist/utils/version.d.ts.map b/dist/utils/version.d.ts.map new file mode 100644 index 0000000..9534a8e --- /dev/null +++ b/dist/utils/version.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/utils/version.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,eAAe,QAAsB,CAAC"} \ No newline at end of file diff --git a/dist/utils/version.js b/dist/utils/version.js new file mode 100644 index 0000000..e43c9d8 --- /dev/null +++ b/dist/utils/version.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.PROJECT_VERSION = void 0; +const fs_1 = require("fs"); +const path_1 = require("path"); +function getProjectVersion() { + try { + const packageJsonPath = (0, path_1.join)(__dirname, '../../package.json'); + const packageJson = JSON.parse((0, fs_1.readFileSync)(packageJsonPath, 'utf-8')); + return packageJson.version || '0.0.0'; + } + catch (error) { + console.error('Failed to read version from package.json:', error); + return '0.0.0'; + } +} +exports.PROJECT_VERSION = getProjectVersion(); +//# sourceMappingURL=version.js.map \ No newline at end of file diff --git a/dist/utils/version.js.map b/dist/utils/version.js.map new file mode 100644 index 0000000..f992eef --- /dev/null +++ b/dist/utils/version.js.map @@ -0,0 +1 @@ +{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/utils/version.ts"],"names":[],"mappings":";;;AAAA,2BAAkC;AAClC,+BAA4B;AAM5B,SAAS,iBAAiB;IACxB,IAAI,CAAC;QACH,MAAM,eAAe,GAAG,IAAA,WAAI,EAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC;QAC9D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAY,EAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;QACvE,OAAO,WAAW,CAAC,OAAO,IAAI,OAAO,CAAC;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,2CAA2C,EAAE,KAAK,CAAC,CAAC;QAClE,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAEY,QAAA,eAAe,GAAG,iBAAiB,EAAE,CAAC"} \ No newline at end of file From 1524fd5a08df20d32c28d403175114a72d0b64f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romuald=20Cz=C5=82onkowski?= Date: Fri, 5 Dec 2025 12:00:13 +0100 Subject: [PATCH 4/5] fix: address code review issues for PR #467 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add 5-minute TTL to version cache (prevents stale data after upgrades) - Add type validation for version string from settings response - Support 'v' prefix in version strings (e.g., v1.2.3) - Fix race condition in getVersion() using promise-based locking - Fix empty settings regression (Issue #431) - use minimal defaults 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/services/n8n-api-client.ts | 45 ++++++++++++++++++++++++-------- src/services/n8n-validation.ts | 12 +++++++-- src/services/n8n-version.ts | 47 +++++++++++++++++++++++----------- 3 files changed, 76 insertions(+), 28 deletions(-) diff --git a/src/services/n8n-api-client.ts b/src/services/n8n-api-client.ts index a697dbf..cf16768 100644 --- a/src/services/n8n-api-client.ts +++ b/src/services/n8n-api-client.ts @@ -43,7 +43,7 @@ export class N8nApiClient { private maxRetries: number; private baseUrl: string; private versionInfo: N8nVersionInfo | null = null; - private versionFetched = false; + private versionPromise: Promise | null = null; constructor(config: N8nApiClientConfig) { const { baseUrl, apiKey, timeout = 30000, maxRetries = 3 } = config; @@ -95,19 +95,42 @@ export class N8nApiClient { } /** - * Get the n8n version, fetching it if not already cached + * Get the n8n version, fetching it if not already cached. + * Uses promise-based locking to prevent concurrent requests. */ async getVersion(): Promise { - if (!this.versionFetched) { - // Check if already cached globally - this.versionInfo = getCachedVersion(this.baseUrl); - if (!this.versionInfo) { - // Fetch from server - this.versionInfo = await fetchN8nVersion(this.baseUrl); - } - this.versionFetched = true; + // If we already have version info, return it + if (this.versionInfo) { + return this.versionInfo; } - return this.versionInfo; + + // If a fetch is already in progress, wait for it + if (this.versionPromise) { + return this.versionPromise; + } + + // Start a new fetch with promise-based locking + this.versionPromise = this.fetchVersionOnce(); + try { + this.versionInfo = await this.versionPromise; + return this.versionInfo; + } finally { + // Clear the promise so future calls can retry if needed + this.versionPromise = null; + } + } + + /** + * Internal method to fetch version once + */ + private async fetchVersionOnce(): Promise { + // Check if already cached globally + let version = getCachedVersion(this.baseUrl); + if (!version) { + // Fetch from server + version = await fetchN8nVersion(this.baseUrl); + } + return version; } /** diff --git a/src/services/n8n-validation.ts b/src/services/n8n-validation.ts index 3fe3a15..12ccae4 100644 --- a/src/services/n8n-validation.ts +++ b/src/services/n8n-validation.ts @@ -181,9 +181,17 @@ export function cleanWorkflowForUpdate(workflow: Workflow): Partial { filteredSettings[key] = value; } } - cleanedWorkflow.settings = filteredSettings; + // If no valid properties remain after filtering, use minimal defaults + // Issue #431: n8n API rejects empty settings objects + if (Object.keys(filteredSettings).length > 0) { + cleanedWorkflow.settings = filteredSettings; + } else { + // Minimal valid settings - executionOrder v1 is the modern default + cleanedWorkflow.settings = { executionOrder: 'v1' as const }; + } } else { - cleanedWorkflow.settings = {}; + // No settings provided - use minimal valid defaults + cleanedWorkflow.settings = { executionOrder: 'v1' as const }; } return cleanedWorkflow; diff --git a/src/services/n8n-version.ts b/src/services/n8n-version.ts index 3c6f279..d36a9ec 100644 --- a/src/services/n8n-version.ts +++ b/src/services/n8n-version.ts @@ -20,8 +20,16 @@ import axios from 'axios'; import { logger } from '../utils/logger'; import { N8nVersionInfo, N8nSettingsResponse } from '../types/n8n-api'; -// Cache version info per base URL to avoid repeated API calls -const versionCache = new Map(); +// Cache version info per base URL with TTL to handle server upgrades +interface CachedVersion { + info: N8nVersionInfo; + fetchedAt: number; +} + +// Cache TTL: 5 minutes - allows for server upgrades without requiring restart +const VERSION_CACHE_TTL_MS = 5 * 60 * 1000; + +const versionCache = new Map(); // Settings properties supported by each n8n version range // These are CUMULATIVE - each version adds to the previous @@ -53,8 +61,9 @@ const SETTINGS_BY_VERSION = { * Parse version string into structured version info */ export function parseVersion(versionString: string): N8nVersionInfo | null { - // Handle formats like "1.119.0", "1.37.0-beta.1", "0.200.0" - const match = versionString.match(/^(\d+)\.(\d+)\.(\d+)/); + // Handle formats like "1.119.0", "1.37.0-beta.1", "0.200.0", "v1.2.3" + // Support optional 'v' prefix for robustness + const match = versionString.match(/^v?(\d+)\.(\d+)\.(\d+)/); if (!match) { return null; } @@ -111,11 +120,11 @@ export function getSupportedSettingsProperties(version: N8nVersionInfo): Set { - // Check cache first + // Check cache first (with TTL) const cached = versionCache.get(baseUrl); - if (cached) { - logger.debug(`Using cached n8n version for ${baseUrl}: ${cached.version}`); - return cached; + if (cached && Date.now() - cached.fetchedAt < VERSION_CACHE_TTL_MS) { + logger.debug(`Using cached n8n version for ${baseUrl}: ${cached.info.version}`); + return cached.info; } try { @@ -138,14 +147,18 @@ export async function fetchN8nVersion(baseUrl: string): Promise Date: Fri, 5 Dec 2025 12:07:04 +0100 Subject: [PATCH 5/5] chore: bump version to 2.28.5 and add changelog entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Conceived by Romuald Członkowski - https://www.aiadvisors.pl/en 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- CHANGELOG.md | 33 +++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efe2a58..50a395b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,39 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [2.28.5] - 2025-12-05 + +### Bug Fixes + +**Version-Aware Settings Filtering for n8n API Compatibility (#464, #465, #466)** + +Fixed `"Invalid request: request/body must NOT have additional properties"` errors when using `n8n_update_partial_workflow` with older n8n instances. + +- **Root Cause**: n8n Public API uses strict JSON schema validation. Different n8n versions support different workflow settings properties: + - All versions: 7 core properties (saveExecutionProgress, saveManualExecutions, saveDataErrorExecution, saveDataSuccessExecution, executionTimeout, errorWorkflow, timezone) + - n8n 1.37.0+: adds `executionOrder` + - n8n 1.119.0+: adds `callerPolicy`, `callerIds`, `timeSavedPerExecution`, `availableInMCP` + +- **Solution**: Auto-detect n8n version via `/rest/settings` endpoint and filter settings accordingly + +- **New Features**: + - Version detection with 5-minute cache TTL (handles server upgrades without restart) + - Type validation for version string responses + - Support for `v` prefix in version strings (e.g., `v1.2.3`) + - Race condition protection with promise-based locking + - Read-only field filtering (`activeVersionId`, `activeVersion`) + +- **Files Changed**: + - `src/services/n8n-version.ts` (NEW) - Version detection and settings filtering + - `src/services/n8n-api-client.ts` - Added `getVersion()` method with locking + - `src/services/n8n-validation.ts` - Added read-only field filtering + - `src/types/n8n-api.ts` - Added version types + - `tests/unit/services/n8n-version.test.ts` (NEW) - 24 unit tests + +Thanks to [@thesved](https://github.com/thesved) for this contribution! + +**Conceived by Romuald Członkowski - [AiAdvisors](https://www.aiadvisors.pl/en)** + ## [2.28.4] - 2025-12-05 ### Features diff --git a/package.json b/package.json index 1893e6c..31c10ea 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "n8n-mcp", - "version": "2.28.4", + "version": "2.28.5", "description": "Integration between n8n workflow automation and Model Context Protocol (MCP)", "main": "dist/index.js", "types": "dist/index.d.ts",