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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@homedev/objector

v1.3.51

Published

object extensions for YAML/JSON

Downloads

757

Readme

@homedev/objector

Object processing library for YAML/JSON with support for includes, field processors, conditional logic, and extensibility.

Overview

Objector is a comprehensive tool for loading, processing, and transforming YAML/JSON documents with advanced features like:

  • 🔄 Document includes and composition
  • 🔌 Extensible field processors and data sources
  • 🎯 Conditional logic and flow control
  • 📦 Module system with custom functions
  • 🔍 Variable substitution and selectors
  • 📝 Output generation and file writing
  • 🎨 Template inheritance and extensions

Installation

bun add @homedev/objector
# or
npm install @homedev/objector
# or
pnpm add @homedev/objector

Quick Start

import { Objector } from '@homedev/objector'

const objector = new Objector()

// Load and process a YAML/JSON file
const result = await objector.load('config.yaml')
import { Objector } from '@homedev/objector'

const objector = new Objector()
      .variables({ env: 'production', version: '1.0.0' }) // Add custom variables
      .include('settings.yaml') // Include additional files

// Process the document
const processed = await objector.load('main.yaml')

Built-in Keys

Keys are object properties prefixed with . and are used for structure/flow control.

  • .output - Register output payload(s)
  • .load - Load one or more additional files
  • .each - Repeat a model over a source list
  • .map - Map a source list into a transformed list
  • .from - Resolve a selector/reference into current node
  • .concat - Concatenate arrays from selectors
  • .extends - Merge from one or many templates
  • .group - Expand grouped items into parent list
  • .if - Conditional branch using .then / .else
  • .switch - Case-based branching with cases / default
  • .skip - Remove parent when condition is true
  • .metadata - Attach metadata for a path
  • .modules - Register source functions from inline JS modules
  • .try - Guard expression with optional .catch
  • .let - Introduce temporary variables into context
  • .tap - Debug current path/value to console

Built-in Data Sources

Sources are used with $() syntax.

Core Sources

  • Files: include, exists, file, scan
  • String/format: substring, repeat, pad, formatAs
  • List: merge, join, range, filter
  • Conditions: if, check, and, or, xor, true, false, eq, ne, lt, le, gt, ge, in, notin, contains, notcontains, containsi, notcontainsi, null, notnull, empty, notempty, nullorempty, notnullorempty
  • Types: convert, isType, typeOf
  • Flow helpers: each, switch, default

Built-in Macro Sources

These are also available as $() sources by default.

  • String/text: env, uuid, pascal, camel, capital, snake, kebab, len, reverse, concat, trim, ltrim, rtrim, lower, upper, encode, decode
  • Collection/object: list, object, unique, groupBy, chunk, flatten, compact, head, tail
  • Path/filepath: pathJoin, resolve, dirname, basename, normalize, extname, relative, isAbsolute, segments
  • Hash/encoding: md5, sha1, sha256, sha512, hash, hmac, base64Encode, base64Decode, hexEncode, hexDecode
  • Math: add, subtract, multiply, divide, modulo, power, sqrt, abs, floor, ceil, round, min, max, clamp, random
  • Date/time: timestamp, iso, utc, formatDate, parseDate, year, month, day, dayOfWeek, hours, minutes, seconds
  • Regex: regexTest, regexMatch, regexMatchAll, regexReplace, regexReplaceAll, regexSplit, regexExec, regexSearch
  • Validation/predicates: isEmail, isUrl, isJson, isUuid, minLength, maxLength, lengthEquals, isNumber, isString, isBoolean, isArray, isObject, isEmpty, isTruthy, isFalsy, inRange, matchesPattern, includes, startsWith, endsWith
  • Debug: log

API Reference

Objector Class

Constructor

const objector = new Objector()

Configuration Methods

  • use(handler: (o: Objector) => void): this
    Apply a configuration handler

  • includeDirectory(...dirs: string[]): this
    Add directories to search for includes

  • include(...files: string[]): this
    Add include files directly

  • keys(keys: FieldProcessorMap): this
    Add or override key processors

  • sources(sources: FieldProcessorMap): this
    Add or override data sources

  • variables(vars: Record<string, any>): this
    Set global variables

  • fieldOptions(options: ProcessFieldsOptions): this
    Customize field processing behavior

  • filter(f: RegExp): this
    Add a filter for field processing

  • output(o: Output): this
    Add an output definition

  • metadata(path: string, value: unknown): this
    Store metadata for a path

  • encoders(encoders: Record<string, Encoder>): this
    Add output encoders (used by formatAs)

  • decoders(decoders: Record<string, LoadFormatParser>): this
    Add input decoders for load()

  • setCacheMaxSize(size: number): this
    Set include/content cache size

  • clearCache(): this
    Clear cached loaded content

Processing Methods

  • async load<T>(fileName: string, cwd?: string, container?: any, noProcess?: boolean): Promise<T | null>
    Load and process a file

  • async loadObject<T>(data: T, container?: any, options?: LoadObjectOptions): Promise<T>
    Process an object with field processors

  • async writeAll(options?: WriteOutputsOption): Promise<void>
    Write all registered outputs to disk

Query Methods

  • getIncludeDirectories(): string[]
    Get all include directories

  • getFunctions(): Record<string, AsyncFunction>
    Get registered functions

  • getOutputs(): Output[]
    Get all registered outputs

  • getMetadata(path: string): any
    Get metadata for a path

  • getAllMetadata(): Record<string, any>
    Get all metadata

  • getCurrentContext(): LoadContext | null
    Get current processing context

  • getEncoder(name: string): Encoder | undefined
    Get an encoder by name

  • getDecoder(name: string): LoadFormatParser | undefined
    Get a decoder by name

Advanced Usage

Custom Data Sources

import { Objector } from '@homedev/objector'

const objector = new Objector()

objector.sources({
  // Simple value source
  timestamp: () => Date.now(),
  
  // Source with arguments
  add: (ctx) => {
    const [a, b] = ctx.args
    return a + b
  },
  
  // Async source
  fetchData: async (ctx) => {
    const url = ctx.args[0]
    const response = await fetch(url)
    return response.json()
  }
})

Usage:

data:
  created: $(timestamp)
  sum: $(add:10, 20)
  remote: $(fetchData:"https://api.example.com/data")

Custom Key Processors

objector.keys({
  // Custom transformation key
  uppercase: (ctx) => {
    return ctx.value.toUpperCase()
  },
  
  // Conditional key
  when: (ctx) => {
    const condition = ctx.value
    if (!condition) {
      return NavigateResult.DeleteParent()
    }
    return NavigateResult.DeleteItem()
  }
})

Usage:

settings:
  name:
    .uppercase: hello world
    # Result: "HELLO WORLD"

feature:
  .when: $(eq:env, "production")
  enabled: true
  # Only included when condition is true

Metadata Collection

const objector = new Objector()

// Metadata is collected during processing
await objector.load('config.yaml')

// Retrieve metadata
const metadata = objector.getMetadata('some.path')
const allMetadata = objector.getAllMetadata()

In documents:

service:
  .metadata:
    version: 1.0
    author: team-a
  name: api
  port: 8080

FAQ

Q: How do I debug field processing?
A: Use the $(log:message) data source to print values during processing.

Q: Can I use async operations in custom sources?
A: Yes! All field processors and data sources support async/await.

Q: How do I handle circular includes?
A: The system tracks included files to prevent circular dependencies.

Q: Can I extend the built-in processors?
A: Yes, use objector.keys() and objector.sources() to add or override processors.

Q: How do I access nested values?
A: Use the selector syntax: $(some.nested.value) or $(@root.some.value) for root access.

Q: What's the difference between keys and sources?
A: Keys are prefixed with . and control structure/flow (.if, .each). Sources use $() syntax and provide values ($(env:VAR), $(file:path)).