Kdljs
JavaScript KDL library
Install / Use
/learn @kdl-org/KdljsREADME
KDL-JS
A JavaScript library for the KDL Document Language.
Install
npm install kdljs
Usage
Parsing
const { parse } = require('kdljs')
parse(`
// Nodes can be separated into multiple lines
title \
"Some title"
`)
// [
// {
// name: 'title',
// properties: {},
// values: [ 'Some title' ],
// children: [],
// tags: {
// name: undefined,
// properties: {},
// values: [ undefined ]
// }
// }
// ]
parse(`
// Files must be utf8 encoded!
smile "😁"
`)
// [
// {
// name: 'smile',
// properties: {},
// values: [ '😁' ],
// children: [],
// tags: {
// name: undefined,
// properties: {},
// values: [ undefined ]
// }
// }
// ]
parse(`
// Instead of anonymous nodes, nodes and properties can be wrapped
// in "" for arbitrary node names.
"!@#$@$%Q#$%~@!40" "1.2.3" "!!!!!"=#true
`)
// [
// {
// name: '!@#$@$%Q#$%~@!40',
// properties: { '!!!!!': true },
// values: [ '1.2.3' ],
// children: [],
// tags: {
// name: undefined,
// properties: { '!!!!!': undefined },
// values: [ undefined ]
// }
// }
// ]
parse(`
// The following is a legal bare identifier:
foo123~!@$%^&*.:'|?+ "weeee"
// And you can also use unicode!
ノード お名前="☜(゚ヮ゚☜)"
`)
// [
// {
// name: "foo123~!@$%^&*.:'|?+",
// properties: {},
// values: [ 'weeee' ],
// children: [],
// tags: {
// name: undefined,
// properties: {},
// values: [ undefined ]
// }
// },
// {
// name: 'ノード',
// properties: { 'お名前': '☜(゚ヮ゚☜)' },
// values: [],
// children: [],
// tags: {
// name: undefined,
// properties: {},
// values: []
// }
// }
// ]
parse(`
// kdl specifically allows properties and values to be
// interspersed with each other, much like CLI commands.
foo bar=#true "baz" quux=#false 1 2 3
`)
// [
// {
// name: 'foo',
// properties: { bar: true, quux: false },
// values: [ 'baz', 1, 2, 3 ],
// children: [],
// tags: {
// name: undefined,
// properties: { bar: undefined, quux: undefined },
// values: [ undefined, undefined, undefined, undefined ]
// }
// }
// ]
parse(`
// kdl also allows for annotationg values with types, and
// for denoting relations between nodes.
package {
(author)person contact=(email)"example@example.org"
(contributor)person homepage=(url)"https://example.org/example"
}
`)
// [
// {
// name: 'package',
// properties: {},
// values: [],
// children: [
// {
// name: 'person',
// properties: { contact: 'example@example.org' },
// values: [],
// children: [],
// tags: {
// name: 'author',
// properties: { contact: 'email' },
// values: []
// }
// },
// {
// name: 'person',
// properties: { homepage: 'https://example.org/example' },
// values: [],
// children: [],
// tags: {
// name: 'contributor',
// properties: { homepage: 'url' },
// values: []
// }
// }
// ],
// tags: { name: undefined, properties: {}, values: [] }
// }
// ]
Querying
const { parse, query } = require('kdljs')
const { output: document } = parse(`package {
name "foo"
version "1.0.0"
dependencies platform="windows" {
winapi "1.0.0" path="./crates/my-winapi-fork"
}
dependencies {
miette "2.0.0" dev=#true
}
}`)
query(document, 'package >> name') // or
query(document, 'top() > package >> name')
// [
// {
// name: 'name',
// values: ['foo'],
// ...
// }
// ]
query(document, 'dependencies')
// [
// {
// name: 'dependencies',
// properties: { platform: 'windows' },
// ...
// },
// {
// name: 'dependencies',
// ...
// }
// ]
query(document, 'dependencies[platform]') // or
query(document, 'dependencies[prop(platform)]')
// [
// {
// name: 'dependencies',
// properties: { platform: 'windows' },
// ...
// }
// ]
query(document, 'dependencies > []')
// [
// {
// name: 'winapi',
// properties: { path: './crates/my-winapi-fork' },
// values: [ '1.0.0' ],
// ...
// },
// {
// name: 'miette',
// properties: { dev: 'true' },
// values: [ '2.0.0' ],
// ...
// }
// ]
// MAP OPERATOR
// ============
query(document, 'package >> name => val()')
// ['foo'].
query(document, 'dependencies[platform] => platform')
// ['windows']
query(document, 'dependencies > [] => (name(), val(), path)')
// [('winapi', '1.0.0', './crates/my-winapi-fork'), ('miette', '2.0.0', None)]
query(document, 'dependencies > [] => (name(), values(), props())')
// [('winapi', ['1.0.0'], {'platform': 'windows'}), ('miette', ['2.0.0'], {'dev': true})]
Formatting
const { format } = require('kdljs')
format([
{
name: 'title',
properties: {},
values: [ 'Some title' ],
children: [],
tags: { properties: {}, values: [] }
},
{
name: 'smile',
properties: {},
values: [ '😁' ],
children: [],
tags: { properties: {}, values: [] }
},
{
name: '!@#$@$%Q#$%~@!40',
properties: { '!!!!!': true },
values: [ '1.2.3' ],
children: [],
tags: { properties: {}, values: [] }
},
{
name: "foo123~!@#$%^&*.:'|/?+",
properties: {},
values: [ 'weeee' ],
children: [],
tags: { properties: {}, values: [] }
},
{
name: 'ノード',
properties: { 'お名前': '☜(゚ヮ゚☜)' },
values: [],
children: [],
tags: { properties: {}, values: [] }
},
{
name: 'foo',
properties: { bar: true, quux: false },
values: [ 'baz', 1, 2, 3 ],
children: [],
tags: { properties: {}, values: [] }
}
])
`title "Some title"
smile "😁"
"!@#$@$%Q#$%~@!40" "1.2.3" !!!!!=true
foo123~!@#$%^&*.:'|/?+ "weeee"
ノード お名前="☜(゚ヮ゚☜)"
foo "baz" 1 2 3 bar=true quux=false
`
License
The code is available under the MIT license. The example above is
made available from https://github.com/kdl-org/kdl under
Creative Commons Attribution-ShareAlike 4.0 International.
The submodule in test/kdl4j is licensed according to its LICENSE.md file.
Related Skills
node-connect
345.9kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
106.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
345.9kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
345.9kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
