Skip to content

feat(json2csv): add contextual Flatten nested keys pill and deep dot-flattening - #232

Merged
obvious-autobuild-staging[bot] merged 1 commit into
masterfrom
feat/json2csv-flatten-pill
Oct 20, 2026
Merged

obvious-autobuild-staging[bot] merged 1 commit into
masterfrom
feat/json2csv-flatten-pill

Conversation

@obvious-autobuild-staging

Copy link
Copy Markdown
Contributor

Human author: David Boskovic (david@obvious.ai)

Why

When users paste JSON containing nested objects ({ "user": { "profile": { "name": "Ada" } } }) or scalar arrays ({ "tags": ["math", "code"] }) into JSON → CSV mode, two friction points occur:

  1. The Flatten option is tucked inside Parse settings, unlike CSV → JSON mode (csv-indexed-array-pill) and wrapped root objects (json-unwrap-pill) which surface contextual one-click pills directly above the editor.
  2. Enabling Flatten previously only joined top-level scalar arrays via joinScalarArrays, leaving nested plain objects unflattened as raw JSON strings in CSV cells (or throwing NonTabularJsonError when nested structures were encountered).

What

  • Deep plain-object dot-flattening (app/src/lib/convert.ts):
    • Added flattenNestedObjects before joinScalarArrays when options.flatten === true in jsonToCsv. Nested plain objects of arbitrary depth expand into dotted column keys (user.profile.name, user.profile.city), nested scalar arrays join with ", ", empty plain objects ({}) normalize to "", and arrays of plain objects continue to use csvjson-json2csv's cartesian row expansion with their inner nested objects also dot-flattened.
  • Nested JSON key detector (detectNestedJsonKeys in app/src/lib/convert.ts):
    • Inspects valid JSON (arrays of objects or single record objects that are not wrappable containers) and multi-line JSONL/NDJSON across up to the first 50 records, returning unique top-level keys holding non-null plain objects or non-empty arrays in insertion order.
  • Contextual Flatten nested keys pill (app/src/components/InputPane.tsx & app/src/App.tsx):
    • Renders data-testid="json-flatten-bar" and data-testid="json-flatten-pill" (aria-pressed={flatten}) above the JSON editor when direction === "json2csv" and nested keys are detected, displaying up to 3 key names (Flatten nested keys (.user, .tags)) with ", +N more" overflow and active pressed styling (Flattened nested keys (...)) when enabled.
  • Changelog & Tests:
    • Added bundled changelog entry #19 in app/src/changelog/entries.ts and rebuilt app/dist.
    • Added unit tests in app/src/lib/__tests__/convert.test.ts and component integration tests in app/src/App.test.tsx.

Tradeoffs

  • Contextual pill synced with options.flatten vs. separate state: Binding the pill directly to options.flatten keeps the contextual strip above the JSON editor and the Parse settings checkbox in lockstep without duplicating state.
  • Deferring wrappable root containers: When a single root object is a wrapper around a record array ({ "data": [...] }), detectNestedJsonKeys returns [] so only the Unwrap .data (N rows) pill is shown first; once unwrapped, if individual records contain nested objects or arrays, the Flatten nested keys pill appears.

How to Review

  • app/src/lib/convert.ts — detectNestedJsonKeys, flattenRecordPlainObjects, flattenNestedObjects, and jsonToCsv pipeline order.
  • app/src/components/InputPane.tsx & app/src/App.tsx — contextual json-flatten-bar / json-flatten-pill rendering and onToggleFlatten wiring.
  • app/src/lib/__tests__/convert.test.ts & app/src/App.test.tsx — unit and component test coverage for AC-15 / D14.

Verification

  • cd app && npm run lint && npx tsc -b --noEmit && npm test && npm run build (34 test suites, 575 tests passing)
  • bash .github/scripts/verify-seo.sh
  • Interactive browser dogfooding at 1440×900 via agent-browser verifying nested key detection, one-click flatten toggle, dotted CSV table columns (USER.PROFILE.NAME, USER.PROFILE.CITY), and scalar array joining (TAGS).

🔗 Obvious Project · 🧵 Obvious Thread · 🔀 Obvious PR Artifact

@obvious-autobuild-staging
obvious-autobuild-staging Bot marked this pull request as ready for review October 20, 2026 02:42
…flattening

Add detectNestedJsonKeys and recursive plain-object dot-flattening in
convert.ts so nested plain objects (e.g. user.profile.name) and scalar
arrays flatten cleanly in JSON -> CSV mode without throwing
NonTabularJsonError, and surface a one-click Flatten nested keys toggle
pill above the JSON editor in InputPane when nested keys are detected.

Co-authored-by: David Boskovic <david@obvious.ai>
@obvious-autobuild-staging
obvious-autobuild-staging Bot force-pushed the feat/json2csv-flatten-pill branch from decde08 to d4f4c1e Compare October 20, 2026 02:49
@obvious-autobuild-staging
obvious-autobuild-staging Bot merged commit d3a2374 into master Oct 20, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants