@greatapps/common 1.1.697 → 1.1.699
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/dist/components/account/ConfigurationsMyAccountModal.mjs +1 -1
- package/dist/components/account/ConfigurationsMyAccountModal.mjs.map +1 -1
- package/dist/components/account/ConfirmDeleteAccountModal.mjs.map +1 -1
- package/dist/components/account/ConfirmGlobalPreferencesModal.mjs.map +1 -1
- package/dist/components/account/DeleteAccountModal.mjs.map +1 -1
- package/dist/components/account/DisableTwoFactorAuthModal.mjs.map +1 -1
- package/dist/components/account/IsntPossibleDeleteAccountModal.mjs.map +1 -1
- package/dist/components/account/TwoFactorAuthModal.mjs.map +1 -1
- package/dist/components/account/hooks/useChangePhoneForm.mjs.map +1 -1
- package/dist/components/account/hooks/useTwoFactorAuthForm.mjs.map +1 -1
- package/dist/components/account/sections/ChangeEmailModal.mjs.map +1 -1
- package/dist/components/account/sections/ChangePasswordSection.mjs.map +1 -1
- package/dist/components/account/sections/ChangePhoneModal.mjs.map +1 -1
- package/dist/components/account/sections/MyProfileSection.mjs.map +1 -1
- package/dist/components/account/sections/PreferencesSection.mjs.map +1 -1
- package/dist/components/account/sections/SecuritySection.mjs.map +1 -1
- package/dist/components/account/sections/TokenSection.mjs.map +1 -1
- package/dist/components/embeds/ClarityEmbed.mjs.map +1 -1
- package/dist/components/embeds/CrispEmbed.mjs.map +1 -1
- package/dist/components/embeds/EmbedWidgets.mjs.map +1 -1
- package/dist/components/embeds/FrillEmbed.mjs.map +1 -1
- package/dist/components/layouts/AppMobileNavBar.mjs.map +1 -1
- package/dist/components/layouts/AppNavBar.mjs.map +1 -1
- package/dist/components/layouts/MdSideBarNavigation.mjs.map +1 -1
- package/dist/components/layouts/NavBar.mjs.map +1 -1
- package/dist/components/layouts/NotificationsPopover.mjs.map +1 -1
- package/dist/components/layouts/ProfilePopover.mjs.map +1 -1
- package/dist/components/layouts/SideBarNavigation.mjs.map +1 -1
- package/dist/components/layouts/UsersSelectorPopover.mjs.map +1 -1
- package/dist/components/layouts/WhitelabelCodes.mjs.map +1 -1
- package/dist/components/modals/BuyCreditsModal.mjs.map +1 -1
- package/dist/components/modals/CreditsDisabledModal.mjs.map +1 -1
- package/dist/components/modals/Modals.mjs.map +1 -1
- package/dist/components/modals/PaidPlanRequiredModal.mjs.map +1 -1
- package/dist/components/modals/cards/AddCardModal.mjs.map +1 -1
- package/dist/components/modals/cards/CannotDeleteCardModal.mjs.map +1 -1
- package/dist/components/modals/cards/CardFormFields.mjs.map +1 -1
- package/dist/components/modals/cards/DeleteCardModal.mjs.map +1 -1
- package/dist/components/navigation/CancelledSubscriptionBanner.mjs.map +1 -1
- package/dist/components/navigation/NavItemsContext.mjs.map +1 -1
- package/dist/components/navigation/OverdueInvoiceBanner.mjs.map +1 -1
- package/dist/components/navigation/PendingCancellationBanner.mjs.map +1 -1
- package/dist/components/navigation/ProjectSelectorPopover.mjs.map +1 -1
- package/dist/components/navigation/SubscriptionBanner.mjs.map +1 -1
- package/dist/components/navigation/TrialBanner.mjs.map +1 -1
- package/dist/components/navigation/UpcomingInvoiceBanner.mjs.map +1 -1
- package/dist/components/navigation/shells/TabsMobileShell.mjs.map +1 -1
- package/dist/components/navigation/subcomponents/BottomLinks.mjs.map +1 -1
- package/dist/components/navigation/subcomponents/ProjectSelector.mjs.map +1 -1
- package/dist/components/pages/NotFoundPage.mjs.map +1 -1
- package/dist/components/pages/notifications/Notifications.mjs.map +1 -1
- package/dist/components/ui/buttons/Button.mjs.map +1 -1
- package/dist/components/ui/buttons/CancelButton.mjs.map +1 -1
- package/dist/components/ui/buttons/CopyButton.mjs.map +1 -1
- package/dist/components/ui/data-display/Accordion.mjs.map +1 -1
- package/dist/components/ui/data-display/Badge.mjs.map +1 -1
- package/dist/components/ui/data-display/Card.mjs.map +1 -1
- package/dist/components/ui/data-display/CardBrandIcons.mjs.map +1 -1
- package/dist/components/ui/data-display/CardItem.mjs.map +1 -1
- package/dist/components/ui/data-display/Pagination.mjs.map +1 -1
- package/dist/components/ui/data-display/PaymentInfoCard.mjs.map +1 -1
- package/dist/components/ui/data-display/ScrollArea.mjs.map +1 -1
- package/dist/components/ui/data-display/Separator.mjs.map +1 -1
- package/dist/components/ui/data-display/Table.mjs.map +1 -1
- package/dist/components/ui/data-display/Tabs.mjs.map +1 -1
- package/dist/components/ui/feedback/CircularProgress.mjs.map +1 -1
- package/dist/components/ui/feedback/DefaultCircularProgress.mjs.map +1 -1
- package/dist/components/ui/feedback/LoadingOverlay.mjs.map +1 -1
- package/dist/components/ui/feedback/Progress.mjs.map +1 -1
- package/dist/components/ui/feedback/Skeleton.mjs.map +1 -1
- package/dist/components/ui/feedback/Toast.mjs.map +1 -1
- package/dist/components/ui/form/Calendar.mjs.map +1 -1
- package/dist/components/ui/form/Checkbox.mjs.map +1 -1
- package/dist/components/ui/form/ComboboxField.mjs.map +1 -1
- package/dist/components/ui/form/DatePicker.mjs.map +1 -1
- package/dist/components/ui/form/DateRangePicker.mjs.map +1 -1
- package/dist/components/ui/form/FormField.mjs.map +1 -1
- package/dist/components/ui/form/Input.mjs.map +1 -1
- package/dist/components/ui/form/InputOtp.mjs.map +1 -1
- package/dist/components/ui/form/PhoneInput.mjs.map +1 -1
- package/dist/components/ui/form/RadioGroup.mjs.map +1 -1
- package/dist/components/ui/form/Select.mjs +1 -1
- package/dist/components/ui/form/Select.mjs.map +1 -1
- package/dist/components/ui/form/Switch.mjs.map +1 -1
- package/dist/components/ui/form/Textarea.mjs.map +1 -1
- package/dist/components/ui/overlay/Command.mjs.map +1 -1
- package/dist/components/ui/overlay/Dialog.mjs.map +1 -1
- package/dist/components/ui/overlay/Popover.mjs.map +1 -1
- package/dist/components/ui/overlay/Sheet.mjs.map +1 -1
- package/dist/components/ui/overlay/Tooltip.mjs.map +1 -1
- package/dist/components/widgets/ImageUpload/ImageCropModal.mjs.map +1 -1
- package/dist/components/widgets/ImageUpload/ImageTooSmallModal.mjs.map +1 -1
- package/dist/components/widgets/ImageUpload/ImageUpload.mjs.map +1 -1
- package/dist/components/widgets/ImageUpload/index.mjs.map +1 -1
- package/dist/components/widgets/notifications/NotificationCard.mjs.map +1 -1
- package/dist/handlers.mjs.map +1 -1
- package/dist/hooks/copy-to-clipboard.hook.mjs.map +1 -1
- package/dist/hooks/useAuthQueryKey.mjs.map +1 -1
- package/dist/hooks/useBrandLoadingIcon.mjs.map +1 -1
- package/dist/hooks/useRouter.mjs.map +1 -1
- package/dist/http.mjs.map +1 -1
- package/dist/i18n/config.mjs.map +1 -1
- package/dist/i18n/country-language.mjs.map +1 -1
- package/dist/i18n/messages/en-us.mjs.map +1 -1
- package/dist/i18n/messages/es-es.mjs.map +1 -1
- package/dist/i18n/messages/index.mjs.map +1 -1
- package/dist/i18n/messages/pt-br.mjs.map +1 -1
- package/dist/i18n/normalize.mjs.map +1 -1
- package/dist/i18n/resolve-locale.mjs.map +1 -1
- package/dist/i18n.mjs.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/infra/http/api-fetch.mjs.map +1 -1
- package/dist/infra/route/parse-id.mjs.map +1 -1
- package/dist/infra/route/parse-numeric.mjs.map +1 -1
- package/dist/infra/route/safe-route-handler.mjs.map +1 -1
- package/dist/infra/route/search-params.mjs.map +1 -1
- package/dist/infra/utils/array.mjs.map +1 -1
- package/dist/infra/utils/date.mjs.map +1 -1
- package/dist/middleware.mjs.map +1 -1
- package/dist/modules/accounts/actions/account-management.action.mjs.map +1 -1
- package/dist/modules/accounts/actions/find-current-account.action.mjs.map +1 -1
- package/dist/modules/accounts/actions/get-account-token.action.mjs.map +1 -1
- package/dist/modules/accounts/actions/list-currencies.action.mjs.map +1 -1
- package/dist/modules/accounts/actions/list-timezones.action.mjs.map +1 -1
- package/dist/modules/accounts/hooks/current-account.hook.mjs.map +1 -1
- package/dist/modules/accounts/hooks/use-account-token.hook.mjs.map +1 -1
- package/dist/modules/accounts/hooks/use-currency-formatter.hook.mjs.map +1 -1
- package/dist/modules/accounts/hooks/useAccountManagement.mjs.map +1 -1
- package/dist/modules/accounts/hooks/useCurrencies.mjs.map +1 -1
- package/dist/modules/accounts/hooks/useTimezones.mjs.map +1 -1
- package/dist/modules/accounts/hooks/useViaCep.mjs.map +1 -1
- package/dist/modules/accounts/services/account-token.service.mjs.map +1 -1
- package/dist/modules/accounts/services/account.service.mjs.map +1 -1
- package/dist/modules/auth/actions/social-google-login.action.mjs.map +1 -1
- package/dist/modules/auth/actions/social-google-onboarding.action.mjs.map +1 -1
- package/dist/modules/auth/actions/unlink-google.action.mjs.map +1 -1
- package/dist/modules/auth/actions/validate-session.action.mjs.map +1 -1
- package/dist/modules/auth/actions/verify-two-factor.action.mjs.map +1 -1
- package/dist/modules/auth/hooks/login.hook.mjs.map +1 -1
- package/dist/modules/auth/hooks/logout.hook.mjs.map +1 -1
- package/dist/modules/auth/hooks/register.hook.mjs.map +1 -1
- package/dist/modules/auth/hooks/social-google-login.hook.mjs.map +1 -1
- package/dist/modules/auth/hooks/social-google-onboarding.hook.mjs.map +1 -1
- package/dist/modules/auth/hooks/unlink-google.hook.mjs.map +1 -1
- package/dist/modules/auth/hooks/useManagementPermissions.mjs.map +1 -1
- package/dist/modules/auth/hooks/useUserQuery.mjs.map +1 -1
- package/dist/modules/auth/utils/assert-management-permission.mjs.map +1 -1
- package/dist/modules/auth/utils/assert-management-subscription.mjs.map +1 -1
- package/dist/modules/auth/utils/assert-paid-subscription.mjs.map +1 -1
- package/dist/modules/auth/utils/assert-subscription-addon.mjs.map +1 -1
- package/dist/modules/auth/utils/build-wl-override.mjs.map +1 -1
- package/dist/modules/auth/utils/require-token-not-expired.mjs.map +1 -1
- package/dist/modules/auth/utils/require-valid-session.mjs.map +1 -1
- package/dist/modules/cards/actions/create-card.action.mjs.map +1 -1
- package/dist/modules/cards/actions/create-setup-intent.action.mjs.map +1 -1
- package/dist/modules/cards/actions/delete-card.action.mjs.map +1 -1
- package/dist/modules/cards/actions/set-default-card.action.mjs.map +1 -1
- package/dist/modules/cards/handlers/find-card-by-id.handler.mjs.map +1 -1
- package/dist/modules/cards/handlers/list-cards.handler.mjs.map +1 -1
- package/dist/modules/cards/hooks/card-by-id.hook.mjs.map +1 -1
- package/dist/modules/cards/hooks/cards.hook.mjs.map +1 -1
- package/dist/modules/cards/hooks/create-card.hook.mjs.map +1 -1
- package/dist/modules/cards/hooks/create-setup-intent.hook.mjs.map +1 -1
- package/dist/modules/cards/hooks/delete-card.hook.mjs.map +1 -1
- package/dist/modules/cards/hooks/delete-confirmation.hook.mjs.map +1 -1
- package/dist/modules/cards/hooks/handle-delete-card.hook.mjs.map +1 -1
- package/dist/modules/cards/hooks/set-default-card.hook.mjs.map +1 -1
- package/dist/modules/cards/services/cards.service.mjs.map +1 -1
- package/dist/modules/cards/types.mjs.map +1 -1
- package/dist/modules/charges/actions/charge-action.action.mjs.map +1 -1
- package/dist/modules/charges/handlers/find-charge-by-id.handler.mjs.map +1 -1
- package/dist/modules/charges/handlers/list-charges.handler.mjs.map +1 -1
- package/dist/modules/charges/hooks/charge-action.hook.mjs.map +1 -1
- package/dist/modules/charges/hooks/charge-by-id.hook.mjs.map +1 -1
- package/dist/modules/charges/hooks/charges.hook.mjs.map +1 -1
- package/dist/modules/charges/services/charges.service.mjs.map +1 -1
- package/dist/modules/charges/types/charge.type.mjs.map +1 -1
- package/dist/modules/ia-credits/handlers/list-ia-credits.handler.mjs.map +1 -1
- package/dist/modules/ia-credits/hooks/ia-credits.hook.mjs.map +1 -1
- package/dist/modules/images/actions/process-image.action.mjs.map +1 -1
- package/dist/modules/images/constants/image.constants.mjs.map +1 -1
- package/dist/modules/images/hooks/use-image-upload.hook.mjs.map +1 -1
- package/dist/modules/images/services/image-processing.service.mjs.map +1 -1
- package/dist/modules/images/utils/base64.mjs.map +1 -1
- package/dist/modules/images/utils/compress-image.mjs.map +1 -1
- package/dist/modules/images/utils/crop-image.mjs.map +1 -1
- package/dist/modules/images/utils/validate-image.mjs.map +1 -1
- package/dist/modules/pages/constants/query-keys.constants.mjs.map +1 -1
- package/dist/modules/pages/handlers/count-pages.handler.mjs.map +1 -1
- package/dist/modules/pages/hooks/count-pages.hook.mjs.map +1 -1
- package/dist/modules/pages/services/pages.service.mjs.map +1 -1
- package/dist/modules/plans/handlers/find-plan-by-id.handler.mjs.map +1 -1
- package/dist/modules/plans/handlers/list-plans.handler.mjs.map +1 -1
- package/dist/modules/plans/hooks/list-plans.hook.mjs.map +1 -1
- package/dist/modules/plans/hooks/use-has-plan-addon.hook.mjs.map +1 -1
- package/dist/modules/plans/hooks/use-plan-by-id.hook.mjs.map +1 -1
- package/dist/modules/plans/services/plans.service.mjs +1 -1
- package/dist/modules/plans/services/plans.service.mjs.map +1 -1
- package/dist/modules/plans/types/plan.type.mjs +5 -1
- package/dist/modules/plans/types/plan.type.mjs.map +1 -1
- package/dist/modules/plans/utils/map-api-plan-to-ui.mjs.map +1 -1
- package/dist/modules/projects/actions/add-project-user.action.mjs.map +1 -1
- package/dist/modules/projects/actions/create-project.action.mjs.map +1 -1
- package/dist/modules/projects/actions/delete-project.action.mjs.map +1 -1
- package/dist/modules/projects/actions/find-project.action.mjs.map +1 -1
- package/dist/modules/projects/actions/list-project-users.action.mjs.map +1 -1
- package/dist/modules/projects/actions/list-projects.action.mjs.map +1 -1
- package/dist/modules/projects/actions/remove-project-user.action.mjs.map +1 -1
- package/dist/modules/projects/actions/update-project.action.mjs.map +1 -1
- package/dist/modules/projects/handlers/find-project.handler.mjs.map +1 -1
- package/dist/modules/projects/handlers/list-all-account-users.handler.mjs.map +1 -1
- package/dist/modules/projects/handlers/list-available-users.handler.mjs.map +1 -1
- package/dist/modules/projects/handlers/list-project-users.handler.mjs.map +1 -1
- package/dist/modules/projects/handlers/list-projects.handler.mjs.map +1 -1
- package/dist/modules/projects/hooks/add-project-user.hook.mjs.map +1 -1
- package/dist/modules/projects/hooks/create-project.hook.mjs.map +1 -1
- package/dist/modules/projects/hooks/delete-project.hook.mjs.map +1 -1
- package/dist/modules/projects/hooks/find-project.hook.mjs.map +1 -1
- package/dist/modules/projects/hooks/list-all-account-users.hook.mjs.map +1 -1
- package/dist/modules/projects/hooks/list-available-users.hook.mjs.map +1 -1
- package/dist/modules/projects/hooks/list-infinite-projects.hook.mjs.map +1 -1
- package/dist/modules/projects/hooks/list-project-users.hook.mjs.map +1 -1
- package/dist/modules/projects/hooks/list-projects.hook.mjs.map +1 -1
- package/dist/modules/projects/hooks/remove-project-user.hook.mjs.map +1 -1
- package/dist/modules/projects/hooks/update-project.hook.mjs.map +1 -1
- package/dist/modules/projects/services/project-users.service.mjs +2 -2
- package/dist/modules/projects/services/project-users.service.mjs.map +1 -1
- package/dist/modules/projects/services/projects.service.mjs.map +1 -1
- package/dist/modules/subscriptions/actions/calculate-subscription.action.mjs.map +1 -1
- package/dist/modules/subscriptions/actions/list-subscriptions.action.mjs.map +1 -1
- package/dist/modules/subscriptions/actions/update-subscription-payment.action.mjs.map +1 -1
- package/dist/modules/subscriptions/actions/update-subscription-plan.action.mjs.map +1 -1
- package/dist/modules/subscriptions/constants/query-keys.constants.mjs.map +1 -1
- package/dist/modules/subscriptions/constants/subscription.constants.mjs.map +1 -1
- package/dist/modules/subscriptions/handlers/list-subscriptions.handler.mjs.map +1 -1
- package/dist/modules/subscriptions/hooks/calculate-subscription.hook.mjs.map +1 -1
- package/dist/modules/subscriptions/hooks/find-active-subscription.hook.mjs.map +1 -1
- package/dist/modules/subscriptions/hooks/list-subscriptions.hook.mjs.map +1 -1
- package/dist/modules/subscriptions/hooks/update-subscription-payment.hook.mjs.map +1 -1
- package/dist/modules/subscriptions/hooks/update-subscription-plan.hook.mjs.map +1 -1
- package/dist/modules/subscriptions/hooks/use-cancelled-subscription-guard.mjs.map +1 -1
- package/dist/modules/subscriptions/types/calculate-subscription.type.mjs.map +1 -1
- package/dist/modules/subscriptions/types/pix-pending.type.mjs.map +1 -1
- package/dist/modules/subscriptions/utils/build-plan-extras.mjs.map +1 -1
- package/dist/modules/subscriptions/utils/get-subscription-cancellation-state.mjs.map +1 -1
- package/dist/modules/subscriptions/utils/get-subscription-expiry-date.mjs.map +1 -1
- package/dist/modules/subscriptions/utils/has-subscription-expired.mjs.map +1 -1
- package/dist/modules/subscriptions/utils/periodicity.mjs.map +1 -1
- package/dist/modules/subscriptions/utils/resolve-plan-extras-prices.mjs.map +1 -1
- package/dist/modules/users/action/find-user-by-id.action.mjs.map +1 -1
- package/dist/modules/users/action/mark-all-messages-as-read.action.mjs.map +1 -1
- package/dist/modules/users/action/mark-message-as-read.action.mjs.map +1 -1
- package/dist/modules/users/handlers/list-messages.handler.mjs.map +1 -1
- package/dist/modules/users/hooks/messages.hook.mjs.map +1 -1
- package/dist/modules/users/services/messages.service.mjs.map +1 -1
- package/dist/modules/whitelabel/actions/find-whitelabel.action.mjs.map +1 -1
- package/dist/modules/whitelabel/actions/revalidate-whitelabel.action.mjs.map +1 -1
- package/dist/modules/whitelabel/utils/normalize-hostname.mjs.map +1 -1
- package/dist/providers/auth.provider.mjs.map +1 -1
- package/dist/providers/navigation.provider.mjs.map +1 -1
- package/dist/providers/whitelabel.provider.mjs.map +1 -1
- package/dist/route.mjs.map +1 -1
- package/dist/store/useAccountModals.mjs.map +1 -1
- package/dist/store/useBuyCreditsModal.mjs.map +1 -1
- package/dist/store/useCreditsDisabledModal.mjs.map +1 -1
- package/dist/store/useDesktopSidebarStore.mjs.map +1 -1
- package/dist/store/useMdSidebarStore.mjs.map +1 -1
- package/dist/store/usePaidPlanRequiredModal.mjs.map +1 -1
- package/dist/utils/constants/br-states.mjs.map +1 -1
- package/dist/utils/countries.mjs.map +1 -1
- package/dist/utils/format/currency.mjs.map +1 -1
- package/dist/utils/intl/cookie-domain.mjs.map +1 -1
- package/dist/utils/intl/locale-cookie.mjs.map +1 -1
- package/dist/utils/next-navigation.mjs.map +1 -1
- package/dist/utils/redirect.mjs.map +1 -1
- package/dist/utils/safeMutationAction.mjs.map +1 -1
- package/dist/utils/safeServerAction.mjs.map +1 -1
- package/dist/utils/withAction.mjs.map +1 -1
- package/package.json +115 -115
- package/src/components/account/ConfigurationsMyAccountModal.tsx +179 -179
- package/src/components/account/ConfirmDeleteAccountModal.tsx +110 -110
- package/src/components/account/ConfirmGlobalPreferencesModal.tsx +68 -68
- package/src/components/account/DeleteAccountModal.tsx +160 -160
- package/src/components/account/DisableTwoFactorAuthModal.tsx +92 -92
- package/src/components/account/IsntPossibleDeleteAccountModal.tsx +51 -51
- package/src/components/account/TwoFactorAuthModal.tsx +220 -220
- package/src/components/account/hooks/useChangePhoneForm.tsx +113 -113
- package/src/components/account/hooks/useTwoFactorAuthForm.tsx +116 -116
- package/src/components/account/sections/ChangeEmailModal.tsx +239 -239
- package/src/components/account/sections/ChangePasswordSection.tsx +68 -68
- package/src/components/account/sections/ChangePhoneModal.tsx +273 -273
- package/src/components/account/sections/MyProfileSection.tsx +276 -276
- package/src/components/account/sections/PreferencesSection.tsx +278 -278
- package/src/components/account/sections/SecuritySection.tsx +102 -102
- package/src/components/account/sections/TokenSection.tsx +85 -85
- package/src/components/embeds/ClarityEmbed.tsx +70 -70
- package/src/components/embeds/CrispEmbed.tsx +195 -195
- package/src/components/embeds/EmbedWidgets.tsx +62 -62
- package/src/components/embeds/FrillEmbed.tsx +146 -146
- package/src/components/layouts/AppMobileNavBar.tsx +214 -214
- package/src/components/layouts/AppNavBar.tsx +40 -40
- package/src/components/layouts/MdSideBarNavigation.tsx +56 -56
- package/src/components/layouts/NavBar.tsx +228 -228
- package/src/components/layouts/NotificationsPopover.tsx +120 -120
- package/src/components/layouts/ProfilePopover.tsx +191 -191
- package/src/components/layouts/SideBarNavigation.tsx +65 -65
- package/src/components/layouts/UsersSelectorPopover.tsx +236 -236
- package/src/components/layouts/WhitelabelCodes.tsx +59 -59
- package/src/components/modals/BuyCreditsModal.tsx +390 -390
- package/src/components/modals/CreditsDisabledModal.tsx +62 -62
- package/src/components/modals/Modals.tsx +25 -25
- package/src/components/modals/PaidPlanRequiredModal.tsx +60 -60
- package/src/components/modals/cards/AddCardModal.tsx +420 -420
- package/src/components/modals/cards/CannotDeleteCardModal.tsx +124 -124
- package/src/components/modals/cards/CardFormFields.tsx +363 -363
- package/src/components/modals/cards/DeleteCardModal.tsx +136 -136
- package/src/components/navigation/CancelledSubscriptionBanner.tsx +62 -62
- package/src/components/navigation/NavItemsContext.ts +20 -20
- package/src/components/navigation/OverdueInvoiceBanner.tsx +51 -51
- package/src/components/navigation/PendingCancellationBanner.tsx +60 -60
- package/src/components/navigation/ProjectSelectorPopover.tsx +180 -180
- package/src/components/navigation/SubscriptionBanner.tsx +94 -94
- package/src/components/navigation/TrialBanner.tsx +54 -54
- package/src/components/navigation/UpcomingInvoiceBanner.tsx +55 -55
- package/src/components/navigation/shells/TabsMobileShell.tsx +74 -74
- package/src/components/navigation/subcomponents/BottomLinks.tsx +85 -85
- package/src/components/navigation/subcomponents/ProjectSelector.tsx +184 -184
- package/src/components/pages/NotFoundPage.tsx +75 -75
- package/src/components/pages/notifications/Notifications.tsx +190 -190
- package/src/components/ui/buttons/Button.tsx +77 -77
- package/src/components/ui/buttons/CancelButton.tsx +14 -14
- package/src/components/ui/buttons/CopyButton.tsx +59 -59
- package/src/components/ui/data-display/Accordion.tsx +81 -81
- package/src/components/ui/data-display/Badge.tsx +47 -47
- package/src/components/ui/data-display/Card.tsx +93 -93
- package/src/components/ui/data-display/CardBrandIcons.tsx +336 -336
- package/src/components/ui/data-display/CardItem.tsx +135 -135
- package/src/components/ui/data-display/Pagination.tsx +126 -126
- package/src/components/ui/data-display/PaymentInfoCard.tsx +193 -193
- package/src/components/ui/data-display/ScrollArea.tsx +59 -59
- package/src/components/ui/data-display/Separator.tsx +29 -29
- package/src/components/ui/data-display/Table.tsx +117 -117
- package/src/components/ui/data-display/Tabs.tsx +67 -67
- package/src/components/ui/feedback/CircularProgress.tsx +79 -79
- package/src/components/ui/feedback/DefaultCircularProgress.tsx +67 -67
- package/src/components/ui/feedback/LoadingOverlay.tsx +30 -30
- package/src/components/ui/feedback/Progress.tsx +40 -40
- package/src/components/ui/feedback/Skeleton.tsx +5 -5
- package/src/components/ui/feedback/Toast.tsx +104 -104
- package/src/components/ui/form/Calendar.tsx +228 -228
- package/src/components/ui/form/Checkbox.tsx +31 -31
- package/src/components/ui/form/ComboboxField.tsx +159 -159
- package/src/components/ui/form/DatePicker.tsx +100 -100
- package/src/components/ui/form/DateRangePicker.tsx +111 -111
- package/src/components/ui/form/FormField.tsx +133 -133
- package/src/components/ui/form/Input.tsx +20 -20
- package/src/components/ui/form/InputOtp.tsx +80 -80
- package/src/components/ui/form/PhoneInput.tsx +210 -210
- package/src/components/ui/form/RadioGroup.tsx +45 -45
- package/src/components/ui/form/Select.tsx +200 -200
- package/src/components/ui/form/Switch.tsx +32 -32
- package/src/components/ui/form/Textarea.tsx +19 -19
- package/src/components/ui/overlay/Command.tsx +185 -185
- package/src/components/ui/overlay/Dialog.tsx +153 -153
- package/src/components/ui/overlay/Popover.tsx +49 -49
- package/src/components/ui/overlay/Sheet.tsx +170 -170
- package/src/components/ui/overlay/Tooltip.tsx +62 -62
- package/src/components/widgets/ImageUpload/ImageCropModal.tsx +392 -392
- package/src/components/widgets/ImageUpload/ImageTooSmallModal.tsx +62 -62
- package/src/components/widgets/ImageUpload/ImageUpload.tsx +131 -131
- package/src/components/widgets/ImageUpload/index.ts +3 -3
- package/src/components/widgets/notifications/NotificationCard.tsx +73 -73
- package/src/handlers.ts +22 -22
- package/src/hooks/copy-to-clipboard.hook.tsx +67 -67
- package/src/hooks/useAuthQueryKey.ts +32 -32
- package/src/hooks/useBrandLoadingIcon.tsx +18 -18
- package/src/hooks/useRouter.ts +38 -38
- package/src/http.ts +1 -1
- package/src/i18n/config.ts +17 -17
- package/src/i18n/country-language.ts +60 -60
- package/src/i18n/messages/en-us.ts +519 -519
- package/src/i18n/messages/es-es.ts +520 -520
- package/src/i18n/messages/index.ts +24 -24
- package/src/i18n/messages/pt-br.ts +543 -543
- package/src/i18n/normalize.ts +15 -15
- package/src/i18n/resolve-locale.ts +77 -77
- package/src/i18n.ts +10 -10
- package/src/index.ts +584 -584
- package/src/infra/http/api-fetch.ts +39 -39
- package/src/infra/route/parse-id.ts +9 -9
- package/src/infra/route/parse-numeric.ts +16 -16
- package/src/infra/route/safe-route-handler.ts +16 -16
- package/src/infra/route/search-params.ts +9 -9
- package/src/infra/utils/array.ts +167 -167
- package/src/infra/utils/date.ts +59 -59
- package/src/middleware.ts +4 -4
- package/src/modules/accounts/actions/account-management.action.ts +109 -109
- package/src/modules/accounts/actions/find-current-account.action.ts +9 -9
- package/src/modules/accounts/actions/get-account-token.action.ts +8 -8
- package/src/modules/accounts/actions/list-currencies.action.ts +8 -8
- package/src/modules/accounts/actions/list-timezones.action.ts +8 -8
- package/src/modules/accounts/hooks/current-account.hook.tsx +26 -26
- package/src/modules/accounts/hooks/use-account-token.hook.tsx +14 -14
- package/src/modules/accounts/hooks/use-currency-formatter.hook.tsx +32 -32
- package/src/modules/accounts/hooks/useAccountManagement.ts +95 -95
- package/src/modules/accounts/hooks/useCurrencies.ts +18 -18
- package/src/modules/accounts/hooks/useTimezones.ts +18 -18
- package/src/modules/accounts/hooks/useViaCep.ts +25 -25
- package/src/modules/accounts/services/account-token.service.ts +52 -52
- package/src/modules/accounts/services/account.service.ts +243 -243
- package/src/modules/accounts/types.ts +230 -230
- package/src/modules/auth/actions/social-google-login.action.ts +12 -12
- package/src/modules/auth/actions/social-google-onboarding.action.ts +13 -13
- package/src/modules/auth/actions/unlink-google.action.ts +8 -8
- package/src/modules/auth/actions/validate-session.action.ts +70 -70
- package/src/modules/auth/actions/verify-two-factor.action.ts +19 -19
- package/src/modules/auth/hooks/login.hook.tsx +13 -13
- package/src/modules/auth/hooks/logout.hook.tsx +11 -11
- package/src/modules/auth/hooks/register.hook.tsx +11 -11
- package/src/modules/auth/hooks/social-google-login.hook.tsx +13 -13
- package/src/modules/auth/hooks/social-google-onboarding.hook.tsx +13 -13
- package/src/modules/auth/hooks/unlink-google.hook.tsx +13 -13
- package/src/modules/auth/hooks/useManagementPermissions.ts +52 -52
- package/src/modules/auth/hooks/useUserQuery.ts +103 -103
- package/src/modules/auth/types/management-permission.type.ts +14 -14
- package/src/modules/auth/utils/assert-management-permission.ts +56 -56
- package/src/modules/auth/utils/assert-management-subscription.ts +38 -38
- package/src/modules/auth/utils/assert-paid-subscription.ts +47 -47
- package/src/modules/auth/utils/assert-subscription-addon.ts +42 -42
- package/src/modules/auth/utils/build-wl-override.ts +43 -43
- package/src/modules/auth/utils/require-token-not-expired.ts +53 -53
- package/src/modules/auth/utils/require-valid-session.ts +35 -35
- package/src/modules/cards/actions/create-card.action.ts +9 -9
- package/src/modules/cards/actions/create-setup-intent.action.ts +8 -8
- package/src/modules/cards/actions/delete-card.action.ts +8 -8
- package/src/modules/cards/actions/set-default-card.action.ts +8 -8
- package/src/modules/cards/handlers/find-card-by-id.handler.ts +15 -15
- package/src/modules/cards/handlers/list-cards.handler.ts +10 -10
- package/src/modules/cards/hooks/card-by-id.hook.ts +17 -17
- package/src/modules/cards/hooks/cards.hook.ts +22 -22
- package/src/modules/cards/hooks/create-card.hook.ts +30 -30
- package/src/modules/cards/hooks/create-setup-intent.hook.ts +11 -11
- package/src/modules/cards/hooks/delete-card.hook.ts +52 -52
- package/src/modules/cards/hooks/delete-confirmation.hook.ts +40 -40
- package/src/modules/cards/hooks/handle-delete-card.hook.ts +47 -47
- package/src/modules/cards/hooks/set-default-card.hook.ts +55 -55
- package/src/modules/cards/services/cards.service.ts +136 -136
- package/src/modules/cards/types.ts +52 -52
- package/src/modules/charges/actions/charge-action.action.ts +13 -13
- package/src/modules/charges/handlers/find-charge-by-id.handler.ts +14 -14
- package/src/modules/charges/handlers/list-charges.handler.ts +15 -15
- package/src/modules/charges/hooks/charge-action.hook.ts +24 -24
- package/src/modules/charges/hooks/charge-by-id.hook.ts +19 -19
- package/src/modules/charges/hooks/charges.hook.ts +19 -19
- package/src/modules/charges/services/charges.service.ts +63 -63
- package/src/modules/charges/types/charge.type.ts +68 -68
- package/src/modules/ia-credits/handlers/list-ia-credits.handler.ts +14 -14
- package/src/modules/ia-credits/hooks/ia-credits.hook.ts +103 -103
- package/src/modules/images/actions/process-image.action.ts +40 -40
- package/src/modules/images/constants/image.constants.ts +11 -11
- package/src/modules/images/hooks/use-image-upload.hook.ts +153 -153
- package/src/modules/images/services/image-processing.service.ts +75 -75
- package/src/modules/images/types/image.type.ts +54 -54
- package/src/modules/images/utils/base64.ts +26 -26
- package/src/modules/images/utils/compress-image.ts +20 -20
- package/src/modules/images/utils/crop-image.ts +68 -68
- package/src/modules/images/utils/validate-image.ts +86 -86
- package/src/modules/pages/constants/query-keys.constants.ts +1 -1
- package/src/modules/pages/handlers/count-pages.handler.ts +12 -12
- package/src/modules/pages/hooks/count-pages.hook.ts +21 -21
- package/src/modules/pages/services/pages.service.ts +27 -27
- package/src/modules/plans/handlers/find-plan-by-id.handler.ts +14 -14
- package/src/modules/plans/handlers/list-plans.handler.ts +22 -22
- package/src/modules/plans/hooks/list-plans.hook.ts +23 -23
- package/src/modules/plans/hooks/use-has-plan-addon.hook.ts +14 -14
- package/src/modules/plans/hooks/use-plan-by-id.hook.ts +39 -39
- package/src/modules/plans/services/plans.service.ts +136 -135
- package/src/modules/plans/types/plan.type.ts +79 -75
- package/src/modules/plans/utils/map-api-plan-to-ui.ts +167 -167
- package/src/modules/projects/actions/add-project-user.action.ts +9 -9
- package/src/modules/projects/actions/create-project.action.ts +9 -9
- package/src/modules/projects/actions/delete-project.action.ts +8 -8
- package/src/modules/projects/actions/find-project.action.ts +8 -8
- package/src/modules/projects/actions/list-project-users.action.ts +9 -9
- package/src/modules/projects/actions/list-projects.action.ts +16 -16
- package/src/modules/projects/actions/remove-project-user.action.ts +9 -9
- package/src/modules/projects/actions/update-project.action.ts +9 -9
- package/src/modules/projects/handlers/find-project.handler.ts +15 -15
- package/src/modules/projects/handlers/list-all-account-users.handler.ts +23 -23
- package/src/modules/projects/handlers/list-available-users.handler.ts +26 -26
- package/src/modules/projects/handlers/list-project-users.handler.ts +26 -26
- package/src/modules/projects/handlers/list-projects.handler.ts +23 -23
- package/src/modules/projects/hooks/add-project-user.hook.ts +72 -72
- package/src/modules/projects/hooks/create-project.hook.ts +120 -120
- package/src/modules/projects/hooks/delete-project.hook.ts +58 -58
- package/src/modules/projects/hooks/find-project.hook.ts +18 -18
- package/src/modules/projects/hooks/list-all-account-users.hook.ts +40 -40
- package/src/modules/projects/hooks/list-available-users.hook.ts +39 -39
- package/src/modules/projects/hooks/list-infinite-projects.hook.ts +44 -44
- package/src/modules/projects/hooks/list-project-users.hook.ts +39 -39
- package/src/modules/projects/hooks/list-projects.hook.ts +23 -23
- package/src/modules/projects/hooks/remove-project-user.hook.ts +72 -72
- package/src/modules/projects/hooks/update-project.hook.ts +86 -86
- package/src/modules/projects/services/project-users.service.ts +3 -2
- package/src/modules/projects/services/projects.service.ts +156 -156
- package/src/modules/subscriptions/actions/calculate-subscription.action.ts +9 -9
- package/src/modules/subscriptions/actions/list-subscriptions.action.ts +9 -9
- package/src/modules/subscriptions/actions/update-subscription-payment.action.ts +13 -13
- package/src/modules/subscriptions/actions/update-subscription-plan.action.ts +14 -14
- package/src/modules/subscriptions/constants/query-keys.constants.ts +3 -3
- package/src/modules/subscriptions/constants/subscription.constants.ts +1 -1
- package/src/modules/subscriptions/handlers/list-subscriptions.handler.ts +17 -17
- package/src/modules/subscriptions/hooks/calculate-subscription.hook.ts +13 -13
- package/src/modules/subscriptions/hooks/find-active-subscription.hook.ts +22 -22
- package/src/modules/subscriptions/hooks/list-subscriptions.hook.ts +22 -22
- package/src/modules/subscriptions/hooks/update-subscription-payment.hook.ts +25 -25
- package/src/modules/subscriptions/hooks/update-subscription-plan.hook.ts +28 -28
- package/src/modules/subscriptions/hooks/use-cancelled-subscription-guard.ts +44 -44
- package/src/modules/subscriptions/types/billing-period.type.ts +1 -1
- package/src/modules/subscriptions/types/calculate-subscription.type.ts +116 -116
- package/src/modules/subscriptions/types/pix-pending.type.ts +38 -38
- package/src/modules/subscriptions/utils/build-plan-extras.ts +56 -56
- package/src/modules/subscriptions/utils/get-subscription-cancellation-state.ts +37 -37
- package/src/modules/subscriptions/utils/get-subscription-expiry-date.ts +33 -33
- package/src/modules/subscriptions/utils/has-subscription-expired.ts +11 -11
- package/src/modules/subscriptions/utils/periodicity.ts +79 -79
- package/src/modules/subscriptions/utils/resolve-plan-extras-prices.ts +23 -23
- package/src/modules/users/action/find-user-by-id.action.ts +8 -8
- package/src/modules/users/action/mark-all-messages-as-read.action.ts +8 -8
- package/src/modules/users/action/mark-message-as-read.action.ts +8 -8
- package/src/modules/users/handlers/list-messages.handler.ts +39 -39
- package/src/modules/users/hooks/messages.hook.ts +69 -69
- package/src/modules/users/services/messages.service.ts +49 -49
- package/src/modules/whitelabel/actions/find-whitelabel.action.ts +23 -23
- package/src/modules/whitelabel/actions/revalidate-whitelabel.action.ts +19 -19
- package/src/modules/whitelabel/schema.ts +84 -84
- package/src/modules/whitelabel/utils/normalize-hostname.ts +26 -26
- package/src/providers/auth.provider.tsx +264 -264
- package/src/providers/navigation.provider.tsx +99 -99
- package/src/providers/whitelabel.provider.tsx +90 -90
- package/src/route.ts +4 -4
- package/src/store/useAccountModals.ts +85 -85
- package/src/store/useBuyCreditsModal.ts +21 -21
- package/src/store/useCreditsDisabledModal.ts +11 -11
- package/src/store/useDesktopSidebarStore.ts +47 -47
- package/src/store/useMdSidebarStore.ts +34 -34
- package/src/store/usePaidPlanRequiredModal.ts +19 -19
- package/src/utils/constants/br-states.ts +29 -29
- package/src/utils/countries.ts +224 -224
- package/src/utils/format/currency.ts +70 -70
- package/src/utils/intl/cookie-domain.ts +29 -29
- package/src/utils/intl/locale-cookie.ts +18 -18
- package/src/utils/next-navigation.ts +7 -7
- package/src/utils/redirect.ts +78 -78
- package/src/utils/safeMutationAction.ts +24 -24
- package/src/utils/safeServerAction.ts +21 -21
- package/src/utils/withAction.ts +13 -13
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
import { buildQueryParams } from '../utils/params';
|
|
2
|
-
import type { ActionResult } from '../api/types';
|
|
3
|
-
|
|
4
|
-
type QueryParams = Parameters<typeof buildQueryParams>[0];
|
|
5
|
-
|
|
6
|
-
interface ApiFetchOptions {
|
|
7
|
-
params?: object;
|
|
8
|
-
signal?: AbortSignal;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export async function apiFetch<T>(path: string, options: ApiFetchOptions = {}): Promise<T> {
|
|
12
|
-
const { params, signal } = options;
|
|
13
|
-
const qs = params ? buildQueryParams(params as QueryParams) : '';
|
|
14
|
-
const url = qs ? `${path}?${qs}` : path;
|
|
15
|
-
|
|
16
|
-
const response = await fetch(url, {
|
|
17
|
-
method: 'GET',
|
|
18
|
-
credentials: 'same-origin',
|
|
19
|
-
headers: { Accept: 'application/json' },
|
|
20
|
-
signal,
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
if (!response.ok) {
|
|
24
|
-
let message = `Erro ${response.status}`;
|
|
25
|
-
try {
|
|
26
|
-
const body = (await response.json()) as ActionResult<unknown>;
|
|
27
|
-
if (body && !body.success && body.error) message = body.error;
|
|
28
|
-
} catch {
|
|
29
|
-
// corpo não-JSON — mantém a mensagem genérica
|
|
30
|
-
}
|
|
31
|
-
throw new Error(message);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const body = (await response.json()) as ActionResult<T>;
|
|
35
|
-
if (!body.success) {
|
|
36
|
-
throw new Error(body.error ?? 'Erro desconhecido');
|
|
37
|
-
}
|
|
38
|
-
return body.data as T;
|
|
39
|
-
}
|
|
1
|
+
import { buildQueryParams } from '../utils/params';
|
|
2
|
+
import type { ActionResult } from '../api/types';
|
|
3
|
+
|
|
4
|
+
type QueryParams = Parameters<typeof buildQueryParams>[0];
|
|
5
|
+
|
|
6
|
+
interface ApiFetchOptions {
|
|
7
|
+
params?: object;
|
|
8
|
+
signal?: AbortSignal;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function apiFetch<T>(path: string, options: ApiFetchOptions = {}): Promise<T> {
|
|
12
|
+
const { params, signal } = options;
|
|
13
|
+
const qs = params ? buildQueryParams(params as QueryParams) : '';
|
|
14
|
+
const url = qs ? `${path}?${qs}` : path;
|
|
15
|
+
|
|
16
|
+
const response = await fetch(url, {
|
|
17
|
+
method: 'GET',
|
|
18
|
+
credentials: 'same-origin',
|
|
19
|
+
headers: { Accept: 'application/json' },
|
|
20
|
+
signal,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
if (!response.ok) {
|
|
24
|
+
let message = `Erro ${response.status}`;
|
|
25
|
+
try {
|
|
26
|
+
const body = (await response.json()) as ActionResult<unknown>;
|
|
27
|
+
if (body && !body.success && body.error) message = body.error;
|
|
28
|
+
} catch {
|
|
29
|
+
// corpo não-JSON — mantém a mensagem genérica
|
|
30
|
+
}
|
|
31
|
+
throw new Error(message);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const body = (await response.json()) as ActionResult<T>;
|
|
35
|
+
if (!body.success) {
|
|
36
|
+
throw new Error(body.error ?? 'Erro desconhecido');
|
|
37
|
+
}
|
|
38
|
+
return body.data as T;
|
|
39
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { ApiError } from '../api/types';
|
|
2
|
-
|
|
3
|
-
export function parseId(value: string): number {
|
|
4
|
-
const id = Number(value);
|
|
5
|
-
if (!Number.isFinite(id) || id <= 0) {
|
|
6
|
-
throw new ApiError('Identificador inválido', 'INVALID_ID', 400);
|
|
7
|
-
}
|
|
8
|
-
return id;
|
|
9
|
-
}
|
|
1
|
+
import { ApiError } from '../api/types';
|
|
2
|
+
|
|
3
|
+
export function parseId(value: string): number {
|
|
4
|
+
const id = Number(value);
|
|
5
|
+
if (!Number.isFinite(id) || id <= 0) {
|
|
6
|
+
throw new ApiError('Identificador inválido', 'INVALID_ID', 400);
|
|
7
|
+
}
|
|
8
|
+
return id;
|
|
9
|
+
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
export function parseNumericFields<T extends object>(
|
|
2
|
-
params: Partial<T>,
|
|
3
|
-
fields: readonly (keyof T)[]
|
|
4
|
-
): Partial<T> {
|
|
5
|
-
const result: Partial<T> = { ...params };
|
|
6
|
-
for (const field of fields) {
|
|
7
|
-
const v = result[field] as unknown;
|
|
8
|
-
if (typeof v === 'string' && v !== '') {
|
|
9
|
-
const n = Number(v);
|
|
10
|
-
if (Number.isFinite(n)) {
|
|
11
|
-
result[field] = n as T[keyof T];
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
return result;
|
|
16
|
-
}
|
|
1
|
+
export function parseNumericFields<T extends object>(
|
|
2
|
+
params: Partial<T>,
|
|
3
|
+
fields: readonly (keyof T)[]
|
|
4
|
+
): Partial<T> {
|
|
5
|
+
const result: Partial<T> = { ...params };
|
|
6
|
+
for (const field of fields) {
|
|
7
|
+
const v = result[field] as unknown;
|
|
8
|
+
if (typeof v === 'string' && v !== '') {
|
|
9
|
+
const n = Number(v);
|
|
10
|
+
if (Number.isFinite(n)) {
|
|
11
|
+
result[field] = n as T[keyof T];
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import 'server-only';
|
|
2
|
-
|
|
3
|
-
import { ApiError } from '../api/types';
|
|
4
|
-
|
|
5
|
-
export async function safeRouteHandler<T>(fn: () => Promise<T>): Promise<Response> {
|
|
6
|
-
try {
|
|
7
|
-
const data = await fn();
|
|
8
|
-
return Response.json({ success: true, data });
|
|
9
|
-
} catch (error) {
|
|
10
|
-
if (error instanceof ApiError) {
|
|
11
|
-
return Response.json({ success: false, error: error.message }, { status: error.statusCode });
|
|
12
|
-
}
|
|
13
|
-
console.error('[safeRouteHandler] erro inesperado', error);
|
|
14
|
-
return Response.json({ success: false, error: 'Erro interno do servidor' }, { status: 500 });
|
|
15
|
-
}
|
|
16
|
-
}
|
|
1
|
+
import 'server-only';
|
|
2
|
+
|
|
3
|
+
import { ApiError } from '../api/types';
|
|
4
|
+
|
|
5
|
+
export async function safeRouteHandler<T>(fn: () => Promise<T>): Promise<Response> {
|
|
6
|
+
try {
|
|
7
|
+
const data = await fn();
|
|
8
|
+
return Response.json({ success: true, data });
|
|
9
|
+
} catch (error) {
|
|
10
|
+
if (error instanceof ApiError) {
|
|
11
|
+
return Response.json({ success: false, error: error.message }, { status: error.statusCode });
|
|
12
|
+
}
|
|
13
|
+
console.error('[safeRouteHandler] erro inesperado', error);
|
|
14
|
+
return Response.json({ success: false, error: 'Erro interno do servidor' }, { status: 500 });
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export function searchParamsToParams<T extends object>(
|
|
2
|
-
searchParams: URLSearchParams
|
|
3
|
-
): Partial<T> {
|
|
4
|
-
const params = Object.create(null) as Partial<Record<keyof T, string>>;
|
|
5
|
-
for (const [key, value] of searchParams.entries()) {
|
|
6
|
-
params[key as keyof T] = value;
|
|
7
|
-
}
|
|
8
|
-
return params as Partial<T>;
|
|
9
|
-
}
|
|
1
|
+
export function searchParamsToParams<T extends object>(
|
|
2
|
+
searchParams: URLSearchParams
|
|
3
|
+
): Partial<T> {
|
|
4
|
+
const params = Object.create(null) as Partial<Record<keyof T, string>>;
|
|
5
|
+
for (const [key, value] of searchParams.entries()) {
|
|
6
|
+
params[key as keyof T] = value;
|
|
7
|
+
}
|
|
8
|
+
return params as Partial<T>;
|
|
9
|
+
}
|
package/src/infra/utils/array.ts
CHANGED
|
@@ -1,167 +1,167 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Insere um item em um array já ordenado, mantendo a ordenação
|
|
3
|
-
* com base na função de comparação fornecida.
|
|
4
|
-
*/
|
|
5
|
-
export function insertSorted<T>(
|
|
6
|
-
data: T[],
|
|
7
|
-
newItem: T,
|
|
8
|
-
compareFn: (a: T, b: T) => number
|
|
9
|
-
): T[] {
|
|
10
|
-
const index = data.findIndex((item) => compareFn(newItem, item) < 0);
|
|
11
|
-
if (index === -1) return [...data, newItem];
|
|
12
|
-
return [...data.slice(0, index), newItem, ...data.slice(index)];
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface PaginatedPageCache<T> {
|
|
16
|
-
data: T[];
|
|
17
|
-
total: number;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface InsertIntoPaginatedCacheParams<T> {
|
|
21
|
-
/** Páginas atuais do cache, ordenadas por número de página (1..N). */
|
|
22
|
-
pages: PaginatedPageCache<T>[];
|
|
23
|
-
/** Números das páginas correspondentes (mesmo tamanho de `pages`). */
|
|
24
|
-
pageNumbers: number[];
|
|
25
|
-
/** Novo item a inserir. */
|
|
26
|
-
newItem: T;
|
|
27
|
-
/** Tamanho fixo de cada página. */
|
|
28
|
-
pageSize: number;
|
|
29
|
-
/**
|
|
30
|
-
* Função de comparação que mantém a ordem.
|
|
31
|
-
* Se não fornecida, insere no topo da página 1 (sem reordenar).
|
|
32
|
-
*/
|
|
33
|
-
compareFn?: (a: T, b: T) => number;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Insere um item em um conjunto de páginas paginadas mantendo ordenação.
|
|
38
|
-
*
|
|
39
|
-
* Quando `compareFn` é fornecida, descobre em qual página o item deveria
|
|
40
|
-
* cair (comparando com o último item de cada página). Insere na posição
|
|
41
|
-
* correta e empurra o último item da página para a próxima, propagando
|
|
42
|
-
* o overflow até a última página disponível.
|
|
43
|
-
*
|
|
44
|
-
* Páginas não-afetadas retornam a mesma referência.
|
|
45
|
-
*/
|
|
46
|
-
export function insertIntoPaginatedCache<T>({
|
|
47
|
-
pages,
|
|
48
|
-
pageNumbers,
|
|
49
|
-
newItem,
|
|
50
|
-
pageSize,
|
|
51
|
-
compareFn,
|
|
52
|
-
}: InsertIntoPaginatedCacheParams<T>): PaginatedPageCache<T>[] {
|
|
53
|
-
if (!pages.length) return pages;
|
|
54
|
-
|
|
55
|
-
// Sem sort: insere no topo da página 1 e propaga overflow
|
|
56
|
-
if (!compareFn) {
|
|
57
|
-
// Só atualiza se a página 1 estiver no cache
|
|
58
|
-
const firstIdx = pageNumbers.indexOf(1);
|
|
59
|
-
if (firstIdx === -1) return pages;
|
|
60
|
-
|
|
61
|
-
const result: PaginatedPageCache<T>[] = pages.slice();
|
|
62
|
-
let carry: T | null = newItem;
|
|
63
|
-
for (let i = firstIdx; i < result.length && carry !== null; i++) {
|
|
64
|
-
const current = result[i];
|
|
65
|
-
const nextData: T[] = [carry, ...current.data];
|
|
66
|
-
const overflow: T | null =
|
|
67
|
-
nextData.length > pageSize ? nextData[nextData.length - 1] : null;
|
|
68
|
-
result[i] = {
|
|
69
|
-
...current,
|
|
70
|
-
data: overflow !== null ? nextData.slice(0, pageSize) : nextData,
|
|
71
|
-
total: current.total + 1,
|
|
72
|
-
};
|
|
73
|
-
carry = overflow;
|
|
74
|
-
}
|
|
75
|
-
return result;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Descobre em qual página o item cai
|
|
79
|
-
let targetIdx = -1;
|
|
80
|
-
for (let i = 0; i < pages.length; i++) {
|
|
81
|
-
const page = pages[i];
|
|
82
|
-
if (!page.data.length) continue;
|
|
83
|
-
const last = page.data[page.data.length - 1];
|
|
84
|
-
// Se newItem vem antes (ou igual) ao último item desta página, cai aqui
|
|
85
|
-
if (compareFn(newItem, last) <= 0) {
|
|
86
|
-
targetIdx = i;
|
|
87
|
-
break;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Não coube em nenhuma página com itens — tenta a última página se for incompleta
|
|
92
|
-
if (targetIdx === -1) {
|
|
93
|
-
const lastIdx = pages.length - 1;
|
|
94
|
-
const lastPage = pages[lastIdx];
|
|
95
|
-
if (lastPage.data.length < pageSize) {
|
|
96
|
-
targetIdx = lastIdx;
|
|
97
|
-
} else {
|
|
98
|
-
// Não cai em nenhuma página carregada — apenas incrementa total
|
|
99
|
-
return pages.map((p) => ({ ...p, total: p.total + 1 }));
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Insere no target e propaga overflow para as páginas seguintes
|
|
104
|
-
const result: PaginatedPageCache<T>[] = pages.slice();
|
|
105
|
-
let carry: T | null = newItem;
|
|
106
|
-
|
|
107
|
-
for (let i = targetIdx; i < result.length && carry !== null; i++) {
|
|
108
|
-
const current = result[i];
|
|
109
|
-
const withInserted: T[] = insertSorted(current.data, carry, compareFn);
|
|
110
|
-
const overflow: T | null =
|
|
111
|
-
withInserted.length > pageSize ? withInserted[withInserted.length - 1] : null;
|
|
112
|
-
result[i] = {
|
|
113
|
-
...current,
|
|
114
|
-
data: overflow !== null ? withInserted.slice(0, pageSize) : withInserted,
|
|
115
|
-
total: current.total + 1,
|
|
116
|
-
};
|
|
117
|
-
carry = overflow;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Incrementa o total nas páginas anteriores ao target (não mudaram mas o total global cresceu)
|
|
121
|
-
for (let i = 0; i < targetIdx; i++) {
|
|
122
|
-
result[i] = { ...result[i], total: result[i].total + 1 };
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return result;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Cria uma função de comparação a partir de uma string de sort da API.
|
|
130
|
-
* Suporta múltiplos campos separados por vírgula e prefixo `-` para desc.
|
|
131
|
-
*
|
|
132
|
-
* Exemplos:
|
|
133
|
-
* - "title" → ascendente por title
|
|
134
|
-
* - "-title" → descendente por title
|
|
135
|
-
* - "title,-datetime_add" → ascendente por title, depois descendente por datetime_add
|
|
136
|
-
*/
|
|
137
|
-
export function buildCompareFn<T extends Record<string, unknown>>(
|
|
138
|
-
sort: string
|
|
139
|
-
): (a: T, b: T) => number {
|
|
140
|
-
const fields = sort.split(',').map((f) => f.trim()).filter(Boolean);
|
|
141
|
-
|
|
142
|
-
const parsedFields = fields.map((field) => {
|
|
143
|
-
const desc = field.startsWith('-');
|
|
144
|
-
const key = desc ? field.slice(1) : field;
|
|
145
|
-
return { key, desc };
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
return (a: T, b: T) => {
|
|
149
|
-
for (const { key, desc } of parsedFields) {
|
|
150
|
-
const aVal = a[key];
|
|
151
|
-
const bVal = b[key];
|
|
152
|
-
|
|
153
|
-
let result: number;
|
|
154
|
-
|
|
155
|
-
if (typeof aVal === 'string' && typeof bVal === 'string') {
|
|
156
|
-
result = aVal.localeCompare(bVal);
|
|
157
|
-
} else if (typeof aVal === 'number' && typeof bVal === 'number') {
|
|
158
|
-
result = aVal - bVal;
|
|
159
|
-
} else {
|
|
160
|
-
result = String(aVal ?? '').localeCompare(String(bVal ?? ''));
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
if (result !== 0) return desc ? -result : result;
|
|
164
|
-
}
|
|
165
|
-
return 0;
|
|
166
|
-
};
|
|
167
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Insere um item em um array já ordenado, mantendo a ordenação
|
|
3
|
+
* com base na função de comparação fornecida.
|
|
4
|
+
*/
|
|
5
|
+
export function insertSorted<T>(
|
|
6
|
+
data: T[],
|
|
7
|
+
newItem: T,
|
|
8
|
+
compareFn: (a: T, b: T) => number
|
|
9
|
+
): T[] {
|
|
10
|
+
const index = data.findIndex((item) => compareFn(newItem, item) < 0);
|
|
11
|
+
if (index === -1) return [...data, newItem];
|
|
12
|
+
return [...data.slice(0, index), newItem, ...data.slice(index)];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface PaginatedPageCache<T> {
|
|
16
|
+
data: T[];
|
|
17
|
+
total: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface InsertIntoPaginatedCacheParams<T> {
|
|
21
|
+
/** Páginas atuais do cache, ordenadas por número de página (1..N). */
|
|
22
|
+
pages: PaginatedPageCache<T>[];
|
|
23
|
+
/** Números das páginas correspondentes (mesmo tamanho de `pages`). */
|
|
24
|
+
pageNumbers: number[];
|
|
25
|
+
/** Novo item a inserir. */
|
|
26
|
+
newItem: T;
|
|
27
|
+
/** Tamanho fixo de cada página. */
|
|
28
|
+
pageSize: number;
|
|
29
|
+
/**
|
|
30
|
+
* Função de comparação que mantém a ordem.
|
|
31
|
+
* Se não fornecida, insere no topo da página 1 (sem reordenar).
|
|
32
|
+
*/
|
|
33
|
+
compareFn?: (a: T, b: T) => number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Insere um item em um conjunto de páginas paginadas mantendo ordenação.
|
|
38
|
+
*
|
|
39
|
+
* Quando `compareFn` é fornecida, descobre em qual página o item deveria
|
|
40
|
+
* cair (comparando com o último item de cada página). Insere na posição
|
|
41
|
+
* correta e empurra o último item da página para a próxima, propagando
|
|
42
|
+
* o overflow até a última página disponível.
|
|
43
|
+
*
|
|
44
|
+
* Páginas não-afetadas retornam a mesma referência.
|
|
45
|
+
*/
|
|
46
|
+
export function insertIntoPaginatedCache<T>({
|
|
47
|
+
pages,
|
|
48
|
+
pageNumbers,
|
|
49
|
+
newItem,
|
|
50
|
+
pageSize,
|
|
51
|
+
compareFn,
|
|
52
|
+
}: InsertIntoPaginatedCacheParams<T>): PaginatedPageCache<T>[] {
|
|
53
|
+
if (!pages.length) return pages;
|
|
54
|
+
|
|
55
|
+
// Sem sort: insere no topo da página 1 e propaga overflow
|
|
56
|
+
if (!compareFn) {
|
|
57
|
+
// Só atualiza se a página 1 estiver no cache
|
|
58
|
+
const firstIdx = pageNumbers.indexOf(1);
|
|
59
|
+
if (firstIdx === -1) return pages;
|
|
60
|
+
|
|
61
|
+
const result: PaginatedPageCache<T>[] = pages.slice();
|
|
62
|
+
let carry: T | null = newItem;
|
|
63
|
+
for (let i = firstIdx; i < result.length && carry !== null; i++) {
|
|
64
|
+
const current = result[i];
|
|
65
|
+
const nextData: T[] = [carry, ...current.data];
|
|
66
|
+
const overflow: T | null =
|
|
67
|
+
nextData.length > pageSize ? nextData[nextData.length - 1] : null;
|
|
68
|
+
result[i] = {
|
|
69
|
+
...current,
|
|
70
|
+
data: overflow !== null ? nextData.slice(0, pageSize) : nextData,
|
|
71
|
+
total: current.total + 1,
|
|
72
|
+
};
|
|
73
|
+
carry = overflow;
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Descobre em qual página o item cai
|
|
79
|
+
let targetIdx = -1;
|
|
80
|
+
for (let i = 0; i < pages.length; i++) {
|
|
81
|
+
const page = pages[i];
|
|
82
|
+
if (!page.data.length) continue;
|
|
83
|
+
const last = page.data[page.data.length - 1];
|
|
84
|
+
// Se newItem vem antes (ou igual) ao último item desta página, cai aqui
|
|
85
|
+
if (compareFn(newItem, last) <= 0) {
|
|
86
|
+
targetIdx = i;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Não coube em nenhuma página com itens — tenta a última página se for incompleta
|
|
92
|
+
if (targetIdx === -1) {
|
|
93
|
+
const lastIdx = pages.length - 1;
|
|
94
|
+
const lastPage = pages[lastIdx];
|
|
95
|
+
if (lastPage.data.length < pageSize) {
|
|
96
|
+
targetIdx = lastIdx;
|
|
97
|
+
} else {
|
|
98
|
+
// Não cai em nenhuma página carregada — apenas incrementa total
|
|
99
|
+
return pages.map((p) => ({ ...p, total: p.total + 1 }));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Insere no target e propaga overflow para as páginas seguintes
|
|
104
|
+
const result: PaginatedPageCache<T>[] = pages.slice();
|
|
105
|
+
let carry: T | null = newItem;
|
|
106
|
+
|
|
107
|
+
for (let i = targetIdx; i < result.length && carry !== null; i++) {
|
|
108
|
+
const current = result[i];
|
|
109
|
+
const withInserted: T[] = insertSorted(current.data, carry, compareFn);
|
|
110
|
+
const overflow: T | null =
|
|
111
|
+
withInserted.length > pageSize ? withInserted[withInserted.length - 1] : null;
|
|
112
|
+
result[i] = {
|
|
113
|
+
...current,
|
|
114
|
+
data: overflow !== null ? withInserted.slice(0, pageSize) : withInserted,
|
|
115
|
+
total: current.total + 1,
|
|
116
|
+
};
|
|
117
|
+
carry = overflow;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Incrementa o total nas páginas anteriores ao target (não mudaram mas o total global cresceu)
|
|
121
|
+
for (let i = 0; i < targetIdx; i++) {
|
|
122
|
+
result[i] = { ...result[i], total: result[i].total + 1 };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Cria uma função de comparação a partir de uma string de sort da API.
|
|
130
|
+
* Suporta múltiplos campos separados por vírgula e prefixo `-` para desc.
|
|
131
|
+
*
|
|
132
|
+
* Exemplos:
|
|
133
|
+
* - "title" → ascendente por title
|
|
134
|
+
* - "-title" → descendente por title
|
|
135
|
+
* - "title,-datetime_add" → ascendente por title, depois descendente por datetime_add
|
|
136
|
+
*/
|
|
137
|
+
export function buildCompareFn<T extends Record<string, unknown>>(
|
|
138
|
+
sort: string
|
|
139
|
+
): (a: T, b: T) => number {
|
|
140
|
+
const fields = sort.split(',').map((f) => f.trim()).filter(Boolean);
|
|
141
|
+
|
|
142
|
+
const parsedFields = fields.map((field) => {
|
|
143
|
+
const desc = field.startsWith('-');
|
|
144
|
+
const key = desc ? field.slice(1) : field;
|
|
145
|
+
return { key, desc };
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
return (a: T, b: T) => {
|
|
149
|
+
for (const { key, desc } of parsedFields) {
|
|
150
|
+
const aVal = a[key];
|
|
151
|
+
const bVal = b[key];
|
|
152
|
+
|
|
153
|
+
let result: number;
|
|
154
|
+
|
|
155
|
+
if (typeof aVal === 'string' && typeof bVal === 'string') {
|
|
156
|
+
result = aVal.localeCompare(bVal);
|
|
157
|
+
} else if (typeof aVal === 'number' && typeof bVal === 'number') {
|
|
158
|
+
result = aVal - bVal;
|
|
159
|
+
} else {
|
|
160
|
+
result = String(aVal ?? '').localeCompare(String(bVal ?? ''));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (result !== 0) return desc ? -result : result;
|
|
164
|
+
}
|
|
165
|
+
return 0;
|
|
166
|
+
};
|
|
167
|
+
}
|
package/src/infra/utils/date.ts
CHANGED
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
import z from 'zod';
|
|
2
|
-
|
|
3
|
-
function parseCalendarDate(val: unknown): Date | unknown {
|
|
4
|
-
if (val == null) return val;
|
|
5
|
-
if (val instanceof Date) {
|
|
6
|
-
return new Date(val.getUTCFullYear(), val.getUTCMonth(), val.getUTCDate());
|
|
7
|
-
}
|
|
8
|
-
if (typeof val === 'string') {
|
|
9
|
-
const match = val.match(/^(\d{4})-(\d{2})-(\d{2})/);
|
|
10
|
-
if (match) {
|
|
11
|
-
return new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3]));
|
|
12
|
-
}
|
|
13
|
-
const fallback = new Date(val);
|
|
14
|
-
if (!Number.isNaN(fallback.getTime())) {
|
|
15
|
-
return new Date(fallback.getUTCFullYear(), fallback.getUTCMonth(), fallback.getUTCDate());
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
return val;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const calendarDateSchema = () => z.preprocess(parseCalendarDate, z.date());
|
|
22
|
-
|
|
23
|
-
export function toCalendarDate(date: Date | string | null | undefined): Date | null {
|
|
24
|
-
if (!date) return null;
|
|
25
|
-
const parsed = parseCalendarDate(date);
|
|
26
|
-
return parsed instanceof Date ? parsed : null;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Diferença em dias entre duas datas. O caller é responsável por passar
|
|
33
|
-
* datas normalizadas (via toCalendarDate) pra evitar off-by-one por fuso.
|
|
34
|
-
*/
|
|
35
|
-
export function daysBetween(a: Date, b: Date): number {
|
|
36
|
-
return Math.round((b.getTime() - a.getTime()) / MS_PER_DAY);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function formatShortDate(date: Date | string | null | undefined): string {
|
|
40
|
-
if (!date) return '--';
|
|
41
|
-
const d = toCalendarDate(date) ?? new Date(date);
|
|
42
|
-
const day = String(d.getDate()).padStart(2, '0');
|
|
43
|
-
const month = String(d.getMonth() + 1).padStart(2, '0');
|
|
44
|
-
if (d.getFullYear() !== new Date().getFullYear()) {
|
|
45
|
-
return `${day}/${month}/${d.getFullYear()}`;
|
|
46
|
-
}
|
|
47
|
-
return `${day}/${month}`;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function formatDateTime(date: Date | string | null | undefined): string | null {
|
|
51
|
-
if (!date) return null;
|
|
52
|
-
return new Date(date).toLocaleString('pt-BR', {
|
|
53
|
-
day: '2-digit',
|
|
54
|
-
month: '2-digit',
|
|
55
|
-
year: 'numeric',
|
|
56
|
-
hour: '2-digit',
|
|
57
|
-
minute: '2-digit',
|
|
58
|
-
});
|
|
59
|
-
}
|
|
1
|
+
import z from 'zod';
|
|
2
|
+
|
|
3
|
+
function parseCalendarDate(val: unknown): Date | unknown {
|
|
4
|
+
if (val == null) return val;
|
|
5
|
+
if (val instanceof Date) {
|
|
6
|
+
return new Date(val.getUTCFullYear(), val.getUTCMonth(), val.getUTCDate());
|
|
7
|
+
}
|
|
8
|
+
if (typeof val === 'string') {
|
|
9
|
+
const match = val.match(/^(\d{4})-(\d{2})-(\d{2})/);
|
|
10
|
+
if (match) {
|
|
11
|
+
return new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3]));
|
|
12
|
+
}
|
|
13
|
+
const fallback = new Date(val);
|
|
14
|
+
if (!Number.isNaN(fallback.getTime())) {
|
|
15
|
+
return new Date(fallback.getUTCFullYear(), fallback.getUTCMonth(), fallback.getUTCDate());
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return val;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const calendarDateSchema = () => z.preprocess(parseCalendarDate, z.date());
|
|
22
|
+
|
|
23
|
+
export function toCalendarDate(date: Date | string | null | undefined): Date | null {
|
|
24
|
+
if (!date) return null;
|
|
25
|
+
const parsed = parseCalendarDate(date);
|
|
26
|
+
return parsed instanceof Date ? parsed : null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Diferença em dias entre duas datas. O caller é responsável por passar
|
|
33
|
+
* datas normalizadas (via toCalendarDate) pra evitar off-by-one por fuso.
|
|
34
|
+
*/
|
|
35
|
+
export function daysBetween(a: Date, b: Date): number {
|
|
36
|
+
return Math.round((b.getTime() - a.getTime()) / MS_PER_DAY);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function formatShortDate(date: Date | string | null | undefined): string {
|
|
40
|
+
if (!date) return '--';
|
|
41
|
+
const d = toCalendarDate(date) ?? new Date(date);
|
|
42
|
+
const day = String(d.getDate()).padStart(2, '0');
|
|
43
|
+
const month = String(d.getMonth() + 1).padStart(2, '0');
|
|
44
|
+
if (d.getFullYear() !== new Date().getFullYear()) {
|
|
45
|
+
return `${day}/${month}/${d.getFullYear()}`;
|
|
46
|
+
}
|
|
47
|
+
return `${day}/${month}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function formatDateTime(date: Date | string | null | undefined): string | null {
|
|
51
|
+
if (!date) return null;
|
|
52
|
+
return new Date(date).toLocaleString('pt-BR', {
|
|
53
|
+
day: '2-digit',
|
|
54
|
+
month: '2-digit',
|
|
55
|
+
year: 'numeric',
|
|
56
|
+
hour: '2-digit',
|
|
57
|
+
minute: '2-digit',
|
|
58
|
+
});
|
|
59
|
+
}
|
package/src/middleware.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createAuthMiddleware } from './middlewares/create-auth-middleware';
|
|
2
|
-
export { createMiddlewareChain } from './middlewares/chain';
|
|
3
|
-
export type { MiddlewareConfig, MiddlewareFunction, MiddlewareResult } from './middlewares/types';
|
|
4
|
-
export { continueChain, stopChain } from './middlewares/types';
|
|
1
|
+
export { createAuthMiddleware } from './middlewares/create-auth-middleware';
|
|
2
|
+
export { createMiddlewareChain } from './middlewares/chain';
|
|
3
|
+
export type { MiddlewareConfig, MiddlewareFunction, MiddlewareResult } from './middlewares/types';
|
|
4
|
+
export { continueChain, stopChain } from './middlewares/types';
|