@wikibonsai/trug
v0.0.1
Published
A configuration handler for markdown-based PKM systems.
Maintainers
Readme
trug
Config handler that reads configs (config.toml) and returns a typed settings hash.
Supports both TOML and YAML formats.
🧰 Config the rig of your 🎋 WikiBonsai digital garden.
Install
npm install trugUsage
Load
Load configs from TOML or YAML files. Returns an empty object if the file doesn't exist.
loadConfig()
import { loadConfig } from 'trug';
import type { TrugConfig } from 'trug';
const config: TrugConfig = loadConfig('./config.toml');
// config = {
// garden: { title: 'wikibonsai', root: 'i.bonsai', index: 'file', ... },
// format: { case_title: 'Title Case', indent_size: 2, attrs: 'caml', ... },
// doc: { kind: { default: { path: '/' }, template: { prefix: 't.' }, ... }, ... },
// rel: { kind: { fam: { parent: { sync: 'hypernym' }, ... }, ... } },
// attr: { id: { size: 21 }, update: { open: 'open', ... } },
// }loadConfigFromString()
Parse a config string directly. Pass the file extension (.toml, .yaml, .yml) to select the parser.
import { loadConfigFromString } from 'trug';
const content: string = '[garden]\n'
+ 'title = "my-garden"\n'
+ 'root = "i.bonsai"\n';
const config: TrugConfig = loadConfigFromString(content, '.toml');
// config = {
// garden: { title: 'my-garden', root: 'i.bonsai' },
// }Defaults
Defaults can be read from package constants for testing and validation purposes.
import { DEFAULT_CONFIG, DEFAULT_GARDEN, DEFAULT_FORMAT, DEFAULT_DOC, DEFAULT_REL, DEFAULT_ATTR } from 'trug';
// section defaults (loaded from src/default/config.toml)
DEFAULT_GARDEN.title; // 'wikibonsai'
DEFAULT_FORMAT.indent_size; // 2
DEFAULT_DOC.kind?.template?.prefix; // 't.'
DEFAULT_REL.kind?.fam?.parent?.sync;// 'hypernym'
DEFAULT_ATTR.id?.size; // 21Checks
Validates config values and structure. Returns a CheckResult with errors (invalid values) and warnings (deprecated keys, missing sync targets). Optionally pass relData to cross-validate sync targets against known reltype names.
| Skip name | Level | Description |
|-----------|-------|-------------|
| deprecated-keys | warning | Warns if [lint] key exists (renamed to [format]) |
| format-values | error | Enum validation for case, indent, bullet, attrs fields |
| sync-targets | warning | Sync target values should reference known reltype names |
check()
import { check } from 'trug';
import type { CheckResult } from 'trug';
const result: CheckResult = check(config);
// result = {
// errors: [{ rule: 'format-values', message: 'case_title "INVALID" must be one of: ...' }],
// warnings: [{ rule: 'deprecated-keys', message: '[lint] is deprecated — rename to [format]' }],
// }
// or with reltype cross-validation:
const crossResult: CheckResult = check(config, relData);
// crossResult.warnings may include sync-target mismatchesSkip specific validators with the skip option:
const skipped: CheckResult = check(config, relData, { skip: ['deprecated-keys'] });
// skipped = { errors: [...], warnings: [...] } // deprecated-keys warnings omittedConfig Structure
Default config is included:
[garden]
title = "wikibonsai"
root = "i.bonsai"
index = "file"
confirm = true
save = "auto"
[auth]
mode = "user"
owner = ""
agent = ""
password = false
[format]
case_title = "Title Case"
case_file = "kabob-case"
mkdn_bullet = "dash"
indent_kind = "space"
indent_size = 2
attrs = "caml"
[doc]
[doc.kind]
[doc.kind.default]
path = "/"
color = "#3e5c50"
[doc.kind.template]
path = "/template/"
prefix = "t."
emoji = "🧩"
color = "#F8F0E3"
[doc.kind.zombie]
emoji = "🧟"
color = "#959DA5"
[doc.kind.media]
path = "/media/"
[doc.status]
[doc.status.orphan]
color = ""
[doc.status.isolate]
color = ""
[rel]
[rel.kind.fam]
[rel.kind.fam.parent]
sync = "hypernym"
[rel.kind.fam.child]
sync = "hyponym"
[rel.kind.ref]
sync = ["synonym", "antonym"]
[attr]
[attr.id]
alphabet = ""
size = 21
[attr.update]
open = "open"
[attr.update.timestamp]
create = "ctime"
modified = "mtime"
viewed = "vtime"
published = "ptime"
[attr.update.date]
create = "cdate"
modified = "mdate"
viewed = "vdate"
published = "pdate"Sections
[garden]
Garden identity and behavior.
title— garden name. String, defaults to"wikibonsai".root— root node filename. String, defaults to"i.bonsai".index— index storage mode."file","cache", or"db". Defaults to"file".confirm— prompt before destructive actions. Boolean, defaults totrue.save— save mode."auto"or"manual". Defaults to"auto".
[auth]
Access control.
mode— who is operating."user"or"agent". Defaults to"user".owner— owner name. String, defaults to"".agent— agent name. String, defaults to"".password— enable password protection. Boolean, defaults tofalse.
[format]
Formatting preferences.
attrs— attribute syntax."caml"or"yaml". Defaults to"caml".case_file— filename casing."Title Case","lower case","kabob-case", or"snake_case". Defaults to"kabob-case".case_title— title casing."Title Case","lower case","kabob-case", or"snake_case". Defaults to"Title Case".indent_kind— indentation character."space"or"tab". Defaults to"space".indent_size— indentation width. Positive integer, defaults to2.mkdn_bullet— markdown bullet style."dash","asterisk","plus", or"none". Defaults to"dash".
[doc]
Document kinds and statuses. Each sub-section accepts path, prefix, emoji, and color fields.
[doc.kind.default]— default doc kind.path = "/",color = "#3e5c50".[doc.kind.media]— media files.path = "/media/".[doc.kind.template]— template docs.path = "/template/",prefix = "t.",emoji = "🧩",color = "#F8F0E3".[doc.kind.zombie]— zombie docs (no backing file).emoji = "🧟",color = "#959DA5".
[rel]
Relationship kinds and sync mappings.
[rel.kind.fam.parent]— tree parent.sync = "hypernym".[rel.kind.fam.child]— tree child.sync = "hyponym".[rel.kind.ref]— ref sync.sync = ["synonym", "antonym"].
[attr]
Attribute automation.
[attr.id]— ID generation.alphabet = ""(empty = default nanoid alphabet),size = 21.[attr.update]— auto-updated attributes.open = "open".[attr.update.timestamp]— timestamp attribute names.create = "ctime",modified = "mtime",viewed = "vtime",published = "ptime".[attr.update.date]— date attribute names.create = "cdate",modified = "mdate",viewed = "vdate",published = "pdate".
