Détail du package

zenstack

zenstackhq55.1kMIT2.16.0

FullStack enhancement for Prisma ORM: seamless integration from database to UI

fullstack, react, typescript, data modeling

readme

What it is

ZenStack is a Node.js/TypeScript toolkit that simplifies the development of web applications. It enhances Prisma ORM with a flexible Authorization layer and auto-generated, type-safe APIs/hooks, unlocking its full potential for full-stack development.

Our goal is to let you save time writing boilerplate code and focus on building real features!

How it works

Read full documentation at 👉🏻 zenstack.dev. Join Discord for feedback and questions.

ZenStack incrementally extends Prisma's power with the following four layers:

1. ZModel - an extended Prisma schema language

ZenStack introduces a data modeling language called "ZModel" - a superset of Prisma schema language. It extended Prisma schema with custom attributes and functions and, based on that, implemented a flexible access control layer around Prisma.

// base.zmodel
abstract model Base {
    id String @id
    author User @relation(fields: [authorId], references: [id])
    authorId String

    // 🔐 allow full CRUD by author
    @@allow('all', author == auth())
}
// schema.zmodel
import "base"
model Post extends Base {
    title String
    published Boolean @default(false)

    // 🔐 allow logged-in users to read published posts
    @@allow('read', auth() != null && published)
}

The zenstack CLI transpiles the ZModel into a standard Prisma schema, which you can use with the regular Prisma workflows.

2. Runtime enhancements to Prisma client

At runtime, transparent proxies are created around Prisma clients for intercepting queries and mutations to enforce access policies.

import { enhance } from '@zenstackhq/runtime';

// a regular Prisma client
const prisma = new PrismaClient();

async function getPosts(userId: string) {
    // create an enhanced Prisma client that has access control enabled
    const enhanced = enhance(prisma, { user: userId });

    // only posts that're visible to the user will be returned
    return enhanced.post.findMany();
}

3. Automatic RESTful APIs through server adapters

Server adapter packages help you wrap an access-control-enabled Prisma client into backend CRUD APIs that can be safely called from the frontend. Here's an example for Next.js:

// pages/api/model/[...path].ts

import { requestHandler } from '@zenstackhq/next';
import { enhance } from '@zenstackhq/runtime';
import { getSessionUser } from '@lib/auth';
import { prisma } from '@lib/db';

// Mount Prisma-style APIs: "/api/model/post/findMany", "/api/model/post/create", etc.
// Can be configured to provide standard RESTful APIs (using JSON:API) instead.
export default requestHandler({
    getPrisma: (req, res) => enhance(prisma, { user: getSessionUser(req, res) }),
});

4. Generated client libraries (hooks) for data access

Plugins can generate strong-typed client libraries that talk to the aforementioned APIs. Here's an example for React:

// components/MyPosts.tsx

import { useFindManyPost } from '@lib/hooks';

const MyPosts = () => {
    // list all posts that're visible to the current user, together with their authors
    const { data: posts } = useFindManyPost({
        include: { author: true },
        orderBy: { createdAt: 'desc' },
    });

    return (
        <ul>
            {posts?.map((post) => (
                <li key={post.id}>
                    {post.title} by {post.author.name}
                </li>
            ))}
        </ul>
    );
};

Architecture

The following diagram gives a high-level architecture overview of ZenStack.

Architecture

Links

Features

  • Access control and data validation rules right inside your Prisma schema
  • Auto-generated OpenAPI (RESTful) specifications, services, and client libraries
  • End-to-end type safety
  • Extensible: custom attributes, functions, and a plugin system
  • A framework-agnostic core with framework-specific adapters
  • Uncompromised performance

Plugins

Framework adapters

Prisma schema extensions

Examples

Schema Samples

The sample repo includes the following patterns:

  • ACL
  • RBAC
  • ABAC
  • Multi-Tenancy

You can use this blog post as an introduction.

Multi-Tenant Todo App

Check out the Multi-tenant Todo App for a running example. You can find different implementations below:

Blog App

Community

Join our discord server for chat and updates!

Contributing

If you like ZenStack, join us to make it a better tool! Please use the Contributing Guide for details on how to get started, and don't hesitate to join Discord to share your thoughts. Documentations reside in a separate repo: zenstack-docs.

Please also consider sponsoring our work to speed up the development. Your contribution will be 100% used as a bounty reward to encourage community members to help fix bugs, add features, and improve documentation.

Sponsors

Thank you for your generous support!

Current Sponsors

Suhyl
Suhyl
Marblism
Marblism
Mermaid Chart
Mermaid Chart
CodeRabbit
CodeRabbit
Johann Rohn
Johann Rohn

Previous Sponsors

Benjamin Zecirovic
Benjamin Zecirovic
Ulric
Ulric
Fabian Jocks
Fabian Jocks

Contributors

Thanks to all the contributors who have helped make ZenStack better!

Source

Docs

License

MIT

changelog

0.5.0 (2022-12-15)

Features

  • Serialization between client (hooks) and server now uses superjson, [#139]

Fixes and improvements

  • Fixed goto definition issue in VSCode extension, [#69]

Breaking changes

  • Next-auth adapter and helper are moved to a separate package @zenstackhq/next-auth.

0.4.0 (2022-12-01)

Features

  • zenstack init command for initializing a project, #109, doc.

  • Field constraint suport, #94, doc.

  • Support for server-side CRUD with access policy check (SSR), #126, doc.

  • Options for disabling fetching in hooks (useful when arguments are not ready), #57, doc.

  • Telemetry in CLI, #102, doc.

  • Iron-session based starter, #95, link.

  • Barebone starter (without authentication), link.

  • Website is live!

Fixes and improvements

  • Merge @zenstackhq/internal into @zenstackhq/runtime so as to have a single runtime dependency, #70.

  • More accurate log for access policy violation, #71.

  • auth() function's return type is now resolved to User model in ZModel, instead of Any, #65.

  • Improved ZModel type checking, #67, #46, #99.

  • Upgraded to Prisma 4.7.

Breaking changes

  • @zenstackhq/runtime doesn't export anything now.

    Use @zenstackhq/runtime/types for type definitions shared between client and server, @zenstackhq/runtime/client for client-specific libaries (like React hooks), and @zenstackhq/runtime/server for server-specific libraries.

0.3.0 (2022-11-08)

Features

  • @password and @omit attribute support

  • Configurable logging (to stdout and emitting as events)

Fixes and improvements

  • More robust policy checks

  • Properly handles complex types like BigInt, Date, Decimal, etc.

  • Makes sure Prisma schema is regenerated for related CLI commands

  • Lower VSCode engine version requirement for the extension

  • Better overall documentation

0.2.0 (2022-10-29)

Features

  • ZModel data modeling schema (an extension to Prisma Schema)

  • zenstack cli for generating RESTful services, auth adapters and React hooks from ZModel

  • Policy engine that transforms policy rules into Prisma query conditions

  • Runtime packages

  • An initial set of tests