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
8 changes: 3 additions & 5 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,15 @@

- [Commands](cli-commands.md)

- Runtime API

- [`@zenstackhq/runtime/types`](runtime-types.md)
- [`@zenstackhq/runtime/client`](runtime-client.md)
- [`@zenstackhq/runtime/server`](runtime-server.md)
- [Runtime API](runtime-api.md)

- Guide

- [Choosing a database](choosing-a-database.md)
- [Evolving model with migration](evolving-model-with-migration.md)
- [Integrating authentication](integrating-authentication.md)
- [Set up logging](setup-logging.md)
- [Telemetry](telemetry.md)

- [VSCode extension](vscode-extension.md)
- [Reach out to the developers](reach-out.md)
2 changes: 1 addition & 1 deletion docs/building-your-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,6 @@ export const getServerSideProps: GetServerSideProps = async () => {

The Typescript types of data models, filters, sorting, etc., are all shared between the frontend and the backend.

**Note** that server-side database access is not protected by access policies. This is by-design so as to provide a way of bypassing the policies. Please make sure you implement authorization properly.
_Note_ Server-side database access is **NOT PROTECTED** by access policies. This is by-design so as to provide a way of bypassing the policies. Please make sure you implement authorization properly.

_TBD_ In the future we'll provide a utility for explicitly validating access policies in backend code, so that you can reuse your policy definitions in the model.
8 changes: 4 additions & 4 deletions docs/choosing-a-database.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Choosing a database

ZenStack is agnostic about where and how you deploy your web app, but hosting on serverless platforms like [Vercel](https://vercel.com/) is definitely a popular choice.
ZenStack is agnostic about where and how you deploy your web app, but hosting on serverless platforms like [Vercel](https://vercel.com/ ':target=blank') is definitely a popular choice.

Serverless architecture has some implications on how you should care about your database hosting. Different from traditional architecture where you have a fixed number of long-running Node.js servers, in a serverless environment, a new Node.js context can potentially be created for each user request, and if traffic volume is high, this can quickly exhaust your database's connection limit, if you connect to the database directly without a proxy.

You'll likely be OK if your app has a low number of concurrent users, otherwise you should consider using a proxy in front of your database server. Here's a number of (incomplete) solutions you can consider:

- [Prisma Data Proxy](https://www.prisma.io/data-platform/proxy)
- [Supabase](https://supabase.com/)'s [connection pool](https://supabase.com/docs/guides/database/connecting-to-postgres#connection-pool)
- [Deploy pgbouncer with Postgres on Heroku](https://devcenter.heroku.com/articles/postgres-connection-pooling)
- [Prisma Data Proxy](https://www.prisma.io/data-platform/proxy ':target=blank')
- [Supabase](https://supabase.com/)'s [connection pool](https://supabase.com/docs/guides/database/connecting-to-postgres#connection-pool ':target=blank')
- [Deploy pgbouncer with Postgres on Heroku](https://devcenter.heroku.com/articles/postgres-connection-pooling ':target=blank')
2 changes: 1 addition & 1 deletion docs/cli-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Set up ZenStack for an existing Next.js + Typescript project.

```bash
npx zenstack init [dir]
npx zenstack init [options] [dir]
```

_Options_:
Expand Down
84 changes: 84 additions & 0 deletions docs/entity-types-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Types

Module `@zenstackhq/runtime/types` contains type definitions of entities, filters, sorting, etc., generated from ZModel data models. The types can be used in both the front-end and the backend code.

Suppose a `User` model is defined in ZModel:

```prisma
model User {
id String @id @default(cuid())
email String @unique @email
password String @password @omit
name String?
posts Post[]
}
```

The following types are generated:

## Entity type

````ts
export type User = {
id: string
email: string
password: string | null
name: string | null
posts: Post[]
}```

This type serves as the return type of the generated React hooks:

```ts
import { type User } from '@zenstackhq/runtime/types';
import { useUser } from '@zenstackhq/runtime/client';

export function MyComponent() {
const { find } = useUser();
const result = find();
const users: User[] = result.data;
...
}
````

Backend database access API also returns the same type:

```ts
const users: User[] = await service.db.User.find();
```

## Filter and sort type

Types for filtering and sorting entites are also generated:

```ts
export type UserFindManyArgs = {
select?: UserSelect | null;
include?: UserInclude | null;
where?: UserWhereInput;
orderBy?: Enumerable<UserOrderByWithRelationInput>;
...
};
```

You can use it like:

```ts
const { find } = useUser();
const { data: users } = find({
where: {
email: {
endsWith: '@zenstack.dev',
},
},
orderBy: [
{
email: 'asc',
},
],
include: {
// include related Post entities
posts: true,
},
});
```
84 changes: 84 additions & 0 deletions docs/entity-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Types

Module `@zenstackhq/runtime/types` contains type definitions of entities, filters, sorting, etc., generated from ZModel data models. The types can be used in both the front-end and the backend code.

Suppose a `User` model is defined in ZModel:

```prisma
model User {
id String @id @default(cuid())
email String @unique @email
password String @password @omit
name String?
posts Post[]
}
```

The following types are generated:

## Entity type

````ts
export type User = {
id: string
email: string
password: string | null
name: string | null
posts: Post[]
}```

This type serves as the return type of the generated React hooks:

```ts
import { type User } from '@zenstackhq/runtime/types';
import { useUser } from '@zenstackhq/runtime/client';

export function MyComponent() {
const { find } = useUser();
const result = find();
const users: User[] = result.data;
...
}
````

Backend database access API also returns the same type:

```ts
const users: User[] = await service.db.User.find();
```

## Filter and sort type

Types for filtering and sorting entites are also generated:

```ts
export type UserFindManyArgs = {
select?: UserSelect | null;
include?: UserInclude | null;
where?: UserWhereInput;
orderBy?: Enumerable<UserOrderByWithRelationInput>;
...
};
```

You can use it like:

```ts
const { find } = useUser();
const { data: users } = find({
where: {
email: {
endsWith: '@zenstack.dev',
},
},
orderBy: [
{
email: 'asc',
},
],
include: {
// include related Post entities
posts: true,
},
});
```
85 changes: 85 additions & 0 deletions docs/integrating-authentication.md
Original file line number Diff line number Diff line change
@@ -1 +1,86 @@
# Integrating authentication

This documentation explains how to integrate ZenStack with popular authentication frameworks.

## NextAuth

[NextAuth](https://next-auth.js.org/) is a comprehensive framework for implementating authentication. It offers a pluggable mechanism for configuring how user data is persisted.

When `zenstack generate` runs, it generates an adapter for NextAuth if it finds the `next-auth` npm package is installed. The generated adapter can be configured to NextAuth as follows:

```ts
// pages/api/auth/[...nextauth].ts

import service from '@zenstackhq/runtime/server';
import { NextAuthAdapter as Adapter } from '@zenstackhq/runtime/server/auth';
import NextAuth, { type NextAuthOptions } from 'next-auth';

export const authOptions: NextAuthOptions = {
// install ZenStack adapter
adapter: Adapter(service),
...
};

export default NextAuth(authOptions);
```

If you use [`CredentialsProvider`](https://next-auth.js.org/providers/credentials ':target=blank'), i.e. username/password based auth, you can also use the generated `authorize` function to implement how username/password is verified against the database:

```ts
// pages/api/auth/[...nextauth].ts

import service from '@zenstackhq/runtime/server';
import { authorize } from '@zenstackhq/runtime/server/auth';
import NextAuth, { type NextAuthOptions } from 'next-auth';

export const authOptions: NextAuthOptions = {
...
providers: [
CredentialsProvider({
credentials: {
email: {
label: 'Email Address',
type: 'email',
},
password: {
label: 'Password',
type: 'password',
},
},

// use ZenStack's default implementation to verify credentials
authorize: authorize(service),
}),
]};

export default NextAuth(authOptions);
```

NextAuth is agnostic about the type of underlying database, but it requires certain table structures, depending on how you configure it. Your ZModel definitions should reflect these requirements. A sample `User` model is shown here (to be used with `CredentialsProvider`):

```prisma
model User {
id String @id @default(cuid())
email String @unique @email
emailVerified DateTime?
password String @password @omit
name String?
image String? @url

// open to signup
@@allow('create', true)

// full access by oneself
@@allow('all', auth() == this)
}
```

You can find the detailed database model requirements [here](https://next-auth.js.org/adapters/models ':target=blank').

## IronSession

[TBD]

## Custom-built authentication

[TBD]
9 changes: 9 additions & 0 deletions docs/reach-out.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Reach out to the developers

As developers of ZenStack, we hope this toolkit can assist you to build a cool app.
Should you have any questions or ideas, please feel free to reach out to us by any of the following methods. We'll be happy to help you out.

- [Discord](https://go.zenstack.dev/chat)
- [GitHub Discussions](https://github.com/zenstackhq/zenstack/discussions)
- [Twitter](https://twitter.com/zenstackhq)
- Email us: [contact@zenstack.dev](mailto:contact@zenstack.dev)
Loading