Skip to content

fix(scalars): correct jsonSchema definitions that misdescribe their values#3090

Open
ifeanyi-ugwu wants to merge 2 commits into
graphql-hive:masterfrom
ifeanyi-ugwu:fix/jsonschema-definitions
Open

fix(scalars): correct jsonSchema definitions that misdescribe their values#3090
ifeanyi-ugwu wants to merge 2 commits into
graphql-hive:masterfrom
ifeanyi-ugwu:fix/jsonschema-definitions

Conversation

@ifeanyi-ugwu

@ifeanyi-ugwu ifeanyi-ugwu commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Several scalars ship a jsonSchema extension that rejects values the scalar serializes or declares the wrong type. This corrects each to match the serialized output.

Rejecting values the scalar accepts:

  • SESSNSESSN_PATTERNS held the format placeholders YYYYMMDDXXXX / YYMMDDXXXX, used verbatim as regex patterns, so they matched only that literal text and no real personnummer. The length beside them is not a JSON Schema keyword. Replaced with real patterns for the two accepted forms under anyOf.
  • PostalCode — used oneOf over the per-country patterns, but postal formats overlap (a 5-digit code matches US, DE, FR, IT, ES at once), so a valid code matches several patterns and fails oneOf's exactly-one requirement. Changed to anyOf.
  • LocalDateTimeformat:'date-time' mandates an RFC 3339 offset, which an offset-less LocalDateTime never has. Uses the scalar's own regex as pattern, like LocalDate and LocalTime.

Mismatched serialized output:

  • Timestamp — declared type:'string', but serialize returns a number of milliseconds. Now type:'integer'.
  • BigInt / Longint64 implies a 64-bit bound a BigInt does not have and omits the decimal-string form used beyond the safe-integer range. Now oneOf:[integer, numeric-string].
  • USCurrency — the pattern forbade the thousands separators and leading minus that toLocaleString produces, so it rejected the scalar's own output above $999 and for negatives. Widened to match.

Three scalars shipped a jsonSchema that rejects values the scalar itself
accepts:

- SESSN: the "patterns" were the format placeholders 'YYYYMMDDXXXX' /
  'YYMMDDXXXX', used verbatim as regex patterns, so they matched only that
  literal text and no real personnummer. The `length` keyword beside them
  is not a JSON Schema keyword either.
- PostalCode: oneOf over per-country patterns, but postal formats overlap
  — a 5-digit code matches US, DE, FR, IT, ES, ... at once — so every such
  code matches several patterns and fails oneOf's exactly-one requirement.
- LocalDateTime: format 'date-time' requires an RFC 3339 timezone offset,
  which an offset-less LocalDateTime never has.
These jsonSchema definitions did not describe the value their scalar
actually serializes:

- Timestamp: declared type 'string', but serialize() returns a number of
  milliseconds (Date#getTime). 'unix-time' is also a non-standard,
  unenforceable format.
- BigInt / Long: 'int64' implies a 64-bit bound a BigInt does not have, and
  type 'integer' alone omits the decimal-string form used for values beyond
  the safe-integer range.
- USCurrency: the pattern forbade thousands separators and a leading minus,
  but serialize() emits locale-formatted strings like -$1,000.00, so the
  schema rejected the scalar's own output above $999 and for all negatives.
@ardatan

ardatan commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Those format values are actually heavily used in OpenAPI spec. So I am not sure if they should be considered as non-standard.
https://swagger.io/docs/specification/v3_0/data-models/data-types/

@ifeanyi-ugwu
ifeanyi-ugwu force-pushed the fix/jsonschema-definitions branch from b23c016 to 5e7ce49 Compare July 10, 2026 12:20
@ifeanyi-ugwu

Copy link
Copy Markdown
Contributor Author

Those format values are actually heavily used in OpenAPI spec. So I am not sure if they should be considered as non-standard. https://swagger.io/docs/specification/v3_0/data-models/data-types/

byte and int64 are standard OpenAPI formats and "non-standard" was wrong. These annotations feed SOFA, which emits OpenAPI, so OpenAPI's format vocabulary applies.

I dropped the Byte change. serialize returns a Buffer and Buffer encodes on the wire as {"type":"Buffer","data":[...]}. type:'string' mis-describes that output whether the value carries format:'byte' or a pattern. Byte will need its own change.

PostalCode, SESSN, USCurrency, and LocalDateTime reject values the scalar emits.

Timestamp declared type:'string'; serialize returns a number.

BigInt moved to oneOf:[integer, numeric-string]. A BigInt isn't 64-bit-bounded. It serializes as a string once it passes the safe-integer range. int64 captures neither. If SOFA already emits out-of-range int64 as a string, int64 alone suffices and I'll switch back.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants