feat(node-type-registry): blueprint type codegen — TS types from node type definitions#908
Merged
pyramation merged 6 commits intomainfrom Mar 26, 2026
Merged
Conversation
…ypes from node type definitions Adds generate-types.ts codegen that produces blueprint-types.generated.ts with: - Per-node-type parameter interfaces (DataIdParams, AuthzDirectOwnerParams, etc.) - BlueprintNode discriminated union (string shorthand or typed object) - BlueprintRelation, BlueprintTable, BlueprintDefinition types - Static types: BlueprintField, BlueprintPolicy, BlueprintIndex, etc. These are client-side types matching the JSONB shape expected by construct_blueprint(). The GraphQL API stays simple (plain JSON scalar). Also: - Exports generated types from package index - Adds generate:types npm script - Updates README with new usage examples - Deprecates NodeTypeRegistryPreset in favor of generated types
Contributor
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
…types The hand-crafted 963-line GraphQL plugin (from PR #907) is replaced by the codegen approach in node-type-registry. These files were never imported or referenced from any preset or consumer. Removes: - graphile-settings/src/plugins/blueprint-types/ (3 files) - graphile-settings/__tests__/blueprint-types-plugin.test.ts
…nfig deps from node-type-registry
…ype codegen Replace hand-rolled string concatenation with: - schema-typescript's generateTypeScriptTypes() for JSON Schema -> Babel AST - @babel/types for all structural type construction - @babel/generator for final code output No string concatenation in the codegen pipeline. All 52 node types generate correctly with proper enum handling and nested object support.
…or numeric enum/const support - Bump schema-typescript from ^0.14.1 to ^0.14.2 - Remove sanitizeSchema workaround for numeric enums (fixed upstream) - Keep minimal ensureArrayItems() for array types missing items spec - Generated types now include proper numeric literals (e.g. dimension?: 2 | 3 | 4)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a TypeScript codegen script (
src/codegen/generate-types.ts) that reads the existingallNodeTypesarray and producesblueprint-types.generated.ts— a set of TypeScript types matching the JSONB shape expected byconstruct_blueprint().Motivation: Replace the hand-crafted 963-line GraphQL plugin approach (PR #907) with generated client-side types. The GraphQL API stays simple (plain JSONB), while consumers get autocomplete and type safety when building blueprint definitions in TypeScript.
What's generated (916 lines):
parameter_schemaJSON Schema (e.g.DataIdParams,AuthzDirectOwnerParams)BlueprintNodediscriminated union (string shorthand'DataId'or typed object{ $type: 'DataId', data: DataIdParams })BlueprintRelationdiscriminated union for 4 relation typesBlueprintField,BlueprintPolicy,BlueprintIndex,BlueprintFullTextSearch,BlueprintTable,BlueprintDefinitionCleanup: removed dead blueprint-types plugin + NodeTypeRegistryPreset
graphile-settings/src/plugins/blueprint-types/(3 files, ~730 lines) and its test file (~270 lines). These were the hand-crafted GraphQL plugin approach that this codegen replaces — never imported by any preset or consumer onmain.graphile-settings/src/plugins/index.ts.node-type-registry/src/preset.ts(NodeTypeRegistryPreset) — it importedcreateBlueprintTypesPluginfrom the now-deleted plugin. This preset is no longer needed; consumers should use the generated TS types directly instead of GraphQL input types.graphile-settingsandgraphile-configfromnode-type-registrydependencies (only used by the deleted preset). This significantly reduces the package's dependency footprint.AST-based codegen via
schema-typescriptReplaced the hand-rolled
jsonSchemaToTsType()string concatenation with a pure Babel AST approach:schema-typescript@^0.14.2,@babel/generator@^7.29.0,@babel/types@^7.29.0generate-types.tsrewritten (80%): All type construction uses@babel/typesAST nodes. Per-node-type parameter interfaces are produced byschema-typescript'sgenerateTypeScriptTypes()which returnst.ExportNamedDeclaration[]directly. Static structural types (BlueprintTable,BlueprintDefinition, etc.) are built with AST helper functions. Final output via@babel/generator'sgenerate().schema-typescript@0.14.2(dev-utils PR #73) fixesgetTypeForProp()to uset.numericLiteral()/t.booleanLiteral()for non-string enum and const values. Generated types now include proper numeric literal unions (e.g.dimension?: 2 | 3 | 4).ensureArrayItems()sanitizer:schema-typescriptstill throws on array types without anitemsspec. A small recursive function adds{ type: 'string' }as default items for bare arrays — this is the only remaining workaround.Review & Testing Checklist for Human
cd graphile/node-type-registry && pnpm generate:typesand confirmblueprint-types.generated.tsis unchanged (ensures the committed file isn't stale or manually edited)construct_blueprint():BlueprintField,BlueprintPolicy,BlueprintTable,BlueprintDefinitionare hardcoded in the generator (not derived from schema). Verify field names/types match what the SQL function actually reads — especiallyBlueprintPolicy.$type,BlueprintTable.grants(unknown[]is very loose), andBlueprintIndex.access_methodensureArrayItems()default is safe: The sanitizer addsitems: { type: 'string' }for arrays without an items spec. Check whether any node type schemas have array fields that should resolve to something other thanstring[]require('@babel/generator')workaround: The@babel/generatorimport usesconst generate = require(…).default ?? require(…)because@types/babel__generatorisn't in dependencies. Confirm this works in both CJS and ESM buildsNodeTypeRegistryPreset: The preset is deleted — search downstream repos (especially constructive-db) forNodeTypeRegistryPresetorfrom 'node-type-registry/preset'imports. constructive-db PR refactor(codegen): remove dead maxFieldDepth code and enforce trailing commas #697 removes the only known usageNotes
schema-typescript-generated property comments use/* */style while the hand-written static types use/** */JSDoc style — minor cosmetic inconsistency in the outputgenerate()and compares outputNodeTypeRegistryPresetfrom the codegen pipeline; agentic-db upgrade all utils packages #41 updates to use the generated types; dev-utils cleaner API #73 (merged) fixes upstream numeric enum handlingLink to Devin session: https://app.devin.ai/sessions/ce1b2dafd42341bea5d7793b0c05ba6c
Requested by: @pyramation