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.
Files changed (266) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +24 -0
  3. package/bin/create-fate.mjs +412 -0
  4. package/package.json +26 -3
  5. package/templates/fate/README.md +8 -0
  6. package/templates/fate/drizzle/.github/workflows/push.yml +27 -0
  7. package/templates/fate/drizzle/.oxfmtrc.jsonc +23 -0
  8. package/templates/fate/drizzle/.vite-hooks/pre-commit +1 -0
  9. package/templates/fate/drizzle/.vscode/extensions.json +12 -0
  10. package/templates/fate/drizzle/.vscode/settings.json +25 -0
  11. package/templates/fate/drizzle/AGENTS.md +55 -0
  12. package/templates/fate/drizzle/README.md +112 -0
  13. package/templates/fate/drizzle/_gitignore +20 -0
  14. package/templates/fate/drizzle/client/package.json +58 -0
  15. package/templates/fate/drizzle/client/pages/index.tsx +96 -0
  16. package/templates/fate/drizzle/client/pages/layout.tsx +104 -0
  17. package/templates/fate/drizzle/client/pages/login.tsx +107 -0
  18. package/templates/fate/drizzle/client/pages/post/[id].tsx +22 -0
  19. package/templates/fate/drizzle/client/pages/search.tsx +95 -0
  20. package/templates/fate/drizzle/client/public/icon.svg +1 -0
  21. package/templates/fate/drizzle/client/src/App.css +153 -0
  22. package/templates/fate/drizzle/client/src/lib/AvailableLanguages.tsx +5 -0
  23. package/templates/fate/drizzle/client/src/lib/cx.tsx +6 -0
  24. package/templates/fate/drizzle/client/src/lib/env.tsx +5 -0
  25. package/templates/fate/drizzle/client/src/ui/Badge.tsx +31 -0
  26. package/templates/fate/drizzle/client/src/ui/Button.tsx +108 -0
  27. package/templates/fate/drizzle/client/src/ui/Card.tsx +32 -0
  28. package/templates/fate/drizzle/client/src/ui/CommentCard.tsx +75 -0
  29. package/templates/fate/drizzle/client/src/ui/Error.tsx +19 -0
  30. package/templates/fate/drizzle/client/src/ui/H2.tsx +15 -0
  31. package/templates/fate/drizzle/client/src/ui/H3.tsx +20 -0
  32. package/templates/fate/drizzle/client/src/ui/Header.tsx +96 -0
  33. package/templates/fate/drizzle/client/src/ui/Input.tsx +17 -0
  34. package/templates/fate/drizzle/client/src/ui/Link.tsx +11 -0
  35. package/templates/fate/drizzle/client/src/ui/LocaleSwitcher.tsx +52 -0
  36. package/templates/fate/drizzle/client/src/ui/PostCard.tsx +284 -0
  37. package/templates/fate/drizzle/client/src/ui/Section.tsx +23 -0
  38. package/templates/fate/drizzle/client/src/ui/UserCard.tsx +131 -0
  39. package/templates/fate/drizzle/client/src/user/AuthClient.tsx +6 -0
  40. package/templates/fate/drizzle/client/translations/de_DE.json +689 -0
  41. package/templates/fate/drizzle/client/translations/ja_JP.json +689 -0
  42. package/templates/fate/drizzle/client/vite.config.ts +39 -0
  43. package/templates/fate/drizzle/client/void.json +29 -0
  44. package/templates/fate/drizzle/docker-compose.yml +11 -0
  45. package/templates/fate/drizzle/package.json +46 -0
  46. package/templates/fate/drizzle/pnpm-workspace.yaml +36 -0
  47. package/templates/fate/drizzle/public/fate-logo-dark.svg +4 -0
  48. package/templates/fate/drizzle/public/fate-logo.svg +4 -0
  49. package/templates/fate/drizzle/server/.env.example +5 -0
  50. package/templates/fate/drizzle/server/drizzle.config.ts +11 -0
  51. package/templates/fate/drizzle/server/package.json +48 -0
  52. package/templates/fate/drizzle/server/src/__tests__/index.test.tsx +5 -0
  53. package/templates/fate/drizzle/server/src/app.tsx +44 -0
  54. package/templates/fate/drizzle/server/src/drizzle/db.ts +25 -0
  55. package/templates/fate/drizzle/server/src/drizzle/queries.ts +89 -0
  56. package/templates/fate/drizzle/server/src/drizzle/schema.ts +174 -0
  57. package/templates/fate/drizzle/server/src/drizzle/seed.tsx +77 -0
  58. package/templates/fate/drizzle/server/src/drizzle/seedData.ts +205 -0
  59. package/templates/fate/drizzle/server/src/index.tsx +24 -0
  60. package/templates/fate/drizzle/server/src/lib/auth.ts +33 -0
  61. package/templates/fate/drizzle/server/src/lib/env.ts +3 -0
  62. package/templates/fate/drizzle/server/src/lib/origins.ts +18 -0
  63. package/templates/fate/drizzle/server/src/router.ts +15 -0
  64. package/templates/fate/drizzle/server/src/trpc/connection.ts +4 -0
  65. package/templates/fate/drizzle/server/src/trpc/context.ts +22 -0
  66. package/templates/fate/drizzle/server/src/trpc/init.ts +51 -0
  67. package/templates/fate/drizzle/server/src/trpc/routers/comment.ts +146 -0
  68. package/templates/fate/drizzle/server/src/trpc/routers/post.ts +99 -0
  69. package/templates/fate/drizzle/server/src/trpc/routers/user.ts +68 -0
  70. package/templates/fate/drizzle/server/src/trpc/views.ts +75 -0
  71. package/templates/fate/drizzle/server/src/user/SessionUser.tsx +17 -0
  72. package/templates/fate/drizzle/server/vite.config.ts +8 -0
  73. package/templates/fate/drizzle/tsconfig.json +33 -0
  74. package/templates/fate/drizzle/vite.config.ts +71 -0
  75. package/templates/fate/http/.github/workflows/push.yml +27 -0
  76. package/templates/fate/http/.oxfmtrc.jsonc +23 -0
  77. package/templates/fate/http/.vite-hooks/pre-commit +1 -0
  78. package/templates/fate/http/.vscode/extensions.json +12 -0
  79. package/templates/fate/http/.vscode/settings.json +25 -0
  80. package/templates/fate/http/AGENTS.md +55 -0
  81. package/templates/fate/http/README.md +112 -0
  82. package/templates/fate/http/_gitignore +20 -0
  83. package/templates/fate/http/client/package.json +56 -0
  84. package/templates/fate/http/client/pages/index.tsx +96 -0
  85. package/templates/fate/http/client/pages/layout.tsx +89 -0
  86. package/templates/fate/http/client/pages/login.tsx +107 -0
  87. package/templates/fate/http/client/pages/post/[id].tsx +22 -0
  88. package/templates/fate/http/client/pages/search.tsx +95 -0
  89. package/templates/fate/http/client/public/icon.svg +1 -0
  90. package/templates/fate/http/client/src/App.css +153 -0
  91. package/templates/fate/http/client/src/lib/AvailableLanguages.tsx +5 -0
  92. package/templates/fate/http/client/src/lib/cx.tsx +6 -0
  93. package/templates/fate/http/client/src/lib/env.tsx +5 -0
  94. package/templates/fate/http/client/src/ui/Badge.tsx +31 -0
  95. package/templates/fate/http/client/src/ui/Button.tsx +108 -0
  96. package/templates/fate/http/client/src/ui/Card.tsx +32 -0
  97. package/templates/fate/http/client/src/ui/CommentCard.tsx +75 -0
  98. package/templates/fate/http/client/src/ui/Error.tsx +19 -0
  99. package/templates/fate/http/client/src/ui/H2.tsx +15 -0
  100. package/templates/fate/http/client/src/ui/H3.tsx +20 -0
  101. package/templates/fate/http/client/src/ui/Header.tsx +96 -0
  102. package/templates/fate/http/client/src/ui/Input.tsx +17 -0
  103. package/templates/fate/http/client/src/ui/Link.tsx +11 -0
  104. package/templates/fate/http/client/src/ui/LocaleSwitcher.tsx +52 -0
  105. package/templates/fate/http/client/src/ui/PostCard.tsx +281 -0
  106. package/templates/fate/http/client/src/ui/Section.tsx +23 -0
  107. package/templates/fate/http/client/src/ui/UserCard.tsx +131 -0
  108. package/templates/fate/http/client/src/user/AuthClient.tsx +6 -0
  109. package/templates/fate/http/client/translations/de_DE.json +689 -0
  110. package/templates/fate/http/client/translations/ja_JP.json +689 -0
  111. package/templates/fate/http/client/vite.config.ts +40 -0
  112. package/templates/fate/http/client/void.json +29 -0
  113. package/templates/fate/http/docker-compose.yml +11 -0
  114. package/templates/fate/http/package.json +46 -0
  115. package/templates/fate/http/pnpm-workspace.yaml +36 -0
  116. package/templates/fate/http/public/fate-logo-dark.svg +4 -0
  117. package/templates/fate/http/public/fate-logo.svg +4 -0
  118. package/templates/fate/http/server/.env.example +5 -0
  119. package/templates/fate/http/server/drizzle.config.ts +11 -0
  120. package/templates/fate/http/server/package.json +46 -0
  121. package/templates/fate/http/server/src/__tests__/index.test.tsx +5 -0
  122. package/templates/fate/http/server/src/app.tsx +36 -0
  123. package/templates/fate/http/server/src/drizzle/db.ts +25 -0
  124. package/templates/fate/http/server/src/drizzle/queries.ts +89 -0
  125. package/templates/fate/http/server/src/drizzle/schema.ts +174 -0
  126. package/templates/fate/http/server/src/drizzle/seed.tsx +77 -0
  127. package/templates/fate/http/server/src/drizzle/seedData.ts +205 -0
  128. package/templates/fate/http/server/src/fate/context.ts +20 -0
  129. package/templates/fate/http/server/src/fate/server.ts +285 -0
  130. package/templates/fate/http/server/src/fate/views.ts +75 -0
  131. package/templates/fate/http/server/src/index.tsx +24 -0
  132. package/templates/fate/http/server/src/lib/auth.ts +33 -0
  133. package/templates/fate/http/server/src/lib/env.ts +3 -0
  134. package/templates/fate/http/server/src/lib/origins.ts +18 -0
  135. package/templates/fate/http/server/src/router.ts +2 -0
  136. package/templates/fate/http/server/src/user/SessionUser.tsx +17 -0
  137. package/templates/fate/http/server/vite.config.ts +8 -0
  138. package/templates/fate/http/tsconfig.json +33 -0
  139. package/templates/fate/http/vite.config.ts +71 -0
  140. package/templates/fate/prisma/.github/workflows/push.yml +27 -0
  141. package/templates/fate/prisma/.oxfmtrc.jsonc +23 -0
  142. package/templates/fate/prisma/.vite-hooks/pre-commit +1 -0
  143. package/templates/fate/prisma/.vscode/extensions.json +12 -0
  144. package/templates/fate/prisma/.vscode/settings.json +25 -0
  145. package/templates/fate/prisma/AGENTS.md +55 -0
  146. package/templates/fate/prisma/README.md +126 -0
  147. package/templates/fate/prisma/_gitignore +20 -0
  148. package/templates/fate/prisma/client/package.json +58 -0
  149. package/templates/fate/prisma/client/pages/index.tsx +96 -0
  150. package/templates/fate/prisma/client/pages/layout.tsx +94 -0
  151. package/templates/fate/prisma/client/pages/login.tsx +107 -0
  152. package/templates/fate/prisma/client/pages/post/[id].tsx +22 -0
  153. package/templates/fate/prisma/client/pages/search.tsx +95 -0
  154. package/templates/fate/prisma/client/public/icon.svg +1 -0
  155. package/templates/fate/prisma/client/src/App.css +153 -0
  156. package/templates/fate/prisma/client/src/lib/AvailableLanguages.tsx +5 -0
  157. package/templates/fate/prisma/client/src/lib/cx.tsx +6 -0
  158. package/templates/fate/prisma/client/src/lib/env.tsx +5 -0
  159. package/templates/fate/prisma/client/src/ui/Badge.tsx +31 -0
  160. package/templates/fate/prisma/client/src/ui/Button.tsx +108 -0
  161. package/templates/fate/prisma/client/src/ui/Card.tsx +32 -0
  162. package/templates/fate/prisma/client/src/ui/CommentCard.tsx +75 -0
  163. package/templates/fate/prisma/client/src/ui/Error.tsx +19 -0
  164. package/templates/fate/prisma/client/src/ui/H2.tsx +15 -0
  165. package/templates/fate/prisma/client/src/ui/H3.tsx +20 -0
  166. package/templates/fate/prisma/client/src/ui/Header.tsx +96 -0
  167. package/templates/fate/prisma/client/src/ui/Input.tsx +17 -0
  168. package/templates/fate/prisma/client/src/ui/Link.tsx +11 -0
  169. package/templates/fate/prisma/client/src/ui/LocaleSwitcher.tsx +52 -0
  170. package/templates/fate/prisma/client/src/ui/PostCard.tsx +281 -0
  171. package/templates/fate/prisma/client/src/ui/Section.tsx +23 -0
  172. package/templates/fate/prisma/client/src/ui/UserCard.tsx +131 -0
  173. package/templates/fate/prisma/client/src/user/AuthClient.tsx +6 -0
  174. package/templates/fate/prisma/client/translations/de_DE.json +689 -0
  175. package/templates/fate/prisma/client/translations/ja_JP.json +689 -0
  176. package/templates/fate/prisma/client/vite.config.ts +39 -0
  177. package/templates/fate/prisma/client/void.json +29 -0
  178. package/templates/fate/prisma/docker-compose.yml +11 -0
  179. package/templates/fate/prisma/package.json +47 -0
  180. package/templates/fate/prisma/pnpm-workspace.yaml +39 -0
  181. package/templates/fate/prisma/public/fate-logo-dark.svg +4 -0
  182. package/templates/fate/prisma/public/fate-logo.svg +4 -0
  183. package/templates/fate/prisma/server/.env.example +5 -0
  184. package/templates/fate/prisma/server/package.json +42 -0
  185. package/templates/fate/prisma/server/prisma.config.ts +21 -0
  186. package/templates/fate/prisma/server/src/__tests__/index.test.tsx +5 -0
  187. package/templates/fate/prisma/server/src/app.tsx +40 -0
  188. package/templates/fate/prisma/server/src/index.tsx +24 -0
  189. package/templates/fate/prisma/server/src/lib/auth.ts +31 -0
  190. package/templates/fate/prisma/server/src/lib/env.ts +3 -0
  191. package/templates/fate/prisma/server/src/lib/origins.ts +18 -0
  192. package/templates/fate/prisma/server/src/prisma/prisma.ts +9 -0
  193. package/templates/fate/prisma/server/src/prisma/schema.prisma +98 -0
  194. package/templates/fate/prisma/server/src/prisma/seed.tsx +71 -0
  195. package/templates/fate/prisma/server/src/prisma/seedData.ts +205 -0
  196. package/templates/fate/prisma/server/src/router.ts +14 -0
  197. package/templates/fate/prisma/server/src/trpc/connection.ts +4 -0
  198. package/templates/fate/prisma/server/src/trpc/context.ts +22 -0
  199. package/templates/fate/prisma/server/src/trpc/init.ts +8 -0
  200. package/templates/fate/prisma/server/src/trpc/routers/comment.ts +176 -0
  201. package/templates/fate/prisma/server/src/trpc/routers/post.ts +154 -0
  202. package/templates/fate/prisma/server/src/trpc/routers/user.ts +71 -0
  203. package/templates/fate/prisma/server/src/trpc/views.ts +77 -0
  204. package/templates/fate/prisma/server/src/user/SessionUser.tsx +17 -0
  205. package/templates/fate/prisma/server/vite.config.ts +8 -0
  206. package/templates/fate/prisma/tsconfig.json +33 -0
  207. package/templates/fate/prisma/vite.config.ts +72 -0
  208. package/templates/fate/void/.oxfmtrc.jsonc +14 -0
  209. package/templates/fate/void/README.md +55 -0
  210. package/templates/fate/void/auth.ts +22 -0
  211. package/templates/fate/void/db/migrations/20260508073357_initial_schema.sql +133 -0
  212. package/templates/fate/void/db/migrations/20260508120500_seed_void_demo.sql +170 -0
  213. package/templates/fate/void/db/migrations/meta/20260508073357_snapshot.json +868 -0
  214. package/templates/fate/void/db/migrations/meta/_journal.json +20 -0
  215. package/templates/fate/void/db/queries.ts +211 -0
  216. package/templates/fate/void/db/schema.ts +325 -0
  217. package/templates/fate/void/db/seed-auth.ts +31 -0
  218. package/templates/fate/void/db/seed.ts +163 -0
  219. package/templates/fate/void/middleware/01.shared.ts +29 -0
  220. package/templates/fate/void/package.json +65 -0
  221. package/templates/fate/void/pages/category/[id].tsx +23 -0
  222. package/templates/fate/void/pages/index.tsx +153 -0
  223. package/templates/fate/void/pages/layout.tsx +46 -0
  224. package/templates/fate/void/pages/login.tsx +103 -0
  225. package/templates/fate/void/pages/post/[id].tsx +20 -0
  226. package/templates/fate/void/pages/search.tsx +81 -0
  227. package/templates/fate/void/pnpm-workspace.yaml +31 -0
  228. package/templates/fate/void/public/.assetsignore +1 -0
  229. package/templates/fate/void/public/icon.svg +1 -0
  230. package/templates/fate/void/routes/fate-live.ts +8 -0
  231. package/templates/fate/void/routes/fate.ts +8 -0
  232. package/templates/fate/void/seedData.ts +535 -0
  233. package/templates/fate/void/src/App.css +130 -0
  234. package/templates/fate/void/src/fate/__tests__/commentPermissions.test.ts +31 -0
  235. package/templates/fate/void/src/fate/commentPermissions.ts +17 -0
  236. package/templates/fate/void/src/fate/context.ts +15 -0
  237. package/templates/fate/void/src/fate/live.ts +6 -0
  238. package/templates/fate/void/src/fate/server.ts +401 -0
  239. package/templates/fate/void/src/fate/views.ts +164 -0
  240. package/templates/fate/void/src/lib/cx.tsx +6 -0
  241. package/templates/fate/void/src/lib/formatLabel.tsx +6 -0
  242. package/templates/fate/void/src/lib/shared.ts +10 -0
  243. package/templates/fate/void/src/ui/Badge.tsx +31 -0
  244. package/templates/fate/void/src/ui/Button.tsx +92 -0
  245. package/templates/fate/void/src/ui/Card.tsx +29 -0
  246. package/templates/fate/void/src/ui/CategoryCard.tsx +105 -0
  247. package/templates/fate/void/src/ui/CommentCard.tsx +80 -0
  248. package/templates/fate/void/src/ui/CreatePost.tsx +111 -0
  249. package/templates/fate/void/src/ui/Error.tsx +19 -0
  250. package/templates/fate/void/src/ui/EventCard.tsx +152 -0
  251. package/templates/fate/void/src/ui/H2.tsx +15 -0
  252. package/templates/fate/void/src/ui/H3.tsx +20 -0
  253. package/templates/fate/void/src/ui/Header.tsx +96 -0
  254. package/templates/fate/void/src/ui/Input.tsx +33 -0
  255. package/templates/fate/void/src/ui/Link.tsx +11 -0
  256. package/templates/fate/void/src/ui/Number.tsx +5 -0
  257. package/templates/fate/void/src/ui/PostCard.tsx +294 -0
  258. package/templates/fate/void/src/ui/Section.tsx +23 -0
  259. package/templates/fate/void/src/ui/TagBadge.tsx +23 -0
  260. package/templates/fate/void/src/ui/UserCard.tsx +129 -0
  261. package/templates/fate/void/src/user/AuthClient.tsx +1 -0
  262. package/templates/fate/void/src/user/SessionUser.tsx +17 -0
  263. package/templates/fate/void/tsconfig.json +34 -0
  264. package/templates/fate/void/vite.config.ts +83 -0
  265. package/templates/fate/void/void.json +32 -0
  266. 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,8 @@
1
+ import { defineConfig } from 'vite-plus';
2
+
3
+ export default defineConfig({
4
+ pack: {
5
+ entry: ['./src/app.tsx'],
6
+ outputOptions: { file: 'dist/index.js' },
7
+ },
8
+ });
@@ -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`);