Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Contributing to ZenStack

I want to thank you first for considering contributing to ZenStack 🙏🏻. It's people like you who make ZenStack a better toolkit that benefits more developers!

Before you start working on anything major, please make sure to open an issue or discuss with us in our [Discord](https://discord.gg/Ykhr738dUe) first. This will help ensure your work aligns with the project's goals and avoid duplication of effort.

## Prerequisites

- Node.js: v20 or above
- PNPM: as specified in [package.json](./package.json)

Test cases are run against both SQLite and Postgres. You should have a postgres server (16 or above) running (either natively or via Docker). The default connection is:

`postgresql://${TEST_PG_USER}:${TEST_PG_PASSWORD}$@${TEST_PG_HOST}$:${TEST_PG_PORT}$`

The default values for the environment variables (if not set) are:

- `TEST_PG_HOST`: localhost
- `TEST_PG_PORT`: 5432
- `TEST_PG_USER`: postgres
- `TEST_PG_PASSWORD`: postgres

## Get started

1. Install dependencies: `pnpm install`
2. Build all packages: `pnpm build`
3. Run all tests: `pnpm test`

## Development workflow

ZenStack adopts a very simple development workflow:

1. Changes should be made in branches created off the "dev" branch.

1. Non-trivial changes should include test cases. Bug-fixes should include regression tests that refer to GitHub issues if applicable.

1. After coding and testing, create a PR to merge the changes into the "dev" branch.

1. After code review is done, maintainer will squash and merge the PR into the "dev" branch.

1. Periodically, the "dev" branch is merged back to the "main" branch to create a new release.

## Project structure

ZenStack is a monorepo consisting of multiple NPM packages managed by [pnpm workspace](https://pnpm.io/workspaces).

### Packages

The source and tests of ZenStack npm packages reside in the "packages" folder:

#### [language](./packages/language)

The ZModel language's definition, including its syntax definition and parser/linker implementation. The compiler is implemented with the [Langium](https://github.com/langium/langium) toolkit.

#### [cli](./packages/cli)

The `zen` CLI and built-in plugins.

#### [schema](./packages/schema)

The runtime representation of ZModel schema.

#### [orm](./packages/orm)

The ORM runtime built on top of [Kysely](https://kysely.dev).

#### [server](./packages/server)

The `server` package implements the automatic CRUD services and contains two main parts:

1. Framework-agnostic API handlers: defining input/output format and API routes in a framework-independent way. Currently supports "rpc" and "rest" styles.

1. Framework-specific adapters: translating framework-dependent request and response formats.

#### [clients/tanstack-query](./packages/clients/tanstack-query)

TanStack Query client for consuming the automatic CRUD services.

#### [sdk](./packages/sdk)

Utilities for building ZenStack plugins.

#### [plugins/policy](./plugins/policy)

The access policy plugin implementation.

#### [ide/vscode](./packages/ide/vscode)

VSCode extension for ZModel.

#### [testtools](./packages/testtools)

Test utilities.

### Tests

#### [e2e](./tests/e2e/)

End-to-end tests covering essential features (ORM, access policies, etc.).

#### [regression](./tests/regression/)

Regression tests for previously reported issues.

## Testing changed packages locally

The [samples](./samples) folder contains sample projects that directly reference the packages in the workspace. Once you make changes to a package and rebuild it, the sample projects will automatically pick up the changes. They are handy for quick manual testing.

If you prefer to test against your own project, simply copy the built bundles (from the `dist` folder of each package) to your project's `node_modules` folder to overwrite the installed packages.
73 changes: 48 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<img src="https://raw.githubusercontent.com/zenstackhq/zenstack-docs/main/static/img/logo.png" height="128">
</picture>
</a>
<h1>ZenStack V3</h1>
<h1>ZenStack: Modern Data Layer for TypeScript Apps</h1>
<a href="https://www.npmjs.com/package/@zenstackhq/cli?activeTab=versions">
<img src="https://img.shields.io/npm/v/%40zenstackhq%2Fcli/next">
</a>
Expand All @@ -21,40 +21,33 @@
</a>
</div>

> V3 is currently in beta phase and not ready for production use. Feedback and bug reports are greatly appreciated. Please visit this dedicated [discord channel](https://discord.com/channels/1035538056146595961/1352359627525718056) for chat and support.

# What's ZenStack

> Read full documentation at 👉🏻 https://zenstack.dev/v3.
> Read full documentation at 👉🏻 https://zenstack.dev/docs.

ZenStack is a TypeScript database toolkit for developing full-stack or backend Node.js/Bun applications. It provides a unified data modeling and access solution with the following features:
ZenStack is a TypeScript database toolkit for developing full-stack or backend Node.js/Bun applications. It provides a unified data modeling and query solution with the following features:

- A modern schema-first ORM that's compatible with [Prisma](https://github.com/prisma/prisma)'s schema and API
- Versatile data access APIs: high-level (Prisma-style) ORM queries + low-level ([Kysely](https://github.com/kysely-org/kysely)) query builder
- Built-in access control and data validation (coming soon)
- Advanced data modeling patterns like [polymorphism](https://zenstack.dev/blog/polymorphism)
- Designed for extensibility and flexibility: plugins, life-cycle hooks, etc.
- Automatic CRUD web APIs with adapters for popular frameworks (coming soon)
- Automatic [TanStack Query](https://github.com/TanStack/query) hooks for easy CRUD from the frontend (coming soon)
- 🔧 Modern schema-first ORM that's compatible with [Prisma](https://github.com/prisma/prisma)'s schema and API
- 📊 Versatile API - high-level ORM queries + low-level [Kysely](https://kysely.dev) query builder
- 🔐 Built-in access control and data validation
- 🚀 Advanced data modeling patterns like [polymorphism](https://zenstack.dev/docs/orm/polymorphism)
- 🧩 Designed for extensibility and flexibility
- ⚙️ Automatic CRUD web APIs with adapters for popular frameworks
- 🏖️ Automatic [TanStack Query](https://github.com/TanStack/query) hooks for easy CRUD from the frontend

# What's New in V3

ZenStack V3 is a major rewrite of [V2](https://github.com/zenstackhq/zenstack). The biggest change is V3 doesn't have a runtime dependency to Prisma anymore. Instead of working as a big wrapper of Prisma as in V2, V3 made a bold move and implemented the entire ORM engine using [Kysely](https://github.com/kysely-org/kysely), while keeping the query API fully compatible with Prisma.

Please check [this blog post](https://zenstack.dev/blog/next-chapter-1) for why we made this big architectural change decision.
ZenStack V3 is a major rewrite of [V2](https://github.com/zenstackhq/zenstack/docs/2.x). It replaced Prisma ORM with its own ORM engine built on top of [Kysely](https://kysely.dev) while keeping a Prisma-compatible query API. This architecture change brings the level of flexibility that we couldn't imagine in previous versions. Please check [this blog post](https://zenstack.dev/blog/next-chapter-1) for why we made this bold decision.

Even without using advanced features, ZenStack offers the following benefits as a drop-in replacement to Prisma:

1. Pure TypeScript implementation without any Rust/WASM components.
2. More TypeScript type inference, less code generation.
3. Fully-typed query-builder API as a better escape hatch compared to Prisma's [raw queries](https://www.prisma.io/docs/orm/prisma-client/using-raw-sql/raw-queries) or [typed SQL](https://www.prisma.io/docs/orm/prisma-client/using-raw-sql/typedsql).

> Although ZenStack v3's ORM runtime doesn't depend on Prisma anymore (specifically, `@prisma/client`), it still relies on Prisma to handle database migration. See [database migration](https://zenstack.dev/docs/3.x/orm/migration) for more details.

# Quick Start
# Try It Now

- [ORM](./samples/orm): A simple example demonstrating ZenStack ORM usage.
- [Next.js + TanStack Query](./samples/next.js): A full-stack sample demonstrating using TanStack Query to consume ZenStack's automatic CRUD services in a Next.js app.
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/~/github.com/zenstackhq/v3-doc-quick-start?file=zenstack%2fschema.zmodel&file=main.ts&view=editor&showSidebar=0&hideNavigation=1&hideExplorer=1)

## Installation

Expand All @@ -63,28 +56,58 @@ Even without using advanced features, ZenStack offers the following benefits as
Use the following command to scaffold a simple TypeScript command line application with ZenStack configured:

```bash
npm create zenstack@next my-project
npm create zenstack@latest my-project
```

### 2. Setting up an existing project

Or, if you have an existing project, use the CLI to initialize it:

```bash
npx @zenstackhq/cli@next init
npx @zenstackhq/cli@latest init
```

### 3. Setting up manually

Alternatively, you can set it up manually:

```bash
npm install -D @zenstackhq/cli@next
npm install @zenstackhq/orm@next
npm install -D @zenstackhq/cli
npm install @zenstackhq/orm
```

Then create a `zenstack` folder and a `schema.zmodel` file in it.

# Documentation

Please visit the [doc site](https://zenstack.dev/docs/3.x/) for detailed documentation.
[https://zenstack.dev/docs/](https://zenstack.dev/docs/)

# Sponsors

Thank you for your generous support!

## Current Sponsors

<table>
<tr>
<td align="center"><a href="https://suhyl.com/"><img src="https://avatars.githubusercontent.com/u/124434734?s=200&v=4" width="100" style="border-radius:50%" alt="Suhyl"/><br />Suhyl</a></td>
<td align="center"><a href="https://www.marblism.com/"><img src="https://avatars.githubusercontent.com/u/143199531?s=200&v=4" width="100" style="border-radius:50%" alt="Marblism"/><br />Marblism</a></td>
<td align="center"><a href="https://www.mermaidchart.com/"><img src="https://avatars.githubusercontent.com/u/117662492?s=200&v=4" width="100" style="border-radius:50%" alt="Mermaid Chart"/><br />Mermaid Chart</a></td>
<td align="center"><a href="https://coderabbit.ai/"><img src="https://avatars.githubusercontent.com/u/132028505?v=4" width="100" style="border-radius:50%" alt="CodeRabbit"/><br />CodeRabbit</a></td>
<td align="center"><a href="https://github.com/j0hannr"><img src="https://avatars.githubusercontent.com/u/52762073?v=4" width="100" style="border-radius:50%" alt="Johann Rohn"/><br />Johann Rohn</a></td>
</tr>
</table>

## Previous Sponsors

<table>
<tr>
<td align="center"><a href="https://github.com/baenie"><img src="https://avatars.githubusercontent.com/u/58309104?v=4" width="100" style="border-radius:50%" alt="Benjamin Zecirovic"/><br />Benjamin Zecirovic</a></td>
<td align="center"><a href="https://github.com/umussetu"><img src="https://avatars.githubusercontent.com/u/152648499?v=4" width="100" style="border-radius:50%" alt="Ulric"/><br />Ulric</a></td>
<td align="center"><a href="https://github.com/iamfj"><img src="https://avatars.githubusercontent.com/u/24557998?v=4" width="100" style="border-radius:50%" alt="Fabian Jocks"/><br />Fabian Jocks</a></td>
</tr>
</table>

# Community

Join our [discord server](https://discord.gg/Ykhr738dUe) for chat and updates!
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "zenstack-v3",
"version": "3.0.0-beta.34",
"version": "3.0.0",
"description": "ZenStack",
"packageManager": "[email protected]",
"type": "module",
Expand All @@ -9,12 +9,15 @@
"watch": "turbo run watch build",
"lint": "turbo run lint",
"test": "turbo run test",
"test:all": "pnpm run test:sqlite && pnpm run test:pg",
"test:pg": "TEST_DB_PROVIDER=postgresql turbo run test",
"test:sqlite": "TEST_DB_PROVIDER=sqlite turbo run test",
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"pr": "gh pr create --fill-first --base dev",
"merge-main": "gh pr create --title \"merge dev to main\" --body \"\" --base main --head dev",
"bump-version": "gh workflow run .github/workflows/bump-version.yml --ref dev",
"publish-all": "pnpm --filter \"./packages/**\" -r publish --access public --tag next",
"publish-preview": "pnpm --filter \"./packages/**\" -r publish --tag next --force --registry https://preview.registry.zenstack.dev/",
"publish-all": "pnpm --filter \"./packages/**\" -r publish --access public",
"publish-preview": "pnpm --filter \"./packages/**\" -r publish --force --registry https://preview.registry.zenstack.dev/",
"unpublish-preview": "pnpm --filter \"./packages/**\" -r --shell-mode exec -- npm unpublish -f --registry https://preview.registry.zenstack.dev/ \"\\$PNPM_PACKAGE_NAME\""
},
"keywords": [],
Expand Down
2 changes: 1 addition & 1 deletion packages/auth-adapters/better-auth/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/better-auth",
"version": "3.0.0-beta.34",
"version": "3.0.0",
"description": "ZenStack Better Auth Adapter. This adapter is modified from better-auth's Prisma adapter.",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"publisher": "zenstack",
"displayName": "ZenStack CLI",
"description": "FullStack database toolkit with built-in access control and automatic API generation.",
"version": "3.0.0-beta.34",
"version": "3.0.0",
"type": "module",
"author": {
"name": "ZenStack Team"
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function createProgram() {
.description(
`${colors.bold.blue(
'ζ',
)} ZenStack is the data layer for modern TypeScript apps.\n\nDocumentation: https://zenstack.dev/docs/3.x`,
)} ZenStack is the modern data layer for TypeScript apps.\n\nDocumentation: https://zenstack.dev/docs`,
)
.showHelpAfterError()
.showSuggestionAfterError();
Expand Down
2 changes: 1 addition & 1 deletion packages/clients/tanstack-query/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/tanstack-query",
"version": "3.0.0-beta.34",
"version": "3.0.0",
"description": "TanStack Query Client for consuming ZenStack v3's CRUD service",
"main": "index.js",
"type": "module",
Expand Down
2 changes: 1 addition & 1 deletion packages/common-helpers/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/common-helpers",
"version": "3.0.0-beta.34",
"version": "3.0.0",
"description": "ZenStack Common Helpers",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/config/eslint-config/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/eslint-config",
"version": "3.0.0-beta.34",
"version": "3.0.0",
"type": "module",
"private": true,
"license": "MIT"
Expand Down
2 changes: 1 addition & 1 deletion packages/config/typescript-config/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/typescript-config",
"version": "3.0.0-beta.34",
"version": "3.0.0",
"private": true,
"license": "MIT"
}
2 changes: 1 addition & 1 deletion packages/config/vitest-config/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/vitest-config",
"type": "module",
"version": "3.0.0-beta.34",
"version": "3.0.0",
"private": true,
"license": "MIT",
"exports": {
Expand Down
2 changes: 1 addition & 1 deletion packages/create-zenstack/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-zenstack",
"version": "3.0.0-beta.34",
"version": "3.0.0",
"description": "Create a new ZenStack project",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/language/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/language",
"description": "ZenStack ZModel language specification",
"version": "3.0.0-beta.34",
"version": "3.0.0",
"license": "MIT",
"author": "ZenStack Team",
"files": [
Expand Down
2 changes: 1 addition & 1 deletion packages/orm/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/orm",
"version": "3.0.0-beta.34",
"version": "3.0.0",
"description": "ZenStack ORM",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/policy/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/plugin-policy",
"version": "3.0.0-beta.34",
"version": "3.0.0",
"description": "ZenStack Policy Plugin",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/schema/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/schema",
"version": "3.0.0-beta.34",
"version": "3.0.0",
"description": "ZenStack Runtime Schema",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/sdk",
"version": "3.0.0-beta.34",
"version": "3.0.0",
"description": "ZenStack SDK",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/server",
"version": "3.0.0-beta.34",
"version": "3.0.0",
"description": "ZenStack automatic CRUD API handlers and server adapters",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/testtools/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/testtools",
"version": "3.0.0-beta.34",
"version": "3.0.0",
"description": "ZenStack Test Tools",
"type": "module",
"scripts": {
Expand Down
Loading