create-fate 1.8.0 → 1.9.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.
- package/bin/create-fate.mjs +10 -2
- package/package.json +1 -1
- package/templates/fate/_shared/vue-app/package.json +11 -11
- package/templates/fate/drizzle/client/package.json +15 -15
- package/templates/fate/drizzle/package.json +6 -7
- package/templates/fate/drizzle/pnpm-workspace.yaml +5 -5
- package/templates/fate/drizzle/server/package.json +8 -8
- package/templates/fate/graphql/AGENTS.md +1 -1
- package/templates/fate/graphql/README.md +12 -0
- package/templates/fate/graphql/client/package.json +14 -14
- package/templates/fate/graphql/client/pages/index.tsx +1 -1
- package/templates/fate/graphql/client/pages/search.tsx +2 -2
- package/templates/fate/graphql/client/src/fate/graphql.ts +20 -0
- package/templates/fate/graphql/client/src/ui/CommentCard.tsx +1 -1
- package/templates/fate/graphql/client/src/ui/PostCard.tsx +1 -1
- package/templates/fate/graphql/client/src/ui/UserCard.tsx +1 -1
- package/templates/fate/graphql/client/vite.config.ts +1 -1
- package/templates/fate/graphql/package.json +6 -7
- package/templates/fate/graphql/pnpm-workspace.yaml +5 -5
- package/templates/fate/graphql/server/README.md +5 -4
- package/templates/fate/graphql/server/package.json +19 -19
- package/templates/fate/graphql/server/scripts/generate-graphql.tsx +7 -1
- package/templates/fate/graphql/server/src/graphql/fate.ts +0 -56
- package/templates/fate/graphql/server/src/graphql/schema.tsx +22 -3
- package/templates/fate/graphql/server/src/graphql/views.ts +0 -43
- package/templates/fate/graphql-client/README.md +16 -14
- package/templates/fate/graphql-client/package.json +14 -13
- package/templates/fate/graphql-client/pages/index.tsx +2 -2
- package/templates/fate/graphql-client/pnpm-workspace.yaml +5 -6
- package/templates/fate/graphql-client/src/fate/graphql.ts +7 -48
- package/templates/fate/graphql-client/src/fate/schema.graphql +48 -0
- package/templates/fate/http/client/package.json +13 -13
- package/templates/fate/http/package.json +6 -7
- package/templates/fate/http/pnpm-workspace.yaml +5 -5
- package/templates/fate/http/server/package.json +7 -7
- package/templates/fate/prisma/client/package.json +15 -15
- package/templates/fate/prisma/package.json +6 -7
- package/templates/fate/prisma/pnpm-workspace.yaml +5 -5
- package/templates/fate/prisma/server/package.json +8 -8
- package/templates/fate/void/package.json +16 -16
- package/templates/fate/void/pnpm-workspace.yaml +5 -6
package/bin/create-fate.mjs
CHANGED
|
@@ -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: '
|
|
485
|
+
fateModule: './src/fate/graphql.ts',
|
|
486
486
|
fateTransport: `transport: 'graphql',`,
|
|
487
|
-
typeModule: '
|
|
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
|
@@ -18,27 +18,27 @@
|
|
|
18
18
|
"test:all": "vp check && vp test"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@lucide/vue": "^1.
|
|
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.
|
|
25
|
-
"@void/vue": "^1.1.
|
|
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": "^
|
|
29
|
-
"graphql-sse": "^2.6.
|
|
30
|
-
"tailwind-merge": "^3.
|
|
31
|
-
"void": "^1.1.
|
|
32
|
-
"vue": "^3.5.
|
|
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.
|
|
39
|
-
"@swc/core": "^1.16.
|
|
38
|
+
"@oxc-node/core": "^0.1.7",
|
|
39
|
+
"@swc/core": "^1.16.18",
|
|
40
40
|
"@tailwindcss/vite": "^4.3.3",
|
|
41
|
-
"@types/node": "^26.
|
|
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.
|
|
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.
|
|
29
|
-
"@trpc/client": "^11.
|
|
30
|
-
"@void/react": "^1.1.
|
|
31
|
-
"better-auth": "^1.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.
|
|
36
|
-
"react": "^19.3.
|
|
37
|
-
"react-dom": "^19.3.
|
|
38
|
-
"react-error-boundary": "^6.1.
|
|
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.
|
|
41
|
-
"void": "^1.1.
|
|
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.
|
|
48
|
-
"@types/node": "^26.
|
|
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.
|
|
52
|
-
"oxc-transform-react": "^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:"
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
"type": "module",
|
|
12
12
|
"scripts": {
|
|
13
|
-
"build": "dotenv -
|
|
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.
|
|
27
|
-
"@swc/core": "^1.16.
|
|
28
|
-
"@types/node": "^26.
|
|
29
|
-
"dotenv": "^
|
|
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@
|
|
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:
|
|
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.
|
|
15
|
-
vite-plus: 1.
|
|
16
|
-
vitest: 5.0.
|
|
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.
|
|
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.
|
|
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.
|
|
29
|
-
"better-auth": "^1.7.
|
|
28
|
+
"@trpc/server": "^11.19.0",
|
|
29
|
+
"better-auth": "^1.7.11",
|
|
30
30
|
"drizzle-orm": "^0.45.4",
|
|
31
|
-
"hono": "^4.13.
|
|
32
|
-
"pg": "
|
|
33
|
-
"zod": "^4.
|
|
31
|
+
"hono": "^4.13.13",
|
|
32
|
+
"pg": "8.23.1",
|
|
33
|
+
"zod": "^4.6.7"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@types/node": "^26.
|
|
36
|
+
"@types/node": "^26.6.5",
|
|
37
37
|
"@types/pg": "^8.23.1",
|
|
38
|
-
"drizzle-kit": "^0.31.
|
|
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:**
|
|
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,18 @@ 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
|
+
`client/src/fate/graphql.ts` imports the SDL exported from the Pothos schema during `dev:setup` and maps application root
|
|
22
|
+
and mutation names. Fate generates `client/.fate/schema.generated.ts` from that
|
|
23
|
+
schema; its `GraphQLEntities` types are used by the client views. Mutation inputs,
|
|
24
|
+
output nullability, and connection shapes also come from the schema.
|
|
25
|
+
|
|
26
|
+
Run `vp run --filter '@app/server' generate-graphql` after changing schema fields,
|
|
27
|
+
then `vp run fate:generate` to update the client contracts. The server's
|
|
28
|
+
Prisma data views implement live-event resolution and authorization; they are
|
|
29
|
+
independent of these generated client contracts.
|
|
30
|
+
|
|
19
31
|
## Technologies
|
|
20
32
|
|
|
21
33
|
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.
|
|
@@ -21,34 +21,34 @@
|
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@app/server": "workspace:*",
|
|
24
|
-
"@hono/node-server": "^2.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.
|
|
29
|
-
"@void/react": "^1.1.
|
|
30
|
-
"better-auth": "^1.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.
|
|
35
|
-
"lucide-react": "^1.
|
|
36
|
-
"react": "^19.3.
|
|
37
|
-
"react-dom": "^19.3.
|
|
38
|
-
"react-error-boundary": "^6.1.
|
|
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.
|
|
41
|
-
"void": "^1.1.
|
|
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.
|
|
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.
|
|
51
|
-
"oxc-transform-react": "^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:"
|
|
@@ -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
|
|
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';
|
|
@@ -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';
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
"type": "module",
|
|
12
12
|
"scripts": {
|
|
13
|
-
"build": "dotenv -
|
|
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.
|
|
27
|
-
"@swc/core": "^1.16.
|
|
28
|
-
"@types/node": "^26.
|
|
29
|
-
"dotenv": "^
|
|
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@
|
|
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:
|
|
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.
|
|
16
|
-
vite-plus: 1.
|
|
17
|
-
vitest: 5.0.
|
|
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.
|
|
34
|
+
better-auth: 1.7.11
|
|
35
35
|
kysely: 0.28.17
|
|
36
36
|
vite: 'catalog:'
|
|
37
37
|
vitest: 'catalog:'
|
|
@@ -14,14 +14,15 @@ vp run dev
|
|
|
14
14
|
|
|
15
15
|
The server defaults to `http://localhost:9000/graphql`.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
The client mapping imports the SDL exported from the Pothos schema during `dev:setup`. From the client directory, configure the Vite plugin with:
|
|
18
18
|
|
|
19
19
|
```ts
|
|
20
20
|
fate({
|
|
21
|
-
module: '
|
|
21
|
+
module: './src/fate/graphql.ts',
|
|
22
22
|
transport: 'graphql',
|
|
23
23
|
});
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
Fate derives entity fields, connection roots, mutation inputs, and selected results from the schema.
|
|
27
|
+
The server data views in `src/graphql/views.ts` remain responsible for live-event resolution,
|
|
28
|
+
including authorization and computed fields. They do not define the GraphQL client types.
|
|
@@ -16,37 +16,37 @@
|
|
|
16
16
|
"prisma": "prisma"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@graphql-tools/utils": "^12.
|
|
20
|
-
"@graphql-yoga/plugin-graphql-sse": "^3.
|
|
21
|
-
"@hono/node-server": "^2.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.
|
|
26
|
-
"@pothos/plugin-complexity": "^4.2.
|
|
27
|
-
"@pothos/plugin-directives": "^4.3.
|
|
28
|
-
"@pothos/plugin-prisma": "^4.
|
|
29
|
-
"@pothos/plugin-relay": "^4.
|
|
30
|
-
"@pothos/plugin-scope-auth": "^4.1
|
|
31
|
-
"@prisma/adapter-pg": "^7.10.
|
|
32
|
-
"@prisma/client": "^7.10.
|
|
33
|
-
"better-auth": "^1.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.
|
|
36
|
-
"hono": "^4.13.
|
|
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.
|
|
42
|
-
"@swc/core": "^1.16.
|
|
43
|
-
"@types/node": "^26.
|
|
44
|
-
"dotenv": "^
|
|
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.
|
|
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
|
-
|
|
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.'));
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { graphqlMutation } from '@nkzw/fate';
|
|
2
1
|
import { createLiveEventBus } from '@nkzw/fate/server';
|
|
3
2
|
import { createPrismaSourceAdapter } from '@nkzw/fate/server/prisma';
|
|
4
3
|
import type { AppContext } from './context.tsx';
|
|
@@ -11,38 +10,8 @@ import {
|
|
|
11
10
|
Root,
|
|
12
11
|
tagDataView,
|
|
13
12
|
userDataView,
|
|
14
|
-
type Comment,
|
|
15
|
-
type Post,
|
|
16
|
-
type User,
|
|
17
13
|
} from './views.ts';
|
|
18
14
|
|
|
19
|
-
type FateMutationInput<Input extends Record<string, unknown>> = Input & {
|
|
20
|
-
args?: Record<string, unknown>;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export type PostAddInput = FateMutationInput<{
|
|
24
|
-
content: string;
|
|
25
|
-
title: string;
|
|
26
|
-
}>;
|
|
27
|
-
export type PostLikeInput = FateMutationInput<{
|
|
28
|
-
error?: 'boundary' | 'callSite';
|
|
29
|
-
id: string;
|
|
30
|
-
slow?: boolean;
|
|
31
|
-
}>;
|
|
32
|
-
export type PostUnlikeInput = FateMutationInput<{
|
|
33
|
-
id: string;
|
|
34
|
-
}>;
|
|
35
|
-
export type CommentAddInput = FateMutationInput<{
|
|
36
|
-
content: string;
|
|
37
|
-
postId: string;
|
|
38
|
-
}>;
|
|
39
|
-
export type CommentDeleteInput = FateMutationInput<{
|
|
40
|
-
id: string;
|
|
41
|
-
}>;
|
|
42
|
-
export type UserUpdateInput = FateMutationInput<{
|
|
43
|
-
name: string;
|
|
44
|
-
}>;
|
|
45
|
-
|
|
46
15
|
export const live = createLiveEventBus();
|
|
47
16
|
|
|
48
17
|
export const fate = createPrismaSourceAdapter<AppContext>({
|
|
@@ -58,28 +27,3 @@ export const viewsByType = {
|
|
|
58
27
|
Tag: tagDataView,
|
|
59
28
|
User: userDataView,
|
|
60
29
|
} as const;
|
|
61
|
-
|
|
62
|
-
export const fateGraphQL = {
|
|
63
|
-
mutations: {
|
|
64
|
-
'comment.add': graphqlMutation<Comment, CommentAddInput, Comment>('Comment', {
|
|
65
|
-
field: 'commentAdd',
|
|
66
|
-
}),
|
|
67
|
-
'comment.delete': graphqlMutation<Comment, CommentDeleteInput, Comment>('Comment', {
|
|
68
|
-
field: 'commentDelete',
|
|
69
|
-
}),
|
|
70
|
-
'post.add': graphqlMutation<Post, PostAddInput, Post>('Post', {
|
|
71
|
-
field: 'postAdd',
|
|
72
|
-
}),
|
|
73
|
-
'post.like': graphqlMutation<Post, PostLikeInput, Post>('Post', {
|
|
74
|
-
field: 'postLike',
|
|
75
|
-
}),
|
|
76
|
-
'post.unlike': graphqlMutation<Post, PostUnlikeInput, Post>('Post', {
|
|
77
|
-
field: 'postUnlike',
|
|
78
|
-
}),
|
|
79
|
-
'user.update': graphqlMutation<User, UserUpdateInput, User>('User', {
|
|
80
|
-
field: 'userUpdate',
|
|
81
|
-
}),
|
|
82
|
-
},
|
|
83
|
-
} as const;
|
|
84
|
-
|
|
85
|
-
export * from './views.ts';
|