Skip to content

Transform JSON / JSONB parameter keys#1169

Open
karlhorky wants to merge 6 commits into
porsager:masterfrom
karlhorky:sql-json-transforms
Open

Transform JSON / JSONB parameter keys#1169
karlhorky wants to merge 6 commits into
porsager:masterfrom
karlhorky:sql-json-transforms

Conversation

@karlhorky
Copy link
Copy Markdown
Contributor

@karlhorky karlhorky commented May 27, 2026

Hey @porsager, hope you're good! 👋

Postgres.js transforms JS property names passed through sql(...) helpers, eg. with { transform: postgres.camel }:

sql({ firstName: 'Ada' }) // { first_name: 'Ada' }

However, currently JSON parameter keys are not transformed 💥

sql.json({ firstName: 'Ada' }) // {"firstName":"Ada"}

Maybe this was an oversight in my previous PR for "nested transforms":

This PR adds JSON value transforms before serialization for the built-in case transforms, so JSON and JSONB parameters serialize transformed keys:

sql.json({ firstName: 'Ada' }) // {"first_name":"Ada"}

This change also applies to JSON / JSONB data created via sql.typed() and type casts:

sql.typed({ firstName: 'Ada' }, 114) // {"first_name":"Ada"}
sql`${ { firstName: 'Ada' } }::jsonb` // {"first_name":"Ada"}
  • Transform JSON / JSONB parameter keys
  • Add value.to transforms for camel, pascal, and kebab
  • Test nested objects, arrays, result parsing, and untransformed JSON
  • Test implicit and typed JSON parameters
  • Update types

AI disclosure: guided use of gpt-5.5 high through Codex CLI

@karlhorky karlhorky marked this pull request as ready for review May 27, 2026 17:31
Copilot AI review requested due to automatic review settings May 27, 2026 17:31
Comment thread types/index.d.ts
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR extends the library’s transform system so JSON parameter serialization can apply key-casing transforms (e.g., camelCase ⇄ snake_case), and updates typings + tests accordingly.

Changes:

  • Apply transform.value.to during JSON serialization (for JSON/JSONB parameters).
  • Add value.to transform helpers for camel/pascal/kebab transforms.
  • Update TypeScript declarations and expand JSON transform test coverage across builds (node/deno/cjs).

Reviewed changes

Copilot reviewed 11 out of 13 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
types/index.d.ts Updates public typings for transform value-direction helpers and serializer signatures.
src/types.js Applies transform-on-JSON-serialize and wires up value.to for casing transforms.
src/connection.js Passes parsed options into serializers.
tests/index.js Adds coverage for JSON key transforms on parameters/results.
deno/types/index.d.ts Mirrors typing changes for Deno build.
deno/src/types.js Mirrors JSON serialization + transform wiring for Deno build.
deno/src/connection.js Mirrors passing options into serializers for Deno build.
deno/tests/index.js Mirrors JSON transform tests for Deno build.
cjs/src/types.js Mirrors JSON serialization + transform wiring for CJS build.
cjs/src/connection.js Mirrors passing options into serializers for CJS build.
cjs/tests/index.js Mirrors JSON transform tests for CJS build.
cf/src/types.js Mirrors JSON serialization + transform wiring for CF build.
cf/src/connection.js Mirrors passing options into serializers for CF build.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/types.js Outdated
Comment thread deno/src/types.js Outdated
Comment thread cjs/src/types.js Outdated
Comment thread cf/src/types.js Outdated
Comment thread src/types.js Outdated
Comment thread tests/index.js
@karlhorky karlhorky requested a review from Copilot May 27, 2026 20:02
Comment thread src/types.js
Comment on lines -343 to +345
: Object.entries(x).reduce((acc, [k, v]) => Object.assign(acc, { [fn(k)]: jsonTransform(v, column) }), {})
: Object.getPrototypeOf(x) === Object.prototype || Object.getPrototypeOf(x) === null
? Object.entries(x).reduce((acc, [k, v]) => Object.assign(acc, { [fn(k)]: jsonTransform(v, column) }), {})
: x
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only transform plain objects, to avoid transforming objects like Dates

@karlhorky karlhorky force-pushed the sql-json-transforms branch from b50c30c to 5d73037 Compare May 28, 2026 07:47
@karlhorky
Copy link
Copy Markdown
Contributor Author

@porsager I think this is ready for a review

@porsager
Copy link
Copy Markdown
Owner

Nice @karlhorky - Only problem is that this is a breaking change, so I think the behaviour would need to be something toggled by an option??

@karlhorky
Copy link
Copy Markdown
Contributor Author

karlhorky commented May 29, 2026

@porsager yeah technically it's a breaking change to the current behavior.

Although arguably, the original promise of the postgres.camel transform was bidirectional transforms, so in that light it could be considered a "bug fix".

But yeah, to make the library updates less surprising, it's better to consider it as a breaking change, in case users are depending on the half-baked behavior.

Maybe a solution would be to release it in a new major version postgres@4.0.0 - what do you think?

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.

3 participants