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

property-chain

v2.0.3

Published

Use ***`property-chain`*** like `'a.b.c'` to handle a nested value from an object

Downloads

6

Readme

PropertyChain

Use property-chain like 'a.b.c' to handle a nested value from an object

Abstract

The original intention of the property-chain project is only to get/set the property value of the object through the property-chain of the object. There are many similar excellent projects on npm. But property-chain is more focused on property and hopes to explore more possibilities.

Getting Started

You can use the <script> tag to import:

<!-- development version -->
<script src="https://cdn.jsdelivr.net/npm/property-chain@latest/dist/property-chain.umd.js"></script>
<!-- production version -->
<script src="https://cdn.jsdelivr.net/npm/property-chain@latest/dist/property-chain.umd.min.js"></script>

You can also use npm to import:

npm install property-chain

Example

import chain from 'property-chain';
import assert from 'assert';

var source = {
    name: "Joker",
    gender: "male",
    friends: ["Harley Quinn", "Penguin"],
    enemies: ["Batman"],
    "j.o.k.e.r": {
        [Symbol.for("Whatever doesn't kill you")]: {
            "simply makes you": "stranger",
            "simply makes"(target){
                return target === "you" ? "stranger" : void 0;
            }
        }
    }
};

// get value
chain.get(source, `
    j\\.o\\.k\\.e\\.r
    [Symbol(Whatever doesn't kill you)]
    ["simply makes \\u0079\\u{006f}\\u{00075}"]
`, { SymbolFor: true }); // "stranger"

// get value with callable
chain.get(source, `
    j\\.o\\.k\\.e\\.r
    [Symbol(Whatever doesn't kill you)]
    ["simply makes"]
    ("you") // Callable
`, { SymbolFor: true }); // "stranger"

/** Set global config */
chain.config({
    allowDotNumber: false,
    allowNonASCII: false
});

// get value
chain(source, "friends[0]"); // "Harley Quinn"

// set value
chain(source, "[`friends`][1]", "Riddler");
assert(source.friends[1] === "Riddler", `source.friends[1] has changed to "Riddler"`);

// get value by property-chain accessor
chain(source)
    .getValue("friends[0]") // "Harley Quinn"

chain(source)
    .access("friends")
    .access("0")
    .getValue(); // "Harley Quinn"

// set value by property-chain accessor
chain(source)
    .accessChain("friends[1]")
    .setValue("Two-Face");

// Use the template to get every matching value
chain.template`
    ${ /^(friend|enemie)$/ }s
    [${ /^\d+$/ }]
`.each(source, function(value, key, source){
    console.log("match: ", {value, key, source});
});

// Use the template to update every matching value
chain.template`
    ${ /^(friend|enemie)$/ }s
    [0]
`.update(source, (value) => {
    if (value === "Harley Quinn")
        return "Harley";
    if (value === "Batman")
        return "Bruce";
});

// Create accessor
var accessor = chain(source);
var friendAccessorTemplate = accessor.template`
    ["fri${ /** Use RegExp to match placeholders */ /^en$/ }ds"]
    [ ${ /** Use functions to match placeholders */ function(matched, key){ return matched == 0 || matched == 1 } } ]
`;
// Observe property 
friendAccessorTemplate.watch(function (value, oldValue, chain) {
    console.log(`${chain.join(".")} value has changed`, oldValue, "==>", value)
});
accessor.setValue("friends[1]", "Lex Luthor");

// Nothing happend! Refuse to modify the prototype chain
chain(source, "friends.push.apply", function () { });

Api

To learn more, please open the property-chain/types folder.

propertyChain

(source: any): Accessor

Get a PropertyAccessor @since 1.0.0


(source: any, chain: Array<PropertyKey>): any

Get the property value of source by property-chain @since 1.0.0


(source: any, chain: Array<PropertyKey>, value: any): [any, any] | void

Set the property value of source by property-chain @since 1.0.0


accessor(source: any): Accessor

Get a PropertyAccessor @since 1.0.0 accessor(source: any, config: Config): Accessor Get a PropertyAccessor with config @since 1.1.0


template(chain: TemplateStringsArray, ...args: any[]): Template

Get a Template @since 1.0.0


compile(str: str, config?: Config): Array<PropertyKey>

Compile string to property array; @since 1.1.0


get(source: any, chain: string | Array<PropertyKey>, config?: Config): Array<PropertyKey>

Get nested value; @since 1.1.0


set(source: any, chain: string | Array<PropertyKey>, value: any, config?: Config): [any, any] | undefined

Set nested value; @since 1.1.0


delete(source: any, chain: string | Array<PropertyKey>, config?: Config): boolean

Delete nested value; @since 1.1.0


has(source: any, chain: string | Array<PropertyKey>, config?: Config): boolean

Has nested value; @since 1.1.0


config(config: Partial<Config>): void

Set config objects; @since 1.1.0 config<K extends keyof Config = keyof Config>(key: K): Config[K] Get config value; @since 1.1.0 config<K extends keyof Config = keyof Config>(key: K, value: Config[K]): Config[K] Set config value; @since 1.1.0

Accessor

hasValue(): boolean

Has nested value @since 1.0.0 hasValue(chain: Array<PropertyKey> | string): boolean Has nested value by property-chain @since 1.0.0


getValue(): any

Get nested value @since 1.0.0 getValue(chain: Array<PropertyKey> | string): any Get nested value by property-chain @since 1.0.0


setValue(value: any): this

Set nested value @since 1.0.0 setValue(chain: Array<PropertyKey> | string, value: any): this Set nested value by property-chain @since 1.0.0


deleteValue(): this

Delete nested value @since 1.0.0 deleteValue(chain: Array<PropertyKey> | string): this Delete nested value by property-chain @since 1.0.0


updateValue(updater: Function): this

Update nested value @since 1.0.0 updateValue(chain: Array<PropertyKey> | string, updater: Function): this Update nested value by property-chain @since 1.0.0


projection(projection: any): any

Get nested projection @since 1.0.4 projection(chain: Array<PropertyKey> | string, projection: any): any Get nested projection by property-chain @since 1.0.4


root(): Accessor

Get root accessor @since 1.0.0


parent(): Accessor | undefined

Get parent accessor @since 1.0.0


chain(): Readonly<Array<PropertyKey>> | undefined

Get property chain @since 1.0.0


access(key: PropertyKey): Accessor

Create an accessor for the property Key @since 1.0.0


accessChain(chain: string | Array<PropertyKey>): Accessor

Create an accessor for the property-chain chain @since 1.0.0


template(template: TemplateStringsArray, ...injecters: any[]): AccessorTemplate

Create an AccessorTemplate @since 1.0.0


watch(watcher: Function, option?: WatcherOption): this

Add value-change watcher, optional @since 1.0.0


unwatch(): this

Remove all value-change watchers @since 1.0.0 unwatch(watcher: Function): this Remove value-change watcher @since 1.0.0


Template

stringify(): string

Stringify @since 1.0.0 chain(stringifyMode: string): string Stringify, specified mode @since 1.0.0


in(source: any, own?: boolean): boolean

Determine whether there is any property on the prototype-chain @since 1.0.0


own(source: any): boolean

Determine whether there is any property on hasOwnProperty @since 1.0.0


delete(source: any): Array<PropertyKey>

Delete all matchable properties, exclude the prototype chain @since 1.0.0 delete(source: anycallback: Function): Array<PropertyKey> Delete matched properties when callback returns true, exclude the prototype chain @since 1.0.0


update(source: any, callback: TemplateCallback): this

Batch update matching property values, callback returns new value @since 1.0.0


set(source: any, value: any): this

Set all matchable properties as value @since 1.0.0


each(source: any, callback: Function, option?: TemplateCallbackOption): this

Iterate over each matching properties @since 1.0.0


AccessorTemplate

in(own?: boolean): boolean

Determine whether there is any property on the prototype chain @since 1.0.0


own(): boolean

Determine whether there is any property on hasOwnProperty @since 1.0.0


delete(): Array<PropertyKey>

Delete all matchable properties, exclude the prototype chain @since 1.0.0 delete(callback: Function): Array<PropertyKey> Delete matched properties when callback returns true, exclude the prototype chain @since 1.0.0


update(callback: TemplateCallback): this

Batch update matching property values, callback returns new value @since 1.0.0


set(value: any): this

Set all matchable properties as value @since 1.0.0


each(callback: Function, option?: TemplateCallbackOption): this

Iterate over each matching properties @since 1.0.0


chains(option?: TemplateCallbackOption, chains?: Array<Readonly<Array<PropertyKet>>>): Array<ReadonlyPropertyKeyArray>

Get all matching prototype chains @since 1.0.0


chainEntries(option?: TemplateCallbackOption, entries?: Array<[Readonly<Array<PropertyKet>>, any]>): Array<[Readonly<Array<PropertyKet>>, any]>

Get all matching prototype chain entries @since 1.0.0


chainEntries(option?: TemplateCallbackOption, entries?: Array<[Readonly<Array<PropertyKet>>, any]>): Array<[Readonly<Array<PropertyKet>>, any]>

Get all matching prototype chain entries @since 1.0.0


watch(watcher: Function, option?: WatcherOption): this

Add value-change watcher, optional @since 1.0.0


unwatch(): this

Remove all value-change watchers @since 1.0.0


unwatch(watcher: Function): this

Remove value-change watcher @since 1.0.0


WatcherOption

immediate: boolean

Trigger immediately @since 1.0.0


deep: boolean

Deep watch @since 1.0.0

TemplateCallbackOption

writable: boolean

Only contains writable property values @since 1.0.0


configurable: boolean

Only contains configurable property values @since 1.0.0


prototype: boolean

Contains prototype chain @since 1.0.0

Config

allowDotNumber: boolean

if true: "a.0.1b" is illegal, must use a[0]["1b"] else: "a.0.1b" is acceptable @since 1.1.0


allowNonASCII: boolean

Allow non-ASCII property name(when compileStrict is true); The price is reduced performance @since 1.1.0


autoType: boolean

Automatically optimize the compiled property type, the string in the natural number format will be converted into a number, and the number in the non-natural number format will be converted into a string @since 1.1.0


symbolFor: boolean

Use Symbol.for to generate symbol @since 1.1.0


prototypeMutatable: boolean

Allow modifications to the prototype-chain @since 1.1.0

ChangeLog

  • 1.0.1: Created;
  • 1.0.4: Add Accessor.projection;
  • 1.0.5: Provide cjs / esm / umd;
  • 1.0.6: Fixed some bugs; Update README.MD;
  • 1.1.0: Fixed some bugs; Stronger compiler; Configurable;
  • 1.1.2: Support \\u{XXXXX};
  • 2.0.0: Support Callable;