npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@agus01/node-red-contrib-monaco-editor

v1.1.0

Published

Nodo Node-RED con editor Monaco que incluye validación inteligente de sintaxis para múltiples lenguajes de programación

Downloads

9

Readme

node-red-contrib-monaco-editor

Un nodo Node-RED que integra el Monaco Editor (el mismo editor de VS Code) para edición de código con validación inteligente de sintaxis, soporte multi-lenguaje y autenticación flexible.

Descripción

Este nodo permite crear interfaces de edición de código web completas directamente desde Node-RED, generando páginas HTML dinámicas con un editor Monaco totalmente funcional. Incluye soporte para múltiples lenguajes de programación, validación sintáctica en tiempo real, y diversas opciones de autenticación para interactuar con endpoints remotos o archivos locales.

Características Principales

Editor Monaco Integrado

  • Editor de código profesional basado en VS Code
  • Tema oscuro optimizado para sesiones largas de codificación
  • IntelliSense con autocompletado y sugerencias contextuales
  • Minimapa para navegación rápida en archivos grandes
  • Ajuste de línea automático para mejor legibilidad

Soporte Multi-Lenguaje

Validación y resaltado de sintaxis para:

  • JavaScript (.js, .mjs, .cjs) - Validación completa con TypeScript compiler
  • JSON (.json) - Validación de estructura y sintaxis
  • HTML (.html, .htm) - Validación HTML5 completa
  • CSS (.css) - Validación de propiedades y sintaxis
  • XML (.xml) - Validación de estructura
  • Markdown (.md, .markdown) - Resaltado de sintaxis

Validación Inteligente de Sintaxis

JavaScript/TypeScript

  • Detección de variables no definidas (errores semánticos)
  • Validación de sintaxis ES2020+
  • Soporte para módulos ES6+
  • Ignorado inteligente de errores de importación no resueltos
  • Verificación de tipos con JSDoc (opcional)

HTML

  • Validación HTML5 completa
  • Detección de etiquetas no cerradas
  • Verificación de atributos válidos
  • Sugerencias de estructura correcta

JSON

  • Validación de sintaxis JSON estricta
  • Detección de comas finales o faltantes
  • Verificación de estructura de llaves/corchetes

Autenticación Flexible

Cuatro métodos de autenticación soportados:

  1. Ninguna - Sin autenticación
  2. Basic Auth - Usuario y contraseña
  3. Bearer Token - Token de autorización en headers
  4. Query Token - Token como parámetro en URL

Gestión de Archivos

  • Selector de archivos dinámico con carga desde endpoint
  • Guardado automático con detección de cambios
  • Protección contra pérdida de datos (confirmación antes de cerrar)
  • Indicador visual de cambios sin guardar
  • Botón de recarga para descartar cambios

Optimización de Rendimiento

  • Workers sin CSP blob para cumplir políticas de seguridad
  • Carga optimizada desde Node.js local o CDN (fallback)
  • Caché de assets con immutable y maxAge: 1y
  • Debouncing en detección de cambios (500ms)

Instalación

Desde la paleta de Node-RED

cd ~/.node-red
npm install node-red-contrib-monaco-editor

Desde directorio de proyecto

npm install node-red-contrib-monaco-editor

Desarrollo/Local

cd ~/.node-red
npm install /ruta/a/node-red-contrib-monaco-editor

Luego reinicia Node-RED.

Uso Básico

Configuración del Nodo

  1. Arrastra el nodo monaco-editor desde la categoría "function" a tu flujo
  2. Configura las propiedades según tus necesidades:

Propiedades Principales

| Propiedad | Descripción | También vía msg | |-----------|-------------|-----------------| | Nombre | Nombre descriptivo del nodo | - | | Tipo de contenido | Lenguaje del editor (js, json, xml, html, css) | msg.type | | Endpoint GET | URL para obtener contenido desde servidor | msg.endpointget | | Endpoint SET | URL para guardar contenido en servidor | msg.endpointset | | Archivo de contenido | Ruta local al archivo a editar | msg.pathtocontent |

Configuración de Autenticación

| Tipo | Propiedades | También vía msg | |------|-------------|-----------------| | Basic Auth | Usuario y Contraseña | msg.basicuser, msg.basicpass | | Bearer Token | Token de autorización | msg.authtoken | | Query Token | Token y nombre del parámetro | msg.authtoken, msg.tokenParam |

Ejemplo de Flujo Simple

[
    {
        "id": "inject1",
        "type": "inject",
        "name": "Abrir Editor",
        "topic": "",
        "payload": "// Mi código inicial\nconsole.log('Hola mundo');",
        "wires": [["monaco1"]]
    },
    {
        "id": "monaco1",
        "type": "monaco-editor",
        "name": "Editor JavaScript",
        "type": "js",
        "endpointget": "http://localhost:1880/api/code/load",
        "endpointset": "http://localhost:1880/api/code/save",
        "authtype": "none",
        "wires": [["http1"]]
    },
    {
        "id": "http1",
        "type": "http response",
        "name": "Respuesta HTTP",
        "wires": []
    }
]

📘 Ejemplos de Uso

Ejemplo 1: Editor Simple con Contenido Inicial

// Inyectar contenido inicial
msg.payload = "function suma(a, b) {\n    return a + b;\n}";
msg.type = "js";
return msg;

Ejemplo 2: Editor con Archivo Local

msg.pathtocontent = "/ruta/al/archivo/script.js";
msg.type = "js";
return msg;

Ejemplo 3: Editor con API Remota y Basic Auth

msg.endpointget = "https://api.ejemplo.com/code/load";
msg.endpointset = "https://api.ejemplo.com/code/save";
msg.authtype = "basic";
msg.basicuser = "usuario";
msg.basicpass = "contraseña";
msg.type = "json";
return msg;

Ejemplo 4: Editor con Bearer Token

msg.endpointget = "https://api.ejemplo.com/files/load";
msg.endpointset = "https://api.ejemplo.com/files/save";
msg.authtype = "bearer";
msg.authtoken = "mi-token-secreto-123";
msg.type = "html";
return msg;

Ejemplo 5: Múltiples Archivos desde API

// El editor automáticamente llamará a /api/code/files para listar archivos
msg.endpointget = "http://localhost:1880/api/code/load";
msg.endpointset = "http://localhost:1880/api/code/save";
msg.authtype = "querytoken";
msg.authtoken = "abc123";
msg.tokenParam = "apikey";
msg.type = "js";
return msg;

🔌 API de Endpoints

GET - Cargar Contenido

URL: {endpointget}?filename={nombre_archivo}

Headers:

Content-Type: application/json
Authorization: Basic/Bearer (según configuración)

Query Params (Query Token):

?token=abc123 (o el nombre personalizado en tokenParam)

Respuesta esperada:

{
    "content": "contenido del archivo...",
    "filename": "script.js"
}

POST - Guardar Contenido

URL: {endpointset}?filename={nombre_archivo}

Headers:

Content-Type: application/json
Authorization: Basic/Bearer (según configuración)

Body:

{
    "content": "nuevo contenido...",
    "code": "nuevo contenido...",
    "filename": "script.js"
}

GET - Listar Archivos

URL: {endpointget sin /load}/files

Ejemplo: Si endpointget es /api/code/load, el endpoint de archivos será /api/code/files

Respuesta esperada:

{
    "files": [
        { "name": "script1.js" },
        { "name": "config.json" },
        { "name": "styles.css" }
    ]
}

O formato simplificado:

["script1.js", "config.json", "styles.css"]

Configuración Avanzada

Workers de Monaco

El nodo configura automáticamente los workers especializados para cada lenguaje:

  • JavaScript/TypeScript: typescriptWorker.js
  • HTML: htmlWorker.js
  • CSS/SCSS/LESS: cssWorker.js
  • JSON: jsonWorker.js
  • Editor base: monaco-worker.js

Los workers se sirven desde:

  • Local: /monaco-vs/vs/* (cuando monaco-editor está instalado)
  • CDN Fallback: https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.1/

Opciones de Validación JavaScript

// Configuración interna del nodo (no modificable sin editar código)
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
    target: monaco.languages.typescript.ScriptTarget.ES2020,
    allowNonTsExtensions: true,
    moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
    module: monaco.languages.typescript.ModuleKind.ESNext,
    allowJs: true,
    checkJs: true, // Validación semántica activada
    skipLibCheck: true
});

Detección Automática de Lenguaje

El editor detecta automáticamente el lenguaje basándose en la extensión del archivo:

// Mapeo interno
.js, .mjs, .cjs  → JavaScript
.json            → JSON
.html, .htm      → HTML
.css             → CSS
.xml             → XML
.md, .markdown   → Markdown

Arquitectura Técnica

Estructura del Proyecto

node-red-contrib-monaco-editor/
├── monaco.html          # Definición del nodo en Node-RED UI
├── monaco.js            # Lógica del nodo en Node.js
├── package.json         # Metadata y dependencias
└── README.md           # Este archivo

Flujo de Datos

Usuario → Inyecta msg → Nodo Monaco → Genera HTML → HTTP Response
                            ↓
                    Configura opciones
                    (endpoints, auth, tipo)
                            ↓
                    Sirve Monaco assets
                    (workers, VS loader)
                            ↓
                    Cliente web carga editor
                            ↓
                    Interactúa con endpoints
                    (GET/POST archivos)

Componentes Clave

1. monaco.html - Configuración UI

  • Define la interfaz de configuración del nodo
  • Campos dinámicos según tipo de autenticación
  • Validación de inputs
  • Tooltips y ayuda contextual

2. monaco.js - Lógica del Servidor

  • Montaje de assets estáticos: Sirve Monaco desde node_modules
  • Generación HTML dinámica: Crea el HTML del editor con configuración embebida
  • Sistema de syntax providers: Gestión de lenguajes soportados
  • Detección de lenguaje: Por extensión de archivo
  • Gestión de workers: Sin uso de blob: para compatibilidad CSP

3. Editor HTML Generado - Cliente Web

  • Interfaz del editor: Monaco embebido con toolbar
  • Gestión de estado: Detección de cambios, dirty flag
  • Comunicación con endpoints: Fetch API con autenticación
  • Selector de archivos: Listado y carga dinámica
  • Prevención de pérdida: Confirmación antes de cerrar

Opciones de Configuración del Editor

Opciones Monaco Predefinidas

{
    automaticLayout: true,        // Ajuste automático al contenedor
    minimap: { enabled: true },   // Minimapa visible
    theme: 'vs-dark',             // Tema oscuro
    fontSize: 14,                 // Tamaño de fuente
    lineNumbers: 'on',            // Números de línea
    wordWrap: 'on',               // Ajuste de línea
    suggestOnTriggerCharacters: true,
    quickSuggestions: {
        other: true,
        comments: false,
        strings: false
    }
}

Atajos de Teclado

| Atajo | Acción | |-------|--------| | Ctrl/Cmd + S | Guardar archivo | | Ctrl/Cmd + Z | Deshacer | | Ctrl/Cmd + Y | Rehacer | | Ctrl/Cmd + F | Buscar | | Ctrl/Cmd + H | Buscar y reemplazar | | F1 | Paleta de comandos |

Depuración y Logs

Logs del Servidor (Node-RED)

El nodo emite logs en la consola de Node-RED:

[Monaco Worker] editor (local) baseUrl= /monaco-vs/
[Monaco Worker] json (local) baseUrl= /monaco-vs/
[DEBUG] after setModelLanguage(javascript) { langId: 'javascript', ... }

Logs del Cliente (Navegador)

Abre la consola del navegador (F12) para ver:

Monaco Editor Config: { language: 'javascript', endpointGet: '...' }
loadFileList() - Iniciando carga de archivos...
[Markers update][current] { uri: '...', count: 2, markers: [...] }
[HTML markers recargados] [...]

Utilidad de Depuración

El editor expone una utilidad global en la consola del navegador:

// Ver estado actual del editor
window.monacoDebug.debugState('mi-tag');

// Ver markers (errores/advertencias)
window.monacoDebug.getCurrentMarkers();

// Ver lenguajes disponibles
window.monacoDebug.getLanguages();

Seguridad

Content Security Policy (CSP)

El nodo evita el uso de blob: URLs para los workers, siendo compatible con políticas CSP estrictas:

Content-Security-Policy: script-src 'self' 'unsafe-eval'

Recomendaciones de Seguridad

  1. Usa HTTPS para endpoints remotos
  2. Almacena tokens en variables de entorno, no en el flujo
  3. Valida entrada en tus endpoints antes de guardar archivos
  4. Limita permisos de escritura en el sistema de archivos
  5. Implementa rate limiting en tus APIs

📊 Mensajes de Entrada y Salida

Mensaje de Entrada (msg)

{
    payload: "código inicial",     // Contenido inicial del editor
    type: "js",                    // Tipo de contenido (js, json, html, css, xml)
    endpointget: "/api/load",      // Endpoint GET
    endpointset: "/api/save",      // Endpoint POST
    pathtocontent: "/ruta/file.js", // Archivo local
    authtype: "bearer",            // Tipo de autenticación
    authtoken: "token123",         // Token de autenticación
    basicuser: "user",             // Usuario (basic auth)
    basicpass: "pass",             // Contraseña (basic auth)
    tokenParam: "apikey"           // Nombre parámetro token (query)
}

Mensaje de Salida (msg)

{
    payload: "<html>...</html>",   // HTML completo del editor
    editorConfig: {
        language: "javascript",
        endpoints: {
            get: "/api/load",
            set: "/api/save"
        },
        authentication: "bearer",
        filePath: "/ruta/file.js"
    }
}

🧪 Testing

Prueba Básica

  1. Crea un flujo con:
    • Nodo injectmonaco-editorhttp response
  2. Configura un endpoint HTTP GET en el puerto que uses
  3. Inyecta el mensaje
  4. Abre el navegador en la URL configurada

Servidor de Prueba

// Ejemplo de servidor Express simple para testing
const express = require('express');
const app = express();
app.use(express.json());

let codeStorage = {
    'test.js': 'console.log("Hola mundo");',
    'config.json': '{\n  "nombre": "prueba"\n}'
};

// Listar archivos
app.get('/api/code/files', (req, res) => {
    res.json({ 
        files: Object.keys(codeStorage).map(name => ({ name }))
    });
});

// Cargar archivo
app.get('/api/code/load', (req, res) => {
    const filename = req.query.filename;
    res.json({
        content: codeStorage[filename] || '',
        filename: filename
    });
});

// Guardar archivo
app.post('/api/code/save', (req, res) => {
    const { filename, content } = req.body;
    codeStorage[filename] = content;
    res.json({ success: true });
});

app.listen(1880, () => console.log('Server on port 1880'));

Changelog

v1.1.0

  • Validación completa de JavaScript con detección de variables no definidas
  • Validación HTML5 con detección de etiquetas y atributos
  • Sistema de syntax providers extensible
  • Soporte para múltiples archivos desde endpoint
  • Workers sin blob para compatibilidad CSP
  • Debouncing en detección de cambios
  • Protección contra pérdida de datos
  • Corrección de carga de workers HTML
  • Mejoras en detección de lenguaje por extensión

v1.0.0

  • Lanzamiento inicial
  • Integración de Monaco Editor
  • Soporte multi-lenguaje (JS, JSON, HTML, CSS, XML)
  • Autenticación flexible (none, basic, bearer, query token)
  • Carga/guardado desde endpoints
  • Lectura de archivos locales

Licencia

MIT License - Ver archivo LICENSE para más detalles