fix: make templates available in Docker by removing axios from runtime
- Move TemplateFetcher import to dynamic import in fetchAndUpdateTemplates - Templates now work everywhere since they just read from database - axios only loaded when actually fetching new templates - Fixes Docker runtime error while keeping full template functionality 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -17,8 +17,7 @@ import { TaskTemplates } from '../services/task-templates';
|
|||||||
import { ConfigValidator } from '../services/config-validator';
|
import { ConfigValidator } from '../services/config-validator';
|
||||||
import { PropertyDependencies } from '../services/property-dependencies';
|
import { PropertyDependencies } from '../services/property-dependencies';
|
||||||
import { SimpleCache } from '../utils/simple-cache';
|
import { SimpleCache } from '../utils/simple-cache';
|
||||||
// Type import for TypeScript, won't be included in runtime
|
import { TemplateService } from '../templates/template-service';
|
||||||
import type { TemplateService } from '../templates/template-service';
|
|
||||||
|
|
||||||
interface NodeRow {
|
interface NodeRow {
|
||||||
node_type: string;
|
node_type: string;
|
||||||
@@ -91,19 +90,7 @@ export class N8NDocumentationMCPServer {
|
|||||||
try {
|
try {
|
||||||
this.db = await createDatabaseAdapter(dbPath);
|
this.db = await createDatabaseAdapter(dbPath);
|
||||||
this.repository = new NodeRepository(this.db);
|
this.repository = new NodeRepository(this.db);
|
||||||
|
this.templateService = new TemplateService(this.db);
|
||||||
// Only initialize template service when not in Docker (templates are pre-built in DB)
|
|
||||||
if (!process.env.IS_DOCKER) {
|
|
||||||
try {
|
|
||||||
const { TemplateService } = await import('../templates/template-service');
|
|
||||||
this.templateService = new TemplateService(this.db);
|
|
||||||
logger.info('Template service initialized');
|
|
||||||
} catch (error) {
|
|
||||||
logger.warn('Template service not available:', error);
|
|
||||||
// Continue without templates - not critical for operation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info(`Initialized database from: ${dbPath}`);
|
logger.info(`Initialized database from: ${dbPath}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Failed to initialize database:', error);
|
logger.error('Failed to initialize database:', error);
|
||||||
@@ -955,13 +942,7 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
|
|||||||
// Template-related methods
|
// Template-related methods
|
||||||
private async listNodeTemplates(nodeTypes: string[], limit: number = 10): Promise<any> {
|
private async listNodeTemplates(nodeTypes: string[], limit: number = 10): Promise<any> {
|
||||||
await this.ensureInitialized();
|
await this.ensureInitialized();
|
||||||
if (!this.templateService) {
|
if (!this.templateService) throw new Error('Template service not initialized');
|
||||||
return {
|
|
||||||
error: 'Template service not available',
|
|
||||||
message: 'Templates are pre-built in the database. This tool is not available in Docker mode.',
|
|
||||||
templates: []
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const templates = await this.templateService.listNodeTemplates(nodeTypes, limit);
|
const templates = await this.templateService.listNodeTemplates(nodeTypes, limit);
|
||||||
|
|
||||||
@@ -982,12 +963,7 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
|
|||||||
|
|
||||||
private async getTemplate(templateId: number): Promise<any> {
|
private async getTemplate(templateId: number): Promise<any> {
|
||||||
await this.ensureInitialized();
|
await this.ensureInitialized();
|
||||||
if (!this.templateService) {
|
if (!this.templateService) throw new Error('Template service not initialized');
|
||||||
return {
|
|
||||||
error: 'Template service not available',
|
|
||||||
message: 'Templates are pre-built in the database. This tool is not available in Docker mode.'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const template = await this.templateService.getTemplate(templateId);
|
const template = await this.templateService.getTemplate(templateId);
|
||||||
|
|
||||||
@@ -1006,13 +982,7 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
|
|||||||
|
|
||||||
private async searchTemplates(query: string, limit: number = 20): Promise<any> {
|
private async searchTemplates(query: string, limit: number = 20): Promise<any> {
|
||||||
await this.ensureInitialized();
|
await this.ensureInitialized();
|
||||||
if (!this.templateService) {
|
if (!this.templateService) throw new Error('Template service not initialized');
|
||||||
return {
|
|
||||||
error: 'Template service not available',
|
|
||||||
message: 'Templates are pre-built in the database. This tool is not available in Docker mode.',
|
|
||||||
templates: []
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const templates = await this.templateService.searchTemplates(query, limit);
|
const templates = await this.templateService.searchTemplates(query, limit);
|
||||||
|
|
||||||
@@ -1033,13 +1003,7 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
|
|||||||
|
|
||||||
private async getTemplatesForTask(task: string): Promise<any> {
|
private async getTemplatesForTask(task: string): Promise<any> {
|
||||||
await this.ensureInitialized();
|
await this.ensureInitialized();
|
||||||
if (!this.templateService) {
|
if (!this.templateService) throw new Error('Template service not initialized');
|
||||||
return {
|
|
||||||
error: 'Template service not available',
|
|
||||||
message: 'Templates are pre-built in the database. This tool is not available in Docker mode.',
|
|
||||||
templates: []
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const templates = await this.templateService.getTemplatesForTask(task);
|
const templates = await this.templateService.getTemplatesForTask(task);
|
||||||
const availableTasks = this.templateService.listAvailableTasks();
|
const availableTasks = this.templateService.listAvailableTasks();
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { DatabaseAdapter } from '../database/database-adapter';
|
import { DatabaseAdapter } from '../database/database-adapter';
|
||||||
import { TemplateRepository, StoredTemplate } from './template-repository';
|
import { TemplateRepository, StoredTemplate } from './template-repository';
|
||||||
import { TemplateFetcher } from './template-fetcher';
|
|
||||||
import { logger } from '../utils/logger';
|
import { logger } from '../utils/logger';
|
||||||
|
|
||||||
export interface TemplateInfo {
|
export interface TemplateInfo {
|
||||||
@@ -24,11 +23,9 @@ export interface TemplateWithWorkflow extends TemplateInfo {
|
|||||||
|
|
||||||
export class TemplateService {
|
export class TemplateService {
|
||||||
private repository: TemplateRepository;
|
private repository: TemplateRepository;
|
||||||
private fetcher: TemplateFetcher;
|
|
||||||
|
|
||||||
constructor(db: DatabaseAdapter) {
|
constructor(db: DatabaseAdapter) {
|
||||||
this.repository = new TemplateRepository(db);
|
this.repository = new TemplateRepository(db);
|
||||||
this.fetcher = new TemplateFetcher();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -102,12 +99,16 @@ export class TemplateService {
|
|||||||
progressCallback?: (message: string, current: number, total: number) => void
|
progressCallback?: (message: string, current: number, total: number) => void
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
|
// Dynamically import fetcher only when needed (requires axios)
|
||||||
|
const { TemplateFetcher } = await import('./template-fetcher');
|
||||||
|
const fetcher = new TemplateFetcher();
|
||||||
|
|
||||||
// Clear existing templates
|
// Clear existing templates
|
||||||
this.repository.clearTemplates();
|
this.repository.clearTemplates();
|
||||||
|
|
||||||
// Fetch template list
|
// Fetch template list
|
||||||
logger.info('Fetching template list from n8n.io');
|
logger.info('Fetching template list from n8n.io');
|
||||||
const templates = await this.fetcher.fetchTemplates((current, total) => {
|
const templates = await fetcher.fetchTemplates((current, total) => {
|
||||||
progressCallback?.('Fetching template list', current, total);
|
progressCallback?.('Fetching template list', current, total);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -115,7 +116,7 @@ export class TemplateService {
|
|||||||
|
|
||||||
// Fetch details for each template
|
// Fetch details for each template
|
||||||
logger.info('Fetching template details');
|
logger.info('Fetching template details');
|
||||||
const details = await this.fetcher.fetchAllTemplateDetails(templates, (current, total) => {
|
const details = await fetcher.fetchAllTemplateDetails(templates, (current, total) => {
|
||||||
progressCallback?.('Fetching template details', current, total);
|
progressCallback?.('Fetching template details', current, total);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user