Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6

# Add any setup steps before running the `github/codeql-action/init` action.
# This includes steps like installing compilers or runtimes (`actions/setup-node`
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Use Node.js
uses: actions/setup-node@v5
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ yarn-error.log*

# env files (can opt-in for committing if needed)
.env*
!.env.example

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
.env.example
31 changes: 24 additions & 7 deletions Agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,30 @@ This is a Next.js app that compares two JSON API responses.
Core flow:

```text
Parse JSON
Parse JSON or fetch remote JSON
-> Flatten nested paths
-> Compare flattened values
-> Display DiffEntry[] in a table
```

The app supports:

- manual paste entry for `JSON A` and `JSON B`
- JSON file uploads for each response
- remote API URL fetching via `/api/proxy`
- ignore-field filtering during comparison
- copy diff output to clipboard
- download styled Excel reports
- light/dark theme toggling

## Important Files

- `src/app/page.tsx`: main UI and user interaction
- `src/app/api/proxy/route.ts`: server-side proxy route for fetching external JSON URLs
- `src/components/theme-toggle.tsx`: theme toggle button for light/dark mode
- `src/components/theme-provider.tsx`: theme provider wrapper
- `src/lib/flatten.ts`: converts JSON values into path-value pairs
- `src/lib/compare.ts`: compares flattened JSON values
- `src/lib/compare.ts`: compares flattened JSON values and supports ignore keys
- `src/types/diff.ts`: shared `DiffEntry` type
- `test/`: test suite mirroring the `src/` hierarchy

Expand All @@ -31,16 +44,18 @@ Parse JSON
- Mirror source hierarchy when adding tests:

```text
src/app/page.tsx -> test/app/page.test.tsx
src/lib/compare.ts -> test/lib/compare.test.ts
src/lib/flatten.ts -> test/lib/flatten.test.ts
src/types/diff.ts -> test/types/diff.test.ts
src/app/page.tsx -> test/app/page.test.tsx
src/app/api/proxy/route.ts -> test/app/api/proxy/route.test.ts
src/lib/compare.ts -> test/lib/compare.test.ts
src/lib/flatten.ts -> test/lib/flatten.test.ts
src/types/diff.ts -> test/types/diff.test.ts
```

- Prefer small, focused changes.
- Avoid unrelated refactors.
- Preserve accessibility in the UI. Labels should be associated with controls.
- Use visible UI behavior in React Testing Library tests.
- For route handlers, prefer node-compatible test environments and stub `fetch` appropriately.

## Commands

Expand Down Expand Up @@ -68,7 +83,7 @@ For meaningful code changes, run all three before finishing.

`JSON A` is the original value. `JSON B` is the new value.

`compareJson(jsonA, jsonB)` returns:
`compareJson(jsonA, jsonB, ignoreKeys?)` returns:

```ts
DiffEntry[]
Expand All @@ -80,6 +95,8 @@ Supported diff types:
- `REMOVED`: path exists only in `JSON A`
- `CHANGED`: path exists in both, but values differ

The app flattens nested objects and arrays so differences appear as paths like `user.name` or `items[0].price`.

## Dependency Note

`package.json` includes a PostCSS override so npm resolves a patched PostCSS version while using the current Next.js release. Do not remove it unless Next.js no longer needs it and `npm audit` stays clean.
31 changes: 23 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,24 @@ Install dependencies:
npm install
```

Run the app:
Run the app locally:

```bash
npm run dev
```

The app supports:

- manual paste for `JSON A` and `JSON B`
- JSON file uploads for each response
- remote JSON fetch comparison using `API URL A` and `API URL B`
- ignore-field filtering during comparison
- copying diffs to the clipboard
- downloading diffs as an Excel spreadsheet
- light/dark theme toggling

## Verification

Run checks before opening a pull request:

```bash
Expand All @@ -37,20 +49,23 @@ npm run build
Tests live outside `src` under the `test` directory:

```text
test/app/ UI tests for src/app
test/lib/ Utility tests for src/lib
test/types/ Type contract tests for src/types
test/app/ UI tests for src/app
test/app/api/proxy/ API route tests for src/app/api/proxy
test/lib/ Utility tests for src/lib
test/types/ Type contract tests for src/types
```

Use Vitest for all tests. Use React Testing Library for UI behavior and prefer user-visible queries such as labels, roles, and text.
Use Vitest for all tests. Use React Testing Library for UI behavior and prefer user-visible queries such as labels, roles, and text. For route tests, use the node test environment and stub `fetch` as needed.

## Code Conventions

- Keep TypeScript strict and explicit where it helps readability.
- Keep comparison logic in `src/lib`.
- Keep shared data shapes in `src/types`.
- Keep UI state and rendering in `src/app/page.tsx` unless the UI grows enough to justify components.
- Keep UI state and rendering in `src/app/page.tsx` unless the UI grows enough to justify splitting into components.
- Keep proxy or route-specific logic in `src/app/api/proxy/route.ts`.
- Avoid unrelated refactors in feature or bug-fix changes.
- Preserve accessibility in the UI; labels should be connected to inputs and controls.

## Comparator Behavior

Expand All @@ -61,7 +76,7 @@ JSON A = original value
JSON B = new value
```

The app parses both inputs, flattens nested values, compares flattened paths, and renders `DiffEntry[]`.
The app parses both inputs or fetches remote JSON, flattens nested values, compares flattened paths, and renders `DiffEntry[]`.

Supported diff types:

Expand All @@ -75,4 +90,4 @@ Supported diff types:
- `npm test` passes
- `npm run lint` passes
- `npm run build` passes
- README or contributor docs updated when behavior or workflow changes
- README, Agents, or Claude docs updated when behavior or workflow changes
28 changes: 23 additions & 5 deletions Claude.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,23 @@ This repository is API Response Comparator, a small Next.js and TypeScript app f

## What To Know First

The app takes two text inputs:
The app takes two JSON inputs:

- `JSON A`: original response
- `JSON B`: new response

It also supports two remote JSON URLs:

- `API URL A`
- `API URL B`

Then it:

```text
parses JSON -> flattens paths -> compares values -> renders DiffEntry[] in a table
parse JSON or fetch remote JSON
-> flatten nested paths
-> compare flattened values
-> display DiffEntry[] in a table
```

The core data shape is:
Expand All @@ -34,6 +42,11 @@ src/
page.tsx
layout.tsx
globals.css
api/
proxy/route.ts
components/
theme-provider.tsx
theme-toggle.tsx
lib/
compare.ts
flatten.ts
Expand All @@ -42,6 +55,9 @@ src/

test/
app/
api/
proxy/route.test.ts
page.test.tsx
lib/
types/
```
Expand All @@ -52,18 +68,20 @@ Tests should stay under `test/` and mirror the `src/` hierarchy.

- Keep `flatten` behavior in `src/lib/flatten.ts`.
- Keep comparison behavior in `src/lib/compare.ts`.
- Keep UI behavior in `src/app/page.tsx` unless the UI becomes large enough to split.
- Keep UI behavior in `src/app/page.tsx` unless it becomes large enough to split.
- Keep shared type changes in `src/types`.
- Avoid changing public behavior without updating tests.
- Prefer clear, direct TypeScript over extra abstraction.
- Do not move tests back into `src`.
- For route handlers, keep tests in a node-compatible environment and stub `fetch`.

## UI Guidance

- Preserve accessible labels for the JSON textareas.
- Preserve accessible labels for inputs and controls.
- Test UI behavior with React Testing Library using labels, roles, and visible text.
- Keep the results table focused on `Path`, `Type`, `JSON A`, and `JSON B`.
- Show parse errors instead of trying to compare invalid JSON.
- Show parse errors rather than attempting a comparison on invalid JSON.
- Support file uploads, URL fetch comparison, ignore-field filtering, copy diff, and Excel export.

## Verification

Expand Down
2 changes: 2 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ MIT License

Copyright (c) 2026 Arnab Nandy

SPDX-License-Identifier: MIT

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
Expand Down
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@ Parse JSON
## Features

- Paste two JSON responses side by side
- Fetch and compare two remote JSON API URLs directly
- Upload JSON files for Response A and Response B
- Detect added, removed, and changed values
- Optionally ignore specific fields during comparison
- Copy diff output as JSON to clipboard
- Download diff results as a styled Excel spreadsheet
- Light/dark theme toggle
- Flatten nested objects and arrays into readable paths
- Display differences in a table with old and new values
- Display results in an accessible diff table
- Show parse errors for invalid JSON
- Unit and UI tests with Vitest and Testing Library

Expand All @@ -41,6 +47,13 @@ Install dependencies:
npm install
```

Create `.env.local` from `.env.example` and list each remote API hostname the
server may contact:

```bash
ALLOWED_PROXY_HOSTS=www.elevation-api.eu,api.example.com
```

Start the development server:

```bash
Expand All @@ -49,6 +62,18 @@ npm run dev

Open [http://localhost:3000](http://localhost:3000) in your browser.

## How to Use

1. Paste JSON into `JSON A` and `JSON B`, or upload files using the upload buttons.
2. Optionally enter `API URL A` and `API URL B` to fetch remote JSON responses.
3. Use `Ignore fields` to exclude sensitive or irrelevant keys from the diff.
4. Click `Compare` or `Fetch & Compare`.
5. Copy the diff JSON or download an Excel report.

Remote URLs are fetched server-side through `/api/proxy`, which helps avoid
browser CORS restrictions for external JSON endpoints. For SSRF protection,
only HTTPS URLs on hosts listed in `ALLOWED_PROXY_HOSTS` are accepted.

## Scripts

```bash
Expand Down
Loading