vmptk / object-fill-missing-keys

:key: Add missing keys into plain objects, according to provided schema object.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

object-fill-missing-keys

ESLint on airbnb-base with caveats

Add missing keys into plain objects, according to a reference object

Minimum Node version required Link to npm page Build Status Coverage bitHound Overall Score bitHound Dependencies View dependencies as 2D chart bitHound Dev Dependencies Known Vulnerabilities Downloads/Month Test in browser MIT License

Table of Contents

Install

npm i object-fill-missing-keys
// consume as a CommonJS require:
const fillMissingKeys = require('object-fill-missing-keys')
// or as an ES Module:
import fillMissingKeys from 'object-fill-missing-keys'

Here's what you'll get:

Type Key in package.json Path Size
Main export - CommonJS version, transpiled to ES5, contains require and module.exports main dist/object-fill-missing-keys.cjs.js 6 KB
ES module build that Webpack/Rollup understands. Untranspiled ES6 code with import/export. module dist/object-fill-missing-keys.esm.js 6 KB
UMD build for browsers, transpiled, minified, containing iife's and has all dependencies baked-in browser dist/object-fill-missing-keys.umd.js 49 KB

⬆  back to top

Purpose

This library fills missing keys in a plain object according to a supplied reference object. It is driving the json-comb-core method enforceKeyset().

⬆  back to top

How this works

This library performs the key creation part in the JSON files' normalisation operation. JSON file normalisation is, basically, making a set of JSON files to have the same key set.

Here's how it slots in the normalisation process:

First, you take two or more plain objects, normally originating from JSON files' contents.

Then, you calculate the schema reference out of them. It's basically a superset object of all possible keys used across the objects (your JSON files).

Finally, you go through your plain objects second time, one-by-one and fill missing keys using this library. It takes the plain object and your generated schema reference (and optionally a custom placeholder if you don't like Boolean false) and creates missing keys/arrays in that plain object.


Alternatively, you can use this library just to add missing keys. Mind you, for performance reasons, schema is expected to have all key values equal to placeholders. This way, when creation happens, it can be merged over and those placeholder values come into right places as placeholders. This means, if you provide a schema with some keys having values as non-placeholder, you'll get those values written onto your objects.

Previously I kept "insurance" function which took a schema reference object and overwrote all its values to the opts.placeholder, but then I understood that "normal" reference schemas will always come with right key values anyway and such operation would waste resources.

⬆  back to top

Example

const fillMissingKeys = require('object-fill-missing-keys')
const result = fillMissingKeys(
  {
    b: 'b' // <---- input plain object that could have come from JSON
  },
  { // <---- schema reference object
    a: false,
    b: false,
    c: false
  }
)
console.log('result = ' + JSON.stringify(result, null, 4))
// result = {
//   a: false,
//   b: 'b',
//   c: false
// }

⬆  back to top

API

fillMissingKeys(incompleteObj, schemaObj, [opts])

Input arguments are not mutated, inputs are cloned before being used. That's important.

API - Input

Input argument Type Obligatory? Description
incompleteObj Plain object yes Plain object. Can have nested values.
schemaObj Plain object yes Schema object which contains a desired set of values. Can be nested or hold arrays of things.
opts Plain object no Optional Options Object, see below for its API

⬆  back to top

Optional Options Object

options object's key Type of its value Default Description
{
doNotFillThesePathsIfTheyContainPlaceholders Array of zero or more strings [] Handy to activate this for ad-hoc keys in data structures to limit the data bloat.
placeholder Anything false Used only in combination with doNotFillThesePathsIfTheyContainPlaceholders as a means to compare do all children keys contain placeholder values. It won't patch up your reference schema objects (for performance reasons). Always make sure your reference schema object has all values set to be a desired placeholder (default placeholder is usually Boolean false).
}

⬆  back to top

opts.doNotFillThesePathsIfTheyContainPlaceholders

This setting is handy to limit the lengths of your JSON files. Sometimes, you have some ad-hoc keys that are either very large nested trees of values AND/OR they are rarely used. In those cases, you want to manually trigger the normalisation of that key.

It's done this way.

Find out the path of the key you want to limit normalising on. Path notation is following the one used in object-path: if it's object, put the key name, if it's array, put that element's ID. For example: orders.latest.0.first_name would be:

{
  orders: {
    latest: [ // <---- notice it's a nested array within a plain object
      {
        first_name: "Bob", // <------ this key is `orders.latest.0.first_name`
        last_name: "Smith"
      },
      {
        first_name: "John",
        last_name: "Doe"
      }
    ]
  }
}

Put the path you want to skip normalising into opts.doNotFillThesePathsIfTheyContainPlaceholders array. For example:

const res = fillMissingKeys(
  { // <---- input
    a: {
      b: false, // <---- we don't want to automatically normalise this key
      x: 'x',
    },
    z: 'z',
  },
  { // <---- reference schema object
    a: {
      b: {
        c: false,
        d: false,
      },
      x: false,
    },
    z: false,
  },
  {
    doNotFillThesePathsIfTheyContainPlaceholders: ['a.b'],
  },
)
console.log(`res = ${JSON.stringify(res, null, 4)}`)
// res = {
//   a: {
//     b: false, // <---------------- observe, the keys were not added because it had a placeholder
//     x: 'x',
//   },
//   z: 'z',
// }

In order to trigger normalisation on an ignored path, you have to set the value on that path to be falsey, but not placeholder. If you are using default placeholder, false, just set the value in the path as true. If you're using custom placeholder, different as false, set it to false. The normalisation will see not a placeholder and will start to comparing/filling in missing branches in your object.

For example, we want to fill the value for a.b.c, but we are not sure what's the data structure. We actually want a placeholder to be set during normalisation under path a.b. We set a.b to true:

const res = fillMissingKeys(
  {
    a: {
      b: true, // <-- not placeholder but lower in data hierarchy (boolean)
      x: 'x',
    },
    z: 'z',
  },
  {
    a: {
      b: {
        c: false,
        d: false,
      },
      x: false,
    },
    z: false,
  },
  {
    doNotFillThesePathsIfTheyContainPlaceholders: ['a.b'],
  },
)
console.log(`res = ${JSON.stringify(res, null, 4)}`)
// res = {
//   a: {
//     b: {
//       c: false, // <---- values added!
//       d: false, // <---- values added!
//     },
//     x: 'x',
//   },
//   z: 'z',
// }

If any of the branches in given doNotFillThesePathsIfTheyContainPlaceholders paths contain only placeholders and are normalised, they will be truncated (set to a placeholder you provide in the opts, or if you don't supply one, set to a default false):

const res = fillMissingKeys(
  { // <--- input object
    a: {
      b: { // <--- this object in "b"'s value will be removed and set to placeholder "false"
        c: false,
        d: false,
      },
      x: { // <--- this too
        y: false,
      },
    },
    z: 'z',
  },
  { // <--- schema object
    a: {
      b: {
        c: false,
        d: false,
      },
      x: false,
    },
    z: false,
  },
  { // <--- settings
    doNotFillThesePathsIfTheyContainPlaceholders: ['lalala', 'a.b', 'a.x'],
  },
)
console.log(`res = ${JSON.stringify(res, null, 4)}`)
// res = {
//   a: {
//     b: false,
//     x: false,
//   },
//   z: 'z',
// }

⬆  back to top

Contributing

  • If you want a new feature in this package or you would like us to change some of its functionality, raise an issue on this repo.

  • If you tried to use this library but it misbehaves, or you need an advice setting it up, and its readme doesn't make sense, just document it and raise an issue on this repo.

  • If you would like to add or change some features, just fork it, hack away, and file a pull request. We'll do our best to merge it quickly. Code style is airbnb-base, only without semicolons. If you use a good code editor, it will pick up the established ESLint setup.

⬆  back to top

Licence

MIT License (MIT)

Copyright © 2018 Codsen Ltd, Roy Revelt

About

:key: Add missing keys into plain objects, according to provided schema object.

License:MIT License


Languages

Language:JavaScript 100.0%