object-no-new-keys2.9.11

Check, does a plain object (AST/JSON) has any unique keys, not present in a reference object (another AST/JSON)

§ Quick Take

import { strict as assert } from "assert";
import nnk from "object-no-new-keys";

assert.deepEqual(
  nnk(
    {
      a: {
        b: "b",
        c: "c",
      },
      x: "y",
    },
    {
      a: {
        c: "z",
      },
    }
  ),
  ["a.b", "x"]
);

§ Purpose

Check, does a given plain object have any keys, not present in a reference object. Returns array of zero or more paths in object-path opens in a new tab notation.

For example, it can be used to look for any rogue keys in email template content JSON files.

§ API

nnk(input, reference, [opts])

In other words, it's a function which takes two obligatory arguments and third, optional.

§ API - Function's Input

Function's argumentKey value's typeObligatory?Description
inputNormally, a plain object or array — but can be whatever in which case the results will be an empty arrayyesWhat to work upon.
reference | Same, normally, a plain object or array — but can be whatever type in which case result will be empty array | yes | The reference against which we'll match theinput`.
`optsPlain objectnoOptional options object

§ API - Function's Output

Returns an array of zero or more paths to each key/element in the input which does not exist in reference.

§ API - opts - an Optional Options Object

Defaults:

{
mode: 2;
}
Optional Options Object's keyTypeObligatory?DefaultDescription
modeInteger numberno2Choose mode: 1 or 2. See below.

§ Two modes

This library has two modes:

  1. Strict comparing, having no assumptions about the reference.
  2. Comparing, assuming that the reference will be NORMALISED.

By "normalised" we mean if any arrays have object children, those objects have the same keys.

These two modes mainly concern the case when both input and reference have an array, but reference has fewer elements and there's nothing to compare the input element to:

const input = {
a: [
{
// object number 1
b: "b1",
c: "c1",
},
{
// object number 2
b: "b2",
c: "c2",
x: "y",
},
],
};

const reference = {
a: [
{
// << just one object!
b: "b3",
c: "c3",
},
],
};

First mode will report that a[1].b and a[1].c and a[1].x are all rogue keys, not present in reference.

The second mode will anticipate that reference will be normalised, that is, we can compare input array elements to the first element of an array in reference. We'll get the same thing — all objects within an array should have the same keys. This means, input has only one rogue key — a[1].x. And algorithm will identify it by comparing input object a[1] to reference object a[0] — second/third/whatever element in the input to ALWAYS THE FIRST ELEMENT IN REFERENCE, a[0].

We need the second mode, but we give people chance to use the first mode as well. Maybe somebody will find it useful.

§ For example

const nnk = require("object-no-new-keys");
const res = nnk(
{
a: "a",
b: "b",
c: "c",
},
{
c: "z",
}
);
console.log("nnk = " + JSON.stringify(nnk, null, 4));
// => ['a', 'b']
// meaning, path "a" and path "b" were missing
// path notation uses [] to mark array's contents

works with arrays too:

const nnk = require("object-no-new-keys");
const res = nnk(
{
//<<< input
a: [
{
b: "aaa",
d: "aaa", // rogue key, record it
f: "fff", // another rogue key, record it
},
{
c: "aaa",
k: "kkk", // yet another rogue key, record it
},
],
x: "x", // rogue too
},
{
// <<< reference
a: [
{
b: "bbb",
c: "ccc",
},
{
b: "yyy",
c: "zzz",
},
],
}
);
console.log("res = " + JSON.stringify(res, null, 4));
// => ['a[0].d', 'a[0].f', 'a[1].k', 'x']

§ Competition

You could try to use a missing-deep-keys opens in a new tab, but it won't work if your inputs have arrays. For posterity, the algorithm of it is quite wise: run lodash.difference against deep-keys opens in a new tab-flattened stringified key schemas of both object and reference. However, deep-keys does not support arrays, so it's not that easy.

In short, missing-deep-keys is for cases when you have only objects-within-objects. object-no-new-keys is for work with parsed HTML (AST's) or JSON. Higher-end.

§ Licence

MIT opens in a new tab

Copyright © 2010–2020 Roy Revelt and other contributors

Related packages:

📦 object-fill-missing-keys 7.10.28
Add missing keys into plain objects, according to a reference object
📦 object-all-values-equal-to 1.8.25
Does the AST/nested-plain-object/array/whatever contain only one kind of value?
📦 object-flatten-all-arrays 4.8.23
Merge and flatten any arrays found in all values within plain objects
📦 object-flatten-referencing 4.11.27
Flatten complex nested objects according to a reference objects
📦 object-boolean-combinations 2.11.66
Consumes a defaults object with booleans, generates all possible variations of it
📦 object-delete-key 1.9.38
Delete keys from all arrays or plain objects, nested within anything, by key or by value or by both, and clean up afterwards. Accepts wildcards.
📦 object-merge-advanced 10.11.29
Recursive, deep merge of anything (objects, arrays, strings or nested thereof), which weighs contents by type hierarchy to ensure the maximum content is retained