From 29771e632dc0aa4f5c3aca2b380de78e5bab50c5 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Fri, 1 Aug 2025 21:24:34 +0800 Subject: [PATCH 01/51] docs: v3 docs structure --- docusaurus.config.js | 4 + package.json | 1 + pnpm-lock.yaml | 8 + src/components/StackBlitzEmbed.tsx | 26 + src/components/StackBlitzGithubEmbed.tsx | 26 + .../version-3.x/_components/PackageExec.tsx | 28 + .../_components/PackageInstall.tsx | 33 + .../_components/_zmodel-starter.md | 23 + versioned_docs/version-3.x/faq.md | 9 + .../version-3.x/migration/_category_.yml | 7 + .../version-3.x/migration/introduction.md | 6 + versioned_docs/version-3.x/orm/_category_.yml | 7 + .../orm/access-control/_category_.yml | 4 + .../orm/access-control/introduction.md | 3 + .../version-3.x/orm/api/_category_.yml | 7 + .../version-3.x/orm/api/aggregate.md | 6 + versioned_docs/version-3.x/orm/api/count.md | 6 + versioned_docs/version-3.x/orm/api/create.md | 6 + versioned_docs/version-3.x/orm/api/delete.md | 6 + versioned_docs/version-3.x/orm/api/find.md | 6 + .../version-3.x/orm/api/transaction.md | 6 + versioned_docs/version-3.x/orm/api/update.md | 6 + versioned_docs/version-3.x/orm/cli.md | 6 + .../version-3.x/orm/computed-fields.md | 7 + .../version-3.x/orm/database-client.mdx | 65 + .../version-3.x/orm/introduction.md | 120 + .../version-3.x/orm/plugins/_category_.yml | 7 + .../version-3.x/orm/plugins/introduction.md | 6 + .../version-3.x/orm/query-builder.md | 6 + .../version-3.x/orm/quick-start.mdx | 67 + versioned_docs/version-3.x/orm/ts-types.md | 6 + versioned_docs/version-3.x/orm/validation.md | 8 + .../version-3.x/orm/zmodel/_category_.yml | 7 + .../version-3.x/orm/zmodel/attributes.md | 6 + .../version-3.x/orm/zmodel/builtin-types.md | 6 + .../version-3.x/orm/zmodel/components.md | 6 + .../version-3.x/orm/zmodel/custom-types.md | 6 + .../version-3.x/orm/zmodel/datasource.md | 7 + .../version-3.x/orm/zmodel/models.md | 7 + .../version-3.x/orm/zmodel/multi-file.md | 9 + .../version-3.x/orm/zmodel/polymorphism.md | 7 + .../version-3.x/orm/zmodel/relations.md | 6 + .../version-3.x/orm/zmodel/reusing-fields.md | 7 + .../version-3.x/recipes/_category_.yml | 7 + .../version-3.x/reference/_category_.yml | 7 + versioned_docs/version-3.x/reference/cli.md | 251 +++ .../version-3.x/reference/error-handling.md | 43 + .../version-3.x/reference/limitations.md | 40 + .../version-3.x/reference/runtime-api.md | 130 ++ .../reference/server-adapters/_category_.yml | 7 + .../server-adapters/_error-handling.md | 3 + .../reference/server-adapters/_options.mdx | 66 + .../reference/server-adapters/_using-api.mdx | 137 ++ .../api-handlers/_data_type_serialization.md | 16 + .../server-adapters/api-handlers/index.mdx | 31 + .../server-adapters/api-handlers/rest.mdx | 982 ++++++++ .../server-adapters/api-handlers/rpc.mdx | 275 +++ .../reference/server-adapters/elysia.mdx | 69 + .../reference/server-adapters/express.mdx | 66 + .../reference/server-adapters/fastify.mdx | 56 + .../reference/server-adapters/hono.mdx | 57 + .../reference/server-adapters/nestjs.mdx | 268 +++ .../reference/server-adapters/next.mdx | 124 + .../reference/server-adapters/nuxt.mdx | 44 + .../reference/server-adapters/sveltekit.mdx | 63 + .../version-3.x/reference/zmodel-language.md | 1987 +++++++++++++++++ versioned_docs/version-3.x/samples.md | 8 + .../version-3.x/service/_category_.yml | 7 + .../version-3.x/service/introduction.md | 3 + versioned_docs/version-3.x/upgrade.md | 10 + .../version-3.x/utilities/_category_.yml | 7 + versioned_docs/version-3.x/utilities/zod.md | 6 + versioned_docs/version-3.x/welcome.md | 10 + versioned_sidebars/version-3.x-sidebars.json | 8 + versions.json | 2 +- 75 files changed, 5395 insertions(+), 1 deletion(-) create mode 100644 src/components/StackBlitzEmbed.tsx create mode 100644 src/components/StackBlitzGithubEmbed.tsx create mode 100644 versioned_docs/version-3.x/_components/PackageExec.tsx create mode 100644 versioned_docs/version-3.x/_components/PackageInstall.tsx create mode 100644 versioned_docs/version-3.x/_components/_zmodel-starter.md create mode 100644 versioned_docs/version-3.x/faq.md create mode 100644 versioned_docs/version-3.x/migration/_category_.yml create mode 100644 versioned_docs/version-3.x/migration/introduction.md create mode 100644 versioned_docs/version-3.x/orm/_category_.yml create mode 100644 versioned_docs/version-3.x/orm/access-control/_category_.yml create mode 100644 versioned_docs/version-3.x/orm/access-control/introduction.md create mode 100644 versioned_docs/version-3.x/orm/api/_category_.yml create mode 100644 versioned_docs/version-3.x/orm/api/aggregate.md create mode 100644 versioned_docs/version-3.x/orm/api/count.md create mode 100644 versioned_docs/version-3.x/orm/api/create.md create mode 100644 versioned_docs/version-3.x/orm/api/delete.md create mode 100644 versioned_docs/version-3.x/orm/api/find.md create mode 100644 versioned_docs/version-3.x/orm/api/transaction.md create mode 100644 versioned_docs/version-3.x/orm/api/update.md create mode 100644 versioned_docs/version-3.x/orm/cli.md create mode 100644 versioned_docs/version-3.x/orm/computed-fields.md create mode 100644 versioned_docs/version-3.x/orm/database-client.mdx create mode 100644 versioned_docs/version-3.x/orm/introduction.md create mode 100644 versioned_docs/version-3.x/orm/plugins/_category_.yml create mode 100644 versioned_docs/version-3.x/orm/plugins/introduction.md create mode 100644 versioned_docs/version-3.x/orm/query-builder.md create mode 100644 versioned_docs/version-3.x/orm/quick-start.mdx create mode 100644 versioned_docs/version-3.x/orm/ts-types.md create mode 100644 versioned_docs/version-3.x/orm/validation.md create mode 100644 versioned_docs/version-3.x/orm/zmodel/_category_.yml create mode 100644 versioned_docs/version-3.x/orm/zmodel/attributes.md create mode 100644 versioned_docs/version-3.x/orm/zmodel/builtin-types.md create mode 100644 versioned_docs/version-3.x/orm/zmodel/components.md create mode 100644 versioned_docs/version-3.x/orm/zmodel/custom-types.md create mode 100644 versioned_docs/version-3.x/orm/zmodel/datasource.md create mode 100644 versioned_docs/version-3.x/orm/zmodel/models.md create mode 100644 versioned_docs/version-3.x/orm/zmodel/multi-file.md create mode 100644 versioned_docs/version-3.x/orm/zmodel/polymorphism.md create mode 100644 versioned_docs/version-3.x/orm/zmodel/relations.md create mode 100644 versioned_docs/version-3.x/orm/zmodel/reusing-fields.md create mode 100644 versioned_docs/version-3.x/recipes/_category_.yml create mode 100644 versioned_docs/version-3.x/reference/_category_.yml create mode 100644 versioned_docs/version-3.x/reference/cli.md create mode 100644 versioned_docs/version-3.x/reference/error-handling.md create mode 100644 versioned_docs/version-3.x/reference/limitations.md create mode 100644 versioned_docs/version-3.x/reference/runtime-api.md create mode 100644 versioned_docs/version-3.x/reference/server-adapters/_category_.yml create mode 100644 versioned_docs/version-3.x/reference/server-adapters/_error-handling.md create mode 100644 versioned_docs/version-3.x/reference/server-adapters/_options.mdx create mode 100644 versioned_docs/version-3.x/reference/server-adapters/_using-api.mdx create mode 100644 versioned_docs/version-3.x/reference/server-adapters/api-handlers/_data_type_serialization.md create mode 100644 versioned_docs/version-3.x/reference/server-adapters/api-handlers/index.mdx create mode 100644 versioned_docs/version-3.x/reference/server-adapters/api-handlers/rest.mdx create mode 100644 versioned_docs/version-3.x/reference/server-adapters/api-handlers/rpc.mdx create mode 100644 versioned_docs/version-3.x/reference/server-adapters/elysia.mdx create mode 100644 versioned_docs/version-3.x/reference/server-adapters/express.mdx create mode 100644 versioned_docs/version-3.x/reference/server-adapters/fastify.mdx create mode 100644 versioned_docs/version-3.x/reference/server-adapters/hono.mdx create mode 100644 versioned_docs/version-3.x/reference/server-adapters/nestjs.mdx create mode 100644 versioned_docs/version-3.x/reference/server-adapters/next.mdx create mode 100644 versioned_docs/version-3.x/reference/server-adapters/nuxt.mdx create mode 100644 versioned_docs/version-3.x/reference/server-adapters/sveltekit.mdx create mode 100644 versioned_docs/version-3.x/reference/zmodel-language.md create mode 100644 versioned_docs/version-3.x/samples.md create mode 100644 versioned_docs/version-3.x/service/_category_.yml create mode 100644 versioned_docs/version-3.x/service/introduction.md create mode 100644 versioned_docs/version-3.x/upgrade.md create mode 100644 versioned_docs/version-3.x/utilities/_category_.yml create mode 100644 versioned_docs/version-3.x/utilities/zod.md create mode 100644 versioned_docs/version-3.x/welcome.md create mode 100644 versioned_sidebars/version-3.x-sidebars.json diff --git a/docusaurus.config.js b/docusaurus.config.js index 0dd2e501..5eef4d59 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -44,6 +44,10 @@ const config = { label: '1.x', banner: 'none', }, + '3.x': { + label: '3.0 Alpha', + banner: 'none', + }, }, }, blog: false, diff --git a/package.json b/package.json index fa70489e..85733b49 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "@docusaurus/theme-mermaid": "3.4.0", "@giscus/react": "^2.4.0", "@mdx-js/react": "^3.0.1", + "@stackblitz/sdk": "^1.11.0", "autoprefixer": "^10.4.13", "clsx": "^1.2.1", "postcss": "^8.4.21", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 78043273..7b0326f0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,6 +29,9 @@ importers: '@mdx-js/react': specifier: ^3.0.1 version: 3.0.1(@types/react@18.0.26)(react@18.2.0) + '@stackblitz/sdk': + specifier: ^1.11.0 + version: 1.11.0 autoprefixer: specifier: ^10.4.13 version: 10.4.13(postcss@8.4.21) @@ -1113,6 +1116,9 @@ packages: '@slorber/remark-comment@1.0.0': resolution: {integrity: sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==} + '@stackblitz/sdk@1.11.0': + resolution: {integrity: sha512-DFQGANNkEZRzFk1/rDP6TcFdM82ycHE+zfl9C/M/jXlH68jiqHWHFMQURLELoD8koxvu/eW5uhg94NSAZlYrUQ==} + '@svgr/babel-plugin-add-jsx-attribute@8.0.0': resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} engines: {node: '>=14'} @@ -6914,6 +6920,8 @@ snapshots: micromark-util-character: 1.2.0 micromark-util-symbol: 1.1.0 + '@stackblitz/sdk@1.11.0': {} + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.23.9)': dependencies: '@babel/core': 7.23.9 diff --git a/src/components/StackBlitzEmbed.tsx b/src/components/StackBlitzEmbed.tsx new file mode 100644 index 00000000..db7b6418 --- /dev/null +++ b/src/components/StackBlitzEmbed.tsx @@ -0,0 +1,26 @@ +import React, { useEffect, useRef } from 'react'; +import sdk from '@stackblitz/sdk'; + +interface StackBlitzEmbedProps { + projectId: string; + height?: string; +} + +const StackBlitzEmbed: React.FC = ({ projectId, height = '600px' }) => { + const containerRef = useRef(null); + + useEffect(() => { + if (containerRef.current) { + sdk.embedProjectId(containerRef.current, projectId, { + openFile: 'main.ts', + height, + view: 'editor', + forceEmbedLayout: true, + }); + } + }, [projectId, height]); + + return
; +}; + +export default StackBlitzEmbed; diff --git a/src/components/StackBlitzGithubEmbed.tsx b/src/components/StackBlitzGithubEmbed.tsx new file mode 100644 index 00000000..5bddace1 --- /dev/null +++ b/src/components/StackBlitzGithubEmbed.tsx @@ -0,0 +1,26 @@ +import React, { useEffect, useRef } from 'react'; +import sdk from '@stackblitz/sdk'; + +interface StackBlitzGithubEmbedProps { + repoPath: string; + height?: string; +} + +const StackBlitzGithubEmbed: React.FC = ({ repoPath, height = '600px' }) => { + const containerRef = useRef(null); + + useEffect(() => { + if (containerRef.current) { + sdk.embedGithubProject(containerRef.current, repoPath, { + openFile: 'main.ts', + height, + view: 'editor', + forceEmbedLayout: true, + }); + } + }, [repoPath, height]); + + return
; +}; + +export default StackBlitzGithubEmbed; diff --git a/versioned_docs/version-3.x/_components/PackageExec.tsx b/versioned_docs/version-3.x/_components/PackageExec.tsx new file mode 100644 index 00000000..e3df2110 --- /dev/null +++ b/versioned_docs/version-3.x/_components/PackageExec.tsx @@ -0,0 +1,28 @@ +import CodeBlock from '@theme/CodeBlock'; +import TabItem from '@theme/TabItem'; +import Tabs from '@theme/Tabs'; + +interface Props { + command: string; +} + +const pkgManagers = [ + { name: 'npm', command: 'npx' }, + { name: 'pnpm', command: 'pnpm' }, + { name: 'bun', command: 'bunx' }, + { name: 'yarn', command: 'npx' }, +]; + +const PackageInstall = ({ command }: Props) => { + return ( + + {pkgManagers.map((pkg) => ( + + {`${pkg.command} ${command}`} + + ))} + + ); +}; + +export default PackageInstall; diff --git a/versioned_docs/version-3.x/_components/PackageInstall.tsx b/versioned_docs/version-3.x/_components/PackageInstall.tsx new file mode 100644 index 00000000..53bf8805 --- /dev/null +++ b/versioned_docs/version-3.x/_components/PackageInstall.tsx @@ -0,0 +1,33 @@ +import CodeBlock from '@theme/CodeBlock'; +import TabItem from '@theme/TabItem'; +import Tabs from '@theme/Tabs'; + +interface Props { + devDependencies: string[]; + dependencies: string[]; +} + +const pkgManagers = [ + { name: 'npm', command: 'npm install', dev: '--save-dev' }, + { name: 'pnpm', command: 'pnpm add', dev: '--save-dev' }, + { name: 'bun', command: 'bun add', dev: '--dev' }, + { name: 'yarn', command: 'yarn add', dev: '--dev' }, +]; + +const PackageInstall = ({ devDependencies, dependencies }: Props) => { + return ( + + {pkgManagers.map((pkg) => ( + + + {`${devDependencies?.length ? `${pkg.command} ${pkg.dev} ${devDependencies.join(' ')}\n` : ''}${ + dependencies?.length ? `${pkg.command} ${dependencies.join(' ')}` : '' + }`} + + + ))} + + ); +}; + +export default PackageInstall; diff --git a/versioned_docs/version-3.x/_components/_zmodel-starter.md b/versioned_docs/version-3.x/_components/_zmodel-starter.md new file mode 100644 index 00000000..029ef799 --- /dev/null +++ b/versioned_docs/version-3.x/_components/_zmodel-starter.md @@ -0,0 +1,23 @@ + ```zmodel + datasource db { + provider = 'sqlite' + url = "file:./dev.db" + } + + model User { + id String @id @default(cuid()) + email String @unique @email @length(6, 32) + posts Post[] + } + + model Post { + id String @id @default(cuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + title String @length(1, 256) + content String + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id]) + authorId String + } + ``` \ No newline at end of file diff --git a/versioned_docs/version-3.x/faq.md b/versioned_docs/version-3.x/faq.md new file mode 100644 index 00000000..b0e81a65 --- /dev/null +++ b/versioned_docs/version-3.x/faq.md @@ -0,0 +1,9 @@ +--- +description: ZenStack FAQ. + +slug: /faq +sidebar_label: FAQ +sidebar_position: 100 +--- + +# πŸ™‹πŸ» FAQ diff --git a/versioned_docs/version-3.x/migration/_category_.yml b/versioned_docs/version-3.x/migration/_category_.yml new file mode 100644 index 00000000..be8bc9d1 --- /dev/null +++ b/versioned_docs/version-3.x/migration/_category_.yml @@ -0,0 +1,7 @@ +position: 3 +label: Migration +collapsible: true +collapsed: true +link: + type: generated-index + title: Migration diff --git a/versioned_docs/version-3.x/migration/introduction.md b/versioned_docs/version-3.x/migration/introduction.md new file mode 100644 index 00000000..2e8a25db --- /dev/null +++ b/versioned_docs/version-3.x/migration/introduction.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 1 +description: Introduction to ZenStack migration +--- + +# Introduction diff --git a/versioned_docs/version-3.x/orm/_category_.yml b/versioned_docs/version-3.x/orm/_category_.yml new file mode 100644 index 00000000..7e156336 --- /dev/null +++ b/versioned_docs/version-3.x/orm/_category_.yml @@ -0,0 +1,7 @@ +position: 2 +label: ORM +collapsible: true +collapsed: true +link: + type: generated-index + title: ORM diff --git a/versioned_docs/version-3.x/orm/access-control/_category_.yml b/versioned_docs/version-3.x/orm/access-control/_category_.yml new file mode 100644 index 00000000..dcb120ba --- /dev/null +++ b/versioned_docs/version-3.x/orm/access-control/_category_.yml @@ -0,0 +1,4 @@ +position: 8 +label: Access Control +collapsible: true +collapsed: true diff --git a/versioned_docs/version-3.x/orm/access-control/introduction.md b/versioned_docs/version-3.x/orm/access-control/introduction.md new file mode 100644 index 00000000..261e992b --- /dev/null +++ b/versioned_docs/version-3.x/orm/access-control/introduction.md @@ -0,0 +1,3 @@ +# Introduction + +Coming soon 🚧 \ No newline at end of file diff --git a/versioned_docs/version-3.x/orm/api/_category_.yml b/versioned_docs/version-3.x/orm/api/_category_.yml new file mode 100644 index 00000000..2a384497 --- /dev/null +++ b/versioned_docs/version-3.x/orm/api/_category_.yml @@ -0,0 +1,7 @@ +position: 6 +label: ORM API +collapsible: true +collapsed: true +link: + type: generated-index + title: ORM API diff --git a/versioned_docs/version-3.x/orm/api/aggregate.md b/versioned_docs/version-3.x/orm/api/aggregate.md new file mode 100644 index 00000000..0b545613 --- /dev/null +++ b/versioned_docs/version-3.x/orm/api/aggregate.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 6 +description: Aggregate API +--- + +# Aggregate \ No newline at end of file diff --git a/versioned_docs/version-3.x/orm/api/count.md b/versioned_docs/version-3.x/orm/api/count.md new file mode 100644 index 00000000..d22fd667 --- /dev/null +++ b/versioned_docs/version-3.x/orm/api/count.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 5 +description: Count API +--- + +# Count \ No newline at end of file diff --git a/versioned_docs/version-3.x/orm/api/create.md b/versioned_docs/version-3.x/orm/api/create.md new file mode 100644 index 00000000..7bd11da3 --- /dev/null +++ b/versioned_docs/version-3.x/orm/api/create.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 2 +description: Create API +--- + +# Create \ No newline at end of file diff --git a/versioned_docs/version-3.x/orm/api/delete.md b/versioned_docs/version-3.x/orm/api/delete.md new file mode 100644 index 00000000..11e0142c --- /dev/null +++ b/versioned_docs/version-3.x/orm/api/delete.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 4 +description: Delete API +--- + +# Delete \ No newline at end of file diff --git a/versioned_docs/version-3.x/orm/api/find.md b/versioned_docs/version-3.x/orm/api/find.md new file mode 100644 index 00000000..633a25c8 --- /dev/null +++ b/versioned_docs/version-3.x/orm/api/find.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 1 +description: Find API +--- + +# Find \ No newline at end of file diff --git a/versioned_docs/version-3.x/orm/api/transaction.md b/versioned_docs/version-3.x/orm/api/transaction.md new file mode 100644 index 00000000..d24f053d --- /dev/null +++ b/versioned_docs/version-3.x/orm/api/transaction.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 7 +description: Transaction API +--- + +# Transaction \ No newline at end of file diff --git a/versioned_docs/version-3.x/orm/api/update.md b/versioned_docs/version-3.x/orm/api/update.md new file mode 100644 index 00000000..468e8cac --- /dev/null +++ b/versioned_docs/version-3.x/orm/api/update.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 3 +description: Update API +--- + +# Update \ No newline at end of file diff --git a/versioned_docs/version-3.x/orm/cli.md b/versioned_docs/version-3.x/orm/cli.md new file mode 100644 index 00000000..98a18870 --- /dev/null +++ b/versioned_docs/version-3.x/orm/cli.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 4 +description: Using the CLI +--- + +# Using the CLI diff --git a/versioned_docs/version-3.x/orm/computed-fields.md b/versioned_docs/version-3.x/orm/computed-fields.md new file mode 100644 index 00000000..d6e2cbd7 --- /dev/null +++ b/versioned_docs/version-3.x/orm/computed-fields.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 10 +description: Computed fields in ZModel +--- + +# Computed Fields + diff --git a/versioned_docs/version-3.x/orm/database-client.mdx b/versioned_docs/version-3.x/orm/database-client.mdx new file mode 100644 index 00000000..ed04be38 --- /dev/null +++ b/versioned_docs/version-3.x/orm/database-client.mdx @@ -0,0 +1,65 @@ +--- +sidebar_position: 5 +description: Creating a database client +--- + +import TabItem from '@theme/TabItem'; +import Tabs from '@theme/Tabs'; +import PackageInstall from '../_components/PackageInstall'; + +# Database Client + +The `zen generate` command compiles the ZModel schema into TypeScript code, which we can in turn use to initialize a type-safe database client. ZenStack uses Kysely to handle the low-level database operations, so the client is initialize with a Kysely dialect - an object that encapsulates database details. + +The samples below only shows creating a client using SQLite (via [better-sqlite3](https://github.com/WiseLibs/better-sqlite3)) and PostgreSQL (via [node-postgres](https://github.com/brianc/node-postgres)), however you can also use any other Kysely dialects. + + + + + + + +```ts title='db.ts' +import { ZenStackClient } from '@zenstackhq/runtime'; +import { SqliteDialect } from 'kysely'; +import SQLite from 'better-sqlite3'; +import { schema } from '@/zenstack/schema'; + +export const db = new ZenStackClient(schema, { + dialect: new SqliteDialect({ + database: new SQLite(':memory:'), + }), +}); +``` + + + + + + +```ts title='db.ts' +import { ZenStackClient } from '@zenstackhq/runtime'; +import { schema } from '@/zenstack/schema'; +import { PostgresDialect } from 'kysely'; +import { Pool } from 'pg'; + +export const db = new ZenStackClient(schema, { + dialect: new PostgresDialect({ + pool: new Pool({ + connectionString: process.env.DATABASE_URL, + }), + }), +}); +``` + + + + +The created `db` object has the full ORM API inferred from the type of the `schema` parameter. When necessary, you can also explicitly get the inferred client type like: + +```ts +import type { ClientContract } from '@zenstackhq/runtime'; +import type { SchemaType } from '@/zenstack/schema'; + +export type DbClient = ClientContract; +``` diff --git a/versioned_docs/version-3.x/orm/introduction.md b/versioned_docs/version-3.x/orm/introduction.md new file mode 100644 index 00000000..8bcaf843 --- /dev/null +++ b/versioned_docs/version-3.x/orm/introduction.md @@ -0,0 +1,120 @@ +--- +sidebar_position: 1 +description: Introduction to ZenStack ORM +--- + +# Introduction + +ZenStack ORM is a schema-first ORM for modern TypeScript applications. It learnt from the prior arts and aims to provide an awesome developer experience by combining the best ingredients into a cohesive package. + +## Key Facts + +### [Prisma](https://prisma.io/orm)-Compatible Schema Language + +The schema language used by ZenStack (called ZModel) is a superset of Prisma schema language. Every valid Prisma schema can be used with ZenStack unchanged. In addition, ZModel added many important extensions to the language to improve the developer experience and enable advanced features. + +```zmodel +model User { + id String @id @default(cuid()) + email String @unique + posts Post[] +} + +model Post { + id String @id @default(cuid()) + title String @length(1, 256) + author User @relation(fields: [authorId], references: [id]) + authorId String +} +``` + +### [Prisma](https://prisma.io/orm)-Compatible Query API + +Although ZenStack has a completely different implementation (based on [Kysely](https://kysely.dev/)), it replicated Prisma ORM's query API so that you can use it pretty much as a drop-in replacement. Even if you're not a Prisma user, the query API is very intuitive and easy to learn. + +```ts +await db.user.findMany({ + where: { + email: { + endsWith: 'zenstack.dev', + }, + }, + orderBy: { + createdAt: 'desc', + }, + include: { posts: true } +}); +``` + +### Low-Level Query-Builder Powered by [Kysely](https://kysely.dev/) + +ORM APIs are concise and pleasant, but they have their limitations. When you need extra power, you can fall back to the low-level query builder API powered by [Kysely](https://kysely.dev/) - limitless expressiveness, full type safety, and zero extra setup. + +```ts +await db.$qb + .selectFrom('User') + .leftJoin('Post', 'Post.authorId', 'User.id') + .select(['User.id', 'User.email', 'Post.title']) + .execute(); +``` + +### Access Control + +ZenStack ORM comes with a powerful built-in access control system. You can define access rules right inside the schema. The rules are enforced at runtime via query injection, so it doesn't rely on any database specific row-level security features. + +```zmodel +model Post { + id String @id @default(cuid()) + title. String @length(1, 256) + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id]) + authorId String + + // no anonymous access + @@deny('all', auth() == null) + + // author has full access + @@allow('all', authorId == auth().id) + + // published posts are readable by anyone + @@allow('read', published) +} +``` + +### Polymorphic Models + +Real-world applications often involves storing polymorphic data which is notoriously complex to model and query. ZenStack does the heavy-lifting for you so you can model an inheritance hierarchy with simple annotations, and query them with perfect type safety. + +```zmodel +model Asset { + id String @id @default(cuid()) + title String @length(1, 256) + type String + + // the ORM uses the `type` field to determine to which concrete model + // a query should be delegated + @@delegate(type) +} + +model Post extends Asset { + content String +} +``` + +```ts +const asset = await db.asset.findFirst(); +if (asset.type === 'Post') { + // asset's type is narrowed down to `Post` + console.log(asset.content); +} else { + // other asset type +} +``` + +### Straightforward and Light-Weighted + +Compared to Prisma and previous versions of ZenStack, v3 is more straightforward and light-weighted. + +- No runtime dependency to Prisma, thus no overhead of Rust/WASM query engines. +- No magic generating into `node_modules`. You fully control how the generated code is compiled and bundled. +- Less code generation, more type inference. diff --git a/versioned_docs/version-3.x/orm/plugins/_category_.yml b/versioned_docs/version-3.x/orm/plugins/_category_.yml new file mode 100644 index 00000000..60e83429 --- /dev/null +++ b/versioned_docs/version-3.x/orm/plugins/_category_.yml @@ -0,0 +1,7 @@ +position: 12 +label: Plugins +collapsible: true +collapsed: true +link: + type: generated-index + title: Plugins diff --git a/versioned_docs/version-3.x/orm/plugins/introduction.md b/versioned_docs/version-3.x/orm/plugins/introduction.md new file mode 100644 index 00000000..8211aef1 --- /dev/null +++ b/versioned_docs/version-3.x/orm/plugins/introduction.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 1 +description: ORM plugin introduction +--- + +# Introduction to Plugins diff --git a/versioned_docs/version-3.x/orm/query-builder.md b/versioned_docs/version-3.x/orm/query-builder.md new file mode 100644 index 00000000..106b4ae4 --- /dev/null +++ b/versioned_docs/version-3.x/orm/query-builder.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 7 +description: Query builder API +--- + +# Query Builder API diff --git a/versioned_docs/version-3.x/orm/quick-start.mdx b/versioned_docs/version-3.x/orm/quick-start.mdx new file mode 100644 index 00000000..3ffcc406 --- /dev/null +++ b/versioned_docs/version-3.x/orm/quick-start.mdx @@ -0,0 +1,67 @@ +--- +sidebar_position: 2 +description: Quick start guide +--- + +import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import ZModelStarter from '../_components/_zmodel-starter.md'; +import PackageInstall from '../_components/PackageInstall.tsx'; +import PackageExec from '../_components/PackageExec.tsx'; + +# Quick Start + +:::info +All v3 packages are published under the "@next" tag. +::: + +There are multiple ways to start using ZenStack. + +## 1. Creating a project from scratch + +Run the following command to scaffold a new project with a pre-configured minimal starter: + +```bash +npm create zenstack@next my-project +``` + +Or simply use the following playground to experience it inside the browser. + + + +## 2. Adding to an existing project + +To add ZenStack to an existing project, run the CLI `init` command to install dependencies and create a sample schema: + + + +Then create a `zenstack/schema.zmodel` file in the root of your project. You can use the following sample schema to get started: + + + +Finally, run `zen generate` to compile the schema into TypeScript. + + + +## 3. Manual setup + +You can also always configure a project manually with the following steps: + +1. Install dependencies + + + +2. Create a `zenstack/schema.zmodel` file + + You can use the following sample schema to get started: + + + +3. Run the CLI `generate` command to compile the schema into TypeScript + + + +## 4. Custom schema and output paths + +By default, ZenStack CLI loads the schema from `zenstack/schema.zmodel`. You can change this by passing the `--schema` option. TypeScript files are by default generated to the same directory as the schema file. You can change this by passing the `--output` option. + +You can choose to either commit the generated TypeScript files to your source control, or add them to `.gitignore` and generate them on the fly in your CI/CD pipeline. diff --git a/versioned_docs/version-3.x/orm/ts-types.md b/versioned_docs/version-3.x/orm/ts-types.md new file mode 100644 index 00000000..9fd5432d --- /dev/null +++ b/versioned_docs/version-3.x/orm/ts-types.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 11 +description: TypeScript types derived from the ZModel schema +--- + +# TypeScript Types diff --git a/versioned_docs/version-3.x/orm/validation.md b/versioned_docs/version-3.x/orm/validation.md new file mode 100644 index 00000000..7d0fb918 --- /dev/null +++ b/versioned_docs/version-3.x/orm/validation.md @@ -0,0 +1,8 @@ +--- +sidebar_position: 9 +description: Data validation in ZModel +--- + +# Data Validation + + diff --git a/versioned_docs/version-3.x/orm/zmodel/_category_.yml b/versioned_docs/version-3.x/orm/zmodel/_category_.yml new file mode 100644 index 00000000..396fcc06 --- /dev/null +++ b/versioned_docs/version-3.x/orm/zmodel/_category_.yml @@ -0,0 +1,7 @@ +position: 3 +label: Writing Schema +collapsible: true +collapsed: true +link: + type: generated-index + title: Writing Schema diff --git a/versioned_docs/version-3.x/orm/zmodel/attributes.md b/versioned_docs/version-3.x/orm/zmodel/attributes.md new file mode 100644 index 00000000..be676265 --- /dev/null +++ b/versioned_docs/version-3.x/orm/zmodel/attributes.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 4 +description: Attributes in ZModel +--- + +# Attributes diff --git a/versioned_docs/version-3.x/orm/zmodel/builtin-types.md b/versioned_docs/version-3.x/orm/zmodel/builtin-types.md new file mode 100644 index 00000000..d3142702 --- /dev/null +++ b/versioned_docs/version-3.x/orm/zmodel/builtin-types.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 6 +description: Built-in types in ZModel +--- + +# Built-in Types diff --git a/versioned_docs/version-3.x/orm/zmodel/components.md b/versioned_docs/version-3.x/orm/zmodel/components.md new file mode 100644 index 00000000..b0635163 --- /dev/null +++ b/versioned_docs/version-3.x/orm/zmodel/components.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 1 +description: ZModel schema components +--- + +# Schema Components diff --git a/versioned_docs/version-3.x/orm/zmodel/custom-types.md b/versioned_docs/version-3.x/orm/zmodel/custom-types.md new file mode 100644 index 00000000..7208914f --- /dev/null +++ b/versioned_docs/version-3.x/orm/zmodel/custom-types.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 7 +description: Custom types in ZModel +--- + +# Custom Types diff --git a/versioned_docs/version-3.x/orm/zmodel/datasource.md b/versioned_docs/version-3.x/orm/zmodel/datasource.md new file mode 100644 index 00000000..3078fe6e --- /dev/null +++ b/versioned_docs/version-3.x/orm/zmodel/datasource.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 2 +description: Datasource in ZModel +--- + +# Data Source + diff --git a/versioned_docs/version-3.x/orm/zmodel/models.md b/versioned_docs/version-3.x/orm/zmodel/models.md new file mode 100644 index 00000000..f54ac510 --- /dev/null +++ b/versioned_docs/version-3.x/orm/zmodel/models.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 3 +description: Models in ZModel +--- + +# Models + diff --git a/versioned_docs/version-3.x/orm/zmodel/multi-file.md b/versioned_docs/version-3.x/orm/zmodel/multi-file.md new file mode 100644 index 00000000..81500291 --- /dev/null +++ b/versioned_docs/version-3.x/orm/zmodel/multi-file.md @@ -0,0 +1,9 @@ +--- +sidebar_position: 10 +description: Breaking down complex schemas into multiple files +--- + +# Multi-file Schemas + + + diff --git a/versioned_docs/version-3.x/orm/zmodel/polymorphism.md b/versioned_docs/version-3.x/orm/zmodel/polymorphism.md new file mode 100644 index 00000000..62c1797d --- /dev/null +++ b/versioned_docs/version-3.x/orm/zmodel/polymorphism.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 9 +description: Polymorphic models in ZModel +--- + +# Polymorphic Models + diff --git a/versioned_docs/version-3.x/orm/zmodel/relations.md b/versioned_docs/version-3.x/orm/zmodel/relations.md new file mode 100644 index 00000000..96794f67 --- /dev/null +++ b/versioned_docs/version-3.x/orm/zmodel/relations.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 5 +description: Relations in ZModel +--- + +# Relations diff --git a/versioned_docs/version-3.x/orm/zmodel/reusing-fields.md b/versioned_docs/version-3.x/orm/zmodel/reusing-fields.md new file mode 100644 index 00000000..eed27f91 --- /dev/null +++ b/versioned_docs/version-3.x/orm/zmodel/reusing-fields.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 8 +description: Reusing common fields across models in ZModel +--- + +# Reusing Common Fields + diff --git a/versioned_docs/version-3.x/recipes/_category_.yml b/versioned_docs/version-3.x/recipes/_category_.yml new file mode 100644 index 00000000..acb7bc3f --- /dev/null +++ b/versioned_docs/version-3.x/recipes/_category_.yml @@ -0,0 +1,7 @@ +position: 5 +label: Recipes +collapsible: true +collapsed: true +link: + type: generated-index + title: Recipes diff --git a/versioned_docs/version-3.x/reference/_category_.yml b/versioned_docs/version-3.x/reference/_category_.yml new file mode 100644 index 00000000..3e14b45e --- /dev/null +++ b/versioned_docs/version-3.x/reference/_category_.yml @@ -0,0 +1,7 @@ +position: 6 +label: Reference +collapsible: true +collapsed: true +link: + type: generated-index + title: Reference diff --git a/versioned_docs/version-3.x/reference/cli.md b/versioned_docs/version-3.x/reference/cli.md new file mode 100644 index 00000000..e6188f8b --- /dev/null +++ b/versioned_docs/version-3.x/reference/cli.md @@ -0,0 +1,251 @@ +--- +description: CLI references +sidebar_position: 2 +sidebar_label: CLI +--- + +# ZenStack CLI Reference + +## Usage + +``` +zenstack [options] [command] + +ΞΆ ZenStack is a Prisma power pack for building full-stack apps. + +Documentation: https://zenstack.dev. + +Options: + -v --version display CLI version + -h, --help display help for command + +Commands: + info [path] Get information of installed ZenStack and related packages. + init [options] [path] Initialize an existing project for ZenStack. + 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. + +```bash +zenstack init [options] [path] +``` + +#### Arguments + +| Name | Description | Default | +| ---- | ------------ | -------------- | +| path | Project path | current folder | + +#### Options + +| Name | Description | Default | +| --------------------- | ------------------------------------------------ | ----------------------------------------- | +| --prisma | location of Prisma schema file to bootstrap from | <project path>/prisma/schema.prisma | +| -p, --package-manager | package manager to use: "npm", "yarn", or "pnpm" | auto detect | +| --no-version-check | do not check for new versions of ZenStack | false | + +#### Examples + +Initialize current folder with default settings. + +```bash +npx zenstack init +``` + +Initialize "myapp" folder with custom package manager and schema location. + +```bash +npx zenstack init -p pnpm --prisma prisma/my.schema myapp +``` + +### generate + +Generates Prisma schema and other artifacts as specified by "plugin"s in ZModel. + +```bash +zenstack generate [options] +``` + +#### Arguments + +| Name | Description | Default | +| ---- | ------------ | -------------- | +| path | Project path | current folder | + +#### Options + +| Name | Description | Default | +| --------------------- | ------------------------------------------------ | ---------------------- | +| --schema | schema file (with extension .zmodel) | ./schema.zmodel | +| -o, --output <path> | 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 | + +You can also specify the ZModel schema location in the "package.json" file of your project like the following: + +```json title="package.json" +{ + "zenstack": { + "schema": "./db/schema.zmodel" + } +} +``` + +#### Examples + +Generate with default settings. + +```bash +npx zenstack generate +``` + +Generate with custom schema location. + +```bash +npx zenstack generate --schema src/my.zmodel +``` + +### repl + +Starts a REPL session. You should run the command inside the package where you ran `zenstack generate`. + +```bash +npx zenstack repl +``` + +You can call PrismaClient methods interactively in the REPL session. The following variables are available in the REPL session. + +- `prisma` + + The original PrismaClient instance (without ZenStack enhancement). + +- `db` + + The ZenStack enhanced PrismaClient instance. + +You don't need to `await` the Prisma method call result. The REPL session will automatically await and print the result. + +#### Options + +| Name | Description | Default | +| ----- | ------------------- | ------- | +| --debug | Enable debug output. Can be toggled on the fly in the repl session with the ".debug" command. | false | +| --table | Enable table format. Can be toggled on the fly in the repl session with the ".table" command. | false | +| --prisma-client <path> | Path to load PrismaClient module. | "node_modules/.prisma/client" | +| --load-path <path> | Path to load modules generated by ZenStack. | "node_modules/.zenstack" | + +#### Repl Commands + +You can use the following commands in the REPL session. + +- `.debug [on|off]` + + Toggle debug output. + +- `.table [on|off]` + + Toggle table format. + +- `.auth [user object]` + + Set current user. E.g.: `.auth { id: 1 }`. Run the command without argument to reset to anonymous user. + +#### Examples + +Start the session: +```bash +npx zenstack repl +``` + +Inside the session: +```ts +> prisma.user.findMany() +[ + { + id: '7aa301d2-7a29-4e1e-a041-822913a3ea78', + createdAt: 2023-09-05T04:04:43.793Z, + updatedAt: 2023-09-05T04:04:43.793Z, + email: 'yiming@whimslab.io', + ... + } +] + +> .auth { id: '7aa301d2-7a29-4e1e-a041-822913a3ea78' } +Auth user: { id: '7aa301d2-7a29-4e1e-a041-822913a3ea78' }. Use ".auth" to switch to anonymous. + +> .table +Table output: true + +> db.list.findMany({select: { title: true, private: true}}) +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ (index) β”‚ title β”‚ private β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ 0 β”‚ 'L1' β”‚ false β”‚ +β”‚ 1 β”‚ 'Wonderful new world' β”‚ false β”‚ +β”‚ 2 β”‚ 'Model for a space in which users can collaborate' β”‚ false β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +### format + +Format a ZenStack schema file. + +```bash +zenstack format [options] +``` + +#### Options + +| Name | Description | Default | +| --------------------- | ------------------------------------------------ | ---------------------- | +| --schema | schema file (with extension .zmodel) | ./schema.zmodel | + +You can also specify the ZModel schema location in the "package.json" file of your project like the following: + +```json title="package.json" +{ + "zenstack": { + "schema": "./db/schema.zmodel" + } +} +``` + +### check + +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 check [options] +``` + +#### Options + +| Name | Description | Default | +| --------------------- | ------------------------------------------------ | ---------------------- | +| --schema | schema file (with extension .zmodel) | ./schema.zmodel | diff --git a/versioned_docs/version-3.x/reference/error-handling.md b/versioned_docs/version-3.x/reference/error-handling.md new file mode 100644 index 00000000..07d31586 --- /dev/null +++ b/versioned_docs/version-3.x/reference/error-handling.md @@ -0,0 +1,43 @@ +--- +description: Error handling +sidebar_position: 8 +--- + +# Error Handling + +ZenStack's enhancements to Prisma clients are transparent proxies, so normal errors thrown from a Prisma client simply pass through, and you can handle them the same way as you do in a regular Prisma project. It's good to read these references from Prisma: + +- [Handling exceptions and errors](https://www.prisma.io/docs/concepts/components/prisma-client/handling-exceptions-and-errors) +- [Error message reference](https://www.prisma.io/docs/reference/api-reference/error-reference) + +The enhanced Prisma client can throw extra errors when an operation is rejected by [access policies](./zmodel-language#access-policy) or its data fails [validation rules](./zmodel-language#data-validation). To keep a consistent programming experience, a `PrismaClientKnownRequestError` is thrown with code [`P2004`](https://www.prisma.io/docs/reference/api-reference/error-reference#p2004) is used in such cases: + +```ts +throw new PrismaClientKnownRequestError(message, { + clientVersion: getVersion(), + code: 'P2004', + meta: ... +}); +``` + +The error contains a `meta` field providing more information about the error. It contains the following fields: + +- `reason` + + A string field indicating the detailed reason of the rejection. Its value can be one of the following: + + - *ACCESS_POLICY_VIOLATION* + + CRUD failed because of access policy violation. + + - *RESULT_NOT_READABLE* + + CRUD succeeded but the result was not readable (violating "read" access policies). + + - *DATA_VALIDATION_VIOLATION* + + CRUD failed because of a [data validation](./zmodel-language#data-validation) error. + +- `zodErrors` + + An object field containing the raw Zod validation errors. Only present if the `reason` is `DATA_VALIDATION_VIOLATION`. See [Zod documentation](https://zod.dev/?id=error-handling) for more details. diff --git a/versioned_docs/version-3.x/reference/limitations.md b/versioned_docs/version-3.x/reference/limitations.md new file mode 100644 index 00000000..96d02bc0 --- /dev/null +++ b/versioned_docs/version-3.x/reference/limitations.md @@ -0,0 +1,40 @@ +--- +description: Current limitations +sidebar_position: 100 +--- + +# Limitations + +This section lists the current limitations of ZenStack. + +### Sequential operations transaction + +[Sequential operations transaction](https://www.prisma.io/docs/concepts/components/prisma-client/transactions#sequential-prisma-client-operations) is not supported by enhanced Prisma clients yet. + +As a workaround, use [interactive transactions](https://www.prisma.io/docs/concepts/components/prisma-client/transactions#interactive-transactions) instead. + +### Minimum transaction isolation level + +To ensure access policies are properly enforced, the database's transaction isolation level should be set to at least [Repeatable Read](https://en.wikipedia.org/wiki/Isolation_(database_systems)#Repeatable_reads). This can be done by changing the settings of the database, or providing the `isolationLevel` option when creating `PrismaClient`: + +```ts +const prisma = new PrismaClient({ + transactionOptions: { + isolationLevel: Prisma.TransactionIsolationLevel.RepeatableRead, + }, +}); +``` + +If you don't want to change the global settings, alternatively you can set the `transactionIsolationLevel` option when calling ZenStack's `enhance` API. All the transactions initiated internally by ZenStack will use the specified isolation level. + +```ts +const db = enhance(prisma, { user }, { transactionIsolationLevel: 'RepeatableRead' }); +``` + +### MongoDB is not supported + +Right now, the focus of this project is SQL databases, and there's no plan to support MongoDB in the near future. + +### Cloudflare D1 database is not supported + +Prisma doesn't support interactive transactions with D1 databases. ZenStack relies on the feature to enforce access policies in certain cases. diff --git a/versioned_docs/version-3.x/reference/runtime-api.md b/versioned_docs/version-3.x/reference/runtime-api.md new file mode 100644 index 00000000..10d7cf39 --- /dev/null +++ b/versioned_docs/version-3.x/reference/runtime-api.md @@ -0,0 +1,130 @@ +--- +description: Runtime API references +sidebar_position: 3 +sidebar_label: Runtime API +--- + +# Runtime API Reference + +This document provides references for runtime APIs exported from the `@zenstackhq/runtime` package. + +### enhance + +#### Description + +Creates an enhanced wrapper for a `PrismaClient`. The return value has the same APIs as the original `PrismaClient`. + +#### Signature + +```ts +function enhance( + prisma: DbClient, + context?: EnhancementContext, + options?: EnhancementOptions +): DbClient; +``` + +##### Parameter `prisma` + +The PrismaClient instance to enhance. + +##### Parameter `context` + +The context to for evaluating access policies with the following typing. + +```ts +type EnhancementContext = { + user?: Record +}; +``` + +| Field | Description | +| ----- | ----------- | +| user | The user object that provides value for the `auth()` function call in access policies. If provided. Its shape should be consistent with the `User` model in your ZModel, with all fields optional except for id field(s). Pass `undefined` to represent an anonymous user, and the `auth()` function call will evaluate to `null` in that case. | + +##### Parameter `options` + +Options with the following typing. + +```ts +type TransactionIsolationLevel = + | 'ReadUncommitted' + | 'ReadCommitted' + | 'RepeatableRead' + | 'Snapshot' + | 'Serializable'; + +type SimpleEncryption = { + encryptionKey: Uint8Array; + decryptionKeys?: Uint8Array[]; +} + +type CustomEncryption = { + encrypt: (model: string, field: FieldInfo, plain: string) => Promise; + decrypt: (model: string, field: FieldInfo, cipher: string) => Promise; +}; + +type ValidationOptions = { + inputOnlyValidationForUpdate?: boolean; +}; + +type EnhancementOptions = { + kinds?: EnhancementKind[]; + logPrismaQuery?: boolean; + errorTransformer?: ErrorTransformer; + transactionMaxWait?: number; + transactionTimeout?: number; + transactionIsolationLevel?: TransactionIsolationLevel; + encryption?: SimpleEncryption | CustomEncryption; + validation?: ValidationOptions; +}; +``` + +| Field | Description | Default | +| ------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------- | +| kinds | The kinds of enhancements to apply. By default all enhancements are applied. See [the next section](#enhancement-kinds) for more details. | All enhancement kinds | +| logPrismaQuery | Whether to log queries sent to Prisma client. Log will be emitted with "info" level, so please make sure you [turn that level on](https://www.prisma.io/docs/concepts/components/prisma-client/working-with-prismaclient/logging#log-to-stdout) when creating Prisma client | false | +| errorTransformer | A function for transforming error thrown by the enhanced `PrismaClient` into a custom one. | | +| transactionMaxWait | The `maxWait` option (in ms) passed to `prisma.$transaction()` call for transactions initiated by ZenStack. | Database default | +| transactionTimeout | The `timeout` option (in ms) passed to `prisma.$transaction()` call for transactions initiated by ZenStack. | Database default | +| transactionIsolationLevel | The `isolationLevel` option passed to `prisma.$transaction()` call for transactions initiated by ZenStack. | Database default | +| encryption | Field encryption settings. Only required when using the [field encryption](../guides/field-encryption.md) feature. | | +| validation.inputOnlyValidationForUpdate | By default, ZenStack validates an entity after "update" operation to ensure the final result satisfies validation rules as a whole. This implies if the record under update doesn't satisfy the rules prior to update, the update operation will fail even if the fields causing validation errors are not affected by the operation. You can set this option to `true` to let ZenStack only validate data contained in the input args. | false | + +#### Enhancement Kinds + +Here are the kinds of enhancements available: + +- `policy` + + Enforces model-level and field-level access policies defined with `@@allow`, `@@deny`, `@allow`, and `@deny`. + +- `validation` + + Validates create and update input data against rules defined with [data validation attributes](../reference/zmodel-language#data-validation). + +- `delegate` + + Support for modeling [polymorphic relations](../guides/polymorphism) with delegated types pattern. + +- `password` + + Automatically hashes fields marked with the `@password` attribute using `bcryptjs` before saving to the database. + +- `omit` + + Automatically omits fields marked with the `@omit` attribute from read results. + +- `encryption` + + Transparently encrypt and decrypt fields marked with the `@encrypted` attribute. See [this guide](../guides/field-encryption.md) for more details. + +#### Example + +```ts +const session = getSession(); +const enhancedClient = enhance(prisma, + { user: session.user }, + { kinds: ['policy', 'password']} +); +``` diff --git a/versioned_docs/version-3.x/reference/server-adapters/_category_.yml b/versioned_docs/version-3.x/reference/server-adapters/_category_.yml new file mode 100644 index 00000000..f6e05f3e --- /dev/null +++ b/versioned_docs/version-3.x/reference/server-adapters/_category_.yml @@ -0,0 +1,7 @@ +position: 7 +label: Server Adapters +collapsible: true +collapsed: true +link: + type: generated-index + title: Server Adapters diff --git a/versioned_docs/version-3.x/reference/server-adapters/_error-handling.md b/versioned_docs/version-3.x/reference/server-adapters/_error-handling.md new file mode 100644 index 00000000..db2a9b05 --- /dev/null +++ b/versioned_docs/version-3.x/reference/server-adapters/_error-handling.md @@ -0,0 +1,3 @@ +### Error Handling + +Refer to the specific sections for [RPC Handler](./api-handlers/rpc#http-status-code-and-error-responses) and [RESTful Handler](./api-handlers/rest#error-handling). diff --git a/versioned_docs/version-3.x/reference/server-adapters/_options.mdx b/versioned_docs/version-3.x/reference/server-adapters/_options.mdx new file mode 100644 index 00000000..dee02d69 --- /dev/null +++ b/versioned_docs/version-3.x/reference/server-adapters/_options.mdx @@ -0,0 +1,66 @@ +import CodeBlock from '@theme/CodeBlock'; + +- getPrisma (required) + +
{props.getPrisma}
+ + A callback for getting a PrismaClient instance for talking to the database. Usually you'll use an enhanced instance created with ZenStack's [`enhance`](../runtime-api#enhance) API to ensure access policies are enforced. + +- logger (optional) + +
{'LoggerConfig'}
+ + Configuration for customizing logging behavior. + +- modelMeta (optional) + +
{'ModelMeta'}
+ + Model metadata. By default loaded from the `node_module/.zenstack/model-meta` module. You can pass it in explicitly if you configured ZenStack to output to a different location. E.g.: `require('output/model-meta').default`. + +- zodSchemas (optional) + +
{'ModelZodSchema | boolean | undefined'}
+ + Provides the Zod schemas used for validating CRUD request input. The Zod schemas can be generated with the `@core/zod` plugin. Pass `true` for this option to load the schemas from the default location. If you configured `@core/zod` plugin to output to a custom location, you can load the schemas explicitly and pass the loaded module to this option. E.g.: + + ```ts + factory({ + ... + zodSchemas: require('./zod'), + }); + ``` + + Not passing this option or passing in `undefined` disables input validation. + +- handler (optional) + +
{'(req: RequestContext) => Promise'}
+ + The request handler function. This option determines the API endpoints and its input and output formats. Currently ZenStack supports two styles of APIs: RPC (the default) and RESTful. + + - RPC + + The goal of the RPC-style API handler is to fully mirror [PrismaClient's API](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#model-queries) across the network, so that developers can continue enjoying the convenience and flexibility of Prisma's query syntax. This is the default choice for the `handler` option. + + The RPC-style handler can be created like: + + ```ts + import { RPCApiHandler } from '@zenstackhq/server/api'; + const handler = RPCApiHandler(); + ``` + + For more details, please check out [RPC API Handler](./api-handlers/rpc). + + - RESTful + + The goal of RESTful-style API handler is to provide a resource-centric RESTful API using [JSON:API](https://jsonapi.org/) as transportation format. + + The RESTful-style handler can be created like: + + ```ts + import { RestApiHandler } from '@zenstackhq/server/api'; + const handler = RestApiHandler({ endpoint: 'http://myhost/api' }); + ``` + + For more details, please check out [RESTful API Handler](./api-handlers/rest). diff --git a/versioned_docs/version-3.x/reference/server-adapters/_using-api.mdx b/versioned_docs/version-3.x/reference/server-adapters/_using-api.mdx new file mode 100644 index 00000000..1d16241c --- /dev/null +++ b/versioned_docs/version-3.x/reference/server-adapters/_using-api.mdx @@ -0,0 +1,137 @@ +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +The APIs can be used in the following three ways: + +1. With generated client hooks + + ZenStack provides plugins to generate client hooks from the ZModel targeting the most popular frontend data fetching libraries: [TanStack Query](https://tanstack.com/query/latest) and [SWR](https://swr.vercel.app/). The generated hooks can be used to make API calls to the server adapters. Refer to the follow docs for detailed usage: + + - [`@zenstackhq/tanstack-query`](../plugins/tanstack-query) + - [`@zenstackhq/swr`](../plugins/swr) +

+ + :::info + The generated client hooks assumes the server adapter uses [RPC-style API handler](./api-handlers/rpc) (which is the default setting). + ::: + +1. With direct HTTP calls + + You can make direct HTTP calls to the server adapter using your favorite client libraries like `fetch` or `axios`. Refer to the documentation of the [API Handlers](./api-handlers/) for the API endpoints and data formats. + + Here's an example using `fetch`: + + + + + ```ts + // create a user with two posts + const r = await fetch(`/api/user/create`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + include: { posts: true }, + data: { + email: 'user1@abc.com', + posts: { + create: [{ title: 'Post 1' }, { title: 'Post 2' }], + }, + }, + }), + }); + + console.log(await r.json()); + ``` + + Output: + + ```json + { + "id": 1, + "email": "user1@abc.com", + "posts": [ + { + "id": 1, + "createdAt": "2023-03-14T07:45:04.036Z", + "updatedAt": "2023-03-14T07:45:04.036Z", + "title": "Post 1", + "authorId": 1 + }, + { + "id": 2, + "createdAt": "2023-03-14T07:45:04.036Z", + "updatedAt": "2023-03-14T07:45:04.036Z", + "title": "Post 2", + "authorId": 1 + } + ] + } + ``` + + + + + + ```ts + // create a user and attach two posts + const r = await fetch(`/api/user`, { + method: 'POST', + headers: { 'Content-Type': 'application/vnd.api+json' }, + body: JSON.stringify({ + data: { + type: 'user', + attributes: { + email: 'user1@abc.com' + }, + relationships: { + posts: { + data: [ + { type: 'post', id: 1 }, + { type: 'post', id: 2 } + ] + } + } + } + }) + }); + + console.log(await r.json()); + ``` + + Output: + + ```json + { + "jsonapi": { "version": "1.1" }, + "data": { + "type": "user", + "id": 1, + "attributes": { + "email": "user1@abc.com", + }, + "links": { + "self": "http://localhost/api/user/1", + }, + "relationships": { + "posts": { + "links": { + "self": "http://localhost/api/user/1/relationships/posts", + "related": "http://localhost/api/user/1/posts", + }, + "data": [ + { "type": "post", "id": 1 }, + { "type": "post", "id": 2 }, + ], + }, + }, + }, + } + ``` + + + + + +1. With third-party client generators + + ZenStack provides an [OpenAPI](../plugins/openapi) plugin for generating Open API 3.x specification from the ZModel. The generated OpenAPI spec can be used to generate client libraries for various languages and frameworks. For example, you can use [openapi-typescript](https://github.com/drwpow/openapi-typescript) to generate a typescript client. diff --git a/versioned_docs/version-3.x/reference/server-adapters/api-handlers/_data_type_serialization.md b/versioned_docs/version-3.x/reference/server-adapters/api-handlers/_data_type_serialization.md new file mode 100644 index 00000000..d22a602f --- /dev/null +++ b/versioned_docs/version-3.x/reference/server-adapters/api-handlers/_data_type_serialization.md @@ -0,0 +1,16 @@ +- `DateTime` + + ISO 8601 string + +- `Bytes` + + Base64-encoded string + +- `BigInt` + + String representation + +- `Decimal` + + String representation + \ No newline at end of file diff --git a/versioned_docs/version-3.x/reference/server-adapters/api-handlers/index.mdx b/versioned_docs/version-3.x/reference/server-adapters/api-handlers/index.mdx new file mode 100644 index 00000000..df4074ec --- /dev/null +++ b/versioned_docs/version-3.x/reference/server-adapters/api-handlers/index.mdx @@ -0,0 +1,31 @@ +--- +sidebar_position: 100 +--- + +import useBaseUrl from '@docusaurus/useBaseUrl'; +import ThemedImage from '@theme/ThemedImage'; + +# API Handlers + +ZenStack supports two API styles: ***rpc*** and ***rest***: + +- ***rpc*** style API directly mirrors Prisma client's API, thus provides endpoints like `[model]/findMany`, `[model]/create`, etc. Its input and output data format also aligns with that of Prisma client. + +- ***rest*** style API is designed to be more RESTful, thus provides endpoints like `[model]`, `[model]/[id]`, `[model]/[id]/relationships/[relationship]`, etc. It uses [JSON:API](https://jsonapi.org/) as its data format. + +API handlers are framework-agnostic and deals with canonicalized request and response objects. It's the responsibility of the server adapters to translate the framework-specific request and response types. You can use either of these two API handlers with any server adapter. + +The following diagram illustrates their relationships with server adapters. + + + +Checkout the reference pages for detailed information about these API handlers: + +- [RPC API Handler](./rpc) +- [RESTful API Handler](./rest) diff --git a/versioned_docs/version-3.x/reference/server-adapters/api-handlers/rest.mdx b/versioned_docs/version-3.x/reference/server-adapters/api-handlers/rest.mdx new file mode 100644 index 00000000..67365c6f --- /dev/null +++ b/versioned_docs/version-3.x/reference/server-adapters/api-handlers/rest.mdx @@ -0,0 +1,982 @@ +--- +description: RESTful-style API handler that provides resource-centric endpoints +sidebar_position: 2 +title: RESTful API Handler +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import DataTypeSerialization from './_data_type_serialization.md'; + +# RESTful API Handler + +## Introduction + +The RESTful-style API handler exposes CRUD APIs as RESTful endpoints using [JSON:API](https://jsonapi.org/) as transportation format. The API handler is not meant to be used directly; instead, you should use it together with a [server adapter](../../../category/server-adapters) which handles the request and response API for a specific framework. + +It can be created as the following: + + + + +```ts title='/src/app/api/model/[...path]/route.ts' +import { NextRequestHandler } from '@zenstackhq/server/next'; +import { RestApiHandler } from '@zenstackhq/server/api'; +import { getPrisma } from '~/lib/db'; + +const handler = NextRequestHandler({ + getPrisma, + useAppDir: true, + handler: RestApiHandler({ endpoint: 'http://myhost/api' }) +}); + +export { + handler as GET, + handler as POST, + handler as PUT, + handler as PATCH, + handler as DELETE, +}; +``` + + + + + +```ts title='/src/hooks.server.ts' +import { SvelteKitHandler } from '@zenstackhq/server/sveltekit'; +import { RestApiHandler } from '@zenstackhq/server/api'; +import { getPrisma } from './lib/db'; + +export const handle = SvelteKitHandler({ + prefix: '/api/model', + getPrisma, + handler: RestApiHandler({ endpoint: 'http://myhost/api/model' }) +}); +``` + + + + + +```ts title='/server/api/model/[...].ts' +import { createEventHandler } from '@zenstackhq/server/nuxt'; +import { RestApiHandler } from '@zenstackhq/server/api'; +import { getPrisma } from './lib/db'; + +export default createEventHandler({ + handler: RestApiHandler({ endpoint: 'http://myhost/api/model' }) + getPrisma +}); +``` + + + + + +The factory function accepts an options object with the following fields: + +- endpoint + + Required. A `string` field representing the base URL of the RESTful API, used for generating resource links. + +- pageSize + + Optional. A `number` field representing the default page size for listing resources and relationships. Defaults to 100. Set to Infinity to disable pagination. + +- modelNameMapping + + Optional. An `Record` value that provides a mapping from model names (as defined in ZModel) to URL path names. This is useful for example when you want to use plural names in URL endpoints: + + ```ts + // endpoint for accessing User model will then be ".../users" + RestApiHandler({ + modelNameMapping: { + User: 'users' + } + }) + ``` + + The mapping can be partial. You only need to specify the model names that you want to override. If a mapping is provided, only the mapped url path is valid, and accessing to unmapped path will be denied. + + +## Endpoints and Features + +The RESTful API handler conforms to the the [JSON:API](https://jsonapi.org/format/) v1.1 specification for its URL design and input/output format. The following sections list the endpoints and features are implemented. The examples refer to the following schema modeling a blogging app: + +```zmodel +model User { + id Int @id @default(autoincrement()) + email String + posts Post[] +} + +model Profile { + id Int @id @default(autoincrement()) + gender String + user User @relation(fields: [userId], references: [id]) + userId Int @unique +} + +model Post { + id Int @id @default(autoincrement()) + title String + published Boolean @default(false) + viewCount Int @default(0) + author User @relation(fields: [authorId], references: [id]) + authorId Int + comments Comment[] +} + +model Comment { + id Int @id @default(autoincrement()) + content String + post Post @relation(fields: [postId], references: [id]) + postId Int +} +``` + +### Listing resources + +A specific type of resource can be listed using the following endpoint: + +``` +GET /:type +``` + +#### Status codes + +- 200: The request was successful and the response body contains the requested resources. +- 400: The request was malformed. +- 403: The request was forbidden. +- 404: The requested resource type does not exist. +- 422: The request violated data validation rules. + +#### Examples + +```ts +GET /post +``` + +```json +{ + "meta": { + "total": 1 + }, + "data": [ + { + "attributes": { + "authorId": 1, + "published": true, + "title": "My Awesome Post", + "viewCount": 0 + }, + "id": 1, + "links": { + "self": "http://myhost/api/post/1" + }, + "relationships": { + "author": { + "data": { "id": 1, "type": "user" }, + "links": { + "related": "http://myhost/api/post/1/author/1", + "self": "http://myhost/api/post/1/relationships/author/1" + } + } + }, + "type": "post" + } + ], + "jsonapi": { + "version": "1.1" + }, + "links": { + "first": "http://myhost/api/post?page%5Blimit%5D=100", + "last": "http://myhost/api/post?page%5Boffset%5D=0", + "next": null, + "prev": null, + "self": "http://myhost/api/post" + } +} +``` + +### Fetching a resource + +A unique resource can be fetched using the following endpoint: + +```ts +GET /:type/:id +``` + +#### Status codes + +- 200: The request was successful and the response body contains the requested resource. +- 400: The request was malformed. +- 403: The request was forbidden. +- 404: The requested resource type or ID does not exist. + +#### Examples + +```ts +GET /post/1 +``` + +```json +{ + "data": { + "attributes": { + "authorId": 1, + "published": true, + "title": "My Awesome Post", + "viewCount": 0 + }, + "id": 1, + "links": { + "self": "http://myhost/api/post/1" + }, + "relationships": { + "author": { + "data": { "id": 1, "type": "user" }, + "links": { + "related": "http://myhost/api/post/1/author/1", + "self": "http://myhost/api/post/1/relationships/author/1" + } + } + }, + "type": "post" + }, + "jsonapi": { + "version": "1.1" + }, + "links": { + "self": "http://myhost/api/post/1" + } +} +``` + +### Fetching relationships + +A resource's relationships can be fetched using the following endpoint: + +```ts +GET /:type/:id/relationships/:relationship +``` + +#### Status codes + +- 200: The request was successful and the response body contains the requested relationships. +- 400: The request was malformed. +- 403: The request was forbidden. +- 404: The requested resource type, ID, or relationship does not exist. + +#### Examples + +1. Fetching a to-one relationship + + ```ts + GET /post/1/relationships/author + ``` + + ```json + { + "data" : { "id" : 1, "type" : "user" }, + "jsonapi" : { + "version" : "1.1" + }, + "links" : { + "self" : "http://myhost/api/post/1/relationships/author" + } + } + ``` + +1. Fetching a to-many relationship + + ```ts + GET /user/1/relationships/posts + ``` + + ```json + { + "data" : [ + { "id" : 1, "type" : "post" }, + { "id" : 2, "type" : "post" } + ], + "jsonapi" : { + "version" : "1.1" + }, + "links" : { + "first" : "http://myhost/api/user/1/relationships/posts?page%5Blimit%5D=100", + "last" : "http://myhost/api/user/1/relationships/posts?page%5Boffset%5D=0", + "next" : null, + "prev" : null, + "self" : "http://myhost/api/user/1/relationships/posts" + } + } + ``` + +### Fetching related resources + +```ts +GET /:type/:id/:relationship +``` + +#### Status codes + +- 200: The request was successful and the response body contains the requested relationship. +- 400: The request was malformed. +- 403: The request was forbidden. +- 404: The requested resource type, ID, or relationship does not exist. + +#### Examples + +```ts +GET /post/1/author +``` + +```json +{ + "data" : { + "attributes" : { + "email" : "emily@zenstack.dev", + "name" : "Emily" + }, + "id" : 1, + "links" : { + "self" : "http://myhost/api/user/1" + }, + "relationships" : { + "posts" : { + "links" : { + "related" : "http://myhost/api/user/1/posts", + "self" : "http://myhost/api/user/1/relationships/posts" + } + } + }, + "type" : "user" + }, + "jsonapi" : { + "version" : "1.1" + }, + "links" : { + "self" : "http://myhost/api/post/1/author" + } +} +``` + +### Fine-grained data fetching + +#### Filtering + +You can use the `filter[:selector1][:selector2][...]=value` [query parameter family](https://jsonapi.org/format/#query-parameters-families) to filter resource collections or relationship collections. + +##### Examples + +1. Equality filter against plain field + + ```ts + GET /api/post?filter[published]=false + ``` + +1. Equality filter against relationship + + Relationship field can be filtered directly by its id. + + ```ts + GET /api/post?filter[author]=1 + ``` + + If the relationship is to-many, the filter has "some" semantic and evaluates to `true` if any of the items in the relationship matches. + + ```ts + GET /api/user?filter[posts]=1 + ``` + +1. Filtering with multiple values + + Multiple filter values can be separated by comma. Items statisfying any of the values will be returned. + + ```ts + GET /api/post?filter[author]=1,2 + ``` + +1. Multiple filters + + A request can carry multiple filters. Only items statisfying all filters will be returned. + + ```ts + GET /api/post?filter[author]=1&filter[published]=true + ``` + +1. Deep filtering + + A filter can carry multiple field selectors to reach into relationships. + + ```ts + GET /api/post?filter[author][name]=Emily + ``` + + When reaching into a to-many relationship, the filter has "some" semantic and evaluates to `true` if any of the items in the relationship matches. + + ``` + GET /api/user?filter[posts][published]=true + ``` + +1. Filtering with comparison operators + + Filters can go beyond equality by appending an "operator suffix". + + ```ts + GET /api/post?filter[viewCount$gt]=100 + ``` + + The following operators are supported: + + - **$lt** + + Less than + + - **$lte** + + Less than or equal to + + - **$gt** + + Greater than + + - **$gte** + + Greater than or equal to + + - **$contains** + + String contains + + - **$icontains** + + Case-insensitive string contains + + - **$search** + + String full-text search + + - **$startsWith** + + String starts with + + - **$endsWith** + + String ends with + + - **$has** + + Collection has value + + - **$hasEvery** + + Collection has every element in value + + - **$hasSome** + + Collection has some elements in value + + - **$isEmpty** + + Collection is empty + +#### Sorting + +You can use the `sort` query parameter to sort resource collections or relationship collections. The value of the parameter is a comma-separated list of fields names. The order of the fields in the list determines the order of sorting. By default, sorting is done in ascending order. To sort in descending order, prefix the field name with a minus sign. + +##### Examples + +```ts +GET /api/post?sort=createdAt,-viewCount +``` + +#### Pagination + +When creating a RESTful API handler, you can pass in a `pageSize` option to control pagination behavior of fetching a collection of resources, related resources, and relationships. By default the page size is 100, and you can disable pagination by setting `pageSize` option to `Infinity`. + +When fetching a collection resource or relationship, you can use the `page[offset]=value` and `page[limit]=value` [query parameter family](https://jsonapi.org/format/#query-parameters-families) to fetch a specific page. They're mapped to `skip` and `take` parameters in the query arguments sent to PrismaClient. + +The response data of collection fetching contains pagination links that facilitate navigating through the collection. The "meta" section also contains the total count available. E.g.: + +```json +{ + "meta": { + "total": 10 + }, + "data" : [ + ... + ], + "links" : { + "first" : "http://myhost/api/post?page%5Blimit%5D=2", + "last" : "http://myhost/api/post?page%5Boffset%5D=4", + "next" : "http://myhost/api/post?page%5Boffset%5D=4&page%5Blimit%5D=2", + "prev" : "http://myhost/api/post?page%5Boffset%5D=0&page%5Blimit%5D=2", + "self" : "http://myhost/api/post" + } +} +``` + +##### Examples + +1. Fetching a specific page of resources + + ```ts + GET /api/post?page[offset]=10&page[limit]=5 + ``` + +1. Fetching a specific page of relationships + + ```ts + GET /api/user/1/relationships/posts?page[offset]=10&page[limit]=5 + ``` + +1. Fetching a specific page of related resources + + ```ts + GET /api/user/1/posts?page[offset]=10&page[limit]=5 + ``` + +#### Including related resources + +You can use the `include` query parameter to include related resources in the response. The value of the parameter is a comma-separated list of fields names. Field names can contain dots to reach into nested relationships. + +When including related resources, the response data takes the form of [Compound Documents](https://jsonapi.org/format/#document-compound-documents) and contains a `included` field carrying normalized related resources. E.g.: + +```json +{ + "data" : [ + { + "attributes" : { + ... + }, + "id" : 1, + "relationships" : { + "author" : { + "data" : { "id" : 1, "type" : "user" } + } + }, + "type" : "post" + } + ], + "included" : [ + { + "attributes" : { + "email" : "emily@zenstack.dev", + "name" : "Emily" + }, + "id" : 1, + "links" : { + "self" : "http://myhost/api/user/1" + }, + "relationships" : { + "posts" : { + "links" : { + "related" : "http://myhost/api/user/1/posts", + "self" : "http://myhost/api/user/1/relationships/posts" + } + } + }, + "type" : "user" + } + ] +} +``` + +##### Examples + +1. Including a direct relationship + + ```ts + GET /api/post?include=author + ``` + +1. Including a deep relationship + + ```ts + GET /api/post?include=author.profile + ``` + +1. Including multiple relationships + + ```ts + GET /api/post?include=author,comments + ``` + +### Creating a resource + +A new resource can be created using the following endpoint: + +``` +POST /:type +``` + +#### Status codes + +- 201: The request was successful and the resource was created. +- 400: The request was malformed. +- 403: The request was forbidden. +- 404: The requested resource type does not exist. + +#### Examples + +1. Creating a resource + ```json + POST /user + { + "data": { + "type": "user", + "attributes": { + "name": "Emily", + "email": "emily@zenstack.dev" + } + } + } + ``` + +1. Creating a resource with relationships attached + + ```json + POST /user + { + "data": { + "type": "user", + "attributes": { + "name": "Emily", + "email": "emily@zenstack.dev" + }, + "relationships": { + "posts": { + "data": [{ "type": "post", "id": 1 }] + } + } + } + } + ``` + +### Updating a resource + +A resource can be updated using the following endpoints: + +```ts +PUT /:type/:id +PATCH /:type/:id +``` + +Both `PUT` and `PATCH` do partial update and has exactly the same behavior. + +:::info +Besides plain fields, you can also include relationships in the request body. Please note that this won't update the related resource; instead if only replaces the relationships. If you update a to-many relationship, the new collection will entirely replace the old one. + +Relationships can also be manipulated directly. See [Manipulating Relationships](#manipulating-relationships) for more details. +::: + +#### Status codes + +- 200: The request was successful and the resource was updated. +- 400: The request was malformed. +- 403: The request was forbidden. +- 404: The requested resource type or ID does not exist. + +#### Examples + +1. Updating a resource + + ```json + PUT /post/1 + { + "data": { + "type": "post", + "attributes": { + "title": "My Awesome Post" + } + } + } + ``` + +1. Updating a resource's relationships + + ```json + PUT /user/1 + { + "data": { + "type": "user", + "relationships": { + "posts": { + "data": [{ "type": "post", "id": 2 }] + } + } + } + } + ``` + + +### Upserting a resource + +JSON:API didn't specify a convention for "upsert" operations. ZenStack uses a variation of the "create" operation to represent "upsert", and uses the request meta to indicate the intention. See details in [examples](#examples-10). + +``` +POST /:type +``` + +#### Status codes + +- 201: The request was successful and the resource was created. +- 200: The request was successful and the resource was updated. +- 400: The request was malformed. +- 403: The request was forbidden. +- 404: The requested resource type does not exist. + +#### Examples + +```json +POST /user +{ + "data": { + "type": "user", + "attributes": { + "id": 1, + "name": "Emily", + "email": "emily@zenstack.dev" + } + }, + "meta": { + "operation": "upsert", + "matchFields": ["id"], + } +} +``` + +The `meta.operation` field must be "upsert", and the `meta.matchFields` field must be an array of field names that are used to determine if the resource already exists. If an existing resource is found, "update" operation is conducted, otherwise "create". The `meta.matchFields` fields must be unique fields, and they must have corresponding entries in `data.attributes`. + +### Deleting a resource + +A resource can be deleted using the following endpoint: + +#### Status codes + +- 204: The request was successful and the resource was deleted. +- 403: The request was forbidden. +- 404: The requested resource type or ID does not exist. + +```ts +DELETE /:type/:id +``` + +### Manipulating relationships + +Relationships can be manipulated using the following endpoints: + +#### Adding to a to-many relationship + +```ts +POST /:type/:id/relationships/:relationship +``` + +##### Status codes + +- 200: The request was successful and the relationship was updated. +- 403: The request was forbidden. +- 404: The requested resource type, ID, or relationship does not exist. + +##### Examples + +```json +POST /user/1/relationships/posts +{ + "data": [ + { "type": "post", "id": "1" }, + { "type": "post", "id": "2" } + ] +} +``` + +#### Updating a relationship (to-one or to-many) + +```ts +PUT /:type/:id/relationships/:relationship +PATCH /:type/:id/relationships/:relationship +``` + +:::info +`PUT` and `PATCH` has exactly the same behavior and both relace the existing relationships with the new ones entirely. +::: + +##### Status codes + +- 200: The request was successful and the relationship was updated. +- 403: The request was forbidden. +- 404: The requested resource type, ID, or relationship does not exist. + +##### Examples + +1. Replacing a to-many relationship + + ```json + PUT /user/1/relationships/posts + { + "data": [ + { "type": "post", "id": "1" }, + { "type": "post", "id": "2" } + ] + } + ``` + +1. Replacing a to-one relationship + + ```json + PUT /post/1/relationships/author + { + "data": { "type": "user", "id": "2" } + } + ``` + +1. Clearing a to-many relationship + + ```json + PUT /user/1/relationships/posts + { + "data": [] + } + ``` + +1. Clearing a to-one relationship + + ```json + PUT /post/1/relationships/author + { + "data": null + } + ``` + +## Compound ID Fields + +Prisma allows a model to have compound ID fields, e.g.: + +```zmodel +model Post { + id1 Int + id2 Int + @@id([id1, id2]) +} +``` + +The JSON:API specification doesn't have a native way to represent compound IDs. To mitigate this limitation, when returning an entity with compound IDs, ZenStack synthesizes an "id" field to carry the ID values joined with underscore: + +```json +{ + "data": { + "id": "1_2", + "attributes": { + "id1": 1, + "id2": 2, + ... + }, + "links" : { + "self" : "http://localhost:3100/api/model/post/1_2" + }, + ... + } +} +``` + +You can use this ID value convension in places where an ID is needed, e.g., reading a single entity. + +```ts +GET /post/1_2 +``` + +Limitations: + +1. Joining ID values with underscore implies that the ID values themselves cannot contain underscores. We'll make the separator configurable in the future. +1. Prisma allows you to create a name for the compound ID field. Such usage is not yet supported by the RESTful API handler. + +> *Special thanks to [Thomas Sunde Nielsen](https://github.com/thomassnielsen) for implementing this feature!* + +## Serialization + +ZenStack uses [superjson](https://github.com/blitz-js/superjson) to serialize and deserialize data. Superjson generates two parts during serialization: + +- json: + + The JSON-compatible serialization result. + +- meta: + + The serialization metadata including information like field types that facilitates deserialization. + +If the data only involves simple data types, the serialization result is the same as regular `JSON.stringify`, and no `meta` part is generated. However, for complex data types (like `Bytes`, `Decimal`, etc.), a `meta` object will be generated, which needs to be carried along when sending the request, and will also be included in the response. + +When sending requests, if superjson-serializing the request body results in a `meta` object, it should be put into a ```{ "serialization": meta }``` object and included in the `meta` field of the request body. For example, if you have a `bytes` field of type `Bytes`, the request body should look like: + +```json +POST /post +{ + "data": { + "type": "post", + "attributes": { + ... + "bytes": "AQID" // base64-encoded bytes + } + }, + "meta": { + "serialization": {"values": { "data.attributes.bytes": [[ "custom", "Bytes"]] } } + } +} +``` + +Correspondingly, the response body of a query may look like: + +```json +GET /post/1 +{ + "data": { + "id": "1", + "type": "post", + "attributes": { + ... + "bytes": "AQID" // base64-encoded bytes + } + }, + "meta": { + "serialization": {"values": { "data.attributes.bytes": [[ "custom", "Bytes"]] } } + } +} +``` + +You should use the `meta.serialization` field value to superjson-deserialize the response body. + +### Data Type Serialization Format + + + +## Error Handling + +An error response is an object containing the following fields: + +- errors + + An array of error objects, each containing the following fields: + + - code: `string`, error code + - status: `number`, HTTP status code + - title: `string`, error title + - detail: `string`, error detail + - prismaCode: `string`, Prisma error code, if the error is thrown by Prisma + +### Example + +```json +{ + "errors" : [ + { + "code" : "unsupported-model", + "detail" : "Model foo doesn't exist", + "status" : 404, + "title" : "Unsupported model type" + } + ] +} +``` diff --git a/versioned_docs/version-3.x/reference/server-adapters/api-handlers/rpc.mdx b/versioned_docs/version-3.x/reference/server-adapters/api-handlers/rpc.mdx new file mode 100644 index 00000000..ecfd1c96 --- /dev/null +++ b/versioned_docs/version-3.x/reference/server-adapters/api-handlers/rpc.mdx @@ -0,0 +1,275 @@ +--- +description: RPC-style API handler that fully mirrors PrismaClient's query API +sidebar_position: 1 +title: RPC API Handler +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import DataTypeSerialization from './_data_type_serialization.md'; + +# RPC API Handler + +## Introduction + +The RPC-style API handler exposes CRUD endpoints that fully mirror [PrismaClient's query API](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#model-queries). Consuming the APIs feels like making RPC calls to a PrismaClient then. The API handler is not meant to be used directly; instead, you should use it together with a [server adapter](../../../category/server-adapters) which handles the request and response API for a specific framework. + +It can be created and used as the following: + + + + +```ts title='/src/app/api/model/[...path]/route.ts' +import { NextRequestHandler } from '@zenstackhq/server/next'; +import { RestApiHandler } from '@zenstackhq/server/api'; +import { getPrisma } from '~/lib/db'; + +const handler = NextRequestHandler({ + getPrisma, + useAppDir: true, + handler: RPCApiHandler() // you can also omit it since `RPCApiHandler` is the default +}); + +export { + handler as GET, + handler as POST, + handler as PUT, + handler as PATCH, + handler as DELETE, +}; +``` + + + + + +```ts title='/src/hooks.server.ts' +import { SvelteKitHandler } from '@zenstackhq/server/sveltekit'; +import { RPCApiHandler } from '@zenstackhq/server/api'; +import { getPrisma } from './lib/db'; + +export const handle = SvelteKitHandler({ + prefix: '/api/model', + handler: RPCApiHandler(), // you can also omit it since `RPCApiHandler` is the default + getPrisma +}); +``` + + + + + +```ts title='/server/api/model/[...].ts' +import { createEventHandler } from '@zenstackhq/server/nuxt'; +import { RPCApiHandler } from '@zenstackhq/server/api'; +import { getPrisma } from './lib/db'; + +export default createEventHandler({ + handler: RPCApiHandler(), // you can also omit it since `RPCApiHandler` is the default + getPrisma +}); +``` + + + + + +## Wire Format + +### Input + +For endpoints using `GET` and `DELETE` Http verbs, the query body is serialized and passed as the `q` query parameter. E.g.: + +```ts +GET /api/post/findMany?q=%7B%22where%22%3A%7B%22public%22%3Atrue%7D%7D +``` + +- Endpoint: /api/post/findMany +- Query parameters: `q` -> `{ "where" : { "public": true } }` + +For endpoints using other HTTP verbs, the query body is passed as `application/json` in the request body. E.g.: + +```json +POST /api/post/create +{ "data": { "title": "Hello World" } } +``` + +### Output + +The output shape conforms to the data structure returned by the corresponding PrismaClient API, wrapped into a `data` field. E.g.: + +```json +GET /api/post/findMany + +{ + "data": [ { "id": 1, "title": "Hello World" } ] +} +``` + +### Serialization + +This section explains the details about data serialization. If you're using generated hooks to consume the API, the generated code already automatically deals with serialization for you, and you don't need to do any further processing. + +ZenStack uses [superjson](https://github.com/blitz-js/superjson) to serialize and deserialize data - including the `q` query parameter, the request body, and the response body. Superjson generates two parts during serialization: + +- json: + + The JSON-compatible serialization result. + +- meta: + + The serialization metadata including information like field types that facilitates deserialization. + +If the data only involves simple data types, the serialization result is the same as regular `JSON.stringify`, and no `meta` part is generated. However, for complex data types (like `Bytes`, `Decimal`, etc.), a `meta` object will be generated, which needs to be carried along when sending the request, and will also be included in the response. + +The following part explains how the `meta` information is included for different situations: + +- The `q` query parameter + + If during superjson-serialization of the `q` parameter, a `meta` object is generated, it should be put into an object `{ serialization: meta }`, JSON-stringified, and included as an additional query parameter `meta`. For example, if you have a field named `bytes` of `Bytes` type, and you may want to query with a filter like ```{ where: { bytes: Buffer.from([1,2,3]) } }```. Superjson-serializing the query object results in: + ```json + { + "json": { "where": { "bytes": "AQID" } }, // base-64 encoded bytes + "meta": { "values": { "where.bytes": [["custom","Bytes"]] } } + } + ``` + Your query URL should look like: + ```json + GET /api/post/findMany?q={"where":{"bytes":"AQID"}}&meta={"serialization":{"values":{"where.bytes":[["custom","Bytes"]]}}} + ``` + +- The request body + + If during superjson-serialization of the request body, a `meta` object is generated, it should be put into an object `{ serialization: meta }`, and included as an additional field `meta` field in the request body. For example, if you have a field named `bytes` of `Bytes` type, and you may want to create a record with a value like ```{ data: { bytes: Buffer.from([1,2,3]) } }```. Superjson-serializing the request body results in: + ```json + { + "json": { "bytes": "AQID" }, // base-64 encoded bytes + "meta": { "values": { "bytes": [[ "custom", "Bytes" ]] } } + } + ``` + Your request body should look like: + ```json + POST /api/post/create + + { + "data": { "bytes": "AQID" }, + "meta": { "serialization": {"values": { "bytes": [[ "custom","Bytes" ]] } } } + } + ``` + +- The response body + + If during superjson-serialization of the response body, a `meta` object is generated, it will be put into an object `{ serialization: meta }`, and included as an additional field `meta` field in the response body. For example, if you have a field named `bytes` of `Bytes` type, and a `findFirst` query returns ```{ id: 1, bytes: Buffer.from([1,2,3]) }```. Superjson-serializing the request body results in: + ```json + { + "json": { "id": 1, "bytes":"AQID" }, // base-64 encoded bytes + "meta": { "values": { "bytes": [[ "custom", "Bytes" ]] } } + } + ``` + Your response body will look like: + ```json + GET /api/post/findFirst + + { + "data": { "id": 1, "bytes": "AQID" }, + "meta": { "serialization": {"values": { "bytes": [[ "custom","Bytes"]] } } } + } + ``` + + You should use the meta.serialization field value to superjson-deserialize the response body. + +#### Data Type Serialization Format + + + +## Endpoints + +- **[model]/findMany** + + _Http method:_ `GET` + +- **[model]/findUnique** + + _Http method:_ `GET` + +- **[model]/findFirst** + + _Http method:_ `GET` + +- **[model]/count** + + _Http method:_ `GET` + +- **[model]/aggregate** + + _Http method:_ `GET` + +- **[model]/groupBy** + + _Http method:_ `GET` + +- **[model]/create** + + _Http method:_ `POST` + +- **[model]/createMany** + + _Http method:_ `POST` + +- **[model]/update** + + _Http method:_ `PATCH` or `PUT` + +- **[model]/updateMany** + + _Http method:_ `PATCH` or `PUT` + +- **[model]/upsert** + + _Http method:_ `POST` + +- **[model]/delete** + + _Http method:_ `DELETE` + +- **[model]/deleteMany** + + _Http method:_ `DELETE` + +- **[model]/check** + + _Http method:_ `GET` + +## HTTP Status Code and Error Responses + +### Status code + +The HTTP status code used by the endpoints follows the following rules: + +- `create` and `createMany` use `201` for success. Other endpoints use `200`. +- `403` is used for to indicate the request is denied due to lack of permissions, usually caused by access policy violation. +- `400` is used for invalid requests, e.g., malformed request body. +- `422` is used for data validation errors. +- `500` is used for other unexpected errors. + +### Error response format + +```ts +{ + // true to indicate the failure is due to a Prisma error + prisma?: boolean; + + // true to indicate the failure is due to access policy violation + rejectedByPolicy?: boolean; + + // original Prisma error code, available when `prisma` is true + code?: string; + + // error message + message: string; + + // extra reason about why a failure happened (e.g., 'RESULT_NOT_READABLE' indicates + // a mutation succeeded but the result cannot be read back due to access policy) + reason?: string; +} +``` diff --git a/versioned_docs/version-3.x/reference/server-adapters/elysia.mdx b/versioned_docs/version-3.x/reference/server-adapters/elysia.mdx new file mode 100644 index 00000000..41582343 --- /dev/null +++ b/versioned_docs/version-3.x/reference/server-adapters/elysia.mdx @@ -0,0 +1,69 @@ +--- +title: Elysia +description: Adapter for integrating with Elysia +sidebar_position: 8 +--- + +import ErrorHandling from './_error-handling.md'; +import AdapterOptions from './_options.mdx'; +import UsingAPI from './_using-api.mdx' + +# Elysia Adapter + +The `@zenstackhq/server/elysia` module provides a quick way to install a CRUD middleware onto an [Elysia](https://elysiajs.com/) app. Combined with ZenStack's power of enhancing Prisma with access policies, you can achieve a secure data backend without manually coding it. + +This feature is contributed by [@rodrigoburigool](https://github.com/rodrigoburigool). + +### Installation + +```bash +bun install @zenstackhq/server +``` + +### Mounting the API + +You can use the `createElysiaHandler` API to create an Elysia request handler that handles CRUD requests automatically: + +```ts +import { PrismaClient } from '@prisma/client'; +import { Elysia, Context } from 'elysia'; +import { enhance } from '@zenstackhq/runtime'; +import { createElysiaHandler } from '@zenstackhq/server/elysia'; + +const prisma = new PrismaClient(); + +const app = new Elysia({ prefix: '/api' }); + +// install the CRUD middleware under route "/api/crud" +app.group('/crud', (app) => + app.use( + createElysiaHandler({ + getPrisma: (context) => enhance(prisma, { user: getCurrentUser(context) }), + basePath: '/api/crud', + }) + ) +); + +function getCurrentUser(context: Context) { + // the implementation depends on your authentication mechanism + ... +} + +app.listen(3000); +``` + +The middleware factory takes the following options to initialize: + + + +- basePath (optional) + +
string
+ + Optional base path to strip from the request path before passing to the API handler. E.g., if your CRUD handler is mounted at `/api/crud`, set this field to `'/api/crud'`. + +### Using the API + + + + diff --git a/versioned_docs/version-3.x/reference/server-adapters/express.mdx b/versioned_docs/version-3.x/reference/server-adapters/express.mdx new file mode 100644 index 00000000..abc413ec --- /dev/null +++ b/versioned_docs/version-3.x/reference/server-adapters/express.mdx @@ -0,0 +1,66 @@ +--- +title: Express.js +description: Adapter for integrating with Express.js +sidebar_position: 4 +--- + +import ErrorHandling from './_error-handling.md'; +import AdapterOptions from './_options.mdx'; +import UsingAPI from './_using-api.mdx' + +# Express.js Adapter + +The `@zenstackhq/server/express` module provides a quick way to install API routes onto a [Express.js](https://expressjs.com/) project for database CRUD operations. Combined with ZenStack's power of enhancing Prisma with access policies, it's surprisingly simple to achieve a secure data backend without manually coding it. + +### Installation + +```bash +npm install @zenstackhq/server +``` + +### Mounting the API + +You can integrate ZenStack into your project with the `ZenStackMiddleware` [express middleware](https://expressjs.com/en/guide/using-middleware.html): + +```ts +import { PrismaClient } from '@prisma/client'; +import { enhance } from '@zenstackhq/runtime'; +import { ZenStackMiddleware } from '@zenstackhq/server/express'; +import express from 'express'; + +const prisma = new PrismaClient(); +const app = express(); + +app.use(express.json()); + +app.use( + '/api/model', + ZenStackMiddleware({ + // getSessionUser extracts the current session user from the request, its + // implementation depends on your auth solution + getPrisma: (request) => enhance(prisma, { user: getSessionUser(request) }), + }) +); +``` + +The Express.js adapter takes the following options to initialize: + + + +- sendResponse (optional) + +
boolean
+ + Controls if the middleware directly sends a response. If set to false, the response is stored in the `res.locals` object and then the middleware calls the `next()` function to pass the control to the next middleware. Subsequent middleware or request handlers need to make sure to send a response. + + Defaults to `true`. + +### Using the API + + + + + +### Fully working example + +You can find a fully working example [here](https://github.com/zenstackhq/docs-tutorial-express). diff --git a/versioned_docs/version-3.x/reference/server-adapters/fastify.mdx b/versioned_docs/version-3.x/reference/server-adapters/fastify.mdx new file mode 100644 index 00000000..be568e77 --- /dev/null +++ b/versioned_docs/version-3.x/reference/server-adapters/fastify.mdx @@ -0,0 +1,56 @@ +--- +title: Fastify +description: Adapter for integrating with Fastify +sidebar_position: 5 +--- + +import ErrorHandling from './_error-handling.md'; +import AdapterOptions from './_options.mdx'; +import UsingAPI from './_using-api.mdx'; + +# Fastify Adapter + +The `@zenstackhq/server/fastify` module provides a quick way to install API routes onto a [Fastify](https://www.fastify.io/) project for database CRUD operations. Combined with ZenStack's power of enhancing Prisma with access policies, it's surprisingly simple to achieve a secure data backend without manually coding it. + +### Installation + +```bash +npm install @zenstackhq/server +``` + +### Mounting the API + +You can integrate ZenStack into your project with the `ZenStackFastifyPlugin` [fastify plugin](https://www.fastify.io/docs/latest/Reference/Plugins/): + +```ts +import { enhance } from '@zenstackhq/runtime'; +import { ZenStackFastifyPlugin } from '@zenstackhq/server/fastify'; +import { prisma } from './db.ts'; +import { getSessionUser } from './auth.ts'; + +const server = fastify(); + +// serve OpenAPI at /api/model +server.register(ZenStackFastifyPlugin, { + prefix: '/api/model', + // getSessionUser extracts the current session user from the request, its + // implementation depends on your auth solution + getPrisma: (request) => enhance(prisma, { user: getSessionUser(request) }), +}); +``` + +The Fastify adapter takes the following options to initialize: + +- prefix + +
string
+ + Prefix for the mounted API endpoints. E.g.: /api/model. + + + +### Using the API + + + + diff --git a/versioned_docs/version-3.x/reference/server-adapters/hono.mdx b/versioned_docs/version-3.x/reference/server-adapters/hono.mdx new file mode 100644 index 00000000..67fdea3e --- /dev/null +++ b/versioned_docs/version-3.x/reference/server-adapters/hono.mdx @@ -0,0 +1,57 @@ +--- +title: Hono +description: Adapter for integrating with Hono +sidebar_position: 7 +--- + +import ErrorHandling from './_error-handling.md'; +import AdapterOptions from './_options.mdx'; +import UsingAPI from './_using-api.mdx' + +# Hono Adapter + +The `@zenstackhq/server/hono` module provides a quick way to install API routes onto a [Hono](https://hono.dev/) project for database CRUD operations. Combined with ZenStack's power of enhancing Prisma with access policies, it's surprisingly simple to achieve a secure data backend without manually coding it. + +### Installation + +```bash +npm install @zenstackhq/server +``` + +### Mounting the API + +You can use the `createHonoHandler` API to create a [Hono middleware](https://hono.dev/docs/getting-started/basic#using-middleware) that handles CRUD requests automatically: + +```ts +import { PrismaClient } from '@prisma/client'; +import { enhance } from '@zenstackhq/runtime'; +import { createHonoHandler } from '@zenstackhq/server/hono'; +import { Context, Hono } from 'hono'; + +const prisma = new PrismaClient(); +const app = new Hono(); + +app.use( + '/api/model/*', + createHonoHandler({ + getPrisma: (ctx) => { + return enhance(prisma, { user: getCurrentUser(ctx) }); + }, + }) +); + +function getCurrentUser(ctx: Context) { + // the implementation depends on your authentication mechanism + ... +} +``` + +The middleware factory takes the following options to initialize: + + + +### Using the API + + + + diff --git a/versioned_docs/version-3.x/reference/server-adapters/nestjs.mdx b/versioned_docs/version-3.x/reference/server-adapters/nestjs.mdx new file mode 100644 index 00000000..1d558d3d --- /dev/null +++ b/versioned_docs/version-3.x/reference/server-adapters/nestjs.mdx @@ -0,0 +1,268 @@ +--- +title: NestJS +description: Adapter for integrating with NestJS +sidebar_position: 6 +--- + +import ErrorHandling from './_error-handling.md'; +import AdapterOptions from './_options.mdx'; +import UsingAPI from './_using-api.mdx'; + +# NestJS Adapter + +The `@zenstackhq/server/nestjs` module provides a quick way to install a ZenStack-enhanced Prisma service as a dependency injection provider onto a [NestJS](https://nestjs.com/) application. + +### Installation + +```bash +npm install @zenstackhq/server +``` + +### Registering the provider + +You can register the enhanced Prisma service by importing the `ZenStackModule` NestJS module. + +```ts +import { ZenStackModule } from '@zenstackhq/server/nestjs'; +import { enhance } from '@zenstackhq/runtime'; +import { PrismaService } from './prisma.service'; + +@Module({ + imports: [ + ZenStackModule.registerAsync({ + useFactory: (prisma: PrismaService) => { + return { + getEnhancedPrisma: () => enhance(prisma, { user: ... }), + }; + }, + inject: [PrismaService], + extraProviders: [PrismaService], + }), + ], +}) +export class AppModule {} +``` + +The `registerAsync` API takes as input a factory function that returns a config used for creating an enhanced prisma service. The config contains a callback function where you should create and return an enhanced `PrismaClient`. It'll be called each time a Prisma method is invoked. + +You'll usually pass in a user context when calling `enhance` inside the callback. The way how the user context is fetched depends on your authentication mechanism. You can check the [NestJS quick start guide](../../quick-start/nestjs) for a reference solution. + +### Using the enhanced Prisma service + +Inside your NestJS controllers or services, you can inject the enhanced Prisma service and use it as you would with the regular Prisma service. Just use the special token name `ENHANCED_PRISMA` when injecting the service. + +```ts +import { ENHANCED_PRISMA } from '@zenstackhq/server/nestjs'; + +@Controller() +export class MyController { + constructor( + @Inject(ENHANCED_PRISMA) private readonly prismaService: PrismaService, + ) {} + + ... +} +``` + +You can still use the regular Prisma service by injecting as usual. + +### Using the API handler service to automate request handling + +This module also provides an `ApiHandlerService` that can be used to automate the request handling using API handlers. This is useful if you want to handle requests in a more structured way, such as using a controller or middleware. Before using it, you should ensure `ENHANCED_PRISMA` is registered in the module. For example: + +```ts +import { ZenStackModule, ApiHandlerService } from '@zenstackhq/server/nestjs'; +import { enhance } from '@zenstackhq/runtime'; +import { PrismaService } from './prisma.service'; + +@Module({ + imports: [ + // Register the ZenStack module + // The module exports the ENHANCED_PRISMA token and could be used in the ApiHandlerService + ZenStackModule.registerAsync({ + useFactory: (prisma: PrismaService) => { + return { + getEnhancedPrisma: () => enhance(prisma, { user: ... }), + }; + }, + inject: [PrismaService], + extraProviders: [PrismaService], + }), + ], + providers: [ApiHandlerService] +}) +export class AppModule {} +``` + +Then, you can inject the `ApiHandlerService` into your code and use it to handle requests. The service provides a method `handleRequest` to handle request using API handler automatically. + +RPC API Handler: + +```ts +import { Controller, Get, Post } from '@nestjs/common'; +import { ApiHandlerService } from '@zenstackhq/server/nestjs'; + +@Controller('post') +export class PostController { + constructor(private readonly apiHandlerService: ApiHandlerService) {} + + // should align with the route generated by API handler + @Get('findMany') + async findMany() { + return this.apiHandlerService.handleRequest() + } + + @Post('create') + async create() { + return this.apiHandlerService.handleRequest() + } +} +``` + +RESTful API Handler: + +```ts +import { Controller, Get, Post } from '@nestjs/common'; +import { ApiHandlerService } from '@zenstackhq/server/nestjs'; +import RESTApiHandler from '@zenstackhq/server/api/rest'; + +const ENDPOINT = 'http://localhost'; + +@Controller('post') +export class PostController { + constructor(private readonly apiHandlerService: ApiHandlerService) {} + + // should align with the route generated by API handler + @Get() + async list() { + return this.apiHandlerService.handleRequest( + { + handler: RESTApiHandler({ + endpoint: ENDPOINT, + }), + } + ) + } + + @Post() + async create() { + return this.apiHandlerService.handleRequest( + { + handler: RESTApiHandler({ + endpoint: ENDPOINT, + }), + } + ) + } +} +``` + +### API reference + +#### `ZenStackModule.registerAsync` + +##### Signature + +```ts +registerAsync(options: ZenStackModuleAsyncOptions): DynamicModule; +``` + +##### Parameter `options` + +```ts +interface ZenStackModuleAsyncOptions { + /** + * Optional list of imported modules that export the providers which are + * required in this module. + */ + imports?: Array | DynamicModule | Promise | ForwardReference>; + + /** + * Whether the module is global-scoped. + */ + global?: boolean; + + /** + * The token to export the enhanced Prisma service. Default is `'ENHANCED_PRISMA'`. + */ + exportToken?: string; + + /** + * The factory function to create the enhancement options. + */ + useFactory: (...args: unknown[]) => Promise | ZenStackModuleOptions; + + /** + * The dependencies to inject into the factory function. + */ + inject?: FactoryProvider['inject']; + + /** + * Extra providers to facilitate dependency injection. + */ + extraProviders?: Provider[]; +} +``` + +```ts +interface ZenStackModuleOptions { + /** + * A callback for getting an enhanced `PrismaClient`. + */ + getEnhancedPrisma: (model?: string | symbol) => unknown; +} +``` + +#### `ApiHandlerService.handleRequest` + +##### Signature + +```ts +handleRequest(options?: ApiHandlerOptions): Promise; +``` + +##### Parameter `options` + +```ts +interface ApiHandlerOptions { + /** + * Logger settings + */ + logger?: LoggerConfig; + + /** + * Model metadata. By default loaded from the `node_module/.zenstack/model-meta` + * module. You can pass it in explicitly if you configured ZenStack to output to + * a different location. + */ + modelMeta?: ModelMeta; + + /** + * Zod schemas for validating request input. Pass `true` to load from standard location + * (need to enable `@core/zod` plugin in schema.zmodel) or omit to disable input validation. + */ + zodSchemas?: ZodSchemas | boolean; + + /** + * Api request handler function. Can be created using `@zenstackhq/server/api/rest` or `@zenstackhq/server/api/rpc` factory functions. + * Defaults to RPC-style API handler. + */ + handler?: HandleRequestFn; + + /** + * The base URL for the API handler. This is used to determine the base path for the API requests. + * If you are using the ApiHandlerService in a route with a prefix, you should set this to the prefix. + * + * e.g. + * without baseUrl(API handler default route): + * - RPC API handler: [model]/findMany + * - RESTful API handler: /:type + * + * with baseUrl(/api/crud): + * - RPC API handler: /api/crud/[model]/findMany + * - RESTful API handler: /api/crud/:type + */ + baseUrl?: string; +} +``` + diff --git a/versioned_docs/version-3.x/reference/server-adapters/next.mdx b/versioned_docs/version-3.x/reference/server-adapters/next.mdx new file mode 100644 index 00000000..48647a64 --- /dev/null +++ b/versioned_docs/version-3.x/reference/server-adapters/next.mdx @@ -0,0 +1,124 @@ +--- +title: Next.js +description: Adapter for integrating with Next.js +sidebar_position: 1 +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import ErrorHandling from './_error-handling.md'; +import AdapterOptions from './_options.mdx'; +import UsingAPI from './_using-api.mdx'; + +# Next.js Server Adapter + +The `@zenstackhq/server/next` module provides a quick way to install API endpoints onto a [Next.js](https://nextjs.org/) project for database CRUD operations. Combined with ZenStack's power of enhancing Prisma with access policies, it's surprisingly simple to achieve a secure data backend without manually coding it. + +The server adapter supports both the "pages" routes for older versions of Next.js and the new "app" routes for Next.js 13. + +### Installation + +```bash +npm install @zenstackhq/server +``` + +### Mounting the API + +You can use it to create a request handler in an API endpoint like: + + + + + +```ts title='/src/app/api/model/[...path]/route.ts' +import { NextRequestHandler } from '@zenstackhq/server/next'; +import type { NextRequest } from "next/server"; +import { enhance } from '@zenstackhq/runtime'; +import { prisma } from '~/lib/db.ts'; +import { getSessionUser } from '~/lib/auth.ts'; + +// create an enhanced Prisma client with user context +function getPrisma(req: NextRequest) { + // getSessionUser extracts the current session user from the request, its + // implementation depends on your auth solution + return enhance(prisma, { user: getSessionUser(req) }); +} + +const handler = NextRequestHandler({ getPrisma, useAppDir: true }); + +export { + handler as GET, + handler as POST, + handler as PUT, + handler as PATCH, + handler as DELETE, +}; +``` + +The Next.js API route handler takes the following options to initialize: + + + + + + + +```ts title='/src/pages/api/model/[...path].ts' +import { NextRequestHandler } from '@zenstackhq/server/next'; +import type { NextApiRequest, NextApiResponse } from 'next'; +import { enhance } from '@zenstackhq/runtime'; +import { prisma } from '~/lib/db.ts'; +import { getSessionUser } from '~/lib/auth.ts'; + +// create an enhanced Prisma client with user context +function getPrisma(req: NextApiRequest, res: NextApiResponse) { + // getSessionUser extracts the current session user from the request, its + // implementation depends on your auth solution + return enhance(prisma, { user: getSessionUser(req, res) }); +} + +// create the request handler with the `getPrisma` hook +export default NextRequestHandler({ getPrisma }); +``` + +The Next.js API route handler takes the following options to initialize: + + + + + + + +### Controlling what endpoints to expose + +You can use a [Next.js middleware](https://nextjs.org/docs/pages/building-your-application/routing/middleware) to further control what endpoints to expose. For example, if you're using a RESTful API handler installed at "/api/model", you can disallow listing all `User` entities by adding a middleware like: + +```ts title='/src/middleware.ts' +import { type NextRequest, NextResponse } from 'next/server'; + +export function middleware(request: NextRequest) { + const url = new URL(request.url); + if ( + request.method === 'GET' && + url.pathname.match(/^\/api\/model\/user\/?$/) + ) { + return NextResponse.json({ error: 'Not allowed' }, { status: 405 }); + } +} + +export const config = { + matcher: '/api/model/:path*', +}; +``` + +### Using the API + + + + + +### Fully working example + +You can find the fully working examples below: +- [Pages router](https://github.com/zenstackhq/docs-tutorial-nextjs) +- [Apps router](https://github.com/zenstackhq/docs-tutorial-nextjs-app-dir) diff --git a/versioned_docs/version-3.x/reference/server-adapters/nuxt.mdx b/versioned_docs/version-3.x/reference/server-adapters/nuxt.mdx new file mode 100644 index 00000000..c254ccf1 --- /dev/null +++ b/versioned_docs/version-3.x/reference/server-adapters/nuxt.mdx @@ -0,0 +1,44 @@ +--- +title: Nuxt +description: Adapter for integrating with Nuxt +sidebar_position: 2 +--- + +import ErrorHandling from './_error-handling.md'; +import AdapterOptions from './_options.mdx'; +import UsingAPI from './_using-api.mdx'; + +# Nuxt Server Adapter + +The `@zenstackhq/server/nuxt` module provides a quick way to install API endpoints onto a [Nuxt V3](https://nuxt.com/) project for database CRUD operations. Combined with ZenStack's power of enhancing Prisma with access policies, it's surprisingly simple to achieve a secure data backend without manually coding it. + +### Mounting the API + +You can mount the API by creating a Nuxt server event handler like: + +```ts title='/server/api/model/[...].ts' +import { enhance } from '@zenstackhq/runtime'; +import { createEventHandler } from '@zenstackhq/server/nuxt'; +import { getSessionUser } from '~/server/auth'; +import { prisma } from '~/server/prisma'; + +export default createEventHandler({ + getPrisma: async (event) => { + return enhance(prisma, { user: getSessionUser(event) }); + }, +}); +``` + +The Nuxt event handler takes the following options to initialize: + + + +### Using the API + + + + + +### Fully working example + +You can find a fully working example [here](https://github.com/zenstackhq/sample-todo-nuxt). diff --git a/versioned_docs/version-3.x/reference/server-adapters/sveltekit.mdx b/versioned_docs/version-3.x/reference/server-adapters/sveltekit.mdx new file mode 100644 index 00000000..2976149f --- /dev/null +++ b/versioned_docs/version-3.x/reference/server-adapters/sveltekit.mdx @@ -0,0 +1,63 @@ +--- +title: SvelteKit +description: Adapter for integrating with SvelteKit +sidebar_position: 3 +--- + +import ErrorHandling from './_error-handling.md'; +import AdapterOptions from './_options.mdx'; +import UsingAPI from './_using-api.mdx'; + +# SvelteKit Server Adapter + +The `@zenstackhq/server/sveltekit` module provides a quick way to install API endpoints onto a [SvelteKit](https://kit.svelte.dev/) project for database CRUD operations. Combined with ZenStack's power of enhancing Prisma with access policies, it's surprisingly simple to achieve a secure data backend without manually coding it. + +### Installation + +```bash +npm install @zenstackhq/server +``` + +### Mounting the API + +You can mount the API by creating a SvelteKit server hooks like: + +```ts title='/src/hooks.server.ts' +import { SvelteKitHandler } from '@zenstackhq/server/sveltekit'; +import { enhance } from '@zenstackhq/runtime'; +import { getSessionUser } from '$lib/auth.ts'; + +// create an enhanced Prisma client with user context +function getPrisma(event: RequestEvent) { + // getSessionUser extracts the current session user from the request, its + // implementation depends on your auth solution + return enhance({ user: getSessionUser(event) }); +} + +// create the hooks handler with the `getPrisma` hook +export const handle = SvelteKitHandler({ prefix: '/api/model', getPrisma }); +``` + +:::tip +You can use the [sequence helper](https://kit.svelte.dev/docs/modules#sveltejs-kit-hooks) to compose multiple server hooks. +::: + +The SvelteKit hooks handler takes the following options to initialize: + +- prefix + +
string
+ + Prefix for the mounted API endpoints. E.g.: /api/model. + + + +### Using the API + + + + + +### Fully working example + +You can find a fully working example [here](https://github.com/zenstackhq/sample-todo-sveltekit). diff --git a/versioned_docs/version-3.x/reference/zmodel-language.md b/versioned_docs/version-3.x/reference/zmodel-language.md new file mode 100644 index 00000000..49988dce --- /dev/null +++ b/versioned_docs/version-3.x/reference/zmodel-language.md @@ -0,0 +1,1987 @@ +--- +description: ZModel language references +sidebar_position: 1 +sidebar_label: ZModel Language +toc_max_heading_level: 3 +--- + +# ZModel Language Reference + +## Overview + +**ZModel**, the modeling DSL of ZenStack, is the main concept you'll deal with when using this toolkit. The ZModel syntax is a superset of [Prisma Schema](https://www.prisma.io/docs/concepts/components/prisma-schema). Therefore, every valid Prisma schema is a valid ZModel. + +:::info + +We made that choice to extend the Prisma schema for several reasons: + +- Creating a new ORM adds little value to the community. Instead, extending Prisma - the overall best ORM toolkit for Typescript - sounds more sensible. + +- Prisma's schema language is simple and intuitive. + +- Extending an existing popular language lowers the learning curve compared to inventing a new one. + +::: + +However, the standard capability of Prisma schema doesn't allow us to build the functionalities we want in a natural way, so we made several extensions to the language by adding the following: + +1. Custom attributes +1. Custom attribute functions +1. Built-in attributes and functions for defining access policies +1. Built-in attributes for defining field validation rules +1. Utility attributes like `@password` and `@omit` +1. Multi-schema files support + +Some of these extensions have been asked for by the Prisma community for some time, so we hope that ZenStack can be helpful even just as an extensible version of Prisma. + +This section provides detailed descriptions of all aspects of the ZModel language, so you don't have to jump over to Prisma's documentation for extra learning. + +## Import +ZModel allows to import other ZModel files. This is useful when you want to split your schema into multiple files for better organization. Under the hood, it will recursively merge all the imported schemas, and generate a single Prisma schema file for the Prisma CLI to consume. + +### Syntax + +```zmodel +import [IMPORT_SPECIFICATION] +``` + +- **[IMPORT_SPECIFICATION]**: + Path to the ZModel file to be imported. It can be: + + - An absolute path, e.g., "/path/to/user". + - A relative path, e.g., "./user". + - A module resolved to an installed NPM package, e.g., "my-package/base". + + If the import specification doesn't end with ".zmodel", the resolver will automatically append it. Once a file is imported, all the declarations in that file will be included in the building process. + +### Examples + +```zmodel +// there is a file called "user.zmodel" in the same directory +import "user" +``` + + +## Data source + +Every model needs to include exactly one `datasource` declaration, providing information on how to connect to the underlying database. + +### Syntax + +```zmodel +datasource [NAME] { + provider = [PROVIDER] + url = [DB_URL] +} +``` + +- **[NAME]**: + + Name of the data source. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. Name is only informational and serves no other purposes. + +- **[PROVIDER]**: + + Name of database connector. Valid values: + + - sqlite + - postgresql + - mysql + - sqlserver + - cockroachdb + +- **[DB_URL]**: + + Database connection string. Either a plain string or an invocation of `env` function to fetch from an environment variable. + +### Examples + +```zmodel +datasource db { + provider = "postgresql" + url = "postgresql://postgres:abc123@localhost:5432/todo?schema=public" +} +``` + +It's highly recommended that you not commit sensitive database connection strings into source control. Alternatively, you can load it from an environment variable: + +```zmodel +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} +``` + +### Supported databases + +ZenStack uses [Prisma](https://prisma.io ':target=_blank') to talk to databases, so all relational databases supported by Prisma are also supported by ZenStack. + +Here's a list for your reference: + +| Database | Version | +| --------------------- | ------- | +| PostgreSQL | 9.6 | +| PostgreSQL | 10 | +| PostgreSQL | 11 | +| PostgreSQL | 12 | +| PostgreSQL | 13 | +| PostgreSQL | 14 | +| PostgreSQL | 15 | +| MySQL | 5.6 | +| MySQL | 5.7 | +| MySQL | 8 | +| MariaDB | 10 | +| SQLite | \* | +| AWS Aurora | \* | +| AWS Aurora Serverless | \* | +| Microsoft SQL Server | 2022 | +| Microsoft SQL Server | 2019 | +| Microsoft SQL Server | 2017 | +| Azure SQL | \* | +| CockroachDB | 21.2.4+ | + +You can find the orignal list [here](https://www.prisma.io/docs/reference/database-reference/supported-databases ':target=_blank'). + +## Generator + +Generators are used for creating assets (usually code) from a Prisma schema. Check [here](https://www.prisma.io/docs/concepts/components/prisma-schema/generators) for a list of official and community generators. + +### Syntax + +```zmodel +generator [GENERATOR_NAME] { + [OPTION]* +} +``` + +- **[GENERATOR_NAME]** + + Name of the generator. Needs to be unique in the entire model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. + +- **[OPTION]** + + A generator configuration option, in form of "[NAME] = [VALUE]". A generator needs to have at least a "provider" option that specify its provider. + +### Example + +```zmodel +generator client { + provider = "prisma-client-js" + output = "./generated/prisma-client-js" +``` + +## Plugin + +Plugins are ZenStack's extensibility mechanism. It's usage is similar to [Generator](#generator). Users can define their own plugins to generate artifacts from the ZModel schema. Plugins differ from generators mainly in the following ways: + +- They have a cleaner interface without the complexity of JSON-RPC. +- They use an easier-to-program AST representation than generators. +- They have access to language features that ZenStack adds to Prisma, like custom attributes and functions. + +### Syntax + +```zmodel +plugin [PLUGIN_NAME] { + [OPTION]* +} +``` + +- **[PLUGIN_NAME]** + + Name of the plugin. Needs to be unique in the entire model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. + +- **[OPTION]** + + A plugin configuration option, in form of "[NAME] = [VALUE]". A plugin needs to have at least a "provider" option that specify its provider. + +### Example + +```zmodel +plugin swr { + provider = '@zenstackhq/swr' + output = 'lib/hooks' +} +``` + +## Enum + +Enums are container declarations for grouping constant identifiers. You can use them to express concepts like user roles, product categories, etc. + +### Syntax + +```prsima +enum [ENUM_NAME] { + [FIELD]* +} +``` + +- **[ENUM_NAME]** + + Name of the enum. Needs to be unique in the entire model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. + +- **[FIELD]** + + Field identifier. Needs to be unique in the model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. + +### Example + +```zmodel +enum UserRole { + USER + ADMIN +} +``` + +## Model + +Models represent the business entities of your application. A model inherits all fields and attributes from extended abstract models. Abstract models are eliminated in the generated prisma schema file. + +### Syntax +```zmodel +(abstract)? model [NAME] (extends [ABSTRACT_MODEL_NAME](,[ABSTRACT_MODEL_NAME])*)? { + [FIELD]* +} +``` +- **[abstract]**: + + Optional. If present, the model is marked as abstract would not be mapped to a database table. Abstract models are only used as base classes for other models. + +- **[NAME]**: + + Name of the model. Needs to be unique in the entire model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. + +- **[FIELD]**: + + Arbitrary number of fields. See [Field](#field) for details. + +- **[ABSTRACT_MODEL_NAME]**: + + Name of an abstract model. + +### Note + +A model must include a field marked with `@id` attribute. The `id` field serves as a unique identifier for a model entity and is mapped to the database table's primary key. + +See [here](#attribute) for more details about attributes. + +### Example + +```zmodel +abstract model Basic { + id String @id + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model User extends Basic { + name String +} +``` + +The generated prisma file only contains one `User` model: +```zmodel +model User { + id String @id + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + name String @id +} +``` + +## Type + +Types provide a way to modeling object shapes without mapping them to a database table. The use cases of "types" include: + +- Typing JSON fields in models. +- Typing [plugin](#plugin) options. +- Interfacing with data models from external sources (auth providers like [Clerk](https://clerk.com), payment providers like [Stripe](https://stripe.com), etc.). + +### Syntax +```zmodel +type [NAME] { + [FIELD]* +} +``` + +- **[NAME]**: + + Name of the model. Needs to be unique in the entire model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. + +- **[FIELD]**: + + Arbitrary number of fields. See [Field](#field) for details. + +### Example + +```zmodel +type Profile { + email String @email + name String +} + +model User { + id String @id + profile Profile? @json +} +``` + +### Limitations + +- Inheritance is not supported for types yet. A type cannot inherit from another type. A model cannot extend a type. +- Type cannot have type-level attributes like `@@validate`. However, fields in a type can have field-level attributes. + +We may address these limitations in future versions. + +## Attribute + +Attributes decorate fields and models and attach extra behaviors or constraints to them. + +### Syntax + +#### Field attribute + +Field attribute name is prefixed by a single `@`. + +```zmodel +id String @[ATTR_NAME](ARGS)? +``` + +- **[ATTR_NAME]** + +Attribute name. See [below](#predefined-attributes) for a full list of attributes. + +- **[ARGS]** + +See [attribute arguments](#arguments). + +#### Model attribute + +Field attribute name is prefixed double `@@`. + +```zmodel +model Model { + @@[ATTR_NAME](ARGS)? +} +``` + +- **[ATTR_NAME]** + +Attribute name. See [below](#predefined-attributes) for a full list of attributes. + +- **[ARGS]** + +See [attribute arguments](#arguments). + +### Arguments + +Attribute can be declared with a list of parameters and applied with a comma-separated list of arguments. + +Arguments are mapped to parameters by position or by name. For example, for the `@default` attribute declared as: + +```zmodel +attribute @default(_ value: ContextType) +``` + +, the following two ways of applying it are equivalent: + +```zmodel +published Boolean @default(value: false) +``` + +```zmodel +published Boolean @default(false) +``` + +### Parameter types + +Attribute parameters are typed. The following types are supported: + +- Int + + Integer literal can be passed as argument. + + E.g., declaration: + + ```zmodel + attribute @password(saltLength: Int?, salt: String?) + + ``` + + application: + + ```zmodel + password String @password(saltLength: 10) + ``` + +- String + + String literal can be passed as argument. + + E.g., declaration: + + ```zmodel + attribute @id(map: String?) + ``` + + application: + + ```zmodel + id String @id(map: "_id") + ``` + +- Boolean + + Boolean literal or expression can be passed as argument. + + E.g., declaration: + + ```zmodel + attribute @@allow(_ operation: String, _ condition: Boolean) + ``` + + application: + + ```zmodel + @@allow("read", true) + @@allow("update", auth() != null) + ``` + +- ContextType + + A special type that represents the type of the field onto which the attribute is attached. + + E.g., declaration: + + ```zmodel + attribute @default(_ value: ContextType) + ``` + + application: + + ```zmodel + f1 String @default("hello") + f2 Int @default(1) + ``` + +- FieldReference + + References to fields defined in the current model. + + E.g., declaration: + + ```zmodel + attribute @relation( + _ name: String?, + fields: FieldReference[]?, + references: FieldReference[]?, + onDelete: ReferentialAction?, + onUpdate: ReferentialAction?, + map: String?) + ``` + + application: + + ```zmodel + model Model { + ... + // [ownerId] is a list of FieldReference + owner Owner @relation(fields: [ownerId], references: [id]) + ownerId + } + ``` + +- Enum + + Attribute parameter can also be typed as predefined enum. + + E.g., declaration: + + ```zmodel + attribute @relation( + _ name: String?, + fields: FieldReference[]?, + references: FieldReference[]?, + // ReferentialAction is a predefined enum + onDelete: ReferentialAction?, + onUpdate: ReferentialAction?, + map: String?) + ``` + + application: + + ```zmodel + model Model { + // 'Cascade' is a predefined enum value + owner Owner @relation(..., onDelete: Cascade) + } + ``` + +An attribute parameter can be typed as any of the types above, a list of the above type, or an optional of the types above. + +```zmodel + model Model { + ... + f1 String + f2 String + // a list of FieldReference + @@unique([f1, f2]) + } +``` + +### Attribute functions + +Attribute functions are used for providing values for attribute arguments, e.g., current `DateTime`, an autoincrement `Int`, etc. They can be used in place of attribute arguments, like: + +```zmodel +model Model { + ... + serial Int @default(autoincrement()) + createdAt DateTime @default(now()) +} +``` + +You can find a list of predefined attribute functions [here](#predefined-attribute-functions). + +### Predefined attributes + +#### Field attributes + +##### @id + +```zmodel +attribute @id(map: String?) +``` + +Defines an ID on the model. + +_Params_: + +| Name | Description | +| ---- | ----------------------------------------------------------------- | +| map | The name of the underlying primary key constraint in the database | + +##### @default + +```zmodel +attribute @default(_ value: ContextType) +``` + +Defines a default value for a field. + +_Params_: + +| Name | Description | +| ----- | ---------------------------- | +| value | The default value expression | + +##### @unique + +```zmodel +attribute @unique(map: String?) +``` + +Defines a unique constraint for this field. + +_Params_: + +| Name | Description | +| ---- | ----------------------------------------------------------------- | +| map | The name of the underlying primary key constraint in the database | + +##### @relation + +```zmodel +attribute @relation( + _ name: String?, + fields: FieldReference[]?, + references: FieldReference[]?, + onDelete: ReferentialAction?, + onUpdate: ReferentialAction?, + map: String?) +``` + +Defines meta information about a relation. + +_Params_: + +| Name | Description | +| ---------- | ------------------------------------------------------------------------------ | +| name | The name of the relationship | +| fields | A list of fields defined in the current model | +| references | A list of fields of the model on the other side of the relation | +| onDelete | Referential action to take on delete. See details [here](#referential-action). | +| onUpdate | Referential action to take on update. See details [here](#referential-action). | + +##### @map + +```zmodel +attribute @map(_ name: String) +``` + +Maps a field name or enum value from the schema to a column with a different name in the database. + +_Params_: + +| Name | Description | +| ---- | ------------------------------------------------- | +| map | The name of the underlying column in the database | + +##### @updatedAt + +```zmodel +attribute @updatedAt() +``` + +Automatically stores the time when a record was last updated. + +##### @ignore + +```zmodel +attribute @ignore() +``` + +Exclude a field from the Prisma Client (for example, a field that you do not want Prisma users to update). + +##### @allow + +```zmodel +attribute @allow(_ operation: String, _ condition: Boolean) +``` + +Defines an access policy that allows the annotated field to be read or updated. Read more about access policies [here](#access-policy). + +_Params_: + +| Name | Description | +| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| operation | Comma separated list of operations to control, including `"read"` and `"update"`. Pass` "all"` as an abbreviation for including all operations. | +| condition | Boolean expression indicating if the operations should be allowed | + +##### @deny + +```zmodel +attribute @deny(_ operation: String, _ condition: Boolean) +``` + +Defines an access policy that denies the annotated field to be read or updated. Read more about access policies [here](#access-policy). + +_Params_: + +| Name | Description | +| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| operation | Comma separated list of operations to control, including `"read"` and `"update"`. Pass` "all"` as an abbreviation for including all operations. | +| condition | Boolean expression indicating if the operations should be denied + +##### @password + +```zmodel +attribute @password(saltLength: Int?, salt: String?) +``` + +Indicates that the field is a password field and needs to be hashed before persistence. + +_NOTE_: ZenStack uses the "bcryptjs" library to hash passwords. You can use the `saltLength` parameter to configure the cost of hashing or use `salt` parameter to provide an explicit salt. By default, a salt length of 12 is used. See [here](https://www.npmjs.com/package/bcryptjs ':target=blank') for more details. + +_Params_: + +| Name | Description | +| ---------- | ------------------------------------------------------------- | +| saltLength | The length of salt to use (cost factor for the hash function) | +| salt | The salt to use (a pregenerated valid salt) | + +##### @omit + +```zmodel +attribute @omit() +``` + +Indicates that the field should be omitted when read from the generated services. Commonly used together with `@password` attribute. + +##### @json + +```zmodel +attribute @json() +``` + +##### @encrypted + +```zmodel +attribute @encrypted() +``` + +Marks a field to be encrypted during write and decrypted when read. + +```zmodel +model User { + id Int @id + someSecret String @encrypted +} +``` + +Using the attribute requires the "encryption" enhancement kind to be enabled when calling `enhance`, and the `encryption` settings provided in the enhancement options: + +```ts + +function getEncryptionKey(): Uint8Array { + // return a 32-byte key +} + +const db = enhance(prisma, { user }, { + encryption: { + encryptionKey: getEncryptionKey() + } +}); +``` + +See [Encrypting Field](../guides/field-encryption.md) for more details. + +##### @prisma.passthrough + +```zmodel +attribute @prisma.passthrough(_ text: String) +``` + +A utility attribute for passing arbitrary text to the generated Prisma schema. This is useful as a workaround for dealing with discrepancies between Prisma schema and ZModel. + +_Params_: + +| Name | Description | +| ---- | ------------------------------------ | +| text | Text to passthrough to Prisma schema | + +E.g., the following ZModel content: + +```zmodel +model User { + id Int @id @default(autoincrement()) + name String @prisma.passthrough("@unique") +} +``` + +will be translated to the following Prisma schema: + +```zmodel +model User { + id Int @id @default(autoincrement()) + name String @unique +} +``` + +##### @meta + +```zmodel +attribute @meta(_ name: String, _ value: Any) +``` + +Adds arbitrary metadata to a field. The metadata can be accessed by custom plugins for code generation, or at runtime from the `modelMeta` object exported from `@zenstackhq/runtime/model-meta`. The `value` parameter can be an arbitrary literal expression, including object literals. + +```zmodel +model User { + id Int @id + name String @meta(name: "description", value: "The name of the user") +} +``` + +#### Model attributes + +##### @@id + +```zmodel +attribute @@id(_ fields: FieldReference[], name: String?, map: String?) +``` + +Defines a multi-field ID (composite ID) on the model. + +_Params_: + +| Name | Description | +| ------ | ----------------------------------------------------------------------------- | +| fields | A list of fields defined in the current model | +| name | The name that the Client API will expose for the argument covering all fields | +| map | The name of the underlying primary key constraint in the database | + +##### @@unique + +```zmodel +attribute @@unique(_ fields: FieldReference[], name: String?, map: String?) +``` + +Defines a compound unique constraint for the specified fields. + +_Params_: + +| Name | Description | +| ------ | ------------------------------------------------------------ | +| fields | A list of fields defined in the current model | +| name | The name of the unique combination of fields | +| map | The name of the underlying unique constraint in the database | + +##### @@schema + +```zmodel +attribute @@schema(_ name: String) +``` + +Specifies the database schema to use in a [multi-schema setup](https://www.prisma.io/docs/guides/database/multi-schema). + +_Params_: + +| Name | Description | +| ---- | ------------------------------- | +| name | The name of the database schema | + +##### @@index + +```zmodel +attribute @@index(_ fields: FieldReference[], map: String?) +``` + +Defines an index in the database. + +_Params_: + +| Name | Description | +| ------ | ------------------------------------------------ | +| fields | A list of fields defined in the current model | +| map | The name of the underlying index in the database | + +##### @@map + +```zmodel +attribute @@map(_ name: String) +``` + +Maps the schema model name to a table with a different name, or an enum name to a different underlying enum in the database. + +_Params_: + +| Name | Description | +| ---- | -------------------------------------------------------- | +| name | The name of the underlying table or enum in the database | + +##### @@ignore + +```zmodel +attribute @@ignore() +``` + +Exclude a model from the Prisma Client (for example, a model that you do not want Prisma users to update). + +##### @@allow + +```zmodel +attribute @@allow(_ operation: String, _ condition: Boolean) +``` + +Defines an access policy that allows a set of operations when the given condition is true. Read more about access policies [here](#access-policy). + +_Params_: + +| Name | Description | +| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| operation | Comma separated list of operations to control, including `"create"`, `"read"`, `"update"`, and `"delete"`. Pass` "all"` as an abbriviation for including all operations. | +| condition | Boolean expression indicating if the operations should be allowed | + +##### @@deny + +```zmodel +attribute @@deny(_ operation: String, _ condition: Boolean) +``` + +Defines an access policy that denies a set of operations when the given condition is true. Read more about access policies [here](#access-policy). + +_Params_: + +| Name | Description | +| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| operation | Comma separated list of operations to control, including `"create"`, `"read"`, `"update"`, and `"delete"`. Pass` "all"` as an abbreviation for including all operations. | +| condition | Boolean expression indicating if the operations should be denied | + +##### @@auth + +```zmodel +attribute @@auth() +``` + +Specify the model for resolving `auth()` function call in access policies. By default, the model named "User" is used. You can use this attribute to override the default behavior. A Zmodel can have at most one model with this attribute. + +##### @@auth + +```zmodel +attribute @@delegate(_ discriminator: FieldReference) +``` + +Marks a model to be a delegated type. Used for [modeling a polymorphic hierarchy](../guides/polymorphism). + +_Params_: + +| Name | Description | +| ------------- | ---------------------------------------------------------------------------------------------------------------------------- | +| discriminator | A `String` or `enum` field in the same model used to store the name of the concrete model that inherit from this base model. | + +##### @@prisma.passthrough + +```zmodel +attribute @@prisma.passthrough(_ text: String) +``` + +A utility attribute for passing arbitrary text to the generated Prisma schema. This is useful as a workaround for dealing with discrepancies between Prisma schema and ZModel. + +_Params_: + +| Name | Description | +| ---- | ------------------------------------ | +| text | Text to passthrough to Prisma schema | + +E.g., the following ZModel content: + +```zmodel +model User { + id Int @id @default(autoincrement()) + name String + @@prisma.passthrough("@@unique([name])") +} +``` + +will be translated to the following Prisma schema: + +```zmodel +model User { + id Int @id @default(autoincrement()) + name String + @@unique([name]) +} +``` + +##### @@meta + +```zmodel +attribute @@meta(_ name: String, _ value: Any) +``` + +Adds arbitrary metadata to a model. The metadata can be accessed by custom plugins for code generation, or at runtime from the `modelMeta` object exported from `@zenstackhq/runtime/model-meta`. The `value` parameter can be an arbitrary literal expression, including object literals. + +```zmodel +model User { + id Int @id + @@meta('description', 'This is a user model') +} +``` + +### Predefined attribute functions + +##### uuid() + +```zmodel +function uuid(): String {} +``` + +Generates a globally unique identifier based on the UUID spec. + +##### cuid() + +```zmodel +function cuid(version: Int?): String {} +``` + +Generates a unique identifier based on the [CUID](https://github.com/ericelliott/cuid) spec. Pass `2` as an argument to use [cuid2](https://github.com/paralleldrive/cuid2). + +##### nanoid() + +```zmodel +function nanoid(length: Int?): String {} +``` + +Generates an identifier based on the [nanoid](https://github.com/ai/nanoid) spec. + +##### ulid() + +```zmodel +function ulid(): String {} +``` + +Generates a unique identifier based on the [ULID](https://github.com/ulid/spec) spec. + +##### now() + +```zmodel +function now(): DateTime {} +``` + +Gets current date-time. + +##### autoincrement() + +```zmodel +function autoincrement(): Int {} +``` + +Creates a sequence of integers in the underlying database and assign the incremented +values to the ID values of the created records based on the sequence. + +##### dbgenerated() + +```zmodel +function dbgenerated(expr: String): Any {} +``` + +Represents default values that cannot be expressed in the Prisma schema (such as random()). + +##### auth() + +```zmodel +function auth(): User {} +``` + +Gets the current login user. The return type of the function is the `User` model defined in the current ZModel. + +##### future() + +```zmodel +function future(): Any {} +``` + +Gets the "post-update" state of an entity. Only valid when used in a "update" access policy. Read more about access policies [here](#access-policy). + +##### check() + +```zmodel +function check(field: FieldReference, operation String?): Boolean {} +``` + +Checks if the current user can perform the given operation on the given field. + +_Params_ + +- `field`: The field to check access for. Must be a relation field. +- `operation`: The operation to check access for. Can be "read", "create", "update", or "delete". If the operation is not provided, it defaults the operation of the containing policy rule. + +_Example_ + +```zmodel +// delegating a single operation kind +model Post { + id Int @id + author User @relation(fields: [authorId], references: [id]) + authorId Int + + // delegate "read" check to the author, equivalent to + // @@allow('read', check(author)) + @@allow('read', check(author, 'read')) +} +``` + +```zmodel +// delegating all operations +model Post { + id Int @id + author User @relation(fields: [authorId], references: [id]) + authorId Int + + // delegate all access policies to the author, equivalent to: + // @@allow('read', check(author)) + // @@allow('create', check(author)) + // @@allow('update', check(author)) + // @@allow('delete', check(author)) + @@allow('all', check(author)) +} +``` + +```zmodel +// delegating field access control +model Post { + id Int @id + title String @allow('update', check(author)) + author User @relation(fields: [authorId], references: [id]) + authorId Int +} +``` + +:::info +The `check()` function only supports singular relation fields and cannot be used with "to-many" relations. We may add support for it in the future. +::: + +##### contains() + +```zmodel + function contains(field: String, search: String, caseInSensitive: Boolean?): Boolean {} +``` + +Checks if the given field contains the search string. The search string is case-sensitive by default. Use `caseInSensitive` to toggle the case sensitivity. + +Equivalent to Prisma's [contains](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#contains) operator. + +##### search() + +```zmodel +function search(field: String, search: String): Boolean {} +``` + +Checks if the given field contains the search string using [full-text-search](https://www.prisma.io/docs/concepts/components/prisma-client/full-text-search). + +Equivalent to Prisma's [search](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#search) operator. + +##### startsWith() + +```zmodel +function startsWith(field: String, search: String): Boolean {} +``` + +Checks if the given field starts with the search string. + +Equivalent to Prisma's [startsWith](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#startswith) operator. + +##### endsWith() + +```zmodel +function endsWith(field: String, search: String): Boolean {} +``` + +Checks if the given field ends with the search string. + +Equivalent to Prisma's [endsWith](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#endswith) operator. + +##### has() + +```zmodel +function has(field: Any[], search: Any): Boolean {} +``` + +Check if the given field (list) contains the search value. + +Equivalent to Prisma's [has](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#has) operator. + +##### hasEvery() + +```zmodel +function hasEvery(field: Any[], search: Any[]): Boolean {} +``` + +Check if the given field (list) contains every element of the search list. + +Equivalent to Prisma's [hasEvery](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#hasevery) operator. + +##### hasSome() + +```zmodel +function hasSome(field: Any[], search: Any[]): Boolean {} +``` + +Check if the given field (list) contains at least one element of the search list. + +Equivalent to Prisma's [hasSome](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#hassome) operator. + +##### isEmpty() + +```zmodel +function isEmpty(field: Any[]): Boolean {} +``` + +Check if the given field (list) is empty. + +Equivalent to Prisma's [isEmpty](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#isempty) operator. + +##### currentModel() + +```zmodel +function currentModel(casing: String?): String {} +``` + +Can only be used in access policy expressions. Return the name of the model for which the policy rule is defined. If the rule is inherited to a sub model, this function returns the name of the sub model. + +The optional "casing" parameter can be used to control the casing of the returned name. Valid values are "original", "upper", "lower", "capitalize", "uncapitalize". Defaults to "original". + +##### currentOperation() + +```zmodel +function currentOperation(casing: String?): String {} +``` + +Can only be used in access policy expressions. Return the operation for which the policy rule is defined for - "create", "read", "update", or "delete". Note that a rule with "all" operation is expanded to "create", "read", "update", and "delete" rules, and the function returns corresponding value for each expanded version. + +The optional "casing" parameter can be used to control the casing of the returned name. Valid values are "original", "upper", "lower", "capitalize", "uncapitalize". Defaults to "original". + +### Examples + +Here're some examples on using field and model attributes: + +```zmodel +model User { + // unique id field with a default UUID value + id String @id @default(uuid()) + + // require email field to be unique + email String @unique + + // password is hashed with bcrypt with length of 16, omitted when returned from the CRUD services + password String @password(saltLength: 16) @omit + + // default to current date-time + createdAt DateTime @default(now()) + + // auto-updated when the entity is modified + updatedAt DateTime @updatedAt + + // mapping to a different column name in database + description String @map("desc") + + // mapping to a different table name in database + @@map("users") + + // use @@index to specify fields to create database index for + @@index([email]) + + // use @@allow to specify access policies + @@allow("create,read", true) + + // use auth() to reference the current user + // use future() to access the "post-update" state + @@allow("update", auth() == this && future().email == email) +} +``` + +### Custom attributes and functions + +You can find examples of custom attributes and functions in [ZModel Standard Library](https://github.com/zenstackhq/zenstack/blob/main/packages/schema/src/res/stdlib.zmodel). + +## Field + +Fields are typed members of models and types. + +### Syntax + +```zmodel +model Model { + [FIELD_NAME] [FIELD_TYPE] (FIELD_ATTRIBUTES)? +} +``` + +Or + +```zmodel +type Type { + [FIELD_NAME] [FIELD_TYPE] (FIELD_ATTRIBUTES)? +} +``` + +- **[FIELD_NAME]** + + Name of the field. Needs to be unique in the containing model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. + +- **[FIELD_TYPE]** + + Type of the field. Can be a scalar type, a reference to another model if the field belongs to a [model](#model), or a reference to another type if it belongs to a [type](#type). + + The following scalar types are supported: + + - String + - Boolean + - Int + - BigInt + - Float + - Decimal + - Json + - Bytes + - [Unsupported types](https://www.prisma.io/docs/concepts/components/prisma-schema/data-model#unsupported-types) + + A field's type can be any of the scalar or reference type, a list of the aforementioned type (suffixed with `[]`), or an optional of the aforementioned type (suffixed with `?`). + +- **[FIELD_ATTRIBUTES]** + + Field attributes attach extra behaviors or constraints to the field. See [Attribute](#attribute) for more information. + +### Example + +```zmodel +model Post { + // "id" field is a mandatory unique identifier of this model + id String @id @default(uuid()) + + // fields can be DateTime + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + // or string + title String + + // or integer + viewCount Int @default(0) + + // and optional + content String? + + // and a list too + tags String[] + + // and can reference another model too + comments Comment[] +} +``` + +## Relation + +Relations are connections among models. There're three types of relations: + +- One-to-one +- One-to-many +- Many-to-many + +Relations are expressed with a pair of fields and together with the special `@relation` field attribute. One side of the relation field carries the `@relation` attribute to indicate how the connection is established. + +### One-to-one relation + +The _owner_ side of the relation declares an optional field typed as the model of the _owned_ side of the relation. + +On the _owned_ side, a reference field is declared with `@relation` attribute, together with a **foreign key** field storing the id of the owner entity. + +```zmodel +model User { + id String @id + profile Profile? +} + +model Profile { + id String @id + user User @relation(fields: [userId], references: [id]) + userId String @unique +} +``` + +### One-to-many relation + +The _owner_ side of the relation declares a list field typed as the model of the _owned_ side of the relation. + +On the _owned_ side, a reference field is declared with `@relation` attribute, together with a **foreign key** field storing the id of the owner entity. + +```zmodel +model User { + id String @id + posts Post[] +} + +model Post { + id String @id + author User? @relation(fields: [authorId], references: [id]) + authorId String? +} +``` + +### Many-to-many relation + +A _join model_ is declared to connect the two sides of the relation using two one-to-one relations. + +Each side of the relation then establishes a one-to-many relation with the _join model_. + +```zmodel +model Space { + id String @id + // one-to-many with the "join-model" + members Membership[] +} + +// Membership is the "join-model" between User and Space +model Membership { + id String @id() + + // one-to-many from Space + space Space @relation(fields: [spaceId], references: [id]) + spaceId String + + // one-to-many from User + user User @relation(fields: [userId], references: [id]) + userId String + + // a user can be member of a space for only once + @@unique([userId, spaceId]) +} + +model User { + id String @id + // one-to-many with the "join-model" + membership Membership[] +} + +``` + +### Self-relations + +A relation field referencing its own model is called "self-relation". ZModel's represents self-relation in the same way as Prisma does. Please refer to the [Prisma documentation](https://www.prisma.io/docs/concepts/components/prisma-schema/relations/self-relations) for more details. + +### Referential action + +When defining a relation, you can specify what happens when one side of a relation is updated or deleted. See [Referential action](#referential-action) for details. + +## Access policy + +### Model-level policy + +Model-level access policies are defined with `@@allow` and `@@deny` attributes. They specify the eligibility of an operation over a model entity. The signatures of the attributes are: + +- `@@allow` + + ```zmodel + attribute @@allow(_ operation: String, _ condition: Boolean) + ``` + + _Params_: + + | Name | Description | + | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | + | operation | Comma separated list of operations to control, including `"create"`, `"read"`, `"update"`, and `"delete"`. Pass` "all"` as an abbreviation for including all operations. | + | condition | Boolean expression indicating if the operations should be allowed | + +- `@@deny` + + ```zmodel + attribute @@deny(_ operation: String, _ condition: Boolean) + ``` + + _Params_: + + | Name | Description | + | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | + | operation | Comma separated list of operations to control, including `"create"`, `"read"`, `"update"`, and `"delete"`. Pass` "all"` as an abbreviation for including all operations. | + | condition | Boolean expression indicating if the operations should be denied | + +### Field-level policy + +Field-level access policies are defined with `@allow` and `@deny` attributes. They control whether the annotated field can be read or updated. If a field fails "read" check, it'll be deleted when returned. If a field is set to be updated but fails "update" check, the update operation will be rejected. + +Note that it's not allowed to put "update" rule on relation fields, because whether an entity can be updated shouldn't be determined indirectly by a relation, but directly by the entity itself. However, you can put "update" rule on a foreign key field to control how a a relation can be updated. + +The signatures of the attributes are: + +- `@allow` + + ```zmodel + attribute @allow(_ operation: String, _ condition: Boolean, _ override: Boolean?) + ``` + + _Params_: + + | Name | Description | Default | + | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- | + | operation | Comma separated list of operations to control, including `"read"` and `"update"`. Pass` "all"` as an abbreviation for including all operations. | | + | condition | Boolean expression indicating if the operations should be allowed | | + | override | Boolean indicating if the field-level policy should override model-level ones. See [here](../the-complete-guide/part1/access-policy/field-level#overriding-model-level-policies) for more details. | false | + +- `@deny` + + ```zmodel + attribute @deny(_ operation: String, _ condition: Boolean) + ``` + + _Params_: + + | Name | Description | + | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | + | operation | Comma separated list of operations to control, including ``"read"` and `"update"`. Pass` "all"` as an abbreviation for including all operations. | + | condition | Boolean expression indicating if the operations should be denied | + +### Policy expressions + +Policy rules use boolean expressions to make verdicts. ZModel provides a set of literals and operators for constructing expressions of arbitrary complexity. + +``` + +Expression ::= Literal | Array | This | Null | Reference | MemberAccess | Invocation | Binary | Unary | CollectionPredicate + +Literal ::= String | Number | Boolean + +Array ::= "[" Expression [, Expression]* "]" + +This ::= "this" + +Null ::= "null" + +Reference ::= Identifier + +MemberAccess ::= Expression "." Identifier + +Operator_Precedence#table +Binary ::= Expression ("==" | "!=" | ">" | "<" | ">=" | "<=" | "&&" | "||" || "in") + +Unary ::= "!" Expression + +CollectionPredicate ::= Expression ("?" | "!" | "^") "[" Expression "]" + +``` + +Binary operator precedence follows [Javascript's rules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/). + +Collection predicate expressions are used for reaching into relation fields. You can find more details [here](#collection-predicate-expressions). + +### Using authentication in policy rules + +It's very common to use the current login user to verdict if an operation should be permitted. Therefore, ZenStack provides a built-in `auth()` attribute function that evaluates to the `User` entity corresponding to the current user. To use the function, your ZModel file must define a `User` model or a model marked with the `@@auth` attribute. + +You can use `auth()` to: + +- Check if a user is logged in + + ```zmodel + @@deny('all', auth() == null) + ``` + +- Access user's fields + + ```zmodel + @@allow('update', auth().role == 'ADMIN') + ``` + +- Compare user identity + + ```zmodel + // owner is a relation field to User model + @@allow('update', auth() == owner) + ``` + +### Accessing relation fields in policy + +As you've seen in the examples above, you can access fields from relations in policy expressions. For example, to express "a user can be read by any user sharing a space" in the `User` model, you can directly read into its `membership` field. + +```zmodel + @@allow('read', membership?[space.members?[user == auth()]]) +``` + +In most cases, when you use a "to-many" relation in a policy rule, you'll use "Collection Predicate" to express a condition. See [next section](#collection-predicate-expressions) for details. + +### Collection predicate expressions + +Collection predicate expressions are boolean expressions used to express conditions over a list. It's mainly designed for building policy rules for "to-many" relations. It has three forms of syntaxes: + +- Any + + ``` + ?[condition] + ``` + + Any element in `collection` matches `condition` + +- All + + ``` + ![condition] + ``` + + All elements in `collection` match `condition` + +- None + + ``` + ^[condition] + ``` + + None element in `collection` matches `condition` + +The `condition` expression has direct access to fields defined in the model of `collection`. E.g.: + +```zmodel + @@allow('read', members?[user == auth()]) +``` + +, in condition `user == auth()`, `user` refers to the `user` field in model `Membership`, because the collection `members` is resolved to `Membership` model. + +Also, collection predicates can be nested to express complex conditions involving multi-level relation lookup. E.g.: + +```zmodel + @@allow('read', membership?[space.members?[user == auth()]]) +``` + +In this example, `user` refers to `user` field of `Membership` model because `space.members` is resolved to `Membership` model. + +### Combining multiple rules + +A model can contain an arbitrary number of policy rules. The logic of combining model-level rules is as follows: + +- The operation is rejected if any of the conditions in `@@deny` rules evaluate to `true`. +- Otherwise, the operation is permitted if any of the conditions in `@@allow` rules evaluate to `true`. +- Otherwise, the operation is rejected. + +A field can also contain an arbitrary number of policy rules. The logic of combining field-level rules is as follows: + +- The operation is rejected if any of the conditions in `@deny` rules evaluate to `true`. +- Otherwise, if there exists any `@allow` rule and at least one of them evaluates to `true`, the operation is permitted. +- Otherwise, if there exists any `@allow` rule but none one of them evaluates to `true`, the operation is rejected. +- Otherwise, the operation is permitted. + +Please note the difference between model-level and field-level rules. Model-level access are by-default denied, while field-level access are by-default allowed. + +### "Create" rules + +The "create" policy rules should be understood as: **if an entity were to be created, would it satisfy the rules**. Or, in other words, the rules are checked "post create". + +An entity creating process works like the following: + +1. Initiate a transaction and create the entity. +2. In the same transaction, try to read the created entity with the "create" rules as filter, and see if it succeeds. +3. If the read fails, the transaction is rolled back; otherwise it's committed. + +The "post-create check" semantic allows the rules to access relations of the entity being created since they are only accessible after the create happens. For simple cases, ZenStack may apply optimizations to reject a create request without initiating a transaction, but generally speaking the "post-create check" semantic is the correct way to think about it. + +We may introduce a "pre-create" policy type in the future. + +### "Pre-update" vs." post-update" rules + +When an access policy rule is applied to a mutate operation, the entities under operation have a "pre" and "post" state. For a "create" rule, its "pre" state is empty, so the rule implicitly refers to the "post" state. For a "delete" rule, its "post" state is empty, so the rule implicitly refers to the "pre" state. + +However, for "update" rules it is ambiguous; both the "pre" and the "post" states exist. By default, for "update" rules, fields referenced in the expressions refer to the "pre" state, and you can use the `future()` function to refer to the "post" state explicitly. + +In the following example, the "update" rule uses `future()` to ensure an update cannot alter the post's owner. + +```zmodel +model Post { + id String @id @default(uuid()) + title String @length(1, 100) + author User @relation(fields: [authorId], references: [id], onDelete: Cascade) + authorId String + + // update can only be done by the author, and is not allowed to change author + @@allow('update', author == auth() && future().author == author) +} +``` + +:::info +The `future()` function is not supported in field-level access policies. To express post-update rules, put them into model-level policies. +::: + +### Examples + +#### A simple example with Post model + +```zmodel +model Post { + // reject all operations if user's not logged in + @@deny('all', auth() == null) + + // allow all operations if the entity's owner matches the current user + @@allow('all', auth() == owner) + + // posts are readable to anyone + @allow('read', true) +} +``` + +#### A more complex example with multi-user spaces + +```zmodel +model Space { + id String @id + members Membership[] + owner User @relation(fields: [ownerId], references: [id]) + ownerId String + + // require login + @@deny('all', auth() == null) + + // everyone can create a space + @@allow('create', true) + + // owner can do everything + @@allow('all', auth() == owner) + + // any user in the space can read the space + // + // Here the ?[condition] syntax is called + // "Collection Predicate", used to check if any element + // in the "collection" matches the "condition" + @@allow('read', members?[user == auth()]) +} + +// Membership is the "join-model" between User and Space +model Membership { + id String @id() + + // one-to-many from Space + space Space @relation(fields: [spaceId], references: [id]) + spaceId String + + // one-to-many from User + user User @relation(fields: [userId], references: [id]) + userId String + + // a user can be member of a space for only once + @@unique([userId, spaceId]) + + // require login + @@deny('all', auth() == null) + + // space owner can create/update/delete + @@allow('create,update,delete', space.owner == auth()) + + // user can read entries for spaces which he's a member of + @@allow('read', space.members?[user == auth()]) +} + +model User { + id String @id + email String @unique + membership Membership[] + ownedSpaces Space[] + + // allow signup + @@allow('create', true) + + // user can do everything to herself; note that "this" represents + // the current entity + @@allow('all', auth() == this) + + // can be read by users sharing a space + @@allow('read', membership?[space.members?[user == auth()]]) +} + +``` + +## Data validation + +### Overview + +Data validation is used for attaching constraints to field values. Unlike access policies, field validation rules cannot access the current user with the `auth()` function and are only checked for 'create' and 'update' operations. The main purpose of field validation is to ensure data integrity and consistency, not for access control. + +The [`@core/zod`](./plugins/zod) plugin recognizes the validation attributes and includes them into the generated Zod schemas. + +### Field-level validation attributes + +The following attributes can be used to attach validation rules to individual fields: + +#### String + +- `@length(_ min: Int?, _ max: Int?, _ message: String?)` + + Validates length of a string field. + +- `@startsWith(_ text: String, _ message: String?)` + + Validates a string field value starts with the given text. + +- `@endsWith(_ text: String, _ message: String?)` + + Validates a string field value ends with the given text. + +- `@contains(_text: String, _ message: String?)` + + Validates a string field value contains the given text. + +- `@email(_ message: String?)` + + Validates a string field value is a valid email address. + +- `@url(_ message: String?)` + + Validates a string field value is a valid url. + +- `@datetime(_ message: String?)` + + Validates a string field value is a valid ISO datetime. + +- `@regex(_ regex: String, _ message: String?)` + + Validates a string field value matches a regex. + +- `@trim(_ value: String)` + + Trims whitespace. + +- `@lower(_ value: String)` + + Converts to lowercase. + +- `@upper(_ value: String)` + + Converts to uppercase. + +:::info +Attributes `@trim`, `@lower`, and `@upper` are actually "transformation" instead of "validation". They make sure the values are transformed before storing into the database. +::: + +#### Number + +- `@gt(_ value: Int, _ message: String?)` + + Validates a number field is greater than the given value. + +- `@gte(_ value: Int, _ message: String?)` + + Validates a number field is greater than or equal to the given value. + +- `@lt(_ value: Int, _ message: String?)` + + Validates a number field is less than the given value. + +- `@lte(_ value: Int, _ message: String?)` + + Validates a number field is less than or equal to the given value. + +### Model-level validation attributes + +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?, _ path: String[]?) +``` + +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: + +- `function length(field: String, min: Int, max: Int?): Boolean` + + Validates length of a string field. + +- `function regex(field: String, regex: String): Boolean` + + Validates a string field value matches a regex. + +- `function email(field: String): Boolean` + + Validates a string field value is a valid email address. + +- `function datetime(field: String): Boolean` + + Validates a string field value is a valid ISO datetime. + +- `function url(field: String)` + + Validates a string field value is a valid url. + +- `function contains(field: String, search: String, caseInSensitive: Boolean?): Boolean` + + Validates a string field contains the search string. + +- `function startsWith(field: String, search: String): Boolean` + + Validates a string field starts with the search string. + +- `function endsWith(field: String, search: String): Boolean` + + Validates a string field ends with the search string. + +- `function has(field: Any[], search: Any): Boolean` + + Validates a list field contains the search value. + +- `function hasEvery(field: Any[], search: Any[]): Boolean` + + Validates a list field contains every element in the search list. + +- `function hasSome(field: Any[], search: Any[]): Boolean` + + Validates a list field contains some elements in the search list. + +- `function isEmpty(field: Any[]): Boolean` + + Validates a list field is null or empty. + +### Example + +```zmodel +model User { + id String @id + handle String @regex("^[0-9a-zA-Z]{4,16}$") + email String? @email @endsWith("@myorg.com", "must be an email from myorg.com") + profileImage String? @url + age Int @gte(18) + activated Boolean @default(false) + + @@validate(!activated || email != null, "activated user must have an email") +} +``` + +## Referential action + +### Overview + +When defining a relation, you can use referential action to control what happens when one side of a relation is updated or deleted by setting the `onDelete` and `onUpdate` parameters in the `@relation` attribute. + +```zmodel +attribute @relation( + _ name: String?, + fields: FieldReference[]?, + references: FieldReference[]?, + onDelete: ReferentialAction?, + onUpdate: ReferentialAction?, + map: String?) +``` + +The `ReferentialAction` enum is defined as: + +```zmodel +enum ReferentialAction { + Cascade + Restrict + NoAction + SetNull + SetDefault +} +``` + +- `Cascade` + + - **onDelete**: deleting a referenced record will trigger the deletion of referencing record. + + - **onUpdate**: updates the relation scalar fields if the referenced scalar fields of the dependent record are updated. + +- `Restrict` + + - **onDelete**: prevents the deletion if any referencing records exist. + - **onUpdate**: prevents the identifier of a referenced record from being changed. + +- `NoAction` + + Similar to 'Restrict', the difference between the two is dependent on the database being used. + + See details [here](https://www.prisma.io/docs/concepts/components/prisma-schema/relations/referential-actions#noaction ':target=blank') + +- `SetNull` + + - **onDelete**: the scalar field of the referencing object will be set to NULL. + - **onUpdate**: when updating the identifier of a referenced object, the scalar fields of the referencing objects will be set to NULL. + +- `SetDefault` + - **onDelete**: the scalar field of the referencing object will be set to the fields default value. + - **onUpdate**: the scalar field of the referencing object will be set to the fields default value. + +### Example + +```zmodel +model User { + id String @id + profile Profile? +} + +model Profile { + id String @id + user @relation(fields: [userId], references: [id], onUpdate: Cascade, onDelete: Cascade) + userId String @unique +} +``` + +## Comments + +ZModel supports both line comments (starting with `//`) and block comments (starting with `/*` and ending with `*/`). Comments on declarations (models, enums, fields, etc.) starting with triple slashes (`///`) are treated as documentation: + +- They show up as hover tooltips in IDEs. +- They are passed along to the generated Prisma schema. + +```zmodel +/// A user model +model User { + id String @id + + /// The user's email + email String @unique +} +``` + +You can also use JSDoc-style comments as documentation, however they are not passed along to the generated Prisma schema. + +```zmodel +/** + * A user model + */ +model User { + id String @id + + /** + * The user's email + */ + email String @unique +} +``` diff --git a/versioned_docs/version-3.x/samples.md b/versioned_docs/version-3.x/samples.md new file mode 100644 index 00000000..2b78bb7b --- /dev/null +++ b/versioned_docs/version-3.x/samples.md @@ -0,0 +1,8 @@ +--- +sidebar_position: 7 +sidebar_label: Sample Projects +--- + +# A Catalog of Sample Projects + +The ZenStack team maintains the following three series of sample projects. diff --git a/versioned_docs/version-3.x/service/_category_.yml b/versioned_docs/version-3.x/service/_category_.yml new file mode 100644 index 00000000..d66b3af7 --- /dev/null +++ b/versioned_docs/version-3.x/service/_category_.yml @@ -0,0 +1,7 @@ +position: 4 +label: Query as a Service +collapsible: true +collapsed: true +link: + type: generated-index + title: Query as a Service diff --git a/versioned_docs/version-3.x/service/introduction.md b/versioned_docs/version-3.x/service/introduction.md new file mode 100644 index 00000000..261e992b --- /dev/null +++ b/versioned_docs/version-3.x/service/introduction.md @@ -0,0 +1,3 @@ +# Introduction + +Coming soon 🚧 \ No newline at end of file diff --git a/versioned_docs/version-3.x/upgrade.md b/versioned_docs/version-3.x/upgrade.md new file mode 100644 index 00000000..cfeb1049 --- /dev/null +++ b/versioned_docs/version-3.x/upgrade.md @@ -0,0 +1,10 @@ +--- +description: How to upgrade to ZenStack v3 + +slug: /upgrade-v3 +sidebar_label: Upgrading to V3 +sidebar_position: 8 +--- + +# Upgrading to V3 + diff --git a/versioned_docs/version-3.x/utilities/_category_.yml b/versioned_docs/version-3.x/utilities/_category_.yml new file mode 100644 index 00000000..9dd0322c --- /dev/null +++ b/versioned_docs/version-3.x/utilities/_category_.yml @@ -0,0 +1,7 @@ +position: 5 +label: Utilities +collapsible: true +collapsed: true +link: + type: generated-index + title: Utilities diff --git a/versioned_docs/version-3.x/utilities/zod.md b/versioned_docs/version-3.x/utilities/zod.md new file mode 100644 index 00000000..5bfd1865 --- /dev/null +++ b/versioned_docs/version-3.x/utilities/zod.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 1 +description: Zod integration +--- + +# Zod Integration diff --git a/versioned_docs/version-3.x/welcome.md b/versioned_docs/version-3.x/welcome.md new file mode 100644 index 00000000..8309ace6 --- /dev/null +++ b/versioned_docs/version-3.x/welcome.md @@ -0,0 +1,10 @@ +--- +description: Welcome to ZenStack +slug: /welcome +sidebar_label: Welcome +sidebar_position: 1 +--- + +# Welcome to ZenStack V3 + +The modern data layer for TypeScript applications. diff --git a/versioned_sidebars/version-3.x-sidebars.json b/versioned_sidebars/version-3.x-sidebars.json new file mode 100644 index 00000000..fc4fe139 --- /dev/null +++ b/versioned_sidebars/version-3.x-sidebars.json @@ -0,0 +1,8 @@ +{ + "mySidebar": [ + { + "type": "autogenerated", + "dirName": "." + } + ] +} diff --git a/versions.json b/versions.json index c339c072..bbcb99fe 100644 --- a/versions.json +++ b/versions.json @@ -1 +1 @@ -["1.x"] +["1.x", "3.x"] From 4a3bc1899ebaee0d6516ef88e9bd83345f311ff1 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Fri, 1 Aug 2025 21:32:23 +0800 Subject: [PATCH 02/51] fix build --- .../version-3.x/reference/runtime-api.md | 122 - .../reference/server-adapters/_category_.yml | 7 - .../server-adapters/_error-handling.md | 3 - .../reference/server-adapters/_options.mdx | 66 - .../reference/server-adapters/_using-api.mdx | 137 -- .../api-handlers/_data_type_serialization.md | 16 - .../server-adapters/api-handlers/index.mdx | 31 - .../server-adapters/api-handlers/rest.mdx | 982 -------- .../server-adapters/api-handlers/rpc.mdx | 275 --- .../reference/server-adapters/elysia.mdx | 69 - .../reference/server-adapters/express.mdx | 66 - .../reference/server-adapters/fastify.mdx | 56 - .../reference/server-adapters/hono.mdx | 57 - .../reference/server-adapters/nestjs.mdx | 268 --- .../reference/server-adapters/next.mdx | 124 -- .../reference/server-adapters/nuxt.mdx | 44 - .../reference/server-adapters/sveltekit.mdx | 63 - .../version-3.x/reference/zmodel-language.md | 1979 ----------------- 18 files changed, 4365 deletions(-) delete mode 100644 versioned_docs/version-3.x/reference/server-adapters/_category_.yml delete mode 100644 versioned_docs/version-3.x/reference/server-adapters/_error-handling.md delete mode 100644 versioned_docs/version-3.x/reference/server-adapters/_options.mdx delete mode 100644 versioned_docs/version-3.x/reference/server-adapters/_using-api.mdx delete mode 100644 versioned_docs/version-3.x/reference/server-adapters/api-handlers/_data_type_serialization.md delete mode 100644 versioned_docs/version-3.x/reference/server-adapters/api-handlers/index.mdx delete mode 100644 versioned_docs/version-3.x/reference/server-adapters/api-handlers/rest.mdx delete mode 100644 versioned_docs/version-3.x/reference/server-adapters/api-handlers/rpc.mdx delete mode 100644 versioned_docs/version-3.x/reference/server-adapters/elysia.mdx delete mode 100644 versioned_docs/version-3.x/reference/server-adapters/express.mdx delete mode 100644 versioned_docs/version-3.x/reference/server-adapters/fastify.mdx delete mode 100644 versioned_docs/version-3.x/reference/server-adapters/hono.mdx delete mode 100644 versioned_docs/version-3.x/reference/server-adapters/nestjs.mdx delete mode 100644 versioned_docs/version-3.x/reference/server-adapters/next.mdx delete mode 100644 versioned_docs/version-3.x/reference/server-adapters/nuxt.mdx delete mode 100644 versioned_docs/version-3.x/reference/server-adapters/sveltekit.mdx diff --git a/versioned_docs/version-3.x/reference/runtime-api.md b/versioned_docs/version-3.x/reference/runtime-api.md index 10d7cf39..22d84bdd 100644 --- a/versioned_docs/version-3.x/reference/runtime-api.md +++ b/versioned_docs/version-3.x/reference/runtime-api.md @@ -6,125 +6,3 @@ sidebar_label: Runtime API # Runtime API Reference -This document provides references for runtime APIs exported from the `@zenstackhq/runtime` package. - -### enhance - -#### Description - -Creates an enhanced wrapper for a `PrismaClient`. The return value has the same APIs as the original `PrismaClient`. - -#### Signature - -```ts -function enhance( - prisma: DbClient, - context?: EnhancementContext, - options?: EnhancementOptions -): DbClient; -``` - -##### Parameter `prisma` - -The PrismaClient instance to enhance. - -##### Parameter `context` - -The context to for evaluating access policies with the following typing. - -```ts -type EnhancementContext = { - user?: Record -}; -``` - -| Field | Description | -| ----- | ----------- | -| user | The user object that provides value for the `auth()` function call in access policies. If provided. Its shape should be consistent with the `User` model in your ZModel, with all fields optional except for id field(s). Pass `undefined` to represent an anonymous user, and the `auth()` function call will evaluate to `null` in that case. | - -##### Parameter `options` - -Options with the following typing. - -```ts -type TransactionIsolationLevel = - | 'ReadUncommitted' - | 'ReadCommitted' - | 'RepeatableRead' - | 'Snapshot' - | 'Serializable'; - -type SimpleEncryption = { - encryptionKey: Uint8Array; - decryptionKeys?: Uint8Array[]; -} - -type CustomEncryption = { - encrypt: (model: string, field: FieldInfo, plain: string) => Promise; - decrypt: (model: string, field: FieldInfo, cipher: string) => Promise; -}; - -type ValidationOptions = { - inputOnlyValidationForUpdate?: boolean; -}; - -type EnhancementOptions = { - kinds?: EnhancementKind[]; - logPrismaQuery?: boolean; - errorTransformer?: ErrorTransformer; - transactionMaxWait?: number; - transactionTimeout?: number; - transactionIsolationLevel?: TransactionIsolationLevel; - encryption?: SimpleEncryption | CustomEncryption; - validation?: ValidationOptions; -}; -``` - -| Field | Description | Default | -| ------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------- | -| kinds | The kinds of enhancements to apply. By default all enhancements are applied. See [the next section](#enhancement-kinds) for more details. | All enhancement kinds | -| logPrismaQuery | Whether to log queries sent to Prisma client. Log will be emitted with "info" level, so please make sure you [turn that level on](https://www.prisma.io/docs/concepts/components/prisma-client/working-with-prismaclient/logging#log-to-stdout) when creating Prisma client | false | -| errorTransformer | A function for transforming error thrown by the enhanced `PrismaClient` into a custom one. | | -| transactionMaxWait | The `maxWait` option (in ms) passed to `prisma.$transaction()` call for transactions initiated by ZenStack. | Database default | -| transactionTimeout | The `timeout` option (in ms) passed to `prisma.$transaction()` call for transactions initiated by ZenStack. | Database default | -| transactionIsolationLevel | The `isolationLevel` option passed to `prisma.$transaction()` call for transactions initiated by ZenStack. | Database default | -| encryption | Field encryption settings. Only required when using the [field encryption](../guides/field-encryption.md) feature. | | -| validation.inputOnlyValidationForUpdate | By default, ZenStack validates an entity after "update" operation to ensure the final result satisfies validation rules as a whole. This implies if the record under update doesn't satisfy the rules prior to update, the update operation will fail even if the fields causing validation errors are not affected by the operation. You can set this option to `true` to let ZenStack only validate data contained in the input args. | false | - -#### Enhancement Kinds - -Here are the kinds of enhancements available: - -- `policy` - - Enforces model-level and field-level access policies defined with `@@allow`, `@@deny`, `@allow`, and `@deny`. - -- `validation` - - Validates create and update input data against rules defined with [data validation attributes](../reference/zmodel-language#data-validation). - -- `delegate` - - Support for modeling [polymorphic relations](../guides/polymorphism) with delegated types pattern. - -- `password` - - Automatically hashes fields marked with the `@password` attribute using `bcryptjs` before saving to the database. - -- `omit` - - Automatically omits fields marked with the `@omit` attribute from read results. - -- `encryption` - - Transparently encrypt and decrypt fields marked with the `@encrypted` attribute. See [this guide](../guides/field-encryption.md) for more details. - -#### Example - -```ts -const session = getSession(); -const enhancedClient = enhance(prisma, - { user: session.user }, - { kinds: ['policy', 'password']} -); -``` diff --git a/versioned_docs/version-3.x/reference/server-adapters/_category_.yml b/versioned_docs/version-3.x/reference/server-adapters/_category_.yml deleted file mode 100644 index f6e05f3e..00000000 --- a/versioned_docs/version-3.x/reference/server-adapters/_category_.yml +++ /dev/null @@ -1,7 +0,0 @@ -position: 7 -label: Server Adapters -collapsible: true -collapsed: true -link: - type: generated-index - title: Server Adapters diff --git a/versioned_docs/version-3.x/reference/server-adapters/_error-handling.md b/versioned_docs/version-3.x/reference/server-adapters/_error-handling.md deleted file mode 100644 index db2a9b05..00000000 --- a/versioned_docs/version-3.x/reference/server-adapters/_error-handling.md +++ /dev/null @@ -1,3 +0,0 @@ -### Error Handling - -Refer to the specific sections for [RPC Handler](./api-handlers/rpc#http-status-code-and-error-responses) and [RESTful Handler](./api-handlers/rest#error-handling). diff --git a/versioned_docs/version-3.x/reference/server-adapters/_options.mdx b/versioned_docs/version-3.x/reference/server-adapters/_options.mdx deleted file mode 100644 index dee02d69..00000000 --- a/versioned_docs/version-3.x/reference/server-adapters/_options.mdx +++ /dev/null @@ -1,66 +0,0 @@ -import CodeBlock from '@theme/CodeBlock'; - -- getPrisma (required) - -
{props.getPrisma}
- - A callback for getting a PrismaClient instance for talking to the database. Usually you'll use an enhanced instance created with ZenStack's [`enhance`](../runtime-api#enhance) API to ensure access policies are enforced. - -- logger (optional) - -
{'LoggerConfig'}
- - Configuration for customizing logging behavior. - -- modelMeta (optional) - -
{'ModelMeta'}
- - Model metadata. By default loaded from the `node_module/.zenstack/model-meta` module. You can pass it in explicitly if you configured ZenStack to output to a different location. E.g.: `require('output/model-meta').default`. - -- zodSchemas (optional) - -
{'ModelZodSchema | boolean | undefined'}
- - Provides the Zod schemas used for validating CRUD request input. The Zod schemas can be generated with the `@core/zod` plugin. Pass `true` for this option to load the schemas from the default location. If you configured `@core/zod` plugin to output to a custom location, you can load the schemas explicitly and pass the loaded module to this option. E.g.: - - ```ts - factory({ - ... - zodSchemas: require('./zod'), - }); - ``` - - Not passing this option or passing in `undefined` disables input validation. - -- handler (optional) - -
{'(req: RequestContext) => Promise'}
- - The request handler function. This option determines the API endpoints and its input and output formats. Currently ZenStack supports two styles of APIs: RPC (the default) and RESTful. - - - RPC - - The goal of the RPC-style API handler is to fully mirror [PrismaClient's API](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#model-queries) across the network, so that developers can continue enjoying the convenience and flexibility of Prisma's query syntax. This is the default choice for the `handler` option. - - The RPC-style handler can be created like: - - ```ts - import { RPCApiHandler } from '@zenstackhq/server/api'; - const handler = RPCApiHandler(); - ``` - - For more details, please check out [RPC API Handler](./api-handlers/rpc). - - - RESTful - - The goal of RESTful-style API handler is to provide a resource-centric RESTful API using [JSON:API](https://jsonapi.org/) as transportation format. - - The RESTful-style handler can be created like: - - ```ts - import { RestApiHandler } from '@zenstackhq/server/api'; - const handler = RestApiHandler({ endpoint: 'http://myhost/api' }); - ``` - - For more details, please check out [RESTful API Handler](./api-handlers/rest). diff --git a/versioned_docs/version-3.x/reference/server-adapters/_using-api.mdx b/versioned_docs/version-3.x/reference/server-adapters/_using-api.mdx deleted file mode 100644 index 1d16241c..00000000 --- a/versioned_docs/version-3.x/reference/server-adapters/_using-api.mdx +++ /dev/null @@ -1,137 +0,0 @@ -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - -The APIs can be used in the following three ways: - -1. With generated client hooks - - ZenStack provides plugins to generate client hooks from the ZModel targeting the most popular frontend data fetching libraries: [TanStack Query](https://tanstack.com/query/latest) and [SWR](https://swr.vercel.app/). The generated hooks can be used to make API calls to the server adapters. Refer to the follow docs for detailed usage: - - - [`@zenstackhq/tanstack-query`](../plugins/tanstack-query) - - [`@zenstackhq/swr`](../plugins/swr) -

- - :::info - The generated client hooks assumes the server adapter uses [RPC-style API handler](./api-handlers/rpc) (which is the default setting). - ::: - -1. With direct HTTP calls - - You can make direct HTTP calls to the server adapter using your favorite client libraries like `fetch` or `axios`. Refer to the documentation of the [API Handlers](./api-handlers/) for the API endpoints and data formats. - - Here's an example using `fetch`: - - - - - ```ts - // create a user with two posts - const r = await fetch(`/api/user/create`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - include: { posts: true }, - data: { - email: 'user1@abc.com', - posts: { - create: [{ title: 'Post 1' }, { title: 'Post 2' }], - }, - }, - }), - }); - - console.log(await r.json()); - ``` - - Output: - - ```json - { - "id": 1, - "email": "user1@abc.com", - "posts": [ - { - "id": 1, - "createdAt": "2023-03-14T07:45:04.036Z", - "updatedAt": "2023-03-14T07:45:04.036Z", - "title": "Post 1", - "authorId": 1 - }, - { - "id": 2, - "createdAt": "2023-03-14T07:45:04.036Z", - "updatedAt": "2023-03-14T07:45:04.036Z", - "title": "Post 2", - "authorId": 1 - } - ] - } - ``` - - - - - - ```ts - // create a user and attach two posts - const r = await fetch(`/api/user`, { - method: 'POST', - headers: { 'Content-Type': 'application/vnd.api+json' }, - body: JSON.stringify({ - data: { - type: 'user', - attributes: { - email: 'user1@abc.com' - }, - relationships: { - posts: { - data: [ - { type: 'post', id: 1 }, - { type: 'post', id: 2 } - ] - } - } - } - }) - }); - - console.log(await r.json()); - ``` - - Output: - - ```json - { - "jsonapi": { "version": "1.1" }, - "data": { - "type": "user", - "id": 1, - "attributes": { - "email": "user1@abc.com", - }, - "links": { - "self": "http://localhost/api/user/1", - }, - "relationships": { - "posts": { - "links": { - "self": "http://localhost/api/user/1/relationships/posts", - "related": "http://localhost/api/user/1/posts", - }, - "data": [ - { "type": "post", "id": 1 }, - { "type": "post", "id": 2 }, - ], - }, - }, - }, - } - ``` - - - - - -1. With third-party client generators - - ZenStack provides an [OpenAPI](../plugins/openapi) plugin for generating Open API 3.x specification from the ZModel. The generated OpenAPI spec can be used to generate client libraries for various languages and frameworks. For example, you can use [openapi-typescript](https://github.com/drwpow/openapi-typescript) to generate a typescript client. diff --git a/versioned_docs/version-3.x/reference/server-adapters/api-handlers/_data_type_serialization.md b/versioned_docs/version-3.x/reference/server-adapters/api-handlers/_data_type_serialization.md deleted file mode 100644 index d22a602f..00000000 --- a/versioned_docs/version-3.x/reference/server-adapters/api-handlers/_data_type_serialization.md +++ /dev/null @@ -1,16 +0,0 @@ -- `DateTime` - - ISO 8601 string - -- `Bytes` - - Base64-encoded string - -- `BigInt` - - String representation - -- `Decimal` - - String representation - \ No newline at end of file diff --git a/versioned_docs/version-3.x/reference/server-adapters/api-handlers/index.mdx b/versioned_docs/version-3.x/reference/server-adapters/api-handlers/index.mdx deleted file mode 100644 index df4074ec..00000000 --- a/versioned_docs/version-3.x/reference/server-adapters/api-handlers/index.mdx +++ /dev/null @@ -1,31 +0,0 @@ ---- -sidebar_position: 100 ---- - -import useBaseUrl from '@docusaurus/useBaseUrl'; -import ThemedImage from '@theme/ThemedImage'; - -# API Handlers - -ZenStack supports two API styles: ***rpc*** and ***rest***: - -- ***rpc*** style API directly mirrors Prisma client's API, thus provides endpoints like `[model]/findMany`, `[model]/create`, etc. Its input and output data format also aligns with that of Prisma client. - -- ***rest*** style API is designed to be more RESTful, thus provides endpoints like `[model]`, `[model]/[id]`, `[model]/[id]/relationships/[relationship]`, etc. It uses [JSON:API](https://jsonapi.org/) as its data format. - -API handlers are framework-agnostic and deals with canonicalized request and response objects. It's the responsibility of the server adapters to translate the framework-specific request and response types. You can use either of these two API handlers with any server adapter. - -The following diagram illustrates their relationships with server adapters. - - - -Checkout the reference pages for detailed information about these API handlers: - -- [RPC API Handler](./rpc) -- [RESTful API Handler](./rest) diff --git a/versioned_docs/version-3.x/reference/server-adapters/api-handlers/rest.mdx b/versioned_docs/version-3.x/reference/server-adapters/api-handlers/rest.mdx deleted file mode 100644 index 67365c6f..00000000 --- a/versioned_docs/version-3.x/reference/server-adapters/api-handlers/rest.mdx +++ /dev/null @@ -1,982 +0,0 @@ ---- -description: RESTful-style API handler that provides resource-centric endpoints -sidebar_position: 2 -title: RESTful API Handler ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import DataTypeSerialization from './_data_type_serialization.md'; - -# RESTful API Handler - -## Introduction - -The RESTful-style API handler exposes CRUD APIs as RESTful endpoints using [JSON:API](https://jsonapi.org/) as transportation format. The API handler is not meant to be used directly; instead, you should use it together with a [server adapter](../../../category/server-adapters) which handles the request and response API for a specific framework. - -It can be created as the following: - - - - -```ts title='/src/app/api/model/[...path]/route.ts' -import { NextRequestHandler } from '@zenstackhq/server/next'; -import { RestApiHandler } from '@zenstackhq/server/api'; -import { getPrisma } from '~/lib/db'; - -const handler = NextRequestHandler({ - getPrisma, - useAppDir: true, - handler: RestApiHandler({ endpoint: 'http://myhost/api' }) -}); - -export { - handler as GET, - handler as POST, - handler as PUT, - handler as PATCH, - handler as DELETE, -}; -``` - - - - - -```ts title='/src/hooks.server.ts' -import { SvelteKitHandler } from '@zenstackhq/server/sveltekit'; -import { RestApiHandler } from '@zenstackhq/server/api'; -import { getPrisma } from './lib/db'; - -export const handle = SvelteKitHandler({ - prefix: '/api/model', - getPrisma, - handler: RestApiHandler({ endpoint: 'http://myhost/api/model' }) -}); -``` - - - - - -```ts title='/server/api/model/[...].ts' -import { createEventHandler } from '@zenstackhq/server/nuxt'; -import { RestApiHandler } from '@zenstackhq/server/api'; -import { getPrisma } from './lib/db'; - -export default createEventHandler({ - handler: RestApiHandler({ endpoint: 'http://myhost/api/model' }) - getPrisma -}); -``` - - - - - -The factory function accepts an options object with the following fields: - -- endpoint - - Required. A `string` field representing the base URL of the RESTful API, used for generating resource links. - -- pageSize - - Optional. A `number` field representing the default page size for listing resources and relationships. Defaults to 100. Set to Infinity to disable pagination. - -- modelNameMapping - - Optional. An `Record` value that provides a mapping from model names (as defined in ZModel) to URL path names. This is useful for example when you want to use plural names in URL endpoints: - - ```ts - // endpoint for accessing User model will then be ".../users" - RestApiHandler({ - modelNameMapping: { - User: 'users' - } - }) - ``` - - The mapping can be partial. You only need to specify the model names that you want to override. If a mapping is provided, only the mapped url path is valid, and accessing to unmapped path will be denied. - - -## Endpoints and Features - -The RESTful API handler conforms to the the [JSON:API](https://jsonapi.org/format/) v1.1 specification for its URL design and input/output format. The following sections list the endpoints and features are implemented. The examples refer to the following schema modeling a blogging app: - -```zmodel -model User { - id Int @id @default(autoincrement()) - email String - posts Post[] -} - -model Profile { - id Int @id @default(autoincrement()) - gender String - user User @relation(fields: [userId], references: [id]) - userId Int @unique -} - -model Post { - id Int @id @default(autoincrement()) - title String - published Boolean @default(false) - viewCount Int @default(0) - author User @relation(fields: [authorId], references: [id]) - authorId Int - comments Comment[] -} - -model Comment { - id Int @id @default(autoincrement()) - content String - post Post @relation(fields: [postId], references: [id]) - postId Int -} -``` - -### Listing resources - -A specific type of resource can be listed using the following endpoint: - -``` -GET /:type -``` - -#### Status codes - -- 200: The request was successful and the response body contains the requested resources. -- 400: The request was malformed. -- 403: The request was forbidden. -- 404: The requested resource type does not exist. -- 422: The request violated data validation rules. - -#### Examples - -```ts -GET /post -``` - -```json -{ - "meta": { - "total": 1 - }, - "data": [ - { - "attributes": { - "authorId": 1, - "published": true, - "title": "My Awesome Post", - "viewCount": 0 - }, - "id": 1, - "links": { - "self": "http://myhost/api/post/1" - }, - "relationships": { - "author": { - "data": { "id": 1, "type": "user" }, - "links": { - "related": "http://myhost/api/post/1/author/1", - "self": "http://myhost/api/post/1/relationships/author/1" - } - } - }, - "type": "post" - } - ], - "jsonapi": { - "version": "1.1" - }, - "links": { - "first": "http://myhost/api/post?page%5Blimit%5D=100", - "last": "http://myhost/api/post?page%5Boffset%5D=0", - "next": null, - "prev": null, - "self": "http://myhost/api/post" - } -} -``` - -### Fetching a resource - -A unique resource can be fetched using the following endpoint: - -```ts -GET /:type/:id -``` - -#### Status codes - -- 200: The request was successful and the response body contains the requested resource. -- 400: The request was malformed. -- 403: The request was forbidden. -- 404: The requested resource type or ID does not exist. - -#### Examples - -```ts -GET /post/1 -``` - -```json -{ - "data": { - "attributes": { - "authorId": 1, - "published": true, - "title": "My Awesome Post", - "viewCount": 0 - }, - "id": 1, - "links": { - "self": "http://myhost/api/post/1" - }, - "relationships": { - "author": { - "data": { "id": 1, "type": "user" }, - "links": { - "related": "http://myhost/api/post/1/author/1", - "self": "http://myhost/api/post/1/relationships/author/1" - } - } - }, - "type": "post" - }, - "jsonapi": { - "version": "1.1" - }, - "links": { - "self": "http://myhost/api/post/1" - } -} -``` - -### Fetching relationships - -A resource's relationships can be fetched using the following endpoint: - -```ts -GET /:type/:id/relationships/:relationship -``` - -#### Status codes - -- 200: The request was successful and the response body contains the requested relationships. -- 400: The request was malformed. -- 403: The request was forbidden. -- 404: The requested resource type, ID, or relationship does not exist. - -#### Examples - -1. Fetching a to-one relationship - - ```ts - GET /post/1/relationships/author - ``` - - ```json - { - "data" : { "id" : 1, "type" : "user" }, - "jsonapi" : { - "version" : "1.1" - }, - "links" : { - "self" : "http://myhost/api/post/1/relationships/author" - } - } - ``` - -1. Fetching a to-many relationship - - ```ts - GET /user/1/relationships/posts - ``` - - ```json - { - "data" : [ - { "id" : 1, "type" : "post" }, - { "id" : 2, "type" : "post" } - ], - "jsonapi" : { - "version" : "1.1" - }, - "links" : { - "first" : "http://myhost/api/user/1/relationships/posts?page%5Blimit%5D=100", - "last" : "http://myhost/api/user/1/relationships/posts?page%5Boffset%5D=0", - "next" : null, - "prev" : null, - "self" : "http://myhost/api/user/1/relationships/posts" - } - } - ``` - -### Fetching related resources - -```ts -GET /:type/:id/:relationship -``` - -#### Status codes - -- 200: The request was successful and the response body contains the requested relationship. -- 400: The request was malformed. -- 403: The request was forbidden. -- 404: The requested resource type, ID, or relationship does not exist. - -#### Examples - -```ts -GET /post/1/author -``` - -```json -{ - "data" : { - "attributes" : { - "email" : "emily@zenstack.dev", - "name" : "Emily" - }, - "id" : 1, - "links" : { - "self" : "http://myhost/api/user/1" - }, - "relationships" : { - "posts" : { - "links" : { - "related" : "http://myhost/api/user/1/posts", - "self" : "http://myhost/api/user/1/relationships/posts" - } - } - }, - "type" : "user" - }, - "jsonapi" : { - "version" : "1.1" - }, - "links" : { - "self" : "http://myhost/api/post/1/author" - } -} -``` - -### Fine-grained data fetching - -#### Filtering - -You can use the `filter[:selector1][:selector2][...]=value` [query parameter family](https://jsonapi.org/format/#query-parameters-families) to filter resource collections or relationship collections. - -##### Examples - -1. Equality filter against plain field - - ```ts - GET /api/post?filter[published]=false - ``` - -1. Equality filter against relationship - - Relationship field can be filtered directly by its id. - - ```ts - GET /api/post?filter[author]=1 - ``` - - If the relationship is to-many, the filter has "some" semantic and evaluates to `true` if any of the items in the relationship matches. - - ```ts - GET /api/user?filter[posts]=1 - ``` - -1. Filtering with multiple values - - Multiple filter values can be separated by comma. Items statisfying any of the values will be returned. - - ```ts - GET /api/post?filter[author]=1,2 - ``` - -1. Multiple filters - - A request can carry multiple filters. Only items statisfying all filters will be returned. - - ```ts - GET /api/post?filter[author]=1&filter[published]=true - ``` - -1. Deep filtering - - A filter can carry multiple field selectors to reach into relationships. - - ```ts - GET /api/post?filter[author][name]=Emily - ``` - - When reaching into a to-many relationship, the filter has "some" semantic and evaluates to `true` if any of the items in the relationship matches. - - ``` - GET /api/user?filter[posts][published]=true - ``` - -1. Filtering with comparison operators - - Filters can go beyond equality by appending an "operator suffix". - - ```ts - GET /api/post?filter[viewCount$gt]=100 - ``` - - The following operators are supported: - - - **$lt** - - Less than - - - **$lte** - - Less than or equal to - - - **$gt** - - Greater than - - - **$gte** - - Greater than or equal to - - - **$contains** - - String contains - - - **$icontains** - - Case-insensitive string contains - - - **$search** - - String full-text search - - - **$startsWith** - - String starts with - - - **$endsWith** - - String ends with - - - **$has** - - Collection has value - - - **$hasEvery** - - Collection has every element in value - - - **$hasSome** - - Collection has some elements in value - - - **$isEmpty** - - Collection is empty - -#### Sorting - -You can use the `sort` query parameter to sort resource collections or relationship collections. The value of the parameter is a comma-separated list of fields names. The order of the fields in the list determines the order of sorting. By default, sorting is done in ascending order. To sort in descending order, prefix the field name with a minus sign. - -##### Examples - -```ts -GET /api/post?sort=createdAt,-viewCount -``` - -#### Pagination - -When creating a RESTful API handler, you can pass in a `pageSize` option to control pagination behavior of fetching a collection of resources, related resources, and relationships. By default the page size is 100, and you can disable pagination by setting `pageSize` option to `Infinity`. - -When fetching a collection resource or relationship, you can use the `page[offset]=value` and `page[limit]=value` [query parameter family](https://jsonapi.org/format/#query-parameters-families) to fetch a specific page. They're mapped to `skip` and `take` parameters in the query arguments sent to PrismaClient. - -The response data of collection fetching contains pagination links that facilitate navigating through the collection. The "meta" section also contains the total count available. E.g.: - -```json -{ - "meta": { - "total": 10 - }, - "data" : [ - ... - ], - "links" : { - "first" : "http://myhost/api/post?page%5Blimit%5D=2", - "last" : "http://myhost/api/post?page%5Boffset%5D=4", - "next" : "http://myhost/api/post?page%5Boffset%5D=4&page%5Blimit%5D=2", - "prev" : "http://myhost/api/post?page%5Boffset%5D=0&page%5Blimit%5D=2", - "self" : "http://myhost/api/post" - } -} -``` - -##### Examples - -1. Fetching a specific page of resources - - ```ts - GET /api/post?page[offset]=10&page[limit]=5 - ``` - -1. Fetching a specific page of relationships - - ```ts - GET /api/user/1/relationships/posts?page[offset]=10&page[limit]=5 - ``` - -1. Fetching a specific page of related resources - - ```ts - GET /api/user/1/posts?page[offset]=10&page[limit]=5 - ``` - -#### Including related resources - -You can use the `include` query parameter to include related resources in the response. The value of the parameter is a comma-separated list of fields names. Field names can contain dots to reach into nested relationships. - -When including related resources, the response data takes the form of [Compound Documents](https://jsonapi.org/format/#document-compound-documents) and contains a `included` field carrying normalized related resources. E.g.: - -```json -{ - "data" : [ - { - "attributes" : { - ... - }, - "id" : 1, - "relationships" : { - "author" : { - "data" : { "id" : 1, "type" : "user" } - } - }, - "type" : "post" - } - ], - "included" : [ - { - "attributes" : { - "email" : "emily@zenstack.dev", - "name" : "Emily" - }, - "id" : 1, - "links" : { - "self" : "http://myhost/api/user/1" - }, - "relationships" : { - "posts" : { - "links" : { - "related" : "http://myhost/api/user/1/posts", - "self" : "http://myhost/api/user/1/relationships/posts" - } - } - }, - "type" : "user" - } - ] -} -``` - -##### Examples - -1. Including a direct relationship - - ```ts - GET /api/post?include=author - ``` - -1. Including a deep relationship - - ```ts - GET /api/post?include=author.profile - ``` - -1. Including multiple relationships - - ```ts - GET /api/post?include=author,comments - ``` - -### Creating a resource - -A new resource can be created using the following endpoint: - -``` -POST /:type -``` - -#### Status codes - -- 201: The request was successful and the resource was created. -- 400: The request was malformed. -- 403: The request was forbidden. -- 404: The requested resource type does not exist. - -#### Examples - -1. Creating a resource - ```json - POST /user - { - "data": { - "type": "user", - "attributes": { - "name": "Emily", - "email": "emily@zenstack.dev" - } - } - } - ``` - -1. Creating a resource with relationships attached - - ```json - POST /user - { - "data": { - "type": "user", - "attributes": { - "name": "Emily", - "email": "emily@zenstack.dev" - }, - "relationships": { - "posts": { - "data": [{ "type": "post", "id": 1 }] - } - } - } - } - ``` - -### Updating a resource - -A resource can be updated using the following endpoints: - -```ts -PUT /:type/:id -PATCH /:type/:id -``` - -Both `PUT` and `PATCH` do partial update and has exactly the same behavior. - -:::info -Besides plain fields, you can also include relationships in the request body. Please note that this won't update the related resource; instead if only replaces the relationships. If you update a to-many relationship, the new collection will entirely replace the old one. - -Relationships can also be manipulated directly. See [Manipulating Relationships](#manipulating-relationships) for more details. -::: - -#### Status codes - -- 200: The request was successful and the resource was updated. -- 400: The request was malformed. -- 403: The request was forbidden. -- 404: The requested resource type or ID does not exist. - -#### Examples - -1. Updating a resource - - ```json - PUT /post/1 - { - "data": { - "type": "post", - "attributes": { - "title": "My Awesome Post" - } - } - } - ``` - -1. Updating a resource's relationships - - ```json - PUT /user/1 - { - "data": { - "type": "user", - "relationships": { - "posts": { - "data": [{ "type": "post", "id": 2 }] - } - } - } - } - ``` - - -### Upserting a resource - -JSON:API didn't specify a convention for "upsert" operations. ZenStack uses a variation of the "create" operation to represent "upsert", and uses the request meta to indicate the intention. See details in [examples](#examples-10). - -``` -POST /:type -``` - -#### Status codes - -- 201: The request was successful and the resource was created. -- 200: The request was successful and the resource was updated. -- 400: The request was malformed. -- 403: The request was forbidden. -- 404: The requested resource type does not exist. - -#### Examples - -```json -POST /user -{ - "data": { - "type": "user", - "attributes": { - "id": 1, - "name": "Emily", - "email": "emily@zenstack.dev" - } - }, - "meta": { - "operation": "upsert", - "matchFields": ["id"], - } -} -``` - -The `meta.operation` field must be "upsert", and the `meta.matchFields` field must be an array of field names that are used to determine if the resource already exists. If an existing resource is found, "update" operation is conducted, otherwise "create". The `meta.matchFields` fields must be unique fields, and they must have corresponding entries in `data.attributes`. - -### Deleting a resource - -A resource can be deleted using the following endpoint: - -#### Status codes - -- 204: The request was successful and the resource was deleted. -- 403: The request was forbidden. -- 404: The requested resource type or ID does not exist. - -```ts -DELETE /:type/:id -``` - -### Manipulating relationships - -Relationships can be manipulated using the following endpoints: - -#### Adding to a to-many relationship - -```ts -POST /:type/:id/relationships/:relationship -``` - -##### Status codes - -- 200: The request was successful and the relationship was updated. -- 403: The request was forbidden. -- 404: The requested resource type, ID, or relationship does not exist. - -##### Examples - -```json -POST /user/1/relationships/posts -{ - "data": [ - { "type": "post", "id": "1" }, - { "type": "post", "id": "2" } - ] -} -``` - -#### Updating a relationship (to-one or to-many) - -```ts -PUT /:type/:id/relationships/:relationship -PATCH /:type/:id/relationships/:relationship -``` - -:::info -`PUT` and `PATCH` has exactly the same behavior and both relace the existing relationships with the new ones entirely. -::: - -##### Status codes - -- 200: The request was successful and the relationship was updated. -- 403: The request was forbidden. -- 404: The requested resource type, ID, or relationship does not exist. - -##### Examples - -1. Replacing a to-many relationship - - ```json - PUT /user/1/relationships/posts - { - "data": [ - { "type": "post", "id": "1" }, - { "type": "post", "id": "2" } - ] - } - ``` - -1. Replacing a to-one relationship - - ```json - PUT /post/1/relationships/author - { - "data": { "type": "user", "id": "2" } - } - ``` - -1. Clearing a to-many relationship - - ```json - PUT /user/1/relationships/posts - { - "data": [] - } - ``` - -1. Clearing a to-one relationship - - ```json - PUT /post/1/relationships/author - { - "data": null - } - ``` - -## Compound ID Fields - -Prisma allows a model to have compound ID fields, e.g.: - -```zmodel -model Post { - id1 Int - id2 Int - @@id([id1, id2]) -} -``` - -The JSON:API specification doesn't have a native way to represent compound IDs. To mitigate this limitation, when returning an entity with compound IDs, ZenStack synthesizes an "id" field to carry the ID values joined with underscore: - -```json -{ - "data": { - "id": "1_2", - "attributes": { - "id1": 1, - "id2": 2, - ... - }, - "links" : { - "self" : "http://localhost:3100/api/model/post/1_2" - }, - ... - } -} -``` - -You can use this ID value convension in places where an ID is needed, e.g., reading a single entity. - -```ts -GET /post/1_2 -``` - -Limitations: - -1. Joining ID values with underscore implies that the ID values themselves cannot contain underscores. We'll make the separator configurable in the future. -1. Prisma allows you to create a name for the compound ID field. Such usage is not yet supported by the RESTful API handler. - -> *Special thanks to [Thomas Sunde Nielsen](https://github.com/thomassnielsen) for implementing this feature!* - -## Serialization - -ZenStack uses [superjson](https://github.com/blitz-js/superjson) to serialize and deserialize data. Superjson generates two parts during serialization: - -- json: - - The JSON-compatible serialization result. - -- meta: - - The serialization metadata including information like field types that facilitates deserialization. - -If the data only involves simple data types, the serialization result is the same as regular `JSON.stringify`, and no `meta` part is generated. However, for complex data types (like `Bytes`, `Decimal`, etc.), a `meta` object will be generated, which needs to be carried along when sending the request, and will also be included in the response. - -When sending requests, if superjson-serializing the request body results in a `meta` object, it should be put into a ```{ "serialization": meta }``` object and included in the `meta` field of the request body. For example, if you have a `bytes` field of type `Bytes`, the request body should look like: - -```json -POST /post -{ - "data": { - "type": "post", - "attributes": { - ... - "bytes": "AQID" // base64-encoded bytes - } - }, - "meta": { - "serialization": {"values": { "data.attributes.bytes": [[ "custom", "Bytes"]] } } - } -} -``` - -Correspondingly, the response body of a query may look like: - -```json -GET /post/1 -{ - "data": { - "id": "1", - "type": "post", - "attributes": { - ... - "bytes": "AQID" // base64-encoded bytes - } - }, - "meta": { - "serialization": {"values": { "data.attributes.bytes": [[ "custom", "Bytes"]] } } - } -} -``` - -You should use the `meta.serialization` field value to superjson-deserialize the response body. - -### Data Type Serialization Format - - - -## Error Handling - -An error response is an object containing the following fields: - -- errors - - An array of error objects, each containing the following fields: - - - code: `string`, error code - - status: `number`, HTTP status code - - title: `string`, error title - - detail: `string`, error detail - - prismaCode: `string`, Prisma error code, if the error is thrown by Prisma - -### Example - -```json -{ - "errors" : [ - { - "code" : "unsupported-model", - "detail" : "Model foo doesn't exist", - "status" : 404, - "title" : "Unsupported model type" - } - ] -} -``` diff --git a/versioned_docs/version-3.x/reference/server-adapters/api-handlers/rpc.mdx b/versioned_docs/version-3.x/reference/server-adapters/api-handlers/rpc.mdx deleted file mode 100644 index ecfd1c96..00000000 --- a/versioned_docs/version-3.x/reference/server-adapters/api-handlers/rpc.mdx +++ /dev/null @@ -1,275 +0,0 @@ ---- -description: RPC-style API handler that fully mirrors PrismaClient's query API -sidebar_position: 1 -title: RPC API Handler ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import DataTypeSerialization from './_data_type_serialization.md'; - -# RPC API Handler - -## Introduction - -The RPC-style API handler exposes CRUD endpoints that fully mirror [PrismaClient's query API](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#model-queries). Consuming the APIs feels like making RPC calls to a PrismaClient then. The API handler is not meant to be used directly; instead, you should use it together with a [server adapter](../../../category/server-adapters) which handles the request and response API for a specific framework. - -It can be created and used as the following: - - - - -```ts title='/src/app/api/model/[...path]/route.ts' -import { NextRequestHandler } from '@zenstackhq/server/next'; -import { RestApiHandler } from '@zenstackhq/server/api'; -import { getPrisma } from '~/lib/db'; - -const handler = NextRequestHandler({ - getPrisma, - useAppDir: true, - handler: RPCApiHandler() // you can also omit it since `RPCApiHandler` is the default -}); - -export { - handler as GET, - handler as POST, - handler as PUT, - handler as PATCH, - handler as DELETE, -}; -``` - - - - - -```ts title='/src/hooks.server.ts' -import { SvelteKitHandler } from '@zenstackhq/server/sveltekit'; -import { RPCApiHandler } from '@zenstackhq/server/api'; -import { getPrisma } from './lib/db'; - -export const handle = SvelteKitHandler({ - prefix: '/api/model', - handler: RPCApiHandler(), // you can also omit it since `RPCApiHandler` is the default - getPrisma -}); -``` - - - - - -```ts title='/server/api/model/[...].ts' -import { createEventHandler } from '@zenstackhq/server/nuxt'; -import { RPCApiHandler } from '@zenstackhq/server/api'; -import { getPrisma } from './lib/db'; - -export default createEventHandler({ - handler: RPCApiHandler(), // you can also omit it since `RPCApiHandler` is the default - getPrisma -}); -``` - - - - - -## Wire Format - -### Input - -For endpoints using `GET` and `DELETE` Http verbs, the query body is serialized and passed as the `q` query parameter. E.g.: - -```ts -GET /api/post/findMany?q=%7B%22where%22%3A%7B%22public%22%3Atrue%7D%7D -``` - -- Endpoint: /api/post/findMany -- Query parameters: `q` -> `{ "where" : { "public": true } }` - -For endpoints using other HTTP verbs, the query body is passed as `application/json` in the request body. E.g.: - -```json -POST /api/post/create -{ "data": { "title": "Hello World" } } -``` - -### Output - -The output shape conforms to the data structure returned by the corresponding PrismaClient API, wrapped into a `data` field. E.g.: - -```json -GET /api/post/findMany - -{ - "data": [ { "id": 1, "title": "Hello World" } ] -} -``` - -### Serialization - -This section explains the details about data serialization. If you're using generated hooks to consume the API, the generated code already automatically deals with serialization for you, and you don't need to do any further processing. - -ZenStack uses [superjson](https://github.com/blitz-js/superjson) to serialize and deserialize data - including the `q` query parameter, the request body, and the response body. Superjson generates two parts during serialization: - -- json: - - The JSON-compatible serialization result. - -- meta: - - The serialization metadata including information like field types that facilitates deserialization. - -If the data only involves simple data types, the serialization result is the same as regular `JSON.stringify`, and no `meta` part is generated. However, for complex data types (like `Bytes`, `Decimal`, etc.), a `meta` object will be generated, which needs to be carried along when sending the request, and will also be included in the response. - -The following part explains how the `meta` information is included for different situations: - -- The `q` query parameter - - If during superjson-serialization of the `q` parameter, a `meta` object is generated, it should be put into an object `{ serialization: meta }`, JSON-stringified, and included as an additional query parameter `meta`. For example, if you have a field named `bytes` of `Bytes` type, and you may want to query with a filter like ```{ where: { bytes: Buffer.from([1,2,3]) } }```. Superjson-serializing the query object results in: - ```json - { - "json": { "where": { "bytes": "AQID" } }, // base-64 encoded bytes - "meta": { "values": { "where.bytes": [["custom","Bytes"]] } } - } - ``` - Your query URL should look like: - ```json - GET /api/post/findMany?q={"where":{"bytes":"AQID"}}&meta={"serialization":{"values":{"where.bytes":[["custom","Bytes"]]}}} - ``` - -- The request body - - If during superjson-serialization of the request body, a `meta` object is generated, it should be put into an object `{ serialization: meta }`, and included as an additional field `meta` field in the request body. For example, if you have a field named `bytes` of `Bytes` type, and you may want to create a record with a value like ```{ data: { bytes: Buffer.from([1,2,3]) } }```. Superjson-serializing the request body results in: - ```json - { - "json": { "bytes": "AQID" }, // base-64 encoded bytes - "meta": { "values": { "bytes": [[ "custom", "Bytes" ]] } } - } - ``` - Your request body should look like: - ```json - POST /api/post/create - - { - "data": { "bytes": "AQID" }, - "meta": { "serialization": {"values": { "bytes": [[ "custom","Bytes" ]] } } } - } - ``` - -- The response body - - If during superjson-serialization of the response body, a `meta` object is generated, it will be put into an object `{ serialization: meta }`, and included as an additional field `meta` field in the response body. For example, if you have a field named `bytes` of `Bytes` type, and a `findFirst` query returns ```{ id: 1, bytes: Buffer.from([1,2,3]) }```. Superjson-serializing the request body results in: - ```json - { - "json": { "id": 1, "bytes":"AQID" }, // base-64 encoded bytes - "meta": { "values": { "bytes": [[ "custom", "Bytes" ]] } } - } - ``` - Your response body will look like: - ```json - GET /api/post/findFirst - - { - "data": { "id": 1, "bytes": "AQID" }, - "meta": { "serialization": {"values": { "bytes": [[ "custom","Bytes"]] } } } - } - ``` - - You should use the meta.serialization field value to superjson-deserialize the response body. - -#### Data Type Serialization Format - - - -## Endpoints - -- **[model]/findMany** - - _Http method:_ `GET` - -- **[model]/findUnique** - - _Http method:_ `GET` - -- **[model]/findFirst** - - _Http method:_ `GET` - -- **[model]/count** - - _Http method:_ `GET` - -- **[model]/aggregate** - - _Http method:_ `GET` - -- **[model]/groupBy** - - _Http method:_ `GET` - -- **[model]/create** - - _Http method:_ `POST` - -- **[model]/createMany** - - _Http method:_ `POST` - -- **[model]/update** - - _Http method:_ `PATCH` or `PUT` - -- **[model]/updateMany** - - _Http method:_ `PATCH` or `PUT` - -- **[model]/upsert** - - _Http method:_ `POST` - -- **[model]/delete** - - _Http method:_ `DELETE` - -- **[model]/deleteMany** - - _Http method:_ `DELETE` - -- **[model]/check** - - _Http method:_ `GET` - -## HTTP Status Code and Error Responses - -### Status code - -The HTTP status code used by the endpoints follows the following rules: - -- `create` and `createMany` use `201` for success. Other endpoints use `200`. -- `403` is used for to indicate the request is denied due to lack of permissions, usually caused by access policy violation. -- `400` is used for invalid requests, e.g., malformed request body. -- `422` is used for data validation errors. -- `500` is used for other unexpected errors. - -### Error response format - -```ts -{ - // true to indicate the failure is due to a Prisma error - prisma?: boolean; - - // true to indicate the failure is due to access policy violation - rejectedByPolicy?: boolean; - - // original Prisma error code, available when `prisma` is true - code?: string; - - // error message - message: string; - - // extra reason about why a failure happened (e.g., 'RESULT_NOT_READABLE' indicates - // a mutation succeeded but the result cannot be read back due to access policy) - reason?: string; -} -``` diff --git a/versioned_docs/version-3.x/reference/server-adapters/elysia.mdx b/versioned_docs/version-3.x/reference/server-adapters/elysia.mdx deleted file mode 100644 index 41582343..00000000 --- a/versioned_docs/version-3.x/reference/server-adapters/elysia.mdx +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: Elysia -description: Adapter for integrating with Elysia -sidebar_position: 8 ---- - -import ErrorHandling from './_error-handling.md'; -import AdapterOptions from './_options.mdx'; -import UsingAPI from './_using-api.mdx' - -# Elysia Adapter - -The `@zenstackhq/server/elysia` module provides a quick way to install a CRUD middleware onto an [Elysia](https://elysiajs.com/) app. Combined with ZenStack's power of enhancing Prisma with access policies, you can achieve a secure data backend without manually coding it. - -This feature is contributed by [@rodrigoburigool](https://github.com/rodrigoburigool). - -### Installation - -```bash -bun install @zenstackhq/server -``` - -### Mounting the API - -You can use the `createElysiaHandler` API to create an Elysia request handler that handles CRUD requests automatically: - -```ts -import { PrismaClient } from '@prisma/client'; -import { Elysia, Context } from 'elysia'; -import { enhance } from '@zenstackhq/runtime'; -import { createElysiaHandler } from '@zenstackhq/server/elysia'; - -const prisma = new PrismaClient(); - -const app = new Elysia({ prefix: '/api' }); - -// install the CRUD middleware under route "/api/crud" -app.group('/crud', (app) => - app.use( - createElysiaHandler({ - getPrisma: (context) => enhance(prisma, { user: getCurrentUser(context) }), - basePath: '/api/crud', - }) - ) -); - -function getCurrentUser(context: Context) { - // the implementation depends on your authentication mechanism - ... -} - -app.listen(3000); -``` - -The middleware factory takes the following options to initialize: - - - -- basePath (optional) - -
string
- - Optional base path to strip from the request path before passing to the API handler. E.g., if your CRUD handler is mounted at `/api/crud`, set this field to `'/api/crud'`. - -### Using the API - - - - diff --git a/versioned_docs/version-3.x/reference/server-adapters/express.mdx b/versioned_docs/version-3.x/reference/server-adapters/express.mdx deleted file mode 100644 index abc413ec..00000000 --- a/versioned_docs/version-3.x/reference/server-adapters/express.mdx +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: Express.js -description: Adapter for integrating with Express.js -sidebar_position: 4 ---- - -import ErrorHandling from './_error-handling.md'; -import AdapterOptions from './_options.mdx'; -import UsingAPI from './_using-api.mdx' - -# Express.js Adapter - -The `@zenstackhq/server/express` module provides a quick way to install API routes onto a [Express.js](https://expressjs.com/) project for database CRUD operations. Combined with ZenStack's power of enhancing Prisma with access policies, it's surprisingly simple to achieve a secure data backend without manually coding it. - -### Installation - -```bash -npm install @zenstackhq/server -``` - -### Mounting the API - -You can integrate ZenStack into your project with the `ZenStackMiddleware` [express middleware](https://expressjs.com/en/guide/using-middleware.html): - -```ts -import { PrismaClient } from '@prisma/client'; -import { enhance } from '@zenstackhq/runtime'; -import { ZenStackMiddleware } from '@zenstackhq/server/express'; -import express from 'express'; - -const prisma = new PrismaClient(); -const app = express(); - -app.use(express.json()); - -app.use( - '/api/model', - ZenStackMiddleware({ - // getSessionUser extracts the current session user from the request, its - // implementation depends on your auth solution - getPrisma: (request) => enhance(prisma, { user: getSessionUser(request) }), - }) -); -``` - -The Express.js adapter takes the following options to initialize: - - - -- sendResponse (optional) - -
boolean
- - Controls if the middleware directly sends a response. If set to false, the response is stored in the `res.locals` object and then the middleware calls the `next()` function to pass the control to the next middleware. Subsequent middleware or request handlers need to make sure to send a response. - - Defaults to `true`. - -### Using the API - - - - - -### Fully working example - -You can find a fully working example [here](https://github.com/zenstackhq/docs-tutorial-express). diff --git a/versioned_docs/version-3.x/reference/server-adapters/fastify.mdx b/versioned_docs/version-3.x/reference/server-adapters/fastify.mdx deleted file mode 100644 index be568e77..00000000 --- a/versioned_docs/version-3.x/reference/server-adapters/fastify.mdx +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: Fastify -description: Adapter for integrating with Fastify -sidebar_position: 5 ---- - -import ErrorHandling from './_error-handling.md'; -import AdapterOptions from './_options.mdx'; -import UsingAPI from './_using-api.mdx'; - -# Fastify Adapter - -The `@zenstackhq/server/fastify` module provides a quick way to install API routes onto a [Fastify](https://www.fastify.io/) project for database CRUD operations. Combined with ZenStack's power of enhancing Prisma with access policies, it's surprisingly simple to achieve a secure data backend without manually coding it. - -### Installation - -```bash -npm install @zenstackhq/server -``` - -### Mounting the API - -You can integrate ZenStack into your project with the `ZenStackFastifyPlugin` [fastify plugin](https://www.fastify.io/docs/latest/Reference/Plugins/): - -```ts -import { enhance } from '@zenstackhq/runtime'; -import { ZenStackFastifyPlugin } from '@zenstackhq/server/fastify'; -import { prisma } from './db.ts'; -import { getSessionUser } from './auth.ts'; - -const server = fastify(); - -// serve OpenAPI at /api/model -server.register(ZenStackFastifyPlugin, { - prefix: '/api/model', - // getSessionUser extracts the current session user from the request, its - // implementation depends on your auth solution - getPrisma: (request) => enhance(prisma, { user: getSessionUser(request) }), -}); -``` - -The Fastify adapter takes the following options to initialize: - -- prefix - -
string
- - Prefix for the mounted API endpoints. E.g.: /api/model. - - - -### Using the API - - - - diff --git a/versioned_docs/version-3.x/reference/server-adapters/hono.mdx b/versioned_docs/version-3.x/reference/server-adapters/hono.mdx deleted file mode 100644 index 67fdea3e..00000000 --- a/versioned_docs/version-3.x/reference/server-adapters/hono.mdx +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: Hono -description: Adapter for integrating with Hono -sidebar_position: 7 ---- - -import ErrorHandling from './_error-handling.md'; -import AdapterOptions from './_options.mdx'; -import UsingAPI from './_using-api.mdx' - -# Hono Adapter - -The `@zenstackhq/server/hono` module provides a quick way to install API routes onto a [Hono](https://hono.dev/) project for database CRUD operations. Combined with ZenStack's power of enhancing Prisma with access policies, it's surprisingly simple to achieve a secure data backend without manually coding it. - -### Installation - -```bash -npm install @zenstackhq/server -``` - -### Mounting the API - -You can use the `createHonoHandler` API to create a [Hono middleware](https://hono.dev/docs/getting-started/basic#using-middleware) that handles CRUD requests automatically: - -```ts -import { PrismaClient } from '@prisma/client'; -import { enhance } from '@zenstackhq/runtime'; -import { createHonoHandler } from '@zenstackhq/server/hono'; -import { Context, Hono } from 'hono'; - -const prisma = new PrismaClient(); -const app = new Hono(); - -app.use( - '/api/model/*', - createHonoHandler({ - getPrisma: (ctx) => { - return enhance(prisma, { user: getCurrentUser(ctx) }); - }, - }) -); - -function getCurrentUser(ctx: Context) { - // the implementation depends on your authentication mechanism - ... -} -``` - -The middleware factory takes the following options to initialize: - - - -### Using the API - - - - diff --git a/versioned_docs/version-3.x/reference/server-adapters/nestjs.mdx b/versioned_docs/version-3.x/reference/server-adapters/nestjs.mdx deleted file mode 100644 index 1d558d3d..00000000 --- a/versioned_docs/version-3.x/reference/server-adapters/nestjs.mdx +++ /dev/null @@ -1,268 +0,0 @@ ---- -title: NestJS -description: Adapter for integrating with NestJS -sidebar_position: 6 ---- - -import ErrorHandling from './_error-handling.md'; -import AdapterOptions from './_options.mdx'; -import UsingAPI from './_using-api.mdx'; - -# NestJS Adapter - -The `@zenstackhq/server/nestjs` module provides a quick way to install a ZenStack-enhanced Prisma service as a dependency injection provider onto a [NestJS](https://nestjs.com/) application. - -### Installation - -```bash -npm install @zenstackhq/server -``` - -### Registering the provider - -You can register the enhanced Prisma service by importing the `ZenStackModule` NestJS module. - -```ts -import { ZenStackModule } from '@zenstackhq/server/nestjs'; -import { enhance } from '@zenstackhq/runtime'; -import { PrismaService } from './prisma.service'; - -@Module({ - imports: [ - ZenStackModule.registerAsync({ - useFactory: (prisma: PrismaService) => { - return { - getEnhancedPrisma: () => enhance(prisma, { user: ... }), - }; - }, - inject: [PrismaService], - extraProviders: [PrismaService], - }), - ], -}) -export class AppModule {} -``` - -The `registerAsync` API takes as input a factory function that returns a config used for creating an enhanced prisma service. The config contains a callback function where you should create and return an enhanced `PrismaClient`. It'll be called each time a Prisma method is invoked. - -You'll usually pass in a user context when calling `enhance` inside the callback. The way how the user context is fetched depends on your authentication mechanism. You can check the [NestJS quick start guide](../../quick-start/nestjs) for a reference solution. - -### Using the enhanced Prisma service - -Inside your NestJS controllers or services, you can inject the enhanced Prisma service and use it as you would with the regular Prisma service. Just use the special token name `ENHANCED_PRISMA` when injecting the service. - -```ts -import { ENHANCED_PRISMA } from '@zenstackhq/server/nestjs'; - -@Controller() -export class MyController { - constructor( - @Inject(ENHANCED_PRISMA) private readonly prismaService: PrismaService, - ) {} - - ... -} -``` - -You can still use the regular Prisma service by injecting as usual. - -### Using the API handler service to automate request handling - -This module also provides an `ApiHandlerService` that can be used to automate the request handling using API handlers. This is useful if you want to handle requests in a more structured way, such as using a controller or middleware. Before using it, you should ensure `ENHANCED_PRISMA` is registered in the module. For example: - -```ts -import { ZenStackModule, ApiHandlerService } from '@zenstackhq/server/nestjs'; -import { enhance } from '@zenstackhq/runtime'; -import { PrismaService } from './prisma.service'; - -@Module({ - imports: [ - // Register the ZenStack module - // The module exports the ENHANCED_PRISMA token and could be used in the ApiHandlerService - ZenStackModule.registerAsync({ - useFactory: (prisma: PrismaService) => { - return { - getEnhancedPrisma: () => enhance(prisma, { user: ... }), - }; - }, - inject: [PrismaService], - extraProviders: [PrismaService], - }), - ], - providers: [ApiHandlerService] -}) -export class AppModule {} -``` - -Then, you can inject the `ApiHandlerService` into your code and use it to handle requests. The service provides a method `handleRequest` to handle request using API handler automatically. - -RPC API Handler: - -```ts -import { Controller, Get, Post } from '@nestjs/common'; -import { ApiHandlerService } from '@zenstackhq/server/nestjs'; - -@Controller('post') -export class PostController { - constructor(private readonly apiHandlerService: ApiHandlerService) {} - - // should align with the route generated by API handler - @Get('findMany') - async findMany() { - return this.apiHandlerService.handleRequest() - } - - @Post('create') - async create() { - return this.apiHandlerService.handleRequest() - } -} -``` - -RESTful API Handler: - -```ts -import { Controller, Get, Post } from '@nestjs/common'; -import { ApiHandlerService } from '@zenstackhq/server/nestjs'; -import RESTApiHandler from '@zenstackhq/server/api/rest'; - -const ENDPOINT = 'http://localhost'; - -@Controller('post') -export class PostController { - constructor(private readonly apiHandlerService: ApiHandlerService) {} - - // should align with the route generated by API handler - @Get() - async list() { - return this.apiHandlerService.handleRequest( - { - handler: RESTApiHandler({ - endpoint: ENDPOINT, - }), - } - ) - } - - @Post() - async create() { - return this.apiHandlerService.handleRequest( - { - handler: RESTApiHandler({ - endpoint: ENDPOINT, - }), - } - ) - } -} -``` - -### API reference - -#### `ZenStackModule.registerAsync` - -##### Signature - -```ts -registerAsync(options: ZenStackModuleAsyncOptions): DynamicModule; -``` - -##### Parameter `options` - -```ts -interface ZenStackModuleAsyncOptions { - /** - * Optional list of imported modules that export the providers which are - * required in this module. - */ - imports?: Array | DynamicModule | Promise | ForwardReference>; - - /** - * Whether the module is global-scoped. - */ - global?: boolean; - - /** - * The token to export the enhanced Prisma service. Default is `'ENHANCED_PRISMA'`. - */ - exportToken?: string; - - /** - * The factory function to create the enhancement options. - */ - useFactory: (...args: unknown[]) => Promise | ZenStackModuleOptions; - - /** - * The dependencies to inject into the factory function. - */ - inject?: FactoryProvider['inject']; - - /** - * Extra providers to facilitate dependency injection. - */ - extraProviders?: Provider[]; -} -``` - -```ts -interface ZenStackModuleOptions { - /** - * A callback for getting an enhanced `PrismaClient`. - */ - getEnhancedPrisma: (model?: string | symbol) => unknown; -} -``` - -#### `ApiHandlerService.handleRequest` - -##### Signature - -```ts -handleRequest(options?: ApiHandlerOptions): Promise; -``` - -##### Parameter `options` - -```ts -interface ApiHandlerOptions { - /** - * Logger settings - */ - logger?: LoggerConfig; - - /** - * Model metadata. By default loaded from the `node_module/.zenstack/model-meta` - * module. You can pass it in explicitly if you configured ZenStack to output to - * a different location. - */ - modelMeta?: ModelMeta; - - /** - * Zod schemas for validating request input. Pass `true` to load from standard location - * (need to enable `@core/zod` plugin in schema.zmodel) or omit to disable input validation. - */ - zodSchemas?: ZodSchemas | boolean; - - /** - * Api request handler function. Can be created using `@zenstackhq/server/api/rest` or `@zenstackhq/server/api/rpc` factory functions. - * Defaults to RPC-style API handler. - */ - handler?: HandleRequestFn; - - /** - * The base URL for the API handler. This is used to determine the base path for the API requests. - * If you are using the ApiHandlerService in a route with a prefix, you should set this to the prefix. - * - * e.g. - * without baseUrl(API handler default route): - * - RPC API handler: [model]/findMany - * - RESTful API handler: /:type - * - * with baseUrl(/api/crud): - * - RPC API handler: /api/crud/[model]/findMany - * - RESTful API handler: /api/crud/:type - */ - baseUrl?: string; -} -``` - diff --git a/versioned_docs/version-3.x/reference/server-adapters/next.mdx b/versioned_docs/version-3.x/reference/server-adapters/next.mdx deleted file mode 100644 index 48647a64..00000000 --- a/versioned_docs/version-3.x/reference/server-adapters/next.mdx +++ /dev/null @@ -1,124 +0,0 @@ ---- -title: Next.js -description: Adapter for integrating with Next.js -sidebar_position: 1 ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import ErrorHandling from './_error-handling.md'; -import AdapterOptions from './_options.mdx'; -import UsingAPI from './_using-api.mdx'; - -# Next.js Server Adapter - -The `@zenstackhq/server/next` module provides a quick way to install API endpoints onto a [Next.js](https://nextjs.org/) project for database CRUD operations. Combined with ZenStack's power of enhancing Prisma with access policies, it's surprisingly simple to achieve a secure data backend without manually coding it. - -The server adapter supports both the "pages" routes for older versions of Next.js and the new "app" routes for Next.js 13. - -### Installation - -```bash -npm install @zenstackhq/server -``` - -### Mounting the API - -You can use it to create a request handler in an API endpoint like: - - - - - -```ts title='/src/app/api/model/[...path]/route.ts' -import { NextRequestHandler } from '@zenstackhq/server/next'; -import type { NextRequest } from "next/server"; -import { enhance } from '@zenstackhq/runtime'; -import { prisma } from '~/lib/db.ts'; -import { getSessionUser } from '~/lib/auth.ts'; - -// create an enhanced Prisma client with user context -function getPrisma(req: NextRequest) { - // getSessionUser extracts the current session user from the request, its - // implementation depends on your auth solution - return enhance(prisma, { user: getSessionUser(req) }); -} - -const handler = NextRequestHandler({ getPrisma, useAppDir: true }); - -export { - handler as GET, - handler as POST, - handler as PUT, - handler as PATCH, - handler as DELETE, -}; -``` - -The Next.js API route handler takes the following options to initialize: - - - - - - - -```ts title='/src/pages/api/model/[...path].ts' -import { NextRequestHandler } from '@zenstackhq/server/next'; -import type { NextApiRequest, NextApiResponse } from 'next'; -import { enhance } from '@zenstackhq/runtime'; -import { prisma } from '~/lib/db.ts'; -import { getSessionUser } from '~/lib/auth.ts'; - -// create an enhanced Prisma client with user context -function getPrisma(req: NextApiRequest, res: NextApiResponse) { - // getSessionUser extracts the current session user from the request, its - // implementation depends on your auth solution - return enhance(prisma, { user: getSessionUser(req, res) }); -} - -// create the request handler with the `getPrisma` hook -export default NextRequestHandler({ getPrisma }); -``` - -The Next.js API route handler takes the following options to initialize: - - - - - - - -### Controlling what endpoints to expose - -You can use a [Next.js middleware](https://nextjs.org/docs/pages/building-your-application/routing/middleware) to further control what endpoints to expose. For example, if you're using a RESTful API handler installed at "/api/model", you can disallow listing all `User` entities by adding a middleware like: - -```ts title='/src/middleware.ts' -import { type NextRequest, NextResponse } from 'next/server'; - -export function middleware(request: NextRequest) { - const url = new URL(request.url); - if ( - request.method === 'GET' && - url.pathname.match(/^\/api\/model\/user\/?$/) - ) { - return NextResponse.json({ error: 'Not allowed' }, { status: 405 }); - } -} - -export const config = { - matcher: '/api/model/:path*', -}; -``` - -### Using the API - - - - - -### Fully working example - -You can find the fully working examples below: -- [Pages router](https://github.com/zenstackhq/docs-tutorial-nextjs) -- [Apps router](https://github.com/zenstackhq/docs-tutorial-nextjs-app-dir) diff --git a/versioned_docs/version-3.x/reference/server-adapters/nuxt.mdx b/versioned_docs/version-3.x/reference/server-adapters/nuxt.mdx deleted file mode 100644 index c254ccf1..00000000 --- a/versioned_docs/version-3.x/reference/server-adapters/nuxt.mdx +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: Nuxt -description: Adapter for integrating with Nuxt -sidebar_position: 2 ---- - -import ErrorHandling from './_error-handling.md'; -import AdapterOptions from './_options.mdx'; -import UsingAPI from './_using-api.mdx'; - -# Nuxt Server Adapter - -The `@zenstackhq/server/nuxt` module provides a quick way to install API endpoints onto a [Nuxt V3](https://nuxt.com/) project for database CRUD operations. Combined with ZenStack's power of enhancing Prisma with access policies, it's surprisingly simple to achieve a secure data backend without manually coding it. - -### Mounting the API - -You can mount the API by creating a Nuxt server event handler like: - -```ts title='/server/api/model/[...].ts' -import { enhance } from '@zenstackhq/runtime'; -import { createEventHandler } from '@zenstackhq/server/nuxt'; -import { getSessionUser } from '~/server/auth'; -import { prisma } from '~/server/prisma'; - -export default createEventHandler({ - getPrisma: async (event) => { - return enhance(prisma, { user: getSessionUser(event) }); - }, -}); -``` - -The Nuxt event handler takes the following options to initialize: - - - -### Using the API - - - - - -### Fully working example - -You can find a fully working example [here](https://github.com/zenstackhq/sample-todo-nuxt). diff --git a/versioned_docs/version-3.x/reference/server-adapters/sveltekit.mdx b/versioned_docs/version-3.x/reference/server-adapters/sveltekit.mdx deleted file mode 100644 index 2976149f..00000000 --- a/versioned_docs/version-3.x/reference/server-adapters/sveltekit.mdx +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: SvelteKit -description: Adapter for integrating with SvelteKit -sidebar_position: 3 ---- - -import ErrorHandling from './_error-handling.md'; -import AdapterOptions from './_options.mdx'; -import UsingAPI from './_using-api.mdx'; - -# SvelteKit Server Adapter - -The `@zenstackhq/server/sveltekit` module provides a quick way to install API endpoints onto a [SvelteKit](https://kit.svelte.dev/) project for database CRUD operations. Combined with ZenStack's power of enhancing Prisma with access policies, it's surprisingly simple to achieve a secure data backend without manually coding it. - -### Installation - -```bash -npm install @zenstackhq/server -``` - -### Mounting the API - -You can mount the API by creating a SvelteKit server hooks like: - -```ts title='/src/hooks.server.ts' -import { SvelteKitHandler } from '@zenstackhq/server/sveltekit'; -import { enhance } from '@zenstackhq/runtime'; -import { getSessionUser } from '$lib/auth.ts'; - -// create an enhanced Prisma client with user context -function getPrisma(event: RequestEvent) { - // getSessionUser extracts the current session user from the request, its - // implementation depends on your auth solution - return enhance({ user: getSessionUser(event) }); -} - -// create the hooks handler with the `getPrisma` hook -export const handle = SvelteKitHandler({ prefix: '/api/model', getPrisma }); -``` - -:::tip -You can use the [sequence helper](https://kit.svelte.dev/docs/modules#sveltejs-kit-hooks) to compose multiple server hooks. -::: - -The SvelteKit hooks handler takes the following options to initialize: - -- prefix - -
string
- - Prefix for the mounted API endpoints. E.g.: /api/model. - - - -### Using the API - - - - - -### Fully working example - -You can find a fully working example [here](https://github.com/zenstackhq/sample-todo-sveltekit). diff --git a/versioned_docs/version-3.x/reference/zmodel-language.md b/versioned_docs/version-3.x/reference/zmodel-language.md index 49988dce..8b540c21 100644 --- a/versioned_docs/version-3.x/reference/zmodel-language.md +++ b/versioned_docs/version-3.x/reference/zmodel-language.md @@ -6,1982 +6,3 @@ toc_max_heading_level: 3 --- # ZModel Language Reference - -## Overview - -**ZModel**, the modeling DSL of ZenStack, is the main concept you'll deal with when using this toolkit. The ZModel syntax is a superset of [Prisma Schema](https://www.prisma.io/docs/concepts/components/prisma-schema). Therefore, every valid Prisma schema is a valid ZModel. - -:::info - -We made that choice to extend the Prisma schema for several reasons: - -- Creating a new ORM adds little value to the community. Instead, extending Prisma - the overall best ORM toolkit for Typescript - sounds more sensible. - -- Prisma's schema language is simple and intuitive. - -- Extending an existing popular language lowers the learning curve compared to inventing a new one. - -::: - -However, the standard capability of Prisma schema doesn't allow us to build the functionalities we want in a natural way, so we made several extensions to the language by adding the following: - -1. Custom attributes -1. Custom attribute functions -1. Built-in attributes and functions for defining access policies -1. Built-in attributes for defining field validation rules -1. Utility attributes like `@password` and `@omit` -1. Multi-schema files support - -Some of these extensions have been asked for by the Prisma community for some time, so we hope that ZenStack can be helpful even just as an extensible version of Prisma. - -This section provides detailed descriptions of all aspects of the ZModel language, so you don't have to jump over to Prisma's documentation for extra learning. - -## Import -ZModel allows to import other ZModel files. This is useful when you want to split your schema into multiple files for better organization. Under the hood, it will recursively merge all the imported schemas, and generate a single Prisma schema file for the Prisma CLI to consume. - -### Syntax - -```zmodel -import [IMPORT_SPECIFICATION] -``` - -- **[IMPORT_SPECIFICATION]**: - Path to the ZModel file to be imported. It can be: - - - An absolute path, e.g., "/path/to/user". - - A relative path, e.g., "./user". - - A module resolved to an installed NPM package, e.g., "my-package/base". - - If the import specification doesn't end with ".zmodel", the resolver will automatically append it. Once a file is imported, all the declarations in that file will be included in the building process. - -### Examples - -```zmodel -// there is a file called "user.zmodel" in the same directory -import "user" -``` - - -## Data source - -Every model needs to include exactly one `datasource` declaration, providing information on how to connect to the underlying database. - -### Syntax - -```zmodel -datasource [NAME] { - provider = [PROVIDER] - url = [DB_URL] -} -``` - -- **[NAME]**: - - Name of the data source. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. Name is only informational and serves no other purposes. - -- **[PROVIDER]**: - - Name of database connector. Valid values: - - - sqlite - - postgresql - - mysql - - sqlserver - - cockroachdb - -- **[DB_URL]**: - - Database connection string. Either a plain string or an invocation of `env` function to fetch from an environment variable. - -### Examples - -```zmodel -datasource db { - provider = "postgresql" - url = "postgresql://postgres:abc123@localhost:5432/todo?schema=public" -} -``` - -It's highly recommended that you not commit sensitive database connection strings into source control. Alternatively, you can load it from an environment variable: - -```zmodel -datasource db { - provider = "postgresql" - url = env("DATABASE_URL") -} -``` - -### Supported databases - -ZenStack uses [Prisma](https://prisma.io ':target=_blank') to talk to databases, so all relational databases supported by Prisma are also supported by ZenStack. - -Here's a list for your reference: - -| Database | Version | -| --------------------- | ------- | -| PostgreSQL | 9.6 | -| PostgreSQL | 10 | -| PostgreSQL | 11 | -| PostgreSQL | 12 | -| PostgreSQL | 13 | -| PostgreSQL | 14 | -| PostgreSQL | 15 | -| MySQL | 5.6 | -| MySQL | 5.7 | -| MySQL | 8 | -| MariaDB | 10 | -| SQLite | \* | -| AWS Aurora | \* | -| AWS Aurora Serverless | \* | -| Microsoft SQL Server | 2022 | -| Microsoft SQL Server | 2019 | -| Microsoft SQL Server | 2017 | -| Azure SQL | \* | -| CockroachDB | 21.2.4+ | - -You can find the orignal list [here](https://www.prisma.io/docs/reference/database-reference/supported-databases ':target=_blank'). - -## Generator - -Generators are used for creating assets (usually code) from a Prisma schema. Check [here](https://www.prisma.io/docs/concepts/components/prisma-schema/generators) for a list of official and community generators. - -### Syntax - -```zmodel -generator [GENERATOR_NAME] { - [OPTION]* -} -``` - -- **[GENERATOR_NAME]** - - Name of the generator. Needs to be unique in the entire model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. - -- **[OPTION]** - - A generator configuration option, in form of "[NAME] = [VALUE]". A generator needs to have at least a "provider" option that specify its provider. - -### Example - -```zmodel -generator client { - provider = "prisma-client-js" - output = "./generated/prisma-client-js" -``` - -## Plugin - -Plugins are ZenStack's extensibility mechanism. It's usage is similar to [Generator](#generator). Users can define their own plugins to generate artifacts from the ZModel schema. Plugins differ from generators mainly in the following ways: - -- They have a cleaner interface without the complexity of JSON-RPC. -- They use an easier-to-program AST representation than generators. -- They have access to language features that ZenStack adds to Prisma, like custom attributes and functions. - -### Syntax - -```zmodel -plugin [PLUGIN_NAME] { - [OPTION]* -} -``` - -- **[PLUGIN_NAME]** - - Name of the plugin. Needs to be unique in the entire model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. - -- **[OPTION]** - - A plugin configuration option, in form of "[NAME] = [VALUE]". A plugin needs to have at least a "provider" option that specify its provider. - -### Example - -```zmodel -plugin swr { - provider = '@zenstackhq/swr' - output = 'lib/hooks' -} -``` - -## Enum - -Enums are container declarations for grouping constant identifiers. You can use them to express concepts like user roles, product categories, etc. - -### Syntax - -```prsima -enum [ENUM_NAME] { - [FIELD]* -} -``` - -- **[ENUM_NAME]** - - Name of the enum. Needs to be unique in the entire model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. - -- **[FIELD]** - - Field identifier. Needs to be unique in the model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. - -### Example - -```zmodel -enum UserRole { - USER - ADMIN -} -``` - -## Model - -Models represent the business entities of your application. A model inherits all fields and attributes from extended abstract models. Abstract models are eliminated in the generated prisma schema file. - -### Syntax -```zmodel -(abstract)? model [NAME] (extends [ABSTRACT_MODEL_NAME](,[ABSTRACT_MODEL_NAME])*)? { - [FIELD]* -} -``` -- **[abstract]**: - - Optional. If present, the model is marked as abstract would not be mapped to a database table. Abstract models are only used as base classes for other models. - -- **[NAME]**: - - Name of the model. Needs to be unique in the entire model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. - -- **[FIELD]**: - - Arbitrary number of fields. See [Field](#field) for details. - -- **[ABSTRACT_MODEL_NAME]**: - - Name of an abstract model. - -### Note - -A model must include a field marked with `@id` attribute. The `id` field serves as a unique identifier for a model entity and is mapped to the database table's primary key. - -See [here](#attribute) for more details about attributes. - -### Example - -```zmodel -abstract model Basic { - id String @id - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt -} - -model User extends Basic { - name String -} -``` - -The generated prisma file only contains one `User` model: -```zmodel -model User { - id String @id - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - name String @id -} -``` - -## Type - -Types provide a way to modeling object shapes without mapping them to a database table. The use cases of "types" include: - -- Typing JSON fields in models. -- Typing [plugin](#plugin) options. -- Interfacing with data models from external sources (auth providers like [Clerk](https://clerk.com), payment providers like [Stripe](https://stripe.com), etc.). - -### Syntax -```zmodel -type [NAME] { - [FIELD]* -} -``` - -- **[NAME]**: - - Name of the model. Needs to be unique in the entire model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. - -- **[FIELD]**: - - Arbitrary number of fields. See [Field](#field) for details. - -### Example - -```zmodel -type Profile { - email String @email - name String -} - -model User { - id String @id - profile Profile? @json -} -``` - -### Limitations - -- Inheritance is not supported for types yet. A type cannot inherit from another type. A model cannot extend a type. -- Type cannot have type-level attributes like `@@validate`. However, fields in a type can have field-level attributes. - -We may address these limitations in future versions. - -## Attribute - -Attributes decorate fields and models and attach extra behaviors or constraints to them. - -### Syntax - -#### Field attribute - -Field attribute name is prefixed by a single `@`. - -```zmodel -id String @[ATTR_NAME](ARGS)? -``` - -- **[ATTR_NAME]** - -Attribute name. See [below](#predefined-attributes) for a full list of attributes. - -- **[ARGS]** - -See [attribute arguments](#arguments). - -#### Model attribute - -Field attribute name is prefixed double `@@`. - -```zmodel -model Model { - @@[ATTR_NAME](ARGS)? -} -``` - -- **[ATTR_NAME]** - -Attribute name. See [below](#predefined-attributes) for a full list of attributes. - -- **[ARGS]** - -See [attribute arguments](#arguments). - -### Arguments - -Attribute can be declared with a list of parameters and applied with a comma-separated list of arguments. - -Arguments are mapped to parameters by position or by name. For example, for the `@default` attribute declared as: - -```zmodel -attribute @default(_ value: ContextType) -``` - -, the following two ways of applying it are equivalent: - -```zmodel -published Boolean @default(value: false) -``` - -```zmodel -published Boolean @default(false) -``` - -### Parameter types - -Attribute parameters are typed. The following types are supported: - -- Int - - Integer literal can be passed as argument. - - E.g., declaration: - - ```zmodel - attribute @password(saltLength: Int?, salt: String?) - - ``` - - application: - - ```zmodel - password String @password(saltLength: 10) - ``` - -- String - - String literal can be passed as argument. - - E.g., declaration: - - ```zmodel - attribute @id(map: String?) - ``` - - application: - - ```zmodel - id String @id(map: "_id") - ``` - -- Boolean - - Boolean literal or expression can be passed as argument. - - E.g., declaration: - - ```zmodel - attribute @@allow(_ operation: String, _ condition: Boolean) - ``` - - application: - - ```zmodel - @@allow("read", true) - @@allow("update", auth() != null) - ``` - -- ContextType - - A special type that represents the type of the field onto which the attribute is attached. - - E.g., declaration: - - ```zmodel - attribute @default(_ value: ContextType) - ``` - - application: - - ```zmodel - f1 String @default("hello") - f2 Int @default(1) - ``` - -- FieldReference - - References to fields defined in the current model. - - E.g., declaration: - - ```zmodel - attribute @relation( - _ name: String?, - fields: FieldReference[]?, - references: FieldReference[]?, - onDelete: ReferentialAction?, - onUpdate: ReferentialAction?, - map: String?) - ``` - - application: - - ```zmodel - model Model { - ... - // [ownerId] is a list of FieldReference - owner Owner @relation(fields: [ownerId], references: [id]) - ownerId - } - ``` - -- Enum - - Attribute parameter can also be typed as predefined enum. - - E.g., declaration: - - ```zmodel - attribute @relation( - _ name: String?, - fields: FieldReference[]?, - references: FieldReference[]?, - // ReferentialAction is a predefined enum - onDelete: ReferentialAction?, - onUpdate: ReferentialAction?, - map: String?) - ``` - - application: - - ```zmodel - model Model { - // 'Cascade' is a predefined enum value - owner Owner @relation(..., onDelete: Cascade) - } - ``` - -An attribute parameter can be typed as any of the types above, a list of the above type, or an optional of the types above. - -```zmodel - model Model { - ... - f1 String - f2 String - // a list of FieldReference - @@unique([f1, f2]) - } -``` - -### Attribute functions - -Attribute functions are used for providing values for attribute arguments, e.g., current `DateTime`, an autoincrement `Int`, etc. They can be used in place of attribute arguments, like: - -```zmodel -model Model { - ... - serial Int @default(autoincrement()) - createdAt DateTime @default(now()) -} -``` - -You can find a list of predefined attribute functions [here](#predefined-attribute-functions). - -### Predefined attributes - -#### Field attributes - -##### @id - -```zmodel -attribute @id(map: String?) -``` - -Defines an ID on the model. - -_Params_: - -| Name | Description | -| ---- | ----------------------------------------------------------------- | -| map | The name of the underlying primary key constraint in the database | - -##### @default - -```zmodel -attribute @default(_ value: ContextType) -``` - -Defines a default value for a field. - -_Params_: - -| Name | Description | -| ----- | ---------------------------- | -| value | The default value expression | - -##### @unique - -```zmodel -attribute @unique(map: String?) -``` - -Defines a unique constraint for this field. - -_Params_: - -| Name | Description | -| ---- | ----------------------------------------------------------------- | -| map | The name of the underlying primary key constraint in the database | - -##### @relation - -```zmodel -attribute @relation( - _ name: String?, - fields: FieldReference[]?, - references: FieldReference[]?, - onDelete: ReferentialAction?, - onUpdate: ReferentialAction?, - map: String?) -``` - -Defines meta information about a relation. - -_Params_: - -| Name | Description | -| ---------- | ------------------------------------------------------------------------------ | -| name | The name of the relationship | -| fields | A list of fields defined in the current model | -| references | A list of fields of the model on the other side of the relation | -| onDelete | Referential action to take on delete. See details [here](#referential-action). | -| onUpdate | Referential action to take on update. See details [here](#referential-action). | - -##### @map - -```zmodel -attribute @map(_ name: String) -``` - -Maps a field name or enum value from the schema to a column with a different name in the database. - -_Params_: - -| Name | Description | -| ---- | ------------------------------------------------- | -| map | The name of the underlying column in the database | - -##### @updatedAt - -```zmodel -attribute @updatedAt() -``` - -Automatically stores the time when a record was last updated. - -##### @ignore - -```zmodel -attribute @ignore() -``` - -Exclude a field from the Prisma Client (for example, a field that you do not want Prisma users to update). - -##### @allow - -```zmodel -attribute @allow(_ operation: String, _ condition: Boolean) -``` - -Defines an access policy that allows the annotated field to be read or updated. Read more about access policies [here](#access-policy). - -_Params_: - -| Name | Description | -| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| operation | Comma separated list of operations to control, including `"read"` and `"update"`. Pass` "all"` as an abbreviation for including all operations. | -| condition | Boolean expression indicating if the operations should be allowed | - -##### @deny - -```zmodel -attribute @deny(_ operation: String, _ condition: Boolean) -``` - -Defines an access policy that denies the annotated field to be read or updated. Read more about access policies [here](#access-policy). - -_Params_: - -| Name | Description | -| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| operation | Comma separated list of operations to control, including `"read"` and `"update"`. Pass` "all"` as an abbreviation for including all operations. | -| condition | Boolean expression indicating if the operations should be denied - -##### @password - -```zmodel -attribute @password(saltLength: Int?, salt: String?) -``` - -Indicates that the field is a password field and needs to be hashed before persistence. - -_NOTE_: ZenStack uses the "bcryptjs" library to hash passwords. You can use the `saltLength` parameter to configure the cost of hashing or use `salt` parameter to provide an explicit salt. By default, a salt length of 12 is used. See [here](https://www.npmjs.com/package/bcryptjs ':target=blank') for more details. - -_Params_: - -| Name | Description | -| ---------- | ------------------------------------------------------------- | -| saltLength | The length of salt to use (cost factor for the hash function) | -| salt | The salt to use (a pregenerated valid salt) | - -##### @omit - -```zmodel -attribute @omit() -``` - -Indicates that the field should be omitted when read from the generated services. Commonly used together with `@password` attribute. - -##### @json - -```zmodel -attribute @json() -``` - -##### @encrypted - -```zmodel -attribute @encrypted() -``` - -Marks a field to be encrypted during write and decrypted when read. - -```zmodel -model User { - id Int @id - someSecret String @encrypted -} -``` - -Using the attribute requires the "encryption" enhancement kind to be enabled when calling `enhance`, and the `encryption` settings provided in the enhancement options: - -```ts - -function getEncryptionKey(): Uint8Array { - // return a 32-byte key -} - -const db = enhance(prisma, { user }, { - encryption: { - encryptionKey: getEncryptionKey() - } -}); -``` - -See [Encrypting Field](../guides/field-encryption.md) for more details. - -##### @prisma.passthrough - -```zmodel -attribute @prisma.passthrough(_ text: String) -``` - -A utility attribute for passing arbitrary text to the generated Prisma schema. This is useful as a workaround for dealing with discrepancies between Prisma schema and ZModel. - -_Params_: - -| Name | Description | -| ---- | ------------------------------------ | -| text | Text to passthrough to Prisma schema | - -E.g., the following ZModel content: - -```zmodel -model User { - id Int @id @default(autoincrement()) - name String @prisma.passthrough("@unique") -} -``` - -will be translated to the following Prisma schema: - -```zmodel -model User { - id Int @id @default(autoincrement()) - name String @unique -} -``` - -##### @meta - -```zmodel -attribute @meta(_ name: String, _ value: Any) -``` - -Adds arbitrary metadata to a field. The metadata can be accessed by custom plugins for code generation, or at runtime from the `modelMeta` object exported from `@zenstackhq/runtime/model-meta`. The `value` parameter can be an arbitrary literal expression, including object literals. - -```zmodel -model User { - id Int @id - name String @meta(name: "description", value: "The name of the user") -} -``` - -#### Model attributes - -##### @@id - -```zmodel -attribute @@id(_ fields: FieldReference[], name: String?, map: String?) -``` - -Defines a multi-field ID (composite ID) on the model. - -_Params_: - -| Name | Description | -| ------ | ----------------------------------------------------------------------------- | -| fields | A list of fields defined in the current model | -| name | The name that the Client API will expose for the argument covering all fields | -| map | The name of the underlying primary key constraint in the database | - -##### @@unique - -```zmodel -attribute @@unique(_ fields: FieldReference[], name: String?, map: String?) -``` - -Defines a compound unique constraint for the specified fields. - -_Params_: - -| Name | Description | -| ------ | ------------------------------------------------------------ | -| fields | A list of fields defined in the current model | -| name | The name of the unique combination of fields | -| map | The name of the underlying unique constraint in the database | - -##### @@schema - -```zmodel -attribute @@schema(_ name: String) -``` - -Specifies the database schema to use in a [multi-schema setup](https://www.prisma.io/docs/guides/database/multi-schema). - -_Params_: - -| Name | Description | -| ---- | ------------------------------- | -| name | The name of the database schema | - -##### @@index - -```zmodel -attribute @@index(_ fields: FieldReference[], map: String?) -``` - -Defines an index in the database. - -_Params_: - -| Name | Description | -| ------ | ------------------------------------------------ | -| fields | A list of fields defined in the current model | -| map | The name of the underlying index in the database | - -##### @@map - -```zmodel -attribute @@map(_ name: String) -``` - -Maps the schema model name to a table with a different name, or an enum name to a different underlying enum in the database. - -_Params_: - -| Name | Description | -| ---- | -------------------------------------------------------- | -| name | The name of the underlying table or enum in the database | - -##### @@ignore - -```zmodel -attribute @@ignore() -``` - -Exclude a model from the Prisma Client (for example, a model that you do not want Prisma users to update). - -##### @@allow - -```zmodel -attribute @@allow(_ operation: String, _ condition: Boolean) -``` - -Defines an access policy that allows a set of operations when the given condition is true. Read more about access policies [here](#access-policy). - -_Params_: - -| Name | Description | -| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| operation | Comma separated list of operations to control, including `"create"`, `"read"`, `"update"`, and `"delete"`. Pass` "all"` as an abbriviation for including all operations. | -| condition | Boolean expression indicating if the operations should be allowed | - -##### @@deny - -```zmodel -attribute @@deny(_ operation: String, _ condition: Boolean) -``` - -Defines an access policy that denies a set of operations when the given condition is true. Read more about access policies [here](#access-policy). - -_Params_: - -| Name | Description | -| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| operation | Comma separated list of operations to control, including `"create"`, `"read"`, `"update"`, and `"delete"`. Pass` "all"` as an abbreviation for including all operations. | -| condition | Boolean expression indicating if the operations should be denied | - -##### @@auth - -```zmodel -attribute @@auth() -``` - -Specify the model for resolving `auth()` function call in access policies. By default, the model named "User" is used. You can use this attribute to override the default behavior. A Zmodel can have at most one model with this attribute. - -##### @@auth - -```zmodel -attribute @@delegate(_ discriminator: FieldReference) -``` - -Marks a model to be a delegated type. Used for [modeling a polymorphic hierarchy](../guides/polymorphism). - -_Params_: - -| Name | Description | -| ------------- | ---------------------------------------------------------------------------------------------------------------------------- | -| discriminator | A `String` or `enum` field in the same model used to store the name of the concrete model that inherit from this base model. | - -##### @@prisma.passthrough - -```zmodel -attribute @@prisma.passthrough(_ text: String) -``` - -A utility attribute for passing arbitrary text to the generated Prisma schema. This is useful as a workaround for dealing with discrepancies between Prisma schema and ZModel. - -_Params_: - -| Name | Description | -| ---- | ------------------------------------ | -| text | Text to passthrough to Prisma schema | - -E.g., the following ZModel content: - -```zmodel -model User { - id Int @id @default(autoincrement()) - name String - @@prisma.passthrough("@@unique([name])") -} -``` - -will be translated to the following Prisma schema: - -```zmodel -model User { - id Int @id @default(autoincrement()) - name String - @@unique([name]) -} -``` - -##### @@meta - -```zmodel -attribute @@meta(_ name: String, _ value: Any) -``` - -Adds arbitrary metadata to a model. The metadata can be accessed by custom plugins for code generation, or at runtime from the `modelMeta` object exported from `@zenstackhq/runtime/model-meta`. The `value` parameter can be an arbitrary literal expression, including object literals. - -```zmodel -model User { - id Int @id - @@meta('description', 'This is a user model') -} -``` - -### Predefined attribute functions - -##### uuid() - -```zmodel -function uuid(): String {} -``` - -Generates a globally unique identifier based on the UUID spec. - -##### cuid() - -```zmodel -function cuid(version: Int?): String {} -``` - -Generates a unique identifier based on the [CUID](https://github.com/ericelliott/cuid) spec. Pass `2` as an argument to use [cuid2](https://github.com/paralleldrive/cuid2). - -##### nanoid() - -```zmodel -function nanoid(length: Int?): String {} -``` - -Generates an identifier based on the [nanoid](https://github.com/ai/nanoid) spec. - -##### ulid() - -```zmodel -function ulid(): String {} -``` - -Generates a unique identifier based on the [ULID](https://github.com/ulid/spec) spec. - -##### now() - -```zmodel -function now(): DateTime {} -``` - -Gets current date-time. - -##### autoincrement() - -```zmodel -function autoincrement(): Int {} -``` - -Creates a sequence of integers in the underlying database and assign the incremented -values to the ID values of the created records based on the sequence. - -##### dbgenerated() - -```zmodel -function dbgenerated(expr: String): Any {} -``` - -Represents default values that cannot be expressed in the Prisma schema (such as random()). - -##### auth() - -```zmodel -function auth(): User {} -``` - -Gets the current login user. The return type of the function is the `User` model defined in the current ZModel. - -##### future() - -```zmodel -function future(): Any {} -``` - -Gets the "post-update" state of an entity. Only valid when used in a "update" access policy. Read more about access policies [here](#access-policy). - -##### check() - -```zmodel -function check(field: FieldReference, operation String?): Boolean {} -``` - -Checks if the current user can perform the given operation on the given field. - -_Params_ - -- `field`: The field to check access for. Must be a relation field. -- `operation`: The operation to check access for. Can be "read", "create", "update", or "delete". If the operation is not provided, it defaults the operation of the containing policy rule. - -_Example_ - -```zmodel -// delegating a single operation kind -model Post { - id Int @id - author User @relation(fields: [authorId], references: [id]) - authorId Int - - // delegate "read" check to the author, equivalent to - // @@allow('read', check(author)) - @@allow('read', check(author, 'read')) -} -``` - -```zmodel -// delegating all operations -model Post { - id Int @id - author User @relation(fields: [authorId], references: [id]) - authorId Int - - // delegate all access policies to the author, equivalent to: - // @@allow('read', check(author)) - // @@allow('create', check(author)) - // @@allow('update', check(author)) - // @@allow('delete', check(author)) - @@allow('all', check(author)) -} -``` - -```zmodel -// delegating field access control -model Post { - id Int @id - title String @allow('update', check(author)) - author User @relation(fields: [authorId], references: [id]) - authorId Int -} -``` - -:::info -The `check()` function only supports singular relation fields and cannot be used with "to-many" relations. We may add support for it in the future. -::: - -##### contains() - -```zmodel - function contains(field: String, search: String, caseInSensitive: Boolean?): Boolean {} -``` - -Checks if the given field contains the search string. The search string is case-sensitive by default. Use `caseInSensitive` to toggle the case sensitivity. - -Equivalent to Prisma's [contains](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#contains) operator. - -##### search() - -```zmodel -function search(field: String, search: String): Boolean {} -``` - -Checks if the given field contains the search string using [full-text-search](https://www.prisma.io/docs/concepts/components/prisma-client/full-text-search). - -Equivalent to Prisma's [search](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#search) operator. - -##### startsWith() - -```zmodel -function startsWith(field: String, search: String): Boolean {} -``` - -Checks if the given field starts with the search string. - -Equivalent to Prisma's [startsWith](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#startswith) operator. - -##### endsWith() - -```zmodel -function endsWith(field: String, search: String): Boolean {} -``` - -Checks if the given field ends with the search string. - -Equivalent to Prisma's [endsWith](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#endswith) operator. - -##### has() - -```zmodel -function has(field: Any[], search: Any): Boolean {} -``` - -Check if the given field (list) contains the search value. - -Equivalent to Prisma's [has](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#has) operator. - -##### hasEvery() - -```zmodel -function hasEvery(field: Any[], search: Any[]): Boolean {} -``` - -Check if the given field (list) contains every element of the search list. - -Equivalent to Prisma's [hasEvery](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#hasevery) operator. - -##### hasSome() - -```zmodel -function hasSome(field: Any[], search: Any[]): Boolean {} -``` - -Check if the given field (list) contains at least one element of the search list. - -Equivalent to Prisma's [hasSome](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#hassome) operator. - -##### isEmpty() - -```zmodel -function isEmpty(field: Any[]): Boolean {} -``` - -Check if the given field (list) is empty. - -Equivalent to Prisma's [isEmpty](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#isempty) operator. - -##### currentModel() - -```zmodel -function currentModel(casing: String?): String {} -``` - -Can only be used in access policy expressions. Return the name of the model for which the policy rule is defined. If the rule is inherited to a sub model, this function returns the name of the sub model. - -The optional "casing" parameter can be used to control the casing of the returned name. Valid values are "original", "upper", "lower", "capitalize", "uncapitalize". Defaults to "original". - -##### currentOperation() - -```zmodel -function currentOperation(casing: String?): String {} -``` - -Can only be used in access policy expressions. Return the operation for which the policy rule is defined for - "create", "read", "update", or "delete". Note that a rule with "all" operation is expanded to "create", "read", "update", and "delete" rules, and the function returns corresponding value for each expanded version. - -The optional "casing" parameter can be used to control the casing of the returned name. Valid values are "original", "upper", "lower", "capitalize", "uncapitalize". Defaults to "original". - -### Examples - -Here're some examples on using field and model attributes: - -```zmodel -model User { - // unique id field with a default UUID value - id String @id @default(uuid()) - - // require email field to be unique - email String @unique - - // password is hashed with bcrypt with length of 16, omitted when returned from the CRUD services - password String @password(saltLength: 16) @omit - - // default to current date-time - createdAt DateTime @default(now()) - - // auto-updated when the entity is modified - updatedAt DateTime @updatedAt - - // mapping to a different column name in database - description String @map("desc") - - // mapping to a different table name in database - @@map("users") - - // use @@index to specify fields to create database index for - @@index([email]) - - // use @@allow to specify access policies - @@allow("create,read", true) - - // use auth() to reference the current user - // use future() to access the "post-update" state - @@allow("update", auth() == this && future().email == email) -} -``` - -### Custom attributes and functions - -You can find examples of custom attributes and functions in [ZModel Standard Library](https://github.com/zenstackhq/zenstack/blob/main/packages/schema/src/res/stdlib.zmodel). - -## Field - -Fields are typed members of models and types. - -### Syntax - -```zmodel -model Model { - [FIELD_NAME] [FIELD_TYPE] (FIELD_ATTRIBUTES)? -} -``` - -Or - -```zmodel -type Type { - [FIELD_NAME] [FIELD_TYPE] (FIELD_ATTRIBUTES)? -} -``` - -- **[FIELD_NAME]** - - Name of the field. Needs to be unique in the containing model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. - -- **[FIELD_TYPE]** - - Type of the field. Can be a scalar type, a reference to another model if the field belongs to a [model](#model), or a reference to another type if it belongs to a [type](#type). - - The following scalar types are supported: - - - String - - Boolean - - Int - - BigInt - - Float - - Decimal - - Json - - Bytes - - [Unsupported types](https://www.prisma.io/docs/concepts/components/prisma-schema/data-model#unsupported-types) - - A field's type can be any of the scalar or reference type, a list of the aforementioned type (suffixed with `[]`), or an optional of the aforementioned type (suffixed with `?`). - -- **[FIELD_ATTRIBUTES]** - - Field attributes attach extra behaviors or constraints to the field. See [Attribute](#attribute) for more information. - -### Example - -```zmodel -model Post { - // "id" field is a mandatory unique identifier of this model - id String @id @default(uuid()) - - // fields can be DateTime - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - // or string - title String - - // or integer - viewCount Int @default(0) - - // and optional - content String? - - // and a list too - tags String[] - - // and can reference another model too - comments Comment[] -} -``` - -## Relation - -Relations are connections among models. There're three types of relations: - -- One-to-one -- One-to-many -- Many-to-many - -Relations are expressed with a pair of fields and together with the special `@relation` field attribute. One side of the relation field carries the `@relation` attribute to indicate how the connection is established. - -### One-to-one relation - -The _owner_ side of the relation declares an optional field typed as the model of the _owned_ side of the relation. - -On the _owned_ side, a reference field is declared with `@relation` attribute, together with a **foreign key** field storing the id of the owner entity. - -```zmodel -model User { - id String @id - profile Profile? -} - -model Profile { - id String @id - user User @relation(fields: [userId], references: [id]) - userId String @unique -} -``` - -### One-to-many relation - -The _owner_ side of the relation declares a list field typed as the model of the _owned_ side of the relation. - -On the _owned_ side, a reference field is declared with `@relation` attribute, together with a **foreign key** field storing the id of the owner entity. - -```zmodel -model User { - id String @id - posts Post[] -} - -model Post { - id String @id - author User? @relation(fields: [authorId], references: [id]) - authorId String? -} -``` - -### Many-to-many relation - -A _join model_ is declared to connect the two sides of the relation using two one-to-one relations. - -Each side of the relation then establishes a one-to-many relation with the _join model_. - -```zmodel -model Space { - id String @id - // one-to-many with the "join-model" - members Membership[] -} - -// Membership is the "join-model" between User and Space -model Membership { - id String @id() - - // one-to-many from Space - space Space @relation(fields: [spaceId], references: [id]) - spaceId String - - // one-to-many from User - user User @relation(fields: [userId], references: [id]) - userId String - - // a user can be member of a space for only once - @@unique([userId, spaceId]) -} - -model User { - id String @id - // one-to-many with the "join-model" - membership Membership[] -} - -``` - -### Self-relations - -A relation field referencing its own model is called "self-relation". ZModel's represents self-relation in the same way as Prisma does. Please refer to the [Prisma documentation](https://www.prisma.io/docs/concepts/components/prisma-schema/relations/self-relations) for more details. - -### Referential action - -When defining a relation, you can specify what happens when one side of a relation is updated or deleted. See [Referential action](#referential-action) for details. - -## Access policy - -### Model-level policy - -Model-level access policies are defined with `@@allow` and `@@deny` attributes. They specify the eligibility of an operation over a model entity. The signatures of the attributes are: - -- `@@allow` - - ```zmodel - attribute @@allow(_ operation: String, _ condition: Boolean) - ``` - - _Params_: - - | Name | Description | - | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | - | operation | Comma separated list of operations to control, including `"create"`, `"read"`, `"update"`, and `"delete"`. Pass` "all"` as an abbreviation for including all operations. | - | condition | Boolean expression indicating if the operations should be allowed | - -- `@@deny` - - ```zmodel - attribute @@deny(_ operation: String, _ condition: Boolean) - ``` - - _Params_: - - | Name | Description | - | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | - | operation | Comma separated list of operations to control, including `"create"`, `"read"`, `"update"`, and `"delete"`. Pass` "all"` as an abbreviation for including all operations. | - | condition | Boolean expression indicating if the operations should be denied | - -### Field-level policy - -Field-level access policies are defined with `@allow` and `@deny` attributes. They control whether the annotated field can be read or updated. If a field fails "read" check, it'll be deleted when returned. If a field is set to be updated but fails "update" check, the update operation will be rejected. - -Note that it's not allowed to put "update" rule on relation fields, because whether an entity can be updated shouldn't be determined indirectly by a relation, but directly by the entity itself. However, you can put "update" rule on a foreign key field to control how a a relation can be updated. - -The signatures of the attributes are: - -- `@allow` - - ```zmodel - attribute @allow(_ operation: String, _ condition: Boolean, _ override: Boolean?) - ``` - - _Params_: - - | Name | Description | Default | - | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- | - | operation | Comma separated list of operations to control, including `"read"` and `"update"`. Pass` "all"` as an abbreviation for including all operations. | | - | condition | Boolean expression indicating if the operations should be allowed | | - | override | Boolean indicating if the field-level policy should override model-level ones. See [here](../the-complete-guide/part1/access-policy/field-level#overriding-model-level-policies) for more details. | false | - -- `@deny` - - ```zmodel - attribute @deny(_ operation: String, _ condition: Boolean) - ``` - - _Params_: - - | Name | Description | - | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | - | operation | Comma separated list of operations to control, including ``"read"` and `"update"`. Pass` "all"` as an abbreviation for including all operations. | - | condition | Boolean expression indicating if the operations should be denied | - -### Policy expressions - -Policy rules use boolean expressions to make verdicts. ZModel provides a set of literals and operators for constructing expressions of arbitrary complexity. - -``` - -Expression ::= Literal | Array | This | Null | Reference | MemberAccess | Invocation | Binary | Unary | CollectionPredicate - -Literal ::= String | Number | Boolean - -Array ::= "[" Expression [, Expression]* "]" - -This ::= "this" - -Null ::= "null" - -Reference ::= Identifier - -MemberAccess ::= Expression "." Identifier - -Operator_Precedence#table -Binary ::= Expression ("==" | "!=" | ">" | "<" | ">=" | "<=" | "&&" | "||" || "in") - -Unary ::= "!" Expression - -CollectionPredicate ::= Expression ("?" | "!" | "^") "[" Expression "]" - -``` - -Binary operator precedence follows [Javascript's rules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/). - -Collection predicate expressions are used for reaching into relation fields. You can find more details [here](#collection-predicate-expressions). - -### Using authentication in policy rules - -It's very common to use the current login user to verdict if an operation should be permitted. Therefore, ZenStack provides a built-in `auth()` attribute function that evaluates to the `User` entity corresponding to the current user. To use the function, your ZModel file must define a `User` model or a model marked with the `@@auth` attribute. - -You can use `auth()` to: - -- Check if a user is logged in - - ```zmodel - @@deny('all', auth() == null) - ``` - -- Access user's fields - - ```zmodel - @@allow('update', auth().role == 'ADMIN') - ``` - -- Compare user identity - - ```zmodel - // owner is a relation field to User model - @@allow('update', auth() == owner) - ``` - -### Accessing relation fields in policy - -As you've seen in the examples above, you can access fields from relations in policy expressions. For example, to express "a user can be read by any user sharing a space" in the `User` model, you can directly read into its `membership` field. - -```zmodel - @@allow('read', membership?[space.members?[user == auth()]]) -``` - -In most cases, when you use a "to-many" relation in a policy rule, you'll use "Collection Predicate" to express a condition. See [next section](#collection-predicate-expressions) for details. - -### Collection predicate expressions - -Collection predicate expressions are boolean expressions used to express conditions over a list. It's mainly designed for building policy rules for "to-many" relations. It has three forms of syntaxes: - -- Any - - ``` - ?[condition] - ``` - - Any element in `collection` matches `condition` - -- All - - ``` - ![condition] - ``` - - All elements in `collection` match `condition` - -- None - - ``` - ^[condition] - ``` - - None element in `collection` matches `condition` - -The `condition` expression has direct access to fields defined in the model of `collection`. E.g.: - -```zmodel - @@allow('read', members?[user == auth()]) -``` - -, in condition `user == auth()`, `user` refers to the `user` field in model `Membership`, because the collection `members` is resolved to `Membership` model. - -Also, collection predicates can be nested to express complex conditions involving multi-level relation lookup. E.g.: - -```zmodel - @@allow('read', membership?[space.members?[user == auth()]]) -``` - -In this example, `user` refers to `user` field of `Membership` model because `space.members` is resolved to `Membership` model. - -### Combining multiple rules - -A model can contain an arbitrary number of policy rules. The logic of combining model-level rules is as follows: - -- The operation is rejected if any of the conditions in `@@deny` rules evaluate to `true`. -- Otherwise, the operation is permitted if any of the conditions in `@@allow` rules evaluate to `true`. -- Otherwise, the operation is rejected. - -A field can also contain an arbitrary number of policy rules. The logic of combining field-level rules is as follows: - -- The operation is rejected if any of the conditions in `@deny` rules evaluate to `true`. -- Otherwise, if there exists any `@allow` rule and at least one of them evaluates to `true`, the operation is permitted. -- Otherwise, if there exists any `@allow` rule but none one of them evaluates to `true`, the operation is rejected. -- Otherwise, the operation is permitted. - -Please note the difference between model-level and field-level rules. Model-level access are by-default denied, while field-level access are by-default allowed. - -### "Create" rules - -The "create" policy rules should be understood as: **if an entity were to be created, would it satisfy the rules**. Or, in other words, the rules are checked "post create". - -An entity creating process works like the following: - -1. Initiate a transaction and create the entity. -2. In the same transaction, try to read the created entity with the "create" rules as filter, and see if it succeeds. -3. If the read fails, the transaction is rolled back; otherwise it's committed. - -The "post-create check" semantic allows the rules to access relations of the entity being created since they are only accessible after the create happens. For simple cases, ZenStack may apply optimizations to reject a create request without initiating a transaction, but generally speaking the "post-create check" semantic is the correct way to think about it. - -We may introduce a "pre-create" policy type in the future. - -### "Pre-update" vs." post-update" rules - -When an access policy rule is applied to a mutate operation, the entities under operation have a "pre" and "post" state. For a "create" rule, its "pre" state is empty, so the rule implicitly refers to the "post" state. For a "delete" rule, its "post" state is empty, so the rule implicitly refers to the "pre" state. - -However, for "update" rules it is ambiguous; both the "pre" and the "post" states exist. By default, for "update" rules, fields referenced in the expressions refer to the "pre" state, and you can use the `future()` function to refer to the "post" state explicitly. - -In the following example, the "update" rule uses `future()` to ensure an update cannot alter the post's owner. - -```zmodel -model Post { - id String @id @default(uuid()) - title String @length(1, 100) - author User @relation(fields: [authorId], references: [id], onDelete: Cascade) - authorId String - - // update can only be done by the author, and is not allowed to change author - @@allow('update', author == auth() && future().author == author) -} -``` - -:::info -The `future()` function is not supported in field-level access policies. To express post-update rules, put them into model-level policies. -::: - -### Examples - -#### A simple example with Post model - -```zmodel -model Post { - // reject all operations if user's not logged in - @@deny('all', auth() == null) - - // allow all operations if the entity's owner matches the current user - @@allow('all', auth() == owner) - - // posts are readable to anyone - @allow('read', true) -} -``` - -#### A more complex example with multi-user spaces - -```zmodel -model Space { - id String @id - members Membership[] - owner User @relation(fields: [ownerId], references: [id]) - ownerId String - - // require login - @@deny('all', auth() == null) - - // everyone can create a space - @@allow('create', true) - - // owner can do everything - @@allow('all', auth() == owner) - - // any user in the space can read the space - // - // Here the ?[condition] syntax is called - // "Collection Predicate", used to check if any element - // in the "collection" matches the "condition" - @@allow('read', members?[user == auth()]) -} - -// Membership is the "join-model" between User and Space -model Membership { - id String @id() - - // one-to-many from Space - space Space @relation(fields: [spaceId], references: [id]) - spaceId String - - // one-to-many from User - user User @relation(fields: [userId], references: [id]) - userId String - - // a user can be member of a space for only once - @@unique([userId, spaceId]) - - // require login - @@deny('all', auth() == null) - - // space owner can create/update/delete - @@allow('create,update,delete', space.owner == auth()) - - // user can read entries for spaces which he's a member of - @@allow('read', space.members?[user == auth()]) -} - -model User { - id String @id - email String @unique - membership Membership[] - ownedSpaces Space[] - - // allow signup - @@allow('create', true) - - // user can do everything to herself; note that "this" represents - // the current entity - @@allow('all', auth() == this) - - // can be read by users sharing a space - @@allow('read', membership?[space.members?[user == auth()]]) -} - -``` - -## Data validation - -### Overview - -Data validation is used for attaching constraints to field values. Unlike access policies, field validation rules cannot access the current user with the `auth()` function and are only checked for 'create' and 'update' operations. The main purpose of field validation is to ensure data integrity and consistency, not for access control. - -The [`@core/zod`](./plugins/zod) plugin recognizes the validation attributes and includes them into the generated Zod schemas. - -### Field-level validation attributes - -The following attributes can be used to attach validation rules to individual fields: - -#### String - -- `@length(_ min: Int?, _ max: Int?, _ message: String?)` - - Validates length of a string field. - -- `@startsWith(_ text: String, _ message: String?)` - - Validates a string field value starts with the given text. - -- `@endsWith(_ text: String, _ message: String?)` - - Validates a string field value ends with the given text. - -- `@contains(_text: String, _ message: String?)` - - Validates a string field value contains the given text. - -- `@email(_ message: String?)` - - Validates a string field value is a valid email address. - -- `@url(_ message: String?)` - - Validates a string field value is a valid url. - -- `@datetime(_ message: String?)` - - Validates a string field value is a valid ISO datetime. - -- `@regex(_ regex: String, _ message: String?)` - - Validates a string field value matches a regex. - -- `@trim(_ value: String)` - - Trims whitespace. - -- `@lower(_ value: String)` - - Converts to lowercase. - -- `@upper(_ value: String)` - - Converts to uppercase. - -:::info -Attributes `@trim`, `@lower`, and `@upper` are actually "transformation" instead of "validation". They make sure the values are transformed before storing into the database. -::: - -#### Number - -- `@gt(_ value: Int, _ message: String?)` - - Validates a number field is greater than the given value. - -- `@gte(_ value: Int, _ message: String?)` - - Validates a number field is greater than or equal to the given value. - -- `@lt(_ value: Int, _ message: String?)` - - Validates a number field is less than the given value. - -- `@lte(_ value: Int, _ message: String?)` - - Validates a number field is less than or equal to the given value. - -### Model-level validation attributes - -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?, _ path: String[]?) -``` - -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: - -- `function length(field: String, min: Int, max: Int?): Boolean` - - Validates length of a string field. - -- `function regex(field: String, regex: String): Boolean` - - Validates a string field value matches a regex. - -- `function email(field: String): Boolean` - - Validates a string field value is a valid email address. - -- `function datetime(field: String): Boolean` - - Validates a string field value is a valid ISO datetime. - -- `function url(field: String)` - - Validates a string field value is a valid url. - -- `function contains(field: String, search: String, caseInSensitive: Boolean?): Boolean` - - Validates a string field contains the search string. - -- `function startsWith(field: String, search: String): Boolean` - - Validates a string field starts with the search string. - -- `function endsWith(field: String, search: String): Boolean` - - Validates a string field ends with the search string. - -- `function has(field: Any[], search: Any): Boolean` - - Validates a list field contains the search value. - -- `function hasEvery(field: Any[], search: Any[]): Boolean` - - Validates a list field contains every element in the search list. - -- `function hasSome(field: Any[], search: Any[]): Boolean` - - Validates a list field contains some elements in the search list. - -- `function isEmpty(field: Any[]): Boolean` - - Validates a list field is null or empty. - -### Example - -```zmodel -model User { - id String @id - handle String @regex("^[0-9a-zA-Z]{4,16}$") - email String? @email @endsWith("@myorg.com", "must be an email from myorg.com") - profileImage String? @url - age Int @gte(18) - activated Boolean @default(false) - - @@validate(!activated || email != null, "activated user must have an email") -} -``` - -## Referential action - -### Overview - -When defining a relation, you can use referential action to control what happens when one side of a relation is updated or deleted by setting the `onDelete` and `onUpdate` parameters in the `@relation` attribute. - -```zmodel -attribute @relation( - _ name: String?, - fields: FieldReference[]?, - references: FieldReference[]?, - onDelete: ReferentialAction?, - onUpdate: ReferentialAction?, - map: String?) -``` - -The `ReferentialAction` enum is defined as: - -```zmodel -enum ReferentialAction { - Cascade - Restrict - NoAction - SetNull - SetDefault -} -``` - -- `Cascade` - - - **onDelete**: deleting a referenced record will trigger the deletion of referencing record. - - - **onUpdate**: updates the relation scalar fields if the referenced scalar fields of the dependent record are updated. - -- `Restrict` - - - **onDelete**: prevents the deletion if any referencing records exist. - - **onUpdate**: prevents the identifier of a referenced record from being changed. - -- `NoAction` - - Similar to 'Restrict', the difference between the two is dependent on the database being used. - - See details [here](https://www.prisma.io/docs/concepts/components/prisma-schema/relations/referential-actions#noaction ':target=blank') - -- `SetNull` - - - **onDelete**: the scalar field of the referencing object will be set to NULL. - - **onUpdate**: when updating the identifier of a referenced object, the scalar fields of the referencing objects will be set to NULL. - -- `SetDefault` - - **onDelete**: the scalar field of the referencing object will be set to the fields default value. - - **onUpdate**: the scalar field of the referencing object will be set to the fields default value. - -### Example - -```zmodel -model User { - id String @id - profile Profile? -} - -model Profile { - id String @id - user @relation(fields: [userId], references: [id], onUpdate: Cascade, onDelete: Cascade) - userId String @unique -} -``` - -## Comments - -ZModel supports both line comments (starting with `//`) and block comments (starting with `/*` and ending with `*/`). Comments on declarations (models, enums, fields, etc.) starting with triple slashes (`///`) are treated as documentation: - -- They show up as hover tooltips in IDEs. -- They are passed along to the generated Prisma schema. - -```zmodel -/// A user model -model User { - id String @id - - /// The user's email - email String @unique -} -``` - -You can also use JSDoc-style comments as documentation, however they are not passed along to the generated Prisma schema. - -```zmodel -/** - * A user model - */ -model User { - id String @id - - /** - * The user's email - */ - email String @unique -} -``` From ae008285df3a291cb26d8a65f1d84ddbb1096d18 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Sun, 3 Aug 2025 17:15:05 +0800 Subject: [PATCH 03/51] WIP --- .../version-3.x/_components/ZModelVsPSL.tsx | 16 ++ .../version-3.x/migration/_category_.yml | 2 +- .../version-3.x/migration/introduction.md | 6 - .../version-3.x/migration/overview.md | 6 + .../{orm/zmodel => modeling}/_category_.yml | 6 +- .../version-3.x/modeling/attribute.md | 47 ++++ .../version-3.x/modeling/custom-type.md | 46 ++++ .../version-3.x/modeling/datasource.md | 46 ++++ versioned_docs/version-3.x/modeling/enum.md | 27 +++ versioned_docs/version-3.x/modeling/mixin.md | 47 ++++ versioned_docs/version-3.x/modeling/model.md | 190 +++++++++++++++ .../{orm/zmodel => modeling}/multi-file.md | 4 +- .../version-3.x/modeling/overview.md | 52 +++++ versioned_docs/version-3.x/modeling/plugin.md | 7 + .../version-3.x/modeling/polymorphism.md | 34 +++ .../version-3.x/modeling/relations.md | 219 ++++++++++++++++++ .../version-3.x/modeling/strong-typed-json.md | 50 ++++ versioned_docs/version-3.x/orm/_category_.yml | 2 +- .../orm/{introduction.md => overview.md} | 6 +- .../version-3.x/orm/quick-start.mdx | 2 +- .../version-3.x/orm/zmodel/attributes.md | 6 - .../version-3.x/orm/zmodel/builtin-types.md | 6 - .../version-3.x/orm/zmodel/components.md | 6 - .../version-3.x/orm/zmodel/custom-types.md | 6 - .../version-3.x/orm/zmodel/datasource.md | 7 - .../version-3.x/orm/zmodel/models.md | 7 - .../version-3.x/orm/zmodel/polymorphism.md | 7 - .../version-3.x/orm/zmodel/relations.md | 6 - .../version-3.x/orm/zmodel/reusing-fields.md | 7 - .../version-3.x/reference/_category_.yml | 2 +- versioned_docs/version-3.x/samples.md | 2 +- .../version-3.x/service/_category_.yml | 2 +- .../service/{introduction.md => overview.md} | 2 +- versioned_docs/version-3.x/upgrade.md | 2 +- .../version-3.x/utilities/_category_.yml | 2 +- .../version-3.x/utilities/tanstack-query.md | 6 + versioned_docs/version-3.x/utilities/zod.md | 2 +- versioned_docs/version-3.x/welcome.md | 22 +- 38 files changed, 831 insertions(+), 84 deletions(-) create mode 100644 versioned_docs/version-3.x/_components/ZModelVsPSL.tsx delete mode 100644 versioned_docs/version-3.x/migration/introduction.md create mode 100644 versioned_docs/version-3.x/migration/overview.md rename versioned_docs/version-3.x/{orm/zmodel => modeling}/_category_.yml (52%) create mode 100644 versioned_docs/version-3.x/modeling/attribute.md create mode 100644 versioned_docs/version-3.x/modeling/custom-type.md create mode 100644 versioned_docs/version-3.x/modeling/datasource.md create mode 100644 versioned_docs/version-3.x/modeling/enum.md create mode 100644 versioned_docs/version-3.x/modeling/mixin.md create mode 100644 versioned_docs/version-3.x/modeling/model.md rename versioned_docs/version-3.x/{orm/zmodel => modeling}/multi-file.md (64%) create mode 100644 versioned_docs/version-3.x/modeling/overview.md create mode 100644 versioned_docs/version-3.x/modeling/plugin.md create mode 100644 versioned_docs/version-3.x/modeling/polymorphism.md create mode 100644 versioned_docs/version-3.x/modeling/relations.md create mode 100644 versioned_docs/version-3.x/modeling/strong-typed-json.md rename versioned_docs/version-3.x/orm/{introduction.md => overview.md} (98%) delete mode 100644 versioned_docs/version-3.x/orm/zmodel/attributes.md delete mode 100644 versioned_docs/version-3.x/orm/zmodel/builtin-types.md delete mode 100644 versioned_docs/version-3.x/orm/zmodel/components.md delete mode 100644 versioned_docs/version-3.x/orm/zmodel/custom-types.md delete mode 100644 versioned_docs/version-3.x/orm/zmodel/datasource.md delete mode 100644 versioned_docs/version-3.x/orm/zmodel/models.md delete mode 100644 versioned_docs/version-3.x/orm/zmodel/polymorphism.md delete mode 100644 versioned_docs/version-3.x/orm/zmodel/relations.md delete mode 100644 versioned_docs/version-3.x/orm/zmodel/reusing-fields.md rename versioned_docs/version-3.x/service/{introduction.md => overview.md} (53%) create mode 100644 versioned_docs/version-3.x/utilities/tanstack-query.md diff --git a/versioned_docs/version-3.x/_components/ZModelVsPSL.tsx b/versioned_docs/version-3.x/_components/ZModelVsPSL.tsx new file mode 100644 index 00000000..0ea279d3 --- /dev/null +++ b/versioned_docs/version-3.x/_components/ZModelVsPSL.tsx @@ -0,0 +1,16 @@ +import React, { FC } from 'react'; +import Admonition from '@theme/Admonition'; + +interface ZModelVsPSLProps { + children: React.ReactNode; +} + +const ZModelVsPSL: FC = ({ children }) => { + return ( + + {children} + + ); +}; + +export default ZModelVsPSL; diff --git a/versioned_docs/version-3.x/migration/_category_.yml b/versioned_docs/version-3.x/migration/_category_.yml index be8bc9d1..013a697a 100644 --- a/versioned_docs/version-3.x/migration/_category_.yml +++ b/versioned_docs/version-3.x/migration/_category_.yml @@ -1,4 +1,4 @@ -position: 3 +position: 4 label: Migration collapsible: true collapsed: true diff --git a/versioned_docs/version-3.x/migration/introduction.md b/versioned_docs/version-3.x/migration/introduction.md deleted file mode 100644 index 2e8a25db..00000000 --- a/versioned_docs/version-3.x/migration/introduction.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -sidebar_position: 1 -description: Introduction to ZenStack migration ---- - -# Introduction diff --git a/versioned_docs/version-3.x/migration/overview.md b/versioned_docs/version-3.x/migration/overview.md new file mode 100644 index 00000000..9fe870b2 --- /dev/null +++ b/versioned_docs/version-3.x/migration/overview.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 1 +description: ZenStack migration overview +--- + +# Overview diff --git a/versioned_docs/version-3.x/orm/zmodel/_category_.yml b/versioned_docs/version-3.x/modeling/_category_.yml similarity index 52% rename from versioned_docs/version-3.x/orm/zmodel/_category_.yml rename to versioned_docs/version-3.x/modeling/_category_.yml index 396fcc06..8dbacd32 100644 --- a/versioned_docs/version-3.x/orm/zmodel/_category_.yml +++ b/versioned_docs/version-3.x/modeling/_category_.yml @@ -1,7 +1,7 @@ -position: 3 -label: Writing Schema +position: 2 +label: Data Modeling collapsible: true collapsed: true link: type: generated-index - title: Writing Schema + title: Data Modeling diff --git a/versioned_docs/version-3.x/modeling/attribute.md b/versioned_docs/version-3.x/modeling/attribute.md new file mode 100644 index 00000000..7994aff6 --- /dev/null +++ b/versioned_docs/version-3.x/modeling/attribute.md @@ -0,0 +1,47 @@ +--- +sidebar_position: 4 +description: Attributes in ZModel +--- + +import ZModelVsPSL from '../_components/ZModelVsPSL'; + +# Attribute + +Attributes allow you to attach metadata to models and fields. As you've seen in the previous sections, they are used for many purposes, like adding unique constraints, mapping names, etc. Attributes are also indispensable for modeling relations between models. + +## Naming conventions + +By convention, attributes attached to models use a double `@@` prefix, while those for fields use a single `@` prefix. + +```zmodel +model User { + id Int @id + email String @unique + + @@index([email, name]) +} +``` + +## Defining and applying attributes + + +Prisma schema doesn't allow users to define custom attributes, while ZModel allows it and uses it as a key mechanism for extensibility. + + +ZModel comes with a rich set of attributes that you can use directly. See [ZModel Language Reference](../reference/zmodel-language.md) for a complete list. You can also define your own custom attributes for specific purposes. Attributes are defined with a list of typed parameters. Parameters can named (default) or positional. Positional parameters can be passed with or without an explicit name. Parameters can also be optional. + +Here's an example for how the `@unique` attribute is defined: + +```zmodel +attribute @unique(map: String?, length: Int?, sort: SortOrder?) +``` + +You can apply it in various ways: + +```zmodel +model Foo { + x String @unique() // default application + y String @unique('y_unique') // positional parameter + z String @unique(map: 'z_unique', length: 10) // named parameter +} +``` diff --git a/versioned_docs/version-3.x/modeling/custom-type.md b/versioned_docs/version-3.x/modeling/custom-type.md new file mode 100644 index 00000000..46f966ea --- /dev/null +++ b/versioned_docs/version-3.x/modeling/custom-type.md @@ -0,0 +1,46 @@ +--- +sidebar_position: 7 +description: Custom types in ZModel +--- + +import ZModelVsPSL from '../_components/ZModelVsPSL'; + +# Custom Type + + +Custom type is a ZModel concept and doesn't exist in PSL. + + +Besides models, you can also define custom types to encapsulate complex data structures. The main difference between a model and a custom type is that the latter is not backed by a database table. + +Here's a simple example: + +```zmodel +type Address { + street String + city String + country String + zip Int +} +``` + +Custom types are defined exactly like models, with the exception that they cannot contain fields that are relations to other models. They can, however, contain fields that are other custom types. + +There are two ways to use custom types: + +```zmodel +type Address { + street String + city String + country String + zip Int +} + +type UserProfile { + gender String + address Address? +} +``` + +- [Mixin](./mixin.md) +- [Strongly typed JSON fields](./strong-typed-json.md) diff --git a/versioned_docs/version-3.x/modeling/datasource.md b/versioned_docs/version-3.x/modeling/datasource.md new file mode 100644 index 00000000..6f308fff --- /dev/null +++ b/versioned_docs/version-3.x/modeling/datasource.md @@ -0,0 +1,46 @@ +--- +sidebar_position: 2 +description: Datasource in ZModel +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import ZModelVsPSL from '../_components/ZModelVsPSL'; + +# Data Source + +The `datasource` block provides information about the database your application uses. The ORM relies on it to determine the proper SQL dialect to use when generating queries. If you use [Migration](../migration/), it must also have a `url` field that specifies the database connection string, so that the migration engine knows how to connect to the database. The `env` function can be used to reference environment variables so you can keep sensitive information out of the code. + +:::tip +You can use both single quote and double quote for string literals. +::: + +Each ZModel schema must have exactly one `datasource` block. + + + + +```zmodel +datasource db { + provider = 'postgresql' + url = env('DATABASE_URL') +} +``` + + + +```zmodel +datasource db { + provider = 'sqlite' + url = 'file:./dev.db' +} +``` + + + + +Currently only PostgreSQL and SQLite are supported. MySql will be supported in a future release. There's no plan for other relational database types or NoSQL databases. + + +ZenStack's ORM runtime doesn't rely on the `url` information to connect to the database. Instead, you provide the information when constructing an ORM client. More on this in the [ORM](../orm/) section. + diff --git a/versioned_docs/version-3.x/modeling/enum.md b/versioned_docs/version-3.x/modeling/enum.md new file mode 100644 index 00000000..f6410bba --- /dev/null +++ b/versioned_docs/version-3.x/modeling/enum.md @@ -0,0 +1,27 @@ +--- +sidebar_position: 4 +description: Enums in ZModel +--- + +# Enum + +Enums are simple constructs that allow you to define a set of named values. + +```zmodel +enum Role { + USER + ADMIN +} +``` + +They can be used to type model fields: + +```zmodel +model User { + id Int @id + // highlight-next-line + role Role @default(USER) +} +``` + +Enum field names are added to the global scope and are resolved without qualification. You need to make sure they don't collide with other global names. \ No newline at end of file diff --git a/versioned_docs/version-3.x/modeling/mixin.md b/versioned_docs/version-3.x/modeling/mixin.md new file mode 100644 index 00000000..c08b2b95 --- /dev/null +++ b/versioned_docs/version-3.x/modeling/mixin.md @@ -0,0 +1,47 @@ +--- +sidebar_position: 8 +description: Reusing common fields with mixins +--- + +import ZModelVsPSL from '../_components/ZModelVsPSL'; + +# Mixin + + +Mixin is a ZModel concept and don't exist in PSL. + + +:::info +Mixin was previously known as "abstract inheritance" in ZenStack v2. It's renamed and changed to use the `with` keyword to distinguish from polymorphic model inheritance. +::: + +Very often you'll find many of your models share quite a few common fields. It's tedious and error-prone to repeat them. As a rescue, you can put those fields into custom types, and "mix-in" them into your models. + +***Before:*** + +```zmodel +model User { + id String @id + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + email String @unique +} +``` + +***After:*** + +```zmodel +type BaseFieldsMixin { + id String @id + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model User with BaseFieldsMixin { + email String @unique +} +``` + +A model can use multiple mixins as long as their field names don't conflict. + +Mixins don't exist at the database level. The fields defined in the mixin types are conceptually inlined into the models that use them. diff --git a/versioned_docs/version-3.x/modeling/model.md b/versioned_docs/version-3.x/modeling/model.md new file mode 100644 index 00000000..1af5b1a3 --- /dev/null +++ b/versioned_docs/version-3.x/modeling/model.md @@ -0,0 +1,190 @@ +--- +sidebar_position: 3 +description: Models in ZModel +--- + +# Model + +The `model` construct is the core of ZModel. It defines the structure of your data and their relations. A model represents a domain entity, and is mapped to a database table. + +## Defining models + +A typical model looks like this: + +```zmodel +model User { + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + email String @unique + name String +} +``` + +The simplest models are just a collection of fields. A model must be uniquely identifiable by some of its fields. For most cases, you'll have a field marked with the `@id` attribute (more about [attributes](./attribute) later). + +```zmodel +model User { + // highlight-next-line + id Int @id +} +``` + +If your model needs a composite id, you can use the `@@id` model-level attribute to specify it: + +```zmodel +model City { + country String + name String + // highlight-next-line + @@id([country, name]) +} +``` + +If no `@id` or `@@id` is specified, the ORM will resort to using a field (or fields) marked with the `@unique` or `@@unique` attribute as the identifier. + +```zmodel +model User { + // highlight-next-line + email String @unique +} + +model City { + country String + name String + // highlight-next-line + @@unique([country, name]) +} +``` + +## Model fields + +Each model field must at least have a name and a type. A field can be typed in one of the following ways: + +1. Built-in types, including: + - String + - Boolean + - Int + - BigInt + - Float + - Decimal + - DateTime + - Json + - Bytes + - Unsupported + + The `Unsupported` type is for defining fields of types not supported by the ORM, however letting the migration engine know how to create the field in the database. + + ```zmodel + // from Prisma docs + model Star { + id Int @id + // highlight-next-line + position Unsupported("circle")? @default(dbgenerated("'<(10,4),11>'::circle")) + } + ``` + +2. Enum + + We'll talk about [enums](./enum) later. + + ```zmodel + enum Role { + USER + ADMIN + } + + model User { + id Int @id + // highlight-next-line + role Role + } + ``` + +3. Model + + It'll then form a relation. We'll cover that topic [later](./relation). + ```zmodel + model Post { + id Int @id + // highlight-next-line + author User @relation(fields: [authorId], references: [id]) + authorId Int + } + ``` +4. Custom type + + ZenStack allows you to define custom types in the schema and use that to type Json fields. This will be covered in more details in the [Custom Types](./custom-type) section. + + ```zmodel + type Address { + street String + city String + country String + zip Int + } + + model User { + id Int @id + // highlight-next-line + address Address @json + } + ``` + +A field can be set optional by adding the `?` suffix to its type, or list by adding the `[]` suffix. However, a field cannot be both optional and a list at the same time. + +```zmodel +model User { + id Int @id + // highlight-next-line + name String? + // highlight-next-line + tags String[] +} +``` + +A default value can be specified for a field with the `@default` attribute. The value can be a literal, or a supported function call, including: + +- `now()`: returns the current timestamp +- `cuid()`: returns a CUID +- `uuid()`: returns a UUID +- `ulid()`: returns a ULID +- `nanoid()`: returns a Nano ID +- `autoincrement()`: returns an auto-incrementing integer (only for integer fields) +- `dbgenerated("...")`: calls a native db function + +```zmodel +model User { + id Int @id @default(autoincrement()) + role Role @default("USER") + createdAt DateTime @default(now()) +} +``` + +## Native type mapping + +Besides giving field a type, you can also specify the native database type to use with the `@db.` series of attributes. + +```zmodel +model User { + ... + // highlight-next-line + name String @db.VarChar(64) +} +``` + +These attributes control what data type is used when the migration engine maps the schema to DDL. You can find a full list of native type attributes in the [ZModel Language Reference](../reference/zmodel-language). + +## Name mapping + +Quite often you want to use a different naming scheme for your models and fields than the database. You can achieve that with the `@map` attribute. The ORM respects the mapping when generation queries, and the migration engine uses it to generate the DDL. + +```zmodel +model User { + // highlight-next-line + id Int @id + name String @map("full_name") + + @@map("users") +} +``` diff --git a/versioned_docs/version-3.x/orm/zmodel/multi-file.md b/versioned_docs/version-3.x/modeling/multi-file.md similarity index 64% rename from versioned_docs/version-3.x/orm/zmodel/multi-file.md rename to versioned_docs/version-3.x/modeling/multi-file.md index 81500291..ad1ba638 100644 --- a/versioned_docs/version-3.x/orm/zmodel/multi-file.md +++ b/versioned_docs/version-3.x/modeling/multi-file.md @@ -1,9 +1,9 @@ --- -sidebar_position: 10 +sidebar_position: 11 description: Breaking down complex schemas into multiple files --- -# Multi-file Schemas +# Multi-file Schema diff --git a/versioned_docs/version-3.x/modeling/overview.md b/versioned_docs/version-3.x/modeling/overview.md new file mode 100644 index 00000000..b2d9e3c1 --- /dev/null +++ b/versioned_docs/version-3.x/modeling/overview.md @@ -0,0 +1,52 @@ +--- +sidebar_position: 1 +description: ZModel overview +--- + +import ZModelVsPSL from '../_components/ZModelVsPSL'; + +# Overview + +ZenStack uses a schema language named **ZModel** to define data models and their related aspects. We know that designing a good schema language is difficult, and we know it's even more difficult to convince people to learn a new one. So we made the decision to design ZModel as a superset of the [Prisma Schema Language (PSL)](https://www.prisma.io/docs/orm/prisma-schema), which is one of the best data modeling language out there. + +If you're already familiar with PSL, you'll find yourself at home with ZModel. However, we'd still recommend that you skim through this section to learn about the important extensions we made to PSL. Please pay attention to callouts like the following one: + + +ZModel uses the explicit `import` syntax for composing multi-file schemas. + + +Don't worry if you've never used Prima before. This section will introduce all aspects of ZModel, so no prior knowledge is required. + +A very simple ZModel schema looks like this: + +```zmodel title='zenstack/schema.zmodel' +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +model User { + id Int @id @default(autoincrement()) + email String @unique + name String +} + +model Post { + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + title String + content String + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id]) + authorId String +} +``` + + +Prisma has the concept of "generator" which provides a pluggable mechanism to generate artifacts from PSL. Specifically, you need to define a "prisma-client-js" (or "prisma-client") generator to get the ORM client. + +ZenStack CLI always generates a TypeScript schema without needing any configuration. Also, it replaced PSL's "generator" with a more generalized "plugin" construct that allows you to extend the system both at the schema level and the runtime level. Read more in the [Plugin](./plugin) section. + + +Let's dissect it piece by piece. diff --git a/versioned_docs/version-3.x/modeling/plugin.md b/versioned_docs/version-3.x/modeling/plugin.md new file mode 100644 index 00000000..10506f39 --- /dev/null +++ b/versioned_docs/version-3.x/modeling/plugin.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 11 +description: ZenStack plugins +--- + +# Plugin + diff --git a/versioned_docs/version-3.x/modeling/polymorphism.md b/versioned_docs/version-3.x/modeling/polymorphism.md new file mode 100644 index 00000000..c529c030 --- /dev/null +++ b/versioned_docs/version-3.x/modeling/polymorphism.md @@ -0,0 +1,34 @@ +--- +sidebar_position: 10 +description: Polymorphic models in ZModel +--- + +import ZModelVsPSL from '../_components/ZModelVsPSL'; + +# Polymorphism + + +Polymorphism is a ZModel feature and doesn't exist in PSL. + + +## Introduction + +When modeling non-trivial applications, the need of an "Object-Oriented" kind of polymorphism often arises: +- Something **IS-A** more abstract type of thing. +- Something **HAS-A/HAS-many** a more abstract type of thing(s). + +Imagine we're modeling a content library system where users own different types of content: posts, videos, images, etc. They share some common traits like name, creation date, owner, etc., but have different specific fields. + +It may be tempting to use mixins to share the common fields, however it's not an ideal solution because: + +- The `User` table will have relations to each of the content types. +- There's no efficient and clean way to query all content types together (e.g., all content owned by a user). +- Consequently, whenever you add a new content type, you'll need to modify the `User` model, and probably lots of query code too. + +A true solution involves having a in-database model of polymorphism, where we really have a `Content` table that serves as an intermediary between `User` and the concrete content types. This is what ZModel polymorphism is about. + +:::info +There are [two main ways](https://www.prisma.io/docs/orm/prisma-schema/data-model/table-inheritance) to model polymorphism in relational databases: single-table inheritance (STI) and multi-table inheritance (MTI, aka. delegate types). ZModel only supports MTI. +::: + +## Modeling polymorphism diff --git a/versioned_docs/version-3.x/modeling/relations.md b/versioned_docs/version-3.x/modeling/relations.md new file mode 100644 index 00000000..6a74b365 --- /dev/null +++ b/versioned_docs/version-3.x/modeling/relations.md @@ -0,0 +1,219 @@ +--- +sidebar_position: 5 +description: Relations in ZModel +--- + +# Relations + +Relation is a fundamental concept in relational databases. It connect models into a graph, and allows you to query interconnected data efficiently. In ZModel, relations are modeled using the `@relation` attribute. For most cases it involves one side of the relation defining a foreign key field that references the primary key of the other side. By convention, we call the model that defines the foreign key the "owner" side. + +## One-to-one relations + +A typical one-to-one relation looks like this: + +```zmodel +model User { + id Int @id + profile Profile? +} + +model Profile { + id Int @id + user User @relation(fields: [userId], references: [id]) + userId Int @unique +} +``` + +The `Profile` model holds the foreign key `userId` and is the owner of the relation. The pk-fk association is established by the `@relation` attribute, where the `fields` parameters specifies the foreign key field(s) and the `references` parameter specifies the primary key field(s) of the other side. + +In one-to-one relations, the "non-owner" side must declare the relation field as optional (here `User.profile`), because there's no way to guarantee a `User` row always has a corresponding `Profile` row at the database level. The owner side can be either optional or required. + +Relations can also be explicitly named, and it's useful to disambiguate relations when a model has multiple relations to the same model, or to control the constraint name generated by the migration engine. + +```zmodel +model User { + id Int @id + profile Profile? @relation('UserProfile') +} + +model Profile { + id Int @id + user User @relation('UserProfile', fields: [userId], references: [id]) + userId Int @unique +} +``` + +Please note that even though both sides of the relation now have the `@relation` attribute, only the owner side can have the `fields` and `references` parameters. + +If a relation involves a model with composite PK fields, the FK fields must match the PK fields' count and types, and the `fields` and `references` parameters must be specified with those field tuples with matching order. + +```zmodel +model User { + id1 Int + id2 Int + profile Profile? + + @@id([id1, id2]) +} + +model Profile { + id Int @id + user User @relation(fields: [userId1, userId2], references: [id1, id2]) + userId1 Int + userId2 Int +} +``` + +## One-to-many relations + +A typical one-to-many relation looks like this: + +```zmodel +model User { + id Int @id + posts Post[] +} + +model Post { + id Int @id + author User @relation(fields: [authorId], references: [id]) + authorId Int +} +``` + +It's modeled pretty much the same way as one-to-one relations, except that the "non-owner" side (here `User.posts`) is a of list of the other side's model type. + +## Many-to-many relations + +Many-to-many relations are modeled in the database through a join table - which forms a many-to-one relation with each of the two sides. + +In ZModel, there are two ways to model many-to-many relations: implicitly or explicitly. + +### Implicit many-to-many + +An implicit many-to-many relation simply defines both sides of the relation as lists of the other side's model type, without defining a join table explicitly. + +```zmodel +model User { + id Int @id + posts Post[] +} + +model Post { + id Int @id + editors User[] +} +``` + +Under the hood, the migration engine creates a join table named `_PostToUser` (model names are sorted alphabetically), and the ORM runtime transparently handles the join table for you. + +You can also name the join table explicitly by adding the `@relation` attribute to both sides: + +```zmodel +model User { + id Int @id + posts Post[] @relation('UserPosts') +} + +model Post { + id Int @id + editors User[] @relation('UserPosts') +} +``` + +### Explicit many-to-many + +Explicit many-to-many relations are nothing but a join table with foreign keys linking the two sides. + +```zmodel +model User { + id Int @id + posts UserPost[] +} + +model Post { + id Int @id + editors UserPost[] +} + +model UserPost { + userId Int + postId Int + user User @relation(fields: [userId], references: [id]) + post Post @relation(fields: [postId], references: [id]) + + @@id([userId, postId]) +} +``` + +Since the join table is explicitly defined, when using the ORM, you'll need to involve it in your queries with an extra level of nesting. + +## Self relations + +Self relations are cases where a model has a relation to itself. They can be one-to-one, one-to-many, or many-to-many. + +### One-to-one + +```zmodel +model Employee { + id Int @id + mentorId Int? @unique + mentor Employee? @relation('Mentorship', fields: [mentorId], references: [id]) + mentee Employee? @relation('Mentorship') +} +``` + +Quick notes: + +- Both sides of the relation are defined in the same model. +- Both relation fields need to have `@relation` attributes with matching names. +- One side (here `mentor`) has a foreign key field (`mentorId`) that references the primary key. +- The foreign key field is marked `@unique` to guarantee one-to-one. + +### One-to-many + +```zmodel +model Employee { + id Int @id + managerId Int + manager Employee @relation('Management', fields: [managerId], references: [id]) + subordinates Employee[] @relation('Management') +} +``` + +Quick notes: +- Both sides of the relation are defined in the same model. +- Both relation fields need to have `@relation` attributes with matching names. +- One side (here `manager`) has a foreign key field (`managerId`) that references the primary key. +- The owner side (`Employee.manager`) can be either optional or required based on your needs. + +### Many-to-many + +Defining an implicit many-to-many self relation is very straightforward. + +```zmodel +model Employee { + id Int @id + mentors Employee[] @relation('Mentorship') + mentees Employee[] @relation('Mentorship') +} +``` + +You can also define an explicit one by modeling the join table explicitly. + +```zmodel +model Employee { + id Int @id + mentors Mentorship[] @relation('Mentorship') + mentees Mentorship[] @relation('Mentorship') +} + +model Mentorship { + mentorId Int + menteeId Int + mentor Employee @relation('Mentorship', fields: [mentorId], references: [id]) + mentee Employee @relation('Mentorship', fields: [menteeId], references: [id]) + + @@id([mentorId, menteeId]) +} +``` \ No newline at end of file diff --git a/versioned_docs/version-3.x/modeling/strong-typed-json.md b/versioned_docs/version-3.x/modeling/strong-typed-json.md new file mode 100644 index 00000000..2426d926 --- /dev/null +++ b/versioned_docs/version-3.x/modeling/strong-typed-json.md @@ -0,0 +1,50 @@ +--- +sidebar_position: 9 +description: Strongly typed JSON fields +--- + +import ZModelVsPSL from '../_components/ZModelVsPSL'; + +# Strongly Typed JSON + + +Strongly typed JSON is a ZModel feature and doesn't exist in PSL. + + +With relational databases providing better and better JSON support, their usage has become more common. However, in many cases your JSON fields still follow a specific structure, and when so, you can make the fields strongly typed so that: + +- When mutating the field, its structure is validated. +- When querying the field, its result is strongly typed. + +To type a JSON field, define a custom type in ZModel, use it as the field's type, and additionally mark the field with the `@json` attribute. + +***Before:*** + +```zmodel +model User { + id Int @id + address Json +} +``` + +***After:*** + +```zmodel +type Address { + street String + city String + country String + zip Int +} + +model User { + id Int @id + address Address @json +} +``` + +:::info +The `@json` attribute doesn't do anything except to clearly mark the field is a JSON field but not a relation to another model. +::: + +The migration engine still sees the field as a plain Json field. However, the ORM client enforces its structure and takes care of properly typing the query results. We'll revisit the topic in the [ORM](../orm/) part. diff --git a/versioned_docs/version-3.x/orm/_category_.yml b/versioned_docs/version-3.x/orm/_category_.yml index 7e156336..50000096 100644 --- a/versioned_docs/version-3.x/orm/_category_.yml +++ b/versioned_docs/version-3.x/orm/_category_.yml @@ -1,4 +1,4 @@ -position: 2 +position: 3 label: ORM collapsible: true collapsed: true diff --git a/versioned_docs/version-3.x/orm/introduction.md b/versioned_docs/version-3.x/orm/overview.md similarity index 98% rename from versioned_docs/version-3.x/orm/introduction.md rename to versioned_docs/version-3.x/orm/overview.md index 8bcaf843..dc4fe7aa 100644 --- a/versioned_docs/version-3.x/orm/introduction.md +++ b/versioned_docs/version-3.x/orm/overview.md @@ -1,13 +1,13 @@ --- sidebar_position: 1 -description: Introduction to ZenStack ORM +description: ZenStack ORM overview --- -# Introduction +# Overview ZenStack ORM is a schema-first ORM for modern TypeScript applications. It learnt from the prior arts and aims to provide an awesome developer experience by combining the best ingredients into a cohesive package. -## Key Facts +## Key Features ### [Prisma](https://prisma.io/orm)-Compatible Schema Language diff --git a/versioned_docs/version-3.x/orm/quick-start.mdx b/versioned_docs/version-3.x/orm/quick-start.mdx index 3ffcc406..5e738583 100644 --- a/versioned_docs/version-3.x/orm/quick-start.mdx +++ b/versioned_docs/version-3.x/orm/quick-start.mdx @@ -11,7 +11,7 @@ import PackageExec from '../_components/PackageExec.tsx'; # Quick Start :::info -All v3 packages are published under the "@next" tag. +All v3 packages are currently published under the "@next" tag. ::: There are multiple ways to start using ZenStack. diff --git a/versioned_docs/version-3.x/orm/zmodel/attributes.md b/versioned_docs/version-3.x/orm/zmodel/attributes.md deleted file mode 100644 index be676265..00000000 --- a/versioned_docs/version-3.x/orm/zmodel/attributes.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -sidebar_position: 4 -description: Attributes in ZModel ---- - -# Attributes diff --git a/versioned_docs/version-3.x/orm/zmodel/builtin-types.md b/versioned_docs/version-3.x/orm/zmodel/builtin-types.md deleted file mode 100644 index d3142702..00000000 --- a/versioned_docs/version-3.x/orm/zmodel/builtin-types.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -sidebar_position: 6 -description: Built-in types in ZModel ---- - -# Built-in Types diff --git a/versioned_docs/version-3.x/orm/zmodel/components.md b/versioned_docs/version-3.x/orm/zmodel/components.md deleted file mode 100644 index b0635163..00000000 --- a/versioned_docs/version-3.x/orm/zmodel/components.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -sidebar_position: 1 -description: ZModel schema components ---- - -# Schema Components diff --git a/versioned_docs/version-3.x/orm/zmodel/custom-types.md b/versioned_docs/version-3.x/orm/zmodel/custom-types.md deleted file mode 100644 index 7208914f..00000000 --- a/versioned_docs/version-3.x/orm/zmodel/custom-types.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -sidebar_position: 7 -description: Custom types in ZModel ---- - -# Custom Types diff --git a/versioned_docs/version-3.x/orm/zmodel/datasource.md b/versioned_docs/version-3.x/orm/zmodel/datasource.md deleted file mode 100644 index 3078fe6e..00000000 --- a/versioned_docs/version-3.x/orm/zmodel/datasource.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 2 -description: Datasource in ZModel ---- - -# Data Source - diff --git a/versioned_docs/version-3.x/orm/zmodel/models.md b/versioned_docs/version-3.x/orm/zmodel/models.md deleted file mode 100644 index f54ac510..00000000 --- a/versioned_docs/version-3.x/orm/zmodel/models.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 3 -description: Models in ZModel ---- - -# Models - diff --git a/versioned_docs/version-3.x/orm/zmodel/polymorphism.md b/versioned_docs/version-3.x/orm/zmodel/polymorphism.md deleted file mode 100644 index 62c1797d..00000000 --- a/versioned_docs/version-3.x/orm/zmodel/polymorphism.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 9 -description: Polymorphic models in ZModel ---- - -# Polymorphic Models - diff --git a/versioned_docs/version-3.x/orm/zmodel/relations.md b/versioned_docs/version-3.x/orm/zmodel/relations.md deleted file mode 100644 index 96794f67..00000000 --- a/versioned_docs/version-3.x/orm/zmodel/relations.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -sidebar_position: 5 -description: Relations in ZModel ---- - -# Relations diff --git a/versioned_docs/version-3.x/orm/zmodel/reusing-fields.md b/versioned_docs/version-3.x/orm/zmodel/reusing-fields.md deleted file mode 100644 index eed27f91..00000000 --- a/versioned_docs/version-3.x/orm/zmodel/reusing-fields.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 8 -description: Reusing common fields across models in ZModel ---- - -# Reusing Common Fields - diff --git a/versioned_docs/version-3.x/reference/_category_.yml b/versioned_docs/version-3.x/reference/_category_.yml index 3e14b45e..1352c105 100644 --- a/versioned_docs/version-3.x/reference/_category_.yml +++ b/versioned_docs/version-3.x/reference/_category_.yml @@ -1,4 +1,4 @@ -position: 6 +position: 7 label: Reference collapsible: true collapsed: true diff --git a/versioned_docs/version-3.x/samples.md b/versioned_docs/version-3.x/samples.md index 2b78bb7b..3e385d1b 100644 --- a/versioned_docs/version-3.x/samples.md +++ b/versioned_docs/version-3.x/samples.md @@ -1,5 +1,5 @@ --- -sidebar_position: 7 +sidebar_position: 8 sidebar_label: Sample Projects --- diff --git a/versioned_docs/version-3.x/service/_category_.yml b/versioned_docs/version-3.x/service/_category_.yml index d66b3af7..9159f276 100644 --- a/versioned_docs/version-3.x/service/_category_.yml +++ b/versioned_docs/version-3.x/service/_category_.yml @@ -1,4 +1,4 @@ -position: 4 +position: 5 label: Query as a Service collapsible: true collapsed: true diff --git a/versioned_docs/version-3.x/service/introduction.md b/versioned_docs/version-3.x/service/overview.md similarity index 53% rename from versioned_docs/version-3.x/service/introduction.md rename to versioned_docs/version-3.x/service/overview.md index 261e992b..d97b5285 100644 --- a/versioned_docs/version-3.x/service/introduction.md +++ b/versioned_docs/version-3.x/service/overview.md @@ -1,3 +1,3 @@ -# Introduction +# Overview Coming soon 🚧 \ No newline at end of file diff --git a/versioned_docs/version-3.x/upgrade.md b/versioned_docs/version-3.x/upgrade.md index cfeb1049..710d5964 100644 --- a/versioned_docs/version-3.x/upgrade.md +++ b/versioned_docs/version-3.x/upgrade.md @@ -3,7 +3,7 @@ description: How to upgrade to ZenStack v3 slug: /upgrade-v3 sidebar_label: Upgrading to V3 -sidebar_position: 8 +sidebar_position: 9 --- # Upgrading to V3 diff --git a/versioned_docs/version-3.x/utilities/_category_.yml b/versioned_docs/version-3.x/utilities/_category_.yml index 9dd0322c..1fdb7623 100644 --- a/versioned_docs/version-3.x/utilities/_category_.yml +++ b/versioned_docs/version-3.x/utilities/_category_.yml @@ -1,4 +1,4 @@ -position: 5 +position: 6 label: Utilities collapsible: true collapsed: true diff --git a/versioned_docs/version-3.x/utilities/tanstack-query.md b/versioned_docs/version-3.x/utilities/tanstack-query.md new file mode 100644 index 00000000..fa0f1bda --- /dev/null +++ b/versioned_docs/version-3.x/utilities/tanstack-query.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 2 +description: TanStack Query integration +--- + +# TanStack Query diff --git a/versioned_docs/version-3.x/utilities/zod.md b/versioned_docs/version-3.x/utilities/zod.md index 5bfd1865..7f16ec55 100644 --- a/versioned_docs/version-3.x/utilities/zod.md +++ b/versioned_docs/version-3.x/utilities/zod.md @@ -3,4 +3,4 @@ sidebar_position: 1 description: Zod integration --- -# Zod Integration +# Zod diff --git a/versioned_docs/version-3.x/welcome.md b/versioned_docs/version-3.x/welcome.md index 8309ace6..60442d84 100644 --- a/versioned_docs/version-3.x/welcome.md +++ b/versioned_docs/version-3.x/welcome.md @@ -5,6 +5,24 @@ sidebar_label: Welcome sidebar_position: 1 --- -# Welcome to ZenStack V3 +# Welcome -The modern data layer for TypeScript applications. +Welcome to ZenStack - the modern data layer for your TypeScript application! + +ZenStack is built with the belief that most applications should use the data model as its center pillar. If that model is well-designed, it can serve as the single source of truth throughout the app's lifecycle, and be used to derive many other aspects of the app. The result is a smaller, more cohesive code base that scales well as your team grows while maintaining a high level of developer experience. + +Inside the package you'll find: + +- #### An intuitive schema language + That helps you model data, relation, access control, and more, in one place. [πŸ”—](./modeling/) + +- #### A powerful ORM + With awesomely-typed API, built-in access control, and unmatched flexibility. [πŸ”—](./orm/) + +- #### A Query-as-a-Service layer + That provides a full-fledged data API without the need to code it up. [πŸ”—](./service/) + +- #### Utilities + For deriving artifacts like Zod schemas, frontend hooks, OpenAPI specs, etc., from the schema. [πŸ”—](./utilities/) + +> *ZenStack originated as an extension to Prisma ORM. V3 is a complete rewrite that removed Prisma as a runtime dependency and replaced it with an implementation built from the scratch ("scratch" = [Kysely](https://kysely.dev/) πŸ˜†). On its surface, it continues to use a "Prisma-superset" schema language and a query API compatible with PrismaClient.* \ No newline at end of file From 2815551802e9ca9efeac92af741310ac106d3c28 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Sun, 3 Aug 2025 18:46:08 +0800 Subject: [PATCH 04/51] WIP --- .../version-3.x/_components/ZModelVsPSL.tsx | 2 +- .../version-3.x/migration/_category_.yml | 3 - .../migration/{overview.md => index.md} | 0 .../version-3.x/modeling/_category_.yml | 3 - .../modeling/{overview.md => index.md} | 0 .../version-3.x/modeling/multi-file.md | 33 +++++++ versioned_docs/version-3.x/modeling/plugin.md | 31 +++++++ .../version-3.x/modeling/polymorphism.md | 90 ++++++++++++++++++- .../modeling/{relations.md => relation.md} | 0 versioned_docs/version-3.x/orm/_category_.yml | 3 - .../version-3.x/orm/{overview.md => index.md} | 0 .../orm/{ts-types.md => inferred-types.md} | 2 +- .../version-3.x/orm/plugins/_category_.yml | 3 - .../orm/plugins/{introduction.md => index.md} | 0 .../version-3.x/reference/error-handling.md | 43 --------- .../version-3.x/reference/plugin-dev.md | 7 ++ .../reference/plugins/_category_.yml | 7 ++ .../version-3.x/reference/runtime-api.md | 2 +- .../version-3.x/service/_category_.yml | 3 - .../service/{overview.md => index.md} | 0 versioned_docs/version-3.x/welcome.md | 2 +- 21 files changed, 171 insertions(+), 63 deletions(-) rename versioned_docs/version-3.x/migration/{overview.md => index.md} (100%) rename versioned_docs/version-3.x/modeling/{overview.md => index.md} (100%) rename versioned_docs/version-3.x/modeling/{relations.md => relation.md} (100%) rename versioned_docs/version-3.x/orm/{overview.md => index.md} (100%) rename versioned_docs/version-3.x/orm/{ts-types.md => inferred-types.md} (79%) rename versioned_docs/version-3.x/orm/plugins/{introduction.md => index.md} (100%) delete mode 100644 versioned_docs/version-3.x/reference/error-handling.md create mode 100644 versioned_docs/version-3.x/reference/plugin-dev.md create mode 100644 versioned_docs/version-3.x/reference/plugins/_category_.yml rename versioned_docs/version-3.x/service/{overview.md => index.md} (100%) diff --git a/versioned_docs/version-3.x/_components/ZModelVsPSL.tsx b/versioned_docs/version-3.x/_components/ZModelVsPSL.tsx index 0ea279d3..46b7a50d 100644 --- a/versioned_docs/version-3.x/_components/ZModelVsPSL.tsx +++ b/versioned_docs/version-3.x/_components/ZModelVsPSL.tsx @@ -7,7 +7,7 @@ interface ZModelVsPSLProps { const ZModelVsPSL: FC = ({ children }) => { return ( - + {children} ); diff --git a/versioned_docs/version-3.x/migration/_category_.yml b/versioned_docs/version-3.x/migration/_category_.yml index 013a697a..6cb70365 100644 --- a/versioned_docs/version-3.x/migration/_category_.yml +++ b/versioned_docs/version-3.x/migration/_category_.yml @@ -2,6 +2,3 @@ position: 4 label: Migration collapsible: true collapsed: true -link: - type: generated-index - title: Migration diff --git a/versioned_docs/version-3.x/migration/overview.md b/versioned_docs/version-3.x/migration/index.md similarity index 100% rename from versioned_docs/version-3.x/migration/overview.md rename to versioned_docs/version-3.x/migration/index.md diff --git a/versioned_docs/version-3.x/modeling/_category_.yml b/versioned_docs/version-3.x/modeling/_category_.yml index 8dbacd32..2df4bdd6 100644 --- a/versioned_docs/version-3.x/modeling/_category_.yml +++ b/versioned_docs/version-3.x/modeling/_category_.yml @@ -2,6 +2,3 @@ position: 2 label: Data Modeling collapsible: true collapsed: true -link: - type: generated-index - title: Data Modeling diff --git a/versioned_docs/version-3.x/modeling/overview.md b/versioned_docs/version-3.x/modeling/index.md similarity index 100% rename from versioned_docs/version-3.x/modeling/overview.md rename to versioned_docs/version-3.x/modeling/index.md diff --git a/versioned_docs/version-3.x/modeling/multi-file.md b/versioned_docs/version-3.x/modeling/multi-file.md index ad1ba638..75aaeb26 100644 --- a/versioned_docs/version-3.x/modeling/multi-file.md +++ b/versioned_docs/version-3.x/modeling/multi-file.md @@ -3,7 +3,40 @@ sidebar_position: 11 description: Breaking down complex schemas into multiple files --- +import ZModelVsPSL from '../_components/ZModelVsPSL'; + # Multi-file Schema + +Prisma uses an implicit approach that simply merges all schema files in a folder. ZModel uses explicit `import` syntax for better clarity and flexibility. + + +When your schema grows large, you can break them down to smaller files and stitch them together using the `import` statement. + +```zmodel title="zenstack/user.zmodel" +import './post' + +model User { + id Int @id + posts Post[] +} +``` + +```zmodel title="zenstack/post.zmodel" +import './user' + +model Post { + id Int @id + content String + author User @relation(fields: [authorId], references: [id]) + authorId Int +} +``` + +```zmodel title="zenstack/schema.zmodel" +import './user' +import './post' +``` +After type-checking, these files are merged into a single schema AST before passed to the downstream tools. diff --git a/versioned_docs/version-3.x/modeling/plugin.md b/versioned_docs/version-3.x/modeling/plugin.md index 10506f39..25af5443 100644 --- a/versioned_docs/version-3.x/modeling/plugin.md +++ b/versioned_docs/version-3.x/modeling/plugin.md @@ -3,5 +3,36 @@ sidebar_position: 11 description: ZenStack plugins --- +import ZModelVsPSL from '../_components/ZModelVsPSL'; + # Plugin + +ZenStack's "plugin" concept replaces PSL's "generator". + + +Plugin is a powerful mechanism that allows you to extend ZenStack at the schema, CLI, and runtime levels. This section only focuses on how to add plugins to your ZModel. Please refer to the [Plugin Development](../reference/plugin-dev.md) section for more details on how to develop plugins. + +## Adding plugins to ZModel + +Let's take a look at the following example: + +```zmodel +plugin myPlugin { + provider = 'my-zenstack-plugin' + output = './generated' +} +``` + +A plugin declaration involves three parts: + +1. A unique name +2. A `provider` field that specifies where to load the plugin from. It can be a built-in plugin (like `@core/prisma` here), a local folder, or an npm package. +3. Plugin-specific configuration options, such as `output` in this case. + +A plugin can have the following effects to ZModel: + +- It can contribute custom attributes that you can use to annotate models and fields. +- It can contribute code generation logic that's executed when you run the `zenstack generate` command. + +Plugins can also contribute to the ORM runtime behavior, and we'll leave it to the [ORM](../orm/plugins/) part to explain it in detail. diff --git a/versioned_docs/version-3.x/modeling/polymorphism.md b/versioned_docs/version-3.x/modeling/polymorphism.md index c529c030..87006ebe 100644 --- a/versioned_docs/version-3.x/modeling/polymorphism.md +++ b/versioned_docs/version-3.x/modeling/polymorphism.md @@ -17,7 +17,7 @@ When modeling non-trivial applications, the need of an "Object-Oriented" kind of - Something **IS-A** more abstract type of thing. - Something **HAS-A/HAS-many** a more abstract type of thing(s). -Imagine we're modeling a content library system where users own different types of content: posts, videos, images, etc. They share some common traits like name, creation date, owner, etc., but have different specific fields. +Imagine we're modeling a content library system where users own different types of content: posts, images, videos, etc. They share some common traits like name, creation date, owner, etc., but have different specific fields. It may be tempting to use mixins to share the common fields, however it's not an ideal solution because: @@ -32,3 +32,91 @@ There are [two main ways](https://www.prisma.io/docs/orm/prisma-schema/data-mode ::: ## Modeling polymorphism + +Modeling polymorphism in ZModel is similar to designing an OOP class hierarchy - you introduce a base model and then extend it with concrete ones. + +Here's how it looks for our content library example: + +```zmodel +model User { + id Int @id + contents Content[] +} + +model Content { + id Int @id + name String + createdAt DateTime @default(now()) + owner User @relation(fields: [ownerId], references: [id]) + ownerId Int + // highlight-next-line + type String + + // highlight-next-line + @@delegate(type) +} + +model Post extends Content { + content String +} + +model Image extends Content { + data Bytes +} + +model Video extends Content { + url String +} +``` + +```mermaid +erDiagram + User { + id Int PK + } + Content { + id Int PK + name String + createdAt Date + ownerId Int FK + type String + } + User ||--o{ Content: owns + Post { + id Int PK + content String + } + Post ||--|| Content: delegates + Image { + id Int PK + data Bytes + } + Image ||--|| Content: delegates + Video { + id Int PK + url String + } + Video ||--|| Content: delegates +``` + +There are two special things about polymorphic base model: + +1. It must have a "discriminator" field that stores the concrete model type that it should "delegate" to. In the example above, the `type` field serves this purpose. It can be named anything you like, but must be of `String` or enum type. +2. It must have a `@@delegate` attribute. The attribute serves two purposes: it indicates that the model is a base model, and it designates the discriminator field with its parameter. + +You can also have a deep hierarchy involving multiple level of base models. Just need to make sure each base model has its own discriminator field and `@@delegate` attribute. Extending from multiple base models directly is not supported. + +## Migration behavior + +The migration engine takes care of mapping both the base model and the concrete ones to tables, and creates one-to-one relations between the base and each of its derivations. + +To simplify query and conserve space, the base and the concrete are assumed to share the same id values (this is guaranteed by the ORM when creating the records), and consequently, the concrete model's id field is also reused as the foreign key to the base model. So, for a `Post` record with id `1`, the base `Content` record also has id `1`. + +## ORM behavior + +The ORM hides the delegate complexities and provides a simple polymorphic view to the developers: + +1. Creating a concrete model record automatically creates the base model record with the same id and proper discriminator field. +2. Querying with the base model will return entities with concrete model fields. + +We'll revisit the topic in details in the [ORM](../orm/) part. diff --git a/versioned_docs/version-3.x/modeling/relations.md b/versioned_docs/version-3.x/modeling/relation.md similarity index 100% rename from versioned_docs/version-3.x/modeling/relations.md rename to versioned_docs/version-3.x/modeling/relation.md diff --git a/versioned_docs/version-3.x/orm/_category_.yml b/versioned_docs/version-3.x/orm/_category_.yml index 50000096..6f69cf50 100644 --- a/versioned_docs/version-3.x/orm/_category_.yml +++ b/versioned_docs/version-3.x/orm/_category_.yml @@ -2,6 +2,3 @@ position: 3 label: ORM collapsible: true collapsed: true -link: - type: generated-index - title: ORM diff --git a/versioned_docs/version-3.x/orm/overview.md b/versioned_docs/version-3.x/orm/index.md similarity index 100% rename from versioned_docs/version-3.x/orm/overview.md rename to versioned_docs/version-3.x/orm/index.md diff --git a/versioned_docs/version-3.x/orm/ts-types.md b/versioned_docs/version-3.x/orm/inferred-types.md similarity index 79% rename from versioned_docs/version-3.x/orm/ts-types.md rename to versioned_docs/version-3.x/orm/inferred-types.md index 9fd5432d..990d91d6 100644 --- a/versioned_docs/version-3.x/orm/ts-types.md +++ b/versioned_docs/version-3.x/orm/inferred-types.md @@ -3,4 +3,4 @@ sidebar_position: 11 description: TypeScript types derived from the ZModel schema --- -# TypeScript Types +# Schema-Inferred Types diff --git a/versioned_docs/version-3.x/orm/plugins/_category_.yml b/versioned_docs/version-3.x/orm/plugins/_category_.yml index 60e83429..12d5462a 100644 --- a/versioned_docs/version-3.x/orm/plugins/_category_.yml +++ b/versioned_docs/version-3.x/orm/plugins/_category_.yml @@ -2,6 +2,3 @@ position: 12 label: Plugins collapsible: true collapsed: true -link: - type: generated-index - title: Plugins diff --git a/versioned_docs/version-3.x/orm/plugins/introduction.md b/versioned_docs/version-3.x/orm/plugins/index.md similarity index 100% rename from versioned_docs/version-3.x/orm/plugins/introduction.md rename to versioned_docs/version-3.x/orm/plugins/index.md diff --git a/versioned_docs/version-3.x/reference/error-handling.md b/versioned_docs/version-3.x/reference/error-handling.md deleted file mode 100644 index 07d31586..00000000 --- a/versioned_docs/version-3.x/reference/error-handling.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -description: Error handling -sidebar_position: 8 ---- - -# Error Handling - -ZenStack's enhancements to Prisma clients are transparent proxies, so normal errors thrown from a Prisma client simply pass through, and you can handle them the same way as you do in a regular Prisma project. It's good to read these references from Prisma: - -- [Handling exceptions and errors](https://www.prisma.io/docs/concepts/components/prisma-client/handling-exceptions-and-errors) -- [Error message reference](https://www.prisma.io/docs/reference/api-reference/error-reference) - -The enhanced Prisma client can throw extra errors when an operation is rejected by [access policies](./zmodel-language#access-policy) or its data fails [validation rules](./zmodel-language#data-validation). To keep a consistent programming experience, a `PrismaClientKnownRequestError` is thrown with code [`P2004`](https://www.prisma.io/docs/reference/api-reference/error-reference#p2004) is used in such cases: - -```ts -throw new PrismaClientKnownRequestError(message, { - clientVersion: getVersion(), - code: 'P2004', - meta: ... -}); -``` - -The error contains a `meta` field providing more information about the error. It contains the following fields: - -- `reason` - - A string field indicating the detailed reason of the rejection. Its value can be one of the following: - - - *ACCESS_POLICY_VIOLATION* - - CRUD failed because of access policy violation. - - - *RESULT_NOT_READABLE* - - CRUD succeeded but the result was not readable (violating "read" access policies). - - - *DATA_VALIDATION_VIOLATION* - - CRUD failed because of a [data validation](./zmodel-language#data-validation) error. - -- `zodErrors` - - An object field containing the raw Zod validation errors. Only present if the `reason` is `DATA_VALIDATION_VIOLATION`. See [Zod documentation](https://zod.dev/?id=error-handling) for more details. diff --git a/versioned_docs/version-3.x/reference/plugin-dev.md b/versioned_docs/version-3.x/reference/plugin-dev.md new file mode 100644 index 00000000..5cd7ddef --- /dev/null +++ b/versioned_docs/version-3.x/reference/plugin-dev.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 5 +sidebar_label: Plugin Development +description: Plugin development guide +--- + +# Plugin Development diff --git a/versioned_docs/version-3.x/reference/plugins/_category_.yml b/versioned_docs/version-3.x/reference/plugins/_category_.yml new file mode 100644 index 00000000..4a2a7dc0 --- /dev/null +++ b/versioned_docs/version-3.x/reference/plugins/_category_.yml @@ -0,0 +1,7 @@ +position: 6 +label: Plugins +collapsible: true +collapsed: true +link: + type: generated-index + title: Plugins diff --git a/versioned_docs/version-3.x/reference/runtime-api.md b/versioned_docs/version-3.x/reference/runtime-api.md index 22d84bdd..2cc8e47c 100644 --- a/versioned_docs/version-3.x/reference/runtime-api.md +++ b/versioned_docs/version-3.x/reference/runtime-api.md @@ -1,6 +1,6 @@ --- description: Runtime API references -sidebar_position: 3 +sidebar_position: 4 sidebar_label: Runtime API --- diff --git a/versioned_docs/version-3.x/service/_category_.yml b/versioned_docs/version-3.x/service/_category_.yml index 9159f276..938fc11d 100644 --- a/versioned_docs/version-3.x/service/_category_.yml +++ b/versioned_docs/version-3.x/service/_category_.yml @@ -2,6 +2,3 @@ position: 5 label: Query as a Service collapsible: true collapsed: true -link: - type: generated-index - title: Query as a Service diff --git a/versioned_docs/version-3.x/service/overview.md b/versioned_docs/version-3.x/service/index.md similarity index 100% rename from versioned_docs/version-3.x/service/overview.md rename to versioned_docs/version-3.x/service/index.md diff --git a/versioned_docs/version-3.x/welcome.md b/versioned_docs/version-3.x/welcome.md index 60442d84..da83a371 100644 --- a/versioned_docs/version-3.x/welcome.md +++ b/versioned_docs/version-3.x/welcome.md @@ -23,6 +23,6 @@ Inside the package you'll find: That provides a full-fledged data API without the need to code it up. [πŸ”—](./service/) - #### Utilities - For deriving artifacts like Zod schemas, frontend hooks, OpenAPI specs, etc., from the schema. [πŸ”—](./utilities/) + For deriving artifacts like Zod schemas, frontend hooks, OpenAPI specs, etc., from the schema. [πŸ”—](./category/utilities) > *ZenStack originated as an extension to Prisma ORM. V3 is a complete rewrite that removed Prisma as a runtime dependency and replaced it with an implementation built from the scratch ("scratch" = [Kysely](https://kysely.dev/) πŸ˜†). On its surface, it continues to use a "Prisma-superset" schema language and a query API compatible with PrismaClient.* \ No newline at end of file From f215f86e5f4c1d48f53f5ac1886df655ba54361d Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Tue, 5 Aug 2025 17:33:31 +0800 Subject: [PATCH 05/51] progress on ORM part --- src/components/StackBlitzGithubEmbed.tsx | 17 ++++- .../_components/ZenStackVsPrisma.tsx | 16 +++++ .../_components/_zmodel-starter.md | 4 +- versioned_docs/version-3.x/faq.md | 5 ++ .../version-3.x/modeling/conclusion.md | 17 +++++ versioned_docs/version-3.x/modeling/index.md | 2 +- .../orm/api/_select-include-omit.md | 18 +++++ .../version-3.x/orm/api/aggregate.md | 2 +- versioned_docs/version-3.x/orm/api/count.md | 2 +- versioned_docs/version-3.x/orm/api/create.md | 39 +++++++++- versioned_docs/version-3.x/orm/api/delete.md | 2 +- versioned_docs/version-3.x/orm/api/filter.md | 9 +++ versioned_docs/version-3.x/orm/api/find.md | 63 +++++++++++++++- .../version-3.x/orm/api/transaction.md | 2 +- versioned_docs/version-3.x/orm/api/update.md | 2 +- versioned_docs/version-3.x/orm/cli.md | 16 +++++ ...database-client.mdx => database-client.md} | 9 ++- versioned_docs/version-3.x/orm/index.md | 71 +++++++++---------- .../orm/{quick-start.mdx => quick-start.md} | 2 +- 19 files changed, 244 insertions(+), 54 deletions(-) create mode 100644 versioned_docs/version-3.x/_components/ZenStackVsPrisma.tsx create mode 100644 versioned_docs/version-3.x/modeling/conclusion.md create mode 100644 versioned_docs/version-3.x/orm/api/_select-include-omit.md create mode 100644 versioned_docs/version-3.x/orm/api/filter.md rename versioned_docs/version-3.x/orm/{database-client.mdx => database-client.md} (78%) rename versioned_docs/version-3.x/orm/{quick-start.mdx => quick-start.md} (97%) diff --git a/src/components/StackBlitzGithubEmbed.tsx b/src/components/StackBlitzGithubEmbed.tsx index 5bddace1..d65fb762 100644 --- a/src/components/StackBlitzGithubEmbed.tsx +++ b/src/components/StackBlitzGithubEmbed.tsx @@ -4,18 +4,29 @@ import sdk from '@stackblitz/sdk'; interface StackBlitzGithubEmbedProps { repoPath: string; height?: string; + openFile?: string; + startScript?: string; + clickToLoad?: boolean; } -const StackBlitzGithubEmbed: React.FC = ({ repoPath, height = '600px' }) => { +const StackBlitzGithubEmbed: React.FC = ({ + repoPath, + height = '600px', + openFile = 'main.ts', + clickToLoad = false, + startScript, +}) => { const containerRef = useRef(null); useEffect(() => { if (containerRef.current) { sdk.embedGithubProject(containerRef.current, repoPath, { - openFile: 'main.ts', + openFile, height, view: 'editor', - forceEmbedLayout: true, + hideNavigation: true, + startScript, + clickToLoad, }); } }, [repoPath, height]); diff --git a/versioned_docs/version-3.x/_components/ZenStackVsPrisma.tsx b/versioned_docs/version-3.x/_components/ZenStackVsPrisma.tsx new file mode 100644 index 00000000..323adb57 --- /dev/null +++ b/versioned_docs/version-3.x/_components/ZenStackVsPrisma.tsx @@ -0,0 +1,16 @@ +import React, { FC } from 'react'; +import Admonition from '@theme/Admonition'; + +interface ZenStackVsPrismaProps { + children: React.ReactNode; +} + +const ZenStackVsPrisma: FC = ({ children }) => { + return ( + + {children} + + ); +}; + +export default ZenStackVsPrisma; diff --git a/versioned_docs/version-3.x/_components/_zmodel-starter.md b/versioned_docs/version-3.x/_components/_zmodel-starter.md index 029ef799..fbf3eaea 100644 --- a/versioned_docs/version-3.x/_components/_zmodel-starter.md +++ b/versioned_docs/version-3.x/_components/_zmodel-starter.md @@ -6,7 +6,7 @@ model User { id String @id @default(cuid()) - email String @unique @email @length(6, 32) + email String @unique posts Post[] } @@ -14,7 +14,7 @@ id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - title String @length(1, 256) + title String content String published Boolean @default(false) author User @relation(fields: [authorId], references: [id]) diff --git a/versioned_docs/version-3.x/faq.md b/versioned_docs/version-3.x/faq.md index b0e81a65..410fe76c 100644 --- a/versioned_docs/version-3.x/faq.md +++ b/versioned_docs/version-3.x/faq.md @@ -7,3 +7,8 @@ sidebar_position: 100 --- # πŸ™‹πŸ» FAQ + +## What databases are supported? + +Currently only SQLite and PostgreSQL are supported. MySQL will be added in the future. There's no plan to support other relational databases or NoSQL databases. + diff --git a/versioned_docs/version-3.x/modeling/conclusion.md b/versioned_docs/version-3.x/modeling/conclusion.md new file mode 100644 index 00000000..4c5cc632 --- /dev/null +++ b/versioned_docs/version-3.x/modeling/conclusion.md @@ -0,0 +1,17 @@ +--- +sidebar_position: 100 +description: Data modeling conclusion +--- + +# Conclusion + +Congratulations! You have learned all the essentials of data model with ZenStack. What's next? + +In the following parts, you'll learn how to put the schema into use and let it drive many aspects of your application, including: + +- [Creating an ORM to query the database](../orm/) +- [Evolving database schema with migrations](../migration/) +- [Exposing a data API with Query-as-a-Service](../service/) +- [Driving other useful utilities](../service/) + +Let's continue our journey with ZenStack! diff --git a/versioned_docs/version-3.x/modeling/index.md b/versioned_docs/version-3.x/modeling/index.md index b2d9e3c1..5cdd7f40 100644 --- a/versioned_docs/version-3.x/modeling/index.md +++ b/versioned_docs/version-3.x/modeling/index.md @@ -5,7 +5,7 @@ description: ZModel overview import ZModelVsPSL from '../_components/ZModelVsPSL'; -# Overview +# Data Modeling Overview ZenStack uses a schema language named **ZModel** to define data models and their related aspects. We know that designing a good schema language is difficult, and we know it's even more difficult to convince people to learn a new one. So we made the decision to design ZModel as a superset of the [Prisma Schema Language (PSL)](https://www.prisma.io/docs/orm/prisma-schema), which is one of the best data modeling language out there. diff --git a/versioned_docs/version-3.x/orm/api/_select-include-omit.md b/versioned_docs/version-3.x/orm/api/_select-include-omit.md new file mode 100644 index 00000000..5b57c5f4 --- /dev/null +++ b/versioned_docs/version-3.x/orm/api/_select-include-omit.md @@ -0,0 +1,18 @@ +- `select` + + An object specifying the fields to include in the result. Setting a field to `true` means to include it. If a field is a relation, you can provide an nested object to further specify which fields of the relation to include. + + This field is optional. If not provided, all non-relation fields are included by default. The `include` field is mutually exclusive with the `select` field. + +- `include` + + An object specifying the relations to include in the result. Setting a relation to `true` means to include it. You can pass an object to further choose what fields/relations are included for the relation, and/or a `where` clause to filter the included relation records. + + This field is optional. If not provided, no relations are included by default. The `include` field is mutually exclusive with the `select` field. + +- `omit` + + An object specifying the fields to omit from the result. Setting a field to `true` means to omit it. Only applicable to non-relation fields. + + This field is optional. If not provided, no fields are omitted by default. The `omit` field is mutually exclusive with the `select` field. + \ No newline at end of file diff --git a/versioned_docs/version-3.x/orm/api/aggregate.md b/versioned_docs/version-3.x/orm/api/aggregate.md index 0b545613..f7f12077 100644 --- a/versioned_docs/version-3.x/orm/api/aggregate.md +++ b/versioned_docs/version-3.x/orm/api/aggregate.md @@ -1,5 +1,5 @@ --- -sidebar_position: 6 +sidebar_position: 7 description: Aggregate API --- diff --git a/versioned_docs/version-3.x/orm/api/count.md b/versioned_docs/version-3.x/orm/api/count.md index d22fd667..7402362e 100644 --- a/versioned_docs/version-3.x/orm/api/count.md +++ b/versioned_docs/version-3.x/orm/api/count.md @@ -1,5 +1,5 @@ --- -sidebar_position: 5 +sidebar_position: 6 description: Count API --- diff --git a/versioned_docs/version-3.x/orm/api/create.md b/versioned_docs/version-3.x/orm/api/create.md index 7bd11da3..d6b8326e 100644 --- a/versioned_docs/version-3.x/orm/api/create.md +++ b/versioned_docs/version-3.x/orm/api/create.md @@ -3,4 +3,41 @@ sidebar_position: 2 description: Create API --- -# Create \ No newline at end of file +import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; + +# Create + +The `create` series of APIs are used to create new records in the database. It has the following methods: + +- `create` + Create a single record, optionally with nested relations. +- `createMany` + Create multiple records in a single operation. Nested relations are not supported. Only the number of records created is returned. +- `createManyAndReturn` + Similar to `createMany`, but returns the created records. + +## Samples + + + +## Input + +The create APIs accept an input object with the following fields: + +- `data` + + The data used to create the record. It must contain all non-optional fields of the model. It can also include nested object for creating or connecting relation entities. For `create` the data field must be an object. For `createMany` and `createManyAndReturn`, it can be either an object or an array of objects. + + This field is required. + +- `skipDuplicates` + + A boolean flag that indicates whether to skip records that would violate unique constraints. Only applicable to `createMany` and `createManyAndReturn`. + + This field is optional and defaults to `false`. + +You can also control what fields are turned in the result using the `select`, `include`, and `omit` fields. Read more about field selection in the [next section](./find.md#field-selection). + +## Output + +The output shape of `create` and `createManyAndReturn` API is determined by the `select`, `include`, and `omit` fields in the input object. The output of `createMany` is `{ count: number }`, giving the number of records created. diff --git a/versioned_docs/version-3.x/orm/api/delete.md b/versioned_docs/version-3.x/orm/api/delete.md index 11e0142c..358e28e8 100644 --- a/versioned_docs/version-3.x/orm/api/delete.md +++ b/versioned_docs/version-3.x/orm/api/delete.md @@ -1,5 +1,5 @@ --- -sidebar_position: 4 +sidebar_position: 5 description: Delete API --- diff --git a/versioned_docs/version-3.x/orm/api/filter.md b/versioned_docs/version-3.x/orm/api/filter.md new file mode 100644 index 00000000..01a84115 --- /dev/null +++ b/versioned_docs/version-3.x/orm/api/filter.md @@ -0,0 +1,9 @@ +--- +sidebar_position: 3 +description: how to filter entities +--- + +import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; + +# Filter + diff --git a/versioned_docs/version-3.x/orm/api/find.md b/versioned_docs/version-3.x/orm/api/find.md index 633a25c8..78fdebf5 100644 --- a/versioned_docs/version-3.x/orm/api/find.md +++ b/versioned_docs/version-3.x/orm/api/find.md @@ -1,6 +1,65 @@ --- -sidebar_position: 1 +sidebar_position: 2 description: Find API --- -# Find \ No newline at end of file +import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import SelectIncludeOmit from './_select-include-omit.md'; + +# Find + +The `find` series of APIs are used to query records from the database. It has the following methods: + +- `findMany` + + Find multiple records that match the query criteria. + +- `findUnique` + + Find a single record with a unique criteria. + +- `findFirst` + + Find the first record that matches the query criteria. + +- `findUniqueOrThrow` + + Similar to `findUnique`, but throws an error if no record is found. + +- `findFirstOrThrow` + + Similar to `findFirst`, but throws an error if no record is found. + +## Basic usage + + + +## Filtering + +The API provides a very flexible set of filtering options. We've put it into a [dedicated section](./filter.md). + +## Sorting + +Use the `sort` field to control the sort field, direction, and null field placement. Sorting is not supported for `findUnique` and `findUniqueOrThrow`. + + + +## Pagination + +You can use two strategies for pagination: offset-based or cursor-based. Pagination is not supported for `findUnique` and `findUniqueOrThrow`. + + + +## Field selection + +You can use the following fields to control what fields are returned in the result: + + + + + +## Finding distinct rows + +You can use the `distinct` field to find distinct rows based on specific fields. One row for each unique combination of the specified fields will be returned. The implementation uses SQL `DISTINCT ON` if it's supported by the dialect, otherwise falls back to in-memory deduplication. + + diff --git a/versioned_docs/version-3.x/orm/api/transaction.md b/versioned_docs/version-3.x/orm/api/transaction.md index d24f053d..79bbcb5f 100644 --- a/versioned_docs/version-3.x/orm/api/transaction.md +++ b/versioned_docs/version-3.x/orm/api/transaction.md @@ -1,5 +1,5 @@ --- -sidebar_position: 7 +sidebar_position: 8 description: Transaction API --- diff --git a/versioned_docs/version-3.x/orm/api/update.md b/versioned_docs/version-3.x/orm/api/update.md index 468e8cac..383bb752 100644 --- a/versioned_docs/version-3.x/orm/api/update.md +++ b/versioned_docs/version-3.x/orm/api/update.md @@ -1,5 +1,5 @@ --- -sidebar_position: 3 +sidebar_position: 4 description: Update API --- diff --git a/versioned_docs/version-3.x/orm/cli.md b/versioned_docs/version-3.x/orm/cli.md index 98a18870..86de9ffd 100644 --- a/versioned_docs/version-3.x/orm/cli.md +++ b/versioned_docs/version-3.x/orm/cli.md @@ -3,4 +3,20 @@ sidebar_position: 4 description: Using the CLI --- +import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; + # Using the CLI + +ZenStack CLI is a command-line tool that takes the ZModel schema as input and complete different tasks for you. It's included in the "@zenstackhq/cli" package, and can be invoked with either `zen` or `zenstack` command. + +In the context of ORM, the CLI compiles ZModel into a TypeScript representation, which can in turn be used to create a type-safe ORM client. + +You can try running the `npx zen generate` command in the following playground and inspect the TypeScript code generated inside the "zenstack" folder. + + + +The `generate` command outputs the following TypeScript files in the same folder of the schema file: + +- `schema.ts`: TypeScript representation of the ZModel schema, used by the ORM client to understand the database's structure and infer types. +- `models.ts`: Exports types for all models, types, and enums defined in the schema. +- `input.ts`: Export types that you can use to type the arguments passed to the ORM client methods, such as `findMany`, `create`, etc. diff --git a/versioned_docs/version-3.x/orm/database-client.mdx b/versioned_docs/version-3.x/orm/database-client.md similarity index 78% rename from versioned_docs/version-3.x/orm/database-client.mdx rename to versioned_docs/version-3.x/orm/database-client.md index ed04be38..166bafb7 100644 --- a/versioned_docs/version-3.x/orm/database-client.mdx +++ b/versioned_docs/version-3.x/orm/database-client.md @@ -6,12 +6,17 @@ description: Creating a database client import TabItem from '@theme/TabItem'; import Tabs from '@theme/Tabs'; import PackageInstall from '../_components/PackageInstall'; +import ZenStackVsPrisma from '../_components/ZenStackVsPrisma'; # Database Client -The `zen generate` command compiles the ZModel schema into TypeScript code, which we can in turn use to initialize a type-safe database client. ZenStack uses Kysely to handle the low-level database operations, so the client is initialize with a Kysely dialect - an object that encapsulates database details. + +Unlike Prisma, ZenStack doesn't bundle any database driver. You're responsible for installing a compatible one. Also it doesn't read database connection string from the schema. Instead, you pass in the connection information when creating the client. + -The samples below only shows creating a client using SQLite (via [better-sqlite3](https://github.com/WiseLibs/better-sqlite3)) and PostgreSQL (via [node-postgres](https://github.com/brianc/node-postgres)), however you can also use any other Kysely dialects. +The `zen generate` command compiles the ZModel schema into TypeScript code, which we can in turn use to initialize a type-safe database client. ZenStack uses Kysely to handle the low-level database operations, so the client is initialize with a [Kysely dialect](https://kysely.dev/docs/dialects) - an object that encapsulates database details. + +The samples below only shows creating a client using SQLite (via [better-sqlite3](https://github.com/WiseLibs/better-sqlite3)) and PostgreSQL (via [node-postgres](https://github.com/brianc/node-postgres)), however you can also use any other Kysely dialects for these two types of databases. diff --git a/versioned_docs/version-3.x/orm/index.md b/versioned_docs/version-3.x/orm/index.md index dc4fe7aa..1096aad7 100644 --- a/versioned_docs/version-3.x/orm/index.md +++ b/versioned_docs/version-3.x/orm/index.md @@ -3,34 +3,17 @@ sidebar_position: 1 description: ZenStack ORM overview --- +import ZenStackVsPrisma from '../_components/ZenStackVsPrisma'; + # Overview -ZenStack ORM is a schema-first ORM for modern TypeScript applications. It learnt from the prior arts and aims to provide an awesome developer experience by combining the best ingredients into a cohesive package. +ZenStack ORM is a schema-first ORM for modern TypeScript applications. It learnt from the prior arts and strives to provide an awesome developer experience by combining the best ingredients into a cohesive package. ## Key Features -### [Prisma](https://prisma.io/orm)-Compatible Schema Language - -The schema language used by ZenStack (called ZModel) is a superset of Prisma schema language. Every valid Prisma schema can be used with ZenStack unchanged. In addition, ZModel added many important extensions to the language to improve the developer experience and enable advanced features. - -```zmodel -model User { - id String @id @default(cuid()) - email String @unique - posts Post[] -} - -model Post { - id String @id @default(cuid()) - title String @length(1, 256) - author User @relation(fields: [authorId], references: [id]) - authorId String -} -``` - -### [Prisma](https://prisma.io/orm)-Compatible Query API +### [Prisma](https://prisma.io/orm)-compatible query API -Although ZenStack has a completely different implementation (based on [Kysely](https://kysely.dev/)), it replicated Prisma ORM's query API so that you can use it pretty much as a drop-in replacement. Even if you're not a Prisma user, the query API is very intuitive and easy to learn. +ZenStack v3 is inspired by Prisma ORM but it has a completely different implementation (based on [Kysely](https://kysely.dev/)). On the surface, it replicated Prisma ORM's query API so that you can use it pretty much as a drop-in replacement. Even if you're not a Prisma user, the query API is very intuitive and easy to learn. ```ts await db.user.findMany({ @@ -46,7 +29,7 @@ await db.user.findMany({ }); ``` -### Low-Level Query-Builder Powered by [Kysely](https://kysely.dev/) +### Low-level query builder powered by [Kysely](https://kysely.dev/) ORM APIs are concise and pleasant, but they have their limitations. When you need extra power, you can fall back to the low-level query builder API powered by [Kysely](https://kysely.dev/) - limitless expressiveness, full type safety, and zero extra setup. @@ -58,17 +41,17 @@ await db.$qb .execute(); ``` -### Access Control +### Access control ZenStack ORM comes with a powerful built-in access control system. You can define access rules right inside the schema. The rules are enforced at runtime via query injection, so it doesn't rely on any database specific row-level security features. -```zmodel +```zmodel" model Post { - id String @id @default(cuid()) - title. String @length(1, 256) + id Int @id + title String @length(1, 256) published Boolean @default(false) - author User @relation(fields: [authorId], references: [id]) - authorId String + author User @relation(fields: [authorId], references: [id]) + authorId Int // no anonymous access @@deny('all', auth() == null) @@ -81,14 +64,14 @@ model Post { } ``` -### Polymorphic Models +### Polymorphic models Real-world applications often involves storing polymorphic data which is notoriously complex to model and query. ZenStack does the heavy-lifting for you so you can model an inheritance hierarchy with simple annotations, and query them with perfect type safety. -```zmodel -model Asset { - id String @id @default(cuid()) - title String @length(1, 256) +```zmodel title="zenstack/schema.zmodel" +model Content { + id Int @id + name String @length(1, 256) type String // the ORM uses the `type` field to determine to which concrete model @@ -96,12 +79,12 @@ model Asset { @@delegate(type) } -model Post extends Asset { +model Post extends Content { content String } ``` -```ts +```ts title="main.ts" const asset = await db.asset.findFirst(); if (asset.type === 'Post') { // asset's type is narrowed down to `Post` @@ -111,10 +94,24 @@ if (asset.type === 'Post') { } ``` -### Straightforward and Light-Weighted +### Straightforward and light-Weighted Compared to Prisma and previous versions of ZenStack, v3 is more straightforward and light-weighted. - No runtime dependency to Prisma, thus no overhead of Rust/WASM query engines. - No magic generating into `node_modules`. You fully control how the generated code is compiled and bundled. - Less code generation, more type inference. + +## Documentation Conventions + +### Sample playground + +Throughout the documentation we'll use [StackBlitz](https://stackblitz.com/) to provide interactive code samples. StackBlitz's [WebContainers](https://webcontainers.io/) is an awesome technology that allows you to run a Node.js environment inside the browser. The embedded samples use the [sql.js](https://github.com/sql-js/sql.js) (a WASM implementation of SQLite) for WebContainers compatibility, which is not suitable for production use. + +### If you already know Prisma + +Although ZenStack ORM has a Prisma-compatible query API, the documentation doesn't assume prior knowledge of using Prisma. However, readers already familiar with Prisma can quickly skim through most of the content and focus on the differences. The documentation uses the following callout to indicate major differences between ZenStack ORM and Prisma: + + +Explanation of some key differences between ZenStack and Prisma ORM. + diff --git a/versioned_docs/version-3.x/orm/quick-start.mdx b/versioned_docs/version-3.x/orm/quick-start.md similarity index 97% rename from versioned_docs/version-3.x/orm/quick-start.mdx rename to versioned_docs/version-3.x/orm/quick-start.md index 5e738583..aa91ee71 100644 --- a/versioned_docs/version-3.x/orm/quick-start.mdx +++ b/versioned_docs/version-3.x/orm/quick-start.md @@ -14,7 +14,7 @@ import PackageExec from '../_components/PackageExec.tsx'; All v3 packages are currently published under the "@next" tag. ::: -There are multiple ways to start using ZenStack. +There are several ways to start using ZenStack ORM. ## 1. Creating a project from scratch From a43c1d805cbe3cf6066cbc3af9a1dce1cb3b469e Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Tue, 5 Aug 2025 17:36:19 +0800 Subject: [PATCH 06/51] update --- versioned_docs/version-3.x/modeling/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versioned_docs/version-3.x/modeling/index.md b/versioned_docs/version-3.x/modeling/index.md index 5cdd7f40..95211884 100644 --- a/versioned_docs/version-3.x/modeling/index.md +++ b/versioned_docs/version-3.x/modeling/index.md @@ -15,7 +15,7 @@ If you're already familiar with PSL, you'll find yourself at home with ZModel. H ZModel uses the explicit `import` syntax for composing multi-file schemas. -Don't worry if you've never used Prima before. This section will introduce all aspects of ZModel, so no prior knowledge is required. +Don't worry if you've never used Prisma before. This section will introduce all aspects of ZModel, so no prior knowledge is required. A very simple ZModel schema looks like this: From f64946712537e84dd94660a0b4b06324b2ca38a1 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Tue, 5 Aug 2025 22:11:29 +0800 Subject: [PATCH 07/51] update embed mechanism --- package.json | 1 + pnpm-lock.yaml | 8 +++ src/components/GithubCodeBlock.tsx | 40 ++++++++++++++ src/components/StackBlitzGithubEmbed.tsx | 61 ++++++++++++++++++---- versioned_docs/version-3.x/orm/api/find.md | 5 ++ 5 files changed, 105 insertions(+), 10 deletions(-) create mode 100644 src/components/GithubCodeBlock.tsx diff --git a/package.json b/package.json index 85733b49..d5b8de74 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@stackblitz/sdk": "^1.11.0", "autoprefixer": "^10.4.13", "clsx": "^1.2.1", + "is-mobile": "^5.0.0", "postcss": "^8.4.21", "prism-react-renderer": "^2.3.1", "prism-svelte": "^0.5.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7b0326f0..ec59cc8f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,6 +38,9 @@ importers: clsx: specifier: ^1.2.1 version: 1.2.1 + is-mobile: + specifier: ^5.0.0 + version: 5.0.0 postcss: specifier: ^8.4.21 version: 8.4.21 @@ -3016,6 +3019,9 @@ packages: resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} engines: {node: '>=10'} + is-mobile@5.0.0: + resolution: {integrity: sha512-Tz/yndySvLAEXh+Uk8liFCxOwVH6YutuR74utvOcu7I9Di+DwM0mtdPVZNaVvvBUM2OXxne/NhOs1zAO7riusQ==} + is-npm@6.0.0: resolution: {integrity: sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -9099,6 +9105,8 @@ snapshots: global-dirs: 3.0.1 is-path-inside: 3.0.3 + is-mobile@5.0.0: {} + is-npm@6.0.0: {} is-number@7.0.0: {} diff --git a/src/components/GithubCodeBlock.tsx b/src/components/GithubCodeBlock.tsx new file mode 100644 index 00000000..5ab8770a --- /dev/null +++ b/src/components/GithubCodeBlock.tsx @@ -0,0 +1,40 @@ +import CodeBlock from '@theme/CodeBlock'; +import { useEffect, useState } from 'react'; + +interface GithubCodeBlockProps { + repoPath: string; + file: string; +} + +const GithubCodeBlock: React.FC = ({ repoPath, file }) => { + const [code, setCode] = useState('Loading...'); + + useEffect(() => { + (async function () { + const response = await fetch(`https://cdn.jsdelivr.net/gh/${repoPath}/${file}`); + if (!response.ok) { + setCode(`Unable to load "${repoPath}/${file}"`); + return; + } + const text = await response.text(); + setCode(text); + })(); + }, [repoPath, file]); + + const getLanguage = (file: string): string => { + if (file.endsWith('.ts')) { + return 'typescript'; + } else if (file.endsWith('.zmodel')) { + return 'zmodel'; + } else { + return 'plaintext'; + } + }; + return ( + + {code} + + ); +}; + +export default GithubCodeBlock; diff --git a/src/components/StackBlitzGithubEmbed.tsx b/src/components/StackBlitzGithubEmbed.tsx index d65fb762..7a3b1d47 100644 --- a/src/components/StackBlitzGithubEmbed.tsx +++ b/src/components/StackBlitzGithubEmbed.tsx @@ -1,10 +1,15 @@ -import React, { useEffect, useRef } from 'react'; import sdk from '@stackblitz/sdk'; +import TabItem from '@theme/TabItem'; +import Tabs from '@theme/Tabs'; +import mobile from 'is-mobile'; +import React, { useEffect, useRef } from 'react'; +import GithubCodeBlock from './GithubCodeBlock'; interface StackBlitzGithubEmbedProps { repoPath: string; height?: string; openFile?: string; + plainCodeFiles?: string[]; startScript?: string; clickToLoad?: boolean; } @@ -13,25 +18,61 @@ const StackBlitzGithubEmbed: React.FC = ({ repoPath, height = '600px', openFile = 'main.ts', + plainCodeFiles = undefined, clickToLoad = false, startScript, }) => { const containerRef = useRef(null); + const options = { + openFile, + height, + view: 'editor', + startScript, + clickToLoad, + } as const; + + if (!plainCodeFiles) { + plainCodeFiles = [openFile]; + } + useEffect(() => { if (containerRef.current) { - sdk.embedGithubProject(containerRef.current, repoPath, { - openFile, - height, - view: 'editor', - hideNavigation: true, - startScript, - clickToLoad, - }); + sdk.embedGithubProject(containerRef.current, repoPath, options); } }, [repoPath, height]); - return
; + const PlainCode = () => ( + <> + {plainCodeFiles.map((file) => ( + + ))} + + ); + + if (mobile()) { + return ; + } else { + return ( + + +
+
+ Click{' '} + sdk.openGithubProject(repoPath, options)}> + here + {' '} + to pop out if the embed doesn't load an interactive terminal. +
+
+
+ + + + + + ); + } }; export default StackBlitzGithubEmbed; diff --git a/versioned_docs/version-3.x/orm/api/find.md b/versioned_docs/version-3.x/orm/api/find.md index 78fdebf5..75e0204e 100644 --- a/versioned_docs/version-3.x/orm/api/find.md +++ b/versioned_docs/version-3.x/orm/api/find.md @@ -4,6 +4,7 @@ description: Find API --- import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import GithubCodeBlock from '@site/src/components/GithubCodeBlock'; import SelectIncludeOmit from './_select-include-omit.md'; # Find @@ -30,6 +31,10 @@ The `find` series of APIs are used to query records from the database. It has th Similar to `findFirst`, but throws an error if no record is found. +Throughout this section all samples are based on the following ZModel schema: + + + ## Basic usage From 5cfdf6d04e9b9cb2379d9587fa0ff6c17b788440 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Tue, 5 Aug 2025 23:13:29 +0800 Subject: [PATCH 08/51] fix stackblitz embed --- src/components/StackBlitzGithubEmbed.tsx | 28 +++++++++++++--------- versioned_docs/version-3.x/orm/api/find.md | 8 +++---- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/components/StackBlitzGithubEmbed.tsx b/src/components/StackBlitzGithubEmbed.tsx index 7a3b1d47..b3ff03eb 100644 --- a/src/components/StackBlitzGithubEmbed.tsx +++ b/src/components/StackBlitzGithubEmbed.tsx @@ -38,9 +38,13 @@ const StackBlitzGithubEmbed: React.FC = ({ useEffect(() => { if (containerRef.current) { - sdk.embedGithubProject(containerRef.current, repoPath, options); + setTimeout(() => { + // docusaurus seems to recreate the tab after mounting, give it a + // chance to complete + sdk.embedGithubProject(containerRef.current, repoPath, options); + }, 0); } - }, [repoPath, height]); + }, [repoPath, height, containerRef]); const PlainCode = () => ( <> @@ -54,9 +58,9 @@ const StackBlitzGithubEmbed: React.FC = ({ return ; } else { return ( - - -
+ <> + +
-
-
- - - -
+ + + + + + +
+ ); } }; diff --git a/versioned_docs/version-3.x/orm/api/find.md b/versioned_docs/version-3.x/orm/api/find.md index 75e0204e..61636451 100644 --- a/versioned_docs/version-3.x/orm/api/find.md +++ b/versioned_docs/version-3.x/orm/api/find.md @@ -47,13 +47,13 @@ The API provides a very flexible set of filtering options. We've put it into a [ Use the `sort` field to control the sort field, direction, and null field placement. Sorting is not supported for `findUnique` and `findUniqueOrThrow`. - + ## Pagination You can use two strategies for pagination: offset-based or cursor-based. Pagination is not supported for `findUnique` and `findUniqueOrThrow`. - + ## Field selection @@ -61,10 +61,10 @@ You can use the following fields to control what fields are returned in the resu - + ## Finding distinct rows You can use the `distinct` field to find distinct rows based on specific fields. One row for each unique combination of the specified fields will be returned. The implementation uses SQL `DISTINCT ON` if it's supported by the dialect, otherwise falls back to in-memory deduplication. - + From 2c526ff61837490577baae04b7e0837bac343694 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Tue, 5 Aug 2025 23:15:24 +0800 Subject: [PATCH 09/51] make code tabs sync --- src/components/StackBlitzGithubEmbed.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/StackBlitzGithubEmbed.tsx b/src/components/StackBlitzGithubEmbed.tsx index b3ff03eb..de68def6 100644 --- a/src/components/StackBlitzGithubEmbed.tsx +++ b/src/components/StackBlitzGithubEmbed.tsx @@ -59,7 +59,7 @@ const StackBlitzGithubEmbed: React.FC = ({ } else { return ( <> - +
Click{' '} From a9d76ec5863b0e14a61636037c169fc516fdea34 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Sat, 9 Aug 2025 18:03:22 +0800 Subject: [PATCH 10/51] complete filter section --- versioned_docs/version-3.x/orm/api/filter.md | 81 ++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/versioned_docs/version-3.x/orm/api/filter.md b/versioned_docs/version-3.x/orm/api/filter.md index 01a84115..46fb196a 100644 --- a/versioned_docs/version-3.x/orm/api/filter.md +++ b/versioned_docs/version-3.x/orm/api/filter.md @@ -3,7 +3,88 @@ sidebar_position: 3 description: how to filter entities --- +import GithubCodeBlock from '@site/src/components/GithubCodeBlock'; import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; # Filter +Filtering is an important topic because it's involved in many ORM operations, for example when you find records, selecting relations, and updating or deleting multiple records. + +Throughout this section all samples are based on the following ZModel schema: + + + +## Basic filters + +You can filter on scalar fields with values or operators as supported by the field type. The following filter operators are available. + +- `equals` `not`: all scalar fields. +- `in` `notIn`: all scalar fields +- `contains` `startsWith` `endsWith`: String fields +- `lt` `lte` `gt` `gte`: String, Int, BigInt, Float, Decimal, and Date fields + +A filter object can contain multiple field filters, and they are combined with `AND` semantic. You can also use the `AND`, `OR`, and `NOT` logical operators to combine filter objects to form a complex filter. + + + +## Relation filters + +Filters can be defined on conditions over relations. For one-to-one relations, you can filter on their fields directly. For one-to-many relations, use the "some", "every", or "none" operators to build a condition over a list of records. + + + +## List filters + +List fields allow extra filter operators to filter on the list content: + +- `has`: checks if the list contains a specific value. +- `hasEvery`: checks if the list contains all values in a given array. +- `hasSome`: checks if the list contains at least one value in a given array. +- `isEmpty`: checks if the list is empty. + +:::info +List type is only supported for PostgreSQL. +::: + +```zmodel +model Post { + ... + topics String[] +} +``` + +```ts +await db.post.findMany({ + where: { topics: { has: 'webdev' } } +}); + +await db.post.findMany({ + where: { topics: { hasSome: ['webdev', 'typescript'] } } +}); + +await db.post.findMany({ + where: { topics: { hasEvery: ['webdev', 'typescript'] } } +}); + +await db.post.findMany({ + where: { topics: { hasNone: ['webdev', 'typescript'] } } +}); + +await db.post.findMany({ + where: { topics: { isEmpty: true } } +}); +``` + +## Json filters + +:::info WORK IN PROGRESS +Filtering on Json fields is work in progress and will be available soon. +::: + +## Query builder filters + +ZenStack v3 is implemented on top of [Kysely](https://kysely.dev/), and it leverages Kysely's powerful query builder API to extend the filtering capabilities. You can use the `$expr` operator to define a boolean expression that can express almost everything that can be expressed in SQL. + +The `$expr` operator can be used together with other filter operators, so you can keep most of your filters simple and only reach to the query builder level for complicated components. + + From 09208d32538887d580cc6383033a0721e6b80b3a Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Sat, 9 Aug 2025 21:43:49 +0800 Subject: [PATCH 11/51] update docs --- versioned_docs/version-3.x/orm/api/update.md | 44 ++++++++++++++++++- versioned_docs/version-3.x/reference/api.md | 7 +++ .../version-3.x/reference/limitations.md | 40 ----------------- .../version-3.x/reference/runtime-api.md | 8 ---- versioned_docs/version-3.x/welcome.md | 6 +-- 5 files changed, 53 insertions(+), 52 deletions(-) create mode 100644 versioned_docs/version-3.x/reference/api.md delete mode 100644 versioned_docs/version-3.x/reference/limitations.md delete mode 100644 versioned_docs/version-3.x/reference/runtime-api.md diff --git a/versioned_docs/version-3.x/orm/api/update.md b/versioned_docs/version-3.x/orm/api/update.md index 383bb752..9adcce77 100644 --- a/versioned_docs/version-3.x/orm/api/update.md +++ b/versioned_docs/version-3.x/orm/api/update.md @@ -3,4 +3,46 @@ sidebar_position: 4 description: Update API --- -# Update \ No newline at end of file +import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; + +# Update + +Update to records can be done with the following methods: + +- `update` - Update a single, unique record. +- `updateMany` - Update multiple records that match the query criteria. +- `updateManyAndReturn` - Similar to `updateMany`, but returns the updated records +- `upsert` - Update a single, unique record, or create it if it does not exist. + +## Updating scalar fields + + + +In additional to the standard way of updating fields, list fields support the following operators: + +- `push`: Append a value or a list of values to the end of the list. +- `set`: Replace the entire list with a new list (equivalent to setting the field directly). + +```ts +await db.post.update({ + where: { id: '1' }, + data: { + topics: { push: 'webdev'}, + }, +}); + +await db.post.update({ + where: { id: '1' }, + data: { + topics: { set: ['orm', 'typescript'] }, + }, +}); +``` + +## Manipulating relations + +THe `update` and `upsert` methods are very powerful in that they allow you to freely manipulate relations. You can create, connect, disconnect, update, and delete relations in a single operation. You can also reach deeply into indirect relations. + +`updateMany` and `updateManyAndReturn` only support updating scalar fields. + + diff --git a/versioned_docs/version-3.x/reference/api.md b/versioned_docs/version-3.x/reference/api.md new file mode 100644 index 00000000..52b981ba --- /dev/null +++ b/versioned_docs/version-3.x/reference/api.md @@ -0,0 +1,7 @@ +--- +description: API references +sidebar_position: 4 +sidebar_label: API +--- + +# API Reference diff --git a/versioned_docs/version-3.x/reference/limitations.md b/versioned_docs/version-3.x/reference/limitations.md deleted file mode 100644 index 96d02bc0..00000000 --- a/versioned_docs/version-3.x/reference/limitations.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -description: Current limitations -sidebar_position: 100 ---- - -# Limitations - -This section lists the current limitations of ZenStack. - -### Sequential operations transaction - -[Sequential operations transaction](https://www.prisma.io/docs/concepts/components/prisma-client/transactions#sequential-prisma-client-operations) is not supported by enhanced Prisma clients yet. - -As a workaround, use [interactive transactions](https://www.prisma.io/docs/concepts/components/prisma-client/transactions#interactive-transactions) instead. - -### Minimum transaction isolation level - -To ensure access policies are properly enforced, the database's transaction isolation level should be set to at least [Repeatable Read](https://en.wikipedia.org/wiki/Isolation_(database_systems)#Repeatable_reads). This can be done by changing the settings of the database, or providing the `isolationLevel` option when creating `PrismaClient`: - -```ts -const prisma = new PrismaClient({ - transactionOptions: { - isolationLevel: Prisma.TransactionIsolationLevel.RepeatableRead, - }, -}); -``` - -If you don't want to change the global settings, alternatively you can set the `transactionIsolationLevel` option when calling ZenStack's `enhance` API. All the transactions initiated internally by ZenStack will use the specified isolation level. - -```ts -const db = enhance(prisma, { user }, { transactionIsolationLevel: 'RepeatableRead' }); -``` - -### MongoDB is not supported - -Right now, the focus of this project is SQL databases, and there's no plan to support MongoDB in the near future. - -### Cloudflare D1 database is not supported - -Prisma doesn't support interactive transactions with D1 databases. ZenStack relies on the feature to enforce access policies in certain cases. diff --git a/versioned_docs/version-3.x/reference/runtime-api.md b/versioned_docs/version-3.x/reference/runtime-api.md deleted file mode 100644 index 2cc8e47c..00000000 --- a/versioned_docs/version-3.x/reference/runtime-api.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -description: Runtime API references -sidebar_position: 4 -sidebar_label: Runtime API ---- - -# Runtime API Reference - diff --git a/versioned_docs/version-3.x/welcome.md b/versioned_docs/version-3.x/welcome.md index da83a371..29665f23 100644 --- a/versioned_docs/version-3.x/welcome.md +++ b/versioned_docs/version-3.x/welcome.md @@ -13,13 +13,13 @@ ZenStack is built with the belief that most applications should use the data mod Inside the package you'll find: -- #### An intuitive schema language +- #### Intuitive schema language That helps you model data, relation, access control, and more, in one place. [πŸ”—](./modeling/) -- #### A powerful ORM +- #### Powerful ORM With awesomely-typed API, built-in access control, and unmatched flexibility. [πŸ”—](./orm/) -- #### A Query-as-a-Service layer +- #### Query-as-a-Service That provides a full-fledged data API without the need to code it up. [πŸ”—](./service/) - #### Utilities From b61a2e028e155483a8a5c4cde983dd2d328a3099 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Sun, 10 Aug 2025 07:44:48 +0800 Subject: [PATCH 12/51] progress on delete --- versioned_docs/version-3.x/orm/api/delete.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/versioned_docs/version-3.x/orm/api/delete.md b/versioned_docs/version-3.x/orm/api/delete.md index 358e28e8..e16e4dda 100644 --- a/versioned_docs/version-3.x/orm/api/delete.md +++ b/versioned_docs/version-3.x/orm/api/delete.md @@ -3,4 +3,18 @@ sidebar_position: 5 description: Delete API --- -# Delete \ No newline at end of file +import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; + +# Delete + +Deleting records can be done with the following methods: + +- `delete` - Delete a single, unique record. +- `deleteMany` - Delete multiple records that match the query criteria. +- `deleteManyAndReturn` - Similar to `deleteMany`, but returns the deleted records + +You can also delete records as part of an `update` operation from a relation. See [Manipulating relations](./update.md#manipulating-relations) for details. + +## Samples + + From 7531a1808953147ab5151734a80ab2f3fe485d2b Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Sun, 10 Aug 2025 21:20:04 +0800 Subject: [PATCH 13/51] more progress on ORM API --- .../version-3.x/orm/api/_category_.yml | 7 -- .../version-3.x/orm/api/aggregate.md | 18 ++- versioned_docs/version-3.x/orm/api/count.md | 10 +- versioned_docs/version-3.x/orm/api/create.md | 21 ---- versioned_docs/version-3.x/orm/api/filter.md | 5 - versioned_docs/version-3.x/orm/api/find.md | 5 - .../version-3.x/orm/api/group-by.md | 6 + versioned_docs/version-3.x/orm/api/index.md | 117 ++++++++++++++++++ .../version-3.x/orm/api/transaction.md | 2 +- 9 files changed, 150 insertions(+), 41 deletions(-) delete mode 100644 versioned_docs/version-3.x/orm/api/_category_.yml create mode 100644 versioned_docs/version-3.x/orm/api/group-by.md create mode 100644 versioned_docs/version-3.x/orm/api/index.md diff --git a/versioned_docs/version-3.x/orm/api/_category_.yml b/versioned_docs/version-3.x/orm/api/_category_.yml deleted file mode 100644 index 2a384497..00000000 --- a/versioned_docs/version-3.x/orm/api/_category_.yml +++ /dev/null @@ -1,7 +0,0 @@ -position: 6 -label: ORM API -collapsible: true -collapsed: true -link: - type: generated-index - title: ORM API diff --git a/versioned_docs/version-3.x/orm/api/aggregate.md b/versioned_docs/version-3.x/orm/api/aggregate.md index f7f12077..27b95a31 100644 --- a/versioned_docs/version-3.x/orm/api/aggregate.md +++ b/versioned_docs/version-3.x/orm/api/aggregate.md @@ -3,4 +3,20 @@ sidebar_position: 7 description: Aggregate API --- -# Aggregate \ No newline at end of file +import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; + +# Aggregate + +The `aggregate` method allows you to conduct multiple aggregations on a set of records with one operation. The supported aggregations are: + +- `_count` - equivalent to the [Count API](./count.md). +- `_sum` - sum of a numeric field. +- `_avg` - average of a numeric field. +- `_min` - minimum value of a field. +- `_max` - maximum value of a field. + +You can also use `where`, `orderBy`, `skip`, and `take` to control what records are included in the aggregation. + +## Samples + + diff --git a/versioned_docs/version-3.x/orm/api/count.md b/versioned_docs/version-3.x/orm/api/count.md index 7402362e..d337e632 100644 --- a/versioned_docs/version-3.x/orm/api/count.md +++ b/versioned_docs/version-3.x/orm/api/count.md @@ -3,4 +3,12 @@ sidebar_position: 6 description: Count API --- -# Count \ No newline at end of file +import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; + +# Count + +You can use the `count` method to count the number of records that match a query. It also allows to count non-null field values with an `select` clause. + + + +To count relations, please use a `find` API with the special `_count` field as demonstrated in the [Find](./find.md#field-selection) section. diff --git a/versioned_docs/version-3.x/orm/api/create.md b/versioned_docs/version-3.x/orm/api/create.md index d6b8326e..74c8f447 100644 --- a/versioned_docs/version-3.x/orm/api/create.md +++ b/versioned_docs/version-3.x/orm/api/create.md @@ -20,24 +20,3 @@ The `create` series of APIs are used to create new records in the database. It h -## Input - -The create APIs accept an input object with the following fields: - -- `data` - - The data used to create the record. It must contain all non-optional fields of the model. It can also include nested object for creating or connecting relation entities. For `create` the data field must be an object. For `createMany` and `createManyAndReturn`, it can be either an object or an array of objects. - - This field is required. - -- `skipDuplicates` - - A boolean flag that indicates whether to skip records that would violate unique constraints. Only applicable to `createMany` and `createManyAndReturn`. - - This field is optional and defaults to `false`. - -You can also control what fields are turned in the result using the `select`, `include`, and `omit` fields. Read more about field selection in the [next section](./find.md#field-selection). - -## Output - -The output shape of `create` and `createManyAndReturn` API is determined by the `select`, `include`, and `omit` fields in the input object. The output of `createMany` is `{ count: number }`, giving the number of records created. diff --git a/versioned_docs/version-3.x/orm/api/filter.md b/versioned_docs/version-3.x/orm/api/filter.md index 46fb196a..47fc7e6c 100644 --- a/versioned_docs/version-3.x/orm/api/filter.md +++ b/versioned_docs/version-3.x/orm/api/filter.md @@ -3,17 +3,12 @@ sidebar_position: 3 description: how to filter entities --- -import GithubCodeBlock from '@site/src/components/GithubCodeBlock'; import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; # Filter Filtering is an important topic because it's involved in many ORM operations, for example when you find records, selecting relations, and updating or deleting multiple records. -Throughout this section all samples are based on the following ZModel schema: - - - ## Basic filters You can filter on scalar fields with values or operators as supported by the field type. The following filter operators are available. diff --git a/versioned_docs/version-3.x/orm/api/find.md b/versioned_docs/version-3.x/orm/api/find.md index 61636451..ce718521 100644 --- a/versioned_docs/version-3.x/orm/api/find.md +++ b/versioned_docs/version-3.x/orm/api/find.md @@ -4,7 +4,6 @@ description: Find API --- import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; -import GithubCodeBlock from '@site/src/components/GithubCodeBlock'; import SelectIncludeOmit from './_select-include-omit.md'; # Find @@ -31,10 +30,6 @@ The `find` series of APIs are used to query records from the database. It has th Similar to `findFirst`, but throws an error if no record is found. -Throughout this section all samples are based on the following ZModel schema: - - - ## Basic usage diff --git a/versioned_docs/version-3.x/orm/api/group-by.md b/versioned_docs/version-3.x/orm/api/group-by.md new file mode 100644 index 00000000..7ed21962 --- /dev/null +++ b/versioned_docs/version-3.x/orm/api/group-by.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 8 +description: GroupBy API +--- + +# GroupBy \ No newline at end of file diff --git a/versioned_docs/version-3.x/orm/api/index.md b/versioned_docs/version-3.x/orm/api/index.md new file mode 100644 index 00000000..88eb3a66 --- /dev/null +++ b/versioned_docs/version-3.x/orm/api/index.md @@ -0,0 +1,117 @@ +--- +sidebar_position: 1 +sidebar_label: Query API +title: Query API Overview +--- + +ZenStack ORM's query API provides a powerful and high-level way to interact with your database with awesome type safety. The API is a superset of [Prisma ORM's query API](https://www.prisma.io/docs/orm/prisma-client/queries), so if you are familiar with Prisma, you will feel right at home. If not, it's intuitive and easy to learn. + +The API is organized into several categories covered by the following sections. The API methods share many common input and output patterns, and we'll cover them in this overview section. + +## Common Input Fields + +- `where` + + When an operation can involve filtering records, a `where` clause is used to specify the condition. E.g., `findUnique`, `updateMany`, `delete`, etc. `where` clause also exists in nested payload for filtering relations. + + ```ts + await db.post.findMany({ where: { published: true } }); + ``` + + The [Filter](./filter) section describes the filtering capabilities in detail. + +- `select`, `include`, `omit` + + When an operation returns record(s), you can use these clauses to control the fields and relations returned in the result. The `select` clause is used to specify the fields/relations to return, `omit` to exclude, and `include` to include relations (together with all regular fields). + + When selecting relations, you can nest these clauses to further control fields and relations returned in the nested relations. + + ```ts + // results will include `title` field and `author` relation + await db.post.findMany({ + select: { title: true, author: true }, + }); + + // results will include all fields except `content`, plus `author` relation + await db.post.findMany({ + omit: { content: true }, include: { author: true } + }); + ``` + +- `orderBy`, `take`, `skip` + + When an operation returns multiple records, you can use these clauses to control the sort order, number of records returned, and the offset for pagination. + + ```ts + // results will be sorted by `createdAt` in descending order, and return + // 10 records starting from the 5th record + await db.post.findMany({ orderBy: { createdAt: 'desc' }, skip: 5, take: 10 }); + ``` + +- `data` + + When an operation involves creating or updating records, a `data` clause is used to specify the data to be used. It can include nested objects for manipulating relations. See the [Create](./create) and [Update](./update) sections for details. + + ```ts + // Create a new post and connect it to an author + await db.post.create({ + data: { title: 'New Post', author: { connect: { id: 1 } } } + }); + ``` + +## Output Types + +The output types of the API methods generally fall into three categories: + +1. When the operation returns record(s) + + The output type is "contextual" to the input's shape, meaning that when you specify `select`, `include`, or `omit` clauses, the output type will reflect that. + + ```ts + // result will be `Promise<{ title: string; author: { name: string } }[]>` + await db.post.findMany({ + select: { title: true, author: { select: { name: true } } } + }); + ``` + +2. When the operation returns a batch result + + Some operations only returns a batch result `{ count: number }`, indicating the number of records affected. These include `createMany`, `updateMany`, and `deleteMany`. + +3. Aggregation + + Aggregation operations' output type is contextual to the input's shape as well. See [Count](./count) and [Aggregate](./aggregate) sections for details. + + +## Sample Schema + +Throughout the following sections, we will use the following ZModel schema as the basis for our examples: + +```zmodel title="zenstack/schema.zmodel" +// This is a sample model to get you started. + +datasource db { + provider = 'sqlite' +} + +/// User model +model User { + id Int @id @default(autoincrement()) + email String @unique + posts Post[] +} + +/// Post model +model Post { + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + title String + content String? + slug String? @unique + published Boolean @default(false) + viewCount Int @default(0) + author User? @relation(fields: [authorId], references: [id]) + authorId Int? +} +``` diff --git a/versioned_docs/version-3.x/orm/api/transaction.md b/versioned_docs/version-3.x/orm/api/transaction.md index 79bbcb5f..66bf2c9f 100644 --- a/versioned_docs/version-3.x/orm/api/transaction.md +++ b/versioned_docs/version-3.x/orm/api/transaction.md @@ -1,5 +1,5 @@ --- -sidebar_position: 8 +sidebar_position: 9 description: Transaction API --- From c608cf46a8a0466dc86c0473d4627dd42a5ab128 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Tue, 12 Aug 2025 21:44:37 +0800 Subject: [PATCH 14/51] ORM docs progress --- .../version-3.x/orm/api/group-by.md | 39 ++++++++++++++++++- versioned_docs/version-3.x/orm/api/index.md | 4 +- .../version-3.x/orm/api/transaction.md | 39 ++++++++++++++++++- versioned_docs/version-3.x/orm/cli.md | 6 ++- .../version-3.x/orm/database-client.md | 4 +- .../version-3.x/orm/inferred-types.md | 2 +- .../version-3.x/orm/polymorphism.md | 8 ++++ versioned_docs/version-3.x/orm/quick-start.md | 6 ++- 8 files changed, 97 insertions(+), 11 deletions(-) create mode 100644 versioned_docs/version-3.x/orm/polymorphism.md diff --git a/versioned_docs/version-3.x/orm/api/group-by.md b/versioned_docs/version-3.x/orm/api/group-by.md index 7ed21962..92d7937e 100644 --- a/versioned_docs/version-3.x/orm/api/group-by.md +++ b/versioned_docs/version-3.x/orm/api/group-by.md @@ -3,4 +3,41 @@ sidebar_position: 8 description: GroupBy API --- -# GroupBy \ No newline at end of file +import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; + +# GroupBy + +The `groupBy` method allows you to group records by one or more fields and perform aggregations on the grouped records - very useful for generating summary statistics or reports. + +Use the `by` field to specify the field(s) to group by, and the following aggregation operators to perform on the grouped records: + +- `_count` - count the number of records in each group. +- `_sum` - sum of a numeric field in each group. +- `_avg` - average of a numeric field in each group. +- `_min` - minimum value of a field in each group. +- `_max` - maximum value of a field in each group. + +You can also use `where`, `orderBy`, `skip`, and `take` to control what records are included in the aggregation. + +The `having` field can be used to filter the aggregated results. Two types of filters can be used in the `having` clause: + +- A regular field that's used in the `by` clause, e.g.: + + ```ts + await db.post.groupBy({ by: 'published', having: { published: true } }); + ``` + +- An aggregation, e.g.: + + In this case, the fields of aggregation doesn't need to be in the `by` clause. + + ```ts + await db.post.groupBy({ + by: 'authorId', + having: { viewCount: { _sum: { gt: 100 }} } + }); + ``` + +## Samples + + diff --git a/versioned_docs/version-3.x/orm/api/index.md b/versioned_docs/version-3.x/orm/api/index.md index 88eb3a66..6bd18a7d 100644 --- a/versioned_docs/version-3.x/orm/api/index.md +++ b/versioned_docs/version-3.x/orm/api/index.md @@ -1,7 +1,7 @@ --- -sidebar_position: 1 +sidebar_position: 4 sidebar_label: Query API -title: Query API Overview +title: Query API --- ZenStack ORM's query API provides a powerful and high-level way to interact with your database with awesome type safety. The API is a superset of [Prisma ORM's query API](https://www.prisma.io/docs/orm/prisma-client/queries), so if you are familiar with Prisma, you will feel right at home. If not, it's intuitive and easy to learn. diff --git a/versioned_docs/version-3.x/orm/api/transaction.md b/versioned_docs/version-3.x/orm/api/transaction.md index 66bf2c9f..a0cf5767 100644 --- a/versioned_docs/version-3.x/orm/api/transaction.md +++ b/versioned_docs/version-3.x/orm/api/transaction.md @@ -3,4 +3,41 @@ sidebar_position: 9 description: Transaction API --- -# Transaction \ No newline at end of file +import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; + +# Transaction + +You can use the `$transaction` method to run multiple operations in a transaction. There are two overloads of this method: + +## Sequential Transaction + +This overload takes an array of promises as input. The operations are executed sequentially in the order they are provided. The operations are independent of each other, because there's no way to access the result of a previous operation and use it to influence the later operations. + +```ts +// Note that the `db.user.create` and `db.post.create` calls are not awaited. They +// are passed to the `$transaction` method to execute. +const [user, post] = await db.$transaction([ + db.user.create({ data: { name: 'Alice' } }), + db.user.create({ data: { name: 'Bob' } }), +]); +``` + +The result of each operation is returned in the same order as the input. + +## Interactive Transaction + +This overload takes an async callback function as input. The callback receives a transaction client that can be used to perform database operations within the transaction. + +Interactive transactions allows you to write imperative code that can access the results of previous operations and use them to influence later operations. Albeit it's flexibility, you should make the transaction callback run as fast as possible so as to reduce the performance impact of the transaction on the database. + +```ts +const [user, post] = await db.$transaction(async (tx) => { + const user = await tx.user.create({ data: { name: 'Alice' } }); + const post = await tx.post.create({ data: { title: 'Hello World', authorId: user.id } }); + return [user, post]; +}); +``` + +## Samples + + diff --git a/versioned_docs/version-3.x/orm/cli.md b/versioned_docs/version-3.x/orm/cli.md index 86de9ffd..d4f52ab2 100644 --- a/versioned_docs/version-3.x/orm/cli.md +++ b/versioned_docs/version-3.x/orm/cli.md @@ -1,5 +1,5 @@ --- -sidebar_position: 4 +sidebar_position: 2 description: Using the CLI --- @@ -7,7 +7,7 @@ import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; # Using the CLI -ZenStack CLI is a command-line tool that takes the ZModel schema as input and complete different tasks for you. It's included in the "@zenstackhq/cli" package, and can be invoked with either `zen` or `zenstack` command. +ZenStack CLI is a command-line tool that takes the ZModel schema as input and complete different tasks for you. It's included in the "@zenstackhq/cli" package, and can be invoked with either `zen` or `zenstack` command (they are equivalent). In the context of ORM, the CLI compiles ZModel into a TypeScript representation, which can in turn be used to create a type-safe ORM client. @@ -20,3 +20,5 @@ The `generate` command outputs the following TypeScript files in the same folder - `schema.ts`: TypeScript representation of the ZModel schema, used by the ORM client to understand the database's structure and infer types. - `models.ts`: Exports types for all models, types, and enums defined in the schema. - `input.ts`: Export types that you can use to type the arguments passed to the ORM client methods, such as `findMany`, `create`, etc. + +Refer to the [CLI Reference](../reference/cli.md) for the full list of commands and options. \ No newline at end of file diff --git a/versioned_docs/version-3.x/orm/database-client.md b/versioned_docs/version-3.x/orm/database-client.md index 166bafb7..f3187fb4 100644 --- a/versioned_docs/version-3.x/orm/database-client.md +++ b/versioned_docs/version-3.x/orm/database-client.md @@ -1,5 +1,5 @@ --- -sidebar_position: 5 +sidebar_position: 3 description: Creating a database client --- @@ -16,7 +16,7 @@ Unlike Prisma, ZenStack doesn't bundle any database driver. You're responsible f The `zen generate` command compiles the ZModel schema into TypeScript code, which we can in turn use to initialize a type-safe database client. ZenStack uses Kysely to handle the low-level database operations, so the client is initialize with a [Kysely dialect](https://kysely.dev/docs/dialects) - an object that encapsulates database details. -The samples below only shows creating a client using SQLite (via [better-sqlite3](https://github.com/WiseLibs/better-sqlite3)) and PostgreSQL (via [node-postgres](https://github.com/brianc/node-postgres)), however you can also use any other Kysely dialects for these two types of databases. +The samples below only show creating a client using SQLite (via [better-sqlite3](https://github.com/WiseLibs/better-sqlite3)) and PostgreSQL (via [node-postgres](https://github.com/brianc/node-postgres)), however you can also use any other Kysely dialects for these two types of databases. diff --git a/versioned_docs/version-3.x/orm/inferred-types.md b/versioned_docs/version-3.x/orm/inferred-types.md index 990d91d6..ee1183ae 100644 --- a/versioned_docs/version-3.x/orm/inferred-types.md +++ b/versioned_docs/version-3.x/orm/inferred-types.md @@ -1,5 +1,5 @@ --- -sidebar_position: 11 +sidebar_position: 12 description: TypeScript types derived from the ZModel schema --- diff --git a/versioned_docs/version-3.x/orm/polymorphism.md b/versioned_docs/version-3.x/orm/polymorphism.md new file mode 100644 index 00000000..3e99fb1f --- /dev/null +++ b/versioned_docs/version-3.x/orm/polymorphism.md @@ -0,0 +1,8 @@ +--- +sidebar_position: 11 +description: Polymorphic models +--- + +# Polymorphic Models + + diff --git a/versioned_docs/version-3.x/orm/quick-start.md b/versioned_docs/version-3.x/orm/quick-start.md index aa91ee71..1cc2ad48 100644 --- a/versioned_docs/version-3.x/orm/quick-start.md +++ b/versioned_docs/version-3.x/orm/quick-start.md @@ -1,5 +1,5 @@ --- -sidebar_position: 2 +sidebar_position: 1 description: Quick start guide --- @@ -60,8 +60,10 @@ You can also always configure a project manually with the following steps: -## 4. Custom schema and output paths +:::info By default, ZenStack CLI loads the schema from `zenstack/schema.zmodel`. You can change this by passing the `--schema` option. TypeScript files are by default generated to the same directory as the schema file. You can change this by passing the `--output` option. You can choose to either commit the generated TypeScript files to your source control, or add them to `.gitignore` and generate them on the fly in your CI/CD pipeline. + +::: \ No newline at end of file From 710b83c59e3d9b2c03a9be43508a9fc6519e3237 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Tue, 12 Aug 2025 22:59:24 +0800 Subject: [PATCH 15/51] query builder docs --- .../orm/access-control/_category_.yml | 4 ---- .../version-3.x/orm/access-control/index.md | 7 +++++++ .../orm/access-control/introduction.md | 3 --- .../orm/{database-client.md => client.md} | 0 .../version-3.x/orm/query-builder.md | 18 +++++++++++++++++- versioned_docs/version-3.x/orm/validation.md | 2 +- 6 files changed, 25 insertions(+), 9 deletions(-) delete mode 100644 versioned_docs/version-3.x/orm/access-control/_category_.yml create mode 100644 versioned_docs/version-3.x/orm/access-control/index.md delete mode 100644 versioned_docs/version-3.x/orm/access-control/introduction.md rename versioned_docs/version-3.x/orm/{database-client.md => client.md} (100%) diff --git a/versioned_docs/version-3.x/orm/access-control/_category_.yml b/versioned_docs/version-3.x/orm/access-control/_category_.yml deleted file mode 100644 index dcb120ba..00000000 --- a/versioned_docs/version-3.x/orm/access-control/_category_.yml +++ /dev/null @@ -1,4 +0,0 @@ -position: 8 -label: Access Control -collapsible: true -collapsed: true diff --git a/versioned_docs/version-3.x/orm/access-control/index.md b/versioned_docs/version-3.x/orm/access-control/index.md new file mode 100644 index 00000000..94c9b191 --- /dev/null +++ b/versioned_docs/version-3.x/orm/access-control/index.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 6 +--- + +# Access Control + +Coming soon 🚧 \ No newline at end of file diff --git a/versioned_docs/version-3.x/orm/access-control/introduction.md b/versioned_docs/version-3.x/orm/access-control/introduction.md deleted file mode 100644 index 261e992b..00000000 --- a/versioned_docs/version-3.x/orm/access-control/introduction.md +++ /dev/null @@ -1,3 +0,0 @@ -# Introduction - -Coming soon 🚧 \ No newline at end of file diff --git a/versioned_docs/version-3.x/orm/database-client.md b/versioned_docs/version-3.x/orm/client.md similarity index 100% rename from versioned_docs/version-3.x/orm/database-client.md rename to versioned_docs/version-3.x/orm/client.md diff --git a/versioned_docs/version-3.x/orm/query-builder.md b/versioned_docs/version-3.x/orm/query-builder.md index 106b4ae4..f4fcd831 100644 --- a/versioned_docs/version-3.x/orm/query-builder.md +++ b/versioned_docs/version-3.x/orm/query-builder.md @@ -1,6 +1,22 @@ --- -sidebar_position: 7 +sidebar_position: 5 description: Query builder API --- +import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; + # Query Builder API + +The [Query API](./api/) introduced in the previous sections provide a powerful and intuitive way to query databases. However, complex applications usually have use cases that outgrow its capabilities. For typical ORMs, this is where you leave the comfort zone and resort to writing SQL. + +The unique advantage of ZenStack is that it's built above [Kysely](https://kysely.dev) - a highly popular, well-designed and type-safe SQL query builder. This means we can easily expose the full power of Kysely to you as a much better alternative to writing raw SQL. + +No extra setup is needed to use the query builder API. The ORM client has a `$qb` property that provides the Kysely query builder, and it's typing is inferred from the ZModel schema. + +Besides building full queries, the query builder API can also be embedded inside the ORM query API with a `$expr` key inside a `where` clause. See [Filter](./api/filter.md) section for details. + +## Samples + +The samples assume you have a basic understanding of Kysely. + + diff --git a/versioned_docs/version-3.x/orm/validation.md b/versioned_docs/version-3.x/orm/validation.md index 7d0fb918..1668a477 100644 --- a/versioned_docs/version-3.x/orm/validation.md +++ b/versioned_docs/version-3.x/orm/validation.md @@ -5,4 +5,4 @@ description: Data validation in ZModel # Data Validation - +Coming soon 🚧 From f0014f0887494adc9f9be260511665ee62ab35e3 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Wed, 13 Aug 2025 12:10:36 +0800 Subject: [PATCH 16/51] computed fields --- versioned_docs/version-3.x/orm/api/filter.md | 5 +++ .../version-3.x/orm/computed-fields.md | 43 +++++++++++++++++++ .../version-3.x/orm/query-builder.md | 5 +++ 3 files changed, 53 insertions(+) diff --git a/versioned_docs/version-3.x/orm/api/filter.md b/versioned_docs/version-3.x/orm/api/filter.md index 47fc7e6c..80321ccf 100644 --- a/versioned_docs/version-3.x/orm/api/filter.md +++ b/versioned_docs/version-3.x/orm/api/filter.md @@ -3,6 +3,7 @@ sidebar_position: 3 description: how to filter entities --- +import ZenStackVsPrisma from '../../_components/ZenStackVsPrisma'; import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; # Filter @@ -78,6 +79,10 @@ Filtering on Json fields is work in progress and will be available soon. ## Query builder filters + +The ability to mix SQL query builder into ORM filters is a major improvement over Prisma. + + ZenStack v3 is implemented on top of [Kysely](https://kysely.dev/), and it leverages Kysely's powerful query builder API to extend the filtering capabilities. You can use the `$expr` operator to define a boolean expression that can express almost everything that can be expressed in SQL. The `$expr` operator can be used together with other filter operators, so you can keep most of your filters simple and only reach to the query builder level for complicated components. diff --git a/versioned_docs/version-3.x/orm/computed-fields.md b/versioned_docs/version-3.x/orm/computed-fields.md index d6e2cbd7..55222236 100644 --- a/versioned_docs/version-3.x/orm/computed-fields.md +++ b/versioned_docs/version-3.x/orm/computed-fields.md @@ -3,5 +3,48 @@ sidebar_position: 10 description: Computed fields in ZModel --- +import ZenStackVsPrisma from '../_components/ZenStackVsPrisma'; +import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; + # Computed Fields + +Prisma client extensions allow you to define computed fields. ZenStack's approach is very different in two aspects: +1. Computed fields are evaluated on the database side, not in the client. +2. Computed fields are defined in the schema and can be used in most places where regular fields are used. + + +Computed fields are "virtual" fields that do not physically exist in the database. They are computed on the fly, but other than that, they behave like regular fields. They are returned as part of the query results, can be used for filtering, sorting, etc., and can be used to define access policies. + +## Defining Computed Fields + +Defining a computed fields involves two steps. First, add the field in the ZModel schema to a model and annotate it with an extra `@computed` attribute. + +```zmodel +model User { + ... + postCount Int @computed +} +``` + +Then, when creating a `ZenStackClient`, provide the implementation of the field using the Kysely query builder. + +```ts +import { ZenStackClient } from '@zenstackhq/runtime'; + +const db = new ZenStackClient(schema, { + ... + computedFields: { + User: { + postCount: (eb) => + eb.selectFrom('Post') + .whereRef('Post.authorId', '=', 'User.id') + .select(({fn}) => fn.countAll().as('count')), + }, + }, +}); +``` + +## Samples + + diff --git a/versioned_docs/version-3.x/orm/query-builder.md b/versioned_docs/version-3.x/orm/query-builder.md index f4fcd831..af26c2e9 100644 --- a/versioned_docs/version-3.x/orm/query-builder.md +++ b/versioned_docs/version-3.x/orm/query-builder.md @@ -3,10 +3,15 @@ sidebar_position: 5 description: Query builder API --- +import ZenStackVsPrisma from '../_components/ZenStackVsPrisma'; import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; # Query Builder API + +Query builder API is a major feature that sets ZenStack apart from Prisma. + + The [Query API](./api/) introduced in the previous sections provide a powerful and intuitive way to query databases. However, complex applications usually have use cases that outgrow its capabilities. For typical ORMs, this is where you leave the comfort zone and resort to writing SQL. The unique advantage of ZenStack is that it's built above [Kysely](https://kysely.dev) - a highly popular, well-designed and type-safe SQL query builder. This means we can easily expose the full power of Kysely to you as a much better alternative to writing raw SQL. From 016fc3d605063de003606f1b58eb3e8ca96563a3 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Wed, 13 Aug 2025 16:22:24 +0800 Subject: [PATCH 17/51] polymorphism --- versioned_docs/version-3.x/faq.md | 2 +- versioned_docs/version-3.x/migrate-prisma.md | 6 ++++ versioned_docs/version-3.x/orm/index.md | 2 +- .../version-3.x/orm/inferred-types.md | 2 +- versioned_docs/version-3.x/orm/logging.md | 6 ++++ .../version-3.x/orm/polymorphism.md | 28 +++++++++++++++++++ versioned_docs/version-3.x/samples.md | 3 +- .../version-3.x/utilities/tanstack-query.md | 6 ---- 8 files changed, 44 insertions(+), 11 deletions(-) create mode 100644 versioned_docs/version-3.x/migrate-prisma.md create mode 100644 versioned_docs/version-3.x/orm/logging.md delete mode 100644 versioned_docs/version-3.x/utilities/tanstack-query.md diff --git a/versioned_docs/version-3.x/faq.md b/versioned_docs/version-3.x/faq.md index 410fe76c..0a788729 100644 --- a/versioned_docs/version-3.x/faq.md +++ b/versioned_docs/version-3.x/faq.md @@ -10,5 +10,5 @@ sidebar_position: 100 ## What databases are supported? -Currently only SQLite and PostgreSQL are supported. MySQL will be added in the future. There's no plan to support other relational databases or NoSQL databases. +Currently only SQLite (with [better-sqlite3](https://github.com/WiseLibs/better-sqlite3) or [sql.js](https://github.com/sql-js/sql.js) driver) and PostgreSQL (with [node-postgres](https://github.com/brianc/node-postgres) driver) are supported. MySQL will be added in the future. There's no plan to support other relational databases or NoSQL databases. diff --git a/versioned_docs/version-3.x/migrate-prisma.md b/versioned_docs/version-3.x/migrate-prisma.md new file mode 100644 index 00000000..4dcfc511 --- /dev/null +++ b/versioned_docs/version-3.x/migrate-prisma.md @@ -0,0 +1,6 @@ +--- +description: How to migrate from a Prisma project to ZenStack v3 +sidebar_position: 10 +--- + +# Migrating From Prisma diff --git a/versioned_docs/version-3.x/orm/index.md b/versioned_docs/version-3.x/orm/index.md index 1096aad7..57da3251 100644 --- a/versioned_docs/version-3.x/orm/index.md +++ b/versioned_docs/version-3.x/orm/index.md @@ -5,7 +5,7 @@ description: ZenStack ORM overview import ZenStackVsPrisma from '../_components/ZenStackVsPrisma'; -# Overview +# ORM Overview ZenStack ORM is a schema-first ORM for modern TypeScript applications. It learnt from the prior arts and strives to provide an awesome developer experience by combining the best ingredients into a cohesive package. diff --git a/versioned_docs/version-3.x/orm/inferred-types.md b/versioned_docs/version-3.x/orm/inferred-types.md index ee1183ae..74c292f7 100644 --- a/versioned_docs/version-3.x/orm/inferred-types.md +++ b/versioned_docs/version-3.x/orm/inferred-types.md @@ -1,5 +1,5 @@ --- -sidebar_position: 12 +sidebar_position: 14 description: TypeScript types derived from the ZModel schema --- diff --git a/versioned_docs/version-3.x/orm/logging.md b/versioned_docs/version-3.x/orm/logging.md new file mode 100644 index 00000000..abb4c943 --- /dev/null +++ b/versioned_docs/version-3.x/orm/logging.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 13 +description: Setup logging +--- + +# Logging diff --git a/versioned_docs/version-3.x/orm/polymorphism.md b/versioned_docs/version-3.x/orm/polymorphism.md index 3e99fb1f..0b47630c 100644 --- a/versioned_docs/version-3.x/orm/polymorphism.md +++ b/versioned_docs/version-3.x/orm/polymorphism.md @@ -3,6 +3,34 @@ sidebar_position: 11 description: Polymorphic models --- +import ZenStackVsPrisma from '../_components/ZenStackVsPrisma'; +import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import GithubCodeBlock from '@site/src/components/GithubCodeBlock'; + # Polymorphic Models + +Polymorphic models is a major feature that sets ZenStack apart from Prisma. + + +ZenStack natively supports polymorphic models. As we have seen in the [Polymorphism](../modeling/polymorphism.md) section in the data modeling part, the ZModel language allows you to define models with Object-Oriented style inheritance. This section will describe the ORM runtime behavior of polymorphic models. + +## CRUD behavior + +Polymorphic models' CRUD behavior is similar to that of regular models, with two major differences: + +1. Base model entities cannot be created directly as they cannot exist without an associated concrete model entity. +2. When querying a base model (either top-level or nested), the result will include all fields of the associated concrete model (unless fields are explicitly selected). The result's type is a discriminated union, so you can use TypeScript's type narrowing to access the concrete model's specific fields. + +The ORM query API hides all the complexity of managing polymorphic models for you: +- When creating a concrete model entity, its base entity is automatically created. +- When querying a base entity, the ORM fetches the associated concrete entity and merges the results. +- When deleting a base or concrete entity, the ORM automatically deletes the counterpart entity. + +## Samples + +The schema used in the sample involves a base model and three concrete models: + + + diff --git a/versioned_docs/version-3.x/samples.md b/versioned_docs/version-3.x/samples.md index 3e385d1b..8701ccc0 100644 --- a/versioned_docs/version-3.x/samples.md +++ b/versioned_docs/version-3.x/samples.md @@ -3,6 +3,5 @@ sidebar_position: 8 sidebar_label: Sample Projects --- -# A Catalog of Sample Projects +# Sample Projects -The ZenStack team maintains the following three series of sample projects. diff --git a/versioned_docs/version-3.x/utilities/tanstack-query.md b/versioned_docs/version-3.x/utilities/tanstack-query.md deleted file mode 100644 index fa0f1bda..00000000 --- a/versioned_docs/version-3.x/utilities/tanstack-query.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -sidebar_position: 2 -description: TanStack Query integration ---- - -# TanStack Query From 963d91f6ab752f243a2f868ba121e40b7654b854 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Wed, 13 Aug 2025 23:27:20 +0800 Subject: [PATCH 18/51] plugins part --- .../orm/plugins/entity-mutation-hooks.md | 47 +++++++++++++++++++ .../version-3.x/orm/plugins/index.md | 38 ++++++++++++++- .../orm/plugins/kysely-query-hooks.md | 24 ++++++++++ .../orm/plugins/query-api-hooks.md | 30 ++++++++++++ 4 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 versioned_docs/version-3.x/orm/plugins/entity-mutation-hooks.md create mode 100644 versioned_docs/version-3.x/orm/plugins/kysely-query-hooks.md create mode 100644 versioned_docs/version-3.x/orm/plugins/query-api-hooks.md diff --git a/versioned_docs/version-3.x/orm/plugins/entity-mutation-hooks.md b/versioned_docs/version-3.x/orm/plugins/entity-mutation-hooks.md new file mode 100644 index 00000000..154845c2 --- /dev/null +++ b/versioned_docs/version-3.x/orm/plugins/entity-mutation-hooks.md @@ -0,0 +1,47 @@ +--- +sidebar_position: 2 +--- + +import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; + +# Entity Mutation Hooks + +## Introduction + +Entity mutation hooks allow you to intercept entity mutation operations, i.e., "create", "update", and "delete". They are triggered regardless of whether the operations are performed through the ORM queries or the query builder API. + +To create an entity mutation hook plugin, call the `$use` method with an object containing the following optional keys: + +- `beforeEntityMutation` + A callback function that is called before the entity mutation operation. It receives a context object containing: + - The model + - The action (create, update, delete) + - The Kysely query node (SQL AST) + - The entities being mutated (only available when opted in) + +- `afterEntityMutation` + A callback function that is called after the entity mutation operation. It receives a context object containing: + - The model + - The action (create, update, delete) + - The Kysely query node (SQL AST) + - The entities before the mutation (only available when opted in) + - The entities after the mutation (only available when opted in) + +- `mutationInterceptionFilter` + + A callback used to determine if an operation should be intercepted, and if so, whether entities should be loaded and passed to the `beforeEntityMutation` and `afterEntityMutation` hooks. It receives a context object containing: + - The model + - The action (create, update, delete) + - The Kysely query node (SQL AST) + + The callback should return an object indicating if the operation should be intercepted and whether entities should be loaded. If this callback is not provided, by default, all mutation operations are intercepted, but entities are not loaded. + +If a mutation happens inside a transaction, the `afterEntityMutation` callback is called after the transaction is committed. + +:::warning +Be very careful about opting in to load before and after mutation entities. Batch mutations can result in a large number of entities being loaded and incur significant performance overhead. +::: + +## Samples + + diff --git a/versioned_docs/version-3.x/orm/plugins/index.md b/versioned_docs/version-3.x/orm/plugins/index.md index 8211aef1..e10da89d 100644 --- a/versioned_docs/version-3.x/orm/plugins/index.md +++ b/versioned_docs/version-3.x/orm/plugins/index.md @@ -3,4 +3,40 @@ sidebar_position: 1 description: ORM plugin introduction --- -# Introduction to Plugins +import ZenStackVsPrisma from '../../_components/ZenStackVsPrisma'; + +# Plugin Overview + + +ZenStack's plugin system aims to provide a more flexible extensibility solution than [Prisma Client Extensions](https://www.prisma.io/docs/orm/prisma-client/client-extensions), allowing you to tap into the ORM runtime at different levels. Some parts of the plugin design resemble client extensions, but overall it's not meant to be compatible. + + +As you go deeper using an ORM, you'll find the need to tap into its engine for different purposes. For example, you may want to: + +- Log the time cost of each query operation. +- Block certain CRUD operations. +- Execute code when an entity is created, updated, or deleted. +- Alter the SQL query before it's sent to the database. +- ... + +ZenStack ORM provides three ways for you to tap into its runtime: + +1. **Query API hooks** + + Query API hooks allow you to intercept ORM query operations (`create`, `findUnique`, etc.). You can execute arbitrary code before or after the query operation, or even block the operation altogether. See [Query API Hooks](./query-api-hooks.md) for details. + +2. **Entity mutation hooks** + + Entity mutation hooks allow you to execute code before or after an entity is created, updated, or deleted. This is very useful when you only care about entity changes instead of what triggered the changes. See [Entity Mutation Hooks](./entity-mutation-hooks.md) for details. + +3. **Kysely query hooks** + + Kysely query hooks give you the ultimate power to inspect and alter the SQL query (in AST form) before it's sent to the database. This is a very powerful low-level extensibility that should be used with care. See [Kysely Query Hooks](./kysely-query-hooks.md) for details. + +All three types of plugins are installed via the unified `$use` method on the ORM client. The `$use` method returns a new ORM client with the plugin applied, without modifying the original client. You can use the `$unuse` or `$unuseAll` methods to remove plugin(s) from a client. + +```ts +const db = new ZenStackClient({ ... }); +const withPlugin = $db.use({ ... }); +const noPlugin = withPlugin.$unuseAll(); +``` diff --git a/versioned_docs/version-3.x/orm/plugins/kysely-query-hooks.md b/versioned_docs/version-3.x/orm/plugins/kysely-query-hooks.md new file mode 100644 index 00000000..dbfc5d3d --- /dev/null +++ b/versioned_docs/version-3.x/orm/plugins/kysely-query-hooks.md @@ -0,0 +1,24 @@ +--- +sidebar_position: 3 +--- + +import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; + +# Kysely Query Hooks + +## Introduction + +Kysely query hooks are the lowest level of interceptor in the plugin system. Since ZenStack eventually delegates all database access to Kysely, these hooks allow you to inspect and alter all SQL queries before they are sent to the database, regardless of whether they originate from the ORM query API or the query builder API. + +This mechanism gives you great power to entirely control the ORM's behavior. One good example is the [access policy](../access-control/) - the access policy enforcement is entirely achieved via intercepting the Kysely queries. + +To create a Kysely query hook plugin, call the `$use` method with an object containing a `onKyselyQuery` callback. The callback is triggered before each Kysely query is executed. It receives a context object containing: + +- The Kysely instance +- The Kysely query node (SQL AST) +- The ORM client that triggered the query +- A "proceed query" function, which you can call to send the query to the database + +## Samples + + diff --git a/versioned_docs/version-3.x/orm/plugins/query-api-hooks.md b/versioned_docs/version-3.x/orm/plugins/query-api-hooks.md new file mode 100644 index 00000000..b453e1b7 --- /dev/null +++ b/versioned_docs/version-3.x/orm/plugins/query-api-hooks.md @@ -0,0 +1,30 @@ +--- +sidebar_position: 1 +--- + +import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; + +# Query API Hooks + +## Introduction + +Query API hooks allow you to intercept ORM queries, like `create`, `findUnique`, etc. You can execute arbitrary code before or after the query operation, modify query args, or even block the operation altogether. + +To create a query API hook plugin, call the `$use` method with an object containing the `onQuery` key. The `onQuery` object allows you to define hooks in a per-model and per-operation manner. You can also use the special `$allModels` and `$allOperations` keys to apply hooks to all models or operations, respectively. + +At the operation level, you provide a callback function that receives a context object containing: +- The model +- The operation +- The query args +- The ORM client that triggered the query +- A "proceed query" function, which you can call to continue executing the operation + +:::info +The `onQuery` hook's configuration structure is compatible with Prisma Client Extensions' [query extension](https://www.prisma.io/docs/orm/prisma-client/client-extensions/query). +::: + +As its name suggests, query API hooks are only triggered by ORM query calls, not by query builder API calls. + +## Samples + + From dda23fc852878e46aa005afbc8f28ee35b6bb7f9 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Thu, 14 Aug 2025 20:36:19 +0800 Subject: [PATCH 19/51] update plugins part --- .../version-3.x/orm/plugins/entity-mutation-hooks.md | 6 +++++- .../version-3.x/orm/plugins/kysely-query-hooks.md | 4 ++++ versioned_docs/version-3.x/orm/plugins/query-api-hooks.md | 7 +------ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/versioned_docs/version-3.x/orm/plugins/entity-mutation-hooks.md b/versioned_docs/version-3.x/orm/plugins/entity-mutation-hooks.md index 154845c2..d231060f 100644 --- a/versioned_docs/version-3.x/orm/plugins/entity-mutation-hooks.md +++ b/versioned_docs/version-3.x/orm/plugins/entity-mutation-hooks.md @@ -10,7 +10,7 @@ import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; Entity mutation hooks allow you to intercept entity mutation operations, i.e., "create", "update", and "delete". They are triggered regardless of whether the operations are performed through the ORM queries or the query builder API. -To create an entity mutation hook plugin, call the `$use` method with an object containing the following optional keys: +To create an entity mutation hook plugin, call the `$use` method with an `onEntityMutation` key containing an object with the following fields (all optional): - `beforeEntityMutation` A callback function that is called before the entity mutation operation. It receives a context object containing: @@ -38,6 +38,10 @@ To create an entity mutation hook plugin, call the `$use` method with an object If a mutation happens inside a transaction, the `afterEntityMutation` callback is called after the transaction is committed. +:::info +Update and delete triggered by cascading operations are not captured by the entity mutation hooks. +::: + :::warning Be very careful about opting in to load before and after mutation entities. Batch mutations can result in a large number of entities being loaded and incur significant performance overhead. ::: diff --git a/versioned_docs/version-3.x/orm/plugins/kysely-query-hooks.md b/versioned_docs/version-3.x/orm/plugins/kysely-query-hooks.md index dbfc5d3d..4d7bca47 100644 --- a/versioned_docs/version-3.x/orm/plugins/kysely-query-hooks.md +++ b/versioned_docs/version-3.x/orm/plugins/kysely-query-hooks.md @@ -21,4 +21,8 @@ To create a Kysely query hook plugin, call the `$use` method with an object cont ## Samples +:::info +Kysely's `QueryNode` objects are low-level and not easy to process. ZenStack will provide helpers to facilitate common tasks in the future. +::: + diff --git a/versioned_docs/version-3.x/orm/plugins/query-api-hooks.md b/versioned_docs/version-3.x/orm/plugins/query-api-hooks.md index b453e1b7..8ee7d456 100644 --- a/versioned_docs/version-3.x/orm/plugins/query-api-hooks.md +++ b/versioned_docs/version-3.x/orm/plugins/query-api-hooks.md @@ -10,19 +10,14 @@ import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; Query API hooks allow you to intercept ORM queries, like `create`, `findUnique`, etc. You can execute arbitrary code before or after the query operation, modify query args, or even block the operation altogether. -To create a query API hook plugin, call the `$use` method with an object containing the `onQuery` key. The `onQuery` object allows you to define hooks in a per-model and per-operation manner. You can also use the special `$allModels` and `$allOperations` keys to apply hooks to all models or operations, respectively. +To create a query API hook plugin, call the `$use` method with an object with the `onQuery` key providing a callback. The callback is invoked with an argument containing the following fields: -At the operation level, you provide a callback function that receives a context object containing: - The model - The operation - The query args - The ORM client that triggered the query - A "proceed query" function, which you can call to continue executing the operation -:::info -The `onQuery` hook's configuration structure is compatible with Prisma Client Extensions' [query extension](https://www.prisma.io/docs/orm/prisma-client/client-extensions/query). -::: - As its name suggests, query API hooks are only triggered by ORM query calls, not by query builder API calls. ## Samples From d7b5e4ef0be63c628e27be7707e7339a1e817ae9 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Thu, 14 Aug 2025 21:23:13 +0800 Subject: [PATCH 20/51] add logging --- versioned_docs/version-3.x/orm/logging.md | 38 +++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/versioned_docs/version-3.x/orm/logging.md b/versioned_docs/version-3.x/orm/logging.md index abb4c943..a6a4ad1d 100644 --- a/versioned_docs/version-3.x/orm/logging.md +++ b/versioned_docs/version-3.x/orm/logging.md @@ -4,3 +4,41 @@ description: Setup logging --- # Logging + +Logging can be enabled by passing a `log` option when creating a `ZenStackClient` instance. The log option can be a list of log levels, causing the client to log messages at those levels to the console: + +```ts +const db = new ZenStackClient(..., { + log: ['query', 'error'], +}); +``` + +Or it can be a logging function that receives a log object with the following type: + +```ts +// https://kysely.dev/docs/recipes/logging + +interface LogEvent { + // log level + level: 'query' | 'error'; + + // the query compiled by Kysely, including the SQL AST, raw SQL string, and parameters. + query: CompiledQuery; + + // time taken to execute the query + queryDurationMillis: number; + + // error information, only present if `level` is `'error'` + error: unknown; +} +``` + +```ts +const db = new ZenStackClient(..., { + log: (event) => { + console.log(`[${event.level}] ${event.queryDurationMillis}ms`); + }, +}); +``` + +The `log` option is passed through to the underlying Kysely instance. From e087eb8ee4571fde334700dbb66fe1613c81e5da Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Fri, 15 Aug 2025 08:34:50 +0800 Subject: [PATCH 21/51] add inferred types section --- .../version-3.x/orm/inferred-types.md | 20 +++++++++++++++++++ .../orm/plugins/query-api-hooks.md | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/versioned_docs/version-3.x/orm/inferred-types.md b/versioned_docs/version-3.x/orm/inferred-types.md index 74c292f7..4ac02b32 100644 --- a/versioned_docs/version-3.x/orm/inferred-types.md +++ b/versioned_docs/version-3.x/orm/inferred-types.md @@ -3,4 +3,24 @@ sidebar_position: 14 description: TypeScript types derived from the ZModel schema --- +import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; + # Schema-Inferred Types + +Most of the time, you don't need to explicitly type the input and output of the ORM methods, thanks to TypeScript's powerful inference capabilities. However, when you do have the need, you can rely on the following utilities to type things: + +- `zenstack/models` + + The `zen generate` command generates a `models` module that exports types for all models, types, and enums. The model types include all scalar fields (including computed ones). + +- `zenstack/input` + + The `zen generate` command generates an `input` module that exports types for input arguments of the ORM methods, such as `UserCreateArgs`, `PostUpsertArgs`, etc. You can use them to type intermediary variables that are later passed to the ORM methods. + +- `ModelResult` + + The `ModelResult` generic type from `@zenstackhq/runtime` allows you to infer the exact model type given field selection and relation inclusion information. + +## Samples + + diff --git a/versioned_docs/version-3.x/orm/plugins/query-api-hooks.md b/versioned_docs/version-3.x/orm/plugins/query-api-hooks.md index 8ee7d456..2ee43085 100644 --- a/versioned_docs/version-3.x/orm/plugins/query-api-hooks.md +++ b/versioned_docs/version-3.x/orm/plugins/query-api-hooks.md @@ -22,4 +22,4 @@ As its name suggests, query API hooks are only triggered by ORM query calls, not ## Samples - + From 617275e72c0e5212bb93e42dfe3b9355c677485a Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Fri, 15 Aug 2025 23:37:03 +0800 Subject: [PATCH 22/51] progress --- .../version-3.x/migration/_category_.yml | 4 -- versioned_docs/version-3.x/migration/index.md | 6 -- .../version-3.x/modeling/datasource.md | 4 -- versioned_docs/version-3.x/modeling/index.md | 2 +- versioned_docs/version-3.x/orm/api/create.md | 2 +- versioned_docs/version-3.x/orm/api/filter.md | 10 +-- versioned_docs/version-3.x/orm/api/find.md | 15 +++-- .../version-3.x/orm/computed-fields.md | 2 +- versioned_docs/version-3.x/orm/index.md | 8 +-- versioned_docs/version-3.x/orm/migration.md | 62 +++++++++++++++++++ .../version-3.x/reference/plugin-dev.md | 2 + versioned_docs/version-3.x/upgrade.md | 10 --- versioned_docs/version-3.x/utilities/zod.md | 2 + versioned_docs/version-3.x/welcome.md | 12 ++-- 14 files changed, 93 insertions(+), 48 deletions(-) delete mode 100644 versioned_docs/version-3.x/migration/_category_.yml delete mode 100644 versioned_docs/version-3.x/migration/index.md create mode 100644 versioned_docs/version-3.x/orm/migration.md delete mode 100644 versioned_docs/version-3.x/upgrade.md diff --git a/versioned_docs/version-3.x/migration/_category_.yml b/versioned_docs/version-3.x/migration/_category_.yml deleted file mode 100644 index 6cb70365..00000000 --- a/versioned_docs/version-3.x/migration/_category_.yml +++ /dev/null @@ -1,4 +0,0 @@ -position: 4 -label: Migration -collapsible: true -collapsed: true diff --git a/versioned_docs/version-3.x/migration/index.md b/versioned_docs/version-3.x/migration/index.md deleted file mode 100644 index 9fe870b2..00000000 --- a/versioned_docs/version-3.x/migration/index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -sidebar_position: 1 -description: ZenStack migration overview ---- - -# Overview diff --git a/versioned_docs/version-3.x/modeling/datasource.md b/versioned_docs/version-3.x/modeling/datasource.md index 6f308fff..8a69f2cc 100644 --- a/versioned_docs/version-3.x/modeling/datasource.md +++ b/versioned_docs/version-3.x/modeling/datasource.md @@ -11,10 +11,6 @@ import ZModelVsPSL from '../_components/ZModelVsPSL'; The `datasource` block provides information about the database your application uses. The ORM relies on it to determine the proper SQL dialect to use when generating queries. If you use [Migration](../migration/), it must also have a `url` field that specifies the database connection string, so that the migration engine knows how to connect to the database. The `env` function can be used to reference environment variables so you can keep sensitive information out of the code. -:::tip -You can use both single quote and double quote for string literals. -::: - Each ZModel schema must have exactly one `datasource` block. diff --git a/versioned_docs/version-3.x/modeling/index.md b/versioned_docs/version-3.x/modeling/index.md index 95211884..4ba2969d 100644 --- a/versioned_docs/version-3.x/modeling/index.md +++ b/versioned_docs/version-3.x/modeling/index.md @@ -12,7 +12,7 @@ ZenStack uses a schema language named **ZModel** to define data models and their If you're already familiar with PSL, you'll find yourself at home with ZModel. However, we'd still recommend that you skim through this section to learn about the important extensions we made to PSL. Please pay attention to callouts like the following one: -ZModel uses the explicit `import` syntax for composing multi-file schemas. +ZModel allows both single quote and double quote for string literals. Don't worry if you've never used Prisma before. This section will introduce all aspects of ZModel, so no prior knowledge is required. diff --git a/versioned_docs/version-3.x/orm/api/create.md b/versioned_docs/version-3.x/orm/api/create.md index 74c8f447..5135ed23 100644 --- a/versioned_docs/version-3.x/orm/api/create.md +++ b/versioned_docs/version-3.x/orm/api/create.md @@ -18,5 +18,5 @@ The `create` series of APIs are used to create new records in the database. It h ## Samples - + diff --git a/versioned_docs/version-3.x/orm/api/filter.md b/versioned_docs/version-3.x/orm/api/filter.md index 80321ccf..53ac20d7 100644 --- a/versioned_docs/version-3.x/orm/api/filter.md +++ b/versioned_docs/version-3.x/orm/api/filter.md @@ -21,13 +21,13 @@ You can filter on scalar fields with values or operators as supported by the fie A filter object can contain multiple field filters, and they are combined with `AND` semantic. You can also use the `AND`, `OR`, and `NOT` logical operators to combine filter objects to form a complex filter. - + ## Relation filters Filters can be defined on conditions over relations. For one-to-one relations, you can filter on their fields directly. For one-to-many relations, use the "some", "every", or "none" operators to build a condition over a list of records. - + ## List filters @@ -62,10 +62,6 @@ await db.post.findMany({ where: { topics: { hasEvery: ['webdev', 'typescript'] } } }); -await db.post.findMany({ - where: { topics: { hasNone: ['webdev', 'typescript'] } } -}); - await db.post.findMany({ where: { topics: { isEmpty: true } } }); @@ -87,4 +83,4 @@ ZenStack v3 is implemented on top of [Kysely](https://kysely.dev/), and it lever The `$expr` operator can be used together with other filter operators, so you can keep most of your filters simple and only reach to the query builder level for complicated components. - + diff --git a/versioned_docs/version-3.x/orm/api/find.md b/versioned_docs/version-3.x/orm/api/find.md index ce718521..738a5a93 100644 --- a/versioned_docs/version-3.x/orm/api/find.md +++ b/versioned_docs/version-3.x/orm/api/find.md @@ -32,7 +32,7 @@ The `find` series of APIs are used to query records from the database. It has th ## Basic usage - + ## Filtering @@ -42,13 +42,13 @@ The API provides a very flexible set of filtering options. We've put it into a [ Use the `sort` field to control the sort field, direction, and null field placement. Sorting is not supported for `findUnique` and `findUniqueOrThrow`. - + ## Pagination You can use two strategies for pagination: offset-based or cursor-based. Pagination is not supported for `findUnique` and `findUniqueOrThrow`. - + ## Field selection @@ -56,10 +56,13 @@ You can use the following fields to control what fields are returned in the resu - + ## Finding distinct rows -You can use the `distinct` field to find distinct rows based on specific fields. One row for each unique combination of the specified fields will be returned. The implementation uses SQL `DISTINCT ON` if it's supported by the dialect, otherwise falls back to in-memory deduplication. +You can use the `distinct` field to find distinct rows based on specific fields. One row for each unique combination of the specified fields will be returned. The implementation relies on SQL `DISTINCT ON`, so it's not available for SQLite provider. - +```ts +// returns one Post for each unique authorId +await db.post.findMany({ distinct: ['authorId'] }); +``` diff --git a/versioned_docs/version-3.x/orm/computed-fields.md b/versioned_docs/version-3.x/orm/computed-fields.md index 55222236..889cca12 100644 --- a/versioned_docs/version-3.x/orm/computed-fields.md +++ b/versioned_docs/version-3.x/orm/computed-fields.md @@ -47,4 +47,4 @@ const db = new ZenStackClient(schema, { ## Samples - + diff --git a/versioned_docs/version-3.x/orm/index.md b/versioned_docs/version-3.x/orm/index.md index 57da3251..3cd0ddd5 100644 --- a/versioned_docs/version-3.x/orm/index.md +++ b/versioned_docs/version-3.x/orm/index.md @@ -85,10 +85,10 @@ model Post extends Content { ``` ```ts title="main.ts" -const asset = await db.asset.findFirst(); -if (asset.type === 'Post') { - // asset's type is narrowed down to `Post` - console.log(asset.content); +const content = await db.content.findFirstOrThrow(); +if (content.type === 'Post') { + // content's type is narrowed down to `Post` + console.log(content.content); } else { // other asset type } diff --git a/versioned_docs/version-3.x/orm/migration.md b/versioned_docs/version-3.x/orm/migration.md new file mode 100644 index 00000000..67dc6cad --- /dev/null +++ b/versioned_docs/version-3.x/orm/migration.md @@ -0,0 +1,62 @@ +--- +sidebar_position: 15 +description: Schema migration introduction +--- + +# Database Schema Migration + +Database schema migration is a crucial aspect of application development. It helps you keep your database schema in sync with your data model, and ensures deployments are smooth and predictable. ZenStack provides migration tools that create migration scripts based on the ZModel schema and apply them to the database. + +## Introduction + +ZenStack migration is built on top of [Prisma Migrate](https://www.prisma.io/docs/concepts/components/prisma-migrate). The `zen` CLI provides a set of migration-related commands that are simple wrappers around Prisma CLI. When running these commands, the CLI automatically generates a Prisma schema from ZModel, and then executes the corresponding Prisma CLI. + +Basing on Prisma Migrate brings the following benefits: + +- **No reinventing the wheels**: Prisma Migrate is a mature and widely used migration tool, ensuring reliability and stability. + +- **Backward compatibility**: When migrating from Prisma to ZenStack, you can continue using your existing migration scripts without any changes. + +If you are already familiar with Prisma Migrate, you can continue using your current workflow with ZenStack, simply swapping `prisma` CLI with `zen`. If not, this section will guide you through the commands and common workflows, but it's strongly recommended to check [Prisma Migrate documentation](https://www.prisma.io/docs/orm/prisma-migrate/understanding-prisma-migrate/overview) for in-depth information too. + +## Commands + +Please refer to the [CLI Reference](../reference/cli.md) for the full list of commands and options. + +### db push + +The `zen db push` command is used to push your ZModel schema changes to the database without creating a migration file. This is useful for development and testing purposes. Never use it in production. + +### migrate dev + +The `zen migrate dev` command is used to create a new migration file based on your ZModel schema changes. It will also apply the migration to your database. The command is for development only and should never be used in production. + +### migrate deploy + +The `zen migrate deploy` command is used to apply all pending migrations to your production database. This is typically run in your deployment pipeline. + +### migrate reset + +The `zen migrate reset` command is used to reset your database to a clean state by dropping all tables and reapplying all migrations. This is useful for testing and development purposes. + +### migrate status + +The `zen migrate status` command is used to check the status of your migrations. It will show you which migrations have been applied and which are pending. + +### migrate resolve + +The `zen migrate resolve` command is used to mark a migration as applied or rolled back without changing the database schema. This is useful for situations where you need to manually intervene in the migration process. + +## Workflow + +### Typical development workflow + +1. Make changes to your ZModel schema. +2. Run `zen db push` to push the changes to your database without creating a migration file. +3. Test the changes locally. +4. Run `zen migrate dev` to create a migration file. You'll be promoted if a full reset is needed. +5. Carefully review the migration file, make changes as needed, and commit it to source control. + +### Typical deployment workflow + +The most common practice is to run `zen migrate deploy` as part of your production deployment pipeline, which simply applies all pending migrations to the database. diff --git a/versioned_docs/version-3.x/reference/plugin-dev.md b/versioned_docs/version-3.x/reference/plugin-dev.md index 5cd7ddef..6c007c6c 100644 --- a/versioned_docs/version-3.x/reference/plugin-dev.md +++ b/versioned_docs/version-3.x/reference/plugin-dev.md @@ -5,3 +5,5 @@ description: Plugin development guide --- # Plugin Development + +Coming soon 🚧 diff --git a/versioned_docs/version-3.x/upgrade.md b/versioned_docs/version-3.x/upgrade.md deleted file mode 100644 index 710d5964..00000000 --- a/versioned_docs/version-3.x/upgrade.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -description: How to upgrade to ZenStack v3 - -slug: /upgrade-v3 -sidebar_label: Upgrading to V3 -sidebar_position: 9 ---- - -# Upgrading to V3 - diff --git a/versioned_docs/version-3.x/utilities/zod.md b/versioned_docs/version-3.x/utilities/zod.md index 7f16ec55..28340f3a 100644 --- a/versioned_docs/version-3.x/utilities/zod.md +++ b/versioned_docs/version-3.x/utilities/zod.md @@ -4,3 +4,5 @@ description: Zod integration --- # Zod + +Coming soon 🚧 diff --git a/versioned_docs/version-3.x/welcome.md b/versioned_docs/version-3.x/welcome.md index 29665f23..cd8bb659 100644 --- a/versioned_docs/version-3.x/welcome.md +++ b/versioned_docs/version-3.x/welcome.md @@ -13,16 +13,20 @@ ZenStack is built with the belief that most applications should use the data mod Inside the package you'll find: -- #### Intuitive schema language +- **Intuitive schema language** + That helps you model data, relation, access control, and more, in one place. [πŸ”—](./modeling/) -- #### Powerful ORM +- **Powerful ORM** + With awesomely-typed API, built-in access control, and unmatched flexibility. [πŸ”—](./orm/) -- #### Query-as-a-Service +- **Query-as-a-Service** + That provides a full-fledged data API without the need to code it up. [πŸ”—](./service/) -- #### Utilities +- **Utilities** + For deriving artifacts like Zod schemas, frontend hooks, OpenAPI specs, etc., from the schema. [πŸ”—](./category/utilities) > *ZenStack originated as an extension to Prisma ORM. V3 is a complete rewrite that removed Prisma as a runtime dependency and replaced it with an implementation built from the scratch ("scratch" = [Kysely](https://kysely.dev/) πŸ˜†). On its surface, it continues to use a "Prisma-superset" schema language and a query API compatible with PrismaClient.* \ No newline at end of file From 6ff351085645e1204ec996887ee351a91fd5d71f Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Sun, 17 Aug 2025 16:41:59 +0800 Subject: [PATCH 23/51] progress --- src/components/StackBlitzGithubEmbed.tsx | 8 ++--- versioned_docs/version-3.x/modeling/plugin.md | 13 +++++++++ .../version-3.x/modeling/polymorphism.md | 2 +- .../version-3.x/orm/access-control/index.md | 2 +- versioned_docs/version-3.x/orm/cli.md | 8 +---- versioned_docs/version-3.x/orm/validation.md | 2 +- .../version-3.x/reference/plugin-dev.md | 3 +- .../reference/plugins/_category_.yml | 4 +-- .../version-3.x/reference/plugins/prisma.md | 23 +++++++++++++++ .../reference/plugins/typescript.md | 29 +++++++++++++++++++ versioned_docs/version-3.x/roadmap.md | 11 +++++++ .../version-3.x/service/_category_.yml | 2 +- versioned_docs/version-3.x/utilities/zod.md | 2 +- 13 files changed, 89 insertions(+), 20 deletions(-) create mode 100644 versioned_docs/version-3.x/reference/plugins/prisma.md create mode 100644 versioned_docs/version-3.x/reference/plugins/typescript.md create mode 100644 versioned_docs/version-3.x/roadmap.md diff --git a/src/components/StackBlitzGithubEmbed.tsx b/src/components/StackBlitzGithubEmbed.tsx index de68def6..052aff98 100644 --- a/src/components/StackBlitzGithubEmbed.tsx +++ b/src/components/StackBlitzGithubEmbed.tsx @@ -60,7 +60,10 @@ const StackBlitzGithubEmbed: React.FC = ({ return ( <> - + + + +
- - -
diff --git a/versioned_docs/version-3.x/modeling/plugin.md b/versioned_docs/version-3.x/modeling/plugin.md index 25af5443..ca8f9589 100644 --- a/versioned_docs/version-3.x/modeling/plugin.md +++ b/versioned_docs/version-3.x/modeling/plugin.md @@ -24,6 +24,19 @@ plugin myPlugin { } ``` +:::info +In fact, the `zen generate` command is entirely implemented with plugins. The ZModel -> TypeScript generation is supported by the built-in `@core/typescript` plugin, which can be explicitly declared if you wish: + +```zmodel +plugin typescript { + provider = '@core/typescript' + output = '../generated' +} +``` + +Please refer to the [Plugin References](../category/plugins) for the full list of built-in plugins. +::: + A plugin declaration involves three parts: 1. A unique name diff --git a/versioned_docs/version-3.x/modeling/polymorphism.md b/versioned_docs/version-3.x/modeling/polymorphism.md index 87006ebe..98d78b71 100644 --- a/versioned_docs/version-3.x/modeling/polymorphism.md +++ b/versioned_docs/version-3.x/modeling/polymorphism.md @@ -119,4 +119,4 @@ The ORM hides the delegate complexities and provides a simple polymorphic view t 1. Creating a concrete model record automatically creates the base model record with the same id and proper discriminator field. 2. Querying with the base model will return entities with concrete model fields. -We'll revisit the topic in details in the [ORM](../orm/) part. +We'll revisit the topic in details in the [ORM](../orm/polymorphism.md) part. diff --git a/versioned_docs/version-3.x/orm/access-control/index.md b/versioned_docs/version-3.x/orm/access-control/index.md index 94c9b191..0b584167 100644 --- a/versioned_docs/version-3.x/orm/access-control/index.md +++ b/versioned_docs/version-3.x/orm/access-control/index.md @@ -2,6 +2,6 @@ sidebar_position: 6 --- -# Access Control +# Access Control 🚧 Coming soon 🚧 \ No newline at end of file diff --git a/versioned_docs/version-3.x/orm/cli.md b/versioned_docs/version-3.x/orm/cli.md index d4f52ab2..c798b998 100644 --- a/versioned_docs/version-3.x/orm/cli.md +++ b/versioned_docs/version-3.x/orm/cli.md @@ -15,10 +15,4 @@ You can try running the `npx zen generate` command in the following playground a -The `generate` command outputs the following TypeScript files in the same folder of the schema file: - -- `schema.ts`: TypeScript representation of the ZModel schema, used by the ORM client to understand the database's structure and infer types. -- `models.ts`: Exports types for all models, types, and enums defined in the schema. -- `input.ts`: Export types that you can use to type the arguments passed to the ORM client methods, such as `findMany`, `create`, etc. - -Refer to the [CLI Reference](../reference/cli.md) for the full list of commands and options. \ No newline at end of file +The `generate` command generates several TypeScript files from the ZModel schema that support both development-time typing and runtime access to the schema. For more details of the generated code, please refer to the [@core/typescript plugin](../reference/plugins/typescript.md) documentation. diff --git a/versioned_docs/version-3.x/orm/validation.md b/versioned_docs/version-3.x/orm/validation.md index 1668a477..d505d5a9 100644 --- a/versioned_docs/version-3.x/orm/validation.md +++ b/versioned_docs/version-3.x/orm/validation.md @@ -3,6 +3,6 @@ sidebar_position: 9 description: Data validation in ZModel --- -# Data Validation +# Data Validation 🚧 Coming soon 🚧 diff --git a/versioned_docs/version-3.x/reference/plugin-dev.md b/versioned_docs/version-3.x/reference/plugin-dev.md index 6c007c6c..658cf50b 100644 --- a/versioned_docs/version-3.x/reference/plugin-dev.md +++ b/versioned_docs/version-3.x/reference/plugin-dev.md @@ -1,9 +1,8 @@ --- sidebar_position: 5 -sidebar_label: Plugin Development description: Plugin development guide --- -# Plugin Development +# Plugin Development 🚧 Coming soon 🚧 diff --git a/versioned_docs/version-3.x/reference/plugins/_category_.yml b/versioned_docs/version-3.x/reference/plugins/_category_.yml index 4a2a7dc0..d74396e4 100644 --- a/versioned_docs/version-3.x/reference/plugins/_category_.yml +++ b/versioned_docs/version-3.x/reference/plugins/_category_.yml @@ -1,7 +1,7 @@ -position: 6 +position: 4 label: Plugins collapsible: true collapsed: true link: type: generated-index - title: Plugins + title: Plugin Reference diff --git a/versioned_docs/version-3.x/reference/plugins/prisma.md b/versioned_docs/version-3.x/reference/plugins/prisma.md new file mode 100644 index 00000000..3975097d --- /dev/null +++ b/versioned_docs/version-3.x/reference/plugins/prisma.md @@ -0,0 +1,23 @@ +--- +sidebar_position: 2 +sidebar_label: "@core/prisma" +--- + +# @core/prisma + +The `@core/prisma` plugin generates a Prisma schema file from ZModel. + +Please note that ZenStack's ORM runtime doesn't depend on Prisma, so you don't need to use this plugin to use the ORM. However, you can use it to generate a Prisma schema and then run custom Prisma generators or other tools that consumes a Prisma schema. + +## Options + +- `output`: Specifies the path of the generated Prisma schema file. If a relative path is provided, it will be resolved relative to the ZModel schema. + +## Example + +```zmodel +plugin prisma { + provider = '@core/prisma' + output = '../prisma/schema.prisma' +} +``` diff --git a/versioned_docs/version-3.x/reference/plugins/typescript.md b/versioned_docs/version-3.x/reference/plugins/typescript.md new file mode 100644 index 00000000..94979282 --- /dev/null +++ b/versioned_docs/version-3.x/reference/plugins/typescript.md @@ -0,0 +1,29 @@ +--- +sidebar_position: 1 +sidebar_label: "@core/typescript" +--- + +# @core/typescript + +The `@core/typescript` plugin generates TypeScript code from ZModel. The generated code is used to access the schema at runtime, as well as type declarations at development time. + +## Options + +- `output`: Specifies the output directory for the generated TypeScript code. If a relative path is provided, it will be resolved relative to the ZModel schema. + +## Output + +The plugin generates the following TypeScript files: + +- `schema.ts`: TypeScript object representation of the ZModel schema. +- `models.ts`: Exports types for all models, types, and enums defined in the schema. +- `input.ts`: Exports types that you can use to type the arguments passed to the ORM query API, such as `findMany`, `create`, etc. + +## Example + +```zmodel +plugin ts { + provider = '@core/typescript' + output = '../generated' +} +``` diff --git a/versioned_docs/version-3.x/roadmap.md b/versioned_docs/version-3.x/roadmap.md new file mode 100644 index 00000000..ff2fb508 --- /dev/null +++ b/versioned_docs/version-3.x/roadmap.md @@ -0,0 +1,11 @@ +--- +sidebar_position: 11 +--- + +# Roadmap + +- [ ] Access Control +- [ ] Data Validation +- [ ] Zod integration +- [ ] Query-as-a-Service (automatic CRUD API) +- [ ] Json filter diff --git a/versioned_docs/version-3.x/service/_category_.yml b/versioned_docs/version-3.x/service/_category_.yml index 938fc11d..9f3e3b17 100644 --- a/versioned_docs/version-3.x/service/_category_.yml +++ b/versioned_docs/version-3.x/service/_category_.yml @@ -1,4 +1,4 @@ position: 5 -label: Query as a Service +label: Query as a Service 🚧 collapsible: true collapsed: true diff --git a/versioned_docs/version-3.x/utilities/zod.md b/versioned_docs/version-3.x/utilities/zod.md index 28340f3a..a35591cd 100644 --- a/versioned_docs/version-3.x/utilities/zod.md +++ b/versioned_docs/version-3.x/utilities/zod.md @@ -3,6 +3,6 @@ sidebar_position: 1 description: Zod integration --- -# Zod +# Zod 🚧 Coming soon 🚧 From 22de9b912cc0bdbceaee69d8f39f9f50efb9f01b Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Sun, 17 Aug 2025 21:36:48 +0800 Subject: [PATCH 24/51] prisma migration guide --- versioned_docs/version-3.x/migrate-prisma.md | 255 ++++++++++++++++++ .../version-3.x/reference/plugins/prisma.md | 1 + .../reference/plugins/typescript.md | 1 + versioned_docs/version-3.x/samples.md | 8 + 4 files changed, 265 insertions(+) diff --git a/versioned_docs/version-3.x/migrate-prisma.md b/versioned_docs/version-3.x/migrate-prisma.md index 4dcfc511..c5310bb6 100644 --- a/versioned_docs/version-3.x/migrate-prisma.md +++ b/versioned_docs/version-3.x/migrate-prisma.md @@ -3,4 +3,259 @@ description: How to migrate from a Prisma project to ZenStack v3 sidebar_position: 10 --- +import PackageInstall from './_components/PackageInstall'; +import TabItem from '@theme/TabItem'; +import Tabs from '@theme/Tabs'; + # Migrating From Prisma + +## Overview + +This guide will help you migrate an existing Prisma project to ZenStack v3. The process is made straightforward by the following design decisions: + +1. The ZModel schema language is a superset of Prisma Schema Language. +2. The ORM provides a Prisma-compatible API. +3. The migration engine is built on top of Prisma Migrate. + +In the following sections, we'll cover various aspects of the migration process where care needs to be taken. + +:::warning +ZenStack v3 currently only supports PostgreSQL and SQLite databases. +::: + +## Migration Steps + +### 1. Project dependencies + +ZenStack v3 doesn't depend on Prisma at runtime. Its CLI has a peer dependency to the `prisma` package for migration related commands. The most straightforward way is to follow these steps: + +- Remove `prisma` and `@prisma/client` from your project dependencies. +- Install ZenStack packages + + + +- Install database driver + + ZenStack doesn't bundle database drivers. Install the appropriate driver for your database: + + + + + + + + + + + + + + + +You don't need to explicitly install `prisma` package because the `@zenstackhq/cli` has a peer dependency on it. + +### 2. Migrate your schema + +If you have a single `schema.prisma` file, you can move and rename it to `zenstack/schema.zmodel`. No change should be necessary because every valid Prisma schema is also a valid ZModel schema. The only optional change you can consider to make is to remove the Prisma client generator block since it doesn't have any effect in ZenStack: + +```zmodel +generator client { + provider = "prisma-client-js" +} +``` + +If you use Prisma's [multi-schema feature](https://www.prisma.io/docs/orm/prisma-schema/overview/location#multi-file-prisma-schema), you'll need to explicitly use the `import` statement to merge related schema file into a whole graph. See [Multi-file Schema](./modeling/multi-file.md) for details. + +### 3. Update generation command + +In your `package.json` scripts, replace the `prisma generate` command with `zen generate`. + +```json +{ + "scripts": { + "generate": "zen generate" + } +} +``` + +### 4. Update database client instantiation + +Replace `new PrismaClient()` with `new ZenStackClient(schema, ...)` where `schema` is imported from the TypeScript code generated by the `zen generate` command. + + + + + +```ts title='db.ts' +import { ZenStackClient } from '@zenstackhq/runtime'; +import { schema } from '@/zenstack/schema'; +import { PostgresDialect } from 'kysely'; +import { Pool } from 'pg'; + +export const db = new ZenStackClient(schema, { + dialect: new PostgresDialect({ + pool: new Pool({ + connectionString: process.env.DATABASE_URL, + }), + }), +}); +``` + + + + +```ts title='db.ts' +import { ZenStackClient } from '@zenstackhq/runtime'; +import { SqliteDialect } from 'kysely'; +import SQLite from 'better-sqlite3'; +import { schema } from '@/zenstack/schema'; + +export const db = new ZenStackClient(schema, { + dialect: new SqliteDialect({ + database: new SQLite('./db.sqlite'), + }), +}); +``` + + + + +Since `ZenStackClient` has a PrismaClient-compatible API, you should not need to change your existing code that uses the database client. + +### 5. Update type references + +Prisma generates many TypeScript types that you may have used in your code, such as `User`, `UserCreateArgs`, etc. ZenStack replicates some of the most useful types in its generated code. + +For top-level model types like `User`, you can import from the `models.ts` file. For other detailed input types like `UserCreateArgs`, import them from the `input.ts` file. + +### 6. Update migration command + +In your `package.json` scripts, replace the Prisma `db` and `migrate` commands with ZenStack equivalents: + +```json +{ + "scripts": { + "db:push": "zen db push", + "migrate:dev": "zen migrate dev", + "migrate:deploy": "zen migrate deploy" + } +} +``` + +## Other Considerations + +Now let's check the areas less straightforward to migrate. + +### Prisma custom generators + +ZenStack has its own plugin system and doesn't support Prisma custom generators. However, you can continue running them with the following two steps: + +1. Use the [@core/prisma](./reference/plugins/prisma.md) plugin to generate a Prisma schema from ZModel. + + ```zmodel + plugin prisma { + provider = '@core/prisma' + output = './schema.prisma' + } + ``` + +2. Run a`prisma generate` command after `zen generate` with the prisma schema as input. + + ```json + { + "scripts": { + "generate": "zen generate && prisma generate --schema=zenstack/schema.prisma" + } + } + ``` + +### Prisma client extensions + +ZenStack has its own [runtime plugin mechanism](./orm/plugins/) and doesn't plan to be compatible with Prisma client extensions. However, there are easy migration paths for the two most popular types of Prisma client extensions. + +**1. Query extension** + +[Query extension](https://www.prisma.io/docs/orm/prisma-client/client-extensions/query) allows you to intercepts ORM query calls. + +Suppose you have an extension like: + +```ts +const extPrisma = prisma.$extends({ + query: { + user: { + async findMany({ model, operation, args, query }) { + // take incoming `where` and set `age` + args.where = { ...args.where, age: { gt: 18 } } + return query(args) + }, + }, + }, +}); +``` + +You can replace it with an equivalent ZenStack plugin: + +```ts +const extDb = db.$use({ + id: 'my-plugin', + onQuery: { + user: { + async findMany({ model, operation, args, proceed }) { + // take incoming `where` and set `age` + args.where = { ...args.where, age: { gt: 18 } } + return proceed(args) + }, + }, + }, +}); +``` + +You can also use the special `$allModels` and `$allOperations` keys to apply the plugin to all models and operations like when using Prisma client extensions. + +**2. Result extension** + +[Result extension](https://www.prisma.io/docs/orm/prisma-client/client-extensions/result) allows you to add custom fields to query results. ZenStack provides a mechanism that achieves the same goal but a lot more powerful. + +Suppose you have a result extension like: + +```ts +const extPrisma = prisma.$extends({ + result: { + user: { + fullName: { + // the dependencies + needs: { firstName: true, lastName: true }, + compute(user) { + // the computation logic + return `${user.firstName} ${user.lastName}` + }, + }, + }, + }, +}); +``` + +You can replace it with a ZenStack computed fields with changes in ZModel and database client instantiation. + +```zmodel title="zenstack/schema.zmodel" +model User { + ... + firstName String + lastName String + fullName String @computed +} +``` + +```ts +export const db = new ZenStackClient(schema, { + ..., + computedFields: { + User: { + // SQL: CONCAT(firstName, ' ', lastName) + fullName: (eb) => eb.fn('concat', ['firstName', eb.val(' '), 'lastName']) + }, + }, +}); +``` + +The biggest difference is ZenStack's computed fields are evaluated on the database side - much more efficient and flexible than client-side computation. Read more in the [Computed Fields](./orm/computed-fields.md) documentation. diff --git a/versioned_docs/version-3.x/reference/plugins/prisma.md b/versioned_docs/version-3.x/reference/plugins/prisma.md index 3975097d..2e40f1b6 100644 --- a/versioned_docs/version-3.x/reference/plugins/prisma.md +++ b/versioned_docs/version-3.x/reference/plugins/prisma.md @@ -1,6 +1,7 @@ --- sidebar_position: 2 sidebar_label: "@core/prisma" +description: Generating Prisma schema from ZModel --- # @core/prisma diff --git a/versioned_docs/version-3.x/reference/plugins/typescript.md b/versioned_docs/version-3.x/reference/plugins/typescript.md index 94979282..d14d5a98 100644 --- a/versioned_docs/version-3.x/reference/plugins/typescript.md +++ b/versioned_docs/version-3.x/reference/plugins/typescript.md @@ -1,6 +1,7 @@ --- sidebar_position: 1 sidebar_label: "@core/typescript" +description: Generating TypeScript code from ZModel --- # @core/typescript diff --git a/versioned_docs/version-3.x/samples.md b/versioned_docs/version-3.x/samples.md index 8701ccc0..2e2a6f1a 100644 --- a/versioned_docs/version-3.x/samples.md +++ b/versioned_docs/version-3.x/samples.md @@ -5,3 +5,11 @@ sidebar_label: Sample Projects # Sample Projects +You can find sample projects in the [samples](https://github.com/zenstackhq/zenstack-v3/tree/main/samples) folder of the GitHub repository. New samples will continue to be added. + +## Blog + +https://github.com/zenstackhq/zenstack-v3/tree/main/samples/blog + +A simple TypeScript application that demonstrates how to model a minimum blog app and how to use the ORM client to query the database. + From 2fd667e6a203908f4339cbf3fef500319a27e585 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Sun, 17 Aug 2025 21:46:32 +0800 Subject: [PATCH 25/51] update broken links --- versioned_docs/version-3.x/modeling/conclusion.md | 5 ++--- versioned_docs/version-3.x/modeling/datasource.md | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/versioned_docs/version-3.x/modeling/conclusion.md b/versioned_docs/version-3.x/modeling/conclusion.md index 4c5cc632..06890e4a 100644 --- a/versioned_docs/version-3.x/modeling/conclusion.md +++ b/versioned_docs/version-3.x/modeling/conclusion.md @@ -9,9 +9,8 @@ Congratulations! You have learned all the essentials of data model with ZenStack In the following parts, you'll learn how to put the schema into use and let it drive many aspects of your application, including: -- [Creating an ORM to query the database](../orm/) -- [Evolving database schema with migrations](../migration/) +- [Using ORM to query the database](../orm/) - [Exposing a data API with Query-as-a-Service](../service/) -- [Driving other useful utilities](../service/) +- [Deriving other useful utilities](../service/) Let's continue our journey with ZenStack! diff --git a/versioned_docs/version-3.x/modeling/datasource.md b/versioned_docs/version-3.x/modeling/datasource.md index 8a69f2cc..a6b84c52 100644 --- a/versioned_docs/version-3.x/modeling/datasource.md +++ b/versioned_docs/version-3.x/modeling/datasource.md @@ -9,7 +9,7 @@ import ZModelVsPSL from '../_components/ZModelVsPSL'; # Data Source -The `datasource` block provides information about the database your application uses. The ORM relies on it to determine the proper SQL dialect to use when generating queries. If you use [Migration](../migration/), it must also have a `url` field that specifies the database connection string, so that the migration engine knows how to connect to the database. The `env` function can be used to reference environment variables so you can keep sensitive information out of the code. +The `datasource` block provides information about the database your application uses. The ORM relies on it to determine the proper SQL dialect to use when generating queries. If you use [Migration](../orm/migration.md), it must also have a `url` field that specifies the database connection string, so that the migration engine knows how to connect to the database. The `env` function can be used to reference environment variables so you can keep sensitive information out of the code. Each ZModel schema must have exactly one `datasource` block. From b9e61934ef657b4ad9b0eec9e499bf6557013c9d Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Sun, 17 Aug 2025 21:47:26 +0800 Subject: [PATCH 26/51] update --- versioned_docs/version-3.x/modeling/relation.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/versioned_docs/version-3.x/modeling/relation.md b/versioned_docs/version-3.x/modeling/relation.md index 6a74b365..5c7004d0 100644 --- a/versioned_docs/version-3.x/modeling/relation.md +++ b/versioned_docs/version-3.x/modeling/relation.md @@ -3,11 +3,11 @@ sidebar_position: 5 description: Relations in ZModel --- -# Relations +# Relation Relation is a fundamental concept in relational databases. It connect models into a graph, and allows you to query interconnected data efficiently. In ZModel, relations are modeled using the `@relation` attribute. For most cases it involves one side of the relation defining a foreign key field that references the primary key of the other side. By convention, we call the model that defines the foreign key the "owner" side. -## One-to-one relations +## One-to-one relation A typical one-to-one relation looks like this: @@ -64,7 +64,7 @@ model Profile { } ``` -## One-to-many relations +## One-to-many relation A typical one-to-many relation looks like this: @@ -83,7 +83,7 @@ model Post { It's modeled pretty much the same way as one-to-one relations, except that the "non-owner" side (here `User.posts`) is a of list of the other side's model type. -## Many-to-many relations +## Many-to-many relation Many-to-many relations are modeled in the database through a join table - which forms a many-to-one relation with each of the two sides. @@ -148,7 +148,7 @@ model UserPost { Since the join table is explicitly defined, when using the ORM, you'll need to involve it in your queries with an extra level of nesting. -## Self relations +## Self relation Self relations are cases where a model has a relation to itself. They can be one-to-one, one-to-many, or many-to-many. From 1a2a102d0d301ae8cfc9c9f2340e1b5f5f6fb90d Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Mon, 18 Aug 2025 12:03:27 +0800 Subject: [PATCH 27/51] copywriting --- .../version-3.x/modeling/attribute.md | 6 ++--- .../version-3.x/modeling/datasource.md | 4 +-- versioned_docs/version-3.x/modeling/index.md | 12 ++++----- versioned_docs/version-3.x/modeling/model.md | 26 +++++++------------ .../version-3.x/modeling/relation.md | 14 +++++----- versioned_docs/version-3.x/roadmap.md | 1 + versioned_docs/version-3.x/welcome.md | 6 ++--- 7 files changed, 31 insertions(+), 38 deletions(-) diff --git a/versioned_docs/version-3.x/modeling/attribute.md b/versioned_docs/version-3.x/modeling/attribute.md index 7994aff6..df89825e 100644 --- a/versioned_docs/version-3.x/modeling/attribute.md +++ b/versioned_docs/version-3.x/modeling/attribute.md @@ -7,7 +7,7 @@ import ZModelVsPSL from '../_components/ZModelVsPSL'; # Attribute -Attributes allow you to attach metadata to models and fields. As you've seen in the previous sections, they are used for many purposes, like adding unique constraints, mapping names, etc. Attributes are also indispensable for modeling relations between models. +Attributes allow you to attach metadata to models and fields. As you've seen in the previous sections, they are used for many purposes, such as adding unique constraints and mapping names. Attributes are also indispensable for modeling relations between models. ## Naming conventions @@ -28,9 +28,9 @@ model User { Prisma schema doesn't allow users to define custom attributes, while ZModel allows it and uses it as a key mechanism for extensibility. -ZModel comes with a rich set of attributes that you can use directly. See [ZModel Language Reference](../reference/zmodel-language.md) for a complete list. You can also define your own custom attributes for specific purposes. Attributes are defined with a list of typed parameters. Parameters can named (default) or positional. Positional parameters can be passed with or without an explicit name. Parameters can also be optional. +ZModel comes with a rich set of attributes that you can use directly. See [ZModel Language Reference](../reference/zmodel-language.md) for a complete list. You can also define your own custom attributes for specific purposes. Attributes are defined with a list of typed parameters. Parameters can be named (default) or positional. Positional parameters can be passed with or without an explicit name. Parameters can also be optional. -Here's an example for how the `@unique` attribute is defined: +Here's an example of how the `@unique` attribute is defined: ```zmodel attribute @unique(map: String?, length: Int?, sort: SortOrder?) diff --git a/versioned_docs/version-3.x/modeling/datasource.md b/versioned_docs/version-3.x/modeling/datasource.md index a6b84c52..2ac7a052 100644 --- a/versioned_docs/version-3.x/modeling/datasource.md +++ b/versioned_docs/version-3.x/modeling/datasource.md @@ -35,8 +35,8 @@ datasource db { -Currently only PostgreSQL and SQLite are supported. MySql will be supported in a future release. There's no plan for other relational database types or NoSQL databases. +Currently, only PostgreSQL and SQLite are supported. MySQL will be supported in a future release. There's no plan for other relational database types or NoSQL databases. -ZenStack's ORM runtime doesn't rely on the `url` information to connect to the database. Instead, you provide the information when constructing an ORM client. More on this in the [ORM](../orm/) section. +ZenStack's ORM runtime doesn't rely on the `url` information to connect to the database. Instead, you provide the information when constructing an ORM client β€” more on this in the [ORM](../orm/) section. diff --git a/versioned_docs/version-3.x/modeling/index.md b/versioned_docs/version-3.x/modeling/index.md index 4ba2969d..2f7d5cf7 100644 --- a/versioned_docs/version-3.x/modeling/index.md +++ b/versioned_docs/version-3.x/modeling/index.md @@ -7,17 +7,17 @@ import ZModelVsPSL from '../_components/ZModelVsPSL'; # Data Modeling Overview -ZenStack uses a schema language named **ZModel** to define data models and their related aspects. We know that designing a good schema language is difficult, and we know it's even more difficult to convince people to learn a new one. So we made the decision to design ZModel as a superset of the [Prisma Schema Language (PSL)](https://www.prisma.io/docs/orm/prisma-schema), which is one of the best data modeling language out there. +ZenStack uses a schema language named **ZModel** to define data models and their related aspects. We know that designing a good schema language is difficult, and we know it's even more challenging to convince people to learn a new one. We therefore decided to design ZModel as a superset of the [Prisma Schema Language (PSL)](https://www.prisma.io/docs/orm/prisma-schema), one of the best data modeling languages available. -If you're already familiar with PSL, you'll find yourself at home with ZModel. However, we'd still recommend that you skim through this section to learn about the important extensions we made to PSL. Please pay attention to callouts like the following one: +If you're already familiar with PSL, you'll find yourself at home with ZModel. However, we recommend that you skim through this section to learn about the essential extensions we made to PSL. Please pay attention to callouts like the following one: -ZModel allows both single quote and double quote for string literals. +ZModel allows both single quotes and double quotes for string literals. Don't worry if you've never used Prisma before. This section will introduce all aspects of ZModel, so no prior knowledge is required. -A very simple ZModel schema looks like this: +A simplest ZModel schema looks like this: ```zmodel title='zenstack/schema.zmodel' datasource db { @@ -44,9 +44,9 @@ model Post { ``` -Prisma has the concept of "generator" which provides a pluggable mechanism to generate artifacts from PSL. Specifically, you need to define a "prisma-client-js" (or "prisma-client") generator to get the ORM client. +Prisma has the concept of "generator", which provides a pluggable mechanism to generate artifacts from PSL. Specifically, you need to define a "prisma-client-js" (or "prisma-client") generator to get the ORM client. -ZenStack CLI always generates a TypeScript schema without needing any configuration. Also, it replaced PSL's "generator" with a more generalized "plugin" construct that allows you to extend the system both at the schema level and the runtime level. Read more in the [Plugin](./plugin) section. +ZenStack CLI generates a TypeScript schema without needing any configuration. Also, it replaced PSL's "generator" with a more generalized "plugin" construct that allows you to extend the system both at the schema level and the runtime level. Read more in the [Plugin](./plugin) section. Let's dissect it piece by piece. diff --git a/versioned_docs/version-3.x/modeling/model.md b/versioned_docs/version-3.x/modeling/model.md index 1af5b1a3..0442bf5b 100644 --- a/versioned_docs/version-3.x/modeling/model.md +++ b/versioned_docs/version-3.x/modeling/model.md @@ -5,7 +5,7 @@ description: Models in ZModel # Model -The `model` construct is the core of ZModel. It defines the structure of your data and their relations. A model represents a domain entity, and is mapped to a database table. +The `model` construct is the core of ZModel. It defines the structure of your data and relations. A model represents a domain entity and is mapped to a database table. ## Defining models @@ -30,7 +30,7 @@ model User { } ``` -If your model needs a composite id, you can use the `@@id` model-level attribute to specify it: +If your model needs a composite ID, you can use the `@@id` model-level attribute to specify it: ```zmodel model City { @@ -73,7 +73,7 @@ Each model field must at least have a name and a type. A field can be typed in o - Bytes - Unsupported - The `Unsupported` type is for defining fields of types not supported by the ORM, however letting the migration engine know how to create the field in the database. + The `Unsupported` type is for defining fields of types not supported by the ORM; however, it lets the migration engine know how to create the field in the database. ```zmodel // from Prisma docs @@ -104,6 +104,7 @@ Each model field must at least have a name and a type. A field can be typed in o 3. Model It'll then form a relation. We'll cover that topic [later](./relation). + ```zmodel model Post { id Int @id @@ -114,7 +115,7 @@ Each model field must at least have a name and a type. A field can be typed in o ``` 4. Custom type - ZenStack allows you to define custom types in the schema and use that to type Json fields. This will be covered in more details in the [Custom Types](./custom-type) section. + ZenStack allows you to define custom types in the schema and use them to type JSON fields. This will be covered in more detail in the [Custom Types](./custom-type) section. ```zmodel type Address { @@ -131,7 +132,7 @@ Each model field must at least have a name and a type. A field can be typed in o } ``` -A field can be set optional by adding the `?` suffix to its type, or list by adding the `[]` suffix. However, a field cannot be both optional and a list at the same time. +A field can be set as optional by adding the `?` suffix to its type, or list by adding the `[]` suffix. However, a field cannot be both optional and a list at the same time. ```zmodel model User { @@ -163,7 +164,7 @@ model User { ## Native type mapping -Besides giving field a type, you can also specify the native database type to use with the `@db.` series of attributes. +Besides giving a field a type, you can also specify the native database type to use with the `@db.` series of attributes. ```zmodel model User { @@ -173,18 +174,9 @@ model User { } ``` -These attributes control what data type is used when the migration engine maps the schema to DDL. You can find a full list of native type attributes in the [ZModel Language Reference](../reference/zmodel-language). +These attributes control what data type is used when the [migration engine](../orm/migration.md) maps the schema to DDL. You can find a complete list of native type attributes in the [ZModel Language Reference](../reference/zmodel-language). ## Name mapping -Quite often you want to use a different naming scheme for your models and fields than the database. You can achieve that with the `@map` attribute. The ORM respects the mapping when generation queries, and the migration engine uses it to generate the DDL. +Quite often, you want to use a different naming scheme for your models and fields than the database. You can achieve that with the `@map` attribute. The ORM respects the mapping when generating queries, and the migration engine uses it to generate the DDL. -```zmodel -model User { - // highlight-next-line - id Int @id - name String @map("full_name") - - @@map("users") -} -``` diff --git a/versioned_docs/version-3.x/modeling/relation.md b/versioned_docs/version-3.x/modeling/relation.md index 5c7004d0..d0b023b9 100644 --- a/versioned_docs/version-3.x/modeling/relation.md +++ b/versioned_docs/version-3.x/modeling/relation.md @@ -5,7 +5,7 @@ description: Relations in ZModel # Relation -Relation is a fundamental concept in relational databases. It connect models into a graph, and allows you to query interconnected data efficiently. In ZModel, relations are modeled using the `@relation` attribute. For most cases it involves one side of the relation defining a foreign key field that references the primary key of the other side. By convention, we call the model that defines the foreign key the "owner" side. +Relation is a fundamental concept in relational databases. It lets you connect models into a graph, and allows you to query interconnected data efficiently. In ZModel, relations are modeled using the `@relation` attribute. For most cases, it involves one side of the relation defining a foreign key field that references the primary key of the other side. By convention, we call the model that holds the foreign key the "owner" side. ## One-to-one relation @@ -24,7 +24,7 @@ model Profile { } ``` -The `Profile` model holds the foreign key `userId` and is the owner of the relation. The pk-fk association is established by the `@relation` attribute, where the `fields` parameters specifies the foreign key field(s) and the `references` parameter specifies the primary key field(s) of the other side. +The `Profile` model holds the foreign key `userId` and is the owner of the relation. The pk-fk association is established by the `@relation` attribute, where the `fields` parameter specifies the foreign key field(s) and the `references` parameter specifies the primary key field(s) of the other side. In one-to-one relations, the "non-owner" side must declare the relation field as optional (here `User.profile`), because there's no way to guarantee a `User` row always has a corresponding `Profile` row at the database level. The owner side can be either optional or required. @@ -81,17 +81,17 @@ model Post { } ``` -It's modeled pretty much the same way as one-to-one relations, except that the "non-owner" side (here `User.posts`) is a of list of the other side's model type. +It's modeled pretty much the same way as one-to-one relations, except that the "non-owner" side (here `User.posts`) is a list of the other side's model type. ## Many-to-many relation -Many-to-many relations are modeled in the database through a join table - which forms a many-to-one relation with each of the two sides. +Many-to-many relations are modeled in the database through a join table, which forms a many-to-one relation with each of the two sides. In ZModel, there are two ways to model many-to-many relations: implicitly or explicitly. ### Implicit many-to-many -An implicit many-to-many relation simply defines both sides of the relation as lists of the other side's model type, without defining a join table explicitly. +An implicit many-to-many relation simply defines both sides of the relation as lists of the other side's model type, without modeling a join table explicitly. ```zmodel model User { @@ -150,7 +150,7 @@ Since the join table is explicitly defined, when using the ORM, you'll need to i ## Self relation -Self relations are cases where a model has a relation to itself. They can be one-to-one, one-to-many, or many-to-many. +Self-relations are cases where a model has a relation to itself. They can be one-to-one, one-to-many, or many-to-many. ### One-to-one @@ -189,7 +189,7 @@ Quick notes: ### Many-to-many -Defining an implicit many-to-many self relation is very straightforward. +Defining an implicit many-to-many self-relation is very straightforward. ```zmodel model Employee { diff --git a/versioned_docs/version-3.x/roadmap.md b/versioned_docs/version-3.x/roadmap.md index ff2fb508..0e9555f0 100644 --- a/versioned_docs/version-3.x/roadmap.md +++ b/versioned_docs/version-3.x/roadmap.md @@ -7,5 +7,6 @@ sidebar_position: 11 - [ ] Access Control - [ ] Data Validation - [ ] Zod integration +- [ ] Performance benchmark - [ ] Query-as-a-Service (automatic CRUD API) - [ ] Json filter diff --git a/versioned_docs/version-3.x/welcome.md b/versioned_docs/version-3.x/welcome.md index cd8bb659..fa3bd385 100644 --- a/versioned_docs/version-3.x/welcome.md +++ b/versioned_docs/version-3.x/welcome.md @@ -9,13 +9,13 @@ sidebar_position: 1 Welcome to ZenStack - the modern data layer for your TypeScript application! -ZenStack is built with the belief that most applications should use the data model as its center pillar. If that model is well-designed, it can serve as the single source of truth throughout the app's lifecycle, and be used to derive many other aspects of the app. The result is a smaller, more cohesive code base that scales well as your team grows while maintaining a high level of developer experience. +ZenStack is built with the belief that most applications should use the data model as their center pillar. If that model is well-designed, it can serve as the single source of truth throughout the app's lifecycle and be used to derive many other aspects of the app. The result is a smaller, more cohesive code base that scales well as your team grows while maintaining a high level of developer experience. Inside the package you'll find: - **Intuitive schema language** - That helps you model data, relation, access control, and more, in one place. [πŸ”—](./modeling/) + That helps you model data, relations, access control, and more, in one place. [πŸ”—](./modeling/) - **Powerful ORM** @@ -29,4 +29,4 @@ Inside the package you'll find: For deriving artifacts like Zod schemas, frontend hooks, OpenAPI specs, etc., from the schema. [πŸ”—](./category/utilities) -> *ZenStack originated as an extension to Prisma ORM. V3 is a complete rewrite that removed Prisma as a runtime dependency and replaced it with an implementation built from the scratch ("scratch" = [Kysely](https://kysely.dev/) πŸ˜†). On its surface, it continues to use a "Prisma-superset" schema language and a query API compatible with PrismaClient.* \ No newline at end of file +ZenStack originated as an extension to Prisma ORM. V3 is a complete rewrite that removed Prisma as a runtime dependency and replaced it with an implementation built from scratch ("scratch" = [Kysely](https://kysely.dev/) πŸ˜†). On its surface, it continues to use a "Prisma-superset" schema language and a query API compatible with PrismaClient. [This blog post](https://zenstack.dev/blog/next-chapter-1) contains more background about the thoughts behind the v3 refactor. \ No newline at end of file From 847a11e24e8e2fbd2fc0023f10a61785e7458fda Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Tue, 19 Aug 2025 12:52:27 +0800 Subject: [PATCH 28/51] zmodel language reference --- versioned_docs/version-3.x/migrate-prisma.md | 18 +- .../version-3.x/modeling/custom-type.md | 4 +- versioned_docs/version-3.x/modeling/mixin.md | 15 +- .../version-3.x/modeling/relation.md | 67 ++- .../{strong-typed-json.md => typed-json.md} | 6 +- .../version-3.x/orm/inferred-types.md | 2 +- versioned_docs/version-3.x/orm/logging.md | 2 +- versioned_docs/version-3.x/orm/migration.md | 18 +- .../version-3.x/orm/plugins/_category_.yml | 2 +- .../version-3.x/orm/plugins/index.md | 8 +- .../orm/plugins/kysely-query-hooks.md | 4 +- versioned_docs/version-3.x/orm/typed-json.md | 25 + .../version-3.x/reference/zmodel-language.md | 8 - .../reference/zmodel/_category_.yml | 6 + .../version-3.x/reference/zmodel/attribute.md | 539 ++++++++++++++++++ .../reference/zmodel/data-field.md | 77 +++ .../reference/zmodel/datasource.md | 49 ++ .../version-3.x/reference/zmodel/enum.md | 32 ++ .../version-3.x/reference/zmodel/function.md | 148 +++++ .../version-3.x/reference/zmodel/import.md | 30 + .../version-3.x/reference/zmodel/model.md | 56 ++ .../version-3.x/reference/zmodel/plugin.md | 37 ++ .../version-3.x/reference/zmodel/type.md | 52 ++ 23 files changed, 1162 insertions(+), 43 deletions(-) rename versioned_docs/version-3.x/modeling/{strong-typed-json.md => typed-json.md} (64%) create mode 100644 versioned_docs/version-3.x/orm/typed-json.md delete mode 100644 versioned_docs/version-3.x/reference/zmodel-language.md create mode 100644 versioned_docs/version-3.x/reference/zmodel/_category_.yml create mode 100644 versioned_docs/version-3.x/reference/zmodel/attribute.md create mode 100644 versioned_docs/version-3.x/reference/zmodel/data-field.md create mode 100644 versioned_docs/version-3.x/reference/zmodel/datasource.md create mode 100644 versioned_docs/version-3.x/reference/zmodel/enum.md create mode 100644 versioned_docs/version-3.x/reference/zmodel/function.md create mode 100644 versioned_docs/version-3.x/reference/zmodel/import.md create mode 100644 versioned_docs/version-3.x/reference/zmodel/model.md create mode 100644 versioned_docs/version-3.x/reference/zmodel/plugin.md create mode 100644 versioned_docs/version-3.x/reference/zmodel/type.md diff --git a/versioned_docs/version-3.x/migrate-prisma.md b/versioned_docs/version-3.x/migrate-prisma.md index c5310bb6..3b3bd047 100644 --- a/versioned_docs/version-3.x/migrate-prisma.md +++ b/versioned_docs/version-3.x/migrate-prisma.md @@ -27,14 +27,14 @@ ZenStack v3 currently only supports PostgreSQL and SQLite databases. ### 1. Project dependencies -ZenStack v3 doesn't depend on Prisma at runtime. Its CLI has a peer dependency to the `prisma` package for migration related commands. The most straightforward way is to follow these steps: +ZenStack v3 doesn't depend on Prisma at runtime. Its CLI has a peer dependency on the `prisma` package for migration related commands. The most straightforward way is to follow these steps: - Remove `prisma` and `@prisma/client` from your project dependencies. - Install ZenStack packages -- Install database driver +- Install a database driver ZenStack doesn't bundle database drivers. Install the appropriate driver for your database: @@ -56,7 +56,7 @@ You don't need to explicitly install `prisma` package because the `@zenstackhq/c ### 2. Migrate your schema -If you have a single `schema.prisma` file, you can move and rename it to `zenstack/schema.zmodel`. No change should be necessary because every valid Prisma schema is also a valid ZModel schema. The only optional change you can consider to make is to remove the Prisma client generator block since it doesn't have any effect in ZenStack: +If you have a single `schema.prisma` file, you can move and rename it to `zenstack/schema.zmodel`. No change should be necessary because every valid Prisma schema is also a valid ZModel schema. The only optional change you can consider making is to remove the Prisma client generator block since it doesn't have any effect in ZenStack: ```zmodel generator client { @@ -64,7 +64,7 @@ generator client { } ``` -If you use Prisma's [multi-schema feature](https://www.prisma.io/docs/orm/prisma-schema/overview/location#multi-file-prisma-schema), you'll need to explicitly use the `import` statement to merge related schema file into a whole graph. See [Multi-file Schema](./modeling/multi-file.md) for details. +If you use Prisma's [multi-schema feature](https://www.prisma.io/docs/orm/prisma-schema/overview/location#multi-file-prisma-schema), you'll need to explicitly use the `import` statement to merge related schema files into a whole graph. See [Multi-file Schema](./modeling/multi-file.md) for details. ### 3. Update generation command @@ -144,11 +144,11 @@ In your `package.json` scripts, replace the Prisma `db` and `migrate` commands w ## Other Considerations -Now let's check the areas less straightforward to migrate. +Now, let's check the areas that are less straightforward to migrate. ### Prisma custom generators -ZenStack has its own plugin system and doesn't support Prisma custom generators. However, you can continue running them with the following two steps: +ZenStack has its own CLI plugin system and doesn't support Prisma custom generators. However, you can continue running them with the following two steps: 1. Use the [@core/prisma](./reference/plugins/prisma.md) plugin to generate a Prisma schema from ZModel. @@ -210,7 +210,7 @@ const extDb = db.$use({ }); ``` -You can also use the special `$allModels` and `$allOperations` keys to apply the plugin to all models and operations like when using Prisma client extensions. +You can also use the special `$allModels` and `$allOperations` keys to apply the plugin to all models and operations, like when using Prisma client extensions. **2. Result extension** @@ -235,7 +235,7 @@ const extPrisma = prisma.$extends({ }); ``` -You can replace it with a ZenStack computed fields with changes in ZModel and database client instantiation. +You can replace it with a ZenStack computed field, which involves changes in ZModel and database client instantiation. ```zmodel title="zenstack/schema.zmodel" model User { @@ -258,4 +258,4 @@ export const db = new ZenStackClient(schema, { }); ``` -The biggest difference is ZenStack's computed fields are evaluated on the database side - much more efficient and flexible than client-side computation. Read more in the [Computed Fields](./orm/computed-fields.md) documentation. +The biggest difference is ZenStack's computed fields are evaluated on the database side, which much more efficient and flexible than client-side computation. Read more in the [Computed Fields](./orm/computed-fields.md) documentation. diff --git a/versioned_docs/version-3.x/modeling/custom-type.md b/versioned_docs/version-3.x/modeling/custom-type.md index 46f966ea..b7a36c9b 100644 --- a/versioned_docs/version-3.x/modeling/custom-type.md +++ b/versioned_docs/version-3.x/modeling/custom-type.md @@ -26,8 +26,6 @@ type Address { Custom types are defined exactly like models, with the exception that they cannot contain fields that are relations to other models. They can, however, contain fields that are other custom types. -There are two ways to use custom types: - ```zmodel type Address { street String @@ -42,5 +40,7 @@ type UserProfile { } ``` +There are two ways to use custom types: + - [Mixin](./mixin.md) - [Strongly typed JSON fields](./strong-typed-json.md) diff --git a/versioned_docs/version-3.x/modeling/mixin.md b/versioned_docs/version-3.x/modeling/mixin.md index c08b2b95..19916a1b 100644 --- a/versioned_docs/version-3.x/modeling/mixin.md +++ b/versioned_docs/version-3.x/modeling/mixin.md @@ -8,14 +8,14 @@ import ZModelVsPSL from '../_components/ZModelVsPSL'; # Mixin -Mixin is a ZModel concept and don't exist in PSL. +Mixin is a ZModel concept and doesn't exist in PSL. :::info Mixin was previously known as "abstract inheritance" in ZenStack v2. It's renamed and changed to use the `with` keyword to distinguish from polymorphic model inheritance. ::: -Very often you'll find many of your models share quite a few common fields. It's tedious and error-prone to repeat them. As a rescue, you can put those fields into custom types, and "mix-in" them into your models. +Very often you'll find many of your models share quite a few common fields. It's tedious and error-prone to repeat them. As a rescue, you can put those fields into custom types and "mix-in" them into your models. ***Before:*** @@ -26,6 +26,13 @@ model User { updatedAt DateTime @updatedAt email String @unique } + +model Post { + id String @id + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + title String +} ``` ***After:*** @@ -40,6 +47,10 @@ type BaseFieldsMixin { model User with BaseFieldsMixin { email String @unique } + +model Post with BaseFieldsMixin { + title String +} ``` A model can use multiple mixins as long as their field names don't conflict. diff --git a/versioned_docs/version-3.x/modeling/relation.md b/versioned_docs/version-3.x/modeling/relation.md index d0b023b9..030135a3 100644 --- a/versioned_docs/version-3.x/modeling/relation.md +++ b/versioned_docs/version-3.x/modeling/relation.md @@ -216,4 +216,69 @@ model Mentorship { @@id([mentorId, menteeId]) } -``` \ No newline at end of file +``` + +## Referential Actions + +When defining a relation, you can use referential action to control what happens when one side of a relation is updated or deleted by setting the `onDelete` and `onUpdate` parameters in the `@relation` attribute. + +```zmodel +attribute @relation( + _ name: String?, + fields: FieldReference[]?, + references: FieldReference[]?, + onDelete: ReferentialAction?, + onUpdate: ReferentialAction?, + map: String?) +``` + +The `ReferentialAction` enum is defined as: + +```zmodel +enum ReferentialAction { + Cascade + Restrict + NoAction + SetNull + SetDefault +} +``` + +- `Cascade` + + - **onDelete**: deleting a referenced record will trigger the deletion of referencing record. + + - **onUpdate**: updates the relation scalar fields if the referenced scalar fields of the dependent record are updated. + +- `Restrict` + + - **onDelete**: prevents the deletion if any referencing records exist. + - **onUpdate**: prevents the identifier of a referenced record from being changed. + +- `NoAction` + + Similar to 'Restrict', the difference between the two is dependent on the database being used. + +- `SetNull` + + - **onDelete**: the scalar field of the referencing object will be set to NULL. + - **onUpdate**: when updating the identifier of a referenced object, the scalar fields of the referencing objects will be set to NULL. + +- `SetDefault` + - **onDelete**: the scalar field of the referencing object will be set to the fields default value. + - **onUpdate**: the scalar field of the referencing object will be set to the fields default value. + +### Example + +```zmodel +model User { + id String @id + profile Profile? +} + +model Profile { + id String @id + user @relation(fields: [userId], references: [id], onUpdate: Cascade, onDelete: Cascade) + userId String @unique +} +``` diff --git a/versioned_docs/version-3.x/modeling/strong-typed-json.md b/versioned_docs/version-3.x/modeling/typed-json.md similarity index 64% rename from versioned_docs/version-3.x/modeling/strong-typed-json.md rename to versioned_docs/version-3.x/modeling/typed-json.md index 2426d926..2581d739 100644 --- a/versioned_docs/version-3.x/modeling/strong-typed-json.md +++ b/versioned_docs/version-3.x/modeling/typed-json.md @@ -11,7 +11,7 @@ import ZModelVsPSL from '../_components/ZModelVsPSL'; Strongly typed JSON is a ZModel feature and doesn't exist in PSL. -With relational databases providing better and better JSON support, their usage has become more common. However, in many cases your JSON fields still follow a specific structure, and when so, you can make the fields strongly typed so that: +With relational databases providing better and better JSON support, their usage has become more common. However, in many cases, your JSON fields still follow a specific structure, and when so, you can make the fields strongly typed so that: - When mutating the field, its structure is validated. - When querying the field, its result is strongly typed. @@ -44,7 +44,7 @@ model User { ``` :::info -The `@json` attribute doesn't do anything except to clearly mark the field is a JSON field but not a relation to another model. +The `@json` attribute serves no purpose other than to indicate (for readability) that the field is a JSON field, not a relation to another model. ::: -The migration engine still sees the field as a plain Json field. However, the ORM client enforces its structure and takes care of properly typing the query results. We'll revisit the topic in the [ORM](../orm/) part. +The migration engine still sees the field as a plain JSON field. However, the ORM client enforces its structure and takes care of properly typing the query results. We'll revisit this topic in the [ORM part](../orm/typed-json.md). diff --git a/versioned_docs/version-3.x/orm/inferred-types.md b/versioned_docs/version-3.x/orm/inferred-types.md index 4ac02b32..0a99274a 100644 --- a/versioned_docs/version-3.x/orm/inferred-types.md +++ b/versioned_docs/version-3.x/orm/inferred-types.md @@ -1,5 +1,5 @@ --- -sidebar_position: 14 +sidebar_position: 15 description: TypeScript types derived from the ZModel schema --- diff --git a/versioned_docs/version-3.x/orm/logging.md b/versioned_docs/version-3.x/orm/logging.md index a6a4ad1d..357ecad4 100644 --- a/versioned_docs/version-3.x/orm/logging.md +++ b/versioned_docs/version-3.x/orm/logging.md @@ -1,5 +1,5 @@ --- -sidebar_position: 13 +sidebar_position: 14 description: Setup logging --- diff --git a/versioned_docs/version-3.x/orm/migration.md b/versioned_docs/version-3.x/orm/migration.md index 67dc6cad..80d894b1 100644 --- a/versioned_docs/version-3.x/orm/migration.md +++ b/versioned_docs/version-3.x/orm/migration.md @@ -1,31 +1,31 @@ --- -sidebar_position: 15 +sidebar_position: 16 description: Schema migration introduction --- # Database Schema Migration -Database schema migration is a crucial aspect of application development. It helps you keep your database schema in sync with your data model, and ensures deployments are smooth and predictable. ZenStack provides migration tools that create migration scripts based on the ZModel schema and apply them to the database. +Database schema migration is a crucial aspect of application development. It helps you keep your database schema in sync with your data model and ensures deployments are smooth and predictable. ZenStack provides migration tools that create migration scripts based on the ZModel schema and apply them to the database. ## Introduction -ZenStack migration is built on top of [Prisma Migrate](https://www.prisma.io/docs/concepts/components/prisma-migrate). The `zen` CLI provides a set of migration-related commands that are simple wrappers around Prisma CLI. When running these commands, the CLI automatically generates a Prisma schema from ZModel, and then executes the corresponding Prisma CLI. +ZenStack migration is built on top of [Prisma Migrate](https://www.prisma.io/docs/concepts/components/prisma-migrate). The `zen` CLI provides a set of migration-related commands that are simple wrappers around Prisma CLI. When running these commands, the CLI automatically generates a Prisma schema from ZModel and then executes the corresponding Prisma CLI. Basing on Prisma Migrate brings the following benefits: -- **No reinventing the wheels**: Prisma Migrate is a mature and widely used migration tool, ensuring reliability and stability. +- **No reinventing the wheel**: Prisma Migrate is a mature and widely used migration tool, ensuring reliability and stability. - **Backward compatibility**: When migrating from Prisma to ZenStack, you can continue using your existing migration scripts without any changes. -If you are already familiar with Prisma Migrate, you can continue using your current workflow with ZenStack, simply swapping `prisma` CLI with `zen`. If not, this section will guide you through the commands and common workflows, but it's strongly recommended to check [Prisma Migrate documentation](https://www.prisma.io/docs/orm/prisma-migrate/understanding-prisma-migrate/overview) for in-depth information too. +If you are already familiar with Prisma Migrate, you can continue using your current workflow with ZenStack, simply swapping the `prisma` CLI with `zen`. If not, this section will guide you through the commands and common workflows, but it's strongly recommended to check [Prisma Migrate documentation](https://www.prisma.io/docs/orm/prisma-migrate/understanding-prisma-migrate/overview) for in-depth information. ## Commands -Please refer to the [CLI Reference](../reference/cli.md) for the full list of commands and options. +Please refer to the [CLI Reference](../reference/cli.md) for the complete list of commands and options. ### db push -The `zen db push` command is used to push your ZModel schema changes to the database without creating a migration file. This is useful for development and testing purposes. Never use it in production. +The `zen db push` command is used to push your ZModel schema changes to the database without creating a migration file. It's useful for development and testing purposes, but should never be used in production. ### migrate dev @@ -33,11 +33,11 @@ The `zen migrate dev` command is used to create a new migration file based on yo ### migrate deploy -The `zen migrate deploy` command is used to apply all pending migrations to your production database. This is typically run in your deployment pipeline. +The `zen migrate deploy` command is used to apply all pending migrations to your production database. It's typically used in your deployment pipeline. ### migrate reset -The `zen migrate reset` command is used to reset your database to a clean state by dropping all tables and reapplying all migrations. This is useful for testing and development purposes. +The `zen migrate reset` command is used to reset your database to a clean state by dropping all tables and reapplying all migrations. It's useful for testing and development purposes, but should never be used in production. ### migrate status diff --git a/versioned_docs/version-3.x/orm/plugins/_category_.yml b/versioned_docs/version-3.x/orm/plugins/_category_.yml index 12d5462a..5effe808 100644 --- a/versioned_docs/version-3.x/orm/plugins/_category_.yml +++ b/versioned_docs/version-3.x/orm/plugins/_category_.yml @@ -1,4 +1,4 @@ -position: 12 +position: 13 label: Plugins collapsible: true collapsed: true diff --git a/versioned_docs/version-3.x/orm/plugins/index.md b/versioned_docs/version-3.x/orm/plugins/index.md index e10da89d..c2b299bb 100644 --- a/versioned_docs/version-3.x/orm/plugins/index.md +++ b/versioned_docs/version-3.x/orm/plugins/index.md @@ -8,7 +8,7 @@ import ZenStackVsPrisma from '../../_components/ZenStackVsPrisma'; # Plugin Overview -ZenStack's plugin system aims to provide a more flexible extensibility solution than [Prisma Client Extensions](https://www.prisma.io/docs/orm/prisma-client/client-extensions), allowing you to tap into the ORM runtime at different levels. Some parts of the plugin design resemble client extensions, but overall it's not meant to be compatible. +ZenStack's plugin system aims to provide a more flexible extensibility solution than [Prisma Client Extensions](https://www.prisma.io/docs/orm/prisma-client/client-extensions), allowing you to tap into the ORM runtime at different levels. Some parts of the plugin design resemble client extensions, but overall, it's not meant to be compatible. As you go deeper using an ORM, you'll find the need to tap into its engine for different purposes. For example, you may want to: @@ -16,7 +16,7 @@ As you go deeper using an ORM, you'll find the need to tap into its engine for d - Log the time cost of each query operation. - Block certain CRUD operations. - Execute code when an entity is created, updated, or deleted. -- Alter the SQL query before it's sent to the database. +- Modify the SQL query before it's sent to the database. - ... ZenStack ORM provides three ways for you to tap into its runtime: @@ -27,11 +27,11 @@ ZenStack ORM provides three ways for you to tap into its runtime: 2. **Entity mutation hooks** - Entity mutation hooks allow you to execute code before or after an entity is created, updated, or deleted. This is very useful when you only care about entity changes instead of what triggered the changes. See [Entity Mutation Hooks](./entity-mutation-hooks.md) for details. + Entity mutation hooks allow you to execute code before or after an entity is created, updated, or deleted. It's very useful when you only care about entity changes instead of how the mutations are triggered. See [Entity Mutation Hooks](./entity-mutation-hooks.md) for details. 3. **Kysely query hooks** - Kysely query hooks give you the ultimate power to inspect and alter the SQL query (in AST form) before it's sent to the database. This is a very powerful low-level extensibility that should be used with care. See [Kysely Query Hooks](./kysely-query-hooks.md) for details. + Kysely query hooks give you the ultimate power to inspect and alter the SQL query (in AST form) before it's sent to the database. It's a very powerful low-level extensibility that should be used with care. See [Kysely Query Hooks](./kysely-query-hooks.md) for details. All three types of plugins are installed via the unified `$use` method on the ORM client. The `$use` method returns a new ORM client with the plugin applied, without modifying the original client. You can use the `$unuse` or `$unuseAll` methods to remove plugin(s) from a client. diff --git a/versioned_docs/version-3.x/orm/plugins/kysely-query-hooks.md b/versioned_docs/version-3.x/orm/plugins/kysely-query-hooks.md index 4d7bca47..11911f97 100644 --- a/versioned_docs/version-3.x/orm/plugins/kysely-query-hooks.md +++ b/versioned_docs/version-3.x/orm/plugins/kysely-query-hooks.md @@ -8,9 +8,9 @@ import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; ## Introduction -Kysely query hooks are the lowest level of interceptor in the plugin system. Since ZenStack eventually delegates all database access to Kysely, these hooks allow you to inspect and alter all SQL queries before they are sent to the database, regardless of whether they originate from the ORM query API or the query builder API. +Kysely query hooks are the lowest level of interceptors in the plugin system. Since ZenStack eventually delegates all database access to Kysely, these hooks allow you to inspect and modify all SQL queries before they are sent to the database, regardless of whether they originate from the ORM query API or the query builder API. -This mechanism gives you great power to entirely control the ORM's behavior. One good example is the [access policy](../access-control/) - the access policy enforcement is entirely achieved via intercepting the Kysely queries. +This mechanism gives you great power to control the ORM's behavior entirely. One good example is the [access policy](../access-control/) - the access policy enforcement is entirely achieved via intercepting the Kysely queries. To create a Kysely query hook plugin, call the `$use` method with an object containing a `onKyselyQuery` callback. The callback is triggered before each Kysely query is executed. It receives a context object containing: diff --git a/versioned_docs/version-3.x/orm/typed-json.md b/versioned_docs/version-3.x/orm/typed-json.md new file mode 100644 index 00000000..c5fb2a52 --- /dev/null +++ b/versioned_docs/version-3.x/orm/typed-json.md @@ -0,0 +1,25 @@ +--- +sidebar_position: 12 +description: Strongly typed JSON fields +--- + +import ZenStackVsPrisma from '../_components/ZenStackVsPrisma'; +import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import GithubCodeBlock from '@site/src/components/GithubCodeBlock'; + +# Strongly Typed JSON + + +Strongly typed JSON is a ZModel feature and doesn't exist in Prisma. + + +ZModel allows you to define custom types and use them to [type JSON fields](../modeling/typed-json.md). The ORM respects such fields in two ways: + +1. The return type of such fields is typed as TypeScript types derived from the ZModel custom type definition. +2. When creating or updating such fields, the ORM validates the input against the custom type definition. The engine "loosely" validates the mutation input and doesn't prevent you from including fields not defined in the custom type. + +## Samples + + + + diff --git a/versioned_docs/version-3.x/reference/zmodel-language.md b/versioned_docs/version-3.x/reference/zmodel-language.md deleted file mode 100644 index 8b540c21..00000000 --- a/versioned_docs/version-3.x/reference/zmodel-language.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -description: ZModel language references -sidebar_position: 1 -sidebar_label: ZModel Language -toc_max_heading_level: 3 ---- - -# ZModel Language Reference diff --git a/versioned_docs/version-3.x/reference/zmodel/_category_.yml b/versioned_docs/version-3.x/reference/zmodel/_category_.yml new file mode 100644 index 00000000..aeb71fb9 --- /dev/null +++ b/versioned_docs/version-3.x/reference/zmodel/_category_.yml @@ -0,0 +1,6 @@ +position: 1 +label: ZModel Language +collapsible: true +collapsed: true +link: + type: generated-index diff --git a/versioned_docs/version-3.x/reference/zmodel/attribute.md b/versioned_docs/version-3.x/reference/zmodel/attribute.md new file mode 100644 index 00000000..eb1b8369 --- /dev/null +++ b/versioned_docs/version-3.x/reference/zmodel/attribute.md @@ -0,0 +1,539 @@ +--- +sidebar_position: 6 +--- + +# Attribute + +Attributes decorate fields and models and attach extra behaviors or constraints to them. + +ZModel's standard library provides a set of predefined attributes, plugins can provide additional attributes, and you can also define your own attributes in the schema. + +## Syntax + +### Field attribute + +#### Definition + +Field attribute name is prefixed by a single `@`. + +```zmodel +attribute NAME(PARAMS) +``` + +- **NAME** + + Attribute name. Field attribute's name must start with '@'. + +- **PARAMS** + + Attribute parameters. See [Parameters](#parameters) for details. + +Example: + +```zmodel +attribute @id(map: String?, length: Int?) +``` + +#### Application + +```zmodel +id String ATTR_NAME(ARGS)? +``` + +- **ATTR_NAME** + + Attribute name. + +- **ARGS** + + Argument list. See [Parameters](#parameters) for details. + +Example: + +```zmodel +model User { + id Int @id(map: "_id") +} +``` + +### Model attribute + +#### Definition + +Field attribute name is prefixed by double `@@`. + +```zmodel +attribute @@NAME(PARAMS) +``` + +- **NAME** + + Attribute name. Model attribute's name must start with '@@'. + +- **PARAMS** + + Attribute parameters. See [Parameters](#parameters) for details. + +Example: + +```zmodel +attribute @@unique(_ fields: FieldReference[], name: String?, map: String?) +``` + +#### Application + +```zmodel +model Model { + ATTR_NAME(ARGS)? +} +``` + +- **ATTR_NAME** + + Attribute name. + +- **ARGS** + + Argument list. See [Parameters](#parameters) for details. + +Example: + +```zmodel +model User { + org String + userName String + @@unique([org, userName]) +} +``` + +### Parameters + +Attribute can be declared with a list of parameters and applied with a comma-separated list of arguments. + +Arguments are mapped to parameters by position or by name. For example, for the `@default` attribute declared as: + +```zmodel +attribute @default(_ value: ContextType) +``` + +, the following two ways of applying it are equivalent: + +```zmodel +published Boolean @default(value: false) +``` + +```zmodel +published Boolean @default(false) +``` + +### Parameter types + +Attribute parameters are typed. The following types are supported: + +- Int + + Integer literal can be passed as argument. + + E.g., declaration: + + ```zmodel + attribute @password(saltLength: Int?, salt: String?) + + ``` + + application: + + ```zmodel + password String @password(saltLength: 10) + ``` + +- String + + String literal can be passed as argument. + + E.g., declaration: + + ```zmodel + attribute @id(map: String?) + ``` + + application: + + ```zmodel + id String @id(map: "_id") + ``` + +- Boolean + + Boolean literal or expression can be passed as argument. + + E.g., declaration: + + ```zmodel + attribute @@allow(_ operation: String, _ condition: Boolean) + ``` + + application: + + ```zmodel + @@allow("read", true) + @@allow("update", auth() != null) + ``` + +- ContextType + + A special type that represents the type of the field onto which the attribute is attached. + + E.g., declaration: + + ```zmodel + attribute @default(_ value: ContextType) + ``` + + application: + + ```zmodel + f1 String @default("hello") + f2 Int @default(1) + ``` + +- FieldReference + + References to fields defined in the current model. + + E.g., declaration: + + ```zmodel + attribute @relation( + _ name: String?, + fields: FieldReference[]?, + references: FieldReference[]?, + onDelete: ReferentialAction?, + onUpdate: ReferentialAction?, + map: String?) + ``` + + application: + + ```zmodel + model Model { + ... + // [ownerId] is a list of FieldReference + owner Owner @relation(fields: [ownerId], references: [id]) + ownerId + } + ``` + +- Enum + + Attribute parameter can also be typed as predefined enum. + + E.g., declaration: + + ```zmodel + attribute @relation( + _ name: String?, + fields: FieldReference[]?, + references: FieldReference[]?, + // ReferentialAction is a predefined enum + onDelete: ReferentialAction?, + onUpdate: ReferentialAction?, + map: String?) + ``` + + application: + + ```zmodel + model Model { + // 'Cascade' is a predefined enum value + owner Owner @relation(..., onDelete: Cascade) + } + ``` + +An attribute parameter can be typed as any of the types above, a list of the above type, or an optional of the types above. + +```zmodel +model Model { + ... + f1 String + f2 String + // a list of FieldReference + @@unique([f1, f2]) +} +``` + +## Predefined attributes + +### @@id + +```zmodel +attribute @@id(_ fields: FieldReference[], name: String?, map: String?) +``` + +Defines a multi-field ID (composite ID) on the model. + +_Params_: + +| Name | Description | +| ------ | ----------------------------------------------------------------------------- | +| fields | A list of fields defined in the current model | +| name | The name that the Client API will expose for the argument covering all fields | +| map | The name of the underlying primary key constraint in the database | + +### @@unique + +```zmodel +attribute @@unique(_ fields: FieldReference[], name: String?, map: String?) +``` + +Defines a compound unique constraint for the specified fields. + +_Params_: + +| Name | Description | +| ------ | ------------------------------------------------------------ | +| fields | A list of fields defined in the current model | +| name | The name of the unique combination of fields | +| map | The name of the underlying unique constraint in the database | + +### @@index + +```zmodel +attribute @@index(_ fields: FieldReference[], map: String?) +``` + +Defines an index in the database. + +_Params_: + +| Name | Description | +| ------ | ------------------------------------------------ | +| fields | A list of fields defined in the current model | +| map | The name of the underlying index in the database | + +### @@map + +```zmodel +attribute @@map(_ name: String) +``` + +Maps the schema model name to a table with a different name, or an enum name to a different underlying enum in the database. + +_Params_: + +| Name | Description | +| ---- | -------------------------------------------------------- | +| name | The name of the underlying table or enum in the database | + +### @@ignore + +```zmodel +attribute @@ignore() +``` + +Exclude a model from the ORM Client. + +### @@auth + +```zmodel +attribute @@auth() +``` + +Specify the model for resolving `auth()` function call. + +### @@delegate + +```zmodel +attribute @@delegate(_ discriminator: FieldReference) +``` + +Marks a model to be a delegated base. Used for [modeling a polymorphic hierarchy](../../modeling/polymorphism.md). + +_Params_: + +| Name | Description | +| ------------- | ---------------------------------------------------------------------------------------------------------------------------- | +| discriminator | A `String` or `enum` field in the same model used to store the name of the concrete model that inherit from this base model. | + +### @@meta + +```zmodel +attribute @@meta(_ name: String, _ value: Any) +``` + +Adds arbitrary metadata to a model. The metadata can be accessed by custom plugins for code generation, or at runtime from the `modelMeta` object exported from `@zenstackhq/runtime/model-meta`. The `value` parameter can be an arbitrary literal expression, including object literals. + +```zmodel +model User { + id Int @id + @@meta('description', 'This is a user model') +} +``` + +### @id + +```zmodel +attribute @id(map: String?) +``` + +Defines an ID on the model. + +_Params_: + +| Name | Description | +| ---- | ----------------------------------------------------------------- | +| map | The name of the underlying primary key constraint in the database | + +### @default + +```zmodel +attribute @default(_ value: ContextType) +``` + +Defines a default value for a field. + +_Params_: + +| Name | Description | +| ----- | ---------------------------- | +| value | The default value expression | + +### @unique + +```zmodel +attribute @unique(map: String?) +``` + +Defines a unique constraint for this field. + +_Params_: + +| Name | Description | +| ---- | ----------------------------------------------------------------- | +| map | The name of the underlying primary key constraint in the database | + +### @relation + +```zmodel +attribute @relation( + _ name: String?, + fields: FieldReference[]?, + references: FieldReference[]?, + onDelete: ReferentialAction?, + onUpdate: ReferentialAction?, + map: String?) +``` + +Defines meta information about a relation. + +_Params_: + +| Name | Description | +| ---------- | ------------------------------------------------------------------------------ | +| name | The name of the relationship | +| fields | A list of fields defined in the current model | +| references | A list of fields of the model on the other side of the relation | +| onDelete | Referential action to take on delete. See details [here](#referential-action). | +| onUpdate | Referential action to take on update. See details [here](#referential-action). | + +### @map + +```zmodel +attribute @map(_ name: String) +``` + +Maps a field name or enum value from the schema to a column with a different name in the database. + +_Params_: + +| Name | Description | +| ---- | ------------------------------------------------- | +| map | The name of the underlying column in the database | + +### @updatedAt + +```zmodel +attribute @updatedAt() +``` + +Automatically stores the time when a record was last updated. + +### @ignore + +```zmodel +attribute @ignore() +``` + +Exclude a field from the ORM Client (so that the field is not included in the input and output of ORM queries). + +### @json + +```zmodel +attribute @json() +``` + +### @meta + +```zmodel +attribute @meta(_ name: String, _ value: Any) +``` + +Adds arbitrary metadata to a field. The metadata can be accessed by custom plugins for code generation, or at runtime from the `modelMeta` object exported from `@zenstackhq/runtime/model-meta`. The `value` parameter can be an arbitrary literal expression, including object literals. + +```zmodel +model User { + id Int @id + name String @meta(name: "description", value: "The name of the user") +} +``` + +## Native type mapping attributes + +Native type mapping attributes are a special set of field attributes that allow you to specify the native database type for a field. They are prefixed with `@db.`. + +Without native type mappings, ZModel types are by default mapped to the database types as follows: + +| ZModel Type | SQLite Type | PostgreSQL Type | +|-------------|-------------|----------------------| +| `String` | `TEXT` | `text` | +| `Boolean` | `INTEGER` | `boolean` | +| `Int` | `INTEGER` | `integer` | +| `BigInt` | `INTEGER` | `bigint` | +| `Float` | `REAL` | `double precision` | +| `Decimal` | `DECIMAL` | `decimal(65,30)` | +| `DateTime` | `NUMERIC` | `timestamp(3)` | +| `Json` | `JSONB` | `jsonb` | +| `Bytes` | `BLOB` | `bytea` | + + +The following native type mapping attributes can be used to override the default mapping: + +| Attribute | ZModel Type | SQLite Type | PostgreSQL Type | +|--------------------------|-------------------------------|-------------|----------------------| +| `@db.Text` | `String` | - | `text` | +| `@db.Char(x)` | `String` | - | `char(x)` | +| `@db.VarChar(x)` | `String` | - | `varchar(x)` | +| `@db.Bit(x)` | `String` `Boolean` `Bytes` | - | `bit(x)` | +| `@db.VarBit` | `String` | - | `varbit` | +| `@db.Uuid` | `String` | - | `uuid` | +| `@db.Xml` | `String` | - | `xml` | +| `@db.Inet` | `String` | - | `inet` | +| `@db.Citext` | `String` | - | `citext` | +| `@db.Boolean` | `Boolean` | - | `boolean` | +| `@db.Int` | `Int` | - | `serial` `serial4` | +| `@db.Integer` | `Int` | - | `integer` `int`,`int4` | +| `@db.SmallInt` | `Int` | - | `smallint` `int2` | +| `@db.Oid` | `Int` | - | `oid` | +| `@db.BigInt` | `BigInt` | - | `bigint` `int8` | +| `@db.DoublePrecision` | `Float` `Decimal` | - | `double precision` | +| `@db.Real` | `Float` `Decimal` | - | `real` | +| `@db.Decimal` | `Float` `Decimal` | - | `decimal` `numeric` | +| `@db.Money` | `Float` `Decimal` | - | `money` | +| `@db.Timestamp(x)` | `DateTime` | - | `timestamp(x)` | +| `@db.Timestamptz(x)` | `DateTime` | - | `timestampz(x)` | +| `@db.Date` | `DateTime` | - | `date` | +| `@db.Time(x)` | `DateTime` | - | `time(x)` | +| `@db.Timetz` | `DateTime` | - | `timez(x)` | +| `@db.Json` | `Json` | - | `json` | +| `@db.JsonB` | `Json` | - | `jsonb` | +| `@db.ByteA` | `Bytes` | - | `bytea` | \ No newline at end of file diff --git a/versioned_docs/version-3.x/reference/zmodel/data-field.md b/versioned_docs/version-3.x/reference/zmodel/data-field.md new file mode 100644 index 00000000..82d984d0 --- /dev/null +++ b/versioned_docs/version-3.x/reference/zmodel/data-field.md @@ -0,0 +1,77 @@ +--- +sidebar_position: 5 +--- + +# Data Field + +Data fields are typed members of models and types. + +## Syntax + +```zmodel +model Model { + FIELD_NAME FIELD_TYPE FIELD_ATTRIBUTES? +} +``` + +Or + +```zmodel +type Type { + FIELD_NAME FIELD_TYPE (FIELD_ATTRIBUTES)? +} +``` + +- **FIELD_NAME** + + Name of the field. Needs to be unique in the containing model or type. Must be a valid identifier. + +- **FIELD_TYPE** + + Type of the field. Can be a scalar type, a reference to another model or type if the field belongs to a [model](#model), or a reference to another type if it belongs to a [type](#type). + + The following scalar types are supported: + + - String + - Boolean + - Int + - BigInt + - Float + - Decimal + - Json + - Bytes + - Unsupported + + A field's type can be any of the scalar or reference type, a list of the aforementioned type (suffixed with `[]`), or an optional of the aforementioned type (suffixed with `?`). + +- **FIELD_ATTRIBUTES** + + Field attributes attach extra behaviors or constraints to the field. See [Attribute](./attribute.md) for more information. + +## Example + +```zmodel +model Post { + // "id" field is a mandatory unique identifier of this model + id String @id @default(uuid()) + + // fields can be DateTime + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + // or string + title String + + // or integer + viewCount Int @default(0) + + // and optional + content String? + + // and a list too + tags String[] + + // and can reference another model too + comments Comment[] +} +``` \ No newline at end of file diff --git a/versioned_docs/version-3.x/reference/zmodel/datasource.md b/versioned_docs/version-3.x/reference/zmodel/datasource.md new file mode 100644 index 00000000..1bdc5368 --- /dev/null +++ b/versioned_docs/version-3.x/reference/zmodel/datasource.md @@ -0,0 +1,49 @@ +--- +sidebar_position: 1 +--- + +# Data Source + +Every model needs to include exactly one `datasource` declaration, providing information on how to connect to the underlying database. + +## Syntax + +```zmodel +datasource NAME { + provider = PROVIDER + url = DB_URL +} +``` + +- **NAME**: + + Name of the data source. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. Name is only informational and serves no other purposes. + +- **`provider`**: + + Name of database connector. Valid values: + + - sqlite + - postgresql + +- **`url`**: + + Database connection string. Either a plain string or an invocation of `env` function to fetch from an environment variable. For SQLite provider, the URL should be a file protocol, like `file:./dev.db`. For PostgreSQL provider, it should be a postgres connection string, like `postgresql://user:password@localhost:5432/dbname`. + + The `url` option is only used by the migration engine to connect to the database. The ORM runtime doesn't rely on it. Instead, you provide the connection information when constructing an ORM client. + +## Example + +```zmodel +datasource db { + provider = 'postgresql' + url = env('DATABASE_URL') +} +``` + +```zmodel +datasource db { + provider = 'sqlite' + url = 'file:./dev.db' +} +``` diff --git a/versioned_docs/version-3.x/reference/zmodel/enum.md b/versioned_docs/version-3.x/reference/zmodel/enum.md new file mode 100644 index 00000000..56e9ac94 --- /dev/null +++ b/versioned_docs/version-3.x/reference/zmodel/enum.md @@ -0,0 +1,32 @@ +--- +sidebar_position: 3 +--- + +# Enum + +Enums are container declarations for grouping constant identifiers. You can use them to express concepts like user roles, product categories, etc. + +### Syntax + +```zmodel +enum NAME { + FIELD* +} +``` + +- **ENUM_NAME** + + Name of the enum. Needs to be unique in the entire model. Must be a valid identifier. + +- **FIELD** + + Field identifier. Needs to be unique in the model. Must be a valid identifier. + +### Example + +```zmodel +enum UserRole { + USER + ADMIN +} +``` \ No newline at end of file diff --git a/versioned_docs/version-3.x/reference/zmodel/function.md b/versioned_docs/version-3.x/reference/zmodel/function.md new file mode 100644 index 00000000..c4608840 --- /dev/null +++ b/versioned_docs/version-3.x/reference/zmodel/function.md @@ -0,0 +1,148 @@ +--- +sidebar_position: 7 +--- + +# Function + +Functions are used to provide values for attribute arguments, e.g., current `DateTime`, an auto-increment `Int`, etc. They can be used in place of attribute arguments, like: + +```zmodel +model Model { + ... + serial Int @default(autoincrement()) + createdAt DateTime @default(now()) +} +``` + +ZModel's standard library provides a set of predefined functions, plugins can provide additional functions, and you can also define your own functions in the schema. + +## Syntax + +### Definition + +```zmodel +function NAME(PARAMS): RETURN_TYPE {} +``` + +- **NAME** + + Function name. Must be a valid identifier. + +- **PARAMS** + + Parameters. See [Parameters](#parameters) for details. + +- **RETURN_TYPE** + + Return type. Must be a valid type as described in [Parameters](#parameters). + +Example: + +```zmodel +function uuid(version: Int?): String {} +``` + +### Application + +```zmodel +id String @default(FUNC_NAME(ARGS)) +``` +- **FUNC_NAME** + + Function name. + +- **ARGS** + + Argument list. See [Parameters](#parameters) for details. + +Example: + +```zmodel +id String @default(uuid(4)) +``` + +### Parameters + +A function can have zero or more parameters. A parameter has a name and a type. + +Valid parameter types include: + - `String` + - `Boolean` + - `Int` + - `BigInt` + - `Float` + - `Decimal` + - `DateTime` + - `Bytes` + - `Any` + +Parameter's type can also carry the following suffix: + - `[]` to indicate it's a list type + - `?` to indicate it's optional + +## Predefined functions + +### uuid() + +```zmodel +function uuid(): String {} +``` + +Generates a globally unique identifier based on the UUID spec. + +### cuid() + +```zmodel +function cuid(version: Int?): String {} +``` + +Generates a unique identifier based on the [CUID](https://github.com/ericelliott/cuid) spec. Pass `2` as an argument to use [cuid2](https://github.com/paralleldrive/cuid2). + +### nanoid() + +```zmodel +function nanoid(length: Int?): String {} +``` + +Generates an identifier based on the [nanoid](https://github.com/ai/nanoid) spec. + +### ulid() + +```zmodel +function ulid(): String {} +``` + +Generates a unique identifier based on the [ULID](https://github.com/ulid/spec) spec. + +### now() + +```zmodel +function now(): DateTime {} +``` + +Gets current date-time. + +### autoincrement() + +```zmodel +function autoincrement(): Int {} +``` + +Creates a sequence of integers in the underlying database and assign the incremented +values to the ID values of the created records based on the sequence. + +### dbgenerated() + +```zmodel +function dbgenerated(expr: String): Any {} +``` + +Represents default values that cannot be expressed in the Prisma schema (such as random()). + +### auth() + +```zmodel +function auth(): AUTH_TYPE {} +``` + +Gets the current login user. The return type is resolved to a model or type annotated with the `@@auth` attribute, and if not available, a model or type named `User`. diff --git a/versioned_docs/version-3.x/reference/zmodel/import.md b/versioned_docs/version-3.x/reference/zmodel/import.md new file mode 100644 index 00000000..97402358 --- /dev/null +++ b/versioned_docs/version-3.x/reference/zmodel/import.md @@ -0,0 +1,30 @@ +--- +sidebar_position: 8 +--- + +# Import + +ZModel allows to import other ZModel files. This is useful when you want to split your schema into multiple files for better organization. + +## Syntax + +```zmodel +import IMPORT_SPEC +``` + +- *IMPORT_SPEC**: + + Path to the ZModel file to be imported. It can be: + + - An absolute path, e.g., "/path/to/user". + - A relative path, e.g., "./user". + - A module resolved to an installed NPM package, e.g., "my-package/base". + + If the import specification doesn't end with ".zmodel", the resolver will automatically append it. Once a file is imported, all the declarations in that file will be included in the building process. + +## Examples + +```zmodel +// there is a file called "user.zmodel" in the same directory +import "user" +``` diff --git a/versioned_docs/version-3.x/reference/zmodel/model.md b/versioned_docs/version-3.x/reference/zmodel/model.md new file mode 100644 index 00000000..75cf0672 --- /dev/null +++ b/versioned_docs/version-3.x/reference/zmodel/model.md @@ -0,0 +1,56 @@ +--- +sidebar_position: 2 +--- + +# Model + +Models represent the business entities of your application. A model can have zero or more [mixins](../../modeling/mixin.md), and zero or more [polymorphic base models](../../modeling/polymorphism.md). + +## Syntax + +```zmodel +model NAME (with MIXIN_NAME(,MIXIN_NAME)*)? (extends BASE_NAME)? { + FIELD* + ATTRIBUTE* +} +``` +- **NAME**: + + Name of the model. Needs to be unique in the entire schema. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. + +- **FIELD**: + + Arbitrary number of fields. See [Field](./field.md) for details. + +- **ATTRIBUTE**: + + Arbitrary number of attributes. See [Attribute](./attribute.md) for details. + +- **MIXIN_NAME**: + + Name of a custom type used as a mixin. + +- **BASE_NAME**: + + Name of a polymorphic base model. + +## Note + +A model must be uniquely identifiable by one or several of its fields. For most cases, you'll have a field marked with the `@id` attribute. If needed, you can use multiple fields as unique identifier by using the `@@id` model-level attribute. + +If no `@id` or `@@id` is specified, field(s) marked with the `@unique` or `@@unique` attribute will be used as fallback identifier. + +## Example + +```zmodel +type CommonFields { + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model User with CommonFields { + email String @unique + name String +} +``` diff --git a/versioned_docs/version-3.x/reference/zmodel/plugin.md b/versioned_docs/version-3.x/reference/zmodel/plugin.md new file mode 100644 index 00000000..6fa84bd6 --- /dev/null +++ b/versioned_docs/version-3.x/reference/zmodel/plugin.md @@ -0,0 +1,37 @@ +--- +sidebar_position: 9 +--- + +# Plugin + +Plugins allow you to extend the ZModel language and add custom code generation logic. + +## Syntax + +```zmodel +plugin PLUGIN_NAME { + provider = PROVIDER + OPTION* +} +``` + +- **PLUGIN_NAME** + + Name of the plugin. Needs to be unique in the entire model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. + +- **`provider`** + + The JavaScript module that provides the plugin's implementation. It can be a built-in plugin (like `@core/typescript`), a local JavaScript file, or an installed NPM package that exports a plugin. + +- **OPTION** + + A plugin configuration option, in form of "[NAME] = [VALUE]". Option values can be literal, array, or object. + +## Example + +```zmodel +plugin custom { + provider = './my-plugin.js' + output = './generated' +} +``` \ No newline at end of file diff --git a/versioned_docs/version-3.x/reference/zmodel/type.md b/versioned_docs/version-3.x/reference/zmodel/type.md new file mode 100644 index 00000000..cd89e8dc --- /dev/null +++ b/versioned_docs/version-3.x/reference/zmodel/type.md @@ -0,0 +1,52 @@ +--- +sidebar_position: 4 +--- + +# Type + +Types provide a way to define complex data structures that are not backed by a database table. They server two purposes: + +1. Types can be used as [mixins](../../modeling/mixin.md) to contain common fields and attributes shared by multiple models. +2. Types can be used to define [strongly typed JSON fields](../../modeling/typed-json.md) in models. + +## Syntax + +```zmodel +type NAME { + FIELD* + ATTRIBUTE* +} +``` + +- **NAME**: + + Name of the model. Needs to be unique in the entire model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. + +- **FIELD**: + + Arbitrary number of fields. See [Field](./field.md) for details. + +- **ATTRIBUTE**: + + Arbitrary number of attributes. See [Attribute](./attribute.md) for details. + +## Example + +```zmodel +type Profile { + age Int + gender String +} + +type CommonFields { + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model User with CommonFields { + email String @unique + name String + profile Profile? @json +} +``` \ No newline at end of file From ec14645a2454ae83c1bab91a4609d3beaf1b285f Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Tue, 19 Aug 2025 12:53:12 +0800 Subject: [PATCH 29/51] update --- src/lib/prism-zmodel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/prism-zmodel.js b/src/lib/prism-zmodel.js index a5198df6..63ea4f97 100644 --- a/src/lib/prism-zmodel.js +++ b/src/lib/prism-zmodel.js @@ -1,5 +1,5 @@ Prism.languages.zmodel = Prism.languages.extend('clike', { - keyword: /\b(?:datasource|enum|generator|model|type|abstract|import|extends|attribute|view|plugin|proc)\b/, + keyword: /\b(?:datasource|enum|generator|model|type|abstract|import|extends|attribute|view|plugin|proc|with)\b/, 'type-class-name': /(\b()\s+)[\w.\\]+/, }); From 3ebe44f0e0d8cff001da9be95f2872953a3a4667 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Tue, 19 Aug 2025 13:35:50 +0800 Subject: [PATCH 30/51] fix links --- versioned_docs/version-3.x/modeling/attribute.md | 2 +- versioned_docs/version-3.x/modeling/custom-type.md | 2 +- versioned_docs/version-3.x/modeling/model.md | 2 +- versioned_docs/version-3.x/reference/zmodel/model.md | 2 +- versioned_docs/version-3.x/reference/zmodel/type.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/versioned_docs/version-3.x/modeling/attribute.md b/versioned_docs/version-3.x/modeling/attribute.md index df89825e..dffe2a26 100644 --- a/versioned_docs/version-3.x/modeling/attribute.md +++ b/versioned_docs/version-3.x/modeling/attribute.md @@ -28,7 +28,7 @@ model User { Prisma schema doesn't allow users to define custom attributes, while ZModel allows it and uses it as a key mechanism for extensibility. -ZModel comes with a rich set of attributes that you can use directly. See [ZModel Language Reference](../reference/zmodel-language.md) for a complete list. You can also define your own custom attributes for specific purposes. Attributes are defined with a list of typed parameters. Parameters can be named (default) or positional. Positional parameters can be passed with or without an explicit name. Parameters can also be optional. +ZModel comes with a rich set of attributes that you can use directly. See [ZModel Language Reference](../category/zmodel-language) for a complete list. You can also define your own custom attributes for specific purposes. Attributes are defined with a list of typed parameters. Parameters can be named (default) or positional. Positional parameters can be passed with or without an explicit name. Parameters can also be optional. Here's an example of how the `@unique` attribute is defined: diff --git a/versioned_docs/version-3.x/modeling/custom-type.md b/versioned_docs/version-3.x/modeling/custom-type.md index b7a36c9b..7314678b 100644 --- a/versioned_docs/version-3.x/modeling/custom-type.md +++ b/versioned_docs/version-3.x/modeling/custom-type.md @@ -43,4 +43,4 @@ type UserProfile { There are two ways to use custom types: - [Mixin](./mixin.md) -- [Strongly typed JSON fields](./strong-typed-json.md) +- [Strongly typed JSON fields](./typed-json.md) diff --git a/versioned_docs/version-3.x/modeling/model.md b/versioned_docs/version-3.x/modeling/model.md index 0442bf5b..524a31d0 100644 --- a/versioned_docs/version-3.x/modeling/model.md +++ b/versioned_docs/version-3.x/modeling/model.md @@ -174,7 +174,7 @@ model User { } ``` -These attributes control what data type is used when the [migration engine](../orm/migration.md) maps the schema to DDL. You can find a complete list of native type attributes in the [ZModel Language Reference](../reference/zmodel-language). +These attributes control what data type is used when the [migration engine](../orm/migration.md) maps the schema to DDL. You can find a complete list of native type attributes in the [ZModel Language Reference](../category/zmodel-language). ## Name mapping diff --git a/versioned_docs/version-3.x/reference/zmodel/model.md b/versioned_docs/version-3.x/reference/zmodel/model.md index 75cf0672..7cc50325 100644 --- a/versioned_docs/version-3.x/reference/zmodel/model.md +++ b/versioned_docs/version-3.x/reference/zmodel/model.md @@ -20,7 +20,7 @@ model NAME (with MIXIN_NAME(,MIXIN_NAME)*)? (extends BASE_NAME)? { - **FIELD**: - Arbitrary number of fields. See [Field](./field.md) for details. + Arbitrary number of fields. See [Field](./data-field.md) for details. - **ATTRIBUTE**: diff --git a/versioned_docs/version-3.x/reference/zmodel/type.md b/versioned_docs/version-3.x/reference/zmodel/type.md index cd89e8dc..2585b7fe 100644 --- a/versioned_docs/version-3.x/reference/zmodel/type.md +++ b/versioned_docs/version-3.x/reference/zmodel/type.md @@ -24,7 +24,7 @@ type NAME { - **FIELD**: - Arbitrary number of fields. See [Field](./field.md) for details. + Arbitrary number of fields. See [Field](./data-field.md) for details. - **ATTRIBUTE**: From f847870717347a0b0cb1e5de449360f377e69939 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Tue, 19 Aug 2025 15:21:24 +0800 Subject: [PATCH 31/51] almost done --- .../_components/_zmodel-starter.md | 26 +- .../version-3.x/modeling/attribute.md | 4 +- .../version-3.x/modeling/datasource.md | 2 +- versioned_docs/version-3.x/modeling/index.md | 4 +- versioned_docs/version-3.x/modeling/mixin.md | 4 +- versioned_docs/version-3.x/modeling/model.md | 16 +- versioned_docs/version-3.x/modeling/plugin.md | 4 +- .../version-3.x/modeling/polymorphism.md | 8 +- .../version-3.x/modeling/typed-json.md | 4 +- versioned_docs/version-3.x/orm/index.md | 8 +- versioned_docs/version-3.x/reference/api.md | 41 +++ versioned_docs/version-3.x/reference/cli.md | 306 +++++++++--------- .../version-3.x/reference/zmodel/function.md | 2 +- .../version-3.x/reference/zmodel/import.md | 2 +- versioned_docs/version-3.x/welcome.md | 2 +- 15 files changed, 250 insertions(+), 183 deletions(-) diff --git a/versioned_docs/version-3.x/_components/_zmodel-starter.md b/versioned_docs/version-3.x/_components/_zmodel-starter.md index fbf3eaea..bfff33d5 100644 --- a/versioned_docs/version-3.x/_components/_zmodel-starter.md +++ b/versioned_docs/version-3.x/_components/_zmodel-starter.md @@ -1,23 +1,23 @@ ```zmodel datasource db { - provider = 'sqlite' - url = "file:./dev.db" + provider = 'sqlite' + url = "file:./dev.db" } model User { - id String @id @default(cuid()) - email String @unique - posts Post[] + id String @id @default(cuid()) + email String @unique + posts Post[] } model Post { - id String @id @default(cuid()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - title String - content String - published Boolean @default(false) - author User @relation(fields: [authorId], references: [id]) - authorId String + id String @id @default(cuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + title String + content String + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id]) + authorId String } ``` \ No newline at end of file diff --git a/versioned_docs/version-3.x/modeling/attribute.md b/versioned_docs/version-3.x/modeling/attribute.md index dffe2a26..e7f0c6f7 100644 --- a/versioned_docs/version-3.x/modeling/attribute.md +++ b/versioned_docs/version-3.x/modeling/attribute.md @@ -28,7 +28,7 @@ model User { Prisma schema doesn't allow users to define custom attributes, while ZModel allows it and uses it as a key mechanism for extensibility. -ZModel comes with a rich set of attributes that you can use directly. See [ZModel Language Reference](../category/zmodel-language) for a complete list. You can also define your own custom attributes for specific purposes. Attributes are defined with a list of typed parameters. Parameters can be named (default) or positional. Positional parameters can be passed with or without an explicit name. Parameters can also be optional. +ZModel comes with a rich set of attributes that you can use directly. See [ZModel Language Reference](../reference/zmodel/attribute#predefined-attributes) for a complete list. You can also define your own attributes for specific purposes. Attributes are defined with a list of typed parameters. Parameters can be named (default) or positional. Positional parameters can be passed with or without an explicit name. Parameters can also be optional. Here's an example of how the `@unique` attribute is defined: @@ -45,3 +45,5 @@ model Foo { z String @unique(map: 'z_unique', length: 10) // named parameter } ``` + +Read the [ZModel Language Reference](../reference/zmodel/attribute#syntax) for more details on how to define and use attributes. diff --git a/versioned_docs/version-3.x/modeling/datasource.md b/versioned_docs/version-3.x/modeling/datasource.md index 2ac7a052..bbdeb7d1 100644 --- a/versioned_docs/version-3.x/modeling/datasource.md +++ b/versioned_docs/version-3.x/modeling/datasource.md @@ -38,5 +38,5 @@ datasource db { Currently, only PostgreSQL and SQLite are supported. MySQL will be supported in a future release. There's no plan for other relational database types or NoSQL databases. -ZenStack's ORM runtime doesn't rely on the `url` information to connect to the database. Instead, you provide the information when constructing an ORM client β€” more on this in the [ORM](../orm/) section. +ZenStack's ORM runtime doesn't rely on the `url` information to connect to the database. Instead, you provide the information when constructing an ORM client β€” more on this in the [ORM](../orm/) part. diff --git a/versioned_docs/version-3.x/modeling/index.md b/versioned_docs/version-3.x/modeling/index.md index 2f7d5cf7..6ed0aa9b 100644 --- a/versioned_docs/version-3.x/modeling/index.md +++ b/versioned_docs/version-3.x/modeling/index.md @@ -9,13 +9,13 @@ import ZModelVsPSL from '../_components/ZModelVsPSL'; ZenStack uses a schema language named **ZModel** to define data models and their related aspects. We know that designing a good schema language is difficult, and we know it's even more challenging to convince people to learn a new one. We therefore decided to design ZModel as a superset of the [Prisma Schema Language (PSL)](https://www.prisma.io/docs/orm/prisma-schema), one of the best data modeling languages available. -If you're already familiar with PSL, you'll find yourself at home with ZModel. However, we recommend that you skim through this section to learn about the essential extensions we made to PSL. Please pay attention to callouts like the following one: +If you're already familiar with PSL, you'll find yourself at home with ZModel. However, we recommend that you skim through this section to learn about the essential extensions we made to PSL. Please pay attention to callouts like the following: ZModel allows both single quotes and double quotes for string literals. -Don't worry if you've never used Prisma before. This section will introduce all aspects of ZModel, so no prior knowledge is required. +Don't worry if you've never used Prisma before. This part of documentation will introduce all aspects of ZModel, so no prior knowledge is required. A simplest ZModel schema looks like this: diff --git a/versioned_docs/version-3.x/modeling/mixin.md b/versioned_docs/version-3.x/modeling/mixin.md index 19916a1b..51451c67 100644 --- a/versioned_docs/version-3.x/modeling/mixin.md +++ b/versioned_docs/version-3.x/modeling/mixin.md @@ -21,10 +21,10 @@ Very often you'll find many of your models share quite a few common fields. It's ```zmodel model User { - id String @id + id String @id createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - email String @unique + email String @unique } model Post { diff --git a/versioned_docs/version-3.x/modeling/model.md b/versioned_docs/version-3.x/modeling/model.md index 524a31d0..4b9e50ae 100644 --- a/versioned_docs/version-3.x/modeling/model.md +++ b/versioned_docs/version-3.x/modeling/model.md @@ -5,7 +5,7 @@ description: Models in ZModel # Model -The `model` construct is the core of ZModel. It defines the structure of your data and relations. A model represents a domain entity and is mapped to a database table. +The `model` construct is the core of ZModel. It defines the structure of your data and relations. A model represents a domain entity and is backed by a database table. ## Defining models @@ -73,7 +73,7 @@ Each model field must at least have a name and a type. A field can be typed in o - Bytes - Unsupported - The `Unsupported` type is for defining fields of types not supported by the ORM; however, it lets the migration engine know how to create the field in the database. + The `Unsupported` type is for defining fields of types not supported by the ORM. It lets the migration engine know how to create the field in the database. ```zmodel // from Prisma docs @@ -115,7 +115,7 @@ Each model field must at least have a name and a type. A field can be typed in o ``` 4. Custom type - ZenStack allows you to define custom types in the schema and use them to type JSON fields. This will be covered in more detail in the [Custom Types](./custom-type) section. + ZenStack allows you to define custom types in the schema and use them to type JSON fields. This will be covered in more detail in the [Custom Type](./custom-type) section. ```zmodel type Address { @@ -174,9 +174,15 @@ model User { } ``` -These attributes control what data type is used when the [migration engine](../orm/migration.md) maps the schema to DDL. You can find a complete list of native type attributes in the [ZModel Language Reference](../category/zmodel-language). +These attributes control what data type is used when the [migration engine](../orm/migration.md) maps the schema to DDL. You can find a complete list of native type attributes in the [ZModel Language Reference](../reference/zmodel/attribute#native-type-mapping-attributes). ## Name mapping -Quite often, you want to use a different naming scheme for your models and fields than the database. You can achieve that with the `@map` attribute. The ORM respects the mapping when generating queries, and the migration engine uses it to generate the DDL. +Quite often, you want to use a different naming scheme for your models and fields than the database. You can achieve that with the `@map` and `@@map` attribute. The ORM respects the mapping when generating queries, and the migration engine uses it to generate the DDL. +```zmodel +model User { + id Int @id @map('_id') + @@map('users') +} +``` diff --git a/versioned_docs/version-3.x/modeling/plugin.md b/versioned_docs/version-3.x/modeling/plugin.md index ca8f9589..b3256c8c 100644 --- a/versioned_docs/version-3.x/modeling/plugin.md +++ b/versioned_docs/version-3.x/modeling/plugin.md @@ -25,7 +25,7 @@ plugin myPlugin { ``` :::info -In fact, the `zen generate` command is entirely implemented with plugins. The ZModel -> TypeScript generation is supported by the built-in `@core/typescript` plugin, which can be explicitly declared if you wish: +In fact, the `zen generate` command is entirely implemented with plugins. The ZModel -> TypeScript generation is supported by the built-in `@core/typescript` plugin which runs automatically. You can explicitly declare it if you wish: ```zmodel plugin typescript { @@ -40,7 +40,7 @@ Please refer to the [Plugin References](../category/plugins) for the full list o A plugin declaration involves three parts: 1. A unique name -2. A `provider` field that specifies where to load the plugin from. It can be a built-in plugin (like `@core/prisma` here), a local folder, or an npm package. +2. A `provider` field that specifies where to load the plugin from. It can be a built-in plugin (like `@core/prisma` here), a local JavaScript module, or an NPM package name. 3. Plugin-specific configuration options, such as `output` in this case. A plugin can have the following effects to ZModel: diff --git a/versioned_docs/version-3.x/modeling/polymorphism.md b/versioned_docs/version-3.x/modeling/polymorphism.md index 98d78b71..384b1b84 100644 --- a/versioned_docs/version-3.x/modeling/polymorphism.md +++ b/versioned_docs/version-3.x/modeling/polymorphism.md @@ -28,7 +28,7 @@ It may be tempting to use mixins to share the common fields, however it's not an A true solution involves having a in-database model of polymorphism, where we really have a `Content` table that serves as an intermediary between `User` and the concrete content types. This is what ZModel polymorphism is about. :::info -There are [two main ways](https://www.prisma.io/docs/orm/prisma-schema/data-model/table-inheritance) to model polymorphism in relational databases: single-table inheritance (STI) and multi-table inheritance (MTI, aka. delegate types). ZModel only supports MTI. +There are [two main ways](https://www.prisma.io/docs/orm/prisma-schema/data-model/table-inheritance) to model polymorphism in relational databases: single-table inheritance (STI) and multi-table inheritance (MTI, aka. "Delegate Types"). ZModel only supports MTI. ::: ## Modeling polymorphism @@ -83,17 +83,17 @@ erDiagram } User ||--o{ Content: owns Post { - id Int PK + id Int PK,FK content String } Post ||--|| Content: delegates Image { - id Int PK + id Int PK,FK data Bytes } Image ||--|| Content: delegates Video { - id Int PK + id Int PK,FK url String } Video ||--|| Content: delegates diff --git a/versioned_docs/version-3.x/modeling/typed-json.md b/versioned_docs/version-3.x/modeling/typed-json.md index 2581d739..70694b7f 100644 --- a/versioned_docs/version-3.x/modeling/typed-json.md +++ b/versioned_docs/version-3.x/modeling/typed-json.md @@ -22,7 +22,7 @@ To type a JSON field, define a custom type in ZModel, use it as the field's type ```zmodel model User { - id Int @id + id Int @id address Json } ``` @@ -44,7 +44,7 @@ model User { ``` :::info -The `@json` attribute serves no purpose other than to indicate (for readability) that the field is a JSON field, not a relation to another model. +The `@json` attribute serves no purpose today other than to indicate (for readability) that the field is a JSON field, not a relation to another model. We may extend it in the future for fine-tuning the JSON field's behavior. ::: The migration engine still sees the field as a plain JSON field. However, the ORM client enforces its structure and takes care of properly typing the query results. We'll revisit this topic in the [ORM part](../orm/typed-json.md). diff --git a/versioned_docs/version-3.x/orm/index.md b/versioned_docs/version-3.x/orm/index.md index 3cd0ddd5..e39d720c 100644 --- a/versioned_docs/version-3.x/orm/index.md +++ b/versioned_docs/version-3.x/orm/index.md @@ -7,7 +7,7 @@ import ZenStackVsPrisma from '../_components/ZenStackVsPrisma'; # ORM Overview -ZenStack ORM is a schema-first ORM for modern TypeScript applications. It learnt from the prior arts and strives to provide an awesome developer experience by combining the best ingredients into a cohesive package. +ZenStack ORM is a schema-first ORM for modern TypeScript applications. It learnt from the prior arts and strives to provide an excellent developer experience and incredible flexibility by combining the best ingredients into a cohesive package. ## Key Features @@ -45,7 +45,7 @@ await db.$qb ZenStack ORM comes with a powerful built-in access control system. You can define access rules right inside the schema. The rules are enforced at runtime via query injection, so it doesn't rely on any database specific row-level security features. -```zmodel" +```zmodel model Post { id Int @id title String @length(1, 256) @@ -68,7 +68,7 @@ model Post { Real-world applications often involves storing polymorphic data which is notoriously complex to model and query. ZenStack does the heavy-lifting for you so you can model an inheritance hierarchy with simple annotations, and query them with perfect type safety. -```zmodel title="zenstack/schema.zmodel" +```zmodel model Content { id Int @id name String @length(1, 256) @@ -106,7 +106,7 @@ Compared to Prisma and previous versions of ZenStack, v3 is more straightforward ### Sample playground -Throughout the documentation we'll use [StackBlitz](https://stackblitz.com/) to provide interactive code samples. StackBlitz's [WebContainers](https://webcontainers.io/) is an awesome technology that allows you to run a Node.js environment inside the browser. The embedded samples use the [sql.js](https://github.com/sql-js/sql.js) (a WASM implementation of SQLite) for WebContainers compatibility, which is not suitable for production use. +Throughout the documentation we'll use [StackBlitz](https://stackblitz.com/) to provide interactive samples alongside with static code snippets. StackBlitz's [WebContainers](https://webcontainers.io/) is an awesome technology that allows you to run a Node.js environment inside the browser. The embedded samples use the [sql.js](https://github.com/sql-js/sql.js) (a WASM implementation of SQLite) for WebContainers compatibility, which is not suitable for production use. Feel free to make changes and try things out in the playground. ### If you already know Prisma diff --git a/versioned_docs/version-3.x/reference/api.md b/versioned_docs/version-3.x/reference/api.md index 52b981ba..591870dd 100644 --- a/versioned_docs/version-3.x/reference/api.md +++ b/versioned_docs/version-3.x/reference/api.md @@ -5,3 +5,44 @@ sidebar_label: API --- # API Reference + +## `@zenstackhq/runtime` + +### `class ZenStackClient` + +```ts +/** + * ZenStack ORM client. + */ +export const ZenStackClient = function ( + this: any, + schema: Schema, + options: ClientOptions, +); + +/** + * ZenStack client options. + */ +export type ClientOptions = { + /** + * Kysely dialect. + */ + dialect: Dialect; + + /** + * Plugins. + */ + plugins?: RuntimePlugin[]; + + /** + * Logging configuration. + */ + log?: KyselyConfig['log']; + + // only required when using computed fields + /** + * Computed field definitions. + */ + computedFields: ComputedFieldsOptions; +}; +``` \ No newline at end of file diff --git a/versioned_docs/version-3.x/reference/cli.md b/versioned_docs/version-3.x/reference/cli.md index e6188f8b..0e4a97f9 100644 --- a/versioned_docs/version-3.x/reference/cli.md +++ b/versioned_docs/version-3.x/reference/cli.md @@ -11,241 +11,259 @@ sidebar_label: CLI ``` zenstack [options] [command] -ΞΆ ZenStack is a Prisma power pack for building full-stack apps. +ΞΆ ZenStack is the data layer for modern TypeScript apps. Documentation: https://zenstack.dev. Options: - -v --version display CLI version - -h, --help display help for command + -v --version display CLI version + -h, --help display help for command Commands: - info [path] Get information of installed ZenStack and related packages. - init [options] [path] Initialize an existing project for ZenStack. - 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. + generate [options] Run code generation. + migrate Run database schema migration related tasks. + db Manage your database schema during development. + info [path] Get information of installed ZenStack packages. + init [path] Initialize an existing project for ZenStack. + check [options] Check a ZModel schema for syntax or semantic errors. + help [command] display help for command ``` ## Sub Commands -### info +### generate -Get information of installed ZenStack and related packages. +Run code generation plugins. ```bash -zenstack info [options] [path] -``` +Usage: zenstack generate [options] -#### Arguments +Run code generation plugins. -| Name | Description | Default | -| ---- | ------------ | -------------- | -| path | Project path | current folder | +Options: + --schema schema file (with extension .zmodel). Defaults to "zenstack/schema.zmodel" unless + specified in package.json. + -o, --output default output directory for code generation + -h, --help display help for command +``` -### init +### migrate -Initializes an existing project to use ZenStack. +Run database schema migration related tasks. ```bash -zenstack init [options] [path] -``` +Usage: zenstack migrate [options] [command] -#### Arguments +Run database schema migration related tasks. -| Name | Description | Default | -| ---- | ------------ | -------------- | -| path | Project path | current folder | +Options: + -h, --help display help for command -#### Options +Commands: + dev [options] Create a migration from changes in schema and apply it to the database. + reset [options] Reset your database and apply all migrations, all data will be lost. + deploy [options] Deploy your pending migrations to your production/staging database. + status [options] Check the status of your database migrations. + resolve [options] Resolve issues with database migrations in deployment databases + help [command] display help for command +``` -| Name | Description | Default | -| --------------------- | ------------------------------------------------ | ----------------------------------------- | -| --prisma | location of Prisma schema file to bootstrap from | <project path>/prisma/schema.prisma | -| -p, --package-manager | package manager to use: "npm", "yarn", or "pnpm" | auto detect | -| --no-version-check | do not check for new versions of ZenStack | false | +#### migrate dev -#### Examples +Create a migration from changes in schema and apply it to the database. -Initialize current folder with default settings. +:::warning +For development only. Do not use this command in production. +::: ```bash -npx zenstack init -``` +Usage: zenstack migrate dev [options] -Initialize "myapp" folder with custom package manager and schema location. +Create a migration from changes in schema and apply it to the database. -```bash -npx zenstack init -p pnpm --prisma prisma/my.schema myapp +Options: + --schema schema file (with extension .zmodel). Defaults to "zenstack/schema.zmodel" unless + specified in package.json. + -n, --name migration name + --create-only only create migration, do not apply + --migrations path that contains the "migrations" directory + -h, --help display help for command ``` -### generate +#### migrate reset + +Reset your database and apply all migrations, all data will be lost. -Generates Prisma schema and other artifacts as specified by "plugin"s in ZModel. +:::danger +Never run this command in production. It will drop all data in the database. +::: ```bash -zenstack generate [options] -``` +Usage: zenstack migrate reset [options] -#### Arguments +Reset your database and apply all migrations, all data will be lost. -| Name | Description | Default | -| ---- | ------------ | -------------- | -| path | Project path | current folder | +Options: + --schema schema file (with extension .zmodel). Defaults to "zenstack/schema.zmodel" unless + specified in package.json. + --force skip the confirmation prompt + --migrations path that contains the "migrations" directory + -h, --help display help for command +``` -#### Options +#### migrate deploy -| Name | Description | Default | -| --------------------- | ------------------------------------------------ | ---------------------- | -| --schema | schema file (with extension .zmodel) | ./schema.zmodel | -| -o, --output <path> | 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 | +Deploy your pending migrations to your production/staging database. -You can also specify the ZModel schema location in the "package.json" file of your project like the following: +```bash +Usage: zenstack migrate deploy [options] -```json title="package.json" -{ - "zenstack": { - "schema": "./db/schema.zmodel" - } -} +Deploy your pending migrations to your production/staging database. + +Options: + --schema schema file (with extension .zmodel). Defaults to "zenstack/schema.zmodel" unless + specified in package.json. + --migrations path that contains the "migrations" directory + -h, --help display help for command ``` -#### Examples +#### migrate status -Generate with default settings. +Check the status of your database migrations. ```bash -npx zenstack generate +Usage: zenstack migrate status [options] + +Check the status of your database migrations. + +Options: + --schema schema file (with extension .zmodel). Defaults to "zenstack/schema.zmodel" unless + specified in package.json. + --migrations path that contains the "migrations" directory + -h, --help display help for command ``` -Generate with custom schema location. +#### migrate resolve + +Resolve issues with database migrations in deployment databases. ```bash -npx zenstack generate --schema src/my.zmodel +Usage: zenstack migrate resolve [options] + +Resolve issues with database migrations in deployment databases. + +Options: + --schema schema file (with extension .zmodel). Defaults to "zenstack/schema.zmodel" unless + specified in package.json. + --migrations path that contains the "migrations" directory + --applied record a specific migration as applied + --rolled-back record a specific migration as rolled back + -h, --help display help for command ``` -### repl +### db -Starts a REPL session. You should run the command inside the package where you ran `zenstack generate`. +Manage your database schema during development. ```bash -npx zenstack repl -``` +Usage: zenstack db [options] [command] -You can call PrismaClient methods interactively in the REPL session. The following variables are available in the REPL session. +Manage your database schema during development. -- `prisma` +Options: + -h, --help display help for command - The original PrismaClient instance (without ZenStack enhancement). +Commands: + push [options] Push the state from your schema to your database + help [command] display help for command +``` -- `db` +#### db push - The ZenStack enhanced PrismaClient instance. +Push the state from your schema to your database. -You don't need to `await` the Prisma method call result. The REPL session will automatically await and print the result. +```bash +Usage: zenstack db push [options] -#### Options +Push the state from your schema to your database. -| Name | Description | Default | -| ----- | ------------------- | ------- | -| --debug | Enable debug output. Can be toggled on the fly in the repl session with the ".debug" command. | false | -| --table | Enable table format. Can be toggled on the fly in the repl session with the ".table" command. | false | -| --prisma-client <path> | Path to load PrismaClient module. | "node_modules/.prisma/client" | -| --load-path <path> | Path to load modules generated by ZenStack. | "node_modules/.zenstack" | +Options: + --schema schema file (with extension .zmodel). Defaults to "zenstack/schema.zmodel" + unless specified in package.json. + --accept-data-loss ignore data loss warnings + --force-reset force a reset of the database before push + -h, --help display help for command +``` -#### Repl Commands +### info -You can use the following commands in the REPL session. +Get information of installed ZenStack packages. -- `.debug [on|off]` - - Toggle debug output. +```bash +Usage: zenstack info [options] [path] -- `.table [on|off]` +Get information of installed ZenStack. - Toggle table format. +Arguments: + path project path (default: ".") -- `.auth [user object]` +Options: + -h, --help display help for command +``` - Set current user. E.g.: `.auth { id: 1 }`. Run the command without argument to reset to anonymous user. +### init -#### Examples +Initialize an existing project for ZenStack. -Start the session: ```bash -npx zenstack repl -``` - -Inside the session: -```ts -> prisma.user.findMany() -[ - { - id: '7aa301d2-7a29-4e1e-a041-822913a3ea78', - createdAt: 2023-09-05T04:04:43.793Z, - updatedAt: 2023-09-05T04:04:43.793Z, - email: 'yiming@whimslab.io', - ... - } -] +Usage: zenstack init [options] [path] -> .auth { id: '7aa301d2-7a29-4e1e-a041-822913a3ea78' } -Auth user: { id: '7aa301d2-7a29-4e1e-a041-822913a3ea78' }. Use ".auth" to switch to anonymous. +Initialize an existing project for ZenStack. -> .table -Table output: true +Arguments: + path project path (default: ".") -> db.list.findMany({select: { title: true, private: true}}) -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ (index) β”‚ title β”‚ private β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ 0 β”‚ 'L1' β”‚ false β”‚ -β”‚ 1 β”‚ 'Wonderful new world' β”‚ false β”‚ -β”‚ 2 β”‚ 'Model for a space in which users can collaborate' β”‚ false β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +Options: + -h, --help display help for command ``` -### format +### check -Format a ZenStack schema file. +Check a ZModel schema for syntax or semantic errors. ```bash -zenstack format [options] +Usage: zenstack check [options] + +Check a ZModel schema for syntax or semantic errors. + +Options: + --schema schema file (with extension .zmodel). Defaults to "zenstack/schema.zmodel" unless + specified in package.json. + -h, --help display help for command ``` -#### Options +## Overriding Default Options -| Name | Description | Default | -| --------------------- | ------------------------------------------------ | ---------------------- | -| --schema | schema file (with extension .zmodel) | ./schema.zmodel | +### Default Schema Location -You can also specify the ZModel schema location in the "package.json" file of your project like the following: +You can override the default path that the CLI loads the schema by adding the following key to your `package.json`: -```json title="package.json" +```json { "zenstack": { - "schema": "./db/schema.zmodel" + "schema": "path/to/your/schema.zmodel" } } ``` -### check +### Default Output Directory -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. +You can override the default code generation output path that the CLI uses by adding the following key to your `package.json`: -```bash -zenstack check [options] +```json +{ + "zenstack": { + "output": "path/to/your/output/directory" + } +} ``` - -#### Options - -| Name | Description | Default | -| --------------------- | ------------------------------------------------ | ---------------------- | -| --schema | schema file (with extension .zmodel) | ./schema.zmodel | diff --git a/versioned_docs/version-3.x/reference/zmodel/function.md b/versioned_docs/version-3.x/reference/zmodel/function.md index c4608840..1e91123b 100644 --- a/versioned_docs/version-3.x/reference/zmodel/function.md +++ b/versioned_docs/version-3.x/reference/zmodel/function.md @@ -137,7 +137,7 @@ values to the ID values of the created records based on the sequence. function dbgenerated(expr: String): Any {} ``` -Represents default values that cannot be expressed in the Prisma schema (such as random()). +Represents default values that cannot be expressed in ZModel (such as random()). ### auth() diff --git a/versioned_docs/version-3.x/reference/zmodel/import.md b/versioned_docs/version-3.x/reference/zmodel/import.md index 97402358..6d0cab02 100644 --- a/versioned_docs/version-3.x/reference/zmodel/import.md +++ b/versioned_docs/version-3.x/reference/zmodel/import.md @@ -12,7 +12,7 @@ ZModel allows to import other ZModel files. This is useful when you want to spli import IMPORT_SPEC ``` -- *IMPORT_SPEC**: +- **IMPORT_SPEC**: Path to the ZModel file to be imported. It can be: diff --git a/versioned_docs/version-3.x/welcome.md b/versioned_docs/version-3.x/welcome.md index fa3bd385..b59821c0 100644 --- a/versioned_docs/version-3.x/welcome.md +++ b/versioned_docs/version-3.x/welcome.md @@ -7,7 +7,7 @@ sidebar_position: 1 # Welcome -Welcome to ZenStack - the modern data layer for your TypeScript application! +Welcome to ZenStack - the data layer for modern TypeScript applications. ZenStack is built with the belief that most applications should use the data model as their center pillar. If that model is well-designed, it can serve as the single source of truth throughout the app's lifecycle and be used to derive many other aspects of the app. The result is a smaller, more cohesive code base that scales well as your team grows while maintaining a high level of developer experience. From 07209d78885e171a09953a121c4f3cda30062c3f Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Tue, 19 Aug 2025 15:38:32 +0800 Subject: [PATCH 32/51] updates --- .../version-3.x/_components/_zmodel-starter.md | 2 +- versioned_docs/version-3.x/migrate-prisma.md | 6 +++--- versioned_docs/version-3.x/modeling/index.md | 2 +- versioned_docs/version-3.x/modeling/model.md | 10 +++++----- versioned_docs/version-3.x/modeling/polymorphism.md | 6 +++--- versioned_docs/version-3.x/modeling/relation.md | 8 ++++---- versioned_docs/version-3.x/orm/index.md | 4 ++-- .../version-3.x/reference/zmodel/datasource.md | 2 +- versioned_docs/version-3.x/reference/zmodel/model.md | 8 ++++---- versioned_docs/version-3.x/reference/zmodel/plugin.md | 2 +- versioned_docs/version-3.x/reference/zmodel/type.md | 2 +- 11 files changed, 26 insertions(+), 26 deletions(-) diff --git a/versioned_docs/version-3.x/_components/_zmodel-starter.md b/versioned_docs/version-3.x/_components/_zmodel-starter.md index bfff33d5..b02e72d3 100644 --- a/versioned_docs/version-3.x/_components/_zmodel-starter.md +++ b/versioned_docs/version-3.x/_components/_zmodel-starter.md @@ -1,7 +1,7 @@ ```zmodel datasource db { provider = 'sqlite' - url = "file:./dev.db" + url = 'file:./dev.db' } model User { diff --git a/versioned_docs/version-3.x/migrate-prisma.md b/versioned_docs/version-3.x/migrate-prisma.md index 3b3bd047..acc70e5d 100644 --- a/versioned_docs/version-3.x/migrate-prisma.md +++ b/versioned_docs/version-3.x/migrate-prisma.md @@ -159,7 +159,7 @@ ZenStack has its own CLI plugin system and doesn't support Prisma custom generat } ``` -2. Run a`prisma generate` command after `zen generate` with the prisma schema as input. +2. Run a `prisma generate` command after `zen generate` with the prisma schema as input. ```json { @@ -175,7 +175,7 @@ ZenStack has its own [runtime plugin mechanism](./orm/plugins/) and doesn't plan **1. Query extension** -[Query extension](https://www.prisma.io/docs/orm/prisma-client/client-extensions/query) allows you to intercepts ORM query calls. +[Query extension](https://www.prisma.io/docs/orm/prisma-client/client-extensions/query) allows you to intercept ORM query calls. Suppose you have an extension like: @@ -258,4 +258,4 @@ export const db = new ZenStackClient(schema, { }); ``` -The biggest difference is ZenStack's computed fields are evaluated on the database side, which much more efficient and flexible than client-side computation. Read more in the [Computed Fields](./orm/computed-fields.md) documentation. +A key difference is that ZenStack's computed fields are evaluated on the database side, which much more efficient and flexible than client-side computation. Read more in the [Computed Fields](./orm/computed-fields.md) documentation. diff --git a/versioned_docs/version-3.x/modeling/index.md b/versioned_docs/version-3.x/modeling/index.md index 6ed0aa9b..6aace027 100644 --- a/versioned_docs/version-3.x/modeling/index.md +++ b/versioned_docs/version-3.x/modeling/index.md @@ -39,7 +39,7 @@ model Post { content String published Boolean @default(false) author User @relation(fields: [authorId], references: [id]) - authorId String + authorId Int } ``` diff --git a/versioned_docs/version-3.x/modeling/model.md b/versioned_docs/version-3.x/modeling/model.md index 4b9e50ae..f51c3f8f 100644 --- a/versioned_docs/version-3.x/modeling/model.md +++ b/versioned_docs/version-3.x/modeling/model.md @@ -21,7 +21,7 @@ model User { } ``` -The simplest models are just a collection of fields. A model must be uniquely identifiable by some of its fields. For most cases, you'll have a field marked with the `@id` attribute (more about [attributes](./attribute) later). +The simplest models are just a collection of fields. A model must be uniquely identifiable by some of its fields. In most cases, you'll have a field marked with the `@id` attribute (more about [attributes](./attribute) later). ```zmodel model User { @@ -115,7 +115,7 @@ Each model field must at least have a name and a type. A field can be typed in o ``` 4. Custom type - ZenStack allows you to define custom types in the schema and use them to type JSON fields. This will be covered in more detail in the [Custom Type](./custom-type) section. + ZenStack allows you to define custom types in the schema and use them to type JSON fields. This is covered in more detail in the [Custom Type](./custom-type) section. ```zmodel type Address { @@ -144,7 +144,7 @@ model User { } ``` -A default value can be specified for a field with the `@default` attribute. The value can be a literal, or a supported function call, including: +A default value can be specified for a field with the `@default` attribute. The value can be a literal, an enum value, or a supported function call, including: - `now()`: returns the current timestamp - `cuid()`: returns a CUID @@ -156,8 +156,8 @@ A default value can be specified for a field with the `@default` attribute. The ```zmodel model User { - id Int @id @default(autoincrement()) - role Role @default("USER") + id Int @id @default(autoincrement()) + role Role @default(USER) createdAt DateTime @default(now()) } ``` diff --git a/versioned_docs/version-3.x/modeling/polymorphism.md b/versioned_docs/version-3.x/modeling/polymorphism.md index 384b1b84..7192354b 100644 --- a/versioned_docs/version-3.x/modeling/polymorphism.md +++ b/versioned_docs/version-3.x/modeling/polymorphism.md @@ -25,7 +25,7 @@ It may be tempting to use mixins to share the common fields, however it's not an - There's no efficient and clean way to query all content types together (e.g., all content owned by a user). - Consequently, whenever you add a new content type, you'll need to modify the `User` model, and probably lots of query code too. -A true solution involves having a in-database model of polymorphism, where we really have a `Content` table that serves as an intermediary between `User` and the concrete content types. This is what ZModel polymorphism is about. +A true solution involves having an in-database model of polymorphism, where we really have a `Content` table that serves as an intermediary between `User` and the concrete content types. This is what ZModel polymorphism is about. :::info There are [two main ways](https://www.prisma.io/docs/orm/prisma-schema/data-model/table-inheritance) to model polymorphism in relational databases: single-table inheritance (STI) and multi-table inheritance (MTI, aka. "Delegate Types"). ZModel only supports MTI. @@ -99,12 +99,12 @@ erDiagram Video ||--|| Content: delegates ``` -There are two special things about polymorphic base model: +There are two special things about a polymorphic base model: 1. It must have a "discriminator" field that stores the concrete model type that it should "delegate" to. In the example above, the `type` field serves this purpose. It can be named anything you like, but must be of `String` or enum type. 2. It must have a `@@delegate` attribute. The attribute serves two purposes: it indicates that the model is a base model, and it designates the discriminator field with its parameter. -You can also have a deep hierarchy involving multiple level of base models. Just need to make sure each base model has its own discriminator field and `@@delegate` attribute. Extending from multiple base models directly is not supported. +You can also have a deep hierarchy involving multiple levels of base models. Just need to make sure each base model has its own discriminator field and `@@delegate` attribute. Extending from multiple base models directly is not supported. ## Migration behavior diff --git a/versioned_docs/version-3.x/modeling/relation.md b/versioned_docs/version-3.x/modeling/relation.md index 030135a3..fc06ee92 100644 --- a/versioned_docs/version-3.x/modeling/relation.md +++ b/versioned_docs/version-3.x/modeling/relation.md @@ -5,7 +5,7 @@ description: Relations in ZModel # Relation -Relation is a fundamental concept in relational databases. It lets you connect models into a graph, and allows you to query interconnected data efficiently. In ZModel, relations are modeled using the `@relation` attribute. For most cases, it involves one side of the relation defining a foreign key field that references the primary key of the other side. By convention, we call the model that holds the foreign key the "owner" side. +Relations are a fundamental concept in relational databases. They connect models into a graph and allow you to query interconnected data efficiently. In ZModel, relations are modeled using the `@relation` attribute. In most cases, it involves one side of the relation defining a foreign key field that references the primary key of the other side. By convention, we call the model that holds the foreign key the "owner" side. ## One-to-one relation @@ -272,13 +272,13 @@ enum ReferentialAction { ```zmodel model User { - id String @id + id String @id profile Profile? } model Profile { - id String @id - user @relation(fields: [userId], references: [id], onUpdate: Cascade, onDelete: Cascade) + id String @id + user User @relation(fields: [userId], references: [id], onUpdate: Cascade, onDelete: Cascade) userId String @unique } ``` diff --git a/versioned_docs/version-3.x/orm/index.md b/versioned_docs/version-3.x/orm/index.md index e39d720c..b765facd 100644 --- a/versioned_docs/version-3.x/orm/index.md +++ b/versioned_docs/version-3.x/orm/index.md @@ -48,7 +48,7 @@ ZenStack ORM comes with a powerful built-in access control system. You can defin ```zmodel model Post { id Int @id - title String @length(1, 256) + title String published Boolean @default(false) author User @relation(fields: [authorId], references: [id]) authorId Int @@ -71,7 +71,7 @@ Real-world applications often involves storing polymorphic data which is notorio ```zmodel model Content { id Int @id - name String @length(1, 256) + name String type String // the ORM uses the `type` field to determine to which concrete model diff --git a/versioned_docs/version-3.x/reference/zmodel/datasource.md b/versioned_docs/version-3.x/reference/zmodel/datasource.md index 1bdc5368..2213ed6f 100644 --- a/versioned_docs/version-3.x/reference/zmodel/datasource.md +++ b/versioned_docs/version-3.x/reference/zmodel/datasource.md @@ -17,7 +17,7 @@ datasource NAME { - **NAME**: - Name of the data source. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. Name is only informational and serves no other purposes. + Name of the data source. Must be a valid identifier. Name is only informational and serves no other purposes. - **`provider`**: diff --git a/versioned_docs/version-3.x/reference/zmodel/model.md b/versioned_docs/version-3.x/reference/zmodel/model.md index 7cc50325..aa0624f6 100644 --- a/versioned_docs/version-3.x/reference/zmodel/model.md +++ b/versioned_docs/version-3.x/reference/zmodel/model.md @@ -4,7 +4,7 @@ sidebar_position: 2 # Model -Models represent the business entities of your application. A model can have zero or more [mixins](../../modeling/mixin.md), and zero or more [polymorphic base models](../../modeling/polymorphism.md). +Models represent the business entities of your application. A model can have zero or more [mixins](../../modeling/mixin.md), and zero or one [polymorphic base models](../../modeling/polymorphism.md). ## Syntax @@ -16,7 +16,7 @@ model NAME (with MIXIN_NAME(,MIXIN_NAME)*)? (extends BASE_NAME)? { ``` - **NAME**: - Name of the model. Needs to be unique in the entire schema. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. + Name of the model. Needs to be unique in the entire schema. Must be a valid identifier. - **FIELD**: @@ -36,9 +36,9 @@ model NAME (with MIXIN_NAME(,MIXIN_NAME)*)? (extends BASE_NAME)? { ## Note -A model must be uniquely identifiable by one or several of its fields. For most cases, you'll have a field marked with the `@id` attribute. If needed, you can use multiple fields as unique identifier by using the `@@id` model-level attribute. +A model must be uniquely identifiable by one or several of its fields. In most cases, you'll have a field marked with the `@id` attribute. If needed, you can use multiple fields as unique identifier by using the `@@id` model-level attribute. -If no `@id` or `@@id` is specified, field(s) marked with the `@unique` or `@@unique` attribute will be used as fallback identifier. +If no `@id` or `@@id` is specified, the field(s) marked with the `@unique` or `@@unique` attribute will be used as fallback identifier. ## Example diff --git a/versioned_docs/version-3.x/reference/zmodel/plugin.md b/versioned_docs/version-3.x/reference/zmodel/plugin.md index 6fa84bd6..a5a5d9ce 100644 --- a/versioned_docs/version-3.x/reference/zmodel/plugin.md +++ b/versioned_docs/version-3.x/reference/zmodel/plugin.md @@ -17,7 +17,7 @@ plugin PLUGIN_NAME { - **PLUGIN_NAME** - Name of the plugin. Needs to be unique in the entire model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. + Name of the plugin. Needs to be unique in the entire model. Must be a valid identifier. - **`provider`** diff --git a/versioned_docs/version-3.x/reference/zmodel/type.md b/versioned_docs/version-3.x/reference/zmodel/type.md index 2585b7fe..22b78387 100644 --- a/versioned_docs/version-3.x/reference/zmodel/type.md +++ b/versioned_docs/version-3.x/reference/zmodel/type.md @@ -20,7 +20,7 @@ type NAME { - **NAME**: - Name of the model. Needs to be unique in the entire model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. + Name of the model. Needs to be unique in the entire model. Must be a valid identifier. - **FIELD**: From 16d96b1e2dfbd97214356648602aaa26920b7f73 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Tue, 19 Aug 2025 15:47:09 +0800 Subject: [PATCH 33/51] update --- versioned_docs/version-3.x/reference/zmodel/plugin.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versioned_docs/version-3.x/reference/zmodel/plugin.md b/versioned_docs/version-3.x/reference/zmodel/plugin.md index a5a5d9ce..d2350ab2 100644 --- a/versioned_docs/version-3.x/reference/zmodel/plugin.md +++ b/versioned_docs/version-3.x/reference/zmodel/plugin.md @@ -25,7 +25,7 @@ plugin PLUGIN_NAME { - **OPTION** - A plugin configuration option, in form of "[NAME] = [VALUE]". Option values can be literal, array, or object. + A plugin configuration option, in form of "NAME = VALUE". Option values can be literal, array, or object. ## Example From 25822c83386c5cd72c532850e6299101beeb705d Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Wed, 20 Aug 2025 16:43:47 +0800 Subject: [PATCH 34/51] update --- .../version-3.x/orm/computed-fields.md | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/versioned_docs/version-3.x/orm/computed-fields.md b/versioned_docs/version-3.x/orm/computed-fields.md index 889cca12..fc9fd74b 100644 --- a/versioned_docs/version-3.x/orm/computed-fields.md +++ b/versioned_docs/version-3.x/orm/computed-fields.md @@ -30,15 +30,33 @@ model User { Then, when creating a `ZenStackClient`, provide the implementation of the field using the Kysely query builder. ```ts -import { ZenStackClient } from '@zenstackhq/runtime'; - const db = new ZenStackClient(schema, { ... computedFields: { User: { postCount: (eb) => eb.selectFrom('Post') - .whereRef('Post.authorId', '=', 'User.id') + .whereRef('Post.authorId', '=', 'id') + .select(({fn}) => fn.countAll().as('count')), + }, + }, +}); +``` + +The computed field callback is also passed with a second `context` argument containing other useful information related to the current query. For example, you can use the `currentModel` property to refer to the containing model and use it to qualify field names in case of conflicts. + +```ts +import { sql } from 'kysely'; + +const db = new ZenStackClient(schema, { + ... + computedFields: { + User: { + postCount: (eb, { currentModel }) => + eb.selectFrom('Post') + // the `currentModel` context property gives you a name that you can + // use to address the containing model (here `User`) at runtime + .whereRef('Post.authorId', '=', sql.ref(currentModel, 'id')) .select(({fn}) => fn.countAll().as('count')), }, }, From 192910f4a799baf0e66e3f81d5e82193b4f3bb0c Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Thu, 21 Aug 2025 19:43:10 +0800 Subject: [PATCH 35/51] update --- .../version-3.x/modeling/_category_.yml | 2 +- versioned_docs/version-3.x/orm/_category_.yml | 2 +- versioned_docs/version-3.x/orm/errors.md | 20 +++++++++++++++++ versioned_docs/version-3.x/orm/migration.md | 5 ++--- versioned_docs/version-3.x/prerequisite.md | 21 ++++++++++++++++++ .../version-3.x/recipes/_category_.yml | 7 ------ versioned_docs/version-3.x/roadmap.md | 1 + versioned_docs/version-3.x/vscode.png | Bin 0 -> 434009 bytes 8 files changed, 46 insertions(+), 12 deletions(-) create mode 100644 versioned_docs/version-3.x/orm/errors.md create mode 100644 versioned_docs/version-3.x/prerequisite.md delete mode 100644 versioned_docs/version-3.x/recipes/_category_.yml create mode 100644 versioned_docs/version-3.x/vscode.png diff --git a/versioned_docs/version-3.x/modeling/_category_.yml b/versioned_docs/version-3.x/modeling/_category_.yml index 2df4bdd6..9f8d1691 100644 --- a/versioned_docs/version-3.x/modeling/_category_.yml +++ b/versioned_docs/version-3.x/modeling/_category_.yml @@ -1,4 +1,4 @@ -position: 2 +position: 3 label: Data Modeling collapsible: true collapsed: true diff --git a/versioned_docs/version-3.x/orm/_category_.yml b/versioned_docs/version-3.x/orm/_category_.yml index 6f69cf50..8e6b7172 100644 --- a/versioned_docs/version-3.x/orm/_category_.yml +++ b/versioned_docs/version-3.x/orm/_category_.yml @@ -1,4 +1,4 @@ -position: 3 +position: 4 label: ORM collapsible: true collapsed: true diff --git a/versioned_docs/version-3.x/orm/errors.md b/versioned_docs/version-3.x/orm/errors.md new file mode 100644 index 00000000..2c8db21a --- /dev/null +++ b/versioned_docs/version-3.x/orm/errors.md @@ -0,0 +1,20 @@ +--- +sidebar_position: 16 +description: ORM Errors +--- + +# Errors + +The ORM uses the following error classes from `@zenstackhq/runtime` to represent different types of failures: + +## `ValidationError` + +This error is thrown when the argument passed to the ORM methods is invalid, e.g., missing required fields, or containing unknown fields. The `cause` property is set to the original error thrown during validation. + +## `NotFoundError` + +This error is thrown when a requested record is not found in the database, e.g., when calling `findUniqueOrThrow`, `update`, etc. + +## `QueryError` + +This error is used to encapsulate all other errors thrown from the underlying database driver. The `cause` property is set to the original error thrown. diff --git a/versioned_docs/version-3.x/orm/migration.md b/versioned_docs/version-3.x/orm/migration.md index 80d894b1..90bac71e 100644 --- a/versioned_docs/version-3.x/orm/migration.md +++ b/versioned_docs/version-3.x/orm/migration.md @@ -1,9 +1,8 @@ --- -sidebar_position: 16 -description: Schema migration introduction +sidebar_position: 17 --- -# Database Schema Migration +# Database Migration Database schema migration is a crucial aspect of application development. It helps you keep your database schema in sync with your data model and ensures deployments are smooth and predictable. ZenStack provides migration tools that create migration scripts based on the ZModel schema and apply them to the database. diff --git a/versioned_docs/version-3.x/prerequisite.md b/versioned_docs/version-3.x/prerequisite.md new file mode 100644 index 00000000..5aec199d --- /dev/null +++ b/versioned_docs/version-3.x/prerequisite.md @@ -0,0 +1,21 @@ +--- +sidebar_position: 2 +--- + +# Prerequisite + +## Node.js + +Node.js v20 or above. + +## TypeScript + +TypeScript v5.8.0 or above. + +## IDE Extension + +If you use VSCode, please install the [ZenStack VSCode Extension](https://marketplace.visualstudio.com/items?itemName=zenstack.zenstack) for syntax highlighting, auto-completion, and error reporting. Make sure you switch to the prerelease version that's compatible with v3. + +![VSCode Extension](./vscode.png) + +Other IDEs are not supported at this time. diff --git a/versioned_docs/version-3.x/recipes/_category_.yml b/versioned_docs/version-3.x/recipes/_category_.yml deleted file mode 100644 index acb7bc3f..00000000 --- a/versioned_docs/version-3.x/recipes/_category_.yml +++ /dev/null @@ -1,7 +0,0 @@ -position: 5 -label: Recipes -collapsible: true -collapsed: true -link: - type: generated-index - title: Recipes diff --git a/versioned_docs/version-3.x/roadmap.md b/versioned_docs/version-3.x/roadmap.md index 0e9555f0..f46b901d 100644 --- a/versioned_docs/version-3.x/roadmap.md +++ b/versioned_docs/version-3.x/roadmap.md @@ -10,3 +10,4 @@ sidebar_position: 11 - [ ] Performance benchmark - [ ] Query-as-a-Service (automatic CRUD API) - [ ] Json filter +- [ ] Custom procedures \ No newline at end of file diff --git a/versioned_docs/version-3.x/vscode.png b/versioned_docs/version-3.x/vscode.png new file mode 100644 index 0000000000000000000000000000000000000000..35b10df9e840d3c0b2757894a6ec7b039dca190c GIT binary patch literal 434009 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

_Y%)T=G(bk#^&w1eRt-pP?44*57GzMv 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

qYs_|!s-9rXd02wqlMLRq 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�_ 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%0Do6o*aKe7!-kZOugM) zXi9i1x;_b!%r$H{8=h(?S=V(^WjV%{Z-ram>yb?*oNQz1Hjc z3c|SdmdB|77>-CiS0CnFGef4V&hEugq-lU_c3f(Kp3^l0UvjW9qTZWjL?L;Z+y7&7 z>gi>MH-2x4On7>#z>Lwjpc2A{mJa0Zm+sVMe3= z^y&KGByHvu?Kbb=WgFk64nY|vTM9i7+;l4Kiboao=jNeh4KI*n)4pY6cJ|7dN$?Ss z7n1YOUzxaUc~NhKT8>0kVWD$V%*Tma@A!N}T~L=H>kDjyx>B7E_~;CFYu7 z2}KHlatf!;u220GPD#G#blHw`WMKFzhBY5y$IV_`BTY=L2}G8r!MgLmzD{LgTUn#p zwB#WMhV*6~kg*vg0gRnUFpPKpC z*I%D(#RN^{B@;S}#S^-!0*?h}5+6-g8dnQ_V|RBAqY&dm7dH!lwVk`$T~zcgG#ITF z8#Q}x_U0qd6VTq4b*f0VGB|tRV;5cWPnKGPiz7BPS*<}ejydKCi_#O5LRdaEbZn*6 za>k&%PddUzI6=P|E^;PR_pWQ(?;ng(c*FI}cCn` z{%-h$JqxnbnpS5Z=b6K4V_^5^Huqx`k9 ziWtl*Cv(6rOj*zZ*_w|ej2(xCBm~RvON|3q_I14K* zoDB1K-MdMyA3PDsm6bM0dUx{4Cq@~m56(Shb8MhMOddm8eH>ET?8B@oDLbYq5#%y$ z8nG8g0MaI+{Ze~I82Q*zP!E~#rJehY6*p0h*qieAB0O}Dexyg|V@~mVW=B*__wiZ2 z@uZofdZ0IQ>d~Po1v@j|ejeD{l?LL(Ra2hxJ&R?buPWl|GUF$4|L~s7z-LTpq_XPI zw|QJ+Yp0jsz0SQ)ks&fRCi0>SwN9W~s@*ZMd(+pI-~gw^sZ9N_d3Lo3x-fVWj9aDz zQ>4qUvV4t;%iz0w4Pl@`IgM%&(yII%ibWS2ckzwYsc6o}Eu4)LWwg7%OW_cL8$o=u z(B(iGl5fwKY9O3Wh}LF5;SaXs5%=aapwb`Vg`4c+Rq1m$rmeFVE%gO3{gvZ>_X6)j zYB;7X-(Qhsv{w2*f+wCKJ~%nuF=G9%$LI-Oe65z#Iqdq?o2!c0hW-iP4R+8@O?DFj z`vT<_3}=PbJ#h8WNmE)~7FdW#_|eicfAcLKr&_PE&vUl!^@@Yx`;w68bY#eVpG^f2 zAKS3#Qk^8N(s~dz-ur;PswS+NMWwm(1%)D#c=%EY2hWypQ6lABV;V_Z^|X0h1%Wqt z*Ytxu7xJ;v#VQJ^KJ-I9?fKG&&}93`0Q_h91u3A*!VV}jzEQ(m4cohbl;(moiZbcsli~6r0w|VN+YDua;kIyy! z$LFzkgu5oL_n&Sb%O1TBK~B&xXdoV)s}AN;;xhw|CvZoC6CiMbaMUmMe&`$Q)(7%G zP%*q!2-I&#+alLrtpDUJ#G-HX-Syqk&iK;3gg<^)4&DD8$<&G$6NEziKnOM!3!#eG zM*EkE)GXWwqn**cXSOz8}z-&_b=v!S#cXla0 zloW&;)h58Gz~7b`vV4C?kbCl>@X=8dZ*z@(-lI<<*@#K;AyJxo$$pAdwJb<*{C~m6 z5i<114fkfO>i!QFE!oxDe=kA!T`g%OWezi*u}pZ}ZW#7$a37XCgIpNzDo}m6F}3Ad zep~UO4nM;Kh|$mB9Y5LL=-Cjl71obl(r4C!Jx$6$ zMot6n&3s~dkYY0ntknFygDd9`y~J(8+O}p%FY5SCs^=C>aNPI+S}bNwaD*fa({(Wg2olD;whIqVDtY=+2G3)0ue0s>&P#R* z7dg_>(T@wJoca989@sj&Y=pbWm|~DZh1L!Ra?sdpSG9OWT?>_%uz(3mZMdjt8a=0#PF$f< z7hvpzcodCU5ldq&Zl(v^2eT-IVES3%>A|mj8x^y6FA0I(e3DSflFr>^*4)C349jnu zu&+aM0-z62waVTth(x~-!&6JwdhgftM3ejL7cfe?y%RLJrXM}(YnnJc41`3<@7pcB zj>`SMWVA(SF1V01uNM(mNVyIB!F2v^eZQo$_9nRkBEKrt*7$9n9oF)roj&cO9=d>j z-;ghU*tIgutA$1|oD+Piug?6s(BPguHXxrX&X+|b=v&S?v}#LG@R!XeY|*A$Jr`vv za7`;Pu`qDn0*lW~${G7p`epkU=a#|)8@6t}>mQ5{LNsbMb4^T5tFgXFNbH}j=shm= zCl-T&-p#i@zcgl+k0eoYA-;QP5w}dDzFt&~QeY}0ofn8T#g;daai>9b9)^2ir5%o? zUvK(lGEu!<{p2gD_X6}sn;BBPEk~t5}#a)Q3HT$r*ajbZ+8?6|mh$g~c*)jLhvu8kVA3x5goeH6U&;T5z zzbBD%k~vJ7*BD%%dDZ2L{8DM{W+?f@{>s-!9i5#xN+7wMB{2v^K5xvURw0JkN^bUT&)|Xgo z1kNl_x?yMhXw!^<2ZQ?F&B6>OynOrRy z-m9V*2$#Sf25>6u3GYzesD+p7!0qUvh|Q2>h@}AqW8SYSQ=TevG4c8;z%nWDADGW^ zF6!YDos9(Y7ghf{KgDmVct!97J`)GSKP3J(4HVbHWG2>!+ffT7N((2%VjQ+$C;l={mNNzUax3)gYOh-r0db_ z3ItgXu@i7(LUB(}?s(9#^g^NRBvD7FaxkM;zN?@k`WKhit)9AiGAGk!zI@6L+Kmy$ zT=GXF?^=t>Bc_v%Z94jj@+TIu9@#&2pniJ!a@VpECq@Hzr*hrW&%{=kJad;qYgZJ5 z8zMu4g{JpZb|4%VcWo&;J$oMZ;V6j~LkQn8YF`=&+8hkhoAKxEzR3b{25>QKL zCqS)jIe$pSJf?%^R=3Zab9G`!S}+qk&lTMak7nYVlyvw~DWP@#AP2D~I0~7dMp5T7 z)N*X~2ojkcARqwScyPyJR;*6$M}&$^&v#TnaKO z4(bx-Mj)QHh)Zam(AvibgHX(;yo{C+uO~uipA0@6qP=Vt&Wr=BmnM~i|DYeZj9jEn zq`mUp6BFGJPV&HU&+E1G9`n@4<;rN@&^HA*_Vws3f0Hxtn^T6rV(6~HnHVN(>l(G( z=Zylv$Vhp>lwKRz_zN+h1Rxy**;Y%-(dR>o0x64;^fwblmFj`ohOcQos~Kf{tyk_S zwcmT295esoA%p5oxJBnkW1%7LonD2%!LC;CKZ@DRKT~%M>iCGdP3gCvQ7bwgS2>Vu z+iko!e6yc=UdiGt7CaQ28HfATNZwX^(9dwOj-&KCLZZMw-0tbC_+ALHkFoJf|DIp2 zWcoCxc3sOO{1Fyjyv;`{p+F=1$#MfsA5QzXU-kM?U3~)AOTG$yYa~HnT1!v77O?c^ z>ni!h@{c%R^q^M{FV=?CQ7|WT+HcWmbY*i#`K+_M z&E?kGo~(Y><5pbO^w0Fq55&Lw?Up5S4QGQsN~T=?ZS`lMeyB1J1nCHeNZr7;yB3(B z_EG1JoY0HCIhNg=d-*s$gYhdmC3KfqUK@q9@3d_Lg2$)u3)9bt28B3dhS1z zp+YhNEf>DYX)Ub)VWmM>)?<1)ZV?8F>&(raP=xdk>Iqw4-w%2dhciz0C>mX3)E~8> zTpqYwsezkvcndYbE@xpX9CWR#d7L&#yDj`SA!D`$e+;>*j-+u>Kx);@SZH*(MY!)6%$%xbtmFiR~8c z(4nx;jO)byI3i@SOg4!j`$6zumlT!~I^RmRBr|7^$DjY<#T5|bW#FSQjZmbIBMA}~ z$kQ=hAKRYcgKxvk!iA3(5Kty3zKC`l?^y$0@&0o6?4l3wq-?&D*M`xId>lBH9*<&b zulhY44)>Rs8M_ZI{jgf8s&H1}^zg?0G5<-O80m6I$81EJT4acXl9aOV{!KU`;N6QU z=@CFzjt)Z}*kCuZLgR~i%JApYNY8z4$pnvOl^Y3V54y)Bg7=cuAVhj2(={F}15t;lgHYw*28&|kX;36B*Y%$Q&R0o7 zHo4WkEJHeAT|Jb+`~dj>f$&)G(d%doIYQypX6J|J+8$3ai1y}VQLACu0i@X9@-l>* zoViqAXQ$qbzGnjxmCK+`Q{rMLwcUIGh*El8$j@RND?GkDY{n$G`_P^5jKI>C3Jsfk z+#EaCnWMY@F5Mb}hmV}akt=Wa{L^pA8bV`Aiq z%ze`N9fPUFbno`d>c*G%Poy{d$thD&BJO>nR)9Ga8N5oEI$en!A8O|^@!NLi*(b@C zdk%~^WC1U=Rjs_E(ISw_Zm_DxVie-Q+F8pas(pIl3e=(74nT~JOc5eTXUD3<-SePy zpF5NcX27sz&8rFEn3l{+PRmToz;{7&SDHT)N9ged3w$|yl+UY z%y_;(6Jqi#gyU9U06_iT=283@>ojTU==kMxXv_a={niZrmm5r!v#SB zIoIKw4Cgq{b3gZeKhNv2AEE!WL!j=|bX$J%z1+z_+bFUgH)>uzVL)M+lkqdXvq{KN zJ7SotY6xR>M8!*a-<>XZ%wA-OJx`~XQ+X~W$l=bi?OU^FX3EZr1UTdsoXZk3yu$IU zneUGG0OIY=wS$^4#%EE_-Q&iYw~5uqY0brzO5r5$y-?L>hc?Te46ATz#AM6|YoGNg z$nI8L;c48>d*aZ0lnil_&jbSH;TBu~=J~SDlqu)pG!2cDv=dNhN?mvclcDA&@$Xx$ zSzr2(ZO^ib03~{%{m=xKO9o#xqxSbd9R4E6PzM!NhObR>M_{~^T|#6-!WR;I_i_7= z9yB!8p?6jG&2nfRI2xxKQRr+0iQ zA09BH&5AGIv^>s_?dXP_2O<3~|2a5^a$#2gegDdOX^vgzwWHuG{~05HijZ&&KiFc_ zh~Kq3q*Zn(y=ZrPz82WN_v$m(n3m%%Lnsr|%`b}v7rra^m~EJ7mp!|wyh`O>UNLDF zsZ5z~X;i-6VM-9Zr_I(a_sLeB;qeE&;*0lpmS}gYp)Chx_nRdLUQ;rOmCnw8KRY|O z6-z(PAx`_@F(nlevdiplc0g2qa1b0D*vZ1h{6zfI{3{Rf9}gm5#Oe+FI&CbN8xSYN z`Ne#RmC@-F!~%q=8g1>KWjx=DEmW?_zGM+SFKEr-k4Hin_v|4@X2cqdox7Rw6Z_J@tq=GRQ8oc^ zMTKq(ne65RSZ&5G+9XC$+gPQ44wAEA-P$N4nHo;=v2dJ2=P6lp)w*YAmi_)(XGrTV zE;^W5-GUvJ+W^)FVKJJhywHe#uWBjXcn)b_ehUjVQ8s(6Q>U3YzxkZzVxAxiooY_d z0-ilQ-6GDZGBJy15oWn$%E`~mUu^bky2*^sYWl-jj@Rm6w2*5pk91ak%ujmPn)WqP zl8uA>$N~PyeLwaK)<&}VS*B{p_z`RU) zKg8IF_0N;ZB1-+6MMMsS_hHHmgkht5MBAxM!No4frH+^g&# zd8`cDY$m6;ro~Nmd|tgBTa0C=hSmyOlvUL49={oTQJF40Am!1Xq42zQ zh2Gn5%ezjFOd>hXLVgKZGlVQxlde5)3Ycw2+5vmh(bb>|^WONd6KJk)BM2JCgLtLh z#I&^;qLtYn*8->J9}0O@;SKX+7WO9ViI>aIf=szCwwA7Mrs?RYfrBhwAX(J!X;t<5 z)5yp4rAR+SF$p8^TkpX!^^&)BIZzisqfg4#L4Pp`;Fh&&JUl`7nSc2Pku(R*%*;p_ z*#J1%@d*liof=FU6@6opr$0#gMYBp$S;~ylObO;l7n|K>(uf0uTr*sI>?#ZAw&4ZR z7YN=i#jHOsTgLjRDV_aZqcNyo^j3+wib#eQ-lX_b z{QTK2-(rzb!`wl&LZd%>-kNq3lYU4UxXv`R^Q~i-W!{2vw#eCYgSZ_`(d@{rbcIhc zJY?7u`%afx(rvA;;QGaI?Xc`>8TFTRIEpS}EB4?kO$_cT9cq*w*!fj=rr`Kq;j%KV zWt7=qfN&e!uJSVg`U^~DToxRE5*@K{ek_2rVyPeLzr1eZZH{f)b9iYK&&FtC^(4sR zl4ey$nK%b&JADmd*qKEdLY7o-Q@k6LT^}Nl;vovo>>85n@Xdxh5EV4v`#JbTuWj+k(a~N2#PPTKk?wk{J*}-{qFq(^hu^fKE5a{P}-TUMbTcTT&v~F^`MRai9g7yk7PFgo1U;0RM{*q;MVA#kQ z#Sp7RKX%(~l!pC2rI@Y{K<}jMHN6wRU?6KY#|55lZX428$WA+>lhM8fnJlRfPsR0G zekpxQITqg|(qdF#tu=T9JI5DB$8A$JR)SOAVF`V+7tz<0T}W8s5v<8~ll_Gec1ktd z_qa$BkI*f3OHT*6y=|d9i`(5zuEE6{u2$C%4Xg(ZYiJ18r4}D_KujJsoSdjmmSI-~ zFR>+ZJa@Xj`*653{cFNW+q$tF-KWHs2rROQF4?N&Y*ef>D0gm1djiQeb*s31h_=Ca zCT}ZuX zoFZyZtQR9XzwX`mtV$z{Dqa;1=nLrc@AwJYvqWj3wUEBsLc6kS?4i$S%#~R$Gjgxh z-(BPvk2&*4-?zoN#r%~l@Y?gwjZbxCZ|~2~`@{*VpeCHNFGg=x`)#0Md%8MFBae#s zu3{C2S!?g@O0j2$n00->YK265?w7|4y%<6)$J;CgFTR?$;rAogRB8n}Q9sN#zwb zo%BCs;KSDPguSxIeP{9QgP~1c3ua2!)!i%PS1eI1)qb;M5DSNduCA^mMrxN+9sk!= z66*mgiB<1ljGA~b;R?FFgiuqBJ5A4S|D?G4pW9p5u*0+F^^K)?4{7o6RAuUqwZHvb z!5=2>L7PyP2~Kg#7{3L#Wm5rtVS;;zAMv;9N#bVDz!_%PH13V*`1d@;mhte@*|=qg zMEQ5zI%>8L_-dlmfPn8=675sS1~1$3lJ+8h>NHq)UQIq|J=_BNV$fqk?B;rx%;#VZ zFnG94`24#)?>1eii1khbXfu3gf7D}VIkErB?-)6GDL4b+CTTj-(vXF<-jCGH_cN|= z_zGeGlk}N}Y`M(7^wXpcu^hv=xNtOS+WhfwC_*Udu})&|8&ee@%DYQ~P}EzZ?9n4i ztre7#PUI_sYuh!~rQ_^jJO9On1em*t^OGrOwELTX8&TP)3?Fn`(-VGsY*V2l^@b`>4$k?h3MJZxV`?6hF7UzfaPxfUiA% z-^3IDCM)~Jt&o`_=cY4ot6LposhMp*4fVVNdE;fj|Q(Efzerum3pHxLXbr1Lm?t6%jeN@2uzBkSDYW!!{uat zwWVVmU}E%gs`3HfHfVfK10Niu6BwvcoBq=i9Rfp>`k4sJsdbOwgueB`D5zm62GrI{i{AQJYj(7gnNHCnx@E+lQ`j+0Wfe1JOZcp4 zV{Y4Wh^dmjAYBQfBI1)eG(K!%J`=61Y5eQ^1Az+{SOt@`kLyidd{wHRmXcX6oEM*I+4 z^OP#yI{xp=Hz8^@0vst9pg6P2Arg}vX6yMZc86f0nV|HD1g=479w3{u{j%tj%#|^O zY@qEZ4D5~+SAH!&gY{LvyXsS`NNGwd&>8KWr5crxq$%Zk$c-lPEtnI^fHENcfOr|_RVvf$Wv&IN8nKFC$A3Ff@|2-aFFpAcjtM5{MN#S$z81sM$=DJ z1BKD)k$po|Oh|};_+8nDR%O0N3no})A;FYkX@qTFz$H((Kxqq;4<{#iO`9z-fF60P zWSq_1KcYX^ayE*%nKe&mOlz-<=>d8!)V7F$4`=E|9F}5OTNWXFG#UCBh*n#GWps;J z%{Q1@&N$ePLKRr6Fe@(yParXgs=xZ__&inDOOmizCt=F5XI8?i^GD;>=O3(YUzuS% zmsj)_9sR9pB^~3k({JZK>e_iQmtMC}NHp&O2`-i_Pc-=i)a z`;{l@`PWx0$Yv?c^IEQr-Qtrfnp`H**NWKwKHCS!R~UeJ-k26d^k-U2>6Ww2K5Xn# zAnddTwdvvKYOANF503m?-z}8wI#W8e*^JJ=?6^I4rey)8tS0@F`%K`w==yq#i8ke& zk(Hjji2k_bZ>>2G+@xHpC48^_!03Zs*XMyYun9=S!3fb7>LMy~?wiPf_dl^O6n~}{ ztl8m6-_OlqI*w|2>0ZOAM!D{x`3<w2xVqW| z<6G_fcL`>}Rf{ri`_pHR@tRIRueWqq;JJ1XdBV|`up&4rbP&?%@RB5Lm|$(L564k6 zsoR9uru<@IlP48_uCjZ4s_xV#RDO_BsCIY1o;341kL9o7{nJAhO3qtZk$3&OM%USk zl%unJe$NaXb<;5(1c}*Isg(=lPPtSyFR?W@1-u z((bj4ZHFtdEO4c#Ulm&68%dWPKvm9t+J95{=gphjj}r`Zt*Wptn4U{<99E~nXAj0D z=KxuP&&m#vfRGxpg0!*;_-W3Bz8ArjNWBHk!4>?_;5`XkM>IP~n;DXk<;T8rMml)= z{E^2m5vd!U=5~ikmMj~Gb*p4#wRL)c2;97I+41THRw*BK9Sj}tV<}d(Q9TCT(C3>_ zX^+dr^`h>h+S0tRQSLJnDcgCEPNamg8EA8rQX4V1z?7(}awCW~97+uOP%X)edG?1b z4l}AQK0-9K*D#}F-J2W=*YEiTq*Q&J>5_S)tJ8*U9mB8{j?d;+lf!d&|Mo&O#yvmn zVl-Xd++&HXEMsYuV`;Cp&>x_p515fJtPx`XPi4$-*AsaW;7fC}?M*h238Wn@SeM+b z_OwJh(M;-1sS;=4^Lp9>5t-3?y((wn2StqLyV(`KhA4jg81nbn zV`_g#Cox?n9x?W6(7%gpWm4!76aOHJF>HNczh;cA(fWnBA#yqj#IYY(fkXsT_76+t z(J>GDz+lfHy~|Ab1HJJ%ibLjGFE`mo+S(4oW*&DsFsi~Ag5B9Or7v>EFziN?eRo>l z0$wSGS3^xcCe}qZmyJ^Y*YLyvcuh%E!p&wq$ahyzg__ zuJl=&U0N?WGliyAE1t1 zvTUJ+1Rapd66@J9w^^?k@%it2z{U9_q~~w;UjZeB!4J4$VpD3Kw$!j5Y{WVOHyHv- z(d=6Kb;Wfmli9gkH>74SL7+JQXDtl66O|ku3SBRrw05{!-ccUbq6sx~nZn*;PYhLQPUXr-D4_F|^9*^5Hb}stoL_U4Yd;8KaIOuo<#6)&YGW zlWm8q32=FagXlaB`O6cx>rBj5^P=N6kxY8ag2`{6Z;+{n^ded9lYR!saRF%O~^|s z$)=Ji;a?QXX}~+J2)k(X?+?c9N4yx>5nYB*y*tVI2#My}H@RLOQ?-(1lZa16*pMT{HuFCuU?S8}>y|M@ABdtK_bOiKkb*mhp z$>z!jEk20T9#4`fA$e3^RYOHZf=+ulyZ(7=33-QG`&y70|GJ91nS4Gnq;n~eo`VlA z)t5Ku)I(neXgqcTZBY+HvcVK*@mR!=y12EkJMi)J2OHTnl^JSh$XbchcKBJ1q06C( zA{B9qmmS1g#6=RF-u~LmBP271G0IVJfu3FSk&(=a<_bCA?TLPdxvZyZ$h7k|V8n;h5sL1|Lv{vTATf3001c`h3RKKlI-AOHA#vYXn2HDSXErXKA$~0iNBP1 z5)Xes`LjUoN@$`s_&zNGI=f<0^_j`x25K5^RBsy1rsbOJ?d|MM*&EHbNw_k%^fL5L z7sNVxUqx9qOU+GF03PyN)C2vZaO}-w>?NCo{YPs@5*VVR6)0no@c^6-YxJ;{*d2^V z_7&e~ebfB=cfaQsm4fx|H?OXZ@w7?RuqhS-tzIWyzjE9Q12wz>9X}j<@i#&R<1@Fp z-Tp#$At`1SoOQDBQ(pw!3gWm|5ikE47#8CYvun%6fBE%0bzH~8qH$($e+ZOxGCOrwrC~SfKGYRsm~ULH?4SXT8OL zo|nWtOJC$F9o>;le?DGqg@q=R&%ObnhGI8`jK@8e#?~e9=TA4QA-l$Ik74C~#OU z@nBJ$w%F9*qgR4GsV%aLJi4?^=wgou2e|^TLleH!d{&Xpc7m_F@+3^Tv=@GSFU0%c zx7IpVC_!l<=S(i_B9K=EP^``@j|=OUHM1KRwgdA*Ljp*^0W8Ts?kM=MZ>{(6w*j2j zMSlOLJwh+Q;t(e~|yNm#x-M;vz!O1oVh+b;>jpP>gbOZ!paX9J$LqXg~Sijq}{l^xlzxO#m7ke zQ4@LDT*o)~N2bE9$f7;-5*v~+6mhgeG%2RK?KI{cY=6N5H}@e{<96!2alua1dR5x@ z<+0ytGj@LS+%fcVDzegjQH4fv<3#J>$$%Q_qQvoVgA#g~JRM@Uih7(am~(k}WK~|| z@zaD?bmmB^=>}KibwESONo-+2H(A&1fc%$L^?~woQW`O7in6lQ|3zHe~0< zkVDsBFN&QRI1&+x|+R1vpZ4~0!XRWfSRQ=z-B-P5cAX@d58y>v%`~}PF zN5k0@gCU1rJI;W%Qu3je+BpQWf%vzfW$C|#&X;UWLD#;48~c8ea2EXhU5w3Maar>| zjIyyU3K45N!2U>ill$mHYFpol4|TUkXeb8|`@D2001p{JGKjhYjFvSTnvX^ zR7@J&ac3qknr4c;(Pp<9oC=2{axr5NsM!XoRpvqDTtUuC03}1E2zh*k^PB0?6O(!9 z>u9)i5FtmQ%y8(k2fBK_n3s0Q=^APc~{k@y6LxIgqcP7Bus zu5LUrM9nUaVEDwoiUPJF5BfOz0PDc2^faNhJux5-j6HD^Xo*^rY^G;ms*zKkfN=z1 zbx?9>z?GpR3lRIvA|+j;bmY#$L(=m$_>07O=bU-FHVtR9`8K4#Wpqt9pog*=CwfHc zr^(bH)j#a2Zh8hZV_>gdn6xRw#mS++OWpX1Ziyr`o5z5-Stu z&}iKx9Se+v>Kr@7YzUs*srpvt4lZmtY2WpX+vSq=tm>yNUNLWL_>+ZelDY-pdlO1k z%F-}Ib!GExjMs~s)d@_|3%5Q|v$}?jE1=j2QQLZn3*7s$Z3_vGrFSN+$gb^BhD zs`O8s%B>2{pvQ4~uWM|IYa8eBfUcp>LxvnuD6G_8WJ*>fTKSIr9pyVWAbcO`T;Pt) z=Vo8XD>1|sZ-ijn@#()#Hf_*Xq%V0jh*Nb;r%<@#u&^+B7JAA364Ldaxm0tS$NguF z`e&#dDLj5^RVvmIm^CSyRw;$F$=PlPsk^0~KYPBJou3HC<@i=>k^zb_({kWm#dEvU+{%+Vpd$3zT+jS$?AOiW0wEf$3O=DU8xd>VOj;e~P@!!8R zkl+OjoC-N&hx^~?R$0g@co!Dd>QT)=DL?9f${ls)3;C73FSY~ciel!PDu|H=D^07I zb12qvzGDcZC}?D9*$P1$Lkl^XuMzL;fwU5~l9x|7YD21tUoF7u?kaM#`h6PeoSJpN zU9-0Z%Yro=nT*@{bddqnsU*P)Wc{Jz3~y8_*kYdqr;|%#OBMGL!i$)nIeLVNrqzTe zfwM_MrBk}KrAF(&xevV#P)CFJ;2clZScmw=C=F=okY|~g8BE{HxU#hx<|nDl9-K{o zyd)>k0fw}koKjaoJV{sX!a4R6-x5|vRdfBO+}qE&F&QFUfgW$}yI?)WBgaef3S}lL zjXB02+(Fu&smaqqsV@;Gw|}ayhh5oR_b%(3+2pHQ`0H7Tk|Q^fjW+ZqxSK zt(-Y-?m))+nx`SPdsj_DAHq7{KF!!V`d;%h@(p$PC}h`Wd%4~%4K9B-gcw=YHs80{ z{wsl!?6qVhnQ#&?H>C!zoEWydy>jN69)~#GncA!})C1Ra>+E@BC(E<;;qw?>g%Jv% zes@bvgJz40jqTjY6Z^Zn54j@5wOMR3C1roo_Io8ao#E0en=3W~GwcPmVrRcUl#VOr ziC)(C=BwRY6+jwt`Lz|VPC~w?d}3Kv$3{Lrpe4ajKsYm10hjwZ$z18S|KgMSR=xAYQTN$Zxa z*Gbq>e=D&ym(fd#th=?W$DZHy$f}E7hoc$SD&7EFS{`ct&B{aipw13*GY39}$4cog zE;#)5iCdm=Fw;;k{l2pa`690MiPtJ6-6)e-Y8qElSc@Vt*Sfkb3eoAT+c7l`FNvVh zZhTR=s#;;*Ht(FYZv0ugmOK#-_J`{gc5qAA)LX5c{1#>3g`LP}N(H}O>&-d!N6`e3 zak+jx|L~Z4L~|>S$VSyv=>8(>GWH}*0(W&!6WnSmy5s1K##pW0l#>|@wO@!!H`Pq5 z<|MlpNA#NmtfJq8@@ss_HOk!}BMF1p(*ggR1&~MYaOF|smny%miCxXp3!=;4w1H=A zFoCj~iuhB~w>WYxchgKI%SWNCNLnMQaJIwVDbL6)7{0)1=^|X(iG65wQafCKaG}}x z=TvO6vG^)ca%ktmvZ-eUXXE#|{08(N(>RAesaBdC=6wKRFam5wCDH0$(do!q3m!ze z{v@kKK(_x0S#y?7(#aiSNaAx+Kj1X$00hdll`pvhHw-uts>%Ks*^d!sGr7!f@dWX4 z)sam~m-@0TqISHJa|cyKm%03H=CpbLC*H)hAKL!C!}gDEk;{8p)9cR_K@xht3;m`W zB3vKYD;_ECvgYMI{q4H9Z9&8$XVp?In=O6XK&JH~+JObaYj+4?Pwb8CU17>mdNR!a zjim$UnlonPgbw@8-g7=XBtP(F zup6lqa*dL(cK^e1%#xemQAU6Mr=ZQWt<$6`j}&RwZ(lnNZqU5xXhNy&fa|n%&}MjZ1adCL z{-QlJGV+Ogr8OB~w@Y<{v_|$fW*|xKHlBpeaX)o^*|2F!fTqdWD)0;59O>9ApHFms zYsESJo-+SO(&4;Zz_7SXIwso<+w#R6V}>Qw2(eLMXUqb1Qf~_9KmXKaM046YpIszh z(P|wh``Qg@g%I}`@diHIf~!)0z>2=4{s^Ih3SNdi0@b3X7Z+!|e4co$?|Ek`YBt#9 zLb~+uc>mvhe0yKZ?=%>-J1I`+ z;Vb1_->f-uotfAX(qnI?l3ZTylA*2?lG-y}v^+%Pq8|Ixi6?tkfRg(yW%fYNITF2} z!|-bV#1qztD3c{?qjcXz0k1ji@ukXiv2GoGhWD`!w}#RdwA2j%G~ZNWw4Nbx;p zeYb1S#TK{`S5BZ#MaK_#&D8iTbx2QHFJrp(Cvwn=L^3HwxY3%?1mG`pQ%K=1JeqnD z$dAMRIv!MO_WO0ag~85^=8DBv_S3e$5G^_Sa7ls+DCF8>Vu4E_$xj7w0y6S69@YW! zXf8S@{N|UpDQKG_jzpq!u5J|5I+7lu+NMDt}~Dn z-36D@f2j*tU-fp#i}_gvK<8!Y1qFd!sBrDL-Ble$>^lHkD+m~~>%7lQqQm_y)q2V> z@VYknD*5i>+o?gyk*(c2gnEpvw@8r@INbAF00^^H1BCgKB+94i=eS=6*Dd6?WTAr0 zt0O>#39T#??yFKi2Z1TooC9@M7Ja7ytE<8BG=U>bA&NklCe)kKm;Mg0bcwo|7$LS~ zlz%*^95$~Y$taR*t z`Ng>14qE)N&vt7mU^Rvzc<3vD4dL*-xE-V_wMW#XXFiJb5CH9!OULYEcLUb;Kd1>O z8vV7l`16L%CsuFENZD##mTWE=g$K<;LM zz7~VvVumq&A;QMacm4OY>F26JW5CZYGzr{}NuXsXaaO+bY8;lV44O|a=<{u{VJ z(f;%A#hbSesjjG|Q7fC>olffLM;MEk80Y1S44Q<7TjZ9uTTMYdj*0#GbsSO^s5^v? zG3eJ)KgasD`n>G)Ce^095GgdDh7}R`{fK?D7F|EUb-@KVz{%4ac6*iwi_~YfO5JCA zHpnjOiZVBzADODRo1I-J;??umn>RkUP|wS*>>@UW5VY*!)yn>)?F|vHc5?tyTupg` zn2{kkIn45mLaM49sn{XSg8Ox>Fhy86SWCG{*5w3({a}Ss%di!#_EXn{da9_^E%OB;(1hldNO6zt%sn0rC_1#m zwrRU%TLDPI6*9x!>6DW>>~jzAtR&2F1Kf);7|D zS=@e#HCHtq7jC^kRXb5Ksjj0g;;Sd&ryXl5}x?spEKJRl-yF z44Je7{gNO&AWWlL3TS?X#fk#Ii(^USXo{ut)EH&Crf{9ef>UYUyTVMNe6OL-H4)2~ zulVqa^nnp}frj44{;vWbHP}5o*~t_#$8at1uD?_bGRK*#l_%7&2%G3?e8Mm~u0nef z+)$rMm1yLT@u)dljPH9$Gqe!H`d}Wrw8c9_Pl--|HmOW;wyL5CCU5}av z%gUdrmBdep5D?|EM?nX}2H<{MZxhtUYxA-$Z#7&)0oTj9@AQo&UAO?(#Gydj}U!Kw=w3od{^TD zcCGBQjcQ+?FlrS-%LdL47koG%hTp&+SJF(c(3z|PJVEXxdm1T<@t~X9|6#Hqt%DmM zbG-#>#V&t)QUFh|Q=yHmG!4>Cc6G1>AwaBgYHJcvJauDd^+*j!7Nn)**j1p)af)6g zHlT0*+qylIX#{X%qJOJv#qfAzUwQiTIbyD9$)@dOMqEwUdL7wBJaTrq=zs<^!J0!g zexcGg{0i4bEmr7Nw3JQWvbZ&a$kwb_7g#RDKhhr(>Ycn+z}hE8p6CcsrG-l@%#(ZV4*k@XBJTT8^6j>}&>fRR#_ z*b+(g)+w6h%6qhj%@NcsOQ-AJPA}|9$=1^(TdGC?f!sDbwSd5IzeoY!qy6RQw&1bj zCB#sE(i2hN89+}{>+g_4`~j1|WLx=3$V!4t#Yj9e)|v+~CG?Mj3>iS*hn>*pthitQ zGq;W-Pm{3d=}zo3&9;Vt{9^*f?GWY9c2S5z45Bc>7g}2qfY-y3AXo^zPd@@M`vy6f z-;yRvuNDudxj$r$JLO@Qt>`3P_11OJ2n54#8GVeDiQDzIEw2&3&f+8$D{%W6t?v&rdhoyA?lM|J)ut%kc@Z!*pur@l}5YWy}ceOshv9c>ap{v`8^FG_W@E zRsMwFjm_S2gw%;0d!ovfy-1-}uXecu@);AlVXNYV-Q^jrfzEHlel|&d*%W;2A9Kdv z@GCy$er1;P$C^sTz^d*uN(U#CQRmN2NG-)MlmyW{o9bQ_k4#(=mX*xv2g1;Ue0GZx zyZPICp$ltx*3;@2+gI8mOX1Pg!J#2sn;htvi44mEw<>f3qTmtF(_5E6d1Tj`Akw{PM)dL)|ILIIocx zN}GI}ClaNEhRACpI4f`6HzQJ%W)+v8?_ZF#oc1FXcfMNaLgy_jO|gADHwyBx+i})^ z6^F<0(gGo~l_kYRzGCBQCQI>8HJ=BEG>rccx^pR^j-csrIWep6F0C_NN$^{2A8L#Q zzg7jmZK4^cm+*O?Xi=nW^(So_Qq_-X4_>BE8TL~>=@X?HK;BH`pZ61a^YHeK>Zq;q z5HRX<+46ujF$V65i*ckZS}(!^P!Iu4M72gxl;^a`c;+l23btc>VAnYgkoeXU=6kA-VGf?R14Db?d?G&YTV3Gks96 zFg(t4-LgOuSn7(~JmT+KI(tZPF?suqU}4fyhSb*s2@2|$xLbW-Ni{nF}G#*#-Y?(FUirDK3&~R71_|#P??Yk z`1w0R_esWCsfsB|T263&LS{3;XjpzHM9@<9nsp;qOYBCIz^(;3LJ+K~BV2nf-?uuu%mnb`4wAQqVgIQB@n&&;ND3W?l` z%S@TosG4YX!4~hW7@Mah0w%FyC$>&a$05I^^`DxxJ?!Rlpj_>vkKscI_`dm3oSb z2j%bm*XY(HdbnKm%NlpNzWcdEkL-j$odWNM{=V-n^BgBnbnU2SMco<1pSzg zcHAs(X2xwkHzpSxU9%jj2M9}F%kympCU!dmEJR3@*Ssu+g||RZ#{GI!y@V_cL$@%` z&Pvxfew@y4d0y+IZq|*&v_rx}&xl|qJ42WCODu3cZ7~FOU6zKqs zd4Owe8`XBYhZb(FsV5xXi;6JNFVcgMtntXklva(-977L{EZGtwz6>`7B`5PcsLmqX=7uF3i2>t_%gYUI~qOwKZYg`)cDC<32-AsA_B3 zN5c_QM$ZYdn{vrqg@2gsw`l2ImVThBZMt>3buo)dTIkHxD)sXE@mcoTBluQOHh~2l zvgE*9;@+5wWxf&d;@g9E+E(j!gRw?OcX%h}MAsww1#r@&-@*b^ot&H#eoUAHWwAv3 zsu`~z9vR^quO-t2LtQxd$?t3L$wl**5W>QI+k{l0!l&RNz5h0Z&^KDGY=`Vdi;j5- zQL{Z@U)wsTAXI_Q$qHkj2F4R_*^I3`Jt05#Y*LqHfZam_jmISge(?~U3p>RSc6|vb z0paK~k3I0^PoH?MYE$)T;D~!f&^=l3hj~EBdJ~)p-$vRlS{5;D*HZQ{$r}HfDvbP4 zjshx-{In4IryJ*9JKqtQ60$YDMY&s+Cmb7pHnf8pa%_la&eoo-NG_!WJOQ)hQo9w`pOlyL{z=y`vu+8t56LEABe)m z_X|;(=w(vS5I_xX-J(+{ufvvzybtKXp6H}U^cN*d_?N7R9%~qZ&%%Px+L|)1M8V7Mg%Bd)O>H!F@XzIj+5OAMc6pHQ*K(Goz|g+iu!bE%Sq? z39QUbSEY4BnkIx>vHJpUqfC8<(a-1IuY23aMTm-2UTzHYpGZ}hrx8Z9p%y5swf&?^ zfD_QQC02&vY{%=nX(bW4G*l zUWV?E&6~?_x$z4o2M{iItKuY=o5uaQAE=h~Cu>n?f!i`g{G5tX#fU!#dec5Fq|M)w z2e<97mL6ageOxh~-y&#NFspmnHs{Viz(xzk_76VW$P8`O|HnsP{#KDvA9(_D6SBzk zJ$~bErhcccs;^V-++VC_aZrLZap&v&c%#YPMD_^o{sb&~MR00e-1mr80Q_?mM`V;3 z`jQU4hn=goWH?>?GARTlIcfs=x$qRgvdH` zzxPTx^FOB7f4+2Ny8)rn%Sod0(%Eabc^LLA)OmiUA{xKeV)$JgrnhxwHmiQFM*U#IOzDUY z5&z4P{I{L#?6rr@TK{Cosmt!e8soydf!jYD#r>aF`YYVb*n_%_P$&`g{7?1B+7}6V z=qVMY8v5Ky&9+-roUWkAKg1x^RNO569&^wUa^FV5oN(Nq#UVOe9#`K$y!Cs2kWvPL zJDIt^XoS1uk)UFu$R-v?X`~(5uu{Skf$3{Xw>TfXeI!IrOiI1BC z|NbuRAn21wQ#uZ2?q|2yOHTYMn&08umQIp6@57~tWK5aS>615<6oC= zMZqZ#g8$x&bM#ny*^eP4e*pR#A;AAN@AJCV1vF=)*6@^s(k3bVv>W~Hn-#Z4SCxHF z3UIwLgPah%U~q}}h+|yvyHiF6+wa{?O&=5QboIUd{Jxe zgMid4%wObL^NN_^U&YUQhak6E>ArJT!}qfbhFejBMVXrNtOC4T!1E+QGHm>w+#33Q z1yU9Xr);-7tau=hAykch`ba!FWh!jQvJcZ>AX? z1n!qa^n;tFVposNeB`2As(U)Ia{s|1xvKPL)+boqoAihOMK_(d+z#pN?JMNlx-#j{ zA+0M{skftY5YsEphZr$-%IO#xgffIajd&lrAStELWxtg;UvPKmTUvERH!%+jubhfTi z$8Ip#wdl1}^~#rDo>wkx>&0f`72h;AnU=`x2S_t^=^-n(FL^@z{hfc z9&VwIlovlsZmJ3hat)s&UO5nR1E#68bFsY#d4~hAAXz7_Y(a}?W7GUk5?bc}>D>Ld zZ2teX3FQgZ(TPim`1PNwL=TG_2JLf$!F5C0EAn)+TcowLuFQay3nfNdEmk38`LD%Z z((P+));cSqhAHJRw|YJD@v=_bE;;8D_Awn@2GOY(b9#$~f@qk5kz7hS>R;0QG}DiZ z*X*?vAEex)e?srax6V(9%yY@~Ja)nuw<}P~yn%iTFD)7847%22*L5{sDF1quSlvkY z=_<2==@A;)3-tkNYn=ymcq^`VL%d4H7GVuuo^J{)Evq*z@>V_ZwTGEV=9(EREU~hv zdv&lGo@21dsTO^<6*13dwOBXCbty0mg7FlhaLw^jocC9Suu~FggR&^pQ2EPM_w7o> zvVcCDTKg8*=UE#1l;+*-Uu$8VA18|E>Q9#T4_ksAVIJSgajvbidv<*hOs7Jwxz$1$ z;no^5Gw;6GhrDVjQ@)-I{)Q|v9yUh1dgLNz^!pymLB-imiVW_v3`t~-W_7BXa_crkodU@ng>)}XGLU2+EC%P=rsL`=F*XaVKo0`D+`9VKm{rL&@=xd5&qw~ z!Kt2 zxecS$>36%tRC|SbNIeX-D1r*U7n<0aou6fQQ;v53W$BV1Dx#~jDz*By|F6h7*0a8l z$6QLScP*(|78b&%Kq9%{ncP*Kzn@NGVrs;wQ z+}6PC`=$3<72^<}F3vp8#1g)bLtkwsx)3384)jm3e>+SHXHu#=D*5UW!{Gaxw{(h& z!T6W)Pm5NxF`VvMPMeXgZZ@^{33mGkWq0{$5x*|Z0IQof%f`pQT0}Fc{yL|7 z;p~AC*S$?yfG{1BF4%q;P{p$!15dvjcKHAGG|{ir|K+^ins%?eh`KG8dWkwppq%sd zS=Uz~&sl#r+y$gQNR<^g(`sb(`S*oKvRa*QsdJTL|6(j5hMeynvXvu|TX_*;{3D<8 z#`Syj-7FkVxgC`+AASz3Hnnzm>+EjjSRIcreJ~wZ5GlqJt=tQ8Yb;8x*jK`32&3p7 zEeuAdUc@j;dAt>6*k(E{`+g9F8}mZB8l6ZtN*mraar-!z&*I&~#6S*bnB(GbIXVUU zf7tu-c&OJe{+TgZiiip+O9n+EE%vRAL8NRUv{15_eK0fa`)EW9nTnES?Ae*ATM0!} z24l;TG{#smgE2F|NB3Lz-s*n8w{Cy@e!o|*mtKvJ&+E{~&BkNbm`*MS|aI zZsumS?zr{8-&V>B_y*y-${`A~hUE)V)9*TOc2vih zD4B{=Ye`~G3uT7cXLeh{N3s&~H^UN4JdXJ8c{v4#y6inSb0*woVYkS*UxocXwzmy@ zq`l}kY-%&is7q$jr69(qg#pw}wd;lZPX2dM#*GXi7&A7CFWM(JK!jWTgxZXAKYi}n z+ltPpGR)p%(V6ShwXfd1CA9d_qu{LP9O46#jm?WfNP-j@u()CRKK0oa*l)V=zk>+A zg)NG?FJ!&;&7)7=djV})nCBs-3Jn9T&%euv+#+#xnbYYR|7%;OxZ9dnw<=$0@R|>v zvAuvCCh4+}TJXvlTdbBIVp#jTKsB$z5W-Sc+um=S1&MdX811X9M=+z+`hlv*b=$9p z-|UjnY*FK&Tb|`!)`;_efBU47U?2G#yGrx1fP=1QCCXdoHKl9mmgz4m6%gfKpDX{eDIISrnq#c zEvqYw+{#*=JMsJB^AXUhoa!0NXY-eTtv(?Nn)a(U7ad=`Ty*Q=<()S<$UL!YOJ)hh z#{CpTFmzK6tO0b{JV9)pT@@gi$My!`8$IVgRxROG-M`^sO zG^vc1dqw3obL4a&;AFDYf_ue`oJeZdny~}5{(lnL?9!YMf?lLlPtJQb{G~uKjg6~%?se{?uJiA@*;ys}-VZG>)o|kd$I+ief zKw|DI*@7@oi0?mP;9r+EL#)L`xel&ge2>mI&sqq%bo(6XEnwc*H45F@%&7qqTJHRr z8<~4mqR`R2j+C?ZE02D>KRH%tk`;$`pJGvB{m7ceml!z=5=wa7YxKjHPk$AUk;AcP zheufi(?9q1@Pu!H(VY}aO#9OGJhFt6mdZ*GrRYykJ>8vkG!{l27|%=;r3`L58of5I zx~)Fn7(C5n8F(d5DY}Y1P>JSJ6p;CKRlMOhM#J_wtB15dN^wMRl7&OdP0fy2q`^Ui zS1`>jKgBMgj07mSd}-R`mIWide#Ts8Z;-K(oIa{H`73!tV2V3ED3?li`7ZiO*yoj@ zj0HW4t)RJm<0ahbi)Jt9=MsOH$%joC1}Wxd-rV0W+O&$ynh-lS9{i=mzVSSe%mLeM zr)H!hHh!f}e_he9P42(hvs5mSJ-?OtoPRWiFGcnBT7De5aOLcRb|xLz{Drmrn_oT1 zvo2awVbM3G^AAV%<+Yk0W^WpKBzeJq6Vi7I7z>?69P)9y9~{&-FC)L0z3Ds9Jo+=& zpMMqL=1_?p(67|^OG$lmP~TqvO|yjmmiB=357LKkYVa>b{iUeC6!jOP{yd=ie+p4^ zX)lbG8cu&3aR2PPHLuS}p2zU3R8-4fS+!BGr?EoCSN|)aop;7245SQf?3gxxYeBi! zF>k}tuN~k&hg_3rAp^Z9|}JPda>tG}D8^wnQ5ul-DqVRDlMocp_+rL?bNg8wbXzjb$-=Vuwi)~MtqUkmIzdBPtzz;frtYThIr z&N}rkM)u{9$(nPA^v*Xt-}yOb^tIqWJ?=aNySumb%^LOP<#j&4y?wGE*VGsGmDb2> zw!j*X_e;dwjz2lAk;#+#+EZiKEZ6k+*(0UM{_V>c?O!ko5KKwJdTDz#T9H4K{XDq} zc(%a+kv9@~^6nF0%NW6TZIW?~gcXLg(-;9y;kf|L-36_t$5n0JLSq8(*1JGKd`vJ)a;+F;Gb3fmzsUI;{8&y zUuyPk{QQMx-|zT-In8hD(tnZUFE#rw!ugv&{Zg}EYW8hPx#|?Tv@Xx;BhSVX=SHoG z?|b5{RGN-F{N^6M{eF!@!&{w?VTw=oVctG+sWCN&Jg-xN$%5KPh z))wZ&@B~+?)TckIpB}1Ht$CbMn-$&LS-~S{RNTWGu$(-5?^U9^jLfHMeN<~)npJBA z?#541#$#%*YN{8kZl5T zDEA&`)dIiu@do~`$mEDrd{lLbmcDN}ihhh<9@^njff=~dq%JkmXcyWTbdIu?kt+$# z*%udK7DDY>n;txGPN5n1LF!@VT>hESQ))E=Y4M@WeJjmWX$-S%Udv>dZ#le~7q*_0 zN1+4@rK#55_~-NBzD}LQ)x-uLunzj*UqhB%5xPsezL)c0VGE7%xCrxjeCIXNbGB=P zTw~5akeO<^yJq+Pf)L|k`oPGwmlk6;Z9Qo|lMf5?(J{tt3~Iz2J|oTaEO&;pXHmU? zyWO?QE_!8={Ie$!q;Yf4N)MB`se;nEZ3-f{LI+v_&&F7Z`~KEOREh6X zx#)-|B|3O6|{)=0eW*LzV z2+(3moqtR_3e*CJTMa7Wmqs)IMpxK|;S=AOF0XG;F7&+w5C&OF0pT8Y#ig6x(`^_fi$P0jf3q)oOmU zp$UqEDs7JWR$!lAs4jyH-_Tb*6QrK^wbLY->(AV~y3+77^g_HVDg$3J9_+bcxc7i+ z&5`VT2p-2izAt&3SG8YQK(TQ(eP)~+{gTNx^iir1|0*Bzk1`5Zg;q#u7UUL-&Z#$c zMQ(jwG&LuNdQVG#xEg1V53>R`lLHjTiq{GBX&C9r!LoytDvKLS@~4iWD^;f3gxUn? z^>X$_G0hEDY8}0d!zKA4ykY4gik5c~5f{NpKYJ9Kc%~AyW0%JHpu0_m(|6S3``Az7 z{drFk0<1kb2n|U39qxbNxdfA9HU<+3q)Jj9jN3E11UIORwuH>)}t0?T`^isAVl}Xh4A&+F@ zAq1bV{$PoE(3v^)0Ii3>vNr?cuTb87l^1TW^t{V5n{?He>Vl;ZvVsR@9>-g-syYJ8 z@KI6DgBM>OK1V)vH$MBx8~|*r^J*PjVo~7<-M7nll$W&?ZgjX{`z11An<|n`4nqxX z032kA^~gx(@^kDY=q-EGy6Lq&%E6{CwI3FkLh)-LZ{%o3B zX`E!&7UrfscZO4#pSON0!B$E4RVtPAI-wjW^jiz1h(QZa<}^K}_IDmo<<@;6u9i~V zp3mz8zLbRn69@hlud!i}>9flhYZmQzr~Cq&woMymteK4vm9{UtGLeA1L(T3V60C^WF_>JgE*9voTGLw{KOB@}Y>)K!Z=$<1 z69VKM%jPl+cO#9cU?v?23@JxEL&ni7hb3cQgxXLo;pC6iNX5GrI}AE6m3G9l*CAy? zkU%H(mE--(6CN)v8MxQ9yZ1`H-OpPUx;|D#Ha%E_M)#S0M#rMbL#j12u>*I?v^Oh#`}ikJY`?RQ4*?7TJCpha*M-h^FQM(v_R zUwCWyj+dGeKin#(pB+r?iZ09N8iIAq@yvtQr{XKd_TMQlLI=m(p;mPybZ{#Q3BNth z{*BS5#^05iF-R+*Ph3h2_&KX{xQOGFE(Y}jsFGd!l3lh>?om+?Q5n1jryOc_2 zoIGj0Oxh(t*uYz9#u_cIk3otZU-t#|T8vRu)Cxvt?SOCy-+rei3*E|cxbDa7=2eh9 zxK%IXQ=|Pl>MfNb`bzNU0nKBY_7{;1JJqmMiOEVpIvQnPh|1mgz6NW@vR=8hKs*e~U1aKdm zTxOQsL6;R+QERmtOGh>DT3P!yDHo`X`{FMUsc7R5q=1=ZKVGu5=?@`hZprLE#&G5R ze09P0weeHb0pRYBLQ`sIdO!Hube~H{Z1eRd_VfdG(k2UQGH##wCi5}RK&78 zS6GhDu0hhdY{b3Cwr{XMFNp#jO7pa@5N9yV}20I293x_{<-tqtw;m^Lq zQOb<(tJijX>;78O$PsCD_^uXvS(0{7tC?yIa4i)n^R3GPG#$xtUHN0s)GE1MvwKJ; zagW@*LecDo@<-)&^T+85DHey*l=Y2m^v60=EZD={RaN_T47#CRAU8v3vO&}YCUk;l zKzugc8J=<5gKX7T1c-D(gP{X5IV1~TfdZWS=sfh{O-iMsR{cc-C6!@0?wJTi*)1*h zJesJKy??;*4Y1$lwetd%O4)BLc(l@YGqucyBS%zeC+q-}^b!J7oBX<3#teIFBWZ`? zT*|2rRT%_3JOD(0dQpK5Jeyz_%Gk@D0$S595#OO7z}7eXs1x)~!w}^kVs^oVcvgfJ5iw$T-eCJ*QfemgqY~uR^!nYw|-6 z3|fq}D%VtA55@s^YQmPRLwf)ap)?QdOh+&PKMu>X$48)rD%CYdX4F(`Ugu;WSl&&^ zuW9*nlbk-X;nIhZIY%uH(~dDYHl-*hADRPcG`-+;!BfVD0MW zkCbK|S_~|p^llSlDOH-&78g%HA2<{W z9|m0S2(WWt7c60IE7gurb+{nH{m`uE)nzZ&zJs5s0m0#bzRTKn-S}aqwj4mTuuM<4 zTemt?D*{3KVU|_$rjtORommD#i5OBcb?&5LIq_83KjuY$0XhN8?)GCLrP&GOVZo?y zXXLCqZI}Xn^y3WDnpMXeMitFe$JqlDGaUmU0JU-SGK&s$209rbTG+64)!R-GW7Y6{ zv|M^Y8excI&1w_yB!mOM=U-R%XMwC(f{x;u^mxZE9 zVW@g*OZ~3AI@Ox>z|EAp-3NeSL_`4X_TmVHGyv9Ec_cgWhg7%Q7m%#L4IwvBT|$MT zR;2LzTD&n?{p@E9N`WDkx1NZQyWvo_&t|tfa=7CoEmXU%9?>vZ>-#D(I~~zrYNuhd%+xb5sIE5)Ljg z9y@mNxGuzJTX!3SAkqbxv-Y(K2CH(OS^Thl=c~(Z=0@v?h;sWCZ=>TZ!m5h;xd2rC z8E%A#Ec^_&#-e!SQC)ThLZdQ2Ka6spx^~Kt>SsHk_+#NY0=wy4p_Gq;rcL*ebc9C5 zZTw7sAqag`R%aq4*8y(Zdd-AQ=00h}Ri!qOwws_jRhAJ88D2R7CAaWVz~e_ZvW72N z90rl`@F8><5#X@DB^xuG*sR*oD0#zuu*gRt_Zf_^O(_DPo?{On4aL#r>Y_4$e#&MC zo7r3^QmeXLWY=ed7=O@>PI4zA2;NQfu0wUF(&GD+9PP_eWOXtSU0NBz?1s>~j-ANl zf*phP%NB$k}R5xx>@cyV1Y{t@fED#JNlg22&T1K zwIfDdU*aI68U*_tM+`;}0vh%*p&EogjoQiSSzSCp&q?ppZH%1J5VG6qawiZ*k~ z?yd0)?SMYT)#->#M+dzA`fFhym{goGF`pAOzO{WSP-*IUrrJ0!f2?8@)xk|hdUB8T zje{@Y84M{xW5e5hYo3sjI8Ok6cl6d;A84H_A#!;Y9n#5>g<7QU$1g!3UkrR7Q?D(e zjRd~m#8Ry$1w1Qd9ArvyAejkBARhs61O46J4NcL}V?gsp?={gW8$FB#XVNkOqja-x ztyFW4Fjcz7>gM@aJCuzZP90QwzK>hJ>-8W=XMUut5md&pq8IgBKt>czV(gB&o$n_0 zHvA5o)4X_o_}kIiA?&nSl%rC_i+lK}5s>o%#B&3W^$0|LHKG^Pq@&7@sMe4oO_g-> zoUiR}2I;-NHV{bHmT1wshC8?Oszy;o9s2#@KSnG(#b(oy!(*_lQIJb1FOKcKV&BZu ziY%bV+`=#|!q{a;?joyN_VXl#56Zm=Fl?iM>}lWdwzlRDRP@737R4T9Ip9R+IjSBA z;68WAr}EsRVw|rT`>^E)16+3_V>p|YBKn>0=nosFsnwvaXR&hD56bGK-HDE6Zc&TZ z74TNhwSl*hmZJB8r$_6>4>uc?bX55p0OJLzBQ8Tu3nXEef>kn|W)pjmvi+>%E(99JrUjoQ@gT?^!AK zkTQ2pA!R&2Qx%D7-@UVyTSO)8bK$VIp-7y6N7+v;4)b;hjfJ-fkf+_oXVVqHmRtFP zczf>PE2gHwB0tr?1L$kJ-F$A53zzul3K%QFuC2M%hi$^k@(g3i8fHH;9w1oHIz~g2 zh%0s*xcHr%a2PBKXg<6m{!K9| z4e#3OTSMBNjv&&kb4K<6e!cfjzFVvZ817NS1MKm}P8^{kt7&(Li+nH0EESXdT8H$g zy(c3lP#Z2+MEqDl$V?&YYNP$AILU$QvwIpK>~7mADtFDn3w^DOQ%CbtI6iL&vdYg6 zIjo(LrQHI~$+ej?>#KmT#5b%%R)LRQIvJ@e^|zl8kTu9aNM2N>i4^fEb+d*{I#x?s z{tyzq*a-kS8FNzN$C8GBxeBWQpD(f|UH8WX^un6AI8^S{~-qQg)D@ZgJ?p2 zNLlHJ-1uK6359V$an-wl1M7Y$$opb8Qk#MJOwjJC&OrCdS4o zKSN{5@<3sQANue38RCCo1N0&$X6sKeOH-h*QpY<|e}?#P5`bQCX3i^rp?hCg?-$zi zHzywhHIJHt<;b5QeiLJ$7t>SH+rBXU|E^7cb29$|KoZ14<9=`}r3EQYsuBgmm47(k*hPyOlD)Tf z0f}+U8Ui(vG17Rf)nr$C@`%^+Q!`aXbdtk*s(9Qp8%TgAAg5T@g zmWimrrk@cTkhjlAts|~8 z+77u|*1nA6ESR(no45nnX`KFyFxV5MREh$viGIyTVha31UrigFQcIK@5d8FDEOoXb zp1Hg52Xieg3FLqqS%?6FUD+nNXrL7FYHFa=5MFBje+0`N|mXGj*9txGr- z*5JD4dzry!S^nw6(^BC-{q`NOHvcXel#?0h5}&#M#@QO*XAK%5qm|fl8|^%mmWflA7PQai~Dsz_SkigL!cdCuN3(WPFa?Jsi_z5;>nU*}S zN*mWkRvmGznLcK|h-!f4^cXOBInS$9+CrkW;wN~bcjJrhvm?XpcJV6K4>F6pGzeE6 z$~b;?v(4%CA8QN!26!U?Ix=deX@&T=FKr1pre4*`_&(DVi!qF?XXTzN#hx5)r{~tR z|I{Kk&zX_w;PHQ9e}7)Azx@-IPxXZn1T_@y$z9Ivo(3i59yHSy$8De&0(7{_G}yhx zF+OD7#iuO;wYsx?@Xe`5f*B`^ZB%I#R6ZVb0GA$nnSDnq4D}2M{e+`Kv)n>|E!K#O zey2e?f>hyLdOxC0AC!@T_U;NTbW21!BA~2Fi&qk1NC2`tbRR!6nu@>cYPx9E)$->- z`T_Ux22r<|M zH-C!90PP5PSA&e;hJx3i@3W>{Ievmsx--77BTdc4(2`YR<_g*$`VP)EVK%9go0dgX ztJjTjqO0dd{+?CFc8Ikg*A#YKrRe^c9x~0l)m~bR%>!=&$jNpH-M+%(w~4Al#C)#F z$V=54f{m)o{I&;F4bUy|?ySWauNB3Dm}ThEdD2p1yMmT%UkG1`E(>?*^mcR=JN|0L zQ#Dxc>7F@x<&Wz!-nG0xdiLt0c`MHD%gMr&S)0uXs`OAhDyX$+!RFnmW{YiKh51z6 zY)@SfyjyJQ_0DHkS_ZSz_2MmdAdM%cQpz&wSxGwysc{xN22h=DD$?R}_WRP#?t)eL zE`n}=BlZQJIk#)$u`5~2$)3;}s2AVfI|=p9$#oM>yajNb zbZboUYvjNg*wCt+Yf5B&8a$kafDWI}+tJ}7+C~dwS>5xJj)i{w!6Nu9q+<7PWqX?N z@BjBd9_GSP-q#_L8<3+aA?&4R_=l`7&G5Zq@I$SW5ajrR)Jd-Mg$-idK0RoC)&hM! z9h&HCL65b+Q6oZV!dYC2_wdOO^Rm~@5%1#%#taq@)ezT^eUt?QBTUM=s^y-EcbBY( zPx_gcQHF0;#Dq0q4ki3P4XCvF+FS!7=3*U2`03C15iY`xU*G>mcSvU=W*{3uPKk!i zDDh8vnqbs6Ea-Mr*yV(y=RJZBSV?r-_ddFKH%CKIFmPfOQiGQ?7s?z(zT!!F?6O)H zYsi1~j3n7>u1&^Nk}`DuT)~n3ghC7UsQB|$vf|xUSDQz1+U7pxoScrWf`OBVnqms? zbL4S_MRD9i{P0POI7Ga23A)P`HuIYW%;2FSnXw7xT7GFWj=gG^Q~+vK5P5JX+(}X+ zG&sEZ*xRWa_ORolO_57u^3OoJ=9~MV+3sczf+Oa*LODM_;|GdFx*Nxn7nWv?KQVCa zl_;BsVjhAGy}#rzn79!ZweKWEyZ%!1D3dfaiAob3X$*n4sNSs%=F&|gIQ8h0XD@#e z_PbXYasJ>#+efwJ`F_HWrU(CgqF6V5J!}-(t@Sn#( zsxQW!2%-cmuUUJ8@n%7HfA9W16}03dG6=)>lWUqH4f5w7tTK`(3+;sG9v7plx1Fbv z<_qPPo3&Yr3^Q*=7(G?7?KyWffhDsMpRC!fYXoI7k!n?|(7UC?x={s)N=L>$@$T&e zh)Xr1`a<=*z+EP{DT#W>)uf<=&1dvsFoQ0Yntpx59nBPmb%W&}!kQBCjW@Qt^b;ia zQT)gDcVlev3brOxq~APPg;x?pU^PY|Ui@w5V{6x63&?412 z4`%fm8QEpDLy5e{2x+s>W4-f65zBRB0rq>%;wT4R3k8N*9WJdftDT;{!HQa_@<}ze zCt>>^+uynV6Y%9DLe(DhxUvBDin72X!it+LtGyLd$A@=qxFFwX)xV~u-(Lhd7NkG6 zpU~pKo$xsX*Fnh7qqVjw&SPEiYzUPnn`I(O9Z^$=sqkh+_7uFO${J(*c-8qTUBo<= z=zH0S)f7cm3I<`!%PKar7tF=k_y%w%EC`TlI9w+Uxw!cNPtsUe(1WKv&$5iZl1(e7 zw%#lJggPeL!YlTeXlG?ue?r(#HuE3A{mx%kT*9VhBTk>XcI0M6T3xRJ-mNZRBi_y5 z5tn+UTuUA!r$NrY`k{m=u4aNsn@r^#oGSK{N9C}2leRF|wU&z`r=!gm56itW9COV! zTYdV<2cruV^GIEacy+V+WlfJo$cvp~u|4AampK#qt;a8Z#?BA5WQWQ_=Jd}8{^f@c z)#SLS9Z^)=g!$ph;**G}l4TJq1iK%fqwg-Mx`)JsQG^0_K6`k$?d38){qwQIuZYer z{C%bUJpsJ3NQo(`;W)1obs3`ni9>!nv!w_LOF!`1>dH!JLx*G^fj&H^b91Y=4HIHsQDM?A~Lv zvdWTrF}CM@bjXFxLW0UdvmPvmcYPPErOdDgV+%7lvK~7BgHUd?6>9K7N0khG($-|T zoC36}3qhVxI5YR);8To2SZafAOO(shcBh3Jf@?snl;f1;7j!}eeSdK;7P0Q z_%!O9I|1Q%k#73GPSAY%u$eh#889$6r9Xg5J_k!2 z<5#u*H2QzdkjnOu#RZb8EgY-&rdQeg@^*Ro8x(5hk}3%?kL7Nc zSKM^z>@RikDtKMK$b5RtF?Lvkbu?9D7yE`=oW&pZNKO!0)it(fS^RfG%V+ie@&lH; zq@_-g?6w{@b3{0Bn+e8e6Kp0>5xSvXTt`EtS!kqFiVWIf4wcD{yo`keWX26WryE;9 z0_H$v`z5+>t!cD+w}yCJSaej-gT}HF?-nRPpvsRq??|p2eM*EN-G?EAT>SkT3vj_C z<3px@i1xCkNyAT@16C_nL~z8$=uGn(a?lzwVIQUy12L_DNUlRprzdyF_ivLLDdk5R z<2I?m!~HHmM9(2{ma2Ijf=E5RD0YA8QrzI-Scm23jIpa+V|al~DJ`WT-EYp&~-ga-!&jEa}81HUi=_VLX6s&@{71NNdLSC(iC^aU{6&hh*?K{lT zJM3wKcj*FX$hdc@USf`urS^$OMJLhf4gHbl!&v5r2~`DW5ONytpN1tON{b8)@KLU2 zf2j1$gTMf{7uvr5?4SQ7hudz!=T-qxAu0{-u2?NU*q@(JB7@)^mK5xndM%l_r{hq} z+e0wlW&2R$ISe?|Ul7TSo%22`w3zzwCr$>`ZdA=>uEgARD+TniMnETd@^h?9m^?1IS1_6}+#hRB7XRgY-y=A!g(rjgS4L$8) zhnC@1#hgb4Bq^RASUF(TpIx`fwCRe+N%>@zs<>-C4L6j@Dl&-5jy)^aWF?y!;JGXO zgv}#M-L6ccaFFr~v3<=NqJkrLFo-L4k$p!okSlP6?xE@hFoRY=WrP2+AUBUgx5(H> z|11`3&7WL^Pd&AibQ1X1)GNi}Xy_R)Wt?R9OOd^1lG%RUIg%Rla4PiH4n?Gy3)_Z( zATL`(uoptPT02=bx$JgSAxp1^wadoI9^hS(BPf&EG=$->pN~+ky;WpH{2$1Oy)C>- zBV+k%#gEIY>B>KR;Rv#*3R7l?Aj@rn`3@}bP{Bde_G0|@-rVv@ZEv39ALfU?-FrL4 z9AkV6-ts_^d{Ndk$^E+Y-H8*yh&`tlm&X*y4Gopiaq`50-;NnHm0gs9Hioo|87>M| z{XW5J#_}g?TVonF2#%y(J&|^}cPZ3ugDHk@t57cE(9y}&?@%eZ{cCLZVlj}euFV+t z6Z`j6(ot@e2@vX&Lb+|7F@j%tLW54VZBkLqX~ z`Cu5>kidhU=}hB;xyp)lS0@Sv0&a(vI=8X7#9-vNrnl#t8=R2N?oQ=iPdfMR(`(6t zTEYWC8iB?qPSjq|T^1|P+Di#acr&vGB~DJ}*^DDE>!>P+t(|)rTeak%RouIfwTRa8 zv5Y0&9pRtFLot`1WO_pIB$qxl15@a=J+I4VXdF{T zqIc~}P55uA9gmeV;Rg*C&E1|U-hEsTseSnIsx!mqIxDPkEr-u2sv(vkilP8_0oGu-ulPn?%op3n!RBo=fQ`l^JDh zyv=@oWdRHNI$h*)AvrfPre6vQvRi{=0m(qU&K0EEb5#@uqaQ+O4@Q9%I;arYtLWiP zZNt@8ddVTYm=uI=o>_CG-Jj@}-g*E#H0llIO^-E1@%@S1o8Jg&}1>J4C@SG?=lS+}R^|FHw zOjmY%+($|Qdk7bl2)yozXn=~XcwV~uA|xJ1yp_FsUM z&w)=Kyy28yPYETxkjX?u8YHwZ-v0K!Ra{}|60vS9`;i{H_Cq0mB4i-i9u{@j1{PIj zT1JTn{C1>lN#pUe9czi#KWkzBlI;&MS$8cQhGoUnXF)Fa1=&xYTzx1tO0L~czHMq7 ztY!M~BG`F~;7IJ%69Z|6zat?_CijsVK^PgTwgEDEMFA>Hzce&@%weop!CT~b7@fBu zQz&=Ull6L)6^62MS#byNPR6EIPh>pG0kM}Vf*c_t&cWC#k>42A@P2d3sZSZAw+p~r zrNzkN8;+0esOoeV7b7>L)(MU@uYno7R_Uh|M=(b+<2pX18o^R}r@GALJ@(j3L+AS_$V?nYJ@5QMb)76x;%` ztbh;i7Ha|ZeN^Q!GrgSZ`zI?{nW7m32xAqBVBmHWOin}WyO^R~_=T_A0)!Shqu%m7 z`KAXLyG!C(qq*0!&a;14oR13dU~bRJ5@{PKgMtr(5f5 zQ)Y6H2}Zja$)IYuoGYu>peo+x&c;>b9)9bqh}M92hjRL#+s~%)=w|oT|Dp?@1@id= zXMLc)`MMF1PXx5Yh%*N+bp|Rsyuc$2S6Dki%P~F*mPg**WrL=9**UQF&)v0)&J-Xu7e@ zkB|x7kK8muM+I}YS=ntr_lIx1{E9q=XIggPKZYmfYdqu%jhz(9bGG5d*FjDN5ERKZ zA+U;-{NY%e$S~Mj3ctkxzX+e-&G1DuAM@Db&J=h_Xu|#g)sp&n&!Z$QcA&CzPq70u?QY>M> zj9;mO`~k8`Z;{e}q-WWIp|KX$nK)~&TNQ%VLrXi=@_Y3vk+1{-#97w9F~?N%{}D&M zJBnRqidh!jbb`Ok_0IEE{xtvfEJ3mE1xAAoY8hcI2Gr=$gp$24AcU&q~*bXS(9va(C`)i5PvJsm>cc*H6DB|#?Fer#jTJZgwB}XDAaP29gItDdQ9g% zTL(32ly9X)cSu3q^sMu%(^F@q-M1bj>w7>__=zrTW*vguYlttF>_5jwD?lHH2Qj)9 z?0aOGZTQeD7EOaoCvS$*2fV2{#JG2ywfy0?ZHDeO8_yRE>{%E@coVfoxiNE@j-b<2PEf4WqFRIl8-mml(ZOXk>&fmXR*5C@G=GO z$^hQXe3);N67v2)7pce^Q(yp_LCe;-cil8=8z1e{8|1bQZP*CWaKo4pN515zhL?NUD3g-IPb#{^Tk&zU`O1z2~}nh^vJ0n>*^!Usk{P0}t*cQT+gdwaV>O6$ahPUV`qkTw1LL;15h`YB~x1>Uid(M{T_o=TNtR;e- zDxGH))MS^4)84AJluP-{9h~36M#_P&ny6&^5F>==tfC(|xJ#ng%UB}*yK}JEH`;*W z@l8unA>oOmC=(mSJn95L(jY0a`_3ZRP;cC;9#wfhzCGPLMVcZU-M1@{!!O9o&Tp;3 zJY~wZT0KcIg8FjsYs5vCwi|RCGpy=1Kt_|6K;2vv>6I^vW>sR9A>S#7)2N3S>VV)# z3Z~GlSm1Rxjt|yuVAkHyqr0d__P_!(KeX9q0W}fLd8-P&I3nc1D46m|lJgc)S!MeW zYXq%YCf2

>CZ#%)I+RyifoyQI#jh7$HG;ARY!pY<;Px-iu@lTUu}(Vl#>insC{M z8xzcZqDVeOD0FkLPhLL7Ysk8>lLntOHiCv;%uD$wSMrEdE{oA&sAVv4XYKDaPfC~% z6@i!rFJL0G@0yPdRH&d37EumL!seN|*40<9=d#IDFz z@zJiT%-HIhV(-RZ>)m}awvd0gpMFO~Cu-+~g@hIIM0X}n8b@#yU8-r(bQ_N&yhJpb z+y~hxz2&pOZuyw}G78orT$DW!?QP;x;;AlP7@L^e62_ZUL! zooygWWkGqF`Tx|mKU@9__gN!%=N*bJz`CD;hX>r~ql{&%4t8KNW(@69h4*WZ^n2qg zqfj+ySw$lB6ulZ%S-H%7UEFIum_f+pKE`9pT_iVrOYJPD$dzhY0@v|X3Np?N*dP>W za~>5%QXHNGt!hRLSL$YM)FWM-8Cn<=(6!t;N8BTT(9+2zhD`_tzMX;xInPmc2;BWJ z92z4fMtS#OC654wR<$8+u&7>;``GCl6elZ@P(xNSP}PjsnUGl~JJX+o{BnoUo4*JO zm8D&3ZZqQTT3%Wh84LoT?@ejnGyo3trUC9Te&~#dd1kd`%p4Uvq3*|)+{lG1`8?MJ z{-)g1xi)dn^t+%Q*)IC&etEJ>Gk%81p=`w)yL}vzrZ0c8p>=yht=BZy)TF(ay)0;( z2}EC%!Zo0(WZM$QfCXtcTx#ZKp_dKCjUnb9WU%Vx8`+`pg>uiUqNC08ugG1-Gb{8x z&-O7Um_ZgNSD0>!hiu?G$X!w{<9)_L*$1vuxN)pFqHQ6RD;`IZ{kQ~QbMx;yLf)YT zfXQ;OarK+hY=W{$Cw7y-6kO+_ijsk82$EkN=Y?KwWm=Q>Sm`f zOyqhb$QNyKcb=8DN4m^Gg2Ic})k@oXmb~VTUEzOJDTfM&hvR`SQt#1L$Wv!c)IB+k za?MekKZ^9>x1ca{x;6u=a<8&goRZkuBAx7@)W2=%9*&i>OAluER`VU{eH`uj1s?lM z@O6WyKe@f{n%x&Co790F{zBJxIkHP~r9F&0*)2~^u8FkI1+O|= z`m}qMz$5~VMlS)K~C-V&eSBmUtW^5tj zc@_P!C3B3UTDnNE+wn9?Bm0KZaFFMP5=poY2|30Z%bg3|8jU9<$Cw$x;o%f#JW2bC z00LdH{0oc!ZVjGYgO$=wRhO+D2HMbkVVKQ)=6B7xTsw-m#}+GYWUaWjoBv!uwOvdw z{cFgIdvD)2!|XPI`N~Nwa_u=M(o!Y@FIg{ty10k_oNt7;q+v@}B-dbJYX57m3P#xS zvxzYAkW~X?fw(^5;Y}^ZlZZnlvc2ucWH!NCdIwywu)Tat^oR0T$PtCv%?bJ%BKFY+ z%|I0~4>KG@QTB{m+TH}Wy^^TiBqc=S`Iic3+`9H**n7oXQi^Zv14FsZk%bnW1DkJ` zuuJ)q2PHf*tlQN}wB*STjDm0s`$wWMJn8+TE2+1llP3+$KN!iy9$fZvdL~cAoOUEBI;MaYTz*lNq1bvOdDm@8b~~FI3n85| zo$;pU*uG@y`hmqeZ{tka*0@?7z3(O`!keIio_BPzwRRvg;yy#Njc|o}^y7XCc1*fN zpfAA4{S*t0JH(Jf!@Z;HV-V&aDv#SZvy1r~4{Hm0bh)%I#veqDvl^KkT(or_;|)D} zzYPKG-$=_6&`{_QYAf6ASyameAsX#PS*d@tuu8Ik!Qjo`Y*{Q)=q@lgT_M%WG>}W^ zaygrK`=dera|FCuF^hc_xaZrMLwq6PB03!g+n-J#+?^H3Mn*vwhTS8|_s}yi5cjJJ zWKl2V04E>2HB%L?b0`Udibx%w9&a8w7YmU~T;A#v(Rm2A^j%z^PI=JyZE(dkg(-r2 zbJImdxQ>SswE4V5_oyr=*m9?elt#ELxqR&wea6?LmYtEhKK8{$6{4Sf^UEl_-P}>X z{))Vr4@=JYW2%lJuJAfnA&ruQ`!X)T!|M=8)%XftVF-MbPV1<^cJLqKXv&j|L8h`9 zF(qJBM7YK=URH)L#Y9oUk^S8OoF)%zKzM7A$Wz&1U{>^J5y@i{s8W=IjU_gEF@=<7#@ zdoa;%Ge{GR%2XqiQ-W?%ffy6M$FMbgQ`LAKy7(BSFr- zGBg^pp+q`c9G6@8)Yke}noz% z$`mI6V(hXOlv|83_c@4lPcA{OcKmS3#T0_#l^i^|`3!8#O}kj>Zd8`pZH7&?;D|5b z124KS5ei+MtZ)f)zAlj>-fb(3oL{zDo=kzkTwfq+`gh_AD>dYt6o`yFb;;)BP8)S- zM?VzWQ^$UKZnwbQNb{8*glf*~)QQTAN*?Ay8bi5C?M{x0wj1m8%_Aquvw@%WK~zQ+ zTekG(+vPOSBW*~>+y?`SVeH$`>^9r50-<0j0$IxQ3|r54$Yn@) zY%*D#Knuo+c;v|(@T;s3Z~~qyb8A3Oo#F6U z?W#f2mhi=(}^R=TBGX zC^SC99C^ekq)+!s&#u4aaiyfdZBl`cS3!rSx@b@lZ?5mj=?V(pDWbABalf(uT5~Vl zRrfJ%1*F`&wZ<7}7f~2AnHI;LNO4zp>A8CD`lCw8@(W_!f`pQ4QHw{WMqq>B{Uc7< zzJ2DiN%Ib4n)^xk)oaS+fy7i4y=_1TwX9%5Rs^=xaH}()be+*AI%A`_($hrcj&Vtl z1PC?14ZX7#?j)mOQfy=s%(#}@f8B4ZBg!qAB0tQtaq+(s@`}GNCc_ls;&Sw4N;Q%p z@&10~JraK-=DB$?>qx%Rp{XPrjGKyVe#6TI!HKfi5@YddqB2n@G0!09io-S+Ze0~_ zW|29wzaa&InyOIpgA5I%2?g$n>m#Zg*0<>st)07Y6&~jy4KiRmdd=X(BKwEpiY3Zd z?=x;u*?R`2hV@pi&a*=4Gpl@kEVl<)oq$NJZ{i&nW})XK?0n1A_(kbw}fom0R$>Sf$DTm?{5%D2)H)GXBpWa$#N-y9JY(@!sM= zKZO5oUOV zp5&qiK&ibk=PO8R^yCD!t3Q;ywkk(UBa_;gzC$LsLJ!rBV>dG6f(5o)rg@tJ{B2p2cZN#Wh7H*0;>`e{k`c=Ta{kXV|8Jg- zci*~I!e$B>fW<3`ut7&2-_2w}3Ro zRlRV;F=%=ZJ5QM6b<6>L^ko?m%G z?{AlgvM&T?SB%C`cLgz>97lQJV~HZ#WgZ=xJ-LWW+g7|;{FXStsk zw_-<-uw!Fo0a^dK@XjEX}DeUiCx?~}sn!S`? zNQ5h)e@S_bOaE41U@)S-0v~SDAC#Uc%iY?TK6P6(tzF-G%B_$3XVq(W0NubS^G4qpgn(Q8C45eU z3ho61xRN;SU8>cyTh8kKuQStd6;}YuLS~;hON!OL{K!f=&U92I;lUUUBQqm2TpG)1 zKdy|5Q@Yx&NTxtoZ3x%GFicMN)o;?m6Ld3%>&eESO(UW}P2BGm2@V{lN5d2kaL5FC ze87L2ApU3Qni&j;`b>_9mL8~=R9Zrtub_Ojs~f^_Z39!BLBmB4IAAu4 z_RF=W<_$PT-!FXbXWsE3zjPCfWvp2;*m<6tQBEo2O&y43=G0#y{##uwQY=79+~ z`Xt^ofe%)wQpn?}6po&P2-Xnal-@5~ZOXfiugEAuc#z4vG&z!|Kap1qhr%$xJHgDsT=f57d zvP%U#Pa8c2nsCa>80!)J8{1t@lH@kUOg029vnK5V^-S#*R6CvlmO4P{Ppy>fNR6B< zic_qoQE9({$(M->*yx}Y!{H*&Xg3950^2CU&HlUb{nfHib`CaSiQ*;Ote}#A`yRjm zJqXtT!T~=pZ`?8%T@TzXbnNvl7plg^oixFaj`JoUbMJ#=Fny89l%Yd5fXuzs2k#_m zUf>@$`^%@h_tSP?V^4@z95;ZU?TO}#n2Uyg5{0u7GMQsGw!oxTNU>xBMX=jPlCtgI zl|pHS3r0;IU1SSU{}H&}{+<+aPeFZAzuw0z=Sc#e=Y$!-e)bRDS(AHyFYHk}^OgBz zJ9tu?jszk!pRaK6B~I0*RizTW~PK9R{MIA{Bm&V%f2#z1?PTfbI zgl20Vzt*ux6$O;@kDK2oec+z4s{zsj=@ZHmfgj#l6@#SbRN%LURB=Pfs||`D@|BB- zjRh{l%W*T1a6&ZyA$dvmUts>j*nGYxDKcIQvXM$pzxd6hDevZRV)y8~U9nq-B|C&r zKPz4z@D*4}Re*Gu?v~Qe4tl^eK9Oli`OLBKodvnlO=6P7h^W?5)~x3tzyoEXb-CE| zch|j?$8RPe#W@+T*4)2R#u@tnC;eKlP%i>|2TeRUHib3@5*TYRfZ11C-kkko&vNwR zoa~+N-f2{TppX4vh3ez4t%)5o_6(4onL+WvSt^0`Uo~_E@N}y)eDKG7*-=L-o-6|6 z9`i&n3gL>~Ir|O(TuMYQyW5S*P>X8@agsr^~I!f_C+ck4Rxj1#vd#Cj-qQP z(JDECrkM?o^M+-@DCVj_Kij=>i$awU2K!5LXK4mL_Y)KL`aKcAKA=KV3NTrdi7 zTV2tdf{E@kbp|Lshe-x6!sH3_&TV)?iv@9EKK4iUSDMCrJ;tN=zYuf(_g~Exgj&uz zm2HyWJtoLEO9)2sRC-OX(qA7Sv<%f&sv}m-qB?M0?=T3Si-w$vmow1 z;31ya6s;+{U}*X#&z}%&yrSFYs{sl!yU$v0Bk8^Bgq}w93W7|WARP<=!me3a8|TFF zkcz0pyC*Ud27ct!lgW_PDp;gaFK|g%)f!|F@LpEsVDmk*zwJy40g}|qdg*)P)U+2c zPq$(j`8BPE)Jp;y<-m++N1Ce*LB{3Z(J1s76k5e%>vFhtUeew@E8B9l+A zvs#?Z{v$EFSbRz`lije&U;NrxCE)4Kw>ofxX+seob@n$P5tTSBcryEFhwIeA(ieAUr*H7H zdtwODM?N^n35HI7hF4yz@_jXcibFn_HO%Dkb~xb=qZC)+q{({|>`N&>c!R|--~#>?+?y{2-$vWt7*yG1#=K|;a%s}49V9klw^0sMG?Vq? z63A(j5??Q^`tn06pVGTbHeSE=lxdxLWy3}_<(jIQk1-&nS=}$@Gm_b4M5XZorWR_P z_x#cKgw;USt>|z-3LrrS3)EKNbue7>1(eR14C4}LEK@bCj<&KAH<{X6jW0UV;pua$ zq|ey{xF&F$@sig}xb;~jar%{iCuMBN-z?h8VDY_FlAL+!G8=M7GwqUqNaK|yBnW&hynG$m8T$}>HxjJ=;-XL75 zx$0=7$M;J^m;YQq{w4iHy+rs4`FufxkeAIp>X*m)Al3$<7YbEg4B{xz8bf`RYu?Y) zl9noZI-n}@(^-7>8&+Fw+ag|^dJywkY4$0AcX!&KFs^ zW$3UjD1Ypt0l@FY@eT>_|4@hu(wIOY3ci2aj%;a+|I3M%b&kKy`(ZPYyQ`K2ZAk_x zO3iuLV<16l-}UX%0n>QwU4`@Kf*uK2WG{IqoeV{ib~@vwX?ufHrB#~zz*AWI&QMWViheB0EAlHgacAuFT2IWGN;|(}6#xt3BvkAQ)w5R!j{BzV+={ z9Ns@kY8l>IYzU>vM8t(%FXYP+?!vyH36*YM`XsL}#n?^*u#wPCE3sx?gvFV=cthHl zvUI0U8wua~d6vL5xnrNk4o>>WbR#abUC_k)H0}*Zc*x&H|2y{ae{Tf;@vmmudwjKQ znsxQTg4^4j;hDUxiuFtrh$Hvl)1-Rvfz2_f4##*95*=ujR+l&7p=}4S7>rpptF$I* zN`Yzz>>`j3l`@)SH4NN)P-@>o;a;0l$=42i%opJU9n04E*rjBKdeRLz#Wel&f8s!U zHo?*!fE(iSf~OG|vD3Lh0{hYJz-{2hT+;t`h;DGxm?+fMSc_pOsaAmkCLo(H>g5+a z|M5p;Vo$M5**ca?v3e_AQgRTw@QBrG0s{y55j*2DJ=%w*BNBFx-QaI4v6~9S-pk)Y zylM)xUjQ6jHj*74&hFF+`15+{nQ>}XpmC=ww`NpukHZ@h19i`-Mw_n`W8Fto0L-Ij zJ~j9BX%vun5=dVHf}ej}9z{Fhb?XFc=mPWl>icUzL-w9ls5qc4)?`IOCxj=#wWcRC ztjNQYLy+i_139A|W$Ap*1DQZ2y}ylEr!B~I2-P-T30u&VpMmLEqHn3M1{ac)QKJhU zogAq{LMpJZGsB#p)B%R0)w+NQ2@WM%`(f09T(cz?RIx&jYzZd*?Pn*&n2Z1eOyoFK z)GJ9~I`Hek+dN^Kiv`MuD9Hddc;^3!QsvgtG-~PIQCD1MGwbB<+{05p9FXQ90k_L$ zRH{A7>v6Msd2YGP3|P^MXF>)1$RmJt4$U#QT2IoLhF?z=u|AW#Yz&$|jN9Xe6> zI?f_3OXJ1SpW_ICgaD8j3DoPsz+d1O3;4w6jz07tu80G!o6lroeftn$j{mMO3ypR- zB}|6WTTO+6UO~@kdl@5@f_`S!Qf8p~`-E+05$)@bria9{rtS8pkLVPDdqcMDkLT3$ zo~ElPtZ=#0=9Xt5(J5g#npJYOiA8Nb8jFZx)HcFcM9?5q z!{0Q&Jva#$^vWmZ(Up_F0@+t*J;$V!X$+S=(@=ZvostDx8HS+m7)FMeL00{C#U$(g z;axkkDVDd%3Wtb&Jb0un3gn?}K1FS*v_j#!ntKi%2)+9kUxdOnN31`6oWY95y{Vxd zWKI8Bh25SjMA+8@dF#Lx^0v;2E-a!o^kt`kgT<0)X%3<*uuX;WhY*m8-zlATJlfWQcOpf-T0@SWqSZUF4?NyXuw57)aC`9XKZC z5Ygk1Ct|=L6vLQw;s1e^qF_GMnFb|7vAk)ZuR`_9fe-gj-zfEVcc_$sp6~* zV{_LDKu5PAr~XI`bfj|b{btEKB+nQ5+#Y4`B)WDpZ3~CAGOi(})X53ntb5A$W(1fg zV>4%;1oLPYXAw?%TAjw%rJ}`RORT0K=w+!H9uojMzY_J6GuRD3v8%hZ^k%#Y%(wxR zleU$(vcdr};?Ebt$HLWa>p+P#)=t;(*Noi-oAOnk?QBV`}#iH4Y;z6uu5sKH?oYK;v=bG^;OZc8lgYC zQTs>b88L>o-+qy2*@-~4KJ7Erd#&MM^)=u2M#$u&rtu{zPepzhQ=)8FDAO;@Wu)m@X$F)kB|inn2y~G-(DCc@U^o#gLQNI^@+Yx$!;OM`!B8OBp(} zgDbCzbmKP{rrfYmkn`uxm1KeBtp1Ukp#K;^e33l(LwnRBUC;n~g%56`j&?blI!;|2 z7u?IecHFW#%N$SfV8Z~4ksR@;x#!rY0hDSDAmdGWyD)F~l=6sHW1G|Gq*a&RN|FlV z3M0M74uJLsv)-KKtZgioLIw&IM|LreHC8-uk2{dkwGH(&C8|&KMYjH^I}YF*>-;Wb zJ1J{Y$KOC(kX2nh1(NCvIX<3G`b2|mt;DMq7k7YJ~BMBfQq_&M$ z>zt$+lbdRfLt*}iE=9#f5R zNlMr-9HQ^WK8VKP7l@fiYh2Th$T$C;gZRJb2C{+zoWmy!L=f4rO2Mz9s_ZtXZ>v=k z7b4v=aQQ`-$^Yo(s{@KNGK}Vs%gbVbsU@#^rC+E^_c$_Io-dFy=;@%H(Mq!dYMzeD zYUt(5MqI#t{8%Z(bkBud>6rv-qV#V+;vNNc zds(kNZzuvRjNhvA&S3r!xwm<^ck+Z6OSS_V(yusy&IC->9L_J`#fq=&C5^9cgO`F) zBku!6zEPy^e^h9`IWWN-{;4+X2S@_${v102Ay1ub*!n)1mhn%A`l|P^;Ph9U+_(7#3Ple zq-FqD17J$6Y^aC6L|VVNlje3@6(=LjsB6Ga_`)f`q`JEBVAp)Fy8@9Jg1<@`KL ziww}<9aCw15f_X{x6w8o!uex0l_y9ydV_?*;!G%6?h+q7(0I(}IN+?CjT|2RJF}Bm zF-TQRw#%YQIIa=wZeIxaAZ{u;{Aos({|diX{!A~_!Ey=@2ewPFu@(obS};Zu<&un3 zQ-`G)&23Vx80F}aXK8qdA^2Ph@6x~u&B$tf~3%XGnJF9FaJpf@J>R|{Bd(vQPO z07)S#vXIYrvw&mcm?;#53c>`jg;aPONPtLdcgrw}-^*Bdl2X{yOU~D^dOkA+z@nRr zmYG-7X@FLwbkjmo!g{7dP-9nYT&({|mC9=PEjgex)F<}wXF3IZUte$n?En3r<`QZb zl1xD4tB?*PAo6aG0dTZ(BDpnM_{;v4PHC&dp6VUDpkpmBxT86dLJph7)SOk52;9CT zxV)Z2n2V>rdE6|*h1ZD1@2)>D$I|fli?ifaofCpJ z+*abZ!o(-2OGzQ-z$-Kfbs2};JhIG*xk}_P53g%U&OACEiqyL`r2a!1|SC! znx?d!i2kjMbMnOcKSEa`qA=R2a(3&3B+gK)6we`fm^cBaS*Q<$5H^Q_>;yaKwS$Cm@F0BI% zr`NbA(R_`KzueBF(1LOkGs%zq}N_YC5`A4jl|9a%C1lK?ok!Guw%9R!kTp6gIZWA z(lg~Q-WJ2eCLkyqnb530SeK7pk|G_aFwM|=`wpTAd{hm- zwW4eddoP&fX@Wk9-PBx4*7(@xYs(*I_#oUBw+|z!OiSMMr%Uv$lU9{i{Wfo=HTQ%Y zeKNr>f0ycj3gRb2Fc?OJ&@ueR7b)pDnCx&XLSYr)d>{P?-c1Mx@*~j)_zy41%=DUo z8lU!(z7mp#>ASOO;bYXz&n450>=i~zExl*@?U8>eBD~xii(jT$Q(}B|I7LIsyRFw! zay}|}AhDuUI*gnKNj4fr32zC z;QIqo6;}1Bpw(OE#VbI7UZy|qp>QyG-ID7;VlDli_5)*)@l5^;eENgDj?7n<~UL3F=ioHIan!K4p{~PJTX+raW(q>R$H<`ALB$0XU@C`T+Ao`XU z-{d6fMbwE#r&(cZ1SNWime-H1=nLo%NRhs_E28&eOcQf4H%`+wze<1JT8e>Lq-}k@ z5@X~xZ9(We;O_m}9u?^$v&>Exox>kB|~1J$!DcvErMgG3;W?L7g} zWNPQ~qRycb1EMPnG+)9G(Tp=)p zC1(IH1u#xLZH+g4H(k4o^96^}Y$rn6B25$SUmCYrh=v1bhOglES(x$DKIlxMHh*lX z9S|=bQMDyRe?nOcWMbV<`0I2`HjX`$j}j4?>9G!sJ0h~?2?9a$Rbp-lNGtrh_ntau zKPIx)D7RQcFnJVd`0bOlkQj5}waHujNGVmU!^s~bwB-ViCQ7JO-hFt-qjsNV?SkLW zr}~GcLLWWn8Mb*6!<$Y)s-4{CSLk&Oel2SX^{egbaKYT07oXbS3BWsB9}c1l zEB-PR*_KxwVw3{AZNkueY3pAEUO(YVxT7_>l73hd&vTP;7!UQS!ebZyB{?tzkOSlX z^bb)2JXZ+Nwwr-v4EG+{Kc#tM0!PG`H&Ymfw>#Kl4Z6RCg36Yhf#&=Nz^7p33yaVL zj`R{#m@8?miz3P&TW^l)bds8RZs=kNEXtF@s_tP9V}Q7)0J$)>rf?|*3+8U47lF~M zKAwvd4D~!2Kl+#LtRnJ@L1>yo7e^>as2|94jz)n7-%58p%NY!I|EAKx1Egl)t=t4< zB6rX32?AlvSh?m$pj7@kHM?4HhC)TpQz^jq&DzM;dQH@zoVJLW4u~f8vCf^Kf#3OY z&eVKWM^zcE^gTOX`a0X+P@BoYyJ7AW&vgqtn!7kbkh|C@!dD z^;(6<+OC>Qxt{AnT+dke&A~eX@>v?k%YZ}$u z6Q`-X8VcA?0HfLJ`qS}RkhSu+oA$+^QwM72b5B}mNLgmr`W~+n2bSj~!|@LR@629= zwC0kP+o>0^VOPn3*|#gMH%8$(aqg9hSPkvO2A9`TfHN&7>U{aR;)j`C1p#>Vvs~20 z7hxU?OQC>nW&QfGDeA7j{yojaY=r#y0HnhO&`@W8UyQ_{{&lP*eHvgV?nLT3s=|aoWM}nV`>K{~w{^j2(7*XZu0vO(L5s#dRu z8JjBi~t} zaxi~(goBRR^KQX287+j#MLIpdf!eaVP5%&xboBUlW#EpNzx>VidVAzzA$H*2R*_XE z((Il1@^p`S=R&A@+NFijcWLt^3P7^^sVN4BDGX5BoA1K(pN_@(cEgWh)`hu z0qm~<%q`=7s=bOtYGyS>6IkAYU41<%?<8OfEQKsvwZjir`)C3Q)VKDARpC){k$k-X z&%_#T&B++s4TdZE2di`FB9a=ux@%g%4y5`yv%Td>Kvu9h2m<&#p1ifRKNv{U4VR9i zNC~h@>|+RjU62Fj@N8Wu)`W6j!|?cjla>DeUYX53({ZfQMI8NuKmT}tcC~t2js>6m zI91N{=zQdMA{-VBJyH-oiWRyH1UPkTY|oA8%NgjK19sZ*+10tmbiP)2moeh%kyU;W zU^gvfOhUPawHHu01`tj9qvnZ)s{q$1cs)Cv4-L!Qv-;rSkkyqxtuUUdwZQN@0j64= zNuPpr^f_fL3lOSw<=?X2%Ynwm5*0>U90VlzlZ39^5V?oQx`UyUK%mqutNT+2KzmmE zE+JWs7lPVWip&OHhTCu$kt zw&$ZQG0s$MA^}g+OUUAU)gx80qb#})`4Py)lrqVxjqU}MykJH=U!QlaIivce@gO#E zotquuaem4zj_S(4Op^gF>X!~J`5JH`Wmx$$dT}vaT6KB+<T|3o5f_04Z*W7KbLoz_?LM=E0^1)V0k=ydLdG(T1Nh%@7YJ8Qu5nTXo1;@N{nlFV z_(tU0nrMxKO^zJ(LPLv*=dFN$Fn5FVzr3hsLI?Fb;LLh9Z@CbTQn?Y`PPyE6BKe4N zA|YTu%}7YxJj*7&yEQ~B|E;W_`A}k0c$@c#XC(a4=kVv3Y>SO#H2*YLtuXhIeywgk zr#smFDv4;mfBymKizsIV{UGaF5b>b<==6idi8n>2<9324ua z6&xIxQJ?D19xzRyrQBK4G)=$#kx%Hc_L}_Z1kDUBuQkQ)l6m2SHXJ@Gxeh*CpFxIK zXB17I-nDt!quc*W`nN4bWL2XuC$0HVoN%p3-0CM^?;Wu|3CWLp>{Am}c z#Prk8rS&qIGVa-oSD1Dk*UG|pOVobR*Rza;MU5=3!ph++o^jRand_MvCGvjkkQl$d z?I}pii%&qdgHK2c_22#&e?lx>%PR{h&9yfV7%2E?zx}}$ zqCnD0VCbCE5Eg&FGqwx8HJBM1;wXS#m0b+2D`PUN{(zPg-Jpj~pVJ{Xad) z@B73MMVLUj#rHbqE$6#uIHSQIj?_i;rO20Y*G(EpBQT3+apG;EPclL#v{QlBxtKUsNjp2w*9n-$vFE)-rEb~6qX0#9MUdzYeG$C=&i68SEkIVc| zcc!)~aFZ-byH_~{Gsoqwr@E{RRUvpc{1BS*z0GQ3iJKqr^+{Dss(!sKCt{8;%lQMk zHbgGDUEXBs{mBudq-#pje&4V@hRe(_8P%ruIESlEQhUYPmsfK?k}wf{=Q-j=)#n91 zom$Snon{9Y3pypxrvNF$-f`khajSev)57|flwh~gwCbo*N%vezk&5RO(!n%!q zS{Q4x7K?a=cwhkgHy7&m-i4Bd%Qvs!B9gcMR&_wW(tbeQ%r}2(_MT~+;`c1~`+TFg z1Mje2U-El8{^h|Et$VjRM`*|Rzu?HabQ0|OLCRA8M~er;|8Zhxm&IZkw*AaP-+q-i z1hI13;BjFRJ4>N1Vy-HtR6!$4ZTsxRmZ$0R9f&x~xWcggJk|J(Z|QkjXU4DZpC3Ty zgi!mI{IHW8g!hsXb~$?M;{wR$7acbA{Au$6n3UC!!Wr0W}% zaT8$^T69uy{Xq-;{uyG00h-t^zqkOtX4p>@1>?^3%@LsNhe z$4{-bLmH6J4-lhuPbo4Pxy!v8kju)jQN)p}k?q0djfVG@rj51fcm||Z97kL#DEVw4 zXK>3r=6gMuEr$4}o6zJ*%|3^w1;&0`*o=eU{^NgI`u@3OEPb<2C=MJ_O-?DqKggllRE%FRqQDt@iQjy9Pqid z(2<1?M<7_g-clX+>Rc{Wq-Nr%PF+rP5`*e%>tOmyoyqx8n-Os;_o%P&+jx;=vY~%D zW22!uqkTv>`qNX*a9cVegrY@w4}8?q0mL?U;6hxvC2UFnDg!3+8TzXwuZ=XKG@#v+ z&s@<9c-CWE@X_K>d_QvHbONJ}tdV169>dB6$DT%u(9pG%sHD59}gnxAO#4uQ4JzbU-_POM` zB^*Z}Z`~!zgu=keZSBTVJjOr$k6PaUTUCw~=at++jk0Z3R)hDEO z+;LADf7xlKAoP{cGm6O-GYn=&4Q(csE{5@;@7w2QvoJX zlU-xoE)+fO#i&VegYb5KV+KM;n_zo7AhPbK_>uG1ZYfds&E!6QM+%r5;}v#UGF(ny z7u-Llus&gJ&UERse4ycAI@7uu`lJf^K6yXRLU@I?ngz6xzp2|Y@#|8Fn}ezj*qkVn zaXp~y_&vrTx+*XqzMW3swcFRuFQvW5VWq~yv5oJL?7E*RTkxce>Vo$;NL9$hf}#0S z7Jf;w3Q1EB)*-yfw&gLe%~d^9!?vrKyV5Aeo-1;TTa8KAoIE9%A1V=o0U<&H8Cvtc zn`K1*&UW!dI!(f+nB zW3GGD-7WpxCB}vS&6L8lLsbmU)&*C$uijvgTW(*Mpt2)pDpLJ*a9n?)rJqJV(~s$v zWF=!;<={O~pqm`_z4o06H;P<8Ble?Hd96oEE-3en-)R z#&Yb4BQVpTXMY7{c$cl;X35vbv7fA+C*gd0D=E>j&T8VNU$U8gq4+A`5v7Mn={T8$ zPl}o3M>PJ>nUWw6$4{T;H>0}l0PAfzbD8f*u9I(h@45HDi$8%j);7yz7oUYx-5H_z zRk^bLdPeNujvBQOhl|ApE;Ut<_8`G;?vT%vCaPkjBYlqMu+Erj z;n?|FPdkk$jhLxiXd8O;j?(w!5CA($06u`pf87-TFqk!y=sNm0zY?=m#89N z;9lP4O;qR2yLrsMCIH{HmTT;T<(4-*qjN((?(cK1P=Vf5+&0lIU%!m{-0J{c^RO?_ z4a`ZOdvcnf1GVMkA?9q}NXxj*HF4*_kUcDs#{0_JAcI38uWAtX!V!Qh@k1xksUdXz zX~q%dw*jppCk-5-bEoW!^b*oErIE&~cOY@tKp`4zM8kAKn=nj*u90cl{$Ksr3T+E1 zL-#M3$9N2jnU3(k|tnt$! zrBvu8|6RjXBcx&QSL%zE-EWy0v+XyXV2<-WhXa-v2a(8klvn8U|*1qWkr9qTsIk{FI?55mWWxYRx9ZHBzb0uK}?C z2cO5ZrT_`4HFjBc1~+O<%v5IO*l<~lnc3*N;;7b*zyiGN#Boc^f5<54@KC@MYZUAg?{U3 zg4@Y0Rwscu2E_87T+uW9p-;pG<1UjdbNnhtU4n|{#N;hqN4o^dY(^)k&a_Br$Y-&y z38^a5C(cETSxU*aOp5x)^sol1d(lco(|Xv3C79Atd=A4d`OICfdzcCQN%_U^b>=bA zeUKrxqGFTK9W!Q$dh*sU@GyKV0oKEr{moV<%Jh32t1<(Tt{sK+)rgF= zVX}f@7mA~bPF8q2DKb7=);Ks}0;139zkCk#`KR|#7OiRLMVU_6?83pW>$d#$aB4w>QV=#<8YK0 z86LW@r8Ir%(5XvMHZY-LEKz3>w8N0@e}ST8)dhsphP}XnAv67rV3Tj#nbjG!qAw3_ zaP_Gb4$$PVd*<}Iw#Ui)LF&VGWihO`;CQ7pv@Rhj31~$?SxV%Y9a{N1CWYcq6tcJ$ zlhHamHY=eoMS@x$co#pX$AA-2=(zG&5T;kp;s`3b;>-em@L>N&@e7PbJmbstn4~k0E;>jk?O@+3pQs~ zTz0^9Iya{5rw#k~*>D6;OG&Q76d>3KLzdb)Fiu95?KAnWmUv3YMn}*2G%oP@uD17C zN=d?Fy~`PL@h&hJ0FbSL|4?ndJvrp-cB*HzU~yZUf9V9!zT=YfT50zxGmc!n%TBJu zC(dogl|<{X#pbYnQVcZZiVcmN(xiZg*^{7zJYvqk+FUFp)5_0vy0yKhG-I`K)H2dP z_sshn-sPqXTvv0ZIkA+HPz@}k$gAl((hSG;A?Muz75pnn=>bC!Q8XP zcDo7I=1=KZwUjVQu({!Jh`YKPa$geOe@lky`L%RzIe+Wyd!LPkCQH;o`V;pa25a6Z zIcz2QHe90-7u;!?hSnpv9khM#fy*@D1wGu78SWByP;2tolMYLrLZ_U!GeLb;@F99;nzoUHFCs&M+m|fwx=Euqpa>h9G`AhM{Oc z%Bjj7U@)2%!8&Y~EG3}@shP;?9nOcYg?5E+Mh}-E_y>336wi9#e%AU5DcQU96#yj0 zC#t-wd5m43BW`uf*qiOXUaG3I!+{_qc%)wQm@YlYG_t!?luw75c1n8m)`%_vekggX zT6Gu~hm*6P3}KFX^8&z$kN*4vz?qv7D%~+(D>Lj0^$1vLh{E%0$gOoabt<)&7otRb z)?#deXwCRqv_Rc%@}NhXcxrAQKJ-6_gI+Ucdu3Z2p2KVKDZMFS#Kw7?>D)eTvI1Fa z3HgLF=*)eu4UI)oi<7W);<}QMj{+#NDIoVu$HG;h+WctRmi?!i$46^tO>P#Had*FY zhl}0vR1;V6ms{)&)@kwij7(0Uzc6m{t-j?gG%jzG8~eD)+NuASX_~WQ^N-JY0Ns~= z?Ye*BtjOIYzDGL}+c#R1QM2&0XZ=)Qfkw6(OH($cL(PH@MW*yus`xkWVUP?O-HAw~k35mDo6z!`#m~nM6-YsP-RaM7OSfc23#i1`}S~6Bi4k}XpJMf^_ymbaG}&gV+$k2!CXHqRZxv)&`COeNNLW9RG~I3Luzjeaq;bDrq@~>&r<%rnSh5S9< zIDsLDH^SU4U>ipFJ+?Ad3@r5w(k9?_HWpq-4OSaHoKsKPdhJ^mLHt-7YH~)KU=fjb zCbX~iScSWXBF=#u(rfuX6+b_qo*ee$Z#5ogy}?+`{;o9Vxzamw5z7|5C?Vs3S%Fq6 zAcSpq8m|?K6==4R*W_Z}`*Dp7{-d2;biKGWU_tCn%2gGUaYL&HWQABW!l zA2Zt^vE(`cTPIJnGDcIub?0H9zH@t%GX_b)8+nsYj7LRYa;9p*jZI4{5J@)OC?(9& zoW4DBOI{$-DtYUtn16M!5Kn>_ZlMrw?ArU56nlpb3H>CR1a@h9tzhguS*mj$YVF_9 zZd5H+>YjPbJ$q0$+AP}TbLX8>(>y%_>7cF4%F?{l+pXxlij#5OaWC?nSsTZO0T@sG z0kU-_-4%~8sq!V5wYy|_P+Flo0zKiz(ju|uP&EHo0xqZ(v+)qLd+fO!`LQgkA+wPbz(9uG)n&_d?-M z>CTr8oux@Na%GjiyHy>w>HVFHe%S) zzCfqMIw~9>=nmc4D&i~!_lOO?>CYWCvfE+{CuNvm`z-$wJaFy(Ps3`rb@l;j{`7OF zG`wfvlMF?8trgOuDwhDQXoo;ga_d&iW4^uwo789twR@oZRNM%H$82?W`ujr_EA`*R zKLf}DblQ<2z?P*GV__eZcV@^Y`|K+&XLf#5jpr^U`rxs`q6SbTHcKcv!*-Yvfs6zyWMRG%ypxrs_+4dee%{9aNU>%4cR9DwUknU zO>*!yAK_}~JEdd+0suhqYJlYflPk{VTi|6EyShe9uM3`R_Zs`5BS)kyb_9e{AA_fD zzH4_bu1M=}Pubfg@7GCB<$>Kf;7eYs1rfPn(7`|bK4F<9DHQUK!a5s3_hFOClxRnV z^%Z%wLeZ!vF04x+>|D^DXZ80|Ggim7unl_L?PCt+F)qVDlB}HIKZxlW9_^i$68Wbq z;zqu+kn<6c%QH)B#;J`@EZ=U7JxHz(CnRsn1`d&o)lx?Kv$>+*#=LC~`^4NFeprF7q)}*zQd(=gh}_t+kBF7A0A#iKU_{uFxvVz`8NH(O-wXqh#p& znC4ePm()o&f8}^CEx0~(pJ9=O9eA-2=vq*5ox89Cock@z|HIyUM>V-_>*6Ykx)f1C z=|!U;7J9F`lq3p-g;7zefPhGoE};aLiqe7+q!*P4A__`x0hAJ{kx&8z0#Xev^hhA& zzH#4k_8EJhd+%Dyea86x#@PQj1`P7~eeXBRGoSg)nWG9Fr;;54xxS5vMP9h(Ar`!Z zfHXvXHgU(3A2mf;zkDvB676l)@^+|o7Ia0Hx1x7YZ}JU5lBz@h6{o9XJVJ#*Cu!#~eyI8DVc zbPS+obBRA*-={pibVd7ORjV~u5oo_Z25TEI8oeBGpn-KOpcCGy5{3xaZ`npANztZRGawlB0 zVysE)Z}+Zs!k4u6hFYYIX9}@jEcTs&oS9R;+&Zr=J1L}eiLlo!zu%@ucK`E??C-iT z+b7>+Mp^yux;Lj=;EuEMBxF{bnV60qqAF%VBGtNIxtS!ZzVNB+^nuSpTeo`Xii`&w zBCo(-do)McNRht>HZYc+89^F+XYwmHA03CV>E z@-8~28@Dod6q)MOP%oT2@I+#$^9}3mH9QCj`Y*BT#~q3>*J_6DS)nesz~!8TWwzaz zW~f_4>ZK}@Dv2tjE4E?NUOHy5=c5_LQC)YEqxr6{KbHZ`%}zMcHEAJ$Y8}H^J*zuW zS^-7*P`cC(DE+2)r|}1SXv4RwI*rG$ep+R}{GQ zb=7IL>Kqp=;@L{%%R?iS9z=Evh*Vgr>rcvLcg&gQH0g)h)qtoVQ^gvSq3m?@t*exnW1UOt16^m? zThDj}w<;b;TzyhMM)Z)lp-8InZ9U2Bpf^Y`Y`G!2dW9*PAV}jDT6dC{()Y-SoDKwC z*F@!;@9l8Ba!DN-R|e=3Dz3PlAmPkMbx61uqpB8{usSCu$sbDTiloVewr`l=$%_yj zyGks^IdPLEp=$$WXb-R-*L9Z}+v2XHKLEI?31xnHDl{i(N@i|FN@d*8O3%;BYjdFb z-L7+)P&83WbJ5@;26K&t}E4!gr@jX5TUB8p;9HRKqgzpy!IJDlNJ&t%L zWr}s}oe*OPhDcFXsErb;*?wKkCGm|T-ecNGxpgXv(? zX@w?)VT0Y9apX`Th*;8*cyTW648|@Y&sem(&}GTCKi=4{O%&|)T%+0>HnzwsyqDR# zVIjr4!L%a7huYv|%h>!;y)CfH^S4MzrK{XH*v$*uEn)&{5vV(-oo^05Qlz1)<^*N7 zJ!g1Fdp8}9-AUTG*#Me7PlBHw8NBrg{>UhC*~`BiJEF%F?~^CFOF1lY|K4aA`t?J~ z8Il?((%RRc%&XAk&tsktOFanBE@uD*YK00>N{bw}fsVmer(>&!EFqQyDx~x?QW-MK zjR`5sEQ2Uza5-0Dhn2=$g&QNRm?Wh-I}376r-IYAq%%;aJ(O8(?M9-T)ZvCQ!?2k4 zCv$O$o4W<;f8V;-1;r)c6TO^a8LKC4)vrQhp(3#(!L0jv*nMg8&FQ+V4I#$t+wWhN ztJAQ0rqq`p7R{7qUG&#CgrbJGA2(H%xM;lwXElziy5s|9V6_ctvn9<_yXSi7&MRe4D z1jXOm7fqzRP+arcoV6!SZq&cE4)N98et7TAn{cjxTcjF>w;_`e9_2l#u(o8keZq?2 z8N0KUFeC&y()y%MsBDdKi?rTI9qKlv`c;~4u#|(*gdy|bvIZRSV}c0nNf<}^;Iyq8 zA4I z`*(AF-~SK4`^}d)f&I)`{O5BXig69G96s%K=K4SNuC-kp#B)DL$kY;;ezsE?!xE) z4CDVtkLZbf2=R}Q8GX4j=ytYl{j^2*f8eqqp$f_zayqb6Q1OpwN&n=*fs_;YKXBPCTz0pIhZRJX{>5f})}E{8 z3AUP~;9q$E7LIaUN^bHHxcyKMh487F4Zj#$bs!VkHDFm}J_o925vXQ? zO*7@g&L8&BNU8M$m0Z_bne>+OzRRbxw{wYf)T-EDm%sZk^!|a+Kl#S~`SIkb+($#0 zWW_bl`(Z%VgH6aM=N2B0?rMq;DA|^9e2@L zDZmKYK;sHHG3)NIAW()?ymek&s&=Xa5cqS8|5ak`xs^9ak)QU5o0&rDKJ9R{vh(5! zOw%DVI)1@Ll}lneaj}q@t&gm(aUp_^FKgwcj4}UjJ=LWf83~5&PSt}cpN|gJo#KT5 z?!AF;>~Mtk}h#I49O*hEWzK6OROl{pQW-3|6-73FeL2gz?Pz1CHIEb(VD;**`CoH2oM8;w<2CY+;rK6gn z7=@e*y_;H)s(9Q7iji1GJXZ5*;W|OtQ z&}@ZhU!t^sTlp4t17DjRT!+5^cn$)npg)_7$;4vR6iCsEi!2{&{pbC>6_4`g>YI~`|k5pRcLmwOn@e3x5Wz_7l z&;~XAJZ1}?y3jRYNU(dIq0e-O(<$o77}FJw@ja8@IiF&PH{oG`AqyAxo%Yh@a(Q#=<$7!!8f2* z4hf?Cj@5mC>*eaz9#^3>c_-Zb!O$wxoEtQIi=EWMo4CRR!-rV`1P}b_?Uu~wix9Dz zZg@nM*v(4kHw@28 zK!G?n!+|&@HzDz*-z^V3x+xV~-J^mp#sR*brp|{Ps4=ml zEc0D)Ln(mTG0VC)gkiFJtU;D@jfDPU%<6C0gh&|%r^V3M!^6YPQXIwTokOxhP8#N< z2im8yHniQ9ZGez&Y$d&N5DpYIR@MFac}x+z;uwAQ&pW8yEy-GI4swhKg zo7&kLnCZM2@*&3Ca7RY~7YxvQG~=vjZ$bt{s8nu_90R3v$sXZhtXM`N(*y{Zj>aU=8diSRqmnHRvI%*uG|(P5V%vvG63 zJBb@hYPZiid9}mY#V(7ZI`;jz(8pk8MZtYBq^xSoG5ENa7R(C1 z(}xSidjXA&mm&MXu@3jvR#tW)v~Qy~{Yd59!O>`Xi~XrAu&i#^X;vVaKZe=8Wb|PJ zT_J@xK9e}I8GM{KLt%WkNpnB!*N26mi~4SHaejI9P%L@fhCD{OYOVhgOfGZe8pvXw z4_5c0SGf3MsoBC=*U?vw>ore^8tbtOp-fvce}JA(zstsjtqO|#HGg;d){&)+c>P$aoSz7dJuA=R%dNk+KB%|(!Vb4qLPPs1R?T@CGhWEnG&UM8yikZ8SN@`0c_3-=v0EdBsIp}&*%eVsa>sMF$RpR5Csf9 z&^MZ*g*kYq`Ocvh^pRMq07a_C`mnQA(8U|ShGsOsW&Qdoq}Z?hz|Y3S+A!658hHO? z)s;ugcZVQ4HLf_l*<>bb*?B<%IPVS0a;{~y-nLX*)>IaDE8=j@R-{l~jOIJY-L-PBtj%>{LWEH9=(_J6 zG92`TU#ooA+~!?aR=2#w7g~Iup-w%+>z=s0uHzJ@mrx*-nK?;KdX!n^!lGgTM!Ng` z0hTiybfFHn_4|)`szs_D_nK*`Q9m6KOV3}QLfhlWB}N~7j-{#xli&x```61OLnulV zD9WRge|`Fl|5Zwy^e>OMi~8yIz+uu*P4)8;LZ52NC|8Uh@Qq#vfgxYOC~nm{|CRyE zw`1wNgW<}9t!NPa(jui$GI=q{@}#uV*pL=T$M z>4}RMwqk#q-e+#a)S$XX>=qu`*tBVeOG{@3Dkn6-SqFCv*pc9VeRpsoYEeMptbFb) z8JG|*%|Bg$!jG4_B~I<;I%;y(;*oB-3o4+k)SV(v z62qumKDLF~2xwnV^4JP_{m^c%o^`R|?>`#_Z{8Oyd+z)Oyp!6uT4K(mknA&A>Z8*s z0@3`TxVrQ?f3Z$Ile62!SKE8VcOS5YlBo;Y*{-;UfE;#Bq?&b?T9Z^8LRu)wQAI1) zW7|)pV7W_XRU5VxsEs>qpS7n{-n5YQeeh`JlOImF=WRygn9jgQ71lktme02!3*=#ldl4%M8jG4`$CI;Io>L;~(?x#Dp@>|CP z4`;+4>|~!faGf1iBGVIdmMAbMPg+sRyDW$8xI!4)4Sfl14cY9&2x%X=bmL_R%t*+o z!agE&)*ZBv@di@RXFE4H0f@a1KnXw*td?!{8D!;^8aa=ksO^#-RnaA~OC+uKagM9( zXM9a?Q6r@t?4%e}i)AbYld)9|o7O?k?V9;^q$=9u`r@1Tw$Id*7I{mZ2NK#~>q@J- zxDw%eu)xjqZq>`j7HPBdNg!f{l$Wwl?z|%M65$W62qX{;1|h>lAm{E@>2dN&zQCfsxLH|vBm45EsTpJ&>K zEsxzm8orTgSosdjpX9Cs{v&rE6)8; z6bli%^WGs&kUl2$IO*fi`#LyG)$oIB>&!Yc9;;h+YY}ze`6f{;wp}?LcyblWtfl^% zZl~W3kkN*nZy8YCimg}((CZ?2Y`(N73851V<1W>x+2b6G0R-vE-z>0i)+5G%#64=B zC8#bo8eK17?3!|-jeOvXppvWc=e;#9pbuUhjy?L^<9j-9l=#uR#iv6w56Ub1B?dOG z2Kyd;@}bmf`@M|nx*2Jcv&Q!+$DybT1TdHb>S=Cc!7pCwIv)M-m}HR3mu7cuN7KWl zt@vRJELDZM<_)Nfi`Kj zyIO;<{qdb@QQr5X3e5ap#wbkyacHZHE*f*u@i6g3kBHC3*6UOexER6zTO1Y)v7C5U zjR{$T5fi6o-}G#Ne%1lOz>Wx+5^-f4{SVm-vf-2Q#%EGS%C&Dc!_kU%5$gd4vI$tK zvO9`#37cq-YFtJmv@{e*da}YY>BgCpXft_|1Tpc1SRg9`B(A54wt72TaKt^GQh41W zBP+UyWvqJwo>^_^p#esFjrqS&>UivNBC0@PJF*(-o4A4MGKZvR=vLiY#AD~bzEF~q zqch%2Ew!jsf`$3+Fxw0Pm9}qux1OcJj@5o2tdHw{V-@_{%A2k~qdWNT8BtK@+hz?E zBo(-m<(+CRT0rL7rFP))_orDxmS-2GHM7*00!0})ozMzD+lcUOFR3cG7SFCH3Tdqp zG#v^y?+`9Hv3#~G<9#1-0)mdUIW!`Ky-N_o`mhNl)E}PiR^6{;h`!mxA9HxCweg)K zkW4xjF&v|jZ?+Q)mujEo9NS>)VH)p2r3(7^Fhn>%p53iLGU(4zU;Un5UEsvrxeDXO zN{*d3kh-+ABH^yI;#j47M8RKg;f>l^)#mBESQo6gh8?pM6T+D9qKsrKjC-J^;XFq_o_pKkAQdx>>dLLatUJ}1p!4i-1tF{1E^5vRCnOuqj3Uf0NTyAGt?Yb;3E87_w_OzkQ7alXLD3 z7o4iw7yWQ#!Wkid|GwPU3@v2V^;6qgA_JzLU9e3r00Jev{zxQsQRh@vX;E2FnW0Dd zy#}}=K!}-9ws@0g^(#~Gq-Fn7M=@d@o)B5T9lx^f3ag}UqDt8wAD81NC=0=sNQc>Y z23;{zOMEvMbnVTtLrZkKS>DA{-G!3$P7ZE%V z*4HSRIlAfMgLoO<=bJHkG_t|k=B;KpLD|qBPX%*HSj4~`;21*#b`j%oZ!w{X8dYx@ zlWIo(FCz+k8E~NI8d&X_o>9cV>MjM~=JNJ?rtTMwL_kW$O_my!$13@OHhq{(KDlzz zK&;a|*?p+Y2JDOj`wEULHXPsPjs~;I8YMv2n+MzC)}5Yr3TYAC1B#Cm;b*%l5y>DT zfkFXCXcf*$J415Rg7)?8^Q>Mwpt_n{P=C}fN%^vcV-NFm^T8_vSvI7k7DoHc>YmY) zT2_HW8QPA`T-}f(m-~Dw-?H1TiSIr_t-2lIC_s+v*#{9zHF;}#ZLvI0hLSSmK5Zp| z?ow$8mZO5lylOC~XTMmleU;L%WaZ9+i*}h)D}w@Un=|Z)Hxy}Ji$FLY1WNenWGYpa zxSDT|>#%-hT z9Ir`AEOOJzG|OalF}(@=egkXQk*D*`4sOl&OIPMdqNq%RN~3B^M)xcqvh=DIJBugQ zP0rq;d^Et)Yg|h1T3;<%HfiMC(fQ)j`zv~F*~d$Ddf*ampQkTKE{`jAJ6^_!2M6Sa zpXs^E^Y$~Gn4)y~#_&XL3bf*C-IZCLe1=Za;`kv~WHtJWPJ(YVplWicEdxa|yoR&n zPL*2`Ekt{!9EjYP;|WqLi+Yww7clbsAsq}xo-axAPD^C&7LS1S3m#`z--@u)u*sE) z&%fHlPIZrfrD*r?w~#BxXkJjWrudQDR(;B(-QhBGdcR$2pH9?PfYJSpZ$)}Tf%KpF z?Oiu|z0wkCMK3Cm8M5{xmR5qf;i^p~GpV6G=G1Ulj#=e(xr6RiZ=6W$*C_mSa}S9C z@>3wjo({XnCuS%@+YC2}r`n@;TSY*66ORu8hKY0tDLOhRl6Aeh|9HTyW`fGMg^Pmn zuQmGrjO6#fqxeFNY=?KA%DSgWFiN)dAAEZL7H*g1sXg_lrWuZk4Yk>?*`;94bs{yK z#GIyrD0)6Aqj$(X=v30jgm5r|uX6^>&a7J^XQshw1^nH1eun9pweJNo`9VpBETQt4 zJBf?IeT6{eM6J5n0~dIg7&Luv8Z6NO+Z7sER}Exo$#05brgWI1)2EQADb~Ie!AvH0 z)q3f17=Wd?16Z>><|5>-x7WLAja4 z4vB;ZTQmJG#r$-U@OE$9j{2d+>q-?!jXWD%LG4BXmxux* z;_Eks;yu*n2M-~G59h9|MM5@#HX~#rEc|j$rsBM_5bc>OB41Rl0!oa-QRz`Ato zNtlfLN_?7wcWCm?Cb*h=;^L^=vJM$c)6^rPmWS)%Y^nk&&jlM_c>LYBL20!|q4Ux^Q~|1ui&X3!Z#&z!=n#K&KExW-Do z{rm*L4->JV(bXkD!fJSBeLD`_1l6=#8Yj;N-7ev$NKoW2S2{(k?>tkU-uhimEgqY$ zZifSCNc&^6MkKW2xicw3rzOT7rv?U+yegxYlf@jo8JX#In82lV#c_jsC-Xg40)i`S z^Qzl7SMz$jL~B%59a9v4K90GF51O>&wDOde@)%M5f&2;~q1|fpre`2N@rDcc7-@q9Th+=VL%uohsd?T&OQaQ-+7piA zmjpQoVVQzW3|5Mya6AJeB3?!$Gl#o@$Iq3z;m z)KoXvu~St_Z@yxE^e&^-AE_G~*ey=?e0z~^ySEYbgK@6*lA9!ICfq%eu z_lf2oTCz2|wCX5%u*1bDihnxaNCfx-wBlaFm`@Sg^J> zOy%x{I({x@b%9Hm#42wEn0l>q29tZY`9p0L3i5sT?&kWmbGlpM?s(LD%cN5Ya%t{) z17i(|g5R$Y;Q6j8BhO=!`yiG|nb+NWIoaZvISx@WhL;5kP#%O~_cF zMtQUA;~3&wM>zPj2~@!BY(-YWdRyY+15tE2Q0yAF&ePr52fA}Ti1oOwT|%T>iWJ@M zIAFAodO=Zj`;?e;r(>SqT?k`Dq(ZfGQCwNjjh3LOg?*Vblwo>ZXi3x*^WHR|OA6ZH?l+Xn+xD0ma-hl!p4bwz=CXn{vTw>M zHQ4G%R`|urQx`uk$%%Ecy*9uykR;%!-VL}N$6JWEm~xaXBR1-)v*?xLqbolPmA7!K zW{18*X5DiWcqd4kwgh3lcx==XS?ueN2cwc6>`9^;E$R!W19nAeJ~A)o8sqF+AF>Qm zdnw;Lx=1>+EaPdky`+P(9^N&=F6HxKnu=Cb!91O{BSgS_pXnk2nbk{RT#H)XD3RfA zJ#0Q>elQe+uDOYmZch%Hj;iZ%HiP!-I^tq{qLy=`n2z(W@?=UP>y_<8*$s!+<3(c= zgIcN%g}b#|$v3dmqy?t5Dw|v`@|{qQ=2z+#aK>aEJLuesNU_bx zxUNc?HqR=nv2Fr`|IA20`rANjd_`Q@bqH0Gfti%imL7!_m=LjJ63}a_rMDAp{kxx* zi7)qnIbrN(p&g15@16l9{l|qGP>(q4{W`?*&$d(1>6>n6=aChz?eL~pKZ0UbQpdJdIl|CKgfoD|243lrdjHn+vNED z>g4A5k-YbioV?=9jw+P?kE8KKHk?p;1LLZli9WKha3GrfTs zJ#EDk8=S5bF?#Ro+lyRne!{eV@O1Xa^PPp9$WNP`2XjEtlIxdTm1=rl=-%X08Fvw- zFg@4yIC5^qq--n{Wz!i~T48BRN}_9J3BDI0ze_bN`+hTGMvX9lfsgK9#SskPtH(_l$Sf}u%sP*&@((ld#pkU_xg zW>~1MdDu42?Wu%n9#H@y50btRDLcV1xF&M_%R2`{s&y5rHA+S=A1tlX{NU#sip^89 zA&q*2`B+J&7LZJ!iv~F%t2c%FwWC4xAiY~D1*+-Z2gmM$^f#=pz2=Md23l;f((W;$ zSU`o;tYZuZ2cfX-Zi2MWVNETtm6O`m{b2ev!H^no>^kaWDz?2B%;7m&753-eL%$rN zUc){f$vDgzMCvrpWv*tF8u_#4gPNNFf7q=PLv_RH!43U$AGHBtF3=XE{fw;GK>$mW zz~p>DGcE(DfPp62@{0;dz&B-tv6LPwMfbC?V!1THC9D+Jn5$sZi#Qlobl`yuDxcRp z0jZhWsFRIl-cW5Q)N^X)Z^?}p%@CxaT#;3C+IUw|y{IK*u-azP!%8xiN1 zZ!BsG(Hg@qTF+RHY#=CZxP(%pnYI{q*$s&P7Iw@v!-b^-XC&0^aq!y*GHQAy$T_{T z=CI$B3s^oaym^!m=1*Dg4+Tw1ORWib1T8S8sVSvLNYr51gJ}K97cy926QR@!y-C?K zX+$Ny&!2lHNbA*yqz$R~=c8+Gks%1e?r1LXbEHv9eZ3sy&!(~UQ~=< z3cz+?-<=<*Nv@@reKl2N@tq#{4XO!d0h3*k%Llj4{}|ejgj^qbnq6e5S?Et03m3D! zg57dtZs+W2ughrT4&9!Fre$kD7qg~Uat~~-cSq7KYf!9J>mC)>o$;-sa(zxXfwpAZ zkr4RXgVUQjbn{VRKCtA*gBlUSyv~b~Jph-e;p3i_J}8q`45k;;RQ!j7mqo&_+6MHl zunxxRf<->cU*Vt|$V$M-#KSHg`{mv>pzhF97-9Q5vG}+l5!`npWIdlxm)eWE_1a$4~V}n)R2l@w}UQI;0j(0EFV-8 zjGE;=Q*d+Ct60!|VUI&=_3=CQZ-QX1tLwZ-ZxRy*V-=NTG=0}-5b8@5ZLnqaIroUB z;_dZ{*`sF*?o@tH*Tvi8w7d;bIw@+bd~-aZ+!D<3C8~l6A(Zo>(tH&g(&DqIQ>QEn zZSn@*vPLTSq+EMC-D@yl4xSd(Nf4&l8Dt5{59DX`N+@Zu!I%vqU7`6?zgVyCjOXj9 zBD-vW`&Aoi7lR2JHYA+V12w~%ey5jD@#JiXmXuEL;T$WfthRO_Xh-Y>dY%l*w6bA; zb(+byZzFlwqYJ;i_|^C$kSmXx$o@#R?C-djJ=Kq0&HfjcE;-Y4LGI2FgaR@+K;Pbwirk zSBymEzhm=m-(dLL{wjqQ*9iEC3#CM64H);S(^Z^s>#jl#UBXFde$xM^NZx$IUEFj%^zkc-qpJ3OI6@yx6&9@44tLuCE-<4Wa``xHK?|JNJ z3%>W|JR83PN;9_bm0;P%+bpbjYU0%B+9d*lL8$my+f6oucDUMr8#1;loY72@Z4JFvb?C;0OucAB*Q3y?_^W); z5yzujvASBc zI6Ix-TCA1YMBMnGZUlM7x;Tw_#ag$8R(9`v6pXjYMAsz6`Jyuaejerev~sPs zN!)?#swKZD_To7hiur`^)p9~g?W`v*;}s&<#s|BxZ&Lq?MS8Wd6}t2&X^;=rpAWa{ z$R70Z#96<>c>7>U_R<=!>O#-JG|R@}l>$w$>(6DY(xk@liB_CXhlJpQ=&=Ys}%f9}>qta+S*FJPKkst!DCV2>Z?Qqi&I~+1t z{CQE|`OX$d$+urL{Lky>AcJKa8PLE@F-d8^W<4?1+C6xSNk?m(NV3`MIVp{C#z2E- zGq>T$`WambJC*MQ}6|U|HRa)kLmR{?mbF!BjzckJ)!MCyJhS4zxYplSgp7x zs@leDw0TI{1Gf+lHoOjCb=7Ffh*k6MPeH_5!$ zj$?{mjKdwHwARETrPJm__CMBA*K?0XT1j@zM%3@fF&ZU$uiFNDWKRmFyRwgj#}2(H zeZ0I7jk$tXT69U^>tvvIe$85#>_5^Y$Mhh46P)Xc(X!8|_=w$v_$-F)>(LqGzWe^$I^8!3~W}c~^yb@nvFmQ3>aXl7u zLJ>{0Q=a!U9BCc$bkLgoUS)nFp)ZgAt8opw1)Hukc6ynVu(@c<9{v~((JA{(vZk+D z)!mk~u^(w=kR0^by)hb!9ymy3YjCxZ*L62tBg%nst-89VB)TOGb^897n`>$91n+1nf zAA0^Vq&nzMpZtF@=-Qz~#DDAp_~+03ssBDS7@SH-aIkNm>VNqUe)gjO?Op%uMgM)L z|7;2WKGQ#C?f>w{|Gjtp`%M4gnEup{|GzrZUfSvz%OSTTB4K|yh5d6nIVs$Uo&$$ViLD~LS)*WK!u7|umwh$krz{)HF)_nrRxO#f}C|MsYVieY~- z9R7bkO4VYd?^cRx{tZ7f&2N%7soEv`{#4fdr$3%MF~3uT#KvK~^$*Z`>#?h+Jqa@R zqRz5^8IXc$>iOUbk+6zyX0QrnFI-EO7)@3mxBku(w>~!tCmh2pzpn4t*V!=H#6ZHB zL0HcviDY%soPP6Sd9e4jDY$itH!i~-v)s~(-DmX`4ig`T^BRiM!o!u=)7kn{ZqH&X zahT<2(HL)=2{_qMYkZpd_$p?(R|T_N25#l#Q{v+vk9YIpFEifj@opFM#7;f@i45`^ zUzrKUI|y6AZ1=<*HyA_67NQBH@zE$F7iRv_N!6Jk_aCAeBm6brs zYY59@qzinlxaYG}&$UTI4Lou7+!+{(!VT*$h0~XA+(B-DqEoFzjP`pgE$EDC-d&tp z##kKBnPpw+tRJ*OqH$>2q}N2N$UnWaKMovk&h4P~`Qozke497DdNfbYNzk=E6a5(M z;xx~-54v*Kr$O1B#5UZ~p6ES=B&20!U(U8N-o1?_xu1tSRhOo$#=l?SlAi4|20V3mL~0i{y|Ty2?ZnOM5<0_kanDznXimQx9%unmoViO|ssrNrLdf%x>WPBS*bf$5t@>88r$G2~uJ- z6@8r6q456kPB!4DB&gp`2Xbw_nu9hFqix7!zr{z2I z8VW^$%#J5Sp;$x^KE^=Q>F#G4kzXDw_&tS)rKpoycBZ{Pvo3H8<9%)_Ze06U&Ldy9 z*ebmDx&=BO^VfZU`Se{!4blP^B4|-bT1;l{wS|P8?{VwFZ(WlfL-CLXvC3(?-wOD* z?{m^1HQ6D8KQ3v)P=+I?AFA9E+n~rfK1uvbc75B$a*SPs<*mKEuoUNTCdg7#yx6g=Je7ovEJcI~(GLTk-%fED-f{PAP}Dnv>Svn3zZ|D4wDzSb(7+e0mfP{f9N+}5 z!{={;Vb~Kb7kc!;IyY}`_`);_(X9?gqMy2*xV6FH{R2(O^*169vP=pnVZUd7_ZiX4NlZ74>;g7bd)3^ zjnMryVQ|)SaqSjnxvu7^D?5bNA;!~$eJ2jSvS({*j4v@kHnq}UB%6=K zOZw?*8fOba?8Q6gxA1orc3Vk>LFLAF7!cz2VE?#Se!Zh7JV^`%a z_Yg8O95G#8^KErzh$#H>dIIOCyZWU=um#q7-U@<2VcqY-ia%2yG$theFc+^=X8~I{ z-8AsW6T?5go6sG6kN2o&R5fCC)xX9?>Uoi{R+hI`1(Ml>2gr6k@rE6*PK|jFH9Q>6 z5cR?t8)^<3qsLCdgw00bO0I%mc_0{XY8+CQU2g)r6oJsRugA8hc{VSMm{>>-(6+Ue zL6#~MV449W84>8?wQi=XhUUw0xHPXOiR)mts;}M0gv&59vTt+8r==nv#0~0frt=s) zL)Z&f#^q!2xZg?FW9N(`2+B%fqE5u4X<4$38d| z>L))XNT+#LoB{ynP#tD@)dZ&bc07*f%f{?uBtjqtV~{#duB~%dlrDKmMc*FjYRNq= zA>@U-8^wH-@0l!ez07Q%7>Ap#wcRsQ)qART@rNh;#n<5=J>OgJlukfr|1fg{MOcNT z*OZ-v-f&k-$|c)iIq*$F)ZfmwGB#wS-S@wkg-eL|z4TpWr6|Erb?-X|emh%g5V41p zQPYDR`JL=0_c~_0KG3Sm*R#e$`i?*~yRa2&^}YwIt3mVb*z&9W)jFHH2N3-2UhK%q zWuc(P`;#CORg`qz4Wf(=9tUb z|Zu1fA zFK6op4;JLQ>lJ6AIknK-F*rou6ntAqUihU#C z))+?=yt}9ci_rk(!OM~vg4l?4zi;#6y=7ik7!w_?}wjmRgRm0q(M(2oexu?;sCx{FHy_?*hQ zIINC~en;zam6cr-$D_~N0f?y}eJ6lUc(~cIzb=KW(UxC&3Mxk9sl!}xJv%bfg$>sI z=IyrY1w+LlqJjT0x1N>GOqWRGWA5Xd9%&G<>$eoh_XuXbf!3)X`kgkl-@K`^>AJB= zBwtNJ4r)5FV0adk_4?b-VlOPRg)Y80X;tA^AB<9_Lt!qoM2)wRr9C|IW zGw`dgq5rKBI9<@^Wzh^_$5(5Ew1U8_7=(}yE?Wx0;Mq~XD0?YQ@Z`G3qv_tw0tZSA z2LScHMyks1@1!4b+^lR-f?bNttFGEvoVtOSu|s&B-wH;30oY$GwWtla&9N(X`9)Yo zHT(v3I`euB0$elDv>9uqG7;PTMqd0=YPD1x#?1yBloREBn{<{Y$7+Npjs`%9^7Ou`I%%q&=KF?u&%?%}ctWicE((G2X-R)s&|YPNa7*&DPTMdGl(Jm++81 zX#8O%@loDgFiiYKB?&2)eanAW{ra2{1k`X6A66Go+CKLoZL2=~ORt7fY6JQ)afd8} z`pMCnq*INeG&)R-CIpIvjT8Q^6b@=MsaReIon9u&N@F%|+}bdWIgJ|s1tu)+)x3}! zlULr86MyNHyWiiBur_Z`rF#6&@ci;a+hEd|B05UC=81pHL)wRdqHnltX+&H+i*1y~ z^j2uJdz30THBfV>9~=>2PS6zJsg=R_)HKaDJ8L;ue=dCKUU%|+K9Kv?=M};sVpY^1 znRx9%U2Z=RSp-tB;z{bH4lV@MUE{JvqIJ8Cjf7>I#)>^Pd%UX!kQOypG2U}=$oBE( zv{cVBGVD=ts#W$$g7t?OGpC&1mFZ=Bvz-MGTjCZyNjM@7Di4lnDpBAGjh4Z~KD6OeUMG5env`E(= zt%FEjMNS_BnvonbtSLX66PDIXQ#})5KRi7W0z5r(wEgm5$5x^Ke7*XZWt<9v_35*m zv3eU1_lD_Imnl6FJa6gI6=v2`Yexj~T^H?l_JmAjZn-L;F1XAPex0r3*E@duxNhvX zxX1L77%d?QX-$gu#O1$2^u;Jhd;tX%c-T?C?4=zU3M`lPZY@*7#+-i{-}yqi#D|zz zHNoF-sn*E*JH`bmXnukH?&!A@{b^%gRw8Sq31T!5v4e7{8dG0>J8S7+W1y?}wJSl0 zM_t?fGbj9P-ua9zFha1_rG>rAk9pw&ic+U6;@jtg&t&@tS?P|v{(fzNamhQzD7C;Q z`9%I|=Et-QM?~>8&FA1{%ADi)^7ZRm)iCED{q^!$^2?)bgyV>yI@!;nGO~}O6x^Oc zK$_>c^(WzM(FqgxZ96}M4LTpORHZ4n5fRxrFuE3CO2I-S5D|N{QnFI$iC>)(qp&*_H(BNPF#{UGoxso0*lLn?&-2e3}=tV0!ShEHm2kqiri)e~V*LzzGWl<9|TPzepmz z|FVs7M}q|76yPS~oENNfAUyjtNE!f@@Oc<6B-V$&m|OQaH+l$(&=}m!g;`Ek$UaSH zz$!n35gm`_&1qQLhW{nN3bkUZ{nH_7TH|AU*D98>MV-9su~d9}PL%Sa`$oh`{gl*l z^Do4FpQ$CSn-4*_+8%1Pz2}|Z6tX^zoRP`_*oUtTFSa^aP3Vj*Q)eMCP&svp9P5qK zT-$XKyYZ1UW2-f?zBbe4WJSJx;wD-nt&*M%Jn7jfQQAj#&qmtI3|4QMwci_1g%X zDC&u0yaV;3+g;qXj&8APrE$30p&T;tYE$T`ROUdiBCybaGi&#OuiONvrx^plh0MQyaes=)mDQYgc|Bvb@txYGk>FGYrC@jN zJbC_19ZxKEiU8&FGCc=kB;X`m$yk);Rd4GQD+kp|qI%n?zEN4A11X$T!0uA{kbTAxEz&dnsTHH+65?Jsk;pDW zMQLiE-!uWRZM|43)fXoXYC3vW`%JDcv^0K-A!+1!ShRbWn^$NSZFtF%ra{8JkbWjqh3cb`sEuX4w`~y1>Gn?qiAo+GZkRG}mT2 zJT=?wCsq~$t21Z2CYLG>z?hSrVt_DMS$K2&>q^!N2WkahAK?^1&jmtHjVb#Pt)`X9 z46~(S&~{*CBJz<5qwb=9$#Qq~+?zS+pLG9Vc4{>l#;J)Lx@g)fJCMM)(CK$^?l^$5 zFReOjkgRz$Ow3lR2$@`g8224a$IVzg({GOqh*=oSRah%*E)Y;-Y z>TznjKvd(7{A`5!%4~V0DD8bbGCw2tDGTT`#Q{HGgU}owkW2Ah+=GLqZfqNl6{T67 z$qv*3?hKp)$8ht$l;MdnLc^a6p9&O&-VE4gl<|m?;t=3tYOF;O$*imxYNib| zOxjH{{JHEJ%F0(!o6QX5q%L+QBf&T zQKKSYK}vvt6%Y*~DhdKBD!rEw2#LJB3Wx^jEf5t1krH|*K>;H*Lg+2D5FtPa0Ydt> zea}62&N+9^{bn+m$z(FKv-V!=d7l6O_pBuW2HYyDB9IdU3wD(v&D6_HpBo++>-*2n zm?<{ft6xv~`qC%fY{#6zQzXb=rL6AU_c=7M;H&`uUQt%!D$zD~Lq*@G;}o5w`mbdB z`3R7Ym`@`ftN&YiBz!a>Y)=(~K6oX?i*IA~xN_gsO>8W)QQwWB^Y@jh(Y8Kk z|63Rv*%c|zm}180J~^{wTK3NDMdm-0 zTzm_yh-U>0y{8nl1_7hXu$X3Q4b#uiG1 zLPFhs=6POh+O~S4_!qr>>9o`OnAM(KuB0dkZFtn@1+o5B;Cy+#v+is{0A_U#ND+Vi zbAi1W`u(M93&%<;@;qD5GjrtwATVX(eY3qR^ww&i9>4OE$>qne<7a10BQW}i&HC~% zrk^Y>_MFos!6Dee>R$sb&^;`}liIU5xWnC0QvY>h&cZW(O1Z;N1l9iz|4#Ut*u4*fN~dN}X^rTxhUc0Jf8u^zJjGGb0+I!VC%X1mfC!n4UGQ2F04nH)M@JG&UU z6>M*?(2IVLo&pr6#T1GG4t7xiuwhey(WTzP?8Q&duacF#v#sCi_1Q!*TWYr-Z;@`koy&(8u~ zIp^@IK&*0MU{8LI`8O$T#Hbg0cH~hHLhq^o*|eOO_b2})9x+L^ArR0d;gv%gN4n7b z2w6-yJhsa(lpCp8Trm;r(1x#6YpW>hxzt?G?Dq zn=*!B2{$f`dDY$lq|GO}D3NK+KjSJb2&_+-cNLjllNXPZ8xNds7yNkmZ$V#$(d$tF z6ydK%An)w>AJ|eLP3ZXCNIq}Eo3D}qj#QD$WjNuPl!0$ zV`zi%H*Jr_IO{!kU<0wVSDXmp(jDhbNhe?k6`x1HjV$s%&K>O;ure7=fb=lmnCdIU ze)<^xfEaGug)H31zV;_$Pf-i2amG3q^}ph}n@pI`!F$@zyEO4GfI~mc-I>d*oE;2n zvgx@HAv&gKz@(_lhPl|`m|x96%KRI_J|~3ynJR7jI1W11?p&y2RenkgXv_y}u&`W5 z-;A!AwTQoe)bKRow(sM+J=7;#P>I6pI?wexX6GG989XVgBg?UC7=Pqc0{Xx;!%(1l zKuIRQ0MwZ2O{NVmMvfC<86E@buXaJa^v4n}5$Vp`4ko~WR4&N~keFJ8-yg~$< zdJVQ-+}1%fu4m#?fsu72=6d#69QXN%rm#Uq3I4;gKmcXSHL#j~v(M)WzI~=3v!JkT zL372FnrqyYA}buT1$Ma?u6ov*ndO<(qT6mVkp^VJ)RC20eJ{77oEOsjQu2xB@Y_)B zKMr|HMPsrRNfxX>M#fC*kJ+A^T~YY+93~Ub+7>HGO`nk82d7xpu)hj_~(cd2RXqj7o$;2i@w*g13 zi@*j~g`mtU#uzPz$<41mxB>oF4sAyE&@El=JNZhj$HV?ACTF|>Z6SF1w8;PSLI+^-1iKh zYe%b^@b1kgZ1s7`k%+QNVs8t3wKtNSzaen7S%0UmcdMe4W(3P9mFhac_5^&qvsk%i z^$HAU@lMF~U|XCsca7I^DtD}m_GdkNphp)Wn^6{MC|;)Fo=)rBXh3koJ^C)$;nm^W z#<`$CIzObOR(XeJk#YSJppNotN7a1pV#m)ZfP;FIjko`&diyJV6G<(Yowhhg&jqx7 zsgA&!oByt6zd(}R?#wMP1QkIo(^R^=&;UbM}Wsl_cN8vU6kRFmD-+p6fQc2pTyAM2{H zHT(vS9Yaa|fdX9zaO_VhgcK^x^#Ia~LGKlyDW}X-PjnOX3cl(D!Oi>oJaN~0>wS4@ zM#op}s9maFk9umn5gJG`hJ0t2x_+~TJQcvsiaq-2zbJo?Ev10e(vtg7SJF?_`#K6l zGCw~zGbwiqo6e!v>9gN5-D}S{{5(FCxTt6~hqFL0{#KQD!K*0l+z3ZTT_4}{ZGNDF z+(x%r#OO~xiJ%&4BB{0VB$Z6S=D7YCCH1ML`~o!gH>f>QH8i9x zPw~vU#2W9AWvS}+X1T3o`)N}khYSb_T>}fRi~x3yIAz2#U+I+1YRn2u zhy#jc)VZ;b>L$FpOD47GsRaI9_gUk&AR(7$|CUQ}u#psNFU`Qurg+aY*2#eVtG~CG z^x@yC`u~wuFxF=ZICp2YG}+zxN^^-|J=*r4Eci8c!hgsS3)>`b!B4;Spb7)QuYarl zo5>Z|Z_yN7R__XCU9Z=En*(SG>baU&m|hgy1-6G*QI3Iwll-@GWgpOIb; zb-MJCcKF(VvDF`&$^3fU7>5dOOAK-L1uZ6*TCJVNt(U7)fLv`)Z7Xu zx2k#rb4?4cpM0ZEjlO`?)siT@XZ=a0(-4iKfe&Qyg3S5y(}dg0g;|=1Y!dI1Tvf(L z9~t`@Ufgyjr!h7P2**lrSU?9(%fX!G&9r$ zsA^}_SNB^EjCuGbd6D>mTqwMNJG#A?dI6rKzk*$g(>V-JR+?Y~00;bzNv&V(N=UAC z7Ou@@38vzo?Yx@+c_Em1q#iR_BLePN4{*nPoIZc9xL+Xq|4!92jjT5>(z#!19>-hZ z`~(^79|2vXVkXIdoMH2-MV>dW6*c}dcX3&1utpe#0C$;A1$N(D?k2^w|0w{ zTQ?`Q`c*>oAT_pxB7_6neAer;SC4v&l!KeKnEa!)9HHl!btPQR#f;;r+%uey&~lx9 zIB|tRd@nlVVgK`EVWJxH+mDdz4uL)AqWquv;``ssc2}H#7`u=;AdXe}AhhkFyvE!@ z=Kg@c3w7~6?e-o~e;bck^Gt;a0!t49sh^nNK{xvdBbg7Eo${Y>)p##<&>Uz=O zwb~qyq)z~Tl2+$a_?TJUOd?um9s5z5&VCsBy*r|A@=eat!m9MpzK2%o|DSubdcu1e z1`AEArqGLgfB!dgC@fXxk7hCpZUB$Zk(%qo<>t2i9ZOmslcS3yVqruFW^Z83v!}VB3sXJPi)=biJ*NRy2rg>#awqDtEoQw%xE!D$Kxzp zqo1jO@RQb=DXaNOb~<4fXZP?7XQE%ClrFU4n6A5;ahwa!yoPry|M+-%pc`z)S^8LMKeb zwLHcIca5s+;MV>Q^jvCY^3|eEiKZF#4p(d4cF&EggT(@OJ;07z*`92wz!390PFc^x zx%q?m>71n%0h_i`U|(n64)l`d0Wy)VhbT1I1KRzE2eQ0cn-f`Xu^SE2tMLOQB}Dh% zf$bil3VWRtWn}P*7jmKB3F;=bKjd07hY;i;OJN`=8|zz495MiAr-MpkLK9nApNk<}1VkC@pfdTDOm7=8ly-`D!#1GBQr}oS)*?%>`7Mhz9-VpxJ;Od%@<~FsMJIJR`vnAkl`$nXV4~gaa`spla_ocUfd8JMC?CRRX4KuZh)+L z0Sxa@Vw&i4QK7rVV>71weXVLQhJ@EK{^qj@7e*>*T4?GIIzOj3R(l_dnvC)192JE$ zpW?)?d_CURf+BgOS{2#ka>np9Q}j=)Z*4k|f>-mt%!R5mFI?q{sLfQWpB{A1%LeZp)8o46u`qpTG0Sq&@GG9ez0 z*@@~-Y}R3&0$ppn1qb2bfHo$dK}(=ov4VrVr+PV*S=Z37?1viof%#x^pl)U|E(eAh zecn#Ds<)VC>k?w7{SYOJXQP-6fN~tuq(`HM`yh|lTap}5b;z-jXpkZ-Cavn8(=AMM=DDXGF z`HrFAFk|M+MplCbK$3>G$`v44Oj!}C#wm7%kG9YogR=sg4D~3uowKgOeYh7I^R#m8Cb4Ro4IvQAKDARLuC-13lz_Ax@OVRO zT`qHs0?YHs6}Z11!jf-yxiA14Za+2Os2%HzK8|vL8u-jEZP5GON`kKVJkp2CIU4DT zFfr2&EckLLAUAQ!xWjQ9*l05GCJd!i9_f!iiU69>sqJjb{n^oLkpq@UqaQxw8wMlR zFch%q%Stuxju?w!;^sNN6J6^Y*N~nXy{wc6Ojn`{x?+w=*{GWp^qz_Vwb1XaPH$Ku zQNT`bTt7pk%dBZ1^Wz4edsdIez2NgGv}nN5B;7#?Y@t#V95 zv5{14eKzC{#XCuSyYgua&?~P{fcXAF^Dv@o(5KaqEgI+2>gw`18eV6QtVQ`VUC=M4 z{;qde>>_M5C}PYLa0$iS%Pea-oc6j=-sM7bljxm-6EX* z9PRmOgBI8x8FN!5s9JL{m^ESb29zXrSZQo-^6R^{`4C8v@9Oi7Nzy?DOidwYb#77< zaM;1;$uzKQ0Wf)FRP6nFE^JkKZ)#S0n)M27{#jo~=pr&ZCZsK&TJ*~4bX)6})jag5 zFRuSYjM>gkK6|VsN{W0iaNay*5#YCv`^>Lp+<@XBJ-H{aD-m5VN}kE z9>r%~3Umbai~B1@HS|eOt3|@89^w3G6(9-$`RK){Y4UW7p5+3~Eu;QPx=Sv9afAIN z7a@>~`4@LY)Vuznc0z+kV+jUxcS*xt%Si)$S%4nqP~em8xW`GK(pl_UQ^?$*B@>DO0PwtH!?*blpZwzUjfL)=te3%%9kGqog5Qkqkv>mizyC@{+1wG~GIn4@B65)={!NTY$Rj}|$C zV*%MY4aJIptm zbfQan;6oiL7vNfeTG=;k5Y6x13idkS)h^{Y4KQ1&X1Pj4N>dF&o_JUJKe9m-x~$EoypZ0enEO*BqG`PX9dAD%B2$$I1}6+werKByY{{mkoM zhYB>OVKwNzcsk6l)_f!ub|@eld;*r6SBrN5;>l9gm%4L~Xu97tX0>~JE}!FqL<`o; zFfn!249}smgKF!lgcJyu^=b{qMCU@ECdPxT?WTc)8({Q{(F5ib`f@B#FapFYof~jS z752>NNre@NKd}!6q#3nVc(2o3pos=F^4pYdp?Ax1pxx0(@DR9r8_f^vr}wR09Ibtp zCo&|AuH&ZuPR$t*Q?@F(JnM)(@k4p8NxrL}+^QW>i4@1Yg+Nv2dmXHOj*RjFV-TK$ z_2}}+|L(jgVDV)*!trFTLw-(0MC{Kgg#kA z`IzDV+zVhRD9K9u!!H$|Y(GHc*rkAq$Lqx?^g&rzU{ebM>I`0s?hcLt?S4t53 zo(lhhFi=Uf8F&yro8=a963ejTiVp~9{8pwXfC`@gSXMoXKd`}}xqrwzng|sjAmeEM z=*cDDF^4D)dcg^&J$d(HT7;vKoAa+!u20(R@eYs9J0YOJ5Ud6!83_)^MyGh!>Sk8H z(j-)geSfu5t*>--Xa+5*1CGI^1Hd) zz#bod4Q%M~GqrB(mZ!q00ImfiLj}X}LS#;@Ar>q#S_ZQng3x=3QPeELdk9xF^bbYI zht4YSoyd=-XXqh2^vvmNdr9i{&;>0oDxil5;1TD*l|?ngL6YNFxBd7!Pcih}06otm zmrw585JXPLvGmKynIn0%cP<%HBm+^^ctZ{W_Y8@19o3i%_dP#=2f z!q=%TS@?kfn96v<*qzbtwc~CB6~uJS-2B&)l_fLyT)Ic?QB8*iUSbpBF*Af4>WClz z5p?TXM8#77$}4X77MvB+CB0Aags>)6uZ$^8mNAZ-f5Xh+Nd_)DJX2>0qE<%ijuL zxt)AmREdY+bS;0YJHikjJTJ!nd#_osEq`b%M zw^`Y>=zbKAd4R>DLq2W#A@@iQMNK}Ec2x|J(Qi^zk)h7s+Yf)~V`JqD#gg>1+S$pZumrG=~^yQ;$d>&o%in_)_8`PEmjqp%-_9k zb2*%O!0!*HdEXEwcssxaSZPpAX0K$FsMIOchKfa&L=bD+k z5fc3F{aSn{r?sdp7k7%FX zA5ux{_HH+8f+3E$=)(2I8=}b96;n)+XD$#GG&|`tw)r~sy z={z5kZ$R)}E1CMvug-D}eLH>w61r3fZJRS7SNlzckd#0mcrfsQ=P9ySU7 zRvfQ$xXzwsFi%*R%u1AZD7X7KWjopEg1*y?O?Hi!!G%j=ZURW%8uiD@W zU{gbZFHrSH_BiqRIa9J7!?aAuhYXkK`ZS-40XHM08$8hqxK~aFnvqt!#=|-ZecyN6?*N4uZFL-Jw=TZ2`2e6t0UsDIii&^zZLe*?CNBl&8`dXg` zSGfY-CM`NyBc9}&OltGc7X?ct%xr=mZ4~0}XgQ+3Qd=v7b4B}ku*H3>{H9JT&!Sev zt)}P|Ik`LH!=rBSOSO5< zCnxfnyj;upye|Xy|ak*QWcisX~0m+{y0SjTc^zEP7>k zmO-C4$!v{rH6yD8yZe&siI3`ZOVnVx&b9I|cL(g*K=&zAj)$J*$Y_lGR_M7Utr#8Z zMb>8Iqd_IGmcNasJA5>?gtFlyxfDUd!W_w=LZ}*crR!SvCsgk7mY`cgyBYr_Xfot^ zlYB-_B&~(vLfr?XXl?q3fnCt%3{aE>G-jI`kw*aOP^f00B^XW|M3`%@}NwU zdJiTH0O9d4^GMcLAy8^&E@l#v1aew#VA%9FCz!X;8j1Ks>#pjg1-b9y#)Aa46_}^Sepfw`*cXg5BqB1 z``S6l3Qr>L>AUHF#;c22)A6w0e*PG*CBbKsE|n+$`2y3yXmJL9+Eu?3{Py(~12K!Y zSU#iMtqCh;Xo>FR$LL#<)~^#O!9e&Ej?J8T1hR@e zj)m@>(SubKe-hp&jl{b?uQdR-l?PYqyc1U+$<3=ggXX7DLc$HlAU}c$F3mowxm{BM z?LsDtRx8%3XpJ5351c2X>oY$&fE*cd8;`gf)v7J8;%#H@?QB6^t73~sv!}PhbwFOH z>AhoFgW`p9`@WihI+RZsIr_SiczhDTN^>eH0?xw%Cp_AsKJ+__35EGp-HoxB()NGfsG-@ z|LG)|y1u2`d$f||s_|~XT#4$g;^%j(z$6r-34`^TOI^ONN3+-?b~!IAz>TbgUWq5Ra1G zH|(0=u~X1(DQCL#Ckfzb{J^M;J`*mA7k`V`8jY(A_HQ=oFoZArxGfFEsU#bm(bHwp z6;jCa|G)!=l)vn2@$J&%gezh!+M+z$(@mDQm&w)Ae=RHY0DT?G@b67Ki6PKsLI4{={c~;RoSu4gqk3Zw&g-^HdA}kPyDr zw9(D6vyF)K%D%IW(kGxekrv)a8(~^{9_Ns≈XMLKp$Agp)oxS5L@hk?q(MNvlp= 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

NcpVgLAE5TMI*>-dC@va1q&u5=4yM_5oht^m+N zA;(31(A^Y*zE1|vIxC+?!|K;3uh>eV_c4SY)|V+4FA`@<`LLrFv}8Y_xO%C!bjA77 z)FzH)Em@Ou@+kT929>ha`qLiEieK!_i@vGWob*|kH%;$kC$iS%zW>H%t&qk~9`xF` zVxjlBz3TIiMnV|NOXs8J*gvbUXm-osH7~Evk6OE-tz)KmkFW5=l&}*? zwzBhnM0bDG%GT-i7=t`hmBIWGuZBXO&K-#>F%Npr{Ycx&lM8}V()|Rq?@(Yr#7R5& z?ZV?77yI#+aFzlsE*nL}VDT$3@P91DR_GgC3eQpB@kPLKs{bx(rb zUCnD1IIX(7I*}}lH=hscN>obo${rw(K-IWQoB%o0NX59a!YTo(jWBW2t-18WH)-3i zduQii;MgL-BqsxT(H*8J_n6$EHTCbKsM70tmBwM}&74JqF<18!?v}x;@!s=VEj{9D+xHU& znb+D&ua@}}JP`G8)5{$^^%Gj`*FzLF;B#b#t;Yg7I`IZPJMHC1KHpx^V_5ikH(53k zU##pHJlD@}H!;9K>Q66@sXPtic#p~&2mu5aM6hOXtT(JRn!w{Z0z|zp9D;0Aq4F1qU*{tB6DLlTQAYnPwRAbstS^6fv`Sl@|1q(!|1FSyJx3md7Ce&G85OT^u2Dk# z_OcxNQReWUH(`GKrAy^wBzBsO%0A58UJdSRhs}mnKUpHeNvww$xGB|+=KN^v%R1IK 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
1a?+_HDa|dhu@izr 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 literal 0 HcmV?d00001 From db39b2115e6ef5f211d78a2b282cf58b8f97592f Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Sun, 24 Aug 2025 16:08:07 +0800 Subject: [PATCH 36/51] add feature gap --- versioned_docs/version-3.x/migrate-prisma.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/versioned_docs/version-3.x/migrate-prisma.md b/versioned_docs/version-3.x/migrate-prisma.md index acc70e5d..4a5689bb 100644 --- a/versioned_docs/version-3.x/migrate-prisma.md +++ b/versioned_docs/version-3.x/migrate-prisma.md @@ -259,3 +259,15 @@ export const db = new ZenStackClient(schema, { ``` A key difference is that ZenStack's computed fields are evaluated on the database side, which much more efficient and flexible than client-side computation. Read more in the [Computed Fields](./orm/computed-fields.md) documentation. + +## Feature Gap + +Here's a list of Prisma features that are not supported in ZenStack v3: + +| Feature | Planned | Notes | +|---------|-------------| --- | +| [Client Extensions](https://www.prisma.io/docs/orm/prisma-client/client-extensions) | No | Replaced with ZenStack runtime plugins | +| [JSON Filters](https://www.prisma.io/docs/orm/reference/prisma-client-reference#json-filters) | Yes | | +| [Full-Text Search](https://www.prisma.io/docs/orm/prisma-client/queries/full-text-search) | Yes | | +| [Comparing Columns](https://www.prisma.io/docs/orm/reference/prisma-client-reference#compare-columns-in-the-same-table) | Yes | | +| [Postgres Multi-Schema](https://www.prisma.io/docs/orm/prisma-schema/data-model/multi-schema) | Yes | | From 3dc70c7dc538ae1cd0f935510d4dcb070005267f Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Sun, 24 Aug 2025 16:15:55 +0800 Subject: [PATCH 37/51] update --- docusaurus.config.js | 2 +- versioned_docs/version-3.x/{welcome.md => index.md} | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) rename versioned_docs/version-3.x/{welcome.md => index.md} (99%) diff --git a/docusaurus.config.js b/docusaurus.config.js index 5eef4d59..3786d47c 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -45,7 +45,7 @@ const config = { banner: 'none', }, '3.x': { - label: '3.0 Alpha', + label: '3.0 Beta', banner: 'none', }, }, diff --git a/versioned_docs/version-3.x/welcome.md b/versioned_docs/version-3.x/index.md similarity index 99% rename from versioned_docs/version-3.x/welcome.md rename to versioned_docs/version-3.x/index.md index b59821c0..ab6c42a4 100644 --- a/versioned_docs/version-3.x/welcome.md +++ b/versioned_docs/version-3.x/index.md @@ -1,6 +1,5 @@ --- description: Welcome to ZenStack -slug: /welcome sidebar_label: Welcome sidebar_position: 1 --- From 2a1cbbbd5439fbc279ebc591b26ac21987d894eb Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Sun, 24 Aug 2025 18:51:58 +0800 Subject: [PATCH 38/51] use git submodules to implement code snippet loading --- .gitmodules | 18 ++++ code-repos/zenstackhq/v3-doc-orm | 1 + .../zenstackhq/v3-doc-orm-computed-fields | 1 + code-repos/zenstackhq/v3-doc-orm-polymorphism | 1 + code-repos/zenstackhq/v3-doc-orm-typed-json | 1 + code-repos/zenstackhq/v3-doc-quick-start | 1 + package.json | 4 +- pnpm-lock.yaml | 15 ++++ src/components/GithubCodeBlock.tsx | 15 +--- src/components/StackBlitzGithub.tsx | 44 ++++++++++ src/components/StackBlitzGithubEmbed.tsx | 84 ------------------- .../version-3.x/orm/api/aggregate.md | 4 +- versioned_docs/version-3.x/orm/api/count.md | 4 +- versioned_docs/version-3.x/orm/api/create.md | 4 +- versioned_docs/version-3.x/orm/api/delete.md | 4 +- versioned_docs/version-3.x/orm/api/filter.md | 8 +- versioned_docs/version-3.x/orm/api/find.md | 10 +-- .../version-3.x/orm/api/group-by.md | 4 +- .../version-3.x/orm/api/transaction.md | 4 +- versioned_docs/version-3.x/orm/api/update.md | 6 +- versioned_docs/version-3.x/orm/cli.md | 4 +- .../version-3.x/orm/computed-fields.md | 4 +- .../version-3.x/orm/inferred-types.md | 4 +- .../orm/plugins/entity-mutation-hooks.md | 4 +- .../orm/plugins/kysely-query-hooks.md | 4 +- .../orm/plugins/query-api-hooks.md | 4 +- .../version-3.x/orm/polymorphism.md | 7 +- .../version-3.x/orm/query-builder.md | 4 +- versioned_docs/version-3.x/orm/quick-start.md | 4 +- versioned_docs/version-3.x/orm/typed-json.md | 6 +- 30 files changed, 130 insertions(+), 148 deletions(-) create mode 100644 .gitmodules create mode 160000 code-repos/zenstackhq/v3-doc-orm create mode 160000 code-repos/zenstackhq/v3-doc-orm-computed-fields create mode 160000 code-repos/zenstackhq/v3-doc-orm-polymorphism create mode 160000 code-repos/zenstackhq/v3-doc-orm-typed-json create mode 160000 code-repos/zenstackhq/v3-doc-quick-start create mode 100644 src/components/StackBlitzGithub.tsx delete mode 100644 src/components/StackBlitzGithubEmbed.tsx diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..5b3bd36c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,18 @@ +[submodule "code-repos/zenstackhq/v3-doc-orm"] + path = code-repos/zenstackhq/v3-doc-orm + url = https://github.com/zenstackhq/v3-doc-orm.git +[submodule "code-repos/zenstackhq/v3-doc-orm-computed-fields"] + path = code-repos/zenstackhq/v3-doc-orm-computed-fields + url = https://github.com/zenstackhq/v3-doc-orm-computed-fields.git +[submodule "code-repos/zenstackhq/v3-doc-orm-computed-polymorphism"] + path = code-repos/zenstackhq/v3-doc-orm-computed-polymorphism + url = https://github.com/zenstackhq/v3-doc-orm-polymorphism.git +[submodule "code-repos/zenstackhq/v3-doc-orm-typed-json"] + path = code-repos/zenstackhq/v3-doc-orm-typed-json + url = https://github.com/zenstackhq/v3-doc-orm-typed-json.git +[submodule "code-repos/zenstackhq/v3-doc-quick-start"] + path = code-repos/zenstackhq/v3-doc-quick-start + url = https://github.com/zenstackhq/v3-doc-quick-start.git +[submodule "code-repos/zenstackhq/v3-doc-orm-polymorphism"] + path = code-repos/zenstackhq/v3-doc-orm-polymorphism + url = https://github.com/zenstackhq/v3-doc-orm-polymorphism.git diff --git a/code-repos/zenstackhq/v3-doc-orm b/code-repos/zenstackhq/v3-doc-orm new file mode 160000 index 00000000..94c95137 --- /dev/null +++ b/code-repos/zenstackhq/v3-doc-orm @@ -0,0 +1 @@ +Subproject commit 94c95137c07fe67c89ad552a8b5cebfcf493121d diff --git a/code-repos/zenstackhq/v3-doc-orm-computed-fields b/code-repos/zenstackhq/v3-doc-orm-computed-fields new file mode 160000 index 00000000..e27eda24 --- /dev/null +++ b/code-repos/zenstackhq/v3-doc-orm-computed-fields @@ -0,0 +1 @@ +Subproject commit e27eda24564ac6a9a17a460731ec78b62f194809 diff --git a/code-repos/zenstackhq/v3-doc-orm-polymorphism b/code-repos/zenstackhq/v3-doc-orm-polymorphism new file mode 160000 index 00000000..bcfc5541 --- /dev/null +++ b/code-repos/zenstackhq/v3-doc-orm-polymorphism @@ -0,0 +1 @@ +Subproject commit bcfc5541033b966e6a614962cfce6391378be413 diff --git a/code-repos/zenstackhq/v3-doc-orm-typed-json b/code-repos/zenstackhq/v3-doc-orm-typed-json new file mode 160000 index 00000000..55c73f46 --- /dev/null +++ b/code-repos/zenstackhq/v3-doc-orm-typed-json @@ -0,0 +1 @@ +Subproject commit 55c73f46b1169f053c19b1bb635187cc15b4ec7e diff --git a/code-repos/zenstackhq/v3-doc-quick-start b/code-repos/zenstackhq/v3-doc-quick-start new file mode 160000 index 00000000..81b6de5c --- /dev/null +++ b/code-repos/zenstackhq/v3-doc-quick-start @@ -0,0 +1 @@ +Subproject commit 81b6de5c65ec8dbbd53d174644c4e8516ee9e1f6 diff --git a/package.json b/package.json index d5b8de74..e881f2b9 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "serve": "docusaurus serve", "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids", - "typecheck": "tsc" + "typecheck": "tsc", + "pull-submodules": "git submodule foreach git pull origin main" }, "dependencies": { "@algolia/client-search": "^4.22.1", @@ -30,6 +31,7 @@ "prism-react-renderer": "^2.3.1", "prism-svelte": "^0.5.0", "prismjs": "^1.29.0", + "raw-loader": "^4.0.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-icons": "^5.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ec59cc8f..5631d504 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -53,6 +53,9 @@ importers: prismjs: specifier: ^1.29.0 version: 1.29.0 + raw-loader: + specifier: ^4.0.2 + version: 4.0.2(webpack@5.90.1) react: specifier: ^18.2.0 version: 18.2.0 @@ -4262,6 +4265,12 @@ packages: resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} engines: {node: '>= 0.8'} + raw-loader@4.0.2: + resolution: {integrity: sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true @@ -10787,6 +10796,12 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 + raw-loader@4.0.2(webpack@5.90.1): + dependencies: + loader-utils: 2.0.4 + schema-utils: 3.3.0 + webpack: 5.90.1 + rc@1.2.8: dependencies: deep-extend: 0.6.0 diff --git a/src/components/GithubCodeBlock.tsx b/src/components/GithubCodeBlock.tsx index 5ab8770a..4f3692b7 100644 --- a/src/components/GithubCodeBlock.tsx +++ b/src/components/GithubCodeBlock.tsx @@ -1,5 +1,4 @@ import CodeBlock from '@theme/CodeBlock'; -import { useEffect, useState } from 'react'; interface GithubCodeBlockProps { repoPath: string; @@ -7,19 +6,7 @@ interface GithubCodeBlockProps { } const GithubCodeBlock: React.FC = ({ repoPath, file }) => { - const [code, setCode] = useState('Loading...'); - - useEffect(() => { - (async function () { - const response = await fetch(`https://cdn.jsdelivr.net/gh/${repoPath}/${file}`); - if (!response.ok) { - setCode(`Unable to load "${repoPath}/${file}"`); - return; - } - const text = await response.text(); - setCode(text); - })(); - }, [repoPath, file]); + const code = require(`!!raw-loader!@site/code-repos/${repoPath}/${file}`).default; const getLanguage = (file: string): string => { if (file.endsWith('.ts')) { diff --git a/src/components/StackBlitzGithub.tsx b/src/components/StackBlitzGithub.tsx new file mode 100644 index 00000000..8e2302dc --- /dev/null +++ b/src/components/StackBlitzGithub.tsx @@ -0,0 +1,44 @@ +import sdk from '@stackblitz/sdk'; +import React from 'react'; +import GithubCodeBlock from './GithubCodeBlock'; + +interface StackBlitzGithubProps { + repoPath: string; + openFile?: string; + codeFiles?: string[]; + startScript?: string; +} + +const StackBlitzGithub: React.FC = ({ + repoPath, + openFile = 'main.ts', + codeFiles: plainCodeFiles = undefined, + startScript, +}) => { + const options = { + openFile, + view: 'editor', + startScript, + } as const; + + if (!plainCodeFiles) { + plainCodeFiles = [openFile]; + } + + return ( + <> + + {plainCodeFiles.map((file) => ( + + ))} + + ); +}; + +export default StackBlitzGithub; diff --git a/src/components/StackBlitzGithubEmbed.tsx b/src/components/StackBlitzGithubEmbed.tsx deleted file mode 100644 index 052aff98..00000000 --- a/src/components/StackBlitzGithubEmbed.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import sdk from '@stackblitz/sdk'; -import TabItem from '@theme/TabItem'; -import Tabs from '@theme/Tabs'; -import mobile from 'is-mobile'; -import React, { useEffect, useRef } from 'react'; -import GithubCodeBlock from './GithubCodeBlock'; - -interface StackBlitzGithubEmbedProps { - repoPath: string; - height?: string; - openFile?: string; - plainCodeFiles?: string[]; - startScript?: string; - clickToLoad?: boolean; -} - -const StackBlitzGithubEmbed: React.FC = ({ - repoPath, - height = '600px', - openFile = 'main.ts', - plainCodeFiles = undefined, - clickToLoad = false, - startScript, -}) => { - const containerRef = useRef(null); - - const options = { - openFile, - height, - view: 'editor', - startScript, - clickToLoad, - } as const; - - if (!plainCodeFiles) { - plainCodeFiles = [openFile]; - } - - useEffect(() => { - if (containerRef.current) { - setTimeout(() => { - // docusaurus seems to recreate the tab after mounting, give it a - // chance to complete - sdk.embedGithubProject(containerRef.current, repoPath, options); - }, 0); - } - }, [repoPath, height, containerRef]); - - const PlainCode = () => ( - <> - {plainCodeFiles.map((file) => ( - - ))} - - ); - - if (mobile()) { - return ; - } else { - return ( - <> - - - - - -
- Click{' '} - sdk.openGithubProject(repoPath, options)}> - here - {' '} - to pop out if the embed doesn't load an interactive terminal. -
-
- - - -
- - ); - } -}; - -export default StackBlitzGithubEmbed; diff --git a/versioned_docs/version-3.x/orm/api/aggregate.md b/versioned_docs/version-3.x/orm/api/aggregate.md index 27b95a31..7f0856d1 100644 --- a/versioned_docs/version-3.x/orm/api/aggregate.md +++ b/versioned_docs/version-3.x/orm/api/aggregate.md @@ -3,7 +3,7 @@ sidebar_position: 7 description: Aggregate API --- -import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import StackBlitzGithub from '@site/src/components/StackBlitzGithub'; # Aggregate @@ -19,4 +19,4 @@ You can also use `where`, `orderBy`, `skip`, and `take` to control what records ## Samples - + diff --git a/versioned_docs/version-3.x/orm/api/count.md b/versioned_docs/version-3.x/orm/api/count.md index d337e632..a463523e 100644 --- a/versioned_docs/version-3.x/orm/api/count.md +++ b/versioned_docs/version-3.x/orm/api/count.md @@ -3,12 +3,12 @@ sidebar_position: 6 description: Count API --- -import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import StackBlitzGithub from '@site/src/components/StackBlitzGithub'; # Count You can use the `count` method to count the number of records that match a query. It also allows to count non-null field values with an `select` clause. - + To count relations, please use a `find` API with the special `_count` field as demonstrated in the [Find](./find.md#field-selection) section. diff --git a/versioned_docs/version-3.x/orm/api/create.md b/versioned_docs/version-3.x/orm/api/create.md index 5135ed23..3d1f0371 100644 --- a/versioned_docs/version-3.x/orm/api/create.md +++ b/versioned_docs/version-3.x/orm/api/create.md @@ -3,7 +3,7 @@ sidebar_position: 2 description: Create API --- -import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import StackBlitzGithub from '@site/src/components/StackBlitzGithub'; # Create @@ -18,5 +18,5 @@ The `create` series of APIs are used to create new records in the database. It h ## Samples - + diff --git a/versioned_docs/version-3.x/orm/api/delete.md b/versioned_docs/version-3.x/orm/api/delete.md index e16e4dda..b5e39961 100644 --- a/versioned_docs/version-3.x/orm/api/delete.md +++ b/versioned_docs/version-3.x/orm/api/delete.md @@ -3,7 +3,7 @@ sidebar_position: 5 description: Delete API --- -import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import StackBlitzGithub from '@site/src/components/StackBlitzGithub'; # Delete @@ -17,4 +17,4 @@ You can also delete records as part of an `update` operation from a relation. Se ## Samples - + diff --git a/versioned_docs/version-3.x/orm/api/filter.md b/versioned_docs/version-3.x/orm/api/filter.md index 53ac20d7..a7d7bf5b 100644 --- a/versioned_docs/version-3.x/orm/api/filter.md +++ b/versioned_docs/version-3.x/orm/api/filter.md @@ -4,7 +4,7 @@ description: how to filter entities --- import ZenStackVsPrisma from '../../_components/ZenStackVsPrisma'; -import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import StackBlitzGithub from '@site/src/components/StackBlitzGithub'; # Filter @@ -21,13 +21,13 @@ You can filter on scalar fields with values or operators as supported by the fie A filter object can contain multiple field filters, and they are combined with `AND` semantic. You can also use the `AND`, `OR`, and `NOT` logical operators to combine filter objects to form a complex filter. - + ## Relation filters Filters can be defined on conditions over relations. For one-to-one relations, you can filter on their fields directly. For one-to-many relations, use the "some", "every", or "none" operators to build a condition over a list of records. - + ## List filters @@ -83,4 +83,4 @@ ZenStack v3 is implemented on top of [Kysely](https://kysely.dev/), and it lever The `$expr` operator can be used together with other filter operators, so you can keep most of your filters simple and only reach to the query builder level for complicated components. - + diff --git a/versioned_docs/version-3.x/orm/api/find.md b/versioned_docs/version-3.x/orm/api/find.md index 738a5a93..cdcb5d41 100644 --- a/versioned_docs/version-3.x/orm/api/find.md +++ b/versioned_docs/version-3.x/orm/api/find.md @@ -3,7 +3,7 @@ sidebar_position: 2 description: Find API --- -import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import StackBlitzGithub from '@site/src/components/StackBlitzGithub'; import SelectIncludeOmit from './_select-include-omit.md'; # Find @@ -32,7 +32,7 @@ The `find` series of APIs are used to query records from the database. It has th ## Basic usage - + ## Filtering @@ -42,13 +42,13 @@ The API provides a very flexible set of filtering options. We've put it into a [ Use the `sort` field to control the sort field, direction, and null field placement. Sorting is not supported for `findUnique` and `findUniqueOrThrow`. - + ## Pagination You can use two strategies for pagination: offset-based or cursor-based. Pagination is not supported for `findUnique` and `findUniqueOrThrow`. - + ## Field selection @@ -56,7 +56,7 @@ You can use the following fields to control what fields are returned in the resu - + ## Finding distinct rows diff --git a/versioned_docs/version-3.x/orm/api/group-by.md b/versioned_docs/version-3.x/orm/api/group-by.md index 92d7937e..fb6d8f32 100644 --- a/versioned_docs/version-3.x/orm/api/group-by.md +++ b/versioned_docs/version-3.x/orm/api/group-by.md @@ -3,7 +3,7 @@ sidebar_position: 8 description: GroupBy API --- -import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import StackBlitzGithub from '@site/src/components/StackBlitzGithub'; # GroupBy @@ -40,4 +40,4 @@ The `having` field can be used to filter the aggregated results. Two types of fi ## Samples - + diff --git a/versioned_docs/version-3.x/orm/api/transaction.md b/versioned_docs/version-3.x/orm/api/transaction.md index a0cf5767..6b97d1e5 100644 --- a/versioned_docs/version-3.x/orm/api/transaction.md +++ b/versioned_docs/version-3.x/orm/api/transaction.md @@ -3,7 +3,7 @@ sidebar_position: 9 description: Transaction API --- -import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import StackBlitzGithub from '@site/src/components/StackBlitzGithub'; # Transaction @@ -40,4 +40,4 @@ const [user, post] = await db.$transaction(async (tx) => { ## Samples - + diff --git a/versioned_docs/version-3.x/orm/api/update.md b/versioned_docs/version-3.x/orm/api/update.md index 9adcce77..a8459186 100644 --- a/versioned_docs/version-3.x/orm/api/update.md +++ b/versioned_docs/version-3.x/orm/api/update.md @@ -3,7 +3,7 @@ sidebar_position: 4 description: Update API --- -import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import StackBlitzGithub from '@site/src/components/StackBlitzGithub'; # Update @@ -16,7 +16,7 @@ Update to records can be done with the following methods: ## Updating scalar fields - + In additional to the standard way of updating fields, list fields support the following operators: @@ -45,4 +45,4 @@ THe `update` and `upsert` methods are very powerful in that they allow you to fr `updateMany` and `updateManyAndReturn` only support updating scalar fields. - + diff --git a/versioned_docs/version-3.x/orm/cli.md b/versioned_docs/version-3.x/orm/cli.md index c798b998..a6944b0b 100644 --- a/versioned_docs/version-3.x/orm/cli.md +++ b/versioned_docs/version-3.x/orm/cli.md @@ -3,7 +3,7 @@ sidebar_position: 2 description: Using the CLI --- -import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import StackBlitzGithub from '@site/src/components/StackBlitzGithub'; # Using the CLI @@ -13,6 +13,6 @@ In the context of ORM, the CLI compiles ZModel into a TypeScript representation, You can try running the `npx zen generate` command in the following playground and inspect the TypeScript code generated inside the "zenstack" folder. - + The `generate` command generates several TypeScript files from the ZModel schema that support both development-time typing and runtime access to the schema. For more details of the generated code, please refer to the [@core/typescript plugin](../reference/plugins/typescript.md) documentation. diff --git a/versioned_docs/version-3.x/orm/computed-fields.md b/versioned_docs/version-3.x/orm/computed-fields.md index fc9fd74b..3be66dbb 100644 --- a/versioned_docs/version-3.x/orm/computed-fields.md +++ b/versioned_docs/version-3.x/orm/computed-fields.md @@ -4,7 +4,7 @@ description: Computed fields in ZModel --- import ZenStackVsPrisma from '../_components/ZenStackVsPrisma'; -import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import StackBlitzGithub from '@site/src/components/StackBlitzGithub'; # Computed Fields @@ -65,4 +65,4 @@ const db = new ZenStackClient(schema, { ## Samples - + diff --git a/versioned_docs/version-3.x/orm/inferred-types.md b/versioned_docs/version-3.x/orm/inferred-types.md index 0a99274a..0b347ecc 100644 --- a/versioned_docs/version-3.x/orm/inferred-types.md +++ b/versioned_docs/version-3.x/orm/inferred-types.md @@ -3,7 +3,7 @@ sidebar_position: 15 description: TypeScript types derived from the ZModel schema --- -import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import StackBlitzGithub from '@site/src/components/StackBlitzGithub'; # Schema-Inferred Types @@ -23,4 +23,4 @@ Most of the time, you don't need to explicitly type the input and output of the ## Samples - + diff --git a/versioned_docs/version-3.x/orm/plugins/entity-mutation-hooks.md b/versioned_docs/version-3.x/orm/plugins/entity-mutation-hooks.md index d231060f..6416702d 100644 --- a/versioned_docs/version-3.x/orm/plugins/entity-mutation-hooks.md +++ b/versioned_docs/version-3.x/orm/plugins/entity-mutation-hooks.md @@ -2,7 +2,7 @@ sidebar_position: 2 --- -import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import StackBlitzGithub from '@site/src/components/StackBlitzGithub'; # Entity Mutation Hooks @@ -48,4 +48,4 @@ Be very careful about opting in to load before and after mutation entities. Batc ## Samples - + diff --git a/versioned_docs/version-3.x/orm/plugins/kysely-query-hooks.md b/versioned_docs/version-3.x/orm/plugins/kysely-query-hooks.md index 11911f97..eac671f3 100644 --- a/versioned_docs/version-3.x/orm/plugins/kysely-query-hooks.md +++ b/versioned_docs/version-3.x/orm/plugins/kysely-query-hooks.md @@ -2,7 +2,7 @@ sidebar_position: 3 --- -import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import StackBlitzGithub from '@site/src/components/StackBlitzGithub'; # Kysely Query Hooks @@ -25,4 +25,4 @@ To create a Kysely query hook plugin, call the `$use` method with an object cont Kysely's `QueryNode` objects are low-level and not easy to process. ZenStack will provide helpers to facilitate common tasks in the future. ::: - + diff --git a/versioned_docs/version-3.x/orm/plugins/query-api-hooks.md b/versioned_docs/version-3.x/orm/plugins/query-api-hooks.md index 2ee43085..53996e4d 100644 --- a/versioned_docs/version-3.x/orm/plugins/query-api-hooks.md +++ b/versioned_docs/version-3.x/orm/plugins/query-api-hooks.md @@ -2,7 +2,7 @@ sidebar_position: 1 --- -import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import StackBlitzGithub from '@site/src/components/StackBlitzGithub'; # Query API Hooks @@ -22,4 +22,4 @@ As its name suggests, query API hooks are only triggered by ORM query calls, not ## Samples - + diff --git a/versioned_docs/version-3.x/orm/polymorphism.md b/versioned_docs/version-3.x/orm/polymorphism.md index 0b47630c..f01bc7a4 100644 --- a/versioned_docs/version-3.x/orm/polymorphism.md +++ b/versioned_docs/version-3.x/orm/polymorphism.md @@ -4,8 +4,7 @@ description: Polymorphic models --- import ZenStackVsPrisma from '../_components/ZenStackVsPrisma'; -import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; -import GithubCodeBlock from '@site/src/components/GithubCodeBlock'; +import StackBlitzGithub from '@site/src/components/StackBlitzGithub'; # Polymorphic Models @@ -31,6 +30,4 @@ The ORM query API hides all the complexity of managing polymorphic models for yo The schema used in the sample involves a base model and three concrete models: - - - + diff --git a/versioned_docs/version-3.x/orm/query-builder.md b/versioned_docs/version-3.x/orm/query-builder.md index af26c2e9..0d909d8a 100644 --- a/versioned_docs/version-3.x/orm/query-builder.md +++ b/versioned_docs/version-3.x/orm/query-builder.md @@ -4,7 +4,7 @@ description: Query builder API --- import ZenStackVsPrisma from '../_components/ZenStackVsPrisma'; -import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import StackBlitzGithub from '@site/src/components/StackBlitzGithub'; # Query Builder API @@ -24,4 +24,4 @@ Besides building full queries, the query builder API can also be embedded inside The samples assume you have a basic understanding of Kysely. - + diff --git a/versioned_docs/version-3.x/orm/quick-start.md b/versioned_docs/version-3.x/orm/quick-start.md index 1cc2ad48..aaa3e972 100644 --- a/versioned_docs/version-3.x/orm/quick-start.md +++ b/versioned_docs/version-3.x/orm/quick-start.md @@ -3,7 +3,7 @@ sidebar_position: 1 description: Quick start guide --- -import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; +import StackBlitzGithub from '@site/src/components/StackBlitzGithub'; import ZModelStarter from '../_components/_zmodel-starter.md'; import PackageInstall from '../_components/PackageInstall.tsx'; import PackageExec from '../_components/PackageExec.tsx'; @@ -26,7 +26,7 @@ npm create zenstack@next my-project Or simply use the following playground to experience it inside the browser. - + ## 2. Adding to an existing project diff --git a/versioned_docs/version-3.x/orm/typed-json.md b/versioned_docs/version-3.x/orm/typed-json.md index c5fb2a52..a96f1475 100644 --- a/versioned_docs/version-3.x/orm/typed-json.md +++ b/versioned_docs/version-3.x/orm/typed-json.md @@ -4,8 +4,7 @@ description: Strongly typed JSON fields --- import ZenStackVsPrisma from '../_components/ZenStackVsPrisma'; -import StackBlitzGithubEmbed from '@site/src/components/StackBlitzGithubEmbed'; -import GithubCodeBlock from '@site/src/components/GithubCodeBlock'; +import StackBlitzGithub from '@site/src/components/StackBlitzGithub'; # Strongly Typed JSON @@ -20,6 +19,5 @@ ZModel allows you to define custom types and use them to [type JSON fields](../m ## Samples - - + From 2fe949ade40a939eced4016aa5434a5f001a658e Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Sun, 24 Aug 2025 20:42:50 +0800 Subject: [PATCH 39/51] addressing review comments --- src/components/StackBlitzGithub.tsx | 2 +- versioned_docs/version-3.x/migrate-prisma.md | 4 +-- versioned_docs/version-3.x/modeling/plugin.md | 2 +- .../version-3.x/modeling/polymorphism.md | 2 +- .../version-3.x/modeling/relation.md | 34 ++++++++++--------- versioned_docs/version-3.x/orm/api/filter.md | 18 +++++----- versioned_docs/version-3.x/orm/api/find.md | 2 +- versioned_docs/version-3.x/orm/api/update.md | 4 +-- versioned_docs/version-3.x/orm/client.md | 4 +-- .../version-3.x/orm/computed-fields.md | 4 +++ versioned_docs/version-3.x/orm/index.md | 9 +++-- versioned_docs/version-3.x/orm/quick-start.md | 4 +-- .../version-3.x/reference/zmodel/attribute.md | 2 +- 13 files changed, 51 insertions(+), 40 deletions(-) diff --git a/src/components/StackBlitzGithub.tsx b/src/components/StackBlitzGithub.tsx index 8e2302dc..59a87ab2 100644 --- a/src/components/StackBlitzGithub.tsx +++ b/src/components/StackBlitzGithub.tsx @@ -27,7 +27,7 @@ const StackBlitzGithub: React.FC = ({ return ( <> -
+
Click{' '} sdk.openGithubProject(repoPath, options)}> here diff --git a/versioned_docs/version-3.x/migrate-prisma.md b/versioned_docs/version-3.x/migrate-prisma.md index 4a5689bb..1f91aa26 100644 --- a/versioned_docs/version-3.x/migrate-prisma.md +++ b/versioned_docs/version-3.x/migrate-prisma.md @@ -88,7 +88,7 @@ Replace `new PrismaClient()` with `new ZenStackClient(schema, ...)` where `schem ```ts title='db.ts' import { ZenStackClient } from '@zenstackhq/runtime'; -import { schema } from '@/zenstack/schema'; +import { schema } from './zenstack/schema'; import { PostgresDialect } from 'kysely'; import { Pool } from 'pg'; @@ -108,7 +108,7 @@ export const db = new ZenStackClient(schema, { import { ZenStackClient } from '@zenstackhq/runtime'; import { SqliteDialect } from 'kysely'; import SQLite from 'better-sqlite3'; -import { schema } from '@/zenstack/schema'; +import { schema } from './zenstack/schema'; export const db = new ZenStackClient(schema, { dialect: new SqliteDialect({ diff --git a/versioned_docs/version-3.x/modeling/plugin.md b/versioned_docs/version-3.x/modeling/plugin.md index b3256c8c..0166b44a 100644 --- a/versioned_docs/version-3.x/modeling/plugin.md +++ b/versioned_docs/version-3.x/modeling/plugin.md @@ -41,7 +41,7 @@ A plugin declaration involves three parts: 1. A unique name 2. A `provider` field that specifies where to load the plugin from. It can be a built-in plugin (like `@core/prisma` here), a local JavaScript module, or an NPM package name. -3. Plugin-specific configuration options, such as `output` in this case. +3. Plugin-specific configuration options, such as `output` in this case. Options are solely interpreted by the plugin implementation. A plugin can have the following effects to ZModel: diff --git a/versioned_docs/version-3.x/modeling/polymorphism.md b/versioned_docs/version-3.x/modeling/polymorphism.md index 7192354b..8e1761ab 100644 --- a/versioned_docs/version-3.x/modeling/polymorphism.md +++ b/versioned_docs/version-3.x/modeling/polymorphism.md @@ -28,7 +28,7 @@ It may be tempting to use mixins to share the common fields, however it's not an A true solution involves having an in-database model of polymorphism, where we really have a `Content` table that serves as an intermediary between `User` and the concrete content types. This is what ZModel polymorphism is about. :::info -There are [two main ways](https://www.prisma.io/docs/orm/prisma-schema/data-model/table-inheritance) to model polymorphism in relational databases: single-table inheritance (STI) and multi-table inheritance (MTI, aka. "Delegate Types"). ZModel only supports MTI. +There are [two main ways](https://www.prisma.io/docs/orm/prisma-schema/data-model/table-inheritance) to model polymorphism in relational databases: single-table inheritance (STI) and multi-table inheritance (MTI, aka. "Delegate Types"). ZModel's implementation follows the MTI pattern. ::: ## Modeling polymorphism diff --git a/versioned_docs/version-3.x/modeling/relation.md b/versioned_docs/version-3.x/modeling/relation.md index fc06ee92..5b391ac0 100644 --- a/versioned_docs/version-3.x/modeling/relation.md +++ b/versioned_docs/version-3.x/modeling/relation.md @@ -32,14 +32,17 @@ Relations can also be explicitly named, and it's useful to disambiguate relation ```zmodel model User { - id Int @id - profile Profile? @relation('UserProfile') + id Int @id + profile Profile? @relation('UserProfile') + privateProfile Profile? @relation('UserPrivateProfile') } model Profile { - id Int @id - user User @relation('UserProfile', fields: [userId], references: [id]) - userId Int @unique + id Int @id + user User @relation('UserProfile', fields: [userId], references: [id]) + userId Int @unique + userPrivate User @relation('UserPrivateProfile', fields: [userPrivateId], references: [id]) + userPrivateId Int @unique } ``` @@ -146,7 +149,7 @@ model UserPost { } ``` -Since the join table is explicitly defined, when using the ORM, you'll need to involve it in your queries with an extra level of nesting. +Since the join table is explicitly defined, when using the ORM, you'll need to involve it in your queries with an extra level of nesting. Albeit the complexity, an explicit join table gives you the flexibility, e.g., to have extra fields. ## Self relation @@ -158,7 +161,7 @@ Self-relations are cases where a model has a relation to itself. They can be one model Employee { id Int @id mentorId Int? @unique - mentor Employee? @relation('Mentorship', fields: [mentorId], references: [id]) + mentor Employee? @relation('Mentorship', fields: [mentorId], references: [id]) mentee Employee? @relation('Mentorship') } ``` @@ -167,7 +170,7 @@ Quick notes: - Both sides of the relation are defined in the same model. - Both relation fields need to have `@relation` attributes with matching names. -- One side (here `mentor`) has a foreign key field (`mentorId`) that references the primary key. +- One side has a foreign key field (`mentorId`) that references the primary key. - The foreign key field is marked `@unique` to guarantee one-to-one. ### One-to-many @@ -184,7 +187,7 @@ model Employee { Quick notes: - Both sides of the relation are defined in the same model. - Both relation fields need to have `@relation` attributes with matching names. -- One side (here `manager`) has a foreign key field (`managerId`) that references the primary key. +- One side has a foreign key field (`managerId`) that references the primary key. - The owner side (`Employee.manager`) can be either optional or required based on your needs. ### Many-to-many @@ -204,15 +207,15 @@ You can also define an explicit one by modeling the join table explicitly. ```zmodel model Employee { id Int @id - mentors Mentorship[] @relation('Mentorship') - mentees Mentorship[] @relation('Mentorship') + mentors Mentorship[] @relation('Mentor') + mentees Mentorship[] @relation('Mentee') } model Mentorship { mentorId Int menteeId Int - mentor Employee @relation('Mentorship', fields: [mentorId], references: [id]) - mentee Employee @relation('Mentorship', fields: [menteeId], references: [id]) + mentor Employee @relation('Mentor', fields: [mentorId], references: [id]) + mentee Employee @relation('Mentee', fields: [menteeId], references: [id]) @@id([mentorId, menteeId]) } @@ -247,16 +250,14 @@ enum ReferentialAction { - `Cascade` - **onDelete**: deleting a referenced record will trigger the deletion of referencing record. - - **onUpdate**: updates the relation scalar fields if the referenced scalar fields of the dependent record are updated. - `Restrict` - - **onDelete**: prevents the deletion if any referencing records exist. - **onUpdate**: prevents the identifier of a referenced record from being changed. - `NoAction` - + Similar to 'Restrict', the difference between the two is dependent on the database being used. - `SetNull` @@ -265,6 +266,7 @@ enum ReferentialAction { - **onUpdate**: when updating the identifier of a referenced object, the scalar fields of the referencing objects will be set to NULL. - `SetDefault` + - **onDelete**: the scalar field of the referencing object will be set to the fields default value. - **onUpdate**: the scalar field of the referencing object will be set to the fields default value. diff --git a/versioned_docs/version-3.x/orm/api/filter.md b/versioned_docs/version-3.x/orm/api/filter.md index a7d7bf5b..00699bab 100644 --- a/versioned_docs/version-3.x/orm/api/filter.md +++ b/versioned_docs/version-3.x/orm/api/filter.md @@ -14,21 +14,15 @@ Filtering is an important topic because it's involved in many ORM operations, fo You can filter on scalar fields with values or operators as supported by the field type. The following filter operators are available. -- `equals` `not`: all scalar fields. +- `equals` `not`: all scalar fields - `in` `notIn`: all scalar fields -- `contains` `startsWith` `endsWith`: String fields -- `lt` `lte` `gt` `gte`: String, Int, BigInt, Float, Decimal, and Date fields +- `contains` `startsWith` `endsWith`: `String` fields +- `lt` `lte` `gt` `gte`: `String`, `Int`, `BigInt`, `Float`, `Decimal`, and `Date` fields A filter object can contain multiple field filters, and they are combined with `AND` semantic. You can also use the `AND`, `OR`, and `NOT` logical operators to combine filter objects to form a complex filter. -## Relation filters - -Filters can be defined on conditions over relations. For one-to-one relations, you can filter on their fields directly. For one-to-many relations, use the "some", "every", or "none" operators to build a condition over a list of records. - - - ## List filters List fields allow extra filter operators to filter on the list content: @@ -73,6 +67,12 @@ await db.post.findMany({ Filtering on Json fields is work in progress and will be available soon. ::: +## Relation filters + +Filters can be defined on conditions over relations. For one-to-one relations, you can filter on their fields directly. For one-to-many relations, use the "some", "every", or "none" operators to build a condition over a list of records. + + + ## Query builder filters diff --git a/versioned_docs/version-3.x/orm/api/find.md b/versioned_docs/version-3.x/orm/api/find.md index cdcb5d41..52a8b00b 100644 --- a/versioned_docs/version-3.x/orm/api/find.md +++ b/versioned_docs/version-3.x/orm/api/find.md @@ -40,7 +40,7 @@ The API provides a very flexible set of filtering options. We've put it into a [ ## Sorting -Use the `sort` field to control the sort field, direction, and null field placement. Sorting is not supported for `findUnique` and `findUniqueOrThrow`. +Use the `orderBy` field to control the sort field, direction, and null field placement. Sorting is not supported for `findUnique` and `findUniqueOrThrow`. diff --git a/versioned_docs/version-3.x/orm/api/update.md b/versioned_docs/version-3.x/orm/api/update.md index a8459186..c0b7e87d 100644 --- a/versioned_docs/version-3.x/orm/api/update.md +++ b/versioned_docs/version-3.x/orm/api/update.md @@ -11,7 +11,7 @@ Update to records can be done with the following methods: - `update` - Update a single, unique record. - `updateMany` - Update multiple records that match the query criteria. -- `updateManyAndReturn` - Similar to `updateMany`, but returns the updated records +- `updateManyAndReturn` - Similar to `updateMany`, but returns the updated records. - `upsert` - Update a single, unique record, or create it if it does not exist. ## Updating scalar fields @@ -41,7 +41,7 @@ await db.post.update({ ## Manipulating relations -THe `update` and `upsert` methods are very powerful in that they allow you to freely manipulate relations. You can create, connect, disconnect, update, and delete relations in a single operation. You can also reach deeply into indirect relations. +The `update` and `upsert` methods are very powerful in that they allow you to freely manipulate relations. You can create, connect, disconnect, update, and delete relations in a single operation. You can also reach deeply into indirect relations. `updateMany` and `updateManyAndReturn` only support updating scalar fields. diff --git a/versioned_docs/version-3.x/orm/client.md b/versioned_docs/version-3.x/orm/client.md index f3187fb4..c190ebb9 100644 --- a/versioned_docs/version-3.x/orm/client.md +++ b/versioned_docs/version-3.x/orm/client.md @@ -28,7 +28,7 @@ The samples below only show creating a client using SQLite (via [better-sqlite3] import { ZenStackClient } from '@zenstackhq/runtime'; import { SqliteDialect } from 'kysely'; import SQLite from 'better-sqlite3'; -import { schema } from '@/zenstack/schema'; +import { schema } from './zenstack/schema'; export const db = new ZenStackClient(schema, { dialect: new SqliteDialect({ @@ -44,7 +44,7 @@ export const db = new ZenStackClient(schema, { ```ts title='db.ts' import { ZenStackClient } from '@zenstackhq/runtime'; -import { schema } from '@/zenstack/schema'; +import { schema } from './zenstack/schema'; import { PostgresDialect } from 'kysely'; import { Pool } from 'pg'; diff --git a/versioned_docs/version-3.x/orm/computed-fields.md b/versioned_docs/version-3.x/orm/computed-fields.md index 3be66dbb..8fd46b88 100644 --- a/versioned_docs/version-3.x/orm/computed-fields.md +++ b/versioned_docs/version-3.x/orm/computed-fields.md @@ -34,9 +34,13 @@ const db = new ZenStackClient(schema, { ... computedFields: { User: { + // equivalent SQL: + // `(SELECT COUNT(*) AS "count" FROM "Post" WHERE "Post"."authorId" = "User"."id")` postCount: (eb) => eb.selectFrom('Post') .whereRef('Post.authorId', '=', 'id') + // the `as('count')` part is required because every Kysely selection + // needs to have a name .select(({fn}) => fn.countAll().as('count')), }, }, diff --git a/versioned_docs/version-3.x/orm/index.md b/versioned_docs/version-3.x/orm/index.md index b765facd..b8a0f92f 100644 --- a/versioned_docs/version-3.x/orm/index.md +++ b/versioned_docs/version-3.x/orm/index.md @@ -82,6 +82,10 @@ model Content { model Post extends Content { content String } + +model Video extends Content { + url String +} ``` ```ts title="main.ts" @@ -94,13 +98,14 @@ if (content.type === 'Post') { } ``` -### Straightforward and light-Weighted +### Straightforward, light-weighted, flexible -Compared to Prisma and previous versions of ZenStack, v3 is more straightforward and light-weighted. +Compared to Prisma and previous versions of ZenStack, v3 is more straightforward, light-weighted, and flexible. - No runtime dependency to Prisma, thus no overhead of Rust/WASM query engines. - No magic generating into `node_modules`. You fully control how the generated code is compiled and bundled. - Less code generation, more type inference. +- A plugin system that allows you to extend ZenStack at the schema, CLI, and runtime levels. ## Documentation Conventions diff --git a/versioned_docs/version-3.x/orm/quick-start.md b/versioned_docs/version-3.x/orm/quick-start.md index aaa3e972..46234ff8 100644 --- a/versioned_docs/version-3.x/orm/quick-start.md +++ b/versioned_docs/version-3.x/orm/quick-start.md @@ -24,7 +24,7 @@ Run the following command to scaffold a new project with a pre-configured minima npm create zenstack@next my-project ``` -Or simply use the following playground to experience it inside the browser. +Or simply use the interactive playground to experience it inside the browser. @@ -38,7 +38,7 @@ Then create a `zenstack/schema.zmodel` file in the root of your project. You can -Finally, run `zen generate` to compile the schema into TypeScript. +Finally, run `zen generate` to compile the schema into TypeScript. Optionally, run `zen db push` to push the schema to the database. diff --git a/versioned_docs/version-3.x/reference/zmodel/attribute.md b/versioned_docs/version-3.x/reference/zmodel/attribute.md index eb1b8369..e8af70c7 100644 --- a/versioned_docs/version-3.x/reference/zmodel/attribute.md +++ b/versioned_docs/version-3.x/reference/zmodel/attribute.md @@ -110,7 +110,7 @@ model User { Attribute can be declared with a list of parameters and applied with a comma-separated list of arguments. -Arguments are mapped to parameters by position or by name. For example, for the `@default` attribute declared as: +Arguments are mapped to parameters by position or by name. Parameter names prefixed with `_ ` are positional and arguments for such parameters can be provided without their names. For example, for the `@default` attribute declared as: ```zmodel attribute @default(_ value: ContextType) From 7d880b082afd537540610735f7cea678c3e392fa Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Tue, 26 Aug 2025 19:40:28 +0800 Subject: [PATCH 40/51] update --- code-repos/zenstackhq/v3-doc-orm | 2 +- .../orm/plugins/entity-mutation-hooks.md | 41 ++++++++++--------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/code-repos/zenstackhq/v3-doc-orm b/code-repos/zenstackhq/v3-doc-orm index 94c95137..2c80953c 160000 --- a/code-repos/zenstackhq/v3-doc-orm +++ b/code-repos/zenstackhq/v3-doc-orm @@ -1 +1 @@ -Subproject commit 94c95137c07fe67c89ad552a8b5cebfcf493121d +Subproject commit 2c80953c048577aefb5987ac0aa5fbe0c9a61da6 diff --git a/versioned_docs/version-3.x/orm/plugins/entity-mutation-hooks.md b/versioned_docs/version-3.x/orm/plugins/entity-mutation-hooks.md index 6416702d..41a88eef 100644 --- a/versioned_docs/version-3.x/orm/plugins/entity-mutation-hooks.md +++ b/versioned_docs/version-3.x/orm/plugins/entity-mutation-hooks.md @@ -14,36 +14,37 @@ To create an entity mutation hook plugin, call the `$use` method with an `onEnti - `beforeEntityMutation` A callback function that is called before the entity mutation operation. It receives a context object containing: - - The model - - The action (create, update, delete) - - The Kysely query node (SQL AST) - - The entities being mutated (only available when opted in) + - The model. + - The action (`create`, `update`, `delete`). + - The Kysely query node (SQL AST). + - An async loader to load the entities to be mutated. + - An `ZenStackClient` instance to perform further queries or mutations. Mutation operations initiated with this client will not trigger the entity mutation hooks again. + - A unique query ID to correlate data between `beforeEntityMutation` and `afterEntityMutation` hooks. - `afterEntityMutation` A callback function that is called after the entity mutation operation. It receives a context object containing: - - The model - - The action (create, update, delete) - - The Kysely query node (SQL AST) - - The entities before the mutation (only available when opted in) - - The entities after the mutation (only available when opted in) - -- `mutationInterceptionFilter` + - The model. + - The action (`create`, `update`, `delete`). + - The Kysely query node (SQL AST). + - An async loader to load the entities after the mutation. + - An `ZenStackClient` instance to perform further queries or mutations. Mutation operations initiated with this client will not trigger the entity mutation hooks again. + - A unique query ID to correlate data between `beforeEntityMutation` and `afterEntityMutation` hooks. + +- `runAfterMutationWithinTransaction` - A callback used to determine if an operation should be intercepted, and if so, whether entities should be loaded and passed to the `beforeEntityMutation` and `afterEntityMutation` hooks. It receives a context object containing: - - The model - - The action (create, update, delete) - - The Kysely query node (SQL AST) - - The callback should return an object indicating if the operation should be intercepted and whether entities should be loaded. If this callback is not provided, by default, all mutation operations are intercepted, but entities are not loaded. - -If a mutation happens inside a transaction, the `afterEntityMutation` callback is called after the transaction is committed. + A boolean option that controls whether to run after-mutation hooks within the transaction that performs the mutation. + - If set to `true`, if the mutation already runs inside a transaction, the callbacks are executed immediately after the mutation within the transaction boundary. If the mutation is not running inside a transaction, a new transaction is created to wrap both the mutation and the callbacks. If your hooks make further mutations, they will succeed or fail atomically with the original mutation. + - If set to `false`, the callbacks are executed after the mutation transaction is committed. + + Defaults to `false`. + :::info Update and delete triggered by cascading operations are not captured by the entity mutation hooks. ::: :::warning -Be very careful about opting in to load before and after mutation entities. Batch mutations can result in a large number of entities being loaded and incur significant performance overhead. +Be very careful about loading before and after mutation entities. Batch mutations can result in a large number of entities being loaded and incur significant performance overhead. ::: ## Samples From 8c059c516e0b346d4de8b2aa43346b8af3a2db57 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Fri, 29 Aug 2025 12:49:18 +0800 Subject: [PATCH 41/51] v3 LP --- docusaurus.config.js | 5 ++ src/lib/prism-zmodel.js | 13 +--- src/pages/v3/AICoding.tsx | 69 ++++++++++++++++++++ src/pages/v3/Notes.tsx | 20 ++++++ src/pages/v3/ORM.tsx | 56 +++++++++++++++++ src/pages/v3/SchemaLanguage.tsx | 55 ++++++++++++++++ src/pages/v3/Service.tsx | 107 ++++++++++++++++++++++++++++++++ src/pages/v3/index.module.css | 30 +++++++++ src/pages/v3/index.tsx | 90 +++++++++++++++++++++++++++ 9 files changed, 434 insertions(+), 11 deletions(-) create mode 100644 src/pages/v3/AICoding.tsx create mode 100644 src/pages/v3/Notes.tsx create mode 100644 src/pages/v3/ORM.tsx create mode 100644 src/pages/v3/SchemaLanguage.tsx create mode 100644 src/pages/v3/Service.tsx create mode 100644 src/pages/v3/index.module.css create mode 100644 src/pages/v3/index.tsx diff --git a/docusaurus.config.js b/docusaurus.config.js index 3786d47c..716c831d 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -104,6 +104,11 @@ const config = { label: 'Handbook', }, { to: '/blog', label: 'Blog', position: 'left' }, + { + to: 'v3', + position: 'left', + label: 'V3 Beta πŸš€', + }, { href: 'https://discord.gg/Ykhr738dUe', label: 'Discord', diff --git a/src/lib/prism-zmodel.js b/src/lib/prism-zmodel.js index 63ea4f97..d26ea9cb 100644 --- a/src/lib/prism-zmodel.js +++ b/src/lib/prism-zmodel.js @@ -1,19 +1,10 @@ Prism.languages.zmodel = Prism.languages.extend('clike', { + function: /@@?[A-Za-z_]\w*/, keyword: /\b(?:datasource|enum|generator|model|type|abstract|import|extends|attribute|view|plugin|proc|with)\b/, + entity: /\b(?:Int|String|Boolean|DateTime|Float|Decimal|BigInt|Bytes|Json|Unsupported)\b/, 'type-class-name': /(\b()\s+)[\w.\\]+/, }); -Prism.languages.javascript['class-name'][0].pattern = - /(\b(?:model|datasource|enum|generator|type|plugin|abstract)\s+)[\w.\\]+/; - -Prism.languages.insertBefore('zmodel', 'function', { - annotation: { - pattern: /(^|[^.])@+\w+/, - lookbehind: true, - alias: 'punctuation', - }, -}); - Prism.languages.insertBefore('zmodel', 'punctuation', { 'type-args': /\b(?:references|fields|onDelete|onUpdate):/, }); diff --git a/src/pages/v3/AICoding.tsx b/src/pages/v3/AICoding.tsx new file mode 100644 index 00000000..c6bffc1c --- /dev/null +++ b/src/pages/v3/AICoding.tsx @@ -0,0 +1,69 @@ +type FeatureItem = { + title: string; + img: string; + description: JSX.Element; +}; + +const FeatureList: FeatureItem[] = [ + { + title: 'Coherent Application Model', + img: '/img/access-control.png', + description: ( + <> + With data models, relations, validation rules, and access control policies all defined in one place, + LLMs can easily get a coherent understanding of the entire application. + + ), + }, + { + title: 'Concise Query API', + img: '/img/auto-api.png', + description: ( + <> + Concise and expressive, while leveraging existing knowledge of Prisma and Kysely, the query API makes it + easy for LLMs to generate high-quality query code. + + ), + }, + { + title: 'Slim Code Base', + img: '/img/ai-friendly.png', + description: ( + <> + By deriving many crucial artifacts from the schema, ZenStack eliminates boilerplate and helps you + maintain a slim code base that is easier for AI to work with. + + ), + }, +]; + +function Proposition({ title, img, description }: FeatureItem) { + return ( +
+
+ {title} +
+
+

{title}

+

{description}

+
+
+ ); +} + +export default function AICoding(): JSX.Element { + return ( +
+
+

+ Perfect Match for AI-Assisted Programming +

+
+
+ {FeatureList.map((props, idx) => ( + + ))} +
+
+ ); +} diff --git a/src/pages/v3/Notes.tsx b/src/pages/v3/Notes.tsx new file mode 100644 index 00000000..175db285 --- /dev/null +++ b/src/pages/v3/Notes.tsx @@ -0,0 +1,20 @@ +export default function Notes(): JSX.Element { + return ( +
+
+

+
Notes to V2 Users
+

+
+
+
+ ZenStack V3 has made the bold decision to remove Prisma as a runtime dependency and implement its + own ORM infrastructure on top of Kysely. Albeit the cost of such a + big refactor, we believe this is the right move to gain the flexibility needed to achieve the + project's vision. Please read blog post for more thoughts behind + the changes. +
+
+
+ ); +} diff --git a/src/pages/v3/ORM.tsx b/src/pages/v3/ORM.tsx new file mode 100644 index 00000000..7422c01c --- /dev/null +++ b/src/pages/v3/ORM.tsx @@ -0,0 +1,56 @@ +import CodeBlock from '@theme/CodeBlock'; + +export default function ORM(): JSX.Element { + return ( +
+
+

+
Flexible and Awesomely Typed ORM
+

+
+
+ + {`import { schema } from './zenstack'; +import { ZenStackClient } from '@zenstackhq/runtime'; + +const db = new ZenStackClient(schema, { ... }); + +// high-level query API +const usersWithPosts = await db.user.findUnique({ + where: { id: userId }, + include: { posts: true } +}); + +// low-level SQL query builder API +const userPostJoin = await db + .$qb + .selectFrom('User') + .innerJoin('Post', 'Post.authorId', 'User.id') + .select(['User.id', 'User.email', 'Post.title']) + .where('User.id', '=', userId) + .execute(); +`} + +
+ + An ORM is derived from the schema that gives you + +
    +
  • πŸ”‹ High-level ORM query API
  • +
  • πŸ”‹ Low-level SQL query builder API
  • +
  • πŸ”‹ Access control enforcement
  • +
  • πŸ”‹ Runtime data validation
  • +
  • πŸ”‹ Computed fields and custom procedures
  • +
  • πŸ”‹ Plugin system for tapping into various lifecycle events
  • +
+ + ZenStack's ORM is built on top of the awesome Kysely SQL query + builder. Its query API is compatible with that of{' '} + Prisma Client, so migrating an + existing Prisma project will require minimal code changes. + +
+
+
+ ); +} diff --git a/src/pages/v3/SchemaLanguage.tsx b/src/pages/v3/SchemaLanguage.tsx new file mode 100644 index 00000000..aa903cc8 --- /dev/null +++ b/src/pages/v3/SchemaLanguage.tsx @@ -0,0 +1,55 @@ +import CodeBlock from '@theme/CodeBlock'; + +export default function SchemaLanguage(): JSX.Element { + return ( +
+
+

+
Intuitive and Expressive Data Modeling
+

+
+
+
+ The modeling language allows you to +
    +
  • βœ… Define data models and relations
  • +
  • βœ… Define access control policies
  • +
  • βœ… Express data validation rules
  • +
  • βœ… Model polymorphic inheritance
  • +
  • βœ… Add custom attributes and functions to introduce custom semantics
  • +
  • βœ… Implement custom code generators
  • +
+ + The schema language is a superset of{' '} + Prisma Schema Language. + Migrating a Prisma schema is as simple as file renaming. + +
+ + {`model User { + id Int @id + email String @unique @email // constraint and validation + role String + posts Post[] // relation to another model + postCount Int @computed // computed field + + // access control rules colocated with data + @@allow('all', auth().id == id) + @@allow('create, read', true) +} + +model Post { + id Int + title String @length(1, 255) + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id]) + authorId Int // relation foreign key + + @@allow('read', published) + @@allow('all', auth().id == authorId || auth().role == 'ADMIN') +}`} + +
+
+ ); +} diff --git a/src/pages/v3/Service.tsx b/src/pages/v3/Service.tsx new file mode 100644 index 00000000..d9bb323f --- /dev/null +++ b/src/pages/v3/Service.tsx @@ -0,0 +1,107 @@ +import CodeBlock from '@theme/CodeBlock'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +export default function Service(): JSX.Element { + return ( +
+
+

+
Automatic HTTP Query Service
{' '} + + coming soon + +

+
+
+
+ + Thanks to the ORM's built-in access control, you get an HTTP query service for free + +
    +
  • πŸš€ Fully mirrors the ORM API
  • +
  • πŸš€ Seamlessly integrates with popular frameworks
  • +
  • πŸš€ Works with any authentication solution
  • +
  • + πŸš€ Type-safe client SDK powered by TanStack Query +
  • +
  • πŸš€ Highly customizable
  • +
+ +

+ Since the ORM is protected with access control, ZenStack can directly map it to an HTTP + service. ZenStack provides out-of-the-box integrations with popular frameworks including + Next.js, Nuxt, Express, etc. +

+

+ Client hooks based on TanStack Query can also be + derived from the schema, allowing you to make type-safe queries to the service without + writing a single line of code. +

+
+
+ + + + {`import { NextRequestHandler } from '@zenstackhq/server/next'; +import { db } from './db'; // ZenStackClient instance +import { getSessionUser } from './auth'; + +// callback to provide a per-request ORM client +async function getClient() { + // call a framework-specific helper to get session user + const authUser = await getSessionUser(); + + // return a new ORM client configured with the user, + // the user info will be used to enforce access control + return db.$setAuth(authUser); +} + +// Create a request handler for all requests to this route +// All CRUD requests are forwarded to the underlying ORM +const handler = NextRequestHandler({ getClient }); + +export { + handler as GET, + handler as PUT + handler as POST, + handler as PATCH, + handler as DELETE, +}; +`} + + + + + {`import { schema } from './zenstack'; +import { useQueryHooks } from '@zenstackhq/query/react'; + +export function UserPosts({ userId }: { userId: number }) { + // use auto-generated hook to query user with posts + const { user: userHooks } = useQueryHooks(schema); + const { data, isLoading } = userHooks.useFindUnique({ + where: { id: userId }, + include: { posts: true } + }); + + if (isLoading) return
Loading...
; + + return ( +
+

{data?.email}'s Posts

+
    + {data?.posts.map((post) => ( +
  • {post.title}
  • + ))} +
+
+ ); +} +`} +
+
+
+
+
+ ); +} diff --git a/src/pages/v3/index.module.css b/src/pages/v3/index.module.css new file mode 100644 index 00000000..228eb5de --- /dev/null +++ b/src/pages/v3/index.module.css @@ -0,0 +1,30 @@ +/** + * CSS files with the .module.css suffix will be treated as CSS modules + * and scoped locally. + */ + +.heroBanner { + padding: 8rem 2rem !important; + text-align: center !important; + position: relative !important; + overflow: hidden !important; +} + +@media screen and (min-width: 1200px) { + .bannerCode code { + font-size: 120% !important; + } +} + +@media screen and (max-width: 996px) { + .heroBanner { + padding-top: 4rem !important; + padding-bottom: 4rem !important; + } +} + +.buttons { + display: flex; + align-items: center; + justify-content: center; +} diff --git a/src/pages/v3/index.tsx b/src/pages/v3/index.tsx new file mode 100644 index 00000000..ace02d82 --- /dev/null +++ b/src/pages/v3/index.tsx @@ -0,0 +1,90 @@ +import Link from '@docusaurus/Link'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import Layout from '@theme/Layout'; +import clsx from 'clsx'; +import React from 'react'; +import AICoding from './AICoding'; +import styles from './index.module.css'; +import Notes from './Notes'; +import ORM from './ORM'; +import SchemaLanguage from './SchemaLanguage'; +import Service from './Service'; + +const description = `ZenStack v3 is a powerful data layer for modern TypeScript applications. It provides an intuitive data modeling language, a fully type-safe ORM, built-in access control and data validation, and automatic data query service that seamlessly integrates with popular frameworks like Next.js and Nuxt.`; + +function Header() { + return ( +
+
+
+
+

+ + The Data Layer for Modern TypeScript Applications + +

+

+ Intuitive data modeling, type-safe ORM, built-in access control, automatic query services, + and more. +

+
+ + Get Started β†’ + +
+
+
+
+
+ ); +} + +function Section({ children, className }: { children: React.ReactNode; className?: string }) { + return ( +
+
{children}
+
+ ); +} + +export default function Home(): JSX.Element { + const { siteConfig } = useDocusaurusContext(); + return ( + +
+
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ + Start Building Now β†’ + +
+
+ +
+ +
+
+ + ); +} From 790de9025908ca838ccdb23d79712c01b57f7c87 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Fri, 29 Aug 2025 13:05:27 +0800 Subject: [PATCH 42/51] update --- src/pages/v3/{ => _components}/AICoding.tsx | 0 src/pages/v3/{ => _components}/Notes.tsx | 4 ++-- src/pages/v3/{ => _components}/ORM.tsx | 0 src/pages/v3/{ => _components}/SchemaLanguage.tsx | 0 src/pages/v3/{ => _components}/Service.tsx | 0 src/pages/v3/index.tsx | 10 +++++----- 6 files changed, 7 insertions(+), 7 deletions(-) rename src/pages/v3/{ => _components}/AICoding.tsx (100%) rename src/pages/v3/{ => _components}/Notes.tsx (85%) rename src/pages/v3/{ => _components}/ORM.tsx (100%) rename src/pages/v3/{ => _components}/SchemaLanguage.tsx (100%) rename src/pages/v3/{ => _components}/Service.tsx (100%) diff --git a/src/pages/v3/AICoding.tsx b/src/pages/v3/_components/AICoding.tsx similarity index 100% rename from src/pages/v3/AICoding.tsx rename to src/pages/v3/_components/AICoding.tsx diff --git a/src/pages/v3/Notes.tsx b/src/pages/v3/_components/Notes.tsx similarity index 85% rename from src/pages/v3/Notes.tsx rename to src/pages/v3/_components/Notes.tsx index 175db285..3acc64f0 100644 --- a/src/pages/v3/Notes.tsx +++ b/src/pages/v3/_components/Notes.tsx @@ -11,8 +11,8 @@ export default function Notes(): JSX.Element { ZenStack V3 has made the bold decision to remove Prisma as a runtime dependency and implement its own ORM infrastructure on top of Kysely. Albeit the cost of such a big refactor, we believe this is the right move to gain the flexibility needed to achieve the - project's vision. Please read blog post for more thoughts behind - the changes. + project's vision. Please read this blog post for more thoughts + behind the changes.
diff --git a/src/pages/v3/ORM.tsx b/src/pages/v3/_components/ORM.tsx similarity index 100% rename from src/pages/v3/ORM.tsx rename to src/pages/v3/_components/ORM.tsx diff --git a/src/pages/v3/SchemaLanguage.tsx b/src/pages/v3/_components/SchemaLanguage.tsx similarity index 100% rename from src/pages/v3/SchemaLanguage.tsx rename to src/pages/v3/_components/SchemaLanguage.tsx diff --git a/src/pages/v3/Service.tsx b/src/pages/v3/_components/Service.tsx similarity index 100% rename from src/pages/v3/Service.tsx rename to src/pages/v3/_components/Service.tsx diff --git a/src/pages/v3/index.tsx b/src/pages/v3/index.tsx index ace02d82..f766515e 100644 --- a/src/pages/v3/index.tsx +++ b/src/pages/v3/index.tsx @@ -3,12 +3,12 @@ import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import Layout from '@theme/Layout'; import clsx from 'clsx'; import React from 'react'; -import AICoding from './AICoding'; +import AICoding from './_components/AICoding'; +import Notes from './_components/Notes'; +import ORM from './_components/ORM'; +import SchemaLanguage from './_components/SchemaLanguage'; +import Service from './_components/Service'; import styles from './index.module.css'; -import Notes from './Notes'; -import ORM from './ORM'; -import SchemaLanguage from './SchemaLanguage'; -import Service from './Service'; const description = `ZenStack v3 is a powerful data layer for modern TypeScript applications. It provides an intuitive data modeling language, a fully type-safe ORM, built-in access control and data validation, and automatic data query service that seamlessly integrates with popular frameworks like Next.js and Nuxt.`; From 014cbbebefd9c9ae07dcf03c1e6e10658bef9b6e Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Fri, 29 Aug 2025 19:04:59 +0800 Subject: [PATCH 43/51] update --- docusaurus.config.js | 19 +++++- src/pages/v3/_components/AICoding.tsx | 8 +-- src/pages/v3/_components/ORM.tsx | 2 +- .../{SchemaLanguage.tsx => Schema.tsx} | 2 +- src/pages/v3/_components/Service.tsx | 2 +- src/pages/v3/_components/ValueProps.tsx | 56 ++++++++++++++++++ src/pages/v3/index.tsx | 29 ++++++--- static/img/diagram.png | Bin 0 -> 7300 bytes static/img/search.png | Bin 0 -> 14012 bytes static/img/versatility.png | Bin 0 -> 33196 bytes .../version-3.x/orm/computed-fields.md | 2 +- 11 files changed, 102 insertions(+), 18 deletions(-) rename src/pages/v3/_components/{SchemaLanguage.tsx => Schema.tsx} (97%) create mode 100644 src/pages/v3/_components/ValueProps.tsx create mode 100644 static/img/diagram.png create mode 100644 static/img/search.png create mode 100644 static/img/versatility.png diff --git a/docusaurus.config.js b/docusaurus.config.js index 716c831d..b160d8f3 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -103,12 +103,12 @@ const config = { position: 'left', label: 'Handbook', }, - { to: '/blog', label: 'Blog', position: 'left' }, { to: 'v3', position: 'left', label: 'V3 Beta πŸš€', }, + { to: '/blog', label: 'Blog', position: 'left' }, { href: 'https://discord.gg/Ykhr738dUe', label: 'Discord', @@ -202,6 +202,23 @@ const config = { }, ], }, + { + title: 'FlatIcon Credits', + items: [ + { + label: 'Endure', + href: 'https://www.flaticon.com/free-icons/endure', + }, + { + label: 'Diagram by Kiranshastry', + href: 'https://www.flaticon.com/free-icons/diagram', + }, + { + href: 'https://www.flaticon.com/free-icons/database', + label: 'Database by kerismaker', + }, + ], + }, ], copyright: `Copyright Β© ${new Date().getFullYear()} ZenStack, Inc.`, }, diff --git a/src/pages/v3/_components/AICoding.tsx b/src/pages/v3/_components/AICoding.tsx index c6bffc1c..826b1b4e 100644 --- a/src/pages/v3/_components/AICoding.tsx +++ b/src/pages/v3/_components/AICoding.tsx @@ -10,8 +10,8 @@ const FeatureList: FeatureItem[] = [ img: '/img/access-control.png', description: ( <> - With data models, relations, validation rules, and access control policies all defined in one place, - LLMs can easily get a coherent understanding of the entire application. + When LLMs see a self-contained, non-ambiguous, and well-defined application model, their inference works + more efficiently and effectively. ), }, @@ -30,8 +30,8 @@ const FeatureList: FeatureItem[] = [ img: '/img/ai-friendly.png', description: ( <> - By deriving many crucial artifacts from the schema, ZenStack eliminates boilerplate and helps you - maintain a slim code base that is easier for AI to work with. + By deriving artifacts from the schema instead of implementing them, ZenStack helps you maintain a slim + code base that is easier for AI to digest. ), }, diff --git a/src/pages/v3/_components/ORM.tsx b/src/pages/v3/_components/ORM.tsx index 7422c01c..6b14aea2 100644 --- a/src/pages/v3/_components/ORM.tsx +++ b/src/pages/v3/_components/ORM.tsx @@ -8,7 +8,7 @@ export default function ORM(): JSX.Element {
Flexible and Awesomely Typed ORM

-
+
{`import { schema } from './zenstack'; import { ZenStackClient } from '@zenstackhq/runtime'; diff --git a/src/pages/v3/_components/SchemaLanguage.tsx b/src/pages/v3/_components/Schema.tsx similarity index 97% rename from src/pages/v3/_components/SchemaLanguage.tsx rename to src/pages/v3/_components/Schema.tsx index aa903cc8..dbd5cc17 100644 --- a/src/pages/v3/_components/SchemaLanguage.tsx +++ b/src/pages/v3/_components/Schema.tsx @@ -25,7 +25,7 @@ export default function SchemaLanguage(): JSX.Element { Migrating a Prisma schema is as simple as file renaming.
- + {`model User { id Int @id email String @unique @email // constraint and validation diff --git a/src/pages/v3/_components/Service.tsx b/src/pages/v3/_components/Service.tsx index d9bb323f..365fd950 100644 --- a/src/pages/v3/_components/Service.tsx +++ b/src/pages/v3/_components/Service.tsx @@ -42,7 +42,7 @@ export default function Service(): JSX.Element {
- + {`import { NextRequestHandler } from '@zenstackhq/server/next'; import { db } from './db'; // ZenStackClient instance import { getSessionUser } from './auth'; diff --git a/src/pages/v3/_components/ValueProps.tsx b/src/pages/v3/_components/ValueProps.tsx new file mode 100644 index 00000000..b6025df4 --- /dev/null +++ b/src/pages/v3/_components/ValueProps.tsx @@ -0,0 +1,56 @@ +type FeatureItem = { + title: string; + img: string; + description: JSX.Element; +}; + +const FeatureList: FeatureItem[] = [ + { + title: 'Coherent Schema', + img: '/img/diagram.png', + description: ( + <> + Simple schema language to capture the most important aspects of your application in one place: data and + security. + + ), + }, + { + title: 'Powerful ORM', + img: '/img/search.png', + description: ( + <>One-of-a-kind ORM that combines type-safety, query flexibility, and access control in one package. + ), + }, + { + title: 'Limitless Utility', + img: '/img/versatility.png', + description: ( + <>Deriving crucial artifacts that streamline development from backend APIs to frontend components. + ), + }, +]; + +function Proposition({ title, img, description }: FeatureItem) { + return ( +
+
+ {title} +
+
+

{title}

+

{description}

+
+
+ ); +} + +export default function ValueProps(): JSX.Element { + return ( +
+ {FeatureList.map((props, idx) => ( + + ))} +
+ ); +} diff --git a/src/pages/v3/index.tsx b/src/pages/v3/index.tsx index f766515e..0bcc3809 100644 --- a/src/pages/v3/index.tsx +++ b/src/pages/v3/index.tsx @@ -4,10 +4,10 @@ import Layout from '@theme/Layout'; import clsx from 'clsx'; import React from 'react'; import AICoding from './_components/AICoding'; -import Notes from './_components/Notes'; import ORM from './_components/ORM'; -import SchemaLanguage from './_components/SchemaLanguage'; +import SchemaLanguage from './_components/Schema'; import Service from './_components/Service'; +import ValueProps from './_components/ValueProps'; import styles from './index.module.css'; const description = `ZenStack v3 is a powerful data layer for modern TypeScript applications. It provides an intuitive data modeling language, a fully type-safe ORM, built-in access control and data validation, and automatic data query service that seamlessly integrates with popular frameworks like Next.js and Nuxt.`; @@ -20,7 +20,7 @@ function Header() {

- The Data Layer for Modern TypeScript Applications + Modern Data Layer for TypeScript Applications

@@ -32,8 +32,15 @@ function Header() { className="button button--secondary button--lg lg:text-2xl lg:px-8 lg:py-4" to="/docs/3.x" > - Get Started β†’ + Check V3 Docs β†’ + + Open Playground +

@@ -61,18 +68,22 @@ export default function Home(): JSX.Element {
- +
- +
- +
+ +
+ +
@@ -81,9 +92,9 @@ export default function Home(): JSX.Element {
-
+ {/*
-
+
*/}
); diff --git a/static/img/diagram.png b/static/img/diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..850806c0e446b37513b8c9a738222466e86a9bba GIT binary patch literal 7300 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 K*+LnU5C0GIN*1gD literal 0 HcmV?d00001 diff --git a/versioned_docs/version-3.x/orm/computed-fields.md b/versioned_docs/version-3.x/orm/computed-fields.md index 8fd46b88..561555e5 100644 --- a/versioned_docs/version-3.x/orm/computed-fields.md +++ b/versioned_docs/version-3.x/orm/computed-fields.md @@ -18,7 +18,7 @@ Computed fields are "virtual" fields that do not physically exist in the databas ## Defining Computed Fields -Defining a computed fields involves two steps. First, add the field in the ZModel schema to a model and annotate it with an extra `@computed` attribute. +Defining a computed field involves two steps. First, add the field in the ZModel schema to a model and annotate it with the `@computed` attribute. ```zmodel model User { From 135684288a1c1cb201be3b11ce1b3ffc2dc43aa9 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Fri, 29 Aug 2025 19:56:30 +0800 Subject: [PATCH 44/51] update responsiveness --- src/css/custom.css | 22 ++++++++++ src/pages/v3/_components/AICoding.tsx | 2 +- src/pages/v3/_components/ORM.tsx | 14 +++---- src/pages/v3/_components/Schema.tsx | 12 +++--- src/pages/v3/_components/Service.tsx | 60 ++++++++++++++------------- src/pages/v3/index.tsx | 8 ++-- 6 files changed, 71 insertions(+), 47 deletions(-) diff --git a/src/css/custom.css b/src/css/custom.css index ae6d471d..a8aa4648 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -68,3 +68,25 @@ right: 0; pointer-events: mouse; } + +@media (max-width: 1200px) { + .navbar__items--right, + .navbar__items--left { + display: none; + } + + /* force display of right items in the toggle menu */ + .navbar__item.navbar__item--right { + display: block !important; + } + + .navbar__toggle { + display: inherit; + } +} + +@media (min-width: 1201px) { + .navbar__toggle { + display: none; + } +} diff --git a/src/pages/v3/_components/AICoding.tsx b/src/pages/v3/_components/AICoding.tsx index 826b1b4e..98059708 100644 --- a/src/pages/v3/_components/AICoding.tsx +++ b/src/pages/v3/_components/AICoding.tsx @@ -55,7 +55,7 @@ export default function AICoding(): JSX.Element { return (
-

+

Perfect Match for AI-Assisted Programming

diff --git a/src/pages/v3/_components/ORM.tsx b/src/pages/v3/_components/ORM.tsx index 6b14aea2..94264959 100644 --- a/src/pages/v3/_components/ORM.tsx +++ b/src/pages/v3/_components/ORM.tsx @@ -5,11 +5,11 @@ export default function ORM(): JSX.Element {

-
Flexible and Awesomely Typed ORM
+
Flexible and Awesomely Typed ORM

- + {`import { schema } from './zenstack'; import { ZenStackClient } from '@zenstackhq/runtime'; @@ -31,11 +31,11 @@ const userPostJoin = await db .execute(); `} -
- +
+

An ORM is derived from the schema that gives you - -
    +

+
  • πŸ”‹ High-level ORM query API
  • πŸ”‹ Low-level SQL query builder API
  • πŸ”‹ Access control enforcement
  • @@ -43,7 +43,7 @@ const userPostJoin = await db
  • πŸ”‹ Computed fields and custom procedures
  • πŸ”‹ Plugin system for tapping into various lifecycle events
- + ZenStack's ORM is built on top of the awesome Kysely SQL query builder. Its query API is compatible with that of{' '} Prisma Client, so migrating an diff --git a/src/pages/v3/_components/Schema.tsx b/src/pages/v3/_components/Schema.tsx index dbd5cc17..918aaaad 100644 --- a/src/pages/v3/_components/Schema.tsx +++ b/src/pages/v3/_components/Schema.tsx @@ -5,13 +5,13 @@ export default function SchemaLanguage(): JSX.Element {

-
Intuitive and Expressive Data Modeling
+
Intuitive and Expressive Data Modeling

-
- The modeling language allows you to -
    +
    +

    The modeling language allows you to

    +
    • βœ… Define data models and relations
    • βœ… Define access control policies
    • βœ… Express data validation rules
    • @@ -19,13 +19,13 @@ export default function SchemaLanguage(): JSX.Element {
    • βœ… Add custom attributes and functions to introduce custom semantics
    • βœ… Implement custom code generators
    - + The schema language is a superset of{' '} Prisma Schema Language. Migrating a Prisma schema is as simple as file renaming.
    - + {`model User { id Int @id email String @unique @email // constraint and validation diff --git a/src/pages/v3/_components/Service.tsx b/src/pages/v3/_components/Service.tsx index 365fd950..7fe1a8ee 100644 --- a/src/pages/v3/_components/Service.tsx +++ b/src/pages/v3/_components/Service.tsx @@ -14,11 +14,11 @@ export default function Service(): JSX.Element {
-
- +
+

Thanks to the ORM's built-in access control, you get an HTTP query service for free - -
    +

+
  • πŸš€ Fully mirrors the ORM API
  • πŸš€ Seamlessly integrates with popular frameworks
  • πŸš€ Works with any authentication solution
  • @@ -27,7 +27,7 @@ export default function Service(): JSX.Element {
  • πŸš€ Highly customizable
- +

Since the ORM is protected with access control, ZenStack can directly map it to an HTTP service. ZenStack provides out-of-the-box integrations with popular frameworks including @@ -40,10 +40,11 @@ export default function Service(): JSX.Element {

- - - - {`import { NextRequestHandler } from '@zenstackhq/server/next'; +
+ + + + {`import { NextRequestHandler } from '@zenstackhq/server/next'; import { db } from './db'; // ZenStackClient instance import { getSessionUser } from './auth'; @@ -68,39 +69,40 @@ export { handler as PATCH, handler as DELETE, }; -`} - - - - - {`import { schema } from './zenstack'; + `} + + + + + {`import { schema } from './zenstack'; import { useQueryHooks } from '@zenstackhq/query/react'; export function UserPosts({ userId }: { userId: number }) { // use auto-generated hook to query user with posts const { user: userHooks } = useQueryHooks(schema); const { data, isLoading } = userHooks.useFindUnique({ - where: { id: userId }, - include: { posts: true } + where: { id: userId }, + include: { posts: true } }); if (isLoading) return
Loading...
; return ( -
-

{data?.email}'s Posts

-
    - {data?.posts.map((post) => ( -
  • {post.title}
  • - ))} -
-
+
+

{data?.email}'s Posts

+
    + {data?.posts.map((post) => ( +
  • {post.title}
  • + ))} +
+
); } -`} -
-
-
+ `} + + + +
); diff --git a/src/pages/v3/index.tsx b/src/pages/v3/index.tsx index 0bcc3809..f6e10a41 100644 --- a/src/pages/v3/index.tsx +++ b/src/pages/v3/index.tsx @@ -18,16 +18,16 @@ function Header() {
-

+

Modern Data Layer for TypeScript Applications

-

+

Intuitive data modeling, type-safe ORM, built-in access control, automatic query services, and more.

-
+
Open Playground From 99c6b5acf7f6695162d5c134404bffdb587bb2b1 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Fri, 29 Aug 2025 20:00:52 +0800 Subject: [PATCH 45/51] update --- src/css/custom.css | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/css/custom.css b/src/css/custom.css index a8aa4648..3559aeea 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -75,11 +75,6 @@ display: none; } - /* force display of right items in the toggle menu */ - .navbar__item.navbar__item--right { - display: block !important; - } - .navbar__toggle { display: inherit; } From 0fdcf9cbc9700c8b4bfb5b50fa0ec9a474c4ae2d Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Sat, 30 Aug 2025 20:55:23 +0800 Subject: [PATCH 46/51] update --- src/components/ValueProposition.tsx | 6 ++-- src/pages/v3/_components/AICoding.tsx | 4 +-- src/pages/v3/_components/Notes.tsx | 10 ++++--- src/pages/v3/_components/ORM.tsx | 13 +++++++-- src/pages/v3/_components/Schema.tsx | 2 +- src/pages/v3/_components/Service.tsx | 6 ++-- src/pages/v3/_components/ValueProps.tsx | 2 +- src/pages/v3/index.module.css | 6 ---- .../version-3.x/modeling/polymorphism.md | 4 +-- versioned_docs/version-3.x/orm/quick-start.md | 4 +-- versioned_docs/version-3.x/prerequisite.md | 12 +++++++- versioned_docs/version-3.x/reference/cli.md | 27 +++++++++--------- versioned_docs/version-3.x/vscode.png | Bin 434009 -> 834577 bytes 13 files changed, 54 insertions(+), 42 deletions(-) diff --git a/src/components/ValueProposition.tsx b/src/components/ValueProposition.tsx index c58a8aef..2593baee 100644 --- a/src/components/ValueProposition.tsx +++ b/src/components/ValueProposition.tsx @@ -33,8 +33,8 @@ const FeatureList: FeatureItem[] = [ img: '/img/ai-friendly.png', description: ( <> - Schema-first reduces code complexity, helping AI understand better with fewer hallucinations. - Schema serves as a single source of truth for AI integration. + Schema-first reduces code complexity, helping AI understand better with fewer hallucinations. Schema + serves as a single source of truth for AI integration. ), }, @@ -47,7 +47,7 @@ function Proposition({ title, img, description }: FeatureItem) { {title}
-

{title}

+

{title}

{description}

diff --git a/src/pages/v3/_components/AICoding.tsx b/src/pages/v3/_components/AICoding.tsx index 98059708..aad73f88 100644 --- a/src/pages/v3/_components/AICoding.tsx +++ b/src/pages/v3/_components/AICoding.tsx @@ -6,7 +6,7 @@ type FeatureItem = { const FeatureList: FeatureItem[] = [ { - title: 'Coherent Application Model', + title: 'Single Source of Truth', img: '/img/access-control.png', description: ( <> @@ -44,7 +44,7 @@ function Proposition({ title, img, description }: FeatureItem) { {title}
-

{title}

+

{title}

{description}

diff --git a/src/pages/v3/_components/Notes.tsx b/src/pages/v3/_components/Notes.tsx index 3acc64f0..6bcfbb83 100644 --- a/src/pages/v3/_components/Notes.tsx +++ b/src/pages/v3/_components/Notes.tsx @@ -1,18 +1,20 @@ +import Link from '@docusaurus/Link'; + export default function Notes(): JSX.Element { return (

-
Notes to V2 Users
+ Notes to V2 Users

ZenStack V3 has made the bold decision to remove Prisma as a runtime dependency and implement its - own ORM infrastructure on top of Kysely. Albeit the cost of such a + own ORM infrastructure on top of Kysely. Albeit the cost of such a big refactor, we believe this is the right move to gain the flexibility needed to achieve the - project's vision. Please read this blog post for more thoughts - behind the changes. + project's vision. Please read this blog post for more + thoughts behind the changes.
diff --git a/src/pages/v3/_components/ORM.tsx b/src/pages/v3/_components/ORM.tsx index 94264959..56a1d1ad 100644 --- a/src/pages/v3/_components/ORM.tsx +++ b/src/pages/v3/_components/ORM.tsx @@ -11,12 +11,19 @@ export default function ORM(): JSX.Element {
{`import { schema } from './zenstack'; -import { ZenStackClient } from '@zenstackhq/runtime'; +import { + ZenStackClient, + AccessControlPlugin +} from '@zenstackhq/runtime'; -const db = new ZenStackClient(schema, { ... }); +const db = new ZenStackClient(schema, { ... }) + // install access control plugin to enforce policies + .$use(new AccessControlPlugin()) + // set current user context + .$setAuth(...); // high-level query API -const usersWithPosts = await db.user.findUnique({ +const userWithPosts = await db.user.findUnique({ where: { id: userId }, include: { posts: true } }); diff --git a/src/pages/v3/_components/Schema.tsx b/src/pages/v3/_components/Schema.tsx index 918aaaad..04fc4a59 100644 --- a/src/pages/v3/_components/Schema.tsx +++ b/src/pages/v3/_components/Schema.tsx @@ -39,7 +39,7 @@ export default function SchemaLanguage(): JSX.Element { } model Post { - id Int + id Int @id title String @length(1, 255) published Boolean @default(false) author User @relation(fields: [authorId], references: [id]) diff --git a/src/pages/v3/_components/Service.tsx b/src/pages/v3/_components/Service.tsx index 7fe1a8ee..ad14b2d3 100644 --- a/src/pages/v3/_components/Service.tsx +++ b/src/pages/v3/_components/Service.tsx @@ -27,7 +27,7 @@ export default function Service(): JSX.Element {
  • πŸš€ Highly customizable
  • - +

    Since the ORM is protected with access control, ZenStack can directly map it to an HTTP service. ZenStack provides out-of-the-box integrations with popular frameworks including @@ -38,7 +38,7 @@ export default function Service(): JSX.Element { derived from the schema, allowing you to make type-safe queries to the service without writing a single line of code.

    - +
    @@ -64,7 +64,7 @@ const handler = NextRequestHandler({ getClient }); export { handler as GET, - handler as PUT + handler as PUT, handler as POST, handler as PATCH, handler as DELETE, diff --git a/src/pages/v3/_components/ValueProps.tsx b/src/pages/v3/_components/ValueProps.tsx index b6025df4..555ecdad 100644 --- a/src/pages/v3/_components/ValueProps.tsx +++ b/src/pages/v3/_components/ValueProps.tsx @@ -38,7 +38,7 @@ function Proposition({ title, img, description }: FeatureItem) { {title}
    -

    {title}

    +

    {title}

    {description}

    diff --git a/src/pages/v3/index.module.css b/src/pages/v3/index.module.css index 228eb5de..b3332046 100644 --- a/src/pages/v3/index.module.css +++ b/src/pages/v3/index.module.css @@ -10,12 +10,6 @@ overflow: hidden !important; } -@media screen and (min-width: 1200px) { - .bannerCode code { - font-size: 120% !important; - } -} - @media screen and (max-width: 996px) { .heroBanner { padding-top: 4rem !important; diff --git a/versioned_docs/version-3.x/modeling/polymorphism.md b/versioned_docs/version-3.x/modeling/polymorphism.md index 8e1761ab..9e36f0e2 100644 --- a/versioned_docs/version-3.x/modeling/polymorphism.md +++ b/versioned_docs/version-3.x/modeling/polymorphism.md @@ -76,8 +76,8 @@ erDiagram } Content { id Int PK - name String - createdAt Date + name String + createdAt DateTime ownerId Int FK type String } diff --git a/versioned_docs/version-3.x/orm/quick-start.md b/versioned_docs/version-3.x/orm/quick-start.md index 46234ff8..52ded564 100644 --- a/versioned_docs/version-3.x/orm/quick-start.md +++ b/versioned_docs/version-3.x/orm/quick-start.md @@ -24,9 +24,7 @@ Run the following command to scaffold a new project with a pre-configured minima npm create zenstack@next my-project ``` -Or simply use the interactive playground to experience it inside the browser. - - +Or simply use the [interactive playground](https://stackblitz.com/~/github.com/zenstackhq/v3-doc-quick-start) to experience it inside the browser. ## 2. Adding to an existing project diff --git a/versioned_docs/version-3.x/prerequisite.md b/versioned_docs/version-3.x/prerequisite.md index 5aec199d..5d9bd1bb 100644 --- a/versioned_docs/version-3.x/prerequisite.md +++ b/versioned_docs/version-3.x/prerequisite.md @@ -14,8 +14,18 @@ TypeScript v5.8.0 or above. ## IDE Extension -If you use VSCode, please install the [ZenStack VSCode Extension](https://marketplace.visualstudio.com/items?itemName=zenstack.zenstack) for syntax highlighting, auto-completion, and error reporting. Make sure you switch to the prerelease version that's compatible with v3. +If you use VSCode, please install the [ZenStack V3 VSCode Extension](https://marketplace.visualstudio.com/items?itemName=zenstack.zenstack-v3) for syntax highlighting, auto-completion, and error reporting. ![VSCode Extension](./vscode.png) +If you use both ZenStack v2 and v3 in different projects, you can install the original [ZenStack VSCode Extension](https://marketplace.visualstudio.com/items?itemName=zenstack.zenstack) side-by-side with the v3 extension. The two extensions have different language ids (v2: `zmodel`, v3: `zmodel-v3`) but handle the same `.zmodel` file extension. To avoid conflicts, make sure you specify the language id explicitly in the `.vscode/settings.json` file in your project: + +```json +{ + "files.associations": { + "*.zmodel": "zmodel-v3" // use "zmodel" for ZenStack v2 projects + } +} +``` + Other IDEs are not supported at this time. diff --git a/versioned_docs/version-3.x/reference/cli.md b/versioned_docs/version-3.x/reference/cli.md index 0e4a97f9..0ae0dc77 100644 --- a/versioned_docs/version-3.x/reference/cli.md +++ b/versioned_docs/version-3.x/reference/cli.md @@ -9,7 +9,7 @@ sidebar_label: CLI ## Usage ``` -zenstack [options] [command] +zen [options] [command] ΞΆ ZenStack is the data layer for modern TypeScript apps. @@ -36,7 +36,7 @@ Commands: Run code generation plugins. ```bash -Usage: zenstack generate [options] +Usage: zen generate [options] Run code generation plugins. @@ -44,6 +44,7 @@ Options: --schema schema file (with extension .zmodel). Defaults to "zenstack/schema.zmodel" unless specified in package.json. -o, --output default output directory for code generation + --silent suppress all output except errors (default: false) -h, --help display help for command ``` @@ -52,7 +53,7 @@ Options: Run database schema migration related tasks. ```bash -Usage: zenstack migrate [options] [command] +Usage: zen migrate [options] [command] Run database schema migration related tasks. @@ -77,7 +78,7 @@ For development only. Do not use this command in production. ::: ```bash -Usage: zenstack migrate dev [options] +Usage: zen migrate dev [options] Create a migration from changes in schema and apply it to the database. @@ -99,7 +100,7 @@ Never run this command in production. It will drop all data in the database. ::: ```bash -Usage: zenstack migrate reset [options] +Usage: zen migrate reset [options] Reset your database and apply all migrations, all data will be lost. @@ -116,7 +117,7 @@ Options: Deploy your pending migrations to your production/staging database. ```bash -Usage: zenstack migrate deploy [options] +Usage: zen migrate deploy [options] Deploy your pending migrations to your production/staging database. @@ -132,7 +133,7 @@ Options: Check the status of your database migrations. ```bash -Usage: zenstack migrate status [options] +Usage: zen migrate status [options] Check the status of your database migrations. @@ -148,7 +149,7 @@ Options: Resolve issues with database migrations in deployment databases. ```bash -Usage: zenstack migrate resolve [options] +Usage: zen migrate resolve [options] Resolve issues with database migrations in deployment databases. @@ -166,7 +167,7 @@ Options: Manage your database schema during development. ```bash -Usage: zenstack db [options] [command] +Usage: zen db [options] [command] Manage your database schema during development. @@ -183,7 +184,7 @@ Commands: Push the state from your schema to your database. ```bash -Usage: zenstack db push [options] +Usage: zen db push [options] Push the state from your schema to your database. @@ -200,7 +201,7 @@ Options: Get information of installed ZenStack packages. ```bash -Usage: zenstack info [options] [path] +Usage: zen info [options] [path] Get information of installed ZenStack. @@ -216,7 +217,7 @@ Options: Initialize an existing project for ZenStack. ```bash -Usage: zenstack init [options] [path] +Usage: zen init [options] [path] Initialize an existing project for ZenStack. @@ -232,7 +233,7 @@ Options: Check a ZModel schema for syntax or semantic errors. ```bash -Usage: zenstack check [options] +Usage: zen check [options] Check a ZModel schema for syntax or semantic errors. diff --git a/versioned_docs/version-3.x/vscode.png b/versioned_docs/version-3.x/vscode.png index 35b10df9e840d3c0b2757894a6ec7b039dca190c..38dbf54f3545ac7e4c96e1c5a221115e88dbddae 100644 GIT binary patch literal 834577 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

    q0T+s?-fz*~St4cn?cW_6!@H)Vj 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�Z7t@v+Xy=U3 zQW`x-eKSM6!L%mcAZAGa*vGi9e1AG?;6&3=wVDkF2{{ZK8{N=W3%zogs7t{e9}3GQ zqcHE9UiDJaEygIntj4s}DW3ri>bd<%FjF-Mc3w6@s8M7PI_rr99Wf>&keho8(Jk1I zHn~2?e%zJ@XOS@TAxoW}ju&qLf-m3D_)dRf1>_5h`q=d@3_QN{8-Su#RvSXLFf?|M zmnf`|kQlZ=akd!(YM=E1RI9)#-k`PEmGc*?@=2@-_E-o zjpgTaNa!f*+j0gkaHe9vKk7n+GE*t#3laY6=2B_Fpp5h~jrK5j2%pr@`OSOD0jW%@ z@~`xoGcl0XS#>`q5@zQ*tNg~k9VE*ygXykBT+A`nL(!b}S0tXNH>PO>)vr3MtORze zt*j|W0CR}L9ccoEhopl%v~N}E8&ThDz1SafnJDG|CU17nUwr2V?PUBdc(sNZmUFL) zJffbe8379#!MsXCJCn_``MAOGc_iVq5Dq?*SQh!2b}p=>U+uhz7npp9u33m{|5a9N zcscVfKKG9Ysn`tORP5KM34v%wHc}3J@P#e%m~JLn=A9N%_<`W6&dWDn*=c)i_EvNB zqQXb)LNi{hMSt?W2K(*og`U3+o9`~-VKQDPlU5i z2qlGAVWgwnsi{M#*mdlKA-PCV)L{QVcqcLM56)k?_Ku3?uh&}!8fd=Dj8jHhuUPM>-7Q+AofnD>H{yo3r*0fWm`L4G9doQ}AXxtefW_(v zc0^ozBWd!m0IDC~!tG37`t+1iwWLuQc<$t*(YER4t5Y31*u9ds1v<`>e&ot;1cJqF z10<7X3G0dIW*J7On^g}|4lUYOV0TLNjllQQ#?;KDe8~5IC{q0`a@F#;$kpE>S2Rhm z{|!~FzeTS87PUL_^PzCUYYZbx zABaIT%-6{M=3&bVh1ekCtyfBMLxY`XQR?HK*Q3qsw)_njO7qP1?fgx9b;4qG z}Kcj>MK@6yBP!rh58Jww7b3*1D=8E`j z)j{R1l4=N1w-KAP24<{P*Ukzdt0~h+@CB8{aj!*%*sV+?s3SJjlk9<^r*~9Wk<`lp z(im!QD)b$yBg7G*d#dyIBrxlYkjGE#MaolX0bvROz}S`y}R zkuQ}9Z6F}2Jqtv=GG$#)0z(kNc#`4FrpNJd;vfkPkvgEwSe(Ps7Jd!ckL2tb>YV%K z@g9`$!A%h^zk0dmQjHnxoC`xz9(Qzu%iX(&lkm!Tg)Lm%yMz`obfYtV0;<8{Ymi8Q z+;I;wpe_Ma0vN-B8T@XF+J3j}(eeE%H597xnV2Gc5mucdWUP@hlI&4?!%6lk zOWl65N&7ywF^AeK>V7tK`ZvgK!ZaX`f6q+5$7+Z{Wi#SpdkXmw))z+1Svh&}tT`raT71Ax&790sBIvmrD z9)J11h5NcGD|ZfMMxV~89c3qU{oq*D{1CDqaX4<+!_F8z@V=LhB3-i>C&R2+04671 zIgyTfahQZ@38n2Ty}gvz*v{06d40w?!>Wi~i7ELG?6G5x_(`!fkv4CLb$&)&Y`Rwx z@Nel5;!+OM@_GB>G9H_AiB#!3w2f(-MAT&^Oxvk@3)#s8sECtn#}x+^K^6xR#7}C0 z6|cRWi!yvB&SiAc55Im@;a+@W+oC*3Z3O6skXS+z5?Klqbz|krRp|v4>#@ha%-PRC zhIs6iUyO0U*xXB1@=GKz;|9O*hT*b%8m4Xc#w*_yH|!SS#Z!dkyCGC6PZRzGF512G zF|UgYLohJco8gMK*b&$8qwYe)rLC|KL^O5HU$gdvZ&Hk0tFd6iIMjk8DRZtBIoaxX*JFWGi zQ_bpU_3EG0G6MLDk~&I$OBH0+?LRQbRNsKDvbrt4IZ1}hOZ+&4FWqL@FmKRY#eYkE@*7#JA!vU%_Gngs)%yqGhOWX>|LB( zX-AcUKu^~Wtd4E~OV`YG%Z{l4x}OhuDA9@k)q9ta=5 zR*h~+n}|&?SMmq%yxkIYlVGWXWR|EUrmI=SHs{vBPn2i@OM~E`9}IwdpvPkr1Z-;q zfqpyM!1t|`oR$ICGP#pV+V$9N49m_VmMUe)87`_>AHWA^ZBdNfs=z+*D;RVammXsU zR;XA4%6E58CL3o1HSTS5SQ1llWr}+*I*@gQ#9=^Gf$~Aud#h;;TYJBMSP9-{y+Z+s zox|^*$rC0?z$Q3oE%d2Geb4>^Ju=<`R=mIuzu7fUM~)od#x9>8cFB5Q+zKDw{63ix zXmQ$}o+e=dI;sExjOU<4s2!3M^a4LVv$8k<^Mk)A9C>=_s5;S|H!Gns(PyfwJ-_G^ zIqZvI1w-Of`=9MFM^*IhjmB?iwyj3v!yEFw8%3(z&>DLIJpWlOn_H8qVKFra_Zzqp>Wv_LPGB98}H{&bI=A$$mMFAZUcQe~n36 zTY-Y8yx=+k8$5`rqrC6liRtL3j&<{4f7sS-0QzWCFgr7-^;5X;2S^@Q^lb&)e2rRl zU0%a||6JNasHm1F9z3|6FMvMDUk~%;AH3-JKT&(BfP6ERtJ5O9z^jf=@cJOGS~t8Po@^Kc$d6W^i*G8#?ay z7qo#*Z6s!oi~;;eZuKJ{se9d|H2@HHuNx2CR9)rADAjsz;Rt{;ILuTLCo(ZJUXva( z33a9e<{&`2iRFPhz}bsr|8H>=oj$cM#e)MM_n5B55?L_V08wZy4%Xr2xT_|%R& zfrkAK;6+%fc=YoEJFIASz3t1Tt6eJ3+w8*%po8$ME_5Oi;RD6jp6t5GMI~~c?*mK+ z9V# zww!@I0uy#UI%$nMu~tXPq(=F~d6Us2Zjw8M5=vA@8>o#)!}QMww?P$s0~-dEZ);#q z2b1M`$WF}Q&tG2A+>1o{rF+ZW*ZXWS5E|^jxRWE|b|NIrylU-DPhzLh)OQ`G0Njko zdX$3^coal_JY&LZmXjXAzcW2YPd)-iV(CHcGUmGu9hGCn)o}U0c7UJ6*`s!x7 zv&PIvPBS~9bDdhT>)kdG(QM|xZ^aLMNs4>qzUlH30!R7km)8KZ^|cLgZlU?4A6@jD;)n;(b1M=s46>Z?}Icr_#AHdy$Z6h;Tlu+xIyV-A?ocQ7o@o!Z^ zL~IawA#T?}gTb^8047_(+4g{2Kk9H03$)JC=Dc2_zvHH`0ZX|db{_A%|HFqWHw##6 z;HER5@_!B-tqd|>n6c|Z?PjCOC_5GbXVKr~1DoY7GHlT9-#T1AB{Kq$K@f6p<@i|- zdW*fb-n8vC4`+JipFd9;L3Y*mqPNQ;HMR$5dDC{<;Ax(Ofp3z}H~hHcC;3{CWE6_@ z--wn#1`HbvU-DVjW5V7A?By)K6wa9frE5tbh;2bYP&!%DafogJZGV6?t$v|10V0LG!uI$+hfste(;?o$vLSc035uN zu~&<4T{@IKu9m)5`AO1wbuEifl1^U81)CkD4w;MDEN`uLc{@VZSygPX&}aS`cp}f@ zFUlh}61Ka>bK%+#0R{_hc#~TtI$l~x4v0RS^Q^pID3{DOoDJ`HhGvYk#8+gK%Xx~} zK7QS2+WLIHJ1bA|{Ju_%0A0b%eeXy|P;-l>*6=3pp@+>1EHHR*>A-o5$3Th-oIN4uJJk ze9#2`PCZqreumJA+l(CuT#37I%Q$Gx6!b}A0Usa&{n`VR-)`So=(+e^NvVD5YwY zVxdDmPa!Ra(PiyrU=AF{P=~plwzH`#bEF5Xx|NMs;HWRX^IJAD)Qcj@Y%MLJT}p(= zz{H^P8bJzV!BeNF>38hObLb5g3EbvYTp$^PC7GY!^(22wsuRb?Y<$d{i&id${C_-g zad69YkM(qcr9Cv+fy8Zg z;=ITv?_{u+Ti5et_I~!h-&4|My=0VIGRK^PqsuLjjjn0OqBipjvHtyFJ3;X)K$aL37=H9!CTp9$Lhs+&+w+C_f~f2|;boUQdd-E@HLd6KW%j zHbN1!345h!Ct~q2e5r{0%qD6ot;7?-IJH!ZrM%Yuszm;v5=tkA2oM|AwJv&9};7Wji2hk zQpA?$h9R>tMEw*gsRU>o#FwY-2|7#qd+tfNMRubGJ|=bH?lpI)T@x~I+k@a4Y;d6Z zzBPD-8W4c2�T^tX~gH(&pbl^G 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