@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,110 @@
1
+ import { FC, useState } from 'react'
2
+ import { isNotEmpty } from '@stone-js/core'
3
+ import { StoneLink } from '@stone-js/use-react'
4
+ import { UserRegister, UserRegisterErrors } from '../../models/User'
5
+
6
+ /**
7
+ * Register Form Options
8
+ */
9
+ export interface RegisterFormOptions {
10
+ done: boolean
11
+ error?: UserRegisterErrors
12
+ onSubmit: (user: UserRegister) => Promise<void>
13
+ }
14
+
15
+ /**
16
+ * Register Form component.
17
+ *
18
+ * @param options - The options to create the Register Form component.
19
+ */
20
+ export const RegisterForm: FC<RegisterFormOptions> = ({ onSubmit, error, done }) => {
21
+ // Create a reference to the user
22
+ const [user, setUser] = useState<UserRegister>({
23
+ name: '',
24
+ email: '',
25
+ password: '',
26
+ confirmPassword: ''
27
+ })
28
+
29
+ // Handle the form submit
30
+ const handleSubmit = (event: React.FormEvent<HTMLFormElement>): void => {
31
+ event.preventDefault()
32
+ isValid() && onSubmit(user).catch(() => {})
33
+ }
34
+
35
+ const isValid = (): boolean => isNotEmpty(user.name) && isNotEmpty(user.email) && isNotEmpty(user.password) && user.password === user.confirmPassword
36
+
37
+ // Handle the field change
38
+ const onChange = (field: keyof UserRegister) => (event: React.ChangeEvent<HTMLInputElement>) => {
39
+ setUser({ ...user, [field]: event.target.value })
40
+ }
41
+
42
+ // Create the form component
43
+ const formComponent = (
44
+ <form onSubmit={handleSubmit} className='panel'>
45
+ {error?.message !== undefined && <p className='alert alert-danger alert-small'>{error?.message}</p>}
46
+
47
+ <div>
48
+ <label htmlFor='name' className='label'>Name:</label>
49
+ <input
50
+ id='name'
51
+ type='text'
52
+ className='input'
53
+ placeholder='Enter your name'
54
+ onChange={onChange('name')} defaultValue={user.name}
55
+ />
56
+ </div>
57
+
58
+ <div>
59
+ <label htmlFor='email' className='label'>Email:</label>
60
+ <input
61
+ id='email'
62
+ type='email'
63
+ className='input'
64
+ placeholder='Enter your email'
65
+ onChange={onChange('email')} defaultValue={user.email}
66
+ />
67
+ </div>
68
+
69
+ <div>
70
+ <label htmlFor='password' className='label'>Password:</label>
71
+ <input
72
+ id='password'
73
+ type='password'
74
+ className='input'
75
+ placeholder='Enter your password'
76
+ onChange={onChange('password')} defaultValue={user.password}
77
+ />
78
+ </div>
79
+
80
+ <div>
81
+ <label htmlFor='confirmPassword' className='label'>Confirm password:</label>
82
+ <input
83
+ id='confirmPassword'
84
+ type='password'
85
+ className='input'
86
+ placeholder='Confirm your password'
87
+ onChange={onChange('confirmPassword')} defaultValue={user.confirmPassword}
88
+ />
89
+ </div>
90
+
91
+ <button type='submit' className='button button-secondary button-full mt-24' disabled={!isValid()}>Register</button>
92
+ </form>
93
+ )
94
+
95
+ // Create the done component
96
+ const doneComponent = <div className='panel'><p className='alert alert-success'>Registration successful! 🎉 You can now login</p></div>
97
+
98
+ // Get the component
99
+ const component = done ? doneComponent : formComponent
100
+
101
+ // Render the component
102
+ return (
103
+ <div>
104
+ {component}
105
+ <p className='mt-24 text-center'>
106
+ <StoneLink to='/login' className='button button-primary'>Login</StoneLink>
107
+ </p>
108
+ </div>
109
+ )
110
+ }
@@ -0,0 +1,47 @@
1
+ import { FC, useRef } from 'react'
2
+ import { UserInput } from '../../models/User'
3
+
4
+ /**
5
+ * User Form Options
6
+ */
7
+ export interface UserFormOptions {
8
+ user?: UserInput
9
+ onSubmit: (user: UserInput) => Promise<void>
10
+ }
11
+
12
+ /**
13
+ * User Form component.
14
+ *
15
+ * @param options - The options to create the User Form component.
16
+ */
17
+ export const UserForm: FC<UserFormOptions> = ({ user, onSubmit }) => {
18
+ // Create a reference to the user
19
+ const userRef = useRef<UserInput>({
20
+ name: user?.name ?? '',
21
+ email: user?.email ?? ''
22
+ })
23
+
24
+ // Handle the form submit
25
+ const handleSubmit = (event: React.FormEvent<HTMLFormElement>): void => {
26
+ event.preventDefault()
27
+ void onSubmit(userRef.current).catch(() => {})
28
+ }
29
+
30
+ // Handle the field change
31
+ const onChange = (field: keyof UserInput) => (event: React.ChangeEvent<HTMLInputElement>) => {
32
+ userRef.current[field] = event.target.value
33
+ }
34
+
35
+ // Render the component
36
+ return (
37
+ <form onSubmit={handleSubmit}>
38
+ <label htmlFor='name'>Name:</label>
39
+ <input id='name' type='text' onChange={onChange('name')} defaultValue={userRef.current.name} />
40
+
41
+ <label htmlFor='email'>Email:</label>
42
+ <input id='email' type='email' onChange={onChange('email')} defaultValue={userRef.current.email} />
43
+
44
+ <button type='submit'>Save</button>
45
+ </form>
46
+ )
47
+ }
@@ -0,0 +1,17 @@
1
+ import { getString } from '@stone-js/env'
2
+ import { Configuration, IBlueprint, IConfiguration, Promiseable } from '@stone-js/core'
3
+
4
+ /**
5
+ * App Configuration
6
+ */
7
+ @Configuration()
8
+ export class AppConfiguration implements IConfiguration {
9
+ /**
10
+ * Configure the application.
11
+ */
12
+ configure (blueprint: IBlueprint): Promiseable<void> {
13
+ blueprint
14
+ .set('stone.kernel.skipMiddleware', false)
15
+ .set('app.api.baseURL', getString('API_BASE_URL', 'http://localhost:8080'))
16
+ }
17
+ }
@@ -0,0 +1,52 @@
1
+ import './DefaultErrorPage.css'
2
+ import { JSX } from 'react'
3
+ import { ILogger } from '@stone-js/core'
4
+ import { ErrorPage, IErrorPage, PageStatus, ReactIncomingEvent, ErrorPageRenderContext } from '@stone-js/use-react'
5
+
6
+ /**
7
+ * Forbidden Error Handler component.
8
+ */
9
+ @ErrorPage({
10
+ layout: 'error',
11
+ error: 'default'
12
+ })
13
+ export class DefaultErrorPage implements IErrorPage<ReactIncomingEvent> {
14
+ private readonly logger: ILogger
15
+
16
+ /**
17
+ * Create an DefaultErrorPage.
18
+ *
19
+ * @param logger - The logger.
20
+ */
21
+ constructor ({ logger }: { logger: ILogger }) {
22
+ this.logger = logger
23
+ }
24
+
25
+ /**
26
+ * Handle the error.
27
+ *
28
+ * @param error - The error to handle.
29
+ * @returns The response.
30
+ */
31
+ @PageStatus(500)
32
+ handle (error: any): { message: string } {
33
+ this.logger.error(error.message, { error })
34
+ return { message: 'Oops! Something went wrong!' }
35
+ }
36
+
37
+ /**
38
+ * Render the component.
39
+ *
40
+ * @param options - The options for rendering the component.
41
+ * @returns The rendered component.
42
+ */
43
+ render ({ data, statusCode }: ErrorPageRenderContext<Error>): JSX.Element {
44
+ return (
45
+ <div className='text-center'>
46
+ <h1 className='h1'>{statusCode}</h1>
47
+ <h2 className='h4'>An Error occured!</h2>
48
+ <p className='text-muted mt-24'>{data?.message}</p>
49
+ </div>
50
+ )
51
+ }
52
+ }
@@ -0,0 +1,53 @@
1
+ import './ForbiddenErrorPage.css'
2
+ import { JSX } from 'react'
3
+ import { ILogger } from '@stone-js/core'
4
+ import { ForbiddenError } from '../../errors/ForbiddenError'
5
+ import { ErrorPage, IErrorPage, PageStatus, ReactIncomingEvent, ErrorPageRenderContext } from '@stone-js/use-react'
6
+
7
+ /**
8
+ * Forbidden Error Handler component.
9
+ */
10
+ @ErrorPage({
11
+ layout: 'error',
12
+ error: 'ForbiddenError'
13
+ })
14
+ export class ForbiddenErrorPage implements IErrorPage<ReactIncomingEvent> {
15
+ private readonly logger: ILogger
16
+
17
+ /**
18
+ * Create an ForbiddenErrorPage.
19
+ *
20
+ * @param logger - The logger.
21
+ */
22
+ constructor ({ logger }: { logger: ILogger }) {
23
+ this.logger = logger
24
+ }
25
+
26
+ /**
27
+ * Handle the error.
28
+ *
29
+ * @param error - The error to handle.
30
+ * @returns The response.
31
+ */
32
+ @PageStatus(403)
33
+ handle (error: ForbiddenError): { message: string } {
34
+ this.logger.error(error.message, { error })
35
+ return { message: "I think you're not supposed to be here! Eh ?" }
36
+ }
37
+
38
+ /**
39
+ * Render the component.
40
+ *
41
+ * @param options - The options for rendering the component.
42
+ * @returns The rendered component.
43
+ */
44
+ render ({ data, statusCode }: ErrorPageRenderContext<ForbiddenError>): JSX.Element {
45
+ return (
46
+ <div className='text-center'>
47
+ <h1 className='h1'>{statusCode}</h1>
48
+ <h2 className='h4'>Are you in the right place?</h2>
49
+ <p className='text-muted mt-24'>{data?.message}</p>
50
+ </div>
51
+ )
52
+ }
53
+ }
@@ -0,0 +1,54 @@
1
+ import './NotFoundErrorPage.css'
2
+ import { JSX } from 'react'
3
+ import { ILogger } from '@stone-js/core'
4
+ import { RouteNotFoundError } from '@stone-js/router'
5
+ import { ErrorPage, IErrorPage, PageStatus, ReactIncomingEvent, ErrorPageRenderContext } from '@stone-js/use-react'
6
+
7
+ /**
8
+ * NotFound Error Handler component.
9
+ */
10
+ @ErrorPage({
11
+ layout: 'error',
12
+ error: ['RouteNotFoundError', 'PostNotFoundError', 'UserNotFoundError']
13
+ })
14
+ export class NotFoundErrorPage implements IErrorPage<ReactIncomingEvent> {
15
+ private readonly logger: ILogger
16
+
17
+ /**
18
+ * Create an NotFoundErrorPage.
19
+ *
20
+ * @param logger - The logger.
21
+ */
22
+ constructor ({ logger }: { logger: ILogger }) {
23
+ this.logger = logger
24
+ }
25
+
26
+ /**
27
+ * Handle the error.
28
+ *
29
+ * @param error - The error to handle.
30
+ * @param event - The incoming event.
31
+ * @returns The response.
32
+ */
33
+ @PageStatus(404)
34
+ handle (error: RouteNotFoundError, event: ReactIncomingEvent): { message: string } {
35
+ this.logger.error(error.message, { error })
36
+ return { message: `Page not found: ${event.pathname}` }
37
+ }
38
+
39
+ /**
40
+ * Render the component.
41
+ *
42
+ * @param options - The options for rendering the component.
43
+ * @returns The rendered component.
44
+ */
45
+ render ({ data, statusCode }: ErrorPageRenderContext<RouteNotFoundError>): JSX.Element {
46
+ return (
47
+ <div className='text-center'>
48
+ <h1 className='h1'>{statusCode}</h1>
49
+ <h2 className='h4'>OOps! It seems you are lost?</h2>
50
+ <p className='text-muted mt-24'>{data?.message}</p>
51
+ </div>
52
+ )
53
+ }
54
+ }
@@ -0,0 +1,53 @@
1
+ import './UnauthorizedErrorPage.css'
2
+ import { JSX } from 'react'
3
+ import { ILogger } from '@stone-js/core'
4
+ import { UnauthorizedError } from '../../errors/UnauthorizedError'
5
+ import { ErrorPage, IErrorPage, PageStatus, ReactIncomingEvent, ErrorPageRenderContext } from '@stone-js/use-react'
6
+
7
+ /**
8
+ * Unauthorized Error Handler component.
9
+ */
10
+ @ErrorPage({
11
+ layout: 'error',
12
+ error: 'UnauthorizedError'
13
+ })
14
+ export class UnauthorizedErrorPage implements IErrorPage<ReactIncomingEvent> {
15
+ private readonly logger: ILogger
16
+
17
+ /**
18
+ * Create an UnauthorizedErrorPage.
19
+ *
20
+ * @param logger - The logger.
21
+ */
22
+ constructor ({ logger }: { logger: ILogger }) {
23
+ this.logger = logger
24
+ }
25
+
26
+ /**
27
+ * Handle the error.
28
+ *
29
+ * @param error - The error to handle.
30
+ * @returns The response.
31
+ */
32
+ @PageStatus(403)
33
+ handle (error: UnauthorizedError): { message: string } {
34
+ this.logger.error(error.message, { error })
35
+ return { message: "I think you're an alien! Eh ?" }
36
+ }
37
+
38
+ /**
39
+ * Render the component.
40
+ *
41
+ * @param options - The options for rendering the component.
42
+ * @returns The rendered component.
43
+ */
44
+ render ({ data, statusCode }: ErrorPageRenderContext<UnauthorizedError>): JSX.Element {
45
+ return (
46
+ <div className='text-center'>
47
+ <h1 className='h1'>{statusCode}</h1>
48
+ <h2 className='h4'>Are you in the right place?</h2>
49
+ <p className='text-muted mt-24'>{data?.message}</p>
50
+ </div>
51
+ )
52
+ }
53
+ }
@@ -0,0 +1,11 @@
1
+ import { ErrorOptions, RuntimeError } from '@stone-js/core'
2
+
3
+ /**
4
+ * Not Forbidden Error
5
+ */
6
+ export class ForbiddenError extends RuntimeError {
7
+ constructor (message: string, options?: ErrorOptions) {
8
+ super(message, options)
9
+ this.name = 'ForbiddenError'
10
+ }
11
+ }
@@ -0,0 +1,11 @@
1
+ import { ErrorOptions, RuntimeError } from '@stone-js/core'
2
+
3
+ /**
4
+ * Post Not found Error
5
+ */
6
+ export class PostNotFoundError extends RuntimeError {
7
+ constructor (message: string, options: ErrorOptions = {}) {
8
+ super(message, options)
9
+ this.name = 'PostNotFoundError'
10
+ }
11
+ }
@@ -0,0 +1,11 @@
1
+ import { ErrorOptions, RuntimeError } from '@stone-js/core'
2
+
3
+ /**
4
+ * Unauthorized Error
5
+ */
6
+ export class UnauthorizedError extends RuntimeError {
7
+ constructor (message: string, options?: ErrorOptions) {
8
+ super(message, options)
9
+ this.name = 'UnauthorizedError'
10
+ }
11
+ }
@@ -0,0 +1,11 @@
1
+ import { ErrorOptions, RuntimeError } from '@stone-js/core'
2
+
3
+ /**
4
+ * User Not found Error
5
+ */
6
+ export class UserNotFoundError extends RuntimeError {
7
+ constructor (message: string, options: ErrorOptions = {}) {
8
+ super(message, options)
9
+ this.name = 'UserNotFoundError'
10
+ }
11
+ }
@@ -0,0 +1,18 @@
1
+ import { User } from '../models/User'
2
+ import { Event } from '@stone-js/core'
3
+
4
+ /**
5
+ * User Event
6
+ */
7
+ export class UserEvent extends Event {
8
+ /**
9
+ * USER_CREATED Event name, fires after a user have been created.
10
+ *
11
+ * @event UserEvent#USER_CREATED
12
+ */
13
+ static USER_CREATED: string = 'user.created'
14
+
15
+ constructor (public readonly user: Partial<User>) {
16
+ super({ type: UserEvent.USER_CREATED })
17
+ }
18
+ }
@@ -0,0 +1,20 @@
1
+ .app-layout .logo {
2
+ margin: 0;
3
+ border: none;
4
+ display: flex;
5
+ width: 300px;
6
+ align-items: center;
7
+ background: none;
8
+ text-align: center;
9
+ }
10
+ .app-layout .logo:hover {
11
+ cursor: pointer;
12
+ }
13
+ .app-layout .logo img {
14
+ width: 24px;
15
+ }
16
+ .app-layout .logo span {
17
+ font-size: 1.5em;
18
+ margin-left: 8px;
19
+ font-weight: bold;
20
+ }
@@ -0,0 +1,101 @@
1
+ import './AppLayout.css'
2
+ import { JSX } from 'react'
3
+ import { User } from '../../models/User'
4
+ import { IBlueprint, isNotEmpty } from '@stone-js/core'
5
+ import { SecurityService } from '../../services/SecurityService'
6
+ import { IPageLayout, IRouter, PageLayout, PageLayoutRenderContext, ReactIncomingEvent, StoneLink, StoneOutlet } from '@stone-js/use-react'
7
+
8
+ /**
9
+ * App Layout options.
10
+ */
11
+ export interface AppLayoutOptions {
12
+ router: IRouter
13
+ blueprint: IBlueprint
14
+ securityService: SecurityService
15
+ }
16
+
17
+ /**
18
+ * App Layout component.
19
+ */
20
+ @PageLayout({ name: 'default' })
21
+ export class AppLayout implements IPageLayout {
22
+ private readonly router: IRouter
23
+ private readonly blueprint: IBlueprint
24
+ private readonly securityService: SecurityService
25
+
26
+ /**
27
+ * Create a new App Layout component.
28
+ *
29
+ * @param options - The options to create the App Layout component.
30
+ */
31
+ constructor ({ router, blueprint, securityService }: AppLayoutOptions) {
32
+ this.router = router
33
+ this.blueprint = blueprint
34
+ this.securityService = securityService
35
+ }
36
+
37
+ /**
38
+ * Render the component.
39
+ *
40
+ * @param options - The options for rendering the component.
41
+ * @returns The rendered component.
42
+ */
43
+ render ({ container, children }: PageLayoutRenderContext): JSX.Element {
44
+ const user = container.make<ReactIncomingEvent>('event').getUser<User>() ?? {} as unknown as User
45
+
46
+ return (
47
+ <div className='app-layout'>
48
+ <header>
49
+ <p>
50
+ <StoneLink to='/' className='logo'>
51
+ <img src='/logo.png' alt='Stone.js Logo' />
52
+ <span>Stone.js</span>
53
+ </StoneLink>
54
+ </p>
55
+ {isNotEmpty<User>(user) && (
56
+ <p>
57
+ <span>
58
+ <img src={this.getUserAvatar(user)} alt='Stone.js Logo' />
59
+ </span>
60
+ <span>
61
+ <span>{user.name}</span>
62
+ <span>{user.email}</span>
63
+ </span>
64
+ </p>
65
+ )}
66
+ <p>
67
+ {isNotEmpty<User>(user)
68
+ ? <button onClick={() => this.logout()}>Logout</button>
69
+ : <StoneLink to='/login'>Login</StoneLink>}
70
+ </p>
71
+ </header>
72
+ <main>
73
+ <StoneOutlet>{children}</StoneOutlet>
74
+ </main>
75
+ <footer>&copy; 2025 Stone.js</footer>
76
+ </div>
77
+ )
78
+ }
79
+
80
+ /**
81
+ * Logout the user.
82
+ */
83
+ logout (): void {
84
+ if (window.confirm('Are you sure you want to logout?')) {
85
+ void this.securityService.logout().then(() => {
86
+ this.router.navigate('/', true)
87
+ })
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Get the user avatar.
93
+ *
94
+ * @param user - The user to get the avatar.
95
+ * @returns The user avatar.
96
+ */
97
+ private getUserAvatar (user: User): string {
98
+ const baseUrl = this.blueprint.get<string>('app.api.baseURL', '')
99
+ return isNotEmpty<string>(user.avatar) ? `${baseUrl}/users/${user.id}/avatar` : '/assets/avatar.png'
100
+ }
101
+ }
@@ -0,0 +1,41 @@
1
+ import './ErrorLayout.css'
2
+ import { JSX } from 'react'
3
+ import { PageLayout, IPageLayout, StoneOutlet, PageLayoutRenderContext } from '@stone-js/use-react'
4
+
5
+ /**
6
+ * Error Layout component.
7
+ */
8
+ @PageLayout({ name: 'error' })
9
+ export class ErrorLayout implements IPageLayout {
10
+ /**
11
+ * Render the component.
12
+ *
13
+ * @param options - The options for rendering the component.
14
+ * @returns The rendered component.
15
+ */
16
+ render ({ children }: PageLayoutRenderContext): JSX.Element {
17
+ return (
18
+ <>
19
+ <header className='mt-64'>
20
+ <div className='container'>
21
+ <p className='pa-24'>
22
+ <img src='/logo.png' className='logo' alt='Stone.js Logo' />
23
+ </p>
24
+ </div>
25
+ </header>
26
+ <main>
27
+ <div className='container'>
28
+ <div className='panel'>
29
+ <StoneOutlet>{children}</StoneOutlet>
30
+ </div>
31
+ </div>
32
+ </main>
33
+ <footer className='mt-24'>
34
+ <div className='container'>
35
+ <p className='px-24 text-muted'>2025 Stone.js &copy; Noowow Labs</p>
36
+ </div>
37
+ </footer>
38
+ </>
39
+ )
40
+ }
41
+ }
@@ -0,0 +1,39 @@
1
+ import './SecurityLayout.css'
2
+ import { JSX } from 'react'
3
+ import { PageLayout, IPageLayout, PageLayoutRenderContext, StoneOutlet } from '@stone-js/use-react'
4
+
5
+ /**
6
+ * Security Layout component.
7
+ */
8
+ @PageLayout({ name: 'security' })
9
+ export class SecurityLayout implements IPageLayout {
10
+ /**
11
+ * Render the component.
12
+ *
13
+ * @param options - The options for rendering the component.
14
+ * @returns The rendered component.
15
+ */
16
+ render ({ children }: PageLayoutRenderContext): JSX.Element {
17
+ return (
18
+ <>
19
+ <header className='mt-64'>
20
+ <div className='container'>
21
+ <p className='pa-24'>
22
+ <img src='/logo.png' className='logo' alt='Stone.js Logo' />
23
+ </p>
24
+ </div>
25
+ </header>
26
+ <main>
27
+ <div className='container'>
28
+ <StoneOutlet>{children}</StoneOutlet>
29
+ </div>
30
+ </main>
31
+ <footer className='mt-24'>
32
+ <div className='container'>
33
+ <p className='px-24 text-muted'>2025 Stone.js &copy; Noowow Labs</p>
34
+ </div>
35
+ </footer>
36
+ </>
37
+ )
38
+ }
39
+ }