Skip to content

CraigFW/JS

Repository files navigation

JSON Audit Helper Proof Of Concept

This project is a proof of concept for a reusable Node.js helper that compares two JSON values with an identity-aware diff engine and returns a structured audit result for a frontend to render.

The CLI in src/index.ts is only a stand-in consumer. The reusable comparison logic lives in src/audit.ts.

Install

npm install

Run

To choose two JSON files from a native Windows file picker that opens on your Desktop, run:

npm run compare

The CLI opens the picker twice, once for each file. The first picker starts on your Desktop and the second picker reuses the folder from the first selection so you can compare two files without typing paths.

To compare two JSON files directly from the CLI, pass the file paths as the first two arguments:

npm run compare -- ./left.json ./right.json

To save the full AuditResult JSON artifact next to the second compared file, add --save:

npm run compare -- --save ./left.json ./right.json

To supply AuditOptions, pass an inline JSON object as the optional third argument:

npm run compare -- ./left.json ./right.json '{"identityByPath":{"items":"id"}}'

If you prefer, the third argument can also be a path to a JSON file that contains the AuditOptions object.

CloudMatrix example:

npm run compare -- "C:/Users/CraigWhittington/OneDrive - SHI - Lab/Desktop/assessmentMockData.json" "C:/Users/CraigWhittington/OneDrive - SHI - Lab/Desktop/assessmentMockData2.json" '{"identityByPath":{"valueAssessment.assessments":"metadata.name","valueAssessment.assessments.profiles":["abbreviation","name"],"valueAssessment.assessments.features":"licensing","valueAssessment.assessments.features.products":"product","breakouts":"breakoutId","breakouts.features":["roadmapElementPath","elementSubdimension","roadmapProduct","feature"]}}'

If you add --save, the CLI writes the full AuditResult to a timestamped snapshot file named like left__vs__right__2026-06-12T14-30-45-000Z.audit.json in the directory of the second compared file. This works for both direct file-path mode and the Windows picker flow.

If the two JSON values are equivalent, the CLI returns an audit result with equal: true. Otherwise it prints a structured result containing:

  • summary: counts for add, remove, update, and move operations
  • changes: detailed change entries
  • diagnostics: warnings when identity matching falls back to low-confidence heuristics

Example output shape:

{
	"equal": false,
	"summary": {
		"totalChanges": 2,
		"adds": 0,
		"removes": 0,
		"updates": 1,
		"moves": 1,
		"diagnostics": 0
	},
	"changes": [
		{
			"path": "$.items[0]",
			"type": "MOVE",
			"identity": "name:Gamma",
			"fromIndex": 2,
			"toIndex": 0,
			"confidence": "high"
		}
	],
	"diagnostics": []
}

Helper API

Use src/audit.ts from a background Node.js service and pass the result to the frontend.

import { auditJson } from "./audit.js";

const result = auditJson(oldValue, newValue, {
	identityByPath: {
		items: "id",
		"items.children": ["type", "name"],
	},
	ambiguousArrayStrategy: "skip",
});

identityByPath lets the caller describe how array items should be matched for a given array path. Arrays with stable identities are compared by those identities instead of by position, which prevents deletes and inserts from cascading into noisy updates.

When no explicit identityByPath rule is provided for an array of objects, the helper now prefers a direct scalar field whose name looks like an identifier. It checks id case-insensitively first, then other direct scalar fields with an id token such as ID, templateId, or template_id, before falling back to the existing fields like name, abbreviation, product, licensing, key, and code.

If your payload needs stricter or composite matching, keep using identityByPath. Explicit rules still take precedence over the generic fallback heuristics.

Build and run compiled output

npm run build
node dist/index.js

Or pass file paths and optional AuditOptions with the compiled output:

npm run build
node dist/index.js ./left.json ./right.json '{"identityByPath":{"items":"id"}}'

To save the compiled-output audit artifact as well:

npm run build
node dist/index.js --save ./left.json ./right.json '{"identityByPath":{"items":"id"}}'

Current limits

  • The CLI accepts AuditOptions as an optional third argument, but callers still need to know which identity rules fit their schema.
  • Interactive file selection currently uses a Windows-native file picker. On non-Windows platforms, pass file paths on the command line instead.
  • Generic move detection is conservative. If no stable identity can be established for an array path, the helper falls back to positional comparison and may emit diagnostics instead of overstating confidence.
  • Large payloads will likely need summary-first rendering in the eventual frontend.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages