property-chain v2.0.3
PropertyChain
Use property-chain like 'a.b.c' to handle a nested value from an object
Abstract
The original intention of the
property-chainproject 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-chainis 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): AccessorGet a PropertyAccessor @since 1.0.0
(source: any, chain: Array<PropertyKey>): anyGet the property value of source by property-chain @since 1.0.0
(source: any, chain: Array<PropertyKey>, value: any): [any, any] | voidSet the property value of source by property-chain @since 1.0.0
accessor(source: any): AccessorGet a PropertyAccessor @since 1.0.0accessor(source: any, config: Config): AccessorGet a PropertyAccessor with config @since 1.1.0
template(chain: TemplateStringsArray, ...args: any[]): TemplateGet 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] | undefinedSet nested value; @since 1.1.0
delete(source: any, chain: string | Array<PropertyKey>, config?: Config): booleanDelete nested value; @since 1.1.0
has(source: any, chain: string | Array<PropertyKey>, config?: Config): booleanHas nested value; @since 1.1.0
config(config: Partial<Config>): voidSet config objects; @since 1.1.0config<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(): booleanHas nested value @since 1.0.0
hasValue(chain: Array<PropertyKey> | string): booleanHas nested value by property-chain @since 1.0.0
getValue(): anyGet nested value @since 1.0.0getValue(chain: Array<PropertyKey> | string): anyGet nested value by property-chain @since 1.0.0
setValue(value: any): thisSet nested value @since 1.0.0setValue(chain: Array<PropertyKey> | string, value: any): thisSet nested value by property-chain @since 1.0.0
deleteValue(): thisDelete nested value @since 1.0.0deleteValue(chain: Array<PropertyKey> | string): thisDelete nested value by property-chain @since 1.0.0
updateValue(updater: Function): thisUpdate nested value @since 1.0.0updateValue(chain: Array<PropertyKey> | string, updater: Function): thisUpdate nested value by property-chain @since 1.0.0
projection(projection: any): anyGet nested projection @since 1.0.4projection(chain: Array<PropertyKey> | string, projection: any): anyGet nested projection by property-chain @since 1.0.4
root(): AccessorGet root accessor @since 1.0.0
parent(): Accessor | undefinedGet parent accessor @since 1.0.0
chain(): Readonly<Array<PropertyKey>> | undefinedGet property chain @since 1.0.0
access(key: PropertyKey): AccessorCreate an accessor for the propertyKey@since 1.0.0
accessChain(chain: string | Array<PropertyKey>): AccessorCreate an accessor for the property-chainchain@since 1.0.0
template(template: TemplateStringsArray, ...injecters: any[]): AccessorTemplateCreate an AccessorTemplate @since 1.0.0
watch(watcher: Function, option?: WatcherOption): thisAdd value-change watcher, optional @since 1.0.0
unwatch(): thisRemove all value-change watchers @since 1.0.0unwatch(watcher: Function): thisRemove value-change watcher @since 1.0.0
Template
stringify(): stringStringify @since 1.0.0
chain(stringifyMode: string): stringStringify, specified mode @since 1.0.0
in(source: any, own?: boolean): booleanDetermine whether there is any property on the prototype-chain @since 1.0.0
own(source: any): booleanDetermine 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.0delete(source: anycallback: Function): Array<PropertyKey>Delete matched properties whencallbackreturns true, exclude the prototype chain @since 1.0.0
update(source: any, callback: TemplateCallback): thisBatch update matching property values,callbackreturns new value @since 1.0.0
set(source: any, value: any): thisSet all matchable properties asvalue@since 1.0.0
each(source: any, callback: Function, option?: TemplateCallbackOption): thisIterate over each matching properties @since 1.0.0
AccessorTemplate
in(own?: boolean): booleanDetermine whether there is any property on the prototype chain @since 1.0.0
own(): booleanDetermine 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.0delete(callback: Function): Array<PropertyKey>Delete matched properties whencallbackreturns true, exclude the prototype chain @since 1.0.0
update(callback: TemplateCallback): thisBatch update matching property values,callbackreturns new value @since 1.0.0
set(value: any): thisSet all matchable properties asvalue@since 1.0.0
each(callback: Function, option?: TemplateCallbackOption): thisIterate 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): thisAdd value-change watcher, optional @since 1.0.0
unwatch(): thisRemove all value-change watchers @since 1.0.0
unwatch(watcher: Function): thisRemove value-change watcher @since 1.0.0
WatcherOption
immediate: booleanTrigger immediately @since 1.0.0
deep: booleanDeep watch @since 1.0.0
TemplateCallbackOption
writable: booleanOnly contains writable property values @since 1.0.0
configurable: booleanOnly contains configurable property values @since 1.0.0
prototype: booleanContains prototype chain @since 1.0.0
Config
allowDotNumber: booleanif true: "a.0.1b" is illegal, must use
a[0]["1b"]else: "a.0.1b" is acceptable @since 1.1.0
allowNonASCII: booleanAllow non-ASCII property name(when compileStrict is true); The price is reduced performance @since 1.1.0
autoType: booleanAutomatically 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: booleanUse Symbol.for to generate symbol @since 1.1.0
prototypeMutatable: booleanAllow 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;