Docs · npm

Node.js

El paquete donly es un módulo ESM con tipos de TypeScript. Permite parsear texto DON, recorrer y buscar directivas, convertirlas a JSON, validarlas con reglas de lint y extender el parseo con plugins.

Instalación

$ npm i donly

El manifiesto declara bun >=1.0.0 en engines. Los ejemplos de esta página se ejecutaron con Node.js 22.

Parsear un documento

Todos los ejemplos usan este documento app.donly:

name "my-app"
port 8080
enabled true

server {
  host "example.com"
  route GET /home {
    respond 200
  }
  route POST /api/user
}

DON.parse(text) devuelve una Directive. Con varias directivas de primer nivel devuelve una raíz sintética (su nombre es el símbolo ROOT_DIRECTIVE_NAME) que las contiene como children. Con una sola, devuelve esa directiva.

import { DON } from "donly";

const root = DON.parse(text);

for (const directive of root.children) {
  console.log(directive.name, directive.args);
}
// name [ 'my-app' ]
// port [ 8080 ]
// enabled [ true ]
// server []

Directive

Buscar directivas

find devuelve la primera coincidencia, findAll todas, y at permite terminar el camino en [N] para obtener un argumento. Las posiciones empiezan en 1. Los grupos ( ) comparan todos los argumentos de la directiva, y { } filtra por descendientes.

root.find("/server/host")?.args;      // [ 'example.com' ]
root.at("/server/host[1]");           // 'example.com'
root.findAll("/server/route").length; // 2

// Una directiva con hijos que cumplan un camino
root.findAll("/server/route{/respond}").length; // 1

// Coincidencia completa de los argumentos
root.findAll("/server/route(GET /home)").length;    // 1
root.findAll("/server/route(* /api/user)").length;  // 1

Las mismas funciones están disponibles como findDirective, findAllDirectives y atDirective en donly/find.

Convertir a JSON

JSON.stringify usa toJSON, que agrupa por el primer argumento (tupleReducer). Con DirectiveJSONEncoder eliges el reducer: nestedReducer anida cada argumento como una clave, y reducer: null devuelve la forma completa { name, args, children }.

import { DON, DirectiveJSONEncoder } from "donly";

JSON.stringify(root);
// {"name":"my-app","port":8080,"enabled":true,
//  "server":{"host":"example.com",
//    "route":[["GET","/home",{"respond":200}],["POST","/api/user"]]}}

DirectiveJSONEncoder.encode(root, {
  reducer: DirectiveJSONEncoder.nestedReducer,
});
// {"name":"my-app","port":8080,"enabled":true,
//  "server":{"host":"example.com",
//    "route":[{"GET":{"/home":{"respond":200}}},{"POST":"/api/user"}]}}

Cargar un archivo

load lee el archivo y devuelve un objeto plano con el reducer anidado.

import { load } from "donly/load";

const config = await load("./app.donly");
// { name: 'my-app', port: 8080, enabled: true, server: { ... } }

Errores de sintaxis

Un documento inválido hace que DON.parse lance un error con el motivo.

import { DON } from "donly";

try {
  DON.parse('container { image "nginx" } extra');
} catch (error) {
  console.error(error.message);
  // Syntax error: tokens after block close are not allowed on the same line (found "extra")
}

Lint

lint(text, rules) valida un documento contra un objeto de reglas y devuelve una lista de issues (vacía si todo es válido). renderReport la formatea para la terminal y renderJSONReport en JSON. Las reglas también pueden escribirse en un archivo .donly y cargarse con parseLintRulesDonly. La CLI npx donly lint usa esta misma API.

import { lint, renderReport } from "donly/lint";

const rules = {
  "/": {
    "/port": { "[1]": { type: "string" } },
  },
};

const issues = lint(text, rules);

console.log(renderReport(issues, { filePath: "app.donly" }));
// app.donly
//   2:6  error  argument at position 1 must be of type string
//
// 1 error 0 warnings 0 info

Plugins

DON.parse(text, { plugins }) acepta una lista de DonPlugin. Cada plugin tiene un name y puede definir initContext, para crear su estado en cada parseo, y onDirective, que recibe cada directiva en orden de lectura. Puede devolver un nodo nuevo para cambiar sus argumentos o null para eliminarla junto con sus hijos.

Importaciones

Módulo Exporta
donly DON, Directive, HeredocValue, DirectiveJSONEncoder, DirectiveJSONDecoder, ROOT_DIRECTIVE_NAME, SyntaxEncode, LexerParser, SyntaxKind, donToParts
donly/load load(filePath): lee un archivo y devuelve un objeto
donly/find findDirective, findAllDirectives, atDirective
donly/encoder DirectiveJSONEncoder
donly/decoder DirectiveJSONDecoder
donly/utils inspect(directive, strategy)
donly/lint lint, parseLintRulesDonly, renderReport, renderJSONReport
donly/common/errors DonSyntaxError
donly/plugins/scoped-variables scopedVariablesPlugin, createScopedVariablesPlugin

Referencia