diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..674d4087
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -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.
diff --git a/README.md b/README.md
index 16f6309f..23290fd9 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
-
ZenStack V3
+ ZenStack: Modern Data Layer for TypeScript Apps
@@ -21,27 +21,23 @@
-> 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:
@@ -49,12 +45,9 @@ Even without using advanced features, ZenStack offers the following benefits as
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.
+[](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
@@ -63,7 +56,7 @@ 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
@@ -71,7 +64,7 @@ npm create zenstack@next my-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
@@ -79,12 +72,42 @@ npx @zenstackhq/cli@next init
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
+
+
+
+## Previous Sponsors
+
+
+
+# Community
+
+Join our [discord server](https://discord.gg/Ykhr738dUe) for chat and updates!
diff --git a/package.json b/package.json
index 3732c8a9..0803435e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "zenstack-v3",
- "version": "3.0.0-beta.34",
+ "version": "3.0.0",
"description": "ZenStack",
"packageManager": "pnpm@10.23.0",
"type": "module",
@@ -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": [],
diff --git a/packages/auth-adapters/better-auth/package.json b/packages/auth-adapters/better-auth/package.json
index cd21a5e6..90beab8f 100644
--- a/packages/auth-adapters/better-auth/package.json
+++ b/packages/auth-adapters/better-auth/package.json
@@ -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": {
diff --git a/packages/cli/package.json b/packages/cli/package.json
index 87a680c3..506a6376 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -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"
diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts
index b48fc321..c2307fa1 100644
--- a/packages/cli/src/index.ts
+++ b/packages/cli/src/index.ts
@@ -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();
diff --git a/packages/clients/tanstack-query/package.json b/packages/clients/tanstack-query/package.json
index b3d799e3..15451c0c 100644
--- a/packages/clients/tanstack-query/package.json
+++ b/packages/clients/tanstack-query/package.json
@@ -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",
diff --git a/packages/common-helpers/package.json b/packages/common-helpers/package.json
index 85c8ba5f..8d60e7df 100644
--- a/packages/common-helpers/package.json
+++ b/packages/common-helpers/package.json
@@ -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": {
diff --git a/packages/config/eslint-config/package.json b/packages/config/eslint-config/package.json
index 12323bf4..c06180d7 100644
--- a/packages/config/eslint-config/package.json
+++ b/packages/config/eslint-config/package.json
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/eslint-config",
- "version": "3.0.0-beta.34",
+ "version": "3.0.0",
"type": "module",
"private": true,
"license": "MIT"
diff --git a/packages/config/typescript-config/package.json b/packages/config/typescript-config/package.json
index b18e688d..a6e97e28 100644
--- a/packages/config/typescript-config/package.json
+++ b/packages/config/typescript-config/package.json
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/typescript-config",
- "version": "3.0.0-beta.34",
+ "version": "3.0.0",
"private": true,
"license": "MIT"
}
diff --git a/packages/config/vitest-config/package.json b/packages/config/vitest-config/package.json
index 341eb16f..26441c95 100644
--- a/packages/config/vitest-config/package.json
+++ b/packages/config/vitest-config/package.json
@@ -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": {
diff --git a/packages/create-zenstack/package.json b/packages/create-zenstack/package.json
index 77c0f809..e532900e 100644
--- a/packages/create-zenstack/package.json
+++ b/packages/create-zenstack/package.json
@@ -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": {
diff --git a/packages/language/package.json b/packages/language/package.json
index cd7c4d81..c4b598dd 100644
--- a/packages/language/package.json
+++ b/packages/language/package.json
@@ -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": [
diff --git a/packages/orm/package.json b/packages/orm/package.json
index 208fc70b..d48d0beb 100644
--- a/packages/orm/package.json
+++ b/packages/orm/package.json
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/orm",
- "version": "3.0.0-beta.34",
+ "version": "3.0.0",
"description": "ZenStack ORM",
"type": "module",
"scripts": {
diff --git a/packages/plugins/policy/package.json b/packages/plugins/policy/package.json
index 757a3c1b..dc95282b 100644
--- a/packages/plugins/policy/package.json
+++ b/packages/plugins/policy/package.json
@@ -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": {
diff --git a/packages/schema/package.json b/packages/schema/package.json
index 4bfe6911..70dcf353 100644
--- a/packages/schema/package.json
+++ b/packages/schema/package.json
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/schema",
- "version": "3.0.0-beta.34",
+ "version": "3.0.0",
"description": "ZenStack Runtime Schema",
"type": "module",
"scripts": {
diff --git a/packages/sdk/package.json b/packages/sdk/package.json
index c0986e7e..afe9f7e3 100644
--- a/packages/sdk/package.json
+++ b/packages/sdk/package.json
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/sdk",
- "version": "3.0.0-beta.34",
+ "version": "3.0.0",
"description": "ZenStack SDK",
"type": "module",
"scripts": {
diff --git a/packages/server/package.json b/packages/server/package.json
index 00539080..4abe793a 100644
--- a/packages/server/package.json
+++ b/packages/server/package.json
@@ -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": {
diff --git a/packages/testtools/package.json b/packages/testtools/package.json
index a60475ae..a79a527c 100644
--- a/packages/testtools/package.json
+++ b/packages/testtools/package.json
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/testtools",
- "version": "3.0.0-beta.34",
+ "version": "3.0.0",
"description": "ZenStack Test Tools",
"type": "module",
"scripts": {
diff --git a/packages/zod/package.json b/packages/zod/package.json
index 48e78f0b..47c1a71e 100644
--- a/packages/zod/package.json
+++ b/packages/zod/package.json
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/zod",
- "version": "3.0.0-beta.34",
+ "version": "3.0.0",
"description": "",
"type": "module",
"main": "index.js",
diff --git a/samples/next.js/package.json b/samples/next.js/package.json
index 3746c18c..08d2945e 100644
--- a/samples/next.js/package.json
+++ b/samples/next.js/package.json
@@ -1,6 +1,6 @@
{
"name": "next.js",
- "version": "3.0.0-beta.34",
+ "version": "3.0.0",
"private": true,
"scripts": {
"generate": "zen generate --lite",
diff --git a/samples/orm/package.json b/samples/orm/package.json
index b5f52e50..e5d02a16 100644
--- a/samples/orm/package.json
+++ b/samples/orm/package.json
@@ -1,6 +1,6 @@
{
"name": "sample-blog",
- "version": "3.0.0-beta.34",
+ "version": "3.0.0",
"description": "",
"main": "index.js",
"private": true,
diff --git a/tests/e2e/package.json b/tests/e2e/package.json
index 6cc90470..201a9211 100644
--- a/tests/e2e/package.json
+++ b/tests/e2e/package.json
@@ -1,6 +1,6 @@
{
"name": "e2e",
- "version": "3.0.0-beta.34",
+ "version": "3.0.0",
"private": true,
"type": "module",
"scripts": {
diff --git a/tests/regression/package.json b/tests/regression/package.json
index 38b5372b..c3568f37 100644
--- a/tests/regression/package.json
+++ b/tests/regression/package.json
@@ -1,6 +1,6 @@
{
"name": "regression",
- "version": "3.0.0-beta.34",
+ "version": "3.0.0",
"private": true,
"type": "module",
"scripts": {
diff --git a/tests/runtimes/bun/package.json b/tests/runtimes/bun/package.json
index 606e6577..cf799384 100644
--- a/tests/runtimes/bun/package.json
+++ b/tests/runtimes/bun/package.json
@@ -1,6 +1,6 @@
{
"name": "bun-e2e",
- "version": "3.0.0-beta.34",
+ "version": "3.0.0",
"private": true,
"type": "module",
"scripts": {
diff --git a/tests/runtimes/edge-runtime/package.json b/tests/runtimes/edge-runtime/package.json
index d576c9be..85669a53 100644
--- a/tests/runtimes/edge-runtime/package.json
+++ b/tests/runtimes/edge-runtime/package.json
@@ -1,6 +1,6 @@
{
"name": "edge-runtime-e2e",
- "version": "3.0.0-beta.34",
+ "version": "3.0.0",
"private": true,
"type": "module",
"scripts": {