refactor: clean up file names and fix version management
- Renamed files to remove unnecessary suffixes: - tools-update.ts → tools.ts - server-update.ts → server.ts - http-server-fixed.ts → http-server.ts - Created version utility to read from package.json as single source of truth - Updated all imports across 21+ files - Removed legacy files: - src/http-server.ts (legacy HTTP server with known issues) - src/utils/n8n-client.ts (unused legacy API client) - Added n8n_diagnostic tool to help troubleshoot management tools visibility - Added script to sync package.runtime.json version - Fixed version mismatch issue (was hardcoded 2.4.1, now reads 2.7.0 from package.json) This addresses GitHub issue #5 regarding version mismatch and provides better diagnostics for users. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,168 +0,0 @@
|
||||
import { N8NConfig } from '../types';
|
||||
|
||||
export class N8NApiClient {
|
||||
private config: N8NConfig;
|
||||
private headers: Record<string, string>;
|
||||
|
||||
constructor(config: N8NConfig) {
|
||||
this.config = config;
|
||||
this.headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'X-N8N-API-KEY': config.apiKey,
|
||||
};
|
||||
}
|
||||
|
||||
private async request(endpoint: string, options: RequestInit = {}): Promise<any> {
|
||||
const url = `${this.config.apiUrl}/api/v1${endpoint}`;
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
...options,
|
||||
headers: {
|
||||
...this.headers,
|
||||
...options.headers,
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.text();
|
||||
throw new Error(`n8n API error: ${response.status} - ${error}`);
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to connect to n8n: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Workflow operations
|
||||
async getWorkflows(filters?: { active?: boolean; tags?: string[] }): Promise<any> {
|
||||
const query = new URLSearchParams();
|
||||
if (filters?.active !== undefined) {
|
||||
query.append('active', filters.active.toString());
|
||||
}
|
||||
if (filters?.tags?.length) {
|
||||
query.append('tags', filters.tags.join(','));
|
||||
}
|
||||
|
||||
return this.request(`/workflows${query.toString() ? `?${query}` : ''}`);
|
||||
}
|
||||
|
||||
async getWorkflow(id: string): Promise<any> {
|
||||
return this.request(`/workflows/${id}`);
|
||||
}
|
||||
|
||||
async createWorkflow(workflowData: any): Promise<any> {
|
||||
return this.request('/workflows', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(workflowData),
|
||||
});
|
||||
}
|
||||
|
||||
async updateWorkflow(id: string, updates: any): Promise<any> {
|
||||
return this.request(`/workflows/${id}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(updates),
|
||||
});
|
||||
}
|
||||
|
||||
async deleteWorkflow(id: string): Promise<any> {
|
||||
return this.request(`/workflows/${id}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
|
||||
async activateWorkflow(id: string): Promise<any> {
|
||||
return this.request(`/workflows/${id}/activate`, {
|
||||
method: 'POST',
|
||||
});
|
||||
}
|
||||
|
||||
async deactivateWorkflow(id: string): Promise<any> {
|
||||
return this.request(`/workflows/${id}/deactivate`, {
|
||||
method: 'POST',
|
||||
});
|
||||
}
|
||||
|
||||
// Execution operations
|
||||
async executeWorkflow(id: string, data?: any): Promise<any> {
|
||||
return this.request(`/workflows/${id}/execute`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ data }),
|
||||
});
|
||||
}
|
||||
|
||||
async getExecutions(filters?: {
|
||||
workflowId?: string;
|
||||
status?: string;
|
||||
limit?: number
|
||||
}): Promise<any> {
|
||||
const query = new URLSearchParams();
|
||||
if (filters?.workflowId) {
|
||||
query.append('workflowId', filters.workflowId);
|
||||
}
|
||||
if (filters?.status) {
|
||||
query.append('status', filters.status);
|
||||
}
|
||||
if (filters?.limit) {
|
||||
query.append('limit', filters.limit.toString());
|
||||
}
|
||||
|
||||
return this.request(`/executions${query.toString() ? `?${query}` : ''}`);
|
||||
}
|
||||
|
||||
async getExecution(id: string): Promise<any> {
|
||||
return this.request(`/executions/${id}`);
|
||||
}
|
||||
|
||||
async deleteExecution(id: string): Promise<any> {
|
||||
return this.request(`/executions/${id}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
|
||||
// Credential operations
|
||||
async getCredentialTypes(): Promise<any> {
|
||||
return this.request('/credential-types');
|
||||
}
|
||||
|
||||
async getCredentials(): Promise<any> {
|
||||
return this.request('/credentials');
|
||||
}
|
||||
|
||||
// Node operations
|
||||
async getNodeTypes(): Promise<any> {
|
||||
return this.request('/node-types');
|
||||
}
|
||||
|
||||
async getNodeType(nodeType: string): Promise<any> {
|
||||
return this.request(`/node-types/${nodeType}`);
|
||||
}
|
||||
|
||||
// Extended methods for node source extraction
|
||||
async getNodeSourceCode(nodeType: string): Promise<any> {
|
||||
// This is a special endpoint we'll need to handle differently
|
||||
// as n8n doesn't expose source code directly through API
|
||||
// We'll need to implement this through file system access
|
||||
throw new Error('Node source code extraction requires special implementation');
|
||||
}
|
||||
|
||||
async getNodeDescription(nodeType: string): Promise<any> {
|
||||
try {
|
||||
const nodeTypeData = await this.getNodeType(nodeType);
|
||||
return {
|
||||
name: nodeTypeData.name,
|
||||
displayName: nodeTypeData.displayName,
|
||||
description: nodeTypeData.description,
|
||||
version: nodeTypeData.version,
|
||||
defaults: nodeTypeData.defaults,
|
||||
inputs: nodeTypeData.inputs,
|
||||
outputs: nodeTypeData.outputs,
|
||||
properties: nodeTypeData.properties,
|
||||
credentials: nodeTypeData.credentials,
|
||||
};
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to get node description: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
19
src/utils/version.ts
Normal file
19
src/utils/version.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
/**
|
||||
* Get the project version from package.json
|
||||
* This ensures we have a single source of truth for versioning
|
||||
*/
|
||||
function getProjectVersion(): string {
|
||||
try {
|
||||
const packageJsonPath = join(__dirname, '../../package.json');
|
||||
const packageJson = JSON.parse(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';
|
||||
}
|
||||
}
|
||||
|
||||
export const PROJECT_VERSION = getProjectVersion();
|
||||
Reference in New Issue
Block a user