Skip to content

refactor(codegen): generic type params for CLI→ORM bridge + flip condition default to false#926

Closed
pyramation wants to merge 4 commits intomainfrom
devin/1774666075-fix-cli-type-errors
Closed

refactor(codegen): generic type params for CLI→ORM bridge + flip condition default to false#926
pyramation wants to merge 4 commits intomainfrom
devin/1774666075-fix-cli-type-errors

Conversation

@pyramation
Copy link
Copy Markdown
Contributor

@pyramation pyramation commented Mar 28, 2026

Summary

Fixes TS2345 build errors in the generated CLI code (e.g. sdk/constructive-cli) where parseFindManyArgs() / parseFindFirstArgs() return Record<string, unknown> but the ORM's findMany/findFirst methods expect typed args with a required select property.

Instead of casting at the ORM call sites (findManyArgs as any), the helpers are now generic and the codegen passes table-specific type parameters:

// Before (hacky):
const findManyArgs = parseFindManyArgs(argv, defaultSelect);
client.car.findMany(findManyArgs as any).execute();

// After (properly typed):
const findManyArgs = parseFindManyArgs<FindManyArgs<CarSelect, CarFilter, never, CarsOrderBy>>(argv, defaultSelect);
client.car.findMany(findManyArgs).execute();

What changed

cli-utils.ts (template): parseFindManyArgs<T>() and parseFindFirstArgs<T>() are now generic with T = Record<string, unknown> default. Internally uses as unknown as T — this is the single controlled bridge between the untyped CLI argv layer and the typed ORM interface.

table-command-generator.ts (codegen):

  • New buildFindManyArgsType() / buildFindFirstArgsType() helpers construct the proper FindManyArgs<Select, Filter, Condition, OrderBy> / FindFirstArgs<Select, Filter, Condition> type instantiations per table
  • All 3 call sites updated: buildListHandler, buildFindFirstHandler, buildSearchHandler
  • Generated code now imports table-specific types (*Select, *Filter, *Condition, *OrderBy) from input-types and FindManyArgs/FindFirstArgs from select-types
  • Added condition?: boolean to TableCommandOptions — no longer hardcoded

Condition default flipped to false (opt-in):

where/filter is now the first-class filtering mechanism; condition (PostGraphile simple equality filters) is opt-in. To enable condition types, set config.codegen.condition: true explicitly.

All 8 locations where condition was checked have been flipped from !== false (default true) to === true (default false):

  • codegen/index.ts — hooks generator
  • codegen/orm/index.ts — ORM generator
  • codegen/orm/model-generator.ts — model generator
  • codegen/orm/input-types-generator.ts — input types generator
  • codegen/cli/table-command-generator.ts — CLI table command generator
  • codegen/cli/index.ts — CLI single-target and multi-target generators
  • codegen/queries.ts — query hook destructuring default
  • generate.ts — multi-target pipeline

When condition is disabled (the new default), the generated code uses never as the condition type parameter, effectively making it unusable at the type level.

Review & Testing Checklist for Human

  • Breaking change audit: Any existing project configs that relied on condition types being generated by default will now need explicit codegen.condition: true. Verify no downstream consumers are broken by this default flip
  • Verify that FindManyArgs and FindFirstArgs are exported from select-types with the expected generic parameters <Select, Filter, Condition, OrderBy> and <Select, Filter, Condition> respectively — the generated imports depend on this
  • Confirm the as unknown as T cast inside the helpers is acceptable — it's architecturally cleaner than as any at every call site but is still an escape hatch at the argv→ORM boundary
  • After merging, re-run the Schema Propagation workflow and confirm sdk/constructive-cli builds successfully (the generated code will now have these new imports, type parameters, and no condition types by default)
  • Spot-check that a project with codegen.condition: true still generates condition types correctly (the updated tests cover this but a real-world config is worth verifying)

Notes

  • 17 snapshots updated — changes include: added type imports and generic type parameters, removed as any from ORM call sites, condition type interfaces removed from default output
  • Tests that explicitly verify condition type generation now pass { condition: true } to the generators, reflecting the new opt-in behavior
  • Function parameter defaults in buildListHandler, buildFindFirstHandler, buildSearchHandler also flipped from = true to = false

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

…M type compatibility

The ORM's findMany/findFirst methods require typed args with a required
'select' property, but the CLI runtime helpers return Record<string, unknown>.
Adding 'as any' casts in the generated code prevents TS2345 errors when the
generated CLI is compiled against the typed ORM client.
@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

…arseFindManyArgs/parseFindFirstArgs

Instead of casting ORM args to 'any', the helpers are now generic:
  parseFindManyArgs<T>() / parseFindFirstArgs<T>()

The codegen passes specific table types:
  parseFindManyArgs<FindManyArgs<CarSelect, CarFilter, CarCondition, CarsOrderBy>>(...)

This gives proper type safety at the ORM call site without escape hatches.
The internal 'as unknown as T' cast in the helpers is the single known
bridge between the untyped CLI argv layer and the typed ORM interface.
@devin-ai-integration devin-ai-integration bot changed the title fix(codegen): cast parseFindManyArgs/parseFindFirstArgs to any for ORM type compatibility refactor(codegen): use generic type parameters instead of as any for CLI→ORM type bridge Mar 28, 2026
…first-class, condition is opt-in

- Change all condition checks from `!== false` to `=== true` (8 locations)
- Flip function parameter defaults from `= true` to `= false`
- Thread config.codegen.condition through CLI codegen TableCommandOptions
- Update tests that explicitly test condition types to pass condition: true
- Update snapshots to reflect condition-disabled output
@devin-ai-integration devin-ai-integration bot changed the title refactor(codegen): use generic type parameters instead of as any for CLI→ORM type bridge refactor(codegen): generic type params for CLI→ORM bridge + flip condition default to false Mar 28, 2026
… params

The ORM's findMany/findFirst methods require select to be present
(via intersection & { select: SelectType }). parseFindManyArgs always
sets select at runtime, but the generic type parameter only had
FindManyArgs<...> where select is optional.

Fix: generate FindManyArgs<...> & { select: SelectType } as the
type parameter, making the type match what the ORM expects.
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