yetter
v2.1.0
Published
A YAML update library with multi-document support and typed JSONPath-like node setters.
Readme
A multi-format config/query toolkit with:
- Modules for YAML (
yq), XML (xq), JSON (jq) and TOML (tq) setandgetAPIs in all modules- JSONPath-style navigation with filters and wildcards
- Type coercion for writes (
string,number,boolean,null,array,object) - Compatibility with Node.js and browsers
- Non-destructive
setoperations that preserve comments and formatting in supported formats
Installation
npm i yetterInstallation Shortcuts
# npm
npm i yetter
# pnpm
pnpm add yetter
# yarn
yarn add yetter
# bun
bun add yetterAPI
yetter exports module namespaces and root shortcuts:
import {
yq,
xq,
jq,
tq,
yqSet,
yqGet,
xqSet,
xqGet,
jqSet,
jqGet,
tqSet,
tqGet,
} from 'yetter'Modules
yq (YAML)
Functions:
yq.setYamlValues(yamlContent, operations, options?)yq.getYamlValues(yamlContent, path, options?)- Aliases:
yq.set,yq.get
Options:
set:{ prettyErrors?: boolean }get:{ prettyErrors?: boolean }
Extra (YAML only):
- Multi-document selector with
$doc[n]and$doc[?(...)]
YAML set operations preserve comments, separators, and untouched formatting.
Example:
import { yq } from 'yetter'
const input = `service:
name: first
---
service:
name: second
`
const output = yq.set(input, [
{ path: '$doc[1].service.name', value: 'changed', valueType: 'string' },
])
const values = yq.get(output, '$.service.name')
// ['first', 'changed']xq (XML)
Functions:
xq.setXmlValues(xmlContent, operations, options?)xq.getXmlValues(xmlContent, path, options?)- Aliases:
xq.set,xq.get
Options:
set:{ prettyPrint?: boolean }get:{ prettyPrint?: boolean }
XML attribute note:
- Attributes are represented as keys prefixed with
@_(for examplekind="core"becomes@_kind)
XML set operations preserve comments and the document structure.
Example:
import { xq } from 'yetter'
const xml = `<root><services><service kind="core"/><service kind="edge"/></services></root>`
const output = xq.set(xml, [
{
path: '$.root.services.service[?(@["@_kind"]=="core")]["@_kind"]',
value: 'platform',
valueType: 'string',
},
])
const values = xq.get(output, '$.root.services.service[]["@_kind"]')
// ['platform', 'edge']jq (JSON)
Functions:
jq.setJsonValues(jsonContent, operations, options?)jq.getJsonValues(jsonContent, path, options?)- Aliases:
jq.set,jq.get
Options:
set:{ prettyPrint?: boolean }get:{ prettyPrint?: boolean }
Example:
import { jq } from 'yetter'
const json = JSON.stringify({
apps: [
{ name: 'app1', ready: false },
{ name: 'app2', ready: false },
],
})
const output = jq.set(json, [
{ path: "$.apps[?(@.name=='app1')].ready", value: 'true', valueType: 'boolean' },
])
const values = jq.get(output, '$.apps[].ready')
// [true, false]JSON set operations preserve comments and formatting when using JSONC-style input.
tq (TOML)
Functions:
tq.setTomlValues(tomlContent, operations, options?)tq.getTomlValues(tomlContent, path, options?)- Aliases:
tq.set,tq.get
Options:
set:{ prettyPrint?: boolean }get:{ prettyPrint?: boolean }
Example:
import { tq } from 'yetter'
const toml = `[[apps]]
name = "app1"
ready = false
[[apps]]
name = "app2"
ready = false
`
const output = tq.set(toml, [
{ path: "$.apps[?(@.name=='app1')].ready", value: 'true', valueType: 'boolean' },
])
const values = tq.get(output, '$.apps[].ready')
// [true, false]TOML set operations preserve comments, whitespace, and formatting.
Operation Types
All set methods accept operation arrays with this shape:
type ValueType = 'string' | 'number' | 'boolean' | 'null' | 'array' | 'object'
interface SetOperation {
path: string
value: unknown
valueType: ValueType
}Path Syntax
Supported navigation patterns:
$.app.name$.services[0].image$["api"]["base-url"]$.items[]$.items[*]$.items[?(@.enabled==true)]
YAML-only document selectors:
$doc[1].app.name$doc[?(@.kind=='Component')].metadata.name
Filters
Filter expressions are evaluated by jsonpath-plus.
Use explicit references like @.field and $.
Supported in filters:
- Comparisons:
==,!=,>,<,>=,<= - Logical operators:
&&,|| - Literals:
string,number,boolean,null
Breaking change in v2.0:
- Legacy shorthand filters like
kind=='Component'are no longer supported. - Use
@.kind=='Component'instead.
Not supported in path syntax:
- Slices (
[1:3])
Root Shortcut Exports
You can call set/get directly from root exports:
import { yqSet, yqGet, jqSet, jqGet } from 'yetter'
const output = yqSet('app:\n name: old\n', [
{ path: '$.app.name', value: 'new', valueType: 'string' },
])
const values = yqGet(output, '$.app.name')
// ['new']
const jsonOut = jqSet('{"a":1}', [
{ path: '$.a', value: '2', valueType: 'number' },
])
const jsonValues = jqGet(jsonOut, '$.a')
// [2]Development
npm test
npm run build