property-chain
v2.0.3
Published
Use ***`property-chain`*** like `'a.b.c'` to handle a nested value from an object
Downloads
6
Maintainers
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 onnpm
. Butproperty-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.0config<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 whencallback
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 whencallback
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
;