@stone-js/starters 0.8.3

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 (352) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +101 -0
  3. package/basic-react-declarative/LICENSE +21 -0
  4. package/basic-react-declarative/README.md +39 -0
  5. package/basic-react-declarative/app/Application.tsx +89 -0
  6. package/basic-react-declarative/assets/css/index.css +26 -0
  7. package/basic-react-declarative/package.json +39 -0
  8. package/basic-react-declarative/public/logo.png +0 -0
  9. package/basic-react-declarative/tests/Application.spec.ts +96 -0
  10. package/basic-react-declarative/tests/__snapshots__/Application.spec.ts.snap +3 -0
  11. package/basic-react-declarative/tsconfig.json +33 -0
  12. package/basic-react-declarative/vitest.config.ts +24 -0
  13. package/basic-react-imperative/LICENSE +21 -0
  14. package/basic-react-imperative/README.md +39 -0
  15. package/basic-react-imperative/app/Application.tsx +89 -0
  16. package/basic-react-imperative/assets/css/index.css +26 -0
  17. package/basic-react-imperative/package.json +39 -0
  18. package/basic-react-imperative/public/logo.png +0 -0
  19. package/basic-react-imperative/tests/Application.spec.ts +80 -0
  20. package/basic-react-imperative/tests/__snapshots__/Application.spec.ts.snap +3 -0
  21. package/basic-react-imperative/tsconfig.json +33 -0
  22. package/basic-react-imperative/vitest.config.ts +24 -0
  23. package/basic-service-declarative/LICENSE +21 -0
  24. package/basic-service-declarative/README.md +39 -0
  25. package/basic-service-declarative/app/Application.ts +56 -0
  26. package/basic-service-declarative/package.json +34 -0
  27. package/basic-service-declarative/tests/Application.spec.ts +60 -0
  28. package/basic-service-declarative/tsconfig.json +25 -0
  29. package/basic-service-declarative/vitest.config.ts +24 -0
  30. package/basic-service-imperative/LICENSE +21 -0
  31. package/basic-service-imperative/README.md +39 -0
  32. package/basic-service-imperative/app/Application.ts +60 -0
  33. package/basic-service-imperative/package.json +34 -0
  34. package/basic-service-imperative/tests/Application.spec.ts +52 -0
  35. package/basic-service-imperative/tsconfig.json +25 -0
  36. package/basic-service-imperative/vitest.config.ts +24 -0
  37. package/continuum-showcase/README.md +44 -0
  38. package/continuum-showcase/app/env.d.ts +34 -0
  39. package/continuum-showcase/app/layouts/MainLayout.tsx +20 -0
  40. package/continuum-showcase/app/pages/BlogPostPage.tsx +62 -0
  41. package/continuum-showcase/app/pages/HomePage.tsx +58 -0
  42. package/continuum-showcase/package.json +25 -0
  43. package/continuum-showcase/stone.config.mjs +20 -0
  44. package/full-react-declarative/.env.example +1 -0
  45. package/full-react-declarative/.env.public.example +1 -0
  46. package/full-react-declarative/LICENSE +21 -0
  47. package/full-react-declarative/README.md +39 -0
  48. package/full-react-declarative/app/Application.ts +85 -0
  49. package/full-react-declarative/app/clients/AxiosClient.ts +136 -0
  50. package/full-react-declarative/app/clients/CommentClient.ts +61 -0
  51. package/full-react-declarative/app/clients/PostClient.ts +90 -0
  52. package/full-react-declarative/app/clients/SecurityClient.ts +66 -0
  53. package/full-react-declarative/app/clients/UserClient.ts +97 -0
  54. package/full-react-declarative/app/components/ChangePasswordForm/ChangePasswordForm.tsx +50 -0
  55. package/full-react-declarative/app/components/CommentForm/CommentForm.tsx +37 -0
  56. package/full-react-declarative/app/components/CommentItem/CommentItem.tsx +42 -0
  57. package/full-react-declarative/app/components/CommentWidget/CommentWidget.tsx +95 -0
  58. package/full-react-declarative/app/components/LoginForm/LoginForm.css +0 -0
  59. package/full-react-declarative/app/components/LoginForm/LoginForm.tsx +71 -0
  60. package/full-react-declarative/app/components/PostDetails/PostDetails.tsx +44 -0
  61. package/full-react-declarative/app/components/PostForm/PostForm.css +0 -0
  62. package/full-react-declarative/app/components/PostForm/PostForm.tsx +47 -0
  63. package/full-react-declarative/app/components/PostItem/PostItem.css +0 -0
  64. package/full-react-declarative/app/components/PostItem/PostItem.tsx +34 -0
  65. package/full-react-declarative/app/components/RegisterForm/RegisterForm.tsx +110 -0
  66. package/full-react-declarative/app/components/UserForm/UserForm.tsx +47 -0
  67. package/full-react-declarative/app/configurations/AppConfiguration.ts +17 -0
  68. package/full-react-declarative/app/error-pages/DefaultErrorPage/DefaultErrorPage.css +0 -0
  69. package/full-react-declarative/app/error-pages/DefaultErrorPage/DefaultErrorPage.tsx +52 -0
  70. package/full-react-declarative/app/error-pages/ForbiddenErrorPage/ForbiddenErrorPage.css +0 -0
  71. package/full-react-declarative/app/error-pages/ForbiddenErrorPage/ForbiddenErrorPage.tsx +53 -0
  72. package/full-react-declarative/app/error-pages/NotFoundErrorPage/NotFoundErrorPage.css +0 -0
  73. package/full-react-declarative/app/error-pages/NotFoundErrorPage/NotFoundErrorPage.tsx +54 -0
  74. package/full-react-declarative/app/error-pages/UnauthorizedErrorPage/UnauthorizedErrorPage.css +0 -0
  75. package/full-react-declarative/app/error-pages/UnauthorizedErrorPage/UnauthorizedErrorPage.tsx +53 -0
  76. package/full-react-declarative/app/errors/ForbiddenError.ts +11 -0
  77. package/full-react-declarative/app/errors/PostNotFoundError.ts +11 -0
  78. package/full-react-declarative/app/errors/UnauthorizedError.ts +11 -0
  79. package/full-react-declarative/app/errors/UserNotFoundError.ts +11 -0
  80. package/full-react-declarative/app/events/UserEvent.ts +18 -0
  81. package/full-react-declarative/app/layout/AppLayout/AppLayout.css +20 -0
  82. package/full-react-declarative/app/layout/AppLayout/AppLayout.tsx +101 -0
  83. package/full-react-declarative/app/layout/ErrorLayout/ErrorLayout.css +0 -0
  84. package/full-react-declarative/app/layout/ErrorLayout/ErrorLayout.tsx +41 -0
  85. package/full-react-declarative/app/layout/SecurityLayout/SecurityLayout.css +0 -0
  86. package/full-react-declarative/app/layout/SecurityLayout/SecurityLayout.tsx +39 -0
  87. package/full-react-declarative/app/middleware/AuthMiddleware.ts +85 -0
  88. package/full-react-declarative/app/models/Comment.ts +31 -0
  89. package/full-react-declarative/app/models/Post.ts +22 -0
  90. package/full-react-declarative/app/models/User.ts +62 -0
  91. package/full-react-declarative/app/pages/home/HomePage.tsx +44 -0
  92. package/full-react-declarative/app/pages/login/LoginPage.css +0 -0
  93. package/full-react-declarative/app/pages/login/LoginPage.tsx +73 -0
  94. package/full-react-declarative/app/pages/posts/CreatePostPage/CreatePostPage.css +0 -0
  95. package/full-react-declarative/app/pages/posts/CreatePostPage/CreatePostPage.tsx +67 -0
  96. package/full-react-declarative/app/pages/posts/PostPage/PostPage.tsx +60 -0
  97. package/full-react-declarative/app/pages/posts/ShowPostPage/ShowPostPage.tsx +83 -0
  98. package/full-react-declarative/app/pages/posts/UpdatePostPage/UpdatePostPage.tsx +77 -0
  99. package/full-react-declarative/app/pages/register/RegisterPage.tsx +68 -0
  100. package/full-react-declarative/app/pages/users/CreateUserPage.tsx +48 -0
  101. package/full-react-declarative/app/pages/users/ShowUserPage.tsx +62 -0
  102. package/full-react-declarative/app/pages/users/UpdateUserPage.tsx +57 -0
  103. package/full-react-declarative/app/pages/users/UserPage.tsx +57 -0
  104. package/full-react-declarative/app/providers/AppServiceProvider.ts +43 -0
  105. package/full-react-declarative/app/services/CommentService.ts +59 -0
  106. package/full-react-declarative/app/services/PostService.ts +108 -0
  107. package/full-react-declarative/app/services/SecurityService.ts +80 -0
  108. package/full-react-declarative/app/services/TokenService.ts +116 -0
  109. package/full-react-declarative/app/services/UserService.ts +126 -0
  110. package/full-react-declarative/app/utils.ts +17 -0
  111. package/full-react-declarative/assets/css/index.css +301 -0
  112. package/full-react-declarative/assets/img/logo.png +0 -0
  113. package/full-react-declarative/package.json +46 -0
  114. package/full-react-declarative/public/logo.png +0 -0
  115. package/full-react-declarative/public/vite.svg +1 -0
  116. package/full-react-declarative/stone.config.mjs +12 -0
  117. package/full-react-declarative/tsconfig.json +29 -0
  118. package/full-react-declarative/vitest.config.ts +24 -0
  119. package/full-react-imperative/.env.example +1 -0
  120. package/full-react-imperative/.env.public.example +1 -0
  121. package/full-react-imperative/LICENSE +21 -0
  122. package/full-react-imperative/README.md +39 -0
  123. package/full-react-imperative/app/Application.ts +79 -0
  124. package/full-react-imperative/app/clients/AxiosClient.ts +124 -0
  125. package/full-react-imperative/app/clients/CommentClient.ts +57 -0
  126. package/full-react-imperative/app/clients/PostClient.ts +86 -0
  127. package/full-react-imperative/app/clients/SecurityClient.ts +60 -0
  128. package/full-react-imperative/app/clients/UserClient.ts +93 -0
  129. package/full-react-imperative/app/clients/contracts/IAxiosClient.ts +97 -0
  130. package/full-react-imperative/app/clients/contracts/ICommentClient.ts +31 -0
  131. package/full-react-imperative/app/clients/contracts/IPostClient.ts +55 -0
  132. package/full-react-imperative/app/clients/contracts/ISecurityClient.ts +33 -0
  133. package/full-react-imperative/app/clients/contracts/IUserClient.ts +61 -0
  134. package/full-react-imperative/app/components/ChangePasswordForm/ChangePasswordForm.tsx +50 -0
  135. package/full-react-imperative/app/components/CommentForm/CommentForm.css +35 -0
  136. package/full-react-imperative/app/components/CommentForm/CommentForm.tsx +45 -0
  137. package/full-react-imperative/app/components/CommentItem/CommentItem.css +74 -0
  138. package/full-react-imperative/app/components/CommentItem/CommentItem.tsx +62 -0
  139. package/full-react-imperative/app/components/CommentWidget/CommentWidget.css +25 -0
  140. package/full-react-imperative/app/components/CommentWidget/CommentWidget.tsx +119 -0
  141. package/full-react-imperative/app/components/Dropdown/Dropdown.css +52 -0
  142. package/full-react-imperative/app/components/Dropdown/Dropdown.tsx +40 -0
  143. package/full-react-imperative/app/components/LayoutHeader/LayoutHeader.css +62 -0
  144. package/full-react-imperative/app/components/LayoutHeader/LayoutHeader.tsx +61 -0
  145. package/full-react-imperative/app/components/LayoutLeftMenu/LayoutLeftMenu.css +25 -0
  146. package/full-react-imperative/app/components/LayoutLeftMenu/LayoutLeftMenu.tsx +32 -0
  147. package/full-react-imperative/app/components/LoginForm/LoginForm.css +0 -0
  148. package/full-react-imperative/app/components/LoginForm/LoginForm.tsx +71 -0
  149. package/full-react-imperative/app/components/NotificationBadge/NotificationBadge.css +41 -0
  150. package/full-react-imperative/app/components/NotificationBadge/NotificationBadge.tsx +63 -0
  151. package/full-react-imperative/app/components/PostCard/PostCard.css +129 -0
  152. package/full-react-imperative/app/components/PostCard/PostCard.tsx +65 -0
  153. package/full-react-imperative/app/components/PostForm/PostForm.css +92 -0
  154. package/full-react-imperative/app/components/PostForm/PostForm.tsx +76 -0
  155. package/full-react-imperative/app/components/PostSkeleton/PostSkeleton.css +65 -0
  156. package/full-react-imperative/app/components/PostSkeleton/PostSkeleton.tsx +25 -0
  157. package/full-react-imperative/app/components/PostWidget/PostWidget.tsx +95 -0
  158. package/full-react-imperative/app/components/ProfileForm/ProfileForm.css +84 -0
  159. package/full-react-imperative/app/components/ProfileForm/ProfileForm.tsx +79 -0
  160. package/full-react-imperative/app/components/RegisterForm/RegisterForm.tsx +110 -0
  161. package/full-react-imperative/app/components/RightAsidePanel/RightAsidePanel.css +32 -0
  162. package/full-react-imperative/app/components/RightAsidePanel/RightAsidePanel.tsx +62 -0
  163. package/full-react-imperative/app/components/SettingsForm/SettingsForm.css +126 -0
  164. package/full-react-imperative/app/components/SettingsForm/SettingsForm.tsx +86 -0
  165. package/full-react-imperative/app/components/UserAvatar/UserAvatar.css +18 -0
  166. package/full-react-imperative/app/components/UserAvatar/UserAvatar.tsx +60 -0
  167. package/full-react-imperative/app/components/UserBadge/UserBadge.css +33 -0
  168. package/full-react-imperative/app/components/UserBadge/UserBadge.tsx +49 -0
  169. package/full-react-imperative/app/components/UserCard/UserCard.css +70 -0
  170. package/full-react-imperative/app/components/UserCard/UserCard.tsx +43 -0
  171. package/full-react-imperative/app/configurations/AppConfiguration.ts +19 -0
  172. package/full-react-imperative/app/error-pages/DefaultErrorPage/DefaultErrorPage.css +0 -0
  173. package/full-react-imperative/app/error-pages/DefaultErrorPage/DefaultErrorPage.tsx +41 -0
  174. package/full-react-imperative/app/error-pages/ForbiddenErrorPage/ForbiddenErrorPage.css +0 -0
  175. package/full-react-imperative/app/error-pages/ForbiddenErrorPage/ForbiddenErrorPage.tsx +42 -0
  176. package/full-react-imperative/app/error-pages/NotFoundErrorPage/NotFoundErrorPage.css +0 -0
  177. package/full-react-imperative/app/error-pages/NotFoundErrorPage/NotFoundErrorPage.tsx +49 -0
  178. package/full-react-imperative/app/error-pages/UnauthorizedErrorPage/UnauthorizedErrorPage.css +0 -0
  179. package/full-react-imperative/app/error-pages/UnauthorizedErrorPage/UnauthorizedErrorPage.tsx +42 -0
  180. package/full-react-imperative/app/errors/ForbiddenError.ts +11 -0
  181. package/full-react-imperative/app/errors/PostNotFoundError.ts +11 -0
  182. package/full-react-imperative/app/errors/UnauthorizedError.ts +11 -0
  183. package/full-react-imperative/app/errors/UserNotFoundError.ts +11 -0
  184. package/full-react-imperative/app/events/UserEvent.ts +18 -0
  185. package/full-react-imperative/app/layout/AppLayout/AppLayout.css +106 -0
  186. package/full-react-imperative/app/layout/AppLayout/AppLayout.tsx +48 -0
  187. package/full-react-imperative/app/layout/ErrorLayout/ErrorLayout.css +0 -0
  188. package/full-react-imperative/app/layout/ErrorLayout/ErrorLayout.tsx +45 -0
  189. package/full-react-imperative/app/layout/SecurityLayout/SecurityLayout.css +0 -0
  190. package/full-react-imperative/app/layout/SecurityLayout/SecurityLayout.tsx +43 -0
  191. package/full-react-imperative/app/layout/SettingsLayout/SettingsLayout.css +99 -0
  192. package/full-react-imperative/app/layout/SettingsLayout/SettingsLayout.tsx +44 -0
  193. package/full-react-imperative/app/middleware/AuthMiddleware.ts +56 -0
  194. package/full-react-imperative/app/models/Comment.ts +35 -0
  195. package/full-react-imperative/app/models/Post.ts +27 -0
  196. package/full-react-imperative/app/models/User.ts +68 -0
  197. package/full-react-imperative/app/pages/Settings/SettingsPage.tsx +23 -0
  198. package/full-react-imperative/app/pages/home/HomePage.tsx +58 -0
  199. package/full-react-imperative/app/pages/login/LoginPage.css +0 -0
  200. package/full-react-imperative/app/pages/login/LoginPage.tsx +65 -0
  201. package/full-react-imperative/app/pages/posts/ShowPostPage/ShowPostPage.tsx +64 -0
  202. package/full-react-imperative/app/pages/posts/UpdatePostPage/UpdatePostPage.tsx +56 -0
  203. package/full-react-imperative/app/pages/register/RegisterPage.tsx +71 -0
  204. package/full-react-imperative/app/pages/users/ShowUserPage/ShowUserPage.css +64 -0
  205. package/full-react-imperative/app/pages/users/ShowUserPage/ShowUserPage.tsx +104 -0
  206. package/full-react-imperative/app/pages/users/UpdateUserPage/UpdateUserPage.css +0 -0
  207. package/full-react-imperative/app/pages/users/UpdateUserPage/UpdateUserPage.tsx +43 -0
  208. package/full-react-imperative/app/pages/users/UserPage/UserPage.css +31 -0
  209. package/full-react-imperative/app/pages/users/UserPage/UserPage.tsx +59 -0
  210. package/full-react-imperative/app/pages/utils.ts +67 -0
  211. package/full-react-imperative/app/providers/AppServiceProvider.ts +40 -0
  212. package/full-react-imperative/app/services/CommentService.ts +53 -0
  213. package/full-react-imperative/app/services/PostService.ts +102 -0
  214. package/full-react-imperative/app/services/SecurityService.ts +72 -0
  215. package/full-react-imperative/app/services/TokenService.ts +108 -0
  216. package/full-react-imperative/app/services/UserService.ts +115 -0
  217. package/full-react-imperative/app/services/contracts/ICommentService.ts +30 -0
  218. package/full-react-imperative/app/services/contracts/IPostService.ts +65 -0
  219. package/full-react-imperative/app/services/contracts/ISecurityService.ts +39 -0
  220. package/full-react-imperative/app/services/contracts/ITokenService.ts +44 -0
  221. package/full-react-imperative/app/services/contracts/IUserService.ts +70 -0
  222. package/full-react-imperative/app/utils.ts +31 -0
  223. package/full-react-imperative/assets/css/index.css +301 -0
  224. package/full-react-imperative/assets/img/logo.png +0 -0
  225. package/full-react-imperative/package.json +48 -0
  226. package/full-react-imperative/public/logo.png +0 -0
  227. package/full-react-imperative/public/vite.svg +1 -0
  228. package/full-react-imperative/stone.config.mjs +12 -0
  229. package/full-react-imperative/tsconfig.json +29 -0
  230. package/full-react-imperative/vitest.config.ts +24 -0
  231. package/full-service-declarative/.env.example +2 -0
  232. package/full-service-declarative/LICENSE +21 -0
  233. package/full-service-declarative/README.md +65 -0
  234. package/full-service-declarative/app/Application.ts +327 -0
  235. package/full-service-declarative/app/commands/ListSessionsCommand.ts +70 -0
  236. package/full-service-declarative/app/commands/ListUsersCommand.ts +56 -0
  237. package/full-service-declarative/app/configurations/AppConfiguration.ts +52 -0
  238. package/full-service-declarative/app/configurations/UserLiveConfiguration.ts +28 -0
  239. package/full-service-declarative/app/database/DatabaseClient.ts +43 -0
  240. package/full-service-declarative/app/database/schema.ts +43 -0
  241. package/full-service-declarative/app/error-handlers/SecurityErrorHandler.ts +61 -0
  242. package/full-service-declarative/app/errors/CredentialsError.ts +12 -0
  243. package/full-service-declarative/app/events/UserEvent.ts +17 -0
  244. package/full-service-declarative/app/handlers/CommentEventHandler.ts +103 -0
  245. package/full-service-declarative/app/handlers/PostEventHandler.ts +104 -0
  246. package/full-service-declarative/app/handlers/SecurityEventHandler.ts +108 -0
  247. package/full-service-declarative/app/handlers/UserEventHandler.ts +159 -0
  248. package/full-service-declarative/app/listeners/UserEventListener.ts +35 -0
  249. package/full-service-declarative/app/middleware/AuthMiddleware.ts +54 -0
  250. package/full-service-declarative/app/models/Comment.ts +38 -0
  251. package/full-service-declarative/app/models/Post.ts +50 -0
  252. package/full-service-declarative/app/models/Session.ts +14 -0
  253. package/full-service-declarative/app/models/User.ts +77 -0
  254. package/full-service-declarative/app/providers/DrizzleServiceProvider.ts +59 -0
  255. package/full-service-declarative/app/repositories/CommentRepository.ts +155 -0
  256. package/full-service-declarative/app/repositories/PostRepository.ts +138 -0
  257. package/full-service-declarative/app/repositories/SessionRepository.ts +123 -0
  258. package/full-service-declarative/app/repositories/UserRepository.ts +99 -0
  259. package/full-service-declarative/app/services/CommentService.ts +112 -0
  260. package/full-service-declarative/app/services/PostService.ts +100 -0
  261. package/full-service-declarative/app/services/SecurityService.ts +232 -0
  262. package/full-service-declarative/app/services/SessionService.ts +130 -0
  263. package/full-service-declarative/app/services/UserService.ts +110 -0
  264. package/full-service-declarative/app/subscribers/UserEventSubscriber.ts +38 -0
  265. package/full-service-declarative/drizzle.config.ts +13 -0
  266. package/full-service-declarative/package.json +48 -0
  267. package/full-service-declarative/stone.config.mjs +12 -0
  268. package/full-service-declarative/tsconfig.json +25 -0
  269. package/full-service-declarative/vitest.config.ts +24 -0
  270. package/full-service-imperative/.env.example +2 -0
  271. package/full-service-imperative/LICENSE +21 -0
  272. package/full-service-imperative/README.md +65 -0
  273. package/full-service-imperative/app/Application.ts +317 -0
  274. package/full-service-imperative/app/commands/ListSessionsCommand.ts +54 -0
  275. package/full-service-imperative/app/commands/ListUsersCommand.ts +42 -0
  276. package/full-service-imperative/app/configurations/AppConfiguration.ts +44 -0
  277. package/full-service-imperative/app/configurations/UserLiveConfiguration.ts +26 -0
  278. package/full-service-imperative/app/database/DatabaseClient.ts +39 -0
  279. package/full-service-imperative/app/database/schema.ts +43 -0
  280. package/full-service-imperative/app/error-handlers/SecurityErrorHandler.ts +58 -0
  281. package/full-service-imperative/app/errors/CredentialsError.ts +12 -0
  282. package/full-service-imperative/app/events/UserEvent.ts +17 -0
  283. package/full-service-imperative/app/handlers/CommentEventHandler.ts +99 -0
  284. package/full-service-imperative/app/handlers/PostEventHandler.ts +99 -0
  285. package/full-service-imperative/app/handlers/SecurityEventHandler.ts +83 -0
  286. package/full-service-imperative/app/handlers/UserEventHandler.ts +132 -0
  287. package/full-service-imperative/app/listeners/UserEventListener.ts +23 -0
  288. package/full-service-imperative/app/middleware/AuthMiddleware.ts +44 -0
  289. package/full-service-imperative/app/models/Comment.ts +38 -0
  290. package/full-service-imperative/app/models/Post.ts +50 -0
  291. package/full-service-imperative/app/models/Session.ts +14 -0
  292. package/full-service-imperative/app/models/User.ts +77 -0
  293. package/full-service-imperative/app/providers/DrizzleServiceProvider.ts +56 -0
  294. package/full-service-imperative/app/repositories/CommentRepository.ts +148 -0
  295. package/full-service-imperative/app/repositories/PostRepository.ts +130 -0
  296. package/full-service-imperative/app/repositories/SessionRepository.ts +115 -0
  297. package/full-service-imperative/app/repositories/UserRepository.ts +91 -0
  298. package/full-service-imperative/app/repositories/contracts/ICommentRepository.ts +72 -0
  299. package/full-service-imperative/app/repositories/contracts/IPostRepository.ts +63 -0
  300. package/full-service-imperative/app/repositories/contracts/ISessionRepository.ts +65 -0
  301. package/full-service-imperative/app/repositories/contracts/IUserRepository.ts +55 -0
  302. package/full-service-imperative/app/services/CommentService.ts +109 -0
  303. package/full-service-imperative/app/services/PostService.ts +97 -0
  304. package/full-service-imperative/app/services/SecurityService.ts +224 -0
  305. package/full-service-imperative/app/services/SessionService.ts +124 -0
  306. package/full-service-imperative/app/services/UserService.ts +105 -0
  307. package/full-service-imperative/app/services/contracts/ICommentService.ts +62 -0
  308. package/full-service-imperative/app/services/contracts/IPostService.ts +53 -0
  309. package/full-service-imperative/app/services/contracts/ISecurityService.ts +97 -0
  310. package/full-service-imperative/app/services/contracts/ISessionService.ts +73 -0
  311. package/full-service-imperative/app/services/contracts/IUserService.ts +57 -0
  312. package/full-service-imperative/app/subscribers/UserEventSubscriber.ts +28 -0
  313. package/full-service-imperative/drizzle.config.ts +13 -0
  314. package/full-service-imperative/package.json +48 -0
  315. package/full-service-imperative/stone.config.mjs +12 -0
  316. package/full-service-imperative/tsconfig.json +25 -0
  317. package/full-service-imperative/vitest.config.ts +24 -0
  318. package/package.json +225 -0
  319. package/standard-react-declarative/LICENSE +21 -0
  320. package/standard-react-declarative/README.md +39 -0
  321. package/standard-react-declarative/app/Application.ts +45 -0
  322. package/standard-react-declarative/app/pages/welcome/WelcomePage.tsx +57 -0
  323. package/standard-react-declarative/app/services/WelcomeService.ts +38 -0
  324. package/standard-react-declarative/assets/css/index.css +26 -0
  325. package/standard-react-declarative/package.json +42 -0
  326. package/standard-react-declarative/tsconfig.json +33 -0
  327. package/standard-react-declarative/vitest.config.ts +24 -0
  328. package/standard-react-imperative/LICENSE +21 -0
  329. package/standard-react-imperative/README.md +39 -0
  330. package/standard-react-imperative/app/Application.ts +41 -0
  331. package/standard-react-imperative/app/pages/welcome/WelcomePage.tsx +50 -0
  332. package/standard-react-imperative/app/services/WelcomeService.ts +38 -0
  333. package/standard-react-imperative/assets/css/index.css +26 -0
  334. package/standard-react-imperative/package.json +42 -0
  335. package/standard-react-imperative/tsconfig.json +33 -0
  336. package/standard-react-imperative/vitest.config.ts +24 -0
  337. package/standard-service-declarative/LICENSE +21 -0
  338. package/standard-service-declarative/README.md +39 -0
  339. package/standard-service-declarative/app/Application.ts +39 -0
  340. package/standard-service-declarative/app/handlers/WelcomeEventHandler.ts +45 -0
  341. package/standard-service-declarative/app/services/WelcomeService.ts +38 -0
  342. package/standard-service-declarative/package.json +36 -0
  343. package/standard-service-declarative/tsconfig.json +25 -0
  344. package/standard-service-declarative/vitest.config.ts +24 -0
  345. package/standard-service-imperative/LICENSE +21 -0
  346. package/standard-service-imperative/README.md +39 -0
  347. package/standard-service-imperative/app/Application.ts +11 -0
  348. package/standard-service-imperative/app/handlers/welcomeEventHandler.ts +31 -0
  349. package/standard-service-imperative/app/services/welcomeService.ts +38 -0
  350. package/standard-service-imperative/package.json +35 -0
  351. package/standard-service-imperative/tsconfig.json +25 -0
  352. package/standard-service-imperative/vitest.config.ts +24 -0
@@ -0,0 +1,327 @@
1
+ import {
2
+ IncomingHttpEvent,
3
+ OutgoingHttpResponse,
4
+ IncomingHttpEventOptions
5
+ } from '@stone-js/http-core'
6
+ import {
7
+ NodeHttp,
8
+ MetaBodyEventMiddleware,
9
+ MetaFilesEventMiddleware
10
+ } from '@stone-js/node-http-adapter'
11
+ import {
12
+ Hook,
13
+ isEmpty,
14
+ StoneApp,
15
+ LogLevel,
16
+ IContainer,
17
+ IBlueprint,
18
+ AdapterContext,
19
+ BlueprintContext,
20
+ AdapterEventBuilderType,
21
+ AdapterHookListenerContext
22
+ } from '@stone-js/core'
23
+ import { getString } from '@stone-js/env'
24
+ import { Routing } from '@stone-js/router'
25
+ import { NodeConsole } from '@stone-js/node-cli-adapter'
26
+ import { PipelineHookContext } from '@stone-js/pipeline'
27
+
28
+ /**
29
+ * Application
30
+ *
31
+ * This is the main application entry point.
32
+ *
33
+ * @StoneApp() is used to enable the Stone application, it is mandatory.
34
+ * @Routing() is used to enable the routing feature.
35
+ * @NodeHttp() is used to enable the Node HTTP adapter.
36
+ * @NodeConsole() is used to enable the Node Console adapter.
37
+ * @NodeConsole() requires the incoming event type.
38
+ * BodyEventMiddleware is used to parse the incoming event body.
39
+ * BodyEventMiddleware is imported because it is not installed by default.
40
+ *
41
+ * Note: In this example we implement the IBlueprintHook, IAdapterHook and IKernelHook interfaces for demonstration purposes.
42
+ */
43
+ @Routing()
44
+ @NodeConsole()
45
+ @StoneApp({ name: 'MyApps', logger: { level: LogLevel.INFO } })
46
+ @NodeHttp({ default: true, middleware: [MetaBodyEventMiddleware, MetaFilesEventMiddleware], url: getString('BASE_URL', 'http://localhost:8080') })
47
+ export class Application {
48
+ /**
49
+ * Run before the blueprint is prepared
50
+ *
51
+ * @param context - The blueprint context
52
+ */
53
+ @Hook('onPreparingBlueprint')
54
+ onPreparingBlueprint ({ blueprint, modules }: BlueprintContext): void {
55
+ blueprint.set('tmpBlueprintTimer', Date.now())
56
+ console.log(`Preparing blueprint by introspecting ${modules.length} modules...`)
57
+ }
58
+
59
+ /**
60
+ * Run before each blueprint middleware is processed
61
+ *
62
+ * @param context - The pipeline context
63
+ */
64
+ @Hook('onProcessingBlueprintMiddleware')
65
+ onProcessingBlueprintMiddleware ({ passable, pipe }: PipelineHookContext<BlueprintContext, IBlueprint>): void {
66
+ passable.blueprint.set(`tmpBlueprintMiddleware.${String(pipe.module.name)}`, Date.now())
67
+ }
68
+
69
+ /**
70
+ * Run after each blueprint middleware is processed
71
+ *
72
+ * @param context - The pipeline context
73
+ */
74
+ @Hook('onBlueprintMiddlewareProcessed')
75
+ onBlueprintMiddlewareProcessed ({ passable, pipe }: PipelineHookContext<BlueprintContext, IBlueprint>): void {
76
+ const name = `tmpBlueprintMiddleware.${String(pipe.module.name)}`
77
+ const start = passable.blueprint.get(name, 0)
78
+ const Type = pipe.isClass !== undefined ? 'Class' : pipe.isFactory !== undefined ? 'Factory' : pipe.isAlias !== undefined ? 'Alias' : 'Callable'
79
+ const value = {
80
+ Middleware: pipe.module.name,
81
+ Type,
82
+ Priority: pipe.priority,
83
+ 'Execution Time': `${Date.now() - start}ms`
84
+ }
85
+
86
+ passable.blueprint.set(name, value)
87
+ }
88
+
89
+ /**
90
+ * Run after the blueprint is prepared
91
+ *
92
+ * @param context - The blueprint context
93
+ */
94
+ @Hook('onBlueprintPrepared')
95
+ onBlueprintPrepared ({ blueprint }: BlueprintContext): void {
96
+ const timer = Date.now() - blueprint.get('tmpBlueprintTimer', 0)
97
+ const middleware = Object.values(blueprint.get('tmpBlueprintMiddleware', {}))
98
+ const message = `Blueprint prepared in ${timer}ms, with ${middleware.length} middleware`
99
+
100
+ console.table(middleware)
101
+ console.log(message)
102
+ }
103
+
104
+ /**
105
+ * Run before the application starts
106
+ *
107
+ * @param context - The adapter context
108
+ */
109
+ @Hook('onStart')
110
+ onStart ({ blueprint, context }: AdapterHookListenerContext): void {
111
+ console.log('Starting application...')
112
+ console.log('Context isEmpty?', isEmpty(context))
113
+ console.log('Blueprint keys:', Object.keys(blueprint.all()).length)
114
+ }
115
+
116
+ /**
117
+ * Run before each adapter middleware is processed
118
+ *
119
+ * @param context - The pipeline context
120
+ */
121
+ @Hook('onProcessingAdapterMiddleware')
122
+ onProcessingAdapterMiddleware ({ passable, pipe, pipes }: PipelineHookContext<
123
+ AdapterContext<unknown, unknown, unknown, IncomingHttpEvent, IncomingHttpEventOptions, OutgoingHttpResponse>,
124
+ AdapterEventBuilderType<any>
125
+ >): void {
126
+ console.log('Processing adapter middleware...')
127
+ console.log('Middleware count:', pipes.length)
128
+ console.log('Middleware name:', pipe.name)
129
+ console.log('IncomingEvent isEmpty?', isEmpty(passable.incomingEvent))
130
+ }
131
+
132
+ /**
133
+ * Run after each adapter middleware is processed
134
+ *
135
+ * @param context - The pipeline context
136
+ */
137
+ @Hook('onAdapterMiddlewareProcessed')
138
+ onAdapterMiddlewareProcessed ({ passable, pipe, pipes }: PipelineHookContext<
139
+ AdapterContext<unknown, unknown, unknown, IncomingHttpEvent, IncomingHttpEventOptions, OutgoingHttpResponse>,
140
+ AdapterEventBuilderType<any>
141
+ >): void {
142
+ console.log('Adapter middleware processed...')
143
+ console.log('Middleware count:', pipes.length)
144
+ console.log('Middleware name:', pipe.name)
145
+ console.log('IncomingEvent isEmpty?', isEmpty(passable.incomingEvent))
146
+ }
147
+
148
+ /**
149
+ * Run before building each incoming event
150
+ *
151
+ * @param context - The adapter context
152
+ */
153
+ @Hook('onBuildingIncomingEvent')
154
+ onBuildingIncomingEvent ({ context }: AdapterHookListenerContext<
155
+ AdapterContext<unknown, unknown, unknown, IncomingHttpEvent, IncomingHttpEventOptions, OutgoingHttpResponse>
156
+ >): void {
157
+ console.log('Building incoming event...')
158
+ console.log('IncomingEvent isEmpty?', isEmpty(context?.incomingEvent))
159
+ }
160
+
161
+ /**
162
+ * Run before handling each adapter error
163
+ *
164
+ * @param context - The adapter context
165
+ */
166
+ @Hook('onHandlingAdapterError')
167
+ onHandlingAdapterError ({ error }: AdapterHookListenerContext<
168
+ AdapterContext<unknown, unknown, unknown, IncomingHttpEvent, IncomingHttpEventOptions, OutgoingHttpResponse>
169
+ >): void {
170
+ console.error('Handling adapter error...')
171
+ console.error('Error:', error)
172
+ }
173
+
174
+ /**
175
+ * Run before building each outgoing response
176
+ *
177
+ * @param context - The adapter context
178
+ */
179
+ @Hook('onBuildingRawResponse')
180
+ onBuildingRawResponse ({ context }: AdapterHookListenerContext<
181
+ AdapterContext<unknown, unknown, unknown, IncomingHttpEvent, IncomingHttpEventOptions, OutgoingHttpResponse>
182
+ >): void {
183
+ console.log('Building raw response...')
184
+ console.log('IncomingEvent isEmpty?', isEmpty(context?.incomingEvent))
185
+ console.log('OutgoingResponse isEmpty?', isEmpty(context?.outgoingResponse))
186
+ }
187
+
188
+ /**
189
+ * Run just before the application stops
190
+ *
191
+ * @param context - The adapter context
192
+ */
193
+ @Hook('onStop')
194
+ onStop ({ blueprint, context }: AdapterHookListenerContext): void {
195
+ console.log('Stopping application...')
196
+ console.log('Context isEmpty?', isEmpty(context))
197
+ console.log('Blueprint keys:', Object.keys(blueprint.all()).length)
198
+ }
199
+
200
+ /**
201
+ * Run after the application is initialized
202
+ * The container is available at this point.
203
+ * All services are registered and ready to be used.
204
+ *
205
+ * @param container - The container
206
+ */
207
+ @Hook('onInit')
208
+ onInit (container: IContainer): void {
209
+ console.log('Initializing application...')
210
+ console.log('Container services count:', container.getBindings().size)
211
+ }
212
+
213
+ /**
214
+ * Run before handling each event
215
+ *
216
+ * @param container - The container
217
+ */
218
+ @Hook('onHandlingEvent')
219
+ onHandlingEvent (container: IContainer): void {
220
+ try {
221
+ console.log('Handling event...')
222
+ container.make('event')
223
+ } catch (error: any) {
224
+ console.log('The incoming event is not yet bound at this stage', error.message)
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Run before processing each kernel middleware
230
+ *
231
+ * @param context - The pipeline context
232
+ */
233
+ @Hook('onProcessingKernelMiddleware')
234
+ onProcessingKernelMiddleware (
235
+ { passable, pipe, pipes }: PipelineHookContext<IncomingHttpEvent, OutgoingHttpResponse>
236
+ ): void {
237
+ console.log('Processing kernel middleware...')
238
+ console.log('Middleware count:', pipes.length)
239
+ console.log('Middleware name:', pipe.name)
240
+ console.log('Incoming Source name', passable.source.platform)
241
+ }
242
+
243
+ /**
244
+ * Run after processing each kernel middleware
245
+ *
246
+ * @param context - The pipeline context
247
+ */
248
+ @Hook('onKernelMiddlewareProcessed')
249
+ onKernelMiddlewareProcessed (
250
+ { passable, pipe, pipes }: PipelineHookContext<IncomingHttpEvent, OutgoingHttpResponse>
251
+ ): void {
252
+ console.log('Kernel middleware processed...')
253
+ console.log('Middleware count:', pipes.length)
254
+ console.log('Middleware name:', pipe.name)
255
+ console.log('Incoming Source name', passable.source.platform)
256
+ }
257
+
258
+ /**
259
+ * Run before executing each event handler
260
+ *
261
+ * @param container - The container
262
+ */
263
+ @Hook('onExecutingEventHandler')
264
+ onExecutingEventHandler ({ event }: { event: IncomingHttpEvent }): void {
265
+ console.log('Executing event handler...')
266
+ console.log('The incoming event is yet bound at this stage', event.source.platform)
267
+ }
268
+
269
+ /**
270
+ * Run before handling each error
271
+ *
272
+ * @param container - The container
273
+ */
274
+ @Hook('onExecutingErrorHandler')
275
+ onExecutingErrorHandler ({ error }: { error: any }): void {
276
+ console.log('Executing error handler...')
277
+ console.log('Error', error)
278
+ }
279
+
280
+ /**
281
+ * Run before preparing each response
282
+ *
283
+ * @param container - The container
284
+ */
285
+ @Hook('onPreparingResponse')
286
+ onPreparingResponse ({ response }: { response: OutgoingHttpResponse }): void {
287
+ console.log('Preparing response...')
288
+ console.log('Response headers', response.headers)
289
+ }
290
+
291
+ /**
292
+ * Run after preparing each response
293
+ *
294
+ * @param container - The container
295
+ */
296
+ @Hook('onResponsePrepared')
297
+ onResponsePrepared ({ response }: { response: OutgoingHttpResponse }): void {
298
+ console.log('Response prepared...')
299
+ console.log('Response headers', response.headers)
300
+ }
301
+
302
+ /**
303
+ * Run after handling each event
304
+ *
305
+ * @param context - The pipeline context
306
+ */
307
+ @Hook('onEventHandled')
308
+ onEventHandled (
309
+ { event, response }: { event: IncomingHttpEvent, response: OutgoingHttpResponse }
310
+ ): void {
311
+ console.log('Event handled...')
312
+ console.log('Event headers', event.headers)
313
+ console.log('Response headers', response.headers)
314
+ }
315
+
316
+ /**
317
+ * Run after executing each event handler
318
+ *
319
+ * @param container - The container
320
+ */
321
+ @Hook('onTerminate')
322
+ onTerminate (container: IContainer): void {
323
+ console.log('Terminating event handling...')
324
+ console.log('Is IncomingEvent exist', container.bound('event'))
325
+ console.log('Is OutgoingResponse exist', container.bound('response'))
326
+ }
327
+ }
@@ -0,0 +1,70 @@
1
+ import { UserService } from '../services/UserService'
2
+ import { SessionService } from '../services/SessionService'
3
+ import { ILogger, IncomingEvent, isEmpty } from '@stone-js/core'
4
+ import { Command, CommandBuilder, ICommandHandler } from '@stone-js/node-cli-adapter'
5
+
6
+ /**
7
+ * ListSessionsCommandOptions
8
+ */
9
+ export interface ListSessionsCommandOptions {
10
+ logger: ILogger
11
+ userService: UserService
12
+ sessionService: SessionService
13
+ }
14
+
15
+ /**
16
+ * List sessions command
17
+ */
18
+ @Command({
19
+ alias: 'ls',
20
+ name: 'list-sessions',
21
+ desc: 'List sessions',
22
+ options: (yargs: CommandBuilder) => {
23
+ return yargs
24
+ .option('email', {
25
+ alias: 'e',
26
+ type: 'string',
27
+ default: undefined,
28
+ desc: 'Filter sessions by email'
29
+ })
30
+ .option('limit', {
31
+ alias: 'l',
32
+ type: 'number',
33
+ default: false,
34
+ desc: 'Number of sessions to list'
35
+ })
36
+ }
37
+ })
38
+ export class ListSessionsCommand implements ICommandHandler<IncomingEvent> {
39
+ private readonly logger: ILogger
40
+ private readonly userService: UserService
41
+ private readonly sessionService: SessionService
42
+
43
+ /**
44
+ * Create a new instance of ListSessionsCommand
45
+ *
46
+ * @param logger
47
+ * @param sessionService
48
+ */
49
+ constructor ({ logger, sessionService, userService }: ListSessionsCommandOptions) {
50
+ this.logger = logger
51
+ this.userService = userService
52
+ this.sessionService = sessionService
53
+ }
54
+
55
+ /**
56
+ * Handler for the ListSessionsCommand
57
+ *
58
+ * @param event - Incoming event
59
+ */
60
+ async handle (event: IncomingEvent): Promise<void> {
61
+ const email = event.get<number>('email')
62
+ const limit = event.get<number>('limit', 10)
63
+ const user = isEmpty(email) ? undefined : await this.userService.findByEmail({ email })
64
+ const sessions = isEmpty(user)
65
+ ? await this.sessionService.list(limit)
66
+ : await this.sessionService.getByUser(user, limit)
67
+ this.logger.info('List sessions command')
68
+ console.table(sessions)
69
+ }
70
+ }
@@ -0,0 +1,56 @@
1
+ import { UserService } from '../services/UserService'
2
+ import { ILogger, IncomingEvent } from '@stone-js/core'
3
+ import { Command, CommandBuilder, ICommandHandler } from '@stone-js/node-cli-adapter'
4
+
5
+ /**
6
+ * ListUsersCommandOptions
7
+ */
8
+ export interface ListUsersCommandOptions {
9
+ logger: ILogger
10
+ userService: UserService
11
+ }
12
+
13
+ /**
14
+ * List users command
15
+ */
16
+ @Command({
17
+ alias: 'lu',
18
+ name: 'list-users',
19
+ desc: 'List users',
20
+ options: (yargs: CommandBuilder) => {
21
+ return yargs
22
+ .option('limit', {
23
+ alias: 'l',
24
+ type: 'number',
25
+ default: false,
26
+ desc: 'Number of users to list'
27
+ })
28
+ }
29
+ })
30
+ export class ListUsersCommand implements ICommandHandler<IncomingEvent> {
31
+ private readonly logger: ILogger
32
+ private readonly userService: UserService
33
+
34
+ /**
35
+ * Create a new instance of ListUsersCommand
36
+ *
37
+ * @param logger
38
+ * @param userService
39
+ */
40
+ constructor ({ logger, userService }: ListUsersCommandOptions) {
41
+ this.logger = logger
42
+ this.userService = userService
43
+ }
44
+
45
+ /**
46
+ * Handler for the ListUsersCommand
47
+ *
48
+ * @param event - Incoming event
49
+ */
50
+ async handle (event: IncomingEvent): Promise<void> {
51
+ const limit = event.get<number>('limit', 10)
52
+ const users = await this.userService.list(limit)
53
+ this.logger.info('List users command')
54
+ console.table(users)
55
+ }
56
+ }
@@ -0,0 +1,52 @@
1
+ import { Config } from '@libsql/client'
2
+ import { getString } from '@stone-js/env'
3
+ import { CORSHeadersMiddleware } from '@stone-js/http-core'
4
+ import { Configuration, defineBlueprintMiddleware, IBlueprint, IConfiguration, LogLevel, Promiseable } from '@stone-js/core'
5
+
6
+ /**
7
+ * User Implicit Configuration
8
+ *
9
+ * Explicit configuration takes precedence over implicit configuration.
10
+ * Implicit configuration are defined at decorators level.
11
+ */
12
+ @Configuration()
13
+ export class AppConfiguration implements IConfiguration {
14
+ /**
15
+ * Configure the application
16
+ *
17
+ * @param blueprint - The blueprint to configure
18
+ */
19
+ configure (blueprint: IBlueprint): Promiseable<void> {
20
+ blueprint
21
+ .set('database', this.databaseConfig())
22
+ .set('security', this.securityConfig())
23
+ .set('stone.logger.level', LogLevel.INFO)
24
+ .set('stone.http.cors.preflightStop', true)
25
+ .set('stone.http.cors.allowedHeaders', ['*'])
26
+ .set(defineBlueprintMiddleware(CORSHeadersMiddleware))
27
+ }
28
+
29
+ /**
30
+ * Get the database configuration
31
+ */
32
+ private databaseConfig (): Config {
33
+ return {
34
+ url: getString('DATABASE_URL', 'file:local.db')
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Get the security configuration
40
+ */
41
+ private securityConfig (): Record<string, any> {
42
+ return {
43
+ jwt: {
44
+ expiresIn: 3600
45
+ },
46
+ secret: getString('SECURITY_JWT_SECRET', 'non_prod_secret'),
47
+ bcrypt: {
48
+ saltRounds: 10
49
+ }
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,28 @@
1
+ import { Configuration, IBlueprint, IConfiguration } from '@stone-js/core'
2
+
3
+ /**
4
+ * User Live Configuration
5
+ * Usefull for loading configuration without restarting the application.
6
+ * Live explicit configuration takes precedence over explicit and implicit configurations.
7
+ * Note: Only applicable for server applications.
8
+ */
9
+ @Configuration({ live: true })
10
+ export class UserLiveConfiguration implements IConfiguration {
11
+ /**
12
+ * Configure the application
13
+ *
14
+ * @param blueprint - The blueprint to configure
15
+ */
16
+ async configure (blueprint: IBlueprint): Promise<void> {
17
+ blueprint.set('stone.name', await this.fetchConfigurationRemotely())
18
+ console.log('I am live cause i am loaded at each request...')
19
+ }
20
+
21
+ /**
22
+ * Fetch the configuration remotely
23
+ */
24
+ async fetchConfigurationRemotely (): Promise<string> {
25
+ console.log('Fetching configuration...')
26
+ return await Promise.resolve('My Fetched app name')
27
+ }
28
+ }
@@ -0,0 +1,43 @@
1
+ import { Client, Config, createClient } from '@libsql/client'
2
+
3
+ /* eslint-disable @typescript-eslint/no-extraneous-class */
4
+
5
+ /**
6
+ * DatabaseClient
7
+ */
8
+ export class DatabaseClient {
9
+ private static _client?: Client
10
+
11
+ /**
12
+ * The client instance
13
+ */
14
+ static get client (): Client {
15
+ if (this._client === undefined) {
16
+ throw new Error('Database client is not initialized.')
17
+ }
18
+ return this._client
19
+ }
20
+
21
+ /**
22
+ * Create a new client instance
23
+ *
24
+ * @param config - The configuration object for the client
25
+ * @returns The client instance
26
+ */
27
+ static create (config: Config): Client {
28
+ if (this._client === undefined) {
29
+ this._client = createClient(config)
30
+ }
31
+ return this._client
32
+ }
33
+
34
+ /**
35
+ * Close the client instance
36
+ */
37
+ static close (): void {
38
+ if (this._client !== undefined) {
39
+ this._client.close()
40
+ this._client = undefined
41
+ }
42
+ }
43
+ }
@@ -0,0 +1,43 @@
1
+ import { sqliteTable, integer, text } from 'drizzle-orm/sqlite-core'
2
+
3
+ // User Table
4
+ export const users = sqliteTable('users', {
5
+ id: integer('id').primaryKey(),
6
+ name: text('name').notNull(),
7
+ password: text('password'),
8
+ avatar: text('avatar'),
9
+ email: text('email').unique().notNull(),
10
+ updatedAt: integer('updated_at').notNull(),
11
+ createdAt: integer('created_at').notNull() // Store timestamps as integers (Unix timestamp)
12
+ })
13
+
14
+ export const sessions = sqliteTable('sessions', {
15
+ id: integer('id').primaryKey(),
16
+ ip: text('ip').notNull(),
17
+ userAgent: text('user_agent'),
18
+ closedAt: integer('closed_at'),
19
+ uuid: text('uuid').unique().notNull(),
20
+ createdAt: integer('created_at').notNull(),
21
+ expiresAt: integer('expires_at').notNull(),
22
+ lastActivityAt: integer('last_activity_at').notNull(),
23
+ userId: integer('user_id').notNull().references(() => users.id, { onDelete: 'cascade' })
24
+ })
25
+
26
+ // Post Table
27
+ export const posts = sqliteTable('posts', {
28
+ id: integer('id').primaryKey(),
29
+ title: text('title').notNull(),
30
+ content: text('content').notNull(),
31
+ createdAt: integer('created_at').notNull(),
32
+ updatedAt: integer('updated_at').notNull(),
33
+ authorId: integer('author_id').notNull().references(() => users.id, { onDelete: 'cascade' })
34
+ })
35
+
36
+ // Comment Table
37
+ export const comments = sqliteTable('comments', {
38
+ id: integer('id').primaryKey(),
39
+ content: text('content').notNull(),
40
+ createdAt: integer('created_at').notNull(),
41
+ authorId: integer('author_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
42
+ postId: integer('post_id').notNull().references(() => posts.id, { onDelete: 'cascade' })
43
+ })
@@ -0,0 +1,61 @@
1
+ import { BadCredentialsError } from '../errors/CredentialsError'
2
+ import { ErrorHandler, IErrorHandler, ILogger, Promiseable } from '@stone-js/core'
3
+ import { BadRequestError, HTTP_BAD_REQUEST, HTTP_INTERNAL_SERVER_ERROR, HTTP_NOT_FOUND, HTTP_UNAUTHORIZED, IncomingHttpEvent, NotFoundError, UnauthorizedError } from '@stone-js/http-core'
4
+
5
+ /**
6
+ * User Error Handler Options
7
+ */
8
+ export interface SecurityErrorHandlerOptions {
9
+ logger: ILogger
10
+ }
11
+
12
+ /**
13
+ * User Error Handler
14
+ */
15
+ @ErrorHandler({ error: ['BadCredentialsError', 'UnauthorizedError', 'NotFoundError', 'BadRequestError'] })
16
+ export class SecurityErrorHandler implements IErrorHandler<IncomingHttpEvent> {
17
+ private readonly logger: ILogger
18
+
19
+ /**
20
+ * Create a new instance of SecurityErrorHandler
21
+ *
22
+ * @param logger
23
+ */
24
+ constructor ({ logger }: SecurityErrorHandlerOptions) {
25
+ this.logger = logger
26
+ }
27
+
28
+ /**
29
+ * Handle CredentialsError and UnauthorizedError
30
+ *
31
+ * @param error - The error to handle
32
+ * @param _event - The incoming event
33
+ * @returns The response
34
+ */
35
+ handle (error: BadCredentialsError | UnauthorizedError | NotFoundError | BadRequestError, _event: IncomingHttpEvent): Promiseable<unknown> {
36
+ this.logger.error(error.message)
37
+ let message: string = 'An error occurred'
38
+ let statusCode: number = HTTP_INTERNAL_SERVER_ERROR
39
+
40
+ if (error instanceof NotFoundError) {
41
+ message = error.message
42
+ statusCode = HTTP_NOT_FOUND
43
+ } else if (error instanceof BadCredentialsError) {
44
+ message = 'Invalid credentials'
45
+ statusCode = HTTP_UNAUTHORIZED
46
+ } else if (error instanceof UnauthorizedError) {
47
+ statusCode = HTTP_UNAUTHORIZED
48
+ message = 'You are not authorized to perform this action'
49
+ } else if (error instanceof BadRequestError) {
50
+ statusCode = HTTP_BAD_REQUEST
51
+ message = error.message
52
+ }
53
+
54
+ return {
55
+ statusCode,
56
+ content: {
57
+ errors: { message }
58
+ }
59
+ }
60
+ }
61
+ }
@@ -0,0 +1,12 @@
1
+ import { ErrorOptions } from '@stone-js/core'
2
+ import { UnauthorizedError } from '@stone-js/http-core'
3
+
4
+ /**
5
+ * Bad Credentials Error
6
+ */
7
+ export class BadCredentialsError extends UnauthorizedError {
8
+ constructor (message: string, options?: ErrorOptions) {
9
+ super(message, options)
10
+ this.name = 'BadCredentialsError'
11
+ }
12
+ }