create-fate 1.8.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/bin/create-fate.mjs +10 -2
  2. package/package.json +1 -1
  3. package/templates/fate/_shared/vue-app/package.json +11 -11
  4. package/templates/fate/drizzle/client/package.json +15 -15
  5. package/templates/fate/drizzle/client/src/ui/PostCard.tsx +6 -1
  6. package/templates/fate/drizzle/package.json +6 -7
  7. package/templates/fate/drizzle/pnpm-workspace.yaml +5 -5
  8. package/templates/fate/drizzle/server/package.json +8 -8
  9. package/templates/fate/graphql/AGENTS.md +1 -1
  10. package/templates/fate/graphql/README.md +12 -1
  11. package/templates/fate/graphql/client/package.json +14 -14
  12. package/templates/fate/graphql/client/pages/index.tsx +1 -1
  13. package/templates/fate/graphql/client/pages/search.tsx +2 -2
  14. package/templates/fate/graphql/client/src/fate/graphql.ts +20 -0
  15. package/templates/fate/graphql/client/src/ui/CommentCard.tsx +1 -1
  16. package/templates/fate/graphql/client/src/ui/PostCard.tsx +7 -2
  17. package/templates/fate/graphql/client/src/ui/UserCard.tsx +1 -1
  18. package/templates/fate/graphql/client/vite.config.ts +1 -1
  19. package/templates/fate/graphql/package.json +6 -7
  20. package/templates/fate/graphql/pnpm-workspace.yaml +5 -5
  21. package/templates/fate/graphql/server/README.md +3 -4
  22. package/templates/fate/graphql/server/package.json +19 -19
  23. package/templates/fate/graphql/server/scripts/generate-graphql.tsx +7 -1
  24. package/templates/fate/graphql/server/src/graphql/fate.ts +0 -56
  25. package/templates/fate/graphql/server/src/graphql/schema.tsx +22 -3
  26. package/templates/fate/graphql/server/src/graphql/views.ts +0 -43
  27. package/templates/fate/graphql-client/README.md +8 -14
  28. package/templates/fate/graphql-client/package.json +14 -13
  29. package/templates/fate/graphql-client/pages/index.tsx +2 -2
  30. package/templates/fate/graphql-client/pnpm-workspace.yaml +5 -6
  31. package/templates/fate/graphql-client/src/fate/graphql.ts +7 -48
  32. package/templates/fate/graphql-client/src/fate/schema.graphql +48 -0
  33. package/templates/fate/http/client/package.json +13 -13
  34. package/templates/fate/http/client/src/ui/PostCard.tsx +6 -1
  35. package/templates/fate/http/package.json +6 -7
  36. package/templates/fate/http/pnpm-workspace.yaml +5 -5
  37. package/templates/fate/http/server/package.json +7 -7
  38. package/templates/fate/prisma/client/package.json +15 -15
  39. package/templates/fate/prisma/client/src/ui/PostCard.tsx +6 -1
  40. package/templates/fate/prisma/package.json +6 -7
  41. package/templates/fate/prisma/pnpm-workspace.yaml +5 -5
  42. package/templates/fate/prisma/server/package.json +8 -8
  43. package/templates/fate/void/package.json +16 -16
  44. package/templates/fate/void/pnpm-workspace.yaml +5 -6
  45. package/templates/fate/void/src/ui/PostCard.tsx +6 -1
@@ -482,9 +482,9 @@ import env from '../src/lib/env.ts';`,
482
482
  envValues: `{
483
483
  SERVER_URL: import.meta.env.VITE_SERVER_URL,
484
484
  }`,
485
- fateModule: '@app/server/src/graphql/fate.ts',
485
+ fateModule: './src/fate/graphql.ts',
486
486
  fateTransport: `transport: 'graphql',`,
487
- typeModule: '@app/server/src/graphql/fate.ts',
487
+ typeModule: './fate/graphql.ts',
488
488
  },
489
489
  'graphql-client': {
490
490
  clientImports: ``,
@@ -796,6 +796,14 @@ const configureVueTemplate = (targetPath, selectedVariant) => {
796
796
  fs.mkdirSync(frontendRoot, { recursive: true });
797
797
  fs.cpSync(vueTemplatePackage(), frontendRoot, { recursive: true });
798
798
 
799
+ if (selectedVariant === 'graphql') {
800
+ fs.cpSync(
801
+ path.join(packageRoot, 'templates/fate/graphql/client/src/fate'),
802
+ path.join(frontendRoot, 'src/fate'),
803
+ { recursive: true },
804
+ );
805
+ }
806
+
799
807
  if (selectedVariant === 'void') {
800
808
  configureVueVoidServerFiles(frontendRoot);
801
809
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-fate",
3
- "version": "1.8.0",
3
+ "version": "1.10.0",
4
4
  "description": "Create a new fate app.",
5
5
  "homepage": "https://github.com/nkzw-tech/fate",
6
6
  "license": "MIT",
@@ -18,27 +18,27 @@
18
18
  "test:all": "vp check && vp test"
19
19
  },
20
20
  "dependencies": {
21
- "@lucide/vue": "^1.34.0",
21
+ "@lucide/vue": "^1.59.0",
22
22
  "@nkzw/core": "^1.3.1",
23
23
  "@nkzw/define-env": "^1.1.0",
24
- "@trpc/client": "^11.18.0",
25
- "@void/vue": "^1.1.0",
24
+ "@trpc/client": "^11.19.0",
25
+ "@void/vue": "^1.1.12",
26
26
  "class-variance-authority": "^0.7.1",
27
27
  "clsx": "^2.1.1",
28
- "dotenv": "^17.4.2",
29
- "graphql-sse": "^2.6.1",
30
- "tailwind-merge": "^3.6.0",
31
- "void": "^1.1.0",
32
- "vue": "^3.5.41",
28
+ "dotenv": "^18.0.8",
29
+ "graphql-sse": "^2.6.3",
30
+ "tailwind-merge": "^3.7.0",
31
+ "void": "^1.1.12",
32
+ "vue": "^3.5.44",
33
33
  "vue-fate": "latest"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@nkzw/eslint-plugin": "^2.0.0",
37
37
  "@nkzw/oxlint-config": "^2.0.1",
38
- "@oxc-node/core": "^0.1.0",
39
- "@swc/core": "^1.16.1",
38
+ "@oxc-node/core": "^0.1.7",
39
+ "@swc/core": "^1.16.18",
40
40
  "@tailwindcss/vite": "^4.3.3",
41
- "@types/node": "^26.4.0",
41
+ "@types/node": "^26.6.5",
42
42
  "@vitejs/plugin-vue": "^6.0.10",
43
43
  "tailwindcss": "^4.3.3",
44
44
  "typescript": "^7.0.2",
@@ -21,35 +21,35 @@
21
21
  },
22
22
  "dependencies": {
23
23
  "@app/server": "workspace:*",
24
- "@hono/node-server": "^2.1.1",
24
+ "@hono/node-server": "^2.1.5",
25
25
  "@nkzw/core": "^1.3.1",
26
26
  "@nkzw/define-env": "^1.1.0",
27
27
  "@nkzw/stack": "^2.3.2",
28
- "@radix-ui/react-slot": "^1.3.3",
29
- "@trpc/client": "^11.18.0",
30
- "@void/react": "^1.1.0",
31
- "better-auth": "^1.7.7",
28
+ "@radix-ui/react-slot": "^1.5.0",
29
+ "@trpc/client": "^11.19.0",
30
+ "@void/react": "^1.1.12",
31
+ "better-auth": "^1.7.11",
32
32
  "class-variance-authority": "^0.7.1",
33
33
  "clsx": "^2.1.1",
34
34
  "fbtee": "^5.0.0",
35
- "lucide-react": "^1.34.0",
36
- "react": "^19.3.0",
37
- "react-dom": "^19.3.0",
38
- "react-error-boundary": "^6.1.3",
35
+ "lucide-react": "^1.59.0",
36
+ "react": "^19.3.1",
37
+ "react-dom": "^19.3.1",
38
+ "react-error-boundary": "^6.1.6",
39
39
  "react-fate": "latest",
40
- "tailwind-merge": "^3.6.0",
41
- "void": "^1.1.0"
40
+ "tailwind-merge": "^3.7.0",
41
+ "void": "^1.1.12"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@nkzw/fbtee-compiler": "^5.0.0",
45
45
  "@nkzw/vite-plugin-fbtee": "^5.0.0",
46
46
  "@tailwindcss/vite": "^4.3.3",
47
- "@trpc/server": "^11.18.0",
48
- "@types/node": "^26.4.0",
47
+ "@trpc/server": "^11.19.0",
48
+ "@types/node": "^26.6.5",
49
49
  "@types/react": "^19.3.0",
50
50
  "@types/react-dom": "^19.3.0",
51
- "@vitejs/plugin-react": "^6.1.0",
52
- "oxc-transform-react": "^0.147.0",
51
+ "@vitejs/plugin-react": "^6.1.2",
52
+ "oxc-transform-react": "^0.154.0",
53
53
  "tailwindcss": "^4.3.3",
54
54
  "vite": "catalog:",
55
55
  "vite-plus": "catalog:"
@@ -78,7 +78,11 @@ const CommentInput = ({
78
78
  post,
79
79
  }: {
80
80
  error?: unknown;
81
- post: { commentCount: number; id: string };
81
+ post: {
82
+ commentCount: number;
83
+ comments: Deferred<{ items: ReadonlyArray<{ node: ViewRef<'Comment'> }> }>;
84
+ id: string;
85
+ };
82
86
  }) => {
83
87
  const fate = useFateClient();
84
88
  const { data: session } = AuthClient.useSession();
@@ -94,6 +98,7 @@ const CommentInput = ({
94
98
 
95
99
  const result = await fate.mutations.comment.add({
96
100
  input: { content, postId: post.id },
101
+ insert: { into: post.comments, position: 'after' },
97
102
  optimistic: {
98
103
  author: user
99
104
  ? {
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "type": "module",
12
12
  "scripts": {
13
- "build": "dotenv -e server/.env -- vp run --filter '@app/client' --filter '@app/server' build",
13
+ "build": "dotenv run -f server/.env -- vp run --filter '@app/client' --filter '@app/server' build",
14
14
  "dev": "npm-run-all --parallel dev:client dev:server",
15
15
  "dev:client": "cd client && vp dev",
16
16
  "dev:server": "cd server && vp run dev",
@@ -23,11 +23,10 @@
23
23
  "@app/server": "workspace:*",
24
24
  "@nkzw/eslint-plugin": "^2.0.0",
25
25
  "@nkzw/oxlint-config": "^2.0.1",
26
- "@oxc-node/core": "^0.1.0",
27
- "@swc/core": "^1.16.1",
28
- "@types/node": "^26.4.0",
29
- "dotenv": "^17.4.2",
30
- "dotenv-cli": "^11.0.0",
26
+ "@oxc-node/core": "^0.1.7",
27
+ "@swc/core": "^1.16.18",
28
+ "@types/node": "^26.6.5",
29
+ "dotenv": "^18.0.8",
31
30
  "npm-run-all2": "^9.0.3",
32
31
  "typescript": "^7.0.2",
33
32
  "vite": "catalog:",
@@ -38,5 +37,5 @@
38
37
  "node": ">=24.0.0",
39
38
  "pnpm": ">=11.0.0"
40
39
  },
41
- "packageManager": "pnpm@11.0.6"
40
+ "packageManager": "pnpm@12.6.0"
42
41
  }
@@ -4,16 +4,16 @@ packages:
4
4
 
5
5
  allowBuilds:
6
6
  '@swc/core': true
7
- better-sqlite3: true
7
+ better-sqlite3: false
8
8
  drizzle-kit: true
9
9
  esbuild: true
10
10
  sharp: true
11
11
  workerd: true
12
12
 
13
13
  catalog:
14
- vite: npm:@voidzero-dev/vite-plus-core@1.2.0
15
- vite-plus: 1.2.0
16
- vitest: 5.0.4
14
+ vite: npm:@voidzero-dev/vite-plus-core@1.3.0
15
+ vite-plus: 1.3.0
16
+ vitest: 5.0.5
17
17
 
18
18
  minimumReleaseAgeExclude:
19
19
  - '@voidzero-dev/vite-plus-core'
@@ -28,7 +28,7 @@ onlyBuiltDependencies:
28
28
  - unrs-resolver
29
29
 
30
30
  overrides:
31
- better-auth: 1.7.7
31
+ better-auth: 1.7.11
32
32
  drizzle-orm: 0.45.4
33
33
  kysely: 0.28.17
34
34
  vite: 'catalog:'
@@ -20,22 +20,22 @@
20
20
  "drizzle": "drizzle-kit --config drizzle.config.ts"
21
21
  },
22
22
  "dependencies": {
23
- "@hono/node-server": "^2.1.1",
23
+ "@hono/node-server": "^2.1.5",
24
24
  "@hono/trpc-server": "^0.4.2",
25
25
  "@nkzw/core": "^1.3.1",
26
26
  "@nkzw/define-env": "^1.1.0",
27
27
  "@nkzw/fate": "latest",
28
- "@trpc/server": "^11.18.0",
29
- "better-auth": "^1.7.7",
28
+ "@trpc/server": "^11.19.0",
29
+ "better-auth": "^1.7.11",
30
30
  "drizzle-orm": "^0.45.4",
31
- "hono": "^4.13.5",
32
- "pg": "^8.23.1",
33
- "zod": "^4.4.3"
31
+ "hono": "^4.13.13",
32
+ "pg": "8.23.1",
33
+ "zod": "^4.6.7"
34
34
  },
35
35
  "devDependencies": {
36
- "@types/node": "^26.4.0",
36
+ "@types/node": "^26.6.5",
37
37
  "@types/pg": "^8.23.1",
38
- "drizzle-kit": "^0.31.10",
38
+ "drizzle-kit": "^0.31.11",
39
39
  "nodemon": "^3.1.14",
40
40
  "vite-plus": "catalog:"
41
41
  },
@@ -23,7 +23,7 @@ This guidance is for agents working in projects bootstrapped from the fate templ
23
23
  - **Use ViewRefs:** Pass references instead of raw data. Keep components focused on views and `ViewRef`s to let fate manage data masking and updates.
24
24
  - **Co-locate data needs:** Keep view definitions near their components and compose them upward to the request root for predictable fetching.
25
25
  - **Use Suspense:** Wrap pages in `Suspense`/`ErrorBoundary` instead of ad-hoc loading/error flags; fate aligns with Async React by design.
26
- - **Do not duplicate types:** Keep generated GraphQL/Fate types and views imported from the server package. Avoid redefining entity shapes on the client. This ensures view selections stay type-safe end-to-end.
26
+ - **Do not duplicate types:** Use `GraphQLEntities` from `client/.fate/schema.generated.ts` for GraphQL view types. The client mapping exports convenient aliases; avoid redefining entity shapes on the client. This ensures view selections stay type-safe end-to-end.
27
27
  - **`useRequest` only at the root:** When adding routes or layouts, create a dedicated `useRequest` call per screen root that pulls together all child views; do not scatter `useRequest` across leaf components unless it's necessary to issue requests due to user input.
28
28
  - **React Actions:** Prefer React Action-friendly UI primitives (buttons/forms that accept an `action` prop). If unavailable, wrap action calls with `startTransition` in `onClick` handlers.
29
29
  - **fate client support** fate's local client support files are maintained by the Vite/fate tooling. Do not manually edit `.fate` files; make the proper schema changes on the server and run `pnpm fate:generate` when working outside Vite dev.
@@ -16,6 +16,17 @@ vp create fate -- --template graphql
16
16
 
17
17
  Read the [Getting Started Guide](https://fate.technology/guide/core-concepts) to learn how to use _fate_ in your React applications.
18
18
 
19
+ ## GraphQL Types
20
+
21
+ After changing your GraphQL schema, regenerate the schema file and client types:
22
+
23
+ ```bash
24
+ vp run --filter '@app/server' generate-graphql
25
+ vp run fate:generate
26
+ ```
27
+
28
+ `client/src/fate/graphql.ts` maps query and mutation names. Client views use `GraphQLEntities` from `client/.fate/schema.generated.ts`, generated from your Pothos schema. Server data views handle live updates and authorization.
29
+
19
30
  ## Technologies
20
31
 
21
32
  This default template combines the Nakazawa Tech's [Web App Template](https://github.com/nkzw-tech/web-app-template) and [Server Template](https://github.com/nkzw-tech/server-template) into a monorepo, with unified tooling and _fate_ as the data client. It currently uses GraphQL with Pothos, Relay-style connections, and Prisma.
@@ -114,7 +125,7 @@ Common commands from the project root:
114
125
  - `vp run dev:client` starts only the client.
115
126
  - `vp run dev:server` starts only the server.
116
127
  - `vp run dev:setup` generates the Prisma client, Pothos schema import map, fbtee setup, and fate client support.
117
- - `vp run fate:generate` refreshes fate client support after changing server views, roots, or routers.
128
+ - `vp run fate:generate` regenerates client types after changing the GraphQL schema or client mapping.
118
129
  - `vp run prisma` runs Prisma CLI commands in the server package.
119
130
  - `vp check --fix` formats, lints, and type-checks the workspace.
120
131
  - `vp test` runs the test suite.
@@ -21,34 +21,34 @@
21
21
  },
22
22
  "dependencies": {
23
23
  "@app/server": "workspace:*",
24
- "@hono/node-server": "^2.1.1",
24
+ "@hono/node-server": "^2.1.5",
25
25
  "@nkzw/core": "^1.3.1",
26
26
  "@nkzw/define-env": "^1.1.0",
27
27
  "@nkzw/stack": "^2.3.2",
28
- "@radix-ui/react-slot": "^1.3.3",
29
- "@void/react": "^1.1.0",
30
- "better-auth": "^1.7.7",
28
+ "@radix-ui/react-slot": "^1.5.0",
29
+ "@void/react": "^1.1.12",
30
+ "better-auth": "^1.7.11",
31
31
  "class-variance-authority": "^0.7.1",
32
32
  "clsx": "^2.1.1",
33
33
  "fbtee": "^5.0.0",
34
- "graphql-sse": "^2.6.1",
35
- "lucide-react": "^1.34.0",
36
- "react": "^19.3.0",
37
- "react-dom": "^19.3.0",
38
- "react-error-boundary": "^6.1.3",
34
+ "graphql-sse": "^2.6.3",
35
+ "lucide-react": "^1.59.0",
36
+ "react": "^19.3.1",
37
+ "react-dom": "^19.3.1",
38
+ "react-error-boundary": "^6.1.6",
39
39
  "react-fate": "latest",
40
- "tailwind-merge": "^3.6.0",
41
- "void": "^1.1.0"
40
+ "tailwind-merge": "^3.7.0",
41
+ "void": "^1.1.12"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@nkzw/fbtee-compiler": "^5.0.0",
45
45
  "@nkzw/vite-plugin-fbtee": "^5.0.0",
46
46
  "@tailwindcss/vite": "^4.3.3",
47
- "@types/node": "^26.4.0",
47
+ "@types/node": "^26.6.5",
48
48
  "@types/react": "^19.3.0",
49
49
  "@types/react-dom": "^19.3.0",
50
- "@vitejs/plugin-react": "^6.1.0",
51
- "oxc-transform-react": "^0.147.0",
50
+ "@vitejs/plugin-react": "^6.1.2",
51
+ "oxc-transform-react": "^0.154.0",
52
52
  "tailwindcss": "^4.3.3",
53
53
  "vite": "catalog:",
54
54
  "vite-plus": "catalog:"
@@ -90,7 +90,7 @@ export default function HomePage() {
90
90
  </Card>
91
91
  {viewer?.id && <UserCard user={viewer} />}
92
92
  </div>
93
- <PostFeed posts={posts} />
93
+ {posts && <PostFeed posts={posts} />}
94
94
  </Section>
95
95
  );
96
96
  }
@@ -1,9 +1,9 @@
1
- import type { Comment, Post } from '@app/server/src/graphql/fate.ts';
2
1
  import Stack, { VStack } from '@nkzw/stack';
3
2
  import { fbs } from 'fbtee';
4
3
  import { Suspense, useDeferredValue, useState } from 'react';
5
4
  import { ErrorBoundary } from 'react-error-boundary';
6
5
  import { useRequest, useView, view, ViewRef } from 'react-fate';
6
+ import type { Comment, Post } from '../src/fate/graphql.ts';
7
7
  import cx from '../src/lib/cx.tsx';
8
8
  import Card from '../src/ui/Card.tsx';
9
9
  import CommentCard, { CommentView } from '../src/ui/CommentCard.tsx';
@@ -37,7 +37,7 @@ const SearchResults = ({ isStale, query }: { isStale: boolean; query: string })
37
37
  commentSearch: { args: { query }, list: CommentSearchView },
38
38
  });
39
39
 
40
- if (commentSearch.length === 0) {
40
+ if (!commentSearch?.length) {
41
41
  return (
42
42
  <p>
43
43
  <fbt desc="No matches text">
@@ -0,0 +1,20 @@
1
+ import schema from '@app/server/src/graphql/schema.graphql?raw';
2
+ import type { GraphQLEntities } from '../../.fate/schema.generated.ts';
3
+
4
+ export type User = GraphQLEntities['User'];
5
+ export type Post = GraphQLEntities['Post'];
6
+ export type Comment = GraphQLEntities['Comment'];
7
+
8
+ export const fateGraphQL = {
9
+ mutations: {
10
+ 'comment.add': { entity: 'Comment', field: 'commentAdd' },
11
+ 'comment.delete': { entity: 'Comment', field: 'commentDelete' },
12
+ 'post.add': { entity: 'Post', field: 'postAdd' },
13
+ 'post.like': { entity: 'Post', field: 'postLike' },
14
+ 'post.unlike': { entity: 'Post', field: 'postUnlike' },
15
+ 'user.update': { entity: 'User', field: 'userUpdate' },
16
+ },
17
+ roots: { categories: {}, commentSearch: {}, events: {}, posts: {}, viewer: {} },
18
+ scalars: { DateTime: 'string' },
19
+ schema,
20
+ } as const;
@@ -1,8 +1,8 @@
1
- import type { Comment } from '@app/server/src/graphql/fate.ts';
2
1
  import Stack from '@nkzw/stack';
3
2
  import { X } from 'lucide-react';
4
3
  import { useView, view, ViewRef } from 'react-fate';
5
4
  import { useFateClient } from 'react-fate';
5
+ import type { Comment } from '../fate/graphql.ts';
6
6
  import { Button } from './Button.tsx';
7
7
  import Link from './Link.tsx';
8
8
 
@@ -1,4 +1,3 @@
1
- import type { Comment as InlineComment, Post } from '@app/server/src/graphql/fate.ts';
2
1
  import Stack, { VStack } from '@nkzw/stack';
3
2
  import { cx } from 'class-variance-authority';
4
3
  import { fbs } from 'fbtee';
@@ -21,6 +20,7 @@ import {
21
20
  view,
22
21
  ViewRef,
23
22
  } from 'react-fate';
23
+ import type { Comment as InlineComment, Post } from '../fate/graphql.ts';
24
24
  import { Button } from '../ui/Button.tsx';
25
25
  import Card from '../ui/Card.tsx';
26
26
  import AuthClient from '../user/AuthClient.tsx';
@@ -74,7 +74,11 @@ const CommentInput = ({
74
74
  post,
75
75
  }: {
76
76
  error?: unknown;
77
- post: { commentCount: number; id: string };
77
+ post: {
78
+ commentCount: number;
79
+ comments: Deferred<{ items: ReadonlyArray<{ node: ViewRef<'Comment'> }> }>;
80
+ id: string;
81
+ };
78
82
  }) => {
79
83
  const fate = useFateClient();
80
84
  const { data: session } = AuthClient.useSession();
@@ -90,6 +94,7 @@ const CommentInput = ({
90
94
 
91
95
  const result = await fate.mutations.comment.add({
92
96
  input: { content, postId: post.id },
97
+ insert: { into: post.comments, position: 'after' },
93
98
  optimistic: {
94
99
  author: user
95
100
  ? {
@@ -1,4 +1,3 @@
1
- import type { User } from '@app/server/src/graphql/fate.ts';
2
1
  import safeParse from '@nkzw/core/safeParse.js';
3
2
  import Stack, { VStack } from '@nkzw/stack';
4
3
  import { fbs } from 'fbtee';
@@ -7,6 +6,7 @@ import { view } from 'react-fate';
7
6
  import { useFateClient } from 'react-fate';
8
7
  import { ViewRef } from 'react-fate';
9
8
  import { useView } from 'react-fate';
9
+ import type { User } from '../fate/graphql.ts';
10
10
  import { Button } from '../ui/Button.tsx';
11
11
  import Card from '../ui/Card.tsx';
12
12
  import AuthClient from '../user/AuthClient.tsx';
@@ -29,7 +29,7 @@ export default defineConfig({
29
29
  voidReact({ react: { compiler: true } }),
30
30
  ]) ?? []),
31
31
  fate({
32
- module: '@app/server/src/graphql/fate.ts',
32
+ module: './src/fate/graphql.ts',
33
33
  transport: 'graphql',
34
34
  }),
35
35
  ],
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "type": "module",
12
12
  "scripts": {
13
- "build": "dotenv -e server/.env -- vp run --filter '@app/client' --filter '@app/server' build",
13
+ "build": "dotenv run -f server/.env -- vp run --filter '@app/client' --filter '@app/server' build",
14
14
  "dev": "npm-run-all --parallel dev:client dev:server",
15
15
  "dev:client": "cd client && vp dev",
16
16
  "dev:server": "cd server && vp run dev",
@@ -23,11 +23,10 @@
23
23
  "@app/server": "workspace:*",
24
24
  "@nkzw/eslint-plugin": "^2.0.0",
25
25
  "@nkzw/oxlint-config": "^2.0.1",
26
- "@oxc-node/core": "^0.1.0",
27
- "@swc/core": "^1.16.1",
28
- "@types/node": "^26.4.0",
29
- "dotenv": "^17.4.2",
30
- "dotenv-cli": "^11.0.0",
26
+ "@oxc-node/core": "^0.1.7",
27
+ "@swc/core": "^1.16.18",
28
+ "@types/node": "^26.6.5",
29
+ "dotenv": "^18.0.8",
31
30
  "npm-run-all2": "^9.0.3",
32
31
  "prisma": "^7.10.0",
33
32
  "typescript": "^7.0.2",
@@ -39,5 +38,5 @@
39
38
  "node": ">=24.0.0",
40
39
  "pnpm": ">=11.0.0"
41
40
  },
42
- "packageManager": "pnpm@11.0.6"
41
+ "packageManager": "pnpm@12.6.0"
43
42
  }
@@ -5,16 +5,16 @@ packages:
5
5
  allowBuilds:
6
6
  '@prisma/engines': true
7
7
  '@swc/core': true
8
- better-sqlite3: true
8
+ better-sqlite3: false
9
9
  esbuild: true
10
10
  prisma: true
11
11
  sharp: true
12
12
  workerd: true
13
13
 
14
14
  catalog:
15
- vite: npm:@voidzero-dev/vite-plus-core@1.2.0
16
- vite-plus: 1.2.0
17
- vitest: 5.0.4
15
+ vite: npm:@voidzero-dev/vite-plus-core@1.3.0
16
+ vite-plus: 1.3.0
17
+ vitest: 5.0.5
18
18
 
19
19
  minimumReleaseAgeExclude:
20
20
  - '@voidzero-dev/vite-plus-core'
@@ -31,7 +31,7 @@ onlyBuiltDependencies:
31
31
  - unrs-resolver
32
32
 
33
33
  overrides:
34
- better-auth: 1.7.7
34
+ better-auth: 1.7.11
35
35
  kysely: 0.28.17
36
36
  vite: 'catalog:'
37
37
  vitest: 'catalog:'
@@ -14,14 +14,13 @@ vp run dev
14
14
 
15
15
  The server defaults to `http://localhost:9000/graphql`.
16
16
 
17
- To generate the Fate client against this server, point the Vite plugin at:
17
+ `vp run dev:setup` exports the GraphQL schema for the client. From the client directory, point the Vite plugin at the mapping module:
18
18
 
19
19
  ```ts
20
20
  fate({
21
- module: '@app/server/src/graphql/fate.ts',
21
+ module: './src/fate/graphql.ts',
22
22
  transport: 'graphql',
23
23
  });
24
24
  ```
25
25
 
26
- The generated client keeps the same Fate roots, views, mutations, store, and cache behavior;
27
- only the transport and server module change.
26
+ fate generates client types from the schema. Server data views in `src/graphql/views.ts` handle live updates, authorization, and computed fields.
@@ -16,37 +16,37 @@
16
16
  "prisma": "prisma"
17
17
  },
18
18
  "dependencies": {
19
- "@graphql-tools/utils": "^12.0.0",
20
- "@graphql-yoga/plugin-graphql-sse": "^3.22.0",
21
- "@hono/node-server": "^2.1.1",
19
+ "@graphql-tools/utils": "^12.1.0",
20
+ "@graphql-yoga/plugin-graphql-sse": "^3.24.6",
21
+ "@hono/node-server": "^2.1.5",
22
22
  "@nkzw/core": "^1.3.1",
23
23
  "@nkzw/define-env": "^1.1.0",
24
24
  "@nkzw/fate": "latest",
25
- "@pothos/core": "^4.13.1",
26
- "@pothos/plugin-complexity": "^4.2.1",
27
- "@pothos/plugin-directives": "^4.3.1",
28
- "@pothos/plugin-prisma": "^4.15.0",
29
- "@pothos/plugin-relay": "^4.7.1",
30
- "@pothos/plugin-scope-auth": "^4.1.7",
31
- "@prisma/adapter-pg": "^7.10.0",
32
- "@prisma/client": "^7.10.0",
33
- "better-auth": "^1.7.7",
25
+ "@pothos/core": "^4.15.1",
26
+ "@pothos/plugin-complexity": "^4.2.3",
27
+ "@pothos/plugin-directives": "^4.3.2",
28
+ "@pothos/plugin-prisma": "^4.17.0",
29
+ "@pothos/plugin-relay": "^4.8.1",
30
+ "@pothos/plugin-scope-auth": "^4.2.1",
31
+ "@prisma/adapter-pg": "^7.10.1",
32
+ "@prisma/client": "^7.10.1",
33
+ "better-auth": "^1.7.11",
34
34
  "graphql": "^17.0.2",
35
- "graphql-yoga": "^5.22.0",
36
- "hono": "^4.13.5"
35
+ "graphql-yoga": "^5.24.6",
36
+ "hono": "^4.13.13"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@nkzw/eslint-plugin": "^2.0.0",
40
40
  "@nkzw/oxlint-config": "^2.0.1",
41
- "@oxc-node/core": "^0.1.0",
42
- "@swc/core": "^1.16.1",
43
- "@types/node": "^26.4.0",
44
- "dotenv": "^17.4.2",
41
+ "@oxc-node/core": "^0.1.7",
42
+ "@swc/core": "^1.16.18",
43
+ "@types/node": "^26.6.5",
44
+ "dotenv": "^18.0.8",
45
45
  "glob": "^13.0.6",
46
46
  "nodemon": "^3.1.14",
47
47
  "oxfmt": "^0.65.0",
48
48
  "prisma": "^7.10.0",
49
- "prisma-json-types-generator": "^5.1.1",
49
+ "prisma-json-types-generator": "^5.2.0",
50
50
  "typescript": "^7.0.2",
51
51
  "vite-plus": "catalog:",
52
52
  "vitest": "catalog:"
@@ -3,6 +3,8 @@ import { createHash } from 'node:crypto';
3
3
  import { writeFileSync } from 'node:fs';
4
4
  import { join, posix, relative, sep } from 'node:path';
5
5
  import { styleText } from 'node:util';
6
+ import { printSchemaWithDirectives } from '@graphql-tools/utils';
7
+ import dotenv from 'dotenv';
6
8
  import { globSync } from 'glob';
7
9
  import { format } from 'oxfmt';
8
10
 
@@ -37,4 +39,8 @@ writeFileSync(
37
39
  ),
38
40
  );
39
41
 
40
- console.log(styleText(['green', 'bold'], '✓ Done generating GraphQL schema import map.'));
42
+ dotenv.config({ path: join(root, '.env'), quiet: true });
43
+ const { default: schema } = await import('../src/graphql/schema.tsx');
44
+ writeFileSync(join(path, 'schema.graphql'), printSchemaWithDirectives(schema), 'utf8');
45
+
46
+ console.log(styleText(['green', 'bold'], '✓ Done generating GraphQL schema and import map.'));