Skip to content

fix(website): patch typescript-json-schema for graphql-js v17 index signatures - #11036

Open
BuddhaBing wants to merge 1 commit into
dotansimha:masterfrom
BuddhaBing:patch-typescript-json-schema
Open

BuddhaBing wants to merge 1 commit into
dotansimha:masterfrom
BuddhaBing:patch-typescript-json-schema

Conversation

@BuddhaBing

Copy link
Copy Markdown
Contributor

What

Patches typescript-json-schema (via pnpm patchedDependencies) so that pnpm --filter website generate-config-schema works under graphql-js v17, and regenerates website/config.schema.json.

Why

After the bump to graphql@17, the website script that generates the JSON Schema for codegen.ts / codegen.yml crashes:

$ pnpm --filter website generate-config-schema

Error: Not supported: IndexSignatureDeclaration with index symbol other than a number or a string
    at JsonSchemaGenerator.getClassDefinition (.../typescript-json-schema.ts:1159:31)
    ...
    at JsonSchemaGenerator.getUnionDefinition (.../typescript-json-schema.ts:986:34)

Root cause

generate-config-schema.ts walks Types.Config to build the schema. The chain to the crash is:

  1. Types.Config.schema is InstanceOrArray<Types.Schema>, and Types.Schema is a union that ends in | GraphQLSchema (packages/utils/plugins-helpers/src/types.ts).

  2. The generator therefore descends into graphql-js's own GraphQLSchema type → its extensions property → the GraphQLSchemaExtensions interface.

  3. In graphql-js v17, that interface changed its index signature:

    - [attributeName: string]: unknown;
    + [attributeName: string | symbol]: unknown;
  4. typescript-json-schema only supports a pure string or number index key. It checks indexType.flags === ts.TypeFlags.String with strict equality, so the union key string | symbol (a Union type) fails the check and it throws.

This is not a bug in this repo's script or types — it's an incompatibility between graphql-js v17's type definitions and typescript-json-schema. Upstream has not fixed it: typescript-json-schema@0.68.0 contains byte-for-byte the same check, so a version bump does not help.

The fix

A one-line change to typescript-json-schema's isIndexedObject check, applied through pnpm patchedDependencies (the same mechanism already used in this repo for bob-the-bundler):

const isIndexedObject =
  indexType.flags === ts.TypeFlags.String ||
  indexType.flags === ts.TypeFlags.Number ||
  (!!(indexType.flags & ts.TypeFlags.Union) &&
    indexType.types.every(t => t.flags & (ts.TypeFlags.StringLike | ts.TypeFlags.ESSymbolLike)));

A union index key whose constituents are all string/symbol is now treated as a normal string-indexed object. GraphQLSchemaExtensions then serializes correctly as:

"GraphQLSchemaExtensions": {
  "description": "Custom extensions",
  "type": "object",
  "additionalProperties": {}
}

This also generalises to graphql-js's other *Extensions interfaces, which moved to the same string | symbol index signature in v17.

About the regenerated config.schema.json

The schema is regenerated as part of this PR. The diff is entirely confined to graphql-internal types reachable from GraphQLSchema (its internals plus the AST-node graph — DocumentNode, FieldNode, GraphQLError, etc.). Every plugin and preset config definition is unchanged — all hunks fall at/after the GraphQLSchema definition; nothing above it (Types.Config, every *PluginConfig, every preset, GeneratedPluginsMap) is touched. The net line reduction reflects graphql-js v17 restructuring its own types, not any loss of plugin/preset config coverage. These graphql-internal definitions are effectively inert in a config JSON Schema anyway, since a live GraphQLSchema object cannot be expressed in YAML/JSON config.

Alternative considered: patch the script instead of the dependency

Rather than patching typescript-json-schema, we could keep GraphQLSchema out of the walked type graph entirely — for example, by post-processing in generate-config-schema.ts to replace the GraphQLSchema branch of the Types.Schema union with an opaque {} / object, so the generator never descends into graphql-js internals.

Pros: no dependency patch to carry across future typescript-json-schema bumps; removes a large block of inert graphql-internal noise from config.schema.json.

Cons: typescript-json-schema has no clean "exclude this type" hook, so it's more code and more fragile than the one-line patch; and the only alternative place to cut the union — editing Types.Schema in plugins-helpers — would change a real, published runtime type purely to satisfy a docs-tooling build, which is undesirable. Editing generate-config-schema.ts to prune the branch after the fact is viable but still more involved than the patch.

The dependency patch was chosen as the smallest, most robust change with the least blast radius. The script-level prune would make a reasonable follow-up if maintainers would prefer to drop the graphql-internal types from the schema altogether — happy to switch approaches if preferred.

Notes

  • typescript-json-schema is a dev-only dependency of the website workspace and is not used anywhere else in the monorepo, so this affects only the docs schema-generation build — no published package or runtime codegen behaviour changes.

🤖 Generated with Claude Code

…ignatures

The website `generate-config-schema` script crashes under graphql-js
v17 with:

    Error: Not supported: IndexSignatureDeclaration with index symbol
    other than a number or a string

`Types.Schema` (packages/utils/plugins-helpers) unions in `GraphQLSchema`,
so the generator walks into graphql-js's own types. In v17,
`GraphQLSchemaExtensions` changed its index signature from
`[attributeName: string]` to `[attributeName: string | symbol]`, and
typescript-json-schema only accepts a pure `string` or `number` index
key, so it throws.

Upstream has not fixed this (0.68.0 has identical logic), so this patches
typescript-json-schema via pnpm `patchedDependencies` (same mechanism
already used for bob-the-bundler) to treat a union index key made of
string/symbol constituents as a normal string-indexed object.
`GraphQLSchemaExtensions` then serializes as
`{ "type": "object", "additionalProperties": {} }`, which is correct.

config.schema.json is regenerated: the diff is confined entirely to
graphql-internal types reachable from `GraphQLSchema`; every plugin and
preset config definition is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Oct 5, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 795fe2c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

This branch has not been deployed

No deployments
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.

1 participant