Skip to content

feat(cli): TypeScript implementation for db pull #27439

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

jharrell
Copy link
Contributor

NOTE: I heavily used Claude Code to write this code. Here be dragons.

The purpose of this pull request is to be a proof of concept for a "native TS" implementation of various CLI commands with the end goal being commands that do not require calling out to prisma-engines and which are runnable programmatically.

This proof of concept starts with a TS implementation of db pull which is a relatively straightforward command. The goal is to:

  • create a native TS implementation of db pull
  • test the new implementation against the existing implementation
  • create a TypeScript API for this command.

The new implementation and the existing one should have the exact same output, obviously.

I am pushing this up as a draft PR because local testing is proving to be quite difficult. I'm hoping that I can use the tests here to help.

jharrell and others added 5 commits June 17, 2025 12:31
- Add DbPullTypeScript command using WASM engines instead of RPC
- Implement identical CLI interface to existing DbPull command
- Add programmatic API with stdout/stderr capture for TypeScript usage
- Support PostgreSQL with driver adapters architecture
- Include proper resource cleanup and error handling
- Export DbPullTypeScriptAPI for programmatic usage

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Register DbPullTypeScript as 'pull-ts' subcommand in db command group
- Enable CLI access to TypeScript-native db pull functionality
- Maintain backwards compatibility with existing pull command

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Comment on lines +323 to +326
const engine = await SchemaEngineWasm.setup({
adapter,
schemaContext: schemaContext ?? undefined,
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still uses the schema engine though, there's no actual db pull implementation in TypeScript.

How is this different to the regular db pull with schema-engine-wasm?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, that’s true. IIUC, using the WASM engine would still be lighter weight and more portable than “true” Rust binaries, right?

Would you look more favorably on this approach or a re-implementation of the underlying engine.introspect command?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, that’s true. IIUC, using the WASM engine would still be lighter weight and more portable than “true” Rust binaries, right?

Yes, but that's exactly what we are already doing when you configure a driver adapter for Migrate, the normal db pull command uses it already

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you look more favorably on this approach or a re-implementation of the underlying engine.introspect command?

Depends on what you want to achieve. This approach mostly requires work on the Rust side and doesn't require rewriting the commands like you did here. This is also something that we have already started working on, although sadly haven't had capacity to work on lately, so if you want to help out, that would definitely be appreciated.

A TypeScript implementation of db pull, however, could be an interesting experiment. A naive quick and dirty implementation that runs introspection queries and directly translates them to a Prisma schema might not be very hard, but it's going to quickly become a lot more complex if you want it to be something that could be extended to support more commands. That would need to start with a TypeScript definition of the abstract data model, implement schema parsing (since db pull doesn't just create a new schema, it needs the current content as well) and rendering, and only then you could implement the actual introspection. If you then implement datamodel diffing in addition to that, that would essentially be a prototype of a TypeScript-based schema engine and Prisma Migrate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depends on what you want to achieve. This approach mostly requires work on the Rust side and doesn't require rewriting the commands like you did here. This is also something that we have already started working on, although sadly haven't had capacity to work on lately, so if you want to help out, that would definitely be appreciated.

Happy to help! Do you have an existing branch or notes I can take a look at?

A TypeScript implementation of db pull, however, could be an interesting experiment...

This was my original intention. I totally understand that a single command POC would quickly balloon once more commands are added, but I wanted to show how moving pieces of functionality could b done.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have an existing branch or notes I can take a look at?

I wanted to send you a bunch of links to Notion and Linear and only then realized you can't see those anymore 😭

All the code is on main in both repos though.

This was my original intention.

Feel free to experiment with that as well! I think at least designing a good TypeScript representation of the data model would already be immensely valuable (and if we could make it interoperable with schema-engine's abstractions, we could even port it piece by piece; e.g., you could have introspection in TypeScript and diffing in WASM).

Copy link
Contributor Author

@jharrell jharrell Jun 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aqrln shot you a message on Discord but just in case you're not active there:

I'm working through an implementation of the datamodel in TypeScript. No PR yet, but here's a super rough example of how it could be used to take data from postgres https://gist.github.com/jharrell/06450f499ef2611eb8e5971d5d67e107

Does that look right to you? Any more info you'd like to see? Let me know what you think!

jharrell added a commit to jharrell/prisma that referenced this pull request Jun 20, 2025
- Add @prisma/schema-datamodel package with proper TypeScript setup
- Configure build system using existing Prisma build helpers
- Set up Vitest testing infrastructure
- Prepare foundation for TypeScript implementation of Prisma abstract data model

This package will serve as the intermediate representation between database
introspection and Prisma Schema Language (PSL) generation, enabling more
modular architecture as discussed in prisma#27439.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
jharrell added a commit to jharrell/prisma that referenced this pull request Jun 20, 2025
Add the main Datamodel class that serves as the complete intermediate
representation between database introspection and PSL generation:

Datamodel Class:
- Multi-file schema organization with Map-based file grouping
- Component management: models, enums, views, composite types
- Configuration support for generators and datasources
- Empty file handling for schema organization

Rendering System:
- render() method producing file name/content pairs
- Proper ordering matching Rust implementation:
  1. Configuration (generators, datasources)
  2. Composite types
  3. Models
  4. Views
  5. Enums
- SourceFile interface for consistent output format
- Multi-file schema generation support

Integration Testing:
- Comprehensive tests matching Rust test cases
- simple_data_model test validating complete flow
- multi-file schema generation validation
- Empty datamodel and file handling verification

Key features:
- Full compatibility with existing Rust implementation
- Type-safe schema construction and validation
- Incremental schema building with builder pattern
- Ready for database introspection integration

This completes the core TypeScript implementation of Prisma's abstract
data model, enabling the incremental migration approach discussed in
prisma#27439 where components can be implemented in TypeScript
while others remain in WASM.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
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.

2 participants