Detalhes do pacote

json-deep-compare

ashmeetsehgal903MIT1.1.3

A powerful library for comparing JSON objects with support for deep comparison, regex validation, and customizable options

json, compare, deep, diff

readme (leia-me)

JSON Deep Compare with Field Validator

JSON Deep Compare

Test Code Coverage Pull Request Validation Publish to npm on merge NPM Version License: MIT Website

A powerful and flexible library for comparing JSON objects with support for deep comparison, regex validation, and customizable options.

Playground

Try before you implement! Test the library's capabilities and experiment with different comparison options using our interactive playground:

JSON Deep Compare Playground

The playground allows you to:

  • Compare JSON objects in real-time
  • Customize comparison options
  • Visualize match results and differences
  • Test regex validations

Features

  • Deep Comparison: Perform a deep comparison of JSON objects, including nested objects and arrays.
  • Advanced Type Checking: Compare values with precise type detection, identifying specific data types (string, number, array, object, null, etc.) and providing detailed type mismatch information.
  • Key and Value Type Comparison: Compare both keys and value types, ensuring that mismatches in types are reported.
  • Regex Checks: Validate string values against regex patterns, with support for both exact path matching and key name matching.
  • Result Structure: Get results in a structured format that clearly indicates matched keys and values, unmatched keys, unmatched values, and regex check results.
  • Customizable Options: Customize the comparison behavior with options for ignoring specific keys, treating certain values as equivalent, and handling different data types.
  • TypeScript Support: Full TypeScript type definitions included for better development experience.
  • Performance Optimized: Designed to efficiently handle large JSON objects.

Installation

npm install json-deep-compare

You can also install from GitHub Packages. See Publishing Documentation for details.

Basic Usage

const JSONCompare = require('json-deep-compare');

// Create objects to compare
const obj1 = {
  user: {
    name: "Ashmeet Sehgal",
    email: "ashmeet@ashmeetsehgal.com",
    details: {
      phone: "+91-9876543210"
    }
  },
  products: [
    { id: "PROD-123", name: "Product 1" }
  ]
};

const obj2 = {
  user: {
    name: "Ashmeet Sehgal",
    email: "contact@ashmeetsehgal.com", // Different email
    details: {
      phone: "+91-9876543210"
    }
  },
  products: [
    { id: "PROD-123", name: "Product 1" }
  ]
};

// Create a comparator with regex checks
const comparator = new JSONCompare({
  regexChecks: {
    'email': /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
    'phone': /\+\d{1,3}-\d{3,14}/,  // Will match any key named 'phone'
    'products[0].id': /^PROD-\d+$/
  },
  matchKeysByName: true // Enable matching by key name for regex checks
});

// Perform the comparison
const result = comparator.compareAndValidate(obj1, obj2);

console.log(result);

Options

You can customize the comparison behavior with the following options:

const options = {
  // Keys to ignore during comparison
  ignoredKeys: ['createdAt', 'updatedAt'],

  // Values to treat as equivalent
  equivalentValues: {
    'booleanTypes': [true, 'true', 1],
    'emptyValues': [null, undefined, '']
  },

  // Regex patterns for value validation
  regexChecks: {
    'email': /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
    'user.details.phone': '\\+\\d{1,3}-\\d{3,14}',  // String pattern
    'products[0].id': /^PROD-\d+$/
  },

  // Whether to strictly compare types
  strictTypes: true,

  // Whether to ignore keys in obj2 that aren't in obj1
  ignoreExtraKeys: false,

  // Whether to match regex by key name instead of only by path
  matchKeysByName: true
};

const comparator = new JSONCompare(options);

Result Structure

The comparison result has the following structure:

{
  matched: {
    keys: [],    // Matched keys
    values: []   // Matched values
  },
  unmatched: {
    keys: [],    // Keys found in one object but not the other
    values: [],  // Values that don't match
    types: []    // Values with mismatched types
  },
  regexChecks: {
    passed: [],  // Values that passed regex validation
    failed: []   // Values that failed regex validation
  },
  summary: {
    matchPercentage: 0,     // Percentage of matched elements
    totalKeysCompared: 0,   // Total number of keys compared
    totalMatched: 0,        // Total number of matched elements
    totalUnmatched: 0,      // Total number of unmatched elements
    totalRegexChecks: 0     // Total number of regex checks performed
  }
}

Advanced Usage

Matching by Key Name

With the matchKeysByName option set to true, the library will apply regex checks to all keys with matching names, not just exact paths. This is useful for validating all fields of a specific type regardless of their location in the object.

const comparator = new JSONCompare({
  regexChecks: {
    'email': /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
  },
  matchKeysByName: true
});

// This will validate both user.email and customer.email fields

Treating Values as Equivalent

You can define sets of values that should be treated as equivalent:

const comparator = new JSONCompare({
  equivalentValues: {
    'booleanTypes': [true, 'true', 1],
    'emptyValues': [null, undefined, '']
  }
});

// true, 'true', and 1 will be considered equivalent
// null, undefined, and '' will be considered equivalent

Ignoring Extra Keys

If you only care about whether obj2 contains all the keys from obj1, you can ignore extra keys:

const comparator = new JSONCompare({
  ignoreExtraKeys: true
});

// Keys in obj2 that aren't in obj1 will be ignored

Type Checking

The library includes advanced type checking capabilities to identify and report the specific types of values being compared.

Supported Types

The following types are precisely detected:

  • Primitive types: string, number, boolean, undefined
  • Complex types: array, object, null
  • Special objects: date, regex
  • Custom object types based on constructor name

Type Checking Example

const JSONCompare = require('json-deep-compare');

const obj1 = {
  id: 1,                     // Number
  name: "Product",           // String
  price: "19.99"             // String (will be compared with a number)
};

const obj2 = {
  id: "1",                   // String (type mismatch with obj1.id)
  name: "Product",           // String (matching)
  price: 19.99               // Number (type mismatch with obj1.price)
};

// Create a JSONCompare instance
const compare = new JSONCompare({
  strictTypes: false  // Set to true to fail comparison on type mismatches
});

// Perform the comparison
const result = compare.compare(obj1, obj2);

// Check for type mismatches
if (result.unmatched.types.length > 0) {
  console.log("Type mismatches found:");
  result.unmatched.types.forEach(mismatch => {
    console.log(`Path: ${mismatch.path}`);
    console.log(`Expected type: ${mismatch.expected}, Actual type: ${mismatch.actual}`);
  });
}

Strict Type Checking

When strictTypes is set to true, the comparison will stop at the first type mismatch for each path:

const strictCompare = new JSONCompare({ strictTypes: true });
const strictResult = strictCompare.compare(obj1, obj2);

Type Information in Results

Type information is included in both matched and unmatched values:

// For matched values
{
  path: "name",
  value: "Product",
  type: "string"
}

// For unmatched values
{
  path: "id",
  expected: 1,
  actual: "1",
  expectedType: "number",
  actualType: "string",
  message: "Values do not match"
}

// For type mismatches
{
  path: "id",
  expected: "number",
  actual: "string",
  message: "Types do not match: expected 'number', got 'string'"
}

Type-Safe Equivalence

When using equivalence rules with different types, the types are still reported correctly:

const compare = new JSONCompare({
  equivalentValues: {
    'nullish': [null, undefined]
  }
});

// Result will show:
// "Values considered equivalent by rule 'nullish'"
// but will still report type1: "null", type2: "undefined"

License

MIT

Support This Project

If you find this library useful for your projects, please consider supporting its development and maintenance:

  • ⭐ Star the project on GitHub - It helps increase visibility

Your support helps keep this project maintained and improved with new features!