@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.
- package/LICENSE +21 -0
- package/README.md +101 -0
- package/basic-react-declarative/LICENSE +21 -0
- package/basic-react-declarative/README.md +39 -0
- package/basic-react-declarative/app/Application.tsx +89 -0
- package/basic-react-declarative/assets/css/index.css +26 -0
- package/basic-react-declarative/package.json +39 -0
- package/basic-react-declarative/public/logo.png +0 -0
- package/basic-react-declarative/tests/Application.spec.ts +96 -0
- package/basic-react-declarative/tests/__snapshots__/Application.spec.ts.snap +3 -0
- package/basic-react-declarative/tsconfig.json +33 -0
- package/basic-react-declarative/vitest.config.ts +24 -0
- package/basic-react-imperative/LICENSE +21 -0
- package/basic-react-imperative/README.md +39 -0
- package/basic-react-imperative/app/Application.tsx +89 -0
- package/basic-react-imperative/assets/css/index.css +26 -0
- package/basic-react-imperative/package.json +39 -0
- package/basic-react-imperative/public/logo.png +0 -0
- package/basic-react-imperative/tests/Application.spec.ts +80 -0
- package/basic-react-imperative/tests/__snapshots__/Application.spec.ts.snap +3 -0
- package/basic-react-imperative/tsconfig.json +33 -0
- package/basic-react-imperative/vitest.config.ts +24 -0
- package/basic-service-declarative/LICENSE +21 -0
- package/basic-service-declarative/README.md +39 -0
- package/basic-service-declarative/app/Application.ts +56 -0
- package/basic-service-declarative/package.json +34 -0
- package/basic-service-declarative/tests/Application.spec.ts +60 -0
- package/basic-service-declarative/tsconfig.json +25 -0
- package/basic-service-declarative/vitest.config.ts +24 -0
- package/basic-service-imperative/LICENSE +21 -0
- package/basic-service-imperative/README.md +39 -0
- package/basic-service-imperative/app/Application.ts +60 -0
- package/basic-service-imperative/package.json +34 -0
- package/basic-service-imperative/tests/Application.spec.ts +52 -0
- package/basic-service-imperative/tsconfig.json +25 -0
- package/basic-service-imperative/vitest.config.ts +24 -0
- package/continuum-showcase/README.md +44 -0
- package/continuum-showcase/app/env.d.ts +34 -0
- package/continuum-showcase/app/layouts/MainLayout.tsx +20 -0
- package/continuum-showcase/app/pages/BlogPostPage.tsx +62 -0
- package/continuum-showcase/app/pages/HomePage.tsx +58 -0
- package/continuum-showcase/package.json +25 -0
- package/continuum-showcase/stone.config.mjs +20 -0
- package/full-react-declarative/.env.example +1 -0
- package/full-react-declarative/.env.public.example +1 -0
- package/full-react-declarative/LICENSE +21 -0
- package/full-react-declarative/README.md +39 -0
- package/full-react-declarative/app/Application.ts +85 -0
- package/full-react-declarative/app/clients/AxiosClient.ts +136 -0
- package/full-react-declarative/app/clients/CommentClient.ts +61 -0
- package/full-react-declarative/app/clients/PostClient.ts +90 -0
- package/full-react-declarative/app/clients/SecurityClient.ts +66 -0
- package/full-react-declarative/app/clients/UserClient.ts +97 -0
- package/full-react-declarative/app/components/ChangePasswordForm/ChangePasswordForm.tsx +50 -0
- package/full-react-declarative/app/components/CommentForm/CommentForm.tsx +37 -0
- package/full-react-declarative/app/components/CommentItem/CommentItem.tsx +42 -0
- package/full-react-declarative/app/components/CommentWidget/CommentWidget.tsx +95 -0
- package/full-react-declarative/app/components/LoginForm/LoginForm.css +0 -0
- package/full-react-declarative/app/components/LoginForm/LoginForm.tsx +71 -0
- package/full-react-declarative/app/components/PostDetails/PostDetails.tsx +44 -0
- package/full-react-declarative/app/components/PostForm/PostForm.css +0 -0
- package/full-react-declarative/app/components/PostForm/PostForm.tsx +47 -0
- package/full-react-declarative/app/components/PostItem/PostItem.css +0 -0
- package/full-react-declarative/app/components/PostItem/PostItem.tsx +34 -0
- package/full-react-declarative/app/components/RegisterForm/RegisterForm.tsx +110 -0
- package/full-react-declarative/app/components/UserForm/UserForm.tsx +47 -0
- package/full-react-declarative/app/configurations/AppConfiguration.ts +17 -0
- package/full-react-declarative/app/error-pages/DefaultErrorPage/DefaultErrorPage.css +0 -0
- package/full-react-declarative/app/error-pages/DefaultErrorPage/DefaultErrorPage.tsx +52 -0
- package/full-react-declarative/app/error-pages/ForbiddenErrorPage/ForbiddenErrorPage.css +0 -0
- package/full-react-declarative/app/error-pages/ForbiddenErrorPage/ForbiddenErrorPage.tsx +53 -0
- package/full-react-declarative/app/error-pages/NotFoundErrorPage/NotFoundErrorPage.css +0 -0
- package/full-react-declarative/app/error-pages/NotFoundErrorPage/NotFoundErrorPage.tsx +54 -0
- package/full-react-declarative/app/error-pages/UnauthorizedErrorPage/UnauthorizedErrorPage.css +0 -0
- package/full-react-declarative/app/error-pages/UnauthorizedErrorPage/UnauthorizedErrorPage.tsx +53 -0
- package/full-react-declarative/app/errors/ForbiddenError.ts +11 -0
- package/full-react-declarative/app/errors/PostNotFoundError.ts +11 -0
- package/full-react-declarative/app/errors/UnauthorizedError.ts +11 -0
- package/full-react-declarative/app/errors/UserNotFoundError.ts +11 -0
- package/full-react-declarative/app/events/UserEvent.ts +18 -0
- package/full-react-declarative/app/layout/AppLayout/AppLayout.css +20 -0
- package/full-react-declarative/app/layout/AppLayout/AppLayout.tsx +101 -0
- package/full-react-declarative/app/layout/ErrorLayout/ErrorLayout.css +0 -0
- package/full-react-declarative/app/layout/ErrorLayout/ErrorLayout.tsx +41 -0
- package/full-react-declarative/app/layout/SecurityLayout/SecurityLayout.css +0 -0
- package/full-react-declarative/app/layout/SecurityLayout/SecurityLayout.tsx +39 -0
- package/full-react-declarative/app/middleware/AuthMiddleware.ts +85 -0
- package/full-react-declarative/app/models/Comment.ts +31 -0
- package/full-react-declarative/app/models/Post.ts +22 -0
- package/full-react-declarative/app/models/User.ts +62 -0
- package/full-react-declarative/app/pages/home/HomePage.tsx +44 -0
- package/full-react-declarative/app/pages/login/LoginPage.css +0 -0
- package/full-react-declarative/app/pages/login/LoginPage.tsx +73 -0
- package/full-react-declarative/app/pages/posts/CreatePostPage/CreatePostPage.css +0 -0
- package/full-react-declarative/app/pages/posts/CreatePostPage/CreatePostPage.tsx +67 -0
- package/full-react-declarative/app/pages/posts/PostPage/PostPage.tsx +60 -0
- package/full-react-declarative/app/pages/posts/ShowPostPage/ShowPostPage.tsx +83 -0
- package/full-react-declarative/app/pages/posts/UpdatePostPage/UpdatePostPage.tsx +77 -0
- package/full-react-declarative/app/pages/register/RegisterPage.tsx +68 -0
- package/full-react-declarative/app/pages/users/CreateUserPage.tsx +48 -0
- package/full-react-declarative/app/pages/users/ShowUserPage.tsx +62 -0
- package/full-react-declarative/app/pages/users/UpdateUserPage.tsx +57 -0
- package/full-react-declarative/app/pages/users/UserPage.tsx +57 -0
- package/full-react-declarative/app/providers/AppServiceProvider.ts +43 -0
- package/full-react-declarative/app/services/CommentService.ts +59 -0
- package/full-react-declarative/app/services/PostService.ts +108 -0
- package/full-react-declarative/app/services/SecurityService.ts +80 -0
- package/full-react-declarative/app/services/TokenService.ts +116 -0
- package/full-react-declarative/app/services/UserService.ts +126 -0
- package/full-react-declarative/app/utils.ts +17 -0
- package/full-react-declarative/assets/css/index.css +301 -0
- package/full-react-declarative/assets/img/logo.png +0 -0
- package/full-react-declarative/package.json +46 -0
- package/full-react-declarative/public/logo.png +0 -0
- package/full-react-declarative/public/vite.svg +1 -0
- package/full-react-declarative/stone.config.mjs +12 -0
- package/full-react-declarative/tsconfig.json +29 -0
- package/full-react-declarative/vitest.config.ts +24 -0
- package/full-react-imperative/.env.example +1 -0
- package/full-react-imperative/.env.public.example +1 -0
- package/full-react-imperative/LICENSE +21 -0
- package/full-react-imperative/README.md +39 -0
- package/full-react-imperative/app/Application.ts +79 -0
- package/full-react-imperative/app/clients/AxiosClient.ts +124 -0
- package/full-react-imperative/app/clients/CommentClient.ts +57 -0
- package/full-react-imperative/app/clients/PostClient.ts +86 -0
- package/full-react-imperative/app/clients/SecurityClient.ts +60 -0
- package/full-react-imperative/app/clients/UserClient.ts +93 -0
- package/full-react-imperative/app/clients/contracts/IAxiosClient.ts +97 -0
- package/full-react-imperative/app/clients/contracts/ICommentClient.ts +31 -0
- package/full-react-imperative/app/clients/contracts/IPostClient.ts +55 -0
- package/full-react-imperative/app/clients/contracts/ISecurityClient.ts +33 -0
- package/full-react-imperative/app/clients/contracts/IUserClient.ts +61 -0
- package/full-react-imperative/app/components/ChangePasswordForm/ChangePasswordForm.tsx +50 -0
- package/full-react-imperative/app/components/CommentForm/CommentForm.css +35 -0
- package/full-react-imperative/app/components/CommentForm/CommentForm.tsx +45 -0
- package/full-react-imperative/app/components/CommentItem/CommentItem.css +74 -0
- package/full-react-imperative/app/components/CommentItem/CommentItem.tsx +62 -0
- package/full-react-imperative/app/components/CommentWidget/CommentWidget.css +25 -0
- package/full-react-imperative/app/components/CommentWidget/CommentWidget.tsx +119 -0
- package/full-react-imperative/app/components/Dropdown/Dropdown.css +52 -0
- package/full-react-imperative/app/components/Dropdown/Dropdown.tsx +40 -0
- package/full-react-imperative/app/components/LayoutHeader/LayoutHeader.css +62 -0
- package/full-react-imperative/app/components/LayoutHeader/LayoutHeader.tsx +61 -0
- package/full-react-imperative/app/components/LayoutLeftMenu/LayoutLeftMenu.css +25 -0
- package/full-react-imperative/app/components/LayoutLeftMenu/LayoutLeftMenu.tsx +32 -0
- package/full-react-imperative/app/components/LoginForm/LoginForm.css +0 -0
- package/full-react-imperative/app/components/LoginForm/LoginForm.tsx +71 -0
- package/full-react-imperative/app/components/NotificationBadge/NotificationBadge.css +41 -0
- package/full-react-imperative/app/components/NotificationBadge/NotificationBadge.tsx +63 -0
- package/full-react-imperative/app/components/PostCard/PostCard.css +129 -0
- package/full-react-imperative/app/components/PostCard/PostCard.tsx +65 -0
- package/full-react-imperative/app/components/PostForm/PostForm.css +92 -0
- package/full-react-imperative/app/components/PostForm/PostForm.tsx +76 -0
- package/full-react-imperative/app/components/PostSkeleton/PostSkeleton.css +65 -0
- package/full-react-imperative/app/components/PostSkeleton/PostSkeleton.tsx +25 -0
- package/full-react-imperative/app/components/PostWidget/PostWidget.tsx +95 -0
- package/full-react-imperative/app/components/ProfileForm/ProfileForm.css +84 -0
- package/full-react-imperative/app/components/ProfileForm/ProfileForm.tsx +79 -0
- package/full-react-imperative/app/components/RegisterForm/RegisterForm.tsx +110 -0
- package/full-react-imperative/app/components/RightAsidePanel/RightAsidePanel.css +32 -0
- package/full-react-imperative/app/components/RightAsidePanel/RightAsidePanel.tsx +62 -0
- package/full-react-imperative/app/components/SettingsForm/SettingsForm.css +126 -0
- package/full-react-imperative/app/components/SettingsForm/SettingsForm.tsx +86 -0
- package/full-react-imperative/app/components/UserAvatar/UserAvatar.css +18 -0
- package/full-react-imperative/app/components/UserAvatar/UserAvatar.tsx +60 -0
- package/full-react-imperative/app/components/UserBadge/UserBadge.css +33 -0
- package/full-react-imperative/app/components/UserBadge/UserBadge.tsx +49 -0
- package/full-react-imperative/app/components/UserCard/UserCard.css +70 -0
- package/full-react-imperative/app/components/UserCard/UserCard.tsx +43 -0
- package/full-react-imperative/app/configurations/AppConfiguration.ts +19 -0
- package/full-react-imperative/app/error-pages/DefaultErrorPage/DefaultErrorPage.css +0 -0
- package/full-react-imperative/app/error-pages/DefaultErrorPage/DefaultErrorPage.tsx +41 -0
- package/full-react-imperative/app/error-pages/ForbiddenErrorPage/ForbiddenErrorPage.css +0 -0
- package/full-react-imperative/app/error-pages/ForbiddenErrorPage/ForbiddenErrorPage.tsx +42 -0
- package/full-react-imperative/app/error-pages/NotFoundErrorPage/NotFoundErrorPage.css +0 -0
- package/full-react-imperative/app/error-pages/NotFoundErrorPage/NotFoundErrorPage.tsx +49 -0
- package/full-react-imperative/app/error-pages/UnauthorizedErrorPage/UnauthorizedErrorPage.css +0 -0
- package/full-react-imperative/app/error-pages/UnauthorizedErrorPage/UnauthorizedErrorPage.tsx +42 -0
- package/full-react-imperative/app/errors/ForbiddenError.ts +11 -0
- package/full-react-imperative/app/errors/PostNotFoundError.ts +11 -0
- package/full-react-imperative/app/errors/UnauthorizedError.ts +11 -0
- package/full-react-imperative/app/errors/UserNotFoundError.ts +11 -0
- package/full-react-imperative/app/events/UserEvent.ts +18 -0
- package/full-react-imperative/app/layout/AppLayout/AppLayout.css +106 -0
- package/full-react-imperative/app/layout/AppLayout/AppLayout.tsx +48 -0
- package/full-react-imperative/app/layout/ErrorLayout/ErrorLayout.css +0 -0
- package/full-react-imperative/app/layout/ErrorLayout/ErrorLayout.tsx +45 -0
- package/full-react-imperative/app/layout/SecurityLayout/SecurityLayout.css +0 -0
- package/full-react-imperative/app/layout/SecurityLayout/SecurityLayout.tsx +43 -0
- package/full-react-imperative/app/layout/SettingsLayout/SettingsLayout.css +99 -0
- package/full-react-imperative/app/layout/SettingsLayout/SettingsLayout.tsx +44 -0
- package/full-react-imperative/app/middleware/AuthMiddleware.ts +56 -0
- package/full-react-imperative/app/models/Comment.ts +35 -0
- package/full-react-imperative/app/models/Post.ts +27 -0
- package/full-react-imperative/app/models/User.ts +68 -0
- package/full-react-imperative/app/pages/Settings/SettingsPage.tsx +23 -0
- package/full-react-imperative/app/pages/home/HomePage.tsx +58 -0
- package/full-react-imperative/app/pages/login/LoginPage.css +0 -0
- package/full-react-imperative/app/pages/login/LoginPage.tsx +65 -0
- package/full-react-imperative/app/pages/posts/ShowPostPage/ShowPostPage.tsx +64 -0
- package/full-react-imperative/app/pages/posts/UpdatePostPage/UpdatePostPage.tsx +56 -0
- package/full-react-imperative/app/pages/register/RegisterPage.tsx +71 -0
- package/full-react-imperative/app/pages/users/ShowUserPage/ShowUserPage.css +64 -0
- package/full-react-imperative/app/pages/users/ShowUserPage/ShowUserPage.tsx +104 -0
- package/full-react-imperative/app/pages/users/UpdateUserPage/UpdateUserPage.css +0 -0
- package/full-react-imperative/app/pages/users/UpdateUserPage/UpdateUserPage.tsx +43 -0
- package/full-react-imperative/app/pages/users/UserPage/UserPage.css +31 -0
- package/full-react-imperative/app/pages/users/UserPage/UserPage.tsx +59 -0
- package/full-react-imperative/app/pages/utils.ts +67 -0
- package/full-react-imperative/app/providers/AppServiceProvider.ts +40 -0
- package/full-react-imperative/app/services/CommentService.ts +53 -0
- package/full-react-imperative/app/services/PostService.ts +102 -0
- package/full-react-imperative/app/services/SecurityService.ts +72 -0
- package/full-react-imperative/app/services/TokenService.ts +108 -0
- package/full-react-imperative/app/services/UserService.ts +115 -0
- package/full-react-imperative/app/services/contracts/ICommentService.ts +30 -0
- package/full-react-imperative/app/services/contracts/IPostService.ts +65 -0
- package/full-react-imperative/app/services/contracts/ISecurityService.ts +39 -0
- package/full-react-imperative/app/services/contracts/ITokenService.ts +44 -0
- package/full-react-imperative/app/services/contracts/IUserService.ts +70 -0
- package/full-react-imperative/app/utils.ts +31 -0
- package/full-react-imperative/assets/css/index.css +301 -0
- package/full-react-imperative/assets/img/logo.png +0 -0
- package/full-react-imperative/package.json +48 -0
- package/full-react-imperative/public/logo.png +0 -0
- package/full-react-imperative/public/vite.svg +1 -0
- package/full-react-imperative/stone.config.mjs +12 -0
- package/full-react-imperative/tsconfig.json +29 -0
- package/full-react-imperative/vitest.config.ts +24 -0
- package/full-service-declarative/.env.example +2 -0
- package/full-service-declarative/LICENSE +21 -0
- package/full-service-declarative/README.md +65 -0
- package/full-service-declarative/app/Application.ts +327 -0
- package/full-service-declarative/app/commands/ListSessionsCommand.ts +70 -0
- package/full-service-declarative/app/commands/ListUsersCommand.ts +56 -0
- package/full-service-declarative/app/configurations/AppConfiguration.ts +52 -0
- package/full-service-declarative/app/configurations/UserLiveConfiguration.ts +28 -0
- package/full-service-declarative/app/database/DatabaseClient.ts +43 -0
- package/full-service-declarative/app/database/schema.ts +43 -0
- package/full-service-declarative/app/error-handlers/SecurityErrorHandler.ts +61 -0
- package/full-service-declarative/app/errors/CredentialsError.ts +12 -0
- package/full-service-declarative/app/events/UserEvent.ts +17 -0
- package/full-service-declarative/app/handlers/CommentEventHandler.ts +103 -0
- package/full-service-declarative/app/handlers/PostEventHandler.ts +104 -0
- package/full-service-declarative/app/handlers/SecurityEventHandler.ts +108 -0
- package/full-service-declarative/app/handlers/UserEventHandler.ts +159 -0
- package/full-service-declarative/app/listeners/UserEventListener.ts +35 -0
- package/full-service-declarative/app/middleware/AuthMiddleware.ts +54 -0
- package/full-service-declarative/app/models/Comment.ts +38 -0
- package/full-service-declarative/app/models/Post.ts +50 -0
- package/full-service-declarative/app/models/Session.ts +14 -0
- package/full-service-declarative/app/models/User.ts +77 -0
- package/full-service-declarative/app/providers/DrizzleServiceProvider.ts +59 -0
- package/full-service-declarative/app/repositories/CommentRepository.ts +155 -0
- package/full-service-declarative/app/repositories/PostRepository.ts +138 -0
- package/full-service-declarative/app/repositories/SessionRepository.ts +123 -0
- package/full-service-declarative/app/repositories/UserRepository.ts +99 -0
- package/full-service-declarative/app/services/CommentService.ts +112 -0
- package/full-service-declarative/app/services/PostService.ts +100 -0
- package/full-service-declarative/app/services/SecurityService.ts +232 -0
- package/full-service-declarative/app/services/SessionService.ts +130 -0
- package/full-service-declarative/app/services/UserService.ts +110 -0
- package/full-service-declarative/app/subscribers/UserEventSubscriber.ts +38 -0
- package/full-service-declarative/drizzle.config.ts +13 -0
- package/full-service-declarative/package.json +48 -0
- package/full-service-declarative/stone.config.mjs +12 -0
- package/full-service-declarative/tsconfig.json +25 -0
- package/full-service-declarative/vitest.config.ts +24 -0
- package/full-service-imperative/.env.example +2 -0
- package/full-service-imperative/LICENSE +21 -0
- package/full-service-imperative/README.md +65 -0
- package/full-service-imperative/app/Application.ts +317 -0
- package/full-service-imperative/app/commands/ListSessionsCommand.ts +54 -0
- package/full-service-imperative/app/commands/ListUsersCommand.ts +42 -0
- package/full-service-imperative/app/configurations/AppConfiguration.ts +44 -0
- package/full-service-imperative/app/configurations/UserLiveConfiguration.ts +26 -0
- package/full-service-imperative/app/database/DatabaseClient.ts +39 -0
- package/full-service-imperative/app/database/schema.ts +43 -0
- package/full-service-imperative/app/error-handlers/SecurityErrorHandler.ts +58 -0
- package/full-service-imperative/app/errors/CredentialsError.ts +12 -0
- package/full-service-imperative/app/events/UserEvent.ts +17 -0
- package/full-service-imperative/app/handlers/CommentEventHandler.ts +99 -0
- package/full-service-imperative/app/handlers/PostEventHandler.ts +99 -0
- package/full-service-imperative/app/handlers/SecurityEventHandler.ts +83 -0
- package/full-service-imperative/app/handlers/UserEventHandler.ts +132 -0
- package/full-service-imperative/app/listeners/UserEventListener.ts +23 -0
- package/full-service-imperative/app/middleware/AuthMiddleware.ts +44 -0
- package/full-service-imperative/app/models/Comment.ts +38 -0
- package/full-service-imperative/app/models/Post.ts +50 -0
- package/full-service-imperative/app/models/Session.ts +14 -0
- package/full-service-imperative/app/models/User.ts +77 -0
- package/full-service-imperative/app/providers/DrizzleServiceProvider.ts +56 -0
- package/full-service-imperative/app/repositories/CommentRepository.ts +148 -0
- package/full-service-imperative/app/repositories/PostRepository.ts +130 -0
- package/full-service-imperative/app/repositories/SessionRepository.ts +115 -0
- package/full-service-imperative/app/repositories/UserRepository.ts +91 -0
- package/full-service-imperative/app/repositories/contracts/ICommentRepository.ts +72 -0
- package/full-service-imperative/app/repositories/contracts/IPostRepository.ts +63 -0
- package/full-service-imperative/app/repositories/contracts/ISessionRepository.ts +65 -0
- package/full-service-imperative/app/repositories/contracts/IUserRepository.ts +55 -0
- package/full-service-imperative/app/services/CommentService.ts +109 -0
- package/full-service-imperative/app/services/PostService.ts +97 -0
- package/full-service-imperative/app/services/SecurityService.ts +224 -0
- package/full-service-imperative/app/services/SessionService.ts +124 -0
- package/full-service-imperative/app/services/UserService.ts +105 -0
- package/full-service-imperative/app/services/contracts/ICommentService.ts +62 -0
- package/full-service-imperative/app/services/contracts/IPostService.ts +53 -0
- package/full-service-imperative/app/services/contracts/ISecurityService.ts +97 -0
- package/full-service-imperative/app/services/contracts/ISessionService.ts +73 -0
- package/full-service-imperative/app/services/contracts/IUserService.ts +57 -0
- package/full-service-imperative/app/subscribers/UserEventSubscriber.ts +28 -0
- package/full-service-imperative/drizzle.config.ts +13 -0
- package/full-service-imperative/package.json +48 -0
- package/full-service-imperative/stone.config.mjs +12 -0
- package/full-service-imperative/tsconfig.json +25 -0
- package/full-service-imperative/vitest.config.ts +24 -0
- package/package.json +225 -0
- package/standard-react-declarative/LICENSE +21 -0
- package/standard-react-declarative/README.md +39 -0
- package/standard-react-declarative/app/Application.ts +45 -0
- package/standard-react-declarative/app/pages/welcome/WelcomePage.tsx +57 -0
- package/standard-react-declarative/app/services/WelcomeService.ts +38 -0
- package/standard-react-declarative/assets/css/index.css +26 -0
- package/standard-react-declarative/package.json +42 -0
- package/standard-react-declarative/tsconfig.json +33 -0
- package/standard-react-declarative/vitest.config.ts +24 -0
- package/standard-react-imperative/LICENSE +21 -0
- package/standard-react-imperative/README.md +39 -0
- package/standard-react-imperative/app/Application.ts +41 -0
- package/standard-react-imperative/app/pages/welcome/WelcomePage.tsx +50 -0
- package/standard-react-imperative/app/services/WelcomeService.ts +38 -0
- package/standard-react-imperative/assets/css/index.css +26 -0
- package/standard-react-imperative/package.json +42 -0
- package/standard-react-imperative/tsconfig.json +33 -0
- package/standard-react-imperative/vitest.config.ts +24 -0
- package/standard-service-declarative/LICENSE +21 -0
- package/standard-service-declarative/README.md +39 -0
- package/standard-service-declarative/app/Application.ts +39 -0
- package/standard-service-declarative/app/handlers/WelcomeEventHandler.ts +45 -0
- package/standard-service-declarative/app/services/WelcomeService.ts +38 -0
- package/standard-service-declarative/package.json +36 -0
- package/standard-service-declarative/tsconfig.json +25 -0
- package/standard-service-declarative/vitest.config.ts +24 -0
- package/standard-service-imperative/LICENSE +21 -0
- package/standard-service-imperative/README.md +39 -0
- package/standard-service-imperative/app/Application.ts +11 -0
- package/standard-service-imperative/app/handlers/welcomeEventHandler.ts +31 -0
- package/standard-service-imperative/app/services/welcomeService.ts +38 -0
- package/standard-service-imperative/package.json +35 -0
- package/standard-service-imperative/tsconfig.json +25 -0
- package/standard-service-imperative/vitest.config.ts +24 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ISecurityService } from '../services/contracts/ISecurityService'
|
|
2
|
+
import { IncomingHttpEvent, OutgoingHttpResponse } from '@stone-js/http-core'
|
|
3
|
+
import { defineMiddleware, FunctionalMiddleware, NextMiddleware } from '@stone-js/core'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Auth middleware Options
|
|
7
|
+
*/
|
|
8
|
+
export interface AuthMiddlewareOptions {
|
|
9
|
+
securityService: ISecurityService
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Factory Auth middleware
|
|
14
|
+
*/
|
|
15
|
+
export function factoryAuthMiddleware ({ securityService }: AuthMiddlewareOptions): FunctionalMiddleware<IncomingHttpEvent, OutgoingHttpResponse> {
|
|
16
|
+
/**
|
|
17
|
+
* Handle the incoming event
|
|
18
|
+
*
|
|
19
|
+
* @param event - The incoming event
|
|
20
|
+
* @param next - The next middleware
|
|
21
|
+
* @returns The response
|
|
22
|
+
*/
|
|
23
|
+
return async function (
|
|
24
|
+
event: IncomingHttpEvent,
|
|
25
|
+
next: NextMiddleware<IncomingHttpEvent, OutgoingHttpResponse>,
|
|
26
|
+
excludes: string[] = []
|
|
27
|
+
): Promise<OutgoingHttpResponse> {
|
|
28
|
+
const isOptionsRequest = event.isMethod('OPTIONS')
|
|
29
|
+
const isExcludedPath = excludes.includes(event.pathname)
|
|
30
|
+
|
|
31
|
+
if (!isExcludedPath && !isOptionsRequest) {
|
|
32
|
+
const token = event.get<string>('Authorization', '').replace('Bearer ', '')
|
|
33
|
+
const user = await securityService.authenticate(token, event.ip, event.userAgent)
|
|
34
|
+
event.setUserResolver(() => user)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return await next(event)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Auth middleware
|
|
43
|
+
*/
|
|
44
|
+
export const AuthMiddleware = defineMiddleware(factoryAuthMiddleware, { isFactory: true, global: true, params: [['/login', '/register']] })
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { User } from './User'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Comment Interface
|
|
5
|
+
*/
|
|
6
|
+
export interface CommentModel {
|
|
7
|
+
id: number
|
|
8
|
+
content: string
|
|
9
|
+
postId: number
|
|
10
|
+
authorId: number
|
|
11
|
+
createdAt: number
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Comment Create Model Interface
|
|
16
|
+
*/
|
|
17
|
+
export interface CommentCreateModel extends Omit<CommentModel, 'id'> {}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Comment Interface
|
|
21
|
+
*/
|
|
22
|
+
export interface Comment extends Omit<CommentModel, 'authorId'> {
|
|
23
|
+
author: User
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Comment Create Request Interface
|
|
28
|
+
* Represents a comment create request resource.
|
|
29
|
+
*/
|
|
30
|
+
export interface CommentCreateRequest {
|
|
31
|
+
content: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Comment Response Interface
|
|
36
|
+
* Represents a comment response resource.
|
|
37
|
+
*/
|
|
38
|
+
export interface CommentResponse extends Comment {}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { User } from './User'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Post Model Interface
|
|
5
|
+
*/
|
|
6
|
+
export interface PostModel {
|
|
7
|
+
id: number
|
|
8
|
+
title: string
|
|
9
|
+
content: string
|
|
10
|
+
authorId: number
|
|
11
|
+
createdAt: number
|
|
12
|
+
updatedAt: number
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Post Create Model Interface
|
|
17
|
+
*/
|
|
18
|
+
export interface PostCreateModel extends Omit<PostModel, 'id'> {}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Post Interface
|
|
22
|
+
*/
|
|
23
|
+
export interface Post extends Omit<PostModel, 'authorId'> {
|
|
24
|
+
author: User
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Post Create Request Interface
|
|
29
|
+
* Represents a post create request resource.
|
|
30
|
+
*/
|
|
31
|
+
export interface PostCreateRequest {
|
|
32
|
+
title: string
|
|
33
|
+
content: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Post Update Request Interface
|
|
38
|
+
* Represents a post update request resource.
|
|
39
|
+
*/
|
|
40
|
+
export interface PostUpdateRequest {
|
|
41
|
+
id: number
|
|
42
|
+
title: string
|
|
43
|
+
content: string
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Post Response Interface
|
|
48
|
+
* Represents a post response resource.
|
|
49
|
+
*/
|
|
50
|
+
export interface PostResponse extends Post {}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import jwt from 'jsonwebtoken'
|
|
2
|
+
import { Session } from './Session'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* User Interface
|
|
6
|
+
*/
|
|
7
|
+
export interface UserModel {
|
|
8
|
+
id: number
|
|
9
|
+
name: string
|
|
10
|
+
email: string
|
|
11
|
+
avatar?: string | null
|
|
12
|
+
password?: string | null
|
|
13
|
+
createdAt: number
|
|
14
|
+
updatedAt: number
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* User Interface
|
|
19
|
+
*/
|
|
20
|
+
export interface User extends Omit<UserModel, 'password'> {}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* User Response Interface
|
|
24
|
+
* Represents a user response resource.
|
|
25
|
+
*/
|
|
26
|
+
export interface UserResponse extends User {}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* User Request Interface
|
|
30
|
+
* Represents a user request resource.
|
|
31
|
+
*/
|
|
32
|
+
export interface UserRequest {
|
|
33
|
+
name: string
|
|
34
|
+
email: string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* User Login Interface
|
|
39
|
+
*/
|
|
40
|
+
export interface UserLogin {
|
|
41
|
+
email: string
|
|
42
|
+
password: string
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* User Register Interface
|
|
47
|
+
*/
|
|
48
|
+
export interface UserRegister {
|
|
49
|
+
name: string
|
|
50
|
+
email: string
|
|
51
|
+
password: string
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* User Change Password Interface
|
|
56
|
+
*/
|
|
57
|
+
export interface UserChangePassword {
|
|
58
|
+
password: string
|
|
59
|
+
newPassword: string
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* User Token Interface
|
|
64
|
+
*/
|
|
65
|
+
export interface UserToken {
|
|
66
|
+
expiresIn: number
|
|
67
|
+
tokenType: string
|
|
68
|
+
accessToken: string
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* User Token Payload Interface
|
|
73
|
+
*/
|
|
74
|
+
export interface UserTokenPayload extends jwt.JwtPayload {
|
|
75
|
+
user: User
|
|
76
|
+
session: Session
|
|
77
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {
|
|
2
|
+
IContainer,
|
|
3
|
+
IServiceProvider,
|
|
4
|
+
defineHookListener,
|
|
5
|
+
defineServiceProvider,
|
|
6
|
+
AdapterHookListenerContext
|
|
7
|
+
} from '@stone-js/core'
|
|
8
|
+
import { Config } from '@libsql/client'
|
|
9
|
+
import { drizzle } from 'drizzle-orm/libsql'
|
|
10
|
+
import { getClient, closeClient, createClient } from '../database/DatabaseClient'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Factory Drizzle Service Provider
|
|
14
|
+
*
|
|
15
|
+
* In this example, we are using both ServiceProvider to bind the drizzle instance to the container
|
|
16
|
+
* And AdapterHook to start and stop the drizzle client
|
|
17
|
+
*/
|
|
18
|
+
export function factoryDrizzleServiceProvider (container: IContainer): IServiceProvider {
|
|
19
|
+
return {
|
|
20
|
+
/**
|
|
21
|
+
* Register services to the container
|
|
22
|
+
*/
|
|
23
|
+
register (): void {
|
|
24
|
+
container
|
|
25
|
+
.instanceIf('drizzle', drizzle(getClient()))
|
|
26
|
+
.alias('drizzle', ['db', 'database'])
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* On start hook that will be called
|
|
33
|
+
* once when the application starts
|
|
34
|
+
*
|
|
35
|
+
* @param context - The adapter hook listener context
|
|
36
|
+
*/
|
|
37
|
+
export const startDatabase = defineHookListener(({ blueprint }: AdapterHookListenerContext): void => {
|
|
38
|
+
createClient(
|
|
39
|
+
blueprint.get<Config>('database', { url: 'file:local.db' })
|
|
40
|
+
)
|
|
41
|
+
}, { name: 'onStart' })
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* On stop hook that will be called
|
|
45
|
+
* once when the application stops
|
|
46
|
+
*
|
|
47
|
+
* @param context - The adapter hook listener context
|
|
48
|
+
*/
|
|
49
|
+
export const closeDatabase = defineHookListener((): void => {
|
|
50
|
+
closeClient()
|
|
51
|
+
}, { name: 'onStop' })
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Drizzle Service Provider
|
|
55
|
+
*/
|
|
56
|
+
export const DrizzleServiceProvider = defineServiceProvider(factoryDrizzleServiceProvider)
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { desc, eq } from 'drizzle-orm'
|
|
2
|
+
import { LibSQLDatabase } from 'drizzle-orm/libsql'
|
|
3
|
+
import { comments, users } from '../database/schema'
|
|
4
|
+
import { defineStone, isNotEmpty } from '@stone-js/core'
|
|
5
|
+
import { ICommentRepository } from './contracts/ICommentRepository'
|
|
6
|
+
import { Comment, CommentCreateModel, CommentModel } from '../models/Comment'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Comment Repository Options
|
|
10
|
+
*/
|
|
11
|
+
export interface CommentRepositoryOptions {
|
|
12
|
+
database: LibSQLDatabase
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Factory Comment Repository
|
|
17
|
+
*/
|
|
18
|
+
export function factoryCommentRepository ({ database }: CommentRepositoryOptions): ICommentRepository {
|
|
19
|
+
return {
|
|
20
|
+
/**
|
|
21
|
+
* Retrieves a list of comments with optional filtering and sorting.
|
|
22
|
+
*
|
|
23
|
+
* @param options - Optional filters (postId, authorId, limit, orderBy).
|
|
24
|
+
* @returns The list of comments.
|
|
25
|
+
*/
|
|
26
|
+
async list (options?: { postId?: number, authorId?: number, limit?: number }): Promise<Comment[]> {
|
|
27
|
+
const query = database
|
|
28
|
+
.select(this.selectWithAuthor())
|
|
29
|
+
.from(comments)
|
|
30
|
+
.innerJoin(users, eq(comments.authorId, users.id))
|
|
31
|
+
|
|
32
|
+
if (options?.postId !== undefined) {
|
|
33
|
+
await query.where(eq(comments.postId, options.postId))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (options?.authorId !== undefined) {
|
|
37
|
+
await query.where(eq(comments.authorId, options.authorId))
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
await query.orderBy(desc(comments.createdAt))
|
|
41
|
+
|
|
42
|
+
if (options?.limit !== undefined) {
|
|
43
|
+
await query.limit(options.limit)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return await query.all() as Comment[]
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Retrieves all comments created by a specific user.
|
|
51
|
+
*
|
|
52
|
+
* @param authorId - The ID of the user whose comments are being retrieved.
|
|
53
|
+
* @param limit - The number of comments to retrieve.
|
|
54
|
+
* @returns The list of comments.
|
|
55
|
+
*/
|
|
56
|
+
async listByAuthor (authorId: number, limit: number): Promise<Comment[]> {
|
|
57
|
+
return await this.list({ authorId, limit })
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Retrieves all comments for a specific post.
|
|
62
|
+
*
|
|
63
|
+
* @param postId - The ID of the post whose comments are being retrieved.
|
|
64
|
+
* @param limit - The number of comments to retrieve.
|
|
65
|
+
* @returns The list of comments.
|
|
66
|
+
*/
|
|
67
|
+
async listByPost (postId: number, limit: number): Promise<Comment[]> {
|
|
68
|
+
return await this.list({ postId, limit })
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Finds a comment by its ID.
|
|
73
|
+
*
|
|
74
|
+
* @param commentId - The ID of the comment to retrieve.
|
|
75
|
+
* @returns The comment or `undefined` if not found.
|
|
76
|
+
*/
|
|
77
|
+
async findById (commentId: number): Promise<Comment | undefined> {
|
|
78
|
+
return await database
|
|
79
|
+
.select(this.selectWithAuthor())
|
|
80
|
+
.from(comments)
|
|
81
|
+
.innerJoin(users, eq(comments.authorId, users.id))
|
|
82
|
+
.where(eq(comments.id, commentId))
|
|
83
|
+
.get() as Comment | undefined
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Creates a new comment.
|
|
88
|
+
*
|
|
89
|
+
* @param comment - The comment to create.
|
|
90
|
+
* @returns The ID of the created comment.
|
|
91
|
+
*/
|
|
92
|
+
async create (comment: CommentCreateModel): Promise<bigint | undefined> {
|
|
93
|
+
const result = await database.insert(comments).values(comment)
|
|
94
|
+
return result.lastInsertRowid
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Updates a comment by its ID.
|
|
99
|
+
*
|
|
100
|
+
* @param commentId - The ID of the comment to update.
|
|
101
|
+
* @param comment - The updated comment data.
|
|
102
|
+
* @returns The updated comment or `undefined` if not found.
|
|
103
|
+
*/
|
|
104
|
+
async update (commentId: number, comment: Partial<CommentModel>): Promise<Comment | undefined> {
|
|
105
|
+
return await database
|
|
106
|
+
.update(comments)
|
|
107
|
+
.set(comment)
|
|
108
|
+
.where(eq(comments.id, commentId))
|
|
109
|
+
.returning(this.selectWithAuthor())
|
|
110
|
+
.get() as Comment | undefined
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Deletes a comment by its ID.
|
|
115
|
+
*
|
|
116
|
+
* @param commentId - The ID of the comment to delete.
|
|
117
|
+
* @returns `true` if the comment was deleted, otherwise `false`.
|
|
118
|
+
*/
|
|
119
|
+
async delete (commentId: number): Promise<boolean> {
|
|
120
|
+
const result = await database.delete(comments).where(eq(comments.id, commentId)).run()
|
|
121
|
+
return isNotEmpty<bigint>(result.lastInsertRowid) && result.lastInsertRowid > 0
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Selects comments with author and post information.
|
|
126
|
+
*/
|
|
127
|
+
selectWithAuthor (): Record<string, any> {
|
|
128
|
+
return {
|
|
129
|
+
id: comments.id,
|
|
130
|
+
postId: comments.postId,
|
|
131
|
+
content: comments.content,
|
|
132
|
+
createdAt: comments.createdAt,
|
|
133
|
+
author: {
|
|
134
|
+
id: users.id,
|
|
135
|
+
name: users.name,
|
|
136
|
+
email: users.email,
|
|
137
|
+
createdAt: users.createdAt,
|
|
138
|
+
updatedAt: users.updatedAt
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Comment Repository
|
|
147
|
+
*/
|
|
148
|
+
export const CommentRepository = defineStone(factoryCommentRepository, { isFactory: true, singleton: true, alias: 'commentRepository' })
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { desc, eq } from 'drizzle-orm'
|
|
2
|
+
import { posts, users } from '../database/schema'
|
|
3
|
+
import { LibSQLDatabase } from 'drizzle-orm/libsql'
|
|
4
|
+
import { defineStone, isNotEmpty } from '@stone-js/core'
|
|
5
|
+
import { IPostRepository } from './contracts/IPostRepository'
|
|
6
|
+
import { Post, PostCreateModel, PostModel } from '../models/Post'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Post Repository Options
|
|
10
|
+
*/
|
|
11
|
+
export interface PostRepositoryOptions {
|
|
12
|
+
database: LibSQLDatabase
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Factory Post Repository
|
|
17
|
+
*/
|
|
18
|
+
export function factoryPostRepository ({ database }: PostRepositoryOptions): IPostRepository {
|
|
19
|
+
return {
|
|
20
|
+
/**
|
|
21
|
+
* Retrieves a list of posts with optional filtering and sorting.
|
|
22
|
+
*
|
|
23
|
+
* @param options - Optional filters (authorId, limit, orderBy).
|
|
24
|
+
* @returns The list of posts.
|
|
25
|
+
*/
|
|
26
|
+
async list (options?: { authorId?: number, limit?: number }): Promise<Post[]> {
|
|
27
|
+
const query = database
|
|
28
|
+
.select(this.selectWithAuthor())
|
|
29
|
+
.from(posts)
|
|
30
|
+
.innerJoin(users, eq(posts.authorId, users.id))
|
|
31
|
+
|
|
32
|
+
if (options?.authorId !== undefined) {
|
|
33
|
+
await query.where(eq(posts.authorId, options.authorId))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
await query.orderBy(desc(posts.createdAt))
|
|
37
|
+
|
|
38
|
+
if (options?.limit !== undefined) {
|
|
39
|
+
await query.limit(options.limit)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return await query.all() as Post[]
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Retrieves all posts created by a specific user.
|
|
47
|
+
*
|
|
48
|
+
* @param user - The user whose posts are being retrieved.
|
|
49
|
+
* @param limit - The number of posts to retrieve.
|
|
50
|
+
* @returns The list of posts.
|
|
51
|
+
*/
|
|
52
|
+
async listByAuthor (authorId: number, limit: number): Promise<Post[]> {
|
|
53
|
+
return await this.list({ authorId, limit })
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Finds a post by its ID.
|
|
58
|
+
*
|
|
59
|
+
* @param postId - The ID of the post to retrieve.
|
|
60
|
+
* @returns The post or `undefined` if not found.
|
|
61
|
+
*/
|
|
62
|
+
async findById (postId: number): Promise<Post | undefined> {
|
|
63
|
+
return await database
|
|
64
|
+
.select(this.selectWithAuthor())
|
|
65
|
+
.from(posts)
|
|
66
|
+
.innerJoin(users, eq(posts.authorId, users.id))
|
|
67
|
+
.where(eq(posts.id, postId))
|
|
68
|
+
.get() as Post | undefined
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Creates a new post.
|
|
73
|
+
*
|
|
74
|
+
* @param post - The post to create.
|
|
75
|
+
* @returns The ID of the created post.
|
|
76
|
+
*/
|
|
77
|
+
async create (post: PostCreateModel): Promise<bigint | undefined> {
|
|
78
|
+
const result = await database.insert(posts).values(post)
|
|
79
|
+
return result.lastInsertRowid
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Updates a post by its ID.
|
|
84
|
+
*
|
|
85
|
+
* @param postId - The ID of the post to update.
|
|
86
|
+
* @param post - The updated post data.
|
|
87
|
+
* @returns The updated post or `undefined` if not found.
|
|
88
|
+
*/
|
|
89
|
+
async update (postId: number, post: Partial<PostModel>): Promise<boolean> {
|
|
90
|
+
const result = await database.update(posts).set(post).where(eq(posts.id, postId))
|
|
91
|
+
return isNotEmpty<bigint>(result.lastInsertRowid) && result.lastInsertRowid > 0
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Deletes a post by its ID.
|
|
96
|
+
*
|
|
97
|
+
* @param postId - The ID of the post to delete.
|
|
98
|
+
* @returns `true` if the post was deleted, otherwise `false`.
|
|
99
|
+
*/
|
|
100
|
+
async delete (postId: number): Promise<boolean> {
|
|
101
|
+
const result = await database.delete(posts).where(eq(posts.id, postId)).run()
|
|
102
|
+
return isNotEmpty<bigint>(result.lastInsertRowid) && result.lastInsertRowid > 0
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Selects posts with author information.
|
|
107
|
+
*/
|
|
108
|
+
selectWithAuthor (): Record<string, any> {
|
|
109
|
+
return {
|
|
110
|
+
id: posts.id,
|
|
111
|
+
title: posts.title,
|
|
112
|
+
content: posts.content,
|
|
113
|
+
createdAt: posts.createdAt,
|
|
114
|
+
updatedAt: posts.updatedAt,
|
|
115
|
+
author: {
|
|
116
|
+
id: users.id,
|
|
117
|
+
name: users.name,
|
|
118
|
+
email: users.email,
|
|
119
|
+
createdAt: users.createdAt,
|
|
120
|
+
updatedAt: users.updatedAt
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Post Repository
|
|
129
|
+
*/
|
|
130
|
+
export const PostRepository = defineStone(factoryPostRepository, { isFactory: true, singleton: true, alias: 'postRepository' })
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { desc, eq } from 'drizzle-orm'
|
|
2
|
+
import { UserModel } from '../models/User'
|
|
3
|
+
import { Session } from '../models/Session'
|
|
4
|
+
import { defineStone } from '@stone-js/core'
|
|
5
|
+
import { sessions } from '../database/schema'
|
|
6
|
+
import { LibSQLDatabase } from 'drizzle-orm/libsql'
|
|
7
|
+
import { ISessionRepository } from './contracts/ISessionRepository'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Session Session Repository Options
|
|
11
|
+
*/
|
|
12
|
+
export interface SessionRepositoryOptions {
|
|
13
|
+
database: LibSQLDatabase
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Factory Session Repository
|
|
18
|
+
*/
|
|
19
|
+
export function factorySessionRepository ({ database }: SessionRepositoryOptions): ISessionRepository {
|
|
20
|
+
return {
|
|
21
|
+
/**
|
|
22
|
+
* List sessions
|
|
23
|
+
*
|
|
24
|
+
* @param limit - The limit of sessions to list
|
|
25
|
+
* @returns The list of sessions
|
|
26
|
+
*/
|
|
27
|
+
async list (limit: number): Promise<Session[]> {
|
|
28
|
+
return await database
|
|
29
|
+
.select()
|
|
30
|
+
.from(sessions)
|
|
31
|
+
.orderBy(desc(sessions.createdAt))
|
|
32
|
+
.limit(limit)
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* List sessions
|
|
37
|
+
*
|
|
38
|
+
* @param limit - The limit of sessions to list
|
|
39
|
+
* @returns The list of sessions
|
|
40
|
+
*/
|
|
41
|
+
async listByUser (user: UserModel, limit: number): Promise<Session[]> {
|
|
42
|
+
return await database
|
|
43
|
+
.select()
|
|
44
|
+
.from(sessions)
|
|
45
|
+
.where(eq(sessions.userId, user.id))
|
|
46
|
+
.orderBy(desc(sessions.createdAt))
|
|
47
|
+
.limit(limit)
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Find a session by ID
|
|
52
|
+
*
|
|
53
|
+
* @param id - The ID of the session to find
|
|
54
|
+
* @returns The session or undefined if not found
|
|
55
|
+
*/
|
|
56
|
+
async findById (id: number): Promise<Session | undefined> {
|
|
57
|
+
const result = await database.select().from(sessions).where(eq(sessions.id, id)).get()
|
|
58
|
+
return result ?? undefined
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Retrieves the latest session for a given user.
|
|
63
|
+
*
|
|
64
|
+
* @param user - The user whose last session is being retrieved.
|
|
65
|
+
* @returns The latest session or `undefined` if none exists.
|
|
66
|
+
*/
|
|
67
|
+
async getLatest (user: UserModel): Promise<Session | undefined> {
|
|
68
|
+
return await database
|
|
69
|
+
.select()
|
|
70
|
+
.from(sessions)
|
|
71
|
+
.where(eq(sessions.userId, user.id))
|
|
72
|
+
.orderBy(desc(sessions.createdAt))
|
|
73
|
+
.limit(1)
|
|
74
|
+
.get()
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Create a session
|
|
79
|
+
*
|
|
80
|
+
* @param session - The session to create
|
|
81
|
+
* @returns The ID of the created session
|
|
82
|
+
*/
|
|
83
|
+
async create (session: Omit<Session, 'id'>): Promise<Session> {
|
|
84
|
+
return await database.insert(sessions).values(session).returning().get()
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Update a session
|
|
89
|
+
*
|
|
90
|
+
* @param id - The ID of the session to update
|
|
91
|
+
* @param session - The session data to update
|
|
92
|
+
* @returns The updated session or undefined if not found
|
|
93
|
+
*/
|
|
94
|
+
async update (id: number, session: Partial<Session>): Promise<Session | undefined> {
|
|
95
|
+
const result = await database.update(sessions).set(session).where(eq(sessions.id, id)).returning().get()
|
|
96
|
+
return result ?? undefined
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Delete a session
|
|
101
|
+
*
|
|
102
|
+
* @param id - The ID of the session to delete
|
|
103
|
+
* @returns `true` if the session was deleted, `false` if the session was not found
|
|
104
|
+
*/
|
|
105
|
+
async delete (id: number): Promise<boolean> {
|
|
106
|
+
const result = await database.delete(sessions).where(eq(sessions.id, id)).run()
|
|
107
|
+
return result.rowsAffected > 0
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Session Repository
|
|
114
|
+
*/
|
|
115
|
+
export const SessionRepository = defineStone(factorySessionRepository, { isFactory: true, singleton: true, alias: 'sessionRepository' })
|