
Security News
Crates.io Users Targeted by Phishing Emails
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
lazy-recursive-merge
Advanced tools
Allow declarative configurations from independent sources with embedded evaluation.
This happens by taking an array of objects and merging them into a new object, and then providing getter functions to call functions with the new object. This allows creating e.g. a configuration where lower-priority configurations can access the higher-priority configuration values for calculations.
Using this concept, you can merge arrays, define file paths with prefixes, conditionally enable features etc.
Example:
Given the objects
const configs = [
{a: 'a'},
{b: cfg => `${cfg.a}/${cfg.p}`},
{p: 'hi'},
{plugin: () => import('myPlugin')},
{f: cfg => `m:${cfg.b}`, p: 'hello'},
]
the resulting configuration is
{a: 'a', b: 'a/hello', p: 'hello', plugin: /* Promise<plugin> */, f: 'm:a/hello'}
In other words, the key p
in the last object was used by the key b
in the second object, and the key f
in the last object used the key b
in turn.
The functions b
, plugin
and f
won't be called until they are referenced, so for example myPlugin
won't be loaded until config.plugin
is read, returning a Promise.
This way, you can define configurations that are loosely coupled but can change any part of the final configuration programmatically. This is a useful property for pluggable systems, as evidenced by NixOS, an entire Linux distribution based on this concept.
Given an array of objects, they are merged as follows:
fn(config, {prev, path})
prev
is the value at the same path of the previous objectsfoo
, return it with () => foo
, it won't be considered for lazy evaluationconst config = lrm(objects, {target} = {})
objects
: array of enumerable objects (these cannot be Promises)target
: optional object that will get the configurationThe return value is the mutated target
object if it was passed. This way, you can retain
references to a changing configuration object.
This only uses Object.defineProperty
and WeakMap
(for loop detection only), so it should work on everything with a polyfill for WeakMap
.
[{env: process.env}, try_load('config/defaults'), try_load('config/defaults.${process.env.NODE_ENV}')]
fn[Symbol.for('lrm.value')]=true
{path, root}
and implement .add()
and .finalize()
makeMerger[Symbol.for('lrm.merge')]=true
WeakMap
is not available, use a recursion depth limitFAQs
Deep-merge objects with lazily-called accessor functions
We found that lazy-recursive-merge demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
Product
Socket now lets you customize pull request alert headers, helping security teams share clear guidance right in PRs to speed reviews and reduce back-and-forth.
Product
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.