├── .env
├── .eslintrc.cjs
├── .gitignore
├── .vscode
└── settings.json
├── LICENSE
├── README.md
├── next.config.js
├── package-lock.json
├── package.json
├── postcss.config.cjs
├── prettier.config.js
├── prisma
└── schema.prisma
├── public
└── favicon.ico
├── schema.zmodel
├── src
├── app
│ ├── api
│ │ ├── auth
│ │ │ └── [...nextauth]
│ │ │ │ └── route.ts
│ │ └── model
│ │ │ └── [...path]
│ │ │ └── route.ts
│ ├── layout.tsx
│ ├── page.tsx
│ ├── providers.tsx
│ ├── signin
│ │ └── page.tsx
│ └── signup
│ │ └── page.tsx
├── env.js
├── lib
│ └── hooks
│ │ ├── __model_meta.ts
│ │ ├── account.ts
│ │ ├── index.ts
│ │ ├── post.ts
│ │ ├── session.ts
│ │ ├── user.ts
│ │ └── verification-token.ts
├── server
│ ├── auth.ts
│ └── db.ts
└── styles
│ └── globals.css
├── tailwind.config.ts
└── tsconfig.json
/.env:
--------------------------------------------------------------------------------
1 | # When adding additional environment variables, the schema in "/src/env.js"
2 | # should be updated accordingly.
3 |
4 | # Prisma
5 | # https://www.prisma.io/docs/reference/database-reference/connection-urls#env
6 | DATABASE_URL="file:./db.sqlite"
7 |
8 | # Next Auth
9 | # You can generate a new secret on the command line with:
10 | # openssl rand -base64 32
11 | # https://next-auth.js.org/configuration/options#secret
12 | # NEXTAUTH_SECRET=""
13 | NEXTAUTH_URL="http://localhost:3000"
14 |
15 | NEXTAUTH_SECRET=abc123
--------------------------------------------------------------------------------
/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | /** @type {import("eslint").Linter.Config} */
2 | const config = {
3 | parser: "@typescript-eslint/parser",
4 | parserOptions: {
5 | project: true,
6 | },
7 | plugins: ["@typescript-eslint"],
8 | extends: [
9 | "next/core-web-vitals",
10 | "plugin:@typescript-eslint/recommended-type-checked",
11 | "plugin:@typescript-eslint/stylistic-type-checked",
12 | ],
13 | rules: {
14 | // These opinionated rules are enabled in stylistic-type-checked above.
15 | // Feel free to reconfigure them to your own preference.
16 | "@typescript-eslint/array-type": "off",
17 | "@typescript-eslint/consistent-type-definitions": "off",
18 |
19 | "@typescript-eslint/consistent-type-imports": [
20 | "warn",
21 | {
22 | prefer: "type-imports",
23 | fixStyle: "inline-type-imports",
24 | },
25 | ],
26 | "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }],
27 | "@typescript-eslint/require-await": "off",
28 | "@typescript-eslint/no-misused-promises": [
29 | "error",
30 | {
31 | checksVoidReturn: { attributes: false },
32 | },
33 | ],
34 | },
35 | };
36 |
37 | module.exports = config;
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # database
12 | /prisma/db.sqlite
13 | /prisma/db.sqlite-journal
14 |
15 | # next.js
16 | /.next/
17 | /out/
18 | next-env.d.ts
19 |
20 | # production
21 | /build
22 |
23 | # misc
24 | .DS_Store
25 | *.pem
26 |
27 | # debug
28 | npm-debug.log*
29 | yarn-debug.log*
30 | yarn-error.log*
31 | .pnpm-debug.log*
32 |
33 | # local env files
34 | # do not commit any .env files to git, except for the .env.example file. https://create.t3.gg/en/usage/env-variables#using-environment-variables
35 | .env
36 | .env*.local
37 |
38 | # vercel
39 | .vercel
40 |
41 | # typescript
42 | *.tsbuildinfo
43 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "typescript.tsdk": "node_modules/typescript/lib"
3 | }
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 ZenStack
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ZenStack Next.js Tutorial Project
2 |
3 | This is a sample project for demonstrating how to use ZenStack in a Next.js project (v14 with the new "app" router).
4 |
5 | See documentation [here](https://zenstack.dev/docs/quick-start/next-app-router).
6 |
7 | To run the project:
8 |
9 | ```
10 | npm run build
11 | npm run dev
12 | ```
13 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful
3 | * for Docker builds.
4 | */
5 | await import("./src/env.js");
6 |
7 | /** @type {import("next").NextConfig} */
8 | const config = {};
9 |
10 | export default config;
11 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "my-blog-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "type": "module",
6 | "scripts": {
7 | "generate": "zenstack generate && prisma db push",
8 | "build": "npm run generate && next build",
9 | "dev": "next dev",
10 | "postinstall": "prisma generate",
11 | "lint": "next lint",
12 | "start": "next start",
13 | "package-clean": "npm rm @zenstackhq/runtime @zenstackhq/server zenstack @zenstackhq/tanstack-query",
14 | "up": "npm run package-clean && npm i --save-exact @zenstackhq/runtime@latest @zenstackhq/server@latest && npm i -D --save-exact zenstack@latest @zenstackhq/tanstack-query@latest"
15 | },
16 | "dependencies": {
17 | "@auth/prisma-adapter": "^1.4.0",
18 | "@prisma/client": "^5.21.1",
19 | "@t3-oss/env-nextjs": "^0.9.2",
20 | "@tanstack/react-query": "^5.24.1",
21 | "@zenstackhq/runtime": "2.7.4",
22 | "@zenstackhq/server": "2.7.4",
23 | "next": "^15.0.1",
24 | "next-auth": "^4.24.10",
25 | "react": "18.2.0",
26 | "react-dom": "18.2.0",
27 | "zod": "^3.22.4"
28 | },
29 | "devDependencies": {
30 | "@types/bcryptjs": "^2.4.6",
31 | "@types/eslint": "^8.56.2",
32 | "@types/node": "^20.11.20",
33 | "@types/react": "^18.2.57",
34 | "@types/react-dom": "^18.2.19",
35 | "@typescript-eslint/eslint-plugin": "^7.6.0",
36 | "@typescript-eslint/parser": "^7.6.0",
37 | "@zenstackhq/tanstack-query": "2.7.4",
38 | "eslint": "^8.57.0",
39 | "eslint-config-next": "^14.1.4",
40 | "postcss": "^8.4.34",
41 | "prettier": "^3.2.5",
42 | "prettier-plugin-tailwindcss": "^0.5.11",
43 | "prisma": "^5.21.1",
44 | "tailwindcss": "^3.4.1",
45 | "typescript": "^5.4.5",
46 | "zenstack": "2.7.4"
47 | },
48 | "ct3aMetadata": {
49 | "initVersion": "7.28.0"
50 | },
51 | "packageManager": "npm@10.2.3"
52 | }
53 |
--------------------------------------------------------------------------------
/postcss.config.cjs:
--------------------------------------------------------------------------------
1 | const config = {
2 | plugins: {
3 | tailwindcss: {},
4 | },
5 | };
6 |
7 | module.exports = config;
8 |
--------------------------------------------------------------------------------
/prettier.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('prettier').Config & import('prettier-plugin-tailwindcss').PluginOptions} */
2 | const config = {
3 | plugins: ["prettier-plugin-tailwindcss"],
4 | };
5 |
6 | export default config;
7 |
--------------------------------------------------------------------------------
/prisma/schema.prisma:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////////////////////////////
2 | // DO NOT MODIFY THIS FILE //
3 | // This file is automatically generated by ZenStack CLI and should not be manually updated. //
4 | //////////////////////////////////////////////////////////////////////////////////////////////
5 |
6 | datasource db {
7 | provider = "sqlite"
8 | url = env("DATABASE_URL")
9 | }
10 |
11 | generator client {
12 | provider = "prisma-client-js"
13 | }
14 |
15 | /// @@allow('all', auth() == createdBy)
16 | /// @@allow('read', auth() != null && published)
17 | model Post {
18 | id Int @id() @default(autoincrement())
19 | name String
20 | createdAt DateTime @default(now())
21 | updatedAt DateTime @updatedAt()
22 | published Boolean @default(false)
23 | createdBy User @relation(fields: [createdById], references: [id])
24 | createdById String
25 |
26 | @@index([name])
27 | }
28 |
29 | model Account {
30 | id String @id() @default(cuid())
31 | userId String
32 | type String
33 | provider String
34 | providerAccountId String
35 | refresh_token String?
36 | access_token String?
37 | expires_at Int?
38 | token_type String?
39 | scope String?
40 | id_token String?
41 | session_state String?
42 | user User @relation(fields: [userId], references: [id], onDelete: Cascade)
43 |
44 | @@unique([provider, providerAccountId])
45 | }
46 |
47 | model Session {
48 | id String @id() @default(cuid())
49 | sessionToken String @unique()
50 | userId String
51 | expires DateTime
52 | user User @relation(fields: [userId], references: [id], onDelete: Cascade)
53 | }
54 |
55 | /// @@allow('create,read', true)
56 | /// @@allow('update,delete', auth() == this)
57 | model User {
58 | id String @id() @default(cuid())
59 | name String?
60 | email String? @unique()
61 | emailVerified DateTime?
62 | /// @password
63 | /// @omit
64 | password String
65 | image String?
66 | accounts Account[]
67 | sessions Session[]
68 | posts Post[]
69 | }
70 |
71 | model VerificationToken {
72 | identifier String
73 | token String @unique()
74 | expires DateTime
75 |
76 | @@unique([identifier, token])
77 | }
78 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zenstackhq/docs-tutorial-nextjs-app-dir/014416c3c44df7eebd4b878236d79b8ef85a4d44/public/favicon.ico
--------------------------------------------------------------------------------
/schema.zmodel:
--------------------------------------------------------------------------------
1 | generator client {
2 | provider = "prisma-client-js"
3 | }
4 |
5 | datasource db {
6 | provider = "sqlite"
7 | url = env("DATABASE_URL")
8 | }
9 |
10 | plugin hooks {
11 | provider = '@zenstackhq/tanstack-query'
12 | target = 'react'
13 | output = "./src/lib/hooks"
14 | }
15 |
16 | model Post {
17 | id Int @id @default(autoincrement())
18 | name String
19 | createdAt DateTime @default(now())
20 | updatedAt DateTime @updatedAt
21 | published Boolean @default(false)
22 |
23 | createdBy User @relation(fields: [createdById], references: [id])
24 | createdById String @default(auth().id)
25 |
26 | @@index([name])
27 |
28 | // author has full access
29 | @@allow('all', auth() == createdBy)
30 |
31 | // logged-in users can view published posts
32 | @@allow('read', auth() != null && published)
33 | }
34 |
35 | // Necessary for Next auth
36 | model Account {
37 | id String @id @default(cuid())
38 | userId String
39 | type String
40 | provider String
41 | providerAccountId String
42 | refresh_token String? // @db.Text
43 | access_token String? // @db.Text
44 | expires_at Int?
45 | token_type String?
46 | scope String?
47 | id_token String? // @db.Text
48 | session_state String?
49 | user User @relation(fields: [userId], references: [id], onDelete: Cascade)
50 |
51 | @@unique([provider, providerAccountId])
52 | }
53 |
54 | model Session {
55 | id String @id @default(cuid())
56 | sessionToken String @unique
57 | userId String
58 | expires DateTime
59 | user User @relation(fields: [userId], references: [id], onDelete: Cascade)
60 | }
61 |
62 | model User {
63 | id String @id @default(cuid())
64 | name String?
65 | email String? @unique
66 | emailVerified DateTime?
67 | password String @password @omit
68 | image String?
69 | accounts Account[]
70 | sessions Session[]
71 | posts Post[]
72 |
73 | // everyone can signup, and user profile is also publicly readable
74 | @@allow('create,read', true)
75 |
76 | // only the user can update or delete their own profile
77 | @@allow('update,delete', auth() == this)
78 | }
79 |
80 | model VerificationToken {
81 | identifier String
82 | token String @unique
83 | expires DateTime
84 |
85 | @@unique([identifier, token])
86 | }
87 |
--------------------------------------------------------------------------------
/src/app/api/auth/[...nextauth]/route.ts:
--------------------------------------------------------------------------------
1 | import NextAuth from "next-auth";
2 |
3 | import { authOptions } from "~/server/auth";
4 |
5 | // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
6 | const handler = NextAuth(authOptions);
7 | export { handler as GET, handler as POST };
8 |
--------------------------------------------------------------------------------
/src/app/api/model/[...path]/route.ts:
--------------------------------------------------------------------------------
1 | import { enhance } from "@zenstackhq/runtime";
2 | import { NextRequestHandler } from "@zenstackhq/server/next";
3 | import { getServerAuthSession } from "~/server/auth";
4 | import { db } from "~/server/db";
5 |
6 | // create an enhanced Prisma client with user context
7 | async function getPrisma() {
8 | const session = await getServerAuthSession();
9 | return enhance(db, { user: session?.user });
10 | }
11 |
12 | const handler = NextRequestHandler({ getPrisma, useAppDir: true });
13 |
14 | export {
15 | handler as DELETE,
16 | handler as GET,
17 | handler as PATCH,
18 | handler as POST,
19 | handler as PUT,
20 | };
21 |
--------------------------------------------------------------------------------
/src/app/layout.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import "~/styles/globals.css";
4 |
5 | import { Inter } from "next/font/google";
6 | import Providers from "./providers";
7 |
8 | const inter = Inter({
9 | subsets: ["latin"],
10 | variable: "--font-sans",
11 | });
12 |
13 | export default function RootLayout({
14 | children,
15 | }: {
16 | children: React.ReactNode;
17 | }) {
18 | return (
19 |
20 |
21 | {children}
22 |
23 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/src/app/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import type { Post } from "@prisma/client";
4 | import { type NextPage } from "next";
5 | import { signOut, useSession } from "next-auth/react";
6 | import Link from "next/link";
7 | import { useRouter } from "next/navigation";
8 | import {
9 | useFindManyPost,
10 | useCreatePost,
11 | useUpdatePost,
12 | useDeletePost,
13 | } from "../lib/hooks";
14 |
15 | type AuthUser = { id: string; email?: string | null };
16 |
17 | const Welcome = ({ user }: { user: AuthUser }) => {
18 | const router = useRouter();
19 | async function onSignout() {
20 | await signOut({ redirect: false });
21 | router.push("/signin");
22 | }
23 | return (
24 |
25 |
Welcome back, {user?.email}
26 |
32 |
33 | );
34 | };
35 |
36 | const SigninSignup = () => {
37 | return (
38 |
39 |
40 | Signin
41 |
42 |
43 | Signup
44 |
45 |
46 | );
47 | };
48 |
49 | const Posts = () => {
50 | // Post crud hooks
51 | const { mutateAsync: createPost } = useCreatePost();
52 | const { mutateAsync: updatePost } = useUpdatePost();
53 | const { mutateAsync: deletePost } = useDeletePost();
54 |
55 | // list all posts that're visible to the current user, together with their authors
56 | const { data: posts } = useFindManyPost({
57 | include: { createdBy: true },
58 | orderBy: { createdAt: "desc" },
59 | });
60 |
61 | async function onCreatePost() {
62 | const name = prompt("Enter post name");
63 | if (name) {
64 | await createPost({ data: { name } });
65 | }
66 | }
67 |
68 | async function onTogglePublished(post: Post) {
69 | await updatePost({
70 | where: { id: post.id },
71 | data: { published: !post.published },
72 | });
73 | }
74 |
75 | async function onDelete(post: Post) {
76 | await deletePost({ where: { id: post.id } });
77 | }
78 |
79 | return (
80 |
81 |
87 |
88 |
89 | {posts?.map((post) => (
90 | -
91 |
92 | {post.name}
93 | by {post.createdBy.email}
94 |
95 |
96 |
102 |
105 |
106 |
107 | ))}
108 |
109 |
110 | );
111 | };
112 |
113 | const Home: NextPage = () => {
114 | const { data: session, status } = useSession();
115 |
116 | if (status === "loading") return Loading ...
;
117 |
118 | return (
119 |
120 |
121 |
My Awesome Blog
122 |
123 | {session?.user ? (
124 | // welcome & blog posts
125 |
131 | ) : (
132 | // if not logged in
133 |
134 | )}
135 |
136 |
137 | );
138 | };
139 |
140 | export default Home;
141 |
--------------------------------------------------------------------------------
/src/app/providers.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
4 | import { SessionProvider } from "next-auth/react";
5 | import type { ReactNode } from "react";
6 |
7 | const queryClient = new QueryClient();
8 |
9 | export default function Providers({ children }: { children: ReactNode }) {
10 | return (
11 |
12 | {children}
13 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/src/app/signin/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import type { NextPage } from "next";
4 | import { signIn } from "next-auth/react";
5 | import { useRouter } from "next/navigation";
6 | import { useState, type FormEvent } from "react";
7 |
8 | const Signin: NextPage = () => {
9 | const [email, setEmail] = useState("");
10 | const [password, setPassword] = useState("");
11 | const router = useRouter();
12 |
13 | async function onSignin(e: FormEvent) {
14 | e.preventDefault();
15 |
16 | const result = await signIn("credentials", {
17 | redirect: false,
18 | email,
19 | password,
20 | });
21 |
22 | if (result?.ok) {
23 | router.push("/");
24 | } else {
25 | alert("Signin failed");
26 | }
27 | }
28 |
29 | return (
30 |
67 | );
68 | };
69 |
70 | export default Signin;
71 |
--------------------------------------------------------------------------------
/src/app/signup/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import type { NextPage } from "next";
4 | import { signIn } from "next-auth/react";
5 | import { useRouter } from "next/navigation";
6 | import { useState, type FormEvent } from "react";
7 | import { useCreateUser } from "~/lib/hooks";
8 |
9 | const Signup: NextPage = () => {
10 | const [email, setEmail] = useState("");
11 | const [password, setPassword] = useState("");
12 | const { mutateAsync: signup } = useCreateUser();
13 | const router = useRouter();
14 |
15 | async function onSignup(e: FormEvent) {
16 | e.preventDefault();
17 | try {
18 | await signup({ data: { email, password } });
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | } catch (err: any) {
21 | console.error(err);
22 | // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
23 | if (err.info?.prisma && err.info?.code === "P2002") {
24 | // P2002 is Prisma's error code for unique constraint violations
25 | alert("User already exists");
26 | } else {
27 | alert("An unknown error occurred");
28 | }
29 | return;
30 | }
31 |
32 | // signin to create a session
33 | await signIn("credentials", { redirect: false, email, password });
34 | router.push("/");
35 | }
36 |
37 | return (
38 |
75 | );
76 | };
77 |
78 | export default Signup;
79 |
--------------------------------------------------------------------------------
/src/env.js:
--------------------------------------------------------------------------------
1 | import { createEnv } from "@t3-oss/env-nextjs";
2 | import { z } from "zod";
3 |
4 | export const env = createEnv({
5 | /**
6 | * Specify your server-side environment variables schema here. This way you can ensure the app
7 | * isn't built with invalid env vars.
8 | */
9 | server: {
10 | DATABASE_URL: z
11 | .string()
12 | .refine(
13 | (str) => !str.includes("YOUR_MYSQL_URL_HERE"),
14 | "You forgot to change the default URL",
15 | ),
16 | NODE_ENV: z
17 | .enum(["development", "test", "production"])
18 | .default("development"),
19 | NEXTAUTH_SECRET:
20 | process.env.NODE_ENV === "production"
21 | ? z.string()
22 | : z.string().optional(),
23 | NEXTAUTH_URL: z.preprocess(
24 | // This makes Vercel deployments not fail if you don't set NEXTAUTH_URL
25 | // Since NextAuth.js automatically uses the VERCEL_URL if present.
26 | (str) => process.env.VERCEL_URL ?? str,
27 | // VERCEL_URL doesn't include `https` so it cant be validated as a URL
28 | process.env.VERCEL ? z.string() : z.string().url(),
29 | ),
30 | },
31 |
32 | /**
33 | * Specify your client-side environment variables schema here. This way you can ensure the app
34 | * isn't built with invalid env vars. To expose them to the client, prefix them with
35 | * `NEXT_PUBLIC_`.
36 | */
37 | client: {
38 | // NEXT_PUBLIC_CLIENTVAR: z.string(),
39 | },
40 |
41 | /**
42 | * You can't destruct `process.env` as a regular object in the Next.js edge runtimes (e.g.
43 | * middlewares) or client-side so we need to destruct manually.
44 | */
45 | runtimeEnv: {
46 | DATABASE_URL: process.env.DATABASE_URL,
47 | NODE_ENV: process.env.NODE_ENV,
48 | NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET,
49 | NEXTAUTH_URL: process.env.NEXTAUTH_URL,
50 | },
51 | /**
52 | * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially
53 | * useful for Docker builds.
54 | */
55 | skipValidation: !!process.env.SKIP_ENV_VALIDATION,
56 | /**
57 | * Makes it so that empty strings are treated as undefined. `SOME_VAR: z.string()` and
58 | * `SOME_VAR=''` will throw an error.
59 | */
60 | emptyStringAsUndefined: true,
61 | });
62 |
--------------------------------------------------------------------------------
/src/lib/hooks/__model_meta.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | const metadata = {
3 | models: {
4 | post: {
5 | name: 'Post', fields: {
6 | id: {
7 | name: "id",
8 | type: "Int",
9 | isId: true,
10 | attributes: [{ "name": "@default", "args": [] }],
11 | isAutoIncrement: true,
12 | }, name: {
13 | name: "name",
14 | type: "String",
15 | }, createdAt: {
16 | name: "createdAt",
17 | type: "DateTime",
18 | attributes: [{ "name": "@default", "args": [] }],
19 | }, updatedAt: {
20 | name: "updatedAt",
21 | type: "DateTime",
22 | attributes: [{ "name": "@updatedAt", "args": [] }],
23 | }, published: {
24 | name: "published",
25 | type: "Boolean",
26 | attributes: [{ "name": "@default", "args": [{ "value": false }] }],
27 | }, createdBy: {
28 | name: "createdBy",
29 | type: "User",
30 | isDataModel: true,
31 | backLink: 'posts',
32 | isRelationOwner: true,
33 | foreignKeyMapping: { "id": "createdById" },
34 | }, createdById: {
35 | name: "createdById",
36 | type: "String",
37 | attributes: [{ "name": "@default", "args": [] }],
38 | isForeignKey: true,
39 | relationField: 'createdBy',
40 | defaultValueProvider: $default$Post$createdById,
41 | },
42 | }
43 | , uniqueConstraints: {
44 | id: {
45 | name: "id",
46 | fields: ["id"]
47 | },
48 | }
49 | ,
50 | }
51 | ,
52 | account: {
53 | name: 'Account', fields: {
54 | id: {
55 | name: "id",
56 | type: "String",
57 | isId: true,
58 | attributes: [{ "name": "@default", "args": [] }],
59 | }, userId: {
60 | name: "userId",
61 | type: "String",
62 | isForeignKey: true,
63 | relationField: 'user',
64 | }, type: {
65 | name: "type",
66 | type: "String",
67 | }, provider: {
68 | name: "provider",
69 | type: "String",
70 | }, providerAccountId: {
71 | name: "providerAccountId",
72 | type: "String",
73 | }, refresh_token: {
74 | name: "refresh_token",
75 | type: "String",
76 | isOptional: true,
77 | }, access_token: {
78 | name: "access_token",
79 | type: "String",
80 | isOptional: true,
81 | }, expires_at: {
82 | name: "expires_at",
83 | type: "Int",
84 | isOptional: true,
85 | }, token_type: {
86 | name: "token_type",
87 | type: "String",
88 | isOptional: true,
89 | }, scope: {
90 | name: "scope",
91 | type: "String",
92 | isOptional: true,
93 | }, id_token: {
94 | name: "id_token",
95 | type: "String",
96 | isOptional: true,
97 | }, session_state: {
98 | name: "session_state",
99 | type: "String",
100 | isOptional: true,
101 | }, user: {
102 | name: "user",
103 | type: "User",
104 | isDataModel: true,
105 | backLink: 'accounts',
106 | isRelationOwner: true,
107 | foreignKeyMapping: { "id": "userId" },
108 | },
109 | }
110 | , uniqueConstraints: {
111 | id: {
112 | name: "id",
113 | fields: ["id"]
114 | }, provider_providerAccountId: {
115 | name: "provider_providerAccountId",
116 | fields: ["provider", "providerAccountId"]
117 | },
118 | }
119 | ,
120 | }
121 | ,
122 | session: {
123 | name: 'Session', fields: {
124 | id: {
125 | name: "id",
126 | type: "String",
127 | isId: true,
128 | attributes: [{ "name": "@default", "args": [] }],
129 | }, sessionToken: {
130 | name: "sessionToken",
131 | type: "String",
132 | }, userId: {
133 | name: "userId",
134 | type: "String",
135 | isForeignKey: true,
136 | relationField: 'user',
137 | }, expires: {
138 | name: "expires",
139 | type: "DateTime",
140 | }, user: {
141 | name: "user",
142 | type: "User",
143 | isDataModel: true,
144 | backLink: 'sessions',
145 | isRelationOwner: true,
146 | foreignKeyMapping: { "id": "userId" },
147 | },
148 | }
149 | , uniqueConstraints: {
150 | id: {
151 | name: "id",
152 | fields: ["id"]
153 | }, sessionToken: {
154 | name: "sessionToken",
155 | fields: ["sessionToken"]
156 | },
157 | }
158 | ,
159 | }
160 | ,
161 | user: {
162 | name: 'User', fields: {
163 | id: {
164 | name: "id",
165 | type: "String",
166 | isId: true,
167 | attributes: [{ "name": "@default", "args": [] }],
168 | }, name: {
169 | name: "name",
170 | type: "String",
171 | isOptional: true,
172 | }, email: {
173 | name: "email",
174 | type: "String",
175 | isOptional: true,
176 | }, emailVerified: {
177 | name: "emailVerified",
178 | type: "DateTime",
179 | isOptional: true,
180 | }, password: {
181 | name: "password",
182 | type: "String",
183 | }, image: {
184 | name: "image",
185 | type: "String",
186 | isOptional: true,
187 | }, accounts: {
188 | name: "accounts",
189 | type: "Account",
190 | isDataModel: true,
191 | isArray: true,
192 | backLink: 'user',
193 | }, sessions: {
194 | name: "sessions",
195 | type: "Session",
196 | isDataModel: true,
197 | isArray: true,
198 | backLink: 'user',
199 | }, posts: {
200 | name: "posts",
201 | type: "Post",
202 | isDataModel: true,
203 | isArray: true,
204 | backLink: 'createdBy',
205 | },
206 | }
207 | , uniqueConstraints: {
208 | id: {
209 | name: "id",
210 | fields: ["id"]
211 | }, email: {
212 | name: "email",
213 | fields: ["email"]
214 | },
215 | }
216 | ,
217 | }
218 | ,
219 | verificationToken: {
220 | name: 'VerificationToken', fields: {
221 | identifier: {
222 | name: "identifier",
223 | type: "String",
224 | }, token: {
225 | name: "token",
226 | type: "String",
227 | isId: true,
228 | }, expires: {
229 | name: "expires",
230 | type: "DateTime",
231 | },
232 | }
233 | , uniqueConstraints: {
234 | token: {
235 | name: "token",
236 | fields: ["token"]
237 | }, identifier_token: {
238 | name: "identifier_token",
239 | fields: ["identifier", "token"]
240 | },
241 | }
242 | ,
243 | }
244 | ,
245 | }
246 | ,
247 | deleteCascade: {
248 | user: ['Account', 'Session'],
249 | }
250 | ,
251 | authModel: 'User'
252 | };
253 | function $default$Post$createdById(user: any): unknown {
254 | return user?.id;
255 | }
256 | export default metadata;
257 |
--------------------------------------------------------------------------------
/src/lib/hooks/account.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import type { Prisma, Account } from "@zenstackhq/runtime/models";
3 | import type { UseMutationOptions, UseQueryOptions, UseInfiniteQueryOptions, InfiniteData } from '@tanstack/react-query';
4 | import { getHooksContext } from '@zenstackhq/tanstack-query/runtime-v5/react';
5 | import { useModelQuery, useInfiniteModelQuery, useModelMutation } from '@zenstackhq/tanstack-query/runtime-v5/react';
6 | import type { PickEnumerable, CheckSelect, QueryError, ExtraQueryOptions, ExtraMutationOptions } from '@zenstackhq/tanstack-query/runtime-v5';
7 | import type { PolicyCrudKind } from '@zenstackhq/runtime'
8 | import metadata from './__model_meta';
9 | type DefaultError = QueryError;
10 | import { useSuspenseModelQuery, useSuspenseInfiniteModelQuery } from '@zenstackhq/tanstack-query/runtime-v5/react';
11 | import type { UseSuspenseQueryOptions, UseSuspenseInfiniteQueryOptions } from '@tanstack/react-query';
12 |
13 | export function useCreateAccount(options?: Omit<(UseMutationOptions<(Account | undefined), DefaultError, Prisma.AccountCreateArgs> & ExtraMutationOptions), 'mutationFn'>) {
14 | const { endpoint, fetch } = getHooksContext();
15 | const _mutation =
16 | useModelMutation('Account', 'POST', `${endpoint}/account/create`, metadata, options, fetch, true)
17 | ;
18 | const mutation = {
19 | ..._mutation,
20 | mutateAsync: async (
21 | args: Prisma.SelectSubset,
22 | options?: Omit<(UseMutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'>
23 | ) => {
24 | return (await _mutation.mutateAsync(
25 | args,
26 | options as any
27 | )) as (CheckSelect> | undefined);
28 | },
29 | };
30 | return mutation;
31 | }
32 |
33 | export function useCreateManyAccount(options?: Omit<(UseMutationOptions & ExtraMutationOptions), 'mutationFn'>) {
34 | const { endpoint, fetch } = getHooksContext();
35 | const _mutation =
36 | useModelMutation('Account', 'POST', `${endpoint}/account/createMany`, metadata, options, fetch, false)
37 | ;
38 | const mutation = {
39 | ..._mutation,
40 | mutateAsync: async (
41 | args: Prisma.SelectSubset,
42 | options?: Omit<(UseMutationOptions> & ExtraMutationOptions), 'mutationFn'>
43 | ) => {
44 | return (await _mutation.mutateAsync(
45 | args,
46 | options as any
47 | )) as Prisma.BatchPayload;
48 | },
49 | };
50 | return mutation;
51 | }
52 |
53 | export function useFindManyAccount & { $optimistic?: boolean }>, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
54 | const { endpoint, fetch } = getHooksContext();
55 | return useModelQuery('Account', `${endpoint}/account/findMany`, args, options, fetch);
56 | }
57 |
58 | export function useInfiniteFindManyAccount>, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: Omit>, 'queryKey' | 'initialPageParam'>) {
59 | options = options ?? { getNextPageParam: () => null };
60 | const { endpoint, fetch } = getHooksContext();
61 | return useInfiniteModelQuery('Account', `${endpoint}/account/findMany`, args, options, fetch);
62 | }
63 |
64 | export function useSuspenseFindManyAccount & { $optimistic?: boolean }>, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
65 | const { endpoint, fetch } = getHooksContext();
66 | return useSuspenseModelQuery('Account', `${endpoint}/account/findMany`, args, options, fetch);
67 | }
68 |
69 | export function useSuspenseInfiniteFindManyAccount>, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: Omit>, 'queryKey' | 'initialPageParam'>) {
70 | options = options ?? { getNextPageParam: () => null };
71 | const { endpoint, fetch } = getHooksContext();
72 | return useSuspenseInfiniteModelQuery('Account', `${endpoint}/account/findMany`, args, options, fetch);
73 | }
74 |
75 | export function useFindUniqueAccount & { $optimistic?: boolean }, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
76 | const { endpoint, fetch } = getHooksContext();
77 | return useModelQuery('Account', `${endpoint}/account/findUnique`, args, options, fetch);
78 | }
79 |
80 | export function useSuspenseFindUniqueAccount & { $optimistic?: boolean }, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
81 | const { endpoint, fetch } = getHooksContext();
82 | return useSuspenseModelQuery('Account', `${endpoint}/account/findUnique`, args, options, fetch);
83 | }
84 |
85 | export function useFindFirstAccount & { $optimistic?: boolean }, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
86 | const { endpoint, fetch } = getHooksContext();
87 | return useModelQuery('Account', `${endpoint}/account/findFirst`, args, options, fetch);
88 | }
89 |
90 | export function useSuspenseFindFirstAccount & { $optimistic?: boolean }, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
91 | const { endpoint, fetch } = getHooksContext();
92 | return useSuspenseModelQuery('Account', `${endpoint}/account/findFirst`, args, options, fetch);
93 | }
94 |
95 | export function useUpdateAccount(options?: Omit<(UseMutationOptions<(Account | undefined), DefaultError, Prisma.AccountUpdateArgs> & ExtraMutationOptions), 'mutationFn'>) {
96 | const { endpoint, fetch } = getHooksContext();
97 | const _mutation =
98 | useModelMutation('Account', 'PUT', `${endpoint}/account/update`, metadata, options, fetch, true)
99 | ;
100 | const mutation = {
101 | ..._mutation,
102 | mutateAsync: async (
103 | args: Prisma.SelectSubset,
104 | options?: Omit<(UseMutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'>
105 | ) => {
106 | return (await _mutation.mutateAsync(
107 | args,
108 | options as any
109 | )) as (CheckSelect> | undefined);
110 | },
111 | };
112 | return mutation;
113 | }
114 |
115 | export function useUpdateManyAccount(options?: Omit<(UseMutationOptions & ExtraMutationOptions), 'mutationFn'>) {
116 | const { endpoint, fetch } = getHooksContext();
117 | const _mutation =
118 | useModelMutation('Account', 'PUT', `${endpoint}/account/updateMany`, metadata, options, fetch, false)
119 | ;
120 | const mutation = {
121 | ..._mutation,
122 | mutateAsync: async (
123 | args: Prisma.SelectSubset,
124 | options?: Omit<(UseMutationOptions> & ExtraMutationOptions), 'mutationFn'>
125 | ) => {
126 | return (await _mutation.mutateAsync(
127 | args,
128 | options as any
129 | )) as Prisma.BatchPayload;
130 | },
131 | };
132 | return mutation;
133 | }
134 |
135 | export function useUpsertAccount(options?: Omit<(UseMutationOptions<(Account | undefined), DefaultError, Prisma.AccountUpsertArgs> & ExtraMutationOptions), 'mutationFn'>) {
136 | const { endpoint, fetch } = getHooksContext();
137 | const _mutation =
138 | useModelMutation('Account', 'POST', `${endpoint}/account/upsert`, metadata, options, fetch, true)
139 | ;
140 | const mutation = {
141 | ..._mutation,
142 | mutateAsync: async (
143 | args: Prisma.SelectSubset,
144 | options?: Omit<(UseMutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'>
145 | ) => {
146 | return (await _mutation.mutateAsync(
147 | args,
148 | options as any
149 | )) as (CheckSelect> | undefined);
150 | },
151 | };
152 | return mutation;
153 | }
154 |
155 | export function useDeleteAccount(options?: Omit<(UseMutationOptions<(Account | undefined), DefaultError, Prisma.AccountDeleteArgs> & ExtraMutationOptions), 'mutationFn'>) {
156 | const { endpoint, fetch } = getHooksContext();
157 | const _mutation =
158 | useModelMutation('Account', 'DELETE', `${endpoint}/account/delete`, metadata, options, fetch, true)
159 | ;
160 | const mutation = {
161 | ..._mutation,
162 | mutateAsync: async (
163 | args: Prisma.SelectSubset,
164 | options?: Omit<(UseMutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'>
165 | ) => {
166 | return (await _mutation.mutateAsync(
167 | args,
168 | options as any
169 | )) as (CheckSelect> | undefined);
170 | },
171 | };
172 | return mutation;
173 | }
174 |
175 | export function useDeleteManyAccount(options?: Omit<(UseMutationOptions & ExtraMutationOptions), 'mutationFn'>) {
176 | const { endpoint, fetch } = getHooksContext();
177 | const _mutation =
178 | useModelMutation('Account', 'DELETE', `${endpoint}/account/deleteMany`, metadata, options, fetch, false)
179 | ;
180 | const mutation = {
181 | ..._mutation,
182 | mutateAsync: async (
183 | args: Prisma.SelectSubset,
184 | options?: Omit<(UseMutationOptions> & ExtraMutationOptions), 'mutationFn'>
185 | ) => {
186 | return (await _mutation.mutateAsync(
187 | args,
188 | options as any
189 | )) as Prisma.BatchPayload;
190 | },
191 | };
192 | return mutation;
193 | }
194 |
195 | export function useAggregateAccount, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
196 | const { endpoint, fetch } = getHooksContext();
197 | return useModelQuery('Account', `${endpoint}/account/aggregate`, args, options, fetch);
198 | }
199 |
200 | export function useSuspenseAggregateAccount, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
201 | const { endpoint, fetch } = getHooksContext();
202 | return useSuspenseModelQuery('Account', `${endpoint}/account/aggregate`, args, options, fetch);
203 | }
204 |
205 | export function useGroupByAccount>, Prisma.Extends<'take', Prisma.Keys>>, OrderByArg extends Prisma.True extends HasSelectOrTake ? { orderBy: Prisma.AccountGroupByArgs['orderBy'] } : { orderBy?: Prisma.AccountGroupByArgs['orderBy'] }, OrderFields extends Prisma.ExcludeUnderscoreKeys>>, ByFields extends Prisma.MaybeTupleToUnion, ByValid extends Prisma.Has, HavingFields extends Prisma.GetHavingFields, HavingValid extends Prisma.Has, ByEmpty extends TArgs['by'] extends never[] ? Prisma.True : Prisma.False, InputErrors extends ByEmpty extends Prisma.True
206 | ? `Error: "by" must not be empty.`
207 | : HavingValid extends Prisma.False
208 | ? {
209 | [P in HavingFields]: P extends ByFields
210 | ? never
211 | : P extends string
212 | ? `Error: Field "${P}" used in "having" needs to be provided in "by".`
213 | : [
214 | Error,
215 | 'Field ',
216 | P,
217 | ` in "having" needs to be provided in "by"`,
218 | ]
219 | }[HavingFields]
220 | : 'take' extends Prisma.Keys
221 | ? 'orderBy' extends Prisma.Keys
222 | ? ByValid extends Prisma.True
223 | ? {}
224 | : {
225 | [P in OrderFields]: P extends ByFields
226 | ? never
227 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"`
228 | }[OrderFields]
229 | : 'Error: If you provide "take", you also need to provide "orderBy"'
230 | : 'skip' extends Prisma.Keys
231 | ? 'orderBy' extends Prisma.Keys
232 | ? ByValid extends Prisma.True
233 | ? {}
234 | : {
235 | [P in OrderFields]: P extends ByFields
236 | ? never
237 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"`
238 | }[OrderFields]
239 | : 'Error: If you provide "skip", you also need to provide "orderBy"'
240 | : ByValid extends Prisma.True
241 | ? {}
242 | : {
243 | [P in OrderFields]: P extends ByFields
244 | ? never
245 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"`
246 | }[OrderFields], TQueryFnData = {} extends InputErrors ?
247 | Array &
248 | {
249 | [P in ((keyof TArgs) & (keyof Prisma.AccountGroupByOutputType))]: P extends '_count'
250 | ? TArgs[P] extends boolean
251 | ? number
252 | : Prisma.GetScalarType
253 | : Prisma.GetScalarType
254 | }
255 | > : InputErrors, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset & InputErrors>, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
256 | const { endpoint, fetch } = getHooksContext();
257 | return useModelQuery('Account', `${endpoint}/account/groupBy`, args, options, fetch);
258 | }
259 |
260 | export function useSuspenseGroupByAccount>, Prisma.Extends<'take', Prisma.Keys>>, OrderByArg extends Prisma.True extends HasSelectOrTake ? { orderBy: Prisma.AccountGroupByArgs['orderBy'] } : { orderBy?: Prisma.AccountGroupByArgs['orderBy'] }, OrderFields extends Prisma.ExcludeUnderscoreKeys>>, ByFields extends Prisma.MaybeTupleToUnion, ByValid extends Prisma.Has, HavingFields extends Prisma.GetHavingFields, HavingValid extends Prisma.Has, ByEmpty extends TArgs['by'] extends never[] ? Prisma.True : Prisma.False, InputErrors extends ByEmpty extends Prisma.True
261 | ? `Error: "by" must not be empty.`
262 | : HavingValid extends Prisma.False
263 | ? {
264 | [P in HavingFields]: P extends ByFields
265 | ? never
266 | : P extends string
267 | ? `Error: Field "${P}" used in "having" needs to be provided in "by".`
268 | : [
269 | Error,
270 | 'Field ',
271 | P,
272 | ` in "having" needs to be provided in "by"`,
273 | ]
274 | }[HavingFields]
275 | : 'take' extends Prisma.Keys
276 | ? 'orderBy' extends Prisma.Keys
277 | ? ByValid extends Prisma.True
278 | ? {}
279 | : {
280 | [P in OrderFields]: P extends ByFields
281 | ? never
282 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"`
283 | }[OrderFields]
284 | : 'Error: If you provide "take", you also need to provide "orderBy"'
285 | : 'skip' extends Prisma.Keys
286 | ? 'orderBy' extends Prisma.Keys
287 | ? ByValid extends Prisma.True
288 | ? {}
289 | : {
290 | [P in OrderFields]: P extends ByFields
291 | ? never
292 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"`
293 | }[OrderFields]
294 | : 'Error: If you provide "skip", you also need to provide "orderBy"'
295 | : ByValid extends Prisma.True
296 | ? {}
297 | : {
298 | [P in OrderFields]: P extends ByFields
299 | ? never
300 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"`
301 | }[OrderFields], TQueryFnData = {} extends InputErrors ?
302 | Array &
303 | {
304 | [P in ((keyof TArgs) & (keyof Prisma.AccountGroupByOutputType))]: P extends '_count'
305 | ? TArgs[P] extends boolean
306 | ? number
307 | : Prisma.GetScalarType
308 | : Prisma.GetScalarType
309 | }
310 | > : InputErrors, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset & InputErrors>, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
311 | const { endpoint, fetch } = getHooksContext();
312 | return useSuspenseModelQuery('Account', `${endpoint}/account/groupBy`, args, options, fetch);
313 | }
314 |
315 | export function useCountAccount : number, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
316 | const { endpoint, fetch } = getHooksContext();
317 | return useModelQuery('Account', `${endpoint}/account/count`, args, options, fetch);
318 | }
319 |
320 | export function useSuspenseCountAccount : number, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
321 | const { endpoint, fetch } = getHooksContext();
322 | return useSuspenseModelQuery('Account', `${endpoint}/account/count`, args, options, fetch);
323 | }
324 |
325 | export function useCheckAccount(args: { operation: PolicyCrudKind; where?: { id?: string; userId?: string; type?: string; provider?: string; providerAccountId?: string; refresh_token?: string; access_token?: string; expires_at?: number; token_type?: string; scope?: string; id_token?: string; session_state?: string }; }, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
326 | const { endpoint, fetch } = getHooksContext();
327 | return useModelQuery('Account', `${endpoint}/account/check`, args, options, fetch);
328 | }
329 |
--------------------------------------------------------------------------------
/src/lib/hooks/index.ts:
--------------------------------------------------------------------------------
1 | export * from './post';
2 | export * from './account';
3 | export * from './session';
4 | export * from './user';
5 | export * from './verification-token';
6 | export { getQueryKey } from '@zenstackhq/tanstack-query/runtime-v5';
7 | export { Provider } from '@zenstackhq/tanstack-query/runtime-v5/react';
8 |
--------------------------------------------------------------------------------
/src/lib/hooks/post.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import type { Prisma, Post } from "@zenstackhq/runtime/models";
3 | import type { UseMutationOptions, UseQueryOptions, UseInfiniteQueryOptions, InfiniteData } from '@tanstack/react-query';
4 | import { getHooksContext } from '@zenstackhq/tanstack-query/runtime-v5/react';
5 | import { useModelQuery, useInfiniteModelQuery, useModelMutation } from '@zenstackhq/tanstack-query/runtime-v5/react';
6 | import type { PickEnumerable, CheckSelect, QueryError, ExtraQueryOptions, ExtraMutationOptions } from '@zenstackhq/tanstack-query/runtime-v5';
7 | import type { PolicyCrudKind } from '@zenstackhq/runtime'
8 | import metadata from './__model_meta';
9 | type DefaultError = QueryError;
10 | import { useSuspenseModelQuery, useSuspenseInfiniteModelQuery } from '@zenstackhq/tanstack-query/runtime-v5/react';
11 | import type { UseSuspenseQueryOptions, UseSuspenseInfiniteQueryOptions } from '@tanstack/react-query';
12 |
13 | export function useCreatePost(options?: Omit<(UseMutationOptions<(Post | undefined), DefaultError, Prisma.PostCreateArgs> & ExtraMutationOptions), 'mutationFn'>) {
14 | const { endpoint, fetch } = getHooksContext();
15 | const _mutation =
16 | useModelMutation('Post', 'POST', `${endpoint}/post/create`, metadata, options, fetch, true)
17 | ;
18 | const mutation = {
19 | ..._mutation,
20 | mutateAsync: async (
21 | args: Prisma.SelectSubset,
22 | options?: Omit<(UseMutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'>
23 | ) => {
24 | return (await _mutation.mutateAsync(
25 | args,
26 | options as any
27 | )) as (CheckSelect> | undefined);
28 | },
29 | };
30 | return mutation;
31 | }
32 |
33 | export function useCreateManyPost(options?: Omit<(UseMutationOptions & ExtraMutationOptions), 'mutationFn'>) {
34 | const { endpoint, fetch } = getHooksContext();
35 | const _mutation =
36 | useModelMutation('Post', 'POST', `${endpoint}/post/createMany`, metadata, options, fetch, false)
37 | ;
38 | const mutation = {
39 | ..._mutation,
40 | mutateAsync: async (
41 | args: Prisma.SelectSubset,
42 | options?: Omit<(UseMutationOptions> & ExtraMutationOptions), 'mutationFn'>
43 | ) => {
44 | return (await _mutation.mutateAsync(
45 | args,
46 | options as any
47 | )) as Prisma.BatchPayload;
48 | },
49 | };
50 | return mutation;
51 | }
52 |
53 | export function useFindManyPost & { $optimistic?: boolean }>, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
54 | const { endpoint, fetch } = getHooksContext();
55 | return useModelQuery('Post', `${endpoint}/post/findMany`, args, options, fetch);
56 | }
57 |
58 | export function useInfiniteFindManyPost>, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: Omit>, 'queryKey' | 'initialPageParam'>) {
59 | options = options ?? { getNextPageParam: () => null };
60 | const { endpoint, fetch } = getHooksContext();
61 | return useInfiniteModelQuery('Post', `${endpoint}/post/findMany`, args, options, fetch);
62 | }
63 |
64 | export function useSuspenseFindManyPost & { $optimistic?: boolean }>, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
65 | const { endpoint, fetch } = getHooksContext();
66 | return useSuspenseModelQuery('Post', `${endpoint}/post/findMany`, args, options, fetch);
67 | }
68 |
69 | export function useSuspenseInfiniteFindManyPost>, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: Omit>, 'queryKey' | 'initialPageParam'>) {
70 | options = options ?? { getNextPageParam: () => null };
71 | const { endpoint, fetch } = getHooksContext();
72 | return useSuspenseInfiniteModelQuery('Post', `${endpoint}/post/findMany`, args, options, fetch);
73 | }
74 |
75 | export function useFindUniquePost & { $optimistic?: boolean }, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
76 | const { endpoint, fetch } = getHooksContext();
77 | return useModelQuery('Post', `${endpoint}/post/findUnique`, args, options, fetch);
78 | }
79 |
80 | export function useSuspenseFindUniquePost & { $optimistic?: boolean }, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
81 | const { endpoint, fetch } = getHooksContext();
82 | return useSuspenseModelQuery('Post', `${endpoint}/post/findUnique`, args, options, fetch);
83 | }
84 |
85 | export function useFindFirstPost & { $optimistic?: boolean }, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
86 | const { endpoint, fetch } = getHooksContext();
87 | return useModelQuery('Post', `${endpoint}/post/findFirst`, args, options, fetch);
88 | }
89 |
90 | export function useSuspenseFindFirstPost & { $optimistic?: boolean }, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
91 | const { endpoint, fetch } = getHooksContext();
92 | return useSuspenseModelQuery('Post', `${endpoint}/post/findFirst`, args, options, fetch);
93 | }
94 |
95 | export function useUpdatePost(options?: Omit<(UseMutationOptions<(Post | undefined), DefaultError, Prisma.PostUpdateArgs> & ExtraMutationOptions), 'mutationFn'>) {
96 | const { endpoint, fetch } = getHooksContext();
97 | const _mutation =
98 | useModelMutation('Post', 'PUT', `${endpoint}/post/update`, metadata, options, fetch, true)
99 | ;
100 | const mutation = {
101 | ..._mutation,
102 | mutateAsync: async (
103 | args: Prisma.SelectSubset,
104 | options?: Omit<(UseMutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'>
105 | ) => {
106 | return (await _mutation.mutateAsync(
107 | args,
108 | options as any
109 | )) as (CheckSelect> | undefined);
110 | },
111 | };
112 | return mutation;
113 | }
114 |
115 | export function useUpdateManyPost(options?: Omit<(UseMutationOptions & ExtraMutationOptions), 'mutationFn'>) {
116 | const { endpoint, fetch } = getHooksContext();
117 | const _mutation =
118 | useModelMutation('Post', 'PUT', `${endpoint}/post/updateMany`, metadata, options, fetch, false)
119 | ;
120 | const mutation = {
121 | ..._mutation,
122 | mutateAsync: async (
123 | args: Prisma.SelectSubset,
124 | options?: Omit<(UseMutationOptions> & ExtraMutationOptions), 'mutationFn'>
125 | ) => {
126 | return (await _mutation.mutateAsync(
127 | args,
128 | options as any
129 | )) as Prisma.BatchPayload;
130 | },
131 | };
132 | return mutation;
133 | }
134 |
135 | export function useUpsertPost(options?: Omit<(UseMutationOptions<(Post | undefined), DefaultError, Prisma.PostUpsertArgs> & ExtraMutationOptions), 'mutationFn'>) {
136 | const { endpoint, fetch } = getHooksContext();
137 | const _mutation =
138 | useModelMutation('Post', 'POST', `${endpoint}/post/upsert`, metadata, options, fetch, true)
139 | ;
140 | const mutation = {
141 | ..._mutation,
142 | mutateAsync: async (
143 | args: Prisma.SelectSubset,
144 | options?: Omit<(UseMutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'>
145 | ) => {
146 | return (await _mutation.mutateAsync(
147 | args,
148 | options as any
149 | )) as (CheckSelect> | undefined);
150 | },
151 | };
152 | return mutation;
153 | }
154 |
155 | export function useDeletePost(options?: Omit<(UseMutationOptions<(Post | undefined), DefaultError, Prisma.PostDeleteArgs> & ExtraMutationOptions), 'mutationFn'>) {
156 | const { endpoint, fetch } = getHooksContext();
157 | const _mutation =
158 | useModelMutation('Post', 'DELETE', `${endpoint}/post/delete`, metadata, options, fetch, true)
159 | ;
160 | const mutation = {
161 | ..._mutation,
162 | mutateAsync: async (
163 | args: Prisma.SelectSubset,
164 | options?: Omit<(UseMutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'>
165 | ) => {
166 | return (await _mutation.mutateAsync(
167 | args,
168 | options as any
169 | )) as (CheckSelect> | undefined);
170 | },
171 | };
172 | return mutation;
173 | }
174 |
175 | export function useDeleteManyPost(options?: Omit<(UseMutationOptions & ExtraMutationOptions), 'mutationFn'>) {
176 | const { endpoint, fetch } = getHooksContext();
177 | const _mutation =
178 | useModelMutation('Post', 'DELETE', `${endpoint}/post/deleteMany`, metadata, options, fetch, false)
179 | ;
180 | const mutation = {
181 | ..._mutation,
182 | mutateAsync: async (
183 | args: Prisma.SelectSubset,
184 | options?: Omit<(UseMutationOptions> & ExtraMutationOptions), 'mutationFn'>
185 | ) => {
186 | return (await _mutation.mutateAsync(
187 | args,
188 | options as any
189 | )) as Prisma.BatchPayload;
190 | },
191 | };
192 | return mutation;
193 | }
194 |
195 | export function useAggregatePost, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
196 | const { endpoint, fetch } = getHooksContext();
197 | return useModelQuery('Post', `${endpoint}/post/aggregate`, args, options, fetch);
198 | }
199 |
200 | export function useSuspenseAggregatePost, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
201 | const { endpoint, fetch } = getHooksContext();
202 | return useSuspenseModelQuery('Post', `${endpoint}/post/aggregate`, args, options, fetch);
203 | }
204 |
205 | export function useGroupByPost>, Prisma.Extends<'take', Prisma.Keys>>, OrderByArg extends Prisma.True extends HasSelectOrTake ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, OrderFields extends Prisma.ExcludeUnderscoreKeys>>, ByFields extends Prisma.MaybeTupleToUnion, ByValid extends Prisma.Has, HavingFields extends Prisma.GetHavingFields, HavingValid extends Prisma.Has, ByEmpty extends TArgs['by'] extends never[] ? Prisma.True : Prisma.False, InputErrors extends ByEmpty extends Prisma.True
206 | ? `Error: "by" must not be empty.`
207 | : HavingValid extends Prisma.False
208 | ? {
209 | [P in HavingFields]: P extends ByFields
210 | ? never
211 | : P extends string
212 | ? `Error: Field "${P}" used in "having" needs to be provided in "by".`
213 | : [
214 | Error,
215 | 'Field ',
216 | P,
217 | ` in "having" needs to be provided in "by"`,
218 | ]
219 | }[HavingFields]
220 | : 'take' extends Prisma.Keys
221 | ? 'orderBy' extends Prisma.Keys
222 | ? ByValid extends Prisma.True
223 | ? {}
224 | : {
225 | [P in OrderFields]: P extends ByFields
226 | ? never
227 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"`
228 | }[OrderFields]
229 | : 'Error: If you provide "take", you also need to provide "orderBy"'
230 | : 'skip' extends Prisma.Keys
231 | ? 'orderBy' extends Prisma.Keys
232 | ? ByValid extends Prisma.True
233 | ? {}
234 | : {
235 | [P in OrderFields]: P extends ByFields
236 | ? never
237 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"`
238 | }[OrderFields]
239 | : 'Error: If you provide "skip", you also need to provide "orderBy"'
240 | : ByValid extends Prisma.True
241 | ? {}
242 | : {
243 | [P in OrderFields]: P extends ByFields
244 | ? never
245 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"`
246 | }[OrderFields], TQueryFnData = {} extends InputErrors ?
247 | Array &
248 | {
249 | [P in ((keyof TArgs) & (keyof Prisma.PostGroupByOutputType))]: P extends '_count'
250 | ? TArgs[P] extends boolean
251 | ? number
252 | : Prisma.GetScalarType
253 | : Prisma.GetScalarType
254 | }
255 | > : InputErrors, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset & InputErrors>, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
256 | const { endpoint, fetch } = getHooksContext();
257 | return useModelQuery('Post', `${endpoint}/post/groupBy`, args, options, fetch);
258 | }
259 |
260 | export function useSuspenseGroupByPost>, Prisma.Extends<'take', Prisma.Keys>>, OrderByArg extends Prisma.True extends HasSelectOrTake ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, OrderFields extends Prisma.ExcludeUnderscoreKeys>>, ByFields extends Prisma.MaybeTupleToUnion, ByValid extends Prisma.Has, HavingFields extends Prisma.GetHavingFields, HavingValid extends Prisma.Has, ByEmpty extends TArgs['by'] extends never[] ? Prisma.True : Prisma.False, InputErrors extends ByEmpty extends Prisma.True
261 | ? `Error: "by" must not be empty.`
262 | : HavingValid extends Prisma.False
263 | ? {
264 | [P in HavingFields]: P extends ByFields
265 | ? never
266 | : P extends string
267 | ? `Error: Field "${P}" used in "having" needs to be provided in "by".`
268 | : [
269 | Error,
270 | 'Field ',
271 | P,
272 | ` in "having" needs to be provided in "by"`,
273 | ]
274 | }[HavingFields]
275 | : 'take' extends Prisma.Keys
276 | ? 'orderBy' extends Prisma.Keys
277 | ? ByValid extends Prisma.True
278 | ? {}
279 | : {
280 | [P in OrderFields]: P extends ByFields
281 | ? never
282 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"`
283 | }[OrderFields]
284 | : 'Error: If you provide "take", you also need to provide "orderBy"'
285 | : 'skip' extends Prisma.Keys
286 | ? 'orderBy' extends Prisma.Keys
287 | ? ByValid extends Prisma.True
288 | ? {}
289 | : {
290 | [P in OrderFields]: P extends ByFields
291 | ? never
292 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"`
293 | }[OrderFields]
294 | : 'Error: If you provide "skip", you also need to provide "orderBy"'
295 | : ByValid extends Prisma.True
296 | ? {}
297 | : {
298 | [P in OrderFields]: P extends ByFields
299 | ? never
300 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"`
301 | }[OrderFields], TQueryFnData = {} extends InputErrors ?
302 | Array &
303 | {
304 | [P in ((keyof TArgs) & (keyof Prisma.PostGroupByOutputType))]: P extends '_count'
305 | ? TArgs[P] extends boolean
306 | ? number
307 | : Prisma.GetScalarType
308 | : Prisma.GetScalarType
309 | }
310 | > : InputErrors, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset & InputErrors>, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
311 | const { endpoint, fetch } = getHooksContext();
312 | return useSuspenseModelQuery('Post', `${endpoint}/post/groupBy`, args, options, fetch);
313 | }
314 |
315 | export function useCountPost : number, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
316 | const { endpoint, fetch } = getHooksContext();
317 | return useModelQuery('Post', `${endpoint}/post/count`, args, options, fetch);
318 | }
319 |
320 | export function useSuspenseCountPost : number, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
321 | const { endpoint, fetch } = getHooksContext();
322 | return useSuspenseModelQuery('Post', `${endpoint}/post/count`, args, options, fetch);
323 | }
324 |
325 | export function useCheckPost(args: { operation: PolicyCrudKind; where?: { id?: number; name?: string; published?: boolean; createdById?: string }; }, options?: (Omit, 'queryKey'> & ExtraQueryOptions)) {
326 | const { endpoint, fetch } = getHooksContext();
327 | return useModelQuery('Post', `${endpoint}/post/check`, args, options, fetch);
328 | }
329 |
--------------------------------------------------------------------------------
/src/lib/hooks/session.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import type { Prisma, Session } from "@zenstackhq/runtime/models";
3 | import type { UseMutationOptions, UseQueryOptions, UseInfiniteQueryOptions, InfiniteData } from '@tanstack/react-query';
4 | import { getHooksContext } from '@zenstackhq/tanstack-query/runtime-v5/react';
5 | import { useModelQuery, useInfiniteModelQuery, useModelMutation } from '@zenstackhq/tanstack-query/runtime-v5/react';
6 | import type { PickEnumerable, CheckSelect, QueryError, ExtraQueryOptions, ExtraMutationOptions } from '@zenstackhq/tanstack-query/runtime-v5';
7 | import type { PolicyCrudKind } from '@zenstackhq/runtime'
8 | import metadata from './__model_meta';
9 | type DefaultError = QueryError;
10 | import { useSuspenseModelQuery, useSuspenseInfiniteModelQuery } from '@zenstackhq/tanstack-query/runtime-v5/react';
11 | import type { UseSuspenseQueryOptions, UseSuspenseInfiniteQueryOptions } from '@tanstack/react-query';
12 |
13 | export function useCreateSession(options?: Omit<(UseMutationOptions<(Session | undefined), DefaultError, Prisma.SessionCreateArgs> & ExtraMutationOptions), 'mutationFn'>) {
14 | const { endpoint, fetch } = getHooksContext();
15 | const _mutation =
16 | useModelMutation('Session', 'POST', `${endpoint}/session/create`, metadata, options, fetch, true)
17 | ;
18 | const mutation = {
19 | ..._mutation,
20 | mutateAsync: async (
21 | args: Prisma.SelectSubset,
22 | options?: Omit<(UseMutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'>
23 | ) => {
24 | return (await _mutation.mutateAsync(
25 | args,
26 | options as any
27 | )) as (CheckSelect