Skip to content

ErlanBelekov/kurut

Repository files navigation

Kurut ORM

npm
A TypeScript ORM for PostgreSQL with no compromise to the DX

More to come soon, hopefully I don't abandon this project

MVP features:

  • TypeScript/JavaScript Entity creation with CRUD methods
  • Type-safe database queries
  • Transactions
  • Migrations (?)
  • Seeding the DB
  • Only Postgres
  • PgBouncer support (prepared statements opt-in setting)
  • Support for NodeJS
  • Heavily tested(unit, integration)

What I need to build:

  • Entity Creation API
  • CRUD operations
  • CI/CD with auto linting, test checks, deployment to npm
  • Contribution guides, clear vision and roadmap

Intended Packages Structure:

@kurut/core - core functionality, such as model definition, CRUD methods, connections
@kurut/cli - CLI helper
@kurut/docs - Docusaurus documentation
@kurut/postgres - Postgres adapter
@kurut/mysql - MySQL adapter, should be compatible with PlanetScale too
@kurut/{INSERT-DATABASE} - it should be simple to add new DB adapters, each adhering to @kurut/core functionality

Example API:

import { table, string, int, relation, timestamp, kurut } from "@kurut/core"

export const User = table("User", {
  id: string().id(), // id() marks the column as primary key. multi column primary keys should be available too
  email: string().unique(), // will automatically generate a unique index in migration
  name: string({ maxLength: 30 }).notNull(), // every type builder function such as string() may take parameters, such as maxLength, etc
  profileId: int().notNull(),
  profile: relation(() => Profile, (tableOne, tableTwo) => ({ references: [tableTwo.id], fields: [tableOne.profileId] }))
})

export const Profile = table("Profile", {
  id: string().id(),
  createdAt: timestamp().default(() => now()), // default(() => ...) will set default value for this column. strong type safety required, timestamp can't use default(() => string("KURUT"))
  userId: int().notNull(),
  user: relation(() => User, (tableOne, tableTwo) => ({ references: [tableTwo.id], fields: [tableOne.userId] }))
})

// create a KurutClient instance, the connection to DB is established on first query and then re-used
const db = kurut({ schema })

async function main() {
  const connectionString = process.env.DATABASE_URL // PostgreSQL connection string

  const kurut = await connect(connectionString, models)

  const firstUser = await kurut.user.safeFindFirst()

  console.log(firstUser.data?.email) // type-safe access
}

main()

inspired by zod:

import { k } from '@kurut/core'

const firstUser = table.safeFindFirst()

typeof firstUser.name === 'string'

About

Type-safe ORM for PostgreSQL

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published