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

logical-config

v1.0.8

Published

Allows you, through a short-hand notation, to invoke functions directly from your configuration files at load-time and map configuration entries to variables, classes, or functions.

Downloads

4

Readme

Logical Config

Sponsor Me! Downloads GitHub stars GitHub issues GitHub license

The logical-config JavaScript package allows you, through short-hand notation, to invoke functions directly from your configuration files at load-time and map configuration entries to variables, classes, or functions.

Install

$ yarn add logical-config

Index

Practical Example

See Winston Logical Config for a practical example of using a Logical Config file. Winston Logical Config allows you to configure a Winston logger directly from a config file.

Simple Example

config.yaml

Data:
  Connection: "{database.getConnection}"

Code

const LogicalConfig = require('logical-config');

const yaml = require('js-yaml');
const fs   = require('fs');

const config = await LogicalConfig.fill({
    input: yaml.load(fs.readFileSync('./config.yaml', 'utf8')),
    data: {
        database: {
            getConnection: async () => Promise.resolve({ connected: true })
        }
    }
});

console.log(config);

Output

{ Data: { Connection: { connected: true } } }

Documentation

Path Objects

Path objects tell the LogicalConfig how to look up the desired value.

Each path object consists of three properties.

|Property|Required|Default|Description| |---|---|---|---| |$fill|Yes|undefined|The dot path at which the desired value can be found in the map.| |parameters|No|[]|When the value found at the specified path is callable, and the call property is enabled, this is a list of parameters that will be passed to it.| |call|No|true|If the value found at the specified path is callable, this boolean indicates if the response of calling that value should be used, or the value itself.|

Example Path Object

{
    '$fill': 'user.isOlderThan',
    parameters: [ 18 ],
    call: true
}

Path Object Short-hand

  • Short-hand path objects should be written as strings and wrapped with {}.
  • Each property should be dilmited with a semi-colon ;.
  • The properties should be listed in the order of ($fill, parameters, call).
  • The parameters property should be a JSON encoded array.
  • At least the $fill property must be specified.

The above example path object can be written in short-hand like this:

"{user.isOlderThan;[18]}"

You can attempt to parse a short-hand path object yourself using the .parsePathObject() function.

const parsed = LogicalConfig.parsePathObject(`{user.setName;["Nathan"];true}`);
console.log(parsed);
{ '$fill': 'user.setName', parameters: [ 'Nathan' ], call: true }

Child Path Objects

You can use Path Objects anywhere within the parameters array property of another Path Object. Please note however that nested Path Objects are not supported in short-hand path objects.

In this example we:

  1. Retrieve the users age using user.getAgeAsStr. The return value of this function is a string.
  2. Retrieve the numeric value by sending the users age to the funcs.toInt Number function.
  3. Evaluate the expression by passing the users age to the user.isOlderThan function and returning the response.

Code

const canBuyAlcohol = await LogicalConfig.fill({
    input: {
        '$fill': 'item.canBuy',
        parameters: [{
            '$fill': 'Number',
            parameters: ["{user.getAgeAsStr}"]
        }]
    },
    data: {
        Number,
        item: {
            name: 'alcohol',
            canBuy: age => age > 21,
        },
        user: {
            getAgeAsStr: () => "27",
        }
    }
});

The .fill() function

const config = await LogicalConfig.fill(...

The .fill() function takes an input object and data object containing data that Path Objects can access. Itt will replace each instance of a Path Object with the value it describes from the datab object. This will be performed on the input object recursively until all path objects have been resolved, at which point the finalized object will be returned.

Parameters

|Parameter|Required|Description| |---|---|---| |input|Yes|The input object that will be parsed. Can be an array of Path Objects, a single Path Object, or an object in which any value (at any depth) is either an array of Path Objects or a Path Object.| |data|Yes|An object containing data to which path objects can correspond| |ignoredPaths|No|An array containing dot paths to keys in the input property that can be ignored when searching for Path Objects.|

Return

The new object.

Advanced Examples

Retrieving Properties

  1. Retrieve a property from the map using short-hand

    const res = await LogicalConfig.fill({
       input: '{user.age}', 
       data: {
           user: {
               age: 27
           }
       }
    });
    console.log(res); // Outputs: 27

Using Functions

  1. Call a function from the map using short-hand

    const res = await LogicalConfig.fill({
        input: '{user.getName}',
        data: {
            user: {
                getName: () => "Nathan"
            }
        }
    });
    console.log(res); // Outputs: "Nathan"
  2. Call a function with parameters from the map using short-hand

    const res = await LogicalConfig.fill({
        input: `{user.info;[{"name":"Nathan"}, 27]}`,
        data: {
            user: {
                info: ({name}, age) => ({name, age})
            }
        }
    });
    console.log(res); // Outputs: { name: 'Nathan', age: 27 }
  3. Retrieve a function as a value from the map using short-hand

    By default, if a property is callable (is a class or a function), it will be invoked and it's return value will be used. You can override this by setting the call property of the Path Object to false.

    const res = await LogicalConfig.fill({
        input: `{user.info;;false}`,
        data: {
            user: {
                info: () => {}
            }
        }
    });
    console.log(res); // Outputs: [Function: info]

Using Classes

  1. Retrieve a new instance of a class from the map using short-hand

    const res = await LogicalConfig.fill({
        input: '{person.c}',
        data: {
            person: {
                c: class {
                    constructor() {
                        this.name = "Nathan";
                    }
                }
            }
        }
    });
    console.log(res); // Outputs: c { name: 'Nathan' }
  2. Retrieve a new instance of a class with parameters from the map using short-hand

    const res = await LogicalConfig.fill({
        input: '{person.c;["Nathan"]}',
        data: {
            person: {
                c: class {
                    constructor(name) {
                        this.name = name;
                    }
                }
            }
        }
    });
    console.log(res); // Outputs: c { name: 'Nathan' }
  3. Retrieve a class as a value from the map using short-hand.

    By default, if a property is callable (is a class or a function), it will be invoked and it's return value will be used. You can override this by setting the call property of the Path Object to false.

    const res = await LogicalConfig.fill({
        input:'{person.c;;false}',
        data: {
            person: {
                c: class {}
            }
        }
    });
    console.log(res); // Outputs: [class c]