php-universal-mcp-server
Version:
Servidor MCP universal para desenvolvimento PHP e criação de sites em qualquer provedor de hospedagem
350 lines (304 loc) • 8.17 kB
JavaScript
/**
* Mock Provider - Implementação simulada para desenvolvimento offline
*/
const BaseProvider = require('./BaseProvider');
const { EventEmitter } = require('events');
const crypto = require('crypto');
const SiteCreator = require('../site-creator');
const fs = require('fs');
const path = require('path');
class MockProvider extends BaseProvider {
/**
* Construtor do Mock Provider
* @param {Object} config - Configuração do provider
*/
constructor(config = {}) {
super(config);
// Configurações específicas do mock
this.mockConfig = {
dataDir: config.mockDataDir || path.join(__dirname, 'mock-data'),
...config
};
// Inicializa o criador de sites
this.siteCreator = new SiteCreator(config);
// Carrega dados simulados
this.mockData = this._loadMockData();
}
/**
* Retorna o nome do provider
*/
getName() {
return 'mock-provider';
}
/**
* Verifica se o provider está disponível
*/
isAvailable() {
return true;
}
/**
* Executa um comando no provider
* @param {Object} payload - Payload do comando
*/
execute(payload) {
if (!payload || !payload.action) {
return {
success: false,
error: 'Ação não especificada',
timestamp: new Date().toISOString()
};
}
try {
const action = payload.action;
// Ações específicas do mock
switch (action) {
case 'getStatus':
return this._getStatus();
case 'createSite':
return this._createSite(payload);
case 'listSites':
return this._listSites();
case 'startServer':
return this._startServer(payload);
case 'listTemplates':
return this._listTemplates();
case 'uploadToFTP':
return this._uploadToFTP(payload);
// Delegação para outros métodos se necessário
default:
// Verifica se existe um PHP Provider para delegar
if (this._hasPHPProvider() && ['executeCode', 'executeFile', 'checkSyntax', 'getInfo'].includes(action)) {
return this._delegateToPHPProvider(payload);
}
// Resposta simulada para ações não implementadas
return {
success: true,
action,
result: `Ação simulada: ${action}`,
timestamp: new Date().toISOString()
};
}
} catch (error) {
return {
success: false,
error: error.message,
timestamp: new Date().toISOString()
};
}
}
/**
* Cria um stream para execução contínua
* @param {Object} payload - Payload do comando
*/
createStream(payload) {
const streamId = crypto.randomUUID();
const emitter = new EventEmitter();
// Processa o stream em background
setTimeout(() => {
// Emite o evento de início
emitter.emit('start', {
id: streamId,
timestamp: new Date().toISOString()
});
// Simulação de processamento
let progress = 0;
const interval = setInterval(() => {
progress += 20;
// Emite evento de progresso
emitter.emit('data', {
id: streamId,
progress,
result: {
output: `Progresso da operação: ${progress}%`
},
timestamp: new Date().toISOString()
});
// Finaliza quando chegar a 100%
if (progress >= 100) {
clearInterval(interval);
// Emite evento de conclusão
emitter.emit('end', {
id: streamId,
completed: true,
result: {
success: true,
output: 'Operação concluída com sucesso!',
action: payload.action
},
timestamp: new Date().toISOString()
});
}
}, 1000);
}, 0);
return {
id: streamId,
emitter
};
}
/**
* Cancela a execução de um comando
* @param {string} sessionId - ID da sessão
*/
cancel(sessionId) {
return {
success: true,
message: `Sessão ${sessionId} cancelada (simulação)`,
timestamp: new Date().toISOString()
};
}
/**
* Fecha um stream ativo
* @param {Object} stream - Stream a ser fechado
*/
closeStream(stream) {
if (!stream || !stream.emitter) return;
// Emite evento de fechamento
stream.emitter.emit('close', {
id: stream.id,
reason: 'user_closed',
timestamp: new Date().toISOString()
});
}
/**
* Carrega dados simulados
* @private
*/
_loadMockData() {
try {
const defaultDataPath = path.join(this.mockConfig.dataDir, 'default.json');
if (fs.existsSync(defaultDataPath)) {
return JSON.parse(fs.readFileSync(defaultDataPath, 'utf8'));
}
// Dados padrão se não encontrar arquivo
return {
sites: [],
status: {
isRunning: true,
uptime: '12 hours',
version: '1.0.0'
}
};
} catch (error) {
console.warn('Erro ao carregar dados simulados:', error.message);
// Retorna dados padrão em caso de erro
return {
sites: [],
status: {
isRunning: true,
uptime: '0 minutes',
version: '1.0.0'
}
};
}
}
/**
* Retorna o status simulado
* @private
*/
_getStatus() {
return {
success: true,
status: this.mockData.status,
timestamp: new Date().toISOString()
};
}
/**
* Cria um site usando o SiteCreator
* @param {Object} payload - Payload com os dados do site
* @private
*/
_createSite(payload) {
const { domain, template, siteName, variables } = payload;
return this.siteCreator.createSite({
domain,
template,
siteName,
variables
});
}
/**
* Lista os sites criados
* @private
*/
_listSites() {
const sites = this.siteCreator.listSites();
return {
success: true,
sites,
count: sites.length,
timestamp: new Date().toISOString()
};
}
/**
* Inicia um servidor para um site
* @param {Object} payload - Payload com os dados do servidor
* @private
*/
_startServer(payload) {
const { domain, port } = payload;
return this.siteCreator.startServer(domain, port);
}
/**
* Lista os templates disponíveis
* @private
*/
_listTemplates() {
const templates = this.siteCreator.listTemplates();
return {
success: true,
templates,
count: templates.length,
timestamp: new Date().toISOString()
};
}
/**
* Verifica se existe um PHP Provider para delegar comandos
* @private
*/
_hasPHPProvider() {
try {
const PHPProvider = require('../php-provider');
return true;
} catch (error) {
return false;
}
}
/**
* Delega um comando para o PHP Provider
* @param {Object} payload - Payload do comando
* @private
*/
_delegateToPHPProvider(payload) {
try {
const PHPProvider = require('../php-provider');
const phpProvider = new PHPProvider(this.config);
return phpProvider.execute(payload);
} catch (error) {
return {
success: false,
error: `Erro ao delegar para PHP Provider: ${error.message}`,
timestamp: new Date().toISOString()
};
}
}
/**
* Faz upload de um site para um servidor FTP
* @param {Object} payload - Payload com as informações FTP
* @private
*/
async _uploadToFTP(payload) {
const FTPUploader = require('../ftp-uploader');
const uploader = new FTPUploader(this.config);
try {
const result = await uploader.uploadSite(payload);
return result;
} catch (error) {
return {
success: false,
error: `Erro ao fazer upload FTP: ${error.message}`,
timestamp: new Date().toISOString()
};
}
}
}
module.exports = MockProvider;