feat(codegen): add pagination, filtering, search, find-first; remove MCP; unify casing#913
Merged
pyramation merged 9 commits intomainfrom Mar 27, 2026
Merged
Conversation
…t commands - Parse --limit, --offset, --fields flags in generated handleList handlers - Use buildSelectFromPaths utility for custom field projection - Build findManyArgs with conditional spread for first/offset pagination - Update MCP tool schemas with limit/offset/fields input properties - Update skill docs with pagination and field selection examples - Update usage text to document new list options
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:
|
…and to CLI - Add --where, --condition, --orderBy JSON passthrough flags to list commands - Add parseJsonFlag() utility for runtime JSON parsing of CLI flags - Generate 'search' subcommand for tables with search-capable fields (tsvector, BM25, trigram, vector embedding) - Search auto-builds where clause from query string for all detected fields - Update MCP tool schemas with new filter/search properties - Update generated README, skills, and usage text with examples - Support both single-target and multi-target CLI configurations
…or where/condition - Replace parseJsonFlag with unflattenDotNotation for --where and --condition - CLI now uses --where.field.op <value> instead of --where '<json>' - Remove parseJsonFlag from cli-utils.ts (no longer needed) - Update all generated docs (MCP tools, skills, usage text) for dot-notation - Update snapshots
… TS SDK parity - Add --last, --after, --before cursor pagination flags to list command - Add find-first subcommand (CLI equivalent of ORM findFirst) - Add buildParseIntFlag/buildParseStringFlag/buildOptionalSpread helpers to reduce AST duplication - Add kebabToPascal for hyphenated subcommand handler names - Update MCP tool schemas with cursor pagination and find-first - Update skills and README with new flags and examples - pageInfo/totalCount already included in list output via ConnectionResult
Remove MCP (Model Context Protocol) tool generation, mcp.json file generation, and related config/types/tests. MCP was generating static JSON tool definition files that weren't providing value. Removed: - getCliMcpTools(), getMultiTargetCliMcpTools() from cli/docs-generator.ts - getOrmMcpTools() from orm/docs-generator.ts - getHooksMcpTools() from hooks-docs-generator.ts - generateCombinedMcpConfig() from target-docs-generator.ts - McpTool interface from docs-utils.ts - mcp option from DocsConfig interface and resolveDocsConfig() - All MCP imports and if(docsConfig.mcp) blocks from generate.ts - 5 MCP test cases and 2 snapshots from cli-generator.test.ts - McpTool re-exports from cli/index.ts barrel
…Case Use the standard toPascalCase from inflekt instead of a hand-rolled kebabToPascal helper. inflekt already handles kebab-case input correctly (e.g. 'find-first' → 'FindFirst').
…eamingSnake, toSnakeCase instead of underscore - Replace all toScreamingSnake imports/usage with toConstantCase from komoji - Replace all underscore imports/usage with toSnakeCase from komoji - Add komoji dependency to graphql/query - Update tests to use toConstantCase - All 312 codegen tests pass, full monorepo build succeeds
4 tasks
…e/toSnakeCase from inflekt Now that inflekt@0.6.0 re-exports toConstantCase and toSnakeCase from komoji, switch all imports to come from inflekt (single import source for case transforms). - Bump inflekt ^0.5.1 → ^0.6.0 in all 5 packages - Bump komoji ^0.8.1 → ^0.9.0 in graphql/codegen (still needs toKebabCase) - Remove komoji from pgpm/export, pgpm/core, graphql/query (no longer imported directly) - Move toConstantCase/toSnakeCase imports from komoji to inflekt - All 312 codegen tests pass, full monorepo build succeeds
Move repetitive inline type coercion (parseIntFlag, parseStringFlag, parseOrderByFlag, parseSelectFlag) and findMany/findFirst arg building into runtime helpers in cli-utils.ts. The generator now emits simple calls like parseFindManyArgs(argv, defaultSelect) instead of ~50 lines of inline ternaries and conditional spreads per handler. - Added parseIntFlag, parseStringFlag, parseOrderByFlag, parseSelectFlag - Added parseFindManyArgs (with extraWhere for search handler) - Added parseFindFirstArgs - Simplified buildListHandler, buildFindFirstHandler, buildSearchHandler - Removed buildParseIntFlag, buildParseStringFlag, buildOptionalSpread AST helpers
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
Addresses feedback that auto-generated CLI
handleListmethods ignore command-line arguments and perform un-paginatedfindManyqueries, causing terminal flooding (especially with large embedding columns). Also adds advanced filtering/ordering capabilities, asearchsubcommand for tables with search-capable fields, cursor-based pagination, and afind-firstsubcommand for full TS SDK parity. Additionally removes all MCP (Model Context Protocol) functionality from the codegen, as it was only generating static JSON tool definition files that weren't providing value. Finally, unifies casing conventions to usekomojias the single origin of truth for case transformations.Changes to
cli-utils.ts(runtime helpers):parseIntFlag(argv, name)— parses a CLI flag as an integer, handling minimist delivering numbers or stringsparseStringFlag(argv, name)— parses a CLI flag as a stringparseOrderByFlag(argv)— parses--orderByas a comma-separated listparseSelectFlag(argv, defaultSelect)— parses--fieldsinto a select object or falls back to defaultparseFindManyArgs(argv, defaultSelect, extraWhere?)— one-stop builder for all findMany args (pagination, filtering, ordering, field selection). Accepts optionalextraWherefor the search handler to inject search-field clausesparseFindFirstArgs(argv, defaultSelect)— likeparseFindManyArgsbut only includes select, where, and condition (no pagination)Changes to
table-command-generator.ts:buildParseIntFlag,buildParseStringFlag, andbuildOptionalSpreadAST helper functions (no longer needed — logic moved to runtime helpers)buildListHandlernow emits:const findManyArgs = parseFindManyArgs(argv, defaultSelect);instead of ~130 lines of inline ASTbuildFindFirstHandlernow emits:const findFirstArgs = parseFindFirstArgs(argv, defaultSelect);instead of ~60 lines of inline ASTbuildSearchHandlernow emits:const findManyArgs = parseFindManyArgs(argv, defaultSelect, searchWhere);instead of ~150 lines of inline AST for limit/offset/select/orderBy parsingbuildSelectFromPaths, coerceAnswers, stripUndefined, unflattenDotNotationtocoerceAnswers, parseFindFirstArgs, parseFindManyArgs, stripUndefined--whereand--conditionuse dot-notation flags (e.g.--where.name.equalTo foo) parsed viaunflattenDotNotation(called internally by the runtime helpers)--orderByaccepts a comma-separated string (e.g.NAME_ASC,CREATED_AT_DESC)--last,--after,--beforeflags for cursor-based paginationtoPascalCasefrominflektbuildSearchHandlerauto-builds awhereclause from the query string for all detected search field types (tsvector, BM25, trigram, vector embedding)Changes to docs generators:
find-firstandsearch <query>subcommand rowsMCP removal (10 files, ~2665 lines deleted):
getCliMcpTools(),getMultiTargetCliMcpTools()fromcli/docs-generator.tsgetOrmMcpTools()fromorm/docs-generator.tsgetHooksMcpTools()fromhooks-docs-generator.tsgenerateCombinedMcpConfig()fromtarget-docs-generator.tsMcpToolinterface fromdocs-utils.tsmcpoption fromDocsConfiginterface intypes/config.tsmcp-related imports,allMcpToolsaccumulation, andif (docsConfig.mcp)blocks fromgenerate.tscli/index.tsbarrelcli-generator.test.tsresolveDocsConfig()to no longer handlemcpoptionCasing unification (
toConstantCase/toSnakeCaseviainflekt←komoji):toScreamingSnake(inflekt) →toConstantCaseacrosscodegen/utils.ts,naming-helpers.ts, and testsunderscore(inflekt) →toSnakeCaseacrossquery-builder.ts,graphql-naming.ts, andexport-utils.tsinflekt(which internally delegates tokomojias ofinflekt@0.6.0)inflekt^0.5.1 → ^0.6.0 in all 5 consuming packages (graphql/codegen,graphql/query,pgpm/export,graphile/graphile-settings,postgres/pg-codegen)komoji^0.8.1 → ^0.9.0 ingraphql/codegen(still needstoKebabCasedirectly)komojidependency frompgpm/export,pgpm/core, andgraphql/query(no longer imported directly)komojithe single origin of truth for case transforms;inflekt@0.6.0re-exportstoConstantCaseandtoSnakeCasefrom itSnapshot updates: 5 snapshots updated to reflect the new generated code (runtime helpers). All 312 tests pass (down from 317 — 5 MCP tests removed).
Updates since last revision
cli-utils.ts. The generator now emitsparseFindManyArgs(argv, defaultSelect)instead of ~50 lines of inline ternaries and conditional spreads per handler. This eliminates the previous inconsistency wherebuildSearchHandlerused inline AST whilebuildListHandlerandbuildFindFirstHandlerused thebuildParseIntFlag/buildOptionalSpreadhelpers — all three handlers now use the same unified runtime helpers.buildParseIntFlag,buildParseStringFlag,buildOptionalSpreadare no longer needed.Review & Testing Checklist for Human
parseFindManyArgswhere-merge precedence: Incli-utils.ts, thewherevariable usesparsed.where ?? extraWhere ? { ... } : undefined. Due to JS operator precedence,??binds looser than?:, so ifparsed.whereis truthy it will be used directly without mergingextraWhere. This meanssearch "query" --where.someField.equalTo valwould lose the auto-generated search field clauses. Consider whether this needs parentheses:(parsed.where ?? extraWhere) ? { ... } : undefinedor a different merge strategy.underscore→toSnakeCasebehavioral change: The oldunderscoresplit every uppercase letter (APIKey→a_p_i_key);toSnakeCase(komoji) groups acronyms (APIKey→api_key). Check if any table/model/field names with consecutive uppercase letters exist across consumers.modelNameToGetMany()andpgpm/export'sgraphqlRowToPostgresRow()operate on arbitrary model/column names.DocsConfigbreaking change — any downstream code or config files that referencemcp: truewill now fail type-checking. Search formcpin codegen config files across consuming repos.buildSearchHandlerAST — still has zero snapshot coverage (test fixtures lack search-capable fields). Consider adding a test fixture with tsvector/embedding columns.cli list --limit 5 --fields id,namecli list --limit 10 --after <cursor>(cursor pagination)cli find-first --where.name.equalTo testcli list --where.name.equalTo test --orderBy NAME_ASCcli search "some query" --limit 10 --fields id,searchScore(if search-capable table)cli search "query" --where.extra.equalTo val(verify both where clauses are present)mcp.jsonis generated whendocs: trueis setNotes
buildSearchHandlercode path has zero snapshot coverage because no test fixture tables have search-capable fields. This is the highest-risk area of the PR.searchsubcommand is only generated for tables wherecategorizeSpecialFields()returns groups withcategory === 'search'orcategory === 'embedding'.find-firstsubcommand is generated for all tables unconditionally.--fields id,id— the template uses--fields id,${pk.name}which producesid,idwhen PK isid. Cosmetic only.inflekt, which delegates tokomojiinternally.graphql/codegenstill importstoKebabCasedirectly fromkomojisinceinflektdoesn't re-export it.pnpm-lock.yamldiff is large but is almost entirely formatting changes (single-quoted vs block-style YAML) plus the dependency resolution updates for the version bumps.Link to Devin session: https://app.devin.ai/sessions/c92c3a11450342f8875625a60fa1be28
Requested by: @pyramation