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
1 change: 1 addition & 0 deletions docs/guides/check-permission.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ ZenStack uses the [logic-solver](https://www.npmjs.com/package/logic-solver) pac
- Array fields are not supported.
- Relation fields are not supported.
- Collection predicates are not supported.
- The API is not supported on edge runtime (e.g., Cloudflare Workers or Vercel Edge).

You can still use the `check` API even if your access policies use these unsupported features. Boolean components containing unsupported features are ignored during SAT solving by being converted to free variables, which can be assigned either `true` or `false` in a solution.

Expand Down
2 changes: 1 addition & 1 deletion docs/guides/edge.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ To workaround this problem, add the following to the "package.json" file to avoi

## Cloudflare Workers

You can use ZenStack-enhanced `PrismaClient` in Cloudflare Workers. Here's an example for using with a Neon database. It's recommended to import `enhance` from `@zenstackhq/runtime/edge` instead of `@zenstackhq/runtime`. Although these two modules are identical today, they may diverge in the future due to limitations of the edge runtime.
You can use ZenStack-enhanced `PrismaClient` in Cloudflare Workers. Here's an example for using with a Neon database. Please make sure to import `enhance` from `@zenstackhq/runtime/edge` instead of `@zenstackhq/runtime`.

```ts
import { PrismaClient } from '@prisma/client';
Expand Down
46 changes: 46 additions & 0 deletions docs/guides/prisma-pulse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
description: Using ZenStack with Prisma Pulse.
sidebar_position: 14
---

# Using with Prisma Pulse (Preview)

## Introduction

[Prisma Pulse](https://www.prisma.io/data-platform/pulse) is Prisma's cloud offering that allows you to easily subscribe to real-time data change events from your database. It's a great way to build real-time applications without managing a Change Data Capture (CDC) infrastructure.

With Prisma Pulse, you can use the new `stream()` API to subscribe to data change events. For example:

```ts
const stream = await prisma.user.stream()

for await (const event of stream) {
console.log('just received an event:', event)
}
```

The `stream()` API also allows you to filter only the events you're interested in.

```ts
// Filter for new User records with a non-null value for name
const stream = await prisma.user.stream({
create: {
name: { not: null },
},
});
```

## ZenStack's access policies and Prisma Pulse

TLDR: it just works!

ZenStack's access policies seamlessly work with the `stream()` API without additional configuration. You can simply use an enhanced Prisma client to subscribe to data change events, and the access policies will be enforced automatically.

```ts
const db = enhance(prisma, { user: session.user });

// The event stream is automatically filtered by the access policies
const stream = await db.user.stream(...);
```

Only events that satisfy the "read" policies will be returned. If there are field-level "read" policies, fields that do not satisfy the policies will be stripped from the event payload. Fields marked with `@omit` are also automatically removed.
74 changes: 73 additions & 1 deletion docs/guides/trpc.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ sidebar_position: 7
---

import InitTips from '../_components/_zenstack-init-tips.md';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Using With tRPC

Expand Down Expand Up @@ -33,15 +35,60 @@ First install the trpc package:
npm install -D @zenstackhq/trpc@latest
```

Then, add the following plugin configuration to your ZModel schema. Note that the configuration is different for tRPC v10 and v11:

<Tabs>

<TabItem value="v10" label={`tRPC v10`}>

```zmodel title='/schema.zmodel'
plugin trpc {
provider = '@zenstackhq/trpc'
output = 'src/server/routers/generated'
}
```
</TabItem>

<TabItem value="v11" label={`tRPC v11 (preview)`}>

To use with tRPC v11, you need to explicitly set the "version" option to "v11" and add two extra options to let ZenStack know where to import the tRPC's router factory (named `createTRPCRouter`) and procedure factory (named `procedure`) from. For example, with the following settings:

```zmodel title='/schema.zmodel'
plugin trpc {
provider = '@zenstackhq/trpc'
output = 'src/server/routers/generated'
version = 'v11'
importCreateRouter = "../../trpc"
importProcedure = "../../trpc"
}
```

The generated tRPC routers will contain code like the following:

```ts
import { createTRPCRouter } from "../../trpc";
import { procedure } from "../../trpc";

export default function createRouter() {
return createTRPCRouter({
findMany: procedure.input(...).query(...) => ...
...
});
}

```

:::info Why is v11 more complicated?

tRPC v11 removed several public TypeScript types that our previous way of code generation relied on. To get around this, we have to resort to letting the user tell us where to import the factories from so we can use them without explicitly typing them.

:::

</TabItem>

</Tabs>


### 3. Setting up the tRPC context

Usually in your tRPC project, you have a function to create a tRPC context. You need to make sure the context contains a `prisma` field that is an instance of Prisma client. The generated tRPC routers use that to talk to the database.
Expand Down Expand Up @@ -73,18 +120,43 @@ npx zenstack generate

You should find a bunch of tRPC routers generated in the output folder, one per each data model. A `createRouter` helper function is also generated, which returns a router instance for all models. You can use it as your top-level tRPC router, or merge it with other routers to form a more complex setup.

<Tabs>

<TabItem value="v10" label={`tRPC v10`}>

```ts title='/src/server/routers/_app.ts'
import { createRouter } from './generated/routers';

const t = initTRPC.context<Context>().create();

export const appRouter = createRouter(t.router, t.procedure);
export type AppRouter = typeof appRouter;
```

</TabItem>

<TabItem value="v11" label={`tRPC v11`}>

```ts title='/src/server/routers/_app.ts'
import { createRouter } from './generated/routers';

const t = initTRPC.context<Context>().create();

export const procedure = t.publicProcedure;
export const createTRPCRouter = t.createRouter;

...

export const appRouter = createRouter();
export type AppRouter = typeof appRouter;
```

</TabItem>

</Tabs>

_NOTE_: The ZenStack trpc plugin is based on the awesome work by [Omar Dulaimi](https://github.com/omar-dulaimi/prisma-trpc-generator).

---

Please refer to the [@zenstackhq/trpc](../reference/plugins/trpc) plugin documentation for more details.
Please refer to the [@zenstackhq/trpc](../reference/plugins/trpc) plugin documentation for more details. You can also use the [sample-todo-trpc](https://github.com/zenstackhq/sample-todo-trpc) project as a reference.
31 changes: 24 additions & 7 deletions docs/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,26 @@ Commands:
generate [options] Generates RESTful API and Typescript client for your data model.
repl [options] Start a REPL session.
format [options] Format a ZenStack schema file.
check [options] Check a ZenStack schema file for syntax or semantic errors.
help [command] Display help for a command.
```

## Sub Commands

### info

Get information of installed ZenStack and related packages.

```bash
zenstack info [options] [path]
```

#### Arguments

| Name | Description | Default |
| ---- | ------------ | -------------- |
| path | Project path | current folder |

### init

Initializes an existing project to use ZenStack.
Expand Down Expand Up @@ -86,6 +101,8 @@ zenstack generate [options]
| --------------------- | ------------------------------------------------ | ---------------------- |
| --schema | schema file (with extension .zmodel) | ./schema.zmodel |
| -o, --output &lt;path&gt; | default output directory for TS/JS files generated by built-in plugins | node_modules/.zenstack |
| --with-plugins | only run specific plugins | |
| --without-plugins | exclude specific plugins | |
| --no-default-plugins | do not automatically run built-in plugins | false |
| --no-compile | do not compile the output of built-in plugins | false |
| --no-version-check | do not check for new versions of ZenStack | false |
Expand Down Expand Up @@ -218,16 +235,16 @@ You can also specify the ZModel schema location in the "package.json" file of yo
}
```

### info
### check

Get information of installed ZenStack and related packages.
Check a ZenStack schema file for syntax or semantic errors. You can use the CLI's exit code to determine if the schema is valid.

```bash
zenstack info [options] [path]
zenstack check [options]
```

#### Arguments
#### Options

| Name | Description | Default |
| ---- | ------------ | -------------- |
| path | Project path | current folder |
| Name | Description | Default |
| --------------------- | ------------------------------------------------ | ---------------------- |
| --schema | schema file (with extension .zmodel) | ./schema.zmodel |
4 changes: 3 additions & 1 deletion docs/reference/plugins/trpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ npm install --save-dev @zenstackhq/trpc
| Name | Type | Description | Required | Default |
| ------ | ------ | ---------------- | -------- | ------- |
| output | String | Output directory (relative to the path of ZModel) | Yes | |
| generateModels | String, String[] | Array or comma separated string for the models to generate routers for. | No | All models |
| version | String | tRPC version to target - "v10" or "v11". "v11" support is still in preview. | No | v10 |
| importCreateRouter | String | Only needed when "version" is set to "v11". This option tells the code generator where to import the `createTRPCRouter` tRPC router factory object from. | Yes (v11) | |
| importProcedure | String | Only needed when "version" is set to "v11". This option tells the code generator where to import the `procedure` tRPC procedure factory object from. | Yes (v11) | || generateModels | String, String[] | Array or comma separated string for the models to generate routers for. | No | All models |
Copy link
Contributor

Choose a reason for hiding this comment

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

Fix required: Table format issue.

The table has too many cells as per the Markdownlint warning. Please ensure that the table format is corrected to display all data properly.

Tools
Markdownlint

29-29: Expected: 5; Actual: 11; Too many cells, extra data will be missing
Table column count

(MD056, table-column-count)

| generateModelActions | String, String[] | Array or comma separated string for actions to generate for each model: `create`, `findUnique`, `update`, etc. | No | All supported Prisma actions |
| generateClientHelpers | String, String[] | Array or comma separated string for the types of client helpers to generate. Supported values: "react" or "next". See [here](#client-helpers) for more details. | No | |
| zodSchemasImport | String | Import path for the generated zod schemas. The trpc plugin relies on the `@core/zod` plugin to generate zod schemas for input validation. If you set a custom output location for the zod schemas, you can use this option to override the import path. | No | @zenstackhq/runtime/zod |
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/prisma-client-ext.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ ZenStack's enhancement to PrismaClient not only alters its existing APIs' behavi

This API is added to each model in the PrismaClient.

:::warning
The API is not supported on edge runtime (e.g., Cloudflare Workers or Vercel Edge). You'll get a runtime error when calling it.
:::

#### Description

Checks if the current user is allowed to perform the specified operation on the model based on the access policies in ZModel. The check is done via pure logical inference and doesn't query the database.
Expand Down
4 changes: 2 additions & 2 deletions docs/reference/zmodel-language.md
Original file line number Diff line number Diff line change
Expand Up @@ -1643,10 +1643,10 @@ Attributes `@trim`, `@lower`, and `@upper` are actually "transformation" instead

### Model-level validation attributes

You can use the `@@validate` attribute to attach validation rules to a model.
You can use the `@@validate` attribute to attach validation rules to a model. Use the `message` parameter to provide an optional custom error message, and the `path` parameter to provide an optional path to the field that caused the error.

```
@@validate(_ value: Boolean, _ message: String?)
@@validate(_ value: Boolean, _ message: String?, _ path: String[]?)
Comment on lines +1646 to +1649
Copy link
Contributor

Choose a reason for hiding this comment

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

Approve the enhancements to the @@validate attribute and suggest Markdown formatting fix.

The updates to the @@validate attribute documentation are clear and align with the PR objectives, enhancing the usability of the validation mechanism by introducing message and path parameters.

However, there's a minor issue with the Markdown formatting:

  • The fenced code block at line 1648 is missing a language specification, which is important for proper syntax highlighting and readability.

Please add a language specification to the fenced code block to resolve the Markdownlint warning. Here's a suggested fix:

- ```
+ ```zmodel
@@validate(_ value: Boolean, _ message: String?, _ path: String[]?)
Tools
Markdownlint

1648-1648: null
Fenced code blocks should have a language specified

(MD040, fenced-code-language)

```

Model-level rules can reference multiple fields, use relation operators (`==`, `!=`, `>`, `>=`, `<`, `<=`) to compare fields, use boolean operators (`&&`, `||`, and `!`) to compose conditions, and can use the following functions to evaluate conditions for fields:
Expand Down