property-chain
TypeScript icon, indicating that this package has built-in type declarations

2.0.3 • Public • Published

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;

Package Sidebar

Install

npm i property-chain

Weekly Downloads

0

Version

2.0.3

License

none

Unpacked Size

648 kB

Total Files

16

Last publish

Collaborators

  • galadrielme