create-fate 0.0.0 → 1.0.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/LICENSE +21 -0
- package/README.md +24 -0
- package/bin/create-fate.mjs +412 -0
- package/package.json +26 -3
- package/templates/fate/README.md +8 -0
- package/templates/fate/drizzle/.github/workflows/push.yml +27 -0
- package/templates/fate/drizzle/.oxfmtrc.jsonc +23 -0
- package/templates/fate/drizzle/.vite-hooks/pre-commit +1 -0
- package/templates/fate/drizzle/.vscode/extensions.json +12 -0
- package/templates/fate/drizzle/.vscode/settings.json +25 -0
- package/templates/fate/drizzle/AGENTS.md +55 -0
- package/templates/fate/drizzle/README.md +112 -0
- package/templates/fate/drizzle/_gitignore +20 -0
- package/templates/fate/drizzle/client/package.json +58 -0
- package/templates/fate/drizzle/client/pages/index.tsx +96 -0
- package/templates/fate/drizzle/client/pages/layout.tsx +104 -0
- package/templates/fate/drizzle/client/pages/login.tsx +107 -0
- package/templates/fate/drizzle/client/pages/post/[id].tsx +22 -0
- package/templates/fate/drizzle/client/pages/search.tsx +95 -0
- package/templates/fate/drizzle/client/public/icon.svg +1 -0
- package/templates/fate/drizzle/client/src/App.css +153 -0
- package/templates/fate/drizzle/client/src/lib/AvailableLanguages.tsx +5 -0
- package/templates/fate/drizzle/client/src/lib/cx.tsx +6 -0
- package/templates/fate/drizzle/client/src/lib/env.tsx +5 -0
- package/templates/fate/drizzle/client/src/ui/Badge.tsx +31 -0
- package/templates/fate/drizzle/client/src/ui/Button.tsx +108 -0
- package/templates/fate/drizzle/client/src/ui/Card.tsx +32 -0
- package/templates/fate/drizzle/client/src/ui/CommentCard.tsx +75 -0
- package/templates/fate/drizzle/client/src/ui/Error.tsx +19 -0
- package/templates/fate/drizzle/client/src/ui/H2.tsx +15 -0
- package/templates/fate/drizzle/client/src/ui/H3.tsx +20 -0
- package/templates/fate/drizzle/client/src/ui/Header.tsx +96 -0
- package/templates/fate/drizzle/client/src/ui/Input.tsx +17 -0
- package/templates/fate/drizzle/client/src/ui/Link.tsx +11 -0
- package/templates/fate/drizzle/client/src/ui/LocaleSwitcher.tsx +52 -0
- package/templates/fate/drizzle/client/src/ui/PostCard.tsx +284 -0
- package/templates/fate/drizzle/client/src/ui/Section.tsx +23 -0
- package/templates/fate/drizzle/client/src/ui/UserCard.tsx +131 -0
- package/templates/fate/drizzle/client/src/user/AuthClient.tsx +6 -0
- package/templates/fate/drizzle/client/translations/de_DE.json +689 -0
- package/templates/fate/drizzle/client/translations/ja_JP.json +689 -0
- package/templates/fate/drizzle/client/vite.config.ts +39 -0
- package/templates/fate/drizzle/client/void.json +29 -0
- package/templates/fate/drizzle/docker-compose.yml +11 -0
- package/templates/fate/drizzle/package.json +46 -0
- package/templates/fate/drizzle/pnpm-workspace.yaml +36 -0
- package/templates/fate/drizzle/public/fate-logo-dark.svg +4 -0
- package/templates/fate/drizzle/public/fate-logo.svg +4 -0
- package/templates/fate/drizzle/server/.env.example +5 -0
- package/templates/fate/drizzle/server/drizzle.config.ts +11 -0
- package/templates/fate/drizzle/server/package.json +48 -0
- package/templates/fate/drizzle/server/src/__tests__/index.test.tsx +5 -0
- package/templates/fate/drizzle/server/src/app.tsx +44 -0
- package/templates/fate/drizzle/server/src/drizzle/db.ts +25 -0
- package/templates/fate/drizzle/server/src/drizzle/queries.ts +89 -0
- package/templates/fate/drizzle/server/src/drizzle/schema.ts +174 -0
- package/templates/fate/drizzle/server/src/drizzle/seed.tsx +77 -0
- package/templates/fate/drizzle/server/src/drizzle/seedData.ts +205 -0
- package/templates/fate/drizzle/server/src/index.tsx +24 -0
- package/templates/fate/drizzle/server/src/lib/auth.ts +33 -0
- package/templates/fate/drizzle/server/src/lib/env.ts +3 -0
- package/templates/fate/drizzle/server/src/lib/origins.ts +18 -0
- package/templates/fate/drizzle/server/src/router.ts +15 -0
- package/templates/fate/drizzle/server/src/trpc/connection.ts +4 -0
- package/templates/fate/drizzle/server/src/trpc/context.ts +22 -0
- package/templates/fate/drizzle/server/src/trpc/init.ts +51 -0
- package/templates/fate/drizzle/server/src/trpc/routers/comment.ts +146 -0
- package/templates/fate/drizzle/server/src/trpc/routers/post.ts +99 -0
- package/templates/fate/drizzle/server/src/trpc/routers/user.ts +68 -0
- package/templates/fate/drizzle/server/src/trpc/views.ts +75 -0
- package/templates/fate/drizzle/server/src/user/SessionUser.tsx +17 -0
- package/templates/fate/drizzle/server/vite.config.ts +8 -0
- package/templates/fate/drizzle/tsconfig.json +33 -0
- package/templates/fate/drizzle/vite.config.ts +71 -0
- package/templates/fate/http/.github/workflows/push.yml +27 -0
- package/templates/fate/http/.oxfmtrc.jsonc +23 -0
- package/templates/fate/http/.vite-hooks/pre-commit +1 -0
- package/templates/fate/http/.vscode/extensions.json +12 -0
- package/templates/fate/http/.vscode/settings.json +25 -0
- package/templates/fate/http/AGENTS.md +55 -0
- package/templates/fate/http/README.md +112 -0
- package/templates/fate/http/_gitignore +20 -0
- package/templates/fate/http/client/package.json +56 -0
- package/templates/fate/http/client/pages/index.tsx +96 -0
- package/templates/fate/http/client/pages/layout.tsx +89 -0
- package/templates/fate/http/client/pages/login.tsx +107 -0
- package/templates/fate/http/client/pages/post/[id].tsx +22 -0
- package/templates/fate/http/client/pages/search.tsx +95 -0
- package/templates/fate/http/client/public/icon.svg +1 -0
- package/templates/fate/http/client/src/App.css +153 -0
- package/templates/fate/http/client/src/lib/AvailableLanguages.tsx +5 -0
- package/templates/fate/http/client/src/lib/cx.tsx +6 -0
- package/templates/fate/http/client/src/lib/env.tsx +5 -0
- package/templates/fate/http/client/src/ui/Badge.tsx +31 -0
- package/templates/fate/http/client/src/ui/Button.tsx +108 -0
- package/templates/fate/http/client/src/ui/Card.tsx +32 -0
- package/templates/fate/http/client/src/ui/CommentCard.tsx +75 -0
- package/templates/fate/http/client/src/ui/Error.tsx +19 -0
- package/templates/fate/http/client/src/ui/H2.tsx +15 -0
- package/templates/fate/http/client/src/ui/H3.tsx +20 -0
- package/templates/fate/http/client/src/ui/Header.tsx +96 -0
- package/templates/fate/http/client/src/ui/Input.tsx +17 -0
- package/templates/fate/http/client/src/ui/Link.tsx +11 -0
- package/templates/fate/http/client/src/ui/LocaleSwitcher.tsx +52 -0
- package/templates/fate/http/client/src/ui/PostCard.tsx +281 -0
- package/templates/fate/http/client/src/ui/Section.tsx +23 -0
- package/templates/fate/http/client/src/ui/UserCard.tsx +131 -0
- package/templates/fate/http/client/src/user/AuthClient.tsx +6 -0
- package/templates/fate/http/client/translations/de_DE.json +689 -0
- package/templates/fate/http/client/translations/ja_JP.json +689 -0
- package/templates/fate/http/client/vite.config.ts +40 -0
- package/templates/fate/http/client/void.json +29 -0
- package/templates/fate/http/docker-compose.yml +11 -0
- package/templates/fate/http/package.json +46 -0
- package/templates/fate/http/pnpm-workspace.yaml +36 -0
- package/templates/fate/http/public/fate-logo-dark.svg +4 -0
- package/templates/fate/http/public/fate-logo.svg +4 -0
- package/templates/fate/http/server/.env.example +5 -0
- package/templates/fate/http/server/drizzle.config.ts +11 -0
- package/templates/fate/http/server/package.json +46 -0
- package/templates/fate/http/server/src/__tests__/index.test.tsx +5 -0
- package/templates/fate/http/server/src/app.tsx +36 -0
- package/templates/fate/http/server/src/drizzle/db.ts +25 -0
- package/templates/fate/http/server/src/drizzle/queries.ts +89 -0
- package/templates/fate/http/server/src/drizzle/schema.ts +174 -0
- package/templates/fate/http/server/src/drizzle/seed.tsx +77 -0
- package/templates/fate/http/server/src/drizzle/seedData.ts +205 -0
- package/templates/fate/http/server/src/fate/context.ts +20 -0
- package/templates/fate/http/server/src/fate/server.ts +285 -0
- package/templates/fate/http/server/src/fate/views.ts +75 -0
- package/templates/fate/http/server/src/index.tsx +24 -0
- package/templates/fate/http/server/src/lib/auth.ts +33 -0
- package/templates/fate/http/server/src/lib/env.ts +3 -0
- package/templates/fate/http/server/src/lib/origins.ts +18 -0
- package/templates/fate/http/server/src/router.ts +2 -0
- package/templates/fate/http/server/src/user/SessionUser.tsx +17 -0
- package/templates/fate/http/server/vite.config.ts +8 -0
- package/templates/fate/http/tsconfig.json +33 -0
- package/templates/fate/http/vite.config.ts +71 -0
- package/templates/fate/prisma/.github/workflows/push.yml +27 -0
- package/templates/fate/prisma/.oxfmtrc.jsonc +23 -0
- package/templates/fate/prisma/.vite-hooks/pre-commit +1 -0
- package/templates/fate/prisma/.vscode/extensions.json +12 -0
- package/templates/fate/prisma/.vscode/settings.json +25 -0
- package/templates/fate/prisma/AGENTS.md +55 -0
- package/templates/fate/prisma/README.md +126 -0
- package/templates/fate/prisma/_gitignore +20 -0
- package/templates/fate/prisma/client/package.json +58 -0
- package/templates/fate/prisma/client/pages/index.tsx +96 -0
- package/templates/fate/prisma/client/pages/layout.tsx +94 -0
- package/templates/fate/prisma/client/pages/login.tsx +107 -0
- package/templates/fate/prisma/client/pages/post/[id].tsx +22 -0
- package/templates/fate/prisma/client/pages/search.tsx +95 -0
- package/templates/fate/prisma/client/public/icon.svg +1 -0
- package/templates/fate/prisma/client/src/App.css +153 -0
- package/templates/fate/prisma/client/src/lib/AvailableLanguages.tsx +5 -0
- package/templates/fate/prisma/client/src/lib/cx.tsx +6 -0
- package/templates/fate/prisma/client/src/lib/env.tsx +5 -0
- package/templates/fate/prisma/client/src/ui/Badge.tsx +31 -0
- package/templates/fate/prisma/client/src/ui/Button.tsx +108 -0
- package/templates/fate/prisma/client/src/ui/Card.tsx +32 -0
- package/templates/fate/prisma/client/src/ui/CommentCard.tsx +75 -0
- package/templates/fate/prisma/client/src/ui/Error.tsx +19 -0
- package/templates/fate/prisma/client/src/ui/H2.tsx +15 -0
- package/templates/fate/prisma/client/src/ui/H3.tsx +20 -0
- package/templates/fate/prisma/client/src/ui/Header.tsx +96 -0
- package/templates/fate/prisma/client/src/ui/Input.tsx +17 -0
- package/templates/fate/prisma/client/src/ui/Link.tsx +11 -0
- package/templates/fate/prisma/client/src/ui/LocaleSwitcher.tsx +52 -0
- package/templates/fate/prisma/client/src/ui/PostCard.tsx +281 -0
- package/templates/fate/prisma/client/src/ui/Section.tsx +23 -0
- package/templates/fate/prisma/client/src/ui/UserCard.tsx +131 -0
- package/templates/fate/prisma/client/src/user/AuthClient.tsx +6 -0
- package/templates/fate/prisma/client/translations/de_DE.json +689 -0
- package/templates/fate/prisma/client/translations/ja_JP.json +689 -0
- package/templates/fate/prisma/client/vite.config.ts +39 -0
- package/templates/fate/prisma/client/void.json +29 -0
- package/templates/fate/prisma/docker-compose.yml +11 -0
- package/templates/fate/prisma/package.json +47 -0
- package/templates/fate/prisma/pnpm-workspace.yaml +39 -0
- package/templates/fate/prisma/public/fate-logo-dark.svg +4 -0
- package/templates/fate/prisma/public/fate-logo.svg +4 -0
- package/templates/fate/prisma/server/.env.example +5 -0
- package/templates/fate/prisma/server/package.json +42 -0
- package/templates/fate/prisma/server/prisma.config.ts +21 -0
- package/templates/fate/prisma/server/src/__tests__/index.test.tsx +5 -0
- package/templates/fate/prisma/server/src/app.tsx +40 -0
- package/templates/fate/prisma/server/src/index.tsx +24 -0
- package/templates/fate/prisma/server/src/lib/auth.ts +31 -0
- package/templates/fate/prisma/server/src/lib/env.ts +3 -0
- package/templates/fate/prisma/server/src/lib/origins.ts +18 -0
- package/templates/fate/prisma/server/src/prisma/prisma.ts +9 -0
- package/templates/fate/prisma/server/src/prisma/schema.prisma +98 -0
- package/templates/fate/prisma/server/src/prisma/seed.tsx +71 -0
- package/templates/fate/prisma/server/src/prisma/seedData.ts +205 -0
- package/templates/fate/prisma/server/src/router.ts +14 -0
- package/templates/fate/prisma/server/src/trpc/connection.ts +4 -0
- package/templates/fate/prisma/server/src/trpc/context.ts +22 -0
- package/templates/fate/prisma/server/src/trpc/init.ts +8 -0
- package/templates/fate/prisma/server/src/trpc/routers/comment.ts +176 -0
- package/templates/fate/prisma/server/src/trpc/routers/post.ts +154 -0
- package/templates/fate/prisma/server/src/trpc/routers/user.ts +71 -0
- package/templates/fate/prisma/server/src/trpc/views.ts +77 -0
- package/templates/fate/prisma/server/src/user/SessionUser.tsx +17 -0
- package/templates/fate/prisma/server/vite.config.ts +8 -0
- package/templates/fate/prisma/tsconfig.json +33 -0
- package/templates/fate/prisma/vite.config.ts +72 -0
- package/templates/fate/void/.oxfmtrc.jsonc +14 -0
- package/templates/fate/void/README.md +55 -0
- package/templates/fate/void/auth.ts +22 -0
- package/templates/fate/void/db/migrations/20260508073357_initial_schema.sql +133 -0
- package/templates/fate/void/db/migrations/20260508120500_seed_void_demo.sql +170 -0
- package/templates/fate/void/db/migrations/meta/20260508073357_snapshot.json +868 -0
- package/templates/fate/void/db/migrations/meta/_journal.json +20 -0
- package/templates/fate/void/db/queries.ts +211 -0
- package/templates/fate/void/db/schema.ts +325 -0
- package/templates/fate/void/db/seed-auth.ts +31 -0
- package/templates/fate/void/db/seed.ts +163 -0
- package/templates/fate/void/middleware/01.shared.ts +29 -0
- package/templates/fate/void/package.json +65 -0
- package/templates/fate/void/pages/category/[id].tsx +23 -0
- package/templates/fate/void/pages/index.tsx +153 -0
- package/templates/fate/void/pages/layout.tsx +46 -0
- package/templates/fate/void/pages/login.tsx +103 -0
- package/templates/fate/void/pages/post/[id].tsx +20 -0
- package/templates/fate/void/pages/search.tsx +81 -0
- package/templates/fate/void/pnpm-workspace.yaml +31 -0
- package/templates/fate/void/public/.assetsignore +1 -0
- package/templates/fate/void/public/icon.svg +1 -0
- package/templates/fate/void/routes/fate-live.ts +8 -0
- package/templates/fate/void/routes/fate.ts +8 -0
- package/templates/fate/void/seedData.ts +535 -0
- package/templates/fate/void/src/App.css +130 -0
- package/templates/fate/void/src/fate/__tests__/commentPermissions.test.ts +31 -0
- package/templates/fate/void/src/fate/commentPermissions.ts +17 -0
- package/templates/fate/void/src/fate/context.ts +15 -0
- package/templates/fate/void/src/fate/live.ts +6 -0
- package/templates/fate/void/src/fate/server.ts +401 -0
- package/templates/fate/void/src/fate/views.ts +164 -0
- package/templates/fate/void/src/lib/cx.tsx +6 -0
- package/templates/fate/void/src/lib/formatLabel.tsx +6 -0
- package/templates/fate/void/src/lib/shared.ts +10 -0
- package/templates/fate/void/src/ui/Badge.tsx +31 -0
- package/templates/fate/void/src/ui/Button.tsx +92 -0
- package/templates/fate/void/src/ui/Card.tsx +29 -0
- package/templates/fate/void/src/ui/CategoryCard.tsx +105 -0
- package/templates/fate/void/src/ui/CommentCard.tsx +80 -0
- package/templates/fate/void/src/ui/CreatePost.tsx +111 -0
- package/templates/fate/void/src/ui/Error.tsx +19 -0
- package/templates/fate/void/src/ui/EventCard.tsx +152 -0
- package/templates/fate/void/src/ui/H2.tsx +15 -0
- package/templates/fate/void/src/ui/H3.tsx +20 -0
- package/templates/fate/void/src/ui/Header.tsx +96 -0
- package/templates/fate/void/src/ui/Input.tsx +33 -0
- package/templates/fate/void/src/ui/Link.tsx +11 -0
- package/templates/fate/void/src/ui/Number.tsx +5 -0
- package/templates/fate/void/src/ui/PostCard.tsx +294 -0
- package/templates/fate/void/src/ui/Section.tsx +23 -0
- package/templates/fate/void/src/ui/TagBadge.tsx +23 -0
- package/templates/fate/void/src/ui/UserCard.tsx +129 -0
- package/templates/fate/void/src/user/AuthClient.tsx +1 -0
- package/templates/fate/void/src/user/SessionUser.tsx +17 -0
- package/templates/fate/void/tsconfig.json +34 -0
- package/templates/fate/void/vite.config.ts +83 -0
- package/templates/fate/void/void.json +32 -0
- package/templates/fate/void/wrangler.jsonc +16 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { dataView, list, resolver, type Entity } from '@nkzw/fate/server';
|
|
2
|
+
import type {
|
|
3
|
+
Comment as PrismaComment,
|
|
4
|
+
Post as PrismaPost,
|
|
5
|
+
User as PrismaUser,
|
|
6
|
+
} from '../prisma/prisma-client/client.ts';
|
|
7
|
+
|
|
8
|
+
export type CommentItem = PrismaComment & {
|
|
9
|
+
author?: PrismaUser | null;
|
|
10
|
+
post?: PrismaPost | null;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type PostItem = PrismaPost & {
|
|
14
|
+
_count?: { comments: number };
|
|
15
|
+
author?: PrismaUser | null;
|
|
16
|
+
comments?: Array<CommentItem>;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const userDataView = dataView<PrismaUser>('User')({
|
|
20
|
+
id: true,
|
|
21
|
+
name: true,
|
|
22
|
+
username: true,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const basePost = {
|
|
26
|
+
author: userDataView,
|
|
27
|
+
commentCount: resolver<PostItem, number>({
|
|
28
|
+
resolve: ({ _count }) => _count?.comments ?? 0,
|
|
29
|
+
select: () => ({
|
|
30
|
+
_count: { select: { comments: true } },
|
|
31
|
+
}),
|
|
32
|
+
}),
|
|
33
|
+
content: true,
|
|
34
|
+
id: true,
|
|
35
|
+
likes: true,
|
|
36
|
+
title: true,
|
|
37
|
+
} as const;
|
|
38
|
+
|
|
39
|
+
const postSummaryDataView = dataView<PostItem>('Post')({
|
|
40
|
+
...basePost,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export const commentDataView = dataView<CommentItem>('Comment')({
|
|
44
|
+
author: userDataView,
|
|
45
|
+
content: true,
|
|
46
|
+
id: true,
|
|
47
|
+
post: postSummaryDataView,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export const postDataView = dataView<PostItem>('Post')({
|
|
51
|
+
...basePost,
|
|
52
|
+
comments: list(commentDataView),
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
export type User = Entity<typeof userDataView, 'User'>;
|
|
56
|
+
export type Comment = Entity<
|
|
57
|
+
typeof commentDataView,
|
|
58
|
+
'Comment',
|
|
59
|
+
{
|
|
60
|
+
author: User;
|
|
61
|
+
post: Post;
|
|
62
|
+
}
|
|
63
|
+
>;
|
|
64
|
+
export type Post = Entity<
|
|
65
|
+
typeof postDataView,
|
|
66
|
+
'Post',
|
|
67
|
+
{
|
|
68
|
+
author: User;
|
|
69
|
+
comments: Array<Comment>;
|
|
70
|
+
}
|
|
71
|
+
>;
|
|
72
|
+
|
|
73
|
+
export const Root = {
|
|
74
|
+
commentSearch: { procedure: 'search', view: list(commentDataView) },
|
|
75
|
+
posts: list(postDataView),
|
|
76
|
+
viewer: userDataView,
|
|
77
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { User } from '../prisma/prisma-client/client.ts';
|
|
2
|
+
|
|
3
|
+
export type SessionUser = Pick<User, 'role' | 'id' | 'username'>;
|
|
4
|
+
|
|
5
|
+
export function toSessionUser({
|
|
6
|
+
email,
|
|
7
|
+
id,
|
|
8
|
+
role,
|
|
9
|
+
username,
|
|
10
|
+
}: Readonly<{
|
|
11
|
+
email: string | null | undefined;
|
|
12
|
+
id: string;
|
|
13
|
+
role?: string | null | undefined;
|
|
14
|
+
username?: string | null | undefined;
|
|
15
|
+
}>): SessionUser {
|
|
16
|
+
return { id, role: role || '', username: username || email || '' };
|
|
17
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"allowJs": true,
|
|
4
|
+
"allowImportingTsExtensions": true,
|
|
5
|
+
"esModuleInterop": true,
|
|
6
|
+
"forceConsistentCasingInFileNames": true,
|
|
7
|
+
"incremental": true,
|
|
8
|
+
"isolatedModules": true,
|
|
9
|
+
"jsx": "react-jsx",
|
|
10
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
11
|
+
"module": "nodenext",
|
|
12
|
+
"moduleResolution": "nodenext",
|
|
13
|
+
"noEmit": true,
|
|
14
|
+
"noImplicitOverride": true,
|
|
15
|
+
"noUnusedLocals": true,
|
|
16
|
+
"resolveJsonModule": true,
|
|
17
|
+
"skipLibCheck": true,
|
|
18
|
+
"strict": true,
|
|
19
|
+
"target": "es2017",
|
|
20
|
+
"types": ["vite/client"]
|
|
21
|
+
},
|
|
22
|
+
"exclude": ["**/.void/**/*.ts", "node_modules"],
|
|
23
|
+
"include": ["**/.fate/*.ts", "**/*.ts", "**/*.tsx"],
|
|
24
|
+
"ts-node": {
|
|
25
|
+
"transpileOnly": true,
|
|
26
|
+
"transpiler": "ts-node/transpilers/swc",
|
|
27
|
+
"files": true,
|
|
28
|
+
"compilerOptions": {
|
|
29
|
+
"module": "esnext",
|
|
30
|
+
"isolatedModules": false
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import nkzw from '@nkzw/oxlint-config';
|
|
3
|
+
import dotenv from 'dotenv';
|
|
4
|
+
import { defineConfig } from 'vite-plus';
|
|
5
|
+
|
|
6
|
+
const root = process.cwd();
|
|
7
|
+
|
|
8
|
+
dotenv.config({
|
|
9
|
+
path: join(root, './server', '.env'),
|
|
10
|
+
quiet: true,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export default defineConfig({
|
|
14
|
+
fmt: {
|
|
15
|
+
experimentalSortImports: {
|
|
16
|
+
newlinesBetween: false,
|
|
17
|
+
},
|
|
18
|
+
experimentalSortPackageJson: {
|
|
19
|
+
sortScripts: true,
|
|
20
|
+
},
|
|
21
|
+
experimentalTailwindcss: {
|
|
22
|
+
stylesheet: 'client/src/App.css',
|
|
23
|
+
},
|
|
24
|
+
ignorePatterns: [
|
|
25
|
+
'coverage/',
|
|
26
|
+
'dist/',
|
|
27
|
+
'.fate/',
|
|
28
|
+
'client/dist/',
|
|
29
|
+
'client/src/translations/',
|
|
30
|
+
'server/dist/',
|
|
31
|
+
'pnpm-lock.yaml',
|
|
32
|
+
],
|
|
33
|
+
singleQuote: true,
|
|
34
|
+
},
|
|
35
|
+
lint: {
|
|
36
|
+
extends: [nkzw],
|
|
37
|
+
ignorePatterns: [
|
|
38
|
+
'coverage',
|
|
39
|
+
'dist',
|
|
40
|
+
'.fate',
|
|
41
|
+
'client/dist',
|
|
42
|
+
'server/dist',
|
|
43
|
+
'server/src/prisma/pothos-types.ts',
|
|
44
|
+
'server/src/prisma/prisma-client/*',
|
|
45
|
+
'vite.config.ts.timestamp-*',
|
|
46
|
+
'client/vite.config.ts.timestamp-*',
|
|
47
|
+
'server/vite.config.ts.timestamp-*',
|
|
48
|
+
],
|
|
49
|
+
options: { typeAware: true, typeCheck: true },
|
|
50
|
+
overrides: [
|
|
51
|
+
{
|
|
52
|
+
files: ['server/src/index.tsx', 'server/src/prisma/seed.tsx', '**/__tests__/**'],
|
|
53
|
+
rules: {
|
|
54
|
+
'no-console': 'off',
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
rules: {
|
|
59
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
run: {
|
|
63
|
+
tasks: {
|
|
64
|
+
'test:all': {
|
|
65
|
+
command: 'vp check && vp test',
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
staged: {
|
|
70
|
+
'*': 'vp check --fix',
|
|
71
|
+
},
|
|
72
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./node_modules/oxfmt/configuration_schema.json",
|
|
3
|
+
"singleQuote": true,
|
|
4
|
+
"experimentalSortImports": {
|
|
5
|
+
"newlinesBetween": false,
|
|
6
|
+
},
|
|
7
|
+
"experimentalSortPackageJson": {
|
|
8
|
+
"sortScripts": true,
|
|
9
|
+
},
|
|
10
|
+
"experimentalTailwindcss": {
|
|
11
|
+
"stylesheet": "src/App.css",
|
|
12
|
+
},
|
|
13
|
+
"ignorePatterns": [".fate/", ".void/", "dist/", "node_modules/", "pnpm-lock.yaml"],
|
|
14
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# _fate_ Void Template
|
|
2
|
+
|
|
3
|
+
Create a new fate app with Vite+:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
vp create fate my-app --template void
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
This template uses the Void pages router with Drizzle, `void-fate`, `react-fate`, Better Auth, Tailwind, and React Compiler.
|
|
10
|
+
|
|
11
|
+
## Folder Structure
|
|
12
|
+
|
|
13
|
+
- `pages/` - Void page routes.
|
|
14
|
+
- `routes/` - API routes, including fate RPC and live SSE routes.
|
|
15
|
+
- `src/` - Shared application, fate, UI, and auth code.
|
|
16
|
+
- `db/` - Drizzle schema, migrations, queries, and seed data.
|
|
17
|
+
|
|
18
|
+
## Initial Setup
|
|
19
|
+
|
|
20
|
+
You'll need Node.js 24+ and [Vite+](https://viteplus.dev/guide/).
|
|
21
|
+
|
|
22
|
+
Install dependencies:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
vp install
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Set up Void local files, seed the local database, and regenerate the fate client:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
vp run dev:setup
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Start the app:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
vp run dev
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The app runs at `http://localhost:6001`. Fate RPC requests go to `/fate`; live updates use the SSE route at `/fate-live`.
|
|
41
|
+
|
|
42
|
+
## Development
|
|
43
|
+
|
|
44
|
+
Common commands from the project root:
|
|
45
|
+
|
|
46
|
+
- `vp run dev` starts the Void app.
|
|
47
|
+
- `vp run dev:setup` prepares Void, seeds the local database, and regenerates the fate client.
|
|
48
|
+
- `vp run prepare:void` regenerates Void local files.
|
|
49
|
+
- `vp run fate:generate` regenerates `.fate/client.generated.ts` after changing `src/fate/server.ts` or views.
|
|
50
|
+
- `vp run db:generate` generates Drizzle migration files from `db/schema.ts`.
|
|
51
|
+
- `vp run db:migrate` applies database migrations.
|
|
52
|
+
- `vp run db:seed` seeds the local database.
|
|
53
|
+
- `vp check --fix` formats, lints, and type-checks the workspace.
|
|
54
|
+
- `vp test` runs the test suite.
|
|
55
|
+
- `vp run build` builds the app.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { admin, username } from 'better-auth/plugins';
|
|
2
|
+
import { defineAuth } from 'void/auth';
|
|
3
|
+
|
|
4
|
+
export default defineAuth(({ defaults }) => ({
|
|
5
|
+
...defaults,
|
|
6
|
+
emailAndPassword: {
|
|
7
|
+
...defaults.emailAndPassword,
|
|
8
|
+
autoSignIn: true,
|
|
9
|
+
enabled: true,
|
|
10
|
+
maxPasswordLength: 128,
|
|
11
|
+
minPasswordLength: 8,
|
|
12
|
+
},
|
|
13
|
+
plugins: [admin(), username()],
|
|
14
|
+
session: {
|
|
15
|
+
...defaults.session,
|
|
16
|
+
cookieCache: {
|
|
17
|
+
enabled: true,
|
|
18
|
+
maxAge: 15 * 24 * 60 * 60,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
telemetry: { enabled: false },
|
|
22
|
+
}));
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
CREATE TABLE `account` (
|
|
2
|
+
`accessToken` text,
|
|
3
|
+
`accessTokenExpiresAt` integer,
|
|
4
|
+
`accountId` text NOT NULL,
|
|
5
|
+
`createdAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
6
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
7
|
+
`idToken` text,
|
|
8
|
+
`password` text,
|
|
9
|
+
`providerId` text NOT NULL,
|
|
10
|
+
`refreshToken` text,
|
|
11
|
+
`refreshTokenExpiresAt` integer,
|
|
12
|
+
`scope` text,
|
|
13
|
+
`updatedAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
14
|
+
`userId` text NOT NULL,
|
|
15
|
+
FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
|
|
16
|
+
);
|
|
17
|
+
--> statement-breakpoint
|
|
18
|
+
CREATE UNIQUE INDEX `account_providerId_accountId_key` ON `account` (`providerId`,`accountId`);--> statement-breakpoint
|
|
19
|
+
CREATE TABLE `Category` (
|
|
20
|
+
`createdAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
21
|
+
`description` text,
|
|
22
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
23
|
+
`name` text NOT NULL
|
|
24
|
+
);
|
|
25
|
+
--> statement-breakpoint
|
|
26
|
+
CREATE UNIQUE INDEX `Category_name_key` ON `Category` (`name`);--> statement-breakpoint
|
|
27
|
+
CREATE TABLE `Comment` (
|
|
28
|
+
`authorId` text,
|
|
29
|
+
`content` text NOT NULL,
|
|
30
|
+
`createdAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
31
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
32
|
+
`postId` text NOT NULL,
|
|
33
|
+
FOREIGN KEY (`authorId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE set null,
|
|
34
|
+
FOREIGN KEY (`postId`) REFERENCES `Post`(`id`) ON UPDATE no action ON DELETE cascade
|
|
35
|
+
);
|
|
36
|
+
--> statement-breakpoint
|
|
37
|
+
CREATE INDEX `Comment_authorId_idx` ON `Comment` (`authorId`);--> statement-breakpoint
|
|
38
|
+
CREATE INDEX `Comment_postId_idx` ON `Comment` (`postId`);--> statement-breakpoint
|
|
39
|
+
CREATE TABLE `Event` (
|
|
40
|
+
`capacity` integer NOT NULL,
|
|
41
|
+
`createdAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
42
|
+
`description` text NOT NULL,
|
|
43
|
+
`endAt` integer NOT NULL,
|
|
44
|
+
`hostId` text NOT NULL,
|
|
45
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
46
|
+
`livestreamUrl` text,
|
|
47
|
+
`location` text NOT NULL,
|
|
48
|
+
`name` text NOT NULL,
|
|
49
|
+
`startAt` integer NOT NULL,
|
|
50
|
+
`topics` text DEFAULT '[]' NOT NULL,
|
|
51
|
+
`type` text DEFAULT 'MEETUP' NOT NULL,
|
|
52
|
+
`updatedAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
53
|
+
FOREIGN KEY (`hostId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
|
|
54
|
+
);
|
|
55
|
+
--> statement-breakpoint
|
|
56
|
+
CREATE INDEX `Event_hostId_idx` ON `Event` (`hostId`);--> statement-breakpoint
|
|
57
|
+
CREATE TABLE `EventAttendee` (
|
|
58
|
+
`createdAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
59
|
+
`eventId` text NOT NULL,
|
|
60
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
61
|
+
`notes` text,
|
|
62
|
+
`status` text DEFAULT 'INVITED' NOT NULL,
|
|
63
|
+
`userId` text NOT NULL,
|
|
64
|
+
FOREIGN KEY (`eventId`) REFERENCES `Event`(`id`) ON UPDATE no action ON DELETE cascade,
|
|
65
|
+
FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
|
|
66
|
+
);
|
|
67
|
+
--> statement-breakpoint
|
|
68
|
+
CREATE UNIQUE INDEX `EventAttendee_eventId_userId_key` ON `EventAttendee` (`eventId`,`userId`);--> statement-breakpoint
|
|
69
|
+
CREATE INDEX `EventAttendee_userId_idx` ON `EventAttendee` (`userId`);--> statement-breakpoint
|
|
70
|
+
CREATE TABLE `Post` (
|
|
71
|
+
`authorId` text NOT NULL,
|
|
72
|
+
`categoryId` text,
|
|
73
|
+
`content` text NOT NULL,
|
|
74
|
+
`createdAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
75
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
76
|
+
`likes` integer DEFAULT 0 NOT NULL,
|
|
77
|
+
`title` text NOT NULL,
|
|
78
|
+
`updatedAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
79
|
+
FOREIGN KEY (`authorId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade,
|
|
80
|
+
FOREIGN KEY (`categoryId`) REFERENCES `Category`(`id`) ON UPDATE no action ON DELETE set null
|
|
81
|
+
);
|
|
82
|
+
--> statement-breakpoint
|
|
83
|
+
CREATE INDEX `Post_authorId_idx` ON `Post` (`authorId`);--> statement-breakpoint
|
|
84
|
+
CREATE TABLE `_PostTags` (
|
|
85
|
+
`A` text NOT NULL,
|
|
86
|
+
`B` text NOT NULL,
|
|
87
|
+
PRIMARY KEY(`A`, `B`),
|
|
88
|
+
FOREIGN KEY (`A`) REFERENCES `Post`(`id`) ON UPDATE no action ON DELETE cascade,
|
|
89
|
+
FOREIGN KEY (`B`) REFERENCES `Tag`(`id`) ON UPDATE no action ON DELETE cascade
|
|
90
|
+
);
|
|
91
|
+
--> statement-breakpoint
|
|
92
|
+
CREATE INDEX `_PostTags_B_index` ON `_PostTags` (`B`);--> statement-breakpoint
|
|
93
|
+
CREATE TABLE `session` (
|
|
94
|
+
`createdAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
95
|
+
`expiresAt` integer NOT NULL,
|
|
96
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
97
|
+
`ipAddress` text,
|
|
98
|
+
`token` text NOT NULL,
|
|
99
|
+
`updatedAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
100
|
+
`userAgent` text,
|
|
101
|
+
`userId` text NOT NULL,
|
|
102
|
+
FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
|
|
103
|
+
);
|
|
104
|
+
--> statement-breakpoint
|
|
105
|
+
CREATE UNIQUE INDEX `session_token_key` ON `session` (`token`);--> statement-breakpoint
|
|
106
|
+
CREATE TABLE `Tag` (
|
|
107
|
+
`createdAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
108
|
+
`description` text,
|
|
109
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
110
|
+
`name` text NOT NULL
|
|
111
|
+
);
|
|
112
|
+
--> statement-breakpoint
|
|
113
|
+
CREATE UNIQUE INDEX `Tag_name_key` ON `Tag` (`name`);--> statement-breakpoint
|
|
114
|
+
CREATE TABLE `user` (
|
|
115
|
+
`banExpires` integer,
|
|
116
|
+
`banned` integer,
|
|
117
|
+
`banReason` text,
|
|
118
|
+
`createdAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
119
|
+
`displayUsername` text,
|
|
120
|
+
`email` text NOT NULL,
|
|
121
|
+
`emailVerified` integer DEFAULT false NOT NULL,
|
|
122
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
123
|
+
`image` text,
|
|
124
|
+
`name` text NOT NULL,
|
|
125
|
+
`password` text,
|
|
126
|
+
`role` text DEFAULT 'user' NOT NULL,
|
|
127
|
+
`updatedAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
128
|
+
`username` text
|
|
129
|
+
);
|
|
130
|
+
--> statement-breakpoint
|
|
131
|
+
CREATE UNIQUE INDEX `user_email_key` ON `user` (`email`);--> statement-breakpoint
|
|
132
|
+
CREATE UNIQUE INDEX `user_username_key` ON `user` (`username`);--> statement-breakpoint
|
|
133
|
+
CREATE INDEX `user_id_idx` ON `user` (`id`);
|