Import mergeDefined, resolveConfig and the ConfigurationValidator<T> type from @neutrium/utilities/configuration or the root export. These helpers add defined-only updates, strict option checking and validated snapshots to native object operations. There is no schema framework, global configuration, deep merge or compatibility layer.
mergeDefined(defaults, ...updates) returns a new mutable object of the defaults' TypeScript type. Updates must be partial values of that type. Later defined values win; undefined inherits the previous value. Null, false, zero and empty strings are explicit replacements. This function does not validate field values at runtime; use resolveConfig at untrusted boundaries.
import { mergeDefined } from '@neutrium/utilities/configuration';
const config = mergeDefined({ precision: 20, enabled: true },
{ precision: undefined }, { enabled: false });
// { precision: 20, enabled: false }
resolveConfig(defaults, input, validate, name?) accepts unknown input, merges it, shallow-freezes the result, and calls an assertion function on the complete result. The assertion must validate every field and any relationships between them. Its errors propagate unchanged. Undefined input means no update. Invalid defaults are also checked, even when no update is supplied. The optional name labels structural errors and defaults to configuration.
import { resolveConfig } from '@neutrium/utilities/configuration';
import { assertKnownKeys, assertPositiveSafeInteger, assertOneOf }
from '@neutrium/utilities/validation';
interface Config { precision: number; mode: 'fast' | 'precise' }
const defaults: Config = { precision: 20, mode: 'fast' };
function validate(value: unknown): asserts value is Config
{
assertKnownKeys(value, ['precision', 'mode']);
assertPositiveSafeInteger(value.precision, 'precision');
assertOneOf(value.mode, ['fast', 'precise'], 'mode');
}
const settings = resolveConfig(defaults, { precision: 30 }, validate);
// Readonly<Config>, shallow-frozen at runtime
Validators are synchronous assertions, not transformations or boolean predicates. JavaScript callers must follow that same contract: returning false does not reject input. Validation cannot modify the frozen outer record and must not mutate nested values. As with any TypeScript assertion, the caller is responsible for truthfully establishing the asserted type.
__proto__ key is handled as data and never changes the prototype.Cache configuration now uses resolveConfig. Its limits and undefined inheritance remain unchanged; configuration accessors and non-plain objects are now rejected.