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 🙏

© 2024 – Pkg Stats / Ryan Hefner

propref-parser

v1.0.1

Published

A minimal parser for (cross-)property references

Downloads

7

Readme

propref-parser

  • Usage
    • Accessing nested properties
  • API
  • Options
  • Examples
    • Custom Key Patterns
    • Dynamic Property Values

Usage

var PropRefParser = require('crossref-obj');

var props = {
    foo: true,
    bar: '@{foo}'
};

// instanciate new PropRefParser
var parser = new PropRefParser(props, opts);

parser.get('bar');
// -> true

Accessing nested properties

Nested properties are supported through the 'getter' option which allows you to define a custom getter function –used to get the value for a referenced property key.

For dot-notation, we recommend using the getobject package to define your custom getter:

var PropRefParser = require('crossref-obj');
var getobject = require('getobject');

var props =
{
    foo: true,
    bar: '@{foo}',

    // nested and relative keys
    nested: {
        foo: false,
        df: '@{foo}', // relative
        rel: '@{-.foo}', // relative
        up: '@{--.foo}', // move up
        abs: '@{.foo}' // absolute
    }
};

var options = {

    splitChar: '.',

    getter: function(props, key, options) {
        return getobject.get(props, key);
    }

};

var parser = new PropRefParser(props, options);

parser.get('bar');
// -> true

parser.parse();
// -> {
//   foo: true,
//   nested: {
//     foo: false,
//     df: false,
//     rel: false,
//     baz: true
//   }
// }

The example above also shows support for relative key paths. How nested and relative key paths are formatted can be controlled using the splitChar and upLvlChar options.

Constructor arguments

props (Object) required

Plain properties object, with cross-referencing property values.

options (Object) [{}]

See Options below for documentation and default values.

API

.parse( value ) Resolves property references in given value.

.get( key ) gets resolved value for given property key

.keyJoin( ..keys ) creates keypath by joining given property keys and resolving relative and absolute patterns.

.keyResolve( ..keys ) creates keypath by joining given property keys,in the context of options.keyBase (will be joined in front of other given keys).

Options

options.getter (Function) required

Custom getter function used to return values for referenced property keys. Signature: function( props, key, options ) { /*...*/ } - props context properties used to resolve given key - key absolute key to resolve - options options for PropRefParser instance

options.parser (Function) [null]

Custom parser function, ran whenever the PropRefParser is parsing a property value. Signature: funcion( props, value, options ) { /* ... */ - props context properties used to resolve given key - value value that is being parsed (with property refernces resolved!) - options options for PropRefParser instance

Important: Referenced property values are already resolved in the value passed as second argument to custom parser functions.

options.refPattern (String | RegExp) [ /@{\s*$&\s*}/ ]

Pattern used to recognize property references in string values. This option needs to include the $& string, used as placeholder for referenced property keys.

options.keyPattern (String | RegExp) [ /[a-zA-Z0-9_]/ ]

Pattern used to recognize property keys in property references.

options.splitChar (String | RegExp) [ /./ ]

Char(s) separating path levels in property keypaths.

options.upLevelChar (String | RegExp) [ /-/ ]

Char(s) used for moving up in relative keypaths.

Examples

Custom key patterns

// Default key patterns
var parser = new PropRefParser();
parser.keyJoin( 'nested.object', '.prop'); // nested.object.prop
parser.keyJoin( 'nested.object', '-.prop'); // nested.object.prop
parser.keyJoin( 'nested.object', '--.prop'); // nested.prop
parser.keyJoin( 'nested.object', '--.--.prop'); // prop
parser.keyResolve( 'nested.object.--.prop'); // nested.prop
// Use *filepath-like* key patterns
var parser = new PropRefParser({ /*...*/ }, {
    splitChar: '/',
    upLevelChar: '.'
});

parser.keyJoin( 'nested/object', '/prop'); // nested/object/prop
parser.keyJoin( 'nested/object', './prop'); // nested/object/prop
parser.keyJoin( 'nested/object', '../prop'); // nested/object/prop
parser.keyJoin( 'nested/object', '../../prop'); // prop
parser.keyResolve( 'nested/object/../prop'); // nested/prop
// Define your own key patterns
var parser = new PropRefParser({ /*...*/ }, {
    splitChar: ':',
    upLevelChar: '_'
});

parser.keyJoin( 'nested:object', ':prop'); // nested:object:prop
parser.keyJoin( 'nested:object', '_:prop'); // nested:object:prop
parser.keyJoin( 'nested:object', '__:prop'); // nested:prop
parser.keyJoin( 'nested:object', '__:__:prop'); // prop
parser.keyResolve( 'nested:object:__:prop'); // nested:prop

Dynamic property values

Using template strings and the parser option, you can get dynamic property values, based on expressions using property references:

var PropRefParser = require('crossref-obj');
var _templ = require('lodash.template');

var props = {

    foo: true,
    bar: '<% if(@{foo}) { print("yup"); }'
};

var opts = {

    getter: function(props, key, opts) {
        return props[key];
    },

    parser: function(props, val, opts) {
        if (typeof val == 'string') {
            return _templ(val)(props);
        }
    }
};

var parser = new PropRefParser(props, opts);
parser.parse('bar');
// -> {
//    foo: true,
//    bar: "yup"
// }

TODO

  • Implement an '.escape' method to escape references in given value

  • Ignore escaped references, split and upLevel characters

  • Ignore context for absolute keypaths in property references

  • Default to simple getter function(props, key, opts) { return props[key]; }

  • Test loading in AMD

  • Test browser global

  • Test multiple split and upLevel characters

  • Write test suite

  • Support advanced keypath using mutliple key adapters –each with their own splitChar, upLevelChar, getter and parser

  • Support file and url references

  • Support custom sources (yaml, json, db, ...)

  • Support sync and async (callback or promise) loading of files and urls