Skip to content

feat: consolidate codegen test helper + runtime sub-export#1023

Open
pyramation wants to merge 8 commits intomainfrom
devin/1776760093-codegen-test-helper-and-runtime
Open

feat: consolidate codegen test helper + runtime sub-export#1023
pyramation wants to merge 8 commits intomainfrom
devin/1776760093-codegen-test-helper-and-runtime

Conversation

@pyramation
Copy link
Copy Markdown
Contributor

@pyramation pyramation commented Apr 21, 2026

Summary

Three packaging consolidations that emerged from the PR #934 refactoring work:

#1 — Move runCodegenAndLoad into @constructive-io/graphql-test

The codegen test helper (introspect → infer tables → generate ORM → compile TS → load createClient) was duplicated between orm-test and constructive-db. This PR:

  • Adds graphql/test/src/codegen-helper.ts with a version that supports both positional (GraphQLQueryFn) and object-style (GraphQLQueryFnObj) query signatures
  • Re-exports getDbConnections and related types from pgsql-test for two-phase test patterns
  • Updates all 4 orm-test suites to import from @constructive-io/graphql-test
  • Deletes the local orm-test/__tests__/helpers/codegen-helper.ts

#2 — Add @constructive-io/graphql-query/runtime sub-export

Generated ORM code currently imports from 3 separate runtime packages (@0no-co/graphql.web, gql-ast, @constructive-io/graphql-types). This PR consolidates two of the three:

  • Adds graphql/query/src/runtime/index.ts that re-exports @0no-co/graphql.web (parseType, print) and @constructive-io/graphql-types (GraphQLAdapter, GraphQLError, QueryResult)
  • Adds an exports field to graphql-query/package.json mapping ./runtime to runtime/index.js (CJS) and esm/runtime/index.js (ESM)
  • Updates query-builder.ts template: parseType/print now import from @constructive-io/graphql-query/runtime
  • Updates orm-client.ts template: GraphQLAdapter/GraphQLError/QueryResult types now import from @constructive-io/graphql-query/runtime
  • gql-ast is intentionally not re-exported — import * as t from 'gql-ast' stays as-is to avoid polluting the t namespace with unrelated symbols like parseType and print
  • Updates snapshot + assertion in client-generator.test.ts

#3 — Add @constructive-io/graphql-codegen/orm and ./cli sub-exports

The codegen-helper previously used a fragile require.resolve + path.join hack to reach into @constructive-io/graphql-codegen internals for generateOrm. The cli-e2e.test.ts similarly used deep path imports (@constructive-io/graphql-codegen/core/codegen/cli). This PR:

  • Adds an exports field to graphql-codegen/package.json with ./orm and ./cli sub-paths mapping to core/codegen/{orm,cli}/index.js (CJS) and esm/core/codegen/{orm,cli}/index.js (ESM)
  • Adds typesVersions to graphql-codegen/package.json — required because the root tsconfig.json uses moduleResolution: "node" which doesn't support the exports field. Packages like graphql/server-test that inherit this setting need typesVersions for TypeScript to resolve the sub-path types correctly. (graphql/test overrides to "nodenext" so it works without this.)
  • Replaces the require.resolve hack in codegen-helper.ts with a clean import { generateOrm } from '@constructive-io/graphql-codegen/orm'
  • Updates cli-e2e.test.ts to import from @constructive-io/graphql-codegen/cli and @constructive-io/graphql-codegen/orm instead of deep internal paths

Updates since last revision

  1. Fixed cli-e2e.test.ts failures — the server-test suite spawns child processes in /tmp/ with NODE_PATH to resolve runtime modules. Two changes were needed:

    • Added @constructive-io/graphql-query as a devDependency of graphql-server-test — pnpm workspace isolation means the package isn't resolvable unless explicitly declared.
    • Added @constructive-io/graphql-query to the runtimeDeps array in resolveNodePaths() — so the function collects the correct node_modules directories for the child process.
  2. Replaced require.resolve hack with ./orm sub-path export — added exports field to graphql-codegen/package.json and updated codegen-helper.ts to use a clean ESM-safe import instead of filesystem crawling.

  3. Added ./cli sub-path exportcli-e2e.test.ts was importing from @constructive-io/graphql-codegen/core/codegen/cli, which breaks once the exports field is present (it restricts resolvable paths). Added ./cli to the exports and updated the test imports.

  4. Added typesVersions for moduleResolution: "node" compat — the root tsconfig.json uses moduleResolution: "node" which ignores the exports field for type resolution. graphql/server-test inherits this setting. Without typesVersions, TypeScript couldn't resolve types for @constructive-io/graphql-codegen/orm or ./cli. Note: graphql/test already overrides to moduleResolution: "nodenext", so it didn't need this.

Review & Testing Checklist for Human

  • typesVersions vs bin for ./cli: The package has "bin": { "graphql-codegen": "cli/index.js" } (the CLI binary at dist/cli/) and "exports": { "./cli": ... } pointing to dist/core/codegen/cli/ (the generator code). With moduleResolution: "node", TypeScript would normally resolve @pkg/cli to dist/cli/index.d.ts (the binary). The typesVersions overrides this to the correct generator types. Verify this doesn't cause issues for any consumer that might import from the cli/ binary path directly.
  • ./orm and ./cli sub-paths expose full internal APIs as public. orm/index.ts exports generateOrm plus all sub-generators (generateAllModelFiles, generateOrmClientFile, etc.). cli/index.ts exports generateCli, generateMultiTargetCli, and all CLI generators. Previously these were internal. Confirm this surface area is acceptable.
  • Template import change is intentionally breaking for codegen consumers. query-builder.ts and orm-client.ts now import from @constructive-io/graphql-query/runtime. All downstream repos will produce new import paths on next codegen run. Verify they already have @constructive-io/graphql-query as a dependency and that the /runtime sub-path resolves.
  • Arity-based query function detection in codegen-helper.ts: queryFn.length <= 1 to distinguish object-style from positional. Verify this heuristic is correct for all graphile-test query wrappers.
  • Run orm-test and server-test suites against a real DB to confirm the sub-path imports resolve correctly end-to-end (CI covers this, but worth watching).

Notes

  • gql-ast remains a direct import in query-builder.ts (import * as t from 'gql-ast') — this is intentional to keep the t namespace clean. The runtime sub-export consolidates the other two runtime deps only.
  • The pnpm-lock.yaml diff is mostly formatting noise from a pnpm version change — the actual dependency changes are just the added workspace deps.
  • graphql-query/package.json does not need typesVersions currently because no consumer using moduleResolution: "node" imports from ./runtime. If that changes, it will need the same treatment.

Link to Devin session: https://app.devin.ai/sessions/18879be982854a40abe5c9b915aa4a84
Requested by: @pyramation

#1: Move runCodegenAndLoad into @constructive-io/graphql-test
- New codegen-helper.ts in graphql-test/src/ with full codegen pipeline
- Supports both positional (GraphQLQueryFn) and object-style (GraphQLQueryFnObj)
- Re-exports getDbConnections and types from pgsql-test for two-phase patterns
- orm-test now imports from @constructive-io/graphql-test instead of local copy
- Deleted local orm-test codegen-helper.ts

#2: Add runtime sub-export to @constructive-io/graphql-query
- New graphql-query/src/runtime/index.ts re-exports:
  - parseType, print from @0no-co/graphql.web
  - All gql-ast exports
  - GraphQLAdapter, GraphQLError, QueryResult types from graphql-types
- Updated codegen templates (query-builder.ts, orm-client.ts) to import
  from @constructive-io/graphql-query/runtime instead of 3 separate packages
- Updated codegen test snapshots and assertions to match new import paths
@devin-ai-integration
Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

The runtime sub-export re-exports parseType, print, and type-only symbols.
Using 'import * as t from runtime' would pollute the t namespace with
unrelated symbols. Keep 'import * as t from gql-ast' as-is in templates.
…tion

The cli-e2e tests generate ORM code in /tmp and require the runtime
sub-path. Without an explicit exports map, Node cannot resolve
@constructive-io/graphql-query/runtime. This adds exports for both
the root and ./runtime sub-paths (CJS, ESM, and types).
…lution

The cli-e2e tests spawn child processes in /tmp that need to resolve
@constructive-io/graphql-query/runtime. Adding the package to
resolveNodePaths() so its node_modules path is included in NODE_PATH.
…b-path resolution

The cli-e2e tests spawn child processes that need to resolve
@constructive-io/graphql-query/runtime via NODE_PATH. Adding the
package as a devDependency so pnpm creates a symlink in
server-test/node_modules, making the exports field accessible.
@socket-security
Copy link
Copy Markdown

socket-security Bot commented Apr 21, 2026

All alerts resolved. Learn more about Socket for GitHub.

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

View full report

Add exports field to graphql-codegen package.json with ./orm sub-path
so generateOrm is a stable contract instead of a filesystem crawl.
Update codegen-helper.ts to use clean import from
@constructive-io/graphql-codegen/orm.
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