156 lines
5.3 KiB
JavaScript
156 lines
5.3 KiB
JavaScript
import { JSDOM } from 'jsdom';
|
|
import axios from 'axios';
|
|
import vm from 'vm';
|
|
|
|
// Cache para los scripts y appParser
|
|
let appParserCache = null;
|
|
let windowCache = null;
|
|
let scriptsCache = null;
|
|
|
|
/**
|
|
* Descarga y ejecuta los scripts remotos necesarios para appParser
|
|
* Igual que en el frontend (src/main.js)
|
|
*/
|
|
async function loadRemoteParser() {
|
|
if (appParserCache) {
|
|
return { appParser: appParserCache, window: windowCache };
|
|
}
|
|
|
|
const scripts = [
|
|
"https://cms.cocosolution.com/lib/plugins/builder_saas/js/lexer.js",
|
|
"https://cms.cocosolution.com/lib/plugins/builder_saas/js/mixins/vuecomponents.js",
|
|
"https://cms.cocosolution.com/lib/plugins/builder_saas/js/mixins/builderdata.js",
|
|
"https://cms.cocosolution.com/lib/plugins/builder_saas/js/mixins/filters.js",
|
|
"https://cms.cocosolution.com/lib/plugins/builder_saas/js/parseDocument.js",
|
|
];
|
|
|
|
// Crear un contexto jsdom
|
|
const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {
|
|
runScripts: "dangerously",
|
|
resources: "usable"
|
|
});
|
|
|
|
const window = dom.window;
|
|
const document = window.document;
|
|
|
|
// Mock de objetos necesarios que pueden no estar en jsdom
|
|
if (!window.btoa) {
|
|
window.btoa = (str) => Buffer.from(str).toString('base64');
|
|
}
|
|
if (!window.atob) {
|
|
window.atob = (str) => Buffer.from(str, 'base64').toString();
|
|
}
|
|
|
|
// Asegurar que DOMParser esté disponible (jsdom lo tiene en window)
|
|
// Pero también lo necesitamos como variable global para los scripts
|
|
const DOMParser = window.DOMParser;
|
|
|
|
// Mock de window.bus (puede que no sea necesario para el parseo)
|
|
if (!window.bus) {
|
|
window.bus = {
|
|
$emit: () => {},
|
|
$on: () => {},
|
|
$off: () => {}
|
|
};
|
|
}
|
|
|
|
// Crear contexto VM con todas las referencias necesarias
|
|
// Los scripts remotos esperan que window, document, DOMParser, etc. estén disponibles globalmente
|
|
const context = vm.createContext({
|
|
window: window,
|
|
document: document,
|
|
DOMParser: DOMParser, // Añadir DOMParser como variable global
|
|
console: console,
|
|
Buffer: Buffer,
|
|
setTimeout: setTimeout,
|
|
setInterval: setInterval,
|
|
clearTimeout: clearTimeout,
|
|
clearInterval: clearInterval,
|
|
// Añadir todas las propiedades globales necesarias
|
|
...global,
|
|
// Asegurar que las referencias estén disponibles también como variables globales
|
|
global: global,
|
|
process: process
|
|
});
|
|
|
|
// Descargar y ejecutar cada script
|
|
for (const scriptUrl of scripts) {
|
|
try {
|
|
console.log(`Descargando script: ${scriptUrl}`);
|
|
const response = await axios.get(scriptUrl, {
|
|
timeout: 10000 // 10 segundos de timeout
|
|
});
|
|
const scriptContent = response.data;
|
|
|
|
// Ejecutar el script en el contexto VM
|
|
// Los scripts pueden usar 'window', 'document', etc. directamente
|
|
vm.runInContext(scriptContent, context);
|
|
} catch (error) {
|
|
console.error(`Error cargando script ${scriptUrl}:`, error.message);
|
|
// Si falla un script crítico, lanzar error
|
|
if (scriptUrl.includes('parseDocument.js')) {
|
|
throw new Error(`Error crítico cargando parseDocument.js: ${error.message}`);
|
|
}
|
|
// Continuar con los demás scripts para los no críticos
|
|
}
|
|
}
|
|
|
|
// Verificar que appParser esté disponible
|
|
if (!window.appParser) {
|
|
throw new Error('appParser no se cargó correctamente desde los scripts remotos');
|
|
}
|
|
|
|
appParserCache = window.appParser;
|
|
windowCache = window;
|
|
scriptsCache = scripts;
|
|
|
|
return { appParser: appParserCache, window: windowCache };
|
|
}
|
|
|
|
/**
|
|
* Obtiene appParser, cargándolo si es necesario
|
|
*/
|
|
export async function getAppParser() {
|
|
const { appParser } = await loadRemoteParser();
|
|
return appParser;
|
|
}
|
|
|
|
/**
|
|
* Wrapper para parseComponents usando appParser remoto
|
|
* Usa tipo 2 (Twig) explícitamente
|
|
* Firma real: parseComponents(code, prefixVar, type = 0)
|
|
*/
|
|
export async function parseComponents(html, moduleIds = [], listTables = [], prefixVar = "", skipBuilderData = false) {
|
|
const { appParser, window } = await loadRemoteParser();
|
|
|
|
// Setear las variables globales en el window real donde se cargó appParser
|
|
window.allModules = moduleIds;
|
|
window.tables = listTables;
|
|
|
|
// La firma real es: parseComponents(code, prefixVar, type = 0)
|
|
// Pasamos 2 (número) para Twig explícitamente
|
|
return appParser.parseComponents(html, prefixVar, 2);
|
|
}
|
|
|
|
/**
|
|
* Wrapper para generateBuilderVars usando appParser remoto
|
|
* Usa tipo 2 (Twig) explícitamente, igual que en Api.js
|
|
* Nota: El código remoto falla si previousSchema es null, así que pasamos {} en su lugar
|
|
*/
|
|
export async function generateBuilderVars(code, previousSchema = null) {
|
|
const appParser = await getAppParser();
|
|
// Pasar 2 para Twig (igual que en Api.js: parseInt(type) donde type="2")
|
|
// El código remoto falla si previousSchema es null, así que usamos {} en su lugar
|
|
const safePreviousSchema = previousSchema || {};
|
|
return appParser.generateBuilderVars(code, 2, safePreviousSchema);
|
|
}
|
|
|
|
/**
|
|
* Limpia la caché (útil para forzar recarga)
|
|
*/
|
|
export function clearCache() {
|
|
appParserCache = null;
|
|
scriptsCache = null;
|
|
}
|
|
|