mojotech / json-type-validation

TypeScript JSON type validation
MIT License
155 stars 15 forks source link

Lodash Dependency #52

Open Joncom opened 4 years ago

Joncom commented 4 years ago

May I suggest removing Lodash as a dependency?

The single call to the Lodash isEqual function could be probably replaced with a simple local implemention:

function isEqual(a: any, b: any) {
  if (a === b) {
    return true;
  }
  if (a === null && b === null) {
    return true;
  }
  if (typeof (a) !== typeof (b)) {
    return false;
  }
  if (typeof (a) === 'object') {
    // Array
    if (Array.isArray(a)) {
      if (!Array.isArray(b)) {
        return false;
      }
      if (a.length !== b.length) {
        return false;
      }
      for (let i = 0; i < a.length; i++) {
        if (!isEqual(a[i], b[i])) {
          return false;
        }
      }
      return true;
    }
    // Hash table
    const keys = Object.keys(a);
    if (keys.length !== Object.keys(b).length) {
      return false;
    }
    for (let i = 0; i < keys.length; i++) {
      if (!b.hasOwnProperty(keys[i])) {
        return false;
      }
      if (!isEqual(a[keys[i]], b[keys[i]])) {
        return false;
      }
    }
    return true;
  }
}
Joncom commented 4 years ago

One reason to not use Lodash: its heavy use of CommonJS/Node style modules means no compiling to ES6 modules from TS.

https://github.com/mojotech/json-type-validation/blob/60576fed5e12ea306e3cd28358d7426df2624907/src/decoder.ts#L2

kat-ya commented 4 years ago

Also I was unable to use json-type-validation library in Stencil project due Cannot Use External Module due to a call to require in dependency #652, which is unfortunate because your json-type-validation is just what I was looking for in dynamic validation of a JSON object.

Addeuz commented 2 years ago

``At my work we heavily relied on this dependency but since we started using svelte we had troubles with lodash.isequal and how its built.

So I forked this repo here and made the change that you suggested. It solves our problem and your function works great. Except for when b is null and a is not and vice versa. Which I found out today after our system tests failed.

So modified the function slightly:

function isEqual(a: any, b: any) {
  if (a === b) {
    return true;
  }
  if (a === null && b === null) {
    return true;
  }
  if (typeof (a) !== typeof (b)) {
    return false;
  }
  if (typeof (a) === 'object') {
    // new if that fixes that bug
    if (a === null && b !== null || a !== null && b === null) {
      return false;
    }
    // Array
    if (Array.isArray(a)) {
      if (!Array.isArray(b)) {
        return false;
      }
      if (a.length !== b.length) {
        return false;
      }
      for (let i = 0; i < a.length; i++) {
        if (!isEqual(a[i], b[i])) {
          return false;
        }
      }
      return true;
    }
    // Hash table
    const keys = Object.keys(a);
    if (keys.length !== Object.keys(b).length) {
      return false;
    }
    for (let i = 0; i < keys.length; i++) {
      if (!b.hasOwnProperty(keys[i])) {
        return false;
      }
      if (!isEqual(a[keys[i]], b[keys[i]])) {
        return false;
      }
    }
    return true;
  }
}