@oxyhq/services 5.10.15 → 5.11.1
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/README.md +604 -127
- package/lib/commonjs/assets/assets/icons/OxyServices.tsx +2 -2
- package/lib/commonjs/assets/assets/illustrations/HighFive.tsx +1 -1
- package/lib/commonjs/assets/icons/OxyServices.js +0 -2
- package/lib/commonjs/assets/icons/OxyServices.js.map +1 -1
- package/lib/commonjs/assets/illustrations/HighFive.js +0 -2
- package/lib/commonjs/assets/illustrations/HighFive.js.map +1 -1
- package/lib/commonjs/core/OxyServices.js +244 -26
- package/lib/commonjs/core/OxyServices.js.map +1 -1
- package/lib/commonjs/core/index.js +7 -0
- package/lib/commonjs/core/index.js.map +1 -1
- package/lib/commonjs/index.js +93 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/lib/sonner-safe.js +2 -0
- package/lib/commonjs/lib/sonner-safe.js.map +1 -1
- package/lib/commonjs/lib/sonner.js +2 -0
- package/lib/commonjs/lib/sonner.js.map +1 -1
- package/lib/commonjs/node/index.js +7 -0
- package/lib/commonjs/node/index.js.map +1 -1
- package/lib/commonjs/ui/components/Avatar.js +0 -2
- package/lib/commonjs/ui/components/Avatar.js.map +1 -1
- package/lib/commonjs/ui/components/FollowButton.js +4 -4
- package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
- package/lib/commonjs/ui/components/FontLoader.js +3 -2
- package/lib/commonjs/ui/components/FontLoader.js.map +1 -1
- package/lib/commonjs/ui/components/GroupedItem.js +7 -4
- package/lib/commonjs/ui/components/GroupedItem.js.map +1 -1
- package/lib/commonjs/ui/components/GroupedSection.js +1 -1
- package/lib/commonjs/ui/components/GroupedSection.js.map +1 -1
- package/lib/commonjs/ui/components/Header.js +0 -1
- package/lib/commonjs/ui/components/Header.js.map +1 -1
- package/lib/commonjs/ui/components/OxyLogo.js +0 -2
- package/lib/commonjs/ui/components/OxyLogo.js.map +1 -1
- package/lib/commonjs/ui/components/OxyPayButton.js +4 -5
- package/lib/commonjs/ui/components/OxyPayButton.js.map +1 -1
- package/lib/commonjs/ui/components/OxyProvider.js +4 -3
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/OxySignInButton.js +0 -1
- package/lib/commonjs/ui/components/OxySignInButton.js.map +1 -1
- package/lib/commonjs/ui/components/ProfileCard.js +0 -1
- package/lib/commonjs/ui/components/ProfileCard.js.map +1 -1
- package/lib/commonjs/ui/components/QuickActions.js +0 -2
- package/lib/commonjs/ui/components/QuickActions.js.map +1 -1
- package/lib/commonjs/ui/components/Section.js +0 -1
- package/lib/commonjs/ui/components/Section.js.map +1 -1
- package/lib/commonjs/ui/components/SectionTitle.js +0 -2
- package/lib/commonjs/ui/components/SectionTitle.js.map +1 -1
- package/lib/commonjs/ui/components/icon/FAIRWalletIcon.js +0 -2
- package/lib/commonjs/ui/components/icon/FAIRWalletIcon.js.map +1 -1
- package/lib/commonjs/ui/components/icon/OxyIcon.js +0 -2
- package/lib/commonjs/ui/components/icon/OxyIcon.js.map +1 -1
- package/lib/commonjs/ui/components/internal/GroupedPillButtons.js +0 -2
- package/lib/commonjs/ui/components/internal/GroupedPillButtons.js.map +1 -1
- package/lib/commonjs/ui/components/internal/PinInput.js +4 -3
- package/lib/commonjs/ui/components/internal/PinInput.js.map +1 -1
- package/lib/commonjs/ui/components/internal/TextField.js +3 -3
- package/lib/commonjs/ui/components/internal/TextField.js.map +1 -1
- package/lib/commonjs/ui/hooks/useAssets.js +263 -0
- package/lib/commonjs/ui/hooks/useAssets.js.map +1 -0
- package/lib/commonjs/ui/navigation/OxyRouter.js +1 -2
- package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountCenterScreen.js +0 -2
- package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountManagementDemo.js +0 -1
- package/lib/commonjs/ui/screens/AccountManagementDemo.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js +2 -2
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +5 -6
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AppInfoScreen.js +1 -2
- package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FileManagementScreen.js +631 -430
- package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PaymentGatewayScreen.js +2 -2
- package/lib/commonjs/ui/screens/PaymentGatewayScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +1 -2
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ProfileScreen.js +1 -2
- package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/RecoverAccountScreen.js +1 -2
- package/lib/commonjs/ui/screens/RecoverAccountScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SessionManagementScreen.js +1 -2
- package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SignInScreen.js +1 -2
- package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/UserLinksScreen.js +0 -2
- package/lib/commonjs/ui/screens/UserLinksScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js +1 -2
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js +1 -2
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignUpIdentityStep.js +1 -2
- package/lib/commonjs/ui/screens/internal/SignUpIdentityStep.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignUpSecurityStep.js +1 -2
- package/lib/commonjs/ui/screens/internal/SignUpSecurityStep.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignUpSummaryStep.js +0 -1
- package/lib/commonjs/ui/screens/internal/SignUpSummaryStep.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignUpWelcomeStep.js +0 -1
- package/lib/commonjs/ui/screens/internal/SignUpWelcomeStep.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js +0 -2
- package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +1 -2
- package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +1 -2
- package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js +0 -2
- package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +1 -2
- package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
- package/lib/commonjs/ui/stores/assetStore.js +225 -0
- package/lib/commonjs/ui/stores/assetStore.js.map +1 -0
- package/lib/commonjs/ui/stores/authStore.js +1 -1
- package/lib/commonjs/ui/stores/authStore.js.map +1 -1
- package/lib/commonjs/ui/stores/fileStore.js +153 -0
- package/lib/commonjs/ui/stores/fileStore.js.map +1 -0
- package/lib/commonjs/ui/stores/followStore.js +2 -2
- package/lib/commonjs/ui/stores/followStore.js.map +1 -1
- package/lib/commonjs/utils/asyncUtils.js +1 -1
- package/lib/commonjs/utils/asyncUtils.js.map +1 -1
- package/lib/commonjs/utils/errorUtils.js +19 -11
- package/lib/commonjs/utils/errorUtils.js.map +1 -1
- package/lib/commonjs/utils/hookUtils.js +1 -1
- package/lib/commonjs/utils/hookUtils.js.map +1 -1
- package/lib/commonjs/utils/loggerUtils.js.map +1 -1
- package/lib/commonjs/utils/validationUtils.js +2 -2
- package/lib/commonjs/utils/validationUtils.js.map +1 -1
- package/lib/module/assets/assets/icons/OxyServices.tsx +2 -2
- package/lib/module/assets/assets/illustrations/HighFive.tsx +1 -1
- package/lib/module/assets/icons/OxyServices.js +0 -1
- package/lib/module/assets/icons/OxyServices.js.map +1 -1
- package/lib/module/assets/illustrations/HighFive.js +0 -1
- package/lib/module/assets/illustrations/HighFive.js.map +1 -1
- package/lib/module/core/OxyServices.js +243 -25
- package/lib/module/core/OxyServices.js.map +1 -1
- package/lib/module/core/index.js +1 -1
- package/lib/module/core/index.js.map +1 -1
- package/lib/module/index.js +3 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/lib/sonner-safe.js +2 -0
- package/lib/module/lib/sonner-safe.js.map +1 -1
- package/lib/module/lib/sonner.js +3 -0
- package/lib/module/lib/sonner.js.map +1 -1
- package/lib/module/node/index.js +2 -2
- package/lib/module/node/index.js.map +1 -1
- package/lib/module/ui/components/Avatar.js +0 -1
- package/lib/module/ui/components/Avatar.js.map +1 -1
- package/lib/module/ui/components/FollowButton.js +4 -3
- package/lib/module/ui/components/FollowButton.js.map +1 -1
- package/lib/module/ui/components/FontLoader.js +3 -2
- package/lib/module/ui/components/FontLoader.js.map +1 -1
- package/lib/module/ui/components/GroupedItem.js +7 -3
- package/lib/module/ui/components/GroupedItem.js.map +1 -1
- package/lib/module/ui/components/GroupedSection.js +1 -1
- package/lib/module/ui/components/GroupedSection.js.map +1 -1
- package/lib/module/ui/components/Header.js +0 -1
- package/lib/module/ui/components/Header.js.map +1 -1
- package/lib/module/ui/components/OxyLogo.js +0 -1
- package/lib/module/ui/components/OxyLogo.js.map +1 -1
- package/lib/module/ui/components/OxyPayButton.js +4 -4
- package/lib/module/ui/components/OxyPayButton.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +4 -2
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/OxySignInButton.js +0 -1
- package/lib/module/ui/components/OxySignInButton.js.map +1 -1
- package/lib/module/ui/components/ProfileCard.js +0 -1
- package/lib/module/ui/components/ProfileCard.js.map +1 -1
- package/lib/module/ui/components/QuickActions.js +0 -1
- package/lib/module/ui/components/QuickActions.js.map +1 -1
- package/lib/module/ui/components/Section.js +0 -1
- package/lib/module/ui/components/Section.js.map +1 -1
- package/lib/module/ui/components/SectionTitle.js +0 -1
- package/lib/module/ui/components/SectionTitle.js.map +1 -1
- package/lib/module/ui/components/icon/FAIRWalletIcon.js +0 -1
- package/lib/module/ui/components/icon/FAIRWalletIcon.js.map +1 -1
- package/lib/module/ui/components/icon/OxyIcon.js +0 -1
- package/lib/module/ui/components/icon/OxyIcon.js.map +1 -1
- package/lib/module/ui/components/internal/GroupedPillButtons.js +0 -1
- package/lib/module/ui/components/internal/GroupedPillButtons.js.map +1 -1
- package/lib/module/ui/components/internal/PinInput.js +4 -2
- package/lib/module/ui/components/internal/PinInput.js.map +1 -1
- package/lib/module/ui/components/internal/TextField.js +3 -3
- package/lib/module/ui/components/internal/TextField.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/hooks/useAssets.js +257 -0
- package/lib/module/ui/hooks/useAssets.js.map +1 -0
- package/lib/module/ui/navigation/OxyRouter.js +1 -1
- package/lib/module/ui/navigation/OxyRouter.js.map +1 -1
- package/lib/module/ui/screens/AccountCenterScreen.js +0 -1
- package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountManagementDemo.js +0 -1
- package/lib/module/ui/screens/AccountManagementDemo.js.map +1 -1
- package/lib/module/ui/screens/AccountSettingsScreen.js +2 -2
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSwitcherScreen.js +5 -5
- package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/module/ui/screens/AppInfoScreen.js +1 -1
- package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
- package/lib/module/ui/screens/FileManagementScreen.js +633 -432
- package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/PaymentGatewayScreen.js +1 -1
- package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -1
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js +1 -1
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/module/ui/screens/ProfileScreen.js +1 -1
- package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/module/ui/screens/RecoverAccountScreen.js +1 -1
- package/lib/module/ui/screens/RecoverAccountScreen.js.map +1 -1
- package/lib/module/ui/screens/SessionManagementScreen.js +1 -1
- package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/SignInScreen.js +1 -1
- package/lib/module/ui/screens/SignInScreen.js.map +1 -1
- package/lib/module/ui/screens/UserLinksScreen.js +0 -1
- package/lib/module/ui/screens/UserLinksScreen.js.map +1 -1
- package/lib/module/ui/screens/internal/SignInPasswordStep.js +1 -1
- package/lib/module/ui/screens/internal/SignInPasswordStep.js.map +1 -1
- package/lib/module/ui/screens/internal/SignInUsernameStep.js +1 -1
- package/lib/module/ui/screens/internal/SignInUsernameStep.js.map +1 -1
- package/lib/module/ui/screens/internal/SignUpIdentityStep.js +1 -1
- package/lib/module/ui/screens/internal/SignUpIdentityStep.js.map +1 -1
- package/lib/module/ui/screens/internal/SignUpSecurityStep.js +1 -1
- package/lib/module/ui/screens/internal/SignUpSecurityStep.js.map +1 -1
- package/lib/module/ui/screens/internal/SignUpSummaryStep.js +0 -1
- package/lib/module/ui/screens/internal/SignUpSummaryStep.js.map +1 -1
- package/lib/module/ui/screens/internal/SignUpWelcomeStep.js +0 -1
- package/lib/module/ui/screens/internal/SignUpWelcomeStep.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaAboutScreen.js +0 -1
- package/lib/module/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaCenterScreen.js +1 -1
- package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +1 -1
- package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaRewardsScreen.js +0 -1
- package/lib/module/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaRulesScreen.js +1 -1
- package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
- package/lib/module/ui/stores/assetStore.js +212 -0
- package/lib/module/ui/stores/assetStore.js.map +1 -0
- package/lib/module/ui/stores/authStore.js +1 -1
- package/lib/module/ui/stores/authStore.js.map +1 -1
- package/lib/module/ui/stores/fileStore.js +145 -0
- package/lib/module/ui/stores/fileStore.js.map +1 -0
- package/lib/module/ui/stores/followStore.js +2 -2
- package/lib/module/ui/stores/followStore.js.map +1 -1
- package/lib/module/ui/styles/fonts.js.map +1 -1
- package/lib/module/ui/styles/theme.js.map +1 -1
- package/lib/module/utils/asyncUtils.js +1 -1
- package/lib/module/utils/asyncUtils.js.map +1 -1
- package/lib/module/utils/errorUtils.js +19 -11
- package/lib/module/utils/errorUtils.js.map +1 -1
- package/lib/module/utils/hookUtils.js +1 -1
- package/lib/module/utils/hookUtils.js.map +1 -1
- package/lib/module/utils/loggerUtils.js.map +1 -1
- package/lib/module/utils/validationUtils.js +2 -2
- package/lib/module/utils/validationUtils.js.map +1 -1
- package/lib/typescript/assets/icons/OxyServices.d.ts +2 -2
- package/lib/typescript/assets/icons/OxyServices.d.ts.map +1 -1
- package/lib/typescript/assets/illustrations/HighFive.d.ts +1 -1
- package/lib/typescript/assets/illustrations/HighFive.d.ts.map +1 -1
- package/lib/typescript/core/OxyServices.d.ts +69 -12
- package/lib/typescript/core/OxyServices.d.ts.map +1 -1
- package/lib/typescript/core/index.d.ts +1 -1
- package/lib/typescript/core/index.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +4 -2
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/lib/sonner-safe.d.ts +2 -1
- package/lib/typescript/lib/sonner-safe.d.ts.map +1 -1
- package/lib/typescript/lib/sonner.d.ts +11 -3
- package/lib/typescript/lib/sonner.d.ts.map +1 -1
- package/lib/typescript/models/interfaces.d.ts +105 -6
- package/lib/typescript/models/interfaces.d.ts.map +1 -1
- package/lib/typescript/node/index.d.ts +2 -2
- package/lib/typescript/node/index.d.ts.map +1 -1
- package/lib/typescript/types/expo-vector-icons.d.ts +8 -1
- package/lib/typescript/types/express.d.ts +22 -3
- package/lib/typescript/ui/components/Avatar.d.ts +2 -2
- package/lib/typescript/ui/components/Avatar.d.ts.map +1 -1
- package/lib/typescript/ui/components/FollowButton.d.ts +2 -2
- package/lib/typescript/ui/components/FollowButton.d.ts.map +1 -1
- package/lib/typescript/ui/components/FontLoader.d.ts +1 -1
- package/lib/typescript/ui/components/FontLoader.d.ts.map +1 -1
- package/lib/typescript/ui/components/GroupedItem.d.ts +2 -1
- package/lib/typescript/ui/components/GroupedItem.d.ts.map +1 -1
- package/lib/typescript/ui/components/GroupedSection.d.ts +2 -1
- package/lib/typescript/ui/components/GroupedSection.d.ts.map +1 -1
- package/lib/typescript/ui/components/Header.d.ts +1 -1
- package/lib/typescript/ui/components/Header.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxyLogo.d.ts +2 -2
- package/lib/typescript/ui/components/OxyLogo.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxyPayButton.d.ts +2 -2
- package/lib/typescript/ui/components/OxyPayButton.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxyProvider.d.ts +2 -2
- package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxySignInButton.d.ts +2 -2
- package/lib/typescript/ui/components/OxySignInButton.d.ts.map +1 -1
- package/lib/typescript/ui/components/ProfileCard.d.ts +1 -1
- package/lib/typescript/ui/components/ProfileCard.d.ts.map +1 -1
- package/lib/typescript/ui/components/QuickActions.d.ts +1 -1
- package/lib/typescript/ui/components/QuickActions.d.ts.map +1 -1
- package/lib/typescript/ui/components/Section.d.ts +1 -1
- package/lib/typescript/ui/components/Section.d.ts.map +1 -1
- package/lib/typescript/ui/components/SectionTitle.d.ts +1 -1
- package/lib/typescript/ui/components/SectionTitle.d.ts.map +1 -1
- package/lib/typescript/ui/components/icon/FAIRWalletIcon.d.ts +1 -1
- package/lib/typescript/ui/components/icon/FAIRWalletIcon.d.ts.map +1 -1
- package/lib/typescript/ui/components/icon/OxyIcon.d.ts +1 -1
- package/lib/typescript/ui/components/icon/OxyIcon.d.ts.map +1 -1
- package/lib/typescript/ui/components/internal/GroupedPillButtons.d.ts +1 -1
- package/lib/typescript/ui/components/internal/GroupedPillButtons.d.ts.map +1 -1
- package/lib/typescript/ui/components/internal/PinInput.d.ts +1 -1
- package/lib/typescript/ui/components/internal/PinInput.d.ts.map +1 -1
- package/lib/typescript/ui/components/internal/TextField.d.ts +1 -1
- package/lib/typescript/ui/components/internal/TextField.d.ts.map +1 -1
- package/lib/typescript/ui/context/OxyContext.d.ts +3 -3
- package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/useAssets.d.ts +35 -0
- package/lib/typescript/ui/hooks/useAssets.d.ts.map +1 -0
- package/lib/typescript/ui/navigation/OxyRouter.d.ts +2 -2
- package/lib/typescript/ui/navigation/OxyRouter.d.ts.map +1 -1
- package/lib/typescript/ui/navigation/types.d.ts +7 -7
- package/lib/typescript/ui/navigation/types.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountCenterScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/AccountCenterScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountManagementDemo.d.ts +1 -1
- package/lib/typescript/ui/screens/AccountManagementDemo.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts +1 -1
- package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts +1 -1
- package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AppInfoScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/AppInfoScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/FeedbackScreen.d.ts +1 -1
- package/lib/typescript/ui/screens/FeedbackScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/FileManagementScreen.d.ts +1 -1
- package/lib/typescript/ui/screens/FileManagementScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/PaymentGatewayScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/PaymentGatewayScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/ProfileScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/ProfileScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts +1 -1
- package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SessionManagementScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/SessionManagementScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SignInScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SignUpScreen.d.ts +1 -1
- package/lib/typescript/ui/screens/SignUpScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/UserLinksScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/UserLinksScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts +1 -1
- package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts +1 -1
- package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/internal/SignUpIdentityStep.d.ts +1 -1
- package/lib/typescript/ui/screens/internal/SignUpIdentityStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/internal/SignUpSecurityStep.d.ts +1 -1
- package/lib/typescript/ui/screens/internal/SignUpSecurityStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/internal/SignUpSummaryStep.d.ts +1 -1
- package/lib/typescript/ui/screens/internal/SignUpSummaryStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/internal/SignUpWelcomeStep.d.ts +1 -1
- package/lib/typescript/ui/screens/internal/SignUpWelcomeStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaAboutScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/karma/KarmaAboutScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaCenterScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/karma/KarmaCenterScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaFAQScreen.d.ts +1 -1
- package/lib/typescript/ui/screens/karma/KarmaFAQScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaLeaderboardScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/karma/KarmaLeaderboardScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaRewardsScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/karma/KarmaRewardsScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaRulesScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/karma/KarmaRulesScreen.d.ts.map +1 -1
- package/lib/typescript/ui/stores/assetStore.d.ts +54 -0
- package/lib/typescript/ui/stores/assetStore.d.ts.map +1 -0
- package/lib/typescript/ui/stores/fileStore.d.ts +31 -0
- package/lib/typescript/ui/stores/fileStore.d.ts.map +1 -0
- package/lib/typescript/ui/stores/followStore.d.ts +1 -1
- package/lib/typescript/ui/stores/followStore.d.ts.map +1 -1
- package/lib/typescript/ui/styles/fonts.d.ts +1 -1
- package/lib/typescript/ui/styles/fonts.d.ts.map +1 -1
- package/lib/typescript/ui/styles/theme.d.ts +1 -1
- package/lib/typescript/ui/styles/theme.d.ts.map +1 -1
- package/lib/typescript/utils/asyncUtils.d.ts.map +1 -1
- package/lib/typescript/utils/errorUtils.d.ts +5 -5
- package/lib/typescript/utils/errorUtils.d.ts.map +1 -1
- package/lib/typescript/utils/hookUtils.d.ts +4 -4
- package/lib/typescript/utils/hookUtils.d.ts.map +1 -1
- package/lib/typescript/utils/loggerUtils.d.ts +18 -18
- package/lib/typescript/utils/loggerUtils.d.ts.map +1 -1
- package/lib/typescript/utils/validationUtils.d.ts +6 -6
- package/lib/typescript/utils/validationUtils.d.ts.map +1 -1
- package/package.json +149 -143
- package/src/assets/icons/OxyServices.tsx +2 -2
- package/src/assets/illustrations/HighFive.tsx +1 -1
- package/src/core/OxyServices.ts +268 -41
- package/src/core/__tests__/OxyServices.test.ts +180 -0
- package/src/core/index.ts +1 -1
- package/src/index.ts +16 -2
- package/src/lib/sonner-safe.ts +4 -1
- package/src/lib/sonner.ts +19 -2
- package/src/models/interfaces.ts +117 -6
- package/src/node/index.ts +2 -2
- package/src/types/expo-vector-icons.d.ts +8 -1
- package/src/types/express.d.ts +22 -3
- package/src/ui/components/Avatar.tsx +2 -2
- package/src/ui/components/FollowButton.tsx +10 -8
- package/src/ui/components/FontLoader.tsx +5 -3
- package/src/ui/components/GroupedItem.tsx +12 -2
- package/src/ui/components/GroupedSection.tsx +3 -1
- package/src/ui/components/Header.tsx +1 -1
- package/src/ui/components/OxyLogo.tsx +2 -2
- package/src/ui/components/OxyPayButton.tsx +6 -5
- package/src/ui/components/OxyProvider.tsx +7 -4
- package/src/ui/components/OxySignInButton.tsx +2 -2
- package/src/ui/components/ProfileCard.tsx +1 -1
- package/src/ui/components/QuickActions.tsx +1 -1
- package/src/ui/components/Section.tsx +1 -1
- package/src/ui/components/SectionTitle.tsx +1 -1
- package/src/ui/components/icon/FAIRWalletIcon.tsx +1 -1
- package/src/ui/components/icon/OxyIcon.tsx +1 -1
- package/src/ui/components/internal/GroupedPillButtons.tsx +1 -1
- package/src/ui/components/internal/PinInput.tsx +3 -2
- package/src/ui/components/internal/TextField.tsx +9 -11
- package/src/ui/context/OxyContext.tsx +3 -3
- package/src/ui/hooks/useAssets.ts +306 -0
- package/src/ui/navigation/OxyRouter.tsx +3 -2
- package/src/ui/navigation/types.ts +8 -8
- package/src/ui/screens/AccountCenterScreen.tsx +2 -2
- package/src/ui/screens/AccountManagementDemo.tsx +1 -1
- package/src/ui/screens/AccountOverviewScreen.tsx +1 -1
- package/src/ui/screens/AccountSettingsScreen.tsx +3 -3
- package/src/ui/screens/AccountSwitcherScreen.tsx +9 -8
- package/src/ui/screens/AppInfoScreen.tsx +3 -2
- package/src/ui/screens/FeedbackScreen.tsx +1 -1
- package/src/ui/screens/FileManagementScreen.tsx +619 -494
- package/src/ui/screens/PaymentGatewayScreen.tsx +3 -2
- package/src/ui/screens/PremiumSubscriptionScreen.tsx +3 -2
- package/src/ui/screens/ProfileScreen.tsx +3 -2
- package/src/ui/screens/RecoverAccountScreen.tsx +3 -2
- package/src/ui/screens/SessionManagementScreen.tsx +4 -3
- package/src/ui/screens/SignInScreen.tsx +3 -2
- package/src/ui/screens/SignUpScreen.tsx +1 -1
- package/src/ui/screens/UserLinksScreen.tsx +2 -2
- package/src/ui/screens/internal/SignInPasswordStep.tsx +3 -2
- package/src/ui/screens/internal/SignInUsernameStep.tsx +3 -2
- package/src/ui/screens/internal/SignUpIdentityStep.tsx +3 -2
- package/src/ui/screens/internal/SignUpSecurityStep.tsx +3 -2
- package/src/ui/screens/internal/SignUpSummaryStep.tsx +1 -1
- package/src/ui/screens/internal/SignUpWelcomeStep.tsx +1 -1
- package/src/ui/screens/karma/KarmaAboutScreen.tsx +2 -2
- package/src/ui/screens/karma/KarmaCenterScreen.tsx +3 -2
- package/src/ui/screens/karma/KarmaFAQScreen.tsx +1 -1
- package/src/ui/screens/karma/KarmaLeaderboardScreen.tsx +3 -2
- package/src/ui/screens/karma/KarmaRewardsScreen.tsx +2 -2
- package/src/ui/screens/karma/KarmaRulesScreen.tsx +3 -2
- package/src/ui/stores/assetStore.ts +281 -0
- package/src/ui/stores/authStore.ts +1 -1
- package/src/ui/stores/fileStore.ts +118 -0
- package/src/ui/stores/followStore.ts +4 -4
- package/src/ui/styles/fonts.ts +1 -1
- package/src/ui/styles/theme.ts +1 -1
- package/src/utils/__tests__/validationUtils.test.ts +236 -0
- package/src/utils/asyncUtils.ts +4 -4
- package/src/utils/errorUtils.ts +35 -23
- package/src/utils/hookUtils.ts +7 -7
- package/src/utils/loggerUtils.ts +18 -18
- package/src/utils/validationUtils.ts +8 -8
package/README.md
CHANGED
|
@@ -1,242 +1,719 @@
|
|
|
1
1
|
# OxyHQServices
|
|
2
2
|
|
|
3
|
-
A TypeScript client library for the Oxy API providing authentication, user management, and UI components for React and
|
|
3
|
+
A comprehensive TypeScript client library for the Oxy API providing authentication, user management, and UI components for React Native, Expo, and Node.js applications.
|
|
4
4
|
|
|
5
|
-
## Table of Contents
|
|
5
|
+
## 📋 Table of Contents
|
|
6
6
|
|
|
7
7
|
- [Features](#features)
|
|
8
|
+
- [Installation](#installation)
|
|
8
9
|
- [Quick Start](#quick-start)
|
|
9
|
-
- [
|
|
10
|
+
- [Usage Patterns](#usage-patterns)
|
|
11
|
+
- [Frontend (React/React Native)](#frontend-reactreact-native)
|
|
12
|
+
- [Backend (Node.js)](#backend-nodejs)
|
|
13
|
+
- [Mixed Applications](#mixed-applications)
|
|
14
|
+
- [API Reference](#api-reference)
|
|
15
|
+
- [Configuration](#configuration)
|
|
16
|
+
- [Authentication](#authentication)
|
|
10
17
|
- [UI Components](#ui-components)
|
|
11
|
-
- [
|
|
18
|
+
- [Troubleshooting](#troubleshooting)
|
|
12
19
|
- [Requirements](#requirements)
|
|
13
|
-
- [Development](#development)
|
|
14
|
-
- [Integration](#integration)
|
|
15
|
-
- [License](#license)
|
|
16
20
|
|
|
17
|
-
## Features
|
|
21
|
+
## ✨ Features
|
|
18
22
|
|
|
19
|
-
- 🔐 **
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
- 📱 **
|
|
24
|
-
- 🔧 **TypeScript**: Full type safety and IntelliSense support
|
|
25
|
-
- 🚀 **Performance
|
|
26
|
-
-
|
|
23
|
+
- 🔐 **Zero-Config Authentication**: Automatic token management and refresh
|
|
24
|
+
- 📱 **React Native First**: Optimized for React Native and Expo applications
|
|
25
|
+
- 🎨 **UI Components**: Pre-built React Native components with built-in bottom sheet
|
|
26
|
+
- 🔄 **Cross-Platform**: Works seamlessly in React Native, Expo, and Node.js
|
|
27
|
+
- 📱 **Multi-Session Support**: Manage multiple user sessions simultaneously
|
|
28
|
+
- 🔧 **TypeScript First**: Full type safety and IntelliSense support
|
|
29
|
+
- 🚀 **Performance Optimized**: Automatic caching and state management
|
|
30
|
+
- 🛡️ **Production Ready**: Error handling, retry logic, and security best practices
|
|
27
31
|
|
|
28
|
-
##
|
|
32
|
+
## 📦 Installation
|
|
29
33
|
|
|
30
34
|
```bash
|
|
31
35
|
npm install @oxyhq/services
|
|
32
36
|
```
|
|
33
37
|
|
|
34
|
-
###
|
|
38
|
+
### React Native/Expo Setup
|
|
35
39
|
|
|
36
|
-
|
|
40
|
+
For React Native and Expo projects, add the polyfill import at the very top of your entry file:
|
|
37
41
|
|
|
38
|
-
```
|
|
39
|
-
|
|
42
|
+
```javascript
|
|
43
|
+
// index.js or App.js (very first line)
|
|
44
|
+
import 'react-native-url-polyfill/auto';
|
|
45
|
+
```
|
|
40
46
|
|
|
41
|
-
|
|
47
|
+
**Note**: This polyfill is already included in the package dependencies, but you need to import it to activate it.
|
|
42
48
|
|
|
43
|
-
|
|
44
|
-
await oxy.signIn('username', 'password');
|
|
45
|
-
await oxy.signUp('username', 'email', 'password');
|
|
49
|
+
## 🚀 Quick Start
|
|
46
50
|
|
|
47
|
-
|
|
48
|
-
const user = await oxy.getCurrentUser();
|
|
49
|
-
await oxy.updateProfile({ name: 'John Doe' });
|
|
50
|
-
await oxy.followUser('user123');
|
|
51
|
+
### React Native/Expo
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const notifications = await oxy.getNotifications();
|
|
53
|
+
```typescript
|
|
54
|
+
import { OxyProvider, useOxy } from '@oxyhq/services';
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
function App() {
|
|
57
|
+
return (
|
|
58
|
+
<OxyProvider baseURL="https://cloud.oxy.so">
|
|
59
|
+
<YourApp />
|
|
60
|
+
</OxyProvider>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
58
63
|
|
|
59
|
-
|
|
60
|
-
const
|
|
64
|
+
function UserProfile() {
|
|
65
|
+
const { oxyServices, user, isAuthenticated } = useOxy();
|
|
66
|
+
|
|
67
|
+
if (!isAuthenticated) {
|
|
68
|
+
return <Text>Please sign in</Text>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return <Text>Welcome, {user?.name}!</Text>;
|
|
72
|
+
}
|
|
73
|
+
```
|
|
61
74
|
|
|
62
|
-
|
|
63
|
-
await oxy.updateLocation(40.7128, -74.0060);
|
|
64
|
-
const nearby = await oxy.getNearbyUsers();
|
|
75
|
+
### Backend (Node.js)
|
|
65
76
|
|
|
66
|
-
|
|
67
|
-
|
|
77
|
+
```typescript
|
|
78
|
+
import { oxyClient } from '@oxyhq/services';
|
|
68
79
|
|
|
69
|
-
//
|
|
80
|
+
// Ready to use - no configuration needed!
|
|
81
|
+
app.get('/api/user', async (req, res) => {
|
|
82
|
+
const user = await oxyClient.getCurrentUser();
|
|
83
|
+
res.json(user);
|
|
84
|
+
});
|
|
70
85
|
```
|
|
71
86
|
|
|
72
|
-
|
|
87
|
+
## 📖 Usage Patterns
|
|
88
|
+
|
|
89
|
+
### React Native/Expo
|
|
90
|
+
|
|
91
|
+
#### 1. **OxyProvider + useOxy Hook (Recommended)**
|
|
92
|
+
|
|
93
|
+
This pattern provides full React Native integration with automatic state management, UI components, and authentication flow.
|
|
73
94
|
|
|
74
95
|
```typescript
|
|
75
96
|
import { OxyProvider, useOxy } from '@oxyhq/services';
|
|
76
97
|
|
|
98
|
+
// App.tsx - Setup the provider
|
|
77
99
|
function App() {
|
|
78
100
|
return (
|
|
79
|
-
<OxyProvider
|
|
101
|
+
<OxyProvider
|
|
102
|
+
baseURL="https://cloud.oxy.so"
|
|
103
|
+
onAuthStateChange={(user) => {
|
|
104
|
+
console.log('Auth state changed:', user ? 'logged in' : 'logged out');
|
|
105
|
+
}}
|
|
106
|
+
>
|
|
80
107
|
<YourApp />
|
|
81
108
|
</OxyProvider>
|
|
82
109
|
);
|
|
83
110
|
}
|
|
84
111
|
|
|
112
|
+
// Component.tsx - Use the hook
|
|
85
113
|
function UserProfile() {
|
|
86
|
-
const {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
//
|
|
90
|
-
|
|
91
|
-
|
|
114
|
+
const {
|
|
115
|
+
oxyServices, // OxyServices instance
|
|
116
|
+
user, // Current user data
|
|
117
|
+
isAuthenticated, // Authentication state
|
|
118
|
+
login, // Login method
|
|
119
|
+
logout, // Logout method
|
|
120
|
+
showBottomSheet // UI methods
|
|
121
|
+
} = useOxy();
|
|
122
|
+
|
|
123
|
+
const handleLogin = async () => {
|
|
124
|
+
try {
|
|
125
|
+
await login('username', 'password');
|
|
126
|
+
} catch (error) {
|
|
127
|
+
console.error('Login failed:', error);
|
|
128
|
+
}
|
|
92
129
|
};
|
|
130
|
+
|
|
131
|
+
const openSignIn = () => {
|
|
132
|
+
showBottomSheet('SignIn');
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
return (
|
|
136
|
+
<View>
|
|
137
|
+
{isAuthenticated ? (
|
|
138
|
+
<View>
|
|
139
|
+
<Text style={styles.title}>Welcome, {user?.name}!</Text>
|
|
140
|
+
<TouchableOpacity onPress={logout} style={styles.button}>
|
|
141
|
+
<Text>Sign Out</Text>
|
|
142
|
+
</TouchableOpacity>
|
|
143
|
+
</View>
|
|
144
|
+
) : (
|
|
145
|
+
<TouchableOpacity onPress={openSignIn} style={styles.button}>
|
|
146
|
+
<Text>Sign In</Text>
|
|
147
|
+
</TouchableOpacity>
|
|
148
|
+
)}
|
|
149
|
+
</View>
|
|
150
|
+
);
|
|
93
151
|
}
|
|
94
152
|
```
|
|
95
153
|
|
|
96
|
-
|
|
154
|
+
#### 2. **Direct Import (Non-React Files)**
|
|
155
|
+
|
|
156
|
+
For utility functions, services, or non-React Native files:
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
import { oxyClient } from '@oxyhq/services';
|
|
160
|
+
|
|
161
|
+
// utils/api.ts
|
|
162
|
+
export const userUtils = {
|
|
163
|
+
async fetchUserById(userId: string) {
|
|
164
|
+
return await oxyClient.getUserById(userId);
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
async fetchProfileByUsername(username: string) {
|
|
168
|
+
return await oxyClient.getProfileByUsername(username);
|
|
169
|
+
},
|
|
170
|
+
|
|
171
|
+
async updateUserProfile(updates: any) {
|
|
172
|
+
return await oxyClient.updateProfile(updates);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Backend (Node.js)
|
|
178
|
+
|
|
179
|
+
#### 1. **Pre-configured Client (Recommended)**
|
|
180
|
+
|
|
181
|
+
Use the pre-configured `oxyClient` for immediate access:
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
import { oxyClient } from '@oxyhq/services';
|
|
185
|
+
|
|
186
|
+
// routes/auth.ts
|
|
187
|
+
export const signIn = async (req, res) => {
|
|
188
|
+
try {
|
|
189
|
+
const { username, password } = req.body;
|
|
190
|
+
const response = await oxyClient.signIn(username, password);
|
|
191
|
+
res.json(response);
|
|
192
|
+
} catch (error) {
|
|
193
|
+
res.status(401).json({ error: error.message });
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
// routes/users.ts
|
|
198
|
+
export const getUserProfile = async (req, res) => {
|
|
199
|
+
try {
|
|
200
|
+
const { userId } = req.params;
|
|
201
|
+
const user = await oxyClient.getUserById(userId);
|
|
202
|
+
res.json(user);
|
|
203
|
+
} catch (error) {
|
|
204
|
+
res.status(500).json({ error: error.message });
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
// routes/profiles.ts
|
|
209
|
+
export const getProfileByUsername = async (req, res) => {
|
|
210
|
+
try {
|
|
211
|
+
const { username } = req.params;
|
|
212
|
+
const profile = await oxyClient.getProfileByUsername(username);
|
|
213
|
+
res.json(profile);
|
|
214
|
+
} catch (error) {
|
|
215
|
+
res.status(500).json({ error: error.message });
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
// routes/social.ts
|
|
220
|
+
export const getFollowers = async (req, res) => {
|
|
221
|
+
try {
|
|
222
|
+
const { userId } = req.params;
|
|
223
|
+
const followers = await oxyClient.getUserFollowers(userId);
|
|
224
|
+
res.json(followers);
|
|
225
|
+
} catch (error) {
|
|
226
|
+
res.status(500).json({ error: error.message });
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
#### 2. **Custom Configuration**
|
|
232
|
+
|
|
233
|
+
Create your own instance with custom settings:
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
import { OxyServices, OXY_CLOUD_URL } from '@oxyhq/services';
|
|
237
|
+
|
|
238
|
+
const oxy = new OxyServices({
|
|
239
|
+
baseURL: process.env.OXY_API_URL || OXY_CLOUD_URL
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
export { oxy };
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Mixed Applications (React Native + Backend)
|
|
97
246
|
|
|
98
|
-
|
|
247
|
+
You can use both patterns in the same application:
|
|
99
248
|
|
|
100
249
|
```typescript
|
|
101
|
-
|
|
250
|
+
// App.tsx - React Native setup
|
|
251
|
+
import { OxyProvider } from '@oxyhq/services';
|
|
102
252
|
|
|
103
253
|
function App() {
|
|
104
254
|
return (
|
|
105
|
-
<OxyProvider
|
|
106
|
-
baseURL="https://api.example.com"
|
|
107
|
-
initialScreen="SignIn"
|
|
108
|
-
theme="light"
|
|
109
|
-
>
|
|
255
|
+
<OxyProvider baseURL="https://cloud.oxy.so">
|
|
110
256
|
<YourApp />
|
|
111
257
|
</OxyProvider>
|
|
112
258
|
);
|
|
113
259
|
}
|
|
114
260
|
|
|
261
|
+
// utils/api.ts - Direct import
|
|
262
|
+
import { oxyClient } from '@oxyhq/services';
|
|
263
|
+
|
|
264
|
+
export const apiUtils = {
|
|
265
|
+
async fetchData() {
|
|
266
|
+
return await oxyClient.getCurrentUser();
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
// Component.tsx - React Native hook
|
|
271
|
+
import { useOxy } from '@oxyhq/services';
|
|
272
|
+
|
|
115
273
|
function Component() {
|
|
116
|
-
const {
|
|
274
|
+
const { oxyServices } = useOxy();
|
|
275
|
+
// Both oxyServices and oxyClient share the same tokens!
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## 🔧 API Reference
|
|
280
|
+
|
|
281
|
+
### Core Exports
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
import {
|
|
285
|
+
OxyServices, // Main service class
|
|
286
|
+
oxyClient, // Pre-configured instance
|
|
287
|
+
OXY_CLOUD_URL, // Default API URL
|
|
288
|
+
OxyAuthenticationError,
|
|
289
|
+
OxyAuthenticationTimeoutError
|
|
290
|
+
} from '@oxyhq/services';
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### React Native Exports
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
import {
|
|
297
|
+
OxyProvider, // Context provider
|
|
298
|
+
useOxy, // React Native hook
|
|
299
|
+
OxySignInButton, // UI components
|
|
300
|
+
Avatar,
|
|
301
|
+
FollowButton
|
|
302
|
+
} from '@oxyhq/services';
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### OxyServices Methods
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
// Authentication
|
|
309
|
+
await oxyClient.signIn(username, password);
|
|
310
|
+
await oxyClient.signUp(username, email, password);
|
|
311
|
+
await oxyClient.logout();
|
|
312
|
+
|
|
313
|
+
// User Management
|
|
314
|
+
const user = await oxyClient.getCurrentUser(); // Get current user
|
|
315
|
+
const userById = await oxyClient.getUserById('user123'); // Get user by ID
|
|
316
|
+
const profileByUsername = await oxyClient.getProfileByUsername('john_doe'); // Get profile by username
|
|
317
|
+
await oxyClient.updateProfile({ name: 'John Doe' }); // Update current user
|
|
318
|
+
await oxyClient.updateUser('user123', { name: 'John' }); // Update user by ID (admin)
|
|
319
|
+
|
|
320
|
+
// Session Management
|
|
321
|
+
const userBySession = await oxyClient.getUserBySession('session123'); // Get user by session
|
|
322
|
+
const sessions = await oxyClient.getSessionsBySessionId('session123'); // Get all sessions
|
|
323
|
+
await oxyClient.logoutSession('session123'); // Logout specific session
|
|
324
|
+
await oxyClient.logoutAllSessions('session123'); // Logout all sessions
|
|
325
|
+
|
|
326
|
+
// Social Features
|
|
327
|
+
await oxyClient.followUser('user123'); // Follow user
|
|
328
|
+
await oxyClient.unfollowUser('user123'); // Unfollow user
|
|
329
|
+
const followStatus = await oxyClient.getFollowStatus('user123'); // Check follow status
|
|
330
|
+
const followers = await oxyClient.getUserFollowers('user123'); // Get user followers
|
|
331
|
+
const following = await oxyClient.getUserFollowing('user123'); // Get user following
|
|
332
|
+
|
|
333
|
+
// Notifications
|
|
334
|
+
const notifications = await oxyClient.getNotifications(); // Get notifications
|
|
335
|
+
const unreadCount = await oxyClient.getUnreadCount(); // Get unread count
|
|
336
|
+
await oxyClient.markNotificationAsRead('notification123'); // Mark as read
|
|
337
|
+
await oxyClient.markAllNotificationsAsRead(); // Mark all as read
|
|
338
|
+
await oxyClient.deleteNotification('notification123'); // Delete notification
|
|
339
|
+
|
|
340
|
+
// File Management
|
|
341
|
+
const fileData = await oxyClient.uploadFile(file); // Upload file
|
|
342
|
+
const file = await oxyClient.getFile('file123'); // Get file info
|
|
343
|
+
await oxyClient.deleteFile('file123'); // Delete file
|
|
344
|
+
const downloadUrl = oxyClient.getFileDownloadUrl('file123'); // Get download URL
|
|
345
|
+
const streamUrl = oxyClient.getFileStreamUrl('file123'); // Get stream URL
|
|
346
|
+
const userFiles = await oxyClient.listUserFiles('user123'); // List user files
|
|
347
|
+
|
|
348
|
+
// Payments
|
|
349
|
+
const payment = await oxyClient.createPayment(paymentData); // Create payment
|
|
350
|
+
const paymentInfo = await oxyClient.getPayment('payment123'); // Get payment info
|
|
351
|
+
const userPayments = await oxyClient.getUserPayments(); // Get user payments
|
|
352
|
+
|
|
353
|
+
// Karma System
|
|
354
|
+
const karma = await oxyClient.getUserKarma('user123'); // Get user karma
|
|
355
|
+
await oxyClient.giveKarma('user123', 10, 'helpful comment'); // Give karma
|
|
356
|
+
const karmaTotal = await oxyClient.getUserKarmaTotal('user123'); // Get karma total
|
|
357
|
+
const karmaHistory = await oxyClient.getUserKarmaHistory('user123'); // Get karma history
|
|
358
|
+
const leaderboard = await oxyClient.getKarmaLeaderboard(); // Get leaderboard
|
|
359
|
+
const rules = await oxyClient.getKarmaRules(); // Get karma rules
|
|
360
|
+
|
|
361
|
+
// Location Services
|
|
362
|
+
await oxyClient.updateLocation(40.7128, -74.0060); // Update location
|
|
363
|
+
const nearby = await oxyClient.getNearbyUsers(1000); // Get nearby users
|
|
364
|
+
|
|
365
|
+
// Analytics
|
|
366
|
+
await oxyClient.trackEvent('user_action', { action: 'click' }); // Track event
|
|
367
|
+
const analytics = await oxyClient.getAnalytics('2024-01-01', '2024-01-31'); // Get analytics
|
|
368
|
+
|
|
369
|
+
// Device Management
|
|
370
|
+
await oxyClient.registerDevice(deviceData); // Register device
|
|
371
|
+
const devices = await oxyClient.getUserDevices(); // Get user devices
|
|
372
|
+
await oxyClient.removeDevice('device123'); // Remove device
|
|
373
|
+
const deviceSessions = await oxyClient.getDeviceSessions('session123'); // Get device sessions
|
|
374
|
+
await oxyClient.logoutAllDeviceSessions('session123'); // Logout device sessions
|
|
375
|
+
await oxyClient.updateDeviceName('session123', 'iPhone 15'); // Update device name
|
|
376
|
+
|
|
377
|
+
// Utilities
|
|
378
|
+
const metadata = await oxyClient.fetchLinkMetadata('https://example.com'); // Fetch link metadata
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### useOxy Hook
|
|
382
|
+
|
|
383
|
+
```typescript
|
|
384
|
+
const {
|
|
385
|
+
// Service instance
|
|
386
|
+
oxyServices,
|
|
117
387
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
388
|
+
// Authentication state
|
|
389
|
+
user,
|
|
390
|
+
isAuthenticated,
|
|
391
|
+
isLoading,
|
|
392
|
+
error,
|
|
121
393
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
394
|
+
// Authentication methods
|
|
395
|
+
login,
|
|
396
|
+
logout,
|
|
397
|
+
signUp,
|
|
398
|
+
|
|
399
|
+
// Session management
|
|
400
|
+
sessions,
|
|
401
|
+
activeSessionId,
|
|
402
|
+
switchSession,
|
|
403
|
+
removeSession,
|
|
404
|
+
|
|
405
|
+
// UI methods
|
|
406
|
+
showBottomSheet,
|
|
407
|
+
hideBottomSheet
|
|
408
|
+
} = useOxy();
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
## ⚙️ Configuration
|
|
412
|
+
|
|
413
|
+
### OxyProvider Props
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
<OxyProvider
|
|
417
|
+
baseURL="https://cloud.oxy.so" // API base URL
|
|
418
|
+
storageKeyPrefix="oxy_session" // Storage key prefix
|
|
419
|
+
onAuthStateChange={(user) => {}} // Auth state callback
|
|
420
|
+
onError={(error) => {}} // Error callback
|
|
421
|
+
bottomSheetRef={bottomSheetRef} // Bottom sheet ref
|
|
422
|
+
>
|
|
423
|
+
{children}
|
|
424
|
+
</OxyProvider>
|
|
129
425
|
```
|
|
130
426
|
|
|
131
|
-
###
|
|
427
|
+
### Environment Variables
|
|
428
|
+
|
|
429
|
+
```bash
|
|
430
|
+
# .env
|
|
431
|
+
OXY_API_URL=https://cloud.oxy.so
|
|
432
|
+
NODE_ENV=production
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
### Custom Configuration
|
|
132
436
|
|
|
133
437
|
```typescript
|
|
134
438
|
import { OxyServices } from '@oxyhq/services';
|
|
135
439
|
|
|
136
440
|
const oxy = new OxyServices({
|
|
137
|
-
baseURL: '
|
|
441
|
+
baseURL: process.env.OXY_API_URL || 'https://cloud.oxy.so'
|
|
138
442
|
});
|
|
443
|
+
```
|
|
139
444
|
|
|
140
|
-
|
|
141
|
-
const response = await oxy.signIn('username', 'password');
|
|
445
|
+
## 🔐 Authentication
|
|
142
446
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
447
|
+
### Automatic Token Management
|
|
448
|
+
|
|
449
|
+
The library handles authentication automatically:
|
|
450
|
+
|
|
451
|
+
- **Token Storage**: Secure storage across sessions
|
|
452
|
+
- **Token Refresh**: Automatic refresh before expiration
|
|
453
|
+
- **Session Management**: Multi-session support
|
|
454
|
+
- **Error Handling**: Graceful handling of auth errors
|
|
455
|
+
|
|
456
|
+
### Manual Token Management
|
|
457
|
+
|
|
458
|
+
```typescript
|
|
459
|
+
import { oxyClient } from '@oxyhq/services';
|
|
147
460
|
|
|
148
|
-
//
|
|
149
|
-
|
|
150
|
-
const notifications = await oxy.getNotifications();
|
|
461
|
+
// Set tokens manually
|
|
462
|
+
oxyClient.setTokens(accessToken, refreshToken);
|
|
151
463
|
|
|
152
|
-
//
|
|
153
|
-
|
|
154
|
-
const downloadUrl = oxy.getFileDownloadUrl(fileId);
|
|
464
|
+
// Clear tokens
|
|
465
|
+
oxyClient.clearTokens();
|
|
155
466
|
|
|
156
|
-
//
|
|
467
|
+
// Check authentication
|
|
468
|
+
const isAuthenticated = oxyClient.hasValidToken();
|
|
157
469
|
```
|
|
158
470
|
|
|
159
|
-
##
|
|
471
|
+
## 🎨 UI Components
|
|
160
472
|
|
|
161
|
-
|
|
473
|
+
### Built-in Components
|
|
162
474
|
|
|
163
|
-
|
|
475
|
+
```typescript
|
|
476
|
+
import {
|
|
477
|
+
OxySignInButton,
|
|
478
|
+
Avatar,
|
|
479
|
+
FollowButton,
|
|
480
|
+
OxyLogo
|
|
481
|
+
} from '@oxyhq/services';
|
|
482
|
+
|
|
483
|
+
function MyComponent() {
|
|
484
|
+
return (
|
|
485
|
+
<View style={styles.container}>
|
|
486
|
+
<OxyLogo />
|
|
487
|
+
<Avatar userId="user123" size={40} />
|
|
488
|
+
<FollowButton userId="user123" />
|
|
489
|
+
<OxySignInButton />
|
|
490
|
+
</View>
|
|
491
|
+
);
|
|
492
|
+
}
|
|
164
493
|
|
|
165
|
-
|
|
494
|
+
const styles = StyleSheet.create({
|
|
495
|
+
container: {
|
|
496
|
+
flex: 1,
|
|
497
|
+
padding: 16,
|
|
498
|
+
},
|
|
499
|
+
});
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### Bottom Sheet Integration
|
|
166
503
|
|
|
167
504
|
```typescript
|
|
168
|
-
import {
|
|
505
|
+
import { useOxy } from '@oxyhq/services';
|
|
506
|
+
|
|
507
|
+
function MyComponent() {
|
|
508
|
+
const { showBottomSheet } = useOxy();
|
|
509
|
+
|
|
510
|
+
const openSignIn = () => {
|
|
511
|
+
showBottomSheet('SignIn');
|
|
512
|
+
};
|
|
513
|
+
|
|
514
|
+
const openProfile = () => {
|
|
515
|
+
showBottomSheet('Profile');
|
|
516
|
+
};
|
|
517
|
+
|
|
518
|
+
return (
|
|
519
|
+
<View style={styles.container}>
|
|
520
|
+
<TouchableOpacity onPress={openSignIn} style={styles.button}>
|
|
521
|
+
<Text>Sign In</Text>
|
|
522
|
+
</TouchableOpacity>
|
|
523
|
+
<TouchableOpacity onPress={openProfile} style={styles.button}>
|
|
524
|
+
<Text>Profile</Text>
|
|
525
|
+
</TouchableOpacity>
|
|
526
|
+
</View>
|
|
527
|
+
);
|
|
528
|
+
}
|
|
169
529
|
```
|
|
170
530
|
|
|
171
|
-
##
|
|
531
|
+
## 🛠️ Troubleshooting
|
|
532
|
+
|
|
533
|
+
### Common Issues
|
|
534
|
+
|
|
535
|
+
#### 1. **"useOxy must be used within an OxyContextProvider"**
|
|
172
536
|
|
|
173
|
-
|
|
537
|
+
**Solution**: Wrap your app with `OxyProvider`
|
|
174
538
|
|
|
175
539
|
```typescript
|
|
176
|
-
|
|
177
|
-
|
|
540
|
+
import { OxyProvider } from '@oxyhq/services';
|
|
541
|
+
|
|
542
|
+
function App() {
|
|
543
|
+
return (
|
|
544
|
+
<OxyProvider baseURL="https://cloud.oxy.so">
|
|
545
|
+
<YourApp />
|
|
546
|
+
</OxyProvider>
|
|
547
|
+
);
|
|
548
|
+
}
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
#### 2. **FormData Issues in React Native/Expo**
|
|
178
552
|
|
|
179
|
-
|
|
180
|
-
const oxy = new OxyServices({ baseURL: 'https://api.example.com' });
|
|
553
|
+
**Solution**: Add polyfill import at the very top of your entry file
|
|
181
554
|
|
|
182
|
-
|
|
183
|
-
|
|
555
|
+
```javascript
|
|
556
|
+
// index.js or App.js (very first line)
|
|
557
|
+
import 'react-native-url-polyfill/auto';
|
|
184
558
|
```
|
|
185
559
|
|
|
560
|
+
**Why needed**: Your app uses file uploads which require `FormData`. React Native with Hermes engine doesn't include `FormData` natively, so it needs to be polyfilled.
|
|
186
561
|
|
|
562
|
+
#### 3. **Authentication Not Persisting**
|
|
187
563
|
|
|
188
|
-
|
|
564
|
+
**Solution**: Check storage configuration
|
|
189
565
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
566
|
+
```typescript
|
|
567
|
+
<OxyProvider
|
|
568
|
+
baseURL="https://cloud.oxy.so"
|
|
569
|
+
storageKeyPrefix="my_app_oxy" // Custom storage key
|
|
570
|
+
>
|
|
571
|
+
{children}
|
|
572
|
+
</OxyProvider>
|
|
573
|
+
```
|
|
194
574
|
|
|
195
|
-
|
|
575
|
+
### Error Handling
|
|
196
576
|
|
|
197
|
-
|
|
577
|
+
```typescript
|
|
578
|
+
import { OxyAuthenticationError } from '@oxyhq/services';
|
|
579
|
+
|
|
580
|
+
try {
|
|
581
|
+
await oxyClient.getCurrentUser();
|
|
582
|
+
} catch (error) {
|
|
583
|
+
if (error instanceof OxyAuthenticationError) {
|
|
584
|
+
// Handle authentication errors
|
|
585
|
+
console.log('Auth error:', error.message);
|
|
586
|
+
} else {
|
|
587
|
+
// Handle other errors
|
|
588
|
+
console.log('Other error:', error.message);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
```
|
|
198
592
|
|
|
199
|
-
|
|
593
|
+
## 📋 Requirements
|
|
200
594
|
|
|
201
|
-
**
|
|
202
|
-
-
|
|
203
|
-
-
|
|
204
|
-
-
|
|
595
|
+
- **Node.js**: 16+ (for backend usage)
|
|
596
|
+
- **React Native**: 0.60+ (for mobile components)
|
|
597
|
+
- **Expo**: 44+ (recommended)
|
|
598
|
+
- **TypeScript**: 4.0+ (optional but recommended)
|
|
205
599
|
|
|
206
|
-
###
|
|
600
|
+
### Peer Dependencies
|
|
207
601
|
|
|
208
|
-
For React Native projects
|
|
602
|
+
For React Native/Expo projects:
|
|
209
603
|
|
|
210
604
|
```bash
|
|
211
605
|
npm install axios jwt-decode invariant
|
|
212
606
|
```
|
|
213
607
|
|
|
214
|
-
|
|
608
|
+
**Note**: `react-native-url-polyfill` is already included as a dependency in this package.
|
|
215
609
|
|
|
216
|
-
|
|
610
|
+
## 📚 Examples
|
|
217
611
|
|
|
218
|
-
|
|
219
|
-
import 'react-native-url-polyfill/auto';
|
|
220
|
-
```
|
|
612
|
+
### Complete React Native App
|
|
221
613
|
|
|
222
|
-
|
|
614
|
+
```typescript
|
|
615
|
+
// App.tsx
|
|
616
|
+
import { OxyProvider } from '@oxyhq/services';
|
|
223
617
|
|
|
224
|
-
|
|
225
|
-
|
|
618
|
+
function App() {
|
|
619
|
+
return (
|
|
620
|
+
<OxyProvider baseURL="https://cloud.oxy.so">
|
|
621
|
+
<UserDashboard />
|
|
622
|
+
</OxyProvider>
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
// UserDashboard.tsx
|
|
627
|
+
import { useOxy } from '@oxyhq/services';
|
|
628
|
+
import { View, Text, StyleSheet } from 'react-native';
|
|
629
|
+
|
|
630
|
+
function UserDashboard() {
|
|
631
|
+
const { user, isAuthenticated, oxyServices } = useOxy();
|
|
632
|
+
|
|
633
|
+
const [followers, setFollowers] = useState([]);
|
|
634
|
+
|
|
635
|
+
useEffect(() => {
|
|
636
|
+
if (isAuthenticated && user) {
|
|
637
|
+
oxyServices.getUserFollowers(user.id).then(setFollowers);
|
|
638
|
+
}
|
|
639
|
+
}, [isAuthenticated, user]);
|
|
640
|
+
|
|
641
|
+
if (!isAuthenticated) {
|
|
642
|
+
return <Text>Please sign in</Text>;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
return (
|
|
646
|
+
<View style={styles.container}>
|
|
647
|
+
<Text style={styles.title}>Welcome, {user?.name}!</Text>
|
|
648
|
+
<Text>Followers: {followers.length}</Text>
|
|
649
|
+
</View>
|
|
650
|
+
);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
const styles = StyleSheet.create({
|
|
654
|
+
container: {
|
|
655
|
+
flex: 1,
|
|
656
|
+
padding: 16,
|
|
657
|
+
justifyContent: 'center',
|
|
658
|
+
},
|
|
659
|
+
title: {
|
|
660
|
+
fontSize: 24,
|
|
661
|
+
fontWeight: 'bold',
|
|
662
|
+
marginBottom: 16,
|
|
663
|
+
},
|
|
664
|
+
});
|
|
226
665
|
```
|
|
227
666
|
|
|
228
|
-
|
|
667
|
+
### Complete Backend API
|
|
229
668
|
|
|
230
|
-
|
|
669
|
+
```typescript
|
|
670
|
+
// server.ts
|
|
671
|
+
import express from 'express';
|
|
672
|
+
import { oxyClient } from '@oxyhq/services';
|
|
673
|
+
|
|
674
|
+
const app = express();
|
|
675
|
+
app.use(express.json());
|
|
676
|
+
|
|
677
|
+
// Auth routes
|
|
678
|
+
app.post('/api/auth/signin', async (req, res) => {
|
|
679
|
+
try {
|
|
680
|
+
const { username, password } = req.body;
|
|
681
|
+
const response = await oxyClient.signIn(username, password);
|
|
682
|
+
res.json(response);
|
|
683
|
+
} catch (error) {
|
|
684
|
+
res.status(401).json({ error: error.message });
|
|
685
|
+
}
|
|
686
|
+
});
|
|
231
687
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
688
|
+
// User routes
|
|
689
|
+
app.get('/api/users/:userId', async (req, res) => {
|
|
690
|
+
try {
|
|
691
|
+
const { userId } = req.params;
|
|
692
|
+
const user = await oxyClient.getUserById(userId);
|
|
693
|
+
res.json(user);
|
|
694
|
+
} catch (error) {
|
|
695
|
+
res.status(500).json({ error: error.message });
|
|
696
|
+
}
|
|
697
|
+
});
|
|
235
698
|
|
|
236
|
-
|
|
237
|
-
|
|
699
|
+
// Social routes
|
|
700
|
+
app.get('/api/users/:userId/followers', async (req, res) => {
|
|
701
|
+
try {
|
|
702
|
+
const { userId } = req.params;
|
|
703
|
+
const followers = await oxyClient.getUserFollowers(userId);
|
|
704
|
+
res.json(followers);
|
|
705
|
+
} catch (error) {
|
|
706
|
+
res.status(500).json({ error: error.message });
|
|
707
|
+
}
|
|
708
|
+
});
|
|
709
|
+
|
|
710
|
+
app.listen(3000, () => {
|
|
711
|
+
console.log('Server running on port 3000');
|
|
712
|
+
});
|
|
238
713
|
```
|
|
239
714
|
|
|
240
|
-
|
|
715
|
+
---
|
|
716
|
+
|
|
717
|
+
## 📄 License
|
|
241
718
|
|
|
242
719
|
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|