ugly-app 0.1.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 (554) hide show
  1. package/.claude/settings.local.json +18 -0
  2. package/.env.example +9 -0
  3. package/.yarn-metadata.json +113 -0
  4. package/README.md +709 -0
  5. package/dist/cli/authCommands.d.ts +6 -0
  6. package/dist/cli/authCommands.d.ts.map +1 -0
  7. package/dist/cli/authCommands.js +50 -0
  8. package/dist/cli/authCommands.js.map +1 -0
  9. package/dist/cli/build.d.ts +2 -0
  10. package/dist/cli/build.d.ts.map +1 -0
  11. package/dist/cli/build.js +26 -0
  12. package/dist/cli/build.js.map +1 -0
  13. package/dist/cli/configure.d.ts +2 -0
  14. package/dist/cli/configure.d.ts.map +1 -0
  15. package/dist/cli/configure.js +53 -0
  16. package/dist/cli/configure.js.map +1 -0
  17. package/dist/cli/dev.d.ts +2 -0
  18. package/dist/cli/dev.d.ts.map +1 -0
  19. package/dist/cli/dev.js +66 -0
  20. package/dist/cli/dev.js.map +1 -0
  21. package/dist/cli/index.d.ts +3 -0
  22. package/dist/cli/index.d.ts.map +1 -0
  23. package/dist/cli/index.js +340 -0
  24. package/dist/cli/index.js.map +1 -0
  25. package/dist/cli/initDb.d.ts +2 -0
  26. package/dist/cli/initDb.d.ts.map +1 -0
  27. package/dist/cli/initDb.js +110 -0
  28. package/dist/cli/initDb.js.map +1 -0
  29. package/dist/cli/logQuery.d.ts +12 -0
  30. package/dist/cli/logQuery.d.ts.map +1 -0
  31. package/dist/cli/logQuery.js +176 -0
  32. package/dist/cli/logQuery.js.map +1 -0
  33. package/dist/cli/migrate.d.ts +4 -0
  34. package/dist/cli/migrate.d.ts.map +1 -0
  35. package/dist/cli/migrate.js +62 -0
  36. package/dist/cli/migrate.js.map +1 -0
  37. package/dist/cli/publishAssets.d.ts +6 -0
  38. package/dist/cli/publishAssets.d.ts.map +1 -0
  39. package/dist/cli/publishAssets.js +87 -0
  40. package/dist/cli/publishAssets.js.map +1 -0
  41. package/dist/cli/purgeAssets.d.ts +2 -0
  42. package/dist/cli/purgeAssets.d.ts.map +1 -0
  43. package/dist/cli/purgeAssets.js +36 -0
  44. package/dist/cli/purgeAssets.js.map +1 -0
  45. package/dist/cli/scaffold.d.ts +2 -0
  46. package/dist/cli/scaffold.d.ts.map +1 -0
  47. package/dist/cli/scaffold.js +37 -0
  48. package/dist/cli/scaffold.js.map +1 -0
  49. package/dist/cli/serverLogQuery.d.ts +6 -0
  50. package/dist/cli/serverLogQuery.d.ts.map +1 -0
  51. package/dist/cli/serverLogQuery.js +76 -0
  52. package/dist/cli/serverLogQuery.js.map +1 -0
  53. package/dist/cli/storageClient.d.ts +3 -0
  54. package/dist/cli/storageClient.d.ts.map +1 -0
  55. package/dist/cli/storageClient.js +22 -0
  56. package/dist/cli/storageClient.js.map +1 -0
  57. package/dist/cli/uglyappConfig.d.ts +29 -0
  58. package/dist/cli/uglyappConfig.d.ts.map +1 -0
  59. package/dist/cli/uglyappConfig.js +125 -0
  60. package/dist/cli/uglyappConfig.js.map +1 -0
  61. package/dist/client/AppProvider.d.ts +32 -0
  62. package/dist/client/AppProvider.d.ts.map +1 -0
  63. package/dist/client/AppProvider.js +126 -0
  64. package/dist/client/AppProvider.js.map +1 -0
  65. package/dist/client/ErrorLog.d.ts +16 -0
  66. package/dist/client/ErrorLog.d.ts.map +1 -0
  67. package/dist/client/ErrorLog.js +28 -0
  68. package/dist/client/ErrorLog.js.map +1 -0
  69. package/dist/client/FeedbackContext.d.ts +7 -0
  70. package/dist/client/FeedbackContext.d.ts.map +1 -0
  71. package/dist/client/FeedbackContext.js +15 -0
  72. package/dist/client/FeedbackContext.js.map +1 -0
  73. package/dist/client/Logger.d.ts +2 -0
  74. package/dist/client/Logger.d.ts.map +1 -0
  75. package/dist/client/Logger.js +72 -0
  76. package/dist/client/Logger.js.map +1 -0
  77. package/dist/client/LoginPopup.d.ts +7 -0
  78. package/dist/client/LoginPopup.d.ts.map +1 -0
  79. package/dist/client/LoginPopup.js +55 -0
  80. package/dist/client/LoginPopup.js.map +1 -0
  81. package/dist/client/Router.d.ts +56 -0
  82. package/dist/client/Router.d.ts.map +1 -0
  83. package/dist/client/Router.js +224 -0
  84. package/dist/client/Router.js.map +1 -0
  85. package/dist/client/Screenshot.d.ts +7 -0
  86. package/dist/client/Screenshot.d.ts.map +1 -0
  87. package/dist/client/Screenshot.js +54 -0
  88. package/dist/client/Screenshot.js.map +1 -0
  89. package/dist/client/ViewFlipper.d.ts +16 -0
  90. package/dist/client/ViewFlipper.d.ts.map +1 -0
  91. package/dist/client/ViewFlipper.js +156 -0
  92. package/dist/client/ViewFlipper.js.map +1 -0
  93. package/dist/client/animation/Animated.d.ts +14 -0
  94. package/dist/client/animation/Animated.d.ts.map +1 -0
  95. package/dist/client/animation/Animated.js +97 -0
  96. package/dist/client/animation/Animated.js.map +1 -0
  97. package/dist/client/animation/animatedValue.d.ts +41 -0
  98. package/dist/client/animation/animatedValue.d.ts.map +1 -0
  99. package/dist/client/animation/animatedValue.js +123 -0
  100. package/dist/client/animation/animatedValue.js.map +1 -0
  101. package/dist/client/animations/FadeIn.d.ts +6 -0
  102. package/dist/client/animations/FadeIn.d.ts.map +1 -0
  103. package/dist/client/animations/FadeIn.js +24 -0
  104. package/dist/client/animations/FadeIn.js.map +1 -0
  105. package/dist/client/animations/SlideFromBottom.d.ts +6 -0
  106. package/dist/client/animations/SlideFromBottom.d.ts.map +1 -0
  107. package/dist/client/animations/SlideFromBottom.js +24 -0
  108. package/dist/client/animations/SlideFromBottom.js.map +1 -0
  109. package/dist/client/animations/SlideFromRight.d.ts +6 -0
  110. package/dist/client/animations/SlideFromRight.d.ts.map +1 -0
  111. package/dist/client/animations/SlideFromRight.js +24 -0
  112. package/dist/client/animations/SlideFromRight.js.map +1 -0
  113. package/dist/client/audio/AudioPlayer.d.ts +11 -0
  114. package/dist/client/audio/AudioPlayer.d.ts.map +1 -0
  115. package/dist/client/audio/AudioPlayer.js +51 -0
  116. package/dist/client/audio/AudioPlayer.js.map +1 -0
  117. package/dist/client/audio/AudioRecorder.d.ts +11 -0
  118. package/dist/client/audio/AudioRecorder.d.ts.map +1 -0
  119. package/dist/client/audio/AudioRecorder.js +66 -0
  120. package/dist/client/audio/AudioRecorder.js.map +1 -0
  121. package/dist/client/audio/audioPlayer.worklet.d.ts +2 -0
  122. package/dist/client/audio/audioPlayer.worklet.d.ts.map +1 -0
  123. package/dist/client/audio/audioPlayer.worklet.js +46 -0
  124. package/dist/client/audio/audioPlayer.worklet.js.map +1 -0
  125. package/dist/client/audio/useSTT.d.ts +19 -0
  126. package/dist/client/audio/useSTT.d.ts.map +1 -0
  127. package/dist/client/audio/useSTT.js +91 -0
  128. package/dist/client/audio/useSTT.js.map +1 -0
  129. package/dist/client/audio/useTTS.d.ts +17 -0
  130. package/dist/client/audio/useTTS.d.ts.map +1 -0
  131. package/dist/client/audio/useTTS.js +70 -0
  132. package/dist/client/audio/useTTS.js.map +1 -0
  133. package/dist/client/components/Button.d.ts +22 -0
  134. package/dist/client/components/Button.d.ts.map +1 -0
  135. package/dist/client/components/Button.js +27 -0
  136. package/dist/client/components/Button.js.map +1 -0
  137. package/dist/client/components/Card.d.ts +8 -0
  138. package/dist/client/components/Card.d.ts.map +1 -0
  139. package/dist/client/components/Card.js +6 -0
  140. package/dist/client/components/Card.js.map +1 -0
  141. package/dist/client/components/EnumInput.d.ts +16 -0
  142. package/dist/client/components/EnumInput.d.ts.map +1 -0
  143. package/dist/client/components/EnumInput.js +11 -0
  144. package/dist/client/components/EnumInput.js.map +1 -0
  145. package/dist/client/components/FeedbackButton.d.ts +9 -0
  146. package/dist/client/components/FeedbackButton.d.ts.map +1 -0
  147. package/dist/client/components/FeedbackButton.js +112 -0
  148. package/dist/client/components/FeedbackButton.js.map +1 -0
  149. package/dist/client/components/Header.d.ts +10 -0
  150. package/dist/client/components/Header.d.ts.map +1 -0
  151. package/dist/client/components/Header.js +12 -0
  152. package/dist/client/components/Header.js.map +1 -0
  153. package/dist/client/components/Image.d.ts +20 -0
  154. package/dist/client/components/Image.d.ts.map +1 -0
  155. package/dist/client/components/Image.js +12 -0
  156. package/dist/client/components/Image.js.map +1 -0
  157. package/dist/client/components/Input.d.ts +14 -0
  158. package/dist/client/components/Input.d.ts.map +1 -0
  159. package/dist/client/components/Input.js +19 -0
  160. package/dist/client/components/Input.js.map +1 -0
  161. package/dist/client/components/Modal.d.ts +9 -0
  162. package/dist/client/components/Modal.d.ts.map +1 -0
  163. package/dist/client/components/Modal.js +19 -0
  164. package/dist/client/components/Modal.js.map +1 -0
  165. package/dist/client/components/PageLayout.d.ts +9 -0
  166. package/dist/client/components/PageLayout.d.ts.map +1 -0
  167. package/dist/client/components/PageLayout.js +6 -0
  168. package/dist/client/components/PageLayout.js.map +1 -0
  169. package/dist/client/components/Panel.d.ts +8 -0
  170. package/dist/client/components/Panel.d.ts.map +1 -0
  171. package/dist/client/components/Panel.js +5 -0
  172. package/dist/client/components/Panel.js.map +1 -0
  173. package/dist/client/components/PopupPanel.d.ts +9 -0
  174. package/dist/client/components/PopupPanel.d.ts.map +1 -0
  175. package/dist/client/components/PopupPanel.js +5 -0
  176. package/dist/client/components/PopupPanel.js.map +1 -0
  177. package/dist/client/components/Pressable.d.ts +14 -0
  178. package/dist/client/components/Pressable.d.ts.map +1 -0
  179. package/dist/client/components/Pressable.js +8 -0
  180. package/dist/client/components/Pressable.js.map +1 -0
  181. package/dist/client/components/ScrollView.d.ts +9 -0
  182. package/dist/client/components/ScrollView.d.ts.map +1 -0
  183. package/dist/client/components/ScrollView.js +7 -0
  184. package/dist/client/components/ScrollView.js.map +1 -0
  185. package/dist/client/components/SettingGroup.d.ts +10 -0
  186. package/dist/client/components/SettingGroup.d.ts.map +1 -0
  187. package/dist/client/components/SettingGroup.js +8 -0
  188. package/dist/client/components/SettingGroup.js.map +1 -0
  189. package/dist/client/components/Text.d.ts +21 -0
  190. package/dist/client/components/Text.d.ts.map +1 -0
  191. package/dist/client/components/Text.js +43 -0
  192. package/dist/client/components/Text.js.map +1 -0
  193. package/dist/client/components/Toast.d.ts +10 -0
  194. package/dist/client/components/Toast.d.ts.map +1 -0
  195. package/dist/client/components/Toast.js +21 -0
  196. package/dist/client/components/Toast.js.map +1 -0
  197. package/dist/client/components/View.d.ts +9 -0
  198. package/dist/client/components/View.d.ts.map +1 -0
  199. package/dist/client/components/View.js +5 -0
  200. package/dist/client/components/View.js.map +1 -0
  201. package/dist/client/components/index.d.ts +33 -0
  202. package/dist/client/components/index.d.ts.map +1 -0
  203. package/dist/client/components/index.js +17 -0
  204. package/dist/client/components/index.js.map +1 -0
  205. package/dist/client/components/zIndex.d.ts +10 -0
  206. package/dist/client/components/zIndex.d.ts.map +1 -0
  207. package/dist/client/components/zIndex.js +12 -0
  208. package/dist/client/components/zIndex.js.map +1 -0
  209. package/dist/client/createSocket.d.ts +26 -0
  210. package/dist/client/createSocket.d.ts.map +1 -0
  211. package/dist/client/createSocket.js +138 -0
  212. package/dist/client/createSocket.js.map +1 -0
  213. package/dist/client/index.d.ts +27 -0
  214. package/dist/client/index.d.ts.map +1 -0
  215. package/dist/client/index.js +20 -0
  216. package/dist/client/index.js.map +1 -0
  217. package/dist/playwright/index.d.ts +16 -0
  218. package/dist/playwright/index.d.ts.map +1 -0
  219. package/dist/playwright/index.js +32 -0
  220. package/dist/playwright/index.js.map +1 -0
  221. package/dist/server/App.d.ts +43 -0
  222. package/dist/server/App.d.ts.map +1 -0
  223. package/dist/server/App.js +215 -0
  224. package/dist/server/App.js.map +1 -0
  225. package/dist/server/Auth.d.ts +21 -0
  226. package/dist/server/Auth.d.ts.map +1 -0
  227. package/dist/server/Auth.js +171 -0
  228. package/dist/server/Auth.js.map +1 -0
  229. package/dist/server/Cache.d.ts +38 -0
  230. package/dist/server/Cache.d.ts.map +1 -0
  231. package/dist/server/Cache.js +113 -0
  232. package/dist/server/Cache.js.map +1 -0
  233. package/dist/server/ChangeStream.d.ts +22 -0
  234. package/dist/server/ChangeStream.d.ts.map +1 -0
  235. package/dist/server/ChangeStream.js +93 -0
  236. package/dist/server/ChangeStream.js.map +1 -0
  237. package/dist/server/DB.d.ts +17 -0
  238. package/dist/server/DB.d.ts.map +1 -0
  239. package/dist/server/DB.js +442 -0
  240. package/dist/server/DB.js.map +1 -0
  241. package/dist/server/Email.d.ts +22 -0
  242. package/dist/server/Email.d.ts.map +1 -0
  243. package/dist/server/Email.js +64 -0
  244. package/dist/server/Email.js.map +1 -0
  245. package/dist/server/EmailTemplate.d.ts +17 -0
  246. package/dist/server/EmailTemplate.d.ts.map +1 -0
  247. package/dist/server/EmailTemplate.js +29 -0
  248. package/dist/server/EmailTemplate.js.map +1 -0
  249. package/dist/server/FeedbackReport.d.ts +19 -0
  250. package/dist/server/FeedbackReport.d.ts.map +1 -0
  251. package/dist/server/FeedbackReport.js +94 -0
  252. package/dist/server/FeedbackReport.js.map +1 -0
  253. package/dist/server/ImageGen.d.ts +5 -0
  254. package/dist/server/ImageGen.d.ts.map +1 -0
  255. package/dist/server/ImageGen.js +5 -0
  256. package/dist/server/ImageGen.js.map +1 -0
  257. package/dist/server/Logging.d.ts +59 -0
  258. package/dist/server/Logging.d.ts.map +1 -0
  259. package/dist/server/Logging.js +293 -0
  260. package/dist/server/Logging.js.map +1 -0
  261. package/dist/server/Nats.d.ts +56 -0
  262. package/dist/server/Nats.d.ts.map +1 -0
  263. package/dist/server/Nats.js +162 -0
  264. package/dist/server/Nats.js.map +1 -0
  265. package/dist/server/NatsStore.d.ts +26 -0
  266. package/dist/server/NatsStore.d.ts.map +1 -0
  267. package/dist/server/NatsStore.js +86 -0
  268. package/dist/server/NatsStore.js.map +1 -0
  269. package/dist/server/PushNotification.d.ts +33 -0
  270. package/dist/server/PushNotification.d.ts.map +1 -0
  271. package/dist/server/PushNotification.js +131 -0
  272. package/dist/server/PushNotification.js.map +1 -0
  273. package/dist/server/RateLimit.d.ts +28 -0
  274. package/dist/server/RateLimit.d.ts.map +1 -0
  275. package/dist/server/RateLimit.js +101 -0
  276. package/dist/server/RateLimit.js.map +1 -0
  277. package/dist/server/Redis.d.ts +61 -0
  278. package/dist/server/Redis.d.ts.map +1 -0
  279. package/dist/server/Redis.js +226 -0
  280. package/dist/server/Redis.js.map +1 -0
  281. package/dist/server/Router.d.ts +27 -0
  282. package/dist/server/Router.d.ts.map +1 -0
  283. package/dist/server/Router.js +71 -0
  284. package/dist/server/Router.js.map +1 -0
  285. package/dist/server/Socket.d.ts +8 -0
  286. package/dist/server/Socket.d.ts.map +1 -0
  287. package/dist/server/Socket.js +278 -0
  288. package/dist/server/Socket.js.map +1 -0
  289. package/dist/server/SpendTracker.d.ts +18 -0
  290. package/dist/server/SpendTracker.d.ts.map +1 -0
  291. package/dist/server/SpendTracker.js +110 -0
  292. package/dist/server/SpendTracker.js.map +1 -0
  293. package/dist/server/Storage.d.ts +16 -0
  294. package/dist/server/Storage.d.ts.map +1 -0
  295. package/dist/server/Storage.js +95 -0
  296. package/dist/server/Storage.js.map +1 -0
  297. package/dist/server/TextGen.d.ts +5 -0
  298. package/dist/server/TextGen.d.ts.map +1 -0
  299. package/dist/server/TextGen.js +6 -0
  300. package/dist/server/TextGen.js.map +1 -0
  301. package/dist/server/WorkerQueue.d.ts +27 -0
  302. package/dist/server/WorkerQueue.d.ts.map +1 -0
  303. package/dist/server/WorkerQueue.js +147 -0
  304. package/dist/server/WorkerQueue.js.map +1 -0
  305. package/dist/server/ai/ImageGenClient.d.ts +6 -0
  306. package/dist/server/ai/ImageGenClient.d.ts.map +1 -0
  307. package/dist/server/ai/ImageGenClient.js +29 -0
  308. package/dist/server/ai/ImageGenClient.js.map +1 -0
  309. package/dist/server/ai/ProviderBalance.d.ts +15 -0
  310. package/dist/server/ai/ProviderBalance.d.ts.map +1 -0
  311. package/dist/server/ai/ProviderBalance.js +110 -0
  312. package/dist/server/ai/ProviderBalance.js.map +1 -0
  313. package/dist/server/ai/ProviderSelector.d.ts +13 -0
  314. package/dist/server/ai/ProviderSelector.d.ts.map +1 -0
  315. package/dist/server/ai/ProviderSelector.js +25 -0
  316. package/dist/server/ai/ProviderSelector.js.map +1 -0
  317. package/dist/server/ai/TextGenClient.d.ts +9 -0
  318. package/dist/server/ai/TextGenClient.d.ts.map +1 -0
  319. package/dist/server/ai/TextGenClient.js +72 -0
  320. package/dist/server/ai/TextGenClient.js.map +1 -0
  321. package/dist/server/ai/fallbacks.d.ts +9 -0
  322. package/dist/server/ai/fallbacks.d.ts.map +1 -0
  323. package/dist/server/ai/fallbacks.js +77 -0
  324. package/dist/server/ai/fallbacks.js.map +1 -0
  325. package/dist/server/ai/index.d.ts +12 -0
  326. package/dist/server/ai/index.d.ts.map +1 -0
  327. package/dist/server/ai/index.js +37 -0
  328. package/dist/server/ai/index.js.map +1 -0
  329. package/dist/server/ai/providers/Claude.d.ts +3 -0
  330. package/dist/server/ai/providers/Claude.d.ts.map +1 -0
  331. package/dist/server/ai/providers/Claude.js +124 -0
  332. package/dist/server/ai/providers/Claude.js.map +1 -0
  333. package/dist/server/ai/providers/FAL.d.ts +3 -0
  334. package/dist/server/ai/providers/FAL.d.ts.map +1 -0
  335. package/dist/server/ai/providers/FAL.js +24 -0
  336. package/dist/server/ai/providers/FAL.js.map +1 -0
  337. package/dist/server/ai/providers/Fireworks.d.ts +3 -0
  338. package/dist/server/ai/providers/Fireworks.d.ts.map +1 -0
  339. package/dist/server/ai/providers/Fireworks.js +79 -0
  340. package/dist/server/ai/providers/Fireworks.js.map +1 -0
  341. package/dist/server/ai/providers/Google.d.ts +3 -0
  342. package/dist/server/ai/providers/Google.d.ts.map +1 -0
  343. package/dist/server/ai/providers/Google.js +105 -0
  344. package/dist/server/ai/providers/Google.js.map +1 -0
  345. package/dist/server/ai/providers/GoogleImage.d.ts +3 -0
  346. package/dist/server/ai/providers/GoogleImage.d.ts.map +1 -0
  347. package/dist/server/ai/providers/GoogleImage.js +24 -0
  348. package/dist/server/ai/providers/GoogleImage.js.map +1 -0
  349. package/dist/server/ai/providers/Groq.d.ts +3 -0
  350. package/dist/server/ai/providers/Groq.d.ts.map +1 -0
  351. package/dist/server/ai/providers/Groq.js +99 -0
  352. package/dist/server/ai/providers/Groq.js.map +1 -0
  353. package/dist/server/ai/providers/Kie.d.ts +3 -0
  354. package/dist/server/ai/providers/Kie.d.ts.map +1 -0
  355. package/dist/server/ai/providers/Kie.js +79 -0
  356. package/dist/server/ai/providers/Kie.js.map +1 -0
  357. package/dist/server/ai/providers/KieImage.d.ts +3 -0
  358. package/dist/server/ai/providers/KieImage.d.ts.map +1 -0
  359. package/dist/server/ai/providers/KieImage.js +50 -0
  360. package/dist/server/ai/providers/KieImage.js.map +1 -0
  361. package/dist/server/ai/providers/OpenAIText.d.ts +3 -0
  362. package/dist/server/ai/providers/OpenAIText.d.ts.map +1 -0
  363. package/dist/server/ai/providers/OpenAIText.js +103 -0
  364. package/dist/server/ai/providers/OpenAIText.js.map +1 -0
  365. package/dist/server/ai/providers/Together.d.ts +3 -0
  366. package/dist/server/ai/providers/Together.d.ts.map +1 -0
  367. package/dist/server/ai/providers/Together.js +99 -0
  368. package/dist/server/ai/providers/Together.js.map +1 -0
  369. package/dist/server/ai/providers/TogetherImage.d.ts +3 -0
  370. package/dist/server/ai/providers/TogetherImage.d.ts.map +1 -0
  371. package/dist/server/ai/providers/TogetherImage.js +24 -0
  372. package/dist/server/ai/providers/TogetherImage.js.map +1 -0
  373. package/dist/server/ai/providers/Wavespeed.d.ts +3 -0
  374. package/dist/server/ai/providers/Wavespeed.d.ts.map +1 -0
  375. package/dist/server/ai/providers/Wavespeed.js +53 -0
  376. package/dist/server/ai/providers/Wavespeed.js.map +1 -0
  377. package/dist/server/ai/registry.d.ts +10 -0
  378. package/dist/server/ai/registry.d.ts.map +1 -0
  379. package/dist/server/ai/registry.js +26 -0
  380. package/dist/server/ai/registry.js.map +1 -0
  381. package/dist/server/ai/types.d.ts +67 -0
  382. package/dist/server/ai/types.d.ts.map +1 -0
  383. package/dist/server/ai/types.js +17 -0
  384. package/dist/server/ai/types.js.map +1 -0
  385. package/dist/server/audio/STTStream.d.ts +12 -0
  386. package/dist/server/audio/STTStream.d.ts.map +1 -0
  387. package/dist/server/audio/STTStream.js +59 -0
  388. package/dist/server/audio/STTStream.js.map +1 -0
  389. package/dist/server/audio/TTSStream.d.ts +16 -0
  390. package/dist/server/audio/TTSStream.d.ts.map +1 -0
  391. package/dist/server/audio/TTSStream.js +151 -0
  392. package/dist/server/audio/TTSStream.js.map +1 -0
  393. package/dist/server/audio/index.d.ts +5 -0
  394. package/dist/server/audio/index.d.ts.map +1 -0
  395. package/dist/server/audio/index.js +14 -0
  396. package/dist/server/audio/index.js.map +1 -0
  397. package/dist/server/audio/resample.d.ts +7 -0
  398. package/dist/server/audio/resample.d.ts.map +1 -0
  399. package/dist/server/audio/resample.js +17 -0
  400. package/dist/server/audio/resample.js.map +1 -0
  401. package/dist/server/audio/stt/GroqWhisper.d.ts +3 -0
  402. package/dist/server/audio/stt/GroqWhisper.d.ts.map +1 -0
  403. package/dist/server/audio/stt/GroqWhisper.js +91 -0
  404. package/dist/server/audio/stt/GroqWhisper.js.map +1 -0
  405. package/dist/server/audio/stt/registry.d.ts +5 -0
  406. package/dist/server/audio/stt/registry.d.ts.map +1 -0
  407. package/dist/server/audio/stt/registry.js +11 -0
  408. package/dist/server/audio/stt/registry.js.map +1 -0
  409. package/dist/server/audio/stt/types.d.ts +25 -0
  410. package/dist/server/audio/stt/types.d.ts.map +1 -0
  411. package/dist/server/audio/stt/types.js +2 -0
  412. package/dist/server/audio/stt/types.js.map +1 -0
  413. package/dist/server/audio/stt/vad.d.ts +18 -0
  414. package/dist/server/audio/stt/vad.d.ts.map +1 -0
  415. package/dist/server/audio/stt/vad.js +90 -0
  416. package/dist/server/audio/stt/vad.js.map +1 -0
  417. package/dist/server/audio/tts/InWorld.d.ts +3 -0
  418. package/dist/server/audio/tts/InWorld.d.ts.map +1 -0
  419. package/dist/server/audio/tts/InWorld.js +147 -0
  420. package/dist/server/audio/tts/InWorld.js.map +1 -0
  421. package/dist/server/audio/tts/providers/Azure.d.ts +3 -0
  422. package/dist/server/audio/tts/providers/Azure.d.ts.map +1 -0
  423. package/dist/server/audio/tts/providers/Azure.js +31 -0
  424. package/dist/server/audio/tts/providers/Azure.js.map +1 -0
  425. package/dist/server/audio/tts/registry.d.ts +6 -0
  426. package/dist/server/audio/tts/registry.d.ts.map +1 -0
  427. package/dist/server/audio/tts/registry.js +12 -0
  428. package/dist/server/audio/tts/registry.js.map +1 -0
  429. package/dist/server/audio/tts/types.d.ts +20 -0
  430. package/dist/server/audio/tts/types.d.ts.map +1 -0
  431. package/dist/server/audio/tts/types.js +2 -0
  432. package/dist/server/audio/tts/types.js.map +1 -0
  433. package/dist/server/billing/BillingGateway.d.ts +40 -0
  434. package/dist/server/billing/BillingGateway.d.ts.map +1 -0
  435. package/dist/server/billing/BillingGateway.js +116 -0
  436. package/dist/server/billing/BillingGateway.js.map +1 -0
  437. package/dist/server/billing/BillingLedger.d.ts +67 -0
  438. package/dist/server/billing/BillingLedger.d.ts.map +1 -0
  439. package/dist/server/billing/BillingLedger.js +214 -0
  440. package/dist/server/billing/BillingLedger.js.map +1 -0
  441. package/dist/server/billing/CreditStore.d.ts +58 -0
  442. package/dist/server/billing/CreditStore.d.ts.map +1 -0
  443. package/dist/server/billing/CreditStore.js +112 -0
  444. package/dist/server/billing/CreditStore.js.map +1 -0
  445. package/dist/server/billing/LimitEnforcer.d.ts +73 -0
  446. package/dist/server/billing/LimitEnforcer.d.ts.map +1 -0
  447. package/dist/server/billing/LimitEnforcer.js +276 -0
  448. package/dist/server/billing/LimitEnforcer.js.map +1 -0
  449. package/dist/server/billing/UserLimitCache.d.ts +35 -0
  450. package/dist/server/billing/UserLimitCache.d.ts.map +1 -0
  451. package/dist/server/billing/UserLimitCache.js +91 -0
  452. package/dist/server/billing/UserLimitCache.js.map +1 -0
  453. package/dist/server/billing/index.d.ts +6 -0
  454. package/dist/server/billing/index.d.ts.map +1 -0
  455. package/dist/server/billing/index.js +4 -0
  456. package/dist/server/billing/index.js.map +1 -0
  457. package/dist/server/billing/types.d.ts +95 -0
  458. package/dist/server/billing/types.d.ts.map +1 -0
  459. package/dist/server/billing/types.js +19 -0
  460. package/dist/server/billing/types.js.map +1 -0
  461. package/dist/server/embeddings/EmbeddingClient.d.ts +8 -0
  462. package/dist/server/embeddings/EmbeddingClient.d.ts.map +1 -0
  463. package/dist/server/embeddings/EmbeddingClient.js +30 -0
  464. package/dist/server/embeddings/EmbeddingClient.js.map +1 -0
  465. package/dist/server/embeddings/index.d.ts +5 -0
  466. package/dist/server/embeddings/index.d.ts.map +1 -0
  467. package/dist/server/embeddings/index.js +6 -0
  468. package/dist/server/embeddings/index.js.map +1 -0
  469. package/dist/server/embeddings/providers/OpenAI.d.ts +3 -0
  470. package/dist/server/embeddings/providers/OpenAI.d.ts.map +1 -0
  471. package/dist/server/embeddings/providers/OpenAI.js +28 -0
  472. package/dist/server/embeddings/providers/OpenAI.js.map +1 -0
  473. package/dist/server/embeddings/registry.d.ts +7 -0
  474. package/dist/server/embeddings/registry.d.ts.map +1 -0
  475. package/dist/server/embeddings/registry.js +15 -0
  476. package/dist/server/embeddings/registry.js.map +1 -0
  477. package/dist/server/embeddings/types.d.ts +12 -0
  478. package/dist/server/embeddings/types.d.ts.map +1 -0
  479. package/dist/server/embeddings/types.js +2 -0
  480. package/dist/server/embeddings/types.js.map +1 -0
  481. package/dist/server/index.d.ts +59 -0
  482. package/dist/server/index.d.ts.map +1 -0
  483. package/dist/server/index.js +41 -0
  484. package/dist/server/index.js.map +1 -0
  485. package/dist/shared/Api.d.ts +40 -0
  486. package/dist/shared/Api.d.ts.map +1 -0
  487. package/dist/shared/Api.js +30 -0
  488. package/dist/shared/Api.js.map +1 -0
  489. package/dist/shared/Audio.d.ts +108 -0
  490. package/dist/shared/Audio.d.ts.map +1 -0
  491. package/dist/shared/Audio.js +3 -0
  492. package/dist/shared/Audio.js.map +1 -0
  493. package/dist/shared/DB.d.ts +339 -0
  494. package/dist/shared/DB.d.ts.map +1 -0
  495. package/dist/shared/DB.js +51 -0
  496. package/dist/shared/DB.js.map +1 -0
  497. package/dist/shared/Errors.d.ts +10 -0
  498. package/dist/shared/Errors.d.ts.map +1 -0
  499. package/dist/shared/Errors.js +19 -0
  500. package/dist/shared/Errors.js.map +1 -0
  501. package/dist/shared/FeedbackReport.d.ts +38 -0
  502. package/dist/shared/FeedbackReport.d.ts.map +1 -0
  503. package/dist/shared/FeedbackReport.js +14 -0
  504. package/dist/shared/FeedbackReport.js.map +1 -0
  505. package/dist/shared/Router.d.ts +28 -0
  506. package/dist/shared/Router.d.ts.map +1 -0
  507. package/dist/shared/Router.js +82 -0
  508. package/dist/shared/Router.js.map +1 -0
  509. package/dist/shared/Socket.d.ts +26 -0
  510. package/dist/shared/Socket.d.ts.map +1 -0
  511. package/dist/shared/Socket.js +2 -0
  512. package/dist/shared/Socket.js.map +1 -0
  513. package/dist/shared/index.d.ts +28 -0
  514. package/dist/shared/index.d.ts.map +1 -0
  515. package/dist/shared/index.js +61 -0
  516. package/dist/shared/index.js.map +1 -0
  517. package/dist/webrtc/index.d.ts +14 -0
  518. package/dist/webrtc/index.d.ts.map +1 -0
  519. package/dist/webrtc/index.js +24 -0
  520. package/dist/webrtc/index.js.map +1 -0
  521. package/package.json +97 -0
  522. package/templates/.claude/skills/assets.md +39 -0
  523. package/templates/.claude/skills/check-errors.md +35 -0
  524. package/templates/.claude/skills/check-feedback.md +23 -0
  525. package/templates/.claude/skills/check-perf.md +22 -0
  526. package/templates/.claude/skills/create-test-users.md +34 -0
  527. package/templates/.claude/skills/extend-api.md +37 -0
  528. package/templates/.claude/skills/fix-code.md +5 -0
  529. package/templates/.claude/skills/fix-errors.md +9 -0
  530. package/templates/.claude/skills/fix-feedback.md +8 -0
  531. package/templates/.claude/skills/fix-perf.md +8 -0
  532. package/templates/.claude/skills/uploads.md +38 -0
  533. package/templates/.claude/skills/use-ai.md +49 -0
  534. package/templates/.env.example +49 -0
  535. package/templates/.husky/pre-commit +2 -0
  536. package/templates/CLAUDE.md +199 -0
  537. package/templates/client/App.tsx +33 -0
  538. package/templates/client/index.html +14 -0
  539. package/templates/client/main.tsx +52 -0
  540. package/templates/client/pages/AuthDemoPage.tsx +85 -0
  541. package/templates/client/pages/HomePage.tsx +111 -0
  542. package/templates/client/pages/SearchPage.tsx +48 -0
  543. package/templates/client/pages/UserPage.tsx +33 -0
  544. package/templates/client/router.ts +4 -0
  545. package/templates/docker-compose.yml +50 -0
  546. package/templates/index.html +14 -0
  547. package/templates/package.json +56 -0
  548. package/templates/playwright.config.ts +21 -0
  549. package/templates/server/index.ts +24 -0
  550. package/templates/shared/api.ts +36 -0
  551. package/templates/shared/collections.ts +11 -0
  552. package/templates/shared/dbIndexes.ts +11 -0
  553. package/templates/shared/pages.ts +8 -0
  554. package/templates/vite.config.ts +17 -0
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env sh
2
+ npx lint-staged
@@ -0,0 +1,199 @@
1
+ # Project Structure & Conventions
2
+
3
+ Generated by `website-core`. See the full framework docs at [npm:website-core](https://www.npmjs.com/package/website-core).
4
+
5
+ ## Stack
6
+ - Server: Express + TypeScript (`server/index.ts`)
7
+ - Client: React + Vite (`client/main.tsx`)
8
+ - Shared: Types + API definitions (`shared/`)
9
+ - CLI: `web` commands from website-core (see package.json scripts)
10
+
11
+ ## Commands
12
+ - `yarn dev` — Start dev server (docker + server + vite + tsc watch + eslint watch)
13
+ - `yarn build` — Build for production
14
+ - `yarn deploy:single` — Deploy to single server
15
+ - `yarn deploy:multi` — Deploy to multiple servers
16
+ - `yarn db:migrate` — Run database migrations
17
+ - `yarn db:init` — (Re)create database indexes
18
+ - `yarn logs` — Show local dev logs
19
+ - `yarn error` — Show local error logs
20
+ - `yarn feedback` — Show user feedback from production
21
+
22
+ ## Adding a new API endpoint
23
+
24
+ 1. Add to `shared/api.ts` using `fn()` or `req()` with Zod schemas:
25
+ ```typescript
26
+ import { fn, req, z } from 'website-core/shared';
27
+
28
+ export const functions = defineFunctions({
29
+ myFunction: fn({
30
+ input: z.object({ name: z.string() }),
31
+ output: z.object({ greeting: z.string() }),
32
+ }),
33
+ });
34
+ ```
35
+ 2. Register handler in `server/index.ts`:
36
+ ```typescript
37
+ app.registerFunction('myFunction', async (ctx, input) => {
38
+ const { name } = input as { name: string };
39
+ return { greeting: `Hello, ${name}` };
40
+ });
41
+ ```
42
+ 3. Available in handlers: `ctx.db`, `ctx.storage`, `ctx.rateLimit`, `ctx.userId`, `ctx.user`
43
+
44
+ ## Adding a new database collection
45
+
46
+ 1. Add to `shared/collections.ts`:
47
+ ```typescript
48
+ export const collections = defineCollections({
49
+ myCollection: { cache: false, trackable: true, public: true, parent: null },
50
+ });
51
+ ```
52
+ 2. Add TypeScript interface to `shared/types.ts` (create if needed)
53
+ 3. Add indexes to `shared/dbIndexes.ts` (create if needed)
54
+ 4. Run `yarn db:init`
55
+
56
+ ## Changing existing data (DB migrations)
57
+
58
+ NEVER just change a TypeScript type for existing data — write a migration:
59
+ 1. Create `server/migrations/NNN-description.ts`:
60
+ ```typescript
61
+ export const name = 'NNN-description';
62
+ export async function up(db: Db) {
63
+ await db.collection('myCollection').updateMany({}, { $set: { newField: 'default' } });
64
+ }
65
+ ```
66
+ 2. Run `yarn db:migrate`
67
+
68
+ ## Static assets
69
+ - Build-time files (favicon, fonts, OG images): `client/public/`
70
+ - User-uploaded files: `ctx.storage.getUploadUrl()` then `ctx.storage.moveToPublic()`
71
+ - Never hardcode `/asset/...` paths — use the buildId from `shared/Build.ts`
72
+
73
+ ## Environment variables
74
+ - Adding a new one: add to `.env` AND `.env.example` with a comment
75
+ - Never read `process.env` in client code (use `import.meta.env.VITE_*`)
76
+ - Never commit `.env`
77
+
78
+ ## Auth
79
+ - Default: ugly.bot OAuth popup — works out of the box, no config needed
80
+ - `ctx.userId`: always a non-null string in authenticated handlers
81
+ - Public handlers: use `defineRequests()` for unauthenticated reads
82
+
83
+ ## Showing Popups / Modals
84
+
85
+ **Always use `useRouter().openPopup()` — never build custom fixed overlays.**
86
+
87
+ The `RouterProvider` (in `client/main.tsx`) manages a popup layer with proper z-index, backdrop, and animation. Use it for all popups, modals, and sheets.
88
+
89
+ ```tsx
90
+ import { useRouter } from '@/router'
91
+
92
+ function MyComponent() {
93
+ const { openPopup } = useRouter()
94
+
95
+ function handleOpen() {
96
+ openPopup(<MyContent />, { mode: 'transient' })
97
+ // mode: 'block' — dark backdrop (40%), clicking it does NOT dismiss
98
+ // mode: 'transient' — light backdrop (20%), clicking it dismisses
99
+ // mode: 'contextMenu'— same as transient, for menus/pickers
100
+ // slideFrom: 'bottom' | 'top' | 'left' | 'right' | 'none'
101
+ }
102
+ }
103
+ ```
104
+
105
+ To dismiss programmatically:
106
+ ```tsx
107
+ const handle = openPopup(<MyContent />, { mode: 'block' })
108
+ handle.hide()
109
+ ```
110
+
111
+ For simple dialogs, `Modal` from `website-core/client` wraps content with backdrop + Escape key handling:
112
+ ```tsx
113
+ import { Modal } from 'website-core/client'
114
+ {open && <Modal title="My Dialog" onClose={() => setOpen(false)}><p>Content</p></Modal>}
115
+ ```
116
+
117
+ **In tests:** mock `../../router` to stub `useRouter`:
118
+ ```tsx
119
+ const mockOpenPopup = vi.fn().mockReturnValue({ id: '1', hide: vi.fn() })
120
+ vi.mock('../../router', () => ({ useRouter: () => ({ openPopup: mockOpenPopup }) }))
121
+ ```
122
+
123
+ ## Common mistakes to avoid
124
+ - Do NOT use in-memory Maps for per-user state — use Redis or MongoDB (multi-server safe)
125
+ - Do NOT change collection field types without a migration
126
+ - Do NOT make NATS subscriptions without storing and calling the returned `unsub()` function
127
+ - Do NOT skip `ctx.rateLimit.check()` before expensive operations (AI, storage, email)
128
+ - Do NOT add `any` types — the TypeScript config enforces `noExplicitAny`
129
+
130
+ ## Feedback System
131
+
132
+ The feedback button is always present at `[data-id="feedback-button"]` (bottom-right corner).
133
+ Bots can trigger it by calling `document.querySelector('[data-id="feedback-button"]').click()`.
134
+ Users see their feedback history at `GET /my_feedback` (returns markdown, requires auth cookie).
135
+ The maintain bot resolves feedback via the `resolveFeedback` socket function (requires MAINTAIN_BOT_USER_ID).
136
+
137
+ ## AI Providers
138
+
139
+ Use `createTextGen(userId, { provider })` or `createImageGen(userId, { provider })`.
140
+ All providers are optional — only configured keys are active.
141
+
142
+ ### Text Generation
143
+
144
+ | Provider | `provider` value | JSON | Tools | Vision | Best for |
145
+ |---|---|---|---|---|---|
146
+ | Together AI (Llama-4-Scout) | `'together'` | ✅ | ✅ | ✅ | Fast, cheap, 10M context |
147
+ | Anthropic (claude-sonnet-4-6) | `'claude'` | ✅ | ✅ | ✅ | Complex reasoning, code |
148
+ | OpenAI (gpt-4o) | `'openai'` | ✅ | ✅ | ✅ | General purpose |
149
+ | Google (gemini-2.0-flash) | `'google'` | ✅ | ✅ | ✅ | Very long context (1M) |
150
+ | Groq (llama-3.3-70b) | `'groq'` | ✅ | ✅ | ❌ | Ultra-fast, no vision |
151
+
152
+ Use `provider: 'auto'` (default) to let the system pick based on requirements.
153
+
154
+ ### JSON Generation (type-safe)
155
+
156
+ ```typescript
157
+ import { z } from 'zod'
158
+ const schema = z.object({ title: z.string(), tags: z.array(z.string()) })
159
+ const result = await textGen.generateJson(schema, messages)
160
+ // result typed as { title: string, tags: string[] }
161
+ // Retries up to 3 times on schema validation failure
162
+ ```
163
+
164
+ ### Tool Calling
165
+
166
+ ```typescript
167
+ const result = await textGen.generateWithTools(messages, {
168
+ myTool: {
169
+ description: 'What the tool does',
170
+ input: z.object({ param: z.string() }),
171
+ handler: async ({ param }) => ({ result: 'value' })
172
+ }
173
+ })
174
+ // Tool loop runs automatically until model produces final text (max 5 rounds)
175
+ ```
176
+
177
+ ### Image Generation
178
+
179
+ | Provider | `provider` value | Best for |
180
+ |---|---|---|
181
+ | Together AI (FLUX schnell) | `'together'` | Free tier, fast |
182
+ | FAL (FLUX pro) | `'fal'` | High quality |
183
+ | Google (Imagen 3) | `'google'` | Photorealistic |
184
+
185
+ ### Adding a Custom Provider
186
+
187
+ ```typescript
188
+ // In server/index.ts, before createApp():
189
+ import { registerTextGenProvider } from 'website-core'
190
+
191
+ registerTextGenProvider({
192
+ name: 'mistral',
193
+ apiKeyEnv: 'MISTRAL_API_KEY',
194
+ capabilities: { json: true, tools: true, vision: false, maxContextTokens: 32_000 },
195
+ costPerMillionInputTokens: 0.20,
196
+ costPerMillionOutputTokens: 0.60,
197
+ generate: (messages, opts) => { /* your implementation */ },
198
+ })
199
+ ```
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ import type { AppSocket } from 'website-core/client';
3
+ import { FeedbackButton } from 'website-core/client';
4
+ import type { AppRegistry } from '../shared/api.js';
5
+ import { AuthDemoPage } from './pages/AuthDemoPage.js';
6
+ import { HomePage } from './pages/HomePage.js';
7
+ import { SearchPage } from './pages/SearchPage.js';
8
+ import { UserPage } from './pages/UserPage.js';
9
+
10
+ interface AppProps {
11
+ socket: AppSocket<AppRegistry> | null;
12
+ }
13
+
14
+ function Router(): React.ReactElement {
15
+ const path = window.location.pathname;
16
+
17
+ if (path.startsWith('/auth-demo')) return <AuthDemoPage />;
18
+ if (path.startsWith('/user/')) {
19
+ const userId = path.split('/')[2] ?? '';
20
+ return <UserPage userId={userId} />;
21
+ }
22
+ if (path.startsWith('/search')) return <SearchPage />;
23
+ return <HomePage />;
24
+ }
25
+
26
+ export default function App({ socket }: AppProps): React.ReactElement {
27
+ return (
28
+ <>
29
+ <Router />
30
+ <FeedbackButton socket={socket} />
31
+ </>
32
+ );
33
+ }
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/x-icon" href="/favicon.ico" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>App</title>
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ </head>
10
+ <body>
11
+ <div id="root"></div>
12
+ <script type="module" src="/client/main.tsx"></script>
13
+ </body>
14
+ </html>
@@ -0,0 +1,52 @@
1
+ import { createRoot } from 'react-dom/client';
2
+ import { AppProvider, createSocket, LoginPopup } from 'website-core/client';
3
+ import { functions, requests } from '../shared/api.js';
4
+ import App from './App.js';
5
+ import { RouterProvider } from './router.js';
6
+
7
+ const root = createRoot(document.getElementById('root')!);
8
+
9
+ const loginPopup = (
10
+ <LoginPopup
11
+ uglyBotUrl={import.meta.env.VITE_UGLY_BOT_URL ?? 'https://ugly.bot'}
12
+ onSuccess={() => {
13
+ window.location.reload();
14
+ }}
15
+ />
16
+ );
17
+
18
+ // Token is injected server-side from the auth_token cookie — no localStorage needed
19
+ const token = (window as unknown as { __AUTH_TOKEN__?: string }).__AUTH_TOKEN__;
20
+
21
+ if (!token) {
22
+ root.render(
23
+ <RouterProvider
24
+ fallback={<div>404 — Page not found</div>}
25
+ loginFallback={loginPopup}
26
+ isAuthenticated={() => false}
27
+ >
28
+ <App socket={null} />
29
+ </RouterProvider>,
30
+ );
31
+ } else {
32
+ const userId = JSON.parse(atob(token.split('.')[1]!)).sub as string;
33
+ const socket = createSocket({ functions, requests, url: '/rpc' });
34
+ socket
35
+ .connect(token)
36
+ .then((user) => {
37
+ root.render(
38
+ <RouterProvider
39
+ fallback={<div>404 — Page not found</div>}
40
+ loginFallback={loginPopup}
41
+ isAuthenticated={() => true}
42
+ >
43
+ <AppProvider socket={socket} userId={userId} user={user}>
44
+ <App socket={socket} />
45
+ </AppProvider>
46
+ </RouterProvider>,
47
+ );
48
+ })
49
+ .catch(() => {
50
+ window.location.reload();
51
+ });
52
+ }
@@ -0,0 +1,85 @@
1
+ import React from 'react';
2
+ import { Button, Card, PageLayout, Text, useApp } from 'website-core/client';
3
+
4
+ function AuthDemoAuthenticated(): React.ReactElement {
5
+ const app = useApp();
6
+
7
+ async function handleLogout(): Promise<void> {
8
+ await fetch('/auth/logout', { method: 'POST' });
9
+ window.location.reload();
10
+ }
11
+
12
+ return (
13
+ <PageLayout
14
+ header={
15
+ <div className="px-6 py-4">
16
+ <a href="/" className="text-blue-600">
17
+ ← Home
18
+ </a>
19
+ </div>
20
+ }
21
+ >
22
+ <div className="max-w-md mx-auto">
23
+ <Text size="xl" weight="bold">
24
+ Auth Demo
25
+ </Text>
26
+ <Card className="mt-4">
27
+ <Text weight="bold">Logged In</Text>
28
+ <pre className="mt-2 text-sm bg-gray-100 dark:bg-gray-900 p-3 rounded overflow-auto">
29
+ {JSON.stringify(
30
+ {
31
+ userId: app.userId,
32
+ email: app.user.email,
33
+ phone: app.user.phone,
34
+ },
35
+ null,
36
+ 2,
37
+ )}
38
+ </pre>
39
+ <Button variant="secondary" onClick={handleLogout} className="mt-4">
40
+ Logout
41
+ </Button>
42
+ </Card>
43
+ </div>
44
+ </PageLayout>
45
+ );
46
+ }
47
+
48
+ function AuthDemoUnauthenticated(): React.ReactElement {
49
+ function handleLogin(): void {
50
+ // The RouterProvider's loginFallback will show the login popup for auth-required routes.
51
+ // For a manual trigger, redirect to initiate the OAuth flow.
52
+ window.location.href = '/?login=1';
53
+ }
54
+
55
+ return (
56
+ <PageLayout
57
+ header={
58
+ <div className="px-6 py-4">
59
+ <a href="/" className="text-blue-600">
60
+ ← Home
61
+ </a>
62
+ </div>
63
+ }
64
+ >
65
+ <div className="max-w-md mx-auto">
66
+ <Text size="xl" weight="bold">
67
+ Auth Demo
68
+ </Text>
69
+ <Card className="mt-4">
70
+ <Text>You are not logged in.</Text>
71
+ <Button onClick={handleLogin} className="mt-4">
72
+ Login with ugly.bot
73
+ </Button>
74
+ </Card>
75
+ </div>
76
+ </PageLayout>
77
+ );
78
+ }
79
+
80
+ export function AuthDemoPage(): React.ReactElement {
81
+ const isLoggedIn = !!(window as unknown as { __AUTH_TOKEN__?: string })
82
+ .__AUTH_TOKEN__;
83
+ if (isLoggedIn) return <AuthDemoAuthenticated />;
84
+ return <AuthDemoUnauthenticated />;
85
+ }
@@ -0,0 +1,111 @@
1
+ import React from 'react';
2
+ import { Button, Card, PageLayout, Text, useApp } from 'website-core/client';
3
+
4
+ function HomePageAuthenticated(): React.ReactElement {
5
+ const app = useApp();
6
+
7
+ async function handleLogout(): Promise<void> {
8
+ await fetch('/auth/logout', { method: 'POST' });
9
+ window.location.reload();
10
+ }
11
+
12
+ return (
13
+ <PageLayout
14
+ header={
15
+ <div className="flex items-center justify-between px-6 py-4">
16
+ <Text size="lg" weight="bold">
17
+ My App
18
+ </Text>
19
+ <Button variant="secondary" onClick={handleLogout}>
20
+ Logout
21
+ </Button>
22
+ </div>
23
+ }
24
+ >
25
+ <HomePageBody userId={app.userId} />
26
+ </PageLayout>
27
+ );
28
+ }
29
+
30
+ function HomePageUnauthenticated(): React.ReactElement {
31
+ function handleLogin(): void {
32
+ // Trigger login — navigate to /auth-demo or show login popup via RouterProvider
33
+ window.location.href = '/auth-demo';
34
+ }
35
+
36
+ return (
37
+ <PageLayout
38
+ header={
39
+ <div className="flex items-center justify-between px-6 py-4">
40
+ <Text size="lg" weight="bold">
41
+ My App
42
+ </Text>
43
+ <Button variant="primary" onClick={handleLogin}>
44
+ Login
45
+ </Button>
46
+ </div>
47
+ }
48
+ >
49
+ <HomePageBody userId={null} />
50
+ </PageLayout>
51
+ );
52
+ }
53
+
54
+ function HomePageBody({
55
+ userId,
56
+ }: {
57
+ userId: string | null;
58
+ }): React.ReactElement {
59
+ return (
60
+ <div className="max-w-2xl mx-auto">
61
+ <Card>
62
+ <Text size="xl" weight="bold">
63
+ Welcome
64
+ </Text>
65
+ {userId ? (
66
+ <Text className="mt-2 text-gray-600 dark:text-gray-400">
67
+ Logged in as: {userId}
68
+ </Text>
69
+ ) : (
70
+ <Text className="mt-2 text-gray-600 dark:text-gray-400">
71
+ This app was built with website-core.
72
+ </Text>
73
+ )}
74
+ </Card>
75
+
76
+ <div className="mt-6 grid gap-4">
77
+ <a href="/auth-demo" className="block">
78
+ <Card className="hover:shadow-md transition-shadow cursor-pointer">
79
+ <Text weight="medium">Auth Demo →</Text>
80
+ <Text size="sm" className="text-gray-500 mt-1">
81
+ See login/logout and user info
82
+ </Text>
83
+ </Card>
84
+ </a>
85
+ <a href="/user/example-user-id" className="block">
86
+ <Card className="hover:shadow-md transition-shadow cursor-pointer">
87
+ <Text weight="medium">Path Params Demo →</Text>
88
+ <Text size="sm" className="text-gray-500 mt-1">
89
+ URL: /user/:userId
90
+ </Text>
91
+ </Card>
92
+ </a>
93
+ <a href="/search?q=hello" className="block">
94
+ <Card className="hover:shadow-md transition-shadow cursor-pointer">
95
+ <Text weight="medium">Query Params Demo →</Text>
96
+ <Text size="sm" className="text-gray-500 mt-1">
97
+ URL: /search?q=...
98
+ </Text>
99
+ </Card>
100
+ </a>
101
+ </div>
102
+ </div>
103
+ );
104
+ }
105
+
106
+ export function HomePage(): React.ReactElement {
107
+ const isLoggedIn = !!(window as unknown as { __AUTH_TOKEN__?: string })
108
+ .__AUTH_TOKEN__;
109
+ if (isLoggedIn) return <HomePageAuthenticated />;
110
+ return <HomePageUnauthenticated />;
111
+ }
@@ -0,0 +1,48 @@
1
+ import React, { useState } from 'react';
2
+ import { Card, Input, PageLayout, Text } from 'website-core/client';
3
+
4
+ export function SearchPage(): React.ReactElement {
5
+ const initialQ = new URLSearchParams(window.location.search).get('q') ?? '';
6
+ const [query, setQuery] = useState(initialQ);
7
+
8
+ function handleQueryChange(v: string): void {
9
+ setQuery(v);
10
+ const url = new URL(window.location.href);
11
+ url.searchParams.set('q', v);
12
+ window.history.replaceState(null, '', url.toString());
13
+ }
14
+
15
+ return (
16
+ <PageLayout
17
+ header={
18
+ <div className="px-6 py-4">
19
+ <a href="/" className="text-blue-600">
20
+ ← Home
21
+ </a>
22
+ </div>
23
+ }
24
+ >
25
+ <div className="max-w-md mx-auto">
26
+ <Text size="xl" weight="bold">
27
+ Search
28
+ </Text>
29
+ <div className="mt-4">
30
+ <Input
31
+ label="Search query"
32
+ value={query}
33
+ onChange={handleQueryChange}
34
+ placeholder="Search..."
35
+ />
36
+ </div>
37
+ <Card className="mt-4">
38
+ <Text size="sm" className="text-gray-500">
39
+ Query parameter:
40
+ </Text>
41
+ <Text weight="bold" className="font-mono mt-1">
42
+ ?q={query}
43
+ </Text>
44
+ </Card>
45
+ </div>
46
+ </PageLayout>
47
+ );
48
+ }
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ import { Card, PageLayout, Text } from 'website-core/client';
3
+
4
+ export function UserPage({ userId }: { userId: string }): React.ReactElement {
5
+ return (
6
+ <PageLayout
7
+ header={
8
+ <div className="px-6 py-4">
9
+ <a href="/" className="text-blue-600">
10
+ ← Home
11
+ </a>
12
+ </div>
13
+ }
14
+ >
15
+ <div className="max-w-md mx-auto">
16
+ <Text size="xl" weight="bold">
17
+ User Profile
18
+ </Text>
19
+ <Card className="mt-4">
20
+ <Text size="sm" className="text-gray-500">
21
+ Path parameter:
22
+ </Text>
23
+ <Text weight="bold" className="font-mono mt-1">
24
+ /user/{userId}
25
+ </Text>
26
+ <Text size="sm" className="text-gray-500 mt-3">
27
+ userId = <code>{userId}</code>
28
+ </Text>
29
+ </Card>
30
+ </div>
31
+ </PageLayout>
32
+ );
33
+ }
@@ -0,0 +1,4 @@
1
+ import { createRouter } from 'website-core/client';
2
+ import { pages } from '../shared/pages.js';
3
+
4
+ export const { RouterProvider, useRouter } = createRouter({ pages });
@@ -0,0 +1,50 @@
1
+ services:
2
+ mongodb:
3
+ image: mongodb/mongodb-atlas-local:8.0
4
+ restart: unless-stopped
5
+ ports:
6
+ - '${PORT_MONGO:-3003}:27017'
7
+ volumes:
8
+ - mongodb_data:/data/db
9
+
10
+ minio:
11
+ image: minio/minio:RELEASE.2024-11-07T00-52-20Z
12
+ ports:
13
+ - '${PORT_MINIO:-3006}:9000'
14
+ - '${PORT_MINIO_CONSOLE:-3007}:9001'
15
+ command: server /data --console-address ":9001"
16
+ environment:
17
+ MINIO_ROOT_USER: minioadmin
18
+ MINIO_ROOT_PASSWORD: minioadmin
19
+ volumes:
20
+ - minio_data:/data
21
+
22
+ minio-init:
23
+ image: minio/mc:RELEASE.2024-11-07T00-37-53Z
24
+ depends_on: [minio]
25
+ restart: 'no'
26
+ entrypoint: >
27
+ /bin/sh -c "
28
+ until mc alias set local http://minio:9000 minioadmin minioadmin; do sleep 1; done;
29
+ mc mb --ignore-existing local/public;
30
+ mc mb --ignore-existing local/temp;
31
+ mc anonymous set download local/public;
32
+ mc anonymous set download local/temp;
33
+ exit 0;"
34
+
35
+ nats:
36
+ image: nats:2-alpine
37
+ command: ['-js']
38
+ ports:
39
+ - '${PORT_NATS:-3005}:4222'
40
+ restart: unless-stopped
41
+
42
+ redis:
43
+ image: redis:7-alpine
44
+ ports:
45
+ - '${PORT_REDIS:-3004}:6379'
46
+ restart: unless-stopped
47
+
48
+ volumes:
49
+ mongodb_data:
50
+ minio_data:
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/x-icon" href="/favicon.ico" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>App</title>
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ </head>
10
+ <body>
11
+ <div id="root"></div>
12
+ <script type="module" src="/client/main.tsx"></script>
13
+ </body>
14
+ </html>