@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,48 @@
|
|
|
1
|
+
import { JSX } from 'react'
|
|
2
|
+
import { UserInput } from '../../models/User'
|
|
3
|
+
import { UserService } from '../../services/UserService'
|
|
4
|
+
import { UserForm } from '../../components/UserForm/UserForm'
|
|
5
|
+
import { IPage, Page, ReactIncomingEvent, StoneLink } from '@stone-js/use-react'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Create User Page component.
|
|
9
|
+
*/
|
|
10
|
+
@Page('/users/create')
|
|
11
|
+
export class CreateUserPage implements IPage<ReactIncomingEvent> {
|
|
12
|
+
private readonly userService: UserService
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Create a new Update User Page component.
|
|
16
|
+
*
|
|
17
|
+
* @param userService - The user service.
|
|
18
|
+
*/
|
|
19
|
+
constructor ({ userService }: { userService: UserService }) {
|
|
20
|
+
this.userService = userService
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Render the component.
|
|
25
|
+
*
|
|
26
|
+
* @param options - The options for rendering the component.
|
|
27
|
+
* @returns The rendered component.
|
|
28
|
+
*/
|
|
29
|
+
render (): JSX.Element {
|
|
30
|
+
return (
|
|
31
|
+
<>
|
|
32
|
+
<h1>User form</h1>
|
|
33
|
+
<UserForm onSubmit={this.saveUser.bind(this)} />
|
|
34
|
+
<StoneLink to='/users'>Go to users</StoneLink>
|
|
35
|
+
</>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Save the user.
|
|
41
|
+
*
|
|
42
|
+
* @param user - The user
|
|
43
|
+
*/
|
|
44
|
+
private async saveUser (user: UserInput): Promise<void> {
|
|
45
|
+
console.log('user saved', user)
|
|
46
|
+
await this.userService.create(user)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { JSX } from 'react'
|
|
2
|
+
import { User } from '../../models/User'
|
|
3
|
+
import { isNotEmpty } from '@stone-js/core'
|
|
4
|
+
import { UserService } from '../../services/UserService'
|
|
5
|
+
import { IPage, Page, ReactIncomingEvent, PageRenderContext, StoneLink } from '@stone-js/use-react'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Show User Page options.
|
|
9
|
+
*/
|
|
10
|
+
export interface ShowUserPageOptions {
|
|
11
|
+
userService: UserService
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Show User Page component.
|
|
16
|
+
*/
|
|
17
|
+
@Page('/users/:user@id(\\d+)', { bindings: { user: 'userService@findBy' } })
|
|
18
|
+
export class ShowUserPage implements IPage<ReactIncomingEvent> {
|
|
19
|
+
private readonly userService: UserService
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Create a new Show User Page component.
|
|
23
|
+
*
|
|
24
|
+
* @param options - The options to create the Show User Page component.
|
|
25
|
+
*/
|
|
26
|
+
constructor ({ userService }: ShowUserPageOptions) {
|
|
27
|
+
this.userService = userService
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Render the component.
|
|
32
|
+
*
|
|
33
|
+
* @param options - The options for rendering the component.
|
|
34
|
+
* @returns The rendered component.
|
|
35
|
+
*/
|
|
36
|
+
render ({ event }: PageRenderContext): JSX.Element {
|
|
37
|
+
const user = event.get<User>('user')
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<>
|
|
41
|
+
<h1>Show user</h1>
|
|
42
|
+
<p>Name: {user?.name}</p>
|
|
43
|
+
<p>Email: {user?.email}</p>
|
|
44
|
+
<StoneLink to={`/users/${String(user?.id)}/edit`}>Edit</StoneLink>
|
|
45
|
+
<button onClick={() => this.deleteUser(user)}>Delete</button>
|
|
46
|
+
<StoneLink to='/users'>Go to users</StoneLink>
|
|
47
|
+
</>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Delete the user.
|
|
53
|
+
*
|
|
54
|
+
* @param container - The container.
|
|
55
|
+
* @param user - The user
|
|
56
|
+
*/
|
|
57
|
+
private deleteUser (user?: User): void {
|
|
58
|
+
if (isNotEmpty<User>(user) && window.confirm('Are you sure you want to delete this user?')) {
|
|
59
|
+
void this.userService.delete(user.id).catch(() => {})
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { JSX } from 'react'
|
|
2
|
+
import { User, UserInput } from '../../models/User'
|
|
3
|
+
import { UserService } from '../../services/UserService'
|
|
4
|
+
import { UserForm } from '../../components/UserForm/UserForm'
|
|
5
|
+
import { IPage, Page, ReactIncomingEvent, PageRenderContext, StoneLink } from '@stone-js/use-react'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Update User Page options.
|
|
9
|
+
*/
|
|
10
|
+
export interface UpdateUserPageOptions {
|
|
11
|
+
userService: UserService
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Update User Page component.
|
|
16
|
+
*/
|
|
17
|
+
@Page('/users/:user@id(\\d+)/edit', { bindings: { user: 'userService@findBy' } })
|
|
18
|
+
export class UpdateUserPage implements IPage<ReactIncomingEvent> {
|
|
19
|
+
private readonly userService: UserService
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Create a new Update User Page component.
|
|
23
|
+
*
|
|
24
|
+
* @param userService - The user service.
|
|
25
|
+
*/
|
|
26
|
+
constructor ({ userService }: UpdateUserPageOptions) {
|
|
27
|
+
this.userService = userService
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Render the component.
|
|
32
|
+
*
|
|
33
|
+
* @param options - The options for rendering the component.
|
|
34
|
+
* @returns The rendered component.
|
|
35
|
+
*/
|
|
36
|
+
render ({ event }: PageRenderContext): JSX.Element {
|
|
37
|
+
const user = event.get<User>('user')
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<>
|
|
41
|
+
<h1>Update user</h1>
|
|
42
|
+
<UserForm user={user} onSubmit={async (userInput) => await this.saveUser(user?.id ?? 0, userInput)} />
|
|
43
|
+
<StoneLink to={`/users/${String(user?.id)}`}>Back to user</StoneLink>
|
|
44
|
+
<StoneLink to='/users'>Go to users</StoneLink>
|
|
45
|
+
</>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Save the user.
|
|
51
|
+
*
|
|
52
|
+
* @param user - The user
|
|
53
|
+
*/
|
|
54
|
+
private async saveUser (id: number, user: UserInput): Promise<void> {
|
|
55
|
+
await this.userService.update(id, user)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { JSX } from 'react'
|
|
2
|
+
import { User } from '../../models/User'
|
|
3
|
+
import { UserService } from '../../services/UserService'
|
|
4
|
+
import { IPage, Page, ReactIncomingEvent, PageRenderContext, StoneLink } from '@stone-js/use-react'
|
|
5
|
+
|
|
6
|
+
export interface UserPageOptions {
|
|
7
|
+
userService: UserService
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* User Page component.
|
|
12
|
+
*/
|
|
13
|
+
@Page('/users')
|
|
14
|
+
export class UserPage implements IPage<ReactIncomingEvent> {
|
|
15
|
+
private readonly userService: UserService
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Create a new Update User Page component.
|
|
19
|
+
*
|
|
20
|
+
* @param userService - The user service.
|
|
21
|
+
*/
|
|
22
|
+
constructor ({ userService }: UserPageOptions) {
|
|
23
|
+
this.userService = userService
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Handle the incoming event.
|
|
28
|
+
*
|
|
29
|
+
* @param event - The incoming event.
|
|
30
|
+
* @returns The event data.
|
|
31
|
+
*/
|
|
32
|
+
async handle (event: ReactIncomingEvent): Promise<User[]> {
|
|
33
|
+
return await this.userService.list(event.get<number>('limit', 10))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Render the component.
|
|
38
|
+
*
|
|
39
|
+
* @param options - The options for rendering the component.
|
|
40
|
+
* @returns The rendered component.
|
|
41
|
+
*/
|
|
42
|
+
render ({ data }: PageRenderContext<User[]>): JSX.Element {
|
|
43
|
+
return (
|
|
44
|
+
<>
|
|
45
|
+
<h1>Users</h1>
|
|
46
|
+
<ul>
|
|
47
|
+
{data?.map(user => (
|
|
48
|
+
<li key={user.id}>
|
|
49
|
+
<StoneLink to={`/users/${user.id}`}>{user.name}</StoneLink>
|
|
50
|
+
</li>
|
|
51
|
+
))}
|
|
52
|
+
</ul>
|
|
53
|
+
<p><StoneLink to='/users/create'>New User</StoneLink></p>
|
|
54
|
+
</>
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import axios, { AxiosInstance } from 'axios'
|
|
2
|
+
import { AxiosClient } from '../clients/AxiosClient'
|
|
3
|
+
import { IBlueprint, IContainer, IServiceProvider, Provider } from '@stone-js/core'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* App Service Provider
|
|
7
|
+
*/
|
|
8
|
+
@Provider()
|
|
9
|
+
export class AppServiceProvider implements IServiceProvider {
|
|
10
|
+
/**
|
|
11
|
+
* Create a new instance of AppServiceProvider
|
|
12
|
+
*
|
|
13
|
+
* @param options
|
|
14
|
+
*/
|
|
15
|
+
constructor (private readonly container: IContainer) {}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Register services to the container
|
|
19
|
+
*/
|
|
20
|
+
register (): void {
|
|
21
|
+
this.container
|
|
22
|
+
.instanceIf('axios', this.getAxiosInstance(this.container))
|
|
23
|
+
.singletonIf(AxiosClient, (container) => {
|
|
24
|
+
return new AxiosClient({
|
|
25
|
+
axios: container.make('axios'),
|
|
26
|
+
event: container.make('event'),
|
|
27
|
+
tokenService: container.make('tokenService')
|
|
28
|
+
})
|
|
29
|
+
})
|
|
30
|
+
.alias(AxiosClient, ['axiosClient', 'httpClient'])
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Get Axios instance
|
|
35
|
+
*
|
|
36
|
+
* @param container - The container
|
|
37
|
+
* @returns The Axios instance
|
|
38
|
+
*/
|
|
39
|
+
private getAxiosInstance (container: IContainer): AxiosInstance {
|
|
40
|
+
const baseURL = container.make<IBlueprint>('blueprint').get<string>('app.api.baseURL', 'http://localhost:8080')
|
|
41
|
+
return axios.create({ baseURL })
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Service } from '@stone-js/core'
|
|
2
|
+
import { CommentClient } from '../clients/CommentClient'
|
|
3
|
+
import { Comment, CommentInput } from '../models/Comment'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Comment Service Options
|
|
7
|
+
*/
|
|
8
|
+
export interface CommentServiceOptions {
|
|
9
|
+
commentClient: CommentClient
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Comment Service
|
|
14
|
+
*
|
|
15
|
+
* @Service() decorator is used to define a new service
|
|
16
|
+
* @Service() is an alias of @Stone() decorator.
|
|
17
|
+
* The alias is required to get benefits of desctructuring Dependency Injection.
|
|
18
|
+
* And because the front-end class will be minified, we need to use alias to keep the class name.
|
|
19
|
+
*/
|
|
20
|
+
@Service({ alias: 'commentService' })
|
|
21
|
+
export class CommentService {
|
|
22
|
+
private readonly commentClient: CommentClient
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Create a new Comment Service
|
|
26
|
+
*/
|
|
27
|
+
constructor ({ commentClient }: CommentServiceOptions) {
|
|
28
|
+
this.commentClient = commentClient
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* List comments
|
|
33
|
+
*
|
|
34
|
+
* @param postId - The id of the post to list comments
|
|
35
|
+
* @param limit - The limit of comments to list
|
|
36
|
+
*/
|
|
37
|
+
async list (postId: number, limit: number = 10): Promise<Comment[]> {
|
|
38
|
+
return await this.commentClient.list(postId, limit)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Create a comment
|
|
43
|
+
*
|
|
44
|
+
* @param postId - The id of the post to create the comment for
|
|
45
|
+
* @param comment - The comment to create
|
|
46
|
+
*/
|
|
47
|
+
async create (postId: number, comment: CommentInput): Promise<void> {
|
|
48
|
+
await this.commentClient.create(postId, comment)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Delete a comment
|
|
53
|
+
*
|
|
54
|
+
* @param id - The id of the comment to delete
|
|
55
|
+
*/
|
|
56
|
+
async delete (id: number): Promise<void> {
|
|
57
|
+
await this.commentClient.delete(id)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Service } from '@stone-js/core'
|
|
2
|
+
import { Post, PostInput } from '../models/Post'
|
|
3
|
+
import { PostClient } from '../clients/PostClient'
|
|
4
|
+
import { PostNotFoundError } from '../errors/PostNotFoundError'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Post Service Options
|
|
8
|
+
*/
|
|
9
|
+
export interface PostServiceOptions {
|
|
10
|
+
postClient: PostClient
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Post Service
|
|
15
|
+
*
|
|
16
|
+
* @Service() decorator is used to define a new service
|
|
17
|
+
* @Service() is an alias of @Stone() decorator.
|
|
18
|
+
* The alias is required to get benefits of desctructuring Dependency Injection.
|
|
19
|
+
* And because the front-end class will be minified, we need to use alias to keep the class name.
|
|
20
|
+
*/
|
|
21
|
+
@Service({ alias: 'postService' })
|
|
22
|
+
export class PostService {
|
|
23
|
+
private readonly postClient: PostClient
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Create a new Post Service
|
|
27
|
+
*/
|
|
28
|
+
constructor ({ postClient }: PostServiceOptions) {
|
|
29
|
+
this.postClient = postClient
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* List posts
|
|
34
|
+
*
|
|
35
|
+
* @param limit - The limit of posts to list
|
|
36
|
+
*/
|
|
37
|
+
async list (limit: number = 10): Promise<Post[]> {
|
|
38
|
+
return await this.postClient.list(limit)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* List posts by author
|
|
43
|
+
*
|
|
44
|
+
* @param id - The id of the author to list posts
|
|
45
|
+
* @param limit - The limit of posts to list
|
|
46
|
+
*/
|
|
47
|
+
async listbyAuthor (id: number, limit: number = 10): Promise<Post[]> {
|
|
48
|
+
return await this.postClient.listByAuthor(id, limit)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Find a post
|
|
53
|
+
*
|
|
54
|
+
* @param conditions - The conditions to find the post
|
|
55
|
+
* @returns The found post
|
|
56
|
+
*/
|
|
57
|
+
async find (conditions: Record<string, any>): Promise<Post> {
|
|
58
|
+
try {
|
|
59
|
+
return await this.postClient.find(conditions.id)
|
|
60
|
+
} catch (error: any) {
|
|
61
|
+
if (error.status === 404) {
|
|
62
|
+
throw new PostNotFoundError(error.message, { cause: error })
|
|
63
|
+
} else {
|
|
64
|
+
throw error
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Find a post by key
|
|
71
|
+
*
|
|
72
|
+
* @param key - The key to find the post
|
|
73
|
+
* @param value - The value to find the post
|
|
74
|
+
* @returns The found post
|
|
75
|
+
* @throws PostNotFoundError
|
|
76
|
+
*/
|
|
77
|
+
async findBy (key: string, value: string): Promise<Post | undefined> {
|
|
78
|
+
return await this.find({ [key]: value })
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Create a post
|
|
83
|
+
*
|
|
84
|
+
* @param post - The post to create
|
|
85
|
+
*/
|
|
86
|
+
async create (post: PostInput): Promise<Post> {
|
|
87
|
+
return await this.postClient.create(post)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Update a post
|
|
92
|
+
*
|
|
93
|
+
* @param id - The id of the post to update
|
|
94
|
+
* @param post - The post data to update
|
|
95
|
+
*/
|
|
96
|
+
async update (id: number, post: PostInput): Promise<Post> {
|
|
97
|
+
return await this.postClient.update(id, post)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Delete a post
|
|
102
|
+
*
|
|
103
|
+
* @param id - The id of the post to delete
|
|
104
|
+
*/
|
|
105
|
+
async delete (id: number): Promise<void> {
|
|
106
|
+
await this.postClient.delete(id)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Service } from '@stone-js/core'
|
|
2
|
+
import { TokenService } from './TokenService'
|
|
3
|
+
import { SecurityClient } from '../clients/SecurityClient'
|
|
4
|
+
import { UserChangePassword, UserLogin, UserRegister } from '../models/User'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Security Service Options
|
|
8
|
+
*/
|
|
9
|
+
export interface SecurityServiceOptions {
|
|
10
|
+
tokenService: TokenService
|
|
11
|
+
securityClient: SecurityClient
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Security Service
|
|
16
|
+
*
|
|
17
|
+
* @Service() decorator is used to define a new service
|
|
18
|
+
* @Service() is an alias of @Stone() decorator.
|
|
19
|
+
* The alias is required to get benefits of desctructuring Dependency Injection.
|
|
20
|
+
* And because the front-end class will be minified, we need to use alias to keep the class name.
|
|
21
|
+
*/
|
|
22
|
+
@Service({ alias: 'securityService' })
|
|
23
|
+
export class SecurityService {
|
|
24
|
+
private readonly tokenService: TokenService
|
|
25
|
+
private readonly securityClient: SecurityClient
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Create a new Security Service
|
|
29
|
+
*/
|
|
30
|
+
constructor ({ tokenService, securityClient }: SecurityServiceOptions) {
|
|
31
|
+
this.tokenService = tokenService
|
|
32
|
+
this.securityClient = securityClient
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Login a user
|
|
37
|
+
*
|
|
38
|
+
* @param user - The user to login
|
|
39
|
+
* @returns The user token
|
|
40
|
+
*/
|
|
41
|
+
async login (user: UserLogin): Promise<void> {
|
|
42
|
+
const token = await this.securityClient.login(user)
|
|
43
|
+
this.tokenService.saveToken(token)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Logout a user
|
|
48
|
+
*/
|
|
49
|
+
async logout (): Promise<void> {
|
|
50
|
+
await this.securityClient.logout()
|
|
51
|
+
this.tokenService.removeToken()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Register a user
|
|
56
|
+
*
|
|
57
|
+
* @param user - The user to register
|
|
58
|
+
*/
|
|
59
|
+
async register (user: UserRegister): Promise<void> {
|
|
60
|
+
await this.securityClient.register(user)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Change the user password
|
|
65
|
+
*
|
|
66
|
+
* @param password - The password to change
|
|
67
|
+
*/
|
|
68
|
+
async changePassword (password: UserChangePassword): Promise<void> {
|
|
69
|
+
await this.securityClient.changePassword(password)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Check if the user is authenticated
|
|
74
|
+
*
|
|
75
|
+
* @returns True if the user is authenticated, false otherwise
|
|
76
|
+
*/
|
|
77
|
+
isAuthenticated (): boolean {
|
|
78
|
+
return this.tokenService.isAuthenticated()
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { Axios } from 'axios'
|
|
2
|
+
import { UserToken } from '../models/User'
|
|
3
|
+
import { ReactIncomingEvent } from '@stone-js/use-react'
|
|
4
|
+
import { IContainer, isNotEmpty, Service } from '@stone-js/core'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Token Service Options
|
|
8
|
+
*/
|
|
9
|
+
export interface TokenServiceOptions {
|
|
10
|
+
axios: Axios
|
|
11
|
+
container: IContainer
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Token Service
|
|
16
|
+
*
|
|
17
|
+
* @Service() decorator is used to define a new service
|
|
18
|
+
* @Service() is an alias of @Stone() decorator.
|
|
19
|
+
* The alias is required to get benefits of desctructuring Dependency Injection.
|
|
20
|
+
* And because the front-end class will be minified, we need to use alias to keep the class name.
|
|
21
|
+
*/
|
|
22
|
+
@Service({ alias: 'tokenService' })
|
|
23
|
+
export class TokenService {
|
|
24
|
+
private readonly axios: Axios
|
|
25
|
+
private readonly container: IContainer
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Create a new Token Service
|
|
29
|
+
*/
|
|
30
|
+
constructor ({ container, axios }: TokenServiceOptions) {
|
|
31
|
+
this.axios = axios
|
|
32
|
+
this.container = container
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Refresh the user token
|
|
37
|
+
*/
|
|
38
|
+
async refresh (): Promise<void> {
|
|
39
|
+
const headers = {
|
|
40
|
+
Accept: 'application/json',
|
|
41
|
+
'Content-Type': 'application/json',
|
|
42
|
+
Authorization: `Bearer ${String(this.getAccessToken())}`
|
|
43
|
+
}
|
|
44
|
+
const response = await this.axios.post<UserToken>('/refresh', {}, { headers })
|
|
45
|
+
|
|
46
|
+
this.saveToken(response.data)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Set the token
|
|
51
|
+
*
|
|
52
|
+
* The event must be resolved on demand
|
|
53
|
+
* because the event is not available at the time of service creation.
|
|
54
|
+
* The event is available only when the request is made.
|
|
55
|
+
*
|
|
56
|
+
* @param token - The token to set
|
|
57
|
+
*/
|
|
58
|
+
saveToken (token: UserToken): void {
|
|
59
|
+
this.container.make<ReactIncomingEvent>('event').cookies.add(
|
|
60
|
+
'token',
|
|
61
|
+
{ ...token, createdAt: Date.now() },
|
|
62
|
+
{
|
|
63
|
+
path: '/',
|
|
64
|
+
secure: true,
|
|
65
|
+
httpOnly: false,
|
|
66
|
+
maxAge: token.expiresIn
|
|
67
|
+
}
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Remove the token
|
|
73
|
+
*/
|
|
74
|
+
removeToken (): void {
|
|
75
|
+
this.container.make<ReactIncomingEvent>('event').cookies.remove(
|
|
76
|
+
'token',
|
|
77
|
+
{
|
|
78
|
+
path: '/',
|
|
79
|
+
secure: true,
|
|
80
|
+
httpOnly: false
|
|
81
|
+
}
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Get the token
|
|
87
|
+
*
|
|
88
|
+
* The event must be resolved on demand
|
|
89
|
+
* because the event is not available at the time of service creation.
|
|
90
|
+
* The event is available only when the request is made.
|
|
91
|
+
*
|
|
92
|
+
* @returns The token
|
|
93
|
+
*/
|
|
94
|
+
getToken (): UserToken | undefined {
|
|
95
|
+
return this.container.make<ReactIncomingEvent>('event').cookies.getValue('token')
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get the access token
|
|
100
|
+
*
|
|
101
|
+
* @returns The access token
|
|
102
|
+
*/
|
|
103
|
+
getAccessToken (): string | undefined {
|
|
104
|
+
return this.getToken()?.accessToken
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Check if the user is authenticated
|
|
109
|
+
*
|
|
110
|
+
* @returns True if the user is authenticated, false otherwise
|
|
111
|
+
*/
|
|
112
|
+
isAuthenticated (): boolean {
|
|
113
|
+
const token = this.getToken()
|
|
114
|
+
return isNotEmpty<UserToken>(token) && (token.createdAt + (token.expiresIn * 1000)) > Date.now()
|
|
115
|
+
}
|
|
116
|
+
}
|