https://github.com/do-/node-subclassable-object-merger
An Object.assign() generalization with overridable rules
https://github.com/do-/node-subclassable-object-merger
Last synced: 2 months ago
JSON representation
An Object.assign() generalization with overridable rules
- Host: GitHub
- URL: https://github.com/do-/node-subclassable-object-merger
- Owner: do-
- License: other
- Created: 2024-07-29T12:34:50.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-08-11T07:50:43.000Z (over 1 year ago)
- Last Synced: 2025-03-07T07:06:35.783Z (about 1 year ago)
- Language: JavaScript
- Size: 42 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README


# Rationale
The public npm [registry](https://www.npmjs.com/) contains a plethora of modules implementing _deep_ (recursive) alternatives to the standard [Object.assign()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign).
Some of them are basically single functions with fixed logic hardly suitable for any extending, for instance:
* [deep-object-merger](https://github.com/DavideCometa/Deep-Object-Merger) (just a recursive `Object.assign()`)
* [multi-merge](https://github.com/eballci/multi-merge) (+something special about Boolean values)
* [object-merger](https://github.com/jarradseers/object-merger) (never mind Booleans, concatenate arrays)
Others offer to set up sophisticated custom rules using some languages other than plain ECMAScript:
* [decorated-merger](https://github.com/neckaros/decorated-merger) (TypeScript Decorations)
* [json-object-merge](https://github.com/sodaru/json-object-merge) (JSONPath)
The author of this module needed something very close to the basic naive implementation, but easily customizable by the means of standard ES. This is why `subclassable-object-merger` was created.
# Installation
```sh
npm install subclassable-object-merger
```
# Usage
```js
const {ObjectMerger} = require ('subclassable-object-merger')
const om = new ObjectMerger (
//{override: [
// 'scalar',
// 'array',
// 'object',
//]}
)
const t1 = {
name: 'users',
label: 'System users',
columns: {
id: {TYPE: 'int'},
},
data: [
{id: 1, label: 'admin'}
],
triggers: null,
}
const t2 = {
name: 'users',
label: undefined,
columns: {
id: {AUTO_INCREMENT: true},
label: {TYPE: 'text'},
},
pk: 'id',
data: [
{id: 2, label: 'employee'}
],
triggers: {before_insert: 'RETURN;'},
}
om.merge (t1, t2) /* result:
{
name: 'users',
label: 'System users',
pk: 'id',
columns: {
id: {TYPE: 'int', AUTO_INCREMENT: true},
label: {TYPE: 'text'},
},
data: [
{id: 1, label: 'admin'},
{id: 2, label: 'employee'}
],
triggers: {before_insert: 'RETURN;'},
})
*/
```
## Constructor
May be invoked without parameters or with a single `{override}` object.
### The `override` option
When set, `override` must be an array of type names (see `getType ()` below) to be forcibly overridden in case of conflict.
In particular, setting `{override: ['scalar']}` will lead to `merge ({name: 'specific'}, {name: 'default'})` into `{name: 'specific'}` instead of throwing an error.
# Internals
## Instance properties
The only property is `sum`: the object mapping type names to corresponding type specific adding functions. Simply put:
```js
this.sum = {
array: (a, b) => a.concat (b),
object: (a, b) => this.merge (a, b),
scalar: (a, b) => a === b ? a : throw Error ()
}
```
With the `override` option, `a => a` is set for types listed therein.
## Methods
### getType (a)
For a given non-null `a`, returns:
* `'array'` if `Array.isArray (a)`
* `'object'` if `typeof a === 'object'` (no advanced checker like [`is-plain-obj`](https://github.com/sindresorhus/is-plain-obj#is-plain-obj) nor [`is-plain-object`](https://github.com/jonschlinkert/is-plain-object) is in use here)
* `'scalar'` otherwise (e. g. for function valued `a`)
### add (a, b, k)
Does the main job here: calls `getType` for `a` and `b` and if the results are the same, merges `b` into `a`; otherwise, throws an error.
When `a` or `b` is `null` or `undefined`, returns the other argument (which may be `null` or `undefined` too).
The `k` parameter is a name of the outer objects properties whose values are `a` and `b`. It doesn't affect the result, but may appear in error messages. Descendant classes may use this argument for some special needs.
### merge (a, b)
This top level method copies `b`'s content into `a` by calling `add` for each of `b`'s keys. Both `a` and `b` must be plain Objects.
## Events
ObjectMerger inherits from [EventEmitter](https://nodejs.org/api/events.html#class-eventemitter). Though never using this feature on its own, it may be used as a message box by containing processes.