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,129 @@
1
+ import safeParse from '@nkzw/core/safeParse.js';
2
+ import Stack, { VStack } from '@nkzw/stack';
3
+ import { ChangeEvent, useActionState, useState } from 'react';
4
+ import { useFateClient, useView, view, ViewRef } from 'react-fate';
5
+ import { User } from '../fate/server.ts';
6
+ import { Button } from '../ui/Button.tsx';
7
+ import Card from '../ui/Card.tsx';
8
+ import AuthClient from '../user/AuthClient.tsx';
9
+ import H2 from './H2.tsx';
10
+ import Input from './Input.tsx';
11
+
12
+ export type SessionUser = {
13
+ id?: string | null;
14
+ name?: string | null;
15
+ username?: string | null;
16
+ };
17
+
18
+ export const UserView = view<User>()({
19
+ id: true,
20
+ name: true,
21
+ username: true,
22
+ });
23
+
24
+ export const UserCardView = view<User>()({
25
+ email: true,
26
+ id: true,
27
+ name: true,
28
+ username: true,
29
+ });
30
+
31
+ const UserNameForm = ({ user }: { user: SessionUser }) => {
32
+ const fate = useFateClient();
33
+ const [name, setName] = useState(user.name ?? '');
34
+ const [error, setError] = useState<string | null>(null);
35
+
36
+ const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
37
+ setError(null);
38
+ setName(event.target.value);
39
+ };
40
+
41
+ const [, submitAction, isPending] = useActionState(async () => {
42
+ const id = user?.id;
43
+ if (!id) {
44
+ return;
45
+ }
46
+
47
+ const newName = name.trim();
48
+ setName(newName);
49
+
50
+ if (newName === user.name) {
51
+ setError(null);
52
+ return;
53
+ }
54
+
55
+ try {
56
+ setError(null);
57
+ await fate.mutations.user.update({
58
+ input: { name: newName },
59
+ optimistic: {
60
+ id,
61
+ username: newName,
62
+ },
63
+ view: UserView,
64
+ });
65
+ await AuthClient.updateUser({ name });
66
+ } catch (error) {
67
+ setError(
68
+ (error instanceof Error &&
69
+ error.message &&
70
+ safeParse<Array<{ message: string }>>(error.message)?.[0]?.message) ||
71
+ 'Failed to update user name.',
72
+ );
73
+ }
74
+ }, null);
75
+
76
+ const trimmedName = name.trim();
77
+ const originalName = user.name ?? '';
78
+ const isSaveDisabled = !user.id || !trimmedName || trimmedName === originalName || isPending;
79
+
80
+ return (
81
+ <div>
82
+ <VStack action={submitAction} as="form" gap={12}>
83
+ <h3 className="font-semibold">Update Name</h3>
84
+ <label className="sr-only" htmlFor="header-username">
85
+ Username
86
+ </label>
87
+ <Input
88
+ aria-describedby={error ? 'header-username-error' : undefined}
89
+ aria-invalid={error ? 'true' : undefined}
90
+ className="w-48"
91
+ disabled={isPending}
92
+ id="header-username"
93
+ name="name"
94
+ onChange={handleChange}
95
+ placeholder="Name"
96
+ title={error ?? undefined}
97
+ value={name}
98
+ />
99
+ <div>
100
+ <Button disabled={isSaveDisabled} size="sm" type="submit" variant="secondary">
101
+ Save
102
+ </Button>
103
+ </div>
104
+ </VStack>
105
+ {error ? <span id="header-username-error">{error}</span> : null}
106
+ </div>
107
+ );
108
+ };
109
+
110
+ export default function UserCard({ viewer: viewerRef }: { viewer: ViewRef<'User'> }) {
111
+ const viewer = useView(UserCardView, viewerRef);
112
+
113
+ return (
114
+ <Card>
115
+ <VStack between className="h-full" gap={16}>
116
+ <VStack gap={16}>
117
+ <H2>Your account</H2>
118
+ <Stack alignCenter between gap={16}>
119
+ <p className="text-sm text-muted-foreground">
120
+ Signed in as {viewer.name}
121
+ {viewer.email ? ` <${viewer.email}>` : null}.
122
+ </p>
123
+ </Stack>
124
+ </VStack>
125
+ <UserNameForm user={viewer} />
126
+ </VStack>
127
+ </Card>
128
+ );
129
+ }
@@ -0,0 +1 @@
1
+ export { auth as default } from 'void/client';
@@ -0,0 +1,17 @@
1
+ import type { UserRow } from '../../db/schema.ts';
2
+
3
+ export type SessionUser = Pick<UserRow, '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,34 @@
1
+ {
2
+ "extends": "./.void/tsconfig.json",
3
+ "compilerOptions": {
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": "ESNext",
12
+ "moduleResolution": "Bundler",
13
+ "noEmit": true,
14
+ "noImplicitOverride": true,
15
+ "noUnusedLocals": true,
16
+ "resolveJsonModule": true,
17
+ "skipLibCheck": true,
18
+ "strict": true,
19
+ "target": "ES2022",
20
+ "types": ["vite/client", "void/env"]
21
+ },
22
+ "include": [
23
+ ".fate/**/*.ts",
24
+ ".void/**/*.d.ts",
25
+ "db/**/*.ts",
26
+ "db/**/*.tsx",
27
+ "middleware/**/*.ts",
28
+ "pages/**/*.ts",
29
+ "pages/**/*.tsx",
30
+ "routes/**/*.ts",
31
+ "src/**/*.ts",
32
+ "src/**/*.tsx"
33
+ ]
34
+ }
@@ -0,0 +1,83 @@
1
+ import babel from '@rolldown/plugin-babel';
2
+ import tailwindcss from '@tailwindcss/vite';
3
+ import { reactCompilerPreset } from '@vitejs/plugin-react';
4
+ import { voidReact } from '@void/react/plugin';
5
+ import { fate } from 'react-fate/vite';
6
+ import { defineConfig, lazyPlugins } from 'vite-plus';
7
+ import { voidPlugin } from 'void';
8
+
9
+ const isTest = process.env.NODE_ENV === 'test' || process.env.VITEST;
10
+
11
+ export default defineConfig({
12
+ environments: {
13
+ void_worker: {
14
+ optimizeDeps: {
15
+ include: [
16
+ '@nkzw/core/safeParse.js',
17
+ '@nkzw/stack',
18
+ '@radix-ui/react-slot',
19
+ '@void/react',
20
+ '@void/react/pages-server',
21
+ 'better-auth',
22
+ 'better-auth/adapters/drizzle',
23
+ 'better-auth/plugins',
24
+ 'class-variance-authority',
25
+ 'clsx',
26
+ 'drizzle-orm',
27
+ 'lucide-react',
28
+ 'react',
29
+ 'react-error-boundary',
30
+ 'react/jsx-dev-runtime',
31
+ 'react/jsx-runtime',
32
+ 'tailwind-merge',
33
+ 'void/schema-d1',
34
+ 'zod',
35
+ ],
36
+ },
37
+ },
38
+ },
39
+ fmt: {
40
+ experimentalSortImports: {
41
+ newlinesBetween: false,
42
+ },
43
+ experimentalSortPackageJson: {
44
+ sortScripts: true,
45
+ },
46
+ experimentalTailwindcss: {
47
+ stylesheet: 'src/App.css',
48
+ },
49
+ ignorePatterns: ['.fate/', '.void/', 'dist/', 'node_modules/', 'pnpm-lock.yaml'],
50
+ singleQuote: true,
51
+ },
52
+ lint: {
53
+ ignorePatterns: ['.fate', '.void', 'dist', 'node_modules', 'vite.config.ts.timestamp-*'],
54
+ options: { typeAware: true, typeCheck: true },
55
+ overrides: [
56
+ {
57
+ files: ['db/seed.ts', 'src/fate/__tests__/**'],
58
+ rules: {
59
+ 'no-console': 'off',
60
+ },
61
+ },
62
+ ],
63
+ rules: {
64
+ '@typescript-eslint/no-explicit-any': 'off',
65
+ },
66
+ },
67
+ plugins: [
68
+ ...(lazyPlugins(() => [
69
+ babel({
70
+ presets: [reactCompilerPreset()],
71
+ }),
72
+ tailwindcss(),
73
+ ...(isTest ? [] : [voidPlugin(), voidReact()]),
74
+ ]) ?? []),
75
+ fate({
76
+ module: './src/fate/server.ts',
77
+ transport: 'void',
78
+ }),
79
+ ],
80
+ resolve: { conditions: ['@nkzw/source'] },
81
+ server: { port: 6001 },
82
+ ssr: { noExternal: ['void-fate'] },
83
+ });
@@ -0,0 +1,32 @@
1
+ {
2
+ "$schema": "./node_modules/void/schema.json",
3
+ "auth": {
4
+ "providers": ["email"]
5
+ },
6
+ "head": {
7
+ "title": "fate",
8
+ "titleTemplate": "%s | fate",
9
+ "htmlAttrs": {
10
+ "lang": "en"
11
+ },
12
+ "meta": [
13
+ {
14
+ "charset": "utf-8"
15
+ },
16
+ {
17
+ "name": "viewport",
18
+ "content": "width=device-width, initial-scale=1"
19
+ }
20
+ ],
21
+ "link": [
22
+ {
23
+ "rel": "icon",
24
+ "href": "/icon.svg"
25
+ }
26
+ ]
27
+ },
28
+ "worker": {
29
+ "compatibility_date": "2025-12-01",
30
+ "compatibility_flags": ["nodejs_compat", "no_handle_cross_request_promise_resolution"]
31
+ }
32
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "durable_objects": {
3
+ "bindings": [
4
+ {
5
+ "name": "VOID_LIVE",
6
+ "class_name": "VoidLiveStreamDurableObject",
7
+ },
8
+ ],
9
+ },
10
+ "migrations": [
11
+ {
12
+ "tag": "live-v1",
13
+ "new_sqlite_classes": ["VoidLiveStreamDurableObject"],
14
+ },
15
+ ],
16
+ }