├── src ├── app.css ├── lib │ ├── constant.ts │ ├── prisma.ts │ ├── auth.ts │ ├── components │ │ ├── Avatar.svelte │ │ ├── TimeInfo.svelte │ │ ├── Spaces.svelte │ │ ├── BreadCrumb.svelte │ │ ├── SpaceMembers.svelte │ │ ├── NavBar.svelte │ │ ├── Todo.svelte │ │ ├── TodoList.svelte │ │ ├── CreateListDialog.svelte │ │ └── ManageMembers.svelte │ └── hooks │ │ ├── index.ts │ │ ├── __model_meta.ts │ │ ├── todo.ts │ │ ├── user.ts │ │ ├── list.ts │ │ ├── space.ts │ │ └── space-user.ts ├── routes │ ├── (app) │ │ ├── +page.server.ts │ │ ├── +layout.server.ts │ │ ├── +layout.svelte │ │ ├── space │ │ │ └── [slug] │ │ │ │ ├── +layout.server.ts │ │ │ │ ├── +page.server.ts │ │ │ │ ├── +page.svelte │ │ │ │ └── [listId] │ │ │ │ ├── +page.svelte │ │ │ │ └── +page.server.ts │ │ ├── +page.svelte │ │ └── create-space │ │ │ ├── +page.server.ts │ │ │ └── +page.svelte │ ├── api │ │ └── auth │ │ │ ├── signout │ │ │ └── +server.ts │ │ │ └── signin │ │ │ └── +server.ts │ ├── +layout.svelte │ └── (auth) │ │ ├── signin │ │ ├── +page.server.ts │ │ └── +page.svelte │ │ └── signup │ │ ├── +page.server.ts │ │ └── +page.svelte ├── app.html ├── app.d.ts ├── components │ └── List.svelte └── hooks.server.ts ├── static ├── logo.png ├── avatar.jpg └── auth-bg.jpg ├── postcss.config.js ├── .gitignore ├── prisma ├── migrations │ ├── migration_lock.toml │ ├── 20241222160427_add_space_owner │ │ └── migration.sql │ └── 20230905040838_init │ │ └── migration.sql └── schema.prisma ├── .env ├── tailwind.config.js ├── tsconfig.json ├── svelte.config.js ├── .github └── workflows │ ├── build.yml │ └── update.yml ├── vite.config.js ├── README.md ├── package.json └── schema.zmodel /src/app.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /src/lib/constant.ts: -------------------------------------------------------------------------------- 1 | export const JWT_TOKEN_COOKIE_NAME = 'ZenStack-Todo-Token'; 2 | -------------------------------------------------------------------------------- /static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenstackhq/sample-todo-sveltekit/HEAD/static/logo.png -------------------------------------------------------------------------------- /static/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenstackhq/sample-todo-sveltekit/HEAD/static/avatar.jpg -------------------------------------------------------------------------------- /static/auth-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenstackhq/sample-todo-sveltekit/HEAD/static/auth-bg.jpg -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | *.db 10 | -------------------------------------------------------------------------------- /prisma/migrations/migration_lock.toml: -------------------------------------------------------------------------------- 1 | # Please do not edit this file manually 2 | # It should be added in your version-control system (e.g., Git) 3 | provider = "postgresql" -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | DATABASE_URL=postgres://postgres:abc123@localhost:5432/todo-sveltekit 2 | DATABASE_DIRECT_URL=postgres://postgres:abc123@localhost:5432/todo-sveltekit 3 | JWT_SECRET=secret -------------------------------------------------------------------------------- /src/routes/(app)/+page.server.ts: -------------------------------------------------------------------------------- 1 | import type { PageServerLoad } from './$types'; 2 | 3 | export const load = (async ({ locals }) => { 4 | const spaces = await locals.db.space.findMany({ 5 | orderBy: { createdAt: 'desc' }, 6 | }); 7 | return { user: locals.user!, spaces }; 8 | }) satisfies PageServerLoad; 9 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: ['./src/**/*.{html,js,svelte,ts}'], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [require('daisyui'), require('@tailwindcss/line-clamp')], 8 | daisyui: { 9 | themes: false, 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /src/routes/api/auth/signout/+server.ts: -------------------------------------------------------------------------------- 1 | import { JWT_TOKEN_COOKIE_NAME } from '$lib/constant'; 2 | import { redirect, type RequestHandler } from '@sveltejs/kit'; 3 | 4 | export const POST = (({ cookies }) => { 5 | cookies.delete(JWT_TOKEN_COOKIE_NAME, { path: '/' }); 6 | throw redirect(303, '/signin'); 7 | }) satisfies RequestHandler; 8 | -------------------------------------------------------------------------------- /src/lib/prisma.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient } from '@prisma/client'; 2 | import { enhance } from '@zenstackhq/runtime'; 3 | 4 | const prisma = new PrismaClient(); 5 | 6 | export function getEnhancedPrisma(userId?: string) { 7 | return enhance(prisma, { user: userId ? { id: userId } : undefined }); 8 | } 9 | 10 | export default prisma; 11 | -------------------------------------------------------------------------------- /src/routes/(app)/+layout.server.ts: -------------------------------------------------------------------------------- 1 | import { redirect } from '@sveltejs/kit'; 2 | import type { LayoutServerLoad } from './$types'; 3 | 4 | export const load = (async ({ locals }) => { 5 | if (!locals.user) { 6 | throw redirect(303, '/signin'); 7 | } 8 | return { 9 | user: locals.user, 10 | }; 11 | }) satisfies LayoutServerLoad; 12 | -------------------------------------------------------------------------------- /src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %sveltekit.head% 8 | 9 | 10 |
%sveltekit.body%
11 | 12 | 13 | -------------------------------------------------------------------------------- /src/app.d.ts: -------------------------------------------------------------------------------- 1 | // See https://kit.svelte.dev/docs/types#app 2 | // for information about these interfaces 3 | 4 | import type { PrismaClient, User } from '@prisma/client'; 5 | 6 | declare global { 7 | namespace App { 8 | interface Locals { 9 | user?: User; 10 | db: PrismaClient; 11 | } 12 | } 13 | } 14 | 15 | export {}; 16 | -------------------------------------------------------------------------------- /src/lib/auth.ts: -------------------------------------------------------------------------------- 1 | import { env } from '$env/dynamic/private'; 2 | import type { User } from '@prisma/client'; 3 | import jwt from 'jsonwebtoken'; 4 | 5 | export function createToken(user: User) { 6 | return jwt.sign( 7 | { 8 | sub: user.id, 9 | email: user.email, 10 | }, 11 | env.JWT_SECRET, 12 | { expiresIn: '7d' } 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.svelte-kit/tsconfig.json", 3 | "compilerOptions": { 4 | "allowJs": true, 5 | "checkJs": true, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "resolveJsonModule": true, 9 | "skipLibCheck": true, 10 | "sourceMap": true, 11 | "strict": true 12 | }, 13 | "ts-node": { 14 | "esm": true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/routes/(app)/+layout.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 | 15 | 16 |
17 | -------------------------------------------------------------------------------- /src/routes/(app)/space/[slug]/+layout.server.ts: -------------------------------------------------------------------------------- 1 | import { error } from '@sveltejs/kit'; 2 | import type { LayoutServerLoad } from './$types'; 3 | 4 | export const load = (async ({ locals, params }) => { 5 | const space = await locals.db.space.findUnique({ 6 | where: { slug: params.slug }, 7 | }); 8 | if (!space) { 9 | throw error(404, 'Space not found'); 10 | } 11 | return { space }; 12 | }) satisfies LayoutServerLoad; 13 | -------------------------------------------------------------------------------- /prisma/migrations/20241222160427_add_space_owner/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - Added the required column `ownerId` to the `Space` table without a default value. This is not possible if the table is not empty. 5 | 6 | */ 7 | -- AlterTable 8 | ALTER TABLE "Space" ADD COLUMN "ownerId" TEXT NOT NULL; 9 | 10 | -- AddForeignKey 11 | ALTER TABLE "Space" ADD CONSTRAINT "Space_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; 12 | -------------------------------------------------------------------------------- /svelte.config.js: -------------------------------------------------------------------------------- 1 | import adapter from '@sveltejs/adapter-auto'; 2 | // import preprocess from 'svelte-preprocess'; 3 | import { vitePreprocess } from '@sveltejs/kit/vite'; 4 | 5 | /** @type {import('@sveltejs/kit').Config} */ 6 | const config = { 7 | // Consult https://github.com/sveltejs/svelte-preprocess 8 | // for more information about preprocessors 9 | preprocess: vitePreprocess(), 10 | 11 | kit: { 12 | adapter: adapter(), 13 | }, 14 | }; 15 | 16 | export default config; 17 | -------------------------------------------------------------------------------- /src/lib/components/Avatar.svelte: -------------------------------------------------------------------------------- 1 | 7 | 8 |
9 | avatar 15 |
16 | -------------------------------------------------------------------------------- /src/lib/components/TimeInfo.svelte: -------------------------------------------------------------------------------- 1 | 10 | 11 |

12 | {value.completedAt 13 | ? `Completed ${moment(value.completedAt).fromNow()}` 14 | : value.createdAt === value.updatedAt 15 | ? `Created ${moment(value.createdAt).fromNow()}` 16 | : `Updated ${moment(value.updatedAt).fromNow()}`} 17 |

18 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | env: 4 | DO_NOT_TRACK: '1' 5 | 6 | on: 7 | push: 8 | branches: ['main'] 9 | pull_request: 10 | branches: ['main'] 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v3 18 | - name: Use Node.js 20.x 19 | uses: actions/setup-node@v3 20 | with: 21 | node-version: 20.x 22 | cache: 'npm' 23 | - run: npm ci 24 | - run: npm run build 25 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { sveltekit } from '@sveltejs/kit/vite'; 2 | 3 | /** @type {import('vite').UserConfig} */ 4 | const config = { 5 | plugins: [sveltekit()], 6 | resolve: { 7 | alias: { 8 | '.prisma/client/index-browser': 9 | './node_modules/.prisma/client/index-browser.js', 10 | }, 11 | }, 12 | ssr: { 13 | // this is needed to make sure "vite" processes "@tanstack/svelte-query" imported inside 14 | // "@zenstackhq/tanstack-query" 15 | noExternal: ['@zenstackhq/tanstack-query'], 16 | }, 17 | }; 18 | 19 | export default config; 20 | -------------------------------------------------------------------------------- /src/lib/hooks/index.ts: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * This file was generated by ZenStack CLI. 3 | ******************************************************************************/ 4 | 5 | /* eslint-disable */ 6 | 7 | export * from './space'; 8 | export * from './space-user'; 9 | export * from './user'; 10 | export * from './list'; 11 | export * from './todo'; 12 | export { getQueryKey } from '@zenstackhq/tanstack-query/runtime-v5'; 13 | export { SvelteQueryContextKey, setHooksContext } from '@zenstackhq/tanstack-query/runtime-v5/svelte'; 14 | export { default as metadata } from './__model_meta'; 15 | -------------------------------------------------------------------------------- /src/lib/components/Spaces.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 | 21 | -------------------------------------------------------------------------------- /src/routes/+layout.svelte: -------------------------------------------------------------------------------- 1 | 17 | 18 |
19 | 20 | 21 | 22 |
23 | -------------------------------------------------------------------------------- /src/routes/(app)/+page.svelte: -------------------------------------------------------------------------------- 1 | 7 | 8 |
9 |

10 | Welcome {data.user.name || data.user.email}! 11 |

12 | 13 |
14 |

15 | Choose a space to start, or{' '} 16 | 17 | create a new one. 18 | 19 |

20 | 21 | 22 |
23 |
24 | -------------------------------------------------------------------------------- /src/routes/(app)/space/[slug]/+page.server.ts: -------------------------------------------------------------------------------- 1 | import type { PageServerLoad } from './$types'; 2 | 3 | export const load = (async ({ locals, params }) => { 4 | const lists = await locals.db.list.findMany({ 5 | where: { 6 | space: { slug: params.slug }, 7 | }, 8 | include: { 9 | owner: true, 10 | }, 11 | orderBy: { 12 | updatedAt: 'desc', 13 | }, 14 | }); 15 | 16 | const members = locals.db.spaceUser.findMany({ 17 | where: { 18 | space: { slug: params.slug }, 19 | }, 20 | include: { 21 | user: true, 22 | }, 23 | orderBy: { 24 | role: 'desc', 25 | }, 26 | }); 27 | 28 | return { 29 | lists, 30 | members, 31 | }; 32 | }) satisfies PageServerLoad; 33 | -------------------------------------------------------------------------------- /.github/workflows/update.yml: -------------------------------------------------------------------------------- 1 | name: Update ZenStack 2 | 3 | env: 4 | DO_NOT_TRACK: '1' 5 | 6 | on: 7 | workflow_dispatch: 8 | repository_dispatch: 9 | types: [zenstack-release] 10 | 11 | jobs: 12 | update: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v3 17 | - name: Update to latest ZenStack 18 | run: | 19 | git config --global user.name ymc9 20 | git config --global user.email yiming@whimslab.io 21 | npm ci 22 | npm run up 23 | 24 | - name: Build 25 | run: | 26 | npm run build 27 | 28 | - name: Commit and push 29 | run: | 30 | git add . 31 | git commit -m "chore: update to latest ZenStack" || true 32 | git push || true 33 | -------------------------------------------------------------------------------- /src/routes/api/auth/signin/+server.ts: -------------------------------------------------------------------------------- 1 | import { createToken } from '$lib/auth'; 2 | import { JWT_TOKEN_COOKIE_NAME } from '$lib/constant'; 3 | import prisma from '$lib/prisma'; 4 | import { error, json, type RequestHandler } from '@sveltejs/kit'; 5 | import bcrypt from 'bcryptjs'; 6 | 7 | export const POST = (async ({ request, cookies }) => { 8 | const { email, password } = await request.json(); 9 | 10 | if (typeof email !== 'string' || typeof password !== 'string') { 11 | throw error(400, 'Invalid credentials'); 12 | } 13 | 14 | const user = await prisma.user.findFirst({ 15 | where: { email }, 16 | }); 17 | if (!user || !bcrypt.compareSync(password, user.password)) { 18 | throw error(401, 'Invalid credentials'); 19 | } 20 | 21 | const token = createToken(user); 22 | cookies.set(JWT_TOKEN_COOKIE_NAME, token, { 23 | httpOnly: true, 24 | expires: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), 25 | path: '/', 26 | }); 27 | return json({ success: true, data: user }); 28 | }) satisfies RequestHandler; 29 | -------------------------------------------------------------------------------- /src/components/List.svelte: -------------------------------------------------------------------------------- 1 | 25 | 26 |
27 | {#if $posts.data} 28 | {#each $posts.data.pages as page} 29 | {#each page as post (post.id)} 30 |
  • {post.title} by {post.author.email}
  • 31 | {/each} 32 | {/each} 33 | {/if} 34 | {#if $posts.hasNextPage} 35 | 36 | {/if} 37 |
    38 | -------------------------------------------------------------------------------- /src/lib/components/BreadCrumb.svelte: -------------------------------------------------------------------------------- 1 | 24 | 25 | 38 | -------------------------------------------------------------------------------- /src/routes/(auth)/signin/+page.server.ts: -------------------------------------------------------------------------------- 1 | import { createToken } from '$lib/auth'; 2 | import { JWT_TOKEN_COOKIE_NAME } from '$lib/constant'; 3 | import prisma from '$lib/prisma'; 4 | import { fail, redirect, type Actions } from '@sveltejs/kit'; 5 | import bcrypt from 'bcryptjs'; 6 | 7 | export const actions = { 8 | default: async ({ request, cookies }) => { 9 | const data = await request.formData(); 10 | 11 | const email = data.get('email'); 12 | const password = data.get('password'); 13 | 14 | if (typeof email !== 'string' || typeof password !== 'string') { 15 | return fail(400, { email, password, missing: true }); 16 | } 17 | 18 | const user = await prisma.user.findFirst({ 19 | where: { email }, 20 | }); 21 | if (!user || !bcrypt.compareSync(password, user.password)) { 22 | return fail(401, { email, password, invalid: true }); 23 | } 24 | 25 | const token = createToken(user); 26 | cookies.set(JWT_TOKEN_COOKIE_NAME, token, { 27 | httpOnly: true, 28 | expires: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), 29 | path: '/', 30 | }); 31 | throw redirect(303, `/`); 32 | }, 33 | } satisfies Actions; 34 | -------------------------------------------------------------------------------- /src/routes/(app)/space/[slug]/+page.svelte: -------------------------------------------------------------------------------- 1 | 10 | 11 |
    12 |
    13 | 14 |
    15 |
    16 |
    19 | 25 | 26 |
    27 | 28 | 35 |
    36 | 37 |
    38 | -------------------------------------------------------------------------------- /src/routes/(app)/space/[slug]/[listId]/+page.svelte: -------------------------------------------------------------------------------- 1 | 11 | 12 |
    13 | 14 |
    15 |
    16 |

    17 | {data.list?.title} 18 |

    19 |
    20 | 21 | 29 | 32 |
    33 | 38 |
    39 | -------------------------------------------------------------------------------- /src/hooks.server.ts: -------------------------------------------------------------------------------- 1 | import { env } from '$env/dynamic/private'; 2 | import { JWT_TOKEN_COOKIE_NAME } from '$lib/constant'; 3 | import prisma, { getEnhancedPrisma } from '$lib/prisma'; 4 | import type { Handle } from '@sveltejs/kit'; 5 | import { sequence } from '@sveltejs/kit/hooks'; 6 | import zenstack from '@zenstackhq/server/sveltekit'; 7 | import jwt from 'jsonwebtoken'; 8 | 9 | const auth = (async ({ event, resolve }) => { 10 | const token = event.cookies.get(JWT_TOKEN_COOKIE_NAME); 11 | if (token) { 12 | try { 13 | const decoded = jwt.verify(token, env.JWT_SECRET); 14 | const user = await prisma.user.findUnique({ 15 | where: { id: decoded.sub as string }, 16 | }); 17 | if (user) { 18 | event.locals.user = user; 19 | } else { 20 | console.warn('User not found:', decoded.sub); 21 | event.cookies.delete(JWT_TOKEN_COOKIE_NAME, { path: '/' }); 22 | } 23 | } catch { 24 | event.cookies.delete(JWT_TOKEN_COOKIE_NAME, { path: '/' }); 25 | } 26 | } 27 | 28 | event.locals.db = getEnhancedPrisma( 29 | event.locals.user ? event.locals.user.id : undefined 30 | ); 31 | 32 | return resolve(event); 33 | }) satisfies Handle; 34 | 35 | const crud = zenstack.SvelteKitHandler({ 36 | prefix: '/api/model', 37 | getPrisma: (event) => event.locals.db, 38 | }); 39 | 40 | export const handle = sequence(auth, crud); 41 | -------------------------------------------------------------------------------- /src/lib/components/SpaceMembers.svelte: -------------------------------------------------------------------------------- 1 | 11 | 12 |
    13 | 16 | 17 |
    18 | 23 |
    24 | 25 | 26 | 27 | 44 |
    45 | -------------------------------------------------------------------------------- /src/routes/(app)/create-space/+page.server.ts: -------------------------------------------------------------------------------- 1 | import { SpaceUserRole, type Space } from '@prisma/client'; 2 | import { error, fail, redirect, type Actions } from '@sveltejs/kit'; 3 | import { isPrismaClientKnownRequestError } from '@zenstackhq/runtime'; 4 | 5 | export const actions = { 6 | default: async ({ request, locals }) => { 7 | if (!locals.user) { 8 | throw error(401, 'Unauthorized'); 9 | } 10 | 11 | const data = await request.formData(); 12 | const name = data.get('name'); 13 | const slug = data.get('slug'); 14 | 15 | if (typeof name !== 'string' || typeof slug !== 'string') { 16 | return fail(400, { name, slug, missing: true }); 17 | } 18 | 19 | let space: Space; 20 | try { 21 | space = await locals.db.space.create({ 22 | data: { 23 | name, 24 | slug, 25 | owner: { connect: { id: locals.user.id } }, 26 | members: { 27 | create: { 28 | user: { connect: { id: locals.user.id } }, 29 | role: SpaceUserRole.ADMIN, 30 | }, 31 | }, 32 | }, 33 | }); 34 | } catch (err) { 35 | if (isPrismaClientKnownRequestError(err) && err.code === 'P2002') { 36 | return fail(400, { name, slug, dup: true }); 37 | } else { 38 | throw err; 39 | } 40 | } 41 | 42 | throw redirect(303, `/space/${space.slug}`); 43 | }, 44 | } satisfies Actions; 45 | -------------------------------------------------------------------------------- /src/routes/(app)/space/[slug]/[listId]/+page.server.ts: -------------------------------------------------------------------------------- 1 | import { error } from '@sveltejs/kit'; 2 | import type { Actions, PageServerLoad } from './$types'; 3 | 4 | export const load = (async ({ locals, params }) => { 5 | const list = await locals.db.list.findUnique({ 6 | where: { id: params?.listId as string }, 7 | }); 8 | if (!list) { 9 | throw error(404, 'List not found'); 10 | } 11 | 12 | const todos = await locals.db.todo.findMany({ 13 | where: { listId: params?.listId as string }, 14 | include: { 15 | owner: true, 16 | }, 17 | orderBy: { 18 | updatedAt: 'desc', 19 | }, 20 | }); 21 | return { list, todos }; 22 | }) satisfies PageServerLoad; 23 | 24 | export const actions = { 25 | create: async ({ request, locals, params }) => { 26 | const data = await request.formData(); 27 | const title = data.get('title') as string; 28 | await locals.db.todo.create({ 29 | data: { 30 | title, 31 | list: { connect: { id: params.listId } }, 32 | }, 33 | }); 34 | }, 35 | 36 | complete: async ({ request, locals }) => { 37 | const data = await request.formData(); 38 | const todoId = data.get('todoId') as string; 39 | const completed = data.get('completed') as string; 40 | await locals.db.todo.update({ 41 | where: { id: todoId }, 42 | data: { completedAt: completed === 'on' ? new Date() : null }, 43 | }); 44 | }, 45 | 46 | delete: async ({ request, locals }) => { 47 | const data = await request.formData(); 48 | const todoId = data.get('todoId') as string; 49 | await locals.db.todo.delete({ where: { id: todoId } }); 50 | }, 51 | } satisfies Actions; 52 | -------------------------------------------------------------------------------- /src/lib/components/NavBar.svelte: -------------------------------------------------------------------------------- 1 | 10 | 11 | 47 | -------------------------------------------------------------------------------- /src/routes/(app)/create-space/+page.svelte: -------------------------------------------------------------------------------- 1 | 11 | 12 |
    13 |
    14 |

    Create a space

    15 | {#if form?.dup} 16 |

    Slug already in use!

    17 | {/if} 18 |
    19 |
    20 | 21 | 22 | 31 |
    32 |
    33 | 34 | 42 |
    43 |
    44 | 45 |
    46 | 20 || 50 | !slug.match(/^[0-9a-zA-Z]{4,16}$/)} 51 | value="Create" 52 | class="btn btn-primary px-8" 53 | /> 54 | 57 |
    58 |
    59 |
    60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
    2 | 3 |

    ZenStack SaaS Demo

    4 | 5 | 6 | 7 | 8 | 9 | 10 |
    11 | 12 | # ZenStack Todo Sample With SvelteKit 13 | 14 | This project is a collaborative Todo app built with [SvelteKit](https://kit.svelte.dev/) and [ZenStack](https://zenstack.dev). 15 | 16 | In this fictitious app, users can be invited to workspaces where they can collaborate on todos. Public todo lists are visible to all members in the workspace. 17 | 18 | ## Live deployment 19 | https://sample-todo-sveltekit.vercel.app/ 20 | 21 | ## Features 22 | 23 | - User signup/signin 24 | - Creating workspaces and inviting members 25 | - Data segregation and permission control 26 | 27 | ## Running the sample 28 | 29 | 1. Setup a new database 30 | 31 | It use PostgreSQL by default, if you want to use MySQL, simply change the db datasource provider to `mysql` in `schema.zmodel` file. 32 | 33 | You can launch a PostgreSQL instance locally, or create one from a hoster like [Supabase](https://supabase.com). Create a new database for this app, and set the connection string in .env file. 34 | 35 | 1. Install dependencies 36 | 37 | ```bash 38 | npm install 39 | ``` 40 | 41 | 1. Generate server and client-side code from model 42 | 43 | ```bash 44 | npm run generate 45 | ``` 46 | 47 | 1. Synchronize database schema 48 | 49 | ```bash 50 | npm run db:push 51 | ``` 52 | 53 | 1. Start dev server 54 | 55 | ```bash 56 | npm run dev 57 | ``` 58 | 59 | 60 | 61 | ## Feedback and Issues 62 | If you encounter any issue or have any feedback, please create a new issue in our main repository so we could respond to it promptly: 63 | 64 | [https://github.com/zenstackhq/zenstack](https://github.com/zenstackhq/zenstack) 65 | -------------------------------------------------------------------------------- /src/lib/components/Todo.svelte: -------------------------------------------------------------------------------- 1 | 13 | 14 |
    17 |
    18 |

    25 | {value.title} 26 |

    27 |
    28 |
    34 | 35 | completeForm.submit()} 41 | /> 42 |
    43 |
    49 | 50 | 56 |
    57 |
    58 |
    59 |
    60 | 61 | 62 |
    63 |
    64 | -------------------------------------------------------------------------------- /src/routes/(auth)/signup/+page.server.ts: -------------------------------------------------------------------------------- 1 | import { createToken } from '$lib/auth'; 2 | import { JWT_TOKEN_COOKIE_NAME } from '$lib/constant'; 3 | import { getEnhancedPrisma } from '$lib/prisma'; 4 | import { SpaceUserRole } from '@prisma/client'; 5 | import { fail, redirect, type Actions } from '@sveltejs/kit'; 6 | import { isPrismaClientKnownRequestError } from '@zenstackhq/runtime'; 7 | import { nanoid } from 'nanoid'; 8 | 9 | export const actions = { 10 | default: async ({ request, cookies, locals }) => { 11 | const data = await request.formData(); 12 | 13 | const email = data.get('email'); 14 | const password = data.get('password'); 15 | 16 | if (typeof email !== 'string' || typeof password !== 'string') { 17 | return fail(400, { email, password, missing: true }); 18 | } 19 | 20 | let db = locals.db; 21 | 22 | try { 23 | // create the user together with a default space 24 | const user = await db.user.create({ 25 | data: { 26 | email, 27 | password, 28 | }, 29 | }); 30 | 31 | // use db under the context of the new user 32 | db = getEnhancedPrisma(user.id); 33 | 34 | const space = await db.space.create({ 35 | data: { 36 | name: `My Space`, 37 | slug: nanoid(8), 38 | owner: { connect: { id: user.id } }, 39 | members: { 40 | create: { 41 | user: { connect: { id: user.id } }, 42 | role: SpaceUserRole.ADMIN, 43 | }, 44 | }, 45 | }, 46 | }); 47 | console.log('Space created for user:', space); 48 | 49 | const token = createToken(user); 50 | cookies.set(JWT_TOKEN_COOKIE_NAME, token, { 51 | httpOnly: true, 52 | expires: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), 53 | path: '/', 54 | }); 55 | } catch (err) { 56 | if (isPrismaClientKnownRequestError(err) && err.code === 'P2002') { 57 | return fail(400, { email, password, dup: true }); 58 | } else { 59 | throw err; 60 | } 61 | } 62 | 63 | throw redirect(303, `/`); 64 | }, 65 | } satisfies Actions; 66 | -------------------------------------------------------------------------------- /src/lib/components/TodoList.svelte: -------------------------------------------------------------------------------- 1 | 30 | 31 |
    32 | 33 |
    34 | Cover 41 |
    42 |
    43 |
    44 | 45 |

    46 | {value.title || 'Missing Title'} 47 |

    48 |
    49 |
    50 |
    51 | 52 |
    53 |
    54 | 55 | {#if value.private} 56 |
    57 | 58 |
    59 | {/if} 60 |
    61 | 62 | 68 |
    69 |
    70 |
    71 |
    72 |
    73 | -------------------------------------------------------------------------------- /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 = "postgresql" 8 | url = env("DATABASE_URL") 9 | directUrl = env("DATABASE_DIRECT_URL") 10 | } 11 | 12 | generator client { 13 | provider = "prisma-client-js" 14 | } 15 | 16 | enum SpaceUserRole { 17 | USER 18 | ADMIN 19 | } 20 | 21 | model Space { 22 | id String @id() @default(uuid()) 23 | createdAt DateTime @default(now()) 24 | updatedAt DateTime @updatedAt() 25 | owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade) 26 | ownerId String 27 | name String 28 | slug String @unique() 29 | members SpaceUser[] 30 | lists List[] 31 | } 32 | 33 | model SpaceUser { 34 | id String @id() @default(uuid()) 35 | createdAt DateTime @default(now()) 36 | updatedAt DateTime @updatedAt() 37 | space Space @relation(fields: [spaceId], references: [id], onDelete: Cascade) 38 | spaceId String 39 | user User @relation(fields: [userId], references: [id], onDelete: Cascade) 40 | userId String 41 | role SpaceUserRole 42 | 43 | @@unique([userId, spaceId]) 44 | } 45 | 46 | model User { 47 | id String @id() @default(cuid()) 48 | email String @unique() 49 | password String 50 | name String? 51 | ownedSpaces Space[] 52 | memberships SpaceUser[] 53 | todos Todo[] 54 | lists List[] 55 | } 56 | 57 | model List { 58 | id String @id() @default(uuid()) 59 | createdAt DateTime @default(now()) 60 | updatedAt DateTime @updatedAt() 61 | space Space @relation(fields: [spaceId], references: [id], onDelete: Cascade) 62 | spaceId String 63 | owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade) 64 | ownerId String 65 | title String 66 | private Boolean @default(false) 67 | todos Todo[] 68 | } 69 | 70 | model Todo { 71 | id String @id() @default(uuid()) 72 | createdAt DateTime @default(now()) 73 | updatedAt DateTime @updatedAt() 74 | owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade) 75 | ownerId String 76 | list List @relation(fields: [listId], references: [id], onDelete: Cascade) 77 | listId String 78 | title String 79 | completedAt DateTime? 80 | } 81 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rest-sveltekit", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "generate": "zenstack generate", 7 | "dev": "vite dev", 8 | "build": "npm run generate && vite build", 9 | "vercel-build": "npm run build && npm run db:deploy", 10 | "preview": "vite preview", 11 | "db:push": "prisma db push", 12 | "db:migrate": "prisma migrate dev", 13 | "db:deploy": "prisma migrate deploy", 14 | "db:reset": "prisma migrate reset", 15 | "db:browse": "prisma studio", 16 | "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", 17 | "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", 18 | "package-clean": "npm rm zenstack @zenstackhq/runtime @zenstackhq/server @zenstackhq/tanstack-query", 19 | "up": "npm run package-clean && npm install -D zenstack@latest && npm install @zenstackhq/runtime@latest @zenstackhq/server@latest @zenstackhq/tanstack-query@latest", 20 | "up-preview": "npm run package-clean && npm install --registry https://preview.registry.zenstack.dev -D zenstack@latest && npm install --registry https://preview.registry.zenstack.dev @zenstackhq/runtime@latest @zenstackhq/server@latest @zenstackhq/tanstack-query@latest" 21 | }, 22 | "devDependencies": { 23 | "@sveltejs/adapter-auto": "^2.1.0", 24 | "@sveltejs/kit": "^1.22.4", 25 | "@sveltejs/package": "^2.2.0", 26 | "@tailwindcss/line-clamp": "^0.4.4", 27 | "@types/bcryptjs": "^2.4.2", 28 | "@types/jsonwebtoken": "^9.0.1", 29 | "@typescript-eslint/eslint-plugin": "^5.45.0", 30 | "@typescript-eslint/parser": "^5.45.0", 31 | "autoprefixer": "^10.4.14", 32 | "eslint": "^8.28.0", 33 | "eslint-config-prettier": "^8.5.0", 34 | "postcss": "^8.4.23", 35 | "prettier": "^2.8.0", 36 | "prettier-plugin-svelte": "^2.8.1", 37 | "prisma": "^6.5.0", 38 | "svelte": "^4.1.2", 39 | "svelte-check": "^3.4.6", 40 | "tailwindcss": "^3.3.2", 41 | "ts-node": "10.9.1", 42 | "tslib": "^2.4.1", 43 | "typescript": "^5.8.2", 44 | "vite": "^4.4.4", 45 | "zenstack": "^2.22.1" 46 | }, 47 | "type": "module", 48 | "dependencies": { 49 | "@prisma/client": "^6.5.0", 50 | "@steeze-ui/heroicons": "^2.2.3", 51 | "@steeze-ui/svelte-icon": "^1.5.0", 52 | "@tanstack/svelte-query": "^4.32.6", 53 | "@zenstackhq/runtime": "^2.22.1", 54 | "@zenstackhq/server": "^2.22.1", 55 | "@zenstackhq/tanstack-query": "^2.22.1", 56 | "bcryptjs": "^2.4.3", 57 | "daisyui": "^2.51.5", 58 | "jsonwebtoken": "^9.0.0", 59 | "moment": "^2.29.4", 60 | "nanoid": "^4.0.2", 61 | "superjson": "^1.12.3", 62 | "zod": "^3.25.0", 63 | "zod-validation-error": "^1.3.0" 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /prisma/migrations/20230905040838_init/migration.sql: -------------------------------------------------------------------------------- 1 | -- CreateEnum 2 | CREATE TYPE "SpaceUserRole" AS ENUM ('USER', 'ADMIN'); 3 | 4 | -- CreateTable 5 | CREATE TABLE "Space" ( 6 | "id" TEXT NOT NULL, 7 | "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, 8 | "updatedAt" TIMESTAMP(3) NOT NULL, 9 | "name" TEXT NOT NULL, 10 | "slug" TEXT NOT NULL, 11 | 12 | CONSTRAINT "Space_pkey" PRIMARY KEY ("id") 13 | ); 14 | 15 | -- CreateTable 16 | CREATE TABLE "SpaceUser" ( 17 | "id" TEXT NOT NULL, 18 | "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, 19 | "updatedAt" TIMESTAMP(3) NOT NULL, 20 | "spaceId" TEXT NOT NULL, 21 | "userId" TEXT NOT NULL, 22 | "role" "SpaceUserRole" NOT NULL, 23 | 24 | CONSTRAINT "SpaceUser_pkey" PRIMARY KEY ("id") 25 | ); 26 | 27 | -- CreateTable 28 | CREATE TABLE "User" ( 29 | "id" TEXT NOT NULL, 30 | "email" TEXT NOT NULL, 31 | "password" TEXT NOT NULL, 32 | "name" TEXT, 33 | 34 | CONSTRAINT "User_pkey" PRIMARY KEY ("id") 35 | ); 36 | 37 | -- CreateTable 38 | CREATE TABLE "List" ( 39 | "id" TEXT NOT NULL, 40 | "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, 41 | "updatedAt" TIMESTAMP(3) NOT NULL, 42 | "spaceId" TEXT NOT NULL, 43 | "ownerId" TEXT NOT NULL, 44 | "title" TEXT NOT NULL, 45 | "private" BOOLEAN NOT NULL DEFAULT false, 46 | 47 | CONSTRAINT "List_pkey" PRIMARY KEY ("id") 48 | ); 49 | 50 | -- CreateTable 51 | CREATE TABLE "Todo" ( 52 | "id" TEXT NOT NULL, 53 | "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, 54 | "updatedAt" TIMESTAMP(3) NOT NULL, 55 | "ownerId" TEXT NOT NULL, 56 | "listId" TEXT NOT NULL, 57 | "title" TEXT NOT NULL, 58 | "completedAt" TIMESTAMP(3), 59 | 60 | CONSTRAINT "Todo_pkey" PRIMARY KEY ("id") 61 | ); 62 | 63 | -- CreateIndex 64 | CREATE UNIQUE INDEX "Space_slug_key" ON "Space"("slug"); 65 | 66 | -- CreateIndex 67 | CREATE UNIQUE INDEX "SpaceUser_userId_spaceId_key" ON "SpaceUser"("userId", "spaceId"); 68 | 69 | -- CreateIndex 70 | CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); 71 | 72 | -- AddForeignKey 73 | ALTER TABLE "SpaceUser" ADD CONSTRAINT "SpaceUser_spaceId_fkey" FOREIGN KEY ("spaceId") REFERENCES "Space"("id") ON DELETE CASCADE ON UPDATE CASCADE; 74 | 75 | -- AddForeignKey 76 | ALTER TABLE "SpaceUser" ADD CONSTRAINT "SpaceUser_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; 77 | 78 | -- AddForeignKey 79 | ALTER TABLE "List" ADD CONSTRAINT "List_spaceId_fkey" FOREIGN KEY ("spaceId") REFERENCES "Space"("id") ON DELETE CASCADE ON UPDATE CASCADE; 80 | 81 | -- AddForeignKey 82 | ALTER TABLE "List" ADD CONSTRAINT "List_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; 83 | 84 | -- AddForeignKey 85 | ALTER TABLE "Todo" ADD CONSTRAINT "Todo_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; 86 | 87 | -- AddForeignKey 88 | ALTER TABLE "Todo" ADD CONSTRAINT "Todo_listId_fkey" FOREIGN KEY ("listId") REFERENCES "List"("id") ON DELETE CASCADE ON UPDATE CASCADE; 89 | -------------------------------------------------------------------------------- /src/lib/components/CreateListDialog.svelte: -------------------------------------------------------------------------------- 1 | 41 | 42 |
    43 | 49 | 95 |
    96 | -------------------------------------------------------------------------------- /src/lib/components/ManageMembers.svelte: -------------------------------------------------------------------------------- 1 | 67 | 68 |
    69 |
    74 | 81 | 82 | 86 | 87 | 90 |
    91 | 92 | 117 |
    118 | -------------------------------------------------------------------------------- /src/routes/(auth)/signin/+page.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 |
    8 |
    11 | 12 |
    13 | logo 14 |

    Welcome to Todo

    15 |
    16 |
    17 |
    20 |
    21 |

    22 | Sign in to your account 23 |

    24 |
    25 | {#if form?.missing} 26 |

    Missing field required!

    27 | {/if} 28 | {#if form?.invalid} 29 |

    30 | Invalid email and password combination! 31 |

    32 | {/if} 33 |
    34 | 40 | 49 |
    50 |
    51 | 57 | 66 |
    67 |
    68 |
    69 |
    70 | 77 |
    78 |
    79 | 85 |
    86 |
    87 |
    88 | 91 |
    92 | Not registered? {' '} 93 | 94 | Create Account 95 | 96 |
    97 |
    98 |
    99 |
    100 |
    101 |
    102 | -------------------------------------------------------------------------------- /src/routes/(auth)/signup/+page.svelte: -------------------------------------------------------------------------------- 1 | 7 | 8 |
    9 |
    12 | 13 |
    14 | logo 15 |

    Welcome to Todo

    16 |
    17 |
    18 |
    21 |
    22 |

    23 | Create a Free Account 24 |

    25 |
    26 | {#if form?.dup} 27 |

    28 | Email already registered! 29 |

    30 | {/if} 31 |
    32 | 38 | 47 |
    48 |
    49 | 55 | 64 |
    65 |
    66 |
    67 | 75 |
    76 |
    77 | 90 |
    91 |
    92 | 95 |
    96 | Already have an account?{' '} 97 | 98 | Login here 99 | 100 |
    101 |
    102 |
    103 |
    104 |
    105 |
    106 | -------------------------------------------------------------------------------- /schema.zmodel: -------------------------------------------------------------------------------- 1 | generator client { 2 | provider = "prisma-client-js" 3 | } 4 | 5 | datasource db { 6 | provider = 'postgresql' 7 | url = env('DATABASE_URL') 8 | directUrl = env('DATABASE_DIRECT_URL') 9 | } 10 | 11 | /* 12 | * Enum for user's role in a space 13 | */ 14 | enum SpaceUserRole { 15 | USER 16 | ADMIN 17 | } 18 | 19 | plugin hooks { 20 | provider = '@zenstackhq/tanstack-query' 21 | output = 'src/lib/hooks' 22 | target = 'svelte' 23 | } 24 | 25 | /* 26 | * Model for a space in which users can collaborate on Lists and Todos 27 | */ 28 | model Space { 29 | id String @id @default(uuid()) 30 | createdAt DateTime @default(now()) 31 | updatedAt DateTime @updatedAt 32 | owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade) 33 | ownerId String @default(auth().id) 34 | name String @length(4, 50) 35 | slug String @unique @regex('^[0-9a-zA-Z\-_]{4,16}$') 36 | members SpaceUser[] 37 | lists List[] 38 | 39 | // require login 40 | @@deny('all', auth() == null) 41 | 42 | // everyone can create a space 43 | @@allow('create', true) 44 | 45 | // any user in the space can read the space 46 | @@allow('read', members?[user == auth()]) 47 | 48 | // space admin can update and delete 49 | @@allow('update,delete', members?[user == auth() && role == ADMIN]) 50 | } 51 | 52 | /* 53 | * Model representing membership of a user in a space 54 | */ 55 | model SpaceUser { 56 | id String @id @default(uuid()) 57 | createdAt DateTime @default(now()) 58 | updatedAt DateTime @updatedAt 59 | space Space @relation(fields: [spaceId], references: [id], onDelete: Cascade) 60 | spaceId String 61 | user User @relation(fields: [userId], references: [id], onDelete: Cascade) 62 | userId String 63 | role SpaceUserRole 64 | @@unique([userId, spaceId]) 65 | 66 | // require login 67 | @@deny('all', auth() == null) 68 | 69 | // space owner can add any one 70 | @@allow('create', space.owner == auth()) 71 | 72 | // space admin can add anyone but not himself 73 | @@allow('create', auth() != user && space.members?[user == auth() && role == ADMIN]) 74 | 75 | // space admin can update/delete 76 | @@allow('update,delete', space.members?[user == auth() && role == ADMIN]) 77 | 78 | // user can read entries for spaces which he's a member of 79 | @@allow('read', space.members?[user == auth()]) 80 | } 81 | 82 | /* 83 | * User model 84 | */ 85 | model User { 86 | id String @id @default(cuid()) 87 | email String @unique @email 88 | password String @password @omit @length(6, 32) 89 | name String? 90 | ownedSpaces Space[] 91 | memberships SpaceUser[] 92 | todos Todo[] 93 | lists List[] 94 | @@allow('create,read', true) 95 | @@allow('all', auth() == this) 96 | } 97 | 98 | /* 99 | * Model for a Todo list 100 | */ 101 | model List { 102 | id String @id @default(uuid()) 103 | createdAt DateTime @default(now()) 104 | updatedAt DateTime @updatedAt 105 | space Space @relation(fields: [spaceId], references: [id], onDelete: Cascade) 106 | spaceId String 107 | owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade) 108 | ownerId String @default(auth().id) 109 | title String @length(1, 100) 110 | private Boolean @default(false) 111 | todos Todo[] 112 | 113 | // require login 114 | @@deny('all', auth() == null) 115 | 116 | // can be read by owner or space members (only if not private) 117 | @@allow('read', owner == auth() || (space.members?[user == auth()] && !private)) 118 | 119 | // when create, owner must be set to current user, and user must be in the space 120 | @@allow('create', owner == auth() && space.members?[user == auth()]) 121 | 122 | // when create, owner must be set to current user, and user must be in the space 123 | // update is not allowed to change owner 124 | @@allow('update', owner == auth() && space.members?[user == auth()] && future().owner == owner) 125 | 126 | // can be deleted by owner 127 | @@allow('delete', owner == auth()) 128 | } 129 | 130 | /* 131 | * Model for a single Todo 132 | */ 133 | model Todo { 134 | id String @id @default(uuid()) 135 | createdAt DateTime @default(now()) 136 | updatedAt DateTime @updatedAt 137 | owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade) 138 | ownerId String @default(auth().id) 139 | list List @relation(fields: [listId], references: [id], onDelete: Cascade) 140 | listId String 141 | title String @length(1, 100) 142 | completedAt DateTime? 143 | 144 | // require login 145 | @@deny('all', auth() == null) 146 | 147 | // owner has full access, also space members have full access (if the parent List is not private) 148 | @@allow('all', list.owner == auth()) 149 | @@allow('all', list.space.members?[user == auth()] && !list.private) 150 | 151 | // update cannot change owner 152 | @@deny('update', future().owner != owner) 153 | } 154 | -------------------------------------------------------------------------------- /src/lib/hooks/__model_meta.ts: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * This file was generated by ZenStack CLI. 3 | ******************************************************************************/ 4 | 5 | /* eslint-disable */ 6 | 7 | import type { ModelMeta } from "@zenstackhq/runtime"; 8 | 9 | const metadata: ModelMeta = { 10 | models: { 11 | space: { 12 | name: 'Space', fields: { 13 | id: { 14 | name: "id", 15 | type: "String", 16 | isId: true, 17 | attributes: [{ "name": "@default", "args": [{ "name": "value" }] }], 18 | }, createdAt: { 19 | name: "createdAt", 20 | type: "DateTime", 21 | attributes: [{ "name": "@default", "args": [{ "name": "value" }] }], 22 | }, updatedAt: { 23 | name: "updatedAt", 24 | type: "DateTime", 25 | attributes: [{ "name": "@updatedAt", "args": [] }], 26 | }, owner: { 27 | name: "owner", 28 | type: "User", 29 | isDataModel: true, 30 | backLink: 'ownedSpaces', 31 | isRelationOwner: true, 32 | onDeleteAction: 'Cascade', 33 | foreignKeyMapping: { "id": "ownerId" }, 34 | }, ownerId: { 35 | name: "ownerId", 36 | type: "String", 37 | attributes: [{ "name": "@default", "args": [{ "name": "value" }] }], 38 | defaultValueProvider: $default$Space$ownerId, 39 | isForeignKey: true, 40 | relationField: 'owner', 41 | }, name: { 42 | name: "name", 43 | type: "String", 44 | }, slug: { 45 | name: "slug", 46 | type: "String", 47 | }, members: { 48 | name: "members", 49 | type: "SpaceUser", 50 | isDataModel: true, 51 | isArray: true, 52 | backLink: 'space', 53 | }, lists: { 54 | name: "lists", 55 | type: "List", 56 | isDataModel: true, 57 | isArray: true, 58 | backLink: 'space', 59 | }, 60 | }, uniqueConstraints: { 61 | id: { 62 | name: "id", 63 | fields: ["id"] 64 | }, slug: { 65 | name: "slug", 66 | fields: ["slug"] 67 | }, 68 | }, 69 | }, 70 | spaceUser: { 71 | name: 'SpaceUser', fields: { 72 | id: { 73 | name: "id", 74 | type: "String", 75 | isId: true, 76 | attributes: [{ "name": "@default", "args": [{ "name": "value" }] }], 77 | }, createdAt: { 78 | name: "createdAt", 79 | type: "DateTime", 80 | attributes: [{ "name": "@default", "args": [{ "name": "value" }] }], 81 | }, updatedAt: { 82 | name: "updatedAt", 83 | type: "DateTime", 84 | attributes: [{ "name": "@updatedAt", "args": [] }], 85 | }, space: { 86 | name: "space", 87 | type: "Space", 88 | isDataModel: true, 89 | backLink: 'members', 90 | isRelationOwner: true, 91 | onDeleteAction: 'Cascade', 92 | foreignKeyMapping: { "id": "spaceId" }, 93 | }, spaceId: { 94 | name: "spaceId", 95 | type: "String", 96 | isForeignKey: true, 97 | relationField: 'space', 98 | }, user: { 99 | name: "user", 100 | type: "User", 101 | isDataModel: true, 102 | backLink: 'memberships', 103 | isRelationOwner: true, 104 | onDeleteAction: 'Cascade', 105 | foreignKeyMapping: { "id": "userId" }, 106 | }, userId: { 107 | name: "userId", 108 | type: "String", 109 | isForeignKey: true, 110 | relationField: 'user', 111 | }, role: { 112 | name: "role", 113 | type: "SpaceUserRole", 114 | }, 115 | }, uniqueConstraints: { 116 | id: { 117 | name: "id", 118 | fields: ["id"] 119 | }, userId_spaceId: { 120 | name: "userId_spaceId", 121 | fields: ["userId", "spaceId"] 122 | }, 123 | }, 124 | }, 125 | user: { 126 | name: 'User', fields: { 127 | id: { 128 | name: "id", 129 | type: "String", 130 | isId: true, 131 | attributes: [{ "name": "@default", "args": [{ "name": "value" }] }], 132 | }, email: { 133 | name: "email", 134 | type: "String", 135 | }, password: { 136 | name: "password", 137 | type: "String", 138 | }, name: { 139 | name: "name", 140 | type: "String", 141 | isOptional: true, 142 | }, ownedSpaces: { 143 | name: "ownedSpaces", 144 | type: "Space", 145 | isDataModel: true, 146 | isArray: true, 147 | backLink: 'owner', 148 | }, memberships: { 149 | name: "memberships", 150 | type: "SpaceUser", 151 | isDataModel: true, 152 | isArray: true, 153 | backLink: 'user', 154 | }, todos: { 155 | name: "todos", 156 | type: "Todo", 157 | isDataModel: true, 158 | isArray: true, 159 | backLink: 'owner', 160 | }, lists: { 161 | name: "lists", 162 | type: "List", 163 | isDataModel: true, 164 | isArray: true, 165 | backLink: 'owner', 166 | }, 167 | }, uniqueConstraints: { 168 | id: { 169 | name: "id", 170 | fields: ["id"] 171 | }, email: { 172 | name: "email", 173 | fields: ["email"] 174 | }, 175 | }, 176 | }, 177 | list: { 178 | name: 'List', fields: { 179 | id: { 180 | name: "id", 181 | type: "String", 182 | isId: true, 183 | attributes: [{ "name": "@default", "args": [{ "name": "value" }] }], 184 | }, createdAt: { 185 | name: "createdAt", 186 | type: "DateTime", 187 | attributes: [{ "name": "@default", "args": [{ "name": "value" }] }], 188 | }, updatedAt: { 189 | name: "updatedAt", 190 | type: "DateTime", 191 | attributes: [{ "name": "@updatedAt", "args": [] }], 192 | }, space: { 193 | name: "space", 194 | type: "Space", 195 | isDataModel: true, 196 | backLink: 'lists', 197 | isRelationOwner: true, 198 | onDeleteAction: 'Cascade', 199 | foreignKeyMapping: { "id": "spaceId" }, 200 | }, spaceId: { 201 | name: "spaceId", 202 | type: "String", 203 | isForeignKey: true, 204 | relationField: 'space', 205 | }, owner: { 206 | name: "owner", 207 | type: "User", 208 | isDataModel: true, 209 | backLink: 'lists', 210 | isRelationOwner: true, 211 | onDeleteAction: 'Cascade', 212 | foreignKeyMapping: { "id": "ownerId" }, 213 | }, ownerId: { 214 | name: "ownerId", 215 | type: "String", 216 | attributes: [{ "name": "@default", "args": [{ "name": "value" }] }], 217 | defaultValueProvider: $default$List$ownerId, 218 | isForeignKey: true, 219 | relationField: 'owner', 220 | }, title: { 221 | name: "title", 222 | type: "String", 223 | }, private: { 224 | name: "private", 225 | type: "Boolean", 226 | attributes: [{ "name": "@default", "args": [{ "name": "value", "value": false }] }], 227 | }, todos: { 228 | name: "todos", 229 | type: "Todo", 230 | isDataModel: true, 231 | isArray: true, 232 | backLink: 'list', 233 | }, 234 | }, uniqueConstraints: { 235 | id: { 236 | name: "id", 237 | fields: ["id"] 238 | }, 239 | }, 240 | }, 241 | todo: { 242 | name: 'Todo', fields: { 243 | id: { 244 | name: "id", 245 | type: "String", 246 | isId: true, 247 | attributes: [{ "name": "@default", "args": [{ "name": "value" }] }], 248 | }, createdAt: { 249 | name: "createdAt", 250 | type: "DateTime", 251 | attributes: [{ "name": "@default", "args": [{ "name": "value" }] }], 252 | }, updatedAt: { 253 | name: "updatedAt", 254 | type: "DateTime", 255 | attributes: [{ "name": "@updatedAt", "args": [] }], 256 | }, owner: { 257 | name: "owner", 258 | type: "User", 259 | isDataModel: true, 260 | backLink: 'todos', 261 | isRelationOwner: true, 262 | onDeleteAction: 'Cascade', 263 | foreignKeyMapping: { "id": "ownerId" }, 264 | }, ownerId: { 265 | name: "ownerId", 266 | type: "String", 267 | attributes: [{ "name": "@default", "args": [{ "name": "value" }] }], 268 | defaultValueProvider: $default$Todo$ownerId, 269 | isForeignKey: true, 270 | relationField: 'owner', 271 | }, list: { 272 | name: "list", 273 | type: "List", 274 | isDataModel: true, 275 | backLink: 'todos', 276 | isRelationOwner: true, 277 | onDeleteAction: 'Cascade', 278 | foreignKeyMapping: { "id": "listId" }, 279 | }, listId: { 280 | name: "listId", 281 | type: "String", 282 | isForeignKey: true, 283 | relationField: 'list', 284 | }, title: { 285 | name: "title", 286 | type: "String", 287 | }, completedAt: { 288 | name: "completedAt", 289 | type: "DateTime", 290 | isOptional: true, 291 | }, 292 | }, uniqueConstraints: { 293 | id: { 294 | name: "id", 295 | fields: ["id"] 296 | }, 297 | }, 298 | }, 299 | 300 | }, 301 | deleteCascade: { 302 | space: ['SpaceUser', 'List'], 303 | user: ['Space', 'SpaceUser', 'List', 'Todo'], 304 | list: ['Todo'], 305 | 306 | }, 307 | authModel: 'User' 308 | 309 | }; 310 | 311 | function $default$Space$ownerId(user: any): unknown { 312 | return user?.id; 313 | } 314 | 315 | function $default$List$ownerId(user: any): unknown { 316 | return user?.id; 317 | } 318 | 319 | function $default$Todo$ownerId(user: any): unknown { 320 | return user?.id; 321 | } 322 | export default metadata; 323 | -------------------------------------------------------------------------------- /src/lib/hooks/todo.ts: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * This file was generated by ZenStack CLI. 3 | ******************************************************************************/ 4 | 5 | /* eslint-disable */ 6 | 7 | import type { Prisma, Todo } from "@zenstackhq/runtime/models"; 8 | import { derived } from 'svelte/store'; 9 | import type { MutationOptions, CreateQueryOptions, CreateInfiniteQueryOptions } from '@tanstack/svelte-query'; 10 | import type { InfiniteData, StoreOrVal } from '@tanstack/svelte-query'; 11 | import { getHooksContext } from '@zenstackhq/tanstack-query/runtime-v5/svelte'; 12 | import { useModelQuery, useInfiniteModelQuery, useModelMutation } from '@zenstackhq/tanstack-query/runtime-v5/svelte'; 13 | import type { PickEnumerable, CheckSelect, QueryError, ExtraQueryOptions, ExtraMutationOptions } from '@zenstackhq/tanstack-query/runtime-v5'; 14 | import type { PolicyCrudKind } from '@zenstackhq/runtime' 15 | import metadata from './__model_meta'; 16 | type DefaultError = QueryError; 17 | 18 | export function useCreateTodo(options?: Omit<(MutationOptions<(Todo | undefined), DefaultError, Prisma.TodoCreateArgs> & ExtraMutationOptions), 'mutationFn'>) { 19 | const { endpoint, fetch } = getHooksContext(); 20 | const _mutation = 21 | useModelMutation('Todo', 'POST', `${endpoint}/todo/create`, metadata, options, fetch, true) 22 | ; 23 | const mutation = derived(_mutation, value => ({ 24 | ...value, 25 | mutateAsync: async ( 26 | args: Prisma.SelectSubset, 27 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 28 | ) => { 29 | return (await value.mutateAsync( 30 | args, 31 | options as any 32 | )) as (CheckSelect> | undefined); 33 | }, 34 | })); 35 | return mutation; 36 | } 37 | 38 | export function useCreateManyTodo(options?: Omit<(MutationOptions & ExtraMutationOptions), 'mutationFn'>) { 39 | const { endpoint, fetch } = getHooksContext(); 40 | const _mutation = 41 | useModelMutation('Todo', 'POST', `${endpoint}/todo/createMany`, metadata, options, fetch, false) 42 | ; 43 | const mutation = derived(_mutation, value => ({ 44 | ...value, 45 | mutateAsync: async ( 46 | args: Prisma.SelectSubset, 47 | options?: Omit<(MutationOptions> & ExtraMutationOptions), 'mutationFn'> 48 | ) => { 49 | return (await value.mutateAsync( 50 | args, 51 | options as any 52 | )) as Prisma.BatchPayload; 53 | }, 54 | })); 55 | return mutation; 56 | } 57 | 58 | export function useFindManyTodo & { $optimistic?: boolean }>, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 59 | const { endpoint, fetch } = getHooksContext(); 60 | return useModelQuery('Todo', `${endpoint}/todo/findMany`, args, options, fetch); 61 | } 62 | 63 | export function useInfiniteFindManyTodo>, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: StoreOrVal>, 'queryKey' | 'initialPageParam'>>) { 64 | options = options ?? { getNextPageParam: () => null }; 65 | const { endpoint, fetch } = getHooksContext(); 66 | return useInfiniteModelQuery('Todo', `${endpoint}/todo/findMany`, args, options, fetch); 67 | } 68 | 69 | export function useFindUniqueTodo & { $optimistic?: boolean }, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 70 | const { endpoint, fetch } = getHooksContext(); 71 | return useModelQuery('Todo', `${endpoint}/todo/findUnique`, args, options, fetch); 72 | } 73 | 74 | export function useFindFirstTodo & { $optimistic?: boolean }, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 75 | const { endpoint, fetch } = getHooksContext(); 76 | return useModelQuery('Todo', `${endpoint}/todo/findFirst`, args, options, fetch); 77 | } 78 | 79 | export function useUpdateTodo(options?: Omit<(MutationOptions<(Todo | undefined), DefaultError, Prisma.TodoUpdateArgs> & ExtraMutationOptions), 'mutationFn'>) { 80 | const { endpoint, fetch } = getHooksContext(); 81 | const _mutation = 82 | useModelMutation('Todo', 'PUT', `${endpoint}/todo/update`, metadata, options, fetch, true) 83 | ; 84 | const mutation = derived(_mutation, value => ({ 85 | ...value, 86 | mutateAsync: async ( 87 | args: Prisma.SelectSubset, 88 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 89 | ) => { 90 | return (await value.mutateAsync( 91 | args, 92 | options as any 93 | )) as (CheckSelect> | undefined); 94 | }, 95 | })); 96 | return mutation; 97 | } 98 | 99 | export function useUpdateManyTodo(options?: Omit<(MutationOptions & ExtraMutationOptions), 'mutationFn'>) { 100 | const { endpoint, fetch } = getHooksContext(); 101 | const _mutation = 102 | useModelMutation('Todo', 'PUT', `${endpoint}/todo/updateMany`, metadata, options, fetch, false) 103 | ; 104 | const mutation = derived(_mutation, value => ({ 105 | ...value, 106 | mutateAsync: async ( 107 | args: Prisma.SelectSubset, 108 | options?: Omit<(MutationOptions> & ExtraMutationOptions), 'mutationFn'> 109 | ) => { 110 | return (await value.mutateAsync( 111 | args, 112 | options as any 113 | )) as Prisma.BatchPayload; 114 | }, 115 | })); 116 | return mutation; 117 | } 118 | 119 | export function useUpsertTodo(options?: Omit<(MutationOptions<(Todo | undefined), DefaultError, Prisma.TodoUpsertArgs> & ExtraMutationOptions), 'mutationFn'>) { 120 | const { endpoint, fetch } = getHooksContext(); 121 | const _mutation = 122 | useModelMutation('Todo', 'POST', `${endpoint}/todo/upsert`, metadata, options, fetch, true) 123 | ; 124 | const mutation = derived(_mutation, value => ({ 125 | ...value, 126 | mutateAsync: async ( 127 | args: Prisma.SelectSubset, 128 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 129 | ) => { 130 | return (await value.mutateAsync( 131 | args, 132 | options as any 133 | )) as (CheckSelect> | undefined); 134 | }, 135 | })); 136 | return mutation; 137 | } 138 | 139 | export function useDeleteTodo(options?: Omit<(MutationOptions<(Todo | undefined), DefaultError, Prisma.TodoDeleteArgs> & ExtraMutationOptions), 'mutationFn'>) { 140 | const { endpoint, fetch } = getHooksContext(); 141 | const _mutation = 142 | useModelMutation('Todo', 'DELETE', `${endpoint}/todo/delete`, metadata, options, fetch, true) 143 | ; 144 | const mutation = derived(_mutation, value => ({ 145 | ...value, 146 | mutateAsync: async ( 147 | args: Prisma.SelectSubset, 148 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 149 | ) => { 150 | return (await value.mutateAsync( 151 | args, 152 | options as any 153 | )) as (CheckSelect> | undefined); 154 | }, 155 | })); 156 | return mutation; 157 | } 158 | 159 | export function useDeleteManyTodo(options?: Omit<(MutationOptions & ExtraMutationOptions), 'mutationFn'>) { 160 | const { endpoint, fetch } = getHooksContext(); 161 | const _mutation = 162 | useModelMutation('Todo', 'DELETE', `${endpoint}/todo/deleteMany`, metadata, options, fetch, false) 163 | ; 164 | const mutation = derived(_mutation, value => ({ 165 | ...value, 166 | mutateAsync: async ( 167 | args: Prisma.SelectSubset, 168 | options?: Omit<(MutationOptions> & ExtraMutationOptions), 'mutationFn'> 169 | ) => { 170 | return (await value.mutateAsync( 171 | args, 172 | options as any 173 | )) as Prisma.BatchPayload; 174 | }, 175 | })); 176 | return mutation; 177 | } 178 | 179 | export function useAggregateTodo, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 180 | const { endpoint, fetch } = getHooksContext(); 181 | return useModelQuery('Todo', `${endpoint}/todo/aggregate`, args, options, fetch); 182 | } 183 | 184 | export function useGroupByTodo>, Prisma.Extends<'take', Prisma.Keys>>, OrderByArg extends Prisma.True extends HasSelectOrTake ? { orderBy: Prisma.TodoGroupByArgs['orderBy'] } : { orderBy?: Prisma.TodoGroupByArgs['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 185 | ? `Error: "by" must not be empty.` 186 | : HavingValid extends Prisma.False 187 | ? { 188 | [P in HavingFields]: P extends ByFields 189 | ? never 190 | : P extends string 191 | ? `Error: Field "${P}" used in "having" needs to be provided in "by".` 192 | : [ 193 | Error, 194 | 'Field ', 195 | P, 196 | ` in "having" needs to be provided in "by"`, 197 | ] 198 | }[HavingFields] 199 | : 'take' extends Prisma.Keys 200 | ? 'orderBy' extends Prisma.Keys 201 | ? ByValid extends Prisma.True 202 | ? {} 203 | : { 204 | [P in OrderFields]: P extends ByFields 205 | ? never 206 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 207 | }[OrderFields] 208 | : 'Error: If you provide "take", you also need to provide "orderBy"' 209 | : 'skip' extends Prisma.Keys 210 | ? 'orderBy' extends Prisma.Keys 211 | ? ByValid extends Prisma.True 212 | ? {} 213 | : { 214 | [P in OrderFields]: P extends ByFields 215 | ? never 216 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 217 | }[OrderFields] 218 | : 'Error: If you provide "skip", you also need to provide "orderBy"' 219 | : ByValid extends Prisma.True 220 | ? {} 221 | : { 222 | [P in OrderFields]: P extends ByFields 223 | ? never 224 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 225 | }[OrderFields], TQueryFnData = {} extends InputErrors ? 226 | Array & 227 | { 228 | [P in ((keyof TArgs) & (keyof Prisma.TodoGroupByOutputType))]: P extends '_count' 229 | ? TArgs[P] extends boolean 230 | ? number 231 | : Prisma.GetScalarType 232 | : Prisma.GetScalarType 233 | } 234 | > : InputErrors, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset & InputErrors>, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 235 | const { endpoint, fetch } = getHooksContext(); 236 | return useModelQuery('Todo', `${endpoint}/todo/groupBy`, args, options, fetch); 237 | } 238 | 239 | export function useCountTodo : number, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 240 | const { endpoint, fetch } = getHooksContext(); 241 | return useModelQuery('Todo', `${endpoint}/todo/count`, args, options, fetch); 242 | } 243 | 244 | export function useCheckTodo(args: { operation: PolicyCrudKind; where?: { id?: string; ownerId?: string; listId?: string; title?: string }; }, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 245 | const { endpoint, fetch } = getHooksContext(); 246 | return useModelQuery('Todo', `${endpoint}/todo/check`, args, options, fetch); 247 | } 248 | -------------------------------------------------------------------------------- /src/lib/hooks/user.ts: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * This file was generated by ZenStack CLI. 3 | ******************************************************************************/ 4 | 5 | /* eslint-disable */ 6 | 7 | import type { Prisma, User } from "@zenstackhq/runtime/models"; 8 | import { derived } from 'svelte/store'; 9 | import type { MutationOptions, CreateQueryOptions, CreateInfiniteQueryOptions } from '@tanstack/svelte-query'; 10 | import type { InfiniteData, StoreOrVal } from '@tanstack/svelte-query'; 11 | import { getHooksContext } from '@zenstackhq/tanstack-query/runtime-v5/svelte'; 12 | import { useModelQuery, useInfiniteModelQuery, useModelMutation } from '@zenstackhq/tanstack-query/runtime-v5/svelte'; 13 | import type { PickEnumerable, CheckSelect, QueryError, ExtraQueryOptions, ExtraMutationOptions } from '@zenstackhq/tanstack-query/runtime-v5'; 14 | import type { PolicyCrudKind } from '@zenstackhq/runtime' 15 | import metadata from './__model_meta'; 16 | type DefaultError = QueryError; 17 | 18 | export function useCreateUser(options?: Omit<(MutationOptions<(User | undefined), DefaultError, Prisma.UserCreateArgs> & ExtraMutationOptions), 'mutationFn'>) { 19 | const { endpoint, fetch } = getHooksContext(); 20 | const _mutation = 21 | useModelMutation('User', 'POST', `${endpoint}/user/create`, metadata, options, fetch, true) 22 | ; 23 | const mutation = derived(_mutation, value => ({ 24 | ...value, 25 | mutateAsync: async ( 26 | args: Prisma.SelectSubset, 27 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 28 | ) => { 29 | return (await value.mutateAsync( 30 | args, 31 | options as any 32 | )) as (CheckSelect> | undefined); 33 | }, 34 | })); 35 | return mutation; 36 | } 37 | 38 | export function useCreateManyUser(options?: Omit<(MutationOptions & ExtraMutationOptions), 'mutationFn'>) { 39 | const { endpoint, fetch } = getHooksContext(); 40 | const _mutation = 41 | useModelMutation('User', 'POST', `${endpoint}/user/createMany`, metadata, options, fetch, false) 42 | ; 43 | const mutation = derived(_mutation, value => ({ 44 | ...value, 45 | mutateAsync: async ( 46 | args: Prisma.SelectSubset, 47 | options?: Omit<(MutationOptions> & ExtraMutationOptions), 'mutationFn'> 48 | ) => { 49 | return (await value.mutateAsync( 50 | args, 51 | options as any 52 | )) as Prisma.BatchPayload; 53 | }, 54 | })); 55 | return mutation; 56 | } 57 | 58 | export function useFindManyUser & { $optimistic?: boolean }>, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 59 | const { endpoint, fetch } = getHooksContext(); 60 | return useModelQuery('User', `${endpoint}/user/findMany`, args, options, fetch); 61 | } 62 | 63 | export function useInfiniteFindManyUser>, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: StoreOrVal>, 'queryKey' | 'initialPageParam'>>) { 64 | options = options ?? { getNextPageParam: () => null }; 65 | const { endpoint, fetch } = getHooksContext(); 66 | return useInfiniteModelQuery('User', `${endpoint}/user/findMany`, args, options, fetch); 67 | } 68 | 69 | export function useFindUniqueUser & { $optimistic?: boolean }, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 70 | const { endpoint, fetch } = getHooksContext(); 71 | return useModelQuery('User', `${endpoint}/user/findUnique`, args, options, fetch); 72 | } 73 | 74 | export function useFindFirstUser & { $optimistic?: boolean }, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 75 | const { endpoint, fetch } = getHooksContext(); 76 | return useModelQuery('User', `${endpoint}/user/findFirst`, args, options, fetch); 77 | } 78 | 79 | export function useUpdateUser(options?: Omit<(MutationOptions<(User | undefined), DefaultError, Prisma.UserUpdateArgs> & ExtraMutationOptions), 'mutationFn'>) { 80 | const { endpoint, fetch } = getHooksContext(); 81 | const _mutation = 82 | useModelMutation('User', 'PUT', `${endpoint}/user/update`, metadata, options, fetch, true) 83 | ; 84 | const mutation = derived(_mutation, value => ({ 85 | ...value, 86 | mutateAsync: async ( 87 | args: Prisma.SelectSubset, 88 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 89 | ) => { 90 | return (await value.mutateAsync( 91 | args, 92 | options as any 93 | )) as (CheckSelect> | undefined); 94 | }, 95 | })); 96 | return mutation; 97 | } 98 | 99 | export function useUpdateManyUser(options?: Omit<(MutationOptions & ExtraMutationOptions), 'mutationFn'>) { 100 | const { endpoint, fetch } = getHooksContext(); 101 | const _mutation = 102 | useModelMutation('User', 'PUT', `${endpoint}/user/updateMany`, metadata, options, fetch, false) 103 | ; 104 | const mutation = derived(_mutation, value => ({ 105 | ...value, 106 | mutateAsync: async ( 107 | args: Prisma.SelectSubset, 108 | options?: Omit<(MutationOptions> & ExtraMutationOptions), 'mutationFn'> 109 | ) => { 110 | return (await value.mutateAsync( 111 | args, 112 | options as any 113 | )) as Prisma.BatchPayload; 114 | }, 115 | })); 116 | return mutation; 117 | } 118 | 119 | export function useUpsertUser(options?: Omit<(MutationOptions<(User | undefined), DefaultError, Prisma.UserUpsertArgs> & ExtraMutationOptions), 'mutationFn'>) { 120 | const { endpoint, fetch } = getHooksContext(); 121 | const _mutation = 122 | useModelMutation('User', 'POST', `${endpoint}/user/upsert`, metadata, options, fetch, true) 123 | ; 124 | const mutation = derived(_mutation, value => ({ 125 | ...value, 126 | mutateAsync: async ( 127 | args: Prisma.SelectSubset, 128 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 129 | ) => { 130 | return (await value.mutateAsync( 131 | args, 132 | options as any 133 | )) as (CheckSelect> | undefined); 134 | }, 135 | })); 136 | return mutation; 137 | } 138 | 139 | export function useDeleteUser(options?: Omit<(MutationOptions<(User | undefined), DefaultError, Prisma.UserDeleteArgs> & ExtraMutationOptions), 'mutationFn'>) { 140 | const { endpoint, fetch } = getHooksContext(); 141 | const _mutation = 142 | useModelMutation('User', 'DELETE', `${endpoint}/user/delete`, metadata, options, fetch, true) 143 | ; 144 | const mutation = derived(_mutation, value => ({ 145 | ...value, 146 | mutateAsync: async ( 147 | args: Prisma.SelectSubset, 148 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 149 | ) => { 150 | return (await value.mutateAsync( 151 | args, 152 | options as any 153 | )) as (CheckSelect> | undefined); 154 | }, 155 | })); 156 | return mutation; 157 | } 158 | 159 | export function useDeleteManyUser(options?: Omit<(MutationOptions & ExtraMutationOptions), 'mutationFn'>) { 160 | const { endpoint, fetch } = getHooksContext(); 161 | const _mutation = 162 | useModelMutation('User', 'DELETE', `${endpoint}/user/deleteMany`, metadata, options, fetch, false) 163 | ; 164 | const mutation = derived(_mutation, value => ({ 165 | ...value, 166 | mutateAsync: async ( 167 | args: Prisma.SelectSubset, 168 | options?: Omit<(MutationOptions> & ExtraMutationOptions), 'mutationFn'> 169 | ) => { 170 | return (await value.mutateAsync( 171 | args, 172 | options as any 173 | )) as Prisma.BatchPayload; 174 | }, 175 | })); 176 | return mutation; 177 | } 178 | 179 | export function useAggregateUser, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 180 | const { endpoint, fetch } = getHooksContext(); 181 | return useModelQuery('User', `${endpoint}/user/aggregate`, args, options, fetch); 182 | } 183 | 184 | export function useGroupByUser>, Prisma.Extends<'take', Prisma.Keys>>, OrderByArg extends Prisma.True extends HasSelectOrTake ? { orderBy: Prisma.UserGroupByArgs['orderBy'] } : { orderBy?: Prisma.UserGroupByArgs['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 185 | ? `Error: "by" must not be empty.` 186 | : HavingValid extends Prisma.False 187 | ? { 188 | [P in HavingFields]: P extends ByFields 189 | ? never 190 | : P extends string 191 | ? `Error: Field "${P}" used in "having" needs to be provided in "by".` 192 | : [ 193 | Error, 194 | 'Field ', 195 | P, 196 | ` in "having" needs to be provided in "by"`, 197 | ] 198 | }[HavingFields] 199 | : 'take' extends Prisma.Keys 200 | ? 'orderBy' extends Prisma.Keys 201 | ? ByValid extends Prisma.True 202 | ? {} 203 | : { 204 | [P in OrderFields]: P extends ByFields 205 | ? never 206 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 207 | }[OrderFields] 208 | : 'Error: If you provide "take", you also need to provide "orderBy"' 209 | : 'skip' extends Prisma.Keys 210 | ? 'orderBy' extends Prisma.Keys 211 | ? ByValid extends Prisma.True 212 | ? {} 213 | : { 214 | [P in OrderFields]: P extends ByFields 215 | ? never 216 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 217 | }[OrderFields] 218 | : 'Error: If you provide "skip", you also need to provide "orderBy"' 219 | : ByValid extends Prisma.True 220 | ? {} 221 | : { 222 | [P in OrderFields]: P extends ByFields 223 | ? never 224 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 225 | }[OrderFields], TQueryFnData = {} extends InputErrors ? 226 | Array & 227 | { 228 | [P in ((keyof TArgs) & (keyof Prisma.UserGroupByOutputType))]: P extends '_count' 229 | ? TArgs[P] extends boolean 230 | ? number 231 | : Prisma.GetScalarType 232 | : Prisma.GetScalarType 233 | } 234 | > : InputErrors, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset & InputErrors>, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 235 | const { endpoint, fetch } = getHooksContext(); 236 | return useModelQuery('User', `${endpoint}/user/groupBy`, args, options, fetch); 237 | } 238 | 239 | export function useCountUser : number, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 240 | const { endpoint, fetch } = getHooksContext(); 241 | return useModelQuery('User', `${endpoint}/user/count`, args, options, fetch); 242 | } 243 | 244 | export function useCheckUser(args: { operation: PolicyCrudKind; where?: { id?: string; email?: string; password?: string; name?: string }; }, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 245 | const { endpoint, fetch } = getHooksContext(); 246 | return useModelQuery('User', `${endpoint}/user/check`, args, options, fetch); 247 | } 248 | -------------------------------------------------------------------------------- /src/lib/hooks/list.ts: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * This file was generated by ZenStack CLI. 3 | ******************************************************************************/ 4 | 5 | /* eslint-disable */ 6 | 7 | import type { Prisma, List } from "@zenstackhq/runtime/models"; 8 | import { derived } from 'svelte/store'; 9 | import type { MutationOptions, CreateQueryOptions, CreateInfiniteQueryOptions } from '@tanstack/svelte-query'; 10 | import type { InfiniteData, StoreOrVal } from '@tanstack/svelte-query'; 11 | import { getHooksContext } from '@zenstackhq/tanstack-query/runtime-v5/svelte'; 12 | import { useModelQuery, useInfiniteModelQuery, useModelMutation } from '@zenstackhq/tanstack-query/runtime-v5/svelte'; 13 | import type { PickEnumerable, CheckSelect, QueryError, ExtraQueryOptions, ExtraMutationOptions } from '@zenstackhq/tanstack-query/runtime-v5'; 14 | import type { PolicyCrudKind } from '@zenstackhq/runtime' 15 | import metadata from './__model_meta'; 16 | type DefaultError = QueryError; 17 | 18 | export function useCreateList(options?: Omit<(MutationOptions<(List | undefined), DefaultError, Prisma.ListCreateArgs> & ExtraMutationOptions), 'mutationFn'>) { 19 | const { endpoint, fetch } = getHooksContext(); 20 | const _mutation = 21 | useModelMutation('List', 'POST', `${endpoint}/list/create`, metadata, options, fetch, true) 22 | ; 23 | const mutation = derived(_mutation, value => ({ 24 | ...value, 25 | mutateAsync: async ( 26 | args: Prisma.SelectSubset, 27 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 28 | ) => { 29 | return (await value.mutateAsync( 30 | args, 31 | options as any 32 | )) as (CheckSelect> | undefined); 33 | }, 34 | })); 35 | return mutation; 36 | } 37 | 38 | export function useCreateManyList(options?: Omit<(MutationOptions & ExtraMutationOptions), 'mutationFn'>) { 39 | const { endpoint, fetch } = getHooksContext(); 40 | const _mutation = 41 | useModelMutation('List', 'POST', `${endpoint}/list/createMany`, metadata, options, fetch, false) 42 | ; 43 | const mutation = derived(_mutation, value => ({ 44 | ...value, 45 | mutateAsync: async ( 46 | args: Prisma.SelectSubset, 47 | options?: Omit<(MutationOptions> & ExtraMutationOptions), 'mutationFn'> 48 | ) => { 49 | return (await value.mutateAsync( 50 | args, 51 | options as any 52 | )) as Prisma.BatchPayload; 53 | }, 54 | })); 55 | return mutation; 56 | } 57 | 58 | export function useFindManyList & { $optimistic?: boolean }>, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 59 | const { endpoint, fetch } = getHooksContext(); 60 | return useModelQuery('List', `${endpoint}/list/findMany`, args, options, fetch); 61 | } 62 | 63 | export function useInfiniteFindManyList>, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: StoreOrVal>, 'queryKey' | 'initialPageParam'>>) { 64 | options = options ?? { getNextPageParam: () => null }; 65 | const { endpoint, fetch } = getHooksContext(); 66 | return useInfiniteModelQuery('List', `${endpoint}/list/findMany`, args, options, fetch); 67 | } 68 | 69 | export function useFindUniqueList & { $optimistic?: boolean }, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 70 | const { endpoint, fetch } = getHooksContext(); 71 | return useModelQuery('List', `${endpoint}/list/findUnique`, args, options, fetch); 72 | } 73 | 74 | export function useFindFirstList & { $optimistic?: boolean }, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 75 | const { endpoint, fetch } = getHooksContext(); 76 | return useModelQuery('List', `${endpoint}/list/findFirst`, args, options, fetch); 77 | } 78 | 79 | export function useUpdateList(options?: Omit<(MutationOptions<(List | undefined), DefaultError, Prisma.ListUpdateArgs> & ExtraMutationOptions), 'mutationFn'>) { 80 | const { endpoint, fetch } = getHooksContext(); 81 | const _mutation = 82 | useModelMutation('List', 'PUT', `${endpoint}/list/update`, metadata, options, fetch, true) 83 | ; 84 | const mutation = derived(_mutation, value => ({ 85 | ...value, 86 | mutateAsync: async ( 87 | args: Prisma.SelectSubset, 88 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 89 | ) => { 90 | return (await value.mutateAsync( 91 | args, 92 | options as any 93 | )) as (CheckSelect> | undefined); 94 | }, 95 | })); 96 | return mutation; 97 | } 98 | 99 | export function useUpdateManyList(options?: Omit<(MutationOptions & ExtraMutationOptions), 'mutationFn'>) { 100 | const { endpoint, fetch } = getHooksContext(); 101 | const _mutation = 102 | useModelMutation('List', 'PUT', `${endpoint}/list/updateMany`, metadata, options, fetch, false) 103 | ; 104 | const mutation = derived(_mutation, value => ({ 105 | ...value, 106 | mutateAsync: async ( 107 | args: Prisma.SelectSubset, 108 | options?: Omit<(MutationOptions> & ExtraMutationOptions), 'mutationFn'> 109 | ) => { 110 | return (await value.mutateAsync( 111 | args, 112 | options as any 113 | )) as Prisma.BatchPayload; 114 | }, 115 | })); 116 | return mutation; 117 | } 118 | 119 | export function useUpsertList(options?: Omit<(MutationOptions<(List | undefined), DefaultError, Prisma.ListUpsertArgs> & ExtraMutationOptions), 'mutationFn'>) { 120 | const { endpoint, fetch } = getHooksContext(); 121 | const _mutation = 122 | useModelMutation('List', 'POST', `${endpoint}/list/upsert`, metadata, options, fetch, true) 123 | ; 124 | const mutation = derived(_mutation, value => ({ 125 | ...value, 126 | mutateAsync: async ( 127 | args: Prisma.SelectSubset, 128 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 129 | ) => { 130 | return (await value.mutateAsync( 131 | args, 132 | options as any 133 | )) as (CheckSelect> | undefined); 134 | }, 135 | })); 136 | return mutation; 137 | } 138 | 139 | export function useDeleteList(options?: Omit<(MutationOptions<(List | undefined), DefaultError, Prisma.ListDeleteArgs> & ExtraMutationOptions), 'mutationFn'>) { 140 | const { endpoint, fetch } = getHooksContext(); 141 | const _mutation = 142 | useModelMutation('List', 'DELETE', `${endpoint}/list/delete`, metadata, options, fetch, true) 143 | ; 144 | const mutation = derived(_mutation, value => ({ 145 | ...value, 146 | mutateAsync: async ( 147 | args: Prisma.SelectSubset, 148 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 149 | ) => { 150 | return (await value.mutateAsync( 151 | args, 152 | options as any 153 | )) as (CheckSelect> | undefined); 154 | }, 155 | })); 156 | return mutation; 157 | } 158 | 159 | export function useDeleteManyList(options?: Omit<(MutationOptions & ExtraMutationOptions), 'mutationFn'>) { 160 | const { endpoint, fetch } = getHooksContext(); 161 | const _mutation = 162 | useModelMutation('List', 'DELETE', `${endpoint}/list/deleteMany`, metadata, options, fetch, false) 163 | ; 164 | const mutation = derived(_mutation, value => ({ 165 | ...value, 166 | mutateAsync: async ( 167 | args: Prisma.SelectSubset, 168 | options?: Omit<(MutationOptions> & ExtraMutationOptions), 'mutationFn'> 169 | ) => { 170 | return (await value.mutateAsync( 171 | args, 172 | options as any 173 | )) as Prisma.BatchPayload; 174 | }, 175 | })); 176 | return mutation; 177 | } 178 | 179 | export function useAggregateList, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 180 | const { endpoint, fetch } = getHooksContext(); 181 | return useModelQuery('List', `${endpoint}/list/aggregate`, args, options, fetch); 182 | } 183 | 184 | export function useGroupByList>, Prisma.Extends<'take', Prisma.Keys>>, OrderByArg extends Prisma.True extends HasSelectOrTake ? { orderBy: Prisma.ListGroupByArgs['orderBy'] } : { orderBy?: Prisma.ListGroupByArgs['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 185 | ? `Error: "by" must not be empty.` 186 | : HavingValid extends Prisma.False 187 | ? { 188 | [P in HavingFields]: P extends ByFields 189 | ? never 190 | : P extends string 191 | ? `Error: Field "${P}" used in "having" needs to be provided in "by".` 192 | : [ 193 | Error, 194 | 'Field ', 195 | P, 196 | ` in "having" needs to be provided in "by"`, 197 | ] 198 | }[HavingFields] 199 | : 'take' extends Prisma.Keys 200 | ? 'orderBy' extends Prisma.Keys 201 | ? ByValid extends Prisma.True 202 | ? {} 203 | : { 204 | [P in OrderFields]: P extends ByFields 205 | ? never 206 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 207 | }[OrderFields] 208 | : 'Error: If you provide "take", you also need to provide "orderBy"' 209 | : 'skip' extends Prisma.Keys 210 | ? 'orderBy' extends Prisma.Keys 211 | ? ByValid extends Prisma.True 212 | ? {} 213 | : { 214 | [P in OrderFields]: P extends ByFields 215 | ? never 216 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 217 | }[OrderFields] 218 | : 'Error: If you provide "skip", you also need to provide "orderBy"' 219 | : ByValid extends Prisma.True 220 | ? {} 221 | : { 222 | [P in OrderFields]: P extends ByFields 223 | ? never 224 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 225 | }[OrderFields], TQueryFnData = {} extends InputErrors ? 226 | Array & 227 | { 228 | [P in ((keyof TArgs) & (keyof Prisma.ListGroupByOutputType))]: P extends '_count' 229 | ? TArgs[P] extends boolean 230 | ? number 231 | : Prisma.GetScalarType 232 | : Prisma.GetScalarType 233 | } 234 | > : InputErrors, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset & InputErrors>, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 235 | const { endpoint, fetch } = getHooksContext(); 236 | return useModelQuery('List', `${endpoint}/list/groupBy`, args, options, fetch); 237 | } 238 | 239 | export function useCountList : number, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 240 | const { endpoint, fetch } = getHooksContext(); 241 | return useModelQuery('List', `${endpoint}/list/count`, args, options, fetch); 242 | } 243 | 244 | export function useCheckList(args: { operation: PolicyCrudKind; where?: { id?: string; spaceId?: string; ownerId?: string; title?: string; private?: boolean }; }, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 245 | const { endpoint, fetch } = getHooksContext(); 246 | return useModelQuery('List', `${endpoint}/list/check`, args, options, fetch); 247 | } 248 | -------------------------------------------------------------------------------- /src/lib/hooks/space.ts: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * This file was generated by ZenStack CLI. 3 | ******************************************************************************/ 4 | 5 | /* eslint-disable */ 6 | 7 | import type { Prisma, Space } from "@zenstackhq/runtime/models"; 8 | import { derived } from 'svelte/store'; 9 | import type { MutationOptions, CreateQueryOptions, CreateInfiniteQueryOptions } from '@tanstack/svelte-query'; 10 | import type { InfiniteData, StoreOrVal } from '@tanstack/svelte-query'; 11 | import { getHooksContext } from '@zenstackhq/tanstack-query/runtime-v5/svelte'; 12 | import { useModelQuery, useInfiniteModelQuery, useModelMutation } from '@zenstackhq/tanstack-query/runtime-v5/svelte'; 13 | import type { PickEnumerable, CheckSelect, QueryError, ExtraQueryOptions, ExtraMutationOptions } from '@zenstackhq/tanstack-query/runtime-v5'; 14 | import type { PolicyCrudKind } from '@zenstackhq/runtime' 15 | import metadata from './__model_meta'; 16 | type DefaultError = QueryError; 17 | 18 | export function useCreateSpace(options?: Omit<(MutationOptions<(Space | undefined), DefaultError, Prisma.SpaceCreateArgs> & ExtraMutationOptions), 'mutationFn'>) { 19 | const { endpoint, fetch } = getHooksContext(); 20 | const _mutation = 21 | useModelMutation('Space', 'POST', `${endpoint}/space/create`, metadata, options, fetch, true) 22 | ; 23 | const mutation = derived(_mutation, value => ({ 24 | ...value, 25 | mutateAsync: async ( 26 | args: Prisma.SelectSubset, 27 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 28 | ) => { 29 | return (await value.mutateAsync( 30 | args, 31 | options as any 32 | )) as (CheckSelect> | undefined); 33 | }, 34 | })); 35 | return mutation; 36 | } 37 | 38 | export function useCreateManySpace(options?: Omit<(MutationOptions & ExtraMutationOptions), 'mutationFn'>) { 39 | const { endpoint, fetch } = getHooksContext(); 40 | const _mutation = 41 | useModelMutation('Space', 'POST', `${endpoint}/space/createMany`, metadata, options, fetch, false) 42 | ; 43 | const mutation = derived(_mutation, value => ({ 44 | ...value, 45 | mutateAsync: async ( 46 | args: Prisma.SelectSubset, 47 | options?: Omit<(MutationOptions> & ExtraMutationOptions), 'mutationFn'> 48 | ) => { 49 | return (await value.mutateAsync( 50 | args, 51 | options as any 52 | )) as Prisma.BatchPayload; 53 | }, 54 | })); 55 | return mutation; 56 | } 57 | 58 | export function useFindManySpace & { $optimistic?: boolean }>, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 59 | const { endpoint, fetch } = getHooksContext(); 60 | return useModelQuery('Space', `${endpoint}/space/findMany`, args, options, fetch); 61 | } 62 | 63 | export function useInfiniteFindManySpace>, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: StoreOrVal>, 'queryKey' | 'initialPageParam'>>) { 64 | options = options ?? { getNextPageParam: () => null }; 65 | const { endpoint, fetch } = getHooksContext(); 66 | return useInfiniteModelQuery('Space', `${endpoint}/space/findMany`, args, options, fetch); 67 | } 68 | 69 | export function useFindUniqueSpace & { $optimistic?: boolean }, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 70 | const { endpoint, fetch } = getHooksContext(); 71 | return useModelQuery('Space', `${endpoint}/space/findUnique`, args, options, fetch); 72 | } 73 | 74 | export function useFindFirstSpace & { $optimistic?: boolean }, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 75 | const { endpoint, fetch } = getHooksContext(); 76 | return useModelQuery('Space', `${endpoint}/space/findFirst`, args, options, fetch); 77 | } 78 | 79 | export function useUpdateSpace(options?: Omit<(MutationOptions<(Space | undefined), DefaultError, Prisma.SpaceUpdateArgs> & ExtraMutationOptions), 'mutationFn'>) { 80 | const { endpoint, fetch } = getHooksContext(); 81 | const _mutation = 82 | useModelMutation('Space', 'PUT', `${endpoint}/space/update`, metadata, options, fetch, true) 83 | ; 84 | const mutation = derived(_mutation, value => ({ 85 | ...value, 86 | mutateAsync: async ( 87 | args: Prisma.SelectSubset, 88 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 89 | ) => { 90 | return (await value.mutateAsync( 91 | args, 92 | options as any 93 | )) as (CheckSelect> | undefined); 94 | }, 95 | })); 96 | return mutation; 97 | } 98 | 99 | export function useUpdateManySpace(options?: Omit<(MutationOptions & ExtraMutationOptions), 'mutationFn'>) { 100 | const { endpoint, fetch } = getHooksContext(); 101 | const _mutation = 102 | useModelMutation('Space', 'PUT', `${endpoint}/space/updateMany`, metadata, options, fetch, false) 103 | ; 104 | const mutation = derived(_mutation, value => ({ 105 | ...value, 106 | mutateAsync: async ( 107 | args: Prisma.SelectSubset, 108 | options?: Omit<(MutationOptions> & ExtraMutationOptions), 'mutationFn'> 109 | ) => { 110 | return (await value.mutateAsync( 111 | args, 112 | options as any 113 | )) as Prisma.BatchPayload; 114 | }, 115 | })); 116 | return mutation; 117 | } 118 | 119 | export function useUpsertSpace(options?: Omit<(MutationOptions<(Space | undefined), DefaultError, Prisma.SpaceUpsertArgs> & ExtraMutationOptions), 'mutationFn'>) { 120 | const { endpoint, fetch } = getHooksContext(); 121 | const _mutation = 122 | useModelMutation('Space', 'POST', `${endpoint}/space/upsert`, metadata, options, fetch, true) 123 | ; 124 | const mutation = derived(_mutation, value => ({ 125 | ...value, 126 | mutateAsync: async ( 127 | args: Prisma.SelectSubset, 128 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 129 | ) => { 130 | return (await value.mutateAsync( 131 | args, 132 | options as any 133 | )) as (CheckSelect> | undefined); 134 | }, 135 | })); 136 | return mutation; 137 | } 138 | 139 | export function useDeleteSpace(options?: Omit<(MutationOptions<(Space | undefined), DefaultError, Prisma.SpaceDeleteArgs> & ExtraMutationOptions), 'mutationFn'>) { 140 | const { endpoint, fetch } = getHooksContext(); 141 | const _mutation = 142 | useModelMutation('Space', 'DELETE', `${endpoint}/space/delete`, metadata, options, fetch, true) 143 | ; 144 | const mutation = derived(_mutation, value => ({ 145 | ...value, 146 | mutateAsync: async ( 147 | args: Prisma.SelectSubset, 148 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 149 | ) => { 150 | return (await value.mutateAsync( 151 | args, 152 | options as any 153 | )) as (CheckSelect> | undefined); 154 | }, 155 | })); 156 | return mutation; 157 | } 158 | 159 | export function useDeleteManySpace(options?: Omit<(MutationOptions & ExtraMutationOptions), 'mutationFn'>) { 160 | const { endpoint, fetch } = getHooksContext(); 161 | const _mutation = 162 | useModelMutation('Space', 'DELETE', `${endpoint}/space/deleteMany`, metadata, options, fetch, false) 163 | ; 164 | const mutation = derived(_mutation, value => ({ 165 | ...value, 166 | mutateAsync: async ( 167 | args: Prisma.SelectSubset, 168 | options?: Omit<(MutationOptions> & ExtraMutationOptions), 'mutationFn'> 169 | ) => { 170 | return (await value.mutateAsync( 171 | args, 172 | options as any 173 | )) as Prisma.BatchPayload; 174 | }, 175 | })); 176 | return mutation; 177 | } 178 | 179 | export function useAggregateSpace, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 180 | const { endpoint, fetch } = getHooksContext(); 181 | return useModelQuery('Space', `${endpoint}/space/aggregate`, args, options, fetch); 182 | } 183 | 184 | export function useGroupBySpace>, Prisma.Extends<'take', Prisma.Keys>>, OrderByArg extends Prisma.True extends HasSelectOrTake ? { orderBy: Prisma.SpaceGroupByArgs['orderBy'] } : { orderBy?: Prisma.SpaceGroupByArgs['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 185 | ? `Error: "by" must not be empty.` 186 | : HavingValid extends Prisma.False 187 | ? { 188 | [P in HavingFields]: P extends ByFields 189 | ? never 190 | : P extends string 191 | ? `Error: Field "${P}" used in "having" needs to be provided in "by".` 192 | : [ 193 | Error, 194 | 'Field ', 195 | P, 196 | ` in "having" needs to be provided in "by"`, 197 | ] 198 | }[HavingFields] 199 | : 'take' extends Prisma.Keys 200 | ? 'orderBy' extends Prisma.Keys 201 | ? ByValid extends Prisma.True 202 | ? {} 203 | : { 204 | [P in OrderFields]: P extends ByFields 205 | ? never 206 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 207 | }[OrderFields] 208 | : 'Error: If you provide "take", you also need to provide "orderBy"' 209 | : 'skip' extends Prisma.Keys 210 | ? 'orderBy' extends Prisma.Keys 211 | ? ByValid extends Prisma.True 212 | ? {} 213 | : { 214 | [P in OrderFields]: P extends ByFields 215 | ? never 216 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 217 | }[OrderFields] 218 | : 'Error: If you provide "skip", you also need to provide "orderBy"' 219 | : ByValid extends Prisma.True 220 | ? {} 221 | : { 222 | [P in OrderFields]: P extends ByFields 223 | ? never 224 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 225 | }[OrderFields], TQueryFnData = {} extends InputErrors ? 226 | Array & 227 | { 228 | [P in ((keyof TArgs) & (keyof Prisma.SpaceGroupByOutputType))]: P extends '_count' 229 | ? TArgs[P] extends boolean 230 | ? number 231 | : Prisma.GetScalarType 232 | : Prisma.GetScalarType 233 | } 234 | > : InputErrors, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset & InputErrors>, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 235 | const { endpoint, fetch } = getHooksContext(); 236 | return useModelQuery('Space', `${endpoint}/space/groupBy`, args, options, fetch); 237 | } 238 | 239 | export function useCountSpace : number, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 240 | const { endpoint, fetch } = getHooksContext(); 241 | return useModelQuery('Space', `${endpoint}/space/count`, args, options, fetch); 242 | } 243 | 244 | export function useCheckSpace(args: { operation: PolicyCrudKind; where?: { id?: string; ownerId?: string; name?: string; slug?: string }; }, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 245 | const { endpoint, fetch } = getHooksContext(); 246 | return useModelQuery('Space', `${endpoint}/space/check`, args, options, fetch); 247 | } 248 | -------------------------------------------------------------------------------- /src/lib/hooks/space-user.ts: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * This file was generated by ZenStack CLI. 3 | ******************************************************************************/ 4 | 5 | /* eslint-disable */ 6 | 7 | import type { Prisma, SpaceUser } from "@zenstackhq/runtime/models"; 8 | import { derived } from 'svelte/store'; 9 | import type { MutationOptions, CreateQueryOptions, CreateInfiniteQueryOptions } from '@tanstack/svelte-query'; 10 | import type { InfiniteData, StoreOrVal } from '@tanstack/svelte-query'; 11 | import { getHooksContext } from '@zenstackhq/tanstack-query/runtime-v5/svelte'; 12 | import { useModelQuery, useInfiniteModelQuery, useModelMutation } from '@zenstackhq/tanstack-query/runtime-v5/svelte'; 13 | import type { PickEnumerable, CheckSelect, QueryError, ExtraQueryOptions, ExtraMutationOptions } from '@zenstackhq/tanstack-query/runtime-v5'; 14 | import type { PolicyCrudKind } from '@zenstackhq/runtime' 15 | import metadata from './__model_meta'; 16 | type DefaultError = QueryError; 17 | 18 | export function useCreateSpaceUser(options?: Omit<(MutationOptions<(SpaceUser | undefined), DefaultError, Prisma.SpaceUserCreateArgs> & ExtraMutationOptions), 'mutationFn'>) { 19 | const { endpoint, fetch } = getHooksContext(); 20 | const _mutation = 21 | useModelMutation('SpaceUser', 'POST', `${endpoint}/spaceUser/create`, metadata, options, fetch, true) 22 | ; 23 | const mutation = derived(_mutation, value => ({ 24 | ...value, 25 | mutateAsync: async ( 26 | args: Prisma.SelectSubset, 27 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 28 | ) => { 29 | return (await value.mutateAsync( 30 | args, 31 | options as any 32 | )) as (CheckSelect> | undefined); 33 | }, 34 | })); 35 | return mutation; 36 | } 37 | 38 | export function useCreateManySpaceUser(options?: Omit<(MutationOptions & ExtraMutationOptions), 'mutationFn'>) { 39 | const { endpoint, fetch } = getHooksContext(); 40 | const _mutation = 41 | useModelMutation('SpaceUser', 'POST', `${endpoint}/spaceUser/createMany`, metadata, options, fetch, false) 42 | ; 43 | const mutation = derived(_mutation, value => ({ 44 | ...value, 45 | mutateAsync: async ( 46 | args: Prisma.SelectSubset, 47 | options?: Omit<(MutationOptions> & ExtraMutationOptions), 'mutationFn'> 48 | ) => { 49 | return (await value.mutateAsync( 50 | args, 51 | options as any 52 | )) as Prisma.BatchPayload; 53 | }, 54 | })); 55 | return mutation; 56 | } 57 | 58 | export function useFindManySpaceUser & { $optimistic?: boolean }>, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 59 | const { endpoint, fetch } = getHooksContext(); 60 | return useModelQuery('SpaceUser', `${endpoint}/spaceUser/findMany`, args, options, fetch); 61 | } 62 | 63 | export function useInfiniteFindManySpaceUser>, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: StoreOrVal>, 'queryKey' | 'initialPageParam'>>) { 64 | options = options ?? { getNextPageParam: () => null }; 65 | const { endpoint, fetch } = getHooksContext(); 66 | return useInfiniteModelQuery('SpaceUser', `${endpoint}/spaceUser/findMany`, args, options, fetch); 67 | } 68 | 69 | export function useFindUniqueSpaceUser & { $optimistic?: boolean }, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 70 | const { endpoint, fetch } = getHooksContext(); 71 | return useModelQuery('SpaceUser', `${endpoint}/spaceUser/findUnique`, args, options, fetch); 72 | } 73 | 74 | export function useFindFirstSpaceUser & { $optimistic?: boolean }, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 75 | const { endpoint, fetch } = getHooksContext(); 76 | return useModelQuery('SpaceUser', `${endpoint}/spaceUser/findFirst`, args, options, fetch); 77 | } 78 | 79 | export function useUpdateSpaceUser(options?: Omit<(MutationOptions<(SpaceUser | undefined), DefaultError, Prisma.SpaceUserUpdateArgs> & ExtraMutationOptions), 'mutationFn'>) { 80 | const { endpoint, fetch } = getHooksContext(); 81 | const _mutation = 82 | useModelMutation('SpaceUser', 'PUT', `${endpoint}/spaceUser/update`, metadata, options, fetch, true) 83 | ; 84 | const mutation = derived(_mutation, value => ({ 85 | ...value, 86 | mutateAsync: async ( 87 | args: Prisma.SelectSubset, 88 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 89 | ) => { 90 | return (await value.mutateAsync( 91 | args, 92 | options as any 93 | )) as (CheckSelect> | undefined); 94 | }, 95 | })); 96 | return mutation; 97 | } 98 | 99 | export function useUpdateManySpaceUser(options?: Omit<(MutationOptions & ExtraMutationOptions), 'mutationFn'>) { 100 | const { endpoint, fetch } = getHooksContext(); 101 | const _mutation = 102 | useModelMutation('SpaceUser', 'PUT', `${endpoint}/spaceUser/updateMany`, metadata, options, fetch, false) 103 | ; 104 | const mutation = derived(_mutation, value => ({ 105 | ...value, 106 | mutateAsync: async ( 107 | args: Prisma.SelectSubset, 108 | options?: Omit<(MutationOptions> & ExtraMutationOptions), 'mutationFn'> 109 | ) => { 110 | return (await value.mutateAsync( 111 | args, 112 | options as any 113 | )) as Prisma.BatchPayload; 114 | }, 115 | })); 116 | return mutation; 117 | } 118 | 119 | export function useUpsertSpaceUser(options?: Omit<(MutationOptions<(SpaceUser | undefined), DefaultError, Prisma.SpaceUserUpsertArgs> & ExtraMutationOptions), 'mutationFn'>) { 120 | const { endpoint, fetch } = getHooksContext(); 121 | const _mutation = 122 | useModelMutation('SpaceUser', 'POST', `${endpoint}/spaceUser/upsert`, metadata, options, fetch, true) 123 | ; 124 | const mutation = derived(_mutation, value => ({ 125 | ...value, 126 | mutateAsync: async ( 127 | args: Prisma.SelectSubset, 128 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 129 | ) => { 130 | return (await value.mutateAsync( 131 | args, 132 | options as any 133 | )) as (CheckSelect> | undefined); 134 | }, 135 | })); 136 | return mutation; 137 | } 138 | 139 | export function useDeleteSpaceUser(options?: Omit<(MutationOptions<(SpaceUser | undefined), DefaultError, Prisma.SpaceUserDeleteArgs> & ExtraMutationOptions), 'mutationFn'>) { 140 | const { endpoint, fetch } = getHooksContext(); 141 | const _mutation = 142 | useModelMutation('SpaceUser', 'DELETE', `${endpoint}/spaceUser/delete`, metadata, options, fetch, true) 143 | ; 144 | const mutation = derived(_mutation, value => ({ 145 | ...value, 146 | mutateAsync: async ( 147 | args: Prisma.SelectSubset, 148 | options?: Omit<(MutationOptions<(CheckSelect> | undefined), DefaultError, Prisma.SelectSubset> & ExtraMutationOptions), 'mutationFn'> 149 | ) => { 150 | return (await value.mutateAsync( 151 | args, 152 | options as any 153 | )) as (CheckSelect> | undefined); 154 | }, 155 | })); 156 | return mutation; 157 | } 158 | 159 | export function useDeleteManySpaceUser(options?: Omit<(MutationOptions & ExtraMutationOptions), 'mutationFn'>) { 160 | const { endpoint, fetch } = getHooksContext(); 161 | const _mutation = 162 | useModelMutation('SpaceUser', 'DELETE', `${endpoint}/spaceUser/deleteMany`, metadata, options, fetch, false) 163 | ; 164 | const mutation = derived(_mutation, value => ({ 165 | ...value, 166 | mutateAsync: async ( 167 | args: Prisma.SelectSubset, 168 | options?: Omit<(MutationOptions> & ExtraMutationOptions), 'mutationFn'> 169 | ) => { 170 | return (await value.mutateAsync( 171 | args, 172 | options as any 173 | )) as Prisma.BatchPayload; 174 | }, 175 | })); 176 | return mutation; 177 | } 178 | 179 | export function useAggregateSpaceUser, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 180 | const { endpoint, fetch } = getHooksContext(); 181 | return useModelQuery('SpaceUser', `${endpoint}/spaceUser/aggregate`, args, options, fetch); 182 | } 183 | 184 | export function useGroupBySpaceUser>, Prisma.Extends<'take', Prisma.Keys>>, OrderByArg extends Prisma.True extends HasSelectOrTake ? { orderBy: Prisma.SpaceUserGroupByArgs['orderBy'] } : { orderBy?: Prisma.SpaceUserGroupByArgs['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 185 | ? `Error: "by" must not be empty.` 186 | : HavingValid extends Prisma.False 187 | ? { 188 | [P in HavingFields]: P extends ByFields 189 | ? never 190 | : P extends string 191 | ? `Error: Field "${P}" used in "having" needs to be provided in "by".` 192 | : [ 193 | Error, 194 | 'Field ', 195 | P, 196 | ` in "having" needs to be provided in "by"`, 197 | ] 198 | }[HavingFields] 199 | : 'take' extends Prisma.Keys 200 | ? 'orderBy' extends Prisma.Keys 201 | ? ByValid extends Prisma.True 202 | ? {} 203 | : { 204 | [P in OrderFields]: P extends ByFields 205 | ? never 206 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 207 | }[OrderFields] 208 | : 'Error: If you provide "take", you also need to provide "orderBy"' 209 | : 'skip' extends Prisma.Keys 210 | ? 'orderBy' extends Prisma.Keys 211 | ? ByValid extends Prisma.True 212 | ? {} 213 | : { 214 | [P in OrderFields]: P extends ByFields 215 | ? never 216 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 217 | }[OrderFields] 218 | : 'Error: If you provide "skip", you also need to provide "orderBy"' 219 | : ByValid extends Prisma.True 220 | ? {} 221 | : { 222 | [P in OrderFields]: P extends ByFields 223 | ? never 224 | : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 225 | }[OrderFields], TQueryFnData = {} extends InputErrors ? 226 | Array & 227 | { 228 | [P in ((keyof TArgs) & (keyof Prisma.SpaceUserGroupByOutputType))]: P extends '_count' 229 | ? TArgs[P] extends boolean 230 | ? number 231 | : Prisma.GetScalarType 232 | : Prisma.GetScalarType 233 | } 234 | > : InputErrors, TData = TQueryFnData, TError = DefaultError>(args: Prisma.SelectSubset & InputErrors>, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 235 | const { endpoint, fetch } = getHooksContext(); 236 | return useModelQuery('SpaceUser', `${endpoint}/spaceUser/groupBy`, args, options, fetch); 237 | } 238 | 239 | export function useCountSpaceUser : number, TData = TQueryFnData, TError = DefaultError>(args?: Prisma.SelectSubset, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 240 | const { endpoint, fetch } = getHooksContext(); 241 | return useModelQuery('SpaceUser', `${endpoint}/spaceUser/count`, args, options, fetch); 242 | } 243 | import type { SpaceUserRole } from '@zenstackhq/runtime/models'; 244 | 245 | export function useCheckSpaceUser(args: { operation: PolicyCrudKind; where?: { id?: string; spaceId?: string; userId?: string; role?: SpaceUserRole }; }, options?: (StoreOrVal, 'queryKey'>> & ExtraQueryOptions)) { 246 | const { endpoint, fetch } = getHooksContext(); 247 | return useModelQuery('SpaceUser', `${endpoint}/spaceUser/check`, args, options, fetch); 248 | } 249 | --------------------------------------------------------------------------------